diff options
author | jenglish <jenglish@flightlab.com> | 2002-10-12 00:50:26 (GMT) |
---|---|---|
committer | jenglish <jenglish@flightlab.com> | 2002-10-12 00:50:26 (GMT) |
commit | 3d16054fbc90ea5fcafd2a89cb69e4ca4c781242 (patch) | |
tree | 33597728e2979793b2b1744fc1555ca80bf1c66e | |
parent | b9e37f089b1bba70eec3e00e70c459fa55355ac6 (diff) | |
download | tk-3d16054fbc90ea5fcafd2a89cb69e4ca4c781242.zip tk-3d16054fbc90ea5fcafd2a89cb69e4ca4c781242.tar.gz tk-3d16054fbc90ea5fcafd2a89cb69e4ca4c781242.tar.bz2 |
* unix/tkUnixWm.c: (rev. 1.8.1.3) Backported changes for
TIP 107 ("Fix the 2-second raise delay") to core-8-3-1-branch
[Patch #601518]
* tests/unixWm.c (unixWm-51.7): added 200 ms delay after
'raise' and 'lower' commands, since these are now asynchronous.
(NB: there may be other regressions, this is the only one
I encountered)
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | tests/unixWm.test | 4 | ||||
-rw-r--r-- | unix/tkUnixWm.c | 186 |
3 files changed, 30 insertions, 169 deletions
@@ -1,3 +1,12 @@ +2002-10-11 Joe English <jenglish@flightlab.com> + * unix/tkUnixWm.c: (rev. 1.8.1.3) Backported changes for + TIP 107 ("Fix the 2-second raise delay") to core-8-3-1-branch + [Patch #601518] + * tests/unixWm.c (unixWm-51.7): added 200 ms delay after + 'raise' and 'lower' commands, since these are now asynchronous. + (NB: there may be other regressions, this is the only one + I encountered) + 2002-10-10 Jeff Hobbs <jeffh@ActiveState.com> * tests/grid.test: diff --git a/tests/unixWm.test b/tests/unixWm.test index eb4a94b..920406b 100644 --- a/tests/unixWm.test +++ b/tests/unixWm.test @@ -7,7 +7,7 @@ # Copyright (c) 1998-1999 by Scriptics Corporation. # All rights reserved. # -# RCS: @(#) $Id: unixWm.test,v 1.12.2.1 2001/04/04 07:57:17 hobbs Exp $ +# RCS: @(#) $Id: unixWm.test,v 1.12.2.2 2002/10/12 00:50:27 jenglish Exp $ if {[lsearch [namespace children] ::tcltest] == -1} { source [file join [pwd] [file dirname [info script]] defs.tcl] @@ -2015,9 +2015,11 @@ test unixWm-51.7 {TkWmRestackToplevel procedure, other window isn't mapped} { wm geometry $w +0+0 } raise .t .t2 + after 200 update set result [list [winfo containing 100 100]] lower .t3 + after 200 lappend result [winfo containing 100 100] } {.t3 .t} test unixWm-51.8 {TkWmRestackToplevel procedure, overrideredirect windows} { diff --git a/unix/tkUnixWm.c b/unix/tkUnixWm.c index 1c60937..f05d18c 100644 --- a/unix/tkUnixWm.c +++ b/unix/tkUnixWm.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: tkUnixWm.c,v 1.8.2.1 2001/08/28 19:28:43 hobbs Exp $ + * RCS: @(#) $Id: tkUnixWm.c,v 1.8.2.2 2002/10/12 00:50:27 jenglish Exp $ */ #include "tkPort.h" @@ -4082,8 +4082,6 @@ TkWmProtocolEventProc(winPtr, eventPtr) * * Side effects: * WinPtr gets restacked as specified by aboveBelow and otherPtr. - * This procedure doesn't return until the restack has taken - * effect and the ConfigureNotify event for it has been received. * *---------------------------------------------------------------------- */ @@ -4098,191 +4096,43 @@ TkWmRestackToplevel(winPtr, aboveBelow, otherPtr) * above or below *all* siblings. */ { XWindowChanges changes; - XWindowAttributes atts; unsigned int mask; - Window window, dummy1, dummy2, vRoot; - Window *children; - unsigned int numChildren; - int i; - int desiredIndex = 0; /* Initialized to stop gcc warnings. */ - int ourIndex = 0; /* Initialized to stop gcc warnings. */ - unsigned long serial; - Tk_ErrorHandler handler; TkWindow *wrapperPtr; + memset(&changes, 0, sizeof(XWindowChanges)); changes.stack_mode = aboveBelow; - changes.sibling = None; mask = CWStackMode; - if (winPtr->window == None) { - Tk_MakeWindowExist((Tk_Window) winPtr); - } - if (winPtr->wmInfoPtr->flags & WM_NEVER_MAPPED) { - /* - * Can't set stacking order properly until the window is on the - * screen (mapping it may give it a reparent window), so make sure - * it's on the screen. - */ - - TkWmMapWindow(winPtr); - } - wrapperPtr = winPtr->wmInfoPtr->wrapperPtr; - window = (winPtr->wmInfoPtr->reparent != None) - ? winPtr->wmInfoPtr->reparent : wrapperPtr->window; - if (otherPtr != NULL) { - if (otherPtr->window == None) { - Tk_MakeWindowExist((Tk_Window) otherPtr); - } - if (otherPtr->wmInfoPtr->flags & WM_NEVER_MAPPED) { - TkWmMapWindow(otherPtr); - } - changes.sibling = (otherPtr->wmInfoPtr->reparent != None) - ? otherPtr->wmInfoPtr->reparent - : otherPtr->wmInfoPtr->wrapperPtr->window; - mask = CWStackMode|CWSibling; - } /* - * Before actually reconfiguring the window, see if it's already - * in the right place. If so then don't reconfigure it. The - * reason for this extra work is that some window managers will - * ignore the reconfigure request if the window is already in - * the right place, causing a long delay in WaitForConfigureNotify - * while it times out. Special note: if the window is almost in - * the right place, and the only windows between it and the right - * place aren't mapped, then we don't reconfigure it either, for - * the same reason. + * Make sure that winPtr and its wrapper window have been created. */ - - vRoot = winPtr->wmInfoPtr->vRoot; - if (vRoot == None) { - vRoot = RootWindowOfScreen(Tk_Screen((Tk_Window) winPtr)); + if (winPtr->wmInfoPtr->flags & WM_NEVER_MAPPED) { + TkWmMapWindow(winPtr); } - if (XQueryTree(winPtr->display, vRoot, &dummy1, &dummy2, - &children, &numChildren) != 0) { - /* - * Find where our window is in the stacking order, and - * compute the desired location in the stacking order. - */ - - for (i = 0; i < numChildren; i++) { - if (children[i] == window) { - ourIndex = i; - } - if (children[i] == changes.sibling) { - desiredIndex = i; - } - } - if (mask & CWSibling) { - if (aboveBelow == Above) { - if (desiredIndex < ourIndex) { - desiredIndex += 1; - } - } else { - if (desiredIndex > ourIndex) { - desiredIndex -= 1; - } - } - } else { - if (aboveBelow == Above) { - desiredIndex = numChildren-1; - } else { - desiredIndex = 0; - } - } + wrapperPtr = winPtr->wmInfoPtr->wrapperPtr; + if (otherPtr != NULL) { /* - * See if there are any mapped windows between where we are - * and where we want to be. + * The window is to be restacked with respect to another toplevel. + * Make sure it has been created as well. */ - - handler = Tk_CreateErrorHandler(winPtr->display, -1, -1, -1, - (Tk_ErrorProc *) NULL, (ClientData) NULL); - while (desiredIndex != ourIndex) { - if ((XGetWindowAttributes(winPtr->display, children[desiredIndex], - &atts) != 0) && (atts.map_state != IsUnmapped)) { - break; - } - if (desiredIndex < ourIndex) { - desiredIndex++; - } else { - desiredIndex--; - } - } - Tk_DeleteErrorHandler(handler); - XFree((char *) children); - if (ourIndex == desiredIndex) { - return; + if (otherPtr->wmInfoPtr->flags & WM_NEVER_MAPPED) { + TkWmMapWindow(otherPtr); } + changes.sibling = otherPtr->wmInfoPtr->wrapperPtr->window; + mask |= CWSibling; } /* - * Reconfigure the window. This tricky because of two things: - * (a) Some window managers, like olvwm, insist that we raise - * or lower the toplevel window itself, as opposed to its - * decorative frame. Attempts to raise or lower the frame - * are ignored. - * (b) If the raise or lower is relative to a sibling, X will - * generate an error unless we work with the frames (the - * toplevels themselves aren't siblings). - * Fortunately, the procedure XReconfigureWMWindow is supposed - * to handle all of this stuff, so be careful to use it instead - * of XConfigureWindow. + * Reconfigure the window. Note that we use XReconfigureWMWindow + * instead of XConfigureWindow, in order to handle the case + * where the window is to be restacked with respect to another toplevel. + * See [ICCCM] 4.1.5 "Configuring the Window" and XReconfigureWMWindow(3) + * for details. */ - serial = NextRequest(winPtr->display); - if (window != wrapperPtr->window) { - /* - * We're going to have to wait for events on a window that - * Tk doesn't own, so we have to tell X specially that we - * want to get events on that window. To make matters worse, - * it's possible that the window doesn't exist anymore (e.g. - * the toplevel could have been withdrawn) so ignore events - * occurring during the request. - */ - - handler = Tk_CreateErrorHandler(winPtr->display, -1, -1, -1, - (Tk_ErrorProc *) NULL, (ClientData) NULL); - XSelectInput(winPtr->display, window, StructureNotifyMask); - Tk_DeleteErrorHandler(handler); - } XReconfigureWMWindow(winPtr->display, wrapperPtr->window, Tk_ScreenNumber((Tk_Window) winPtr), mask, &changes); - - /* - * Wait for the reconfiguration to complete. If we don't wait, then - * the window may not restack for a while and the application might - * observe it before it has restacked. Waiting for the reconfiguration - * is tricky if winPtr has been reparented, since the window getting - * the event isn't one that Tk owns. - */ - - if (window == wrapperPtr->window) { - WaitForConfigureNotify(winPtr, serial); - } else { - XEvent event; - int diff; - - while (1) { - if (WaitForEvent(winPtr->display, winPtr->wmInfoPtr, - ConfigureNotify, &event) != TCL_OK) { - break; - } - diff = event.xconfigure.serial - serial; - if (diff >= 0) { - break; - } - } - /* - * Ignore errors that occur when we are de-selecting events on - * window, since it's possible that the window doesn't exist - * anymore (see comment above previous call to XSelectInput). - */ - - handler = Tk_CreateErrorHandler(winPtr->display, -1, -1, -1, - (Tk_ErrorProc *) NULL, (ClientData) NULL); - XSelectInput(winPtr->display, window, (long) 0); - Tk_DeleteErrorHandler(handler); - } } /* |