mate-desktop / mate-screensaver

MATE screen saver and locker
https://mate-desktop.org
GNU General Public License v2.0
48 stars 40 forks source link

Bug fix: screensaver and lock screen not correctly displayed in configurations with overlapping monitor geometries #120

Closed fuzaburo closed 7 years ago

fuzaburo commented 7 years ago

This fixes a regression introduced in commit 5d4416aa5853de486e62ca97207ee1da4b35b199 which causes screensaver windows to be displayed incorrectly in multi-monitor configurations where monitor geometries overlap (especially for mirrored monitor geometries, window geometries are calculated to zero).

Arnaudddd commented 7 years ago

This commit fixes my problem with cloned monitors and screensaver unlock. It would be nice if it is merged. Thanks a lot :)

joakim-tjernlund commented 7 years ago

I find this else strange:


@@ -343,7 +346,13 @@ get_outside_region (GSWindow *window)
 rectangle.width = geometry.width;
 rectangle.height = geometry.height;
 cairo_region_union_rectangle (region, &rectangle);
+#if GTK_CHECK_VERSION (3, 22, 0)
 }
+ else
+ {
+ break;
+ }
+#endif
 }
joakim-tjernlund commented 7 years ago

For more info see: https://github.com/mate-desktop/mate-screensaver/issues/126

XRevan86 commented 7 years ago

@joakim-tjernlund, the idea of this else is to stop after the current monitor is found.

joakim-tjernlund commented 7 years ago

But what is the purpose of cairo_region_union_rectangle (region, &rectangle) then? Seems like this function is called a bit random depending on if the current monitor is first or last in the list of monitors. I suspect the current code only works well for 2 monitors.

XRevan86 commented 7 years ago

@joakim-tjernlund, the previous behaviour (before I changed it) was to only count monitors before the current one, it was restored. I'm not sure why monitors after should not be counted… really weird stuff.

fuzaburo commented 7 years ago

To understand this, note that mate-screensaver creates a separate screensaver window for each monitor, each window exactly filling the corresponding monitor at first. This is no problem if all monitors show separate regions of the screen (e.g. when screens are positioned next to each other). When the monitor regions overlap, i.e. some screen regions are replicated on several monitors, this leads to overlapping windows so it can happen that some of the lock-screen controls on one monitor are covered by the screensaver window of another monitor.

The procedure in update_geometry using get_outside_region is a sort of hack used to resize the screensaver windows (make them smaller) so the regions where windows overlap are reduced. This works for most common monitor configurations, such as in the cloned case where 2 monitors show the same content. Then, one of the screensaver windows is shrunk to zero size making it invisible and only one window remains visible. However, for some strangely overlapping monitor configurations as X allows them, it is not possible to complete eliminate the overlapping windows by this method. But in any case, all monitors should be covered by at least a single window, so nothing of the desktop should be visible.

With this information it is possible to verify the "correctness" of the else-clause (respectively of the "<" for older GTK versions) in the for-loop in get_outside_region as it is implemented now. The ordering of the monitors is somewhat arbitrary but is only relevant for overlapping monitor configurations, where it determines which screensaver window covers an overlapping (replicated) region.