allow accel activation depending on sensitivity and the attach widget.

Thu Nov 27 16:19:03 2003  Tim Janik  <timj@gtk.org>

        * gtk/gtkmenu.c: allow accel activation depending on sensitivity
        and the attach widget.

        * gtk/gtkmenuitem.c: allow accel activation depending on visibility,
        sensitivity and the parent menu.

        * gtk/gtkwidget.[hc]: introduced ::can-activate-accel signal which
        checks whether accelerators may activate a widget. the default handler
        demands the widget be sensitive and visible+viewable.

        * gtk/gtkaccelgroup.[hc]: export gtk_accel_group_activate().
This commit is contained in:
Tim Janik 2003-11-27 15:51:32 +00:00 committed by Tim Janik
parent 6e63e7f75a
commit 448b576dc1
12 changed files with 156 additions and 16 deletions

View File

@ -1,3 +1,17 @@
Thu Nov 27 16:19:03 2003 Tim Janik <timj@gtk.org>
* gtk/gtkmenu.c: allow accel activation depending on sensitivity
and the attach widget.
* gtk/gtkmenuitem.c: allow accel activation depending on visibility,
sensitivity and the parent menu.
* gtk/gtkwidget.[hc]: introduced ::can-activate-accel signal which
checks whether accelerators may activate a widget. the default handler
demands the widget be sensitive and visible+viewable.
* gtk/gtkaccelgroup.[hc]: export gtk_accel_group_activate().
Tue Nov 25 00:10:05 2003 Matthias Clasen <maclas@gmx.de>
* gtk/gtkuimanager.c (update_node): Don't show accelerators in

View File

@ -1,3 +1,17 @@
Thu Nov 27 16:19:03 2003 Tim Janik <timj@gtk.org>
* gtk/gtkmenu.c: allow accel activation depending on sensitivity
and the attach widget.
* gtk/gtkmenuitem.c: allow accel activation depending on visibility,
sensitivity and the parent menu.
* gtk/gtkwidget.[hc]: introduced ::can-activate-accel signal which
checks whether accelerators may activate a widget. the default handler
demands the widget be sensitive and visible+viewable.
* gtk/gtkaccelgroup.[hc]: export gtk_accel_group_activate().
Tue Nov 25 00:10:05 2003 Matthias Clasen <maclas@gmx.de>
* gtk/gtkuimanager.c (update_node): Don't show accelerators in

View File

@ -1,3 +1,17 @@
Thu Nov 27 16:19:03 2003 Tim Janik <timj@gtk.org>
* gtk/gtkmenu.c: allow accel activation depending on sensitivity
and the attach widget.
* gtk/gtkmenuitem.c: allow accel activation depending on visibility,
sensitivity and the parent menu.
* gtk/gtkwidget.[hc]: introduced ::can-activate-accel signal which
checks whether accelerators may activate a widget. the default handler
demands the widget be sensitive and visible+viewable.
* gtk/gtkaccelgroup.[hc]: export gtk_accel_group_activate().
Tue Nov 25 00:10:05 2003 Matthias Clasen <maclas@gmx.de>
* gtk/gtkuimanager.c (update_node): Don't show accelerators in

View File

@ -1,3 +1,17 @@
Thu Nov 27 16:19:03 2003 Tim Janik <timj@gtk.org>
* gtk/gtkmenu.c: allow accel activation depending on sensitivity
and the attach widget.
* gtk/gtkmenuitem.c: allow accel activation depending on visibility,
sensitivity and the parent menu.
* gtk/gtkwidget.[hc]: introduced ::can-activate-accel signal which
checks whether accelerators may activate a widget. the default handler
demands the widget be sensitive and visible+viewable.
* gtk/gtkaccelgroup.[hc]: export gtk_accel_group_activate().
Tue Nov 25 00:10:05 2003 Matthias Clasen <maclas@gmx.de>
* gtk/gtkuimanager.c (update_node): Don't show accelerators in

View File

@ -1,3 +1,17 @@
Thu Nov 27 16:19:03 2003 Tim Janik <timj@gtk.org>
* gtk/gtkmenu.c: allow accel activation depending on sensitivity
and the attach widget.
* gtk/gtkmenuitem.c: allow accel activation depending on visibility,
sensitivity and the parent menu.
* gtk/gtkwidget.[hc]: introduced ::can-activate-accel signal which
checks whether accelerators may activate a widget. the default handler
demands the widget be sensitive and visible+viewable.
* gtk/gtkaccelgroup.[hc]: export gtk_accel_group_activate().
Tue Nov 25 00:10:05 2003 Matthias Clasen <maclas@gmx.de>
* gtk/gtkuimanager.c (update_node): Don't show accelerators in

View File

