mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-15 21:20:09 +00:00
Merge branch 'wip/gtk-menu-popup-no-more' into 'master'
Remove legacy GtkMenu popup APIs See merge request GNOME/gtk!270
This commit is contained in:
commit
f3f32b47cc
@ -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
|
||||
|
420
gtk/gtkmenu.c
420
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)
|
||||
else
|
||||
{
|
||||
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)
|
||||
{
|
||||
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
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
|
@ -384,8 +384,7 @@ do_popup_menu (GtkWidget *icon_list,
|
||||
event_time = gtk_get_current_event_time ();
|
||||
}
|
||||
|
||||
gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
|
||||
button, event_time);
|
||||
gtk_menu_popup_at_pointer (GTK_MENU (menu), event);
|
||||
}
|
||||
|
||||
|
||||
|
@ -320,34 +320,9 @@ rtl_toggled (GtkCheckButton *check)
|
||||
gtk_widget_set_default_direction (GTK_TEXT_DIR_LTR);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
} MenuPositionData;
|
||||
|
||||
static void
|
||||
position_function (GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer user_data)
|
||||
{
|
||||
/* Do not do this in your own code */
|
||||
|
||||
MenuPositionData *position_data = user_data;
|
||||
|
||||
if (x)
|
||||
*x = position_data->x;
|
||||
|
||||
if (y)
|
||||
*y = position_data->y;
|
||||
|
||||
if (push_in)
|
||||
*push_in = FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
popup_context_menu (GtkToolbar *toolbar, gint x, gint y, gint button_number)
|
||||
{
|
||||
MenuPositionData position_data;
|
||||
|
||||
GtkMenu *menu = GTK_MENU (gtk_menu_new ());
|
||||
int i;
|
||||
|
||||
@ -358,18 +333,27 @@ popup_context_menu (GtkToolbar *toolbar, gint x, gint y, gint button_number)
|
||||
item = gtk_menu_item_new_with_mnemonic (label);
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
|
||||
}
|
||||
gtk_widget_show (GTK_WIDGET (menu));
|
||||
|
||||
if (button_number != -1)
|
||||
{
|
||||
position_data.x = x;
|
||||
position_data.y = y;
|
||||
|
||||
gtk_menu_popup (menu, NULL, NULL, position_function,
|
||||
&position_data, button_number, gtk_get_current_event_time());
|
||||
gtk_menu_popup_at_pointer (menu, NULL);
|
||||
}
|
||||
else
|
||||
gtk_menu_popup (menu, NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time());
|
||||
{
|
||||
GtkWindow *window;
|
||||
GtkWidget *widget;
|
||||
|
||||
window = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (toolbar)));
|
||||
widget = gtk_window_get_focus (window);
|
||||
if (!widget)
|
||||
widget = GTK_WIDGET (toolbar);
|
||||
|
||||
gtk_menu_popup_at_widget (menu,
|
||||
widget,
|
||||
GDK_GRAVITY_SOUTH_EAST,
|
||||
GDK_GRAVITY_NORTH_WEST,
|
||||
NULL);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user