summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--tests/winWm.test31
-rw-r--r--win/tkWinWm.c34
3 files changed, 62 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 8db02f3..836ce89 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2004-09-17 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * win/tkWinWm.c (UpdateWrapper): Ensure that we maintain Z order
+ * tests/winWm.test: and focus of preexisting window
+ when replacing the wrapper window.
+
2004-09-16 David Gravereaux <davygrvy@pobox.com>
* win/makefile.vc : added VC7-safe environment check as used in the
diff --git a/tests/winWm.test b/tests/winWm.test
index 0140218..246aefa 100644
--- a/tests/winWm.test
+++ b/tests/winWm.test
@@ -9,7 +9,7 @@
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.
#
-# RCS: @(#) $Id: winWm.test,v 1.11 2004/06/24 12:45:44 dkf Exp $
+# RCS: @(#) $Id: winWm.test,v 1.12 2004/09/17 22:44:34 hobbs Exp $
package require tcltest 2.1
eval tcltest::configure $argv
@@ -242,9 +242,7 @@ test winWm-6.3 {wm attributes} win {
list [catch {wm attributes .t -foo} msg] $msg
} {1 {wrong # args: should be "wm attributes window ?-disabled ?bool?? ?-toolwindow ?bool?? ?-topmost ?bool??"}}
-destroy .t
-
-test winWm-6.1 {deiconify on an unmapped toplevel\
+test winWm-7.1 {deiconify on an unmapped toplevel\
will raise the window and set the focus} win {
destroy .t
toplevel .t
@@ -255,7 +253,7 @@ test winWm-6.1 {deiconify on an unmapped toplevel\
list [wm stackorder .t isabove .] [focus]
} {1 .t}
-test winWm-6.2 {deiconify on an already mapped toplevel\
+test winWm-7.2 {deiconify on an already mapped toplevel\
will raise the window and set the focus} win {
destroy .t
toplevel .t
@@ -267,6 +265,29 @@ test winWm-6.2 {deiconify on an already mapped toplevel\
list [wm stackorder .t isabove .] [focus]
} {1 .t}
+test winWm-7.3 {UpdateWrapper must maintain Z order} win {
+ destroy .t
+ toplevel .t
+ lower .t
+ update
+ set res [wm stackorder .t isbelow .]
+ wm resizable .t 0 0
+ update
+ list $res [wm stackorder .t isbelow .]
+} {1 1}
+
+test winWm-7.4 {UpdateWrapper must maintain focus} win {
+ destroy .t
+ toplevel .t
+ focus -force .t
+ update
+ set res [focus]
+ wm resizable .t 0 0
+ update
+ list $res [focus]
+} {.t .t}
+
+destroy .t
# cleanup
cleanupTests
diff --git a/win/tkWinWm.c b/win/tkWinWm.c
index 2107cb7..cc77fe0 100644
--- a/win/tkWinWm.c
+++ b/win/tkWinWm.c
@@ -12,7 +12,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkWinWm.c,v 1.69 2004/09/15 04:02:57 mdejong Exp $
+ * RCS: @(#) $Id: tkWinWm.c,v 1.70 2004/09/17 22:44:34 hobbs Exp $
*/
#include "tkWinInt.h"
@@ -1897,7 +1897,7 @@ UpdateWrapper(winPtr)
{
register WmInfo *wmPtr = winPtr->wmInfoPtr;
HWND parentHWND, oldWrapper = wmPtr->wrapper;
- HWND child;
+ HWND child, nextHWND, focusHWND;
int x, y, width, height, state;
WINDOWPLACEMENT place;
HICON hSmallIcon = NULL;
@@ -1916,6 +1916,15 @@ UpdateWrapper(winPtr)
child = TkWinGetHWND(winPtr->window);
parentHWND = NULL;
+ /*
+ * nextHWND will help us maintain Z order.
+ * focusHWND will help us maintain focus, if we had it.
+ */
+ nextHWND = NULL;
+ focusHWND = GetFocus();
+ if ((oldWrapper == NULL) || (oldWrapper != GetForegroundWindow())) {
+ focusHWND = NULL;
+ }
if (winPtr->flags & TK_EMBEDDED) {
wmPtr->wrapper = (HWND) winPtr->privatePtr;
@@ -2025,6 +2034,13 @@ UpdateWrapper(winPtr)
wmPtr->y = place.rcNormalPosition.top;
TkInstallFrameMenu((Tk_Window) winPtr);
+
+ if (oldWrapper && (oldWrapper != wmPtr->wrapper)) {
+ /*
+ * We will adjust wrapper to have the same Z order as oldWrapper
+ */
+ nextHWND = GetNextWindow(oldWrapper, GW_HWNDPREV);
+ }
}
/*
@@ -2097,11 +2113,16 @@ UpdateWrapper(winPtr)
/*
* Force an initial transition from withdrawn to the real
- * initial state.
+ * initial state. Set the Z order based on previous wrapper
+ * before we set the state.
*/
state = wmPtr->hints.initial_state;
wmPtr->hints.initial_state = WithdrawnState;
+ if (nextHWND) {
+ SetWindowPos(wmPtr->wrapper, nextHWND, 0, 0, 0, 0,
+ SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOSENDCHANGING);
+ }
TkpWmSetState(winPtr, state);
if (hSmallIcon != NULL) {
@@ -2158,12 +2179,17 @@ UpdateWrapper(winPtr)
/*
* If this is the first window created by the application, then
- * we should activate the initial window.
+ * we should activate the initial window. Otherwise, if this had
+ * the focus, we need to restore that.
+ * XXX: Rewrapping generates a <FocusOut> and <FocusIn> that would
+ * XXX: best be avoided, if we could safely mask them.
*/
if (tsdPtr->firstWindow) {
tsdPtr->firstWindow = 0;
SetActiveWindow(wmPtr->wrapper);
+ } else if (focusHWND) {
+ SetFocus(focusHWND);
}
}