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:
parent
29b19a7468
commit
9b87b2c8ec
|
@ -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 (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
|
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
|
||||||
|
|
|
@ -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, don’t map it */
|
||||||
|
PDF_IGNORE = 2,
|
||||||
} popup_during_fullscreen;
|
} popup_during_fullscreen;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
31
src/render.c
31
src/render.c
|
@ -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);
|
/* 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);
|
x_raise_con(child);
|
||||||
render_con(child, false);
|
render_con(child, false);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue