diff --git a/src/core/place.c b/src/core/place.c index feb5c4cbf..01b0bd34d 100644 --- a/src/core/place.c +++ b/src/core/place.c @@ -353,7 +353,9 @@ find_most_freespace (MetaWindow *window, } static gboolean -window_overlaps_focus_window (MetaWindow *window) +window_overlaps_focus_window (MetaWindow *window, + int new_x, + int new_y) { MetaWindow *focus_window; MtkRectangle window_frame, focus_frame, overlap; @@ -363,6 +365,9 @@ window_overlaps_focus_window (MetaWindow *window) return FALSE; 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); return mtk_rectangle_intersect (&window_frame, @@ -414,7 +419,7 @@ avoid_being_obscured_as_second_modal_dialog (MetaWindow *window, #ifdef HAVE_X11_CLIENT meta_window_x11_same_application (window, focus_window) && #endif - window_overlaps_focus_window (window)) + window_overlaps_focus_window (window, *x, *y)) { find_most_freespace (window, focus_window, *x, *y, x, y); meta_topic (META_DEBUG_PLACEMENT, @@ -987,7 +992,7 @@ meta_window_place (MetaWindow *window, g_assert (focus_window != NULL); /* 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 * focus window. diff --git a/src/core/window.c b/src/core/window.c index 3c690fa36..d6e8406be 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -2284,8 +2284,8 @@ meta_window_show (MetaWindow *window) if (focus_window && window->showing_for_first_time && !meta_window_is_ancestor_of_transient (focus_window, window) && - ((!place_on_top_on_map && !takes_focus_on_map) || - window_would_be_covered_by_always_above_window (window))) + !place_on_top_on_map && + !takes_focus_on_map) { needs_stacking_adjustment = TRUE; if (!window->placed) @@ -2316,6 +2316,12 @@ meta_window_show (MetaWindow *window) 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) { gboolean overlap; diff --git a/src/tests/meson.build b/src/tests/meson.build index 1194cb006..6b5048490 100644 --- a/src/tests/meson.build +++ b/src/tests/meson.build @@ -726,6 +726,7 @@ stacking_tests = [ 'workspace-basic', 'workspace-test', 'always-on-top', + 'always-on-top-map-new-maximized', 'focus-default-window-globally-active-input', 'workspace-unmanaging-window', 'click-to-focus-and-raise', @@ -739,7 +740,8 @@ stacking_tests = [ 'sticky', 'sticky-modals', 'sticky-transients', - 'strut-monitor-changes' + 'strut-monitor-changes', + 'window-placement', ] foreach stacking_test: stacking_tests diff --git a/src/tests/stacking/always-on-top-map-new-maximized.metatest b/src/tests/stacking/always-on-top-map-new-maximized.metatest new file mode 100644 index 000000000..f93307082 --- /dev/null +++ b/src/tests/stacking/always-on-top-map-new-maximized.metatest @@ -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 diff --git a/src/tests/stacking/window-placement.metatest b/src/tests/stacking/window-placement.metatest new file mode 100644 index 000000000..00634a31a --- /dev/null +++ b/src/tests/stacking/window-placement.metatest @@ -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