build: enable address/undefined sanitizer build target and add -Wpedantic -Wshadow -fstack-protector-strong flags

This commit is contained in:
2026-01-24 12:26:45 +00:00
parent c32bda853c
commit 51c3d4b919
33 changed files with 169 additions and 436 deletions
+1 -1
View File
@@ -39,7 +39,7 @@ static size_t write_callback(void *contents, size_t size, size_t nmemb, void *us
size_t realsize = size * nmemb;
ResponseBuffer *buf = (ResponseBuffer *)userp;
char *ptr = realloc(buf->data, buf->size + realsize + 1);
char *ptr = dwn_realloc(buf->data, buf->size + realsize + 1);
if (ptr == NULL) {
return 0;
}
+14 -10
View File
@@ -244,9 +244,11 @@ static void add_to_recent(const char *desktop_id)
for (int i = 0; i < launcher_state.recent_count; i++) {
if (strcmp(launcher_state.recent[i], desktop_id) == 0) {
for (int j = i; j > 0; j--) {
strcpy(launcher_state.recent[j], launcher_state.recent[j-1]);
memcpy(launcher_state.recent[j], launcher_state.recent[j-1],
sizeof(launcher_state.recent[0]));
}
strcpy(launcher_state.recent[0], desktop_id);
snprintf(launcher_state.recent[0], sizeof(launcher_state.recent[0]),
"%s", desktop_id);
save_recent_apps();
return;
}
@@ -257,9 +259,11 @@ static void add_to_recent(const char *desktop_id)
}
for (int i = launcher_state.recent_count - 1; i > 0; i--) {
strcpy(launcher_state.recent[i], launcher_state.recent[i-1]);
memcpy(launcher_state.recent[i], launcher_state.recent[i-1],
sizeof(launcher_state.recent[0]));
}
strncpy(launcher_state.recent[0], desktop_id, sizeof(launcher_state.recent[0]) - 1);
snprintf(launcher_state.recent[0], sizeof(launcher_state.recent[0]),
"%s", desktop_id);
save_recent_apps();
}
@@ -330,16 +334,16 @@ void applauncher_show(void)
}
size_t buf_size = launcher_state.app_count * 140;
char *choices = malloc(buf_size);
char *choices = dwn_malloc(buf_size);
if (choices == NULL) {
LOG_ERROR("Failed to allocate memory for app list");
return;
}
choices[0] = '\0';
bool *added = calloc(launcher_state.app_count, sizeof(bool));
bool *added = dwn_calloc(launcher_state.app_count, sizeof(bool));
if (added == NULL) {
free(choices);
dwn_free(choices);
return;
}
@@ -379,19 +383,19 @@ void applauncher_show(void)
choices[pos-1] = '\0';
}
free(added);
dwn_free(added);
char tmp_path[] = "/tmp/dwn_apps_XXXXXX";
int tmp_fd = mkstemp(tmp_path);
if (tmp_fd < 0) {
free(choices);
dwn_free(choices);
LOG_ERROR("Failed to create temp file for app list");
return;
}
ssize_t written = write(tmp_fd, choices, strlen(choices));
close(tmp_fd);
free(choices);
dwn_free(choices);
if (written < 0) {
unlink(tmp_path);
+17 -1
View File
@@ -16,6 +16,8 @@ EWMHAtoms ewmh;
ICCCMAtoms icccm;
MiscAtoms misc_atoms;
static Window ewmh_check_window = None;
#define ATOM(name) XInternAtom(display, name, False)
void atoms_init(Display *display)
@@ -124,7 +126,8 @@ void atoms_setup_ewmh(void)
Display *dpy = dwn->display;
Window root = dwn->root;
Window check = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, 0, 0);
ewmh_check_window = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, 0, 0);
Window check = ewmh_check_window;
XChangeProperty(dpy, root, ewmh.NET_SUPPORTING_WM_CHECK,
XA_WINDOW, 32, PropModeReplace,
@@ -510,3 +513,16 @@ bool atoms_update_wm_state(Window window, Atom state, bool add)
return true;
}
void atoms_cleanup(void)
{
if (dwn == NULL || dwn->display == NULL) {
return;
}
if (ewmh_check_window != None) {
XDestroyWindow(dwn->display, ewmh_check_window);
ewmh_check_window = None;
LOG_DEBUG("EWMH check window destroyed");
}
}
+2 -1
View File
@@ -410,7 +410,8 @@ static void demo_phase_workspaces(void)
"DWN provides 9 virtual workspaces:\n\n"
"- F1 to F9: Switch workspace\n"
"- Shift+F1-F9: Move window to workspace\n"
"- Ctrl+Alt+Left/Right: Navigate\n\n"
"- Ctrl+Alt+Left/Right: Navigate\n"
"- Super+Shift+Left/Right: Move window\n\n"
"Watch the workspace indicators in the panel...", 0);
demo_wait_for(DEMO_WAIT_TIME, demo_get_step_delay());
demo_next_step();
+103 -21
View File
@@ -92,140 +92,161 @@ static const TutorialStep tutorial_steps[] = {
MOD_SUPER, XK_t
},
{
"1/20: Open Terminal",
"1/23: Open Terminal",
"The terminal is your command center.\n\n"
"Press: Ctrl + Alt + T",
"Hold Ctrl and Alt, then press T",
MOD_CTRL | MOD_ALT, XK_t
},
{
"2/20: App Launcher",
"2/23: App Launcher",
"Launch any application by name.\n\n"
"Press: Alt + F2",
"Type app name and press Enter",
MOD_ALT, XK_F2
},
{
"3/20: File Manager",
"3/23: File Manager",
"Open the file manager.\n\n"
"Press: Super + E",
"",
MOD_SUPER, XK_e
},
{
"4/20: Web Browser",
"4/23: Web Browser",
"Open your default web browser.\n\n"
"Press: Super + B",
"",
MOD_SUPER, XK_b
},
{
"5/20: Switch Windows",
"5/23: Switch Windows",
"Cycle through open windows.\n\n"
"Press: Alt + Tab",
"Hold Alt, press Tab repeatedly",
MOD_ALT, XK_Tab
},
{
"6/20: Close Window",
"6/23: Close Window",
"Close the focused window.\n\n"
"Press: Alt + F4",
"",
MOD_ALT, XK_F4
},
{
"7/20: Toggle Maximize",
"7/23: Show Desktop",
"Minimize all windows to show desktop.\n\n"
"Press: Super + D",
"Press again to restore windows",
MOD_SUPER, XK_d
},
{
"8/23: Toggle Maximize",
"Maximize or restore a window.\n\n"
"Press: Alt + F10",
"",
MOD_ALT, XK_F10
},
{
"8/20: Toggle Fullscreen",
"9/23: Toggle Fullscreen",
"Make a window fullscreen.\n\n"
"Press: Alt + F11",
"Press again to exit",
MOD_ALT, XK_F11
},
{
"9/20: Toggle Floating",
"10/23: Toggle Floating",
"Make window float above tiled windows.\n\n"
"Press: Super + F9",
"",
MOD_SUPER, XK_F9
},
{
"10/20: Next Workspace",
"11/23: Next Workspace",
"Switch to the next virtual desktop.\n\n"
"Press: Ctrl + Alt + Right",
"",
MOD_CTRL | MOD_ALT, XK_Right
},
{
"11/20: Previous Workspace",
"12/23: Previous Workspace",
"Switch to the previous workspace.\n\n"
"Press: Ctrl + Alt + Left",
"",
MOD_CTRL | MOD_ALT, XK_Left
},
{
"12/20: Go to Workspace",
"13/23: Go to Workspace",
"Jump directly to workspace 1.\n\n"
"Press: F1",
"Use F1-F9 for workspaces 1-9",
0, XK_F1
},
{
"13/20: Cycle Layout",
"14/23: Move Window to Prev Workspace",
"Send the focused window to previous workspace.\n\n"
"Press: Super + Shift + Left",
"Window moves, you stay",
MOD_SUPER | MOD_SHIFT, XK_Left
},
{
"15/23: Move Window to Next Workspace",
"Send the focused window to next workspace.\n\n"
"Press: Super + Shift + Right",
"Window moves, you stay",
MOD_SUPER | MOD_SHIFT, XK_Right
},
{
"16/23: Cycle Layout",
"Switch between tiling, floating, monocle.\n\n"
"Press: Super + Space",
"Try it multiple times!",
MOD_SUPER, XK_space
},
{
"14/20: Expand Master",
"17/23: Expand Master",
"Make the master area larger.\n\n"
"Press: Super + L",
"",
MOD_SUPER, XK_l
},
{
"15/20: Shrink Master",
"18/23: Shrink Master",
"Make the master area smaller.\n\n"
"Press: Super + H",
"",
MOD_SUPER, XK_h
},
{
"16/20: Add to Master",
"19/23: Add to Master",
"Increase windows in master area.\n\n"
"Press: Super + I",
"",
MOD_SUPER, XK_i
},
{
"17/20: AI Command",
"20/23: AI Command",
"Ask AI to run commands for you.\n\n"
"Press: Super + A",
"Requires OPENROUTER_API_KEY",
MOD_SUPER, XK_a
},
{
"18/20: AI Context",
"21/23: AI Context",
"Show AI analysis of your current task.\n\n"
"Press: Super + Shift + A",
"Requires OPENROUTER_API_KEY",
MOD_SUPER | MOD_SHIFT, XK_a
},
{
"19/20: Exa Search",
"22/23: Exa Search",
"Semantic web search.\n\n"
"Press: Super + Shift + E",
"Requires EXA_API_KEY",
MOD_SUPER | MOD_SHIFT, XK_e
},
{
"20/20: Show Shortcuts",
"23/23: Show Shortcuts",
"Display all keyboard shortcuts.\n\n"
"Press: Super + S",
"Shows complete reference",
@@ -519,10 +540,14 @@ void keys_setup_defaults(void)
keys_bind(MOD_SUPER, XK_l, key_increase_master, "Increase master ratio");
keys_bind(MOD_SUPER, XK_h, key_decrease_master, "Decrease master ratio");
keys_bind(MOD_SUPER, XK_i, key_increase_master_count, "Increase master count");
keys_bind(MOD_SUPER, XK_d, key_decrease_master_count, "Decrease master count");
keys_bind(MOD_SUPER, XK_minus, key_decrease_master_count, "Decrease master count");
keys_bind(MOD_SUPER, XK_d, key_show_desktop, "Show desktop");
keys_bind(MOD_SUPER, XK_Left, key_snap_left, "Snap window left");
keys_bind(MOD_SUPER, XK_Right, key_snap_right, "Snap window right");
keys_bind(MOD_SUPER | MOD_SHIFT, XK_Left, key_move_to_workspace_prev, "Move window to previous workspace");
keys_bind(MOD_SUPER | MOD_SHIFT, XK_Right, key_move_to_workspace_next, "Move window to next workspace");
keys_bind(MOD_SUPER, XK_a, key_ai_command, "AI command");
keys_bind(MOD_SUPER | MOD_SHIFT, XK_a, key_toggle_ai, "Toggle AI context");
@@ -725,6 +750,63 @@ void key_decrease_master_count(void)
workspace_adjust_master_count(dwn->current_workspace, -1);
}
void key_show_desktop(void)
{
if (dwn == NULL) {
return;
}
if (!dwn->desktop_shown) {
dwn->desktop_minimized_count = 0;
for (Client *c = dwn->client_list; c != NULL; c = c->next) {
if (c->workspace == (unsigned int)dwn->current_workspace &&
!client_is_minimized(c) &&
dwn->desktop_minimized_count < MAX_CLIENTS) {
dwn->desktop_minimized[dwn->desktop_minimized_count++] = c->window;
client_minimize(c);
}
}
dwn->desktop_shown = true;
} else {
for (int i = 0; i < dwn->desktop_minimized_count; i++) {
Client *c = client_find_by_window(dwn->desktop_minimized[i]);
if (c != NULL && c->workspace == (unsigned int)dwn->current_workspace) {
client_restore(c);
}
}
dwn->desktop_minimized_count = 0;
dwn->desktop_shown = false;
}
}
void key_move_to_workspace_prev(void)
{
if (dwn == NULL) {
return;
}
int target = dwn->current_workspace - 1;
if (target < 0) {
target = MAX_WORKSPACES - 1;
}
move_focused_to_workspace(target);
}
void key_move_to_workspace_next(void)
{
if (dwn == NULL) {
return;
}
int target = dwn->current_workspace + 1;
if (target >= MAX_WORKSPACES) {
target = 0;
}
move_focused_to_workspace(target);
}
void key_toggle_ai(void)
{
if (dwn == NULL) {
-14
View File
@@ -416,15 +416,6 @@ static void handle_button_press(XButtonEvent *ev)
}
}
if (wifi_menu != NULL && wifi_menu->visible) {
if (ev->window == wifi_menu->window) {
dropdown_handle_click(wifi_menu, ev->x, ev->y);
return;
} else {
dropdown_hide(wifi_menu);
}
}
Notification *notif = notification_find_by_window(ev->window);
if (notif != NULL) {
notification_close(notif->id);
@@ -531,11 +522,6 @@ static void handle_motion_notify(XMotionEvent *ev)
return;
}
if (wifi_menu != NULL && wifi_menu->visible && ev->window == wifi_menu->window) {
dropdown_handle_motion(wifi_menu, ev->x, ev->y);
return;
}
if (dwn->drag_client == NULL) {
return;
}
+10 -2
View File
@@ -54,7 +54,7 @@ static size_t news_curl_write_cb(void *contents, size_t size, size_t nmemb, void
size_t realsize = size * nmemb;
CurlBuffer *buf = (CurlBuffer *)userp;
char *ptr = realloc(buf->data, buf->size + realsize + 1);
char *ptr = dwn_realloc(buf->data, buf->size + realsize + 1);
if (ptr == NULL) {
return 0;
}
@@ -374,7 +374,15 @@ static void *news_fetch_thread(void *arg)
}
CurlBuffer buf = {0};
buf.data = malloc(1);
buf.data = dwn_malloc(1);
if (buf.data == NULL) {
curl_easy_cleanup(curl);
pthread_mutex_lock(&news_mutex);
news_state.fetching = false;
news_state.has_error = true;
pthread_mutex_unlock(&news_mutex);
return NULL;
}
buf.data[0] = '\0';
curl_easy_setopt(curl, CURLOPT_URL, NEWS_API_URL);
+2 -2
View File
@@ -552,8 +552,8 @@ void panel_handle_click(Panel *panel, int x, int y, int button)
if (client_is_minimized(c)) {
client_restore(c);
} else {
Workspace *ws = workspace_get(dwn->current_workspace);
if (ws != NULL && ws->focused == c) {
Workspace *current = workspace_get(dwn->current_workspace);
if (current != NULL && current->focused == c) {
client_minimize(c);
} else {
client_focus(c, true);
+1 -347
View File
@@ -35,20 +35,14 @@
#define ASCII_CHARGING "+"
#define SYSTRAY_SPACING 12
#define DROPDOWN_ITEM_HEIGHT 28
#define DROPDOWN_WIDTH 400
#define DROPDOWN_PADDING 8
#define SLIDER_WIDTH 30
#define SLIDER_HEIGHT 120
#define SLIDER_PADDING 8
#define SLIDER_KNOB_HEIGHT 8
#define WIFI_SCAN_INTERVAL 10000
WifiState wifi_state = {0};
AudioState audio_state = {0};
BatteryState battery_state = {0};
DropdownMenu *wifi_menu = NULL;
VolumeSlider *volume_slider = NULL;
TrayIcon tray_icons[MAX_TRAY_ICONS];
@@ -174,10 +168,6 @@ void systray_cleanup(void)
pthread_join(update_thread, NULL);
}
if (wifi_menu != NULL) {
dropdown_destroy(wifi_menu);
wifi_menu = NULL;
}
if (volume_slider != NULL) {
volume_slider_destroy(volume_slider);
volume_slider = NULL;
@@ -309,82 +299,6 @@ void wifi_update_state(void)
{
}
void wifi_scan_networks(void)
{
FILE *fp;
char line[512];
WifiNetwork temp_networks[MAX_WIFI_NETWORKS];
int temp_count = 0;
long scan_time = get_time_ms();
fp = popen("nmcli -t -f SSID,SIGNAL,SECURITY,IN-USE dev wifi list 2>/dev/null", "r");
if (fp == NULL) {
LOG_WARN("Failed to scan WiFi networks");
return;
}
while (fgets(line, sizeof(line), fp) != NULL && temp_count < MAX_WIFI_NETWORKS) {
line[strcspn(line, "\n")] = '\0';
char *ssid = strtok(line, ":");
char *signal = strtok(NULL, ":");
char *security = strtok(NULL, ":");
char *in_use = strtok(NULL, ":");
if (ssid != NULL && strlen(ssid) > 0) {
WifiNetwork *net = &temp_networks[temp_count];
strncpy(net->ssid, ssid, sizeof(net->ssid) - 1);
net->ssid[sizeof(net->ssid) - 1] = '\0';
net->signal = signal ? atoi(signal) : 0;
strncpy(net->security, security ? security : "", sizeof(net->security) - 1);
net->security[sizeof(net->security) - 1] = '\0';
net->connected = (in_use != NULL && in_use[0] == '*');
temp_count++;
}
}
pclose(fp);
pthread_mutex_lock(&state_mutex);
memcpy(wifi_state.networks, temp_networks, sizeof(temp_networks));
wifi_state.network_count = temp_count;
wifi_state.last_scan = scan_time;
pthread_mutex_unlock(&state_mutex);
LOG_DEBUG("Scanned %d WiFi networks", temp_count);
}
void wifi_connect(const char *ssid)
{
if (ssid == NULL || strlen(ssid) == 0) {
return;
}
char cmd[256];
snprintf(cmd, sizeof(cmd), "nmcli dev wifi connect \"%s\" &", ssid);
char msg[128];
snprintf(msg, sizeof(msg), "Connecting to %s...", ssid);
notification_show("WiFi", "Connecting", msg, NULL, 3000);
spawn_async(cmd);
pthread_mutex_lock(&state_mutex);
wifi_state.connected = false;
pthread_mutex_unlock(&state_mutex);
}
void wifi_disconnect(void)
{
spawn_async("nmcli dev disconnect wlan0 &");
pthread_mutex_lock(&state_mutex);
wifi_state.connected = false;
pthread_mutex_unlock(&state_mutex);
notification_show("WiFi", "Disconnected", "WiFi connection closed", NULL, 2000);
}
const char *wifi_get_icon(void)
{
if (!wifi_state.enabled || !wifi_state.connected) {
@@ -615,227 +529,6 @@ void volume_slider_handle_release(VolumeSlider *slider)
}
DropdownMenu *dropdown_create(int x, int y, int width)
{
if (dwn == NULL || dwn->display == NULL) {
return NULL;
}
DropdownMenu *menu = dwn_calloc(1, sizeof(DropdownMenu));
menu->x = x;
menu->y = y;
menu->width = width;
menu->height = 0;
menu->item_count = 0;
menu->hovered_item = -1;
menu->visible = false;
menu->on_select = NULL;
return menu;
}
void dropdown_destroy(DropdownMenu *menu)
{
if (menu == NULL) {
return;
}
if (menu->window != None && dwn != NULL && dwn->display != NULL) {
XDestroyWindow(dwn->display, menu->window);
}
dwn_free(menu);
}
void dropdown_show(DropdownMenu *menu)
{
if (menu == NULL || dwn == NULL || dwn->display == NULL) {
return;
}
wifi_scan_networks();
menu->item_count = wifi_state.network_count;
menu->height = menu->item_count * DROPDOWN_ITEM_HEIGHT + 2 * DROPDOWN_PADDING;
if (menu->height < DROPDOWN_ITEM_HEIGHT + 2 * DROPDOWN_PADDING) {
menu->height = DROPDOWN_ITEM_HEIGHT + 2 * DROPDOWN_PADDING;
menu->item_count = 1;
}
int max_text_width = 0;
for (int i = 0; i < wifi_state.network_count; i++) {
WifiNetwork *net = &wifi_state.networks[i];
char label[128];
snprintf(label, sizeof(label), "%s %d%%", net->ssid, net->signal);
int text_width = get_text_width(label);
if (text_width > max_text_width) {
max_text_width = text_width;
}
}
int min_width = 250;
int calculated_width = max_text_width + 2 * DROPDOWN_PADDING + 30;
menu->width = (calculated_width > min_width) ? calculated_width : min_width;
if (menu->window == None) {
XSetWindowAttributes swa;
swa.override_redirect = True;
swa.background_pixel = dwn->config->colors.panel_bg;
swa.border_pixel = dwn->config->colors.border_focused;
swa.event_mask = ExposureMask | ButtonPressMask | PointerMotionMask |
LeaveWindowMask | EnterWindowMask;
menu->window = XCreateWindow(dwn->display, dwn->root,
menu->x, menu->y,
menu->width, menu->height,
0,
CopyFromParent, InputOutput, CopyFromParent,
CWOverrideRedirect | CWBackPixel | CWBorderPixel | CWEventMask,
&swa);
} else {
XMoveResizeWindow(dwn->display, menu->window,
menu->x, menu->y, menu->width, menu->height);
}
menu->visible = true;
XMapRaised(dwn->display, menu->window);
dropdown_render(menu);
}
void dropdown_hide(DropdownMenu *menu)
{
if (menu == NULL || menu->window == None) {
return;
}
menu->visible = false;
XUnmapWindow(dwn->display, menu->window);
}
void dropdown_render(DropdownMenu *menu)
{
if (menu == NULL || menu->window == None || !menu->visible) {
return;
}
if (dwn == NULL || dwn->display == NULL) {
return;
}
Display *dpy = dwn->display;
const ColorScheme *colors = config_get_colors();
int font_height = 12;
if (dwn->xft_font != NULL) {
font_height = dwn->xft_font->ascent;
} else if (dwn->font != NULL) {
font_height = dwn->font->ascent;
}
int text_y_offset = (DROPDOWN_ITEM_HEIGHT + font_height) / 2;
XSetForeground(dpy, dwn->gc, colors->panel_bg);
XFillRectangle(dpy, menu->window, dwn->gc, 0, 0, menu->width, menu->height);
if (wifi_state.network_count == 0) {
draw_utf8_text(menu->window, DROPDOWN_PADDING, DROPDOWN_PADDING + text_y_offset,
"No networks found", colors->workspace_inactive);
} else {
for (int i = 0; i < wifi_state.network_count && i < MAX_WIFI_NETWORKS; i++) {
WifiNetwork *net = &wifi_state.networks[i];
int y = DROPDOWN_PADDING + i * DROPDOWN_ITEM_HEIGHT;
if (i == menu->hovered_item) {
XSetForeground(dpy, dwn->gc, colors->workspace_active);
XFillRectangle(dpy, menu->window, dwn->gc,
2, y, menu->width - 4, DROPDOWN_ITEM_HEIGHT);
}
unsigned long text_color = (i == menu->hovered_item) ? colors->panel_bg : colors->panel_fg;
char label[80];
if (net->connected) {
snprintf(label, sizeof(label), "> %s", net->ssid);
} else {
snprintf(label, sizeof(label), " %s", net->ssid);
}
if (strlen(label) > 25) {
label[22] = '.';
label[23] = '.';
label[24] = '.';
label[25] = '\0';
}
draw_utf8_text(menu->window, DROPDOWN_PADDING, y + text_y_offset, label, text_color);
char signal[8];
snprintf(signal, sizeof(signal), "%d%%", net->signal);
int signal_width = get_text_width(signal);
int signal_x = menu->width - DROPDOWN_PADDING - signal_width;
unsigned long signal_color = (i == menu->hovered_item) ? colors->panel_bg : colors->workspace_inactive;
draw_utf8_text(menu->window, signal_x, y + text_y_offset, signal, signal_color);
}
}
XFlush(dpy);
}
int dropdown_hit_test(DropdownMenu *menu, int x, int y)
{
(void)x;
if (menu == NULL || !menu->visible) {
return -1;
}
if (y < DROPDOWN_PADDING || y >= menu->height - DROPDOWN_PADDING) {
return -1;
}
int item = (y - DROPDOWN_PADDING) / DROPDOWN_ITEM_HEIGHT;
if (item >= 0 && item < menu->item_count) {
return item;
}
return -1;
}
void dropdown_handle_click(DropdownMenu *menu, int x, int y)
{
if (menu == NULL || !menu->visible) {
return;
}
int item = dropdown_hit_test(menu, x, y);
if (item >= 0 && item < wifi_state.network_count) {
WifiNetwork *net = &wifi_state.networks[item];
if (net->connected) {
wifi_disconnect();
} else {
wifi_connect(net->ssid);
}
dropdown_hide(menu);
}
}
void dropdown_handle_motion(DropdownMenu *menu, int x, int y)
{
if (menu == NULL || !menu->visible) {
return;
}
int old_hovered = menu->hovered_item;
menu->hovered_item = dropdown_hit_test(menu, x, y);
if (menu->hovered_item != old_hovered) {
dropdown_render(menu);
}
}
int systray_get_width(void)
{
pthread_mutex_lock(&state_mutex);
@@ -955,34 +648,7 @@ void systray_handle_click(int x, int y, int button)
return;
}
if (widget == 0) {
if (volume_slider != NULL && volume_slider->visible) {
volume_slider_hide(volume_slider);
}
if (button == 1) {
if (wifi_menu == NULL) {
int panel_height = config_get_panel_height();
wifi_menu = dropdown_create(wifi_icon_x, panel_height, DROPDOWN_WIDTH);
}
if (wifi_menu->visible) {
dropdown_hide(wifi_menu);
} else {
wifi_menu->x = wifi_icon_x;
wifi_menu->y = config_get_panel_height();
dropdown_show(wifi_menu);
}
} else if (button == 3) {
if (wifi_state.connected) {
wifi_disconnect();
}
}
} else if (widget == 1) {
if (wifi_menu != NULL && wifi_menu->visible) {
dropdown_hide(wifi_menu);
}
if (widget == 1) {
if (button == 1) {
if (volume_slider == NULL) {
int panel_height = config_get_panel_height();
@@ -1019,18 +685,6 @@ void systray_handle_click(int x, int y, int button)
void systray_update(void)
{
if (wifi_menu != NULL && wifi_menu->visible) {
long now = get_time_ms();
pthread_mutex_lock(&state_mutex);
long last_scan = wifi_state.last_scan;
pthread_mutex_unlock(&state_mutex);
if (now - last_scan >= WIFI_SCAN_INTERVAL) {
wifi_scan_networks();
dropdown_render(wifi_menu);
}
}
}