]> git.sur5r.net Git - i3/i3/commitdiff
Implement smart popup_during_fullscreen mode
authorMichael Stapelberg <michael@stapelberg.de>
Wed, 24 Oct 2012 17:59:09 +0000 (19:59 +0200)
committerMichael Stapelberg <michael@stapelberg.de>
Wed, 24 Oct 2012 18:54:28 +0000 (20:54 +0200)
With this commit, the default behavior is to display popups while there
is a fullscreen application only if the popup belongs to that
application (as determined by the WM_TRANSIENT_FOR hint which
applications have to set properly).

fixes #663

docs/userguide
include/config.h
src/click.c
src/manage.c
src/render.c

index e76e4e07f0becfbd07c0f402f020a1c0a49691cb..4de69d7a2b0c697c2b9da1f508d3fb479aa7dd5b 100644 (file)
@@ -802,21 +802,23 @@ focus_follows_mouse no
 When you are in fullscreen mode, some applications still open popup windows
 (take Xpdf for example). This is because these applications may not be aware
 that they are in fullscreen mode (they do not check the corresponding hint).
-There are two things which are possible to do in this situation:
+There are three things which are possible to do in this situation:
 
-1. Just ignore the popup (don’t map it). This won’t interrupt you while you are
+1. Display the popup if it belongs to the fullscreen application only. This is
+   the default and should be reasonable behavior for most users.
+2. Just ignore the popup (don’t map it). This won’t interrupt you while you are
    in fullscreen. However, some apps might react badly to this (deadlock until
    you go out of fullscreen).
-2. Leave fullscreen mode. This is the default.
+3. Leave fullscreen mode.
 
 *Syntax*:
 -------------------------------------------------
-popup_during_fullscreen <ignore|leave_fullscreen>
+popup_during_fullscreen <smart|ignore|leave_fullscreen>
 -------------------------------------------------
 
 *Example*:
 ------------------------------
-popup_during_fullscreen ignore
+popup_during_fullscreen smart
 ------------------------------
 
 === Focus wrapping
index fd9c73032ef2506372439c637792e7d2f56ffe27..04f1c85f65ded1e8b1e088afe6a9aa2c6e300489 100644 (file)
@@ -191,8 +191,15 @@ struct Config {
 
     /** What should happen when a new popup is opened during fullscreen mode */
     enum {
-        PDF_LEAVE_FULLSCREEN = 0,
-        PDF_IGNORE = 1
+        /* display (and focus) the popup when it belongs to the fullscreen
+         * window only. */
+        PDF_SMART = 0,
+
+        /* leave fullscreen mode unconditionally */
+        PDF_LEAVE_FULLSCREEN = 1,
+
+        /* just ignore the popup, that is, don’t map it */
+        PDF_IGNORE = 2,
     } popup_during_fullscreen;
 };
 
index 13f51acf398ba3f9929721b1111960ba3d363446..5eedd00041f250b978798649bc8cf503dbbcb0f8 100644 (file)
@@ -229,7 +229,7 @@ static int route_click(Con *con, xcb_button_press_event_t *event, const bool mod
     /* 3: For floating containers, we also want to raise them on click.
      * We will skip handling events on floating cons in fullscreen mode */
     Con *fs = (ws ? con_get_fullscreen_con(ws, CF_OUTPUT) : NULL);
-    if (floatingcon != NULL && fs == NULL) {
+    if (floatingcon != NULL && fs != con) {
         floating_raise_con(floatingcon);
 
         /* 4: floating_modifier plus left mouse button drags */
index b07a9c8aeccd0a8cd3d1eda1800e420c90806dcc..9835aa2a9637a49ae2d1055caddf2cba2e442d00 100644 (file)
@@ -347,6 +347,12 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki
             fs != NULL) {
             LOG("There is a fullscreen window, leaving fullscreen mode\n");
             con_toggle_fullscreen(fs, CF_OUTPUT);
+        } else if (config.popup_during_fullscreen == PDF_SMART &&
+                   fs != NULL &&
+                   fs->window != NULL &&
+                   fs->window->id == cwindow->transient_for) {
+            LOG("This floating window belongs to the fullscreen window (popup_during_fullscreen == smart)\n");
+            con_focus(nc);
         }
     }
 
index 369273c81c46df056dc4ebc77db1c048444fdb50..1216241b49af184a8e2ef45cdf997768b6f54af0 100644 (file)
@@ -245,18 +245,29 @@ void render_con(Con *con, bool render_fullscreen) {
             /* Get the active workspace of that output */
             Con *content = output_get_content(output);
             Con *workspace = TAILQ_FIRST(&(content->focus_head));
-
-            /* Check for fullscreen nodes */
-            /* XXX: This code duplication is unfortunate. Keep in mind to fix
-             * this when we clean up the whole render.c */
-            Con *fullscreen = NULL;
-            fullscreen = con_get_fullscreen_con(workspace, CF_OUTPUT);
-            if (fullscreen)
-                    continue;
-
+            Con *fullscreen = con_get_fullscreen_con(workspace, CF_OUTPUT);
             Con *child;
             TAILQ_FOREACH(child, &(workspace->floating_head), floating_windows) {
-                DLOG("floating child at (%d,%d) with %d x %d\n", child->rect.x, child->rect.y, child->rect.width, child->rect.height);
+                /* Don’t render floating windows when there is a fullscreen window
+                 * on that workspace. Necessary to make floating fullscreen work
+                 * correctly (ticket #564). */
+                if (fullscreen != NULL) {
+                    Con *floating_child = con_descend_focused(child);
+                    /* Exception to the above rule: smart
+                     * popup_during_fullscreen handling (popups belonging to
+                     * the fullscreen app will be rendered). */
+                    if (floating_child->window == NULL ||
+                        fullscreen->window == NULL ||
+                        floating_child->window->transient_for != fullscreen->window->id)
+                        continue;
+                    else {
+                        DLOG("Rendering floating child even though in fullscreen mode: "
+                             "floating->transient_for (0x%08x) == fullscreen->id (0x%08x)\n",
+                             floating_child->window->transient_for, fullscreen->window->id);
+                    }
+                }
+                DLOG("floating child at (%d,%d) with %d x %d\n",
+                     child->rect.x, child->rect.y, child->rect.width, child->rect.height);
                 x_raise_con(child);
                 render_con(child, false);
             }