From 9b87b2c8ec74d74f05e87ce8be8ef96e9322459b Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Wed, 24 Oct 2012 19:59:09 +0200 Subject: [PATCH] Implement smart popup_during_fullscreen mode 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 | 12 +++++++----- include/config.h | 11 +++++++++-- src/click.c | 2 +- src/manage.c | 6 ++++++ src/render.c | 31 +++++++++++++++++++++---------- 5 files changed, 44 insertions(+), 18 deletions(-) diff --git a/docs/userguide b/docs/userguide index e76e4e07..4de69d7a 100644 --- a/docs/userguide +++ b/docs/userguide @@ -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 +popup_during_fullscreen ------------------------------------------------- *Example*: ------------------------------ -popup_during_fullscreen ignore +popup_during_fullscreen smart ------------------------------ === Focus wrapping diff --git a/include/config.h b/include/config.h index fd9c7303..04f1c85f 100644 --- a/include/config.h +++ b/include/config.h @@ -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; }; diff --git a/src/click.c b/src/click.c index 13f51acf..5eedd000 100644 --- a/src/click.c +++ b/src/click.c @@ -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 */ diff --git a/src/manage.c b/src/manage.c index b07a9c8a..9835aa2a 100644 --- a/src/manage.c +++ b/src/manage.c @@ -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); } } diff --git a/src/render.c b/src/render.c index 369273c8..1216241b 100644 --- a/src/render.c +++ b/src/render.c @@ -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); } -- 2.39.2