[Xfce4-commits] [apps/xfce4-screensaver] 01/01: Better handling of multi-monitor add/remove and lid-close events

noreply at xfce.org noreply at xfce.org
Fri Jan 24 04:23:46 CET 2020


This is an automated email from the git hooks/post-receive script.

b   l   u   e   s   a   b   r   e       p   u   s   h   e   d       a       c   o   m   m   i   t       t   o       b   r   a   n   c   h       m   a   s   t   e   r   
   in repository apps/xfce4-screensaver.

commit c44e54350c786497b3bf3835e079d39c39a4951e
Author: Sean Davis <smd.seandavis at gmail.com>
Date:   Thu Jan 23 22:21:43 2020 -0500

    Better handling of multi-monitor add/remove and lid-close events
---
 src/gs-manager.c    | 114 +++++++++++++++++++++++++++++++++++++++++++---------
 src/gs-window-x11.c |   6 +++
 src/gs-window.h     |   1 +
 3 files changed, 103 insertions(+), 18 deletions(-)

diff --git a/src/gs-manager.c b/src/gs-manager.c
index 6c42b78..0eb2ef3 100644
--- a/src/gs-manager.c
+++ b/src/gs-manager.c
@@ -91,18 +91,53 @@ G_DEFINE_TYPE_WITH_PRIVATE (GSManager, gs_manager, G_TYPE_OBJECT)
 static void         remove_deepsleep_idle   (GSManager *manager);
 static gboolean     deepsleep_idle          (GSManager *manager);
 static void         add_deepsleep_idle      (GSManager *manager);
+static void
+gs_manager_create_windows_for_display       (GSManager  *manager,
+                                             GdkDisplay *display);
+
+static gboolean
+gs_manager_is_real_monitor (GdkMonitor *monitor) {
+    // avoiding some weird gdk bug
+    // federico> avb: or if you don't care about a little unexplained messiness,
+    //                just discard monitors where both fields are null? :)
+    if (gdk_monitor_get_manufacturer(monitor) == NULL && gdk_monitor_get_model(monitor) == NULL)
+        return FALSE;
+    return TRUE;
+}
+
+static int
+gs_manager_get_n_monitors (GdkDisplay *display) {
+    // Since gdk_display_get_n_monitors return wrong monitor count
+    // this is a workaround for the problem
+    int n_monitors;
+    int i, count = 0;
+
+    n_monitors = gdk_display_get_n_monitors (display);
+    for (i = 0; i < n_monitors; i++) {
+        GdkMonitor *monitor = gdk_display_get_monitor(display, i);
+        if (gs_manager_is_real_monitor (monitor))
+            count++;
+    }
+    return count;
+}
 
 static gint
 manager_get_monitor_index (GdkMonitor *this_monitor) {
-    GdkDisplay *display = gdk_monitor_get_display (this_monitor);
+    GdkDisplay *display;
     gint        idx;
 
+    if (!gs_manager_is_real_monitor (this_monitor))
+        return -1;
+
+    display = gdk_monitor_get_display (this_monitor);
+
     for (idx = 0; idx < gdk_display_get_n_monitors (display); idx++) {
         GdkMonitor *monitor = gdk_display_get_monitor (display, idx);
         if (monitor == this_monitor)
             return idx;
     }
-    return 0;
+
+    return -1;
 }
 
 static void
