diff options
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | tests/winWm.test | 31 | ||||
-rw-r--r-- | win/tkWinWm.c | 43 |
3 files changed, 66 insertions, 16 deletions
@@ -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; |