getting button_press event for gtk_drawing_area (was: calling gdk_x11_drawable_get_xid() causes corruption...)




Hi,

In short what I want is "packing multiple gtk_drawing_area in a window
and getting button press event from each drawing area".

The drawing areas are meant for "animated video thumbnail"(shortened and
downscaled). When you clicking on a thumbnail, it starts the actual
playback on a different window.

It needs to get XID for each drawing area so that it can feed the
thumbnail video stream from gstreamer pipeline. Also the button press for
each drawing area needs to be distinguishable so that the program can
start the playback of the correct video. I would use the common callback
func for all the drawing area because the number of drawing area is
determined and changes at run time.

This has been working fine until being compiled with gtk+-2.18.0 but does
not work after that. Now I found that it worked with the later gtk if I
add GDK_BUTTON_RELEASE_MASK when calling gtk_widget_set_events(). I don't
know why... I even don't have the callback for the event.

I guess I am simply wrong with my coding. I appreciate if someone can
educate me a bit how this should be done correctly. The sample below is
still valid. (if you add GDK_BUTTON_RELEASE_MASK, it works)

-
Here is some additional note. Firstly I thought this is related with
gdk_x11_drawable_get_xid() because it happens only after I call the
function. However, by conducting "git bisect" against gtk repository and
identifying which exact code makes the change of behavior, I learned that
my guess was most likely wrong.

With a commit (6fef640debbe468586ff866cbef38d7a29c452d1),
get_native_event_mask() in gdk/gdkwindow.c is given much less 'default
(?)' event mask and GDK_BUTTON_RELEASE_MASK is one of those dropped. Then
I found that if I add it at application side, it works as I wish.

If someone wonders what the hell this is all about... you can find the
explanation on the application and download whole source at

http://drag0n.fam.cx/?page_id=237

Regards,
Eigo

-----
On Thu, 3 Dec 2009 00:21:59 +0200
Eigo Mori <eigom pop01 odn ne jp> wrote:


Hi,

I am having trouble to catch button_press_event on gtk_drawing_area
correctly after calling gdk_x11_drawable_get_xid() for the
drawing_areas.

Please find the sample code below. It packs 10 drawing_area and set
event handlers. When you click on the drawing_area, it prints out which
drawing_area has been clicked. (i.e. 0-9)

This seems to work as I hope if I don't call gdk_x11_drawable_get_xid
(). If I call gdk_x11_drawable_get_xid(), it reports correct number
firstly but keep printing out the same number even if I click on the
different drawing_area later. XID itself seems to be collected
correctly.

This does not seem to occur with gtk+-2.18.0 or earlier but occurs with
gtk+-2.18.1 or later.

It is quite possible that my code is wrong and was working by luck. But
I couldn't find the right way after some struggling... I will
appreciate if someone can kindly educate me.

-----
/*
  xid_test.c
  gcc -g -Wall `pkg-config --cflags --libs gtk+-2.0 gdk-2.0` -o
xid_test xid_test.c */

#include <stdlib.h>
#include <gtk/gtk.h>
#include <glib.h>
#include <gdk/gdkx.h>

GtkWidget *hbox, *window, *drawing_area[10];
GMainLoop *loop;
gulong xid[10];

static void
click_handler( GtkWidget *widget, GdkEventButton *event, int* p )
{
  g_printerr( "%dth icon clicked\n", *p );
}


static void
expose_handler( GtkWidget *widget, GdkEventButton *event, int* p )
{

  /*
  xid[*p] = gdk_x11_drawable_get_xid( widget->window );
  g_printerr( "getting xid for %dth icon : %ld\n", *p, xid[*p] );
  */
  gdk_draw_arc( widget->window,
              widget->style->fg_gc[GTK_WIDGET_STATE( widget )],
              TRUE,
              0, 
              0, 
              widget->allocation.width,
              widget->allocation.height,
              0, 
              64*36*(*p+1)
              );
}

int
main(int argc, char *argv[])
{
  int i;
  int id[10] = {0,1,2,3,4,5,6,7,8,9};

  gtk_init(&argc, &argv);

  hbox = gtk_hbox_new(FALSE,0);
  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_widget_set_usize( window, 600, 50 );
  gtk_container_add(GTK_CONTAINER(window), hbox);

  for(i=0;i<10;i++){
    drawing_area[i] = gtk_drawing_area_new();
    gtk_signal_connect(GTK_OBJECT(drawing_area[i]), 
                     "button_press_event", GTK_SIGNAL_FUNC
(click_handler), &id[i] ); gtk_signal_connect(GTK_OBJECT(drawing_area
[i]), "expose_event", GTK_SIGNAL_FUNC(expose_handler), &id[i] );
    gtk_widget_set_events(drawing_area[i], GDK_EXPOSURE_MASK |
GDK_BUTTON_PRESS_MASK); gtk_drawing_area_size(GTK_DRAWING_AREA
(drawing_area[i]), 50, 50 ); gtk_box_pack_start(GTK_BOX(hbox),
drawing_area[i], FALSE, FALSE, 2); }

  gtk_widget_show( hbox );
  for(i=0;i<10;i++){
    gtk_widget_show(drawing_area[i]);
  }
  gtk_widget_show( window );

  for(i=0;i<10;i++){
  /* 
     seems that it does not matter whether you get xid here
     or in expose handler
  */
  /*  works if you comment it out  */
    xid[i] = gdk_x11_drawable_get_xid( drawing_area[i]->window );

    g_printerr( "getting xid for %dth icon : %ld\n", i, xid[i] );
  }

  loop = g_main_loop_new (NULL, FALSE);
  g_main_loop_run( loop );

  exit( 0 );
}
-----

Regards,
Eigo
_______________________________________________
gtk-app-devel-list mailing list
gtk-app-devel-list gnome org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list



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