GDK W32: Don't use SetWindowLong() to set/unset WS_EX_TOPMOST
authorРуслан Ижбулатов <lrn1986@gmail.com>
Sat, 21 Nov 2015 03:48:55 +0000 (03:48 +0000)
committerРуслан Ижбулатов <lrn1986@gmail.com>
Thu, 26 Nov 2015 16:26:32 +0000 (16:26 +0000)
While searching for the cause of bug 746745 it was discovered that one could
not set WS_EX_TOPMOST extended window style with SetWindowLong(),
but must use SetWindowPos() for that purpose.

This was never a problem most likely because it is highly unlikely for windows
to acquire/lose WS_EX_TOPMOST after they are created, by means other
than SetWindowPos() (which GTK does use to raise/lower windows and
set/remove keep_above), and because trying to set/unset WS_EX_TOPMOST with
SetWindowLong() results in WS_EX_TOPMOST merely not being set/unset (that is,
other styles are still set/unset within the same call and no error is
signalled).

https://bugzilla.gnome.org/show_bug.cgi?id=758483

gdk/win32/gdkwindow-win32.c

index 85bdb1fc2ef4a03804d7df7a9547b03d8673d2a1..c4256ebbb7b29c9764c7c81205145ae726b4289e 100644 (file)
@@ -2402,6 +2402,10 @@ update_style_bits (GdkWindow *window)
   LONG old_style, new_style, old_exstyle, new_exstyle;
   gboolean all;
   RECT rect, before, after;
+  gboolean was_topmost;
+  gboolean will_be_topmost;
+  HWND insert_after;
+  UINT flags;
 
   if (window->state & GDK_WINDOW_STATE_FULLSCREEN)
     return;
@@ -2413,15 +2417,27 @@ update_style_bits (GdkWindow *window)
   after = before;
   AdjustWindowRectEx (&before, old_style, FALSE, old_exstyle);
 
+  was_topmost = (old_exstyle & WS_EX_TOPMOST) ? TRUE : FALSE;
+  will_be_topmost = was_topmost;
+
+  old_exstyle &= ~WS_EX_TOPMOST;
+
   new_style = old_style;
   new_exstyle = old_exstyle;
 
   if (window->window_type == GDK_WINDOW_TEMP)
-    new_exstyle |= WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
+    {
+      new_exstyle |= WS_EX_TOOLWINDOW;
+      will_be_topmost = TRUE;
+    }
   else if (impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY)
-    new_exstyle |= WS_EX_TOOLWINDOW ;
+    {
+      new_exstyle |= WS_EX_TOOLWINDOW;
+    }
   else
-    new_exstyle &= ~WS_EX_TOOLWINDOW;
+    {
+      new_exstyle &= ~WS_EX_TOOLWINDOW;
+    }
 
   if (get_effective_window_decorations (window, &decorations))
     {
@@ -2469,12 +2485,26 @@ update_style_bits (GdkWindow *window)
   rect.right += after.right - before.right;
   rect.bottom += after.bottom - before.bottom;
 
-  SetWindowPos (GDK_WINDOW_HWND (window), NULL,
-               rect.left, rect.top,
-               rect.right - rect.left, rect.bottom - rect.top,
-               SWP_FRAMECHANGED | SWP_NOACTIVATE |
-               SWP_NOREPOSITION | SWP_NOZORDER);
+  flags = SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOREPOSITION;
 
+  if (will_be_topmost && !was_topmost)
+    {
+      insert_after = HWND_TOPMOST;
+    }
+  else if (was_topmost && !will_be_topmost)
+    {
+      insert_after = HWND_NOTOPMOST;
+    }
+  else
+    {
+      flags |= SWP_NOZORDER;
+      insert_after = NULL;
+    }
+
+  SetWindowPos (GDK_WINDOW_HWND (window), insert_after,
+               0, 0,
+               rect.right - rect.left, rect.bottom - rect.top,
+               flags);
 }
 
 static void