summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--tests/winWm.test47
-rw-r--r--win/tkWinWm.c19
3 files changed, 66 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 8a1e006..ce9ee3a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2009-11-22 Pat Thoyts <patthoyts@users.sourceforge.net>
+
+ * tests/winWm.test: Make sure the window is still present
+ * win/tkWinWm.c: when handling delayed activation [Bug 2899949]
+
2009-11-13 Pat Thoyts <patthoyts@users.sourceforge.net>
* tests/winDialog.test: Backported fix for running dialog tests
diff --git a/tests/winWm.test b/tests/winWm.test
index 36fcceb..3f7cd0d 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.18.4.2 2009/06/23 14:26:49 dgp Exp $
+# RCS: @(#) $Id: winWm.test,v 1.18.4.3 2009/11/22 23:28:36 patthoyts Exp $
package require tcltest 2.1
eval tcltest::configure $argv
@@ -415,6 +415,51 @@ test winWm-9.0 "Bug #2799589 - delayed activation of destroyed window" -constrai
destroy .tx .t .sd
} -result {ok}
+test winWm-9.1 "delayed activation of grabbed destroyed window" -constraints win -setup {
+ proc winwm91click {w} {
+ if {![winfo ismapped $w]} { update }
+ event generate $w <Enter>
+ focus -force $w
+ event generate $w <ButtonPress-1> -x 5 -y 5
+ event generate $w <ButtonRelease-1> -x 5 -y 5
+ }
+ proc winwm91proc3 {} {
+ global winwm91done winwm91check
+ set w .sd
+ toplevel $w
+ pack [button $w.b -text "OK" -command {set winwm91check 1}]
+ bind $w.b <Map> {after idle {winwm91click %W}}
+ update idletasks
+ tkwait visibility $w
+ grab $w
+ tkwait variable winwm91check
+ #skip the release: #grab release $w
+ destroy $w
+ after idle {set winwm91done ok}
+ }
+ proc winwm91proc2 {w} { winwm91proc3; destroy $w }
+ proc winwm91proc1 {w} {
+ toplevel $w
+ pack [button $w.b -text "Do dialog" -command [list winwm91proc2 $w]]
+ bind $w.b <Map> {bind %W <Map> {}; after idle {winwm91click %W}}
+ }
+ destroy .t
+ global winwm91done
+ set winwm91done wait
+ toplevel .t
+} -body {
+ pack [button .t.b -text "Show" -command {winwm91proc1 .tx}]
+ bind .t.b <Map> {bind %W <Map> {}; after idle {winwm91click %W}}
+ after 5000 {set winwm91done timeout}
+ vwait winwm91done
+ set winwm91done
+} -cleanup {
+ foreach cmd {proc1 proc2 proc3 click} {
+ rename winwm91$cmd {}
+ }
+ destroy .tx .t .sd
+} -result {ok}
+
destroy .t
# cleanup
diff --git a/win/tkWinWm.c b/win/tkWinWm.c
index 4266663..8896b1a 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.124.2.7 2009/11/03 23:49:11 patthoyts Exp $
+ * RCS: @(#) $Id: tkWinWm.c,v 1.124.2.8 2009/11/22 23:28:36 patthoyts Exp $
*/
#include "tkWinInt.h"
@@ -43,7 +43,8 @@
typedef struct ActivateEvent {
Tcl_Event ev;
TkWindow *winPtr;
- int *flagPtr;
+ const int *flagPtr;
+ HWND hwnd;
} ActivateEvent;
/*
@@ -422,7 +423,7 @@ TCL_DECLARE_MUTEX(winWmMutex)
static int ActivateWindow(Tcl_Event *evPtr, int flags);
static void ConfigureTopLevel(WINDOWPOS *pos);
static void GenerateConfigureNotify(TkWindow *winPtr);
-static void GenerateActivateEvent(TkWindow *winPtr, int *flagPtr);
+static void GenerateActivateEvent(TkWindow *winPtr, const int *flagPtr);
static void GetMaxSize(WmInfo *wmPtr,
int *maxWidthPtr, int *maxHeightPtr);
static void GetMinSize(WmInfo *wmPtr,
@@ -8236,13 +8237,14 @@ TkpGetWrapperWindow(
*/
static void
-GenerateActivateEvent(TkWindow * winPtr, int *flagPtr)
+GenerateActivateEvent(TkWindow * winPtr, const int *flagPtr)
{
ActivateEvent *eventPtr;
eventPtr = (ActivateEvent *)ckalloc(sizeof(ActivateEvent));
eventPtr->ev.proc = ActivateWindow;
eventPtr->winPtr = winPtr;
eventPtr->flagPtr = flagPtr;
+ eventPtr->hwnd = Tk_GetHWND(winPtr->window);
Tcl_QueueEvent((Tcl_Event *)eventPtr, TCL_QUEUE_TAIL);
}
@@ -8275,6 +8277,15 @@ ActivateWindow(
}
/*
+ * Ensure the window has not been destroyed while we delayed
+ * processing the WM_ACTIVATE message [Bug 2899949].
+ */
+
+ if (!IsWindow(eventPtr->hwnd)) {
+ return 1;
+ }
+
+ /*
* If the toplevel is in the middle of a move or size operation then
* we must delay handling of this event to avoid stealing the focus
* while the window manage is in control.