"Fossies" - the Fresh Open Source Software Archive

Member "SAOImageDS9/tk8.6/macosx/README" (13 Nov 2019, 39353 Bytes) of package /linux/misc/ds9.8.1.tar.gz:


As a special service "Fossies" has tried to format the requested text file into HTML format (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

    1 Tcl/Tk macOS README
    2 ----------------------
    3 
    4 This is the README file for the macOS/Darwin version of Tcl/Tk.
    5 
    6 1. Where to go for support
    7 --------------------------
    8 
    9 - The tcl-mac mailing list on sourceforge is the best place to ask questions
   10 specific to Tcl & Tk on macOS:
   11 	http://lists.sourceforge.net/lists/listinfo/tcl-mac
   12 (this page also has a link to searchable archives of the list, please check them
   13 before asking on the list, many questions have already been answered).
   14 
   15 - For general Tcl/Tk questions, the newsgroup comp.lang.tcl is your best bet:
   16 	http://groups.google.com/group/comp.lang.tcl/
   17 
   18 - The Tcl'ers Wiki also has many pages dealing with Tcl & Tk on macOS, see
   19 	http://wiki.tcl.tk/_/ref?N=3753
   20 	http://wiki.tcl.tk/_/ref?N=8361
   21 
   22 - Please report bugs with Tk on macOS to the tracker:
   23 	http://core.tcl.tk/tk/reportlist
   24 
   25 2. Using Tcl/Tk on macOS
   26 ---------------------------
   27 
   28 - There are two versions of Tk available on macOS: TkAqua using the native
   29 aqua widgets and look&feel, and TkX11 using the traditional unix X11 widgets.
   30 TkX11 requires an X11 server to be installed, such as Apple's X11 (which is
   31 available as an optional or default install on recent macOS).
   32 TkAqua and TkX11 can be distinguished at runtime via [tk windowingsystem].
   33 
   34 - At a minimum, macOS 10.3 is required to run Tcl and TkX11.
   35 TkAqua requires macOS 10.6 or later.
   36 
   37 - Unless weak-linking is used, Tcl/Tk built on macOS 10.x will not run on
   38 10.y with y < x; on the other hand Tcl/Tk built on 10.y will always run on 10.x
   39 with y <= x (but without any of the fixes and optimizations that would be
   40 available in a binary built on 10.x).
   41 Weak-linking is available on OS X 10.2 or later, it additionally allows Tcl/Tk
   42 built on 10.x to run on any 10.y with x > y >= z (for a chosen z >= 2).
   43 
   44 - Wish checks the Resources/Scripts directory in its application bundle for a
   45 file called AppMain.tcl, if found it is used as the startup script and the
   46 Scripts folder is added to the auto_path. This can be used to emulate the old
   47 OS9 TclTk droplets.
   48 
   49 - If standard input is a special file of zero length (e.g. /dev/null), Wish
   50 brings up the Tk console window at startup. This is the case when double
   51 clicking Wish in the Finder (or using 'open Wish.app' from the Terminal).
   52 
   53 - Tcl extensions can be installed in any of:
   54 	$HOME/Library/Tcl /Library/Tcl /System/Library/Tcl
   55 	$HOME/Library/Frameworks /Library/Frameworks /System/Library/Frameworks
   56 	(searched in that order).
   57 Given a potential package directory $pkg, Tcl on OSX checks for the file
   58 $pkg/Resources/Scripts/pkgIndex.tcl as well as the usual $pkg/pkgIndex.tcl.
   59 This allows building extensions as frameworks with all script files contained in
   60 the Resources/Scripts directory of the framework.
   61 
   62 - The 'deploy' target of macosx/GNUmakefile installs the html manpages into the
   63 standard documentation location in the Tcl/Tk frameworks:
   64 	Tcl.framework/Resources/Documentation/Reference/Tcl
   65 	Tk.framework/Resources/Documentation/Reference/Tk
   66 No nroff manpages are installed by default by the GNUmakefile.
   67 
   68 - The Tcl and Tk frameworks can be installed in any of the system's standard
   69 framework directories:
   70 	$HOME/Library/Frameworks /Library/Frameworks /System/Library/Frameworks
   71 
   72 - ${prefix}/bin/wish8.x is a script that calls a copy of 'Wish' contained in
   73 	Tk.framework/Resources
   74 
   75 - if 'Wish' is started from the Finder or via 'open', $argv may contain a
   76 "-psn_XXXX" argument. This is the process serial number, you may need to filter
   77 it out for cross platform compatibility of your scripts.
   78 
   79 - the env array is different when Wish is started from the Finder (i.e. via
   80 LaunchServices) than when it (or tclsh) is invoked from the Terminal, in
   81 particular PATH may not be what you expect. (Wish started by LaunchServices
   82 inherits loginwindow's environment variables, which are essentially those set in
   83 $HOME/.MacOSX/environment.plist, and are unrelated to those set in your shell).
   84 
   85 - TkAqua provides access to native OS X images via the Tk native bitmap facility
   86 (including any image file readable by NSImage). A native bitmap name is
   87 interpreted as follows (in order):
   88     - predefined builtin 32x32 icon name (stop, caution, document, etc)
   89     - name defined by [tk::mac::iconBitmap]
   90     - NSImage named image name
   91     - NSImage url string
   92     - 4-char OSType of IconServices icon
   93 the syntax of [tk::mac::iconBitmap] is as follows:
   94 	tk::mac::iconBitmap name width height -kind value
   95 where -kind is one of
   96     -file	    icon of file at given path
   97     -fileType	    icon of given file type
   98     -osType	    icon of given 4-char OSType file type
   99     -systemType	    icon for given IconServices 4-char OSType
  100     -namedImage	    named NSImage for given name
  101     -imageFile	    image at given path
  102 This support was added with the Cocoa-based Tk 8.5.7.
  103 
  104 - TkAqua cursor names are interpred as follows (in order):
  105     - standard or platform-specific Tk cursor name (c.f. cursors.n)
  106     - @path to any image file readable by NSImage
  107     - NSImage named image name
  108 Support for the latter two was added with the Cocoa-based Tk 8.5.7.
  109 
  110 - The standard Tk dialog commands [tk_getOpenFile], [tk_chooseDirectory],
  111 [tk_getSaveFile] and [tk_messageBox] all take an additional optional -command
  112 parameter on TkAqua. If it is present, the given command prefix is evaluated at
  113 the global level when the dialog closes, with the dialog command's result
  114 appended (the dialog command itself returning an emtpy result). If the -parent
  115 option is also present, the dialog is configured as a modeless (window-modal)
  116 sheet attached to the parent window and the dialog command returns immediately.
  117 Support for -command was added with the Cocoa-based Tk 8.5.7.
  118 
  119 - The TkAqua-specific [tk::mac::standardAboutPanel] command brings the standard
  120 Cocoa about panel to the front, with all its information filled in from your
  121 application bundle files (i.e. standard about panel with no options specified).
  122 See Apple Technote TN2179 and the AppKit documentation for -[NSApplication
  123 orderFrontStandardAboutPanelWithOptions:] for details on the Info.plist keys and
  124 app bundle files used by the about panel.
  125 This support was added with the Cocoa-based Tk 8.5.7.
  126 
  127 - TkAqua has three special menu names that give access to the standard
  128 Application, Window and Help menus, see menu.n for details.  By default, the
  129 platform-specific standard Help menu item "YourApp Help" performs the default
  130 Cocoa action of showing the Help Book configured in the application's
  131 Info.plist (or displaying an alert if no Help Book is set). This action can be
  132 customized by defining a procedure named [tk::mac::ShowHelp]. If present, this
  133 procedure is invoked instead by the standard Help menu item.  Support for the
  134 Window menu and [tk::mac::ShowHelp] was added with the Cocoa-based Tk 8.5.7.
  135 
  136 - The TkAqua-specific command [tk::unsupported::MacWindowStyle style] is used to
  137 get and set macOS-specific toplevel window class and attributes. Note that
  138 the window class and many attributes have to be set before the window is first
  139 mapped for the change to have any effect.
  140 The command has the following syntax:
  141 	tk::unsupported::MacWindowStyle style window ?class? ?attributes?
  142 The 2 argument form returns a list of the current class and attributes for the
  143 given window. The 3 argument form sets the class for the given window using the
  144 default attributes for that class. The 4 argument form sets the class and the
  145 list of attributes for the given window.
  146 Window class names:
  147     document, modal, floating, utility, toolbar, simple, help, overlay
  148 Window attribute names:
  149     standardDocument, standardFloating, resizable, fullZoom, horizontalZoom,
  150     verticalZoom, closeBox, collapseBox, toolbarButton, sideTitlebar,
  151     noTitleBar, unifiedTitleAndToolbar, metal, hud, noShadow, doesNotCycle,
  152     noActivates, hideOnSuspend, inWindowMenu, ignoreClicks, doesNotHide,
  153     canJoinAllSpaces, moveToActiveSpace, nonActivating
  154 
  155 Note that not all attributes are valid for all window classes.  Support for the
  156 3 argument form was added with the Cocoa-based Tk 8.5.7, at the same time
  157 support for some legacy Carbon-specific classes and attributes was removed
  158 (they are still accepted by the command but no longer have any effect).
  159 
  160 - Another command available in the tk::unsupported::MacWindowStyle namespace is:
  161   tk::unsupported::MacWindowStyle tabbingid window ?newId?
  162 which can be used to get or set the tabbingIdentifier for the NSWindow
  163 associated with a Tk Window.  See section 3 for details.
  164 
  165 - The command:
  166   tk::unsupported::MacWindowStyle appearance window ?newAppearance?
  167 is available when Tk is built and run on macOS 10.14 (Mojave) or later.  In
  168 that case the Ttk widgets all support the "Dark Mode" appearance which was
  169 introduced in 10.14. The command accepts the following values for the optional
  170 newAppearance option: "aqua", "darkaqua", or "auto".  If the appearance is set
  171 to aqua or darkaqua then the window will be displayed with the corresponding
  172 appearance independent of any preferences settings.  If it is set to "auto"
  173 the appearance will be determined by the preferences.  This command can be
  174 used to opt out of Dark Mode on a per-window basis. It may be best to run the "update" command before setting the appearance property, to allow the event loop to run.
  175 
  176 
  177 - To determine the current appearance of a window in macOS 10.14 (Mojave) and
  178 higher, one can use the command:
  179   tk::unsupported::MacWindowStyle isdark window?
  180 The boolean return value is true if the window is currently displayed with the
  181 dark appearance.
  182 
  183 - If you want to use Remote Debugging with Xcode, you need to set the
  184 environment variable XCNOSTDIN to 1 in the Executable editor for Wish. That will
  185 cause us to force closing stdin & stdout.  Otherwise, given how Xcode launches
  186 Wish remotely, they will be left open and then Wish & gdb will fight for stdin.
  187 
  188 3. FullScreen, Split View and Tabbed Windows
  189 --------------------------------------------
  190 
  191 Since the release of OSX 10.6 (Snow Leopard) a steadily expanding sequence of
  192 high level window operations have been added to Apple's window manager.  These
  193 operations are launched by user actions which are handled directly by the
  194 window manager; they are not initiated by the application.  In some, but not
  195 all cases, the application is notified before and after the operations are
  196 carried out.
  197 
  198 In OSX releases up to and including 10.6 there were three buttons with
  199 stoplight colors located on the left side of a window's title bar.  The
  200 function of the green button was to "zoom" or "maximize" the window, i.e. to
  201 expand the window so that it fills the entire screen, while preserving the
  202 appearance of the window including its title bar.  The release of OSX 10.7
  203 (Lion) introduced the "FullScreen" window which not only filled the screen but
  204 also hid the window's title bar and the menu bar which normally appears at the
  205 top of the screen. These hidden objects would only become visible when the
  206 mouse hovered near the top of the screen.  FullScreen mode was initiated by
  207 pressing a button showing two outward pointing arrows located on the right side
  208 of the title bar; it was terminated by pressing a similar button with inward
  209 pointing arrows on the right hand side of the menu bar.  In OSX 10.10
  210 (Yosemite) the FullScreen button was removed. The green button was repurposed
  211 to cause a window to become a FullScreen window. To zoom a window the user had
  212 to hold down the option key while pressing the green button.  The release of
  213 OSX 10.11 added a third function to the green button: to create two half-screen
  214 windows with hidden title bars and a hidden menu bar, called Split View
  215 windows.  If the green button is held down for one second its window expands to
  216 fill half of the screen.  It can be moved to one side or the other with the
  217 mouse.  The opposite side shows thumbnail images of other windows.  Selecting
  218 one of the thumbnails expands its window to fill that half of the screen.  The
  219 divider between the two windows can be moved to adjust the percentage of the
  220 screen occupied by each of the two tiles.  In OSX 10.12 (Sierra) Tabbed windows
  221 were introduced.  These allow an application with multiple windows to display
  222 its windows as tabs within a single window frame.  Clicking on a tab brings its
  223 window into view.  Tabs can be rearranged by dragging.  Dragging a tab to the
  224 desktop turns it into a separate window.  Items in the Window menu can be used
  225 to cycle through the tabs, move tabbed windows to separate windows, or merge a
  226 set of separate windows as tabs in the same window frame.
  227 
  228 Tk now fully supports all of these high level window operations on any system
  229 where the operation exists.  The FullScreen and Split View windows are handled
  230 automatically with no action required on the part of the programmer.  Tabbed
  231 windows, on the other hand, require some attention from the programmer.
  232 Because many of the operations with tabs are handled through the application's
  233 Window menu, it is essential that an application provide a Windows menu to
  234 avoid presenting a confusing interface to the user. This cannot be ignored, in
  235 part because the systemwide Dock Preferences offers an option to always attempt
  236 to open application windows as tabs. An application which does not provide a
  237 Window menu will necessarily present a confusing interface to any user who has
  238 selected this option.
  239 
  240 A further complication is that it is not neccessarily appropriate for all of an
  241 application's windows to be grouped together as tabs in the same frame.  In
  242 fact, the Apple guidelines insist that windows which are grouped together as
  243 tabs should be similar to each other.  The mechanism provided for arranging
  244 this was to assign to each NSwindow a tabbingIdentifier, and to require that
  245 all windows grouped together as tabs in the same window frame must have the
  246 same tabbingIdentifier.  A tabbingIdentifier is implemented as an arbitrary
  247 string, and a system-generated default tabbingIdentifier is provided to all new
  248 windows.
  249 
  250 Tk provides a means for getting and setting the tabbingIdentifier of
  251 the NSWindow underlying a Tk Window. This is handled by the command
  252 
  253 tk::unsupported::MacWindowStyle tabbingid window ?newId?
  254 
  255 (This command generates an error if used on OSX 10.11 or earlier, since the
  256 tabbingIdentifier does not exist on those systems.)  The command returns the
  257 tabbingIdentifier which had been assigned to the window prior to execution of
  258 the command.  If the optional newId argument is omitted, the window's
  259 tabbingIdentifier is not changed.  Otherwise it is set to the string specified
  260 by the argument.
  261 
  262 Since NSWindows can only be grouped together as tabs if they all have the same
  263 tabbingIdentifier, one can prevent a window from becoming a tab by giving it a
  264 unique tabbingIdentifier. This is independent of any preferences setting. To
  265 ensure that we maintain consistency, changing the tabbingIdentifier of a window
  266 which is already displayed as a tab will also cause it to become a separate
  267 window.
  268 
  269 4. Ttk, Dark Mode and semantic colors
  270 ---------------------------------------
  271 
  272 With the release of OSX 10.14 (Mojave), Apple introduced the DarkAqua
  273 appearance.  Part of the implementation of the Dark Mode was to make
  274 some of the named NSColors have dynamic values.  Apple calls these
  275 "semantic colors" because the name does not specify a specific color,
  276 but rather refers to the context in which the color should be used.
  277 Tk now provides the following semantic colors as system colors:
  278 systemTextColor, systemTextBackgroundColor, systemSelectedTextColor,
  279 systemSelectedTextBackgroundColor, systemControlTextColor,
  280 systemDisabledControlTextColor, systemLabelColor, and
  281 systemControlAccentColor.  All of these except the last two were
  282 present in OSX 10.0 (and those two are simulated in systems where they
  283 do not exist).  The change in 10.14 was that the RGB color value of
  284 these colors became dynamic, meaning that the color value can change
  285 when the application appearance changes.  In particular, when a user
  286 selects Dark Mode in the system preferences these colors change
  287 appearance.  For example systemTextColor is dark in Aqua and light in
  288 DarkAqua.  One additional color, systemSelectedTabTextColor, does not
  289 exist in macOS but is used by Tk to match the different colors used
  290 for Notebook tab text in different OS versions.
  291 
  292 The default background and foreground colors of most of the Tk widgets
  293 have been set to semantic colors, which means that the widgets will change
  294 appearance, and remain usable, when Dark Mode is selected in the system
  295 preferences.  However, to get a close match to the native Dark Mode style it
  296 is recommended to use Ttk widgets when possible.
  297 
  298 Apple's tab view and GroupBox objects delimit their content by
  299 displaying it within a rounded rectangle with a background color that
  300 contrasts with the background of the containing object.  This means
  301 that the background color of a Ttk widget depends on how deeply it is
  302 nested inside of other widgets that use contrasting backgrounds.  To
  303 support this, there are 8 contrasting system colors named
  304 systemWindowBackgroundColor, and systemWindowBackgroundColor1 - 7.
  305 The systemWindowBackgroundColor is the standard background for a
  306 dialog window and the others match the contrasting background colors
  307 used in ttk::notebooks and ttk::labelframes which are nested to the
  308 corresponding depth.
  309 
  310 5. Building Tcl/Tk on macOS
  311 ------------------------------
  312 
  313 - macOS 10.6 is required to build TkAqua and TkX11.  The XCode application provides everything needed to build Tk, but it is not necessary to install the full XCode.
  314 It suffices to install the Command Line Tools package, which can be done
  315 by running the command:
  316 xcode-select --install
  317 
  318 - Tcl/Tk are most easily built as macOS frameworks via GNUmakefile in
  319 tcl/macosx and tk/macosx (see below for details), but can also be built with the
  320 standard unix configure and make buildsystem in tcl/unix resp. tk/unix as on any
  321 other unix platform (indeed, the GNUmakefiles are just wrappers around the unix
  322 buildsystem).
  323 The macOS specific configure flags are --enable-aqua, --enable-framework and
  324 --disable-corefoundation (which disables CF and notably reverts to the standard
  325 select based notifier). Note that --enable-aqua is incompatible with
  326 --disable-corefoundation (for both Tcl and Tk configure).
  327 
  328 - It was once possible to build with the Xcode IDE via the projects in
  329 tk/macosx, but this has not been tested recently. Take care to use the
  330 project matching your DevTools and OS version:
  331 	Tk.xcode: 		    for Xcode 3.1 on 10.5
  332 	Tk.xcodeproj:		    for Xcode 3.2 on 10.6
  333 These have the following targets:
  334 	Tk:			    calls through to tk/macosx/GNUMakefile,
  335 				    requires a corresponding build of the Tcl
  336 				    target of tcl/macosx/Tcl.xcode.
  337 	tktest:			    static build of TkAqua tktest for debugging.
  338 	tktest-X11:		    static build of TkX11 tktest for debugging.
  339 The following build configurations are available:
  340 	Debug:			    debug build for the active architecture,
  341 				    with Fix & Continue enabled.
  342 	Debug clang:		    use clang compiler.
  343 	Debug llvm-gcc:		    use llvm-gcc compiler.
  344 	Debug gcc40:		    use gcc 4.0 compiler.
  345 	DebugNoGC:		    disable Objective-C garbage collection.
  346 	DebugNoFixAndContinue:      disable Fix & Continue.
  347 	DebugUnthreaded:	    disable threading.
  348 	DebugNoCF:		    disable corefoundation (X11 only).
  349 	DebugNoCFUnthreaded:	    disable corefoundation an threading.
  350 	DebugMemCompile:	    enable memory and bytecode debugging.
  351 	DebugLeaks:		    define PURIFY.
  352 	DebugGCov:		    enable generation of gcov data files.
  353 	Debug64bit:		    configure with --enable-64bit (requires
  354 				    building on a 64bit capable processor).
  355 	Release:		    release build for the active architecture.
  356 	ReleaseUniversal:	    32/64-bit universal build.
  357 	ReleaseUniversal clang:	    use clang compiler.
  358 	ReleaseUniversal llvm-gcc:  use llvm-gcc compiler.
  359 	ReleaseUniversal gcc40:	    use gcc 4.0 compiler.
  360 	ReleaseUniversal10.5SDK:    build against the 10.5 SDK (with 10.5
  361 				    deployment target).
  362 	Note that the non-SDK configurations have their deployment target set to
  363 	10.5 (Tk.xcode) resp. 10.6 (Tk.xcodeproj).
  364 The Xcode projects refer to the toplevel tcl and tk source directories via the
  365 the TCL_SRCROOT and TK_SRCROOT user build settings, by default these are set to
  366 the project-relative paths '../../tcl' and '../../tk', if your source
  367 directories are named differently, e.g. '../../tcl8.6' and '../../tk8.6', you
  368 need to manually change the TCL_SRCROOT and TK_SRCROOT settings by editing your
  369 ${USER}.pbxuser file (located inside the Tk.xcodeproj bundle directory) with a
  370 text editor.
  371 
  372 - To enable weak-linking, set the MACOSX_DEPLOYMENT_TARGET environment variable
  373 to the minimal OS version the binaries should be able to run on, e.g:
  374 	export MACOSX_DEPLOYMENT_TARGET=10.6
  375 This requires at least gcc 3.1; with gcc 4 or later, set/add to CFLAGS instead:
  376 	export CFLAGS="-mmacosx-version-min=10.6"
  377 Support for weak-linking was added with 8.4.14/8.5a5.
  378 
  379 Detailed Instructions for building with macosx/GNUmakefile
  380 ----------------------------------------------------------
  381 
  382 - Unpack the Tcl and Tk source release archives and place the tcl and tk source
  383 trees in a common parent directory.
  384 [ If you don't want have the two source trees in one directory, you'll need to ]
  385 [ create the following symbolic link for the build to work as setup by default ]
  386 [      ln -fs /path_to_tcl/build /path_to_tk/build			       ]
  387 [ (where /path_to_{tcl,tk} is the directory containing the tcl resp. tk tree)  ]
  388 [ or you can pass an argument of BUILD_DIR=/somewhere to the tcl and tk make.  ]
  389 
  390 - The following instructions assume the Tcl and Tk source trees are named
  391 "tcl${ver}" and "tk${ver}" (where ${ver} is a shell variable containing the
  392 Tcl/Tk version number, e.g. '8.6').
  393 Setup this shell variable as follows:
  394 	ver="8.6"
  395 If you are building from CVS, omit this step (CVS source tree names usually do
  396 not contain a version number).
  397 
  398 - Setup environment variables as desired, e.g. for a universal build on 10.5:
  399 	CFLAGS="-arch i386 -arch x86_64 -arch ppc -mmacosx-version-min=10.5"
  400 	export CFLAGS
  401 
  402 - Change to the directory containing the Tcl and Tk source trees and build:
  403 	make -C tcl${ver}/macosx
  404 	make -C tk${ver}/macosx
  405 
  406 - Install Tcl and Tk onto the root volume (admin password required):
  407 	sudo make -C tcl${ver}/macosx install
  408 	sudo make -C tk${ver}/macosx  install
  409 if you don't have an admin password, you can install into your home directory
  410 instead by passing an INSTALL_ROOT argument to make:
  411 	make -C tcl${ver}/macosx install INSTALL_ROOT="${HOME}/"
  412 	make -C tk${ver}/macosx  install INSTALL_ROOT="${HOME}/"
  413 
  414 - The default GNUmakefile targets will build _both_ debug and optimized versions
  415 of the Tcl and Tk frameworks with the standard convention of naming the debug
  416 library Tcl.framework/Tcl_debug resp. Tk.framework/Tk_debug.
  417 This allows switching to the debug libraries at runtime by setting
  418 	export DYLD_IMAGE_SUFFIX=_debug
  419 (c.f. man dyld for more details)
  420 
  421 If you only want to build and install the debug or optimized build, use the
  422 'develop' or 'deploy' target variants of the GNUmakefile, respectively.
  423 For example, to build and install only the optimized versions:
  424 	make -C tcl${ver}/macosx deploy
  425 	make -C tk${ver}/macosx deploy
  426 	sudo make -C tcl${ver}/macosx install-deploy
  427 	sudo make -C tk${ver}/macosx  install-deploy
  428 
  429 - The GNUmakefile can also build a version of Wish.app that has the Tcl and Tk
  430 frameworks embedded in its application package. This allows for standalone
  431 deployment of the application with no installation required, e.g. from read-only
  432 media. To build & install in this manner, use the 'embedded' variants of
  433 the GNUmakefile targets.
  434 For example, to build a standalone 'Wish.app' in ./emb/Applications/Utilities:
  435 	make -C tcl${ver}/macosx embedded
  436 	make -C tk${ver}/macosx embedded
  437 	sudo make -C tcl${ver}/macosx install-embedded INSTALL_ROOT=`pwd`/emb/
  438 	sudo make -C tk${ver}/macosx  install-embedded INSTALL_ROOT=`pwd`/emb/
  439 Notes:
  440   * if you've already built standard TclTkAqua, building embedded does not
  441   require any new compiling or linking, so you can skip the first two makes.
  442   (making relinking unnecessary was added with 8.4.2)
  443   * the embedded frameworks include only optimized builds and no documentation.
  444   * the standalone Wish has the directory Wish.app/Contents/lib in its
  445   auto_path. Thus you can place tcl extensions in this directory (i.e. embed
  446   them in the app package) and load them with [package require].
  447 
  448 - It is possible to build Tk against an installed Tcl.framework; but you will
  449 still need a tcl sourcetree in the location specified in TCL_SRC_DIR in
  450 Tcl.framework/tclConfig.sh. Also, linking with Tcl.framework has to work exactly
  451 as indicated in TCL_LIB_SPEC in Tcl.framework/tclConfig.sh.
  452 If you used non-default install locations for Tcl.framework, specify them as
  453 make overrides to the tk/macosx GNUmakefile, e.g.
  454 	make -C tk${ver}/macosx \
  455 	    TCL_FRAMEWORK_DIR=$HOME/Library/Frameworks TCLSH_DIR=$HOME/usr/bin
  456 	sudo make -C tk${ver}/macosx install \
  457 	    TCL_FRAMEWORK_DIR=$HOME/Library/Frameworks TCLSH_DIR=$HOME/usr/bin
  458 The Makefile variables TCL_FRAMEWORK_DIR and TCLSH_DIR were added with Tk 8.4.3.
  459 
  460 5. Details regarding the macOS port of Tk.
  461 -------------------------------------------
  462 
  463 5.1 About the event loop
  464 ~~~~~~~~~~~~~~~~~~~~~~~~
  465 
  466 The main program in a typical OSX application looks like this (see
  467 https://developer.apple.com/library/mac/documentation/Cocoa/\
  468 Reference/ApplicationKit/Classes/NSApplication_Class)
  469 
  470     void NSApplicationMain(int argc, char *argv[]) {
  471         [NSApplication sharedApplication];
  472         [NSBundle loadNibNamed:@"myMain" owner:NSApp];
  473         [NSApp run];
  474     }
  475 Here NSApp is a standard global variable, initialized by the OS, which
  476 points to an object in a subclass of NSApplication (called
  477 TKApplication in the case of the macOS port of Tk).
  478 
  479 The [NSApp run] method implements the event loop for a typical Mac
  480 application.  There are three key steps in the run method.  First it
  481 calls [NSApp finishLaunching], which creates the bouncing application
  482 icon and does other mysterious things. Second it creates an
  483 NSAutoreleasePool.  Third, it starts an event loop which drains the
  484 NSAutoreleasePool every time the queue is empty, and replaces the
  485 drained pool with a new one.  This third step is essential to
  486 preventing memory leaks, since the internal methods of Appkit objects
  487 all assume that an autorelease pool is in scope and will be drained
  488 when the event processing cycle ends.
  489 
  490 The macOS Tk application does not call the [NSApp run] method at
  491 all.  Instead it uses the event loop built in to Tk.  So the
  492 application must take care to replicate the important features of the
  493 method ourselves.  The way that autorelease pools are handled is
  494 discussed in 5.2 below.  Here we discuss the event handling itself.
  495 
  496 The Tcl event loop simply consists of repeated calls to TclDoOneEvent.
  497 Each call to TclDoOneEvent begins by collecting all pending events from
  498 an "event source", converting them to Tcl events and adding them
  499 to the Tcl event queue. For macOS, the event source is the NSApp
  500 object, which maintains an event queue even though its run method
  501 will never be called to process them.  The NSApp provides methods for
  502 inspecting the queue and removing events from it as well as the
  503 [NSApp sendevent] which sends an event to all of the application's
  504 NSWindows which can then send it to subwindows, etc.
  505 
  506 The event collection process consists of first calling a platform
  507 specific SetupProc and then a platform specific CheckProc.  In
  508 the macOS port, these are named TkMacOSXEventsSetupProc and
  509 TkMacOSXEventsCheckProc.
  510 
  511 It is important to understand that the Apple window manager does not
  512 have the concept of an expose event.  Their replacement for an expose
  513 event is to have the window manager call the [NSView drawRect] method
  514 in any situation where an expose event for that NSView would be
  515 generated in X11.  The [NSView drawRect] method is a no-op which is
  516 expected to be overridden by any application.  In the case of Tcl, the
  517 replacement [NSView drawRect] method creates a Tcl expose event
  518 for each dirty rectangle of the NSView, and then adds the expose
  519 event to the Tcl queue.
  520 
  521 
  522 5.2 Autorelease pools
  523 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  524 
  525 In order to carry out the job of managing autorelease pools, which
  526 would normally be handled by the [NSApp run] method, a private
  527 NSAutoreleasePool* property is added to the TkApplication subclass of
  528 NSApplication. The TkpInit function calls [NSApp _setup] which
  529 initializes this property by creating an NSAutoreleasePool prior to
  530 calling [NSApp finishLaunching].  This mimics the behavior of the
  531 [NSApp run] method, which calls [NSApp finishLaunching] just before
  532 starting the event loop.
  533 
  534 Since the CheckProc function gets called for every Tk event, it is an
  535 appropriate place to drain the main NSAutoreleasePool and replace it
  536 with a new pool.  This is done by calling the method [NSApp
  537 _resetAutoreleasePool], where _resetAutoreleasePool is a method which
  538 we define for the subclass.  Unfortunately, by itself this is not
  539 sufficient for safe memory managememt because, as was made painfully
  540 evident with the release of OS X 10.13, it is possible for calls to
  541 TclDoOneEvent, and hence to CheckProc, to be nested.  Draining the
  542 autorelease pool in a nested call leads to crashes as objects in use
  543 by the outer call can get freed by the inner call and then reused later.
  544 One particular situation where this happens is when a modal dialogue
  545 gets posted by a Tk Application.  To address this, the NSApp object
  546 also implements a semaphore to prevent draining the autorelease pool
  547 in nested calls to CheckProc.
  548 
  549 One additional minor caveat for developers is that there are several
  550 steps of the Tk initialization which precede the call to TkpInit.
  551 Notably, the font package is initialized first.  Since there is no
  552 NSAutoreleasePool in scope prior to calling TkpInit, the functions
  553 called in these preliminary stages need to create and drain their own
  554 NSAutoreleasePools whenever they call methods of Appkit objects
  555 (e.g. NSFont).
  556 
  557 5.3 Clipping regions and "ghost windows"
  558 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  559 
  560 Another unusual aspect of the macOS port is its use of clipping
  561 regions.  It was part of Daniel Steffen's original design that the
  562 TkWindowPrivate struct maintains three HIShapeRef regions, named
  563 visRgn, aboveVisRgn and drawRgn.  These regions are used as clipping
  564 masks whenever drawing into an NSView.  The visRgn is the bounding box
  565 of the window with a rectangle removed for each subwindow and for each
  566 sibling window at a higher stacking level.  The drawRgn is the
  567 intersection of the visRgn with the clipping rectangle of the
  568 window. (Normally, the clipping rectangle is the same as the bounding
  569 rectangle, but drawing can be clipped to a smaller rectangle by
  570 calling TkpClipDrawableToRect.) The aboveVisRgn is the intersection of
  571 the window's bounding rectangle with the bounding rectangle of the
  572 parent window.  Much of the code in tkMacOSXSubwindows.c is devoted to
  573 rebuilding these clipping regions whenever something changes in the
  574 layout of the windows.  This turns out to be a tricky thing to do and
  575 it is extremely prone to errors which can be difficult to trace.
  576 
  577 It is not entirely clear what the original reason for using these
  578 clipping regions was.  But one benefit is that if they are correctly
  579 maintained then it allows windows to be drawn in any order.  You do
  580 not have to draw them in the order of the window hierarchy.  Each
  581 window can draw its entire rectangle through its own mask and never
  582 have to worry about drawing in the wrong place.  It is likely that
  583 the need for using clipping regions arose because, as Apple explicitly
  584 states in the documentation for [NSView subviews],
  585 
  586     "The order of the subviews may be considered as being
  587     back-to-front, but this does not imply invalidation and drawing
  588     behavior."
  589 
  590 In the early versions of the macOS port, buttons were implemented as
  591 subviews of class TkButton.  This probably exacerbated the likelihood
  592 that Tk windows would need to be drawn in arbitrary order.
  593 
  594 The most obvious side effect caused by not maintaining the clipping
  595 regions is the appearance of so-called "ghost windows".  A common
  596 situation where these may arise is when a window containing buttons
  597 is being scrolled.  A user may see two images of the same button on
  598 the screen, one in the pre-scroll location and one in the post-scroll
  599 location.
  600 
  601 To see how these 'ghost windows' can arise, think about what happens if
  602 the clipping regions are not maintained correctly.  A window might
  603 have a rectangle missing from its clipping region because that
  604 rectangle is the bounding rectangle for a subwindow, say a button.
  605 The parent should not draw in the missing rectangle since doing so
  606 would trash the button.  The button is responsible for drawing
  607 there. Now imagine that the button gets moved, say by a scroll, but
  608 the missing rectangle in the parent's clipping region does not get
  609 moved correctly, or it gets moved later on, after the parent has
  610 redrawn itself.  The parent would still not be allowed to draw in the
  611 old rectangle, so the user would continue to see the image of the
  612 button in its old location, as well as another image in the new
  613 location.  This is a prototypical example of a "ghost window".
  614 Anytime you see a "ghost window", you should suspect problems with the
  615 updates to the clipping region visRgn.  It is natural to look for
  616 timing issues, race conditions, or other "event loop problems".  But
  617 in fact, the whole design of the code is to make those timing issues
  618 irrelevant.  As long as the clipping regions are correctly maintained
  619 the timing does not matter.  And if they are not correctly maintained
  620 then you will see "ghost windows".
  621 
  622 It is worth including a detailed description of one specific place
  623 where the failure to correctly maintain clipping regions caused "ghost
  624 window" artifacts that plagued the macOS port for years.  These
  625 occurred when scrolling a Text widget which contained embedded
  626 subwindows.  It involved some specific differences between the
  627 low-level behavior of Apple's window manager versus those of the other
  628 platforms, and the fix ultimately required changes in the generic Tk
  629 implementation (documented in the comments in the DisplayText
  630 function).
  631 
  632 The Text widget attempts to improve perfomance when scrolling by
  633 minimizing the number of text lines which need to be redisplayed.  It
  634 does this by calling the platform-specific TkScrollWindow function
  635 which uses a low-level routine to map one rectangle of the window to
  636 another.  The TkScrollWindow function returns a damage region which is
  637 then used by the Text widget's DisplayText function to determine which
  638 text lines need to be redrawn.  On the unix and win platforms, this
  639 damage region includes bounding rectangles for all embedded windows
  640 inside the Text widget.  The way that this works is system dependent.
  641 On unix, the low level scrolling is done by XCopyRegion, which
  642 generates a GraphicsExpose event for each embedded window.  These
  643 GraphicsExposed events are processsed within TkScrollWindow, using a
  644 special handler which adds the bounding rectangle of each subwindow to
  645 the damage region.  On the win platform the damage region is built by
  646 the low level function ScrollWindowEx, and it also includes bounding
  647 rectangles for all embedded windows.  This is possible because on X11
  648 and Windows every Tk widget is also known to the window manager as a
  649 window.  The situation is different on macOS.  The underlying object
  650 for a top level window on macOS is the NSView.  However, Apple
  651 explicitly warns in its documentation that performance degradation
  652 occurs when an NSView has more than about 100 subviews.  A Text widget
  653 with thousands of lines of text could easily contain more than 100
  654 embedded windows.  In fact, while the original Cocoa port of Tk did
  655 use the NSButton object, which is derived from NSView, as the basis
  656 for its Tk Buttons, that was changed in order to improve performance.
  657 Moreover, the low level routine used for scrolling on macOS, namely
  658 [NSView scrollrect:by], does not provide any damage information.  So
  659 TkScrollWindow needs to work differently on macOS.  Since it would be
  660 inefficient to iterate through all embedded windows in a Text widget,
  661 looking for those which meet the scrolling area, the damage region
  662 constructed by TkScrollWindow contains only the difference between the
  663 source and destination rectangles for the scrolling.  The embedded
  664 windows are redrawn within the DisplayText function by some
  665 conditional code which is only used for macOS.
  666 
  667 6.0 Virtual events on 10.14
  668 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  669 
  670 10.14 supports system appearance changes, and has added a "Dark Mode"
  671 that casts all window frames and menus as black. Tk 8.6.9 has added two
  672 virtual events, <<LightAqua>> and <<DarkAqua>>, to allow you to update
  673 your Tk app's appearance when the system appearance changes. Just bind
  674 your appearance-updating code to these virtual events and you will see
  675 it triggered when the system appearance toggles between dark and light.
  676 
  677 7.0 Mac Services
  678 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  679 
  680 With 8.6.10, Tk supports the Mac's NSServices API, documented at
  681 https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/SysServices/introduction.html#//apple_ref/doc/uid/10000101-SW1
  682 and in TIP 536 and Tk's man page. Tk presents a simple,
  683 straightforward API to implement the Services functionality.
  684 
  685 The Tk implementation of the NSServices API is intended for standalone
  686 applications, such as one wrapped by the standalone version of Wish
  687 and re-named into a different application.  In particular such an
  688 application would specify its own unique CFBundleIdentifier in its
  689 Info.plist file.  During development, however, if Wish itself is being
  690 used as the receiver, it may be necessary to take some care to ensure
  691 that the correct version of Wish.app is available as a receiver of
  692 NSServices data.
  693 
  694 When one macOS app uses NSServices to send data to another app that is
  695 not running, LaunchServices will launch the receiver.  LaunchServices
  696 assumes that the CFBundleIdentifier uniquely identifies an app among
  697 all of the apps installed on a system.  But this may not be the case
  698 for Wish.app if, for example, you have compiled Tk from source at some
  699 time in the past.  In that case the Tk build directory will contain
  700 its own copy of Wish.app that will be visible to LaunchServices.  It
  701 may be necessary when testing your app to take some steps to ensure
  702 that LaunchServices is launching the correct Wish.app.  Instructions
  703 for doing this are provided below.
  704 
  705 The command line tool which manages the LaunchServices database has
  706 an amazingly unwieldy path name.  So, first, run this command:
  707 
  708 alias lsregister='/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister'
  709 
  710 Then you can reset the LaunchServices database like this:
  711 
  712 $ lsregister -kill
  713 $ lsregister -seed
  714 
  715 To find out which versions of Wish.app have been located by
  716 LaunchServices, run:
  717 
  718 $ lsregister -dump | grep path | grep Wish
  719 
  720 If more than one version of Wish is showing up in this list, eliminate
  721 all of the unintended targets by running
  722 
  723 lsregister -u /path/to/bad/Wish.app
  724 
  725 Continue this until only the correct version of Wish shows up in the
  726 list.