Bug 557266 - Window Management Problem

2008-10-21  Tor Lillqvist  <tml@novell.com>

	Bug 557266 - Window Management Problem

	Also reported in mail to gtk-list, and of course it has been well
	known in general that window state management is messy and buggy
	in various ways in gdk/win32.

	* gdk/win32/gdkwindow-win32.c (show_window_internal): Correct
	handling of GDK_WINDOW_STATE_ABOVE windows. It doesn't work to set
	the WS_EX_TOPMOST extended style bit using SetWindowLong(). We
	must call SetWindowPos() on the window using HWND_TOPMOST
	instead. The description for WS_EX_TOPMOST in the documentation
	for CreateWindowEx() even implies that if you read it carefully.


svn path=/trunk/; revision=21694
This commit is contained in:
Tor Lillqvist
2008-10-21 20:31:05 +00:00
committed by Tor Lillqvist
parent def00e8821
commit c103cbec8a
2 changed files with 39 additions and 15 deletions

View File

@ -1,3 +1,18 @@
2008-10-21 Tor Lillqvist <tml@novell.com>
Bug 557266 - Window Management Problem
Also reported in mail to gtk-list, and of course it has been well
known in general that window state management is messy and buggy
in various ways in gdk/win32.
* gdk/win32/gdkwindow-win32.c (show_window_internal): Correct
handling of GDK_WINDOW_STATE_ABOVE windows. It doesn't work to set
the WS_EX_TOPMOST extended style bit using SetWindowLong(). We
must call SetWindowPos() on the window using HWND_TOPMOST
instead. The description for WS_EX_TOPMOST in the documentation
for CreateWindowEx() even implies that if you read it carefully.
2008-10-21 Michael Natterer <mitch@imendio.com> 2008-10-21 Michael Natterer <mitch@imendio.com>
* gdk/gdkapplaunchcontext.c: reorder functions to be in standard * gdk/gdkapplaunchcontext.c: reorder functions to be in standard

View File

@ -1028,6 +1028,8 @@ show_window_internal (GdkWindow *window,
GdkWindowObject *private; GdkWindowObject *private;
HWND old_active_window; HWND old_active_window;
gboolean focus_on_map = TRUE; gboolean focus_on_map = TRUE;
DWORD exstyle;
HWND top;
private = (GdkWindowObject *) window; private = (GdkWindowObject *) window;
@ -1078,35 +1080,38 @@ show_window_internal (GdkWindow *window,
focus_on_map = private->focus_on_map; focus_on_map = private->focus_on_map;
} }
exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
if (private->state & GDK_WINDOW_STATE_BELOW)
exstyle &= (~WS_EX_TOPMOST);
if (private->state & GDK_WINDOW_STATE_ABOVE)
exstyle |= WS_EX_TOPMOST;
if (exstyle & WS_EX_TOPMOST)
top = HWND_TOPMOST;
else
top = HWND_TOP;
/* Use SetWindowPos to show transparent windows so automatic redraws /* Use SetWindowPos to show transparent windows so automatic redraws
* in other windows can be suppressed. * in other windows can be suppressed.
*/ */
if (GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE) & WS_EX_TRANSPARENT) if (exstyle & WS_EX_TRANSPARENT)
{ {
UINT flags = SWP_SHOWWINDOW | SWP_NOREDRAW | SWP_NOMOVE | SWP_NOSIZE; UINT flags = SWP_SHOWWINDOW | SWP_NOREDRAW | SWP_NOMOVE | SWP_NOSIZE;
if (!raise) if (!raise)
flags |= SWP_NOZORDER; flags |= SWP_NOZORDER;
if (!raise || GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map) if (!raise || GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
flags |= SWP_NOACTIVATE; flags |= SWP_NOACTIVATE;
SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOP, 0, 0, 0, 0, flags); SetWindowPos (GDK_WINDOW_HWND (window), top, 0, 0, 0, 0, flags);
return; return;
} }
old_active_window = GetActiveWindow (); old_active_window = GetActiveWindow ();
if (private->state & (GDK_WINDOW_STATE_BELOW | GDK_WINDOW_STATE_ABOVE))
{
DWORD exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
if (private->state & GDK_WINDOW_STATE_BELOW)
exstyle &= (~WS_EX_TOPMOST);
if (private->state & GDK_WINDOW_STATE_ABOVE)
exstyle |= WS_EX_TOPMOST;
API_CALL (SetWindowLong, (GDK_WINDOW_HWND (window), GWL_EXSTYLE, exstyle));
}
if (private->state & GDK_WINDOW_STATE_FULLSCREEN) if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
{ {
gdk_window_fullscreen (window); gdk_window_fullscreen (window);
@ -1140,10 +1145,14 @@ show_window_internal (GdkWindow *window,
if (focus_on_map && private->accept_focus) if (focus_on_map && private->accept_focus)
{ {
SetForegroundWindow (GDK_WINDOW_HWND (window)); SetForegroundWindow (GDK_WINDOW_HWND (window));
if (top == HWND_TOPMOST)
SetWindowPos (GDK_WINDOW_HWND (window), top,
0, 0, 0, 0,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
} }
else else
{ {
SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOP, SetWindowPos (GDK_WINDOW_HWND (window), top,
0, 0, 0, 0, 0, 0, 0, 0,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
} }