[gnome-panel] status-notifier: fix popup position



commit 79a4d63cc5096a1c8eac75307f97a49d5e84e7a0
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Wed Feb 22 02:29:13 2017 +0200

    status-notifier: fix popup position

 modules/external/status-notifier/sn-applet.c |  159 ++++++++++++++++++++++++++
 modules/external/status-notifier/sn-item.c   |  134 ++--------------------
 modules/external/status-notifier/sn-item.h   |    2 +
 3 files changed, 171 insertions(+), 124 deletions(-)
---
diff --git a/modules/external/status-notifier/sn-applet.c b/modules/external/status-notifier/sn-applet.c
index d09debc..7250b3b 100644
--- a/modules/external/status-notifier/sn-applet.c
+++ b/modules/external/status-notifier/sn-applet.c
@@ -75,6 +75,156 @@ reorder_items (GtkWidget *widget,
 }
 
 static void
+get_popup_position (SnApplet *sn,
+                    SnItem   *item,
+                    gint     *x,
+                    gint     *y)
+{
+  GtkWidget *widget;
+  GtkWidget *toplevel;
+  GdkWindow *window;
+  GpApplet *applet;
+  GtkPositionType position;
+
+  widget = GTK_WIDGET (item);
+  toplevel = gtk_widget_get_toplevel (widget);
+  window = gtk_widget_get_window (toplevel);
+
+  gtk_widget_translate_coordinates (widget, toplevel, 0, 0, x, y);
+  gdk_window_get_root_coords (window, *x, *y, x, y);
+
+  applet = GP_APPLET (sn);
+  position = gp_applet_get_position (applet);
+
+  if (position == GTK_POS_TOP || position == GTK_POS_LEFT)
+    {
+      gint width, height;
+
+      gdk_window_get_geometry (window, NULL, NULL, &width, &height);
+
+      if (gp_applet_get_orientation (applet) == GTK_ORIENTATION_HORIZONTAL)
+        *y += height;
+      else
+        *x += width;
+    }
+}
+
+static void
+popup_menu_at_item (SnApplet *sn,
+                    GtkMenu  *menu,
+                    SnItem   *item,
+                    GdkEvent *event)
+{
+  GdkGravity widget_anchor;
+  GdkGravity menu_anchor;
+
+  switch (gp_applet_get_position (GP_APPLET (sn)))
+    {
+      case GTK_POS_TOP:
+        widget_anchor = GDK_GRAVITY_SOUTH_WEST;
+        menu_anchor = GDK_GRAVITY_NORTH_WEST;
+        break;
+
+      case GTK_POS_LEFT:
+        widget_anchor = GDK_GRAVITY_NORTH_EAST;
+        menu_anchor = GDK_GRAVITY_NORTH_WEST;
+        break;
+
+      case GTK_POS_RIGHT:
+        widget_anchor = GDK_GRAVITY_NORTH_WEST;
+        menu_anchor = GDK_GRAVITY_NORTH_EAST;
+        break;
+
+      case GTK_POS_BOTTOM:
+        widget_anchor = GDK_GRAVITY_NORTH_WEST;
+        menu_anchor = GDK_GRAVITY_SOUTH_WEST;
+        break;
+
+      default:
+        g_assert_not_reached ();
+        break;
+    }
+
+  gtk_menu_popup_at_widget (menu, GTK_WIDGET (item),
+                            widget_anchor, menu_anchor,
+                            event);
+}
+
+static gboolean
+button_press_event_cb (GtkWidget      *widget,
+                       GdkEventButton *event,
+                       SnApplet       *sn)
+{
+  SnItem *item;
+  gint x, y;
+
+  item = SN_ITEM (widget);
+
+  if (event->button == 2)
+    {
+      get_popup_position (sn, item, &x, &y);
+      SN_ITEM_GET_CLASS (item)->secondary_activate (item, x, y);
+    }
+  else if (event->button == 3)
+    {
+      GtkMenu *menu;
+
+      menu = sn_item_get_menu (item);
+
+      if (menu != NULL)
+        {
+          popup_menu_at_item (sn, menu, item, (GdkEvent *) event);
+          return GDK_EVENT_STOP;
+        }
+      else
+        {
+          get_popup_position (sn, item, &x, &y);
+          SN_ITEM_GET_CLASS (item)->context_menu (item, x, y);
+        }
+    }
+
+  return GDK_EVENT_PROPAGATE;
+}
+
+static gboolean
+popup_menu_cb (GtkWidget *widget,
+               SnApplet  *sn)
+{
+  SnItem *item;
+  GtkMenu *menu;
+
+  item = SN_ITEM (widget);
+  menu = sn_item_get_menu (item);
+
+  if (menu != NULL)
+    {
+      popup_menu_at_item (sn, menu, item, NULL);
+    }
+  else
+    {
+      gint x, y;
+
+      get_popup_position (sn, item, &x, &y);
+      SN_ITEM_GET_CLASS (item)->context_menu (item, x, y);
+    }
+
+  return TRUE;
+}
+
+static void
+clicked_cb (GtkButton *button,
+            SnApplet  *sn)
+{
+  SnItem *item;
+  gint x, y;
+
+  item = SN_ITEM (button);
+
+  get_popup_position (sn, item, &x, &y);
+  SN_ITEM_GET_CLASS (item)->activate (item, x, y);
+}
+
+static void
 item_added_cb (SnHost   *host,
                SnItem   *item,
                SnApplet *sn)
