summaryrefslogtreecommitdiff
path: root/src/window.c
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@gnugeneration.com>2017-03-24 01:55:15 -0700
committerVito Caputo <vcaputo@gnugeneration.com>2017-03-24 02:05:22 -0700
commit4ef11bae3fa16cdf7551816d711c38fe063965a7 (patch)
tree7cb9497874132b7ee60a3fa1be4c211c77312810 /src/window.c
parent53702ab184e9133a9cfe28406c71cfdabf2e4db5 (diff)
xevent: cleanup vwm_xevent_handle_map_request()
Long overdue tidying of the map request handling. This moves all the window classifying and placement stuff into a separate helper, adding a call to that in vwm_win_manage_xwin(), where this always belonged. The map request handling now just manages windows that aren't already managed, then lets the usual "is this window mapped?" logic filter the map request. This should fix a lingering bug where a window on the unfocused desktop would become spuriously visible if the client mapped it. Firefox started doing this recently when a page finished loading.
Diffstat (limited to 'src/window.c')
-rw-r--r--src/window.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/window.c b/src/window.c
index 1f0c6bf..a66c448 100644
--- a/src/window.c
+++ b/src/window.c
@@ -377,6 +377,83 @@ vwm_xwindow_t * vwm_win_unmanage(vwm_t *vwm, vwm_window_t *vwin)
}
+/* helper for doing the classification/placement of a window becoming managed */
+static void vwm_win_assimilate(vwm_t *vwm, vwm_window_t *vwin)
+{
+ vwm_xwindow_t *xwin = vwin->xwindow;
+ XWindowAttributes attrs;
+ XWindowChanges changes = {};
+ unsigned changes_mask = (CWX | CWY);
+ XClassHint *classhint;
+ const vwm_screen_t *scr = NULL;
+
+ /* figure out if the window is the console */
+ if ((classhint = XAllocClassHint())) {
+ if (XGetClassHint(VWM_XDISPLAY(vwm), xwin->id, classhint) && !strcmp(classhint->res_class, CONSOLE_WM_CLASS)) {
+ vwm->console = vwin;
+ vwm_win_shelve(vwm, vwin);
+ vwm_win_autoconf(vwm, vwin, VWM_SCREEN_REL_XWIN, VWM_WIN_AUTOCONF_FULL);
+ }
+
+ if (classhint->res_class)
+ XFree(classhint->res_class);
+
+ if (classhint->res_name)
+ XFree(classhint->res_name);
+
+ XFree(classhint);
+ }
+
+ /* TODO: this is a good place to hook in a window placement algo */
+
+ /* on client-requested mapping we place the window */
+ if (!vwin->shelved) {
+ /* we place the window on the screen containing the the pointer only if that screen is empty,
+ * otherwise we place windows on the screen containing the currently focused window */
+ /* since we query the geometry of windows in determining where to place them, a configuring
+ * flag is used to exclude the window being configured from those queries */
+ scr = vwm_screen_find(vwm, VWM_SCREEN_REL_POINTER);
+ vwin->configuring = 1;
+ if (vwm_screen_is_empty(vwm, scr)) {
+ /* focus the new window if it isn't already focused when it's going to an empty screen */
+ VWM_TRACE("window \"%s\" is alone on screen \"%i\", focusing", vwin->xwindow->name, scr->screen_number);
+ vwm_win_focus(vwm, vwin);
+ } else {
+ scr = vwm_screen_find(vwm, VWM_SCREEN_REL_XWIN, vwm->focused_desktop->focused_window->xwindow);
+ }
+ vwin->configuring = 0;
+
+ changes.x = scr->x_org;
+ changes.y = scr->y_org;
+ } else if (vwm->focused_context == VWM_CONTEXT_SHELF) {
+ scr = vwm_screen_find(vwm, VWM_SCREEN_REL_XWIN, vwm->focused_shelf->xwindow);
+ changes.x = scr->x_org;
+ changes.y = scr->y_org;
+ }
+
+ /* XXX TODO: does this belong here? */
+ XGetWMNormalHints(VWM_XDISPLAY(vwm), xwin->id, vwin->hints, &vwin->hints_supplied);
+ XGetWindowAttributes(VWM_XDISPLAY(vwm), xwin->id, &attrs);
+
+ /* if the window size is precisely the screen size then directly "allscreen" the window right here */
+ if (!vwin->shelved && scr &&
+ attrs.width == scr->width &&
+ attrs.height == scr->height) {
+ VWM_TRACE("auto-allscreened window \"%s\"", vwin->xwindow->name);
+ changes.border_width = 0;
+ changes_mask |= CWBorderWidth;
+ vwin->autoconfigured = VWM_WIN_AUTOCONF_ALL;
+ }
+
+ vwin->client.x = changes.x;
+ vwin->client.y = changes.y;
+ vwin->client.height = attrs.height;
+ vwin->client.width = attrs.width;
+
+ XConfigureWindow(VWM_XDISPLAY(vwm), xwin->id, changes_mask, &changes);
+}
+
+
/* promote an unmanaged window to a managed one */
vwm_window_t * vwm_win_manage_xwin(vwm_t *vwm, vwm_xwindow_t *xwin)
{
@@ -436,6 +513,8 @@ vwm_window_t * vwm_win_manage_xwin(vwm_t *vwm, vwm_xwindow_t *xwin)
list_add(&vwin->windows_mru, &vwm->windows_mru);
}
+ vwm_win_assimilate(vwm, vwin);
+
/* always raise newly managed windows so we know about them. */
XRaiseWindow(VWM_XDISPLAY(vwm), xwin->id);
© All Rights Reserved