diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | tests/winWm.test | 31 | ||||
-rw-r--r-- | win/tkWinWm.c | 34 |
3 files changed, 62 insertions, 9 deletions
@@ -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); } } |