summaryrefslogtreecommitdiff
path: root/src/key.c
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2021-01-02 23:27:41 -0800
committerVito Caputo <vcaputo@pengaru.com>2021-01-02 23:27:41 -0800
commitbb59bfd71ec1731587467f64625c7c6818c973dc (patch)
treeaf475dc412cbea3519e5a128641b38057327b247 /src/key.c
parentd08f5671db08de077e271c3e1d3b6b45e11c9ecc (diff)
*: replace the "shelf" with "contexts"
This is unfortunately a bit of a large commit, but it's at least pretty much all on-topic for the generalized "contexts" feature. Rather than waste time trying to split this further into smaller commits, I'm just landing it as-is, now that I've lived with the interaction model long enough to not completely hate it. I fully expect to revisit this in the future. One TODO item in particular I'd like to note is "sending" windows to contexts always creates a new virtual desktop for the sent window in the destination context. What should really happen is the destination context should be checked for an empty desktop, and a new desktop created only when there isn't an empty one to be reused for receiving the sent window. Note this only affects non-migrate sends, as migrates (modified by Shift) explicitly use the existing focused desktop at the destination context. See the README for more information on how contexts work and what's different about the interaction model. It's fairly minimal, most of what you already know how to do should keep working as-is. The only oddity would be Mos1-s no longer "shelves" windows, it's now a modifier to turn "migrates" into "sends", and by itself is a noop now. Colors used for contexts haven't been refined and are enumerated in src/context_colors.def.
Diffstat (limited to 'src/key.c')
-rw-r--r--src/key.c235
1 files changed, 163 insertions, 72 deletions
diff --git a/src/key.c b/src/key.c
index e1eee5d..da1a22b 100644
--- a/src/key.c
+++ b/src/key.c
@@ -31,6 +31,7 @@
static int key_is_grabbed; /* flag for tracking keyboard grab state */
static vwm_direction_t direction = VWM_DIRECTION_FORWARD; /* flag for reversing directional actions */
+static int send_it; /* flag for "sending" a migration operation without following it */
/* Poll the keyboard state to see if _any_ keys are pressed */
static int keys_pressed(vwm_t *vwm)
@@ -75,8 +76,7 @@ void vwm_key_released(vwm_t *vwm, Window win, XKeyReleasedEvent *keyrelease)
vwm_win_mru(vwm, vwin);
/* make the focused desktop the most recently used */
- if (vwm->focused_context == VWM_CONTEXT_DESKTOP && vwm->focused_desktop)
- vwm_desktop_mru(vwm, vwm->focused_desktop);
+ vwm_desktop_mru(vwm, vwm->focused_desktop);
break;
@@ -85,6 +85,11 @@ void vwm_key_released(vwm_t *vwm, Window win, XKeyReleasedEvent *keyrelease)
direction = VWM_DIRECTION_FORWARD;
break;
+ case XK_s:
+ VWM_TRACE("XK_s released with send_it=%i", send_it);
+ send_it = 0;
+ break;
+
default:
VWM_TRACE("Unhandled keycode: %x", (unsigned int)sym);
break;
@@ -144,9 +149,32 @@ void vwm_key_pressed(vwm_t *vwm, Window win, XKeyPressedEvent *keypress)
direction = VWM_DIRECTION_REVERSE;
break;
- case XK_grave: /* toggle shelf visibility */
- vwm_context_focus(vwm, VWM_CONTEXT_OTHER);
+ case XK_s: /* "send" migrational actions */
+ VWM_TRACE("XK_s pressed with send_it=%i", send_it);
+ send_it = 1;
+ break;
+
+ case XK_grave: { /* cycle focused desktop by context */
+ vwm_context_t *next_context;
+
+ do_grab = 1; /* update MRU desktop on commit (Mod1 release) */
+ next_context = vwm_context_next_mru(vwm, vwm->focused_desktop->context, direction);
+
+ if (send_it && (keypress->state & ShiftMask)) { /* "send" the focused window to the MRU context's MRU desktop */
+ if (vwin)
+ vwm_win_send(vwm, vwin, vwm_desktop_mru(vwm, next_context->focused_desktop));
+ } else if (send_it) { /* "send" the focused window to a new desktop created on the MRU context */
+ if (vwin)
+ vwm_win_send(vwm, vwin, vwm_desktop_mru(vwm, vwm_desktop_create(vwm, next_context)));
+ } else if (keypress->state & ShiftMask) {
+ /* migrate the focused window with the desktop focus to the MRU context's MRU desktop */
+ if (vwin)
+ vwm_win_migrate(vwm, vwin, next_context->focused_desktop);
+ } else {
+ vwm_desktop_focus(vwm, next_context->focused_desktop);
+ }
break;
+ }
case XK_Tab: /* cycle focused window */
do_grab = 1; /* update MRU window on commit (Mod1 release) */
@@ -154,22 +182,53 @@ void vwm_key_pressed(vwm_t *vwm, Window win, XKeyPressedEvent *keypress)
/* focus the next window, note this doesn't affect MRU yet, that happens on Mod1 release */
if (vwin) {
if (keypress->state & ShiftMask) {
- vwm_win_focus_next(vwm, vwin, direction, VWM_FENCE_MASKED_VIOLATE);
+ /* TODO: in keeping with the Shift==migrate behavior, perhaps
+ * for Tab it should really do a in-desktop migration of sorts
+ * where the focused window swaps places with the next window?
+ */
+ VWM_TRACE("in-desktop migrate not implemented yet");
} else {
vwm_win_focus_next(vwm, vwin, direction, VWM_FENCE_RESPECT);
}
}
break;
+ case XK_backslash:
+ do_grab = 1;
+
+ if (vwin) {
+ if (keypress->state & ShiftMask) {
+ /* TODO: migrate window to another screen within this desktop,
+ * like VWM_FENCE_MASKED_VIOLATE would focus the next window on
+ * the next screen, but instead of focusing the next window on
+ * the next display, move the focused one to that next desktop.
+ *
+ * since screens are handled within vwm_win_focus_next() via
+ * the fence abstraction, but fences aren't exposed outside of
+ * their, it's non-trivial to implement here. I may want to
+ * break that out into a more public interface to make things
+ * more composable at the screen level.
+ */
+ VWM_TRACE("migrate window to screen not implemented yet");
+ } else {
+ vwm_win_focus_next(vwm, vwin, direction, VWM_FENCE_MASKED_VIOLATE);
+ }
+ }
+ break;
+
case XK_space: { /* cycle focused desktop utilizing MRU */
vwm_desktop_t *next_desktop;
- next_desktop = vwm_desktop_next_mru(vwm, vwm->focused_desktop, direction);
-
do_grab = 1; /* update MRU desktop on commit (Mod1 release) */
+ next_desktop = vwm_desktop_next_mru(vwm, vwm->focused_desktop, direction);
- if (keypress->state & ShiftMask) {
- /* migrate the focused window with the desktop focus to the most recently used desktop */
+ if (send_it && (keypress->state & ShiftMask)) { /* "send" the focused window to the MRU desktop */
+ if (vwin)
+ vwm_win_send(vwm, vwin, vwm_desktop_mru(vwm, next_desktop));
+ } else if (send_it) { /* "send" the focused window to a new desktop in the current context, kind of an alias of send_it+XK_v */
+ if (vwin)
+ vwm_win_send(vwm, vwin, vwm_desktop_mru(vwm, vwm_desktop_create(vwm, vwin->desktop->context)));
+ } else if (keypress->state & ShiftMask) { /* migrate the focused window with the desktop focus to the most recently used desktop */
if (vwin)
vwm_win_migrate(vwm, vwin, next_desktop);
} else {
@@ -185,7 +244,7 @@ void vwm_key_pressed(vwm_t *vwm, Window win, XKeyPressedEvent *keypress)
} else { /* kindly destroy the focused window */
vwm_xwin_message(vwm, vwin->xwindow, vwm->wm_protocols_atom, vwm->wm_delete_atom);
}
- } else if (vwm->focused_context == VWM_CONTEXT_DESKTOP) {
+ } else {
/* destroy the focused desktop when destroy occurs without any windows */
vwm_desktop_destroy(vwm, vwm->focused_desktop);
}
@@ -201,80 +260,111 @@ void vwm_key_pressed(vwm_t *vwm, Window win, XKeyPressedEvent *keypress)
case XK_v: /* instantiate (and focus) a new (potentially empty, unless migrating) virtual desktop */
do_grab = 1; /* update MRU desktop on commit (Mod1 release) */
- if (keypress->state & ShiftMask) {
- if (vwin) {
- /* migrate the focused window to a newly created virtual desktop, focusing the new desktop simultaneously */
- vwm_win_migrate(vwm, vwin, vwm_desktop_create(vwm));
- }
+ if (send_it) { /* "send" the focused window to a newly created virtual desktop, */
+ if (vwin)
+ vwm_win_send(vwm, vwin, vwm_desktop_mru(vwm, vwm_desktop_create(vwm, vwin->desktop->context)));
+ } else if (keypress->state & ShiftMask) { /* migrate the focused window to a newly created virtual desktop, focusing the new desktop simultaneously */
+ if (vwin)
+ vwm_win_migrate(vwm, vwin, vwm_desktop_create(vwm, vwin->desktop->context));
} else {
- vwm_desktop_focus(vwm, vwm_desktop_create(vwm));
- vwm_desktop_mru(vwm, vwm->focused_desktop);
+ vwm_desktop_focus(vwm, vwm_desktop_create(vwm, vwm->focused_desktop->context));
}
break;
- case XK_h: /* previous virtual desktop, if we're in the shelf context this will simply switch to desktop context */
+ case XK_c: /* instantiate (and focus) a new (potentialy empty, unless migrating) virtual desktop in a new context */
do_grab = 1; /* update MRU desktop on commit (Mod1 release) */
- if (keypress->state & ShiftMask) {
- if (vwin) {
- /* migrate the focused window with the desktop focus to the previous desktop */
- vwm_win_migrate(vwm, vwin, vwm_desktop_next(vwm, vwin->desktop, VWM_DIRECTION_REVERSE));
- }
+ if (send_it) { /* "send" the focused window to a newly created virtual desktop in a new context */
+ if (vwin)
+ vwm_win_send(vwm, vwin, vwm_desktop_mru(vwm, vwm_desktop_create(vwm, NULL)));
+ } else if (keypress->state & ShiftMask) { /* migrate the focused window to a newly created virtual desktop in a new context, focusing the new desktop simultaneously */
+
+ if (vwin)
+ vwm_win_migrate(vwm, vwin, vwm_desktop_create(vwm, NULL));
} else {
- if (vwm->focused_context == VWM_CONTEXT_SHELF) {
- /* focus the focused desktop instead of the shelf */
- vwm_context_focus(vwm, VWM_CONTEXT_DESKTOP);
- } else {
- /* focus the previous desktop */
- vwm_desktop_focus(vwm, vwm_desktop_next(vwm, vwm->focused_desktop, VWM_DIRECTION_REVERSE));
- }
+ vwm_desktop_focus(vwm, vwm_desktop_create(vwm, NULL));
}
break;
- case XK_l: /* next virtual desktop, if we're in the shelf context this will simply switch to desktop context */
+ case XK_0:
+ case XK_1:
+ case XK_2:
+ case XK_3:
+ case XK_4:
+ case XK_5:
+ case XK_6:
+ case XK_7:
+ case XK_8:
+ case XK_9:
do_grab = 1; /* update MRU desktop on commit (Mod1 release) */
- if (keypress->state & ShiftMask) {
- if (vwin) {
- /* migrate the focused window with the desktop focus to the next desktop */
- vwm_win_migrate(vwm, vwin, vwm_desktop_next(vwm, vwin->desktop, VWM_DIRECTION_FORWARD));
- }
+ if (send_it && (keypress->state & ShiftMask)) { /* "send" the focused window to the specified context */
+ if (vwin)
+ vwm_win_send(vwm, vwin, vwm_desktop_mru(vwm, vwm_context_by_color(vwm, sym - XK_0)->focused_desktop));
+ } else if (send_it) { /* "send" the focused window to a new desktop created on the specified context */
+ if (vwin)
+ vwm_win_send(vwm, vwin, vwm_desktop_mru(vwm, vwm_desktop_create(vwm, vwm_context_by_color(vwm, sym - XK_0))));
+ } else if (keypress->state & ShiftMask) { /* migrate the focused window to the specified context */
+ if (vwin)
+ vwm_win_migrate(vwm, vwin, vwm_context_by_color(vwm, sym - XK_0)->focused_desktop);
} else {
- if (vwm->focused_context == VWM_CONTEXT_SHELF) {
- /* focus the focused desktop instead of the shelf */
- vwm_context_focus(vwm, VWM_CONTEXT_DESKTOP);
- } else {
- /* focus the next desktop */
- vwm_desktop_focus(vwm, vwm_desktop_next(vwm, vwm->focused_desktop, VWM_DIRECTION_FORWARD));
- }
+ vwm_desktop_focus(vwm, vwm_context_by_color(vwm, sym - XK_0)->focused_desktop);
+ }
+ break;
+
+ case XK_h: /* previous virtual desktop spatially */
+ do_grab = 1; /* update MRU desktop on commit (Mod1 release) */
+
+ if (send_it) { /* "send" the focused window to the previous desktop */
+ if (vwin)
+ vwm_win_send(vwm, vwin, vwm_desktop_mru(vwm, vwm_desktop_next(vwm, vwin->desktop, VWM_DIRECTION_REVERSE)));
+ } else if (keypress->state & ShiftMask) { /* migrate the focused window with the desktop focus to the previous desktop */
+ if (vwin)
+ vwm_win_migrate(vwm, vwin, vwm_desktop_next(vwm, vwin->desktop, VWM_DIRECTION_REVERSE));
+ } else { /* focus the previous desktop */
+ vwm_desktop_focus(vwm, vwm_desktop_next(vwm, vwm->focused_desktop, VWM_DIRECTION_REVERSE));
+ }
+ break;
+
+ case XK_l: /* next virtual desktop spatially */
+ do_grab = 1; /* update MRU desktop on commit (Mod1 release) */
+
+ if (send_it) { /* "send" the focused window to the next desktop */
+ if (vwin)
+ vwm_win_send(vwm, vwin, vwm_desktop_mru(vwm, vwm_desktop_next(vwm, vwin->desktop, VWM_DIRECTION_FORWARD)));
+ } else if (keypress->state & ShiftMask) { /* migrate the focused window with the desktop focus to the next desktop */
+ if (vwin)
+ vwm_win_migrate(vwm, vwin, vwm_desktop_next(vwm, vwin->desktop, VWM_DIRECTION_FORWARD));
+ } else { /* focus the next desktop */
+ vwm_desktop_focus(vwm, vwm_desktop_next(vwm, vwm->focused_desktop, VWM_DIRECTION_FORWARD));
}
break;
- case XK_k: /* raise or shelve the focused window */
+ case XK_k: /* raise or context-migrate the focused window up */
if (vwin) {
- if (keypress->state & ShiftMask) { /* shelf the window and focus the shelf */
- if (vwm->focused_context != VWM_CONTEXT_SHELF) {
- /* shelve the focused window while focusing the shelf */
- vwm_win_shelve(vwm, vwin);
- vwm_context_focus(vwm, VWM_CONTEXT_SHELF);
- }
- } else {
- do_grab = 1;
+ do_grab = 1;
+
+ /* TODO: maybe bare send_it should create a new desktop in the next context,
+ * with Shift+send_it being the migrate-like send */
+ if (send_it) { /* "send" the focused window to the next context */
+ vwm_context_t *next_context = vwm_context_next(vwm, vwin->desktop->context, VWM_DIRECTION_FORWARD);
+
+ vwm_win_send(vwm, vwin, vwm_desktop_mru(vwm, next_context->focused_desktop));
+ } else if (keypress->state & ShiftMask) { /* migrate the window and focus the new context */
+ vwm_context_t *next_context = vwm_context_next(vwm, vwin->desktop->context, VWM_DIRECTION_FORWARD);
+ vwm_win_migrate(vwm, vwin, next_context->focused_desktop);
+ } else {
XRaiseWindow(VWM_XDISPLAY(vwm), vwin->xwindow->id);
- if (repeat_cnt == 1) {
- /* double: reraise & fullscreen */
+ if (repeat_cnt == 1) { /* double: reraise & fullscreen */
vwm_win_autoconf(vwm, vwin, VWM_SCREEN_REL_XWIN, VWM_WIN_AUTOCONF_FULL);
- } else if (repeat_cnt == 2) {
- /* triple: reraise & fullscreen w/borders obscured by screen perimiter */
+ } else if (repeat_cnt == 2) { /* triple: reraise & fullscreen w/borders obscured by screen perimiter */
vwm_win_autoconf(vwm, vwin, VWM_SCREEN_REL_XWIN, VWM_WIN_AUTOCONF_ALL);
} else if (vwm->xinerama_screens_cnt > 1) {
- if (repeat_cnt == 3) {
- /* triple: reraise & fullscreen across all screens */
+ if (repeat_cnt == 3) { /* triple: reraise & fullscreen across all screens */
vwm_win_autoconf(vwm, vwin, VWM_SCREEN_REL_TOTAL, VWM_WIN_AUTOCONF_FULL);
- } else if (repeat_cnt == 4) {
- /* quadruple: reraise & fullscreen w/borders obscured by screen perimiter */
+ } else if (repeat_cnt == 4) { /* quadruple: reraise & fullscreen w/borders obscured by screen perimiter */
vwm_win_autoconf(vwm, vwin, VWM_SCREEN_REL_TOTAL, VWM_WIN_AUTOCONF_ALL);
}
}
@@ -283,13 +373,20 @@ void vwm_key_pressed(vwm_t *vwm, Window win, XKeyPressedEvent *keypress)
}
break;
- case XK_j: /* lower or unshelve the focused window */
+ case XK_j: /* lower or context-migrate the focused window down */
if (vwin) {
- if (keypress->state & ShiftMask) { /* unshelf the window to the focused desktop, and focus the desktop */
- if (vwm->focused_context == VWM_CONTEXT_SHELF) {
- /* unshelve the focused window, focus the desktop it went to */
- vwm_win_migrate(vwm, vwin, vwm->focused_desktop);
- }
+ do_grab = 1;
+
+ /* TODO: maybe bare send_it should create a new desktop in the previous context,
+ * with Shift+send_it being the migrate-like send */
+ if (send_it) { /* "send" the focused window to the previous context */
+ vwm_context_t *prev_context = vwm_context_next(vwm, vwin->desktop->context, VWM_DIRECTION_REVERSE);
+
+ vwm_win_send(vwm, vwin, vwm_desktop_mru(vwm, prev_context->focused_desktop));
+ } else if (keypress->state & ShiftMask) { /* migrate the window and focus the new context */
+ vwm_context_t *prev_context = vwm_context_next(vwm, vwin->desktop->context, VWM_DIRECTION_REVERSE);
+
+ vwm_win_migrate(vwm, vwin, prev_context->focused_desktop);
} else {
if (vwin->autoconfigured == VWM_WIN_AUTOCONF_ALL) {
vwm_win_autoconf(vwm, vwin, VWM_SCREEN_REL_XWIN, VWM_WIN_AUTOCONF_FULL);
@@ -311,12 +408,6 @@ void vwm_key_pressed(vwm_t *vwm, Window win, XKeyPressedEvent *keypress)
}
break;
- case XK_s: /* shelve focused window */
- if (vwin && !vwin->shelved)
- vwm_win_shelve(vwm, vwin);
-
- break;
-
case XK_bracketleft: /* reconfigure the focused window to occupy the left or top half of the screen or left quarters on repeat */
if (vwin) {
do_grab = 1;
© All Rights Reserved