Re: NotifyUngrab handling
- From: Owen Taylor <otaylor redhat com>
- To: gtk-devel-list redhat com
- Subject: Re: NotifyUngrab handling
- Date: 20 Jan 1999 17:31:23 -0500
Felix Bellaby <felix@pooh.u-net.com> writes:
> Owen Taylor writes:
> > Do you have code that demonstrates the problem?
>
> Ok, try the following:
Well, I was hoping for a nice neat example program...
> 1) Start up gnome with the gnome-session manager.
>
> 2) Start up a gnome-terminal (with an enabled menubar).
>
> 3) Execute the command:
>
> $ save-session &
>
> 4) Quickly click on one of the menus on the gnome-terminal and move
> the mouse away over onto the root window (so that the menu stays up).
> The gnome-terminal will now have a grab on the pointer waiting
> for a button press or for a motion event over the menu.
>
> 5) Wait for a few seconds until gnome-session has started the
> save and gnome-terminal has responded by executing the following
> code in gnome-client.c(save_yourself_callback):
>
> gdk_pointer_ungrab (GDK_CURRENT_TIME);
> gdk_keyboard_ungrab (GDK_CURRENT_TIME);
> gtk_grab_add (client_grab_widget);
>
> This code removes the grab held by the gnome-terminal. The
> pointer icon changes to reflect this event and a NotifyUngrab
> is sent by the Xserver (see XUngrabPointer (3)).
Note that there is no "NotifyUngrab" event. There are
enter/leave notify events with a mode sent to Notify[Un]Grab,
but these events are not generated when the mouse
is over the grab window.
To call gdk_pointer_grab() when your code did not grab
the pointer is simply unsupported in GTK+. So your code
might well cause the pointer to be ungrabbed without
the menu code having any knowledge of that at all.
> 6) Now, when you press the mouse button the gnome-terminal menu
> does not recieve the event because it does not have the grab.
> As a result, the menu stays may it is and remains there
> until you send an event to the gnome terminal itself.
>
> 7) For example, you can drag the gnome-terminal out from under
> the menu using the window manager handles on its frame, but
> if you click on the gnome-terminal client window then the menu
> gets the event and pops down (gnome-client.c will have released
> its grab by now).
> Similar effects can be generated by the Xserver spontaneously
> when it issues a NotifyUngrab as a result of the menu becoming
> obscured.
Not true, you can have a grab on an obscured window. You
can't have a grab on a window is not "Viewable" - i.e.,
it or one of its parent windows is hidden.
Basically, when you grab the X the mouse or keyboard, the
only way that any other client can cause your to release
that grab is by hiding your windows.
> However, these are more tricky to reproduce because
> the NotifyUngrab is rarely the LAST event to be recieved by the
> gtk app. Usually, the WM sends some other event (e.g. FocusOut)
> which causes the menu system to close down.
No, the only thing that causes the menu system to close
down is a ButtonPress or Release.
> That said, I have seen menus left hanging on the screen
> occaisonally and my diagnosis of the problem lies with missed
> NotifyUngrab messages.
If anybody can provide a reproducible way of getting
menus to hang on the screen, please do send it in.
> > Offhand, I don't understand why the app needs to
> > to worry about NotifyUngrab at all. (Not saying there
> > isn't a reason, I just don't know it.)
>
> The reason is not to difficult to root out.
>
> Grabs are set so that events that would usually go somewhere else
> go to the window with the grab. This must mean that the window
> intends to respond to these events in some way (e.g. deactivating
> a menu). If the grab is taken away then the events that the window
> was waiting for will go somewhere else. As a result the window
> will be left waiting for something that does not get there.
>
> In most circumstances, some other event gets through that has the
> same effect as the events that were missed and there is no visible
> bug. However, this is a hit and miss approach that resembles
> reading from a stream without checking that the connection is still
> open and free of io errors.
But the point is, X does not provide a reliable way of
detecting ungrabs, because there is no need for such a
mechanism, since no other client can cause you to forcibly
release a grab.
Now, I understand why you don't want to hold a grab while
waiting for SaveYourselfDone - other clients may need
to interact with the use. But Notify[Un]grab enter/leave
events don't do us any good.
If we want a mechanism for this, we need to invent it ourself.
(Actually, session management isn't the only case where this
type of thing comes up. In DND, when a drag starts, one
wants to convince the widget where the drag started that
it should ignore the button press event that started the
drag.)
Perhaps we need an GDK_ABORT_GRAB_REQUEST event which we
send to the window holding the grab to tell it to give
up the grab. But this would require quite a bit of
code modification - there are 15 uses of gdk_pointer_grab()
in GTK+, 9 in gnome-libs, 22 in the GIMP, etc...
(and it would require breaking binary compatibility to add
another event type)
I don't think we want to do that right now.
Isn't the right thing to do just to hold up the processing
of the SaveYourself message until the grab was released -
i.e., poll in a timeout until !gdk_pointer_is_grabbed().
(There is no equivalent gdk_keyboard_is_grabbed(), but
grabbing the keyboard without grabbing the pointer
is a bug, so that should not be a problem)
Regards,
Owen
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]