commit a237c6e6293f2ba916f3ae06fa751a5ba7ba9ad1
parent c538c0234447ae554d095f6dd5e08a88400130b0
Author: nyangkosense <sebastian.michalk@protonmail.com>
Date: Tue, 15 Oct 2024 20:55:25 +0000
fix systray
Diffstat:
D | config.h | | | 59 | ----------------------------------------------------------- |
M | nyxwm.c | | | 183 | +++++++++++++++++++++++++++++++++++++++++++------------------------------------ |
M | nyxwm.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;