summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--tests/winWm.test31
-rw-r--r--win/tkWinWm.c43
3 files changed, 66 insertions, 16 deletions
diff --git a/ChangeLog b/ChangeLog
index c64ae5e..4b5017d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+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.
+ * win/tkWinWm.c (WmIconwindowCmd): Replace bogus call to
+ XWithdrawWindow with proper code. (mdejong)
+
2004-09-16 Jeff Hobbs <jeffh@ActiveState.com>
* generic/tkMenu.c (MenuWorldChanged): ensure that we recompute
diff --git a/tests/winWm.test b/tests/winWm.test
index 7bf9810..a9c014f 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.9 2002/07/25 21:35:23 pspjuth Exp $
+# RCS: @(#) $Id: winWm.test,v 1.9.2.1 2004/09/17 22:45:07 hobbs Exp $
package require tcltest 2.1
namespace import -force tcltest::configure
@@ -245,9 +245,7 @@ test winWm-6.3 {wm attributes} {pcOnly} {
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} {pcOnly} {
destroy .t
toplevel .t
@@ -258,7 +256,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} {pcOnly} {
destroy .t
toplevel .t
@@ -270,6 +268,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
::tcltest::cleanupTests
diff --git a/win/tkWinWm.c b/win/tkWinWm.c
index 8c3a4c8..b7f8e5d 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.54.2.6 2004/09/13 22:54:51 hobbs Exp $
+ * RCS: @(#) $Id: tkWinWm.c,v 1.54.2.7 2004/09/17 22:45:07 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);
}
}
@@ -3893,13 +3919,8 @@ WmIconwindowCmd(tkwin, winPtr, interp, objc, objv)
wmPtr->icon = tkwin2;
wmPtr2->iconFor = (Tk_Window) winPtr;
if (!(wmPtr2->flags & WM_NEVER_MAPPED)) {
- if (XWithdrawWindow(Tk_Display(tkwin2), Tk_WindowId(tkwin2),
- Tk_ScreenNumber(tkwin2)) == 0) {
- Tcl_SetResult(interp,
- "couldn't send withdraw message to window manager",
- TCL_STATIC);
- return TCL_ERROR;
- }
+ wmPtr2->flags |= WM_WITHDRAWN;
+ TkpWmSetState(((TkWindow *) tkwin2), WithdrawnState);
}
}
return TCL_OK;