[gnome-flashback] notifications: Replace deprecated gdk screen functions



commit c2caa35ae33e9dab70cec292678cfc2b3bbd0c19
Author: Ori Avtalion <ori avtalion name>
Date:   Sat Sep 1 21:37:53 2018 +0300

    notifications: Replace deprecated gdk screen functions
    
    stacks was converted to a hash table. It's no longer possible to get a
    monitor's number, so a direct-access array can't be used.
    
    get_work_area was replaced by gdk's implementation.
    
    The monitor-added/removed signals are handled instead of monitor-changed.

 gnome-flashback/libnotifications/nd-queue.c | 238 +++++++++++++---------------
 gnome-flashback/libnotifications/nd-stack.c | 122 +-------------
 gnome-flashback/libnotifications/nd-stack.h |   3 +-
 3 files changed, 117 insertions(+), 246 deletions(-)
---
diff --git a/gnome-flashback/libnotifications/nd-queue.c b/gnome-flashback/libnotifications/nd-queue.c
index 9531ada..8ebe212 100644
--- a/gnome-flashback/libnotifications/nd-queue.c
+++ b/gnome-flashback/libnotifications/nd-queue.c
@@ -36,8 +36,7 @@
 
 typedef struct
 {
-        NdStack   **stacks;
-        int         n_stacks;
+        GHashTable *stacks;
         Atom        workarea_atom;
 } NotifyScreen;
 
@@ -76,94 +75,100 @@ G_DEFINE_TYPE_WITH_PRIVATE (NdQueue, nd_queue, G_TYPE_OBJECT)
 
 static void
 create_stack_for_monitor (NdQueue    *queue,
-                          GdkScreen  *screen,
-                          int         monitor_num)
+                          GdkMonitor *monitor)
 {
         NotifyScreen *nscreen;
+        NdStack      *stack;
 
         nscreen = queue->priv->screen;
+        stack = nd_stack_new (monitor);
 
-        nscreen->stacks[monitor_num] = nd_stack_new (screen,
-                                                     monitor_num);
+        g_hash_table_insert (nscreen->stacks, monitor, stack);
 }
 
