GtkWindow: Add a way to declare initial focus in ui files

With this commit, it is possible to use <initial-focus name="blah">
to declare the initial focus widget for a window.

This is related to
https://bugzilla.gnome.org/show_bug.cgi?id=734033
This commit is contained in:
Matthias Clasen 2014-08-02 11:35:34 +02:00
parent 52ab9a36fa
commit 14eccae603

View File

@ -95,12 +95,17 @@
* elements representing the #GtkAccelGroup objects you want to add to * elements representing the #GtkAccelGroup objects you want to add to
* your window (synonymous with gtk_window_add_accel_group(). * your window (synonymous with gtk_window_add_accel_group().
* *
* It also supports the <initial-focus> element, whose name property names
* the widget to receive the focus when the window is mapped. See
* gtk_window_set_initial_focus().
*
* An example of a UI definition fragment with accel groups: * An example of a UI definition fragment with accel groups:
* |[ * |[
* <object class="GtkWindow"> * <object class="GtkWindow">
* <accel-groups> * <accel-groups>
* <group name="accelgroup1"/> * <group name="accelgroup1"/>
* </accel-groups> * </accel-groups>
* <initial-focus name="thunderclap"/>
* </object> * </object>
* *
* ... * ...
@ -1907,6 +1912,39 @@ static const GMarkupParser window_parser =
window_start_element window_start_element
}; };
typedef struct {
GObject *object;
gchar *name;
} NameSubParserData;
static void
focus_start_element (GMarkupParseContext *context,
const gchar *element_name,
const gchar **names,
const gchar **values,
gpointer user_data,
GError **error)
{
guint i;
NameSubParserData *data = (NameSubParserData*)user_data;
if (strcmp (element_name, "initial-focus") == 0)
{
for (i = 0; names[i]; i++)
{
if (strcmp (names[i], "name") == 0)
data->name = g_strdup (values[i]);
}
}
else
g_warning ("Unsupported tag type for GtkWindow: %s\n", element_name);
}
static const GMarkupParser focus_parser =
{
focus_start_element
};
static gboolean static gboolean
gtk_window_buildable_custom_tag_start (GtkBuildable *buildable, gtk_window_buildable_custom_tag_start (GtkBuildable *buildable,
GtkBuilder *builder, GtkBuilder *builder,
@ -1915,14 +1953,14 @@ gtk_window_buildable_custom_tag_start (GtkBuildable *buildable,
GMarkupParser *parser, GMarkupParser *parser,
gpointer *data) gpointer *data)
{ {
GSListSubParserData *parser_data;
if (parent_buildable_iface->custom_tag_start (buildable, builder, child, if (parent_buildable_iface->custom_tag_start (buildable, builder, child,
tagname, parser, data)) tagname, parser, data))
return TRUE; return TRUE;
if (strcmp (tagname, "accel-groups") == 0) if (strcmp (tagname, "accel-groups") == 0)
{ {
GSListSubParserData *parser_data;
parser_data = g_slice_new0 (GSListSubParserData); parser_data = g_slice_new0 (GSListSubParserData);
parser_data->items = NULL; parser_data->items = NULL;
parser_data->object = G_OBJECT (buildable); parser_data->object = G_OBJECT (buildable);
@ -1932,6 +1970,19 @@ gtk_window_buildable_custom_tag_start (GtkBuildable *buildable,
return TRUE; return TRUE;
} }
if (strcmp (tagname, "initial-focus") == 0)
{
NameSubParserData *parser_data;
parser_data = g_slice_new0 (NameSubParserData);
parser_data->name = NULL;
parser_data->object = G_OBJECT (buildable);
*parser = focus_parser;
*data = parser_data;
return TRUE;
}
return FALSE; return FALSE;
} }
@ -1942,20 +1993,34 @@ gtk_window_buildable_custom_finished (GtkBuildable *buildable,
const gchar *tagname, const gchar *tagname,
gpointer user_data) gpointer user_data)
{ {
GSListSubParserData *data;
parent_buildable_iface->custom_finished (buildable, builder, child, parent_buildable_iface->custom_finished (buildable, builder, child,
tagname, user_data); tagname, user_data);
if (strcmp (tagname, "accel-groups") != 0) if (strcmp (tagname, "accel-groups") == 0)
return; {
GSListSubParserData *data = (GSListSubParserData*)user_data;
data = (GSListSubParserData*)user_data;
g_object_set_qdata_full (G_OBJECT (buildable), quark_gtk_buildable_accels, g_object_set_qdata_full (G_OBJECT (buildable), quark_gtk_buildable_accels,
data->items, (GDestroyNotify) g_slist_free); data->items, (GDestroyNotify) g_slist_free);
g_slice_free (GSListSubParserData, data); g_slice_free (GSListSubParserData, data);
}
if (strcmp (tagname, "initial-focus") == 0)
{
NameSubParserData *data = (NameSubParserData*)user_data;
if (data->name)
{
GObject *object;
object = gtk_builder_get_object (builder, data->name);
gtk_window_set_focus (GTK_WINDOW (buildable), GTK_WIDGET (object));
g_free (data->name);
}
g_slice_free (NameSubParserData, data);
}
} }
/** /**