I've ported a program from Windows to Mac OSX that is built on C++, Tcl
and VTK. A few weeks ago I asked for support of "wm forget/wm manage"
and Kevin Walzer helpfully implemented them:) I finally got all pending
dependencies compiled and my real application runs. However, there are
still bugs in the "wm forget" stuff, which are quite hard to track down
further. Very often, in my real app, "wm manage" produces "dead"
toplevels, that is, the content is not repainted any more. Sometimes the
widgets react on mouseclicks, but don't repaint. This is especially
apparent when the toplevel is resized.
If docking/undocking is repeated many times, eventually the program
crashes. This happens also with the demo toolbar script, but its not
reproducible well. under the debugger it does not happen:( The crash
reporter tells me that its an exception at tkMacOSXWm.c:731. Code at
this point reads:
void
TkWmDeadWindow(
TkWindow *winPtr) /* Top-level window that's being deleted. */
{
WmInfo *wmPtr = winPtr->wmInfoPtr, *wmPtr2;
if (wmPtr == NULL) {
return;
}
// next line is 731
if (wmPtr->hints.flags & IconPixmapHint) {
Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_pixmap);
}
To trigger an exception at this line, wmPtr must be invalid but !=NULL.
The following code almost always displays the problems on my machine
(Snow Leopard):
package require Tk
toplevel .dock
pack [ttk::label .dock.text -text "This is a toplevel\nwhich can be docked"]
pack [ttk::button .dock.d -text "(un)dock" -command dock]
pack [ttk::label .p -text "Place your \nwindow here"] -side left
set docked false
proc dock {} {
if {$::docked} {
pack forget .dock
wm manage .dock
set ::docked false
} else {
wm forget .dock
pack .dock -side left
set ::docked true
}
}
Try for instance to resize the toplevel with the button after it has
been undocked. This script works as expected on X11 and Windows. Maybe
the difference to the toolbar demo is, that the dock operation is
triggered by a button press in the window that is going to disappear.
Christian
From the man page:
"wm manage widget
The widget specified will become a stand alone top-level window. The
window will be decorated with the window managers title bar, etc. Only
frame, labelframe and toplevel widgets can be used with this command.
Attempting to pass any other widget type will raise an error. Attempting
to manage a toplevel widget is benign and achieves nothing. See also
GEOMETRY MANAGEMENT."
The base widget needs to be a frame or labelframe--I don't think this
code sample will work with the wm manage command. If you look at the
demo, it's a frame that is the base widget being managed.
--Kevin
--
Kevin Walzer
Code by Kevin
http://www.codebykevin.com
Am 26.07.11 02:48, schrieb Kevin Walzer:
Yes, it does. Try it on windows or X11 (Mac/X11 works). First, .dock is
a toplevel, then we "wm forget" it to pack it on a button press. After
pressing the button again, we "pack forget" and "wm manage" it to get it
off again. As a side note, also the demos/toolbar.tcl crashes now on my
system (Tcl HEAD). It's just unpredictable. Try to undock/dock
repeatedly. I can send you the stack trace. Below are the first few lines.
Thank you for looking into this issue,
Christian
Process: wish8.6 [19097]
Path: /Users/chris/Programmieren/bin/wish8.6
Identifier: wish8.6
Version: 8.6b1.2 (8.6b1.2)
Code Type: X86-64 (Native)
Parent Process: bash [317]
Date/Time: 2011-07-25 21:58:34.119 +0200
OS Version: Mac OS X 10.6.8 (10K540)
Report Version: 6
Interval Since Last Report: 170653 sec
Crashes Since Last Report: 10
Per-App Crashes Since Last Report: 4
Anonymous UUID: E5D158F2-08EA-4C40-8A5B-DDB4C3FE193C
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000400000d29
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Application Specific Information:
objc[19097]: garbage collection is ON
Thread 0 Crashed: Dispatch queue: com.apple.main-thread
0 libtk8.6.dylib 0x00000001000d34ff TkWmDeadWindow +
30 (tkMacOSXWm.c:731)
1 libtk8.6.dylib 0x00000001000d3cb6 WmForgetCmd + 113
(tkMacOSXWm.c:1650)
2 libtk8.6.dylib 0x00000001000d8250 Tk_WmObjCmd + 1697
(tkMacOSXWm.c:926)
3 libtcl8.6.dylib 0x00000001001c27b2 TclNREvalObjv + 1724
4 libtcl8.6.dylib 0x000000010021076b TEBCresume + 5478
5 libtcl8.6.dylib 0x00000001001bf03a TclNRRunCallbacks + 58
6 libtk8.6.dylib 0x00000001000adc2f Ttk_InvokeEnsemble
+ 148 (ttkTheme.c:1678)
7 libtk8.6.dylib 0x00000001000b583b
WidgetInstanceObjCmd + 92 (ttkWidget.c:161)
8 libtcl8.6.dylib 0x00000001001c27b2 TclNREvalObjv + 1724
9 libtcl8.6.dylib 0x000000010021076b TEBCresume + 5478
10 libtcl8.6.dylib 0x00000001001bf03a TclNRRunCallbacks + 58
11 libtk8.6.dylib 0x00000001000b50ce
TtkWidgetInstateCommand + 219 (ttkWidget.c:743)
12 libtk8.6.dylib 0x00000001000adc2f Ttk_InvokeEnsemble
+ 148 (ttkTheme.c:1678)
13 libtk8.6.dylib 0x00000001000b583b
WidgetInstanceObjCmd + 92 (ttkWidget.c:161)
14 libtcl8.6.dylib 0x00000001001c27b2 TclNREvalObjv + 1724
15 libtcl8.6.dylib 0x000000010021076b TEBCresume + 5478
16 libtcl8.6.dylib 0x00000001001bf03a TclNRRunCallbacks + 58
17 libtk8.6.dylib 0x00000001000b50ce
TtkWidgetInstateCommand + 219 (ttkWidget.c:743)
18 libtk8.6.dylib 0x00000001000adc2f Ttk_InvokeEnsemble
+ 148 (ttkTheme.c:1678)
19 libtk8.6.dylib 0x00000001000b583b
WidgetInstanceObjCmd + 92 (ttkWidget.c:161)
20 libtcl8.6.dylib 0x00000001001c27b2 TclNREvalObjv + 1724
21 libtcl8.6.dylib 0x00000001001c2909 Tcl_EvalObjv + 38
22 libtcl8.6.dylib 0x00000001001c31c9 TclEvalEx + 2217
23 libtcl8.6.dylib 0x00000001001c35ae Tcl_EvalEx + 26
24 libtk8.6.dylib 0x000000010001367f Tk_BindEvent +
4724 (tkBind.c:1493)
25 libtk8.6.dylib 0x00000001000176f1 TkBindEventProc +
342 (tkCmds.c:316)
26 libtk8.6.dylib 0x000000010001dea7 Tk_HandleEvent +
1431 (tkEvent.c:1366)
27 libtk8.6.dylib 0x000000010001df78 WindowEventProc +
92 (tkEvent.c:1754)
28 libtcl8.6.dylib 0x000000010023e108 Tcl_ServiceEvent + 147
29 libtcl8.6.dylib 0x000000010023e3fc Tcl_DoOneEvent + 314
30 libtk8.6.dylib 0x000000010001d6cc Tk_MainLoop + 24
(tkEvent.c:2130)
31 libtk8.6.dylib 0x000000010002b2a5 Tk_MainEx + 1324
(tkMain.c:343)
32 wish8.6 0x0000000100005505 main + 56
(tkAppInit.c:76)
33 wish8.6 0x000000010000545c start + 52
> Yes, it does. Try it on windows or X11 (Mac/X11 works). First, .dock is
> a toplevel, then we "wm forget" it to pack it on a button press. After
> pressing the button again, we "pack forget" and "wm manage" it to get it
> off again. As a side note, also the demos/toolbar.tcl crashes now on my
> system (Tcl HEAD). It's just unpredictable. Try to undock/dock
> repeatedly. I can send you the stack trace. Below are the first few lines.
>
> Thank you for looking into this issue,
>
> Christian
>
I've committed an update that addresses some issues with redraw when the
[wm manage] command is called, but that doesn't fix the crash you
reported, which I also see. I am not sure how to proceed with this.
Err, that should be redraw in the wm forget command.
thank you for looking into this issue.
Am 26.07.11 15:32, schrieb Kevin Walzer:
>> I've committed an update that addresses some issues with redraw when the
>> [wm manage] command is called, but that doesn't fix the crash you
>> reported, which I also see. I am not sure how to proceed with this.
I could compile valgrind for my system, it seems to work. I ran it on
tclsh8.6 and entered the following commands:
package require Tk
toplevel .t
wm forget .t
The toplevel command issues many warnings, but these might as well be
false positives (the list is very long). wm forget triggers an exception
near the point, where the crash usually occurs. The relevant part of
valgrinds output is:
% wm forget .t
==29387== Conditional jump or move depends on uninitialised value(s)
==29387== at 0x1010CD4F9: TkWmDeadWindow (tkMacOSXWm.c:728)
==29387== by 0x1010CDCB5: WmForgetCmd (tkMacOSXWm.c:1649)
==29387== by 0x1010D224F: Tk_WmObjCmd (tkMacOSXWm.c:926)
==29387== by 0x1000377B1: TclNREvalObjv (in
/Users/chris/Programmieren/lib/libtcl8.6.dylib)
==29387== by 0x10008576A: TEBCresume (in
/Users/chris/Programmieren/lib/libtcl8.6.dylib)
==29387== by 0x100034039: TclNRRunCallbacks (in
/Users/chris/Programmieren/lib/libtcl8.6.dylib)
==29387== by 0x100090CC6: Tcl_RecordAndEvalObj (in
/Users/chris/Programmieren/lib/libtcl8.6.dylib)
==29387== by 0x1000AE265: StdinProc (in
/Users/chris/Programmieren/lib/libtcl8.6.dylib)
==29387== by 0x10009AD83: Tcl_NotifyChannel (in
/Users/chris/Programmieren/lib/libtcl8.6.dylib)
==29387== by 0x1000FC7EF: FileHandlerEventProc (in
/Users/chris/Programmieren/lib/libtcl8.6.dylib)
==29387== by 0x1000B3107: Tcl_ServiceEvent (in
/Users/chris/Programmieren/lib/libtcl8.6.dylib)
==29387== by 0x1000B33FB: Tcl_DoOneEvent (in
/Users/chris/Programmieren/lib/libtcl8.6.dylib)
==29387==
So, this means that winPtr->wmInfoPtr is uninitialized, which causes the
following ifs to go crazy (unless winPtr->wmInfoPtr happens to be NULL).
Maybe its really the fault of the toplevel command, however, the stack
trace is really long and my skills and knowledge of Tk internals are not
sufficient to read it. I'll send you the complete stack trace by private
email.
Regards,
Christian
--KEvin
1) The following script crashes always:
package require Tk
toplevel .t
# update
wm forget .t
exit
It crashes on line 726. (wmInfo *wmPtr=winPtr->wmInfoPtr). This means,
th toplevel has not yet been mapped, therefore winPtr is invalid or
NULL. THIS BUG IS ON WINDOWS, TOO! To fix this, wm forget must check if
the toplevel is mapped, which it doesn't. This must be fixed in the
windows implementation also. (Checked only 8.5)
If we insert the "update" in the script above, the crash occurs (if it
occurs) in the next if clause, where valgrind claims that
winPtr->wmInfoPtr has not been set. I'm beginning to believe that this
problem is buried somewhere else. Valgrinds stacktrace tells there is
something fishy with XMapWindow. You could set a breakpoint in MapFrame,
step through it and look at the window sructure.
Regards,
Christian
Valgrind says, after toplevel .t triggers the mapping:
==29387== Address 0x11a246818 is 40 bytes inside a block of size 480
alloc'd
==29387== at 0x10001150E: calloc (vg_replace_malloc.c:467)
==29387== by 0x1039DAD1F: CGSNewWindowWithOpaqueShape (in
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.
framework/Versions/A/CoreGraphics)
==29387== by 0x1016BAF03: _NSCreateWindowWithOpaqueShape2 (in
/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit)
==29387== by 0x10164F690: -[NSWindow _commonAwake] (in
/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit)
==29387== by 0x10166D1C8: -[NSWindow
_makeKeyRegardlessOfVisibility] (in
/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit)
==29387== by 0x10166D13D: -[NSWindow makeKeyAndOrderFront:] (in
/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit)
==29387== by 0x1010C975E: XMapWindow (tkMacOSXSubwindows.c:153)
==29387== by 0x10103238E: Tk_MapWindow (tkWindow.c:1658)
==29387== by 0x10103B239: MapFrame (tkFrame.c:1782)
==29387== by 0x1000CFC02: TclServiceIdle (in
/Users/chris/Programmieren/lib/libtcl8.6.dylib)
==29387== by 0x1000B340A: Tcl_DoOneEvent (in
/Users/chris/Programmieren/lib/libtcl8.6.dylib)
==29387== by 0x1010176CB: Tk_MainLoop (tkEvent.c:2131)
==29387==
It is strange that Tk_MapWindow calls XMapWindow instead of
TkWmMapWindow, because there is the following code:
if (winPtr->flags & TK_WIN_MANAGED) {
/*
* Lots of special processing has to be done for top-level
windows.
* Let tkWm.c handle everything itself.
*/
TkWmMapWindow(winPtr);
return;
}
Can it be, that toplevel does not set TK_WIN_MANAGED correctly?
Christian, off to work now
Christian,
Looking at this and your other reports, I'm wondering if I'm the right
person to handle this issue, since you mention that it also affects
Windows. I have no knowledge of the Windows API and, actually, very
limited knowledge of the general Xlib API that Tk is based on. My
knowledge is stronger on the Cocoa API's that Tk-Mac is based on. As you
say, this appears to be some sort of issue deep within Tk's drawing
internals and may not be platform-specific (or may be cross-platform). I
suggest you file a bug at the SF tracker focusing on the more general
issues you are reporting, and assign it to one of the core Tk developers
(perhaps Jeff Hobbs or Donal Fallows, they will assign it correctly if
they can't handle it). At this point there's not much else I can do to
address this report, since nothing I've tried, even with your very
helpful input, has gained any traction.
--Kevin
Am 27.07.11 16:57, schrieb Kevin Walzer:
> I
> suggest you file a bug at the SF tracker focusing on the more general
> issues you are reporting, and assign it to one of the core Tk developers
> (perhaps Jeff Hobbs or Donal Fallows, they will assign it correctly if
> they can't handle it).
thank you very much for your help. I will file a bug report on
sourceforge, I'm still thinking how to write a good one concerning these
issues. I checked with Windows, and there I can get "zombie" windows
which do not repaint, too, however I could not get it to crash.
Thanks for your time,
Christian