Re: [gtk-list] Questions about event percolation



>  It is my (limited) understanding that events in the gtk widget sysem
>  percolate from children to parent until someone handles it and returns
>  TRUE.

This is correct.

>  Now, lets say i have a container (a GtkLayout widget actually) and this
>  container has one child, say a button or entry widget.
>  
>  I connect a "motion_notify_event" to the container.  I set the events
>  for the container as appropiate.  
>  
>  The signal is triggered for motion not only within the container, but
>  its children as well.

This is correct as well.  If the child window is not selecting for a
particular type of event, X will look for a window up in the hierarchy
that *is* taking that type of event.  Gtk obviously gets it and emits
the appropriate signal.

>  Ok, so I install the signal on the child, set the child events as
>  appropiate and then return TRUE in that signal - a noop.  
>  
>  Is this the only way to avoid the motion signals from being emitted for
>  the case when you are mousing on the child ?

This is an ugly hack and will bloat your program big time.  I think it
is better to set the same event mask for all widgets (with
gtk_widget_set_events()), and then in your GtkLayout signal handlers
test whether the event->window is actually what you are interested in.

Look at the little test program I included below -- in the motion
handler you'll see some interesting numbers.  If you change the "#if
1" to "#if 0", you'll see that the button never gets any motion
events, but the layout does since X looks for a parent window that is
selecting on motion events.

>  if not, are there any effeciency concerns about having to install every
>  single signal on every signal child (along with setting the events,
>  which i preseme ultimately does the x lib selection of event) ?  

Signal connections are not very expensive, but hooking up every single
event signal for all your widgets would use a lot of memory.

As a side question... why does Mozilla care if it gets motion events
even if the mouse is over a child window?

  Federico

======================================================================
#include <stdio.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>

static gint
motion (GtkWidget *widget, GdkEventMotion *event, gpointer data)
{
	printf ("Widget %p got motion originally for %p on window %p\n",
		widget,
		gtk_get_event_widget ((GdkEvent *) event),
		event->window);

	return FALSE;
}

int
main (int argc, char **argv)
{
	GtkWidget *window;
	GtkWidget *layout;
	GtkWidget *button;

	gtk_init (&argc, &argv);

	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

	layout = gtk_layout_new (NULL, NULL);
	gtk_widget_set_events (layout,
			       gtk_widget_get_events (layout) | GDK_POINTER_MOTION_MASK);
	gtk_container_add (GTK_CONTAINER (window), layout);

	gtk_signal_connect (GTK_OBJECT (layout), "motion_notify_event",
			    (GtkSignalFunc) motion,
			    "layout");

	button = gtk_button_new_with_label ("Squeeeek!");
#if 1
	gtk_widget_set_events (button,
			       gtk_widget_get_events (button) | GDK_POINTER_MOTION_MASK);
#endif
	gtk_layout_put (GTK_LAYOUT (layout), button, 30, 30);
	gtk_signal_connect (GTK_OBJECT (button), "motion_notify_event",
			    (GtkSignalFunc) motion,
			    "button");

	gtk_widget_show_all (window);
	printf ("layout->bin_window id: 0x%x\n",
		(int) GDK_WINDOW_XWINDOW (GTK_LAYOUT (layout)->bin_window));

	gtk_main ();
	return 0;
}



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