summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md3
-rw-r--r--default_sxwmrc4
-rw-r--r--src/config.h5
-rw-r--r--src/defs.h2
-rw-r--r--src/sxwm.c72
5 files changed, 85 insertions, 1 deletions
diff --git a/README.md b/README.md
index a08fac6..08d0aea 100644
--- a/README.md
+++ b/README.md
@@ -110,6 +110,8 @@ workspace : modifier + modifier + ... + key : swap n
| `decrease_gaps` | Shrinks gaps. |
| `focus_next` | Moves focus forward in the stack. |
| `focus_previous` | Moves focus backward in the stack. |
+| `focus_next_monitor` | Switches focus to the next monitor. |
+| `focus_prev_monitor` | Switches focus to the previous monitor. |
| `increase_gaps` | Expands gaps. |
| `master_next` | Moves focused window down in master/stack order. |
| `master_prev` | Moves focused window up in master/stack order. |
@@ -147,6 +149,7 @@ workspace : mod + shift + 5 : swap 5
| `MOD` + Left Mouse | Move window by mouse |
| `MOD` + Right Mouse | Resize window by mouse |
| `MOD` + `j` / `k` | Focus next / previous |
+| `MOD` + `,` / `.` | Focus prev / next monitor |
| `MOD` + `Shift` + `j` / `k` | Move in master stack |
| `MOD` + `Space` | Toggle floating |
| `MOD` + `Shift` + `Space` | Toggle all floating |
diff --git a/default_sxwmrc b/default_sxwmrc
index 6efede7..09aa36f 100644
--- a/default_sxwmrc
+++ b/default_sxwmrc
@@ -34,6 +34,10 @@ call : mod + shift + e : quit
call : mod + j : focus_next
call : mod + k : focus_prev
+# Monitor Focus:
+call : mod + comma : focus_prev_monitor
+call : mod + period : focus_next_monitor
+
# Master/Stack Movement
call : mod + shift + j : master_next
call : mod + shift + k : master_previous
diff --git a/src/config.h b/src/config.h
index 7c42764..b67b771 100644
--- a/src/config.h
+++ b/src/config.h
@@ -13,6 +13,9 @@ 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 | ShiftMask, XK_j, {.fn = move_master_next}, TYPE_FUNC},
{Mod4Mask | ShiftMask, XK_k, {.fn = move_master_prev}, TYPE_FUNC},
@@ -53,4 +56,4 @@ const Binding binds[] = {
{Mod4Mask | ShiftMask, XK_8, {.ws = 7}, TYPE_MWKSP},
{Mod4Mask, XK_9, {.ws = 8}, TYPE_CWKSP},
{Mod4Mask | ShiftMask, XK_9, {.ws = 8}, TYPE_MWKSP},
-}; \ No newline at end of file
+};
diff --git a/src/defs.h b/src/defs.h
index 53c7c6a..9bba4be 100644
--- a/src/defs.h
+++ b/src/defs.h
@@ -107,6 +107,8 @@ 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 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 bc6f922..63c0a24 100644
--- a/src/sxwm.c
+++ b/src/sxwm.c
@@ -343,6 +343,78 @@ void focus_prev(void)
update_borders();
}
+void focus_next_monitor(void)
+{
+ if (monsn <= 1) {
+ return; /* only one monitor, nothing to switch to */
+ }
+
+ int current_mon = focused ? focused->mon : 0;
+ int target_mon = (current_mon + 1) % monsn;
+
+ /* find the first window on the target monitor in current workspace */
+ Client *target_client = NULL;
+ for (Client *c = workspaces[current_ws]; c; c = c->next) {
+ if (c->mon == target_mon && c->mapped && !c->fullscreen) {
+ target_client = c;
+ break;
+ }
+ }
+
+ if (target_client) {
+ /* focus the window on target monitor */
+ focused = target_client;
+ 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 */
+ 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);
+ XSync(dpy, False);
+ }
+}
+
+void focus_prev_monitor(void)
+{
+ if (monsn <= 1) {
+ return; /* only one monitor, nothing to switch to */
+ }
+
+ int current_mon = focused ? focused->mon : 0;
+ int target_mon = (current_mon - 1 + monsn) % monsn;
+
+ /* find the first window on the target monitor in current workspace */
+ Client *target_client = NULL;
+ for (Client *c = workspaces[current_ws]; c; c = c->next) {
+ if (c->mon == target_mon && c->mapped && !c->fullscreen) {
+ target_client = c;
+ break;
+ }
+ }
+
+ if (target_client) {
+ /* focus the window on target monitor */
+ focused = target_client;
+ 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 */
+ 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);
+ XSync(dpy, False);
+ }
+}
+
int get_monitor_for(Client *c)
{
int cx = c->x + c->w / 2, cy = c->y + c->h / 2;