@@ -598,7 +633,7 @@ find_window_at_pointer (GSManager *manager) {
     GdkDevice  *device;
     GdkMonitor *monitor;
     int         x, y;
-    GSList     *window;
+    GSList     *window = NULL;
 
     display = gdk_display_get_default ();
 
@@ -607,7 +642,9 @@ find_window_at_pointer (GSManager *manager) {
     monitor = gdk_display_get_monitor_at_point (display, x, y);
 
     /* Find the gs-window that is on that monitor */
-    window = g_slist_nth (manager->priv->windows, manager_get_monitor_index (monitor));
+    if (gs_manager_is_real_monitor (monitor))
+        window = g_slist_nth (manager->priv->windows, manager_get_monitor_index (monitor));
+
     if (window == NULL) {
         gs_debug ("WARNING: Could not find the GSWindow for display %s",
                   gdk_display_get_name (display));
@@ -940,6 +977,9 @@ gs_manager_create_window_for_monitor (GSManager  *manager,
     GSWindow    *window;
     GdkRectangle rect;
 
+    if (!gs_manager_is_real_monitor (monitor))
+        return;
+
     if (g_slist_nth (manager->priv->windows, manager_get_monitor_index(monitor))) {
         gs_debug ("Found already created window for Monitor %d", manager_get_monitor_index(monitor));
         return;
@@ -963,27 +1003,58 @@ gs_manager_create_window_for_monitor (GSManager  *manager,
 }
 
 static void
+reconfigure_monitors (GdkDisplay *display,
+                      GSManager  *manager) {
+    GSList     *l;
+    int         n_monitors;
+
+    n_monitors = gs_manager_get_n_monitors (display);
+
+    if (n_monitors == 0)
+        return;
+
+    /* Remove lost windows */
+    l = manager->priv->windows;
+    while (l != NULL) {
+        GdkMonitor *this_monitor;
+        int         idx;
+        GSList     *next = l->next;
+
+        this_monitor = gs_window_get_monitor (GS_WINDOW (l->data));
+
+        idx = manager_get_monitor_index (this_monitor);
+        if (idx < 0) {
+            manager_maybe_stop_job_for_window (manager, GS_WINDOW (l->data));
+            g_hash_table_remove (manager->priv->jobs, l->data);
+            gs_window_destroy (GS_WINDOW (l->data));
+            manager->priv->windows = g_slist_delete_link (manager->priv->windows, l);
+        } else {
+            gs_window_reposition (GS_WINDOW (l->data));
+        }
+
+        l = next;
+    }
+
+    gs_manager_create_windows_for_display (manager, display);
+
+    gs_manager_request_unlock (manager);
+}
+
+static void
 on_display_monitor_added (GdkDisplay *display,
                           GdkMonitor *monitor,
                           GSManager  *manager) {
-    GSList     *l;
     int         n_monitors;
 
-    n_monitors = gdk_display_get_n_monitors (display);
+    n_monitors = gs_manager_get_n_monitors (display);
 
     gs_debug ("Monitor %s added on display %s, now there are %d",
               gdk_monitor_get_model(monitor), gdk_display_get_name (display), n_monitors);
 
-    l = g_slist_nth (manager->priv->windows, manager_get_monitor_index (monitor));
-    if (l) {
-        gs_debug ("Found window for this Monitor");
-        gs_window_set_monitor (GS_WINDOW (l->data), monitor);
-    } else {
-        gs_debug("Creating new window for Monitor %s", gdk_monitor_get_model (monitor));
-        gs_manager_create_window_for_monitor(manager, monitor);
-        l = g_slist_nth (manager->priv->windows, manager_get_monitor_index (monitor));
-    }
-    gs_window_request_unlock (l->data);
+    if (!gs_manager_is_real_monitor (monitor))
+        return;
+
+    reconfigure_monitors (display, manager);
 }
 
 static void
@@ -992,10 +1063,12 @@ on_display_monitor_removed (GdkDisplay *display,
                             GSManager  *manager) {
     int         n_monitors;
 
-    n_monitors = gdk_display_get_n_monitors (display);
+    n_monitors = gs_manager_get_n_monitors (display);
 
     gs_debug ("Monitor %p removed on display %s, now there are %d",
               monitor, gdk_display_get_name (display), n_monitors);
+
+    reconfigure_monitors (display, manager);
 }
 
 static void
@@ -1218,12 +1291,17 @@ gs_manager_request_unlock (GSManager *manager) {
     }
 
     if (manager->priv->windows == NULL) {
-        gs_debug ("We don't have any windows!");
+        gs_debug ("Request unlock but we don't have any windows!");
         return FALSE;
     }
 
     /* Find the GSWindow that contains the pointer */
     window = find_window_at_pointer (manager);
+    if (window == NULL) {
+        gs_debug ("Request unlock but no window could be found!");
+        return FALSE;
+    }
+
     gs_window_request_unlock (window);
 
     return TRUE;
diff --git a/src/gs-window-x11.c b/src/gs-window-x11.c
index 81bb74b..8ef16e1 100644
--- a/src/gs-window-x11.c
+++ b/src/gs-window-x11.c
@@ -1894,6 +1894,12 @@ gs_window_real_get_preferred_height (GtkWidget *widget,
     *minimal_height = *natural_height = requisition.height;
 }
 
+void
+gs_window_reposition (GSWindow *window) {
+    GtkRequisition requisition;
+    gs_window_real_size_request (GTK_WIDGET (window), &requisition);
+}
+
 static gboolean
 gs_window_real_grab_broken (GtkWidget          *widget,
                             GdkEventGrabBroken *event) {
diff --git a/src/gs-window.h b/src/gs-window.h
index d74cd65..156ee66 100644
--- a/src/gs-window.h
+++ b/src/gs-window.h
@@ -83,6 +83,7 @@ void        gs_window_destroy                 (GSWindow        *window);
 GdkWindow * gs_window_get_gdk_window          (GSWindow        *window);
 GtkWidget * gs_window_get_drawing_area        (GSWindow        *window);
 void        gs_window_clear                   (GSWindow        *window);
+void        gs_window_reposition              (GSWindow        *window);
 
 G_END_DECLS
 

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Xfce4-commits mailing list