@ -718,16 +718,17 @@ gtk_accel_group_from_accel_closure (GClosure *closure)
}
gboolean
_gtk_accel_group_activate (GtkAccelGroup *accel_group,
GQuark accel_quark,
GObject *acceleratable,
guint accel_key,
GdkModifierType accel_mods)
gtk_accel_group_activate (GtkAccelGroup *accel_group,
GQuark accel_quark,
GObject *acceleratable,
guint accel_key,
GdkModifierType accel_mods)
{
gboolean was_handled;
g_return_val_if_fail (GTK_IS_ACCEL_GROUP (accel_group), FALSE);
g_return_val_if_fail (G_IS_OBJECT (acceleratable), FALSE);
was_handled = FALSE;
g_signal_emit (accel_group, signal_accel_activate, accel_quark,
acceleratable, accel_key, accel_mods, &was_handled);
@ -767,7 +768,7 @@ gtk_accel_groups_activate (GObject *object,
g_free (accel_name);
for (slist = gtk_accel_groups_from_object (object); slist; slist = slist->next)
if (_gtk_accel_group_activate (slist->data, accel_quark, object, accel_key, accel_mods))
if (gtk_accel_group_activate (slist->data, accel_quark, object, accel_key, accel_mods))
return TRUE;
}

View File

@ -118,6 +118,11 @@ gboolean gtk_accel_group_disconnect (GtkAccelGroup *accel_group,
gboolean gtk_accel_group_disconnect_key (GtkAccelGroup *accel_group,
guint accel_key,
GdkModifierType accel_mods);
gboolean gtk_accel_group_activate (GtkAccelGroup *accel_group,
GQuark accel_quark,
GObject *acceleratable,
guint accel_key,
GdkModifierType accel_mods);
/* --- GtkActivatable glue --- */

View File

@ -33,6 +33,7 @@ BOOLEAN:OBJECT,BOXED,BOXED
BOOLEAN:OBJECT,STRING,STRING
BOOLEAN:INT,INT
BOOLEAN:INT,INT,INT
BOOLEAN:UINT
BOOLEAN:VOID
BOOLEAN:BOOLEAN
BOOLEAN:NONE

View File

@ -215,6 +215,8 @@ static void gtk_menu_update_title (GtkMenu *menu);
static void menu_grab_transfer_window_destroy (GtkMenu *menu);
static GdkWindow *menu_grab_transfer_window_get (GtkMenu *menu);
static gboolean gtk_menu_real_can_activate_accel (GtkWidget *widget,
guint signal_id);
static void _gtk_menu_refresh_accel_paths (GtkMenu *menu,
gboolean group_changed);
@ -318,6 +320,7 @@ gtk_menu_class_init (GtkMenuClass *class)
widget_class->motion_notify_event = gtk_menu_motion_notify;
widget_class->style_set = gtk_menu_style_set;
widget_class->focus = gtk_menu_focus;
widget_class->can_activate_accel = gtk_menu_real_can_activate_accel;
container_class->remove = gtk_menu_remove;
container_class->get_child_property = gtk_menu_get_child_property;
@ -1416,6 +1419,19 @@ gtk_menu_get_accel_group (GtkMenu *menu)
return menu->accel_group;
}
static gboolean
gtk_menu_real_can_activate_accel (GtkWidget *widget,
guint signal_id)
{
/* menu items chain here to figure whether they can activate their accelerators.
* despite ordinary widgets, menus allow accel activation even if invisible
* since that's the usual case for submenus/popup-menus. however, the state
* of the attch widget affects "activeness" of the menu.
*/
GtkWidget *awidget = gtk_menu_get_attach_widget (GTK_MENU (widget));
return awidget ? gtk_widget_can_activate_accel (awidget, signal_id) : GTK_WIDGET_IS_SENSITIVE (widget);
}
/**
* gtk_menu_set_accel_path
* @menu: a valid #GtkMenu

View File

@ -89,6 +89,8 @@ static void gtk_menu_item_forall (GtkContainer *container,
gboolean include_internals,
GtkCallback callback,
gpointer callback_data);
static gboolean gtk_menu_item_real_can_activate_accel (GtkWidget *widget,
guint signal_id);
static GtkItemClass *parent_class;
@ -147,6 +149,7 @@ gtk_menu_item_class_init (GtkMenuItemClass *klass)
widget_class->hide_all = gtk_menu_item_hide_all;
widget_class->mnemonic_activate = gtk_menu_item_mnemonic_activate;
widget_class->parent_set = gtk_menu_item_parent_set;
widget_class->can_activate_accel = gtk_menu_item_real_can_activate_accel;
container_class->forall = gtk_menu_item_forall;
@ -1214,6 +1217,15 @@ gtk_menu_item_hide_all (GtkWidget *widget)
gtk_widget_hide_all (menu_item->submenu);
}
static gboolean
gtk_menu_item_real_can_activate_accel (GtkWidget *widget,
guint signal_id)
{
/* defer to parent menu to allow accel activation */
return (GTK_WIDGET_IS_SENSITIVE (widget) && GTK_WIDGET_VISIBLE (widget) &&
widget->parent && gtk_widget_can_activate_accel (widget->parent, signal_id));
}
static void
gtk_menu_item_accel_name_foreach (GtkWidget *widget,
gpointer data)