-static void
-on_screen_monitors_changed (GdkScreen *screen,
-                            NdQueue   *queue)
+static NdStack *
+get_stack_with_pointer (NdQueue *queue)
 {
-        NotifyScreen *nscreen;
-        int           n_monitors;
-        int           i;
+        GdkDisplay *display;
+        GdkSeat    *seat;
+        GdkDevice  *pointer;
+        GdkMonitor *monitor;
+        int         x, y;
 
-        nscreen = queue->priv->screen;
+        display = gdk_display_get_default ();
+        seat = gdk_display_get_default_seat (display);
+        pointer = gdk_seat_get_pointer (seat);
 
-        n_monitors = gdk_screen_get_n_monitors (screen);
+        gdk_device_get_position (pointer, NULL, &x, &y);
+        monitor = gdk_display_get_monitor_at_point (display, x, y);
 
-        if (n_monitors > nscreen->n_stacks) {
-                /* grow */
-                nscreen->stacks = g_renew (NdStack *,
-                                           nscreen->stacks,
-                                           n_monitors);
+        return g_hash_table_lookup (queue->priv->screen->stacks, monitor);
+}
 
-                /* add more stacks */
-                for (i = nscreen->n_stacks; i < n_monitors; i++) {
-                        create_stack_for_monitor (queue, screen, i);
-                }
+static void
+monitor_added_cb (GdkDisplay *display,
+                  GdkMonitor *monitor,
+                  NdQueue    *queue)
+{
+        create_stack_for_monitor (queue, monitor);
+}
 
-                nscreen->n_stacks = n_monitors;
-        } else if (n_monitors < nscreen->n_stacks) {
-                NdStack *last_stack;
-
-                last_stack = nscreen->stacks[n_monitors - 1];
-
-                /* transfer items before removing stacks */
-                for (i = n_monitors; i < nscreen->n_stacks; i++) {
-                        NdStack     *stack;
-                        GList       *bubbles;
-                        GList       *l;
-
-                        stack = nscreen->stacks[i];
-                        bubbles = g_list_copy (nd_stack_get_bubbles (stack));
-                        for (l = bubbles; l != NULL; l = l->next) {
-                                /* skip removing the bubble from the
-                                   old stack since it will try to
-                                   unrealize the window.  And the
-                                   stack is going away anyhow. */
-                                nd_stack_add_bubble (last_stack, l->data, TRUE);
-                        }
-                        g_list_free (bubbles);
-                        g_object_unref (stack);
-                        nscreen->stacks[i] = NULL;
-                }
+static void
+monitor_removed_cb (GdkDisplay *display,
+                    GdkMonitor *monitor,
+                    NdQueue    *queue)
+{
+        NotifyScreen *nscreen;
+        NdStack      *stack;
+        NdStack      *focused_stack;
+        GList        *bubbles;
+        GList        *l;
 
-                /* remove the extra stacks */
-                nscreen->stacks = g_renew (NdStack *,
-                                           nscreen->stacks,
-                                           n_monitors);
-                nscreen->n_stacks = n_monitors;
+        /* transfer items before removing stack */
+
+        nscreen = queue->priv->screen;
+        stack = g_hash_table_lookup (nscreen->stacks, monitor);
+        focused_stack = get_stack_with_pointer (queue);
+
+        bubbles = g_list_copy (nd_stack_get_bubbles (stack));
+        for (l = bubbles; l != NULL; l = l->next) {
+                /* skip removing the bubble from the
+                   old stack since it will try to
+                   unrealize the window.  And the
+                   stack is going away anyhow. */
+                nd_stack_add_bubble (focused_stack, l->data, TRUE);
         }
+        g_list_free (bubbles);
+        g_hash_table_remove (nscreen->stacks, monitor);
+
+        queue_update (queue);
 }
 
 static void
-create_stacks_for_screen (NdQueue   *queue,
-                          GdkScreen *screen)
+create_stacks_for_display (NdQueue    *queue,
+                           GdkDisplay *display)
 {
-        NotifyScreen *nscreen;
+        int           n_monitors;
         int           i;
 
-        nscreen = queue->priv->screen;
-
-        nscreen->n_stacks = gdk_screen_get_n_monitors (screen);
+        n_monitors = gdk_display_get_n_monitors (display);
 
-        nscreen->stacks = g_renew (NdStack *,
-                                   nscreen->stacks,
-                                   nscreen->n_stacks);
+        for (i = 0; i < n_monitors; i++) {
+                GdkMonitor *monitor;
 
-        for (i = 0; i < nscreen->n_stacks; i++) {
-                create_stack_for_monitor (queue, screen, i);
+                monitor = gdk_display_get_monitor (display, i);
+                create_stack_for_monitor (queue, monitor);
         }
 }
 
+static void
+queue_update_position (gpointer key,
+                       gpointer value,
+                       gpointer user_data)
+{
+        nd_stack_queue_update_position ((NdStack *) value);
+}
+
 static GdkFilterReturn
 screen_xevent_filter (GdkXEvent    *xevent,
                       GdkEvent     *event,
@@ -175,11 +180,7 @@ screen_xevent_filter (GdkXEvent    *xevent,
 
         if (xev->type == PropertyNotify &&
             xev->xproperty.atom == nscreen->workarea_atom) {
-                int i;
-
-                for (i = 0; i < nscreen->n_stacks; i++) {
-                        nd_stack_queue_update_position (nscreen->stacks[i]);
-                }
+                g_hash_table_foreach (nscreen->stacks, queue_update_position, NULL);
         }
 
         return GDK_FILTER_CONTINUE;
@@ -197,19 +198,21 @@ create_screen (NdQueue *queue)
         display = gdk_display_get_default ();
         screen = gdk_display_get_default_screen (display);
 
-        g_signal_connect (screen,
-                          "monitors-changed",
-                          G_CALLBACK (on_screen_monitors_changed),
-                          queue);
+        g_signal_connect (display, "monitor-added",
+                          G_CALLBACK (monitor_added_cb), queue);
+
+        g_signal_connect (display, "monitor-removed",
+                          G_CALLBACK (monitor_removed_cb), queue);
 
         queue->priv->screen = g_new0 (NotifyScreen, 1);
         queue->priv->screen->workarea_atom = XInternAtom (GDK_DISPLAY_XDISPLAY (display), "_NET_WORKAREA", 
True);
+        queue->priv->screen->stacks = g_hash_table_new_full (NULL, NULL, NULL, g_object_unref);
 
         gdkwindow = gdk_screen_get_root_window (screen);
         gdk_window_add_filter (gdkwindow, (GdkFilterFunc) screen_xevent_filter, queue->priv->screen);
         gdk_window_set_events (gdkwindow, gdk_window_get_events (gdkwindow) | GDK_PROPERTY_CHANGE_MASK);
 
-        create_stacks_for_screen (queue, screen);
+        create_stacks_for_display (queue, display);
 }
 
 static void
@@ -319,18 +322,21 @@ on_dock_key_release (GtkWidget   *widget,
         return TRUE;
 }
 
+static void
+remove_all (gpointer key,
+            gpointer value,
+            gpointer user_data)
+{
+        nd_stack_remove_all ((NdStack *) value);
+}
+
 static void
 clear_stacks (NdQueue *queue)
 {
         NotifyScreen *nscreen;
-        gint          i;
 
         nscreen = queue->priv->screen;
-        for (i = 0; i < nscreen->n_stacks; i++) {
-                NdStack *stack;
-                stack = nscreen->stacks[i];
-                nd_stack_remove_all (stack);
-        }
+        g_hash_table_foreach (nscreen->stacks, remove_all, NULL);
 }
 
 static void
@@ -466,22 +472,22 @@ destroy_screen (NdQueue *queue)
         GdkDisplay *display;
         GdkScreen  *screen;
         GdkWindow  *gdkwindow;
-        gint        i;
 
         display = gdk_display_get_default ();
         screen = gdk_display_get_default_screen (display);
 
-        g_signal_handlers_disconnect_by_func (screen,
-                                              G_CALLBACK (on_screen_monitors_changed),
+        g_signal_handlers_disconnect_by_func (display,
+                                              G_CALLBACK (monitor_added_cb),
+                                              queue);
+
+        g_signal_handlers_disconnect_by_func (display,
+                                              G_CALLBACK (monitor_removed_cb),
                                               queue);
 
         gdkwindow = gdk_screen_get_root_window (screen);
         gdk_window_remove_filter (gdkwindow, (GdkFilterFunc) screen_xevent_filter, queue->priv->screen);
-        for (i = 0; i < queue->priv->screen->n_stacks; i++) {
-                g_clear_object (&queue->priv->screen->stacks[i]);
-        }
 
-        g_free (queue->priv->screen->stacks);
+        g_hash_table_destroy (queue->priv->screen->stacks);
         queue->priv->screen->stacks = NULL;
 
         g_free (queue->priv->screen);
@@ -537,32 +543,6 @@ nd_queue_length (NdQueue *queue)
         return g_hash_table_size (queue->priv->notifications);
 }
 
-static NdStack *
-get_stack_with_pointer (NdQueue *queue)
-{
-        GdkDisplay *display;
-        GdkSeat *seat;
-        GdkDevice *pointer;
-        GdkScreen *screen;
-        int        x, y;
-        int        monitor_num;
-
-        display = gdk_display_get_default ();
-        seat = gdk_display_get_default_seat (display);
-        pointer = gdk_seat_get_pointer (seat);
-
-        gdk_device_get_position (pointer, &screen, &x, &y);
-        monitor_num = gdk_screen_get_monitor_at_point (screen, x, y);
-
-        if (monitor_num >= queue->priv->screen->n_stacks) {
-                /* screw it - dump it on the last one we'll get
-                   a monitors-changed signal soon enough*/
-                monitor_num = queue->priv->screen->n_stacks - 1;
-        }
-
-        return queue->priv->screen->stacks[monitor_num];
-}
-
 static void
 on_bubble_destroyed (GfBubble *bubble,
                      NdQueue  *queue)
@@ -600,6 +580,11 @@ maybe_show_notification (NdQueue *queue)
         }
 
         stack = get_stack_with_pointer (queue);
+        if (stack == NULL) {
+                g_debug ("Monitor not found");
+                return;
+        }
+
         list = nd_stack_get_bubbles (stack);
         if (g_list_length (list) > 0) {
                 /* already showing bubbles */
@@ -647,7 +632,6 @@ update_dock (NdQueue *queue)
         GList       *l;
         int          min_height;
         int          height;
-        int          monitor_num;
         GdkScreen   *screen;
         GdkRectangle area;
         GtkStatusIcon *status_icon;
@@ -696,14 +680,16 @@ update_dock (NdQueue *queue)
         }
 
         if (visible) {
+                GdkMonitor *monitor;
+
                 gtk_widget_get_preferred_height (child, &min_height, &height);
 
                 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
                 gtk_status_icon_get_geometry (status_icon, &screen, &area, NULL);
                 G_GNUC_END_IGNORE_DEPRECATIONS
 
-                monitor_num = gdk_screen_get_monitor_at_point (screen, area.x, area.y);
-                gdk_screen_get_monitor_geometry (screen, monitor_num, &area);
+                monitor = gdk_display_get_monitor_at_point (gdk_screen_get_display (screen), area.x, area.y);
+                gdk_monitor_get_geometry (monitor, &area);
                 height = MIN (height, (area.height / 2));
                 gtk_widget_set_size_request (queue->priv->dock_scrolled_window,
                                              WIDTH,
@@ -731,8 +717,8 @@ popup_dock (NdQueue *queue,
         gboolean       res;
         int            x;
         int            y;
-        int            monitor_num;
-        GdkRectangle   monitor;
+        GdkMonitor    *monitor;
+        GdkRectangle   monitor_rect;
         GtkRequisition dock_req;
         GtkStatusIcon *status_icon;
         GdkWindow *window;
@@ -756,34 +742,34 @@ popup_dock (NdQueue *queue,
         /* position roughly */
         gtk_window_set_screen (GTK_WINDOW (queue->priv->dock), screen);
 
-        monitor_num = gdk_screen_get_monitor_at_point (screen, area.x, area.y);
-        gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+        monitor = gdk_display_get_monitor_at_point (gdk_screen_get_display (screen), area.x, area.y);
+        gdk_monitor_get_geometry (monitor, &monitor_rect);
 
         gtk_container_foreach (GTK_CONTAINER (queue->priv->dock),
                                show_all_cb, NULL);
         gtk_widget_get_preferred_size (queue->priv->dock, &dock_req, NULL);
 
         if (orientation == GTK_ORIENTATION_VERTICAL) {
-                if (area.x + area.width + dock_req.width <= monitor.x + monitor.width) {
+                if (area.x + area.width + dock_req.width <= monitor_rect.x + monitor_rect.width) {
                         x = area.x + area.width;
                 } else {
                         x = area.x - dock_req.width;
                 }
-                if (area.y + dock_req.height <= monitor.y + monitor.height) {
+                if (area.y + dock_req.height <= monitor_rect.y + monitor_rect.height) {
                         y = area.y;
                 } else {
-                        y = monitor.y + monitor.height - dock_req.height;
+                        y = monitor_rect.y + monitor_rect.height - dock_req.height;
                 }
         } else {
-                if (area.y + area.height + dock_req.height <= monitor.y + monitor.height) {
+                if (area.y + area.height + dock_req.height <= monitor_rect.y + monitor_rect.height) {
                         y = area.y + area.height;
                 } else {
                         y = area.y - dock_req.height;
                 }
-                if (area.x + dock_req.width <= monitor.x + monitor.width) {
+                if (area.x + dock_req.width <= monitor_rect.x + monitor_rect.width) {
                         x = area.x;
                 } else {
-                        x = monitor.x + monitor.width - dock_req.width;
+                        x = monitor_rect.x + monitor_rect.width - dock_req.width;
                 }
         }
 
diff --git a/gnome-flashback/libnotifications/nd-stack.c b/gnome-flashback/libnotifications/nd-stack.c
index bc707a0..ea50c9b 100644
--- a/gnome-flashback/libnotifications/nd-stack.c
+++ b/gnome-flashback/libnotifications/nd-stack.c
@@ -21,12 +21,6 @@
 #include <strings.h>
 #include <glib.h>
 
-#include <X11/Xproto.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xatom.h>
-#include <gdk/gdkx.h>
-
 #include "nd-stack.h"
 
 #define NOTIFY_STACK_SPACING 2
@@ -34,8 +28,7 @@
 
 struct NdStackPrivate
 {
-        GdkScreen      *screen;
-        guint           monitor;
+        GdkMonitor     *monitor;
         NdStackLocation location;
         GList          *bubbles;
         guint           update_id;
@@ -51,105 +44,6 @@ nd_stack_get_bubbles (NdStack *stack)
         return stack->priv->bubbles;
 }
 
-static int
-get_current_desktop (GdkScreen *screen)
-{
-        Display *display;
-        Window win;
-        Atom current_desktop, type;
-        int format;
-        unsigned long n_items, bytes_after;
-        unsigned char *data_return = NULL;
-        int workspace = 0;
-
-        display = GDK_DISPLAY_XDISPLAY (gdk_screen_get_display (screen));
-        win = XRootWindow (display, GDK_SCREEN_XNUMBER (screen));
-
-        current_desktop = XInternAtom (display, "_NET_CURRENT_DESKTOP", True);
-
-        XGetWindowProperty (display,
-                            win,
-                            current_desktop,
-                            0, G_MAXLONG,
-                            False, XA_CARDINAL,
-                            &type, &format, &n_items, &bytes_after,
-                            &data_return);
-
-        if (type == XA_CARDINAL && format == 32 && n_items > 0)
-                workspace = (int) data_return[0];
-        if (data_return)
-                XFree (data_return);
-
-        return workspace;
-}
-
-static gboolean
-get_work_area (NdStack      *stack,
-               GdkRectangle *rect)
-{
-        Atom            workarea;
-        Atom            type;
-        Window          win;
-        int             format;
-        gulong          num;
-        gulong          leftovers;
-        gulong          max_len = 4 * 32;
-        guchar         *ret_workarea;
-        long           *workareas;
-        int             result;
-        int             disp_screen;
-        int             desktop;
-        Display        *display;
-
-        display = GDK_DISPLAY_XDISPLAY (gdk_screen_get_display (stack->priv->screen));
-        workarea = XInternAtom (display, "_NET_WORKAREA", True);
-
-        disp_screen = GDK_SCREEN_XNUMBER (stack->priv->screen);
-
-        /* Defaults in case of error */
-        rect->x = 0;
-        rect->y = 0;
-        rect->width = gdk_screen_get_width (stack->priv->screen);
-        rect->height = gdk_screen_get_height (stack->priv->screen);
-
-        if (workarea == None)
-                return FALSE;
-
-        win = XRootWindow (display, disp_screen);
-        result = XGetWindowProperty (display,
-                                     win,
-                                     workarea,
-                                     0,
-                                     max_len,
-                                     False,
-                                     AnyPropertyType,
-                                     &type,
-                                     &format,
-                                     &num,
-                                     &leftovers,
-                                     &ret_workarea);
-
-        if (result != Success
-            || type == None
-            || format == 0
-            || leftovers
-            || num % 4) {
-                return FALSE;
-        }
-
-        desktop = get_current_desktop (stack->priv->screen);
-
-        workareas = (long *) ret_workarea;
-        rect->x = workareas[desktop * 4];
-        rect->y = workareas[desktop * 4 + 1];
-        rect->width = workareas[desktop * 4 + 2];
-        rect->height = workareas[desktop * 4 + 3];
-
-        XFree (ret_workarea);
-
-        return TRUE;
-}
-
 static void
 get_origin_coordinates (NdStackLocation stack_location,
                         GdkRectangle       *workarea,
@@ -274,16 +168,13 @@ nd_stack_set_location (NdStack        *stack,
 }
 
 NdStack *
-nd_stack_new (GdkScreen *screen,
-              guint      monitor)
+nd_stack_new (GdkMonitor *monitor)
 {
         NdStack *stack;
 
-        g_assert (screen != NULL && GDK_IS_SCREEN (screen));
-        g_assert (monitor < (guint)gdk_screen_get_n_monitors (screen));
+        g_assert (monitor != NULL && GDK_IS_MONITOR (monitor));
 
         stack = g_object_new (ND_TYPE_STACK, NULL);
-        stack->priv->screen = screen;
         stack->priv->monitor = monitor;
 
         return stack;
@@ -314,7 +205,6 @@ nd_stack_shift_notifications (NdStack     *stack,
                               gint        *nw_y)
 {
         GdkRectangle    workarea;
-        GdkRectangle    monitor;
         GdkRectangle   *positions;
         GList          *l;
         gint            x, y;
@@ -323,11 +213,7 @@ nd_stack_shift_notifications (NdStack     *stack,
         int             i;
         int             n_wins;
 
-        get_work_area (stack, &workarea);
-        gdk_screen_get_monitor_geometry (stack->priv->screen,
-                                         stack->priv->monitor,
-                                         &monitor);
-        gdk_rectangle_intersect (&monitor, &workarea, &workarea);
+        gdk_monitor_get_workarea (stack->priv->monitor, &workarea);
 
         add_padding_to_rect (&workarea);
 
diff --git a/gnome-flashback/libnotifications/nd-stack.h b/gnome-flashback/libnotifications/nd-stack.h
index 0e2f59c..da6fa7d 100644
--- a/gnome-flashback/libnotifications/nd-stack.h
+++ b/gnome-flashback/libnotifications/nd-stack.h
@@ -55,8 +55,7 @@ typedef enum
 
 GType           nd_stack_get_type              (void);
 
-NdStack *       nd_stack_new                   (GdkScreen      *screen,
-                                                guint           monitor);
+NdStack *       nd_stack_new                   (GdkMonitor     *monitor);
 
 void            nd_stack_set_location          (NdStack        *stack,
                                                 NdStackLocation location);


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