GtkEventBox and GDK_BUTTON1_MOTION_MASK event propagation



I'm trying to creating a panning widget.  The basic idea behind my
approach is to derive my widget from a GtkEventBox, stuff a scrolled
window inside it and connect to the "motion-notify-event" signal
handler.  The users of the widget then put their child in the scrolled
window.

When the widget placed in the scrolled window has its own GdkWindow,
e.g. a GtkDrawingArea, then the motion events are not propagated to
the event box.  This is independent of the "above child" setting on
the event box.

I've included a code snippet below which illustrates the scenario.  As
is, the button press events are passed to both the drawing area and
the event box, however, the event box does not get any motion events.
When nothing is placed inside the event box (by changing the #if 1 to
a #if 0), the event box receives the motion events.

I don't think I should have to add the GDK_BUTTON1_MOTION_MASK to the
GtkDrawingArea's event mask as this violates the encapsulation.

Can someone please tell me where I've gone wrong?

Thanks,
Neal



Makefile:


CFLAGS=`pkg-config gtk+-2.0 --cflags`
LDLIBS=`pkg-config gtk+-2.0 --libs`

eventbox: eventbox.c


eventbox.c:


#include <gtk/gtk.h>

static gboolean
event_box_button_press_event (GtkWidget *widget,
                              GdkEventButton *event,
                              gpointer user_data)
{
  printf ("%s\n", __func__);
  return FALSE;
}

static gboolean
event_box_motion_notify_event (GtkWidget *widget, GdkEventMotion *event,
                               gpointer user_data)
{
  printf ("%s\n", __func__);
  return FALSE;
}

static gboolean
drawing_area_button_press_event (GtkWidget *widget,
                                 GdkEventButton *event,
                                 gpointer user_data)
{
  printf ("%s\n", __func__);
  return FALSE;
}

int
main (int argc, char *argv[])
{
  gtk_init (&argc, &argv);

  GtkWidget *w = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_default_size (GTK_WINDOW (w), 200, 200);
  gtk_widget_show (w);

  GtkWidget *event_box = gtk_event_box_new ();
  gtk_event_box_set_visible_window (GTK_EVENT_BOX (event_box), TRUE);
  // gtk_event_box_set_above_child (GTK_EVENT_BOX (event_box), TRUE);
  gtk_widget_add_events (event_box,
                         GDK_BUTTON1_MOTION_MASK
                         | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
  g_signal_connect (G_OBJECT (event_box), "button-press-event",
                    G_CALLBACK (event_box_button_press_event), NULL);
  g_signal_connect (G_OBJECT (event_box), "motion-notify-event",
                    G_CALLBACK (event_box_motion_notify_event), NULL);
  gtk_container_add (GTK_CONTAINER (w), event_box);
  gtk_widget_show (event_box);

#if 1
  GtkWidget *drawing_area = gtk_drawing_area_new ();
  gtk_widget_add_events (drawing_area,
                         GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
  g_signal_connect (G_OBJECT (drawing_area), "button-press-event",
                    G_CALLBACK (drawing_area_button_press_event), NULL);
  gtk_container_add (GTK_CONTAINER (event_box), drawing_area);
  gtk_widget_show (drawing_area);
#endif

  gtk_main ();

  return 0;
}



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