From 842a27105fe3c5d3943ced05532629d711dc1535 Mon Sep 17 00:00:00 2001 From: cos Date: Fri, 1 Mar 2024 17:02:41 +0100 Subject: Allow configuring workspace count --- Makefile | 2 +- mcwm.c | 94 +++++++++++++++++++++++++++++++++++++++++++--------------------- mcwm.man | 4 +++ 3 files changed, 68 insertions(+), 32 deletions(-) diff --git a/Makefile b/Makefile index 785dee4..baea37f 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ DISTFILES=LICENSE Makefile NEWS README TODO WISHLIST mcwm.man hidden.man scripts CFLAGS+=-g -std=c99 -Wall -Wextra -I/usr/local/include #-DDEBUG #-DDMALLOC LDFLAGS+=-L/usr/local/lib -lxcb -lxcb-randr -lxcb-keysyms -lxcb-icccm \ - -lxcb-util #-ldmalloc + -lxcb-util -lxcb-xrm #-ldmalloc RM=/bin/rm PREFIX=/usr/local diff --git a/mcwm.c b/mcwm.c index bf9ff26..cd23889 100644 --- a/mcwm.c +++ b/mcwm.c @@ -43,6 +43,7 @@ #include #include #include +#include #include @@ -86,15 +87,20 @@ */ #define MCWM_TABBING 4 -/* Number of workspaces. */ +/* Default number of workspaces. */ #define WORKSPACES 10 +/* Maximum number of workspaces (wslist needs update if increased). */ +#define MAX_WORKSPACES 100 + /* Value in WM hint which means this window is fixed on all workspaces. */ #define NET_WM_FIXED 0xffffffff /* This means we didn't get any window hint at all. */ #define MCWM_NOWS 0xfffffffe +long workspaces = WORKSPACES; + /* Types. */ @@ -172,7 +178,7 @@ struct client bool fixed; /* Visible on all workspaces? */ struct monitor *monitor; /* The physical output this window is on. */ struct item *winitem; /* Pointer to our place in global windows list. */ - struct item *wsitem[WORKSPACES]; /* Pointer to our place in every + struct item *wsitem[MAX_WORKSPACES]; /* Pointer to our place in every * workspace window list. */ }; @@ -210,18 +216,18 @@ int mode = 0; /* Internal mode, such as move or resize */ * Workspace list: Every workspace has a list of all visible * windows. */ -struct item *wslist[WORKSPACES] = +struct item *wslist[MAX_WORKSPACES] = { - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; /* Shortcut key type and initializiation. */ @@ -322,6 +328,7 @@ static xcb_keycode_t keysymtokeycode(xcb_keysym_t keysym, static int setupkeys(void); static int setupscreen(void); static int setuprandr(void); +static void setupworkspaces(void); static void getrandr(void); static void getoutputs(xcb_randr_output_t *outputs, int len, xcb_timestamp_t timestamp); @@ -701,7 +708,7 @@ void fixwindow(struct client *client, bool setcolour) } /* Delete from all workspace lists except current. */ - for (ws = 0; ws < WORKSPACES; ws ++) + for (ws = 0; ws < workspaces; ws ++) { if (ws != curws) { @@ -722,7 +729,7 @@ void fixwindow(struct client *client, bool setcolour) setwmdesktop(client->id, NET_WM_FIXED); /* Add window to all workspace lists. */ - for (ws = 0; ws < WORKSPACES; ws ++) + for (ws = 0; ws < workspaces; ws ++) { if (ws != curws) { @@ -785,7 +792,7 @@ void forgetclient(struct client *client) * Note that it's OK to be on several workspaces at once even if * you're not fixed. */ - for (ws = 0; ws < WORKSPACES; ws ++) + for (ws = 0; ws < workspaces; ws ++) { if (NULL != client->wsitem[ws]) { @@ -827,7 +834,7 @@ void forgetwin(xcb_window_t win) * to. Note that it's OK to be on several workspaces at * once. */ - for (ws = 0; ws < WORKSPACES; ws ++) + for (ws = 0; ws < workspaces; ws ++) { PDEBUG("Looking in ws #%d.\n", ws); if (NULL == client->wsitem[ws]) @@ -1142,7 +1149,7 @@ struct client *setupwin(xcb_window_t win) client->winitem = item; - for (ws = 0; ws < WORKSPACES; ws ++) + for (ws = 0; ws < workspaces; ws ++) { client->wsitem[ws] = NULL; } @@ -1411,7 +1418,7 @@ int setupscreen(void) /* Add to all other workspaces. */ fixwindow(client, false); } - else if (MCWM_NOWS != ws && ws < WORKSPACES) + else if (MCWM_NOWS != ws && ws < workspaces) { addtoworkspace(client, ws); /* If it's not our current workspace, hide it. */ @@ -1494,6 +1501,29 @@ int setuprandr(void) return base; } + +/* + * Set user's desired number of workspaces from Xresource. + * TODO Allocate structures to merely occupy their needed size. + */ +void setupworkspaces(void) +{ + xcb_xrm_database_t *xrm_db = xcb_xrm_database_from_default(conn); + long value; + if (! xcb_xrm_resource_get_long(xrm_db, "MCwm.workspaces", NULL, &value)) { + PDEBUG("Xresource configuring workspace count: %ld\n", value); + if (value > 0 && value <= MAX_WORKSPACES) { + workspaces = value; + } else { + fprintf (stderr, "MCwm.workspaces must be a natural number less than " + "or equal to %d.\n", MAX_WORKSPACES); + exit(1); + } + } else { + PDEBUG("Xresource configuring workspace count is not set.\n"); + } +} + /* * Get RANDR resources and figure out how many outputs there are. */ @@ -3259,43 +3289,43 @@ void handle_keypress(xcb_key_press_event_t *ev) break; case KEY_1: - changeworkspace(0); + changeworkspace(0 % workspaces); break; case KEY_2: - changeworkspace(1); + changeworkspace(1 % workspaces); break; case KEY_3: - changeworkspace(2); + changeworkspace(2 % workspaces); break; case KEY_4: - changeworkspace(3); + changeworkspace(3 % workspaces); break; case KEY_5: - changeworkspace(4); + changeworkspace(4 % workspaces); break; case KEY_6: - changeworkspace(5); + changeworkspace(5 % workspaces); break; case KEY_7: - changeworkspace(6); + changeworkspace(6 % workspaces); break; case KEY_8: - changeworkspace(7); + changeworkspace(7 % workspaces); break; case KEY_9: - changeworkspace(8); + changeworkspace(8 % workspaces); break; case KEY_0: - changeworkspace(9); + changeworkspace(9 % workspaces); break; case KEY_Y: @@ -3340,12 +3370,12 @@ void handle_keypress(xcb_key_press_event_t *ev) } else { - changeworkspace(WORKSPACES - 1); + changeworkspace(workspaces - 1); } break; case KEY_NEXTWS: - changeworkspace((curws + 1) % WORKSPACES); + changeworkspace((curws + 1) % workspaces); break; default: @@ -4415,6 +4445,8 @@ int main(int argc, char **argv) exit(1); } + setupworkspaces(); + /* Find our screen. */ iter = xcb_setup_roots_iterator(xcb_get_setup(conn)); for (int i = 0; i < scrno; ++ i) diff --git a/mcwm.man b/mcwm.man index ef59b73..3272f2f 100644 --- a/mcwm.man +++ b/mcwm.man @@ -191,6 +191,10 @@ default button 3 starts the command mcmenu. You can write your own mcmenu by using, for instance, 9menu, dmenu or ratmenu. .SH ENVIRONMENT .B mcwm\fP obeys the $DISPLAY variable. +.SH RESOURCES +.IP "\fBworkspaces:\fR \fInumber\fR" 4 +.IX Item "workspaces: number" +Number of workspaces to use. .SH STARTING Typically the window manager is started from a script, either run by .B startx(1) -- cgit v1.2.3