window: Don't check always-on-top overlap before placing
When we show a window, we'll check if it overlaps with an existing always-on-top window with the intention to deny focus. However, we did this potentially before having placed the window, meaning we effectively checked as if it was placed at (0, 0), which created unexpected results. Instead check the overlap state after placing. A window placement test case is added to verify this works as expected. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3879>
This commit is contained in:
parent
c68d6c4958
commit
74f58674e7
@ -353,7 +353,9 @@ find_most_freespace (MetaWindow *window,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
window_overlaps_focus_window (MetaWindow *window)
|
window_overlaps_focus_window (MetaWindow *window,
|
||||||
|
int new_x,
|
||||||
|
int new_y)
|
||||||
{
|
{
|
||||||
MetaWindow *focus_window;
|
MetaWindow *focus_window;
|
||||||
MtkRectangle window_frame, focus_frame, overlap;
|
MtkRectangle window_frame, focus_frame, overlap;
|
||||||
@ -363,6 +365,9 @@ window_overlaps_focus_window (MetaWindow *window)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
meta_window_get_frame_rect (window, &window_frame);
|
meta_window_get_frame_rect (window, &window_frame);
|
||||||
|
window_frame.x = new_x;
|
||||||
|
window_frame.y = new_y;
|
||||||
|
|
||||||
meta_window_get_frame_rect (focus_window, &focus_frame);
|
meta_window_get_frame_rect (focus_window, &focus_frame);
|
||||||
|
|
||||||
return mtk_rectangle_intersect (&window_frame,
|
return mtk_rectangle_intersect (&window_frame,
|
||||||
@ -414,7 +419,7 @@ avoid_being_obscured_as_second_modal_dialog (MetaWindow *window,
|
|||||||
#ifdef HAVE_X11_CLIENT
|
#ifdef HAVE_X11_CLIENT
|
||||||
meta_window_x11_same_application (window, focus_window) &&
|
meta_window_x11_same_application (window, focus_window) &&
|
||||||
#endif
|
#endif
|
||||||
window_overlaps_focus_window (window))
|
window_overlaps_focus_window (window, *x, *y))
|
||||||
{
|
{
|
||||||
find_most_freespace (window, focus_window, *x, *y, x, y);
|
find_most_freespace (window, focus_window, *x, *y, x, y);
|
||||||
meta_topic (META_DEBUG_PLACEMENT,
|
meta_topic (META_DEBUG_PLACEMENT,
|
||||||
@ -987,7 +992,7 @@ meta_window_place (MetaWindow *window,
|
|||||||
g_assert (focus_window != NULL);
|
g_assert (focus_window != NULL);
|
||||||
|
|
||||||
/* No need to do anything if the window doesn't overlap at all */
|
/* No need to do anything if the window doesn't overlap at all */
|
||||||
found_fit = !window_overlaps_focus_window (window);
|
found_fit = !window_overlaps_focus_window (window, x, y);
|
||||||
|
|
||||||
/* Try to do a first fit again, this time only taking into account the
|
/* Try to do a first fit again, this time only taking into account the
|
||||||
* focus window.
|
* focus window.
|
||||||
|
@ -2284,8 +2284,8 @@ meta_window_show (MetaWindow *window)
|
|||||||
if (focus_window &&
|
if (focus_window &&
|
||||||
window->showing_for_first_time &&
|
window->showing_for_first_time &&
|
||||||
!meta_window_is_ancestor_of_transient (focus_window, window) &&
|
!meta_window_is_ancestor_of_transient (focus_window, window) &&
|
||||||
((!place_on_top_on_map && !takes_focus_on_map) ||
|
!place_on_top_on_map &&
|
||||||
window_would_be_covered_by_always_above_window (window)))
|
!takes_focus_on_map)
|
||||||
{
|
{
|
||||||
needs_stacking_adjustment = TRUE;
|
needs_stacking_adjustment = TRUE;
|
||||||
if (!window->placed)
|
if (!window->placed)
|
||||||
@ -2316,6 +2316,12 @@ meta_window_show (MetaWindow *window)
|
|||||||
meta_window_force_placement (window, place_flags);
|
meta_window_force_placement (window, place_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (focus_window &&
|
||||||
|
window->showing_for_first_time &&
|
||||||
|
!meta_window_is_ancestor_of_transient (focus_window, window) &&
|
||||||
|
window_would_be_covered_by_always_above_window (window))
|
||||||
|
needs_stacking_adjustment = TRUE;
|
||||||
|
|
||||||
if (needs_stacking_adjustment)
|
if (needs_stacking_adjustment)
|
||||||
{
|
{
|
||||||
gboolean overlap;
|
gboolean overlap;
|
||||||
|
@ -726,6 +726,7 @@ stacking_tests = [
|
|||||||
'workspace-basic',
|
'workspace-basic',
|
||||||
'workspace-test',
|
'workspace-test',
|
||||||
'always-on-top',
|
'always-on-top',
|
||||||
|
'always-on-top-map-new-maximized',
|
||||||
'focus-default-window-globally-active-input',
|
'focus-default-window-globally-active-input',
|
||||||
'workspace-unmanaging-window',
|
'workspace-unmanaging-window',
|
||||||
'click-to-focus-and-raise',
|
'click-to-focus-and-raise',
|
||||||
@ -739,7 +740,8 @@ stacking_tests = [
|
|||||||
'sticky',
|
'sticky',
|
||||||
'sticky-modals',
|
'sticky-modals',
|
||||||
'sticky-transients',
|
'sticky-transients',
|
||||||
'strut-monitor-changes'
|
'strut-monitor-changes',
|
||||||
|
'window-placement',
|
||||||
]
|
]
|
||||||
|
|
||||||
foreach stacking_test: stacking_tests
|
foreach stacking_test: stacking_tests
|
||||||
|
20
src/tests/stacking/always-on-top-map-new-maximized.metatest
Normal file
20
src/tests/stacking/always-on-top-map-new-maximized.metatest
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
resize_monitor default 400 400
|
||||||
|
|
||||||
|
new_client w wayland
|
||||||
|
create w/1 csd
|
||||||
|
resize w/1 350 350
|
||||||
|
show w/1
|
||||||
|
move w/1 25 25
|
||||||
|
make_above w/1 true
|
||||||
|
|
||||||
|
assert_focused w/1
|
||||||
|
assert_stacking w/1
|
||||||
|
|
||||||
|
# Map a maximized window; it should not gain focus due to being mostly covered.
|
||||||
|
|
||||||
|
create w/2 csd
|
||||||
|
maximize w/2
|
||||||
|
show w/2
|
||||||
|
|
||||||
|
assert_focused w/1
|
||||||
|
assert_stacking w/2 w/1
|
84
src/tests/stacking/window-placement.metatest
Normal file
84
src/tests/stacking/window-placement.metatest
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
new_client w wayland
|
||||||
|
resize_monitor default 250 250
|
||||||
|
set_pref center-new-windows false
|
||||||
|
|
||||||
|
# Show 4 windows in a row and assert that they are placed in a grid and focused
|
||||||
|
# correctly.
|
||||||
|
|
||||||
|
create w/1 csd
|
||||||
|
resize w/1 100 100
|
||||||
|
show w/1
|
||||||
|
|
||||||
|
assert_focused w/1
|
||||||
|
assert_position w/1 24 16
|
||||||
|
assert_size w/1 100 100
|
||||||
|
|
||||||
|
create w/2 csd
|
||||||
|
resize w/2 100 100
|
||||||
|
show w/2
|
||||||
|
|
||||||
|
assert_focused w/2
|
||||||
|
assert_position w/2 24 116
|
||||||
|
assert_size w/2 100 100
|
||||||
|
|
||||||
|
create w/3 csd
|
||||||
|
resize w/3 100 100
|
||||||
|
show w/3
|
||||||
|
|
||||||
|
assert_focused w/3
|
||||||
|
assert_position w/3 124 16
|
||||||
|
assert_size w/3 100 100
|
||||||
|
|
||||||
|
create w/4 csd
|
||||||
|
resize w/4 100 100
|
||||||
|
show w/4
|
||||||
|
|
||||||
|
assert_focused w/4
|
||||||
|
assert_position w/4 124 116
|
||||||
|
assert_size w/4 100 100
|
||||||
|
|
||||||
|
destroy w/1
|
||||||
|
destroy w/2
|
||||||
|
destroy w/3
|
||||||
|
destroy w/4
|
||||||
|
wait
|
||||||
|
|
||||||
|
assert_stacking
|
||||||
|
|
||||||
|
|
||||||
|
# Show 1 window, make it 'always-on-top' and make sure the following windows
|
||||||
|
# still get placed and focused correctly.
|
||||||
|
|
||||||
|
create w/1 csd
|
||||||
|
resize w/1 100 100
|
||||||
|
show w/1
|
||||||
|
|
||||||
|
assert_focused w/1
|
||||||
|
assert_position w/1 24 16
|
||||||
|
assert_size w/1 100 100
|
||||||
|
|
||||||
|
make_above w/1 true
|
||||||
|
|
||||||
|
create w/2 csd
|
||||||
|
resize w/2 100 100
|
||||||
|
show w/2
|
||||||
|
|
||||||
|
assert_focused w/2
|
||||||
|
assert_position w/2 24 116
|
||||||
|
assert_size w/2 100 100
|
||||||
|
|
||||||
|
create w/3 csd
|
||||||
|
resize w/3 100 100
|
||||||
|
show w/3
|
||||||
|
|
||||||
|
assert_focused w/3
|
||||||
|
assert_position w/3 124 16
|
||||||
|
assert_size w/3 100 100
|
||||||
|
|
||||||
|
create w/4 csd
|
||||||
|
resize w/4 100 100
|
||||||
|
show w/4
|
||||||
|
|
||||||
|
assert_focused w/4
|
||||||
|
assert_position w/4 124 116
|
||||||
|
assert_size w/4 100 100
|
Loading…
x
Reference in New Issue
Block a user