GNOME Bugzilla – Bug 122737
gok masked by 'log out' window
Last modified: 2004-12-22 21:47:04 UTC
using gnome-2.4 build from 18/09/03 -launch GOK -activate 'top panel','menus',actions','log out' .if(often) the GOK window is centered on the screen, whenever 'log out' is selected, it's window is focused on top of gok and gok's controls are inaccessible, yielding log out inpossible.
If clicking on a mouse button doesn't cause GOK to pop to the top in this case, then probably the Log Out button is doing a mouse button grab, which it should NOT be doing. Can you log out with GOK *if* you use XInput (not core pointer, and input devices are not controlling the core pointer), as long as the GOK window is visible on screen?
I've just tried logging out using an xinput switch, and I can log out fine, UI grabbing the 'OK' button if the GOK window is visible on screen. When the logout window hides the GOK window, the xinput device can still be used to log out in the same way, only it is unsighted and needs guessing as to where the buttons are. When using core pointer/direction selection, when the logout window hides the gok window, there is no way to access GOK's controls. Clicking the mouse as you say does not cause GOK to popup, and even if the window is visible and not masked, logout appears to lock out all windows - clicking on GOK's window does nothing...
I think that the first thing to do is make GOK pop to the front when it gets non-corepointer input events (it already does this on receipt of core-pointer events). We need to do that anyhow for xscreensaver compatibility, etc. etc. I don't know if we'll be able to solve the Logout+corepointer issue (until we have XEvIE support for GOK on all platforms), we may just have to say that GOK can't be used to log out (except via the terminal) unless XInput is used.
my suggested fix does not work; looks as though the logout dialog can't be "popped over". workaround is to run GOK in 'dock' mode, reducing severity on that basis.
I wonder if gok should have a logout button, which would make sure gok is docked before invoking a session logout.
It is necessary for GOK to be placed in front of windows that are of type override redirect. This is managed by the window manager. There is currently a discussion on the wm-spect-list trying to define a protocol to address this situation. It was suggested that a new state be added to the wm-spec to indicate this, _NET_WM_STATE_ABOVEALL, although there was some discussion that it would be better handled by a new WM_TYPE rather than a new state.
there's simply no way for gok to be above override redirect windows; metacity doesn't even ever find out these windows exist, much less have any power to control their destiny. The only solution would be to change override redirect to some sort of pseudo-override redirect type of window and then combine that with the aboveall state. Overall quite messy and not assured of working by any means. The best place to deal with this if most likely through an X extension accessiblity framework to allow the installation of an onscreen keyboard; perhaps it could simply claim part of the root window and put all other applications into the remaining space.
tis a bug. Rob, what you said about override redirect is at odds with my understanding of how WMs and XRaiseWindow interact. There have been in the past bugs against WMs complaining that they (incorrectly) allowed windows to pop over override-redirects. I agree that WMs don't manage override-redirect windows, but my understanding is that it is possible for non-override-redirects to raise over them. In any case this is a serious bug, not a 'notabug'; reopening.
Override redirect windows can call XRaiseWindow on themselves and raise to the top of the window stack. Metacity never recieves a ConfigureRequest when such an action is performed (this is the definition of override redirect), so metacity is not informed when such a window is mapped or when such a window raises itself to the top. Metacity does not, therefore, have the ability to either 1) prevent the override redirect window from raising itself or 2) respond to the raise and move gok to the top when it does happen. If you know of a way around this I'd of course be more than happy to know it. From the Xlib documentation: "The XRaiseWindow function raises the specified window to the top of the stack so that no sibling window obscures it. If the windows are regarded as overlapping sheets of paper stacked on a desk, then raising a window is analogous to moving the sheet to the top of the stack but leaving its x and y location on the desk constant. Raising a mapped window may generate Expose events for the window and any mapped subwindows that were formerly obscured. "If the override-redirect attribute of the window is False and some other client has selected SubstructureRedirectMask on the parent, the X server generates a ConfigureRequest event, and no processing is performed. Otherwise, the window is raised. "
I agree with and understand this: "Override redirect windows can call XRaiseWindow on themselves and raise to the top of the window stack. Metacity never recieves a ConfigureRequest when such an action is performed (this is the definition of override redirect), so metacity is not informed when such a window is mapped or when such a window raises itself to the top. Metacity does not, therefore, have the ability to either 1) prevent the override redirect window from raising itself or 2) respond to the raise and move gok to the top when it does happen." We aren't asking metacity to intercept the override-redirect Raises, we're asking metacity not to prevent GOK raises when an override-redirect is present (which metacity appears to do). IOW, at the moment if GOK calls XRaiseWindow, the window doesn't raise. I believe this is because of metacity's intervention but am not 100% sure (not sure what the second paragraph you quote from Xlib about SubstructureRedirectMask means). Can you clarify what is meant by "some other client has selected SubstructureRedirectMask on the parent" ? Thanks
Oh. That's a possiblity. We'll have to look into what's going on there; I honestly don't know what metacity does in response to a raise configure request. The SubstructureRedirectMask client is the window manager; i.e. a client that's told the server it wants to handle ConfigureRequests.
You need to move this bug to gnome-session. Override redirect windows are on top of regular windows, there's no way to change that without breaking tons of stuff. Your only solution is to make the logout window not override redirect. It was probably only override redirect because we used to grab the server, so if we no longer grab the server you could probably just make the logout window state ABOVE and undecorated.
I still think that we need to allow onscreen keyboards to raise above override-redirects. But since we don't have an appropriate WM_STATE or WM_TYPE for onscreen-keyboards yet, I agree that the expedient solution is to change the window type of gnome-session's logout window. This problem will occur with any override-redirect window, however, which required user interaction.
cleared the metacity-maint assignment and assigned to gnome-session-maint.
we still grab the server
If gnome-session grabs the server then metacity can't make any X requests to move GOK anywhere, there's no way to fix this bug in that case. I'm not convinced there's a way to allow GOK to raise above override redirect windows either, really, even without the server grab.
the server is _not_ grabbed if the accessibility gconf key is true. The problem is that gnome-session sets the gtk-window-type for the dialog to GTK_WINDOW_POPUP.
I attach a one-line patch that resolves the symptom. The patch makes the logout window a 'no decorations' window but doesn't make it override-redirect. Since logout grabs mouse and pointer (and, if accessibility == false, the whole server), I don't see much need to make the window override redirect. If you (maintainers) prefer, I can rework the patch to retain override-redirect if accessibility==false.
Created attachment 21464 [details] [review] patch to make window no-decorations but not override-redirect; fixes gok issue
Looks good, please go ahead
Fixed in CVS; thanks Mark!
Okay, I'm seeing serious breakage with this patch. gnome-session is getting a BadMatch when it does the XSetInputFocus in logout.c. Looking at XFree86, the problem is more than likely that the window isn't mapped before we do the SetInputFocus. Bill, were you seeing this when you tested the patch ?
no, I definitely was not seeing this issue. what makes you think the one-line patch is responsible?
Mainly because reverting the patch fixes the problem.
You probably tested it with a11y switched on. Please try turning it off and let me know
if that patch causes this problem then I think it is exposing an underlying bug elsewhere.
Could you take a look at it ?
I am looking at it. Could take some time.
I've reverted this for now
a relatively straightforward solution for the BadMatch would be to conditionally use override-redirect (only if the server is grabbed/accessibility is off). But I somehow feel solving the problem of realize-while-server-grabbed for the general case would be cleaner and better. Is there a reason why the server (in the non-a11y case) must be grabbed prior to the gtk+ calls which set up the dialog? IOW, would it be okay to either: (1) defer the serverlock and screen fade until after the gtk+ window is posted, or (2) fade the screen, then unlock the server just long enough to post the gtk+ window, then lock it again? [I suspect doing #2 might introduce an undesired race condition, so #1 sounds safer to me personally] Whay do you think Mark?
I attach a better patch. It uses override-redirects if a11y is off (i.e. current behavior). It uses an undecorated GtkWindow if a11y is on ( and thus the server isn't grabbed ). Making the non-popup GtkWindow work right if the server is grabbed appears to be, ah, nontrivial. Note also that the revised patch solves a problem with the pointer grab in the non-override-redirect case; we have to wait for gtk idle before moving our pointer grabs, otherwise the GtkButtons won't react to the pointer when we run the dialog. This 'sync' only occurs (and only needs to occur) for the a11y-enabled, non-override case.
Created attachment 22058 [details] [review] better patch which avoids the regressions noted when bug reopened.
Okay, so we can only used a managed window for the logout dialog if we don't grab the server ... because we map the window after the server is grabbed .. So, I've made the window override_redirect only when a11y is disabled. I've also made it not grab the pointer/keyboard which fixes the pointer issues you were seeing. 2004-01-14 Mark McLoughlin <mark@skynet.ie> Fix logout freezing reported in bug #129402. Also, make the logout window WM managed if a11y is enabled, see bug #122737. * logout.c: (force_pango_cache_init): kill, we're not using the pangox backend anymore. (display_gui): Don't grab the keyboard or mouse if a11y is enabled. Also, only create a override_redirect window if a11y is disabled. Don't try and set the GtkWindow's "type" property after construction as gtk+ 2.3 doesn't allow this anymore. Delay grabbing the Xserver as long as possible. Don't leak the invisible window.
Thanks Mark! Just as a final question, your applied patch was substantially similar to the one I posted 12/03/03, wasn't it? From the description above it seems so. regards...
No, I didn't have your patch at hand when I was fixing this and now that I look at your patch again: + You add an extra XUngrabServer for no reason + You continue to use GtkWindow's "type" property after construction which causes logout to freeze with glib 2.3.1 + You add a really hacky looking "process all pending events" which I'm not sure is very reliable. + You don't remove the keyboard/pointer grabs when a11y is disabled, which I'm pretty sure would have cause problems if you had tried to use gok with the logout dialog.
Thanks Mark, particularly for finding the 'set type after construction' issue. For some reason I wasn't seeing that problem though I think I was running 2.3.X. The extra Ungrab was cruft I'm sure. I should have pulled the whole patch out and started over when I realized that 'two codepaths' for creating the window would be necessary. I was having problems if the grab took place before the window was posted however. Thus the mainloop iteration, IIRC. I had no problems running GOK with my previous patch at logout (provided a11y was on). GOK can't work correctly with a11y off anyhow, at least not at logout, for other reasons.
Wow! Nice to log in this morning and see this fixed! Thanks all.