diff options
author | Vito Caputo <vcaputo@pengaru.com> | 2025-02-15 14:50:08 -0800 |
---|---|---|
committer | Vito Caputo <vcaputo@pengaru.com> | 2025-02-23 15:39:35 -0800 |
commit | 638aabfe08e21d3419165dd21ec3da16c3979be5 (patch) | |
tree | 9dd82f69ce15e9086f2dfc2f418d45928ef8140f | |
parent | 797a0cc0f762d823119092ee9260f5b0a1ea10f3 (diff) |
window: support migrating non-autoconf windows by screenmoremoolti
preliminary attempt at supporting this, totally untested
-rw-r--r-- | src/key.c | 24 | ||||
-rw-r--r-- | src/window.c | 38 |
2 files changed, 42 insertions, 20 deletions
@@ -215,20 +215,7 @@ void vwm_key_pressed(vwm_t *vwm, Window win, XKeyPressedEvent *keypress) */ if (vwin) { - if (send_it) { - /* "send" the focused window to the next screen */ - VWM_TRACE("send window to screen not implemented yet"); - /* TODO: this is identical to "migrate" below, but needs to focus - * the next window within the origin screen if there is one. - * It's unclear to me what should happen when you "send" the only - * window in the current scren to another screen - should it just - * turn into a migrate effectively? I don't think there's a situation - * currently where no window is focused in the curent desktop, it's - * one of those things that's prevented from happening, until there's - * no windows left in the desktop. The screens are just subregions - * of the current desktop which map to displays. - */ - } else if (keypress->state & ShiftMask) { + if (send_it || (keypress->state & ShiftMask)) { vwm_screen_rel_t rel; /* "migrate" the focused window to the next screen */ @@ -244,6 +231,15 @@ void vwm_key_pressed(vwm_t *vwm, Window win, XKeyPressedEvent *keypress) assert(0); } + if (send_it) { + /* "sending" only differs in that we try to focus the next window before migrating, + * if vwin is the only window, it stays focused, and this degrades gracefully into + * a migrate. This is done because we never leave a situation without any window + * focused in a desktop. + */ + vwm_win_focus_next(vwm, vwin, direction, VWM_FENCE_RESPECT); + } + vwm_win_autoconf(vwm, vwin, rel, vwin->autoconfigured, vwin->autoconfigured_param); } else { /* focus the MRU window on the next screen */ diff --git a/src/window.c b/src/window.c index 9cf9b0a..0dfdbe9 100644 --- a/src/window.c +++ b/src/window.c @@ -126,12 +126,18 @@ void vwm_win_autoconf_magic(vwm_t *vwm, vwm_window_t *vwin, const vwm_screen_t * /* "autoconfigure" windows (configuration shortcuts like fullscreen/halfscreen/quarterscreen) and restoring the window */ void vwm_win_autoconf(vwm_t *vwm, vwm_window_t *vwin, vwm_screen_rel_t rel, vwm_win_autoconf_t conf, ...) { + XWindowChanges changes = { .border_width = WINDOW_BORDER_WIDTH }; const vwm_screen_t *scr; va_list ap; - XWindowChanges changes = { .border_width = WINDOW_BORDER_WIDTH }; /* remember the current configuration as the "client" configuration if it's not an autoconfigured one. */ - if (vwin->autoconfigured == VWM_WIN_AUTOCONF_NONE) + /* XXX: this isn't perfect, and makes me wonder if there should be two slots you can restore back to: + * 1. the OG window configuration from the X client, or + * 2. the last non-autoconf configuration, which may or may not reflect the OG one + * Right now, the OG one gets overwritten by #2, so you can only restore back to the last + * explicit window configuration with Mod1-Enter. + */ + if (conf != VWM_WIN_AUTOCONF_NONE && vwin->autoconfigured == VWM_WIN_AUTOCONF_NONE) vwin->client = vwin->xwindow->attrs; scr = vwm_screen_find(vwm, rel, vwin->xwindow); /* XXX FIXME: this becomes a bug when vwm_screen_find() uses non-xwin va_args */ @@ -217,10 +223,30 @@ void vwm_win_autoconf(vwm_t *vwm, vwm_window_t *vwin, vwm_screen_rel_t rel, vwm_ break; case VWM_WIN_AUTOCONF_NONE: /* restore window if autoconfigured */ - changes.width = vwin->client.width; - changes.height = vwin->client.height; - changes.x = vwin->client.x; - changes.y = vwin->client.y; + if (vwin->autoconfigured == VWM_WIN_AUTOCONF_NONE) { + if (rel != VWM_SCREEN_REL_XWIN) { + const vwm_screen_t *from_scr; + + /* For now let's just try adjusting the x/y to scr, + * which may or may not change anything at all, but + * it /appears/ we might be trying to switch screens. + */ + from_scr = vwm_screen_find(vwm, VWM_SCREEN_REL_XWIN, vwin->xwindow); + if (from_scr != scr) { + changes.x = vwin->xwindow->attrs.x - from_scr->x_org + scr->x_org; + changes.y = vwin->xwindow->attrs.y - from_scr->y_org + scr->y_org; + /* XXX: undecided on if w/h should get scaled proportionally, leaving alone for now */ + changes.width = vwin->xwindow->attrs.width; + changes.height = vwin->xwindow->attrs.height; + } + } + } else { + changes.width = vwin->client.width; + changes.height = vwin->client.height; + changes.x = vwin->client.x; + changes.y = vwin->client.y; + } + break; } va_end(ap); |