summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbhinav <abhinav.prsai@gmail.com>2025-05-29 13:31:46 +0100
committerAbhinav <abhinav.prsai@gmail.com>2025-05-29 13:31:46 +0100
commitec78d7e63c7290b1b495e8947177d52ccfdc32bb (patch)
tree4b8cee92d515ba486dbaad25621b8a144cac17e8
parent849bdebd1336872dda37d0eb3a87aa21b18402fb (diff)
added proper multi-monitor support.
-rw-r--r--src/defs.h3
-rw-r--r--src/parser.c57
-rw-r--r--src/sxwm.c78
3 files changed, 77 insertions, 61 deletions
diff --git a/src/defs.h b/src/defs.h
index d90ab61..24e9f1b 100644
--- a/src/defs.h
+++ b/src/defs.h
@@ -13,6 +13,7 @@
#define OUT_IN (2 * BORDER_WIDTH)
#define MF_MIN 0.05f
#define MF_MAX 0.95f
+#define MAX_MONITORS 32
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define LENGTH(X) (sizeof X / sizeof X[0])
@@ -81,7 +82,7 @@ typedef struct {
long border_foc_col;
long border_ufoc_col;
long border_swap_col;
- float master_width;
+ float master_width[MAX_MONITORS];
int motion_throttle;
int resize_master_amt;
int snap_distance;
diff --git a/src/parser.c b/src/parser.c
index 7cc59d1..0d086a2 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -143,22 +143,22 @@ int parser(Config *cfg)
// check $XDG_CONFIG_HOME/sxwmrc, then $XDG_CONFIG_HOME/sxwm/sxwmrc, then $HOME/.config/sxwmrc
const char *xdg_config_home = getenv("XDG_CONFIG_HOME");
- if (xdg_config_home) {
- snprintf(path, sizeof path, "%s/sxwmrc", xdg_config_home);
- if (access(path, R_OK) == 0) {
- goto found;
- }
-
- snprintf(path, sizeof path, "%s/sxwm/sxwmrc", xdg_config_home);
- if (access(path, R_OK) == 0) {
- goto found;
- }
- }
-
- snprintf(path, sizeof path, "%s/.config/sxwmrc", home);
- if (access(path, R_OK) == 0) {
- goto found;
- }
+ if (xdg_config_home) {
+ snprintf(path, sizeof path, "%s/sxwmrc", xdg_config_home);
+ if (access(path, R_OK) == 0) {
+ goto found;
+ }
+
+ snprintf(path, sizeof path, "%s/sxwm/sxwmrc", xdg_config_home);
+ if (access(path, R_OK) == 0) {
+ goto found;
+ }
+ }
+
+ snprintf(path, sizeof path, "%s/.config/sxwmrc", home);
+ if (access(path, R_OK) == 0) {
+ goto found;
+ }
snprintf(path, sizeof path, "/usr/local/share/sxwmrc");
if (access(path, R_OK) == 0) {
@@ -166,11 +166,11 @@ int parser(Config *cfg)
}
found:
- FILE *f = fopen(path, "r");
- if (!f) {
- fprintf(stderr, "sxwmrc: cannot open %s\n", path);
- return -1;
- }
+ FILE *f = fopen(path, "r");
+ if (!f) {
+ fprintf(stderr, "sxwmrc: cannot open %s\n", path);
+ return -1;
+ }
char line[512];
int lineno = 0;
@@ -221,7 +221,10 @@ found:
cfg->border_swap_col = parse_col(rest);
}
else if (!strcmp(key, "master_width")) {
- cfg->master_width = atoi(rest) / 100.0f;
+ float mf = atoi(rest) / 100.0f;
+ for (int i = 0; i < MAX_MONITORS; i++) {
+ cfg->master_width[i] = mf;
+ }
}
else if (!strcmp(key, "motion_throttle")) {
cfg->motion_throttle = atoi(rest);
@@ -234,14 +237,14 @@ found:
}
else if (!strcmp(key, "should_float")) {
// should_float: binary --arg,binary2 parameter --arg,binary3
-
+
if (should_floatn >= 256) {
fprintf(stderr, "sxwmrc:%d: too many should_float entries\n", lineno);
continue;
}
char *win = strip(rest);
-
+
cfg->should_float[should_floatn] = malloc(256 * sizeof(char *));
char *comma_ptr, *space_ptr;
@@ -262,7 +265,6 @@ found:
char *argv = strtok_r(comma, " ", &space_ptr);
int i = 0;
-
while (argv) {
printf("argv: %s\n", argv);
cfg->should_float[should_floatn][i] = strdup(argv);
@@ -272,15 +274,14 @@ found:
should_floatn++;
cfg->should_float[should_floatn] = malloc(256 * sizeof(char *));
-
- } else {
+ }
+ else {
fprintf(stderr, "sxwmrc:%d: too many should_float entries\n", lineno);
break;
}
comma = strtok_r(NULL, ",", &comma_ptr);
}
-
should_floatn++;
}
else if (!strcmp(key, "call") || !strcmp(key, "bind")) {
diff --git a/src/sxwm.c b/src/sxwm.c
index 359172a..31ae2d0 100644
--- a/src/sxwm.c
+++ b/src/sxwm.c
@@ -170,24 +170,25 @@ Client *add_client(Window w, int ws)
c->w = wa.width;
c->h = wa.height;
- if (focused) {
- c->mon = focused->mon;
- }
- else {
- /* need better way to determine mon */
- int cx = c->x + c->w / 2, cy = c->y + c->h / 2;
- c->mon = 0;
+ /* set monitor based on pointer location */
+ Window root_ret, child_ret;
+ int root_x, root_y, win_x, win_y;
+ unsigned int mask;
+ int pointer_mon = 0;
+
+ if (XQueryPointer(dpy, root, &root_ret, &child_ret, &root_x, &root_y, &win_x, &win_y, &mask)) {
for (int i = 0; i < monsn; i++) {
- if (cx >= mons[i].x && cx < mons[i].x + mons[i].w && cy >= mons[i].y && cy < mons[i].y + mons[i].h) {
- c->mon = i;
+ if (root_x >= mons[i].x && root_x < mons[i].x + mons[i].w && root_y >= mons[i].y &&
+ root_y < mons[i].y + mons[i].h) {
+ pointer_mon = i;
break;
}
}
}
+ c->mon = pointer_mon;
c->fixed = False;
c->floating = False;
-
c->fullscreen = False;
if (global_floating) {
@@ -594,7 +595,8 @@ void hdl_keypress(XEvent *xev)
spawn(b->action.cmd);
for (int j = 0; j < 256; j++) {
Bool valid = False;
- for (int k = 0; user_config.should_float[j] && user_config.should_float[j][k] && b->action.cmd[k]; k++) {
+ for (int k = 0;
+ user_config.should_float[j] && user_config.should_float[j][k] && b->action.cmd[k]; k++) {
if (!strcmp(b->action.cmd[k], user_config.should_float[j][k])) {
valid = True;
break;
@@ -724,7 +726,7 @@ void hdl_map_req(XEvent *xev)
return;
}
- /* ad client to list */
+ /* add client to list */
Client *c = add_client(w, current_ws);
if (!c)
return;
@@ -753,8 +755,7 @@ void hdl_map_req(XEvent *xev)
c->w = wa.width;
c->h = wa.height;
- XConfigureWindow(
- dpy, c->win, CWX | CWY | CWWidth | CWHeight,
+ XConfigureWindow(dpy, c->win, CWX | CWY | CWWidth | CWHeight,
&(XWindowChanges){.x = c->x, .y = c->y, .width = c->w, .height = c->h});
}
@@ -1011,7 +1012,9 @@ void init_defaults(void)
default_config.border_foc_col = parse_col("#c0cbff");
default_config.border_ufoc_col = parse_col("#555555");
default_config.border_swap_col = parse_col("#fff4c0");
- default_config.master_width = 50 / 100.0f;
+ for (int i = 0; i < MAX_MONITORS; i++)
+ default_config.master_width[i] = 50 / 100.0f;
+
default_config.motion_throttle = 60;
default_config.resize_master_amt = 5;
default_config.snap_distance = 5;
@@ -1131,6 +1134,7 @@ long parse_col(const char *hex)
}
/* return col.pixel |= 0xff << 24; */
+ /* This is a fix for picom making the borders transparent. DANGEROUS */
return col.pixel;
}
@@ -1186,8 +1190,12 @@ void reload_config(void)
void resize_master_add(void)
{
- if (user_config.master_width < MF_MAX - 0.001f) {
- user_config.master_width += ((float)user_config.resize_master_amt / 100);
+ /* pick the monitor of the focused window (or 0 if none) */
+ int m = focused ? focused->mon : 0;
+ float *mw = &user_config.master_width[m];
+
+ if (*mw < MF_MAX - 0.001f) {
+ *mw += ((float)user_config.resize_master_amt / 100);
}
tile();
update_borders();
@@ -1195,8 +1203,12 @@ void resize_master_add(void)
void resize_master_sub(void)
{
- if (user_config.master_width > MF_MIN + 0.001f) {
- user_config.master_width -= ((float)user_config.resize_master_amt / 100);
+ /* pick the monitor of the focused window (or 0 if none) */
+ int m = focused ? focused->mon : 0;
+ float *mw = &user_config.master_width[m];
+
+ if (*mw > MF_MIN + 0.001f) {
+ *mw -= ((float)user_config.resize_master_amt / 100);
}
tile();
update_borders();
@@ -1310,7 +1322,7 @@ void setup(void)
evtable[UnmapNotify] = hdl_unmap_ntf;
scan_existing_windows();
- signal(SIGCHLD, SIG_IGN); /* Prevent child processes from becoming zombies */
+ signal(SIGCHLD, SIG_IGN); /* prevent child processes from becoming zombies */
}
void setup_atoms(void)
@@ -1457,7 +1469,6 @@ void tile(void)
for (Client *c = head; c; c = c->next) {
if (!c->floating) {
- c->mon = get_monitor_for(c);
if (!c->fullscreen) {
total_tiled_count++;
}
@@ -1511,7 +1522,7 @@ void tile(void)
if (tile_h < 1)
tile_h = 1;
- float mfact = user_config.master_width;
+ float mfact = user_config.master_width[m];
if (mfact < MF_MIN)
mfact = MF_MIN;
if (mfact > MF_MAX)
@@ -1585,22 +1596,21 @@ void toggle_floating(void)
focused->h = wa.height;
XConfigureWindow(
- dpy, focused->win,
- CWX | CWY | CWWidth | CWHeight,
- &(XWindowChanges){
- .x = focused->x,
- .y = focused->y,
- .width = focused->w,
- .height = focused->h
- }
- );
+ dpy, focused->win, CWX | CWY | CWWidth | CWHeight,
+ &(XWindowChanges){.x = focused->x, .y = focused->y, .width = focused->w, .height = focused->h});
}
}
+ else {
+ focused->mon = get_monitor_for(focused);
+ }
+ if (!focused->floating) {
+ focused->mon = get_monitor_for(focused);
+ }
tile();
update_borders();
- /* Raise and refocus floating window */
+ /* raise and refocus floating window */
if (focused->floating) {
XRaiseWindow(dpy, focused->win);
XSetInputFocus(dpy, focused->win, RevertToPointerRoot, CurrentTime);
@@ -1671,6 +1681,10 @@ void toggle_fullscreen(void)
else {
XMoveResizeWindow(dpy, focused->win, focused->orig_x, focused->orig_y, focused->orig_w, focused->orig_h);
XSetWindowBorderWidth(dpy, focused->win, user_config.border_width);
+
+ if (!focused->floating) {
+ focused->mon = get_monitor_for(focused);
+ }
tile();
update_borders();
}