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
This commit is contained in:
Michael Stapelberg 2012-10-24 19:59:09 +02:00
parent 29b19a7468
commit 9b87b2c8ec
5 changed files with 44 additions and 18 deletions

View File

@ -802,21 +802,23 @@ focus_follows_mouse no
When you are in fullscreen mode, some applications still open popup windows 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 (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). 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 (dont map it). This wont 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 (dont map it). This wont interrupt you while you are
in fullscreen. However, some apps might react badly to this (deadlock until in fullscreen. However, some apps might react badly to this (deadlock until
you go out of fullscreen). you go out of fullscreen).
2. Leave fullscreen mode. This is the default. 3. Leave fullscreen mode.
*Syntax*: *Syntax*:
------------------------------------------------- -------------------------------------------------
popup_during_fullscreen <ignore|leave_fullscreen> popup_during_fullscreen <smart|ignore|leave_fullscreen>
------------------------------------------------- -------------------------------------------------
*Example*: *Example*:
------------------------------ ------------------------------
popup_during_fullscreen ignore popup_during_fullscreen smart
------------------------------ ------------------------------
=== Focus wrapping === Focus wrapping

View File

@ -191,8 +191,15 @@ struct Config {
/** What should happen when a new popup is opened during fullscreen mode */ /** What should happen when a new popup is opened during fullscreen mode */
enum { enum {
PDF_LEAVE_FULLSCREEN = 0, /* display (and focus) the popup when it belongs to the fullscreen
PDF_IGNORE = 1 * window only. */
PDF_SMART = 0,
/* leave fullscreen mode unconditionally */
PDF_LEAVE_FULLSCREEN = 1,
/* just ignore the popup, that is, dont map it */
PDF_IGNORE = 2,
} popup_during_fullscreen; } popup_during_fullscreen;
}; };

View 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. /* 3: For floating containers, we also want to raise them on click.
* We will skip handling events on floating cons in fullscreen mode */ * We will skip handling events on floating cons in fullscreen mode */
Con *fs = (ws ? con_get_fullscreen_con(ws, CF_OUTPUT) : NULL); 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); floating_raise_con(floatingcon);
/* 4: floating_modifier plus left mouse button drags */ /* 4: floating_modifier plus left mouse button drags */

View File

@ -347,6 +347,12 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki
fs != NULL) { fs != NULL) {
LOG("There is a fullscreen window, leaving fullscreen mode\n"); LOG("There is a fullscreen window, leaving fullscreen mode\n");
con_toggle_fullscreen(fs, CF_OUTPUT); 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);
} }
} }

View File

@ -245,18 +245,29 @@ void render_con(Con *con, bool render_fullscreen) {
/* Get the active workspace of that output */ /* Get the active workspace of that output */
Con *content = output_get_content(output); Con *content = output_get_content(output);
Con *workspace = TAILQ_FIRST(&(content->focus_head)); Con *workspace = TAILQ_FIRST(&(content->focus_head));
Con *fullscreen = con_get_fullscreen_con(workspace, CF_OUTPUT);
/* 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 *child; Con *child;
TAILQ_FOREACH(child, &(workspace->floating_head), floating_windows) { 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); /* Dont 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); x_raise_con(child);
render_con(child, false); render_con(child, false);
} }