Fixes #7–#11: launcher Other tab, ICCCM size hints, icon loading, multi-desktop

Fix #7: Add "Other" catch-all category to the launcher. map_category() now
returns "Other" instead of "" for unrecognized .desktop Categories, and an
"Other" tab is added to the CATS list so those apps are discoverable instead
of silently hidden.

Fix #8: Respect ICCCM WM_NORMAL_HINTS. client_add() reads PMinSize,
PResizeInc, and PBaseSize from the window's size hints. The resize drag
handler in events.c clamps to min_w/min_h and snaps to the
width_inc/height_inc grid, fixing jank in character-cell terminal emulators
(xterm, Alacritty).

Fix #10: Optional freedesktop icon loading via imlib2. The launcher now
parses the Icon= field from .desktop files and attempts to render a PNG icon
from Papirus-Dark (or hicolor fallback). When imlib2 is not present the
existing letter-square is shown unchanged. launcher/Makefile auto-detects
imlib2 via pkg-config and sets -DHAVE_IMLIB2.

Fix #11: True 4-desktop support in the WM. Each Client carries a desktop
field (assigned at map time from wm->cur_desktop). Clicking a workspace
button in the deskbar sends _NET_CURRENT_DESKTOP; the WM now handles it via
wm_switch_desktop() which unmaps frames on the leaving desktop, maps frames
on the arriving desktop, and re-focuses. _NET_WM_DESKTOP is set per window
so the deskbar can filter db_update_apps() to show only current-desktop
windows (sticky windows with desktop 0xFFFFFFFF are always shown).
This commit is contained in:
Claude committed 2026-08-30 20:00:10 +00:00
1 parent 36641e77e2
commit b0f64d9b2e
7 files changed
+173 -16

No files matched your search

+8
View File
@@ -111,8 +111,14 @@ void db_update_apps(Deskbar *db) {
Atom net_wm_state = XInternAtom(db->dpy, "_NET_WM_STATE", False);
Atom net_wm_state_hidden = XInternAtom(db->dpy, "_NET_WM_STATE_HIDDEN", False);
Atom net_wm_desktop = XInternAtom(db->dpy, "_NET_WM_DESKTOP", False);
for (unsigned long i = 0; i < n && db->napps < DB_MAX_APPS; i++) {
/* only show windows on the current desktop (or sticky: desktop == 0xFFFFFFFF) */
long win_desk = ewmh_get_long(db, wins[i], net_wm_desktop);
if (win_desk >= 0 && win_desk != (long)db->cur_ws && win_desk != (long)0xFFFFFFFF)
continue;
db->apps[db->napps].win = wins[i];
db->apps[db->napps].focused = (wins[i] == (Window)active_win);
db->apps[db->napps].minimized = 0;
@@ -1285,6 +1291,8 @@ void db_run(Deskbar *db) {
db_draw(db);
} else if (e.xproperty.atom == db->net_current_desktop) {
db_update_workspace(db);
db_update_apps(db); /* re-filter by new desktop */
db_resize(db);
db_draw(db);
}
break;