gtk_widget_get_parent_window, GTK_NO_WINDOW, and GDK_INPUT_ONLY GdkWindows



This is a similar question to one I asked last week, but I'm not spamming, fishing for another response with 
a re-send.  I actually made quite a bit of progress towards a solution but ran into another tangle of 
confusion, and possibly a Gtk bug (described below).

I am creating a GtkContainer subclass that needs to receive the enter-notify, motion-notify, and leave-notify 
events.  I am copying the design I see in gtkbutton.c.  My GtkContainer subclass actually contains a 
GtkButton as one of its children.  In order to receive events, I copied the following more or less verbatim 
from GtkButton, executing it in my widget's realize:

        GdkWindowAttr attributes;
        attributes.window_type = GDK_WINDOW_CHILD;
        attributes.x = widget->allocation.x;
        attributes.y = widget->allocation.y;
        attributes.width = widget->allocation.width;
        attributes.height = widget->allocation.height;
        attributes.wclass = GDK_INPUT_ONLY;
        attributes.event_mask = gtk_widget_get_events(widget);
        attributes.event_mask |= GDK_ENTER_NOTIFY_MASK
                                                                | GDK_LEAVE_NOTIFY_MASK
                                                                | GDK_POINTER_MOTION_MASK
                                                                | GDK_BUTTON_MOTION_MASK;

        my_gtk_container->event_window = gdk_window_new(        gtk_widget_get_parent_window(widget),
                                                                                                              
  &attributes,
                                                                                                              
  0 );

What I noticed is that as I move the mouse through my container widget and onto a button it contains, my 
widget is receiving continuous motion-notify events.  The GtkButton never receives enter-notify, so it 
doesn't highlight when the mouse is over it, nor does it receive button clicks or the leave-notify event.

Question 1 preface: I know about GtkEventBox.  I was trying to avoid the (IMHO unnecessary) redundant 
parent/child recursion of making my GtkContainer subclass a 2-deep aggregate of a GtkContainer in a 
GtkEventBox.

Question 1a: Should I create the 2-deep GtkEventBox and GtkContainer anyway?

Question 1b: Is the GDK_INPUT_ONLY GdkWindow approach only appropriate for "leaf node" widgets - widgets that 
contain no children - like GtkButton?

Question 2: how does GTK_NO_WINDOW relate to GDK_INPUT_ONLY?  Should a GtkWidget only declare itself to be 
"~GTK_NO_WINDOW" if its GdkWindow supports output, with GDK_INPUT_ONLY GdkWindows being treated as 
GTK_NO_WINDOW?

Question 3: am I responsible for synthesizing enter and leave notification events for child widgets like the 
now-malfunctioning GtkButton?  I would assume not (that being the responsibility of Gdk and the window 
server), but if so then how am I to know which children to synthesize these events for - by peeking at what 
they've requested by way of gtk_widget_set_events or gtk_widget_add_events?

Question 4 preface: When the now-malfunctioning GtkButton realizes itself, in gtkbutton.c I see that it uses 
gtk_widget_get_parent_window to get the GdkWindow of its parent.  I am fairly certain that when it does this, 
it is getting the GdkWindow for the root-level window, not my GtkContainer subclass's GdkWindow.  I can't 
check that (since gtk_button_realize is static so I can't set a breakpoint and couldn't see the Gtk source in 
the debugger even if I could set a breakpoint), but I am fairly certain of this because I looked in 
gtkwidget.c and gtk_widget_get_parent_window gets the parent using this: parent_window = g_object_get_qdata 
(G_OBJECT (widget), quark_parent_window);

Question 4a: the quark_parent_window business seems like it is only used to manage the 
gtk_widget_set_parent_window / gtk_widget_get_parent_window consistency relationship, but is totally unaware 
of the parent / children hierarchy.  Consequently, it looks like my GtkContainer is responsible for 
propogating gtk_widget_set_parent_window to its children when it creates its GdkWindow.  Is this the case?

Question 4b: If the answer to "Is this the case?" in 4a is "yes" then how deep does it need to go?  I note 
that gtk_widget_set_parent_window in gtkwidget.c does not recursively call gtk_widget_set_parent_window for 
child widgets.  Consequently, it looks like my GtkContainer subclass needs to recursively call 
gtk_widget_set_parent_window for not just its children, but its children's children and so on until a widget 
without GTK_NO_WINDOW child is encountered.

Question 4c: Grepping for gtk_widget_set_parent_window and then looking at gtklayout.c, I see that it does 
what I deduced in 4b that I need to do, calling gtk_widget_set_parent_window for children, but I don't see 
any recursion there or (as I also mentioned before) in gtk_widget_set_parent_window.  That actually looks 
like GtkLayout may have a bug and in certain two-deep-or-more GtkWindow-or-not parent / child arrangements, 
fail to propagate the parent GdkWindow information down the child hierarchy.  Before I go too far with this 
and start devising test cases to form a bug report and trying to confirm whether there's really a bug or not, 
can someone shed some light on this?


      



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]