@@ -85,6 +235,15 @@ item_added_cb (SnHost   *host,
   sn->items = g_slist_sort (sn->items, compare_items);
   gtk_container_foreach (GTK_CONTAINER (sn->box), reorder_items, sn);
 
+  g_signal_connect (item, "button-press-event",
+                    G_CALLBACK (button_press_event_cb), sn);
+
+  g_signal_connect (item, "popup-menu",
+                    G_CALLBACK (popup_menu_cb), sn);
+
+  g_signal_connect (item, "clicked",
+                    G_CALLBACK (clicked_cb), sn);
+
   g_object_bind_property (sn->box, "orientation",
                           item, "orientation",
                           G_BINDING_DEFAULT);
diff --git a/modules/external/status-notifier/sn-item.c b/modules/external/status-notifier/sn-item.c
index ad65b1e..8f2a6fe 100644
--- a/modules/external/status-notifier/sn-item.c
+++ b/modules/external/status-notifier/sn-item.c
@@ -148,124 +148,6 @@ sn_item_set_property (GObject      *object,
     }
 }
 
-static void
-sn_item_get_action_coordinates (SnItem *item,
-                                gint   *x,
-                                gint   *y)
-{
-  GtkWidget *widget;
-  SnItemPrivate *priv;
-  GdkWindow *window;
-  GtkWidget *toplevel;
-  gint width;
-  gint height;
-
-  priv = sn_item_get_instance_private (item);
-  widget = GTK_WIDGET (item);
-  window = gtk_widget_get_window (widget);
-  toplevel = gtk_widget_get_toplevel (widget);
-
-  gdk_window_get_geometry (window, x, y, &width, &height);
-  gtk_widget_translate_coordinates (widget, toplevel, *x, *y, x, y);
-
-  if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
-    *y += height;
-  else
-    *x += width;
-}
-
-static gboolean
-sn_item_button_press_event (GtkWidget      *widget,
-                            GdkEventButton *event)
-{
-  SnItem *item;
-  SnItemPrivate *priv;
-  GdkDisplay *display;
-  GdkSeat *seat;
-  gint x;
-  gint y;
-
-  if (event->button < 2 || event->button > 3)
-    return GTK_WIDGET_CLASS (sn_item_parent_class)->button_press_event (widget, event);
-
-  item = SN_ITEM (widget);
-  priv = sn_item_get_instance_private (item);
-  display = gdk_display_get_default ();
-  seat = gdk_display_get_default_seat (display);
-
-  sn_item_get_action_coordinates (item, &x, &y);
-
-  if (event->button == 2)
-    {
-      gdk_seat_ungrab (seat);
-      SN_ITEM_GET_CLASS (item)->secondary_activate (item, x, y);
-    }
-  else if (event->button == 3)
-    {
-      if (priv->menu != NULL)
-        {
-          gtk_menu_popup_at_widget (priv->menu, widget,
-                                    GDK_GRAVITY_SOUTH_WEST,
-                                    GDK_GRAVITY_NORTH_WEST,
-                                    (GdkEvent *) event);
-        }
-      else
-        {
-          gdk_seat_ungrab (seat);
-          SN_ITEM_GET_CLASS (item)->context_menu (item, x, y);
-        }
-    }
-  else
-    {
-      g_assert_not_reached ();
-    }
-
-  return GTK_WIDGET_CLASS (sn_item_parent_class)->button_press_event (widget, event);
-}
-
-static gboolean
-sn_item_popup_menu (GtkWidget *widget)
-{
-  SnItem *item;
-  SnItemPrivate *priv;
-
-  item = SN_ITEM (widget);
-  priv = sn_item_get_instance_private (item);
-
-  if (priv->menu != NULL)
-    {
-      gtk_menu_popup_at_widget (priv->menu, widget,
-                                GDK_GRAVITY_SOUTH_WEST,
-                                GDK_GRAVITY_NORTH_WEST,
-                                NULL);
-    }
-  else
-    {
-      gint x;
-      gint y;
-
-      sn_item_get_action_coordinates (item, &x, &y);
-
-      SN_ITEM_GET_CLASS (item)->context_menu (item, x, y);
-    }
-
-  return TRUE;
-}
-
-static void
-sn_item_clicked (GtkButton *button)
-{
-  SnItem *item;
-  gint x;
-  gint y;
-
-  item = SN_ITEM (button);
-
-  sn_item_get_action_coordinates (item, &x, &y);
-
-  SN_ITEM_GET_CLASS (item)->activate (item, x, y);
-}
-
 static gboolean
 sn_item_scroll_event (GtkWidget      *widget,
                       GdkEventScroll *event)
