summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcos <cos>2024-03-01 17:02:41 +0100
committercos <cos>2024-03-01 20:54:50 +0100
commit842a27105fe3c5d3943ced05532629d711dc1535 (patch)
tree531aac7efaf7215acaa35cd99cebbb8e17b80bea
parent91674cda15561ef4ed98a80ba9246d69a19bae1d (diff)
downloadmcwm-topic/flexible_workspaces.zip
Allow configuring workspace counttopic/flexible_workspaces
-rw-r--r--Makefile2
-rw-r--r--mcwm.c94
-rw-r--r--mcwm.man4
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 <xcb/xcb_keysyms.h>
#include <xcb/xcb_atom.h>
#include <xcb/xcb_icccm.h>
+#include <xcb/xcb_xrm.h>
#include <X11/keysym.h>
@@ -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)