commit
822477cb35
@ -1229,19 +1229,21 @@ mouse_warping none
|
||||
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
|
||||
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
|
||||
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).
|
||||
3. Leave fullscreen mode.
|
||||
1. +smart+: Display the popup if it belongs to the fullscreen application only.
|
||||
This is the default and should be reasonable behavior for most users.
|
||||
2. +ignore+: 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).
|
||||
3. +leave_fullscreen+: Leave fullscreen mode.
|
||||
4. +all+: Since i3 4.24: Display all floating windows regardless to which
|
||||
application they belong to.
|
||||
|
||||
*Syntax*:
|
||||
-----------------------------------------------------
|
||||
popup_during_fullscreen smart|ignore|leave_fullscreen
|
||||
-----------------------------------------------------
|
||||
---------------------------------------------------------
|
||||
popup_during_fullscreen smart|ignore|leave_fullscreen|all
|
||||
---------------------------------------------------------
|
||||
|
||||
*Example*:
|
||||
------------------------------
|
||||
|
@ -262,6 +262,9 @@ struct Config {
|
||||
|
||||
/* just ignore the popup, that is, don’t map it */
|
||||
PDF_IGNORE = 2,
|
||||
|
||||
/* display all floating windows */
|
||||
PDF_ALL = 3,
|
||||
} popup_during_fullscreen;
|
||||
|
||||
/* The number of currently parsed barconfigs */
|
||||
|
@ -366,7 +366,7 @@ state RESTART_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)
|
||||
|
||||
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;
|
||||
} else if (strcmp(value, "leave_fullscreen") == 0) {
|
||||
config.popup_during_fullscreen = PDF_LEAVE_FULLSCREEN;
|
||||
} else if (strcmp(value, "all") == 0) {
|
||||
config.popup_during_fullscreen = PDF_ALL;
|
||||
} else {
|
||||
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 &&
|
||||
fs != NULL) {
|
||||
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 &&
|
||||
fs != 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};
|
||||
}
|
||||
|
||||
if (config.popup_during_fullscreen == PDF_ALL && want_floating && fs != NULL) {
|
||||
set_focus = true;
|
||||
}
|
||||
|
||||
if (want_floating) {
|
||||
DLOG("geometry = %d x %d\n", nc->geometry.width, nc->geometry.height);
|
||||
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);
|
||||
}
|
||||
|
||||
if (set_focus) {
|
||||
/* 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 care of not setting the input focus. However, one exception to
|
||||
* this are clients using the globally active input model which we
|
||||
* don't want to focus at all. */
|
||||
if (nc->window->doesnt_accept_focus && !nc->window->needs_take_focus) {
|
||||
set_focus = false;
|
||||
}
|
||||
/* 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
|
||||
* care of not setting the input focus. However, one exception to this are
|
||||
* clients using the globally active input model which we don't want to
|
||||
* focus at all. */
|
||||
if (nc->window->doesnt_accept_focus && !nc->window->needs_take_focus) {
|
||||
set_focus = false;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
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) {
|
||||
Con *output;
|
||||
if (!fullscreen) {
|
||||
@ -277,24 +297,8 @@ static void render_root(Con *con, Con *fullscreen) {
|
||||
Con *fullscreen = con_get_fullscreen_covering_ws(workspace);
|
||||
Con *child;
|
||||
TAILQ_FOREACH (child, &(workspace->floating_head), floating_windows) {
|
||||
if (fullscreen != NULL) {
|
||||
/* 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: 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;
|
||||
}
|
||||
if (fullscreen_blocks_floating_render(fullscreen, child)) {
|
||||
continue;
|
||||
}
|
||||
DLOG("floating child at (%d,%d) with %d x %d\n",
|
||||
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 leave_fullscreen
|
||||
popup_during_fullscreen SMArt
|
||||
popup_during_fullscreen aLL
|
||||
EOT
|
||||
|
||||
$expected = <<'EOT';
|
||||
cfg_popup_during_fullscreen(ignore)
|
||||
cfg_popup_during_fullscreen(leave_fullscreen)
|
||||
cfg_popup_during_fullscreen(smart)
|
||||
cfg_popup_during_fullscreen(all)
|
||||
EOT
|
||||
|
||||
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