nyxwm

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit a237c6e6293f2ba916f3ae06fa751a5ba7ba9ad1
parent c538c0234447ae554d095f6dd5e08a88400130b0
Author: nyangkosense <sebastian.michalk@protonmail.com>
Date:   Tue, 15 Oct 2024 20:55:25 +0000

fix systray

Diffstat:
Dconfig.h | 59-----------------------------------------------------------
Mnyxwm.c | 183+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Mnyxwm.h | 2+-
3 files changed, 100 insertions(+), 144 deletions(-)

diff --git a/config.h b/config.h @@ -1,59 +0,0 @@ -#ifndef CONFIG_H -#define CONFIG_H - -// stats bar -#define BAR_HEIGHT 20 -#define FONT "monospace:size=10" -#define BAR_COLOR "#333333" -#define TEXT_COLOR "#FFFFFF" - -// tray -#define TRAY_ICON_SIZE 25 -#define TRAY_ICON_SPACING 4 -#define TRAY_PADDING 4 - -#define MOD Mod4Mask -#define BORDER_COLOR "#ffffff" -#define BORDER_WIDTH 1 -const char* menu[] = {"dmenu_run", 0}; -const char* term[] = {"st", 0}; -const char* scrot[] = {"scr", 0}; -const char* briup[] = {"bri", "10", "+", 0}; -const char* bridown[] = {"bri", "10", "-", 0}; -const char* voldown[] = {"amixer", "sset", "Master", "5%-", 0}; -const char* volup[] = {"amixer", "sset", "Master", "5%+", 0}; -const char* volmute[] = {"amixer", "sset", "Master", "toggle", 0}; - -static struct key keys[] = { - {MOD, XK_q, win_kill, {0}}, - {MOD, XK_c, win_center, {0}}, - {MOD, XK_f, win_fs, {0}}, - - {Mod1Mask, XK_Tab, win_next, {0}}, - {Mod1Mask|ShiftMask, XK_Tab, win_prev, {0}}, - - {MOD, XK_d, run, {.com = menu}}, - {MOD, XK_p, run, {.com = scrot}}, - {MOD, XK_Return, run, {.com = term}}, - - {0, XF86XK_AudioLowerVolume, run, {.com = voldown}}, - {0, XF86XK_AudioRaiseVolume, run, {.com = volup}}, - {0, XF86XK_AudioMute, run, {.com = volmute}}, - {0, XF86XK_MonBrightnessUp, run, {.com = briup}}, - {0, XF86XK_MonBrightnessDown, run, {.com = bridown}}, - - {MOD, XK_1, ws_go, {.i = 1}}, - {MOD|ShiftMask, XK_1, win_to_ws, {.i = 1}}, - {MOD, XK_2, ws_go, {.i = 2}}, - {MOD|ShiftMask, XK_2, win_to_ws, {.i = 2}}, - {MOD, XK_3, ws_go, {.i = 3}}, - {MOD|ShiftMask, XK_3, win_to_ws, {.i = 3}}, - {MOD, XK_4, ws_go, {.i = 4}}, - {MOD|ShiftMask, XK_4, win_to_ws, {.i = 4}}, - {MOD, XK_5, ws_go, {.i = 5}}, - {MOD|ShiftMask, XK_5, win_to_ws, {.i = 5}}, - {MOD, XK_6, ws_go, {.i = 6}}, - {MOD|ShiftMask, XK_6, win_to_ws, {.i = 6}}, -}; - -#endif diff --git a/nyxwm.c b/nyxwm.c @@ -180,15 +180,16 @@ void win_fs(const Arg arg) { if (!cur) return; if ((cur->f = cur->f ? 0 : 1)) { + // Going fullscreen win_size(cur->w, &cur->wx, &cur->wy, &cur->ww, &cur->wh); - int tray_width = num_systray_icons * (TRAY_ICON_SIZE + TRAY_ICON_SPACING) + TRAY_PADDING * 2; - if (num_systray_icons > 0) { - tray_width -= TRAY_ICON_SPACING; - } - XMoveResizeWindow(d, cur->w, 0, BAR_HEIGHT, sw - tray_width, sh - BAR_HEIGHT); + XMoveResizeWindow(d, cur->w, 0, BAR_HEIGHT, sw, sh - BAR_HEIGHT); + XRaiseWindow(d, cur->w); } else { + // Exiting fullscreen XMoveResizeWindow(d, cur->w, cur->wx, cur->wy, cur->ww, cur->wh); } + update_systray(); + update_bar(); } void win_to_ws(const Arg arg) { @@ -378,18 +379,50 @@ void create_systray() { } } +void update_systray() { + int tray_width = num_systray_icons * (TRAY_ICON_SIZE + TRAY_ICON_SPACING) + TRAY_PADDING * 2; + if (num_systray_icons > 0) { + tray_width -= TRAY_ICON_SPACING; + + XMapWindow(d, systray); + XMoveResizeWindow(d, systray, + sw - tray_width, 0, + tray_width, BAR_HEIGHT); + + for (int i = 0; i < num_systray_icons; i++) { + XMoveResizeWindow(d, systray_icons[i], + TRAY_PADDING + i * (TRAY_ICON_SIZE + TRAY_ICON_SPACING), + (BAR_HEIGHT - TRAY_ICON_SIZE) / 2, + TRAY_ICON_SIZE, TRAY_ICON_SIZE); + XMapWindow(d, systray_icons[i]); + } + } else { + XUnmapWindow(d, systray); + tray_width = 0; + } + + // Adjust the bar size to account for the systray + int bar_width = sw - tray_width; + XMoveResizeWindow(d, bar, 0, 0, bar_width, BAR_HEIGHT); + + // Raise the bar and systray to ensure they're visible + XRaiseWindow(d, bar); + if (num_systray_icons > 0) { + XRaiseWindow(d, systray); + } + + update_bar(); +} + void handle_systray_request(XClientMessageEvent *cme) { if (cme->data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) { Window icon = cme->data.l[2]; if (num_systray_icons < MAX_SYSTRAY_ICONS) { XWindowAttributes wa; if (XGetWindowAttributes(d, icon, &wa)) { - XReparentWindow(d, icon, systray, - TRAY_PADDING + num_systray_icons * (TRAY_ICON_SIZE + TRAY_ICON_SPACING), - (BAR_HEIGHT - TRAY_ICON_SIZE) / 2); - XResizeWindow(d, icon, TRAY_ICON_SIZE, TRAY_ICON_SIZE); - XMapRaised(d, icon); systray_icons[num_systray_icons++] = icon; + XReparentWindow(d, icon, systray, 0, 0); + XMapRaised(d, icon); XEvent ev; ev.xclient.type = ClientMessage; @@ -403,72 +436,37 @@ void handle_systray_request(XClientMessageEvent *cme) { ev.xclient.data.l[4] = 0; XSendEvent(d, icon, False, NoEventMask, &ev); - XSync(d, False); - printf("Icon docked: %ld\n", icon); + update_systray(); + DEBUG_LOG("Icon docked: %ld", icon); } else { - printf("Failed to get window attributes for icon: %ld\n", icon); + DEBUG_LOG("Failed to get window attributes for icon: %ld", icon); } } else { - printf("Maximum number of systray icons reached\n"); + DEBUG_LOG("Maximum number of systray icons reached"); } } else { - printf("Received unknown systray request: %ld\n", cme->data.l[1]); - } -} - -void update_systray() { - static int prev_num_icons = 0; - static int prev_tray_width = 0; - - int tray_width = num_systray_icons * (TRAY_ICON_SIZE + TRAY_ICON_SPACING) + TRAY_PADDING * 2; - if (num_systray_icons > 0) { - tray_width -= TRAY_ICON_SPACING; - } - - if (num_systray_icons != prev_num_icons || tray_width != prev_tray_width) { - for (int i = 0; i < num_systray_icons; i++) { - XMoveResizeWindow(d, systray_icons[i], - TRAY_PADDING + i * (TRAY_ICON_SIZE + TRAY_ICON_SPACING), - (BAR_HEIGHT - TRAY_ICON_SIZE) / 2, - TRAY_ICON_SIZE, TRAY_ICON_SIZE); - } - - XMoveResizeWindow(d, systray, - sw - tray_width, 0, - tray_width, BAR_HEIGHT); - - prev_num_icons = num_systray_icons; - prev_tray_width = tray_width; + DEBUG_LOG("Received unknown systray request: %ld", cme->data.l[1]); } } void update_bar() { - static char prev_status[256] = {0}; char status[256]; - run_nyxwmblocks(status, sizeof(status)); - if (strcmp(status, prev_status) != 0) { - XClearWindow(d, bar); + XClearWindow(d, bar); - // Calculate the actual width of the bar - int bar_width = sw - 2 * TRAY_PADDING; // Adjust if needed + int bar_width = sw - (num_systray_icons > 0 ? (num_systray_icons * (TRAY_ICON_SIZE + TRAY_ICON_SPACING) + TRAY_PADDING * 2 - TRAY_ICON_SPACING) : 0); - // Calculate the width of the text - XGlyphInfo extents; - XftTextExtentsUtf8(d, xft_font, (XftChar8*)status, strlen(status), &extents); + XGlyphInfo extents; + XftTextExtentsUtf8(d, xft_font, (XftChar8*)status, strlen(status), &extents); - // Calculate the starting x position to center the text - int x = (bar_width - extents.width) / 2; - int y = BAR_HEIGHT / 2 + xft_font->ascent / 2; + int x = (bar_width - extents.width) / 2; + int y = BAR_HEIGHT / 2 + xft_font->ascent / 2; - // Ensure x is not negative - x = (x < 10) ? 10 : x; + x = (x < 10) ? 10 : x; - XftDrawStringUtf8(xft_draw, &xft_color, xft_font, x, y, (XftChar8*)status, strlen(status)); - XFlush(d); - strcpy(prev_status, status); - } + XftDrawStringUtf8(xft_draw, &xft_color, xft_font, x, y, (XftChar8*)status, strlen(status)); + XFlush(d); } int xerror(Display *dpy, XErrorEvent *ee) { @@ -486,6 +484,19 @@ int xerror(Display *dpy, XErrorEvent *ee) { return 0; } +void handle_destroy_notify(XDestroyWindowEvent *ev) { + for (int i = 0; i < num_systray_icons; i++) { + if (systray_icons[i] == ev->window) { + for (int j = i; j < num_systray_icons - 1; j++) { + systray_icons[j] = systray_icons[j+1]; + } + num_systray_icons--; + update_systray(); + break; + } + } +} + int main(void) { DEBUG_LOG("Starting nyxwm"); @@ -528,14 +539,16 @@ int main(void) { DEBUG_LOG("Autostart run"); XEvent ev; - struct timeval tv; + struct timeval tv, last_update; fd_set fds; int xfd = ConnectionNumber(d); + gettimeofday(&last_update, NULL); + DEBUG_LOG("Entering main loop"); while (1) { - if (XPending(d)) { + while (XPending(d)) { XNextEvent(d, &ev); DEBUG_LOG("Received event: type=%d", ev.type); @@ -546,31 +559,32 @@ int main(void) { if (ev.type == ClientMessage && ev.xclient.message_type == system_tray_opcode_atom) { handle_systray_request(&ev.xclient); } else if (ev.type == DestroyNotify) { - for (int i = 0; i < num_systray_icons; i++) { - if (systray_icons[i] == ev.xdestroywindow.window) { - for (int j = i; j < num_systray_icons - 1; j++) { - systray_icons[j] = systray_icons[j+1]; - } - num_systray_icons--; - break; - } - } + handle_destroy_notify(&ev.xdestroywindow); + update_systray(); + } else if (ev.type == MapNotify || ev.type == UnmapNotify) { + update_systray(); } - } else { - FD_ZERO(&fds); - FD_SET(xfd, &fds); - tv.tv_usec = 100000; // 100ms timeout - tv.tv_sec = 0; - - int ready = select(xfd + 1, &fds, 0, 0, &tv); - if (ready == -1) { - if (errno != EINTR) { - ERROR_LOG("select() failed"); - } - } else if (ready == 0) { - // Timeout occurred, update bar and systray + } + + FD_ZERO(&fds); + FD_SET(xfd, &fds); + tv.tv_usec = 100000; // 100ms timeout + tv.tv_sec = 0; + + int ready = select(xfd + 1, &fds, 0, 0, &tv); + if (ready == -1) { + if (errno != EINTR) { + ERROR_LOG("select() failed"); + } + } else if (ready == 0) { + // Timeout occurred, check if it's time to update + struct timeval now; + gettimeofday(&now, NULL); + if ((now.tv_sec - last_update.tv_sec) * 1000000 + (now.tv_usec - last_update.tv_usec) >= 1000000) { + // Update every second update_bar(); update_systray(); + last_update = now; } } } @@ -582,4 +596,4 @@ int main(void) { DEBUG_LOG("Display closed"); return 0; -} +} +\ No newline at end of file diff --git a/nyxwm.h b/nyxwm.h @@ -103,7 +103,7 @@ void create_systray(); void handle_systray_request(XClientMessageEvent *cme); void update_systray(); void run_nyxwmblocks(); - +void handle_destroy_notify(XDestroyWindowEvent *ev); int xerror(Display *dpy, XErrorEvent *ee); extern Window bar;