summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorРуслан Ижбулатов <lrn1986@gmail.com>2015-11-21 03:38:26 +0000
committerРуслан Ижбулатов <lrn1986@gmail.com>2015-11-22 03:20:10 +0000
commitf407871b87288115fe839ffe13a86c789a44ba87 (patch)
tree02fed0fc4898adf31ae6deb251af76c40468aadd
parent6b7951b219979903f32465ec0282ca3943e2279e (diff)
downloadgtk+-f407871b87288115fe839ffe13a86c789a44ba87.tar.gz
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. https://bugzilla.gnome.org/show_bug.cgi?id=746745
-rw-r--r--gdk/win32/gdkevents-win32.c49
1 files changed, 46 insertions, 3 deletions
diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c
index 9b670452d3..e3bfcaf6ad 100644
--- a/gdk/win32/gdkevents-win32.c
+++ b/gdk/win32/gdkevents-win32.c
@@ -1679,11 +1679,41 @@ generate_button_event (GdkEventType type,
_gdk_win32_append_event (event);
}
+/**
+ * Used by the stacking functions to see if a window
+ * should be always on top.
+ * Restacking is only done if both windows are either ontop
+ * or not ontop.
+ */
+static gboolean
+should_window_be_always_on_top (GdkWindow *window)
+{
+ DWORD exstyle;
+
+ if ((GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP) ||
+ (window->state & GDK_WINDOW_STATE_ABOVE))
+ return TRUE;
+
+ exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
+
+ if (exstyle & WS_EX_TOPMOST)
+ return TRUE;
+
+ return FALSE;
+}
+
static void
ensure_stacking_on_unminimize (MSG *msg)
{
HWND rover;
HWND lowest_transient = NULL;
+ GdkWindow *msg_window;
+ gboolean window_ontop = FALSE;
+
+ msg_window = gdk_win32_handle_table_lookup (msg->hwnd);
+
+ if (msg_window)
+ window_ontop = should_window_be_always_on_top (msg_window);
for (rover = GetNextWindow (msg->hwnd, GW_HWNDNEXT);
rover;
@@ -1691,17 +1721,20 @@ ensure_stacking_on_unminimize (MSG *msg)
{
GdkWindow *rover_gdkw = gdk_win32_handle_table_lookup (rover);
GdkWindowImplWin32 *rover_impl;
+ gboolean rover_ontop;
/* Checking window group not implemented yet */
if (rover_gdkw == NULL)
continue;
+ rover_ontop = should_window_be_always_on_top (rover_gdkw);
rover_impl = GDK_WINDOW_IMPL_WIN32 (rover_gdkw->impl);
if (GDK_WINDOW_IS_MAPPED (rover_gdkw) &&
(rover_impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY ||
rover_impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG ||
- rover_impl->transient_owner != NULL))
+ rover_impl->transient_owner != NULL) &&
+ ((window_ontop && rover_ontop) || (!window_ontop && !rover_ontop)))
{
lowest_transient = rover;
}
@@ -1725,6 +1758,7 @@ ensure_stacking_on_window_pos_changing (MSG *msg,
WINDOWPOS *windowpos = (WINDOWPOS *) msg->lParam;
HWND rover;
gboolean restacking;
+ gboolean window_ontop;
if (GetActiveWindow () != msg->hwnd ||
impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY ||
@@ -1740,24 +1774,29 @@ ensure_stacking_on_window_pos_changing (MSG *msg,
* handling to bring any utility windows on top of it.
*/
+ window_ontop = should_window_be_always_on_top (window);
+
for (rover = windowpos->hwndInsertAfter, restacking = FALSE;
rover;
rover = GetNextWindow (rover, GW_HWNDNEXT))
{
GdkWindow *rover_gdkw = gdk_win32_handle_table_lookup (rover);
GdkWindowImplWin32 *rover_impl;
+ gboolean rover_ontop;
/* Checking window group not implemented yet */
if (rover_gdkw == NULL)
continue;
+ rover_ontop = should_window_be_always_on_top (rover_gdkw);
rover_impl = GDK_WINDOW_IMPL_WIN32 (rover_gdkw->impl);
if (GDK_WINDOW_IS_MAPPED (rover_gdkw) &&
(rover_impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY ||
rover_impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG ||
- rover_impl->transient_owner != NULL))
+ rover_impl->transient_owner != NULL) &&
+ ((window_ontop && rover_ontop) || (!window_ontop && !rover_ontop)))
{
restacking = TRUE;
windowpos->hwndInsertAfter = rover;
@@ -1781,6 +1820,7 @@ ensure_stacking_on_activate_app (MSG *msg,
{
GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
HWND rover;
+ gboolean window_ontop;
if (impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY ||
impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG ||
@@ -1802,6 +1842,8 @@ ensure_stacking_on_activate_app (MSG *msg,
* app.
*/
+ window_ontop = should_window_be_always_on_top (window);
+
for (rover = GetNextWindow (msg->hwnd, GW_HWNDPREV);
rover;
rover = GetNextWindow (rover, GW_HWNDPREV))
@@ -1820,7 +1862,8 @@ ensure_stacking_on_activate_app (MSG *msg,
if (GDK_WINDOW_IS_MAPPED (rover_gdkw) &&
(rover_impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY ||
rover_impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG ||
- rover_impl->transient_owner != NULL))
+ rover_impl->transient_owner != NULL) &&
+ ((window_ontop && rover_ontop) || (!window_ontop && !rover_ontop)))
{
GDK_NOTE (EVENTS,
g_print (" restacking %p above %p",