View File

@ -117,6 +117,7 @@ enum {
SHOW_HELP,
ACCEL_CLOSURES_CHANGED,
SCREEN_CHANGED,
CAN_ACTIVATE_ACCEL,
LAST_SIGNAL
};
@ -218,7 +219,9 @@ static void gtk_widget_invalidate_widget_windows (GtkWidget
GdkRegion *region);
static GdkScreen * gtk_widget_get_screen_unchecked (GtkWidget *widget);
static void gtk_widget_queue_shallow_draw (GtkWidget *widget);
static gboolean gtk_widget_real_can_activate_accel (GtkWidget *widget,
guint signal_id);
static void gtk_widget_set_usize_internal (GtkWidget *widget,
gint width,
gint height);
@ -388,6 +391,7 @@ gtk_widget_class_init (GtkWidgetClass *klass)
klass->drag_drop = NULL;
klass->drag_data_received = NULL;
klass->screen_changed = NULL;
klass->can_activate_accel = gtk_widget_real_can_activate_accel;
klass->show_help = gtk_widget_real_show_help;
@ -1309,7 +1313,15 @@ gtk_widget_class_init (GtkWidgetClass *klass)
_gtk_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
GDK_TYPE_SCREEN);
widget_signals[CAN_ACTIVATE_ACCEL] =
g_signal_new ("can_activate_accel",
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, can_activate_accel),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__UINT,
G_TYPE_BOOLEAN, 1, G_TYPE_UINT);
binding_set = gtk_binding_set_by_class (klass);
gtk_binding_entry_add_signal (binding_set, GDK_F10, GDK_SHIFT_MASK,
"popup_menu", 0);
@ -2884,6 +2896,24 @@ gtk_widget_real_size_allocate (GtkWidget *widget,
}
}
static gboolean
gtk_widget_real_can_activate_accel (GtkWidget *widget,
guint signal_id)
{
/* widgets must be onscreen for accels to take effect */
return GTK_WIDGET_IS_SENSITIVE (widget) && GTK_WIDGET_DRAWABLE (widget) && gdk_window_is_viewable (widget->window);
}
gboolean
gtk_widget_can_activate_accel (GtkWidget *widget,
guint signal_id)
{
gboolean can_activate = FALSE;
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
g_signal_emit (widget, widget_signals[CAN_ACTIVATE_ACCEL], 0, signal_id, &can_activate);
return can_activate;
}
typedef struct {
GClosure closure;
guint signal_id;
@ -2898,12 +2928,13 @@ closure_accel_activate (GClosure *closure,
gpointer marshal_data)
{
AccelClosure *aclosure = (AccelClosure*) closure;
gboolean can_activate = gtk_widget_can_activate_accel (closure->data, aclosure->signal_id);
if (GTK_WIDGET_IS_SENSITIVE (closure->data))
if (can_activate)
g_signal_emit (closure->data, aclosure->signal_id, 0);
/* we handled the accelerator */
g_value_set_boolean (return_value, TRUE);
/* wether accelerator was handled */
g_value_set_boolean (return_value, can_activate);
}
static void

View File

@ -399,12 +399,14 @@ struct _GtkWidgetClass
/* accessibility support
*/
AtkObject* (* get_accessible) (GtkWidget *widget);
AtkObject* (*get_accessible) (GtkWidget *widget);
void (*screen_changed) (GtkWidget *widget,
GdkScreen *previous_screen);
gboolean (*can_activate_accel) (GtkWidget *widget,
guint signal_id);
void (* screen_changed) (GtkWidget *widget,
GdkScreen *previous_screen);
/* Padding for future expansion */
void (*_gtk_reserved1) (void);
void (*_gtk_reserved2) (void);
void (*_gtk_reserved3) (void);
void (*_gtk_reserved4) (void);
@ -503,6 +505,8 @@ void gtk_widget_set_accel_path (GtkWidget *widget,
const gchar* _gtk_widget_get_accel_path (GtkWidget *widget,
gboolean *locked);
GList* gtk_widget_list_accel_closures (GtkWidget *widget);
gboolean gtk_widget_can_activate_accel (GtkWidget *widget,
guint signal_id);
gboolean gtk_widget_mnemonic_activate (GtkWidget *widget,
gboolean group_cycling);
gboolean gtk_widget_event (GtkWidget *widget,