[gnome-flashback] desktop: handle workarea changes



commit 2defdb7f5be2cd82ce0b5d246ebc5edc7290f6e8
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Tue Nov 12 19:38:17 2019 +0200

    desktop: handle workarea changes
    
    GTK does not automatically update workarea when it changes!

 gnome-flashback/libdesktop/gf-icon-view.c    | 91 +++++++++++++++++++++++-----
 gnome-flashback/libdesktop/gf-monitor-view.c | 47 +++++---------
 gnome-flashback/libdesktop/gf-monitor-view.h |  4 ++
 3 files changed, 96 insertions(+), 46 deletions(-)
---
diff --git a/gnome-flashback/libdesktop/gf-icon-view.c b/gnome-flashback/libdesktop/gf-icon-view.c
index f9f8444..9abc9b3 100644
--- a/gnome-flashback/libdesktop/gf-icon-view.c
+++ b/gnome-flashback/libdesktop/gf-icon-view.c
@@ -18,6 +18,7 @@
 #include "config.h"
 #include "gf-icon-view.h"
 
+#include <gdk/gdkx.h>
 #include <glib/gi18n.h>
 
 #include "gf-desktop-enum-types.h"
@@ -798,20 +799,29 @@ find_monitor_view_by_monitor (GfIconView *self,
 }
 
 static void
-workarea_cb (GdkMonitor *monitor,
-             GParamSpec *pspec,
-             GfIconView *self)
+workarea_changed (GfIconView *self)
 {
-  GtkWidget *view;
-  GdkRectangle workarea;
+  GList *children;
+  GList *l;
 
-  view = find_monitor_view_by_monitor (self, monitor);
-  if (view == NULL)
-    return;
+  children = gtk_container_get_children (GTK_CONTAINER (self->fixed));
 
-  gdk_monitor_get_workarea (monitor, &workarea);
+  for (l = children; l != NULL; l = l->next)
+    {
+      GfMonitorView *view;
+      GdkMonitor *monitor;
+      GdkRectangle workarea;
+
+      view = GF_MONITOR_VIEW (l->data);
+
+      monitor = gf_monitor_view_get_monitor (view);
+      gdk_monitor_get_workarea (monitor, &workarea);
 
-  gtk_fixed_move (GTK_FIXED (self->fixed), view, workarea.x, workarea.y);
+      gf_monitor_view_set_size (view, workarea.width, workarea.height);
+      gtk_fixed_move (GTK_FIXED (self->fixed), l->data, workarea.x, workarea.y);
+    }
+
+  g_list_free (children);
 }
 
 static void
@@ -838,6 +848,10 @@ create_monitor_view (GfIconView *self,
                               column_spacing,
                               row_spacing);
 
+  gf_monitor_view_set_size (GF_MONITOR_VIEW (view),
+                            workarea.width,
+                            workarea.height);
+
   g_signal_connect (view, "size-changed", G_CALLBACK (size_changed_cb), self);
 
   gtk_fixed_put (GTK_FIXED (self->fixed), view, workarea.x, workarea.y);
@@ -858,10 +872,6 @@ create_monitor_view (GfIconView *self,
   g_settings_bind (self->settings, "row-spacing",
                    view, "row-spacing",
                    G_SETTINGS_BIND_GET);
-
-  g_signal_connect_object (monitor, "notify::workarea",
-                           G_CALLBACK (workarea_cb),
-                           self, 0);
 }
 
 static void
@@ -886,6 +896,55 @@ monitor_removed_cb (GdkDisplay *display,
   gtk_widget_destroy (view);
 }
 
+static GdkFilterReturn
+filter_func (GdkXEvent *xevent,
+             GdkEvent  *event,
+             gpointer   user_data)
+{
+  XEvent *x;
+  GdkAtom atom;
+
+  x = (XEvent *) xevent;
+
+  if (x->type != PropertyNotify)
+    return GDK_FILTER_CONTINUE;
+
+  atom = gdk_atom_intern_static_string ("_NET_WORKAREA");
+  if (x->xproperty.atom == gdk_x11_atom_to_xatom (atom))
+    workarea_changed (GF_ICON_VIEW (user_data));
+
+  return GDK_FILTER_CONTINUE;
+}
+
+static void
+remove_event_filter (GfIconView *self)
+{
+  GdkScreen *screen;
+  GdkWindow *root;
+
+  screen = gtk_widget_get_screen (GTK_WIDGET (self));
+  root = gdk_screen_get_root_window (screen);
+
+  gdk_window_remove_filter (root, filter_func, self);
+}
+
+static void
+add_event_filter (GfIconView *self)
+{
+  GdkScreen *screen;
+  GdkWindow *root;
+  GdkEventMask event_mask;
+
+  screen = gtk_widget_get_screen (GTK_WIDGET (self));
+  root = gdk_screen_get_root_window (screen);
+
+  event_mask = gdk_window_get_events (root);
+  event_mask |= GDK_PROPERTY_NOTIFY;
+
+  gdk_window_add_filter (root, filter_func, self);
+  gdk_window_set_events (root, event_mask);
+}
+
 static void
 gf_icon_view_dispose (GObject *object)
 {
@@ -930,6 +989,8 @@ gf_icon_view_finalize (GObject *object)
       self->add_icons_id = 0;
     }
 
