forked from AuroraMiddleware/gtk
Install accelerators on actions, not on proxies, support accelerator-only
2003-09-18 Matthias Clasen <maclas@gmx.de> Install accelerators on actions, not on proxies, support accelerator-only actions: * gtk/gtkmenu.c (get_accel_path): New function to get the accel path and its lock status either via _gtk_widget_get_accel_path() or by looking at the accel_path stored in the menu item itself and determining its lock status by peeking into the contained accel label. This was already (accidentally) committed a week ago. * gtk/gtkaction.h (gtk_action_set_accel_group): (gtk_action_[dis]connect_accelerator): New functions. * gtk/gtkaction.c (struct _GtkActionPrivate): Add accel_group, accel_closure and accel_count. We must have a reference to the accel_group, since we need it in connect_proxy. The count is necessary to ensure that the accelerator isn't removed before the last proxy requesting it has been unmerged. (connect_proxy): Connect the accelerator to the action now, only set the accel_path on the menuitem. (remove_proxy): Disconnect the accelerator from the action, not from the menuitem. (gtk_action_set_accel_group): Set the accel group. (gtk_action_[dis]connect_accelerator): Count the number of times this functions have been called and install/remove the accelerator if the count leaves/reaches zero. * gtk/gtkuimanager.h (GtkUIManagerItemType): Add GTK_UI_MANAGER_ACCELERATOR. * gtk/gtkuimanager.c (NodeType): Add NODE_TYPE_ACCELERATOR. (start_element_handler): Create NODE_TYPE_ACCELERATOR nodes from <accelerator> elements. (gtk_ui_manager_add_ui): Create NODE_TYPE_ACCELERATOR nodes when type is GTK_UI_MANAGER_ACCELERATOR. (update_node): Set the accel group on actions before creating their proxies. Don't set the accel group on created menus. For NODE_TYPE_ACCELERATOR nodes, [dis]connect the actions' accelerator. (print_node): Also emit <accelerator> elements. * tests/testmerge.c (dump_accels): Add a "Dump Accels" button.
This commit is contained in:
parent
a7ad2a4663
commit
0ceb0db081
41
ChangeLog
41
ChangeLog
@ -1,5 +1,46 @@
|
||||
2003-09-18 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
Install accelerators on actions, not on proxies, support
|
||||
accelerator-only actions:
|
||||
|
||||
* gtk/gtkmenu.c (get_accel_path): New function to get the accel path
|
||||
and its lock status either via _gtk_widget_get_accel_path() or by
|
||||
looking at the accel_path stored in the menu item itself and determining
|
||||
its lock status by peeking into the contained accel label. This was
|
||||
already (accidentally) committed a week ago.
|
||||
|
||||
* gtk/gtkaction.h (gtk_action_set_accel_group):
|
||||
(gtk_action_[dis]connect_accelerator): New functions.
|
||||
|
||||
* gtk/gtkaction.c (struct _GtkActionPrivate): Add accel_group,
|
||||
accel_closure and accel_count. We must have a reference to the accel_group,
|
||||
since we need it in connect_proxy. The count is necessary to ensure
|
||||
that the accelerator isn't removed before the last proxy requesting
|
||||
it has been unmerged.
|
||||
(connect_proxy): Connect the accelerator to the
|
||||
action now, only set the accel_path on the menuitem.
|
||||
(remove_proxy): Disconnect the accelerator from the action, not from
|
||||
the menuitem.
|
||||
(gtk_action_set_accel_group): Set the accel group.
|
||||
(gtk_action_[dis]connect_accelerator): Count the number of times
|
||||
this functions have been called and install/remove the accelerator if
|
||||
the count leaves/reaches zero.
|
||||
|
||||
* gtk/gtkuimanager.h (GtkUIManagerItemType): Add
|
||||
GTK_UI_MANAGER_ACCELERATOR.
|
||||
|
||||
* gtk/gtkuimanager.c (NodeType): Add NODE_TYPE_ACCELERATOR.
|
||||
(start_element_handler): Create NODE_TYPE_ACCELERATOR nodes from
|
||||
<accelerator> elements.
|
||||
(gtk_ui_manager_add_ui): Create NODE_TYPE_ACCELERATOR nodes when
|
||||
type is GTK_UI_MANAGER_ACCELERATOR.
|
||||
(update_node): Set the accel group on actions before creating their
|
||||
proxies. Don't set the accel group on created menus. For
|
||||
NODE_TYPE_ACCELERATOR nodes, [dis]connect the actions' accelerator.
|
||||
(print_node): Also emit <accelerator> elements.
|
||||
|
||||
* tests/testmerge.c (dump_accels): Add a "Dump Accels" button.
|
||||
|
||||
* gtk/gtkuimanager.c (update_node): Robustness improvements.
|
||||
|
||||
2003-09-17 Matthias Clasen <maclas@gmx.de>
|
||||
|
@ -1,5 +1,46 @@
|
||||
2003-09-18 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
Install accelerators on actions, not on proxies, support
|
||||
accelerator-only actions:
|
||||
|
||||
* gtk/gtkmenu.c (get_accel_path): New function to get the accel path
|
||||
and its lock status either via _gtk_widget_get_accel_path() or by
|
||||
looking at the accel_path stored in the menu item itself and determining
|
||||
its lock status by peeking into the contained accel label. This was
|
||||
already (accidentally) committed a week ago.
|
||||
|
||||
* gtk/gtkaction.h (gtk_action_set_accel_group):
|
||||
(gtk_action_[dis]connect_accelerator): New functions.
|
||||
|
||||
* gtk/gtkaction.c (struct _GtkActionPrivate): Add accel_group,
|
||||
accel_closure and accel_count. We must have a reference to the accel_group,
|
||||
since we need it in connect_proxy. The count is necessary to ensure
|
||||
that the accelerator isn't removed before the last proxy requesting
|
||||
it has been unmerged.
|
||||
(connect_proxy): Connect the accelerator to the
|
||||
action now, only set the accel_path on the menuitem.
|
||||
(remove_proxy): Disconnect the accelerator from the action, not from
|
||||
the menuitem.
|
||||
(gtk_action_set_accel_group): Set the accel group.
|
||||
(gtk_action_[dis]connect_accelerator): Count the number of times
|
||||
this functions have been called and install/remove the accelerator if
|
||||
the count leaves/reaches zero.
|
||||
|
||||
* gtk/gtkuimanager.h (GtkUIManagerItemType): Add
|
||||
GTK_UI_MANAGER_ACCELERATOR.
|
||||
|
||||
* gtk/gtkuimanager.c (NodeType): Add NODE_TYPE_ACCELERATOR.
|
||||
(start_element_handler): Create NODE_TYPE_ACCELERATOR nodes from
|
||||
<accelerator> elements.
|
||||
(gtk_ui_manager_add_ui): Create NODE_TYPE_ACCELERATOR nodes when
|
||||
type is GTK_UI_MANAGER_ACCELERATOR.
|
||||
(update_node): Set the accel group on actions before creating their
|
||||
proxies. Don't set the accel group on created menus. For
|
||||
NODE_TYPE_ACCELERATOR nodes, [dis]connect the actions' accelerator.
|
||||
(print_node): Also emit <accelerator> elements.
|
||||
|
||||
* tests/testmerge.c (dump_accels): Add a "Dump Accels" button.
|
||||
|
||||
* gtk/gtkuimanager.c (update_node): Robustness improvements.
|
||||
|
||||
2003-09-17 Matthias Clasen <maclas@gmx.de>
|
||||
|
@ -1,5 +1,46 @@
|
||||
2003-09-18 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
Install accelerators on actions, not on proxies, support
|
||||
accelerator-only actions:
|
||||
|
||||
* gtk/gtkmenu.c (get_accel_path): New function to get the accel path
|
||||
and its lock status either via _gtk_widget_get_accel_path() or by
|
||||
looking at the accel_path stored in the menu item itself and determining
|
||||
its lock status by peeking into the contained accel label. This was
|
||||
already (accidentally) committed a week ago.
|
||||
|
||||
* gtk/gtkaction.h (gtk_action_set_accel_group):
|
||||
(gtk_action_[dis]connect_accelerator): New functions.
|
||||
|
||||
* gtk/gtkaction.c (struct _GtkActionPrivate): Add accel_group,
|
||||
accel_closure and accel_count. We must have a reference to the accel_group,
|
||||
since we need it in connect_proxy. The count is necessary to ensure
|
||||
that the accelerator isn't removed before the last proxy requesting
|
||||
it has been unmerged.
|
||||
(connect_proxy): Connect the accelerator to the
|
||||
action now, only set the accel_path on the menuitem.
|
||||
(remove_proxy): Disconnect the accelerator from the action, not from
|
||||
the menuitem.
|
||||
(gtk_action_set_accel_group): Set the accel group.
|
||||
(gtk_action_[dis]connect_accelerator): Count the number of times
|
||||
this functions have been called and install/remove the accelerator if
|
||||
the count leaves/reaches zero.
|
||||
|
||||
* gtk/gtkuimanager.h (GtkUIManagerItemType): Add
|
||||
GTK_UI_MANAGER_ACCELERATOR.
|
||||
|
||||
* gtk/gtkuimanager.c (NodeType): Add NODE_TYPE_ACCELERATOR.
|
||||
(start_element_handler): Create NODE_TYPE_ACCELERATOR nodes from
|
||||
<accelerator> elements.
|
||||
(gtk_ui_manager_add_ui): Create NODE_TYPE_ACCELERATOR nodes when
|
||||
type is GTK_UI_MANAGER_ACCELERATOR.
|
||||
(update_node): Set the accel group on actions before creating their
|
||||
proxies. Don't set the accel group on created menus. For
|
||||
NODE_TYPE_ACCELERATOR nodes, [dis]connect the actions' accelerator.
|
||||
(print_node): Also emit <accelerator> elements.
|
||||
|
||||
* tests/testmerge.c (dump_accels): Add a "Dump Accels" button.
|
||||
|
||||
* gtk/gtkuimanager.c (update_node): Robustness improvements.
|
||||
|
||||
2003-09-17 Matthias Clasen <maclas@gmx.de>
|
||||
|
@ -1,5 +1,46 @@
|
||||
2003-09-18 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
Install accelerators on actions, not on proxies, support
|
||||
accelerator-only actions:
|
||||
|
||||
* gtk/gtkmenu.c (get_accel_path): New function to get the accel path
|
||||
and its lock status either via _gtk_widget_get_accel_path() or by
|
||||
looking at the accel_path stored in the menu item itself and determining
|
||||
its lock status by peeking into the contained accel label. This was
|
||||
already (accidentally) committed a week ago.
|
||||
|
||||
* gtk/gtkaction.h (gtk_action_set_accel_group):
|
||||
(gtk_action_[dis]connect_accelerator): New functions.
|
||||
|
||||
* gtk/gtkaction.c (struct _GtkActionPrivate): Add accel_group,
|
||||
accel_closure and accel_count. We must have a reference to the accel_group,
|
||||
since we need it in connect_proxy. The count is necessary to ensure
|
||||
that the accelerator isn't removed before the last proxy requesting
|
||||
it has been unmerged.
|
||||
(connect_proxy): Connect the accelerator to the
|
||||
action now, only set the accel_path on the menuitem.
|
||||
(remove_proxy): Disconnect the accelerator from the action, not from
|
||||
the menuitem.
|
||||
(gtk_action_set_accel_group): Set the accel group.
|
||||
(gtk_action_[dis]connect_accelerator): Count the number of times
|
||||
this functions have been called and install/remove the accelerator if
|
||||
the count leaves/reaches zero.
|
||||
|
||||
* gtk/gtkuimanager.h (GtkUIManagerItemType): Add
|
||||
GTK_UI_MANAGER_ACCELERATOR.
|
||||
|
||||
* gtk/gtkuimanager.c (NodeType): Add NODE_TYPE_ACCELERATOR.
|
||||
(start_element_handler): Create NODE_TYPE_ACCELERATOR nodes from
|
||||
<accelerator> elements.
|
||||
(gtk_ui_manager_add_ui): Create NODE_TYPE_ACCELERATOR nodes when
|
||||
type is GTK_UI_MANAGER_ACCELERATOR.
|
||||
(update_node): Set the accel group on actions before creating their
|
||||
proxies. Don't set the accel group on created menus. For
|
||||
NODE_TYPE_ACCELERATOR nodes, [dis]connect the actions' accelerator.
|
||||
(print_node): Also emit <accelerator> elements.
|
||||
|
||||
* tests/testmerge.c (dump_accels): Add a "Dump Accels" button.
|
||||
|
||||
* gtk/gtkuimanager.c (update_node): Robustness improvements.
|
||||
|
||||
2003-09-17 Matthias Clasen <maclas@gmx.de>
|
||||
|
@ -1,5 +1,46 @@
|
||||
2003-09-18 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
Install accelerators on actions, not on proxies, support
|
||||
accelerator-only actions:
|
||||
|
||||
* gtk/gtkmenu.c (get_accel_path): New function to get the accel path
|
||||
and its lock status either via _gtk_widget_get_accel_path() or by
|
||||
looking at the accel_path stored in the menu item itself and determining
|
||||
its lock status by peeking into the contained accel label. This was
|
||||
already (accidentally) committed a week ago.
|
||||
|
||||
* gtk/gtkaction.h (gtk_action_set_accel_group):
|
||||
(gtk_action_[dis]connect_accelerator): New functions.
|
||||
|
||||
* gtk/gtkaction.c (struct _GtkActionPrivate): Add accel_group,
|
||||
accel_closure and accel_count. We must have a reference to the accel_group,
|
||||
since we need it in connect_proxy. The count is necessary to ensure
|
||||
that the accelerator isn't removed before the last proxy requesting
|
||||
it has been unmerged.
|
||||
(connect_proxy): Connect the accelerator to the
|
||||
action now, only set the accel_path on the menuitem.
|
||||
(remove_proxy): Disconnect the accelerator from the action, not from
|
||||
the menuitem.
|
||||
(gtk_action_set_accel_group): Set the accel group.
|
||||
(gtk_action_[dis]connect_accelerator): Count the number of times
|
||||
this functions have been called and install/remove the accelerator if
|
||||
the count leaves/reaches zero.
|
||||
|
||||
* gtk/gtkuimanager.h (GtkUIManagerItemType): Add
|
||||
GTK_UI_MANAGER_ACCELERATOR.
|
||||
|
||||
* gtk/gtkuimanager.c (NodeType): Add NODE_TYPE_ACCELERATOR.
|
||||
(start_element_handler): Create NODE_TYPE_ACCELERATOR nodes from
|
||||
<accelerator> elements.
|
||||
(gtk_ui_manager_add_ui): Create NODE_TYPE_ACCELERATOR nodes when
|
||||
type is GTK_UI_MANAGER_ACCELERATOR.
|
||||
(update_node): Set the accel group on actions before creating their
|
||||
proxies. Don't set the accel group on created menus. For
|
||||
NODE_TYPE_ACCELERATOR nodes, [dis]connect the actions' accelerator.
|
||||
(print_node): Also emit <accelerator> elements.
|
||||
|
||||
* tests/testmerge.c (dump_accels): Add a "Dump Accels" button.
|
||||
|
||||
* gtk/gtkuimanager.c (update_node): Robustness improvements.
|
||||
|
||||
2003-09-17 Matthias Clasen <maclas@gmx.de>
|
||||
|
@ -1,3 +1,8 @@
|
||||
2003-09-18 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* gtk/gtk-sections.txt:
|
||||
* gtk/tmpl/gtkuimanager.sgml: Updates for accelerator-only actions.
|
||||
|
||||
2003-09-16 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* gtk/tmpl/gtkaction.sgml:
|
||||
|
@ -110,9 +110,12 @@ gtk_action_create_tool_item
|
||||
gtk_action_connect_proxy
|
||||
gtk_action_disconnect_proxy
|
||||
gtk_action_get_proxies
|
||||
gtk_action_connect_accelerator
|
||||
gtk_action_disconnect_accelerator
|
||||
gtk_action_block_activate_from
|
||||
gtk_action_unblock_activate_from
|
||||
gtk_action_set_accel_path
|
||||
gtk_action_set_accel_group
|
||||
<SUBSECTION Standard>
|
||||
GTK_TYPE_ACTION
|
||||
GTK_ACTION
|
||||
|
@ -15,7 +15,7 @@ action groups.
|
||||
The UI definitions are specified in an XML format which can be
|
||||
roughly described by the following DTD.
|
||||
<programlisting>
|
||||
<!ELEMENT ui (menubar|toolbar|popup)* >
|
||||
<!ELEMENT ui (menubar|toolbar|popup|accelerator)* >
|
||||
<!ELEMENT menubar (menuitem|separator|placeholder|menu)* >
|
||||
<!ELEMENT menu (menuitem|separator|placeholder|menu)* >
|
||||
<!ELEMENT popup (menuitem|separator|placeholder|menu)* >
|
||||
@ -24,6 +24,7 @@ roughly described by the following DTD.
|
||||
<!ELEMENT menuitem EMPTY >
|
||||
<!ELEMENT toolitem EMPTY >
|
||||
<!ELEMENT separator EMPTY >
|
||||
<!ELEMENT accelerator EMPTY >
|
||||
<!ATTLIST menubar name #IMPLIED >
|
||||
<!ATTLIST toolbar name #IMPLIED >
|
||||
<!ATTLIST popup name #IMPLIED >
|
||||
@ -37,6 +38,8 @@ roughly described by the following DTD.
|
||||
<!ATTLIST toolitem name #IMPLIED
|
||||
action #REQUIRED
|
||||
position (top|bot) #IMPLIED >
|
||||
<!ATTLIST accelerator name #IMPLIED
|
||||
action #REQUIRED >
|
||||
</programlisting>
|
||||
There are some additional restrictions beyond those specified in the
|
||||
DTD, e.g. every toolitem must have a toolbar in its anchestry and
|
||||
@ -105,6 +108,9 @@ action</para></listitem>
|
||||
<listitem><para>a #GtkSeparatorMenuItem or
|
||||
#GtkSeparatorToolItem</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term>accelerator</term>
|
||||
<listitem><para>a keyboard accelerator</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
<para>
|
||||
@ -127,6 +133,16 @@ has the path <literal>/ui/menubar/JustifyMenu/Left</literal> and the
|
||||
toolitem with the same name has path
|
||||
<literal>/ui/toolbar1/JustifyToolItems/Left</literal>.
|
||||
</para>
|
||||
</refsect2>
|
||||
<refsect2>
|
||||
<title>Accelerators</title>
|
||||
<para>
|
||||
Every action has an accelerator path. Accelerators are installed together with
|
||||
menuitem proxies, but they can also be explicitly added with <accelerator>
|
||||
elements in the UI definition. This makes it possible to have accelerators for
|
||||
actions even if they have no visible proxies.
|
||||
</para>
|
||||
</refsect2>
|
||||
<refsect2 id="Smart-Separators">
|
||||
<title>Smart Separators</title>
|
||||
<para>
|
||||
@ -138,7 +154,6 @@ from multiple sources can make it hard or impossible to determine in advance whe
|
||||
separator will end up in such an unfortunate position.
|
||||
</para>
|
||||
</refsect2>
|
||||
</refsect2>
|
||||
|
||||
<!-- ##### SECTION See_Also ##### -->
|
||||
<para>
|
||||
@ -282,6 +297,7 @@ what UI element to create.
|
||||
@GTK_UI_MANAGER_MENUITEM: Create a menuitem.
|
||||
@GTK_UI_MANAGER_TOOLITEM: Create a toolitem.
|
||||
@GTK_UI_MANAGER_SEPARATOR: Create a separator.
|
||||
@GTK_UI_MANAGER_ACCELERATOR: Install an accelerator.
|
||||
|
||||
<!-- ##### FUNCTION gtk_ui_manager_add_ui ##### -->
|
||||
<para>
|
||||
|
174
gtk/gtkaction.c
174
gtk/gtkaction.c
@ -59,7 +59,10 @@ struct _GtkActionPrivate
|
||||
guint is_important : 1;
|
||||
|
||||
/* accelerator */
|
||||
GQuark accel_quark;
|
||||
guint accel_count;
|
||||
GtkAccelGroup *accel_group;
|
||||
GClosure *accel_closure;
|
||||
GQuark accel_quark;
|
||||
|
||||
/* list of proxy widgets */
|
||||
GSList *proxies;
|
||||
@ -130,10 +133,16 @@ static void gtk_action_get_property (GObject *object,
|
||||
|
||||
static GtkWidget *create_menu_item (GtkAction *action);
|
||||
static GtkWidget *create_tool_item (GtkAction *action);
|
||||
static void connect_proxy (GtkAction *action,
|
||||
GtkWidget *proxy);
|
||||
static void connect_proxy (GtkAction *action,
|
||||
GtkWidget *proxy);
|
||||
static void disconnect_proxy (GtkAction *action,
|
||||
GtkWidget *proxy);
|
||||
static void closure_accel_activate (GClosure *closure,
|
||||
GValue *return_value,
|
||||
guint n_param_values,
|
||||
const GValue *param_values,
|
||||
gpointer invocation_hint,
|
||||
gpointer marshal_data);
|
||||
|
||||
static GObjectClass *parent_class = NULL;
|
||||
static guint action_signals[LAST_SIGNAL] = { 0 };
|
||||
@ -260,7 +269,17 @@ gtk_action_init (GtkAction *action)
|
||||
action->private_data->label_set = FALSE;
|
||||
action->private_data->short_label_set = FALSE;
|
||||
|
||||
action->private_data->accel_count = 0;
|
||||
action->private_data->accel_closure =
|
||||
g_closure_new_object (sizeof (GClosure), G_OBJECT (action));
|
||||
g_closure_set_marshal (action->private_data->accel_closure,
|
||||
closure_accel_activate);
|
||||
g_closure_ref (action->private_data->accel_closure);
|
||||
g_closure_sink (action->private_data->accel_closure);
|
||||
|
||||
action->private_data->accel_quark = 0;
|
||||
action->private_data->accel_count = 0;
|
||||
action->private_data->accel_group = NULL;
|
||||
|
||||
action->private_data->proxies = NULL;
|
||||
}
|
||||
@ -277,6 +296,10 @@ gtk_action_finalize (GObject *object)
|
||||
g_free (action->private_data->short_label);
|
||||
g_free (action->private_data->tooltip);
|
||||
g_free (action->private_data->stock_id);
|
||||
|
||||
g_object_unref (action->private_data->accel_closure);
|
||||
if (action->private_data->accel_group)
|
||||
g_object_unref (action->private_data->accel_group);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -441,7 +464,7 @@ remove_proxy (GtkWidget *proxy,
|
||||
GtkAction *action)
|
||||
{
|
||||
if (GTK_IS_MENU_ITEM (proxy))
|
||||
gtk_menu_item_set_accel_path (GTK_MENU_ITEM (proxy), NULL);
|
||||
gtk_action_disconnect_accelerator (action);
|
||||
|
||||
action->private_data->proxies = g_slist_remove (action->private_data->proxies, proxy);
|
||||
}
|
||||
@ -524,8 +547,8 @@ gtk_action_create_menu_proxy (GtkToolItem *tool_item,
|
||||
}
|
||||
|
||||
static void
|
||||
connect_proxy (GtkAction *action,
|
||||
GtkWidget *proxy)
|
||||
connect_proxy (GtkAction *action,
|
||||
GtkWidget *proxy)
|
||||
{
|
||||
g_object_ref (action);
|
||||
g_object_set_data_full (G_OBJECT (proxy), "gtk-action", action,
|
||||
@ -552,6 +575,13 @@ connect_proxy (GtkAction *action,
|
||||
GtkWidget *label;
|
||||
/* menu item specific synchronisers ... */
|
||||
|
||||
if (action->private_data->accel_quark)
|
||||
{
|
||||
gtk_action_connect_accelerator (action);
|
||||
gtk_menu_item_set_accel_path (GTK_MENU_ITEM (proxy),
|
||||
g_quark_to_string (action->private_data->accel_quark));
|
||||
}
|
||||
|
||||
label = GTK_BIN (proxy)->child;
|
||||
|
||||
/* make sure label is a label */
|
||||
@ -560,16 +590,20 @@ connect_proxy (GtkAction *action,
|
||||
gtk_container_remove (GTK_CONTAINER (proxy), label);
|
||||
label = NULL;
|
||||
}
|
||||
|
||||
if (!label)
|
||||
{
|
||||
label = g_object_new (GTK_TYPE_ACCEL_LABEL,
|
||||
"use_underline", TRUE,
|
||||
"xalign", 0.0,
|
||||
"visible", TRUE,
|
||||
"parent", proxy,
|
||||
"accel_widget", proxy,
|
||||
NULL);
|
||||
}
|
||||
label = g_object_new (GTK_TYPE_ACCEL_LABEL,
|
||||
"use_underline", TRUE,
|
||||
"xalign", 0.0,
|
||||
"visible", TRUE,
|
||||
"parent", proxy,
|
||||
NULL);
|
||||
|
||||
if (GTK_IS_ACCEL_LABEL (label) && action->private_data->accel_quark)
|
||||
g_object_set (G_OBJECT (label),
|
||||
"accel_closure", action->private_data->accel_closure,
|
||||
NULL);
|
||||
|
||||
gtk_label_set_label (GTK_LABEL (label), action->private_data->label);
|
||||
g_signal_connect_object (action, "notify::label",
|
||||
G_CALLBACK (gtk_action_sync_label), proxy, 0);
|
||||
@ -599,15 +633,10 @@ connect_proxy (GtkAction *action,
|
||||
proxy, 0);
|
||||
}
|
||||
|
||||
if (action->private_data->accel_quark)
|
||||
{
|
||||
gtk_menu_item_set_accel_path (GTK_MENU_ITEM (proxy),
|
||||
g_quark_to_string (action->private_data->accel_quark));
|
||||
}
|
||||
|
||||
g_signal_connect_object (proxy, "activate",
|
||||
G_CALLBACK (gtk_action_activate), action,
|
||||
G_CONNECT_SWAPPED);
|
||||
|
||||
}
|
||||
else if (GTK_IS_TOOL_BUTTON (proxy))
|
||||
{
|
||||
@ -923,6 +952,21 @@ gtk_action_unblock_activate_from (GtkAction *action,
|
||||
action);
|
||||
}
|
||||
|
||||
static void
|
||||
closure_accel_activate (GClosure *closure,
|
||||
GValue *return_value,
|
||||
guint n_param_values,
|
||||
const GValue *param_values,
|
||||
gpointer invocation_hint,
|
||||
gpointer marshal_data)
|
||||
{
|
||||
if (GTK_ACTION (closure->data)->private_data->sensitive)
|
||||
g_signal_emit (closure->data, action_signals[ACTIVATE], 0);
|
||||
|
||||
/* we handled the accelerator */
|
||||
g_value_set_boolean (return_value, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_action_set_accel_path:
|
||||
* @action: the action object
|
||||
@ -938,5 +982,93 @@ void
|
||||
gtk_action_set_accel_path (GtkAction *action,
|
||||
const gchar *accel_path)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_ACTION (action));
|
||||
|
||||
action->private_data->accel_quark = g_quark_from_string (accel_path);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_action_set_accel_group:
|
||||
* @action: the action object
|
||||
* @accel_group: a #GtkAccelGroup or %NULL
|
||||
*
|
||||
* Sets the #GtkAccelGroup in which the accelerator for this action
|
||||
* will be installed.
|
||||
*
|
||||
* Since: 2.4
|
||||
**/
|
||||
void
|
||||
gtk_action_set_accel_group (GtkAction *action,
|
||||
GtkAccelGroup *accel_group)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_ACTION (action));
|
||||
g_return_if_fail (accel_group == NULL || GTK_IS_ACCEL_GROUP (accel_group));
|
||||
|
||||
if (accel_group)
|
||||
g_object_ref (accel_group);
|
||||
if (action->private_data->accel_group)
|
||||
g_object_unref (action->private_data->accel_group);
|
||||
|
||||
action->private_data->accel_group = accel_group;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_action_connect_accelerator:
|
||||
* @action: a #GtkAction
|
||||
*
|
||||
* Installs the accelerator for @action if @action has an
|
||||
* accel path and group. See gtk_action_set_accel_path() and
|
||||
* gtk_action_set_accel_group()
|
||||
*
|
||||
* Since multiple proxies may independently trigger the installation
|
||||
* of the accelerator, the @action counts the number of times this
|
||||
* function has been called and doesn't remove the accelerator until
|
||||
* gtk_action_disconnect_accelerator() has been called as many times.
|
||||
*
|
||||
* Since: 2.4
|
||||
**/
|
||||
void
|
||||
gtk_action_connect_accelerator (GtkAction *action)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_ACTION (action));
|
||||
|
||||
if (!action->private_data->accel_quark ||
|
||||
!action->private_data->accel_group)
|
||||
return;
|
||||
|
||||
if (action->private_data->accel_count == 0)
|
||||
{
|
||||
const gchar *accel_path =
|
||||
g_quark_to_string (action->private_data->accel_quark);
|
||||
|
||||
gtk_accel_group_connect_by_path (action->private_data->accel_group,
|
||||
accel_path,
|
||||
action->private_data->accel_closure);
|
||||
}
|
||||
|
||||
action->private_data->accel_count++;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_action_disconnect_accelerator:
|
||||
* @action: a #GtkAction
|
||||
*
|
||||
* Undoes the effect of one call to gtk_action_connect_accelerator().
|
||||
*
|
||||
* Since: 2.4
|
||||
**/
|
||||
void
|
||||
gtk_action_disconnect_accelerator (GtkAction *action)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_ACTION (action));
|
||||
|
||||
if (!action->private_data->accel_quark ||
|
||||
!action->private_data->accel_group)
|
||||
return;
|
||||
|
||||
action->private_data->accel_count--;
|
||||
|
||||
if (action->private_data->accel_count == 0)
|
||||
gtk_accel_group_disconnect (action->private_data->accel_group,
|
||||
action->private_data->accel_closure);
|
||||
}
|
||||
|
@ -78,31 +78,32 @@ struct _GtkActionClass
|
||||
void (*_gtk_reserved4) (void);
|
||||
};
|
||||
|
||||
GType gtk_action_get_type (void);
|
||||
const gchar* gtk_action_get_name (GtkAction *action);
|
||||
void gtk_action_activate (GtkAction *action);
|
||||
GtkWidget * gtk_action_create_icon (GtkAction *action,
|
||||
GtkIconSize icon_size);
|
||||
GtkWidget * gtk_action_create_menu_item (GtkAction *action);
|
||||
GtkWidget * gtk_action_create_tool_item (GtkAction *action);
|
||||
void gtk_action_connect_proxy (GtkAction *action,
|
||||
GtkWidget *proxy);
|
||||
void gtk_action_disconnect_proxy (GtkAction *action,
|
||||
GtkWidget *proxy);
|
||||
GSList * gtk_action_get_proxies (GtkAction *action);
|
||||
|
||||
GType gtk_action_get_type (void);
|
||||
const gchar* gtk_action_get_name (GtkAction *action);
|
||||
void gtk_action_activate (GtkAction *action);
|
||||
GtkWidget* gtk_action_create_icon (GtkAction *action,
|
||||
GtkIconSize icon_size);
|
||||
GtkWidget* gtk_action_create_menu_item (GtkAction *action);
|
||||
GtkWidget* gtk_action_create_tool_item (GtkAction *action);
|
||||
void gtk_action_connect_proxy (GtkAction *action,
|
||||
GtkWidget *proxy);
|
||||
void gtk_action_disconnect_proxy (GtkAction *action,
|
||||
GtkWidget *proxy);
|
||||
GSList* gtk_action_get_proxies (GtkAction *action);
|
||||
void gtk_action_connect_accelerator (GtkAction *action);
|
||||
void gtk_action_disconnect_accelerator (GtkAction *action);
|
||||
|
||||
/* protected ... for use by child actions */
|
||||
void gtk_action_block_activate_from (GtkAction *action,
|
||||
GtkWidget *proxy);
|
||||
void gtk_action_unblock_activate_from (GtkAction *action,
|
||||
GtkWidget *proxy);
|
||||
|
||||
void gtk_action_block_activate_from (GtkAction *action,
|
||||
GtkWidget *proxy);
|
||||
void gtk_action_unblock_activate_from (GtkAction *action,
|
||||
GtkWidget *proxy);
|
||||
|
||||
/* protected ... for use by action groups */
|
||||
void gtk_action_set_accel_path (GtkAction *action,
|
||||
const gchar *accel_path);
|
||||
|
||||
void gtk_action_set_accel_path (GtkAction *action,
|
||||
const gchar *accel_path);
|
||||
void gtk_action_set_accel_group (GtkAction *action,
|
||||
GtkAccelGroup *accel_group);
|
||||
|
||||
|
||||
#endif /* __GTK_ACTION_H__ */
|
||||
|
@ -56,6 +56,7 @@ typedef enum
|
||||
NODE_TYPE_MENUITEM,
|
||||
NODE_TYPE_TOOLITEM,
|
||||
NODE_TYPE_SEPARATOR,
|
||||
NODE_TYPE_ACCELERATOR
|
||||
} NodeType;
|
||||
|
||||
|
||||
@ -861,6 +862,24 @@ start_element_handler (GMarkupParseContext *context,
|
||||
|
||||
switch (element_name[0])
|
||||
{
|
||||
case 'a':
|
||||
if (ctx->state == STATE_ROOT && !strcmp (element_name, "accelerator"))
|
||||
{
|
||||
ctx->state = STATE_ROOT;
|
||||
ctx->current = get_child_node (self, ctx->current,
|
||||
node_name, strlen (node_name),
|
||||
NODE_TYPE_ACCELERATOR,
|
||||
TRUE, FALSE);
|
||||
if (NODE_INFO (ctx->current)->action_name == 0)
|
||||
NODE_INFO (ctx->current)->action_name = action_quark;
|
||||
|
||||
node_prepend_ui_reference (NODE_INFO (ctx->current),
|
||||
ctx->merge_id, action_quark);
|
||||
NODE_INFO (ctx->current)->dirty = TRUE;
|
||||
|
||||
raise_error = FALSE;
|
||||
}
|
||||
break;
|
||||
case 'u':
|
||||
if (ctx->state == STATE_START && !strcmp (element_name, "ui"))
|
||||
{
|
||||
@ -1131,7 +1150,6 @@ static GMarkupParser ui_parser = {
|
||||
cleanup
|
||||
};
|
||||
|
||||
|
||||
static guint
|
||||
add_ui_from_string (GtkUIManager *self,
|
||||
const gchar *buffer,
|
||||
@ -1205,8 +1223,8 @@ gtk_ui_manager_add_ui_from_string (GtkUIManager *self,
|
||||
const gchar *p;
|
||||
const gchar *end;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_UI_MANAGER (self), FALSE);
|
||||
g_return_val_if_fail (buffer != NULL, FALSE);
|
||||
g_return_val_if_fail (GTK_IS_UI_MANAGER (self), 0);
|
||||
g_return_val_if_fail (buffer != NULL, 0);
|
||||
|
||||
if (length < 0)
|
||||
length = strlen (buffer);
|
||||
@ -1246,6 +1264,8 @@ gtk_ui_manager_add_ui_from_file (GtkUIManager *self,
|
||||
gint length;
|
||||
guint res;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_UI_MANAGER (self), 0);
|
||||
|
||||
if (!g_file_get_contents (filename, &buffer, &length, error))
|
||||
return 0;
|
||||
|
||||
@ -1365,6 +1385,9 @@ gtk_ui_manager_add_ui (GtkUIManager *self,
|
||||
case GTK_UI_MANAGER_POPUP:
|
||||
node_type = NODE_TYPE_POPUP;
|
||||
break;
|
||||
case GTK_UI_MANAGER_ACCELERATOR:
|
||||
node_type = NODE_TYPE_ACCELERATOR;
|
||||
break;
|
||||
default: ;
|
||||
/* do nothing */
|
||||
}
|
||||
@ -1734,6 +1757,9 @@ update_node (GtkUIManager *self,
|
||||
goto recurse_children;
|
||||
}
|
||||
|
||||
if (action)
|
||||
gtk_action_set_accel_group (action, self->private_data->accel_group);
|
||||
|
||||
/* If the widget already has a proxy and the action hasn't changed, then
|
||||
* we only have to update the tearoff menu items.
|
||||
*/
|
||||
@ -1765,11 +1791,7 @@ update_node (GtkUIManager *self,
|
||||
break;
|
||||
case NODE_TYPE_POPUP:
|
||||
if (info->proxy == NULL)
|
||||
{
|
||||
info->proxy = gtk_menu_new ();
|
||||
gtk_menu_set_accel_group (GTK_MENU (info->proxy),
|
||||
self->private_data->accel_group);
|
||||
}
|
||||
info->proxy = gtk_menu_new ();
|
||||
break;
|
||||
case NODE_TYPE_MENU:
|
||||
{
|
||||
@ -1806,7 +1828,6 @@ update_node (GtkUIManager *self,
|
||||
tearoff = gtk_tearoff_menu_item_new ();
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), tearoff);
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (info->proxy), menu);
|
||||
gtk_menu_set_accel_group (GTK_MENU (menu), self->private_data->accel_group);
|
||||
gtk_menu_shell_insert (GTK_MENU_SHELL (menushell), info->proxy, pos);
|
||||
}
|
||||
}
|
||||
@ -2045,6 +2066,9 @@ update_node (GtkUIManager *self,
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NODE_TYPE_ACCELERATOR:
|
||||
gtk_action_connect_accelerator (action);
|
||||
break;
|
||||
}
|
||||
|
||||
if (action)
|
||||
@ -2081,6 +2105,8 @@ update_node (GtkUIManager *self,
|
||||
gtk_widget_destroy (info->proxy);
|
||||
if (info->extra)
|
||||
gtk_widget_destroy (info->extra);
|
||||
if (info->type == NODE_TYPE_ACCELERATOR)
|
||||
gtk_action_disconnect_accelerator (info->action);
|
||||
free_node (node);
|
||||
g_node_destroy (node);
|
||||
}
|
||||
@ -2181,7 +2207,8 @@ static const gchar *open_tag_format[] = {
|
||||
"%*s<popup name='%s' action=\"%s\">\n",
|
||||
"%*s<menuitem name=\"%s\" action=\"%s\"/>\n",
|
||||
"%*s<toolitem name=\"%s\" action=\"%s\"/>\n",
|
||||
"%*s<separator/>\n",
|
||||
"%*s<separator name=\"%s\"/>\n",
|
||||
"%*s<accelerator name=\"%s\" action=\"%s\"/>\n",
|
||||
};
|
||||
|
||||
static const gchar *close_tag_format[] = {
|
||||
@ -2196,6 +2223,7 @@ static const gchar *close_tag_format[] = {
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -81,7 +81,8 @@ typedef enum {
|
||||
GTK_UI_MANAGER_POPUP,
|
||||
GTK_UI_MANAGER_MENUITEM,
|
||||
GTK_UI_MANAGER_TOOLITEM,
|
||||
GTK_UI_MANAGER_SEPARATOR
|
||||
GTK_UI_MANAGER_SEPARATOR,
|
||||
GTK_UI_MANAGER_ACCELERATOR
|
||||
} GtkUIManagerItemType;
|
||||
|
||||
GType gtk_ui_manager_get_type (void);
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
struct { const gchar *filename; guint merge_id; } merge_ids[] = {
|
||||
@ -19,6 +20,12 @@ dump_tree (GtkWidget *button,
|
||||
g_free (dump);
|
||||
}
|
||||
|
||||
static void
|
||||
dump_accels (void)
|
||||
{
|
||||
gtk_accel_map_save_fd (STDOUT_FILENO);
|
||||
}
|
||||
|
||||
static void
|
||||
toggle_tearoffs (GtkWidget *button,
|
||||
GtkUIManager *merge)
|
||||
@ -538,6 +545,10 @@ main (int argc, char **argv)
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (dump_tree), merge);
|
||||
gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
|
||||
|
||||
button = gtk_button_new_with_label ("Dump Accels");
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (dump_accels), NULL);
|
||||
gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
|
||||
|
||||
view = create_tree_view (merge);
|
||||
gtk_table_attach (GTK_TABLE (table), view, 1,2, 0,1,
|
||||
GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 0, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user