[gtk: 2/3] menu: Remove legacy popup APIs



commit 4497ac7d7587f7a4e5fefafb52f5013d36a35bbe
Author: Jonas Ådahl <jadahl gmail com>
Date:   Wed Jul 25 16:41:15 2018 +0200

    menu: Remove legacy popup APIs
    
    Remove gtk_menu_popup_for_device() and gtk_menu_popup(), as they cannot
    be implemented in a portable manner by all backends. They have been
    deprecated for proper alternative APIs for some time, so lets remove
    them now before its too late.
    
    While at it, fix the example documentation for mapping a menu.

 docs/reference/gtk/gtk4-sections.txt |   4 -
 gtk/gtkmenu.c                        | 420 +----------------------------------
 gtk/gtkmenu.h                        |  52 -----
 gtk/gtkmenuprivate.h                 |   3 -
 4 files changed, 12 insertions(+), 467 deletions(-)
---
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index f035fe37cb..6c0cfb2503 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -679,8 +679,6 @@ gtk_combo_box_get_active_id
 gtk_combo_box_set_active_id
 gtk_combo_box_get_model
 gtk_combo_box_set_model
-gtk_combo_box_popup_for_device
-gtk_combo_box_popup
 gtk_combo_box_popdown
 gtk_combo_box_get_popup_accessible
 gtk_combo_box_get_row_separator_func
@@ -1724,8 +1722,6 @@ gtk_menu_attach
 gtk_menu_popup_at_rect
 gtk_menu_popup_at_widget
 gtk_menu_popup_at_pointer
-gtk_menu_popup_for_device
-gtk_menu_popup
 gtk_menu_set_accel_group
 gtk_menu_get_accel_group
 gtk_menu_set_accel_path
diff --git a/gtk/gtkmenu.c b/gtk/gtkmenu.c
index 1efbb2ed4d..c98ba1bbb7 100644
--- a/gtk/gtkmenu.c
+++ b/gtk/gtkmenu.c
@@ -39,9 +39,9 @@
  * Other composite widgets such as the #GtkNotebook can pop up a
  * #GtkMenu as well.
  *
- * Applications can display a #GtkMenu as a popup menu by calling the
- * gtk_menu_popup() function.  The example below shows how an application
- * can pop up a menu when the 3rd mouse button is pressed.
+ * Applications can display a #GtkMenu as a popup menu by calling one of the
+ * gtk_menu_popup_*() function. The example below shows how an application can
+ * pop up a menu when the 3rd mouse button is pressed.
  *
  * ## Connecting the popup signal handler.
  *
@@ -50,22 +50,22 @@
  *   gesture = gtk_gesture_multi_press_new (window);
  *   gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture),
  *                                  GDK_BUTTON_SECONDARY);
- *   g_signal_connect (gesture, "event", G_CALLBACK (my_popup_handler), menu);
+ *   g_signal_connect (gesture, "begin", G_CALLBACK (my_popup_handler), menu);
  * ]|
  *
  * ## Signal handler which displays a popup menu.
  *
  * |[<!-- language="C" -->
  * static void
- * my_popup_handler (GtkGesture *gesture,
- *                   guint       n_press,
- *                   double      x,
- *                   double      y,
- *                   gpointer    data)
+ * my_popup_handler (GtkGesture       *gesture,
+ *                   GdkEventSequence *sequence
+ *                   gpointer          data)
  * {
  *   GtkMenu *menu = data;
+ *   const GdkEvent *event;
  *
- *   gtk_menu_popup (menu, NULL, NULL, NULL, NULL, button, GDK_CURRENT_TIME);
+ *   event = gtk_gesture_get_last_event (gesture, sequence);
+ *   gtk_menu_popup_at_pointer (menu, event);
  * }
  * ]|
  *
@@ -1207,13 +1207,6 @@ gtk_menu_destroy (GtkWidget *widget)
 
   g_clear_pointer (&priv->heights, g_free);
 
