Optional keybindings
- From: Owen Taylor <otaylor redhat com>
- To: gtk-devel-list gnome org
- Cc: timj gtk org
- Subject: Optional keybindings
- Date: Tue, 15 Jan 2002 17:20:18 -0500 (EST)
As was discussed some earlier, here is a patch to allow keybindings to be
optional: if the action signal for a keybinding has a boolean return value
and returns FALSE, then it is as if that binding didn't exist.
This is needed in particular to fix a problem with activateable
widgets in notebooks. If you hit "space" with the focus on one, then
the space propagates up until it hits the notebook, which has a
binding for "Space" and eats the keystroke. (I think we also need
such binding for GtkPaned)
The notebook patch using this is attached; it makes bindings that should
only have an effect when the focus is on the tabs return FALSE if the
focus is on the child.
There are no compatibility problems with the binding change since action
signals with a boolean return were not previously allowed in this context.
It is a newly exported public API, but I don't see any way around
this ... we need the functionality internal to GTK+, and we can't hide it
since it is a matter of use of existing function calls than adding new
ones.
Regards,
Owen
--- gtkbindings.c.pre Tue Jan 15 15:59:26 2002
+++ gtkbindings.c Tue Jan 15 16:23:11 2002
@@ -356,12 +356,13 @@ binding_compose_params (GtkObject
return valid;
}
-static void
+static gboolean
gtk_binding_entry_activate (GtkBindingEntry *entry,
GtkObject *object)
{
GtkBindingSignal *sig;
gboolean old_emission;
+ gboolean handled = FALSE;
gint i;
old_emission = entry->in_emission;
@@ -374,6 +375,7 @@ gtk_binding_entry_activate (GtkBindingEn
GSignalQuery query;
guint signal_id;
GValue *params = NULL;
+ GValue return_val = { 0, };
gchar *accelerator = NULL;
signal_id = g_signal_lookup (sig->signal_name, G_OBJECT_TYPE (object));
@@ -392,7 +394,7 @@ gtk_binding_entry_activate (GtkBindingEn
g_signal_query (signal_id, &query);
if (query.n_params != sig->n_args ||
- query.return_type != G_TYPE_NONE ||
+ (query.return_type != G_TYPE_NONE && query.return_type != G_TYPE_BOOLEAN) ||
!binding_compose_params (object, sig->args, &query, ¶ms))
{
accelerator = gtk_accelerator_name (entry->keyval, entry->modifiers);
@@ -417,8 +419,20 @@ gtk_binding_entry_activate (GtkBindingEn
if (accelerator)
continue;
- g_signal_emitv (params, signal_id, 0, NULL);
+ if (query.return_type == G_TYPE_BOOLEAN)
+ g_value_init (&return_val, G_TYPE_BOOLEAN);
+
+ g_signal_emitv (params, signal_id, 0, &return_val);
+ if (query.return_type == G_TYPE_BOOLEAN)
+ {
+ if (g_value_get_boolean (&return_val))
+ handled = TRUE;
+ g_value_unset (&return_val);
+ }
+ else
+ handled = TRUE;
+
for (i = 0; i < query.n_params + 1; i++)
g_value_unset (¶ms[i]);
g_free (params);
@@ -432,6 +446,8 @@ gtk_binding_entry_activate (GtkBindingEn
entry->in_emission = old_emission;
if (entry->destroyed && !entry->in_emission)
binding_entry_free (entry);
+
+ return handled;
}
GtkBindingSet*
@@ -515,11 +531,7 @@ gtk_binding_set_activate (GtkBindingSet
entry = binding_ht_lookup_entry (binding_set, keyval, modifiers);
if (entry)
- {
- gtk_binding_entry_activate (entry, object);
-
- return TRUE;
- }
+ return gtk_binding_entry_activate (entry, object);
return FALSE;
}
@@ -815,9 +827,8 @@ binding_match_activate (GSList
binding_set = pspec->user_data;
- gtk_binding_entry_activate (binding_set->current, object);
-
- return TRUE;
+ if (gtk_binding_entry_activate (binding_set->current, object))
+ return TRUE;
}
}
Index: gtknotebook.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtknotebook.c,v
retrieving revision 1.113
diff -u -p -r1.113 gtknotebook.c
--- gtknotebook.c 2002/01/15 17:40:44 1.113
+++ gtknotebook.c 2002/01/15 22:16:19
@@ -115,9 +115,9 @@ struct _GtkNotebookPage
static void gtk_notebook_class_init (GtkNotebookClass *klass);
static void gtk_notebook_init (GtkNotebook *notebook);
-static void gtk_notebook_select_page (GtkNotebook *notebook,
- gboolean move_focus);
-static void gtk_notebook_focus_tab (GtkNotebook *notebook,
+static gboolean gtk_notebook_select_page (GtkNotebook *notebook,
+ gboolean move_focus);
+static gboolean gtk_notebook_focus_tab (GtkNotebook *notebook,
GtkNotebookTab type);
static void gtk_notebook_change_current_page (GtkNotebook *notebook,
gint offset);
@@ -448,7 +448,7 @@ gtk_notebook_class_init (GtkNotebookClas
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (GtkNotebookClass, focus_tab),
NULL, NULL,
- _gtk_marshal_VOID__ENUM,
+ _gtk_marshal_BOOLEAN__ENUM,
G_TYPE_NONE, 1,
GTK_TYPE_NOTEBOOK_TAB);
notebook_signals[SELECT_PAGE] =
@@ -457,8 +457,8 @@ gtk_notebook_class_init (GtkNotebookClas
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (GtkNotebookClass, select_page),
NULL, NULL,
- _gtk_marshal_VOID__BOOLEAN,
- G_TYPE_NONE, 1,
+ _gtk_marshal_BOOLEAN__BOOLEAN,
+ G_TYPE_BOOLEAN, 1,
G_TYPE_BOOLEAN);
notebook_signals[CHANGE_CURRENT_PAGE] =
g_signal_new ("change_current_page",
@@ -467,7 +467,7 @@ gtk_notebook_class_init (GtkNotebookClas
G_STRUCT_OFFSET (GtkNotebookClass, change_current_page),
NULL, NULL,
gtk_marshal_VOID__INT,
- G_TYPE_NONE, 1,
+ G_TYPE_BOOLEAN, 1,
G_TYPE_INT);
binding_set = gtk_binding_set_by_class (object_class);
@@ -543,32 +543,45 @@ gtk_notebook_init (GtkNotebook *notebook
notebook->have_visible_child = FALSE;
}
-static void
+static gboolean
gtk_notebook_select_page (GtkNotebook *notebook,
gboolean move_focus)
{
- gtk_notebook_page_select (notebook, move_focus);
+ if (gtk_widget_is_focus (GTK_WIDGET (notebook)))
+ {
+ gtk_notebook_page_select (notebook, move_focus);
+ return TRUE;
+ }
+ else
+ return FALSE;
}
-static void
+static gboolean
gtk_notebook_focus_tab (GtkNotebook *notebook,
GtkNotebookTab type)
{
GList *list;
-
- switch (type)
+
+ if (gtk_widget_is_focus (GTK_WIDGET (notebook)))
{
- case GTK_NOTEBOOK_TAB_FIRST:
- list = gtk_notebook_search_page (notebook, NULL, STEP_NEXT, TRUE);
- if (list)
- gtk_notebook_switch_focus_tab (notebook, list);
- break;
- case GTK_NOTEBOOK_TAB_LAST:
- list = gtk_notebook_search_page (notebook, NULL, STEP_PREV, TRUE);
- if (list)
- gtk_notebook_switch_focus_tab (notebook, list);
- break;
+ switch (type)
+ {
+ case GTK_NOTEBOOK_TAB_FIRST:
+ list = gtk_notebook_search_page (notebook, NULL, STEP_NEXT, TRUE);
+ if (list)
+ gtk_notebook_switch_focus_tab (notebook, list);
+ break;
+ case GTK_NOTEBOOK_TAB_LAST:
+ list = gtk_notebook_search_page (notebook, NULL, STEP_PREV, TRUE);
+ if (list)
+ gtk_notebook_switch_focus_tab (notebook, list);
+ break;
+ }
+
+ return TRUE;
}
+ else
+ return FALSE;
}
static void
@@ -3773,7 +3786,7 @@ gtk_notebook_mnemonic_activate_switch_pa
{
GtkNotebookPage *page = list->data;
- gtk_widget_grab_focus (notebook); /* Do this first to avoid focusing new page */
+ gtk_widget_grab_focus (GTK_WIDGET (notebook)); /* Do this first to avoid focusing new page */
gtk_notebook_switch_page (notebook, page, -1);
focus_tabs_in (notebook);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]