nyxwm

Owner: IIIlllIIIllI URL: git@github.com:nyangkosense/nyxwm.git

fix systray

Commit a237c6e6293f2ba916f3ae06fa751a5ba7ba9ad1 by nyangkosense <sebastian.michalk@protonmail.com> on 2024-10-15 20:55:25 +0000
diff --git a/config.h b/config.h
deleted file mode 100644
index 6b5f863..0000000
--- a/config.h
+++ /dev/null
@@ -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
index f8cd166..8e5039a 100644
--- 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
index b804efd..547bbfb 100644
--- 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;