Merge branch 'ebassi/activate-signal' into 'master'

Add accessors for GtkWidgetClass.activate_signal

See merge request GNOME/gtk!2925
This commit is contained in:
Emmanuele Bassi 2020-12-07 15:23:55 +00:00
commit 606cb51293
15 changed files with 146 additions and 29 deletions

View File

@ -4366,6 +4366,9 @@ gtk_widget_class_add_binding_signal
gtk_widget_class_add_binding_action
gtk_widget_class_set_layout_manager_type
gtk_widget_class_get_layout_manager_type
gtk_widget_class_set_activate_signal
gtk_widget_class_set_activate_signal_from_name
gtk_widget_class_get_activate_signal
gtk_widget_activate
gtk_widget_is_focus
gtk_widget_grab_focus

View File

@ -282,9 +282,10 @@ gtk_button_class_init (GtkButtonClass *klass)
NULL, NULL,
NULL,
G_TYPE_NONE, 0);
widget_class->activate_signal = button_signals[ACTIVATE];
activate_action = gtk_signal_action_new ("activate");
gtk_widget_class_set_activate_signal (widget_class, button_signals[ACTIVATE]);
activate_action = gtk_signal_action_new ("activate");
for (guint i = 0; i < G_N_ELEMENTS (activate_keyvals); i++)
{
GtkShortcut *activate_shortcut = gtk_shortcut_new (gtk_keyval_trigger_new (activate_keyvals[i], 0),

View File

@ -324,7 +324,7 @@ add_response_data (GtkDialog *dialog,
if (GTK_IS_BUTTON (child))
signal_id = g_signal_lookup ("clicked", GTK_TYPE_BUTTON);
else
signal_id = GTK_WIDGET_GET_CLASS (child)->activate_signal;
signal_id = gtk_widget_class_get_activate_signal (GTK_WIDGET_GET_CLASS (child));
if (signal_id)
{
@ -1287,7 +1287,7 @@ gtk_dialog_buildable_custom_finished (GtkBuildable *buildable,
if (GTK_IS_BUTTON (object))
signal_id = g_signal_lookup ("clicked", GTK_TYPE_BUTTON);
else
signal_id = GTK_WIDGET_GET_CLASS (object)->activate_signal;
signal_id = gtk_widget_class_get_activate_signal (GTK_WIDGET_GET_CLASS (object));
if (signal_id && !is_action)
{

View File

@ -292,6 +292,7 @@ gtk_expander_class_init (GtkExpanderClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
guint activate_signal;
gobject_class->dispose = gtk_expander_dispose;
gobject_class->set_property = gtk_expander_set_property;
@ -368,7 +369,7 @@ gtk_expander_class_init (GtkExpanderClass *klass)
GTK_TYPE_WIDGET,
GTK_PARAM_READWRITE));
widget_class->activate_signal =
activate_signal =
g_signal_new (I_("activate"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
@ -377,6 +378,7 @@ gtk_expander_class_init (GtkExpanderClass *klass)
NULL,
G_TYPE_NONE, 0);
gtk_widget_class_set_activate_signal (widget_class, activate_signal);
gtk_widget_class_set_css_name (widget_class, I_("expander-widget"));
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_BUTTON);
}

View File

@ -547,11 +547,11 @@ gtk_flow_box_child_class_init (GtkFlowBoxChildClass *class)
NULL, NULL,
NULL,
G_TYPE_NONE, 0);
widget_class->activate_signal = child_signals[CHILD_ACTIVATE];
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
gtk_widget_class_set_css_name (widget_class, I_("flowboxchild"));
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_GRID_CELL);
gtk_widget_class_set_activate_signal (widget_class, child_signals[CHILD_ACTIVATE]);
}
static void
@ -3837,7 +3837,7 @@ gtk_flow_box_class_init (GtkFlowBoxClass *class)
NULL,
G_TYPE_NONE, 0);
widget_class->activate_signal = signals[ACTIVATE_CURSOR_CHILD];
gtk_widget_class_set_activate_signal (widget_class, signals[ACTIVATE_CURSOR_CHILD]);
gtk_flow_box_add_move_binding (widget_class, GDK_KEY_Home, 0,
GTK_MOVEMENT_BUFFER_ENDS, -1);

