Skip to content

Commit 06633ca

Browse files
committed
window.c: Improve the test for checking if an 'above' window may
cover a new window. This check occurs prior to placement (and plays a part in how placement is calculated), but prior to placing the window, its position and monitor aren't up-to-date. There are still a number of things we can check, however, and it's better to be accurate on what we do check rather than reporting false positives.
1 parent cd5ed89 commit 06633ca

File tree

1 file changed

+41
-7
lines changed

1 file changed

+41
-7
lines changed

src/core/window.c

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2390,12 +2390,16 @@ windows_overlap (const MetaWindow *w1, const MetaWindow *w2)
23902390
* (say) ninety per cent and almost indistinguishable from total.
23912391
*/
23922392
static 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

24222456
void
@@ -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

Comments
 (0)