summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRick Console <rick@rickconsole.com>2025-06-05 19:52:23 -0400
committerRick Console <rick@rickconsole.com>2025-06-06 17:42:25 -0400
commit08c1543e60d82ca2bff0b3b1027c546ddff07ca3 (patch)
tree19c24cedd37fbd23bfab2600083c79bd1cba59d9 /src
parent787416e6a3cead68472619a42385c58b23b51d81 (diff)
add monitor switching with shortened config names
Diffstat (limited to 'src')
-rw-r--r--src/config.h6
-rw-r--r--src/defs.h6
-rw-r--r--src/sxwm.c109
3 files changed, 109 insertions, 12 deletions
diff --git a/src/config.h b/src/config.h
index b67b771..3c0f0bc 100644
--- a/src/config.h
+++ b/src/config.h
@@ -13,8 +13,10 @@ const Binding binds[] = {
{Mod4Mask, XK_j, {.fn = focus_next}, TYPE_FUNC},
{Mod4Mask, XK_k, {.fn = focus_prev}, TYPE_FUNC},
- {Mod4Mask, XK_comma, {.fn = focus_prev_monitor}, TYPE_FUNC},
- {Mod4Mask, XK_period, {.fn = focus_next_monitor}, TYPE_FUNC},
+ {Mod4Mask, XK_comma, {.fn = focus_prev_mon}, TYPE_FUNC},
+ {Mod4Mask, XK_period, {.fn = focus_next_mon}, TYPE_FUNC},
+ {Mod4Mask | ShiftMask, XK_comma, {.fn = move_prev_mon}, TYPE_FUNC},
+ {Mod4Mask | ShiftMask, XK_period, {.fn = move_next_mon}, TYPE_FUNC},
{Mod4Mask | ShiftMask, XK_j, {.fn = move_master_next}, TYPE_FUNC},
{Mod4Mask | ShiftMask, XK_k, {.fn = move_master_prev}, TYPE_FUNC},
diff --git a/src/defs.h b/src/defs.h
index 9bba4be..74af271 100644
--- a/src/defs.h
+++ b/src/defs.h
@@ -107,8 +107,10 @@ extern void close_focused(void);
extern void dec_gaps(void);
extern void focus_next(void);
extern void focus_prev(void);
-extern void focus_next_monitor(void);
-extern void focus_prev_monitor(void);
+extern void focus_next_mon(void);
+extern void focus_prev_mon(void);
+extern void move_next_mon(void);
+extern void move_prev_mon(void);
extern void inc_gaps(void);
extern void move_master_next(void);
extern void move_master_prev(void);
diff --git a/src/sxwm.c b/src/sxwm.c
index 63c0a24..c76a6c5 100644
--- a/src/sxwm.c
+++ b/src/sxwm.c
@@ -122,6 +122,7 @@ Window root;
Window wm_check_win;
Monitor *mons = NULL;
int monsn = 0;
+int current_monitor = 0;
Bool global_floating = False;
Bool in_ws_switch = False;
Bool running = False;
@@ -305,6 +306,7 @@ void focus_next(void)
}
focused = (focused->next ? focused->next : workspaces[current_ws]);
+ current_monitor = focused->mon;
XSetInputFocus(dpy, focused->win, RevertToPointerRoot, CurrentTime);
XRaiseWindow(dpy, focused->win);
if (user_config.warp_cursor) {
@@ -335,6 +337,7 @@ void focus_prev(void)
focused = prev;
}
+ current_monitor = focused->mon;
XSetInputFocus(dpy, focused->win, RevertToPointerRoot, CurrentTime);
XRaiseWindow(dpy, focused->win);
if (user_config.warp_cursor) {
@@ -343,13 +346,14 @@ void focus_prev(void)
update_borders();
}
-void focus_next_monitor(void)
+void focus_next_mon(void)
{
if (monsn <= 1) {
return; /* only one monitor, nothing to switch to */
}
- int current_mon = focused ? focused->mon : 0;
+ /* use current_monitor if no focused window, otherwise use focused window's monitor */
+ int current_mon = focused ? focused->mon : current_monitor;
int target_mon = (current_mon + 1) % monsn;
/* find the first window on the target monitor in current workspace */
@@ -364,14 +368,17 @@ void focus_next_monitor(void)
if (target_client) {
/* focus the window on target monitor */
focused = target_client;
+ current_monitor = target_mon;
XSetInputFocus(dpy, focused->win, RevertToPointerRoot, CurrentTime);
XRaiseWindow(dpy, focused->win);
if (user_config.warp_cursor) {
warp_cursor(focused);
}
update_borders();
- } else {
- /* no windows on target monitor, just move cursor to center */
+ }
+ else {
+ /* no windows on target monitor, just move cursor to center and update current_monitor */
+ current_monitor = target_mon;
int center_x = mons[target_mon].x + mons[target_mon].w / 2;
int center_y = mons[target_mon].y + mons[target_mon].h / 2;
XWarpPointer(dpy, None, root, 0, 0, 0, 0, center_x, center_y);
@@ -379,13 +386,14 @@ void focus_next_monitor(void)
}
}
-void focus_prev_monitor(void)
+void focus_prev_mon(void)
{
if (monsn <= 1) {
return; /* only one monitor, nothing to switch to */
}
- int current_mon = focused ? focused->mon : 0;
+ /* use current_monitor if no focused window, otherwise use focused window's monitor */
+ int current_mon = focused ? focused->mon : current_monitor;
int target_mon = (current_mon - 1 + monsn) % monsn;
/* find the first window on the target monitor in current workspace */
@@ -400,14 +408,17 @@ void focus_prev_monitor(void)
if (target_client) {
/* focus the window on target monitor */
focused = target_client;
+ current_monitor = target_mon;
XSetInputFocus(dpy, focused->win, RevertToPointerRoot, CurrentTime);
XRaiseWindow(dpy, focused->win);
if (user_config.warp_cursor) {
warp_cursor(focused);
}
update_borders();
- } else {
- /* no windows on target monitor, just move cursor to center */
+ }
+ else {
+ /* no windows on target monitor, just move cursor to center and update current_monitor */
+ current_monitor = target_mon;
int center_x = mons[target_mon].x + mons[target_mon].w / 2;
int center_y = mons[target_mon].y + mons[target_mon].h / 2;
XWarpPointer(dpy, None, root, 0, 0, 0, 0, center_x, center_y);
@@ -415,6 +426,88 @@ void focus_prev_monitor(void)
}
}
+void move_next_mon(void)
+{
+ if (!focused || monsn <= 1) {
+ return; /* no focused window or only one monitor */
+ }
+
+ int target_mon = (focused->mon + 1) % monsn;
+
+ /* update window's monitor assignment */
+ focused->mon = target_mon;
+ current_monitor = target_mon;
+
+ /* if window is floating, center it on the target monitor */
+ if (focused->floating) {
+ int mx = mons[target_mon].x, my = mons[target_mon].y;
+ int mw = mons[target_mon].w, mh = mons[target_mon].h;
+ int x = mx + (mw - focused->w) / 2;
+ int y = my + (mh - focused->h) / 2;
+
+ /* ensure window stays within monitor bounds */
+ if (x < mx) x = mx;
+ if (y < my) y = my;
+ if (x + focused->w > mx + mw) x = mx + mw - focused->w;
+ if (y + focused->h > my + mh) y = my + mh - focused->h;
+
+ focused->x = x;
+ focused->y = y;
+ XMoveWindow(dpy, focused->win, x, y);
+ }
+
+ /* retile to update layouts on both monitors */
+ tile();
+
+ /* follow the window with cursor if enabled */
+ if (user_config.warp_cursor) {
+ warp_cursor(focused);
+ }
+
+ update_borders();
+}
+
+void move_prev_mon(void)
+{
+ if (!focused || monsn <= 1) {
+ return; /* no focused window or only one monitor */
+ }
+
+ int target_mon = (focused->mon - 1 + monsn) % monsn;
+
+ /* update window's monitor assignment */
+ focused->mon = target_mon;
+ current_monitor = target_mon;
+
+ /* if window is floating, center it on the target monitor */
+ if (focused->floating) {
+ int mx = mons[target_mon].x, my = mons[target_mon].y;
+ int mw = mons[target_mon].w, mh = mons[target_mon].h;
+ int x = mx + (mw - focused->w) / 2;
+ int y = my + (mh - focused->h) / 2;
+
+ /* ensure window stays within monitor bounds */
+ if (x < mx) x = mx;
+ if (y < my) y = my;
+ if (x + focused->w > mx + mw) x = mx + mw - focused->w;
+ if (y + focused->h > my + mh) y = my + mh - focused->h;
+
+ focused->x = x;
+ focused->y = y;
+ XMoveWindow(dpy, focused->win, x, y);
+ }
+
+ /* retile to update layouts on both monitors */
+ tile();
+
+ /* follow the window with cursor if enabled */
+ if (user_config.warp_cursor) {
+ warp_cursor(focused);
+ }
+
+ update_borders();
+}
+
int get_monitor_for(Client *c)
{
int cx = c->x + c->w / 2, cy = c->y + c->h / 2;