From 730af28b996cce2118b8cd4d11988dbe155f347e Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Sun, 28 Oct 2018 09:14:53 +0000 Subject: [PATCH] Stop using deprecated gtk_container_set_focus_chain(). In GTK 2, this function was a new and convenient way to override the order in which the Tab key cycled through the sub-widgets of a container, replacing the more verbose mechanism in GTK 1 where you had to provide a custom implementation of the "focus" method in GtkContainerClass. GTK 3.24 has now deprecated gtk_container_set_focus_chain(), apparently on the grounds that that old system is what they think you _ought_ to be doing. So I've abandoned set_focus_chain completely, and switched back to doing it by a custom focus method for _all_ versions of GTK, with the only slight wrinkle being that between GTK 1 and 2 the method in question moved from GtkContainer to GtkWidget (my guess is so that an individual non-container widget can still have multiple separately focusable UI components). --- unix/gtkcols.c | 72 +++++++++++++++++++++++------------------------- unix/gtkcompat.h | 5 ++++ 2 files changed, 39 insertions(+), 38 deletions(-) diff --git a/unix/gtkcols.c b/unix/gtkcols.c index ef060d63..60e39441 100644 --- a/unix/gtkcols.c +++ b/unix/gtkcols.c @@ -6,6 +6,18 @@ #include "gtkcompat.h" #include "gtkcols.h" +#if GTK_CHECK_VERSION(2,0,0) +/* The "focus" method lives in GtkWidget from GTK 2 onwards, but it + * was in GtkContainer in GTK 1 */ +#define FOCUS_METHOD_SUPERCLASS GtkWidget +#define FOCUS_METHOD_LOCATION widget_class /* used in columns_init */ +#define CHILD_FOCUS(cont, dir) gtk_widget_child_focus(GTK_WIDGET(cont), dir) +#else +#define FOCUS_METHOD_SUPERCLASS GtkContainer +#define FOCUS_METHOD_LOCATION container_class +#define CHILD_FOCUS(cont, dir) gtk_container_focus(GTK_CONTAINER(cont), dir) +#endif + static void columns_init(Columns *cols); static void columns_class_init(ColumnsClass *klass); #if !GTK_CHECK_VERSION(2,0,0) @@ -23,9 +35,8 @@ static void columns_base_add(GtkContainer *container, GtkWidget *widget); static void columns_remove(GtkContainer *container, GtkWidget *widget); static void columns_forall(GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data); -#if !GTK_CHECK_VERSION(2,0,0) -static gint columns_focus(GtkContainer *container, GtkDirectionType dir); -#endif +static gint columns_focus(FOCUS_METHOD_SUPERCLASS *container, + GtkDirectionType dir); static GType columns_child_type(GtkContainer *container); #if GTK_CHECK_VERSION(3,0,0) static void columns_get_preferred_width(GtkWidget *widget, @@ -93,10 +104,8 @@ GType columns_get_type(void) } #endif -#if !GTK_CHECK_VERSION(2,0,0) -static gint (*columns_inherited_focus)(GtkContainer *container, +static gint (*columns_inherited_focus)(FOCUS_METHOD_SUPERCLASS *container, GtkDirectionType direction); -#endif static void columns_class_init(ColumnsClass *klass) { @@ -139,12 +148,11 @@ static void columns_class_init(ColumnsClass *klass) container_class->remove = columns_remove; container_class->forall = columns_forall; container_class->child_type = columns_child_type; -#if !GTK_CHECK_VERSION(2,0,0) + /* Save the previous value of this method. */ if (!columns_inherited_focus) - columns_inherited_focus = container_class->focus; - container_class->focus = columns_focus; -#endif + columns_inherited_focus = FOCUS_METHOD_LOCATION->focus; + FOCUS_METHOD_LOCATION->focus = columns_focus; } static void columns_init(Columns *cols) @@ -362,9 +370,6 @@ static void columns_remove(GtkContainer *container, GtkWidget *widget) cols->taborder = g_list_remove_link(cols->taborder, children); g_list_free(children); -#if GTK_CHECK_VERSION(2,0,0) - gtk_container_set_focus_chain(container, cols->taborder); -#endif break; } } @@ -463,10 +468,6 @@ void columns_add(Columns *cols, GtkWidget *child, gtk_widget_set_parent(child, GTK_WIDGET(cols)); -#if GTK_CHECK_VERSION(2,0,0) - gtk_container_set_focus_chain(GTK_CONTAINER(cols), cols->taborder); -#endif - if (gtk_widget_get_realized(GTK_WIDGET(cols))) gtk_widget_realize(child); @@ -548,38 +549,34 @@ void columns_taborder_last(Columns *cols, GtkWidget *widget) cols->taborder = g_list_remove_link(cols->taborder, children); g_list_free(children); cols->taborder = g_list_append(cols->taborder, widget); -#if GTK_CHECK_VERSION(2,0,0) - gtk_container_set_focus_chain(GTK_CONTAINER(cols), cols->taborder); -#endif break; } } -#if !GTK_CHECK_VERSION(2,0,0) /* * Override GtkContainer's focus movement so the user can * explicitly specify the tab order. */ -static gint columns_focus(GtkContainer *container, GtkDirectionType dir) +static gint columns_focus(FOCUS_METHOD_SUPERCLASS *super, GtkDirectionType dir) { Columns *cols; GList *pos; GtkWidget *focuschild; - g_return_val_if_fail(container != NULL, FALSE); - g_return_val_if_fail(IS_COLUMNS(container), FALSE); + g_return_val_if_fail(super != NULL, FALSE); + g_return_val_if_fail(IS_COLUMNS(super), FALSE); - cols = COLUMNS(container); + cols = COLUMNS(super); - if (!GTK_WIDGET_DRAWABLE(cols) || - !GTK_WIDGET_IS_SENSITIVE(cols)) + if (!gtk_widget_is_drawable(GTK_WIDGET(cols)) || + !gtk_widget_is_sensitive(GTK_WIDGET(cols))) return FALSE; - if (!GTK_WIDGET_CAN_FOCUS(container) && + if (!gtk_widget_get_can_focus(GTK_WIDGET(cols)) && (dir == GTK_DIR_TAB_FORWARD || dir == GTK_DIR_TAB_BACKWARD)) { - focuschild = container->focus_child; - gtk_container_set_focus_child(container, NULL); + focuschild = gtk_container_get_focus_child(GTK_CONTAINER(cols)); + gtk_container_set_focus_child(GTK_CONTAINER(cols), NULL); if (dir == GTK_DIR_TAB_FORWARD) pos = cols->taborder; @@ -592,18 +589,18 @@ static gint columns_focus(GtkContainer *container, GtkDirectionType dir) if (focuschild) { if (focuschild == child) { focuschild = NULL; /* now we can start looking in here */ - if (GTK_WIDGET_DRAWABLE(child) && + if (gtk_widget_is_drawable(child) && GTK_IS_CONTAINER(child) && - !GTK_WIDGET_HAS_FOCUS(child)) { - if (gtk_container_focus(GTK_CONTAINER(child), dir)) + !gtk_widget_has_focus(child)) { + if (CHILD_FOCUS(child, dir)) return TRUE; } } - } else if (GTK_WIDGET_DRAWABLE(child)) { + } else if (gtk_widget_is_drawable(child)) { if (GTK_IS_CONTAINER(child)) { - if (gtk_container_focus(GTK_CONTAINER(child), dir)) + if (CHILD_FOCUS(child, dir)) return TRUE; - } else if (GTK_WIDGET_CAN_FOCUS(child)) { + } else if (gtk_widget_get_can_focus(child)) { gtk_widget_grab_focus(child); return TRUE; } @@ -617,9 +614,8 @@ static gint columns_focus(GtkContainer *container, GtkDirectionType dir) return FALSE; } else - return columns_inherited_focus(container, dir); + return columns_inherited_focus(super, dir); } -#endif /* * Underlying parts of the layout algorithm, to compute the Columns diff --git a/unix/gtkcompat.h b/unix/gtkcompat.h index 03947a79..fe070720 100644 --- a/unix/gtkcompat.h +++ b/unix/gtkcompat.h @@ -53,6 +53,7 @@ #define gtk_widget_get_parent(w) ((w)->parent) #define gtk_widget_set_allocation(w, a) ((w)->allocation = *(a)) #define gtk_container_get_border_width(c) ((c)->border_width) +#define gtk_container_get_focus_child(c) ((c)->focus_child) #define gtk_bin_get_child(b) ((b)->child) #define gtk_color_selection_dialog_get_color_selection(cs) ((cs)->colorsel) #define gtk_selection_data_get_target(sd) ((sd)->target) @@ -79,6 +80,10 @@ #define gtk_widget_get_mapped(w) GTK_WIDGET_MAPPED(w) #define gtk_widget_get_realized(w) GTK_WIDGET_REALIZED(w) #define gtk_widget_get_state(w) GTK_WIDGET_STATE(w) +#define gtk_widget_get_can_focus(w) GTK_WIDGET_CAN_FOCUS(w) +#define gtk_widget_is_drawable(w) GTK_WIDGET_DRAWABLE(w) +#define gtk_widget_is_sensitive(w) GTK_WIDGET_IS_SENSITIVE(w) +#define gtk_widget_has_focus(w) GTK_WIDGET_HAS_FOCUS(w) /* This is a bit of a bodge because it relies on us only calling this * macro as GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), so under