diff --git a/gtk/gtkroot.c b/gtk/gtkroot.c index ad93f8791a..249d7405b1 100644 --- a/gtk/gtkroot.c +++ b/gtk/gtkroot.c @@ -21,6 +21,8 @@ #include "gtkrootprivate.h" #include "gdk/gdk-private.h" +#include "gtkprivate.h" +#include "gtkintl.h" /** * SECTION:gtkroot @@ -65,6 +67,13 @@ gtk_root_default_init (GtkRootInterface *iface) iface->get_display = gtk_root_default_get_display; iface->get_renderer = gtk_root_default_get_renderer; iface->get_surface_transform = gtk_root_default_get_surface_transform; + + g_object_interface_install_property (iface, + g_param_spec_object ("focus-widget", + P_("Focus widget"), + P_("The focus widget"), + GTK_TYPE_WIDGET, + GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY)); } GdkDisplay * @@ -124,3 +133,63 @@ gtk_root_get_for_surface (GdkSurface *surface) return NULL; } + +/** + * gtk_root_set_focus: + * @self: a #GtkRoot + * @focus: (allow-none): widget to be the new focus widget, or %NULL + * to unset the focus widget + * + * If @focus is not the current focus widget, and is focusable, sets + * it as the focus widget for the root. If @focus is %NULL, unsets + * the focus widget for the root. + * + * To set the focus to a particular widget in the root, it is usually + * more convenient to use gtk_widget_grab_focus() instead of this function. + */ +void +gtk_root_set_focus (GtkRoot *self, + GtkWidget *focus) +{ + g_return_if_fail (GTK_IS_ROOT (self)); + g_return_if_fail (focus == NULL || GTK_IS_WIDGET (focus)); + + g_object_set (self, "focus-widget", focus, NULL); +} + +/** + * gtk_root_get_focus: + * @self: a #GtkRoot + * + * Retrieves the current focused widget within the root. + * + * Note that this is the widget that would have the focus + * if the root is active; if the root is not focused then + * `gtk_widget_has_focus (widget)` will be %FALSE for the + * widget. + * + * Returns: (nullable) (transfer none): the currently focused widget, + * or %NULL if there is none. + */ +GtkWidget * +gtk_root_get_focus (GtkRoot *self) +{ + GtkWidget *focus; + + g_return_val_if_fail (GTK_IS_ROOT (self), NULL); + + g_object_get (self, "focus-widget", &focus, NULL); + + if (focus) + g_object_unref (focus); + + return focus; +} + +guint +gtk_root_install_properties (GObjectClass *object_class, + guint first_prop) +{ + g_object_class_override_property (object_class, first_prop + GTK_ROOT_PROP_FOCUS_WIDGET, "focus-widget"); + return GTK_ROOT_NUM_PROPERTIES; +} diff --git a/gtk/gtkroot.h b/gtk/gtkroot.h index 45e777ba68..4c7ae89e37 100644 --- a/gtk/gtkroot.h +++ b/gtk/gtkroot.h @@ -56,6 +56,12 @@ struct _GtkRootInterface GDK_AVAILABLE_IN_ALL GtkWidget * gtk_root_get_for_surface (GdkSurface *surface); +GDK_AVAILABLE_IN_ALL +void gtk_root_set_focus (GtkRoot *self, + GtkWidget *focus); +GDK_AVAILABLE_IN_ALL +GtkWidget * gtk_root_get_focus (GtkRoot *self); + G_END_DECLS #endif /* __GTK_ROOT_H__ */ diff --git a/gtk/gtkrootprivate.h b/gtk/gtkrootprivate.h index 07ddc380e5..357bc6441f 100644 --- a/gtk/gtkrootprivate.h +++ b/gtk/gtkrootprivate.h @@ -11,6 +11,14 @@ GskRenderer * gtk_root_get_renderer (GtkRoot void gtk_root_get_surface_transform (GtkRoot *self, int *x, int *y); +enum { + GTK_ROOT_PROP_FOCUS_WIDGET, + GTK_ROOT_NUM_PROPERTIES +} GtkRootProperties; + +guint gtk_root_install_properties (GObjectClass *object_class, + guint first_prop); + G_END_DECLS #endif /* __GTK_ROOT_PRIVATE_H__ */