From 289a84bb2587e4db1a64b76701759a572d6c3447 Mon Sep 17 00:00:00 2001 From: patthoyts Date: Sun, 22 Nov 2009 23:28:36 +0000 Subject: Make sure the window is still present when handling delayed activation [Bug 2899949] --- ChangeLog | 5 +++++ tests/winWm.test | 47 ++++++++++++++++++++++++++++++++++++++++++++++- win/tkWinWm.c | 19 +++++++++++++++---- 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 + + * tests/winWm.test: Make sure the window is still present + * win/tkWinWm.c: when handling delayed activation [Bug 2899949] + 2009-11-13 Pat Thoyts * 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 + focus -force $w + event generate $w -x 5 -y 5 + event generate $w -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 {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 {bind %W {}; 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 {bind %W {}; 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. -- cgit v0.12