@@ -390,23 +272,17 @@ sn_item_class_init (SnItemClass *item_class)
 {
   GObjectClass *object_class;
   GtkWidgetClass *widget_class;
-  GtkButtonClass *button_class;
 
   object_class = G_OBJECT_CLASS (item_class);
   widget_class = GTK_WIDGET_CLASS (item_class);
-  button_class = GTK_BUTTON_CLASS (item_class);
 
   object_class->dispose = sn_item_dispose;
   object_class->finalize = sn_item_finalize;
   object_class->get_property = sn_item_get_property;
   object_class->set_property = sn_item_set_property;
 
-  widget_class->button_press_event = sn_item_button_press_event;
-  widget_class->popup_menu = sn_item_popup_menu;
   widget_class->scroll_event = sn_item_scroll_event;
 
-  button_class->clicked = sn_item_clicked;
-
   item_class->ready = sn_item_ready;
 
   install_properties (object_class);
@@ -445,6 +321,16 @@ sn_item_get_category (SnItem *item)
   return category;
 }
 
+GtkMenu *
+sn_item_get_menu (SnItem *item)
+{
+  SnItemPrivate *priv;
+
+  priv = sn_item_get_instance_private (item);
+
+  return priv->menu;
+}
+
 const gchar *
 sn_item_get_bus_name (SnItem *item)
 {
diff --git a/modules/external/status-notifier/sn-item.h b/modules/external/status-notifier/sn-item.h
index 666e669..a01223e 100644
--- a/modules/external/status-notifier/sn-item.h
+++ b/modules/external/status-notifier/sn-item.h
@@ -72,6 +72,8 @@ const gchar    *sn_item_get_id          (SnItem *item);
 
 SnItemCategory  sn_item_get_category    (SnItem *item);
 
+GtkMenu        *sn_item_get_menu        (SnItem *item);
+
 const gchar    *sn_item_get_bus_name    (SnItem *item);
 const gchar    *sn_item_get_object_path (SnItem *item);
 


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