GNOME Bugzilla – Bug 306372
Non-focusable window overlaps active window
Last modified: 2020-11-06 20:08:55 UTC
Please describe the problem: I have a window F1 that doesn't accept input focus (globally active input model, input field is False, WM_TAKE_FOCUS is present and XSetInputFocus is not called). Another window D1 is focusable and transient for F1. Third window F2 is a separate (not transient for any other window) focusable window. If F2 is an active window and user clicks on F1, then F1 and D1 are raised in the Z-order stack over F2, but do not become active windows. If user then clicks F2, it doesn't get raised over F1 and D1. That is wrong, it should be corrected either to F2 to remain on top of F1 and D1, or to D1 to become an active window as a child of unfocusable F1, or raise F2 when it is clicked with mouse. Steps to reproduce: The file is attached. Compile it with gcc -lX11 -L/usr/X11/lib -o native native.c and the run with ./native Actual results: F1 and D1 are raised over F2, but F2 remains an active window. If user then clicks with mouse on F2, it stays below F1 and D1. Expected results: Either F1 and D1 do not get raised over F2, or F2 get raised over F1 and D1 when user clicks on it. Does this happen every time? Always Other information: The problem first appeared in Java application, see Sun Microsystem's bug database for more info at http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6272225
Created attachment 47188 [details] Test source
Clarification: _only_ affects that buggy focus mode known as click-to-focus. Sorry, couldn't resist. ;-) Also, F2 must still have focus when it's below F1 and D1 in order to trigger this bug. Took me a while to figure that out. It appears to be caused by the following code in meta_window_notify_focus(): /* Ungrab click to focus button since the sync grab can interfere * with some things you might do inside the focused window, by * causing the client to get funky enter/leave events. */ if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK) meta_display_ungrab_focus_window_button (window->display, window) Removing that part of the code (and the corresponding meta_display_grab_focus_window_button() call below it in the same function) "fixes" this problem by allowing F2 to be raised when clicked on. I never understood what the *grab_focus_window_button() stuff was for, and I don't grok the globally active input focus model or what we're supposed to do with it, so maybe Havoc or Rob can comment here...
Yes, that was click-to-focus mode on my desktop, but I suppose it to be the default mode on the most modern desktops, including Win32. And it is strange to have an active window below inactive ones, isn't it? Thanks for the fast reply, Elijah:)
My guess at the fix is that when a window does not accept focus and we try to focus it, we should try to focus its transients, and if that fails we should do the "find a default window to focus" trick. Something like that. Basically try to be sure that F2 gets unfocused. For future reference, the reason we need to ungrab on the focused window is another bug in here: if we have a grab then when you click the window, an enter/leave event pair will be sent. This breaks some applications, I think it was Maya and maybe a random in-house app someone had written.
As I noticed, the behaiviour described (i. e. to try to focus transients if a window doesn't accept focus) is just the same as KDE does, so it would be fine to fix the bug in such a way.
I just tried running the program you gave above under KDE, and it does the same as under Metacity. How will we know to give focus to the transients if XSetInputFocus is never called for F1?
bugzilla.gnome.org is being replaced by gitlab.gnome.org. We are closing all old bug reports in Bugzilla which have not seen updates for many years. If you can still reproduce this issue in a currently supported version of GNOME (currently that would be 3.38), then please feel free to report it at https://gitlab.gnome.org/GNOME/metacity/-/issues/ Thank you for reporting this issue and we are sorry it could not be fixed.