summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjenglish <jenglish@flightlab.com>2002-10-12 00:50:26 (GMT)
committerjenglish <jenglish@flightlab.com>2002-10-12 00:50:26 (GMT)
commit3d16054fbc90ea5fcafd2a89cb69e4ca4c781242 (patch)
tree33597728e2979793b2b1744fc1555ca80bf1c66e
parentb9e37f089b1bba70eec3e00e70c459fa55355ac6 (diff)
downloadtk-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--ChangeLog9
-rw-r--r--tests/unixWm.test4
-rw-r--r--unix/tkUnixWm.c186
3 files changed, 30 insertions, 169 deletions
diff --git a/ChangeLog b/ChangeLog
index 234ea98..f7b3d4d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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);
- }
}
/*