-  if (priv->position_func_data_destroy)
-    {
-      priv->position_func_data_destroy (priv->position_func_data);
-      priv->position_func_data = NULL;
-      priv->position_func_data_destroy = NULL;
-    }
-
   GTK_WIDGET_CLASS (gtk_menu_parent_class)->destroy (widget);
 }
 
@@ -1498,9 +1491,6 @@ gtk_menu_popup_internal (GtkMenu             *menu,
                          GdkDevice           *device,
                          GtkWidget           *parent_menu_shell,
                          GtkWidget           *parent_menu_item,
-                         GtkMenuPositionFunc  func,
-                         gpointer             data,
-                         GDestroyNotify       destroy,
                          guint                button,
                          guint32              activate_time)
 {
@@ -1658,9 +1648,6 @@ gtk_menu_popup_internal (GtkMenu             *menu,
                                   GTK_WINDOW (parent_toplevel));
 
   priv->parent_menu_item = parent_menu_item;
-  priv->position_func = func;
-  priv->position_func_data = data;
-  priv->position_func_data_destroy = destroy;
   menu_shell->priv->activate_time = activate_time;
 
   /* We need to show the menu here rather in the init function
@@ -1703,123 +1690,6 @@ gtk_menu_popup_internal (GtkMenu             *menu,
   _gtk_menu_shell_update_mnemonics (menu_shell);
 }
 
-/**
- * gtk_menu_popup_for_device:
- * @menu: a #GtkMenu
- * @device: (allow-none): a #GdkDevice
- * @parent_menu_shell: (allow-none): the menu shell containing the triggering
- *     menu item, or %NULL
- * @parent_menu_item: (allow-none): the menu item whose activation triggered
- *     the popup, or %NULL
- * @func: (allow-none): a user supplied function used to position the menu,
- *     or %NULL
- * @data: (allow-none): user supplied data to be passed to @func
- * @destroy: (allow-none): destroy notify for @data
- * @button: the mouse button which was pressed to initiate the event
- * @activate_time: the time at which the activation event occurred
- *
- * Displays a menu and makes it available for selection.
- *
- * Applications can use this function to display context-sensitive menus,
- * and will typically supply %NULL for the @parent_menu_shell,
- * @parent_menu_item, @func, @data and @destroy parameters. The default
- * menu positioning function will position the menu at the current position
- * of @device (or its corresponding pointer).
- *
- * The @button parameter should be the mouse button pressed to initiate
- * the menu popup. If the menu popup was initiated by something other than
- * a mouse button press, such as a mouse button release or a keypress,
- * @button should be 0.
- *
- * The @activate_time parameter is used to conflict-resolve initiation of
- * concurrent requests for mouse/keyboard grab requests. To function
- * properly, this needs to be the time stamp of the user event (such as
- * a mouse click or key press) that caused the initiation of the popup.
- * Only if no such event is available, gtk_get_current_event_time() can
- * be used instead.
- */
-void
-gtk_menu_popup_for_device (GtkMenu             *menu,
-                           GdkDevice           *device,
-                           GtkWidget           *parent_menu_shell,
-                           GtkWidget           *parent_menu_item,
-                           GtkMenuPositionFunc  func,
-                           gpointer             data,
-                           GDestroyNotify       destroy,
-                           guint                button,
-                           guint32              activate_time)
-{
-  GtkMenuPrivate *priv;
-
-  g_return_if_fail (GTK_IS_MENU (menu));
-
-  priv = menu->priv;
-  priv->rect_surface = NULL;
-  priv->widget = NULL;
-
-  gtk_menu_popup_internal (menu,
-                           device,
-                           parent_menu_shell,
-                           parent_menu_item,
-                           func,
-                           data,
-                           destroy,
-                           button,
-                           activate_time);
-}
-
-/**
- * gtk_menu_popup:
- * @menu: a #GtkMenu
- * @parent_menu_shell: (allow-none): the menu shell containing the
- *     triggering menu item, or %NULL
- * @parent_menu_item: (allow-none): the menu item whose activation
- *     triggered the popup, or %NULL
- * @func: (scope async) (allow-none): a user supplied function used to position
- *     the menu, or %NULL
- * @data: user supplied data to be passed to @func.
- * @button: the mouse button which was pressed to initiate the event.
- * @activate_time: the time at which the activation event occurred.
- *
- * Displays a menu and makes it available for selection.
- *
- * Applications can use this function to display context-sensitive
- * menus, and will typically supply %NULL for the @parent_menu_shell,
- * @parent_menu_item, @func and @data parameters. The default menu
- * positioning function will position the menu at the current mouse
- * cursor position.
- *
- * The @button parameter should be the mouse button pressed to initiate
- * the menu popup. If the menu popup was initiated by something other
- * than a mouse button press, such as a mouse button release or a keypress,
- * @button should be 0.
- *
- * The @activate_time parameter is used to conflict-resolve initiation
- * of concurrent requests for mouse/keyboard grab requests. To function
- * properly, this needs to be the timestamp of the user event (such as
- * a mouse click or key press) that caused the initiation of the popup.
- * Only if no such event is available, gtk_get_current_event_time() can
- * be used instead.
- */
-void
-gtk_menu_popup (GtkMenu             *menu,
-                GtkWidget           *parent_menu_shell,
-                GtkWidget           *parent_menu_item,
-                GtkMenuPositionFunc  func,
-                gpointer             data,
-                guint                button,
-                guint32              activate_time)
-{
-  g_return_if_fail (GTK_IS_MENU (menu));
-
-  gtk_menu_popup_for_device (menu,
-                             NULL,
-                             parent_menu_shell,
-                             parent_menu_item,
-                             func, data, NULL,
-                             button, activate_time);
-}
-
 static GdkDevice *
 get_device_for_event (const GdkEvent *event)
 {
@@ -1924,9 +1794,6 @@ gtk_menu_popup_at_rect (GtkMenu            *menu,
                            device,
                            NULL,
                            NULL,
-                           NULL,
-                           NULL,
-                           NULL,
                            button,
                            activate_time);
 
@@ -2014,9 +1881,6 @@ gtk_menu_popup_at_widget (GtkMenu        *menu,
                            device,
                            parent_menu_shell,
                            parent_menu_item,
-                           NULL,
-                           NULL,
-                           NULL,
                            button,
                            activate_time);
 
@@ -2516,9 +2380,6 @@ gtk_menu_focus (GtkWidget       *widget,
   return FALSE;
 }
 
-/* See notes in gtk_menu_popup() for information
- * about the “grab transfer window”
- */
 static GdkSurface *
 menu_grab_transfer_surface_get (GtkMenu *menu)
 {
@@ -3713,231 +3574,6 @@ gtk_menu_deactivate (GtkMenuShell *menu_shell)
     gtk_menu_shell_deactivate (GTK_MENU_SHELL (parent));
 }
 
-static void
-gtk_menu_position_legacy (GtkMenu  *menu,
-                          gboolean  set_scroll_offset)
-{
-  GtkMenuPrivate *priv = menu->priv;
-  GtkWidget *widget;
-  GtkRequisition requisition;
-  gint x, y;
-  gint scroll_offset;
-  GdkDisplay *display;
-  GdkMonitor *monitor;
-  GdkRectangle workarea;
-  gint monitor_num;
-  GdkDevice *pointer;
-  GtkBorder border;
-  gint i;
-
-  widget = GTK_WIDGET (menu);
-
-  display = gtk_widget_get_display (widget);
-  pointer = _gtk_menu_shell_get_grab_device (GTK_MENU_SHELL (menu));
-  gdk_device_get_position (pointer, &x, &y);
-
-  /* Realize so we have the proper width and height to figure out
-   * the right place to popup the menu.
-   */
-  gtk_widget_realize (priv->toplevel);
-
-  _gtk_window_get_shadow_width (GTK_WINDOW (priv->toplevel), &border);
-
-  requisition.width = gtk_widget_get_allocated_width (widget);
-  requisition.height = gtk_widget_get_allocated_height (widget);
-
-  monitor = gdk_display_get_monitor_at_point (display, x, y);
-  monitor_num = 0;
-  for (i = 0; ; i++)
-    {
-      GdkMonitor *m = gdk_display_get_monitor (display, i);
-
-      if (m == monitor)
-        {
-          monitor_num = i;
-          break;
-        }
-      if (m == NULL)
-        break;
-    }
-
-  priv->monitor_num = monitor_num;
-  priv->initially_pushed_in = FALSE;
-
-  /* Set the type hint here to allow custom position functions
-   * to set a different hint
-   */
-  if (!gtk_widget_get_visible (priv->toplevel))
-    gtk_window_set_type_hint (GTK_WINDOW (priv->toplevel), GDK_SURFACE_TYPE_HINT_POPUP_MENU);
-
-  if (priv->position_func)
-    {
-      (* priv->position_func) (menu, &x, &y, &priv->initially_pushed_in,
-                               priv->position_func_data);
-
-      if (priv->monitor_num < 0)
-        priv->monitor_num = monitor_num;
-
-      monitor = gdk_display_get_monitor (display, priv->monitor_num);
-      gdk_monitor_get_workarea (monitor, &workarea);
-    }
-  else
-    {
-      gint space_left, space_right, space_above, space_below;
-      gint needed_width;
-      gint needed_height;
-      gboolean rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
-
-      /* The placement of popup menus horizontally works like this (with
-       * RTL in parentheses)
-       *
-       * - If there is enough room to the right (left) of the mouse cursor,
-       *   position the menu there.
-       *
-       * - Otherwise, if if there is enough room to the left (right) of the
-       *   mouse cursor, position the menu there.
-       *
-       * - Otherwise if the menu is smaller than the monitor, position it
-       *   on the side of the mouse cursor that has the most space available
-       *
-       * - Otherwise (if there is simply not enough room for the menu on the
-       *   monitor), position it as far left (right) as possible.
-       *
-       * Positioning in the vertical direction is similar: first try below
-       * mouse cursor, then above.
-       */
-      monitor = gdk_display_get_monitor (display, priv->monitor_num);
-      gdk_monitor_get_workarea (monitor, &workarea);
-
-      space_left = x - workarea.x;
-      space_right = workarea.x + workarea.width - x - 1;
-      space_above = y - workarea.y;
-      space_below = workarea.y + workarea.height - y - 1;
-
-      /* Position horizontally. */
-
-      /* the amount of space we need to position the menu.
-       * Note the menu is offset "thickness" pixels
-       */
-      needed_width = requisition.width;
-
-      if (needed_width <= space_left ||
-          needed_width <= space_right)
-        {
-          if ((rtl  && needed_width <= space_left) ||
-              (!rtl && needed_width >  space_right))
-            {
-              /* position left */
-              x = x - requisition.width + 1;
-            }
-          else
-            {
-              /* position right */
-            }
-
-          /* x is clamped on-screen further down */
-        }
-      else if (requisition.width <= workarea.width)
-        {
-          /* the menu is too big to fit on either side of the mouse
-           * cursor, but smaller than the monitor. Position it on
-           * the side that has the most space
-           */
-          if (space_left > space_right)
-            {
-              /* left justify */
-              x = workarea.x;
-            }
-          else
-            {
-              /* right justify */
-              x = workarea.x + workarea.width - requisition.width;
-            }
-        }
-      else /* menu is simply too big for the monitor */
-        {
-          if (rtl)
-            {
-              /* right justify */
-              x = workarea.x + workarea.width - requisition.width;
-            }
-          else
-            {
-              /* left justify */
-              x = workarea.x;
-            }
-        }
-
-      /* Position vertically.
-       * The algorithm is the same as above, but simpler
-       * because we don't have to take RTL into account.
-       */
-      needed_height = requisition.height;
-
-      if (needed_height <= space_above ||
-          needed_height <= space_below)
-        {
-          if (needed_height > space_below)
-            y = y - requisition.height + 1;
-
-          y = CLAMP (y, workarea.y,
-                     workarea.y + workarea.height - requisition.height);
-        }
-      else if (needed_height > space_below && needed_height > space_above)
-        {
-          if (space_below >= space_above)
-            y = workarea.y + workarea.height - requisition.height;
-          else
-            y = workarea.y;
-        }
-      else
-        {
-          y = workarea.y;
-        }
-    }
-
-  scroll_offset = 0;
-
-  if (y + requisition.height > workarea.y + workarea.height)
-    {
-      if (priv->initially_pushed_in)
-        scroll_offset += (workarea.y + workarea.height) - requisition.height - y;
-      y = (workarea.y + workarea.height) - requisition.height;
-    }
-
-  if (y < workarea.y)
-    {
-      if (priv->initially_pushed_in)
-        scroll_offset += workarea.y - y;
-      y = workarea.y;
-    }
-
-  x = CLAMP (x, workarea.x, MAX (workarea.x, workarea.x + workarea.width - requisition.width));
-
-  x -= border.left;
-  y -= border.top;
-
-  if (GTK_MENU_SHELL (menu)->priv->active)
-    {
-      priv->have_position = TRUE;
-      priv->position_x = x;
-      priv->position_y = y;
-    }
-
-  if (scroll_offset != 0)
-    {
-      GtkBorder arrow_border;
-
-      get_arrows_border (menu, &arrow_border);
-      scroll_offset += arrow_border.top;
-    }
-
-  gtk_window_move (GTK_WINDOW (priv->toplevel), x, y);
-
-  if (set_scroll_offset)
-    priv->scroll_offset = scroll_offset;
-}
-
 static GdkGravity
 get_horizontally_flipped_anchor (GdkGravity anchor)
 {
@@ -4000,41 +3636,9 @@ gtk_menu_position (GtkMenu  *menu,
       gtk_widget_get_surface_allocation (priv->widget, &rect);
       text_direction = gtk_widget_get_direction (priv->widget);
     }
-  else if (!priv->position_func)
-    {
-      GtkWidget *attach_widget;
-      GdkDevice *grab_device;
-
-      /*
-       * One of the legacy gtk_menu_popup*() functions were used to popup but
-       * without a custom positioning function, so make an attempt to let the
-       * backend do the position constraining when required conditions are met.
-       */
-
-      grab_device = _gtk_menu_shell_get_grab_device (GTK_MENU_SHELL (menu));
-      attach_widget = gtk_menu_get_attach_widget (menu);
-
-      if (grab_device && attach_widget)
-        {
-          rect = (GdkRectangle) { 0, 0, 1, 1 };
-
-          rect_surface = gtk_widget_get_surface (attach_widget);
-          gdk_surface_get_device_position (rect_surface, grab_device,
-                                          &rect.x, &rect.y, NULL);
-          text_direction = gtk_widget_get_direction (attach_widget);
-          rect_anchor = GDK_GRAVITY_SOUTH_EAST;
-          menu_anchor = GDK_GRAVITY_NORTH_WEST;
-          anchor_hints = GDK_ANCHOR_FLIP | GDK_ANCHOR_SLIDE | GDK_ANCHOR_RESIZE;
-          rect_anchor_dx = 0;
-          rect_anchor_dy = 0;
-          emulated_move_to_rect = TRUE;
-        }
-    }
-
-  if (!rect_surface)
+  else
     {
-      gtk_menu_position_legacy (menu, set_scroll_offset);
-      return;
+      g_assert_not_reached ();
     }
 
   /* Realize so we have the proper width and height to figure out
diff --git a/gtk/gtkmenu.h b/gtk/gtkmenu.h
index c62c7e5fa9..c9a639c0a8 100644
--- a/gtk/gtkmenu.h
+++ b/gtk/gtkmenu.h
@@ -61,40 +61,6 @@ typedef enum
   GTK_ARROWS_END
 } GtkArrowPlacement;
 
-/**
- * GtkMenuPositionFunc:
- * @menu: a #GtkMenu.
- * @x: (inout): address of the #gint representing the horizontal
- *     position where the menu shall be drawn.
- * @y: (inout): address of the #gint representing the vertical position
- *     where the menu shall be drawn.  This is an output parameter.
- * @push_in: (out): This parameter controls how menus placed outside
- *     the monitor are handled.  If this is set to %TRUE and part of
- *     the menu is outside the monitor then GTK+ pushes the window
- *     into the visible area, effectively modifying the popup
- *     position.  Note that moving and possibly resizing the menu
- *     around will alter the scroll position to keep the menu items
- *     “in place”, i.e. at the same monitor position they would have
- *     been without resizing.  In practice, this behavior is only
- *     useful for combobox popups or option menus and cannot be used
- *     to simply confine a menu to monitor boundaries.  In that case,
- *     changing the scroll offset is not desirable.
- * @user_data: the data supplied by the user in the gtk_menu_popup()
- *     @data parameter.
- *
- * A user function supplied when calling gtk_menu_popup() which
- * controls the positioning of the menu when it is displayed.  The
- * function sets the @x and @y parameters to the coordinates where the
- * menu is to be drawn.  To make the menu appear on a different
- * monitor than the mouse pointer, gtk_menu_set_monitor() must be
- * called.
- */
-typedef void (*GtkMenuPositionFunc) (GtkMenu   *menu,
-                                    gint      *x,
-                                    gint      *y,
-                                    gboolean  *push_in,
-                                    gpointer   user_data);
-
 /**
  * GtkMenuDetachFunc:
  * @attach_widget: the #GtkWidget that the menu is being detached from.
@@ -135,24 +101,6 @@ GtkWidget* gtk_menu_new_from_model        (GMenuModel *model);
 
 /* Display the menu onscreen */
 GDK_AVAILABLE_IN_ALL
-void      gtk_menu_popup                 (GtkMenu             *menu,
-                                          GtkWidget           *parent_menu_shell,
-                                          GtkWidget           *parent_menu_item,
-                                          GtkMenuPositionFunc  func,
-                                          gpointer             data,
-                                          guint                button,
-                                          guint32              activate_time);
-GDK_AVAILABLE_IN_ALL
-void       gtk_menu_popup_for_device      (GtkMenu             *menu,
-                                           GdkDevice           *device,
-                                           GtkWidget           *parent_menu_shell,
-                                           GtkWidget           *parent_menu_item,
-                                           GtkMenuPositionFunc  func,
-                                           gpointer             data,
-                                           GDestroyNotify       destroy,
-                                           guint                button,
-                                           guint32              activate_time);
-GDK_AVAILABLE_IN_ALL
 void       gtk_menu_popup_at_rect         (GtkMenu             *menu,
                                            GdkSurface          *rect_surface,
                                            const GdkRectangle  *rect,
diff --git a/gtk/gtkmenuprivate.h b/gtk/gtkmenuprivate.h
index e1621357a3..5a24b4a465 100644
--- a/gtk/gtkmenuprivate.h
+++ b/gtk/gtkmenuprivate.h
@@ -47,9 +47,6 @@ struct _GtkMenuPrivate
   GtkAccelGroup *accel_group;
   const char    *accel_path;
 
-  GtkMenuPositionFunc position_func;
-  gpointer            position_func_data;
-  GDestroyNotify      position_func_data_destroy;
   gint                position_x;
   gint                position_y;
 


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