View File

@ -551,7 +551,7 @@ gtk_info_bar_add_action_widget (GtkInfoBar *info_bar,
if (GTK_IS_BUTTON (child))
signal_id = g_signal_lookup ("clicked", GTK_TYPE_BUTTON);
else
signal_id = GTK_WIDGET_GET_CLASS (child)->activate_signal;
signal_id = gtk_widget_class_get_activate_signal (GTK_WIDGET_GET_CLASS (child));
if (signal_id)
{
@ -1019,7 +1019,7 @@ gtk_info_bar_buildable_custom_finished (GtkBuildable *buildable,
if (GTK_IS_BUTTON (object))
signal_id = g_signal_lookup ("clicked", GTK_TYPE_BUTTON);
else
signal_id = GTK_WIDGET_GET_CLASS (object)->activate_signal;
signal_id = gtk_widget_class_get_activate_signal (GTK_WIDGET_GET_CLASS (object));
if (signal_id)
{

View File

@ -1452,7 +1452,7 @@ gtk_label_mnemonic_activate (GtkWidget *widget,
while (parent)
{
if (gtk_widget_get_can_focus (parent) ||
(!group_cycling && GTK_WIDGET_GET_CLASS (parent)->activate_signal) ||
(!group_cycling && gtk_widget_can_activate (parent)) ||
GTK_IS_NOTEBOOK (gtk_widget_get_parent (parent)))
return gtk_widget_mnemonic_activate (parent, group_cycling);
parent = gtk_widget_get_parent (parent);

View File

@ -637,7 +637,7 @@ gtk_list_box_class_init (GtkListBoxClass *klass)
G_TYPE_FROM_CLASS (klass),
_gtk_marshal_VOID__ENUM_INT_BOOLEAN_BOOLEANv);
widget_class->activate_signal = signals[ACTIVATE_CURSOR_ROW];
gtk_widget_class_set_activate_signal (widget_class, signals[ACTIVATE_CURSOR_ROW]);
gtk_list_box_add_move_binding (widget_class, GDK_KEY_Home, 0,
GTK_MOVEMENT_BUFFER_ENDS, -1);
@ -3466,7 +3466,7 @@ gtk_list_box_row_class_init (GtkListBoxRowClass *klass)
NULL,
G_TYPE_NONE, 0);
widget_class->activate_signal = row_signals[ROW__ACTIVATE];
gtk_widget_class_set_activate_signal (widget_class, row_signals[ROW__ACTIVATE]);
/**
* GtkListBoxRow:activatable:

View File

@ -263,7 +263,7 @@ gtk_list_item_widget_class_init (GtkListItemWidgetClass *klass)
NULL,
G_TYPE_NONE, 0);
widget_class->activate_signal = signals[ACTIVATE_SIGNAL];
gtk_widget_class_set_activate_signal (widget_class, signals[ACTIVATE_SIGNAL]);
/**
* GtkListItem|listitem.select:

View File

@ -1295,8 +1295,7 @@ gtk_model_button_class_init (GtkModelButtonClass *class)
NULL,
G_TYPE_NONE, 0);
widget_class->activate_signal = signals[SIGNAL_CLICKED];
gtk_widget_class_set_activate_signal (widget_class, signals[SIGNAL_CLICKED]);
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BOX_LAYOUT);
gtk_widget_class_set_css_name (widget_class, I_("modelbutton"));
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_MENU_ITEM);

View File

@ -354,6 +354,7 @@ gtk_popover_menu_bar_item_class_init (GtkPopoverMenuBarItemClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
guint activate_signal;
object_class->dispose = gtk_popover_menu_bar_item_dispose;
object_class->finalize = gtk_popover_menu_bar_item_finalize;
@ -364,7 +365,7 @@ gtk_popover_menu_bar_item_class_init (GtkPopoverMenuBarItemClass *klass)
klass->activate = gtk_popover_menu_bar_item_activate;
widget_class->activate_signal =
activate_signal =
g_signal_new (I_("activate"),
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
@ -375,6 +376,7 @@ gtk_popover_menu_bar_item_class_init (GtkPopoverMenuBarItemClass *klass)
gtk_widget_class_set_css_name (widget_class, I_("item"));
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_MENU_ITEM);
gtk_widget_class_set_activate_signal (widget_class, activate_signal);
}
enum
{

View File

@ -570,7 +570,8 @@ gtk_switch_class_init (GtkSwitchClass *klass)
NULL, NULL,
NULL,
G_TYPE_NONE, 0);
widget_class->activate_signal = signals[ACTIVATE];
gtk_widget_class_set_activate_signal (widget_class, signals[ACTIVATE]);
/**
* GtkSwitch::state-set:

View File

@ -885,7 +885,6 @@ gtk_widget_class_init (GtkWidgetClass *klass)
gobject_class->set_property = gtk_widget_set_property;
gobject_class->get_property = gtk_widget_get_property;
klass->activate_signal = 0;
klass->show = gtk_widget_real_show;
klass->hide = gtk_widget_real_hide;
klass->map = gtk_widget_real_map;
@ -4296,11 +4295,31 @@ gtk_widget_mnemonic_activate (GtkWidget *widget,
return handled;
}
/*< private >
* gtk_widget_can_activate:
* @self: a #GtkWidget
*
* Checks whether a #GtkWidget can be activated using
* gtk_widget_activate().
*/
gboolean
gtk_widget_can_activate (GtkWidget *self)
{
g_return_val_if_fail (GTK_IS_WIDGET (self), FALSE);
GtkWidgetClass *widget_class = GTK_WIDGET_GET_CLASS (self);
if (widget_class->priv->activate_signal != 0)
return TRUE;
return FALSE;
}
static gboolean
gtk_widget_real_mnemonic_activate (GtkWidget *widget,
gboolean group_cycling)
{
if (!group_cycling && GTK_WIDGET_GET_CLASS (widget)->activate_signal)
if (!group_cycling && gtk_widget_can_activate (widget))
gtk_widget_activate (widget);
else if (gtk_widget_get_can_focus (widget))
return gtk_widget_grab_focus (widget);
@ -4562,14 +4581,96 @@ gtk_widget_event (GtkWidget *widget,
return return_val;
}
/**
* gtk_widget_class_get_activate_signal:
* @widget_class: a #GtkWidgetClass
*
* Retrieves the signal id for the activation signal set using
* gtk_widget_class_set_activate_signal().
*
* Returns: a signal id, or 0 if the widget class does not
* specify an activation signal
*/
guint
gtk_widget_class_get_activate_signal (GtkWidgetClass *widget_class)
{
g_return_val_if_fail (GTK_IS_WIDGET_CLASS (widget_class), 0);
return widget_class->priv->activate_signal;
}
/**
* gtk_widget_class_set_activate_signal:
* @widget_class: a #GtkWidgetClass
* @signal_id: the id for the activate signal
*
* Sets the #GtkWidgetClass.activate_signal field with the
* given @signal_id; the signal will be emitted when calling
* gtk_widget_activate().
*
* The @signal_id must have been registered with g_signal_new()
* or g_signal_newv() before calling this function.
*/
void
gtk_widget_class_set_activate_signal (GtkWidgetClass *widget_class,
guint signal_id)
{
g_return_if_fail (GTK_IS_WIDGET_CLASS (widget_class));
g_return_if_fail (signal_id != 0);
widget_class->priv->activate_signal = signal_id;
}
/**
* gtk_widget_class_set_activate_signal_from_name:
* @widget_class: a #GtkWidgetClass
* @signal_name: the name of the activate signal of @widget_type
*
* Sets the #GtkWidgetClass.activate_signal field with the signal id for
* the given @signal_name; the signal will be emitted when calling
* gtk_widget_activate().
*
* The @signal_name of @widget_type must have been registered with
* g_signal_new() or g_signal_newv() before calling this function.
*/
void
gtk_widget_class_set_activate_signal_from_name (GtkWidgetClass *widget_class,
const char *signal_name)
{
guint signal_id;
g_return_if_fail (GTK_IS_WIDGET_CLASS (widget_class));
g_return_if_fail (signal_name != NULL);
signal_id = g_signal_lookup (signal_name, G_TYPE_FROM_CLASS (widget_class));
if (signal_id == 0)
{
g_critical ("Widget type “%s” does not have a “%s” signal",
G_OBJECT_CLASS_NAME (widget_class),
signal_name);
return;
}
widget_class->priv->activate_signal = signal_id;
}
/**
* gtk_widget_activate:
* @widget: a #GtkWidget thats activatable
*
* For widgets that can be activated (buttons, menu items, etc.)
* this function activates them. Activation is what happens when you
* press Enter on a widget during key navigation. If @widget isn't
* activatable, the function returns %FALSE.
* this function activates them. The activation will emit the signal
* set using gtk_widget_class_set_activate_signal() during class
* initialization.
*
* Activation is what happens when you press Enter on a widget during
* key navigation.
*
* If you wish to handle the activation keybinding yourself, it is
* recommended to use gtk_widget_class_add_shortcut() with an action
* created with gtk_signal_action_new().
*
* If @widget isn't activatable, the function returns %FALSE.
*
* Returns: %TRUE if the widget was activatable
**/
@ -4578,10 +4679,11 @@ gtk_widget_activate (GtkWidget *widget)
{
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
if (GTK_WIDGET_GET_CLASS (widget)->activate_signal)
if (gtk_widget_can_activate (widget))
{
GtkWidgetClass *widget_class = GTK_WIDGET_GET_CLASS (widget);
/* FIXME: we should eventually check the signals signature here */
g_signal_emit (widget, GTK_WIDGET_GET_CLASS (widget)->activate_signal, 0);
g_signal_emit (widget, widget_class->priv->activate_signal, 0);
return TRUE;
}

View File

@ -120,9 +120,6 @@ struct _GtkWidget
* element in the widget class structure in order for the class mechanism
* to work correctly. This allows a GtkWidgetClass pointer to be cast to
* a GObjectClass pointer.
* @activate_signal: The signal to emit when a widget of this class is
* activated, gtk_widget_activate() handles the emission.
* Implementation of this signal is optional.
* @show: Signal emitted when widget is shown
* @hide: Signal emitted when widget is hidden.
* @map: Signal emitted when widget is going to be mapped, that is
@ -194,8 +191,6 @@ struct _GtkWidgetClass
/*< public >*/
guint activate_signal;
/* basics */
void (* show) (GtkWidget *widget);
void (* hide) (GtkWidget *widget);
@ -364,6 +359,15 @@ GDK_AVAILABLE_IN_ALL
void gtk_widget_class_add_shortcut (GtkWidgetClass *widget_class,
GtkShortcut *shortcut);
GDK_AVAILABLE_IN_ALL
void gtk_widget_class_set_activate_signal (GtkWidgetClass *widget_class,
guint signal_id);
GDK_AVAILABLE_IN_ALL
void gtk_widget_class_set_activate_signal_from_name (GtkWidgetClass *widget_class,
const char *signal_name);
GDK_AVAILABLE_IN_ALL
guint gtk_widget_class_get_activate_signal (GtkWidgetClass *widget_class);
GDK_AVAILABLE_IN_ALL
gboolean gtk_widget_mnemonic_activate (GtkWidget *widget,
gboolean group_cycling);

View File

@ -215,6 +215,7 @@ struct _GtkWidgetClassPrivate
GType layout_manager_type;
GtkWidgetAction *actions;
GtkAccessibleRole accessible_role;
guint activate_signal;
};
void gtk_widget_root (GtkWidget *widget);
@ -356,6 +357,8 @@ guint gtk_widget_add_surface_transform_changed_callback (GtkWidget
void gtk_widget_remove_surface_transform_changed_callback (GtkWidget *widget,
guint id);
gboolean gtk_widget_can_activate (GtkWidget *widget);
/* focus vfuncs for non-focusable containers with focusable children */
gboolean gtk_widget_grab_focus_child (GtkWidget *widget);
gboolean gtk_widget_focus_child (GtkWidget *widget,