+  remove_event_filter (self);
+
   G_OBJECT_CLASS (gf_icon_view_parent_class)->finalize (object);
 }
 
@@ -1011,6 +1072,8 @@ gf_icon_view_init (GfIconView *self)
   int n_monitors;
   int i;
 
+  add_event_filter (self);
+
   self->multi_press = gtk_gesture_multi_press_new (GTK_WIDGET (self));
   self->drag = gtk_gesture_drag_new (GTK_WIDGET (self));
 
diff --git a/gnome-flashback/libdesktop/gf-monitor-view.c b/gnome-flashback/libdesktop/gf-monitor-view.c
index f2d8513..b104da8 100644
--- a/gnome-flashback/libdesktop/gf-monitor-view.c
+++ b/gnome-flashback/libdesktop/gf-monitor-view.c
@@ -332,37 +332,6 @@ set_row_spacing (GfMonitorView *self,
   recalculate_grid_size (self);
 }
 
-static void
-workarea_cb (GdkMonitor    *monitor,
-             GParamSpec    *pspec,
-             GfMonitorView *self)
-{
-  GdkRectangle workarea;
-
-  gdk_monitor_get_workarea (monitor, &workarea);
-
-  self->view_width = workarea.width;
-  self->view_height = workarea.height;
-
-  recalculate_grid_size (self);
-}
-
-static void
-gf_monitor_view_constructed (GObject *object)
-{
-  GfMonitorView *self;
-
-  self = GF_MONITOR_VIEW (object);
-
-  G_OBJECT_CLASS (gf_monitor_view_parent_class)->constructed (object);
-
-  g_signal_connect_object (self->monitor, "notify::workarea",
-                           G_CALLBACK (workarea_cb),
-                           self, 0);
-
-  workarea_cb (self->monitor, NULL, self);
-}
-
 static void
 gf_monitor_view_dispose (GObject *object)
 {
@@ -620,7 +589,6 @@ gf_monitor_view_class_init (GfMonitorViewClass *self_class)
   object_class = G_OBJECT_CLASS (self_class);
   widget_class = GTK_WIDGET_CLASS (self_class);
 
-  object_class->constructed = gf_monitor_view_constructed;
   object_class->dispose = gf_monitor_view_dispose;
   object_class->finalize = gf_monitor_view_finalize;
   object_class->get_property = gf_monitor_view_get_property;
@@ -656,6 +624,21 @@ gf_monitor_view_new (GdkMonitor *monitor,
                        NULL);
 }
 
+void
+gf_monitor_view_set_size (GfMonitorView *self,
+                          int            width,
+                          int            height)
+{
+  if (self->view_width == width &&
+      self->view_height == height)
+    return;
+
+  self->view_width = width;
+  self->view_height = height;
+
+  recalculate_grid_size (self);
+}
+
 GdkMonitor *
 gf_monitor_view_get_monitor (GfMonitorView *self)
 {
diff --git a/gnome-flashback/libdesktop/gf-monitor-view.h b/gnome-flashback/libdesktop/gf-monitor-view.h
index f52b654..afc676b 100644
--- a/gnome-flashback/libdesktop/gf-monitor-view.h
+++ b/gnome-flashback/libdesktop/gf-monitor-view.h
@@ -32,6 +32,10 @@ GtkWidget  *gf_monitor_view_new         (GdkMonitor    *monitor,
                                          guint          column_spacing,
                                          guint          row_spacing);
 
+void        gf_monitor_view_set_size    (GfMonitorView *self,
+                                         int            width,
+                                         int            height);
+
 GdkMonitor *gf_monitor_view_get_monitor (GfMonitorView *self);
 
 gboolean    gf_monitor_view_is_primary  (GfMonitorView *self);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]