Re: clist/notebook bug? + patch



Damon Chaplin wrote:
> 
> Elliot Turner wrote:
> >
> > Hello,
> >
> > I noticed some strange behaivor with gtk+-1.1.12 in relation to CLists and
> > NoteBooks.
> >
> > I have a notebook widget with several pages, one of which contains a
> > GtkCList as it's child.
> >
> > I use gtk_signal_connect() to connect a signal handler function to the clist
> > to handle the signal "select_row".  inside this handler function, I check to
> > see if the event is a GDK_2BUTTON_PRESS.. if it is, i call
> > gtk_notebook_set_page() to switch the currently active page of the parent
> > notebook.
> >
> > This results in most of the application becoming unresponsive to any mouse
> > clicks.  The notebook is still responsive, (it seems like all parent widgets
> > of the clist which got the GDK_2BUTTON_CLICK are still responsive, but
> > nothing else) but children widgets inside other notebook pages become
> > completely unresponsive.
> 
> This seems to be the same problem I reported about the file selection dialog.
> (If I hid the file dialog when a file is selected with a double-click, it
> froze and I couldn't select any widgets.)


I've figured this out (eventually!)

The problem is due to the double-click, which results in these signals:

  button_press_event    (type = GDK_BUTTON_PRESS)

  button_release_event

  button_press_event    (type = GDK_2BUTTON_PRESS)
  button_press_event    (type = GDK_BUTTON_PRESS)

  button_release_event

In our code we both used handlers which hide the clist on the
GDK_2BUTTON_PRESS (either by hiding a dialog or switching notebook pages).

But the clist still gets the next button_press_event (even though it is now
unmapped). Now it attempts to grab the pointer and a GTK grab again.
X won't let it grab the pointer if it is not mapped, but GTK will let it
grab all GTK events.

This confuses GtkCList, which thinks it will always have both grabs. It uses
this test a lot:
  if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist))

So it doesn't think it has the grabs, and so never releases the GTK grab.


Solution
========

A quick solution is for gtk_clist_button_press() to just return if the widget
is no longer mapped:

--- gtkclist.c.orig     Sat Jan  9 22:32:57 1999
+++ gtkclist.c  Sun Jan 17 17:21:37 1999
@@ -4845,6 +4845,11 @@
   g_return_val_if_fail (GTK_IS_CLIST (widget), FALSE);
   g_return_val_if_fail (event != NULL, FALSE);
 
+  /* It is possible that something handled a double-click event and the clist
+     has now been hidden, in which case we don't want to do anything. */
+  if (!GTK_WIDGET_MAPPED (widget))
+    return FALSE;
+
   clist = GTK_CLIST (widget);
 
   button_actions = clist->button_actions[event->button - 1];


A better approach may be to make sure that only mapped widgets can have GTK
grabs, and for widgets to check that they are mapped before trying to get a
grab.

Damon

P.S. GtkCTree and GtkList have similar code to GtkCList, so they may need
fixing
as well.




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