More menu work

This commit is contained in:
Matthias Clasen 2019-05-31 03:20:50 +00:00
parent 3f6272f56e
commit 8ba3c75682
10 changed files with 90 additions and 92 deletions

View File

@ -1228,7 +1228,7 @@ update_menu_sensitivity (GtkComboBox *combo_box,
if (!priv->model)
return;
children = gtk_container_get_children (GTK_CONTAINER (menu));
children = gtk_menu_shell_get_items (GTK_MENU_SHELL (menu));
for (child = children; child; child = child->next)
{
@ -1321,20 +1321,24 @@ gtk_combo_box_menu_popup (GtkComboBox *combo_box)
if (!(active && gtk_widget_get_visible (active)))
{
for (i = GTK_MENU_SHELL (priv->popup_widget)->priv->children; i && !active; i = i->next)
GList *children;
children = gtk_menu_shell_get_items (GTK_MENU_SHELL (priv->popup_widget));
for (i = children; i && !active; i = i->next)
{
child = i->data;
if (child && gtk_widget_get_visible (child))
active = child;
}
g_list_free (children);
}
if (active)
{
gint child_height;
for (i = GTK_MENU_SHELL (priv->popup_widget)->priv->children; i && i->data != active; i = i->next)
GList *children;
children = gtk_menu_shell_get_items (GTK_MENU_SHELL (priv->popup_widget));
for (i = children; i && i->data != active; i = i->next)
{
child = i->data;
@ -1345,6 +1349,7 @@ gtk_combo_box_menu_popup (GtkComboBox *combo_box)
rect_anchor_dy -= child_height;
}
}
g_list_free (children);
gtk_widget_measure (active, GTK_ORIENTATION_VERTICAL, -1,
&child_height, NULL, NULL, NULL);

View File

@ -652,7 +652,11 @@ gtk_menu_get_property (GObject *object,
switch (prop_id)
{
case PROP_ACTIVE:
g_value_set_int (value, g_list_index (GTK_MENU_SHELL (menu)->priv->children, gtk_menu_get_active (menu)));
{
GList *children = gtk_menu_shell_get_items (GTK_MENU_SHELL (menu));
g_value_set_int (value, g_list_index (children, gtk_menu_get_active (menu)));
g_list_free (children);
}
break;
case PROP_ACCEL_GROUP:
g_value_set_object (value, gtk_menu_get_accel_group (menu));
@ -1015,6 +1019,8 @@ gtk_menu_remove (GtkContainer *container,
gtk_container_remove (GTK_CONTAINER (priv->box), widget);
GTK_CONTAINER_CLASS (gtk_menu_parent_class)->remove (container, widget);
menu_queue_resize (menu);
}
@ -1040,6 +1046,7 @@ gtk_menu_real_insert (GtkMenuShell *menu_shell,
GtkMenuPrivate *priv = menu->priv;
gtk_container_add (GTK_CONTAINER (priv->box), child);
gtk_menu_reorder_child (menu, child, position);
menu_queue_resize (menu);
}
@ -1639,7 +1646,7 @@ gtk_menu_get_active (GtkMenu *menu)
{
GtkMenuPrivate *priv;
GtkWidget *child;
GList *children;
GList *children, *l;
g_return_val_if_fail (GTK_IS_MENU (menu), NULL);
@ -1647,18 +1654,16 @@ gtk_menu_get_active (GtkMenu *menu)
if (!priv->old_active_menu_item)
{
child = NULL;
children = GTK_MENU_SHELL (menu)->priv->children;
while (children)
children = gtk_menu_shell_get_items (GTK_MENU_SHELL (menu));
for (l = children; l; l = l->next)
{
child = children->data;
children = children->next;
child = l->data;
if (gtk_bin_get_child (GTK_BIN (child)))
break;
child = NULL;
}
g_list_free (children);
priv->old_active_menu_item = child;
if (priv->old_active_menu_item)
@ -1683,13 +1688,15 @@ gtk_menu_set_active (GtkMenu *menu,
{
GtkMenuPrivate *priv;
GtkWidget *child;
GList *children;
GList *tmp_list;
g_return_if_fail (GTK_IS_MENU (menu));
priv = menu->priv;
tmp_list = g_list_nth (GTK_MENU_SHELL (menu)->priv->children, index);
children = gtk_menu_shell_get_items (GTK_MENU_SHELL (menu));
tmp_list = g_list_nth (children, index);
if (tmp_list)
{
child = tmp_list->data;
@ -1702,6 +1709,7 @@ gtk_menu_set_active (GtkMenu *menu,
}
}
g_object_notify (G_OBJECT (menu), "active");
g_list_free (children);
}
/**
@ -1904,20 +1912,24 @@ gtk_menu_reorder_child (GtkMenu *menu,
GtkWidget *child,
gint position)
{
GtkMenuShell *menu_shell;
GtkWidget *sibling = NULL;
int i;
g_return_if_fail (GTK_IS_MENU (menu));
g_return_if_fail (GTK_IS_MENU_ITEM (child));
menu_shell = GTK_MENU_SHELL (menu);
if (position < 0)
sibling = gtk_widget_get_last_child (menu->priv->box);
if (g_list_find (menu_shell->priv->children, child))
for (i = 0; i < position; i++)
{
menu_shell->priv->children = g_list_remove (menu_shell->priv->children, child);
menu_shell->priv->children = g_list_insert (menu_shell->priv->children, child, position);
menu_queue_resize (menu);
if (sibling == NULL)
sibling = gtk_widget_get_first_child (menu->priv->box);
else
sibling = gtk_widget_get_next_sibling (sibling);
}
gtk_box_reorder_child_after (GTK_BOX (menu->priv->box), child, sibling);
}
static gboolean

View File

@ -351,9 +351,11 @@ _gtk_menu_bar_cycle_focus (GtkMenuBar *menubar,
{
GtkWidget *next = g_ptr_array_index (menubars, index + 1);
GtkMenuShell *new_menushell = GTK_MENU_SHELL (next);
GList *children = gtk_menu_shell_get_items (new_menushell);
if (new_menushell->priv->children)
to_activate = new_menushell->priv->children->data;
if (children)
to_activate = children->data;
g_list_free (children);
}
g_ptr_array_free (menubars, TRUE);
@ -440,6 +442,30 @@ gtk_menu_bar_remove (GtkContainer *container,
GtkMenuBar *menu_bar = GTK_MENU_BAR (container);
gtk_container_remove (GTK_CONTAINER (menu_bar->box), widget);
GTK_CONTAINER_CLASS (gtk_menu_bar_parent_class)->remove (container, widget);
}
static void
gtk_menu_bar_reorder_child (GtkMenuBar *menu_bar,
GtkWidget *child,
gint position)
{
GtkWidget *sibling = NULL;
int i;
if (position < 0)
sibling = gtk_widget_get_last_child (menu_bar->box);
for (i = 0; i < position; i++)
{
if (sibling == NULL)
sibling = gtk_widget_get_first_child (menu_bar->box);
else
sibling = gtk_widget_get_next_sibling (sibling);
}
gtk_box_reorder_child_after (GTK_BOX (menu_bar->box), child, sibling);
}
static void
@ -450,4 +476,5 @@ gtk_menu_bar_insert (GtkMenuShell *menu_shell,
GtkMenuBar *menu_bar = GTK_MENU_BAR (menu_shell);
gtk_container_add (GTK_CONTAINER (menu_bar->box), child);
gtk_menu_bar_reorder_child (menu_bar, child, position);
}

View File

@ -262,7 +262,7 @@ gtk_menu_item_actionable_interface_init (GtkActionableInterface *iface)
iface->get_action_target_value = gtk_menu_item_get_action_target_value;
}
static GtkMenuShell *
GtkMenuShell *
gtk_menu_item_get_menu_shell (GtkMenuItem *item)
{
return GTK_MENU_SHELL (gtk_widget_get_ancestor (GTK_WIDGET (item), GTK_TYPE_MENU_SHELL));

View File

@ -19,6 +19,7 @@
#define __GTK_MENU_ITEM_PRIVATE_H__
#include <gtk/gtkmenuitem.h>
#include <gtk/gtkmenushell.h>
#include <gtk/gtkactionhelperprivate.h>
#include <gtk/gtkcssnodeprivate.h>
#include <gtk/gtkeventcontrollermotion.h>
@ -56,6 +57,8 @@ gboolean _gtk_menu_item_is_selectable (GtkWidget *menu_item);
void _gtk_menu_item_popup_submenu (GtkWidget *menu_item,
gboolean with_delay);
void _gtk_menu_item_popdown_submenu (GtkWidget *menu_item);
GtkMenuShell *
gtk_menu_item_get_menu_shell (GtkMenuItem *menu_item);
G_END_DECLS

View File

@ -137,12 +137,6 @@ static void gtk_menu_shell_add (GtkContainer *container,
GtkWidget *widget);
static void gtk_menu_shell_remove (GtkContainer *container,
GtkWidget *widget);
static void gtk_menu_shell_forall (GtkContainer *container,
GtkCallback callback,
gpointer callback_data);
static void gtk_menu_shell_real_insert (GtkMenuShell *menu_shell,
GtkWidget *child,
gint position);
static void gtk_real_menu_shell_deactivate (GtkMenuShell *menu_shell);
static GType gtk_menu_shell_child_type (GtkContainer *container);
static void gtk_menu_shell_real_select_item (GtkMenuShell *menu_shell,
@ -191,7 +185,6 @@ gtk_menu_shell_class_init (GtkMenuShellClass *klass)
container_class->add = gtk_menu_shell_add;
container_class->remove = gtk_menu_shell_remove;
container_class->forall = gtk_menu_shell_forall;
container_class->child_type = gtk_menu_shell_child_type;
klass->submenu_placement = GTK_TOP_BOTTOM;
@ -201,7 +194,6 @@ gtk_menu_shell_class_init (GtkMenuShellClass *klass)
klass->activate_current = gtk_real_menu_shell_activate_current;
klass->cancel = gtk_real_menu_shell_cancel;
klass->select_item = gtk_menu_shell_real_select_item;
klass->insert = gtk_menu_shell_real_insert;
klass->move_selected = gtk_menu_shell_real_move_selected;
/**
@ -555,19 +547,6 @@ gtk_menu_shell_insert (GtkMenuShell *menu_shell,
g_signal_emit (menu_shell, menu_shell_signals[INSERT], 0, child, position);
}
static void
gtk_menu_shell_real_insert (GtkMenuShell *menu_shell,
GtkWidget *child,
gint position)
{
GtkMenuShellPrivate *priv = menu_shell->priv;
priv->children = g_list_insert (priv->children, child, position);
if (gtk_widget_get_parent (child) == NULL)
gtk_widget_set_parent (child, GTK_WIDGET (menu_shell));
}
/**
* gtk_menu_shell_deactivate:
* @menu_shell: a #GtkMenuShell
@ -656,16 +635,16 @@ click_pressed (GtkGestureClick *gesture,
GtkMenuShellPrivate *priv = menu_shell->priv;
GtkWidget *menu_item;
GdkEvent *event;
GtkWidget *item_shell;
GtkMenuShell *item_shell;
event = gtk_get_current_event ();
menu_item = gtk_get_event_target_with_type (event, GTK_TYPE_MENU_ITEM);
if (menu_item)
item_shell = gtk_widget_get_ancestor (GTK_WIDGET (menu_item), GTK_TYPE_MENU_SHELL);
item_shell = gtk_menu_item_get_menu_shell (GTK_MENU_ITEM (menu_item));
if (menu_item &&
_gtk_menu_item_is_selectable (menu_item) &&
item_shell == GTK_WIDGET (menu_shell))
item_shell == menu_shell)
{
if (menu_item != menu_shell->priv->active_menu_item)
{
@ -702,7 +681,7 @@ click_pressed (GtkGestureClick *gesture,
if (menu_item)
{
if (_gtk_menu_item_is_selectable (menu_item) &&
item_shell == GTK_WIDGET (menu_shell) &&
item_shell == menu_shell &&
menu_item != priv->active_menu_item)
{
priv->active = TRUE;
@ -798,7 +777,7 @@ click_released (GtkGestureClick *gesture,
if (menu_item)
{
GtkWidget *submenu = GTK_MENU_ITEM (menu_item)->priv->submenu;
GtkWidget *parent_menu_item_shell = gtk_widget_get_parent (menu_item);
GtkMenuShell *parent_menu_item_shell = gtk_menu_item_get_menu_shell (GTK_MENU_ITEM (menu_item));
if (!_gtk_menu_item_is_selectable (GTK_WIDGET (menu_item)))
return;
@ -967,46 +946,14 @@ gtk_menu_shell_remove (GtkContainer *container,
{
GtkMenuShell *menu_shell = GTK_MENU_SHELL (container);
GtkMenuShellPrivate *priv = menu_shell->priv;
gint was_visible;
was_visible = gtk_widget_get_visible (widget);
priv->children = g_list_remove (priv->children, widget);
if (widget == priv->active_menu_item)
{
g_signal_emit_by_name (priv->active_menu_item, "deselect");
priv->active_menu_item = NULL;
}
gtk_widget_unparent (widget);
/* Queue resize regardless of gtk_widget_get_visible (container),
* since that's what is needed by toplevels.
*/
if (was_visible)
gtk_widget_queue_resize (GTK_WIDGET (container));
}
static void
gtk_menu_shell_forall (GtkContainer *container,
GtkCallback callback,
gpointer callback_data)
{
GtkMenuShell *menu_shell = GTK_MENU_SHELL (container);
GtkWidget *child;
GList *children;
children = menu_shell->priv->children;
while (children)
{
child = children->data;
children = children->next;
(* callback) (child, callback_data);
}
}
static void
gtk_real_menu_shell_deactivate (GtkMenuShell *menu_shell)
{
@ -1197,7 +1144,7 @@ gtk_menu_shell_activate_item (GtkMenuShell *menu_shell,
g_object_unref (menu_item);
}
static GList *
GList *
gtk_menu_shell_get_items (GtkMenuShell *menu_shell)
{
return GTK_MENU_SHELL_GET_CLASS (menu_shell)->get_items (menu_shell);
@ -1440,13 +1387,13 @@ gtk_real_menu_shell_move_current (GtkMenuShell *menu_shell,
case GTK_MENU_DIR_PREV:
gtk_menu_shell_move_selected (menu_shell, -1);
if (!had_selection && !priv->active_menu_item && priv->children)
if (!had_selection && !priv->active_menu_item)
_gtk_menu_shell_select_last (menu_shell, TRUE);
break;
case GTK_MENU_DIR_NEXT:
gtk_menu_shell_move_selected (menu_shell, 1);
if (!had_selection && !priv->active_menu_item && priv->children)
if (!had_selection && !priv->active_menu_item)
gtk_menu_shell_select_first (menu_shell, TRUE);
break;

View File

@ -75,6 +75,7 @@ struct _GtkMenuShellClass
gint (*get_popup_delay) (GtkMenuShell *menu_shell);
gboolean (*move_selected) (GtkMenuShell *menu_shell,
gint distance);
GList * (*get_items) (GtkMenuShell *menu_shell);
/*< private >*/
gpointer padding[8];

View File

@ -36,8 +36,6 @@ typedef enum
struct _GtkMenuShellPrivate
{
GList *children;
GtkWidget *active_menu_item; /* This is not an "active" menu item
* (there is no such thing) but rather,
* the selected menu item in that MenuShell,
@ -92,6 +90,7 @@ void _gtk_menu_shell_update_mnemonics (GtkMenuShell *menu_shell);
void _gtk_menu_shell_set_keyboard_mode (GtkMenuShell *menu_shell,
gboolean keyboard_mode);
gboolean _gtk_menu_shell_get_keyboard_mode (GtkMenuShell *menu_shell);
GList *gtk_menu_shell_get_items (GtkMenuShell *menu_shell);
G_END_DECLS

View File

@ -800,6 +800,7 @@ row_changed_cb (GtkTreeModel *model,
GtkTreeMenuPrivate *priv = menu->priv;
gboolean is_separator = FALSE;
GtkWidget *item;
GList *children;
item = gtk_tree_menu_get_path_item (menu, path);
@ -814,7 +815,9 @@ row_changed_cb (GtkTreeModel *model,
{
/* Destroy the header item and then the following separator */
gtk_widget_destroy (item);
gtk_widget_destroy (GTK_MENU_SHELL (menu)->priv->children->data);
children = gtk_menu_shell_get_items (GTK_MENU_SHELL (menu));
gtk_widget_destroy (children->data);
g_list_free (children);
priv->menu_with_header = FALSE;
}
@ -885,6 +888,7 @@ area_apply_attributes_cb (GtkCellArea *area,
GtkWidget *item;
gboolean is_header;
gboolean sensitive;
GList *children;
path = gtk_tree_model_get_path (tree_model, iter);
@ -905,14 +909,14 @@ area_apply_attributes_cb (GtkCellArea *area,
/* For header items we need to set the sensitivity
* of the following separator item
*/
if (GTK_MENU_SHELL (menu)->priv->children &&
GTK_MENU_SHELL (menu)->priv->children->next)
children = gtk_menu_shell_get_items (GTK_MENU_SHELL (menu));
if (children && children->next)
{
GtkWidget *separator =
GTK_MENU_SHELL (menu)->priv->children->next->data;
GtkWidget *separator = children->next->data;
gtk_widget_set_sensitive (separator, sensitive);
}
g_list_free (children);
}
}
}

View File

@ -2025,7 +2025,7 @@ menubar,
&:backdrop { background-color: $backdrop_bg_color; }
> menuitem {
> box > menuitem {
min-height: 16px;
padding: 4px 8px;