GNOME Bugzilla – Bug 784766
Opening tooltip when window out of focus brings window to foreground without taking focus
Last modified: 2018-05-02 18:42:10 UTC
On win32 (not sure if this occurs anywhere else) if a window is in the background, but partially visible, and you hover the mouse over something that has a tooltip, the entire window is brought to the foreground, but does not take focus. The issue here is in order to switch back to whatever window was in the foreground previously, you must click on the gtk+ window, and then back on the other window, as clicking just back on the other window no longer works, as that window still has focus. Better behaviour would be either: a) only the tooltip is brought to foreground, not the entire window (I believe this was the behaviour on versions previous to gtk+4) or b) the window needs to take focus This issue is compounded in one of my applications where a modal GtkDialog is opened from the context menu of a GtkTreeView, however the mouse is left long enough on the treeview to trigger a tooltip, and the modal dialog is sent out of the foreground, and then users can't figure out why the application is not responding (they would need to go to the taskbar to select the modal dialog and close it to regain interactivity) This issue can be reproduced in the gtk4-demo, opening the Builder application, put the window into the background with the "New" button still visible, and another window covering the rest of the window, and hover the mouse over the new button.
This doesn't seem to happen on X11, although the tooltips themselves are placed weirdly - above and to the left of e.g. the buttons in gtk4-widget-factory, in contrast to below and centred in gtk3-widget-factory.
Created attachment 360135 [details] test case I can confirm the reported behaviour on GTK+ 3 too, on win32. It doesn't happen on GTK+ 2, however.
(In reply to Marc Micalizzi from comment #0) > This issue can be reproduced in the gtk4-demo, opening the Builder > application, put the window into the background with the "New" button still > visible, and another window covering the rest of the window, and hover the > mouse over the new button. The Builder window is modal for the main gtk3-demo window, so we can't put the main window over the Builder one to test this. And the reported issue, as far as I can tell, only occurs between GTK+ windows (probably in the same application), not between e.g. the Builder window and the MSYS2 terminal from which I opened it. However, what *does* happen is that if you * have the gtk3-demo open * have the Builder positioned over the main window * open a Windows Explorer window, doesn't matter where * hover over the New button then *now* the main window of gtk3-demo gets raised above the Builder one! So it's not necessarily the window holding the widget whose tooltip is shown, that ends up getting raised. Either that, or transient-for is confusing matters here.
Created attachment 360144 [details] [review] GDK W32: Don't let TEMP windows cause zorder side-effects Pass SWP_NOOWNERZORDER when rising TEMP windows to the top. This ensures that they don't drag anything else to the top with them. The use-case for this is a tooltip appearing for a non-foreground window, causing said window to rise above other windows, some of which maybe foreground at the moment. Here, whipped this up. Fixes the testcase for me. Would you please verify that it also fixes the bug in real apps? Also, what kinds of TEMP windows do we have, other than tooltips?
Answering my own question: GDK_WINDOW_TEMP is used for all GTK_WINDOW_POPUP windows (all DnD indicators, tooltips, and temporary widgets that just pop up somewhere, like combobox dropdown lists, entry completion window, etc). Some widgets use GDK_WINDOW_TEMP directly, other use GTK_WINDOW_POPUP. I don't see any reason to not to use SWP_NOOWNERZORDER on them.
Marc, are you able to test the patch? It could be a while before I'm in a position to build GTK+ on Windows, but I get the impression that you have no problem with that, since you were initially talking about GTK+ 4.
The behaviour is still present using SWP_NOOWNERZORDER in gdk_win32_window_raise for GDK_WINDOW_TEMP
(In reply to Marc Micalizzi from comment #7) > The behaviour is still present using SWP_NOOWNERZORDER in > gdk_win32_window_raise for GDK_WINDOW_TEMP I'll need a testcase that reproduces this (or a way to reproduce this with existing applications), because after applying the SWP_NOOWNERZORDER fix i can't reproduce this bug with attachment 360135 [details]. Also note that i'm working with GTK-3-22, not GTK4.
(In reply to LRN from comment #8) > (In reply to Marc Micalizzi from comment #7) > > The behaviour is still present using SWP_NOOWNERZORDER in > > gdk_win32_window_raise for GDK_WINDOW_TEMP > > I'll need a testcase that reproduces this (or a way to reproduce this with > existing applications), because after applying the SWP_NOOWNERZORDER fix i > can't reproduce this bug with attachment 360135 [details]. Also note that > i'm working with GTK-3-22, not GTK4. I am working with GTK+4, so maybe that could be the difference, I don't have an active GTK+3 environment on Win32 to check with however. As for the test case, I'm using the original testcase from my original report (using gtk4-demo). Just for the sake of demonstration, I recorded the screen running the test case showing popup over both it's own console window, and another (putty) window, and then also with a breakpoint to where the patch to the function is to show that it is in fact following that path. https://youtu.be/D1AbxtDaicE I'll see if I can come up with anything else that could address the issue now that I know where to look in gdk.
Also the test case in attachment 360135 [details] still exhibits the behaviour in gtk+4 for me as well. Could this issue possibly be related to Windows 10 or msvc2017?
Created attachment 361370 [details] [review] Expanded potential fix from attachment 360144 [details] [review] Actually, this seems to be related to gdk_win32_window_set_keep_above and gdk_win32_window_keep_below as well and not just gdk_win32_window_raise. I have no idea if it is correct or not, or would have unintended side-effects, but adding SWP_NOOWNERZORDER if the window is temp to the respective API_CALLs to SetWindowPos in those two functions fixes it for me.
Review of attachment 361370 [details] [review]: ::: gdk/win32/gdkwindow-win32.c @@ +5109,3 @@ setting ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, + SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | (GDK_WINDOW_TYPE(window) == GDK_WINDOW_TEMP ? SWP_NOOWNERZORDER : 0))); obligatory nitpick: space before ( I'd also normally say to ditch the tabs, though in this case there is conflicting whitespace around the edited lines, so it doesn't really matter... not sure in such cases if it's best to use spaces like all of these should, or give up and follow the surrounding lines. :S @@ +5135,3 @@ setting ? HWND_BOTTOM : HWND_NOTOPMOST, 0, 0, 0, 0, + SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | (GDK_WINDOW_TYPE(window) == GDK_WINDOW_TEMP ? SWP_NOOWNERZORDER : 0))); ditto
Created attachment 364840 [details] [review] GDK W32: Don't let window zorder changes cause side-effects v2 * Use SWP_NOOWNERZORDER on nearly all calls to SetWindowPos() where zorder changes. My reasoning is the following: GTK window-handling logic is mostly derived from X, and, AFAIK, X WMs do not try to keep relative Z-order intact when one of the windows is raised or lowered. Therefore we should just disregard this functionality that Windows WM has, and change window Z-order without regarding any other window that might be below or above it. We do have functions that ensure correct stacking order, just for these cases. Also, i've tested the previous patch on GTK4 and was able to confirm that it is insufficient indeed. V2 works though.
-- GitLab Migration Automatic Message -- This bug has been migrated to GNOME's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/gtk/issues/852.