GNOME Bugzilla – Bug 151537
GtkExpander steals activation from label widget
Last modified: 2017-08-24 20:59:00 UTC
I'm trying to create a GtkExpander with a GtkEntry field in place of the label. When I try to click in the GtkEntry field, sometimes it actually expands the GtkExpander instead of giving focus to the GtkEntry (which is what I actually want to happen). I can still get to the GtkEntry, but I only have a few pixels on the top and bottom to try to hit it since the GtkExpander arrow is absorbing the focus all the way across the GtkEntry. I think it would be wise to check to see if the label will respond before having the GtkExpander react. I wrote an example that can be used to see the problem: #include <gtk/gtk.h> int main( int argc, char **argv ) { GtkWidget *window; GtkWidget *expander; GtkWidget *entry; gtk_init( &argc, &argv ); window = gtk_window_new( GTK_WINDOW_TOPLEVEL ); g_signal_connect( G_OBJECT(window), "delete_event", G_CALLBACK(gtk_main_quit), NULL ); entry = gtk_entry_new(); expander = gtk_expander_new( 0 ); gtk_expander_set_label_widget( GTK_EXPANDER(expander), entry ); gtk_container_add( GTK_CONTAINER(window), expander ); gtk_widget_show_all( window ); gtk_main(); return 0; }
I just traced down the problem: During the mapping of the expander in gtk_expander_map [1], the label widget is mapped twice. The first time directly in this function and the second time by the mapping function of GtkContainer [2]. Some widgets show a GdkWindow during mapping to catch mouse events etc. Those event windows are overlapped by the event_window, which is shown by the expander itself. The few pixels which are are catched by the event_window of the label widget are the result of a wrong calculation of the size of the event_window of the expander. (I did not check this). The problem can be solved to replace the gtk_expander_map function with this one: static void gtk_expander_map (GtkWidget *widget) { GtkExpanderPrivate *priv = GTK_EXPANDER (widget)->priv; if (priv->event_window) gdk_window_show (priv->event_window); GTK_WIDGET_CLASS (gtk_expander_parent_class)->map (widget); } In the unmap function can also replaced by a simpler one: static void gtk_expander_unmap (GtkWidget *widget) { GtkExpanderPrivate *priv = GTK_EXPANDER (widget)->priv; if (priv->event_window) gdk_window_hide (priv->event_window); GTK_WIDGET_CLASS (gtk_expander_parent_class)->unmap (widget); } Regards, Gerhard Heift [1] http://git.gnome.org/browse/gtk+/tree/gtk/gtkexpander.c?id=b74fb44c115c61745d691fc2da7aef5505f6eccd#n711 [2] http://git.gnome.org/browse/gtk+/tree/gtk/gtkcontainer.c?id=b74fb44c115c61745d691fc2da7aef5505f6eccd#n2611
*** Bug 705971 has been marked as a duplicate of this bug. ***
<mclasen> thats just not how expanders are supposed to be used
lets just say we won't fix this
*** Bug 318169 has been marked as a duplicate of this bug. ***