commit
822477cb35
@ -1229,19 +1229,21 @@ mouse_warping none
|
|||||||
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 might not be aware
|
(take Xpdf for example). This is because these applications might 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 three things which are possible to do in this situation:
|
i3 supports four options for this situation:
|
||||||
|
|
||||||
1. Display the popup if it belongs to the fullscreen application only. This is
|
1. +smart+: Display the popup if it belongs to the fullscreen application only.
|
||||||
the default and should be reasonable behavior for most users.
|
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
|
2. +ignore+: Just ignore the popup (don’t map it). This won’t interrupt you
|
||||||
in fullscreen. However, some apps might react badly to this (deadlock until
|
while you are in fullscreen. However, some apps might react badly to this
|
||||||
you go out of fullscreen).
|
(deadlock until you go out of fullscreen).
|
||||||
3. Leave fullscreen mode.
|
3. +leave_fullscreen+: Leave fullscreen mode.
|
||||||
|
4. +all+: Since i3 4.24: Display all floating windows regardless to which
|
||||||
|
application they belong to.
|
||||||
|
|
||||||
*Syntax*:
|
*Syntax*:
|
||||||
-----------------------------------------------------
|
---------------------------------------------------------
|
||||||
popup_during_fullscreen smart|ignore|leave_fullscreen
|
popup_during_fullscreen smart|ignore|leave_fullscreen|all
|
||||||
-----------------------------------------------------
|
---------------------------------------------------------
|
||||||
|
|
||||||
*Example*:
|
*Example*:
|
||||||
------------------------------
|
------------------------------
|
||||||
|
@ -262,6 +262,9 @@ struct Config {
|
|||||||
|
|
||||||
/* just ignore the popup, that is, don’t map it */
|
/* just ignore the popup, that is, don’t map it */
|
||||||
PDF_IGNORE = 2,
|
PDF_IGNORE = 2,
|
||||||
|
|
||||||
|
/* display all floating windows */
|
||||||
|
PDF_ALL = 3,
|
||||||
} popup_during_fullscreen;
|
} popup_during_fullscreen;
|
||||||
|
|
||||||
/* The number of currently parsed barconfigs */
|
/* The number of currently parsed barconfigs */
|
||||||
|
@ -366,7 +366,7 @@ state RESTART_STATE:
|
|||||||
|
|
||||||
# popup_during_fullscreen
|
# popup_during_fullscreen
|
||||||
state POPUP_DURING_FULLSCREEN:
|
state POPUP_DURING_FULLSCREEN:
|
||||||
value = 'ignore', 'leave_fullscreen', 'smart'
|
value = 'ignore', 'leave_fullscreen', 'all', 'smart'
|
||||||
-> call cfg_popup_during_fullscreen($value)
|
-> call cfg_popup_during_fullscreen($value)
|
||||||
|
|
||||||
state TILING_DRAG_MODE:
|
state TILING_DRAG_MODE:
|
||||||
|
1
release-notes/changes/6-popup_during_fullscreen-all
Normal file
1
release-notes/changes/6-popup_during_fullscreen-all
Normal file
@ -0,0 +1 @@
|
|||||||
|
Add popup_during_fullscreen all option
|
@ -579,6 +579,8 @@ CFGFUN(popup_during_fullscreen, const char *value) {
|
|||||||
config.popup_during_fullscreen = PDF_IGNORE;
|
config.popup_during_fullscreen = PDF_IGNORE;
|
||||||
} else if (strcmp(value, "leave_fullscreen") == 0) {
|
} else if (strcmp(value, "leave_fullscreen") == 0) {
|
||||||
config.popup_during_fullscreen = PDF_LEAVE_FULLSCREEN;
|
config.popup_during_fullscreen = PDF_LEAVE_FULLSCREEN;
|
||||||
|
} else if (strcmp(value, "all") == 0) {
|
||||||
|
config.popup_during_fullscreen = PDF_ALL;
|
||||||
} else {
|
} else {
|
||||||
config.popup_during_fullscreen = PDF_SMART;
|
config.popup_during_fullscreen = PDF_SMART;
|
||||||
}
|
}
|
||||||
|
22
src/manage.c
22
src/manage.c
@ -502,7 +502,7 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki
|
|||||||
if (config.popup_during_fullscreen == PDF_LEAVE_FULLSCREEN &&
|
if (config.popup_during_fullscreen == PDF_LEAVE_FULLSCREEN &&
|
||||||
fs != NULL) {
|
fs != NULL) {
|
||||||
DLOG("There is a fullscreen window, leaving fullscreen mode\n");
|
DLOG("There is a fullscreen window, leaving fullscreen mode\n");
|
||||||
con_toggle_fullscreen(fs, CF_OUTPUT);
|
con_disable_fullscreen(fs);
|
||||||
} else if (config.popup_during_fullscreen == PDF_SMART &&
|
} else if (config.popup_during_fullscreen == PDF_SMART &&
|
||||||
fs != NULL &&
|
fs != NULL &&
|
||||||
fs->window != NULL) {
|
fs->window != NULL) {
|
||||||
@ -524,6 +524,10 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki
|
|||||||
nc->geometry = (Rect){geom->x, geom->y, geom->width, geom->height};
|
nc->geometry = (Rect){geom->x, geom->y, geom->width, geom->height};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config.popup_during_fullscreen == PDF_ALL && want_floating && fs != NULL) {
|
||||||
|
set_focus = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (want_floating) {
|
if (want_floating) {
|
||||||
DLOG("geometry = %d x %d\n", nc->geometry.width, nc->geometry.height);
|
DLOG("geometry = %d x %d\n", nc->geometry.width, nc->geometry.height);
|
||||||
if (floating_enable(nc, true)) {
|
if (floating_enable(nc, true)) {
|
||||||
@ -646,15 +650,13 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki
|
|||||||
xcb_discard_reply(conn, wm_user_time_cookie.sequence);
|
xcb_discard_reply(conn, wm_user_time_cookie.sequence);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (set_focus) {
|
/* Even if the client doesn't want focus, we still need to focus the
|
||||||
/* Even if the client doesn't want focus, we still need to focus the
|
* container to not break focus workflows. Our handling towards X will take
|
||||||
* container to not break focus workflows. Our handling towards X will
|
* care of not setting the input focus. However, one exception to this are
|
||||||
* take care of not setting the input focus. However, one exception to
|
* clients using the globally active input model which we don't want to
|
||||||
* this are clients using the globally active input model which we
|
* focus at all. */
|
||||||
* don't want to focus at all. */
|
if (nc->window->doesnt_accept_focus && !nc->window->needs_take_focus) {
|
||||||
if (nc->window->doesnt_accept_focus && !nc->window->needs_take_focus) {
|
set_focus = false;
|
||||||
set_focus = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Defer setting focus after the 'new' event has been sent to ensure the
|
/* Defer setting focus after the 'new' event has been sent to ensure the
|
||||||
|
40
src/render.c
40
src/render.c
@ -250,6 +250,26 @@ static int *precalculate_sizes(Con *con, render_params *p) {
|
|||||||
return sizes;
|
return sizes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool fullscreen_blocks_floating_render(Con *fullscreen, Con *floating) {
|
||||||
|
if (fullscreen == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/* Don’t render floating windows when there is a fullscreen window on that
|
||||||
|
* workspace. Necessary to make floating fullscreen work correctly (ticket
|
||||||
|
* #564). Exception to the above rule: popup_during_fullscreen smart|all. */
|
||||||
|
switch (config.popup_during_fullscreen) {
|
||||||
|
case PDF_LEAVE_FULLSCREEN:
|
||||||
|
case PDF_IGNORE:
|
||||||
|
return true;
|
||||||
|
case PDF_SMART:
|
||||||
|
return fullscreen->window == NULL ||
|
||||||
|
!con_find_transient_for_window(con_descend_focused(floating), fullscreen->window->id);
|
||||||
|
case PDF_ALL:
|
||||||
|
return con_has_parent(fullscreen, floating);
|
||||||
|
}
|
||||||
|
return false; /* not reachable */
|
||||||
|
}
|
||||||
|
|
||||||
static void render_root(Con *con, Con *fullscreen) {
|
static void render_root(Con *con, Con *fullscreen) {
|
||||||
Con *output;
|
Con *output;
|
||||||
if (!fullscreen) {
|
if (!fullscreen) {
|
||||||
@ -277,24 +297,8 @@ static void render_root(Con *con, Con *fullscreen) {
|
|||||||
Con *fullscreen = con_get_fullscreen_covering_ws(workspace);
|
Con *fullscreen = con_get_fullscreen_covering_ws(workspace);
|
||||||
Con *child;
|
Con *child;
|
||||||
TAILQ_FOREACH (child, &(workspace->floating_head), floating_windows) {
|
TAILQ_FOREACH (child, &(workspace->floating_head), floating_windows) {
|
||||||
if (fullscreen != NULL) {
|
if (fullscreen_blocks_floating_render(fullscreen, child)) {
|
||||||
/* Don’t render floating windows when there is a fullscreen
|
continue;
|
||||||
* window on that workspace. Necessary to make floating
|
|
||||||
* fullscreen work correctly (ticket #564). Exception to the
|
|
||||||
* above rule: smart popup_during_fullscreen handling (popups
|
|
||||||
* belonging to the fullscreen app will be rendered). */
|
|
||||||
if (config.popup_during_fullscreen != PDF_SMART || fullscreen->window == NULL) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Con *floating_child = con_descend_focused(child);
|
|
||||||
if (con_find_transient_for_window(floating_child, fullscreen->window->id)) {
|
|
||||||
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);
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
DLOG("floating child at (%d,%d) with %d x %d\n",
|
DLOG("floating child at (%d,%d) with %d x %d\n",
|
||||||
child->rect.x, child->rect.y, child->rect.width, child->rect.height);
|
child->rect.x, child->rect.y, child->rect.width, child->rect.height);
|
||||||
|
@ -202,12 +202,14 @@ $config = <<'EOT';
|
|||||||
popup_during_fullscreen ignore
|
popup_during_fullscreen ignore
|
||||||
popup_during_fullscreen leave_fullscreen
|
popup_during_fullscreen leave_fullscreen
|
||||||
popup_during_fullscreen SMArt
|
popup_during_fullscreen SMArt
|
||||||
|
popup_during_fullscreen aLL
|
||||||
EOT
|
EOT
|
||||||
|
|
||||||
$expected = <<'EOT';
|
$expected = <<'EOT';
|
||||||
cfg_popup_during_fullscreen(ignore)
|
cfg_popup_during_fullscreen(ignore)
|
||||||
cfg_popup_during_fullscreen(leave_fullscreen)
|
cfg_popup_during_fullscreen(leave_fullscreen)
|
||||||
cfg_popup_during_fullscreen(smart)
|
cfg_popup_during_fullscreen(smart)
|
||||||
|
cfg_popup_during_fullscreen(all)
|
||||||
EOT
|
EOT
|
||||||
|
|
||||||
is(parser_calls($config),
|
is(parser_calls($config),
|
||||||
|
154
testcases/t/553-popup_during_fullscreen.t
Normal file
154
testcases/t/553-popup_during_fullscreen.t
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
#!perl
|
||||||
|
# vim:ts=4:sw=4:expandtab
|
||||||
|
#
|
||||||
|
# Please read the following documents before working on tests:
|
||||||
|
# • https://build.i3wm.org/docs/testsuite.html
|
||||||
|
# (or docs/testsuite)
|
||||||
|
#
|
||||||
|
# • https://build.i3wm.org/docs/lib-i3test.html
|
||||||
|
# (alternatively: perldoc ./testcases/lib/i3test.pm)
|
||||||
|
#
|
||||||
|
# • https://build.i3wm.org/docs/ipc.html
|
||||||
|
# (or docs/ipc)
|
||||||
|
#
|
||||||
|
# • https://i3wm.org/downloads/modern_perl_a4.pdf
|
||||||
|
# (unless you are already familiar with Perl)
|
||||||
|
#
|
||||||
|
# Test popup_during_fullscreen option
|
||||||
|
use i3test i3_autostart => 0;
|
||||||
|
use i3test::XTEST;
|
||||||
|
|
||||||
|
sub setup {
|
||||||
|
kill_all_windows;
|
||||||
|
|
||||||
|
my $ws = fresh_workspace;
|
||||||
|
my $w1 = open_window;
|
||||||
|
cmd 'fullscreen';
|
||||||
|
is_num_fullscreen($ws, 1, 'sanity check: one fullscreen window');
|
||||||
|
return ($ws, $w1);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub open_transient_for {
|
||||||
|
my $for = shift;
|
||||||
|
my $w = open_window({ dont_map => 1, rect => [ 30, 30, 50, 50 ] });
|
||||||
|
$w->transient_for($for);
|
||||||
|
$w->map;
|
||||||
|
sync_with_i3;
|
||||||
|
return $w;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub open_without_map_wait {
|
||||||
|
my $w = open_window({ dont_map => 1 });
|
||||||
|
$w->map;
|
||||||
|
sync_with_i3;
|
||||||
|
return $w;
|
||||||
|
}
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Test popup_during_fullscreen ignore
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
my $config = <<EOT;
|
||||||
|
# i3 config file (v4)
|
||||||
|
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
|
||||||
|
|
||||||
|
popup_during_fullscreen ignore
|
||||||
|
EOT
|
||||||
|
my $pid = launch_with_config($config);
|
||||||
|
|
||||||
|
my ($ws, $w1) = setup;
|
||||||
|
|
||||||
|
my $w2 = open_transient_for($w1);
|
||||||
|
is_num_fullscreen($ws, 1, 'still one fullscren window');
|
||||||
|
is($x->input_focus, $w1->id, 'fullscreen window still focused');
|
||||||
|
|
||||||
|
open_without_map_wait;
|
||||||
|
is_num_fullscreen($ws, 1, 'still one fullscren window');
|
||||||
|
is($x->input_focus, $w1->id, 'fullscreen window focused');
|
||||||
|
|
||||||
|
exit_gracefully($pid);
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Test popup_during_fullscreen leave_fullscreen
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
$config = <<EOT;
|
||||||
|
# i3 config file (v4)
|
||||||
|
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
|
||||||
|
|
||||||
|
popup_during_fullscreen leave_fullscreen
|
||||||
|
EOT
|
||||||
|
$pid = launch_with_config($config);
|
||||||
|
|
||||||
|
($ws, $w1) = setup;
|
||||||
|
|
||||||
|
# Fullscreen disabled when transient windows open
|
||||||
|
$w2 = open_transient_for($w1);
|
||||||
|
is_num_fullscreen($ws, 0, 'no fullscren window');
|
||||||
|
# XXX: Arguably a bug but leave_fullscreen does not change focus
|
||||||
|
is($x->input_focus, $w1->id, 'fullscreen window focused');
|
||||||
|
|
||||||
|
# Fullscreen stays when regular windows open
|
||||||
|
$w1->fullscreen(1);
|
||||||
|
open_without_map_wait;
|
||||||
|
is_num_fullscreen($ws, 1, 'still one fullscreen window');
|
||||||
|
is($x->input_focus, $w1->id, 'fullscreen window focused');
|
||||||
|
|
||||||
|
|
||||||
|
exit_gracefully($pid);
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Test popup_during_fullscreen smart
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
$config = <<EOT;
|
||||||
|
# i3 config file (v4)
|
||||||
|
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
|
||||||
|
|
||||||
|
popup_during_fullscreen smart
|
||||||
|
EOT
|
||||||
|
$pid = launch_with_config($config);
|
||||||
|
|
||||||
|
($ws, $w1) = setup;
|
||||||
|
|
||||||
|
# Fullscreen stays when transient windows open
|
||||||
|
$w2 = open_transient_for($w1);
|
||||||
|
is_num_fullscreen($ws, 1, 'still one fullscreen window');
|
||||||
|
is($x->input_focus, $w2->id, 'popup focused');
|
||||||
|
|
||||||
|
# Fullscreen stays when regular windows open
|
||||||
|
open_without_map_wait;
|
||||||
|
is_num_fullscreen($ws, 1, 'still one fullscreen window');
|
||||||
|
is($x->input_focus, $w2->id, 'popup still focused');
|
||||||
|
|
||||||
|
|
||||||
|
exit_gracefully($pid);
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Test popup_during_fullscreen all
|
||||||
|
# See #6062
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
$config = <<EOT;
|
||||||
|
# i3 config file (v4)
|
||||||
|
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
|
||||||
|
|
||||||
|
popup_during_fullscreen all
|
||||||
|
EOT
|
||||||
|
$pid = launch_with_config($config);
|
||||||
|
|
||||||
|
($ws, $w1) = setup;
|
||||||
|
|
||||||
|
# Fullscreen stays when transient windows open
|
||||||
|
$w2 = open_transient_for($w1);
|
||||||
|
is_num_fullscreen($ws, 1, 'still one fullscreen window');
|
||||||
|
is($x->input_focus, $w2->id, 'popup focused');
|
||||||
|
|
||||||
|
# Fullscreen stays when regular windows open
|
||||||
|
$w1->fullscreen(1);
|
||||||
|
open_without_map_wait;
|
||||||
|
is_num_fullscreen($ws, 1, 'still one fullscreen window');
|
||||||
|
|
||||||
|
exit_gracefully($pid);
|
||||||
|
|
||||||
|
done_testing;
|
Loading…
Reference in New Issue
Block a user