GNOME Bugzilla – Bug 746745
Window suddenly always on top
Last modified: 2016-01-26 12:01:37 UTC
After opening a closing other windows in the program, suddenly the main window is always on top. No other window/dialog can get in front, also other programs can't get in front. I have a main window that opens another window, showing a calander drawn in Cairo. When I right click I popup a menu. If I popup the menu a few times, suddenly when I go back to the main window, it is always on top, not window will open in front of it, also the calander window can not get back. The windows that should get in front do have focus because I can press "Esc" and they will close. I have tried to uncomment "gtk/gdk_window_keep_above" in the source code and recompile, but the problem is still there. It must be a Windows Manager / Client Side Decoration problem
I was using Gtk+ 3.12.2 before and the problem was not there.
Can you somehow devise a consistently reproducible example, with any program, specifying which GTK+ version and version of the reproduced software?
No it is not that simple, because it is not easy to reproduce. Second I use Gtk#, so making a c program is not very natural to me. But I can try. Any idea where to start to look in the source code, {gtk/gdk}windows.c or someplace else ?
This is really a problem. Just opening and closing windows/dialogs makes this happen randomly. I can't reproduce it on my own computer but customers is complaining. At a point where I'm think of going back to 3.12. Anyone has any idea where this could happen in the code ? How can you even get Windows to make the window block all other windows on the computer (you can minimize and see other windows) but they can't get in front.
You haven't specified the version of Windows, or what your application is. You're also using Gtk#, which only recently acquired some support for GTK+ 3.x — though I am not up to speed with the stability of that binding. Without a small, self-contained reproducer that somebody can run we cannot even start understanding where the problem is. If this bug were common, other applications running with GTK+ 3.x on Windows would have noticed it. You can try and debug the issue on your own, but building a version of GTK+ with debugging messages enabled, and then use the GDK_DEBUG and GTK_DEBUG environment variables to try and trace what's happening. You can also add debugging messages to GDK and see what gets called. I'm sorry that we cannot provide more insight, but we'll need more context.
The version is Window 7 64bit, but the Gtk is 32 bit. I have now narrowed it down to, that it happens when a Gtk window/dialog is opened on top of the main Gtk window, and a program outside of the Gtk application is clicked (like IE or other program). I am still unable to reproduce it. It happen randomly within a couple of hours work. I see a lot of touch/gesture stuff in 3.14, that was not there in 3.12.
I've had this a few times. Randomly, of course. Eventually i've decided to poke the suddenly-on-top window, and discovered that the mechanism by which it is on top is that it has WS_EX_TOPMOST extended style set. That would be a good start. If you have an application that *never* normally displays always-on-top windows, you can set breakpoints on all places in gdk where it sets WS_EX_TOPMOST for a window and catch it in the act. Then backtrace would reveal the culprit.
Created attachment 303256 [details] [review] Don't set WS_EX_TOPMOST on windows This patch prevents the window from suddenly becoming always-on-top. This is properly not the right solution, but can someone see why the WS_EX_TOPMOST is set, when it should not be.
It did not resolve the problem. I will try some more.
Note that there's also the SetWindowPos() function, which can be given the HWND_TOPMOST constant as the second argument. That might be the source of the WS_EX_TOPMOST, given that the documentation says that HWND_TOPMOST is persistent.
Created attachment 303592 [details] [review] Don't call SetWindowPos with HWND_TOPMOST Made this patch. But it did not work (maybe even made i worse). I will try to remove all SetWindowPos calls for my next test.
Updated to Gtk+ 3.16.2. Still the same problem. This is very frustrating.
This is becoming a major problem for me. It happens when you click on another program and when you go back to Gtk program it is always on top (not very often, but happens many times during a working day). Anyone please help, with ideas about what could make this happen when you switches between programs ?
Created attachment 309252 [details] These are the Extended Windows Style of the window. As you can see the pic to the left has WS_EX_TOPMOST set.
Created attachment 309282 [details] [review] GDK W32: Log style changes This adds a GDK EVENTS logging for when a Windows (native) window has its style changed. This should react to a window becoming topmost as well, since topmostness is controlled by an extended window style. This patch should be appropriate for pushing into master (although i see no need to do that, not at the moment).
Created attachment 309283 [details] [review] GDK W32: break when a WM window becomes topmost Extends attachment 309282 [details] [review] to break when extended style acquires the WS_EX_TOPMOST bit. Run a program with gdk event debugging enabled (such as by setting GDK_DEBUG envvar to "events"), redirecting its output into a file (for convenience), then attach gdb to its process, then try to reproduce the bug. Note that this will react to any GDK-controlled windows becoming topmost, including the ones that *should* be made topmost at application's request. On the other hand, it will not react to windows that are created with WS_EX_TOPMOST style already set (previous patches in this bug do something to disable topmostneess at window creation time, that could be of use). This is purely for debugging and must not be pushed. I'll try to reproduce this as well, but this bug does not happen to me often.
Created attachment 309688 [details] [review] Don't set WS_EX_TOPMOST on windows I'm testing this patch now. I think maybe I have made a mistake when testing this earlier. I see this bug from 3.17.6: "752765 GtkWindow: queue states if not mapped not if not realized" could that make a different ?
I know nothing about state change queue in relation to mapping and realization, and thus can't confirm or deny that bug 752765 is related.
Created attachment 310071 [details] [review] Remove WS_EX_TOPMOST if it is set. With inspiration from the log patch. I have tried to remove WS_EX_TOPMOST on all windows if the flags style exists. But to no avail. It is still set suddenly on the main window. How the f... can that happen....
Created attachment 310072 [details] [review] 752765 GtkWindow: queue states if not mapped not if not realized I also tried this patch from 3.17.6 (weird it is not in the source code for 3.17.6). But this did not help either.
Is there a specific application where this happens with some regularity? I need some way to reproduce this.
Unfortunately not It happens when my program (XMedicus) is opening a external browser (Eg. IE/Firefox/ex). When you go back to XMedicus sometimes the main windows gets WS_EX_TOPMOST set. There is no systematic way to reproduce it. It happens sometimes 4 times in an hour. Sometimes never a whole day.
How does it open an external browser? A markup in gtklabel? A g_spawn()?
I'm using C# (Mono) and Gtk#. So I do: Process.Start (url); I have thought about some threading problems. But it also happens for some of my users that don't open anything from my program. It's just when they are going back to XMedicus from any other program.
Well, if logs don't show where the WS_EX_TOPMOST (0x00000008) style bit is being set, and you can't catch that moment with gdb, and disabling the code that sets WS_EX_TOPMOST does not fix this, then i have no idea what to do. I could try to make a different patch that *runs* gdb and attaches it to the program (instead of breaking into already attached gdb instance). That would make it more usable (as running a program under gdb all day long is often counterproductive).
Created attachment 310092 [details] This is the log when it happens. This is the log when it happens. The last line "Found WS_EX_TOPMOST" is my log. I had to remove a lot of events else it was completely impossible to see. Don't know if you can see anything from this. It does not happen i STYLE change.
Where does the "Found WS_EX_TOPMOST" come from? Your own logging code? Anyway, if style messages are not triggered when a GTK-owned window gets on top, then we have no way of catching the code that causes it "in the act", because window styles are stored somewhere in WM code that we have no access to (can't put a watchpoint on them). Best we can do is to periodically check for WS_EX_TOPMOST, which you seem to be doing already (at least that's how it seems to me). (by the way, dumping logs into a file using stderr and stdout redirection is much cleaner than taking screenshots of a console window) At some point i thought that a third-party application could be the culprit (it would certainly explain why some users are affected more than the others), but it would still have to make a window topmost by manipulating the window style, which should trigger a style change message. If a message is not being triggered, then this is some kind of bad mojo that i don't know what to do with.
Created attachment 310094 [details] [review] Prevent any not GDK_WINDOW_TEMP from becoming WS_EX_TOPMOST This will prevent any not GDK_WINDOW_TEMP window from becoming WS_EX_TOPMOST. This is not a solution, but a hack to prevent it from happening.
The patch seems to work. But how do we found the real reason behind it ....
Comment on attachment 309283 [details] [review] GDK W32: break when a WM window becomes topmost >From dea3c9c7efaad8e10b8a1acbd0eb3195db8934d8 Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?=D0=A0=D1=83=D1=81=D0=BB=D0=B0=D0=BD=20=D0=98=D0=B6=D0=B1?= > =?UTF-8?q?=D1=83=D0=BB=D0=B0=D1=82=D0=BE=D0=B2?= <lrn1986@gmail.com> >Date: Fri, 14 Aug 2015 14:29:07 +0000 >Subject: [PATCH 2/2] GDK W32: break when a WM window becomes topmost > >This is purely to debug https://bugzilla.gnome.org/show_bug.cgi?id=746745 >Make sure this is not pushed into master >--- > gdk/win32/gdkevents-win32.c | 8 ++++++++ > 1 file changed, 8 insertions(+) > >diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c >index 32bd78f..1b56df5 100644 >--- a/gdk/win32/gdkevents-win32.c >+++ b/gdk/win32/gdkevents-win32.c >@@ -3179,6 +3179,14 @@ gdk_event_translate (MSG *msg, > ((STYLESTRUCT *) msg->lParam)->styleOld, > ((STYLESTRUCT *) msg->lParam)->styleNew)); > >+ if ((msg->wParam & GWL_EXSTYLE != 0) && >+ (((STYLESTRUCT *) msg->lParam)->styleOld & WS_EX_TOPMOST == 0) && >+ (((STYLESTRUCT *) msg->lParam)->styleNew & WS_EX_TOPMOST == 1)) >+ { >+ if (IsDebuggerPresent ()) >+ DebugBreak (); >+ } >+ > /* We don't really handle this message */ > return_val = FALSE; > break; >-- >2.4.0 >
I screwed up the attachment 309283 [details] [review] - it should have been styleNew instead of styleOld in the third added line. Otherwise it would never trigger. If you've tried to debug the problem with that patch, you might want to try that again, with the corrected version this time.
(In reply to Mikkel Kruse Johnsen from comment #29) > The patch seems to work. > > But how do we found the real reason behind it .... Yeah, no reason why it shouldn't work. Basically, every time a message is processed by a window (which is effectively every time user does anything around the window) you are checking to see if the window has WS_EX_TOPMOST exstyle. If it does and if it isn't a temp window, you remove the WS_EX_TOPMOST from it by using SetWindowPos() with HWND_NOTOPMOST flag. This is obviously a dirty hack, as it completely prevents GTK from having always-no-top windows (except for temp windows), even when it (or the user) wants to. On the other hand, it's blunt and, as you've said, it works. Now, this hack could be refined to look more like the last piece of code in show_window_internal() - make it re-sync WS_EX_TOPMOST with the GDK_WINDOW_STATE_ABOVE. This would serve two purposes: 1) While still being a hack, it would allow GTK to make windows always-on-top when it needs to, while preventing spontaneous ontopness. If the patch still works after this refinement, it means that ontopness is being caused by something outside of GTK. 2) If the culprit is GTK and it makes windows ontop by giving them the GDK_WINDOW_STATE_ABOVE, this refined hack will expose that, because it will stop working. If you want, i can make a refined patch for you (though, obviously, you'd have to re-check that i haven't screwed up again...).
Created attachment 310208 [details] [review] GDK W32: break when a WM window becomes topmost v2: fixed logic errors in the condition
Created attachment 310209 [details] [review] Re-sync WS_EX_TOPMOST with GDK_WINDOW_STATE_ABOVE Refined version of the attachment 310094 [details] [review]
I'm a bit behind my other task, since I spend a lot on this one. I will try to find the real reason soon and try your patch.
Created attachment 315800 [details] A Python 2.x script to make windows ontop or not ontop (requires PyWin32) Got this again, by chance. Tried to reproduce without success. Decided to try to test the patches to see if they react when i deliberately make a window ontop. Here's the script that i ended up using. Note that i've also tried to set WS_EX_TOPMOST directly using SetWindowLong(), that didn't work (STYLECHANGING message is received, but STYLECHANGED is not; also, style bits end up being wrong in the first message), so the script uses SetWindowPos. I've used it on a GTK app and discovered that SetWindowPos(..., HWND_TOPMOST, ...) and SetWindowPos(..., HWND_NOTOPMOST, ...) do NOT cause STYLECHANGING or STYLECHANGED to be posted, even though the appropriate bit is set or cleared, as evident from examining the results of GetWindowLong(). They only ever cause WINDOWPOSCHANGING and WINDOWPOSCHANGED, and even those arrive without any identifying characteristics - GTK code tries to match hwndInsertAfter struct member to HWND_* constants, but it never matches: every time an actual window handle is provided in hwndInsertAfter (it's a handle to the "Default IME" window), both for putting a window on top and for removing the ontop status from it (it still remains foreground, just not alwaysontop, that is why, i presume, its perceived Z-order does not change, and hwndInsertAfter is about Z-order). One could call GetWindowLong() during WINDOWPOSCHANGING, but the style will not change until WINDOWPOSCHANGED, so it's not possible to prevent the window from getting that style bit, it is only possible to detect the occurrence after the fact (although "after the fact" here means "immediately after"). We still do not know what causes the bit to change - whether it's a 3rd-party application, a bug in Windows or a bug in GTK/GDK. Given that the patch that synced window WS_EX_TOPMOST with GDK_WINDOW_STATE_ABOVE seemed to have worked, i would propose to combine GetWindowLong() at WM_WINDOWPOSCHANGED with that re-sync, making the patch less of a blanket stopgap and more of a workaround for a quirk. If everyone is OK with that, i'll make the patch and we'll see if it fixes the problem (it might not - if the bit is not being set as a result of SetWindowPos(), but because of something else). Alternatively, i can add more verbosity to the existing re-sync-on-every-message patch, let the bugreporter try that with event logging and see at which message is desynchronization detected when the bug actually happens by itself (instead of us artificially triggering the code ourselves).
For anyone who is still interested in this: it occurred to me that this could be related to a nasty UI bug Windows has: sometimes a tooltip will be shown in one application (Firefox, for example), and it will persist when you switch to another window, staying on top of everything. It can be destroyed by moving a mouse over it. After a few tries i think i've managed to reproduce this: 1) Run a GTK application (Gedit or Glade, for example). 2) Switch to another window that is positioned in such a way that the GTK application window is still visible, just not focused (if you have no such window, just press WinKey to call up the start menu (Windows 7 or 10), that works just as well). 3) Move the mouse over a tooltipable element (Gedit "save" button or one of the Glade toolbuttons) and wait for a tooltip to appear 4) Alt-tab into another window From that point forward the window of the GTK application will always be on top. Please confirm that this reproduces for GTK builds other than mine (i have quite a few patches, including the ones that i've used to debug this bug).
For the step (4) you should alt-tab specifically to the GTK application (if it has multiple windows - then to the window for which the tooltip is shown), not just to another window.
Created attachment 315991 [details] A log of GDK_DEBUG=events,misc for a test application Test application has a button with a text tooltip (i.e. i provide the text, gtk creates the tooltip internally) and nothing else. Here's the juicy part of the log (i've replaced handle numbers with "MAINWINDOW" and "TOOLTIP" respectively and also made logging more verbose; asterisks mark my comments and cuts): ********** Pressed Winkey ********** WM_KEYDOWN "MAINWINDOW" 0x5b 0x15b0001 Left Windows ch:5b KF_EXTENDED sc:91 rep:1keymap: ********** Keyboard initialization cruft was here ********** ===> GDK_KEY_PRESS "MAINWINDOW" 0x5b group:0 Meta_L 0:"" => 0 ********** More keyboard initialization cruft was here ********** ********** Released Winkey ********** WM_KEYUP "MAINWINDOW" 0x5b 0xc15b0001 Left Windows ch:5b KF_UP KF_REPEAT KF_EXTENDED sc:91 rep:1 ===> GDK_KEY_RELEASE "MAINWINDOW" 0x5b group:0 Meta_L 0:"" => 0 ********** GTK window lost focus, from this point forward GTK window is foreground ********** WM_NCACTIVATE "MAINWINDOW" 0 0 DefWindowProcW => 1 WM_ACTIVATE "MAINWINDOW" 0 0 INACTIVE 00000000 DefWindowProcW => 0 WM_ACTIVATEAPP "MAINWINDOW" 0 0xde4 NO thread: 3556 DefWindowProcW => 0 WM_KILLFOCUS "MAINWINDOW" 0 0 ===> GDK_FOCUS_CHANGE "MAINWINDOW" OUT => 0 WM_IME_SETCONTEXT "MAINWINDOW" 0 0xc000000f DefWindowProcW WM_IME_NOTIFY "MAINWINDOW" 0x1 0 DefWindowProcW => 0 => 0 ********** Moving mouse cursor over the window ********** WM_NCHITTEST "MAINWINDOW" 0 0xc8011d DefWindowProcW => 12 WM_SETCURSOR "MAINWINDOW" 0x342a5a 0x200000c 0xc 0x200 DefWindowProcW => 1 ********** Lots of mouse-move-related messages were here ********** WM_NCHITTEST "MAINWINDOW" 0 0xe60115 DefWindowProcW => 1 WM_SETCURSOR "MAINWINDOW" 0x342a5a 0x2000001 0x1 0x200 DefWindowProcW => 0 WM_MOUSEMOVE "MAINWINDOW" 0 0x45 00000000 (69,0) mouse_sinwod 00000000 -> "MAINWINDOW" ===> GDK_ENTER_NOTIFY "MAINWINDOW" 00000000 (69,0) (277,230) NORMAL ANCESTORgdk_win32_window_set_cursor: "MAINWINDOW": 00000000 (TrackMouseEvent "MAINWINDOW") ===> GDK_MOTION_NOTIFY "MAINWINDOW" (69,0) (277,230) => 0 WM_NCMOUSELEAVE "MAINWINDOW" 0 0 DefWindowProcW => 0 ********** Stopped moving mouse cursor, time passes, tooltip must be shown ********** gdk_win32_window_get_root_coords: "MAINWINDOW": +69+0 +277+230 _gdk_window_impl_new: TEMP gdk_window_set_type_hint: 00000000: GDK_WINDOW_TYPE_HINT_MENU update_style_bits: 00000000: EXSTYLE: => TOOLWINDOW|TOPMOST WM_NCCREATE "TOOLTIP" 0 0x28f4a0 (no GdkWindow) DefWindowProcW => 1 WM_NCCALCSIZE "TOOLTIP" 0 0x28f48c (no GdkWindow) DefWindowProcW => 0 WM_CREATE "TOOLTIP" 0 0x28f4a0 DefWindowProcW => 0 WM_SIZE "TOOLTIP" 0 0x2b004b (no GdkWindow) DefWindowProcW => 0 WM_MOVE "TOOLTIP" 0 0 (no GdkWindow) DefWindowProcW => 0 ... "main_text.exe" 75x43@+0+0 00000000 = "TOOLTIP" with ex style 0x00000088 gdk_window_set_title: "TOOLTIP": main_text.exe WM_SETTEXT "TOOLTIP" 0 0x30f06b8 DefWindowProcW => 1 gdk_window_set_transient_for: "TOOLTIP": "MAINWINDOW" gdk_window_set_decorations: "TOOLTIP": setting update_style_bits: "TOOLTIP": no change gdk_window_set_modal_hint: "TOOLTIP": NO gdk_win32_window_get_geometry: "TOOLTIP": 75x43x32@+0+0 gdk_win32_window_get_root_coords: "TOOLTIP": +0+0 +0+0 gdk_win32_window_get_geometry: "TOOLTIP": 75x43x32@+0+0 gdk_win32_window_get_root_coords: "TOOLTIP": +0+0 +0+0 gdk_win32_window_move_resize: "TOOLTIP": 75x43@+0+0 ... SetWindowPos("TOOLTIP",NULL,0,0,75,43,NOACTIVATE|NOZORDER) WM_WINDOWPOSCHANGING "TOOLTIP" 0 0x28f7b0 NOACTIVATE|NOZORDER TOP 75x43@+0+0 now below 00000000 ('') DefWindowProcW => 0 ===> GDK_CONFIGURE "TOOLTIP" x:0 y:0 w:75 h:43 gdk_win32_window_get_geometry: "TOOLTIP": 75x43x32@+0+0 gdk_win32_window_get_root_coords: "TOOLTIP": +0+0 +0+0 gdk_win32_window_get_geometry: "TOOLTIP": 75x43x32@+0+0 gdk_win32_window_get_root_coords: "TOOLTIP": +0+0 +0+0 gdk_window_set_geometry_hints: "TOOLTIP" ... MIN_SIZE: 75x43 ... MAX_SIZE: 75x43 ... BASE_SIZE: 0x0 ... GRAVITY: 1 update_style_bits: "TOOLTIP": no change gdk_window_unmaximize: "TOOLTIP": WITHDRAWN gdk_window_deiconify: "TOOLTIP": WITHDRAWN gdk_window_set_keep_above: "TOOLTIP": NO gdk_window_set_keep_below: "TOOLTIP": NO gdk_win32_window_raise: "TOOLTIP", which has ex style 0x00000088 WM_WINDOWPOSCHANGING "TOOLTIP" 0 0x28f4d0 NOACTIVATE|NOMOVE|NOSIZE TOP 0x0@+0+0 now below 00000000 ('') DefWindowProcW => 0 WM_WINDOWPOSCHANGING "MAINWINDOW" 0 0x28f4d0 NOACTIVATE|NOMOVE|NOSIZE 00132802 0x0@+0+0 now below 00132802 ('Default IME') DefWindowProcW => 0 show_window_internal: "TOOLTIP": MAPPED WM_SHOWWINDOW "TOOLTIP" 0x1 0 DefWindowProcW => 0 WM_WINDOWPOSCHANGING "TOOLTIP" 0 0x28f4c0 NOACTIVATE|NOMOVE|NOSIZE|NOZORDER|SHOWWINDOW TOP 0x0@+0+0 now below 00000000 ('') DefWindowProcW => 0 WM_NCPAINT "TOOLTIP" 0x1 0 DefWindowProcW => 0 WM_ERASEBKGND "TOOLTIP" 0xd4011022 0 D4011022 => 1 WM_WINDOWPOSCHANGED "TOOLTIP" 0 0x28f4c0 NOACTIVATE|NOMOVE|NOSIZE|NOZORDER|SHOWWINDOW TOP 75x43@+0+0 is below 00000000 ('') ===> GDK_MAP "TOOLTIP" ===> GDK_CONFIGURE "TOOLTIP" x:0 y:0 w:75 h:43 => 0 gdk_win32_window_get_root_coords: "MAINWINDOW": +0+0 +208+230 gdk_win32_window_get_root_coords: "MAINWINDOW": +116+0 +324+230 gdk_win32_window_get_root_coords: "MAINWINDOW": +0+28 +208+258 gdk_win32_window_get_root_coords: "MAINWINDOW": +116+28 +324+258 gdk_win32_window_move: "TOOLTIP": +229+258 ... SetWindowPos("TOOLTIP",NULL,229,258,0,0,NOACTIVATE|NOSIZE|NOZORDER) WM_WINDOWPOSCHANGING "TOOLTIP" 0 0x28fac0 NOACTIVATE|NOSIZE|NOZORDER TOP 0x0@+229+258 now below 00000000 ('') DefWindowProcW => 0 WM_NCPAINT "TOOLTIP" 0x1 0 DefWindowProcW => 0 WM_ERASEBKGND "TOOLTIP" 0x4c012922 0 4C012922 => 1 WM_WINDOWPOSCHANGED "TOOLTIP" 0 0x28fac0 NOACTIVATE|NOSIZE|NOZORDER TOP 75x43@+229+258 is below 00000000 ('') => 0 ===> GDK_CONFIGURE "TOOLTIP" x:229 y:258 w:75 h:43 gdk_window_set_transient_for: "TOOLTIP": "MAINWINDOW" WM_NCHITTEST "MAINWINDOW" 0 0xe60115 DefWindowProcW => 1 WM_SETCURSOR "MAINWINDOW" 0x342a5a 0x2000001 0x1 0x200 (SetCursor(03110640) => 1 WM_MOUSEMOVE "MAINWINDOW" 0 0x45 00000000 (69,0) DefWindowProcW => 0 WM_PAINT "TOOLTIP" 0 0 75x43@+0+0 dc 4C012922 DefWindowProcW => 0 ********** Tooltip was probably shown somewhere around here ********** gdk_win32_window_get_geometry: "TOOLTIP": 75x43x32@+229+258 gdk_win32_window_get_root_coords: "TOOLTIP": +0+0 +229+258 WM_NCHITTEST "MAINWINDOW" 0 0xe60115 DefWindowProcW => 1 WM_SETCURSOR "MAINWINDOW" 0x342a5a 0x2000001 0x1 0x200 (SetCursor(03110640) => 1 WM_MOUSEMOVE "MAINWINDOW" 0 0x45 00000000 (69,0) DefWindowProcW => 0 WM_NCHITTEST "MAINWINDOW" 0 0xe60115 DefWindowProcW => 1 WM_SETCURSOR "MAINWINDOW" 0x342a5a 0x2000001 0x1 0x200 (SetCursor(03110640) => 1 WM_MOUSEMOVE "MAINWINDOW" 0 0x45 00000000 (69,0) DefWindowProcW => 0 WM_NCHITTEST "MAINWINDOW" 0 0xe60115 DefWindowProcW => 1 WM_SETCURSOR "MAINWINDOW" 0x342a5a 0x2000001 0x1 0x200 (SetCursor(03110640) => 1 WM_MOUSEMOVE "MAINWINDOW" 0 0x45 00000000 (69,0) DefWindowProcW => 0 WM_NCHITTEST "MAINWINDOW" 0 0xe60115 DefWindowProcW => 1 WM_SETCURSOR "MAINWINDOW" 0x342a5a 0x2000001 0x1 0x200 (SetCursor(03110640) => 1 WM_MOUSEMOVE "MAINWINDOW" 0 0x45 00000000 (69,0) DefWindowProcW => 0 ********** This is probably where i alt-tabbed back into the GTK window (it does not register any keyboard input, just an activation message) ********** WM_WINDOWPOSCHANGING "TOOLTIP" 0 0x28fc6c NOACTIVATE|NOMOVE|NOSIZE 00222BAC 0x0@+0+0 now below 00212B72 ('Start menu') DefWindowProcW => 0 WM_WINDOWPOSCHANGING "MAINWINDOW" 0 0x28fc6c NOMOVE|NOSIZE 00132802 0x0@+0+0 now below 00132802 ('Default IME') DefWindowProcW => 0 WM_WINDOWPOSCHANGED "TOOLTIP" 0 0x28fc6c NOACTIVATE|NOMOVE|NOSIZE 00222BAC 75x43@+229+258 is below 00222BAC ('') => 0 WM_ACTIVATEAPP "TOOLTIP" 0x1 0xde4 YES thread: 3556 WM_WINDOWPOSCHANGING "TOOLTIP" 0 0x28f718 NOACTIVATE|NOMOVE|NOSIZE TOP 0x0@+0+0 now below 00222BAC ('') DefWindowProcW => 0 WM_WINDOWPOSCHANGING "MAINWINDOW" 0 0x28f718 NOACTIVATE|NOMOVE|NOSIZE 00132802 0x0@+0+0 now below 00132802 ('Default IME') DefWindowProcW => 0 WM_WINDOWPOSCHANGED "TOOLTIP" 0 0x28f718 NOACTIVATE|NOMOVE|NOSIZE TOP 75x43@+229+258 is below 00000000 ('') => 0 DefWindowProcW => 0 ********** This is where main window is re-stacked above tooltip, which still has WS_EX_TOPMOST ********** WM_ACTIVATEAPP "MAINWINDOW" 0x1 0xde4 YES thread: 3556 app activated, restacking "MAINWINDOW" above "TOOLTIP" (has exstyle 0x00000088) WM_WINDOWPOSCHANGING "TOOLTIP" 0 0x28f718 NOACTIVATE|NOMOVE|NOSIZE TOP 0x0@+0+0 now below 00000000 ('') DefWindowProcW => 0 WM_WINDOWPOSCHANGING "MAINWINDOW" 0 0x28f718 NOACTIVATE|NOMOVE|NOSIZE 00132802 0x0@+0+0 now below 00132802 ('Default IME') DefWindowProcW => 0 ********** This is the first time when main window is observed to have WS_EX_TOPMOST ********** WM_WINDOWPOSCHANGED "MAINWINDOW" 0 0x28f718 NOACTIVATE|NOMOVE|NOSIZE 00132802 132x66@+200+200 is below 00132802 ('Default IME') (Window "MAINWINDOW" has ex style 0x00000108 WS_EX_TOPMOST, does not match its state 0x00000000 !GDK_WINDOW_STATE_ABOVE) => 0 (Window "MAINWINDOW" has ex style 0x00000108 WS_EX_TOPMOST, does not match its state 0x00000000 !GDK_WINDOW_STATE_ABOVE) DefWindowProcW => 0 Still not sure how to fix this, but my first instinct is to separate restacking into restacking of the temp windows (and windows with GDK_WINDOW_STATE_ABOVE) and restacking of everything else. That should prevent GDK from stacking main window on top of the tooltip. Will also try to understand why the main window is placed *above* its *own tooltip* in the first place.
Created attachment 316014 [details] [review] GDK W32: Refactor restacking functions a bit I've split the change into 2 patches. Once refactors the code, the other fixes it. This is the refactoring part.
Created attachment 316015 [details] [review] GDK W32: Only restack windows with matching always-on-top status This prevents normal application windows (and other kinds of windows) from being moved up in Z-order to be above windows that have the always-on-top bit set. Doing so would make the previously-normal windows in question also always-on-top implicitly. Windows that are already always-on-top will be restacked on top of other always-on-top windows too.
Review of attachment 316014 [details] [review]: Looks good
Review of attachment 316015 [details] [review]: I know nothing from this parte of the backend but the patch looks fair. If you tested it I'd say go for it.
I've added fanc to the CC List. Fanc, please bless the attachment 316015 [details] [review].
Review of attachment 316015 [details] [review]: Hi LRN, I guess it makes sense to me, after trying the patch, so I'd say go ahead. --- Hello Mikkel, Can you check again whether this works for you? --- With blessings, thank you!
attachment 316914 [details] [review] pushed to master as 6b7951b219979903f32465ec0282ca3943e2279e attachment 316915 [details] pushed to master as f407871b87288115fe839ffe13a86c789a44ba87
Uh...i meant: attachment 316014 [details] [review] pushed to master as 6b7951b219979903f32465ec0282ca3943e2279e attachment 316015 [details] [review] pushed to master as f407871b87288115fe839ffe13a86c789a44ba87
The commits mentioned above should have fixed this bug. Original reporter, please confirm.
Seems to have resolved the problem. Thanks.