From 25da577cdf47ba31dadd5f5234a2b3d60242f9f7 Mon Sep 17 00:00:00 2001 From: patthoyts Date: Sat, 19 Mar 2011 00:39:28 +0000 Subject: [Bug 3205464] - handle [wm forget] when the parent is unmapped on windows The fix for [Bug 2009788] prevented a crash but causes windows to be lost if their parent is unmapped when [wm forget] is called. Added a test for this case and ensure that the parent window exists when we remap the child to its parent. Reported-by: Koen Danckaert Reported-by: Eric Boudaillier Signed-off-by: Pat Thoyts --- tests/winWm.test | 30 ++++++++++++++++++++++++++++++ win/tkWinWm.c | 5 ++--- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/tests/winWm.test b/tests/winWm.test index 3f7cd0d..a026c8e 100644 --- a/tests/winWm.test +++ b/tests/winWm.test @@ -460,6 +460,36 @@ test winWm-9.1 "delayed activation of grabbed destroyed window" -constraints win destroy .tx .t .sd } -result {ok} +test winWm-9.2 "check wm forget for unmapped parent (#3205464,#2967911)" -setup { + destroy .t + toplevel .t + set winwm92 {} + frame .t.f -background blue -height 200 -width 200 + frame .t.f.x -background red -height 100 -width 100 +} -body { + pack .t.f.x + pack .t.f + set aid [after 1000 {set ::winwm92 timeout}] + after 100 { + wm manage .t.f + wm iconify .t + after 100 { + wm forget .t.f + wm deiconify .t + after 100 { + pack .t.f + after 100 {set ::winwm92 [expr {[winfo rooty .t.f.x] == 0 ? "failed" : "ok"}]} + } + } + } + vwait ::winwm92 + after cancel $aid + set winwm92 +} -cleanup { + destroy .t.f.x .t.f .t + unset -nocomplain winwm92 aid +} -result ok + destroy .t # cleanup diff --git a/win/tkWinWm.c b/win/tkWinWm.c index 290fe3e..d8d3b19 100644 --- a/win/tkWinWm.c +++ b/win/tkWinWm.c @@ -3706,9 +3706,8 @@ WmForgetCmd(tkwin, winPtr, interp, objc, objv) if (Tk_IsTopLevel(frameWin)) { Tk_UnmapWindow(frameWin); winPtr->flags &= ~(TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED); - if (Tk_IsMapped(Tk_Parent(frameWin))) { - RemapWindows(winPtr, Tk_GetHWND(winPtr->parentPtr->window)); - } + Tk_MakeWindowExist((Tk_Window)winPtr->parentPtr); + RemapWindows(winPtr, Tk_GetHWND(winPtr->parentPtr->window)); TkWmDeadWindow(winPtr); /* flags (above) must be cleared before calling */ /* TkMapTopFrame (below) */ -- cgit v0.12