@@ -2390,12 +2390,16 @@ windows_overlap (const MetaWindow *w1, const MetaWindow *w2)
23902390 * (say) ninety per cent and almost indistinguishable from total.
23912391 */
23922392static gboolean
2393- window_would_be_covered (const MetaWindow * newbie )
2393+ window_may_be_covered_by_above (const MetaWindow * newbie )
23942394{
2395+ MetaBackend * backend = meta_get_backend ();
2396+ MetaLogicalMonitor * monitor ;
23952397 MetaWorkspace * workspace = meta_window_get_workspace ((MetaWindow * )newbie );
23962398 GList * tmp , * windows ;
23972399
2400+ monitor = meta_backend_get_current_logical_monitor (backend );
23982401 windows = meta_workspace_list_windows (workspace );
2402+ gboolean overlaps = FALSE;
23992403
24002404 tmp = windows ;
24012405 while (tmp != NULL )
@@ -2404,19 +2408,49 @@ window_would_be_covered (const MetaWindow *newbie)
24042408
24052409 if (w -> wm_state_above && w != newbie )
24062410 {
2407- /* We have found a window that is "above". Perhaps it overlaps. */
2408- if (windows_overlap (w , newbie ))
2411+ /* We have found a window that is "above". Do some tests. This is run before
2412+ * newbie is actually placed, so its position and monitor are not yet accurate,
2413+ * but it's not feasible to do it after either (because then it's too late). These
2414+ * tests can eliminate a lot of silly false positives, however. */
2415+
2416+ // Minimized - no overlap
2417+ if (w -> minimized )
2418+ {
2419+ tmp = tmp -> next ;
2420+ continue ;
2421+ }
2422+
2423+ // Maximized, same monitor, overlap.
2424+ if (w -> monitor -> number == monitor -> number && meta_window_get_maximized (w ))
2425+ {
2426+ overlaps = TRUE;
2427+ break ;
2428+ }
2429+
2430+ MetaRectangle w_rect , w_in_area_rect , work_area ;
2431+ meta_window_get_frame_rect (w , & w_rect );
2432+ meta_workspace_get_work_area_for_monitor (workspace , monitor -> number , & work_area );
2433+
2434+ // If the above window is at least partially on the target monitor, check if the new window
2435+ // would theoretically have enough room leftover to be completely uncovered. This is no
2436+ // guarantee it *will* be uncovered, but it's the best we can do without an accurate position
2437+ // for the new window.
2438+ if (meta_rectangle_intersect (& work_area , & w_rect , & w_in_area_rect ))
24092439 {
2410- g_list_free (windows ); /* clean up... */
2411- return TRUE; /* yes, it does */
2440+ if ((newbie -> rect .width + w_in_area_rect .width > work_area .width ) &&
2441+ (newbie -> rect .height + w_in_area_rect .height > work_area .height ))
2442+ {
2443+ overlaps = TRUE;
2444+ break ;
2445+ }
24122446 }
24132447 }
24142448
24152449 tmp = tmp -> next ;
24162450 }
24172451
24182452 g_list_free (windows );
2419- return FALSE; /* none found */
2453+ return overlaps ;
24202454}
24212455
24222456void
@@ -2499,7 +2533,7 @@ meta_window_show (MetaWindow *window)
24992533
25002534 if ( focus_window != NULL && window -> showing_for_first_time &&
25012535 ( (!place_on_top_on_map && !takes_focus_on_map ) ||
2502- window_would_be_covered (window ) )
2536+ window_may_be_covered_by_above (window ) )
25032537 ) {
25042538 if (!meta_window_is_ancestor_of_transient (focus_window , window ))
25052539 {
0 commit comments