summaryrefslogtreecommitdiffstats
path: root/macosx
diff options
context:
space:
mode:
Diffstat (limited to 'macosx')
-rw-r--r--macosx/GNUmakefile4
-rw-r--r--macosx/README61
-rw-r--r--macosx/Tk-Common.xcconfig2
-rw-r--r--macosx/Tk-Info.plist.in4
-rw-r--r--macosx/Tk.xcode/project.pbxproj36
-rw-r--r--macosx/Tk.xcodeproj/project.pbxproj36
-rw-r--r--macosx/Wish-Info.plist.in12
-rw-r--r--macosx/configure.ac2
-rw-r--r--macosx/tkMacOSXButton.c34
-rw-r--r--macosx/tkMacOSXCursor.c5
-rw-r--r--macosx/tkMacOSXDefault.h2
-rw-r--r--macosx/tkMacOSXDialog.c214
-rw-r--r--macosx/tkMacOSXDraw.c188
-rw-r--r--macosx/tkMacOSXEmbed.c2
-rw-r--r--macosx/tkMacOSXEvent.c33
-rw-r--r--macosx/tkMacOSXFont.c32
-rw-r--r--macosx/tkMacOSXHLEvents.c741
-rw-r--r--macosx/tkMacOSXInit.c66
-rw-r--r--macosx/tkMacOSXInt.h2
-rw-r--r--macosx/tkMacOSXKeyEvent.c64
-rw-r--r--macosx/tkMacOSXMenu.c52
-rw-r--r--macosx/tkMacOSXMouseEvent.c121
-rw-r--r--macosx/tkMacOSXNotify.c160
-rw-r--r--macosx/tkMacOSXPrivate.h65
-rw-r--r--macosx/tkMacOSXScrlbr.c86
-rw-r--r--macosx/tkMacOSXSubwindows.c91
-rw-r--r--macosx/tkMacOSXWindowEvent.c156
-rw-r--r--macosx/tkMacOSXWm.c222
-rw-r--r--macosx/tkMacOSXXStubs.c99
-rw-r--r--macosx/ttkMacOSXTheme.c2
30 files changed, 1504 insertions, 1090 deletions
diff --git a/macosx/GNUmakefile b/macosx/GNUmakefile
index 02240ed..57d0206 100644
--- a/macosx/GNUmakefile
+++ b/macosx/GNUmakefile
@@ -35,7 +35,7 @@ MANDIR ?= ${PREFIX}/man
TCL_BUILD_DIR ?= ${BUILD_DIR}/tcl/${BUILD_STYLE}
# location of installed tcl, only used if tcl in TCL_BUILD_DIR can't be found
TCL_FRAMEWORK_DIR ?= /Library/Frameworks
-TCLSH_DIR ?= ${PREFIX}
+TCLSH_DIR ?= ${PREFIX}/bin
# set to non-empty value to install manpages in addition to html help:
INSTALL_MANPAGES ?=
@@ -102,7 +102,7 @@ PROJECT := tk
PRODUCT_NAME := Tk
UNIX_DIR := ${CURDIR}/../unix
-VERSION := $(shell awk -F= '/^TK_VERSION/ {print $$2; nextfile}' ${UNIX_DIR}/configure.in)
+VERSION := $(shell awk -F= '/^TK_VERSION/ {print $$2; nextfile}' ${UNIX_DIR}/configure.ac)
TCL_VERSION := ${VERSION}
wish := wish
WISH = wish${VERSION}
diff --git a/macosx/README b/macosx/README
index 69be037..b27f9ff 100644
--- a/macosx/README
+++ b/macosx/README
@@ -388,3 +388,64 @@ make overrides to the tk/macosx GNUmakefile, e.g.
sudo make -C tk${ver}/macosx install \
TCL_FRAMEWORK_DIR=$HOME/Library/Frameworks TCLSH_DIR=$HOME/usr/bin
The Makefile variables TCL_FRAMEWORK_DIR and TCLSH_DIR were added with Tk 8.4.3.
+
+4. About the event loop in Tk for Mac OSX
+-----------------------------------------
+
+The main program in a typical OSX application looks like this (see *)
+
+ void NSApplicationMain(int argc, char *argv[]) {
+ [NSApplication sharedApplication];
+ [NSBundle loadNibNamed:@"myMain" owner:NSApp];
+ [NSApp run];
+ }
+
+The run method implements the event loop for the application. There
+are three key steps in the run method. First it calls
+[NSApp finishLaunching], which creates the bouncing application icon
+and does other mysterious things. Second it creates an
+NSAutoreleasePool. Third, it starts an event loop which drains the
+NSAutoreleasePool every time the queue is empty, and replaces the
+drained pool with a new one. This third step is essential to
+preventing memory leaks, since the internal methods of Appkit objects
+all assume that an autorelease pool is in scope and will be drained
+when the event processing cycle ends.
+
+Mac OSX Tk does not call the [NSApp run] method at all. Instead it
+uses the event loop built in to Tk. So we must take care to replicate
+the important features of the method ourselves. Here is how this
+works in outline.
+
+We add a private NSAUtoreleasePool* property to our subclass of
+NSApplication. (The subclass is called TKApplication but can be
+referenced with the global variable NSApp). The TkpInit
+function calls [NSApp _setup] which initializes this property by
+creating an NSAutoreleasePool. A bit later on, TkpInit calls
+[NSAPP _setupEventLoop] which in turn calls the
+[NSApp finishLaunching] method.
+
+Each time that Tcl processes an event in its queue, it calls a
+platform specific function which, in the case of Mac OSX, is named
+TkMacOSXEventsCheckProc. In the unix implementations of Tk, including
+the Mac OSX version, this function collects events from an "event
+source", and transfers them to the Tcl event queue. In Mac OSX the
+event source is the NSApplication event queue. Each NSEvent is
+converted to a Tcl event which is added to the Tcl event queue. The
+NSEvent is also passed to [NSApp sendevent], which sends the event on
+to the application's NSWindows, which send it to their NSViews, etc.
+Since the CheckProc function gets called for every Tk event, it is an
+appropriate place to drain the main NSAutoreleasePool and replace it
+with a new pool. This is done by calling the method
+[NSApp _resetAutoreleasePool], where _resetAutoreleasePool is a method
+which we define for the subclass TKApplication.
+
+One minor caveat is that there are several steps of the Tk
+initialization which precede the call to TkpInit. Notably, the font
+package is initialized first. Since there is no NSAUtoreleasePool in
+scope prior to calling TkpInit, the functions called in these
+preliminary stages need to create and drain their own
+NSAutoreleasePools whenever they call methods of Appkit objects
+(e.g. NSFont).
+
+* https://developer.apple.com/library/mac/documentation/Cocoa/\
+Reference/ApplicationKit/Classes/NSApplication_Class
diff --git a/macosx/Tk-Common.xcconfig b/macosx/Tk-Common.xcconfig
index 0d6e474..d75674a 100644
--- a/macosx/Tk-Common.xcconfig
+++ b/macosx/Tk-Common.xcconfig
@@ -43,4 +43,4 @@ TCL_PACKAGE_PATH = "$(LIBDIR)"
TCL_DEFS = HAVE_TCL_CONFIG_H
TK_LIBRARY = $(LIBDIR)/tk$(VERSION)
TK_DEFS = HAVE_TK_CONFIG_H TCL_NO_DEPRECATED
-VERSION = 8.6
+VERSION = 8.7
diff --git a/macosx/Tk-Info.plist.in b/macosx/Tk-Info.plist.in
index 50b9d24..7b0c305 100644
--- a/macosx/Tk-Info.plist.in
+++ b/macosx/Tk-Info.plist.in
@@ -17,6 +17,10 @@
<string>Tk @TK_WINDOWINGSYSTEM@ @TK_VERSION@@TK_PATCH_LEVEL@,
Copyright © 1989-@TK_YEAR@ Tcl Core Team,
Copyright © 2002-@TK_YEAR@ Daniel A. Steffen,
+ Copyright © 1989-@TK_YEAR@ Contributors,
+ Copyright © 2011-@TK_YEAR@ Kevin Walzer/WordTech
+ Communications LLC,
+ Copyright © 2014-@TK_YEAR@ Marc Culler,
Copyright © 2001-2009 Apple Inc.,
Copyright © 2001-2002 Jim Ingham &amp; Ian Reid</string>
<key>CFBundleIdentifier</key>
diff --git a/macosx/Tk.xcode/project.pbxproj b/macosx/Tk.xcode/project.pbxproj
index 70c2472..eee37a2 100644
--- a/macosx/Tk.xcode/project.pbxproj
+++ b/macosx/Tk.xcode/project.pbxproj
@@ -1172,7 +1172,7 @@
F966BC6A08F27A3D005CB29B /* xmfbox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = xmfbox.test; sourceTree = "<group>"; };
F966BC6C08F27A3D005CB29B /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
F966BC6D08F27A3D005CB29B /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
- F966BC6E08F27A3D005CB29B /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = "<group>"; };
+ F966BC6E08F27A3D005CB29B /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = "<group>"; };
F966BC6F08F27A3D005CB29B /* install-sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "install-sh"; sourceTree = "<group>"; };
F966BC7008F27A3D005CB29B /* installManPage */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = installManPage; sourceTree = "<group>"; };
F966BC7108F27A3D005CB29B /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
@@ -1211,7 +1211,7 @@
F966BC9408F27A3D005CB29B /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
F966BC9508F27A3D005CB29B /* buildall.vc.bat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = buildall.vc.bat; sourceTree = "<group>"; };
F966BC9608F27A3E005CB29B /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
- F966BC9708F27A3E005CB29B /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = "<group>"; };
+ F966BC9708F27A3E005CB29B /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = "<group>"; };
F966BC9808F27A3E005CB29B /* makefile.bc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.bc; sourceTree = "<group>"; };
F966BC9908F27A3E005CB29B /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
F966BC9A08F27A3E005CB29B /* makefile.vc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.vc; sourceTree = "<group>"; };
@@ -1916,7 +1916,7 @@
F96D43CF08F272B7004A47F5 /* winTime.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winTime.test; sourceTree = "<group>"; };
F96D43D108F272B8004A47F5 /* checkLibraryDoc.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = checkLibraryDoc.tcl; sourceTree = "<group>"; };
F96D43D208F272B8004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
- F96D43D308F272B8004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = "<group>"; };
+ F96D43D308F272B8004A47F5 /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = "<group>"; };
F96D442208F272B8004A47F5 /* eolFix.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = eolFix.tcl; sourceTree = "<group>"; };
F96D442408F272B8004A47F5 /* fix_tommath_h.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fix_tommath_h.tcl; sourceTree = "<group>"; };
F96D442508F272B8004A47F5 /* genStubs.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = genStubs.tcl; sourceTree = "<group>"; };
@@ -1941,7 +1941,7 @@
F96D443C08F272B9004A47F5 /* uniParse.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uniParse.tcl; sourceTree = "<group>"; };
F96D444008F272B9004A47F5 /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
F96D444108F272B9004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
- F96D444208F272B9004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = "<group>"; };
+ F96D444208F272B9004A47F5 /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = "<group>"; };
F96D444408F272B9004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
F96D444508F272B9004A47F5 /* pkga.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkga.c; sourceTree = "<group>"; };
F96D444608F272B9004A47F5 /* pkgb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgb.c; sourceTree = "<group>"; };
@@ -1986,7 +1986,7 @@
F96D447208F272BA004A47F5 /* cat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cat.c; sourceTree = "<group>"; };
F96D447308F272BA004A47F5 /* coffbase.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = coffbase.txt; sourceTree = "<group>"; };
F96D447408F272BA004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
- F96D447508F272BA004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = "<group>"; };
+ F96D447508F272BA004A47F5 /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = "<group>"; };
F96D447608F272BA004A47F5 /* makefile.bc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.bc; sourceTree = "<group>"; };
F96D447708F272BA004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
F96D447808F272BA004A47F5 /* makefile.vc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.vc; sourceTree = "<group>"; };
@@ -2743,7 +2743,7 @@
children = (
F966BC6C08F27A3D005CB29B /* aclocal.m4 */,
F966BC6D08F27A3D005CB29B /* configure */,
- F966BC6E08F27A3D005CB29B /* configure.in */,
+ F966BC6E08F27A3D005CB29B /* configure.ac */,
F966BC6F08F27A3D005CB29B /* install-sh */,
F966BC7008F27A3D005CB29B /* installManPage */,
F966BC7108F27A3D005CB29B /* Makefile.in */,
@@ -2790,7 +2790,7 @@
F966BC9408F27A3D005CB29B /* aclocal.m4 */,
F966BC9508F27A3D005CB29B /* buildall.vc.bat */,
F966BC9608F27A3E005CB29B /* configure */,
- F966BC9708F27A3E005CB29B /* configure.in */,
+ F966BC9708F27A3E005CB29B /* configure.ac */,
F966BC9808F27A3E005CB29B /* makefile.bc */,
F966BC9908F27A3E005CB29B /* Makefile.in */,
F966BC9A08F27A3E005CB29B /* makefile.vc */,
@@ -3726,7 +3726,7 @@
children = (
F96D43D108F272B8004A47F5 /* checkLibraryDoc.tcl */,
F96D43D208F272B8004A47F5 /* configure */,
- F96D43D308F272B8004A47F5 /* configure.in */,
+ F96D43D308F272B8004A47F5 /* configure.ac */,
F96D442208F272B8004A47F5 /* eolFix.tcl */,
F96D442408F272B8004A47F5 /* fix_tommath_h.tcl */,
F96D442508F272B8004A47F5 /* genStubs.tcl */,
@@ -3759,7 +3759,7 @@
children = (
F96D444008F272B9004A47F5 /* aclocal.m4 */,
F96D444108F272B9004A47F5 /* configure */,
- F96D444208F272B9004A47F5 /* configure.in */,
+ F96D444208F272B9004A47F5 /* configure.ac */,
F96D444308F272B9004A47F5 /* dltest */,
F96D444D08F272B9004A47F5 /* install-sh */,
F96D444E08F272B9004A47F5 /* installManPage */,
@@ -3821,7 +3821,7 @@
F96D447208F272BA004A47F5 /* cat.c */,
F96D447308F272BA004A47F5 /* coffbase.txt */,
F96D447408F272BA004A47F5 /* configure */,
- F96D447508F272BA004A47F5 /* configure.in */,
+ F96D447508F272BA004A47F5 /* configure.ac */,
F96D447608F272BA004A47F5 /* makefile.bc */,
F96D447708F272BA004A47F5 /* Makefile.in */,
F96D447808F272BA004A47F5 /* makefile.vc */,
@@ -3974,7 +3974,7 @@
);
inputPaths = (
"$(TCL_SRCROOT)/macosx/configure.ac",
- "$(TCL_SRCROOT)/unix/configure.in",
+ "$(TCL_SRCROOT)/unix/configure.ac",
"$(TCL_SRCROOT)/unix/tcl.m4",
"$(TCL_SRCROOT)/unix/aclocal.m4",
"$(TCL_SRCROOT)/unix/tclConfig.sh.in",
@@ -3987,7 +3987,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/bash;
- shellScript = "## tcl configure shell script phase\n\ncd \"${TCL_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.in -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tcl/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tcl && cd tcl &&\nif [ \"${TCL_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tcl\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n \"${TCL_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi\n";
+ shellScript = "## tcl configure shell script phase\n\ncd \"${TCL_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.ac -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tcl/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tcl && cd tcl &&\nif [ \"${TCL_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tcl\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n \"${TCL_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi\n";
showEnvVarsInLog = 0;
};
F9A5C5F608F651AB008AE941 /* Configure Tk */ = {
@@ -3997,7 +3997,7 @@
);
inputPaths = (
"$(TK_SRCROOT)/macosx/configure.ac",
- "$(TK_SRCROOT)/unix/configure.in",
+ "$(TK_SRCROOT)/unix/configure.ac",
"$(TK_SRCROOT)/unix/tcl.m4",
"$(TK_SRCROOT)/unix/aclocal.m4",
"$(TK_SRCROOT)/unix/tkConfig.sh.in",
@@ -4008,7 +4008,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/bash;
- shellScript = "## tk configure shell script phase\n\ncd \"${TK_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.in -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tk/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tk && cd tk &&\nif [ \"${TK_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tk\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n \"${TK_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared --enable-aqua --with-tcl=../tcl CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi\n";
+ shellScript = "## tk configure shell script phase\n\ncd \"${TK_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.ac -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tk/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tk && cd tk &&\nif [ \"${TK_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tk\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n \"${TK_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared --enable-aqua --with-tcl=../tcl CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi\n";
showEnvVarsInLog = 0;
};
F9FD30B40CC1AD070073837D /* Configure Tcl */ = {
@@ -4018,7 +4018,7 @@
);
inputPaths = (
"$(TCL_SRCROOT)/macosx/configure.ac",
- "$(TCL_SRCROOT)/unix/configure.in",
+ "$(TCL_SRCROOT)/unix/configure.ac",
"$(TCL_SRCROOT)/unix/tcl.m4",
"$(TCL_SRCROOT)/unix/aclocal.m4",
"$(TCL_SRCROOT)/unix/tclConfig.sh.in",
@@ -4031,7 +4031,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/bash;
- shellScript = "## tcl configure shell script phase\n\ncd \"${TCL_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.in -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tcl/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tcl && cd tcl &&\nif [ \"${TCL_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tcl\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n \"${TCL_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi\n";
+ shellScript = "## tcl configure shell script phase\n\ncd \"${TCL_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.ac -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tcl/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tcl && cd tcl &&\nif [ \"${TCL_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tcl\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n \"${TCL_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi\n";
showEnvVarsInLog = 0;
};
F9FD30B50CC1AD070073837D /* Configure Tk */ = {
@@ -4041,7 +4041,7 @@
);
inputPaths = (
"$(TK_SRCROOT)/macosx/configure.ac",
- "$(TK_SRCROOT)/unix/configure.in",
+ "$(TK_SRCROOT)/unix/configure.ac",
"$(TK_SRCROOT)/unix/tcl.m4",
"$(TK_SRCROOT)/unix/aclocal.m4",
"$(TK_SRCROOT)/unix/tkConfig.sh.in",
@@ -4052,7 +4052,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/bash;
- shellScript = "## tk configure shell script phase\n\ncd \"${TK_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.in -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tk/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tk && cd tk &&\nif [ \"${TK_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tk\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n PATH=\"${PATH}:/usr/X11R6/bin\" \"${TK_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared --enable-xft --with-tcl=../tcl CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi";
+ shellScript = "## tk configure shell script phase\n\ncd \"${TK_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.ac -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tk/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tk && cd tk &&\nif [ \"${TK_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tk\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n PATH=\"${PATH}:/usr/X11R6/bin\" \"${TK_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared --enable-xft --with-tcl=../tcl CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
diff --git a/macosx/Tk.xcodeproj/project.pbxproj b/macosx/Tk.xcodeproj/project.pbxproj
index dcfe9fb..2f7edba 100644
--- a/macosx/Tk.xcodeproj/project.pbxproj
+++ b/macosx/Tk.xcodeproj/project.pbxproj
@@ -1172,7 +1172,7 @@
F966BC6A08F27A3D005CB29B /* xmfbox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = xmfbox.test; sourceTree = "<group>"; };
F966BC6C08F27A3D005CB29B /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
F966BC6D08F27A3D005CB29B /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
- F966BC6E08F27A3D005CB29B /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = "<group>"; };
+ F966BC6E08F27A3D005CB29B /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = "<group>"; };
F966BC6F08F27A3D005CB29B /* install-sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "install-sh"; sourceTree = "<group>"; };
F966BC7008F27A3D005CB29B /* installManPage */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = installManPage; sourceTree = "<group>"; };
F966BC7108F27A3D005CB29B /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
@@ -1211,7 +1211,7 @@
F966BC9408F27A3D005CB29B /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
F966BC9508F27A3D005CB29B /* buildall.vc.bat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = buildall.vc.bat; sourceTree = "<group>"; };
F966BC9608F27A3E005CB29B /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
- F966BC9708F27A3E005CB29B /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = "<group>"; };
+ F966BC9708F27A3E005CB29B /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = "<group>"; };
F966BC9808F27A3E005CB29B /* makefile.bc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.bc; sourceTree = "<group>"; };
F966BC9908F27A3E005CB29B /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
F966BC9A08F27A3E005CB29B /* makefile.vc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.vc; sourceTree = "<group>"; };
@@ -1916,7 +1916,7 @@
F96D43CF08F272B7004A47F5 /* winTime.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winTime.test; sourceTree = "<group>"; };
F96D43D108F272B8004A47F5 /* checkLibraryDoc.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = checkLibraryDoc.tcl; sourceTree = "<group>"; };
F96D43D208F272B8004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
- F96D43D308F272B8004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = "<group>"; };
+ F96D43D308F272B8004A47F5 /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = "<group>"; };
F96D442208F272B8004A47F5 /* eolFix.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = eolFix.tcl; sourceTree = "<group>"; };
F96D442408F272B8004A47F5 /* fix_tommath_h.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fix_tommath_h.tcl; sourceTree = "<group>"; };
F96D442508F272B8004A47F5 /* genStubs.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = genStubs.tcl; sourceTree = "<group>"; };
@@ -1941,7 +1941,7 @@
F96D443C08F272B9004A47F5 /* uniParse.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uniParse.tcl; sourceTree = "<group>"; };
F96D444008F272B9004A47F5 /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
F96D444108F272B9004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
- F96D444208F272B9004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = "<group>"; };
+ F96D444208F272B9004A47F5 /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = "<group>"; };
F96D444408F272B9004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
F96D444508F272B9004A47F5 /* pkga.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkga.c; sourceTree = "<group>"; };
F96D444608F272B9004A47F5 /* pkgb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgb.c; sourceTree = "<group>"; };
@@ -1986,7 +1986,7 @@
F96D447208F272BA004A47F5 /* cat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cat.c; sourceTree = "<group>"; };
F96D447308F272BA004A47F5 /* coffbase.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = coffbase.txt; sourceTree = "<group>"; };
F96D447408F272BA004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
- F96D447508F272BA004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = "<group>"; };
+ F96D447508F272BA004A47F5 /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = "<group>"; };
F96D447608F272BA004A47F5 /* makefile.bc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.bc; sourceTree = "<group>"; };
F96D447708F272BA004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
F96D447808F272BA004A47F5 /* makefile.vc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.vc; sourceTree = "<group>"; };
@@ -2743,7 +2743,7 @@
children = (
F966BC6C08F27A3D005CB29B /* aclocal.m4 */,
F966BC6D08F27A3D005CB29B /* configure */,
- F966BC6E08F27A3D005CB29B /* configure.in */,
+ F966BC6E08F27A3D005CB29B /* configure.ac */,
F966BC6F08F27A3D005CB29B /* install-sh */,
F966BC7008F27A3D005CB29B /* installManPage */,
F966BC7108F27A3D005CB29B /* Makefile.in */,
@@ -2790,7 +2790,7 @@
F966BC9408F27A3D005CB29B /* aclocal.m4 */,
F966BC9508F27A3D005CB29B /* buildall.vc.bat */,
F966BC9608F27A3E005CB29B /* configure */,
- F966BC9708F27A3E005CB29B /* configure.in */,
+ F966BC9708F27A3E005CB29B /* configure.ac */,
F966BC9808F27A3E005CB29B /* makefile.bc */,
F966BC9908F27A3E005CB29B /* Makefile.in */,
F966BC9A08F27A3E005CB29B /* makefile.vc */,
@@ -3726,7 +3726,7 @@
children = (
F96D43D108F272B8004A47F5 /* checkLibraryDoc.tcl */,
F96D43D208F272B8004A47F5 /* configure */,
- F96D43D308F272B8004A47F5 /* configure.in */,
+ F96D43D308F272B8004A47F5 /* configure.ac */,
F96D442208F272B8004A47F5 /* eolFix.tcl */,
F96D442408F272B8004A47F5 /* fix_tommath_h.tcl */,
F96D442508F272B8004A47F5 /* genStubs.tcl */,
@@ -3759,7 +3759,7 @@
children = (
F96D444008F272B9004A47F5 /* aclocal.m4 */,
F96D444108F272B9004A47F5 /* configure */,
- F96D444208F272B9004A47F5 /* configure.in */,
+ F96D444208F272B9004A47F5 /* configure.ac */,
F96D444308F272B9004A47F5 /* dltest */,
F96D444D08F272B9004A47F5 /* install-sh */,
F96D444E08F272B9004A47F5 /* installManPage */,
@@ -3821,7 +3821,7 @@
F96D447208F272BA004A47F5 /* cat.c */,
F96D447308F272BA004A47F5 /* coffbase.txt */,
F96D447408F272BA004A47F5 /* configure */,
- F96D447508F272BA004A47F5 /* configure.in */,
+ F96D447508F272BA004A47F5 /* configure.ac */,
F96D447608F272BA004A47F5 /* makefile.bc */,
F96D447708F272BA004A47F5 /* Makefile.in */,
F96D447808F272BA004A47F5 /* makefile.vc */,
@@ -3977,7 +3977,7 @@
);
inputPaths = (
"$(TCL_SRCROOT)/macosx/configure.ac",
- "$(TCL_SRCROOT)/unix/configure.in",
+ "$(TCL_SRCROOT)/unix/configure.ac",
"$(TCL_SRCROOT)/unix/tcl.m4",
"$(TCL_SRCROOT)/unix/aclocal.m4",
"$(TCL_SRCROOT)/unix/tclConfig.sh.in",
@@ -3990,7 +3990,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/bash;
- shellScript = "## tcl configure shell script phase\n\ncd \"${TCL_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.in -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tcl/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tcl && cd tcl &&\nif [ \"${TCL_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tcl\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n \"${TCL_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi\n";
+ shellScript = "## tcl configure shell script phase\n\ncd \"${TCL_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.ac -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tcl/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tcl && cd tcl &&\nif [ \"${TCL_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tcl\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n \"${TCL_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi\n";
showEnvVarsInLog = 0;
};
F9A5C5F608F651AB008AE941 /* Configure Tk */ = {
@@ -4000,7 +4000,7 @@
);
inputPaths = (
"$(TK_SRCROOT)/macosx/configure.ac",
- "$(TK_SRCROOT)/unix/configure.in",
+ "$(TK_SRCROOT)/unix/configure.ac",
"$(TK_SRCROOT)/unix/tcl.m4",
"$(TK_SRCROOT)/unix/aclocal.m4",
"$(TK_SRCROOT)/unix/tkConfig.sh.in",
@@ -4011,7 +4011,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/bash;
- shellScript = "## tk configure shell script phase\n\ncd \"${TK_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.in -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tk/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tk && cd tk &&\nif [ \"${TK_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tk\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n \"${TK_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared --enable-aqua --with-tcl=../tcl CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi\n";
+ shellScript = "## tk configure shell script phase\n\ncd \"${TK_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.ac -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tk/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tk && cd tk &&\nif [ \"${TK_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tk\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n \"${TK_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared --enable-aqua --with-tcl=../tcl CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi\n";
showEnvVarsInLog = 0;
};
F9FD30B40CC1AD070073837D /* Configure Tcl */ = {
@@ -4021,7 +4021,7 @@
);
inputPaths = (
"$(TCL_SRCROOT)/macosx/configure.ac",
- "$(TCL_SRCROOT)/unix/configure.in",
+ "$(TCL_SRCROOT)/unix/configure.ac",
"$(TCL_SRCROOT)/unix/tcl.m4",
"$(TCL_SRCROOT)/unix/aclocal.m4",
"$(TCL_SRCROOT)/unix/tclConfig.sh.in",
@@ -4034,7 +4034,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/bash;
- shellScript = "## tcl configure shell script phase\n\ncd \"${TCL_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.in -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tcl/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tcl && cd tcl &&\nif [ \"${TCL_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tcl\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n \"${TCL_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi\n";
+ shellScript = "## tcl configure shell script phase\n\ncd \"${TCL_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.ac -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tcl/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tcl && cd tcl &&\nif [ \"${TCL_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tcl\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n \"${TCL_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi\n";
showEnvVarsInLog = 0;
};
F9FD30B50CC1AD070073837D /* Configure Tk */ = {
@@ -4044,7 +4044,7 @@
);
inputPaths = (
"$(TK_SRCROOT)/macosx/configure.ac",
- "$(TK_SRCROOT)/unix/configure.in",
+ "$(TK_SRCROOT)/unix/configure.ac",
"$(TK_SRCROOT)/unix/tcl.m4",
"$(TK_SRCROOT)/unix/aclocal.m4",
"$(TK_SRCROOT)/unix/tkConfig.sh.in",
@@ -4055,7 +4055,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/bash;
- shellScript = "## tk configure shell script phase\n\ncd \"${TK_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.in -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tk/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tk && cd tk &&\nif [ \"${TK_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tk\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n PATH=\"${PATH}:/usr/X11R6/bin\" \"${TK_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared --enable-xft --with-tcl=../tcl CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi";
+ shellScript = "## tk configure shell script phase\n\ncd \"${TK_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.ac -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tk/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tk && cd tk &&\nif [ \"${TK_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tk\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n PATH=\"${PATH}:/usr/X11R6/bin\" \"${TK_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared --enable-xft --with-tcl=../tcl CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
diff --git a/macosx/Wish-Info.plist.in b/macosx/Wish-Info.plist.in
index 78170f1..db75cf2 100644
--- a/macosx/Wish-Info.plist.in
+++ b/macosx/Wish-Info.plist.in
@@ -40,10 +40,14 @@
<string>Wish</string>
<key>CFBundleGetInfoString</key>
<string>Wish Shell @TK_VERSION@@TK_PATCH_LEVEL@,
-Copyright © 1989-@TK_YEAR@ Tcl Core Team,
-Copyright © 2002-@TK_YEAR@ Daniel A. Steffen,
-Copyright © 2001-2009 Apple Inc.,
-Copyright © 2001-2002 Jim Ingham &amp; Ian Reid</string>
+ Copyright © 1989-@TK_YEAR@ Tcl Core Team,
+ Copyright © 1989-@TK_YEAR@ Contributors,
+ Copyright © 2011-@TK_YEAR@ Kevin Walzer/WordTech
+ Communications LLC,
+ Copyright © 2014-@TK_YEAR@ Marc Culler,
+ Copyright © 2002-@TK_YEAR@ Daniel A. Steffen,
+ Copyright © 2001-2009 Apple Inc.,
+ Copyright © 2001-2002 Jim Ingham &amp; Ian Reid</string>
<key>CFBundleIconFile</key>
<string>Wish.icns</string>
<key>CFBundleIdentifier</key>
diff --git a/macosx/configure.ac b/macosx/configure.ac
index 69573c5..41f39d6 100644
--- a/macosx/configure.ac
+++ b/macosx/configure.ac
@@ -8,4 +8,4 @@ dnl include the configure sources from ../unix:
m4_include(../unix/aclocal.m4)
m4_define(SC_USE_CONFIG_HEADERS)
-m4_include(../unix/configure.in)
+m4_include(../unix/configure.ac)
diff --git a/macosx/tkMacOSXButton.c b/macosx/tkMacOSXButton.c
index 5c5aa9e..f4fbc48 100644
--- a/macosx/tkMacOSXButton.c
+++ b/macosx/tkMacOSXButton.c
@@ -30,10 +30,10 @@
* Default insets for controls
*/
-#define DEF_INSET_LEFT 2
-#define DEF_INSET_RIGHT 2
-#define DEF_INSET_TOP 2
-#define DEF_INSET_BOTTOM 4
+#define DEF_INSET_LEFT 12
+#define DEF_INSET_RIGHT 12
+#define DEF_INSET_TOP 1
+#define DEF_INSET_BOTTOM 1
/*
* Some defines used to control what type of control is drawn.
@@ -289,10 +289,10 @@ TkpComputeButtonGeometry(
if ( butPtr->indicatorOn ) {
switch (butPtr->type) {
case TYPE_RADIO_BUTTON:
- GetThemeMetric(kThemeMetricRadioButtonWidth, &butPtr->indicatorDiameter);
+ GetThemeMetric(kThemeMetricRadioButtonWidth, (SInt32 *)&butPtr->indicatorDiameter);
break;
case TYPE_CHECK_BUTTON:
- GetThemeMetric(kThemeMetricCheckBoxWidth, &butPtr->indicatorDiameter);
+ GetThemeMetric(kThemeMetricCheckBoxWidth, (SInt32 *)&butPtr->indicatorDiameter);
break;
default:
break;
@@ -318,8 +318,9 @@ TkpComputeButtonGeometry(
Tcl_GetString(butPtr->textPtr), -1, butPtr->wrapLength,
butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight);
+ /*Remove extraneous padding around label widgets.*/
txtWidth = butPtr->textWidth;
- txtHeight = butPtr->textHeight;
+ txtHeight = butPtr->textHeight + DEF_INSET_BOTTOM + DEF_INSET_TOP;
charWidth = Tk_TextWidth(butPtr->tkfont, "0", 1);
Tk_GetFontMetrics(butPtr->tkfont, &fm);
haveText = (txtWidth != 0 && txtHeight != 0);
@@ -387,7 +388,7 @@ TkpComputeButtonGeometry(
butPtr->inset = 0;
butPtr->inset += butPtr->highlightWidth;
-
+
if (TkMacOSXComputeButtonDrawParams(butPtr,&drawParams)) {
HIRect tmpRect;
HIRect contBounds;
@@ -519,7 +520,7 @@ DrawButtonImageAndText(
/*
* Image is left or right of text
*/
-
+
if (butPtr->compound == COMPOUND_LEFT) {
textXOffset = width + butPtr->padX;
} else {
@@ -536,7 +537,7 @@ DrawButtonImageAndText(
/*
* Image and text are superimposed
*/
-
+
fullWidth = (width > butPtr->textWidth ? width :
butPtr->textWidth);
fullHeight = (height > butPtr->textHeight ? height :
@@ -593,7 +594,7 @@ DrawButtonImageAndText(
imageXOffset, imageYOffset, 1);
XSetClipOrigin(butPtr->display, dpPtr->gc, 0, 0);
}
-
+
Tk_DrawTextLayout(butPtr->display, pixmap,
dpPtr->gc, butPtr->textLayout,
x + textXOffset, y + textYOffset, 0, -1);
@@ -618,7 +619,7 @@ DrawButtonImageAndText(
imageYOffset += y;
if (butPtr->image != NULL) {
-
+
if ((butPtr->selectImage != NULL) &&
(butPtr->flags & SELECTED)) {
Tk_RedrawImage(butPtr->selectImage, 0, 0, width,
@@ -647,7 +648,7 @@ DrawButtonImageAndText(
butPtr->textHeight, &x, &y);
x += butPtr->indicatorSpace;
Tk_DrawTextLayout(butPtr->display, pixmap, dpPtr->gc, butPtr->textLayout,
- x, y, 0, -1);
+ x, y - DEF_INSET_BOTTOM, 0, -1);
}
/*
@@ -807,9 +808,12 @@ TkMacOSXDrawButton(
hiinfo.animation.time.start = hiinfo.animation.time.current;
}
- HIThemeDrawButton(&cntrRect, &hiinfo, dc.context, kHIThemeOrientationNormal, &contHIRec);
+ HIThemeDrawButton(&cntrRect, &hiinfo, dc.context, kHIThemeOrientationNormal,
+ &contHIRec);
+
TkMacOSXRestoreDrawingContext(&dc);
- ButtonContentDrawCB(&contHIRec, mbPtr->btnkind, &mbPtr->drawinfo, (MacButton *)mbPtr, 32, true);
+ ButtonContentDrawCB(&contHIRec, mbPtr->btnkind, &mbPtr->drawinfo,
+ (MacButton *)mbPtr, 32, true);
} else {
if (!TkMacOSXSetupDrawingContext(pixmap, dpPtr->gc, 1, &dc)) {
diff --git a/macosx/tkMacOSXCursor.c b/macosx/tkMacOSXCursor.c
index 53c2cd2..b6394b7 100644
--- a/macosx/tkMacOSXCursor.c
+++ b/macosx/tkMacOSXCursor.c
@@ -344,7 +344,7 @@ FindCursorByName(
macCursor = [[NSCursor alloc] initWithImage:image hotSpot:hotSpot];
[image release];
}
- macCursorPtr->macCursor = TkMacOSXMakeUncollectable(macCursor);
+ macCursorPtr->macCursor = macCursor;
}
/*
@@ -454,7 +454,8 @@ TkpFreeCursor(
{
TkMacOSXCursor *macCursorPtr = (TkMacOSXCursor *) cursorPtr;
- TkMacOSXMakeCollectableAndRelease(macCursorPtr->macCursor);
+ [macCursorPtr->macCursor release];
+ macCursorPtr->macCursor = NULL;
if (macCursorPtr == gCurrentCursor) {
gCurrentCursor = NULL;
}
diff --git a/macosx/tkMacOSXDefault.h b/macosx/tkMacOSXDefault.h
index e95560f..65762b7 100644
--- a/macosx/tkMacOSXDefault.h
+++ b/macosx/tkMacOSXDefault.h
@@ -259,6 +259,7 @@
#define DEF_LISTBOX_HIGHLIGHT_BG NORMAL_BG
#define DEF_LISTBOX_HIGHLIGHT BLACK
#define DEF_LISTBOX_HIGHLIGHT_WIDTH "0"
+#define DEF_LISTBOX_JUSTIFY "left"
#define DEF_LISTBOX_RELIEF "solid"
#define DEF_LISTBOX_SCROLL_COMMAND ""
#define DEF_LISTBOX_LIST_VARIABLE ""
@@ -409,6 +410,7 @@
#define DEF_PANEDWINDOW_HEIGHT ""
#define DEF_PANEDWINDOW_OPAQUERESIZE "1"
#define DEF_PANEDWINDOW_ORIENT "horizontal"
+#define DEF_PANEDWINDOW_PROXYBORDER "2"
#define DEF_PANEDWINDOW_RELIEF "flat"
#define DEF_PANEDWINDOW_SASHCURSOR ""
#define DEF_PANEDWINDOW_SASHPAD "0"
diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c
index a66939a..80a7a11 100644
--- a/macosx/tkMacOSXDialog.c
+++ b/macosx/tkMacOSXDialog.c
@@ -14,6 +14,17 @@
#include "tkMacOSXPrivate.h"
#include "tkFileFilter.h"
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1090
+#define modalOK NSOKButton
+#define modalCancel NSCancelButton
+#else
+#define modalOK NSModalResponseOK
+#define modalCancel NSModalResponseCancel
+#endif
+#define modalOther -1
+#define modalError -2
+
+
static const char *const colorOptionStrings[] = {
"-initialcolor", "-parent", "-title", NULL
};
@@ -130,6 +141,23 @@ static const short alertNativeButtonIndexAndTypeToButtonIndex[][3] = {
[TYPE_YESNO] = {5, 6, 0},
[TYPE_YESNOCANCEL] = {5, 6, 4},
};
+
+/*
+ * Construct a file URL from directory and filename. Either may
+ * be nil. If both are nil, returns nil.
+ */
+#if MAC_OS_X_VERSION_MIN_REQUIRED > 1050
+static NSURL *getFileURL(NSString *directory, NSString *filename) {
+ NSURL *url = nil;
+ if (directory) {
+ url = [NSURL fileURLWithPath:directory];
+ }
+ if (filename) {
+ url = [NSURL URLWithString:filename relativeToURL:url];
+ }
+ return url;
+}
+#endif
#pragma mark TKApplication(TKDialog)
@@ -149,12 +177,12 @@ static const short alertNativeButtonIndexAndTypeToButtonIndex[][3] = {
if (callbackInfo->multiple) {
resultObj = Tcl_NewListObj(0, NULL);
- for (NSString *name in [(NSOpenPanel*)panel filenames]) {
+ for (NSURL *url in [(NSOpenPanel*)panel URLs]) {
Tcl_ListObjAppendElement(callbackInfo->interp, resultObj,
- Tcl_NewStringObj([name UTF8String], -1));
+ Tcl_NewStringObj([[url path] UTF8String], -1));
}
} else {
- resultObj = Tcl_NewStringObj([[panel filename] UTF8String], -1);
+ resultObj = Tcl_NewStringObj([[[panel URL]path] UTF8String], -1);
}
if (callbackInfo->cmdObj) {
Tcl_Obj **objv, **tmpv;
@@ -189,7 +217,7 @@ static const short alertNativeButtonIndexAndTypeToButtonIndex[][3] = {
{
AlertCallbackInfo *callbackInfo = contextInfo;
- if (returnCode != NSAlertErrorReturn) {
+ if (returnCode >= NSAlertFirstButtonReturn) {
Tcl_Obj *resultObj = Tcl_NewStringObj(alertButtonStrings[
alertNativeButtonIndexAndTypeToButtonIndex[callbackInfo->
typeIndex][returnCode - NSAlertFirstButtonReturn]], -1);
@@ -309,7 +337,7 @@ Tk_ChooseColorObjCmd(
[colorPanel setColor:initialColor];
}
returnCode = [NSApp runModalForWindow:colorPanel];
- if (returnCode == NSOKButton) {
+ if (returnCode == modalOK) {
color = [[colorPanel color] colorUsingColorSpace:
[NSColorSpace genericRGBColorSpace]];
numberOfComponents = [color numberOfComponents];
@@ -369,7 +397,8 @@ Tk_GetOpenFileObjCmd(
NSWindow *parent;
NSMutableArray *fileTypes = nil;
NSOpenPanel *panel = [NSOpenPanel openPanel];
- NSInteger returnCode = NSAlertErrorReturn;
+ NSInteger modalReturnCode = modalError;
+ BOOL parentIsKey = NO;
TkInitFileFilters(&fl);
for (i = 1; i < objc; i += 2) {
@@ -439,6 +468,7 @@ Tk_GetOpenFileObjCmd(
break;
}
}
+ [panel setAllowsMultipleSelection:multiple];
if (fl.filters) {
fileTypes = [NSMutableArray array];
for (FileFilter *filterPtr = fl.filters; filterPtr;
@@ -471,7 +501,7 @@ Tk_GetOpenFileObjCmd(
}
}
}
- [panel setAllowsMultipleSelection:multiple];
+ [panel setAllowedFileTypes:fileTypes];
if (cmdObj) {
callbackInfo = ckalloc(sizeof(FilePanelCallbackInfo));
if (Tcl_IsShared(cmdObj)) {
@@ -484,19 +514,41 @@ Tk_GetOpenFileObjCmd(
callbackInfo->multiple = multiple;
parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
if (haveParentOption && parent && ![parent attachedSheet]) {
- [panel beginSheetForDirectory:directory file:filename types:fileTypes
- modalForWindow:parent modalDelegate:NSApp didEndSelector:
- @selector(tkFilePanelDidEnd:returnCode:contextInfo:)
- contextInfo:callbackInfo];
- returnCode = cmdObj ? NSAlertOtherReturn :
- [NSApp runModalForWindow:panel];
+ parentIsKey = [parent isKeyWindow];
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
+ [panel beginSheetForDirectory:directory
+ file:filename
+ types:fileTypes
+ modalForWindow:parent
+ modalDelegate:NSApp
+ didEndSelector:
+ @selector(tkFilePanelDidEnd:returnCode:contextInfo:)
+ contextInfo:callbackInfo];
+#else
+ [panel setAllowedFileTypes:fileTypes];
+ [panel setDirectoryURL:getFileURL(directory, filename)];
+ [panel beginSheetModalForWindow:parent
+ completionHandler:^(NSInteger returnCode)
+ { [NSApp tkFilePanelDidEnd:panel
+ returnCode:returnCode
+ contextInfo:callbackInfo ]; } ];
+#endif
+ modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:panel];
} else {
- returnCode = [panel runModalForDirectory:directory file:filename
- types:fileTypes];
- [NSApp tkFilePanelDidEnd:panel returnCode:returnCode
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
+ modalReturnCode = [panel runModalForDirectory:directory
+ file:filename];
+#else
+ [panel setDirectoryURL:getFileURL(directory, filename)];
+ modalReturnCode = [panel runModal];
+#endif
+ [NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode
contextInfo:callbackInfo];
}
- result = (returnCode != NSAlertErrorReturn) ? TCL_OK : TCL_ERROR;
+ result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
+ if (parentIsKey) {
+ [parent makeKeyWindow];
+ }
if (typeVariablePtr && result == TCL_OK) {
/*
* The -typevariable option is not really supported.
@@ -548,7 +600,8 @@ Tk_GetSaveFileObjCmd(
NSWindow *parent;
NSMutableArray *fileTypes = nil;
NSSavePanel *panel = [NSSavePanel savePanel];
- NSInteger returnCode = NSAlertErrorReturn;
+ NSInteger modalReturnCode = modalError;
+ BOOL parentIsKey = NO;
TkInitFileFilters(&fl);
for (i = 1; i < objc; i += 2) {
@@ -665,19 +718,38 @@ Tk_GetSaveFileObjCmd(
callbackInfo->multiple = 0;
parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
if (haveParentOption && parent && ![parent attachedSheet]) {
- [panel beginSheetForDirectory:directory file:filename
- modalForWindow:parent modalDelegate:NSApp didEndSelector:
- @selector(tkFilePanelDidEnd:returnCode:contextInfo:)
- contextInfo:callbackInfo];
- returnCode = cmdObj ? NSAlertOtherReturn :
- [NSApp runModalForWindow:panel];
+ parentIsKey = [parent isKeyWindow];
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
+ [panel beginSheetForDirectory:directory
+ file:filename
+ modalForWindow:parent
+ modalDelegate:NSApp
+ didEndSelector:
+ @selector(tkFilePanelDidEnd:returnCode:contextInfo:)
+ contextInfo:callbackInfo];
+#else
+ [panel setDirectoryURL:getFileURL(directory, filename)];
+ [panel beginSheetModalForWindow:parent
+ completionHandler:^(NSInteger returnCode)
+ { [NSApp tkFilePanelDidEnd:panel
+ returnCode:returnCode
+ contextInfo:callbackInfo ]; } ];
+#endif
+ modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:panel];
} else {
- returnCode = [panel runModalForDirectory:directory file:filename];
- [NSApp tkFilePanelDidEnd:panel returnCode:returnCode
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
+ modalReturnCode = [panel runModalForDirectory:directory file:filename];
+#else
+ [panel setDirectoryURL:getFileURL(directory, filename)];
+ modalReturnCode = [panel runModal];
+#endif
+ [NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode
contextInfo:callbackInfo];
}
- result = (returnCode != NSAlertErrorReturn) ? TCL_OK : TCL_ERROR;
-
+ result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
+ if (parentIsKey) {
+ [parent makeKeyWindow];
+ }
end:
TkFreeFileFilters(&fl);
return result;
@@ -719,7 +791,8 @@ Tk_ChooseDirectoryObjCmd(
NSString *message, *title;
NSWindow *parent;
NSOpenPanel *panel = [NSOpenPanel openPanel];
- NSInteger returnCode = NSAlertErrorReturn;
+ NSInteger modalReturnCode = modalError;
+ BOOL parentIsKey = NO;
for (i = 1; i < objc; i += 2) {
if (Tcl_GetIndexFromObjStruct(interp, objv[i], chooseOptionStrings,
@@ -787,19 +860,37 @@ Tk_ChooseDirectoryObjCmd(
callbackInfo->multiple = 0;
parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
if (haveParentOption && parent && ![parent attachedSheet]) {
- [panel beginSheetForDirectory:directory file:filename
- modalForWindow:parent modalDelegate:NSApp didEndSelector:
- @selector(tkFilePanelDidEnd:returnCode:contextInfo:)
+ parentIsKey = [parent isKeyWindow];
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
+ [panel beginSheetForDirectory:directory
+ file:filename
+ modalForWindow:parent
+ modalDelegate:NSApp
+ didEndSelector: @selector(tkFilePanelDidEnd:returnCode:contextInfo:)
contextInfo:callbackInfo];
- returnCode = cmdObj ? NSAlertOtherReturn :
- [NSApp runModalForWindow:panel];
+#else
+ [panel setDirectoryURL:getFileURL(directory, filename)];
+ [panel beginSheetModalForWindow:parent
+ completionHandler:^(NSInteger returnCode)
+ { [NSApp tkFilePanelDidEnd:panel
+ returnCode:returnCode
+ contextInfo:callbackInfo ]; } ];
+#endif
+ modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:panel];
} else {
- returnCode = [panel runModalForDirectory:directory file:filename];
- [NSApp tkFilePanelDidEnd:panel returnCode:returnCode
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
+ modalReturnCode = [panel runModalForDirectory:directory file:nil];
+#else
+ [panel setDirectoryURL:getFileURL(directory, filename)];
+ modalReturnCode = [panel runModal];
+#endif
+ [NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode
contextInfo:callbackInfo];
}
- result = (returnCode != NSAlertErrorReturn) ? TCL_OK : TCL_ERROR;
-
+ result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
+ if (parentIsKey) {
+ [parent makeKeyWindow];
+ }
end:
return result;
}
@@ -857,6 +948,9 @@ TkAboutDlg(void)
[[[NSAttributedString alloc] initWithString:
[NSString stringWithFormat:
@"%1$C 1987-%2$@ Tcl Core Team." "\n\n"
+ "%1$C 1989-%2$@ Contributors." "\n\n"
+ "%1$C 2011-%2$@ Kevin Walzer/WordTech Communications LLC." "\n\n"
+ "%1$C 2014-%2$@ Marc Culler." "\n\n"
"%1$C 2002-%2$@ Daniel A. Steffen." "\n\n"
"%1$C 2001-2009 Apple Inc." "\n\n"
"%1$C 2001-2002 Jim Ingham & Ian Reid" "\n\n"
@@ -896,7 +990,7 @@ TkMacOSXStandardAboutPanelObjCmd(
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return TCL_ERROR;
}
- [NSApp orderFrontStandardAboutPanelWithOptions:nil];
+ [NSApp orderFrontStandardAboutPanelWithOptions:[NSDictionary dictionary]];
return TCL_OK;
}
@@ -934,7 +1028,8 @@ Tk_MessageBoxObjCmd(
NSWindow *parent;
NSArray *buttons;
NSAlert *alert = [NSAlert new];
- NSInteger returnCode = NSAlertErrorReturn;
+ NSInteger modalReturnCode = 1;
+ BOOL parentIsKey = NO;
iconIndex = ICON_INFO;
typeIndex = TYPE_OK;
@@ -1061,19 +1156,32 @@ Tk_MessageBoxObjCmd(
callbackInfo->typeIndex = typeIndex;
parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
if (haveParentOption && parent && ![parent attachedSheet]) {
- [alert beginSheetModalForWindow:parent modalDelegate:NSApp
- didEndSelector:@selector(tkAlertDidEnd:returnCode:contextInfo:)
- contextInfo:callbackInfo];
- returnCode = cmdObj ? NSAlertOtherReturn :
- [NSApp runModalForWindow:[alert window]];
+ parentIsKey = [parent isKeyWindow];
+#if MAC_OS_X_VERSION_MIN_REQUIRED > 1090
+ [alert beginSheetModalForWindow:parent
+ completionHandler:^(NSModalResponse returnCode)
+ { [NSApp tkAlertDidEnd:alert
+ returnCode:returnCode
+ contextInfo:callbackInfo ]; } ];
+#else
+ [alert beginSheetModalForWindow:parent
+ modalDelegate:NSApp
+ didEndSelector:@selector(tkAlertDidEnd:returnCode:contextInfo:)
+ contextInfo:callbackInfo];
+#endif
+ modalReturnCode = cmdObj ? 0 :
+ [NSApp runModalForWindow:[alert window]];
} else {
- returnCode = [alert runModal];
- [NSApp tkAlertDidEnd:alert returnCode:returnCode
+ modalReturnCode = [alert runModal];
+ [NSApp tkAlertDidEnd:alert returnCode:modalReturnCode
contextInfo:callbackInfo];
}
- result = (returnCode != NSAlertErrorReturn) ? TCL_OK : TCL_ERROR;
+ result = (modalReturnCode >= NSAlertFirstButtonReturn) ? TCL_OK : TCL_ERROR;
end:
[alert release];
+ if (parentIsKey) {
+ [parent makeKeyWindow];
+ }
return result;
}
@@ -1212,7 +1320,7 @@ FontchooserEvent(
switch (kind) {
case FontchooserClosed:
if (fcdPtr->parent != None) {
- TkSendVirtualEvent(fcdPtr->parent, "TkFontchooserVisibility");
+ TkSendVirtualEvent(fcdPtr->parent, "TkFontchooserVisibility", NULL);
fontchooserInterp = NULL;
}
break;
@@ -1235,7 +1343,7 @@ FontchooserEvent(
ckfree(tmpv);
}
}
- TkSendVirtualEvent(fcdPtr->parent, "TkFontchooserFontChanged");
+ TkSendVirtualEvent(fcdPtr->parent, "TkFontchooserFontChanged", NULL);
}
break;
}
@@ -1445,7 +1553,7 @@ FontchooserConfigureCmd(
[fm setSelectedAttributes:fontPanelFontAttributes
isMultiple:NO];
if ([fp isVisible]) {
- TkSendVirtualEvent(fcdPtr->parent, "TkFontchooserFontChanged");
+ TkSendVirtualEvent(fcdPtr->parent, "TkFontchooserFontChanged", NULL);
}
break;
case FontchooserCmd:
@@ -1508,7 +1616,7 @@ FontchooserShowCmd(
}
if (![fp isVisible]) {
[fm orderFrontFontPanel:NSApp];
- TkSendVirtualEvent(fcdPtr->parent, "TkFontchooserVisibility");
+ TkSendVirtualEvent(fcdPtr->parent, "TkFontchooserVisibility", NULL);
}
fontchooserInterp = interp;
@@ -1643,9 +1751,7 @@ TkInitFontchooser(
Tcl_SetAssocData(interp, "::tk::fontchooser", DeleteFontchooserData,
fcdPtr);
if (!fontPanelFontAttributes) {
- NSAutoreleasePool *pool = [NSAutoreleasePool new];
fontPanelFontAttributes = [NSMutableDictionary new];
- [pool drain];
}
return TCL_OK;
}
diff --git a/macosx/tkMacOSXDraw.c b/macosx/tkMacOSXDraw.c
index 328f905..f48538d 100644
--- a/macosx/tkMacOSXDraw.c
+++ b/macosx/tkMacOSXDraw.c
@@ -141,7 +141,7 @@ BitmapRepFromDrawableRect(
if ( mac_drawable->flags & TK_IS_PIXMAP ) {
/*
This means that the MacDrawable is functioning as a Tk Pixmap, so its view
- field is NULL. It's context field should point to a CGImage.
+ field is NULL.
*/
cg_context = GetCGContextForDrawable(drawable);
CGRect image_rect = CGRectMake(x, y, width, height);
@@ -199,10 +199,10 @@ XCopyArea(
Display *display, /* Display. */
Drawable src, /* Source drawable. */
Drawable dst, /* Destination drawable. */
- GC gc, /* GC to use. */
+ GC gc, /* GC to use. */
int src_x, /* X & Y, width & height */
int src_y, /* define the source rectangle */
- unsigned int width, /* that will be copied. */
+ unsigned int width, /* that will be copied. */
unsigned int height,
int dest_x, /* Dest X & Y on dest rect. */
int dest_y)
@@ -222,7 +222,8 @@ XCopyArea(
}
if (!TkMacOSXSetupDrawingContext(dst, gc, 1, &dc)) {
- TkMacOSXDbgMsg("Failed to setup drawing context.");
+ return;
+ /*TkMacOSXDbgMsg("Failed to setup drawing context.");*/
}
if ( dc.context ) {
@@ -243,6 +244,8 @@ XCopyArea(
CGRectMake(src_x, src_y, width, height),
CGRectMake(dest_x, dest_y, width, height));
CFRelease(img);
+
+
} else {
TkMacOSXDbgMsg("Failed to construct CGImage.");
}
@@ -279,10 +282,10 @@ XCopyPlane(
Display *display, /* Display. */
Drawable src, /* Source drawable. */
Drawable dst, /* Destination drawable. */
- GC gc, /* GC to use. */
+ GC gc, /* GC to use. */
int src_x, /* X & Y, width & height */
int src_y, /* define the source rectangle */
- unsigned int width, /* that will be copied. */
+ unsigned int width, /* that will be copied. */
unsigned int height,
int dest_x, /* Dest X & Y on dest rect. */
int dest_y,
@@ -290,6 +293,7 @@ XCopyPlane(
{
TkMacOSXDrawingContext dc;
MacDrawable *srcDraw = (MacDrawable *) src;
+ MacDrawable *dstDraw = (MacDrawable *) dst;
display->request++;
if (!width || !height) {
@@ -303,33 +307,53 @@ XCopyPlane(
if (!TkMacOSXSetupDrawingContext(dst, gc, 1, &dc)) {
return;
}
- if (dc.context) {
+ CGContextRef context = dc.context;
+ if (context) {
CGImageRef img = TkMacOSXCreateCGImageWithDrawable(src);
-
if (img) {
TkpClipMask *clipPtr = (TkpClipMask *) gc->clip_mask;
unsigned long imageBackground = gc->background;
-
- if (clipPtr && clipPtr->type == TKP_CLIP_PIXMAP &&
- clipPtr->value.pixmap == src) {
- imageBackground = TRANSPARENT_PIXEL << 24;
+ if (clipPtr && clipPtr->type == TKP_CLIP_PIXMAP){
+ CGRect srcRect = CGRectMake(src_x, src_y, width, height);
+ CGImageRef mask = TkMacOSXCreateCGImageWithDrawable(clipPtr->value.pixmap);
+ CGImageRef submask = CGImageCreateWithImageInRect(img, srcRect);
+ CGRect rect = CGRectMake(dest_x, dest_y, width, height);
+ rect = CGRectOffset(rect, dstDraw->xOff, dstDraw->yOff);
+ CGContextSaveGState(context);
+ /* Move the origin of the destination to top left. */
+ CGContextTranslateCTM(context, 0, rect.origin.y + CGRectGetMaxY(rect));
+ CGContextScaleCTM(context, 1, -1);
+ /* Fill with the background color, clipping to the mask. */
+ CGContextClipToMask(context, rect, submask);
+ TkMacOSXSetColorInContext(gc, gc->background, dc.context);
+ CGContextFillRect(context, rect);
+ /* Fill with the foreground color, clipping to the
+ intersection of img and mask. */
+ CGImageRef subimage = CGImageCreateWithImageInRect(img, srcRect);
+ CGContextClipToMask(context, rect, subimage);
+ TkMacOSXSetColorInContext(gc, gc->foreground, context);
+ CGContextFillRect(context, rect);
+ CGContextRestoreGState(context);
+ CGImageRelease(img);
+ CGImageRelease(mask);
+ CGImageRelease(submask);
+ CGImageRelease(subimage);
+ } else {
+ DrawCGImage(dst, gc, dc.context, img, gc->foreground, imageBackground,
+ CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height),
+ CGRectMake(src_x, src_y, width, height),
+ CGRectMake(dest_x, dest_y, width, height));
+ CGImageRelease(img);
}
- DrawCGImage(dst, gc, dc.context, img, gc->foreground,
- imageBackground, CGRectMake(0, 0,
- srcDraw->size.width, srcDraw->size.height),
- CGRectMake(src_x, src_y, width, height),
- CGRectMake(dest_x, dest_y, width, height));
- CFRelease(img);
- } else {
+ } else { /* no image */
TkMacOSXDbgMsg("Invalid source drawable");
}
} else {
- TkMacOSXDbgMsg("Invalid destination drawable");
+ TkMacOSXDbgMsg("Invalid destination drawable - could not get a bitmap context.");
}
TkMacOSXRestoreDrawingContext(&dc);
- } else {
- XCopyArea(display, src, dst, gc, src_x, src_y, width, height, dest_x,
- dest_y);
+ } else { /* source drawable is a window, not a Pixmap */
+ XCopyArea(display, src, dst, gc, src_x, src_y, width, height, dest_x, dest_y);
}
}
@@ -353,16 +377,16 @@ XCopyPlane(
int
TkPutImage(
unsigned long *colors, /* Unused on Macintosh. */
- int ncolors, /* Unused on Macintosh. */
+ int ncolors, /* Unused on Macintosh. */
Display* display, /* Display. */
Drawable d, /* Drawable to place image on. */
- GC gc, /* GC to use. */
+ GC gc, /* GC to use. */
XImage* image, /* Image to place. */
int src_x, /* Source X & Y. */
int src_y,
int dest_x, /* Destination X & Y. */
int dest_y,
- unsigned int width, /* Same width & height for both */
+ unsigned int width, /* Same width & height for both */
unsigned int height) /* distination and source. */
{
TkMacOSXDrawingContext dc;
@@ -375,9 +399,11 @@ TkPutImage(
CGImageRef img = CreateCGImageWithXImage(image);
if (img) {
+ /* If the XImage has big pixels, rescale the source dimensions.*/
+ int pp = image->pixelpower;
DrawCGImage(d, gc, dc.context, img, gc->foreground, gc->background,
- CGRectMake(0, 0, image->width, image->height),
- CGRectMake(src_x, src_y, width, height),
+ CGRectMake(0, 0, image->width<<pp, image->height<<pp),
+ CGRectMake(src_x<<pp, src_y<<pp, width<<pp, height<<pp),
CGRectMake(dest_x, dest_y, width, height));
CFRelease(img);
} else {
@@ -428,11 +454,12 @@ CreateCGImageWithXImage(
* BW image
*/
+ /* Reverses the sense of the bits */
static const CGFloat decodeWB[2] = {1, 0};
+ decode = decodeWB;
bitsPerComponent = 1;
bitsPerPixel = 1;
- decode = decodeWB;
if (image->bitmap_bit_order != MSBFirst) {
char *srcPtr = image->data + image->xoffset;
char *endPtr = srcPtr + len;
@@ -442,16 +469,14 @@ CreateCGImageWithXImage(
*destPtr++ = xBitReverseTable[(unsigned char)(*(srcPtr++))];
}
} else {
- data = memcpy(ckalloc(len), image->data + image->xoffset,
- len);
+ data = memcpy(ckalloc(len), image->data + image->xoffset, len);
}
if (data) {
provider = CGDataProviderCreateWithData(data, data, len, releaseData);
}
if (provider) {
img = CGImageMaskCreate(image->width, image->height, bitsPerComponent,
- bitsPerPixel, image->bytes_per_line,
- provider, decode, 0);
+ bitsPerPixel, image->bytes_per_line, provider, decode, 0);
}
} else if (image->format == ZPixmap && image->bits_per_pixel == 32) {
/*
@@ -473,6 +498,7 @@ CreateCGImageWithXImage(
img = CGImageCreate(image->width, image->height, bitsPerComponent,
bitsPerPixel, image->bytes_per_line, colorspace, bitmapInfo,
provider, decode, 0, kCGRenderingIntentDefault);
+ CFRelease(provider);
}
if (colorspace) {
CFRelease(colorspace);
@@ -480,10 +506,6 @@ CreateCGImageWithXImage(
} else {
TkMacOSXDbgMsg("Unsupported image type");
}
- if (provider) {
- CFRelease(provider);
- }
-
return img;
}
@@ -652,17 +674,16 @@ GetCGContextForDrawable(
CGColorSpaceRef colorspace = NULL;
CGBitmapInfo bitmapInfo =
#ifdef __LITTLE_ENDIAN__
- kCGBitmapByteOrder32Host;
+ kCGBitmapByteOrder32Host;
#else
- kCGBitmapByteOrderDefault;
+ kCGBitmapByteOrderDefault;
#endif
char *data;
- CGRect bounds = CGRectMake(0, 0, macDraw->size.width,
- macDraw->size.height);
+ CGRect bounds = CGRectMake(0, 0, macDraw->size.width, macDraw->size.height);
if (macDraw->flags & TK_IS_BW_PIXMAP) {
bitsPerPixel = 8;
- bitmapInfo = kCGImageAlphaOnly;
+ bitmapInfo = (CGBitmapInfo)kCGImageAlphaOnly;
} else {
colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
bitsPerPixel = 32;
@@ -731,9 +752,11 @@ DrawCGImage(
}
}
dstBounds = CGRectOffset(dstBounds, macDraw->xOff, macDraw->yOff);
+
if (CGImageIsMask(image)) {
/*CGContextSaveGState(context);*/
if (macDraw->flags & TK_IS_BW_PIXMAP) {
+ /* Set fill color to black, background comes from the context, or is transparent. */
if (imageBackground != TRANSPARENT_PIXEL << 24) {
CGContextClearRect(context, dstBounds);
}
@@ -746,6 +769,7 @@ DrawCGImage(
TkMacOSXSetColorInContext(gc, imageForeground, context);
}
}
+
#ifdef TK_MAC_DEBUG_IMAGE_DRAWING
CGContextSaveGState(context);
CGContextSetLineWidth(context, 1.0);
@@ -765,15 +789,11 @@ DrawCGImage(
dstBounds.size.width, dstBounds.size.height);
#else /* TK_MAC_DEBUG_IMAGE_DRAWING */
CGContextSaveGState(context);
- CGContextTranslateCTM(context,
- 0, dstBounds.origin.y + CGRectGetMaxY(dstBounds));
+ CGContextTranslateCTM(context, 0, dstBounds.origin.y + CGRectGetMaxY(dstBounds));
CGContextScaleCTM(context, 1, -1);
CGContextDrawImage(context, dstBounds, image);
CGContextRestoreGState(context);
#endif /* TK_MAC_DEBUG_IMAGE_DRAWING */
- /*if (CGImageIsMask(image)) {
- CGContextRestoreGState(context);
- }*/
if (subImage) {
CFRelease(subImage);
}
@@ -1476,12 +1496,11 @@ TkScrollWindow(
{
Drawable drawable = Tk_WindowId(tkwin);
MacDrawable *macDraw = (MacDrawable *) drawable;
- NSView *view = TkMacOSXDrawableView(macDraw);
+ TKContentView *view = (TKContentView *)TkMacOSXDrawableView(macDraw);
CGRect srcRect, dstRect;
- HIShapeRef dmgRgn = NULL, extraRgn;
+ HIShapeRef dmgRgn = NULL, extraRgn = NULL;
NSRect bounds, visRect, scrollSrc, scrollDst;
- int result;
-
+ int result = 0;
if ( view ) {
/* Get the scroll area in NSView coordinates (origin at bottom left). */
@@ -1491,36 +1510,78 @@ TkScrollWindow(
bounds.size.height - height - (macDraw->yOff + y),
width, height);
scrollDst = NSOffsetRect(scrollSrc, dx, -dy);
+
/* Limit scrolling to the window content area. */
visRect = [view visibleRect];
scrollSrc = NSIntersectionRect(scrollSrc, visRect);
scrollDst = NSIntersectionRect(scrollDst, visRect);
-
if ( !NSIsEmptyRect(scrollSrc) && !NSIsEmptyRect(scrollDst) ) {
/*
* Mark the difference between source and destination as damaged.
- * This region is described in the Tk coordinate system.
+ * This region is described in NSView coordinates (y=0 at the bottom)
+ * and converted to Tk coordinates later.
*/
- srcRect = CGRectMake(x, y, width, height);
- dstRect = CGRectOffset(srcRect, dx, dy);
+ srcRect = CGRectMake(x, y, width, height);
+ dstRect = CGRectOffset(srcRect, dx, dy);
+
+ /* Expand the rectangles slightly to avoid degeneracies. */
+ srcRect.origin.y -= 1;
+ srcRect.size.height += 2;
+ dstRect.origin.y += 1;
+ dstRect.size.height -= 2;
+
+ /* Compute the damage. */
dmgRgn = HIShapeCreateMutableWithRect(&srcRect);
extraRgn = HIShapeCreateWithRect(&dstRect);
ChkErr(HIShapeDifference, dmgRgn, extraRgn, (HIMutableShapeRef) dmgRgn);
- CFRelease(extraRgn);
+ result = HIShapeIsEmpty(dmgRgn) ? 0 : 1;
+
+ /* Convert to Tk coordinates. */
+ TkMacOSXSetWithNativeRegion(damageRgn, dmgRgn);
+ if (extraRgn) {
+ CFRelease(extraRgn);
+ }
/* Scroll the rectangle. */
[view scrollRect:scrollSrc by:NSMakeSize(dx, -dy)];
+
+ /* Shift the Tk children which meet the source rectangle. */
+ TkWindow *winPtr = (TkWindow *)tkwin;
+ TkWindow *childPtr;
+ CGRect childBounds;
+ for (childPtr = winPtr->childList; childPtr != NULL; childPtr = childPtr->nextPtr) {
+ if (Tk_IsMapped(childPtr) && !Tk_IsTopLevel(childPtr)) {
+ TkMacOSXWinCGBounds(childPtr, &childBounds);
+ if (CGRectIntersectsRect(srcRect, childBounds)) {
+ MacDrawable *macChild = childPtr->privatePtr;
+ if (macChild) {
+ macChild->yOff += dy;
+ macChild->xOff += dx;
+ childPtr->changes.y = macChild->yOff;
+ childPtr->changes.x = macChild->xOff;
+ }
+ }
+ }
+ }
+
+ /* Queue up Expose events for the damage region. */
+ int oldMode = Tcl_SetServiceMode(TCL_SERVICE_NONE);
+ [view generateExposeEvents:dmgRgn childrenOnly:1];
+ Tcl_SetServiceMode(oldMode);
+
+ /* Belt and suspenders: make the AppKit request a redraw
+ when it gets control again. */
}
+ } else {
+ dmgRgn = HIShapeCreateEmpty();
+ TkMacOSXSetWithNativeRegion(damageRgn, dmgRgn);
}
- if ( dmgRgn == NULL ) {
- dmgRgn = HIShapeCreateEmpty();
+ if (dmgRgn) {
+ CFRelease(dmgRgn);
}
- TkMacOSXSetWithNativeRegion(damageRgn, dmgRgn);
- result = HIShapeIsEmpty(dmgRgn) ? 0 : 1;
- CFRelease(dmgRgn);
return result;
}
@@ -1797,7 +1858,6 @@ TkMacOSXGetClipRgn(
} else if (macDraw->visRgn) {
clipRgn = HIShapeCreateCopy(macDraw->visRgn);
}
-
return clipRgn;
}
@@ -1855,6 +1915,7 @@ TkpClipDrawableToRect(
CFRelease(macDraw->drawRgn);
macDraw->drawRgn = NULL;
}
+
if (width >= 0 && height >= 0) {
CGRect clipRect = CGRectMake(x + macDraw->xOff, y + macDraw->yOff,
width, height);
@@ -2002,7 +2063,7 @@ TkpDrawHighlightBorder (
* TkpDrawFrame --
*
* This procedure draws the rectangular frame area. If the user
- * has request themeing, it draws with a the background theme.
+ * has requested themeing, it draws with the background theme.
*
* Results:
* None.
@@ -2032,6 +2093,7 @@ TkpDrawFrame(
border = themedBorder;
}
}
+
Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin),
border, highlightWidth, highlightWidth,
Tk_Width(tkwin) - 2 * highlightWidth,
diff --git a/macosx/tkMacOSXEmbed.c b/macosx/tkMacOSXEmbed.c
index 99f7584..5ea7603 100644
--- a/macosx/tkMacOSXEmbed.c
+++ b/macosx/tkMacOSXEmbed.c
@@ -193,7 +193,7 @@ TkpMakeWindow(
int
TkpScanWindowId(
Tcl_Interp *interp,
- CONST char * string,
+ const char * string,
Window *idPtr)
{
int code;
diff --git a/macosx/tkMacOSXEvent.c b/macosx/tkMacOSXEvent.c
index ea262ff..7f3357f 100644
--- a/macosx/tkMacOSXEvent.c
+++ b/macosx/tkMacOSXEvent.c
@@ -31,18 +31,19 @@ enum {
NSEvent *processedEvent = theEvent;
NSEventType type = [theEvent type];
NSInteger subtype;
- NSUInteger flags;
switch ((NSInteger)type) {
case NSAppKitDefined:
subtype = [theEvent subtype];
switch (subtype) {
+ /* Ignored at the moment. */
case NSApplicationActivatedEventType:
break;
case NSApplicationDeactivatedEventType:
break;
case NSWindowExposedEventType:
+ break;
case NSScreenChangedEventType:
break;
case NSWindowMovedEventType:
@@ -53,13 +54,12 @@ enum {
default:
break;
}
- break;
+ break; /* AppkitEvent. Return theEvent */
case NSKeyUp:
case NSKeyDown:
case NSFlagsChanged:
- flags = [theEvent modifierFlags];
processedEvent = [self tkProcessKeyEvent:theEvent];
- break;
+ break; /* Key event. Return the processed event. */
case NSLeftMouseDown:
case NSLeftMouseUp:
case NSRightMouseDown:
@@ -76,7 +76,7 @@ enum {
case NSTabletPoint:
case NSTabletProximity:
processedEvent = [self tkProcessMouseEvent:theEvent];
- break;
+ break; /* Mouse event. Return the processed event. */
#if 0
case NSSystemDefined:
subtype = [theEvent subtype];
@@ -100,7 +100,7 @@ enum {
#endif
default:
- break;
+ break; /* return theEvent */
}
return processedEvent;
}
@@ -113,14 +113,14 @@ enum {
*
* TkMacOSXFlushWindows --
*
- * This routine flushes all the windows of the application. It is
+ * This routine flushes all the visible windows of the application. It is
* called by XSync().
*
* Results:
* None.
*
* Side effects:
- * Flushes all Carbon windows
+ * Flushes all visible Cocoa windows
*
*----------------------------------------------------------------------
*/
@@ -128,22 +128,15 @@ enum {
MODULE_SCOPE void
TkMacOSXFlushWindows(void)
{
- NSInteger windowCount;
- NSInteger *windowNumbers;
+ NSArray *macWindows = [NSApp orderedWindows];
- NSCountWindows(&windowCount);
- if(windowCount) {
- windowNumbers = ckalloc(windowCount * sizeof(NSInteger));
- NSWindowList(windowCount, windowNumbers);
- for (NSInteger index = 0; index < windowCount; index++) {
- NSWindow *w = [NSApp windowWithWindowNumber:windowNumbers[index]];
- if (TkMacOSXGetXWindow(w)) {
- [w flushWindow];
- }
+ for (NSWindow *w in macWindows) {
+ if (TkMacOSXGetXWindow(w)) {
+ [w flushWindow];
}
- ckfree(windowNumbers);
}
}
+
/*
* Local Variables:
diff --git a/macosx/tkMacOSXFont.c b/macosx/tkMacOSXFont.c
index 4c8ac30..d3e0e41 100644
--- a/macosx/tkMacOSXFont.c
+++ b/macosx/tkMacOSXFont.c
@@ -15,6 +15,19 @@
#include "tkMacOSXPrivate.h"
#include "tkMacOSXFont.h"
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1080
+#define defaultOrientation kCTFontDefaultOrientation
+#define verticalOrientation kCTFontVerticalOrientation
+#else
+#define defaultOrientation kCTFontOrientationDefault
+#define verticalOrientation kCTFontOrientationVertical
+#endif
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 101100
+#define fixedPitch kCTFontUserFixedPitchFontType
+#else
+#define fixedPitch kCTFontUIFontUserFixedPitch
+#endif
+
/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_FONTS
@@ -197,6 +210,7 @@ FindNSFont(
nsFont = [fm convertFont:nsFont toSize:size];
nsFont = [fm convertFont:nsFont toHaveTrait:traits];
}
+ [nsFont retain];
#undef defaultFont
return nsFont;
}
@@ -270,7 +284,7 @@ InitFont(
fmPtr->fixed = [nsFont advancementForGlyph:glyphs[0]].width ==
[nsFont advancementForGlyph:glyphs[1]].width;
bounds = NSRectFromCGRect(CTFontGetBoundingRectsForGlyphs((CTFontRef)
- nsFont, kCTFontDefaultOrientation, ch, boundingRects, nCh));
+ nsFont, defaultOrientation, ch, boundingRects, nCh));
kern = [nsFont advancementForGlyph:glyphs[2]].width -
[fontPtr->nsFont advancementForGlyph:glyphs[2]].width;
}
@@ -293,7 +307,7 @@ InitFont(
[NSNumber numberWithInt:fmPtr->fixed ? 0 : 1],
NSLigatureAttributeName,
[NSNumber numberWithDouble:kern], NSKernAttributeName, nil];
- fontPtr->nsAttributes = TkMacOSXMakeUncollectableAndRetain(nsAttributes);
+ fontPtr->nsAttributes = [nsAttributes retain];
#undef nCh
}
@@ -358,6 +372,7 @@ TkpFontPkgInit(
NSFont *nsFont;
TkFontAttributes fa;
NSMutableCharacterSet *cs;
+ /* Since we called before TkpInit, we need our own autorelease pool. */
NSAutoreleasePool *pool = [NSAutoreleasePool new];
/* force this for now */
@@ -382,8 +397,7 @@ TkpFontPkgInit(
systemFont++;
}
TkInitFontAttributes(&fa);
- nsFont = (NSFont*) CTFontCreateUIFontForLanguage(
- kCTFontUserFixedPitchFontType, 11, NULL);
+ nsFont = (NSFont*) CTFontCreateUIFontForLanguage(fixedPitch, 11, NULL);
if (nsFont) {
GetTkFontAttributesForNSFont(nsFont, &fa);
CFRelease(nsFont);
@@ -518,7 +532,7 @@ TkpGetFontFromAttributes(
nsFont = FindNSFont(faPtr->family, traits, weight, points, 1);
}
if (!nsFont) {
- Tcl_Panic("Could not deternmine NSFont from TkFontAttributes");
+ Tcl_Panic("Could not determine NSFont from TkFontAttributes");
}
if (tkFontPtr == NULL) {
fontPtr = ckalloc(sizeof(MacFont));
@@ -557,7 +571,8 @@ TkpDeleteFont(
{
MacFont *fontPtr = (MacFont *) tkFontPtr;
- TkMacOSXMakeCollectableAndRelease(fontPtr->nsAttributes);
+ [fontPtr->nsAttributes release];
+ fontPtr->nsAttributes = NULL;
CFRelease(fontPtr->nsFont); /* Either a CTFontRef or a CFRetained NSFont */
}
@@ -657,15 +672,14 @@ void
TkpGetFontAttrsForChar(
Tk_Window tkwin, /* Window on the font's display */
Tk_Font tkfont, /* Font to query */
- Tcl_UniChar c, /* Character of interest */
+ int c, /* Character of interest */
TkFontAttributes* faPtr) /* Output: Font attributes */
{
MacFont *fontPtr = (MacFont *) tkfont;
NSFont *nsFont = fontPtr->nsFont;
-
*faPtr = fontPtr->font.fa;
if (nsFont && ![[nsFont coveredCharacterSet] characterIsMember:c]) {
- UTF16Char ch = c;
+ UTF16Char ch = (UTF16Char) c;
nsFont = [nsFont bestMatchingFontForCharacters:&ch
length:1 attributes:nil actualCoveredLength:NULL];
diff --git a/macosx/tkMacOSXHLEvents.c b/macosx/tkMacOSXHLEvents.c
index daf860f..f5aeff0 100644
--- a/macosx/tkMacOSXHLEvents.c
+++ b/macosx/tkMacOSXHLEvents.c
@@ -7,12 +7,15 @@
* Copyright (c) 1995-1997 Sun Microsystems, Inc.
* Copyright 2001-2009, Apple Inc.
* Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
+ * Copyright (c) 2015 Marc Culler
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkMacOSXPrivate.h"
+#include <sys/param.h>
+#define URL_MAX_LENGTH (17 + MAXPATHLEN)
/*
* This is a Tcl_Event structure that the Quit AppleEvent handler uses to
@@ -30,154 +33,32 @@ typedef struct KillEvent {
* Static functions used only in this file.
*/
-static OSErr QuitHandler(const AppleEvent *event,
- AppleEvent *reply, SRefCon handlerRefcon);
-static OSErr OappHandler(const AppleEvent *event,
- AppleEvent *reply, SRefCon handlerRefcon);
-static OSErr RappHandler(const AppleEvent *event,
- AppleEvent *reply, SRefCon handlerRefcon);
-static OSErr OdocHandler(const AppleEvent *event,
- AppleEvent *reply, SRefCon handlerRefcon);
-static OSErr PrintHandler(const AppleEvent *event,
- AppleEvent *reply, SRefCon handlerRefcon);
-static OSErr ScriptHandler(const AppleEvent *event,
- AppleEvent *reply, SRefCon handlerRefcon);
-static OSErr PrefsHandler(const AppleEvent *event,
- AppleEvent *reply, SRefCon handlerRefcon);
-static int MissedAnyParameters(const AppleEvent *theEvent);
-static int ReallyKillMe(Tcl_Event *eventPtr, int flags);
-static OSStatus FSRefToDString(const FSRef *fsref, Tcl_DString *ds);
+static void tkMacOSXProcessFiles(NSAppleEventDescriptor* event,
+ NSAppleEventDescriptor* replyEvent,
+ Tcl_Interp *interp,
+ char* procedure);
+static int MissedAnyParameters(const AppleEvent *theEvent);
+static int ReallyKillMe(Tcl_Event *eventPtr, int flags);
#pragma mark TKApplication(TKHLEvents)
@implementation TKApplication(TKHLEvents)
- (void) terminate: (id) sender
{
- QuitHandler(NULL, NULL, (SRefCon) _eventInterp);
+ [self handleQuitApplicationEvent:Nil withReplyEvent:Nil];
}
- (void) preferences: (id) sender
{
- PrefsHandler(NULL, NULL, (SRefCon) _eventInterp);
+ [self handleShowPreferencesEvent:Nil withReplyEvent:Nil];
}
-@end
-
-#pragma mark -
-
-/*
- *----------------------------------------------------------------------
- *
- * TkMacOSXInitAppleEvents --
- *
- * Initilize the Apple Events on the Macintosh. This registers the core
- * event handlers.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-void
-TkMacOSXInitAppleEvents(
- Tcl_Interp *interp) /* Interp to handle basic events. */
-{
- AEEventHandlerUPP OappHandlerUPP, RappHandlerUPP, OdocHandlerUPP;
- AEEventHandlerUPP PrintHandlerUPP, QuitHandlerUPP, ScriptHandlerUPP;
- AEEventHandlerUPP PrefsHandlerUPP;
- static Boolean initialized = FALSE;
-
- if (!initialized) {
- initialized = TRUE;
-
- /*
- * Install event handlers for the core apple events.
- */
-
- QuitHandlerUPP = NewAEEventHandlerUPP(QuitHandler);
- ChkErr(AEInstallEventHandler, kCoreEventClass, kAEQuitApplication,
- QuitHandlerUPP, (SRefCon) interp, false);
-
- OappHandlerUPP = NewAEEventHandlerUPP(OappHandler);
- ChkErr(AEInstallEventHandler, kCoreEventClass, kAEOpenApplication,
- OappHandlerUPP, (SRefCon) interp, false);
-
- RappHandlerUPP = NewAEEventHandlerUPP(RappHandler);
- ChkErr(AEInstallEventHandler, kCoreEventClass, kAEReopenApplication,
- RappHandlerUPP, (SRefCon) interp, false);
-
- OdocHandlerUPP = NewAEEventHandlerUPP(OdocHandler);
- ChkErr(AEInstallEventHandler, kCoreEventClass, kAEOpenDocuments,
- OdocHandlerUPP, (SRefCon) interp, false);
-
- PrintHandlerUPP = NewAEEventHandlerUPP(PrintHandler);
- ChkErr(AEInstallEventHandler, kCoreEventClass, kAEPrintDocuments,
- PrintHandlerUPP, (SRefCon) interp, false);
-
- PrefsHandlerUPP = NewAEEventHandlerUPP(PrefsHandler);
- ChkErr(AEInstallEventHandler, kCoreEventClass, kAEShowPreferences,
- PrefsHandlerUPP, (SRefCon) interp, false);
-
- if (interp) {
- ScriptHandlerUPP = NewAEEventHandlerUPP(ScriptHandler);
- ChkErr(AEInstallEventHandler, kAEMiscStandards, kAEDoScript,
- ScriptHandlerUPP, (SRefCon) interp, false);
- }
- }
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TkMacOSXDoHLEvent --
- *
- * Dispatch incomming highlevel events.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Depends on the incoming event.
- *
- *----------------------------------------------------------------------
- */
-
-int
-TkMacOSXDoHLEvent(
- void *theEvent)
-{
- return AEProcessAppleEvent((EventRecord *)theEvent);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * QuitHandler --
- *
- * This is the 'quit' core Apple event handler.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-static OSErr
-QuitHandler(
- const AppleEvent *event,
- AppleEvent *reply,
- SRefCon handlerRefcon)
+- (void) handleQuitApplicationEvent: (NSAppleEventDescriptor *)event
+ withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
- Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon;
KillEvent *eventPtr;
- if (interp) {
+ if (_eventInterp) {
/*
* Call the exit command from the event loop, since you are not
* supposed to call ExitToShell in an Apple Event Handler. We put this
@@ -188,233 +69,221 @@ QuitHandler(
eventPtr = ckalloc(sizeof(KillEvent));
eventPtr->header.proc = ReallyKillMe;
- eventPtr->interp = interp;
+ eventPtr->interp = _eventInterp;
Tcl_QueueEvent((Tcl_Event *) eventPtr, TCL_QUEUE_HEAD);
}
- return noErr;
}
-
-/*
- *----------------------------------------------------------------------
- *
- * OappHandler --
- *
- * This is the 'oapp' core Apple event handler.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-static OSErr
-OappHandler(
- const AppleEvent *event,
- AppleEvent *reply,
- SRefCon handlerRefcon)
+- (void) handleOpenApplicationEvent: (NSAppleEventDescriptor *)event
+ withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
- Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon;
+ Tcl_Interp *interp = _eventInterp;
if (interp &&
- Tcl_FindCommand(interp, "::tk::mac::OpenApplication", NULL, 0)){
- int code = Tcl_EvalEx(interp, "::tk::mac::OpenApplication", -1, TCL_EVAL_GLOBAL);
+ Tcl_FindCommand(_eventInterp, "::tk::mac::OpenApplication", NULL, 0)){
+ int code = Tcl_EvalEx(_eventInterp, "::tk::mac::OpenApplication",
+ -1, TCL_EVAL_GLOBAL);
if (code != TCL_OK) {
- Tcl_BackgroundException(interp, code);
+ Tcl_BackgroundException(_eventInterp, code);
}
}
- return noErr;
}
-
-/*
- *----------------------------------------------------------------------
- *
- * RappHandler --
- *
- * This is the 'rapp' core Apple event handler.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-static OSErr
-RappHandler(
- const AppleEvent *event,
- AppleEvent *reply,
- SRefCon handlerRefcon)
+- (void) handleReopenApplicationEvent: (NSAppleEventDescriptor *)event
+ withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
- Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon;
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1090
ProcessSerialNumber thePSN = {0, kCurrentProcess};
- OSStatus err = ChkErr(SetFrontProcess, &thePSN);
-
- if (interp && Tcl_FindCommand(interp,
+ SetFrontProcess(&thePSN);
+#else
+ [[NSApplication sharedApplication] activateIgnoringOtherApps: YES];
+#endif
+ if (_eventInterp && Tcl_FindCommand(_eventInterp,
"::tk::mac::ReopenApplication", NULL, 0)) {
- int code = Tcl_EvalEx(interp, "::tk::mac::ReopenApplication", -1, TCL_EVAL_GLOBAL);
+ int code = Tcl_EvalEx(_eventInterp, "::tk::mac::ReopenApplication",
+ -1, TCL_EVAL_GLOBAL);
if (code != TCL_OK){
- Tcl_BackgroundException(interp, code);
+ Tcl_BackgroundException(_eventInterp, code);
}
}
- return err;
}
-
-/*
- *----------------------------------------------------------------------
- *
- * PrefsHandler --
- *
- * This is the 'pref' core Apple event handler. Called when the user
- * selects 'Preferences...' in MacOS X
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-static OSErr
-PrefsHandler(
- const AppleEvent *event,
- AppleEvent *reply,
- SRefCon handlerRefcon)
+- (void) handleShowPreferencesEvent: (NSAppleEventDescriptor *)event
+ withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
- Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon;
-
- if (interp &&
- Tcl_FindCommand(interp, "::tk::mac::ShowPreferences", NULL, 0)){
- int code = Tcl_EvalEx(interp, "::tk::mac::ShowPreferences", -1, TCL_EVAL_GLOBAL);
+ if (_eventInterp &&
+ Tcl_FindCommand(_eventInterp, "::tk::mac::ShowPreferences", NULL, 0)){
+ int code = Tcl_EvalEx(_eventInterp, "::tk::mac::ShowPreferences",
+ -1, TCL_EVAL_GLOBAL);
if (code != TCL_OK) {
- Tcl_BackgroundException(interp, code);
+ Tcl_BackgroundException(_eventInterp, code);
}
}
- return noErr;
}
-
-/*
- *----------------------------------------------------------------------
- *
- * OdocHandler --
- *
- * This is the 'odoc' core Apple event handler.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-static OSErr
-OdocHandler(
- const AppleEvent *event,
- AppleEvent *reply,
- SRefCon handlerRefcon)
+- (void) handleOpenDocumentsEvent: (NSAppleEventDescriptor *)event
+ withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
- Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon;
- AEDescList fileSpecList;
- FSRef file;
- DescType type;
- Size actual;
- long count, index;
- AEKeyword keyword;
- Tcl_DString command, pathName;
- int code;
+ tkMacOSXProcessFiles(event, replyEvent, _eventInterp, "::tk::mac::OpenDocument");
+}
- /*
- * Don't bother if we don't have an interp or the open document procedure
- * doesn't exist.
- */
+- (void) handlePrintDocumentsEvent: (NSAppleEventDescriptor *)event
+ withReplyEvent: (NSAppleEventDescriptor *)replyEvent
+{
+ tkMacOSXProcessFiles(event, replyEvent, _eventInterp, "::tk::mac::PrintDocument");
+}
- if (!interp ||
- !Tcl_FindCommand(interp, "::tk::mac::OpenDocument", NULL, 0)) {
- return noErr;
- }
+- (void) handleDoScriptEvent: (NSAppleEventDescriptor *)event
+ withReplyEvent: (NSAppleEventDescriptor *)replyEvent
+{
+ OSStatus err;
+ const AEDesc *theDesc = nil;
+ DescType type = 0, initialType = 0;
+ Size actual;
+ int tclErr = -1;
+ char URLBuffer[1 + URL_MAX_LENGTH];
+ char errString[128];
+ char typeString[5];
/*
- * If we get any errors while retrieving our parameters we just return with
- * no error.
+ * The DoScript event receives one parameter that should be text data or a
+ * fileURL.
*/
- if (ChkErr(AEGetParamDesc, event, keyDirectObject, typeAEList,
- &fileSpecList) != noErr) {
- return noErr;
+ theDesc = [event aeDesc];
+ if (theDesc == nil) {
+ return;
}
- if (MissedAnyParameters(event) != noErr) {
- return noErr;
- }
- if (ChkErr(AECountItems, &fileSpecList, &count) != noErr) {
- return noErr;
+
+ err = AEGetParamPtr(theDesc, keyDirectObject, typeWildCard, &initialType,
+ NULL, 0, NULL);
+ if (err != noErr) {
+ sprintf(errString, "AEDoScriptHandler: GetParamDesc error %d", (int)err);
+ AEPutParamPtr((AppleEvent*)[replyEvent aeDesc], keyErrorString, typeChar,
+ errString, strlen(errString));
+ return;
}
- /*
- * Convert our parameters into a script to evaluate, skipping things that
- * we can't handle right.
- */
+ if (MissedAnyParameters((AppleEvent*)theDesc)) {
+ sprintf(errString, "AEDoScriptHandler: extra parameters");
+ AEPutParamPtr((AppleEvent*)[replyEvent aeDesc], keyErrorString, typeChar,
+ errString, strlen(errString));
+ return;
+ }
- Tcl_DStringInit(&command);
- Tcl_DStringAppend(&command, "::tk::mac::OpenDocument", -1);
- for (index = 1; index <= count; index++) {
- if (ChkErr(AEGetNthPtr, &fileSpecList, index, typeFSRef, &keyword,
- &type, (Ptr) &file, sizeof(FSRef), &actual) != noErr) {
- continue;
+ if (initialType == typeFileURL || initialType == typeAlias) {
+ /*
+ * The descriptor can be coerced to a file url. Source the file, or
+ * pass the path as a string argument to ::tk::mac::DoScriptFile if
+ * that procedure exists.
+ */
+ err = AEGetParamPtr(theDesc, keyDirectObject, typeFileURL, &type,
+ (Ptr) URLBuffer, URL_MAX_LENGTH, &actual);
+ if (err == noErr && actual > 0){
+ URLBuffer[actual] = '\0';
+ NSString *urlString = [NSString stringWithUTF8String:(char*)URLBuffer];
+ NSURL *fileURL = [NSURL URLWithString:urlString];
+ Tcl_DString command;
+ Tcl_DStringInit(&command);
+ if (Tcl_FindCommand(_eventInterp, "::tk::mac::DoScriptFile", NULL, 0)){
+ Tcl_DStringAppend(&command, "::tk::mac::DoScriptFile", -1);
+ } else {
+ Tcl_DStringAppend(&command, "source", -1);
+ }
+ Tcl_DStringAppendElement(&command, [[fileURL path] UTF8String]);
+ tclErr = Tcl_EvalEx(_eventInterp, Tcl_DStringValue(&command),
+ Tcl_DStringLength(&command), TCL_EVAL_GLOBAL);
}
-
- if (ChkErr(FSRefToDString, &file, &pathName) == noErr) {
- Tcl_DStringAppendElement(&command, Tcl_DStringValue(&pathName));
- Tcl_DStringFree(&pathName);
+ } else if (noErr == AEGetParamPtr(theDesc, keyDirectObject, typeUTF8Text, &type,
+ NULL, 0, &actual)) {
+ if (actual > 0) {
+ /*
+ * The descriptor can be coerced to UTF8 text. Evaluate as Tcl, or
+ * or pass the text as a string argument to ::tk::mac::DoScriptText
+ * if that procedure exists.
+ */
+ char *data = ckalloc(actual + 1);
+ if (noErr == AEGetParamPtr(theDesc, keyDirectObject, typeUTF8Text, &type,
+ data, actual, NULL)) {
+ if (Tcl_FindCommand(_eventInterp, "::tk::mac::DoScriptText", NULL, 0)){
+ Tcl_DString command;
+ Tcl_DStringInit(&command);
+ Tcl_DStringAppend(&command, "::tk::mac::DoScriptText", -1);
+ Tcl_DStringAppendElement(&command, data);
+ tclErr = Tcl_EvalEx(_eventInterp, Tcl_DStringValue(&command),
+ Tcl_DStringLength(&command), TCL_EVAL_GLOBAL);
+ } else {
+ tclErr = Tcl_EvalEx(_eventInterp, data, actual, TCL_EVAL_GLOBAL);
+ }
+ }
+ ckfree(data);
+ }
+ } else {
+ /*
+ * The descriptor can not be coerced to a fileURL or UTF8 text.
+ */
+ for (int i = 0; i < 4; i++) {
+ typeString[i] = ((char*)&initialType)[3-i];
}
+ typeString[4] = '\0';
+ sprintf(errString, "AEDoScriptHandler: invalid script type '%s', "
+ "must be coercable to 'furl' or 'utf8'", typeString);
+ AEPutParamPtr((AppleEvent*)[replyEvent aeDesc], keyErrorString, typeChar, errString,
+ strlen(errString));
}
-
/*
- * Now handle the event by evaluating a script.
+ * If we ran some Tcl code, put the result in the reply.
*/
-
- code = Tcl_EvalEx(interp, Tcl_DStringValue(&command),
- Tcl_DStringLength(&command), TCL_EVAL_GLOBAL);
- if (code != TCL_OK) {
- Tcl_BackgroundException(interp, code);
+ if (tclErr >= 0) {
+ int reslen;
+ const char *result =
+ Tcl_GetStringFromObj(Tcl_GetObjResult(_eventInterp), &reslen);
+ if (tclErr == TCL_OK) {
+ AEPutParamPtr((AppleEvent*)[replyEvent aeDesc], keyDirectObject, typeChar,
+ result, reslen);
+ } else {
+ AEPutParamPtr((AppleEvent*)[replyEvent aeDesc], keyErrorString, typeChar,
+ result, reslen);
+ AEPutParamPtr((AppleEvent*)[replyEvent aeDesc], keyErrorNumber, typeSInt32,
+ (Ptr) &tclErr,sizeof(int));
+ }
}
- Tcl_DStringFree(&command);
- return noErr;
+ return;
}
-
+@end
+
+#pragma mark -
+
/*
*----------------------------------------------------------------------
*
- * PrintHandler --
+ * TkMacOSXProcessFiles --
*
- * This is the 'pdoc' core Apple event handler.
+ * Extract a list of fileURLs from an AppleEvent and call the specified
+ * procedure with the file paths as arguments.
*
* Results:
* None.
*
* Side effects:
- * None.
+ * The event is handled by running the procedure.
*
*----------------------------------------------------------------------
*/
-static OSErr
-PrintHandler(
- const AppleEvent * event,
- AppleEvent * reply,
- SRefCon handlerRefcon)
+static void
+tkMacOSXProcessFiles(
+ NSAppleEventDescriptor* event,
+ NSAppleEventDescriptor* replyEvent,
+ Tcl_Interp *interp,
+ char* procedure)
{
- Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon;
- AEDescList fileSpecList;
- FSRef file;
+ Tcl_Encoding utf8 = Tcl_GetEncoding(NULL, "utf-8");
+ const AEDesc *fileSpecDesc = nil;
+ AEDesc contents;
+ char URLString[1 + URL_MAX_LENGTH];
+ NSURL *fileURL;
DescType type;
Size actual;
long count, index;
@@ -423,47 +292,67 @@ PrintHandler(
int code;
/*
- * Don't bother if we don't have an interp or the print document procedure
- * doesn't exist.
+ * Do nothing if we don't have an interpreter or the procedure doesn't exist.
*/
- if (!interp ||
- !Tcl_FindCommand(interp, "::tk::mac::PrintDocument", NULL, 0)) {
- return noErr;
+ if (!interp || !Tcl_FindCommand(interp, procedure, NULL, 0)) {
+ return;
+ }
+
+ fileSpecDesc = [event aeDesc];
+ if (fileSpecDesc == nil ) {
+ return;
}
/*
- * If we get any errors while retrieving our parameters we just return with
- * no error.
+ * The AppleEvent's descriptor should either contain a value of
+ * typeObjectSpecifier or typeAEList. In the first case, the descriptor
+ * can be treated as a list of size 1 containing a value which can be
+ * coerced into a fileURL. In the second case we want to work with the list
+ * itself. Values in the list will be coerced into fileURL's if possible;
+ * otherwise they will be ignored.
*/
- if (ChkErr(AEGetParamDesc, event, keyDirectObject, typeAEList,
- &fileSpecList) != noErr) {
- return noErr;
- }
- if (ChkErr(MissedAnyParameters, event) != noErr) {
- return noErr;
+ /* Get a copy of the AppleEvent's descriptor. */
+ AEGetParamDesc(fileSpecDesc, keyDirectObject, typeWildCard, &contents);
+ if (contents.descriptorType == typeAEList) {
+ fileSpecDesc = &contents;
}
- if (ChkErr(AECountItems, &fileSpecList, &count) != noErr) {
- return noErr;
+
+ if (AECountItems(fileSpecDesc, &count) != noErr) {
+ AEDisposeDesc(&contents);
+ return;
}
+ /*
+ * Construct a Tcl command which calls the procedure, passing the
+ * paths contained in the AppleEvent as arguments.
+ */
+
Tcl_DStringInit(&command);
- Tcl_DStringAppend(&command, "::tk::mac::PrintDocument", -1);
+ Tcl_DStringAppend(&command, procedure, -1);
+
for (index = 1; index <= count; index++) {
- if (ChkErr(AEGetNthPtr, &fileSpecList, index, typeFSRef, &keyword,
- &type, (Ptr) &file, sizeof(FSRef), &actual) != noErr) {
+ if (noErr != AEGetNthPtr(fileSpecDesc, index, typeFileURL, &keyword,
+ &type, (Ptr) URLString, URL_MAX_LENGTH, &actual)) {
continue;
}
-
- if (ChkErr(FSRefToDString, &file, &pathName) == noErr) {
- Tcl_DStringAppendElement(&command, Tcl_DStringValue(&pathName));
- Tcl_DStringFree(&pathName);
+ if (type != typeFileURL) {
+ continue;
+ }
+ URLString[actual] = '\0';
+ fileURL = [NSURL URLWithString:[NSString stringWithUTF8String:(char*)URLString]];
+ if (fileURL == nil) {
+ continue;
}
+ Tcl_ExternalToUtfDString(utf8, [[fileURL path] UTF8String], -1, &pathName);
+ Tcl_DStringAppendElement(&command, Tcl_DStringValue(&pathName));
+ Tcl_DStringFree(&pathName);
}
+ AEDisposeDesc(&contents);
/*
- * Now handle the event by evaluating a script.
+ * Handle the event by evaluating the Tcl expression we constructed.
*/
code = Tcl_EvalEx(interp, Tcl_DStringValue(&command),
@@ -472,18 +361,19 @@ PrintHandler(
Tcl_BackgroundException(interp, code);
}
Tcl_DStringFree(&command);
- return noErr;
+ return;
}
/*
*----------------------------------------------------------------------
*
- * ScriptHandler --
+ * TkMacOSXInitAppleEvents --
*
- * This handler process the script event.
+ * Register AppleEvent handlers with the NSAppleEventManager for
+ * this NSApplication.
*
* Results:
- * Schedules the given event to be processed.
+ * None.
*
* Side effects:
* None.
@@ -491,112 +381,91 @@ PrintHandler(
*----------------------------------------------------------------------
*/
-static OSErr
-ScriptHandler(
- const AppleEvent *event,
- AppleEvent *reply,
- SRefCon handlerRefcon)
+void
+TkMacOSXInitAppleEvents(
+ Tcl_Interp *interp) /* not used */
{
- OSStatus theErr;
- AEDescList theDesc;
- Size size;
- int tclErr = -1;
- Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon;
- char errString[128];
+ NSAppleEventManager *aeManager = [NSAppleEventManager sharedAppleEventManager];
+ static Boolean initialized = FALSE;
- /*
- * The do script event receives one parameter that should be data or a
- * file.
- */
+ if (!initialized) {
+ initialized = TRUE;
- theErr = AEGetParamDesc(event, keyDirectObject, typeWildCard,
- &theDesc);
- if (theErr != noErr) {
- sprintf(errString, "AEDoScriptHandler: GetParamDesc error %d",
- (int)theErr);
- theErr = AEPutParamPtr(reply, keyErrorString, typeChar, errString,
- strlen(errString));
- } else if (MissedAnyParameters(event)) {
- /*
- * Return error if parameter is missing.
- */
+ [aeManager setEventHandler:NSApp
+ andSelector:@selector(handleQuitApplicationEvent:withReplyEvent:)
+ forEventClass:kCoreEventClass andEventID:kAEQuitApplication];
- sprintf(errString, "AEDoScriptHandler: extra parameters");
- AEPutParamPtr(reply, keyErrorString, typeChar, errString,
- strlen(errString));
- theErr = -1771;
- } else if (theDesc.descriptorType == (DescType) typeAlias &&
- AEGetParamPtr(event, keyDirectObject, typeFSRef, NULL, NULL,
- 0, &size) == noErr && size == sizeof(FSRef)) {
- /*
- * We've had a file sent to us. Source it.
- */
+ [aeManager setEventHandler:NSApp
+ andSelector:@selector(handleOpenApplicationEvent:withReplyEvent:)
+ forEventClass:kCoreEventClass andEventID:kAEOpenApplication];
- FSRef file;
- theErr = AEGetParamPtr(event, keyDirectObject, typeFSRef, NULL, &file,
- size, NULL);
- if (theErr == noErr) {
- Tcl_DString scriptName;
+ [aeManager setEventHandler:NSApp
+ andSelector:@selector(handleReopenApplicationEvent:withReplyEvent:)
+ forEventClass:kCoreEventClass andEventID:kAEReopenApplication];
- theErr = FSRefToDString(&file, &scriptName);
- if (theErr == noErr) {
- Tcl_Obj *pathName =
- Tcl_NewStringObj(Tcl_DStringValue(&scriptName), -1);
- Tcl_DStringFree(&scriptName);
+ [aeManager setEventHandler:NSApp
+ andSelector:@selector(handleShowPreferencesEvent:withReplyEvent:)
+ forEventClass:kCoreEventClass andEventID:kAEShowPreferences];
- tclErr = Tcl_FSEvalFile(interp, pathName);
- Tcl_DecrRefCount(pathName);
- } else {
- sprintf(errString, "AEDoScriptHandler: file not found");
- AEPutParamPtr(reply, keyErrorString, typeChar, errString,
- strlen(errString));
- }
- }
- } else if (AEGetParamPtr(event, keyDirectObject, typeUTF8Text, NULL, NULL,
- 0, &size) == noErr && size) {
- /*
- * We've had some data sent to us. Evaluate it.
- */
+ [aeManager setEventHandler:NSApp
+ andSelector:@selector(handleOpenDocumentsEvent:withReplyEvent:)
+ forEventClass:kCoreEventClass andEventID:kAEOpenDocuments];
- char *data = ckalloc(size + 1);
- theErr = AEGetParamPtr(event, keyDirectObject, typeUTF8Text, NULL, data,
- size, NULL);
- if (theErr == noErr) {
- tclErr = Tcl_EvalEx(interp, data, size, TCL_EVAL_GLOBAL);
- }
- } else {
- /*
- * Umm, don't recognize what we've got...
- */
+ [aeManager setEventHandler:NSApp
+ andSelector:@selector(handleOpenDocumentsEvent:withReplyEvent:)
+ forEventClass:kCoreEventClass andEventID:kAEPrintDocuments];
- sprintf(errString, "AEDoScriptHandler: invalid script type '%-4.4s', "
- "must be 'alis' or coercable to 'utf8'",
- (char*) &theDesc.descriptorType);
- AEPutParamPtr(reply, keyErrorString, typeChar, errString,
- strlen(errString));
- theErr = -1770;
+ [aeManager setEventHandler:NSApp
+ andSelector:@selector(handleDoScriptEvent:withReplyEvent:)
+ forEventClass:kAEMiscStandards andEventID:kAEDoScript];
}
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXDoHLEvent --
+ *
+ * Dispatch an AppleEvent.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Depend on the AppleEvent.
+ *
+ *----------------------------------------------------------------------
+ */
- /*
- * If we actually go to run Tcl code - put the result in the reply.
+int
+TkMacOSXDoHLEvent(
+ void *theEvent)
+{
+ /* According to the NSAppleEventManager reference:
+ * "The theReply parameter always specifies a reply Apple event, never
+ * nil. However, the handler should not fill out the reply if the
+ * descriptor type for the reply event is typeNull, indicating the sender
+ * does not want a reply."
+ * The specified way to build such a non-nil descriptor is used here. But
+ * on OSX 10.11, the compiler nonetheless generates a warning. I am
+ * supressing the warning here -- maybe the warnings will stop in a future
+ * compiler release.
*/
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
+#endif
- if (tclErr >= 0) {
- int reslen;
- const char *result =
- Tcl_GetStringFromObj(Tcl_GetObjResult(interp), &reslen);
+ NSAppleEventDescriptor* theReply = [NSAppleEventDescriptor nullDescriptor];
+ NSAppleEventManager *aeManager = [NSAppleEventManager sharedAppleEventManager];
- if (tclErr == TCL_OK) {
- AEPutParamPtr(reply, keyDirectObject, typeChar, result, reslen);
- } else {
- AEPutParamPtr(reply, keyErrorString, typeChar, result, reslen);
- AEPutParamPtr(reply, keyErrorNumber, typeSInt32, (Ptr) &tclErr,
- sizeof(int));
- }
- }
+ return [aeManager dispatchRawAppleEvent:(const AppleEvent*)theEvent
+ withRawReply: (AppleEvent *)theReply
+ handlerRefCon: (SRefCon)0];
- AEDisposeDesc(&theDesc);
- return theErr;
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
}
/*
@@ -604,8 +473,8 @@ ScriptHandler(
*
* ReallyKillMe --
*
- * This proc tries to kill the shell by running exit, called from an
- * event scheduled by the "Quit" AppleEvent handler.
+ * This procedure tries to kill the shell by running exit, called from
+ * an event scheduled by the "Quit" AppleEvent handler.
*
* Results:
* Runs the "exit" command which might kill the shell.
@@ -665,37 +534,7 @@ MissedAnyParameters(
return (err != errAEDescNotFound);
}
-/*
- *----------------------------------------------------------------------
- *
- * FSRefToDString --
- *
- * Get a POSIX path from an FSRef.
- *
- * Results:
- * In the parameter ds.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-static OSStatus
-FSRefToDString(
- const FSRef *fsref,
- Tcl_DString *ds)
-{
- UInt8 fileName[PATH_MAX+1];
- OSStatus err;
- err = ChkErr(FSRefMakePath, fsref, fileName, sizeof(fileName));
- if (err == noErr) {
- Tcl_ExternalToUtfDString(NULL, (char*) fileName, -1, ds);
- }
- return err;
-}
-
/*
* Local Variables:
* mode: objc
diff --git a/macosx/tkMacOSXInit.c b/macosx/tkMacOSXInit.c
index 6a881d3..33a60f2 100644
--- a/macosx/tkMacOSXInit.c
+++ b/macosx/tkMacOSXInit.c
@@ -28,7 +28,6 @@ static char tkLibPath[PATH_MAX + 1] = "";
static char scriptPath[PATH_MAX + 1] = "";
-int tkMacOSXGCEnabled = 0;
long tkMacOSXMacOSXVersion = 0;
#pragma mark TKApplication(TKInit)
@@ -58,9 +57,17 @@ static void keyboardChanged(CFNotificationCenterRef center, void *observer, CFSt
@end
@implementation TKApplication
+@synthesize poolProtected = _poolProtected;
@end
@implementation TKApplication(TKInit)
+- (void) _resetAutoreleasePool
+{
+ if(![self poolProtected]) {
+ [_mainPool drain];
+ _mainPool = [NSAutoreleasePool new];
+ }
+}
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
- (void) _postedNotification: (NSNotification *) notification
{
@@ -87,15 +94,17 @@ static void keyboardChanged(CFNotificationCenterRef center, void *observer, CFSt
- (void) _setupEventLoop
{
-
- /*Remove private API flags here.*/
+ NSAutoreleasePool *pool = [NSAutoreleasePool new];
[self finishLaunching];
[self setWindowsNeedUpdate:YES];
+ [pool drain];
}
- (void) _setup: (Tcl_Interp *) interp
{
_eventInterp = interp;
+ _mainPool = [NSAutoreleasePool new];
+ [NSApp setPoolProtected:NO];
_defaultMainMenu = nil;
[self _setupMenus];
[self setDelegate:self];
@@ -110,7 +119,7 @@ static void keyboardChanged(CFNotificationCenterRef center, void *observer, CFSt
- (NSString *) tkFrameworkImagePath: (NSString *) image
{
NSString *path = nil;
-
+ NSAutoreleasePool *pool = [NSAutoreleasePool new];
if (tkLibPath[0] != '\0') {
path = [[NSBundle bundleWithPath:[[NSString stringWithUTF8String:
tkLibPath] stringByAppendingString:@"/../.."]]
@@ -143,6 +152,8 @@ static void keyboardChanged(CFNotificationCenterRef center, void *observer, CFSt
}
}
#endif
+ [path retain];
+ [pool drain];
return path;
}
@end
@@ -169,6 +180,7 @@ static void
SetApplicationIcon(
ClientData clientData)
{
+ NSAutoreleasePool *pool = [NSAutoreleasePool new];
NSString *path = [NSApp tkFrameworkImagePath:@"Tk.icns"];
if (path) {
NSImage *image = [[NSImage alloc] initWithContentsOfFile:path];
@@ -177,6 +189,7 @@ SetApplicationIcon(
[image release];
}
}
+ [pool drain];
}
/*
@@ -254,20 +267,19 @@ TkpInit(
}
#endif
- static NSAutoreleasePool *pool = nil;
- if (!pool) {
- pool = [NSAutoreleasePool new];
+ {
+ NSAutoreleasePool *pool = [NSAutoreleasePool new];
+ [[NSUserDefaults standardUserDefaults] registerDefaults:
+ [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithBool:YES],
+ @"_NSCanWrapButtonTitles",
+ [NSNumber numberWithInt:-1],
+ @"NSStringDrawingTypesetterBehavior",
+ nil]];
+ [TKApplication sharedApplication];
+ [pool drain];
+ [NSApp _setup:interp];
}
- tkMacOSXGCEnabled = ([NSGarbageCollector defaultCollector] != nil);
- [[NSUserDefaults standardUserDefaults] registerDefaults:
- [NSDictionary dictionaryWithObjectsAndKeys:
- [NSNumber numberWithBool:YES],
- @"_NSCanWrapButtonTitles",
- [NSNumber numberWithInt:-1],
- @"NSStringDrawingTypesetterBehavior",
- nil]];
- [TKApplication sharedApplication];
- [NSApp _setup:interp];
/* Check whether we are a bundled executable: */
bundleRef = CFBundleGetMainBundle();
@@ -324,12 +336,14 @@ TkpInit(
Tcl_DoWhenIdle(SetApplicationIcon, NULL);
}
- [NSApp _setupEventLoop];
- TkMacOSXInitAppleEvents(interp);
- TkMacOSXUseAntialiasedText(interp, -1);
- TkMacOSXInitCGDrawing(interp, TRUE, 0);
- [pool drain];
- pool = [NSAutoreleasePool new];
+ {
+ NSAutoreleasePool *pool = [NSAutoreleasePool new];
+ [NSApp _setupEventLoop];
+ TkMacOSXInitAppleEvents(interp);
+ TkMacOSXUseAntialiasedText(interp, -1);
+ TkMacOSXInitCGDrawing(interp, TRUE, 0);
+ [pool drain];
+ }
/*
* FIXME: Close stdin & stdout for remote debugging otherwise we will
@@ -486,9 +500,8 @@ TkpDisplayWarning(
MODULE_SCOPE void
TkMacOSXDefaultStartupScript(void)
{
- CFBundleRef bundleRef;
-
- bundleRef = CFBundleGetMainBundle();
+ NSAutoreleasePool *pool = [NSAutoreleasePool new];
+ CFBundleRef bundleRef = CFBundleGetMainBundle();
if (bundleRef != NULL) {
CFURLRef appMainURL = CFBundleCopyResourceURL(bundleRef,
@@ -512,6 +525,7 @@ TkMacOSXDefaultStartupScript(void)
CFRelease(appMainURL);
}
}
+ [pool drain];
}
/*
diff --git a/macosx/tkMacOSXInt.h b/macosx/tkMacOSXInt.h
index 249d5cf..6971e26 100644
--- a/macosx/tkMacOSXInt.h
+++ b/macosx/tkMacOSXInt.h
@@ -86,7 +86,7 @@ typedef struct TkWindowPrivate MacDrawable;
#define TK_FOCUSED_VIEW 0x10
#define TK_IS_PIXMAP 0x20
#define TK_IS_BW_PIXMAP 0x40
-
+#define TK_DO_NOT_DRAW 0x80
/*
* I am reserving TK_EMBEDDED = 0x100 in the MacDrawable flags
* This is defined in tk.h. We need to duplicate the TK_EMBEDDED flag in the
diff --git a/macosx/tkMacOSXKeyEvent.c b/macosx/tkMacOSXKeyEvent.c
index c9ad9f1..151b4f2 100644
--- a/macosx/tkMacOSXKeyEvent.c
+++ b/macosx/tkMacOSXKeyEvent.c
@@ -7,6 +7,7 @@
* Copyright 2001-2009, Apple Inc.
* Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
* Copyright (c) 2012 Adrian Robert.
+ * Copyright 2015 Marc Culler.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -27,7 +28,9 @@ static Tk_Window grabWinPtr = NULL;
/* Current grab window, NULL if no grab. */
static Tk_Window keyboardGrabWinPtr = NULL;
/* Current keyboard grab window. */
-static NSModalSession modalSession = NULL;
+static NSWindow *keyboardGrabNSWindow = nil;
+ /* NSWindow for the current keyboard grab window. */
+static NSModalSession modalSession = nil;
static BOOL processingCompose = NO;
static BOOL finishedCompose = NO;
@@ -78,16 +81,18 @@ static unsigned isFunctionKey(unsigned int code);
case NSFlagsChanged:
modifiers = [theEvent modifierFlags];
keyCode = [theEvent keyCode];
- w = [self windowWithWindowNumber:[theEvent windowNumber]];
+ // w = [self windowWithWindowNumber:[theEvent windowNumber]];
+ w = [theEvent window];
#if defined(TK_MAC_DEBUG_EVENTS) || NS_KEYLOG == 1
NSLog(@"-[%@(%p) %s] r=%d mods=%u '%@' '%@' code=%u c=%d %@ %d", [self class], self, _cmd, repeat, modifiers, characters, charactersIgnoringModifiers, keyCode,([charactersIgnoringModifiers length] == 0) ? 0 : [charactersIgnoringModifiers characterAtIndex: 0], w, type);
#endif
break;
default:
- return theEvent;
+ return theEvent; /* Unrecognized key event. */
}
+ /* Create an Xevent to add to the Tk queue. */
if (!processingCompose) {
unsigned int state = 0;
@@ -128,7 +133,7 @@ static unsigned isFunctionKey(unsigned int code);
tkwin = (Tk_Window) winPtr->dispPtr->focusPtr;
if (!tkwin) {
TkMacOSXDbgMsg("tkwin == NULL");
- return theEvent;
+ return theEvent; /* Give up. No window for this event. */
}
/*
@@ -222,7 +227,7 @@ static unsigned isFunctionKey(unsigned int code);
-@implementation TKContentView(TKKeyEvent)
+@implementation TKContentView
/* <NSTextInput> implementation (called through interpretKeyEvents:]). */
/* <NSTextInput>: called when done composing;
@@ -288,22 +293,6 @@ static unsigned isFunctionKey(unsigned int code);
}
-/* delete display of composing characters [not in <NSTextInput>] */
-- (void)deleteWorkingText
-{
- if (privateWorkingText == nil)
- return;
- if (NS_KEYLOG)
- NSLog(@"deleteWorkingText len = %lu\n",
- (unsigned long)[privateWorkingText length]);
- [privateWorkingText release];
- privateWorkingText = nil;
- processingCompose = NO;
-
- //PENDING: delete working text
-}
-
-
- (BOOL)hasMarkedText
{
return privateWorkingText != nil;
@@ -339,7 +328,7 @@ static unsigned isFunctionKey(unsigned int code);
pt.y = caret_y;
pt = [self convertPoint: pt toView: nil];
- pt = [[self window] convertBaseToScreen: pt];
+ pt = [[self window] convertPointToScreen: pt];
pt.y -= caret_height;
rect.origin = pt;
@@ -413,6 +402,24 @@ static unsigned isFunctionKey(unsigned int code);
@end
+@implementation TKContentView(TKKeyEvent)
+/* delete display of composing characters [not in <NSTextInput>] */
+- (void)deleteWorkingText
+{
+ if (privateWorkingText == nil)
+ return;
+ if (NS_KEYLOG)
+ NSLog(@"deleteWorkingText len = %lu\n",
+ (unsigned long)[privateWorkingText length]);
+ [privateWorkingText release];
+ privateWorkingText = nil;
+ processingCompose = NO;
+
+ //PENDING: delete working text
+}
+@end
+
+
/*
* Set up basic fields in xevent for keyboard input.
@@ -474,7 +481,9 @@ XGrabKeyboard(
if (modalSession) {
Tcl_Panic("XGrabKeyboard: already grabbed");
}
- modalSession = [NSApp beginModalSessionForWindow:[w retain]];
+ keyboardGrabNSWindow = w;
+ [w retain];
+ modalSession = [NSApp beginModalSessionForWindow:w];
}
}
return GrabSuccess;
@@ -502,11 +511,12 @@ XUngrabKeyboard(
Time time)
{
if (modalSession) {
- NSWindow *w = keyboardGrabWinPtr ? TkMacOSXDrawableWindow(
- ((TkWindow *) keyboardGrabWinPtr)->window) : nil;
[NSApp endModalSession:modalSession];
- [w release];
- modalSession = NULL;
+ modalSession = nil;
+ }
+ if (keyboardGrabNSWindow) {
+ [keyboardGrabNSWindow release];
+ keyboardGrabNSWindow = nil;
}
keyboardGrabWinPtr = NULL;
}
diff --git a/macosx/tkMacOSXMenu.c b/macosx/tkMacOSXMenu.c
index 85e1d6c..c7e3a78 100644
--- a/macosx/tkMacOSXMenu.c
+++ b/macosx/tkMacOSXMenu.c
@@ -258,9 +258,10 @@ static int ModifierCharWidth(Tk_Font tkfont);
if (menuPtr && mePtr) {
Tcl_Interp *interp = menuPtr->interp;
- /*Add time for errors to fire if necessary. This is sub-optimal but avoids issues with Tcl/Cocoa event loop integration.*/
+ /*Add time for errors to fire if necessary. This is sub-optimal
+ *but avoids issues with Tcl/Cocoa event loop integration.
+ */
Tcl_Sleep(100);
-
Tcl_Preserve(interp);
Tcl_Preserve(menuPtr);
@@ -411,7 +412,7 @@ static int ModifierCharWidth(Tk_Font tkfont);
if (!mePtr || !(mePtr->entryFlags & ENTRY_APPLE_MENU)) {
applicationMenuItem = [NSMenuItem itemWithSubmenu:
- [[_defaultApplicationMenu copy] autorelease]];
+ [_defaultApplicationMenu copy]];
[menu insertItem:applicationMenuItem atIndex:0];
}
[menu setSpecial:tkMainMenu];
@@ -419,7 +420,7 @@ static int ModifierCharWidth(Tk_Font tkfont);
applicationMenu = (TKMenu *)[applicationMenuItem submenu];
if (![applicationMenu isSpecial:tkApplicationMenu]) {
for (NSMenuItem *item in _defaultApplicationMenuItems) {
- [applicationMenu addItem:[[item copy] autorelease]];
+ [applicationMenu addItem:[item copy]];
}
[applicationMenu setSpecial:tkApplicationMenu];
}
@@ -429,15 +430,13 @@ static int ModifierCharWidth(Tk_Font tkfont);
for (NSMenuItem *item in itemArray) {
TkMenuEntry *mePtr = (TkMenuEntry *)[item tag];
TKMenu *submenu = (TKMenu *)[item submenu];
-
if (mePtr && submenu) {
if ((mePtr->entryFlags & ENTRY_WINDOWS_MENU) &&
![submenu isSpecial:tkWindowsMenu]) {
NSInteger index = 0;
for (NSMenuItem *i in _defaultWindowsMenuItems) {
- [submenu insertItem:[[i copy] autorelease] atIndex:
- index++];
+ [submenu insertItem:[i copy] atIndex:index++];
}
[self setWindowsMenu:submenu];
[submenu setSpecial:tkWindowsMenu];
@@ -446,8 +445,7 @@ static int ModifierCharWidth(Tk_Font tkfont);
NSInteger index = 0;
for (NSMenuItem *i in _defaultHelpMenuItems) {
- [submenu insertItem:[[i copy] autorelease] atIndex:
- index++];
+ [submenu insertItem:[i copy] atIndex:index++];
}
[submenu setSpecial:tkHelpMenu];
}
@@ -496,8 +494,7 @@ TkpNewMenu(
* platform structure for. */
{
TKMenu *menu = [[TKMenu alloc] initWithTkMenu:menuPtr];
- menuPtr->platformData = (TkMenuPlatformData)
- TkMacOSXMakeUncollectable(menu);
+ menuPtr->platformData = (TkMenuPlatformData) menu;
CheckForSpecialMenu(menuPtr);
return TCL_OK;
}
@@ -522,7 +519,10 @@ void
TkpDestroyMenu(
TkMenu *menuPtr) /* The common menu structure */
{
- TkMacOSXMakeCollectableAndRelease(menuPtr->platformData);
+ NSMenu* nsmenu = (NSMenu*)(menuPtr->platformData);
+
+ [nsmenu release];
+ menuPtr->platformData = NULL;
}
/*
@@ -555,8 +555,7 @@ TkpMenuNewEntry(
} else {
menuItem = [menu newTkMenuItem:mePtr];
}
- mePtr->platformEntryData = (TkMenuPlatformEntryData)
- TkMacOSXMakeUncollectable(menuItem);
+ mePtr->platformEntryData = (TkMenuPlatformEntryData) menuItem;
/*
* Caller TkMenuEntry() already did this same insertion into the generic
@@ -720,16 +719,21 @@ void
TkpDestroyMenuEntry(
TkMenuEntry *mePtr)
{
+ NSMenuItem *menuItem;
+ TKMenu *menu;
+ NSInteger index;
+
if (mePtr->platformEntryData && mePtr->menuPtr->platformData) {
- TKMenu *menu = (TKMenu *) mePtr->menuPtr->platformData;
- NSMenuItem *menuItem = (NSMenuItem *) mePtr->platformEntryData;
- NSInteger index = [menu indexOfItem:menuItem];
+ menu = (TKMenu *) mePtr->menuPtr->platformData;
+ menuItem = (NSMenuItem *) mePtr->platformEntryData;
+ index = [menu indexOfItem:menuItem];
if (index > -1) {
[menu removeItemAtIndex:index];
}
+ [menuItem release];
+ mePtr->platformEntryData = NULL;
}
- TkMacOSXMakeCollectableAndRelease(mePtr->platformEntryData);
}
/*
@@ -777,7 +781,7 @@ TkpPostMenu(
NSRect frame = NSMakeRect(x + 9, tkMacOSXZeroScreenHeight - y - 9, 1, 1);
frame.origin = [view convertPoint:
- [win convertScreenToBase:frame.origin] fromView:nil];
+ [win convertPointFromScreen:frame.origin] fromView:nil];
NSMenu *menu = (NSMenu *) menuPtr->platformData;
NSPopUpButtonCell *popUpButtonCell = [[NSPopUpButtonCell alloc]
@@ -830,11 +834,16 @@ TkpSetWindowMenuBar(
* Puts the menu associated with a window into the menubar. Should only
* be called when the window is in front.
*
+ * This is a no-op on all other platforms. On OS X it is a no-op when
+ * passed a NULL menuName or a nonexistent menuName, with an exception
+ * for the first call in a new interpreter. In that special case, passing a
+ * NULL menuName installs the default menu.
+ *
* Results:
* None.
*
* Side effects:
- * The menubar is changed.
+ * The menubar may be changed.
*
*----------------------------------------------------------------------
*/
@@ -843,8 +852,7 @@ void
TkpSetMainMenubar(
Tcl_Interp *interp, /* The interpreter of the application */
Tk_Window tkwin, /* The frame we are setting up */
- const char *menuName) /* The name of the menu to put in front. If
- * NULL, use the default menu bar. */
+ const char *menuName) /* The name of the menu to put in front. */
{
static Tcl_Interp *currentInterp = NULL;
TKMenu *menu = nil;
diff --git a/macosx/tkMacOSXMouseEvent.c b/macosx/tkMacOSXMouseEvent.c
index 90d2d00..c4197f7 100644
--- a/macosx/tkMacOSXMouseEvent.c
+++ b/macosx/tkMacOSXMouseEvent.c
@@ -26,13 +26,22 @@ typedef struct {
static int GenerateButtonEvent(MouseEventData *medPtr);
static unsigned int ButtonModifiers2State(UInt32 buttonState,
- UInt32 keyModifiers);
+ UInt32 keyModifiers);
#pragma mark TKApplication(TKMouseEvent)
enum {
NSWindowWillMoveEventType = 20
};
+/*
+ * In OS X 10.6 an NSEvent of type NSMouseMoved would always have a non-Nil
+ * window attribute pointing to the active window. As of 10.8 this behavior
+ * had changed. The new behavior was that if the mouse were ever moved outside
+ * of a window, all subsequent NSMouseMoved NSEvents would have a Nil window
+ * attribute. To work around this the TKApplication remembers the last non-Nil
+ * window that it received in a mouse event. If it receives an NSEvent with a
+ * Nil window attribute then the saved window is used.
+ */
@implementation TKApplication(TKMouseEvent)
- (NSEvent *) tkProcessMouseEvent: (NSEvent *) theEvent
@@ -40,80 +49,72 @@ enum {
#ifdef TK_MAC_DEBUG_EVENTS
TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent);
#endif
- id win;
- NSEventType type = [theEvent type];
+ NSWindow* eventWindow = [theEvent window];
+ NSEventType eventType = [theEvent type];
#if 0
NSTrackingArea *trackingArea = nil;
NSInteger eventNumber, clickCount, buttonNumber;
#endif
-
- switch (type) {
+ switch (eventType) {
case NSMouseEntered:
case NSMouseExited:
case NSCursorUpdate:
-#if 0
- trackingArea = [theEvent trackingArea];
-#endif
- /* fall through */
case NSLeftMouseDown:
case NSLeftMouseUp:
case NSRightMouseDown:
case NSRightMouseUp:
case NSOtherMouseDown:
case NSOtherMouseUp:
-
case NSLeftMouseDragged:
case NSRightMouseDragged:
case NSOtherMouseDragged:
-
case NSMouseMoved:
-#if 0
- eventNumber = [theEvent eventNumber];
- if (!trackingArea) {
- clickCount = [theEvent clickCount];
- buttonNumber = [theEvent buttonNumber];
- }
-#endif
-
case NSTabletPoint:
case NSTabletProximity:
-
case NSScrollWheel:
- win = [self windowWithWindowNumber:[theEvent windowNumber]];
break;
-
- default:
+ default: /* Unrecognized mouse event. */
return theEvent;
- break;
}
- NSPoint global, local = [theEvent locationInWindow];
+ /* Remember the window in case we need it next time. */
+ if (eventWindow && eventWindow != _windowWithMouse) {
+ if (_windowWithMouse) {
+ [_windowWithMouse release];
+ }
+ _windowWithMouse = eventWindow;
+ [_windowWithMouse retain];
+ }
- if (win) {
- global = [win convertBaseToScreen:local];
- local.y = [win frame].size.height - local.y;
+ /* Create an Xevent to add to the Tk queue. */
+ NSPoint global, local = [theEvent locationInWindow];
+ if (eventWindow) { /* local will be in window coordinates. */
+ global = [eventWindow convertPointToScreen: local];
+ local.y = [eventWindow frame].size.height - local.y;
global.y = tkMacOSXZeroScreenHeight - global.y;
- } else {
- local.y = tkMacOSXZeroScreenHeight - local.y;
- global = local;
+ } else { /* local will be in screen coordinates. */
+ if (_windowWithMouse ) {
+ eventWindow = _windowWithMouse;
+ global = local;
+ local = [eventWindow convertPointFromScreen: local];
+ local.y = [eventWindow frame].size.height - local.y;
+ global.y = tkMacOSXZeroScreenHeight - global.y;
+ } else { /* We have no window. Use the screen???*/
+ local.y = tkMacOSXZeroScreenHeight - local.y;
+ global = local;
+ }
}
- Window window = TkMacOSXGetXWindow(win);
+ Window window = TkMacOSXGetXWindow(eventWindow);
Tk_Window tkwin = window ? Tk_IdToWindow(TkGetDisplayList()->display,
window) : NULL;
if (!tkwin) {
tkwin = TkMacOSXGetCapture();
}
if (!tkwin) {
- return theEvent;
+ return theEvent; /* Give up. No window for this event. */
}
- /*
- MacDrawable *macWin = (MacDrawable *) window;
- NSView *view = TkMacOSXDrawableView(macWin);
- local = [view convertPoint:local fromView:nil];
- local.y = NSHeight([view bounds]) - local.y;
- */
TkWindow *winPtr = (TkWindow *) tkwin;
local.x -= winPtr->wmInfoPtr->xInParent;
local.y -= winPtr->wmInfoPtr->yInParent;
@@ -127,12 +128,12 @@ enum {
EventRef eventRef = (EventRef)[theEvent eventRef];
UInt32 buttons;
OSStatus err = GetEventParameter(eventRef, kEventParamMouseChord,
- typeUInt32, NULL, sizeof(UInt32), NULL, &buttons);
+ typeUInt32, NULL, sizeof(UInt32), NULL, &buttons);
if (err == noErr) {
- state |= (buttons & ((1<<5) - 1)) << 8;
+ state |= (buttons & ((1<<5) - 1)) << 8;
} else if (button < 5) {
- switch (type) {
+ switch (eventType) {
case NSLeftMouseDown:
case NSRightMouseDown:
case NSLeftMouseDragged:
@@ -169,12 +170,12 @@ enum {
state |= Mod4Mask;
}
- if (type != NSScrollWheel) {
+ if (eventType != NSScrollWheel) {
#ifdef TK_MAC_DEBUG_EVENTS
TKLog(@"UpdatePointer %p x %f.0 y %f.0 %d", tkwin, global.x, global.y, state);
#endif
Tk_UpdatePointer(tkwin, global.x, global.y, state);
- } else {
+ } else { /* handle scroll wheel event */
CGFloat delta;
int coarseDelta;
XEvent xEvent;
@@ -190,7 +191,8 @@ enum {
delta = [theEvent deltaY];
if (delta != 0.0) {
- coarseDelta = (delta > -1.0 && delta < 1.0) ? (signbit(delta) ? -1 : 1) : lround(delta);
+ coarseDelta = (delta > -1.0 && delta < 1.0) ?
+ (signbit(delta) ? -1 : 1) : lround(delta);
xEvent.xbutton.state = state;
xEvent.xkey.keycode = coarseDelta;
xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
@@ -198,14 +200,14 @@ enum {
}
delta = [theEvent deltaX];
if (delta != 0.0) {
- coarseDelta = (delta > -1.0 && delta < 1.0) ? (signbit(delta) ? -1 : 1) : lround(delta);
+ coarseDelta = (delta > -1.0 && delta < 1.0) ?
+ (signbit(delta) ? -1 : 1) : lround(delta);
xEvent.xbutton.state = state | ShiftMask;
xEvent.xkey.keycode = coarseDelta;
xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
}
}
-
return theEvent;
}
@end
@@ -370,7 +372,7 @@ XQueryPointer(
if (win) {
NSPoint local;
- local = [win convertScreenToBase:global];
+ local = [win convertPointFromScreen:global];
local.y = [win frame].size.height - local.y;
if (macWin->winPtr && macWin->winPtr->wmInfoPtr) {
local.x -= macWin->winPtr->wmInfoPtr->xInParent;
@@ -468,7 +470,7 @@ TkGenerateButtonEvent(
if (win) {
NSPoint local = NSMakePoint(x, tkMacOSXZeroScreenHeight - y);
- local = [win convertScreenToBase:local];
+ local = [win convertPointFromScreen:local];
local.y = [win frame].size.height - local.y;
if (macWin->winPtr && macWin->winPtr->wmInfoPtr) {
local.x -= macWin->winPtr->wmInfoPtr->xInParent;
@@ -554,19 +556,18 @@ TkpWarpPointer(
}
/*
- * Tell the OSX core to generate the events to make it happen. This is
- * fairly ugly, but means that under most circumstances we'll register all
- * the events that would normally be generated correctly. If we use
- * CGWarpMouseCursorPosition instead, strange things happen.
+ * Tell the OSX core to generate the events to make it happen.
*/
- buttonState = (GetCurrentEvent() && Tk_MacOSXIsAppInFront())
- ? GetCurrentEventButtonState() : GetCurrentButtonState();
-
- CGPostMouseEvent(pt, 1 /* generate motion events */, 5,
- buttonState&1 ? 1 : 0, buttonState&2 ? 1 : 0,
- buttonState&4 ? 1 : 0, buttonState&8 ? 1 : 0,
- buttonState&16 ? 1 : 0);
+ buttonState = [NSEvent pressedMouseButtons];
+ CGEventType type = kCGEventMouseMoved;
+ CGEventRef theEvent = CGEventCreateMouseEvent(NULL,
+ type,
+ pt,
+ buttonState);
+ CGWarpMouseCursorPosition(pt);
+ CGEventPost(kCGHIDEventTap, theEvent);
+ CFRelease(theEvent);
}
/*
diff --git a/macosx/tkMacOSXNotify.c b/macosx/tkMacOSXNotify.c
index 3e0dfde..f14e1b8 100644
--- a/macosx/tkMacOSXNotify.c
+++ b/macosx/tkMacOSXNotify.c
@@ -7,6 +7,7 @@
* Copyright (c) 1995-1997 Sun Microsystems, Inc.
* Copyright 2001-2009, Apple Inc.
* Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
+ * Copyright 2015 Marc Culler.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -18,9 +19,9 @@
#include <pthread.h>
#import <objc/objc-auto.h>
+/* This is not used for anything at the moment. */
typedef struct ThreadSpecificData {
- int initialized, sendEventNestingLevel;
- NSEvent *currentEvent;
+ int initialized;
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
@@ -34,6 +35,7 @@ static void TkMacOSXEventsCheckProc(ClientData clientData, int flags);
#pragma mark TKApplication(TKNotify)
@interface NSApplication(TKNotify)
+/* We need to declare this hidden method. */
- (void) _modalSession: (NSModalSession) session sendEvent: (NSEvent *) event;
@end
@@ -48,41 +50,27 @@ static void TkMacOSXEventsCheckProc(ClientData clientData, int flags);
@end
@implementation TKApplication(TKNotify)
+/* Display all windows each time an event is removed from the queue.*/
- (NSEvent *) nextEventMatchingMask: (NSUInteger) mask
untilDate: (NSDate *) expiration inMode: (NSString *) mode
dequeue: (BOOL) deqFlag
{
- NSAutoreleasePool *pool = [NSAutoreleasePool new];
-
+ NSEvent *event = [super nextEventMatchingMask:mask
+ untilDate:expiration
+ inMode:mode
+ dequeue:deqFlag];
+ /* Retain this event for later use. Must be released.*/
+ [event retain];
[NSApp makeWindowsPerform:@selector(tkDisplayIfNeeded) inOrder:NO];
-
- int oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
- NSEvent *event = [[super nextEventMatchingMask:mask untilDate:expiration
- inMode:mode dequeue:deqFlag] retain];
-
- Tcl_SetServiceMode(oldMode);
- if (event) {
- TSD_INIT();
- if (tsdPtr->sendEventNestingLevel) {
- if (![NSApp tkProcessEvent:event]) {
- [event release];
- event = nil;
- }
- }
- }
- [pool drain];
- return [event autorelease];
+ return event;
}
+/*
+ * Call super then check the pasteboard.
+ */
- (void) sendEvent: (NSEvent *) theEvent
{
- TSD_INIT();
- int oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
-
- tsdPtr->sendEventNestingLevel++;
[super sendEvent:theEvent];
- tsdPtr->sendEventNestingLevel--;
- Tcl_SetServiceMode(oldMode);
[NSApp tkCheckPasteboard];
}
@end
@@ -161,7 +149,8 @@ Tk_MacOSXSetupTkNotifier(void)
"first [load] of TkAqua has to occur in the main thread!");
}
Tcl_CreateEventSource(TkMacOSXEventsSetupProc,
- TkMacOSXEventsCheckProc, GetMainEventQueue());
+ TkMacOSXEventsCheckProc,
+ GetMainEventQueue());
TkCreateExitHandler(TkMacOSXNotifyExitHandler, NULL);
Tcl_SetServiceMode(TCL_SERVICE_ALL);
TclMacOSXNotifierAddRunLoopMode(NSEventTrackingRunLoopMode);
@@ -194,7 +183,8 @@ TkMacOSXNotifyExitHandler(
TSD_INIT();
Tcl_DeleteEventSource(TkMacOSXEventsSetupProc,
- TkMacOSXEventsCheckProc, GetMainEventQueue());
+ TkMacOSXEventsCheckProc,
+ GetMainEventQueue());
tsdPtr->initialized = 0;
}
@@ -203,16 +193,19 @@ TkMacOSXNotifyExitHandler(
*
* TkMacOSXEventsSetupProc --
*
- * This procedure implements the setup part of the TkAqua Events event
- * source. It is invoked by Tcl_DoOneEvent before entering the notifier
- * to check for events.
+ * This procedure implements the setup part of the MacOSX event
+ * source. It is invoked by Tcl_DoOneEvent before calling
+ * TkMacOSXEventsProc to process all queued NSEvents. In our
+ * case, all we need to do is to set the Tcl MaxBlockTime to
+ * 0 before starting the loop to process all queued NSEvents.
*
* Results:
* None.
*
* Side effects:
- * If TkAqua events are queued, then the maximum block time will be set
- * to 0 to ensure that the notifier returns control to Tcl.
+ *
+ * If NSEvents are queued, then the maximum block time will be set
+ * to 0 to ensure that control returns immediately to Tcl.
*
*----------------------------------------------------------------------
*/
@@ -222,24 +215,20 @@ TkMacOSXEventsSetupProc(
ClientData clientData,
int flags)
{
- if (flags & TCL_WINDOW_EVENTS &&
- ![[NSRunLoop currentRunLoop] currentMode]) {
+ NSString *runloopMode = [[NSRunLoop currentRunLoop] currentMode];
+ /* runloopMode will be nil if we are in the Tcl event loop. */
+ if (flags & TCL_WINDOW_EVENTS && !runloopMode) {
static const Tcl_Time zeroBlockTime = { 0, 0 };
- TSD_INIT();
-
- if (!tsdPtr->currentEvent) {
- NSEvent *currentEvent = [NSApp nextEventMatchingMask:NSAnyEventMask
- untilDate:[NSDate distantPast]
- inMode:GetRunLoopMode(TkMacOSXGetModalSession())
- dequeue:YES];
-
- if (currentEvent) {
- tsdPtr->currentEvent =
- TkMacOSXMakeUncollectableAndRetain(currentEvent);
+ /* Call this with dequeue=NO -- just checking if the queue is empty. */
+ NSEvent *currentEvent = [NSApp nextEventMatchingMask:NSAnyEventMask
+ untilDate:[NSDate distantPast]
+ inMode:GetRunLoopMode(TkMacOSXGetModalSession())
+ dequeue:NO];
+ if (currentEvent) {
+ if (currentEvent.type > 0) {
+ Tcl_SetMaxBlockTime(&zeroBlockTime);
}
- }
- if (tsdPtr->currentEvent) {
- Tcl_SetMaxBlockTime(&zeroBlockTime);
+ [currentEvent release];
}
}
}
@@ -249,69 +238,74 @@ TkMacOSXEventsSetupProc(
*
* TkMacOSXEventsCheckProc --
*
- * This procedure processes events sitting in the TkAqua event queue.
+ * This procedure loops through all NSEvents waiting in the
+ * TKApplication event queue, generating X events from them.
*
* Results:
* None.
*
* Side effects:
- * Moves applicable queued TkAqua events onto the Tcl event queue.
+ * NSevents are used to generate X events, which are added to the
+ * Tcl event queue.
*
*----------------------------------------------------------------------
*/
-
static void
TkMacOSXEventsCheckProc(
ClientData clientData,
int flags)
{
- if (flags & TCL_WINDOW_EVENTS &&
- ![[NSRunLoop currentRunLoop] currentMode]) {
+ NSString *runloopMode = [[NSRunLoop currentRunLoop] currentMode];
+ /* runloopMode will be nil if we are in the Tcl event loop. */
+ if (flags & TCL_WINDOW_EVENTS && !runloopMode) {
NSEvent *currentEvent = nil;
- NSAutoreleasePool *pool = nil;
+ NSEvent *testEvent = nil;
NSModalSession modalSession;
- TSD_INIT();
- if (tsdPtr->currentEvent) {
- currentEvent = TkMacOSXMakeCollectableAndAutorelease(
- tsdPtr->currentEvent);
- }
do {
+ [NSApp _resetAutoreleasePool];
modalSession = TkMacOSXGetModalSession();
- if (!currentEvent) {
- currentEvent = [NSApp nextEventMatchingMask:NSAnyEventMask
- untilDate:[NSDate distantPast]
- inMode:GetRunLoopMode(modalSession) dequeue:YES];
- }
- if (!currentEvent) {
+ testEvent = [NSApp nextEventMatchingMask:NSAnyEventMask
+ untilDate:[NSDate distantPast]
+ inMode:GetRunLoopMode(modalSession)
+ dequeue:NO];
+ /* We must not steal any events during LiveResize. */
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
+ if (testEvent && [[testEvent window] inLiveResize]) {
break;
}
- [currentEvent retain];
- pool = [NSAutoreleasePool new];
- if (tkMacOSXGCEnabled) {
- objc_clear_stack(0);
- }
- if (![NSApp tkProcessEvent:currentEvent]) {
- [currentEvent release];
- currentEvent = nil;
+#else
+ if (testEvent && [[[testEvent window] contentView] inLiveResize]) {
+ break;
}
+#endif
+ currentEvent = [NSApp nextEventMatchingMask:NSAnyEventMask
+ untilDate:[NSDate distantPast]
+ inMode:GetRunLoopMode(modalSession)
+ dequeue:YES];
if (currentEvent) {
+ /* Generate Xevents. */
+ int oldServiceMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
+ NSEvent *processedEvent = [NSApp tkProcessEvent:currentEvent];
+ Tcl_SetServiceMode(oldServiceMode);
+ if (processedEvent) { /* Should always be non-NULL. */
#ifdef TK_MAC_DEBUG_EVENTS
- TKLog(@" event: %@", currentEvent);
+ TKLog(@" event: %@", currentEvent);
#endif
- if (modalSession) {
- [NSApp _modalSession:modalSession sendEvent:currentEvent];
- } else {
- [NSApp sendEvent:currentEvent];
+ if (modalSession) {
+ [NSApp _modalSession:modalSession sendEvent:currentEvent];
+ } else {
+ [NSApp sendEvent:currentEvent];
+ }
}
[currentEvent release];
- currentEvent = nil;
+ } else {
+ break;
}
- [pool drain];
- pool = nil;
} while (1);
}
}
+
/*
* Local Variables:
diff --git a/macosx/tkMacOSXPrivate.h b/macosx/tkMacOSXPrivate.h
index 3664850..65d60ce 100644
--- a/macosx/tkMacOSXPrivate.h
+++ b/macosx/tkMacOSXPrivate.h
@@ -144,23 +144,6 @@
}
/*
- * Macros for GC
- */
-
-#define TkMacOSXMakeUncollectable(x) ({ id o = (id)(x); \
- if (o) { if(tkMacOSXGCEnabled) CFRetain(o); } o; })
-#define TkMacOSXMakeUncollectableAndRetain(x) ({ id o = (id)(x); \
- if (o) { if(tkMacOSXGCEnabled) CFRetain(o); else [o retain]; } o; })
-#define TkMacOSXMakeCollectable(x) ({ id o = (id)(x); \
- if (o) { x = nil; if (tkMacOSXGCEnabled) CFRelease(o); } o; })
-#define TkMacOSXMakeCollectableAndRelease(x) ({ id o = (id)(x); \
- if (o) { x = nil; if (tkMacOSXGCEnabled) CFRelease(o); \
- else [o release]; } o; })
-#define TkMacOSXMakeCollectableAndAutorelease(x) ({ id o = (id)(x); \
- if (o) { x = nil; if (tkMacOSXGCEnabled) CFRelease(o); \
- else [o autorelease]; } o; })
-
-/*
* Structure encapsulating current drawing environment.
*/
@@ -178,7 +161,6 @@ typedef struct TkMacOSXDrawingContext {
MODULE_SCOPE CGFloat tkMacOSXZeroScreenHeight;
MODULE_SCOPE CGFloat tkMacOSXZeroScreenTop;
-MODULE_SCOPE int tkMacOSXGCEnabled;
MODULE_SCOPE long tkMacOSXMacOSXVersion;
/*
@@ -292,10 +274,18 @@ VISIBILITY_HIDDEN
TKMenu *_defaultMainMenu, *_defaultApplicationMenu;
NSArray *_defaultApplicationMenuItems, *_defaultWindowsMenuItems;
NSArray *_defaultHelpMenuItems;
+ NSWindow *_windowWithMouse;
+ NSAutoreleasePool *_mainPool;
+#ifdef __i386__
+ /* The Objective C runtime used on i386 requires this. */
+ BOOL _poolProtected;
+#endif
}
+@property BOOL poolProtected;
@end
@interface TKApplication(TKInit)
- (NSString *)tkFrameworkImagePath:(NSString*)image;
+- (void)_resetAutoreleasePool;
@end
@interface TKApplication(TKEvent)
- (NSEvent *)tkProcessEvent:(NSEvent *)theEvent;
@@ -313,15 +303,33 @@ VISIBILITY_HIDDEN
- (void)tkProvidePasteboard:(TkDisplay *)dispPtr;
- (void)tkCheckPasteboard;
@end
+@interface TKApplication(TKHLEvents)
+- (void) terminate: (id) sender;
+- (void) preferences: (id) sender;
+- (void) handleQuitApplicationEvent: (NSAppleEventDescriptor *)event
+ withReplyEvent: (NSAppleEventDescriptor *)replyEvent;
+- (void) handleOpenApplicationEvent: (NSAppleEventDescriptor *)event
+ withReplyEvent: (NSAppleEventDescriptor *)replyEvent;
+- (void) handleReopenApplicationEvent: (NSAppleEventDescriptor *)event
+ withReplyEvent: (NSAppleEventDescriptor *)replyEvent;
+- (void) handleShowPreferencesEvent: (NSAppleEventDescriptor *)event
+ withReplyEvent: (NSAppleEventDescriptor *)replyEvent;
+- (void) handleOpenDocumentsEvent: (NSAppleEventDescriptor *)event
+ withReplyEvent: (NSAppleEventDescriptor *)replyEvent;
+- (void) handlePrintDocumentsEvent: (NSAppleEventDescriptor *)event
+ withReplyEvent: (NSAppleEventDescriptor *)replyEvent;
+- (void) handleDoScriptEvent: (NSAppleEventDescriptor *)event
+ withReplyEvent: (NSAppleEventDescriptor *)replyEvent;
+@end
VISIBILITY_HIDDEN
@interface TKContentView : NSView <NSTextInput> {
@private
/*Remove private API calls.*/
- #if 0
+#if 0
id _savedSubviews;
BOOL _subviewsSetAside;
- #endif
+#endif
NSString *privateWorkingText;
}
@end
@@ -330,10 +338,27 @@ VISIBILITY_HIDDEN
- (void) deleteWorkingText;
@end
+@interface TKContentView(TKWindowEvent)
+- (void) drawRect: (NSRect) rect;
+- (void) generateExposeEvents: (HIShapeRef) shape;
+- (void) generateExposeEvents: (HIShapeRef) shape childrenOnly: (int) childrenOnly;
+- (void) viewDidEndLiveResize;
+- (void) tkToolbarButton: (id) sender;
+- (BOOL) isOpaque;
+- (BOOL) wantsDefaultClipping;
+- (BOOL) acceptsFirstResponder;
+- (void) keyDown: (NSEvent *) theEvent;
+@end
+
VISIBILITY_HIDDEN
@interface TKWindow : NSWindow
@end
+@interface NSWindow(TKWm)
+- (NSPoint) convertPointToScreen:(NSPoint)point;
+- (NSPoint) convertPointFromScreen:(NSPoint)point;
+@end
+
#pragma mark NSMenu & NSMenuItem Utilities
@interface NSMenu(TKUtils)
diff --git a/macosx/tkMacOSXScrlbr.c b/macosx/tkMacOSXScrlbr.c
index 7370ff5..91cf112 100644
--- a/macosx/tkMacOSXScrlbr.c
+++ b/macosx/tkMacOSXScrlbr.c
@@ -26,6 +26,7 @@
#define RangeToFactor(maximum) (((double) (LONG_MAX >> 1)) / (maximum))
#endif /* __LP64__ */
+#define MOUNTAIN_LION_STYLE (NSAppKitVersionNumber < 1138)
/*
* Declaration of Mac specific scrollbar structure.
@@ -80,7 +81,6 @@ static void ScrollbarEventProc(ClientData clientData, XEvent *eventPtr);
static int ScrollbarPress(TkScrollbar *scrollPtr, XEvent *eventPtr);
static void UpdateControlValues(TkScrollbar *scrollPtr);
-
/*
*----------------------------------------------------------------------
*
@@ -136,27 +136,26 @@ TkpDisplayScrollbar(
{
register TkScrollbar *scrollPtr = (TkScrollbar *) clientData;
register Tk_Window tkwin = scrollPtr->tkwin;
+ TkWindow *winPtr = (TkWindow *) tkwin;
+ TkMacOSXDrawingContext dc;
+ scrollPtr->flags &= ~REDRAW_PENDING;
- if ((scrollPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
+ if (tkwin == NULL || !Tk_IsMapped(tkwin)) {
return;
}
- TkWindow *winPtr = (TkWindow *) tkwin;
MacDrawable *macWin = (MacDrawable *) winPtr->window;
- TkMacOSXDrawingContext dc;
NSView *view = TkMacOSXDrawableView(macWin);
+ if (!view ||
+ macWin->flags & TK_DO_NOT_DRAW ||
+ !TkMacOSXSetupDrawingContext((Drawable) macWin, NULL, 1, &dc)) {
+ return;
+ }
+
CGFloat viewHeight = [view bounds].size.height;
CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1, .tx = 0,
.ty = viewHeight};
-
-
- scrollPtr->flags &= ~REDRAW_PENDING;
- if (!scrollPtr->tkwin || !Tk_IsMapped(tkwin) || !view ||
- !TkMacOSXSetupDrawingContext((Drawable) macWin, NULL, 1, &dc)) {
- return;
- }
-
CGContextConcatCTM(dc.context, t);
/*Draw Unix-style scroll trough to provide rect for native scrollbar.*/
@@ -173,7 +172,6 @@ TkpDisplayScrollbar(
(Pixmap) macWin);
}
-
Tk_Draw3DRectangle(tkwin, (Pixmap) macWin, scrollPtr->bgBorder,
scrollPtr->highlightWidth, scrollPtr->highlightWidth,
Tk_Width(tkwin) - 2*scrollPtr->highlightWidth,
@@ -186,15 +184,11 @@ TkpDisplayScrollbar(
/*Update values and draw in native rect.*/
UpdateControlValues(scrollPtr);
-#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
- if (scrollPtr->vertical) {
- HIThemeDrawTrack (&info, 0, dc.context, kHIThemeOrientationNormal);
- } else {
+ if (MOUNTAIN_LION_STYLE) {
HIThemeDrawTrack (&info, 0, dc.context, kHIThemeOrientationInverted);
+ } else {
+ HIThemeDrawTrack (&info, 0, dc.context, kHIThemeOrientationNormal);
}
-#else
- HIThemeDrawTrack (&info, 0, dc.context, kHIThemeOrientationNormal);
-#endif
TkMacOSXRestoreDrawingContext(&dc);
scrollPtr->flags &= ~REDRAW_PENDING;
@@ -265,11 +259,12 @@ TkpComputeScrollbarGeometry(
if (scrollPtr->sliderLast > fieldLength) {
scrollPtr->sliderLast = fieldLength;
}
- scrollPtr->sliderFirst += scrollPtr->inset +
+ if (!(MOUNTAIN_LION_STYLE)) {
+ scrollPtr->sliderFirst += scrollPtr->inset +
metrics[variant].topArrowHeight;
- scrollPtr->sliderLast += scrollPtr->inset +
+ scrollPtr->sliderLast += scrollPtr->inset +
metrics[variant].bottomArrowHeight;
-
+ }
/*
* Register the desired geometry for the window (leave enough space
* for the two arrows plus a minimum-size slider, plus border around
@@ -370,21 +365,29 @@ TkpScrollbarPosition(
int x, int y) /* Coordinates within scrollPtr's window. */
{
- /*Using code from tkUnixScrlbr.c because Unix scroll bindings are driving the display at the script level. All the Mac scrollbar has to do is re-draw itself.*/
+ /*
+ * Using code from tkUnixScrlbr.c because Unix scroll bindings are
+ * driving the display at the script level. All the Mac scrollbar
+ * has to do is re-draw itself.
+ */
- int length, width, tmp;
+ int length, fieldlength, width, tmp;
register const int inset = scrollPtr->inset;
+ register const int arrowSize = scrollPtr->arrowLength + inset;
if (scrollPtr->vertical) {
length = Tk_Height(scrollPtr->tkwin);
+ fieldlength = length - 2 * arrowSize;
width = Tk_Width(scrollPtr->tkwin);
} else {
tmp = x;
x = y;
y = tmp;
length = Tk_Width(scrollPtr->tkwin);
+ fieldlength = length - 2 * arrowSize;
width = Tk_Height(scrollPtr->tkwin);
}
+ fieldlength = fieldlength < 0 ? 0 : fieldlength;
if (x<inset || x>=width-inset || y<inset || y>=length-inset) {
return OUTSIDE;
@@ -395,19 +398,19 @@ TkpScrollbarPosition(
* TkpDisplayScrollbar. Be sure to keep the two consistent.
*/
- if (y < inset + scrollPtr->arrowLength) {
- return TOP_ARROW;
- }
if (y < scrollPtr->sliderFirst) {
return TOP_GAP;
}
if (y < scrollPtr->sliderLast) {
return SLIDER;
}
- if (y >= length - (scrollPtr->arrowLength + inset)) {
- return BOTTOM_ARROW;
+ if (y < fieldlength){
+ return BOTTOM_GAP;
+ }
+ if (y < fieldlength + arrowSize) {
+ return TOP_ARROW;
}
- return BOTTOM_GAP;
+ return BOTTOM_ARROW;
}
/*
@@ -415,9 +418,11 @@ TkpScrollbarPosition(
*
* UpdateControlValues --
*
- * This procedure updates the Macintosh scrollbar control to display the
- * values defined by the Tk scrollbar. This is the key interface to the Mac-native * scrollbar; the Unix bindings drive scrolling in the Tk window and all the Mac
- * scrollbar has to do is redraw itself.
+ * This procedure updates the Macintosh scrollbar control to
+ * display the values defined by the Tk scrollbar. This is the
+ * key interface to the Mac-native * scrollbar; the Unix bindings
+ * drive scrolling in the Tk window and all the Mac scrollbar has
+ * to do is redraw itself.
*
* Results:
* None.
@@ -432,12 +437,11 @@ static void
UpdateControlValues(
TkScrollbar *scrollPtr) /* Scrollbar data struct. */
{
-
Tk_Window tkwin = scrollPtr->tkwin;
MacDrawable *macWin = (MacDrawable *) Tk_WindowId(scrollPtr->tkwin);
double dViewSize;
HIRect contrlRect;
- int variant;
+ int variant;
short width, height;
NSView *view = TkMacOSXDrawableView(macWin);
@@ -462,8 +466,10 @@ UpdateControlValues(
*/
info.bounds = contrlRect;
- if (!scrollPtr->vertical) {
- info.attributes |= kThemeTrackHorizontal;
+ if (scrollPtr->vertical) {
+ info.attributes &= ~kThemeTrackHorizontal;
+ } else {
+ info.attributes |= kThemeTrackHorizontal;
}
/*
@@ -484,7 +490,11 @@ UpdateControlValues(
factor - dViewSize;
info.trackInfo.scrollbar.viewsize = dViewSize;
if (scrollPtr->vertical) {
+ if (MOUNTAIN_LION_STYLE) {
+ info.value = factor * scrollPtr->firstFraction;
+ } else {
info.value = info.max - factor * scrollPtr->firstFraction;
+ }
} else {
info.value = MIN_SCROLLBAR_VALUE + factor * scrollPtr->firstFraction;
}
diff --git a/macosx/tkMacOSXSubwindows.c b/macosx/tkMacOSXSubwindows.c
index 1a71746..f92d260 100644
--- a/macosx/tkMacOSXSubwindows.c
+++ b/macosx/tkMacOSXSubwindows.c
@@ -149,9 +149,10 @@ XMapWindow(
if (Tk_IsTopLevel(macWin->winPtr)) {
if (!Tk_IsEmbedded(macWin->winPtr)) {
NSWindow *win = TkMacOSXDrawableWindow(window);
-
- [win makeKeyAndOrderFront:NSApp];
- [win windowRef];
+ [NSApp activateIgnoringOtherApps:YES];
+ if ( [win canBecomeKeyWindow] ) {
+ [win makeKeyAndOrderFront:NSApp];
+ }
TkMacOSXApplyWindowAttributes(macWin->winPtr, win);
}
TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr);
@@ -310,11 +311,9 @@ XResizeWindow(
unsigned int height)
{
MacDrawable *macWin = (MacDrawable *) window;
-
display->request++;
if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
NSWindow *w = macWin->winPtr->wmInfoPtr->window;
-
if (w) {
NSRect r = [w contentRectForFrameRect:[w frame]];
r.origin.y += r.size.height - height;
@@ -357,12 +356,20 @@ XMoveResizeWindow(
display->request++;
if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
NSWindow *w = macWin->winPtr->wmInfoPtr->window;
-
if (w) {
- NSRect r = NSMakeRect(x + macWin->winPtr->wmInfoPtr->xInParent,
- tkMacOSXZeroScreenHeight - (y +
- macWin->winPtr->wmInfoPtr->yInParent + height),
- width, height);
+ /* We explicitly convert everything to doubles so we don't get
+ * surprised (again) by what happens when you do arithmetic with
+ * unsigned ints.
+ */
+ CGFloat X = (CGFloat)x;
+ CGFloat Y = (CGFloat)y;
+ CGFloat Width = (CGFloat)width;
+ CGFloat Height = (CGFloat)height;
+ CGFloat XOff = (CGFloat)macWin->winPtr->wmInfoPtr->xInParent;
+ CGFloat YOff = (CGFloat)macWin->winPtr->wmInfoPtr->yInParent;
+ NSRect r = NSMakeRect(X + XOff,
+ tkMacOSXZeroScreenHeight - Y - YOff - Height,
+ Width, Height);
[w setFrame:[w frameRectForContentRect:r] display:YES];
}
} else {
@@ -398,7 +405,6 @@ XMoveWindow(
display->request++;
if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
NSWindow *w = macWin->winPtr->wmInfoPtr->window;
-
if (w) {
[w setFrameTopLeftPoint:NSMakePoint(x, tkMacOSXZeroScreenHeight - y)];
}
@@ -649,6 +655,65 @@ XConfigureWindow(
/*
*----------------------------------------------------------------------
*
+ * TkMacOSXSetDrawingEnabled --
+ *
+ * This function sets the TK_DO_NOT_DRAW flag for a given window and
+ * all of its children.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The clipping regions for the window and its children are cleared.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXSetDrawingEnabled(
+ TkWindow *winPtr,
+ int flag)
+{
+ TkWindow *childPtr;
+ MacDrawable *macWin = winPtr->privatePtr;
+
+ if (macWin) {
+ if (flag ) {
+ macWin->flags &= ~TK_DO_NOT_DRAW;
+ } else {
+ macWin->flags |= TK_DO_NOT_DRAW;
+ }
+ }
+
+ /*
+ * Set the flag for all children & their descendants, excluding
+ * Toplevels. (??? Do we need to exclude Toplevels?)
+ */
+
+ childPtr = winPtr->childList;
+ while (childPtr) {
+ if (!Tk_IsTopLevel(childPtr)) {
+ TkMacOSXSetDrawingEnabled(childPtr, flag);
+ }
+ childPtr = childPtr->nextPtr;
+ }
+
+ /*
+ * If the window is a container, set the flag for its embedded window.
+ */
+
+ if (Tk_IsContainer(winPtr)) {
+ childPtr = TkpGetOtherWindow(winPtr);
+
+ if (childPtr) {
+ TkMacOSXSetDrawingEnabled(childPtr, flag);
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* TkMacOSXUpdateClipRgn --
*
* This function updates the clipping regions for a given window and all of
@@ -738,10 +803,6 @@ TkMacOSXUpdateClipRgn(
/*
* TODO: Here we should handle out of process embedding.
*/
- } else if (winPtr->wmInfoPtr->attributes &
- kWindowResizableAttribute) {
- NSWindow *w = TkMacOSXDrawableWindow(winPtr->window);
-
}
macWin->aboveVisRgn = HIShapeCreateCopy(rgn);
diff --git a/macosx/tkMacOSXWindowEvent.c b/macosx/tkMacOSXWindowEvent.c
index 5f782c5..461a94c 100644
--- a/macosx/tkMacOSXWindowEvent.c
+++ b/macosx/tkMacOSXWindowEvent.c
@@ -29,7 +29,7 @@
* Declaration of functions used only in this file
*/
-static int GenerateUpdates(HIMutableShapeRef updateRgn,
+static int GenerateUpdates(HIShapeRef updateRgn,
CGRect *updateBounds, TkWindow *winPtr);
static int GenerateActivateEvents(TkWindow *winPtr,
int activeFlag);
@@ -48,7 +48,7 @@ extern NSString *NSWindowDidOrderOffScreenNotification;
#endif
#endif
-extern NSString *opaqueTag;
+extern BOOL opaqueTag;
@implementation TKApplication(TKWindowEvent)
@@ -165,6 +165,10 @@ extern NSString *opaqueTag;
if (winPtr) {
TkGenWMDestroyEvent((Tk_Window) winPtr);
+ if (_windowWithMouse == w) {
+ _windowWithMouse = nil;
+ [w release];
+ }
}
/*
@@ -315,7 +319,7 @@ extern NSString *opaqueTag;
static int
GenerateUpdates(
- HIMutableShapeRef updateRgn,
+ HIShapeRef updateRgn,
CGRect *updateBounds,
TkWindow *winPtr)
{
@@ -745,15 +749,16 @@ TkWmProtocolEventProc(
int
Tk_MacOSXIsAppInFront(void)
{
- OSStatus err;
- ProcessSerialNumber frontPsn, ourPsn = {0, kCurrentProcess};
Boolean isFrontProcess = true;
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
+ ProcessSerialNumber frontPsn, ourPsn = {0, kCurrentProcess};
- err = ChkErr(GetFrontProcess, &frontPsn);
- if (err == noErr) {
- ChkErr(SameProcess, &frontPsn, &ourPsn, &isFrontProcess);
+ if (noErr == GetFrontProcess(&frontPsn)){
+ SameProcess(&frontPsn, &ourPsn, &isFrontProcess);
}
-
+#else
+ isFrontProcess = [NSRunningApplication currentApplication].active;
+#endif
return (isFrontProcess == true);
}
@@ -763,7 +768,7 @@ Tk_MacOSXIsAppInFront(void)
/*
* Custom content view for use in Tk NSWindows.
- *
+ *
* Since Tk handles all drawing of widgets, we only use the AppKit event loop
* as a source of input events. To do this, we overload the NSView drawRect
* method with a method which generates Expose events for Tk but does no
@@ -780,21 +785,6 @@ Tk_MacOSXIsAppInFront(void)
*
*/
-@interface TKContentView(TKWindowEvent)
-- (void) drawRect: (NSRect) rect;
-- (void) generateExposeEvents: (HIMutableShapeRef) shape;
-- (void) viewDidEndLiveResize;
-- (void) tkToolbarButton: (id) sender;
-- (BOOL) isOpaque;
-- (BOOL) wantsDefaultClipping;
-- (BOOL) acceptsFirstResponder;
-- (void) keyDown: (NSEvent *) theEvent;
-@end
-
-@implementation TKContentView
-@end
-
-
/*Restrict event processing to Expose events.*/
static Tk_RestrictAction
ExposeRestrictProc(
@@ -805,6 +795,15 @@ ExposeRestrictProc(
? TK_PROCESS_EVENT : TK_DEFER_EVENT);
}
+/*Restrict event processing to ConfigureNotify events.*/
+static Tk_RestrictAction
+ConfigureRestrictProc(
+ ClientData arg,
+ XEvent *eventPtr)
+{
+ return (eventPtr->type==ConfigureNotify ? TK_PROCESS_EVENT : TK_DEFER_EVENT);
+}
+
@implementation TKContentView(TKWindowEvent)
- (void) drawRect: (NSRect) rect
@@ -830,11 +829,12 @@ ExposeRestrictProc(
HIShapeUnionWithRect(drawShape, &r);
}
if (CFRunLoopGetMain() == CFRunLoopGetCurrent()) {
- [self generateExposeEvents:drawShape];
+ [self generateExposeEvents:(HIShapeRef)drawShape];
} else {
[self performSelectorOnMainThread:@selector(generateExposeEvents:)
withObject:(id)drawShape waitUntilDone:NO
modes:[NSArray arrayWithObjects:NSRunLoopCommonModes,
+
NSEventTrackingRunLoopMode, NSModalPanelRunLoopMode,
nil]];
}
@@ -842,62 +842,107 @@ ExposeRestrictProc(
CFRelease(drawShape);
}
+-(void) setFrameSize: (NSSize)newsize
+{
+ [super setFrameSize: newsize];
+ if ([self inLiveResize]) {
+ NSWindow *w = [self window];
+ TkWindow *winPtr = TkMacOSXGetTkWindow(w);
+ Tk_Window tkwin = (Tk_Window) winPtr;
+ unsigned int width = (unsigned int)newsize.width;
+ unsigned int height=(unsigned int)newsize.height;
+ ClientData oldArg;
+ Tk_RestrictProc *oldProc;
+
+ /* This can be called from outside the Tk event loop.
+ * Since it calls Tcl_DoOneEvent, we need to make sure we
+ * don't clobber the AutoreleasePool set up by the caller.
+ */
+ [NSApp setPoolProtected:YES];
+
+ /*
+ * Try to prevent flickers and flashes.
+ */
+ [w disableFlushWindow];
+ NSDisableScreenUpdates();
+
+ /* Disable Tk drawing until the window has been completely configured.*/
+ TkMacOSXSetDrawingEnabled(winPtr, 0);
+
+ /* Generate and handle a ConfigureNotify event for the new size.*/
+ TkGenWMConfigureEvent(tkwin, Tk_X(tkwin), Tk_Y(tkwin), width, height,
+ TK_SIZE_CHANGED | TK_MACOSX_HANDLE_EVENT_IMMEDIATELY);
+ oldProc = Tk_RestrictEvents(ConfigureRestrictProc, NULL, &oldArg);
+ while (Tk_DoOneEvent(TK_X_EVENTS|TK_DONT_WAIT)) {}
+ Tk_RestrictEvents(oldProc, oldArg, &oldArg);
+
+ /* Now that Tk has configured all subwindows we can create the clip regions. */
+ TkMacOSXSetDrawingEnabled(winPtr, 1);
+ TkMacOSXInvalClipRgns(tkwin);
+ TkMacOSXUpdateClipRgn(winPtr);
+
+ /* Finally, generate and process expose events to redraw the window. */
+ HIRect bounds = NSRectToCGRect([self bounds]);
+ HIShapeRef shape = HIShapeCreateWithRect(&bounds);
+ [self generateExposeEvents: shape];
+ while (Tk_DoOneEvent(TK_ALL_EVENTS|TK_DONT_WAIT)) {}
+ [w enableFlushWindow];
+ [w flushWindowIfNeeded];
+ NSEnableScreenUpdates();
+ [NSApp setPoolProtected:NO];
+ }
+}
+
/*
* As insurance against bugs that might cause layout glitches during a live
- * resize, we redraw the window at the end of the resize operation.
+ * resize, we redraw the window one more time at the end of the resize
+ * operation.
*/
- (void)viewDidEndLiveResize
{
HIRect bounds = NSRectToCGRect([self bounds]);
HIShapeRef shape = HIShapeCreateWithRect(&bounds);
+ [super viewDidEndLiveResize];
[self generateExposeEvents: shape];
-
}
-/*Core function of this class, generates expose events for redrawing.*/
-- (void) generateExposeEvents: (HIMutableShapeRef) shape
+/* Core method of this class: generates expose events for redrawing. If the
+ * Tcl_ServiceMode is set to TCL_SERVICE_ALL then the expose events will be
+ * immediately removed from the Tcl event loop and processed. Typically, they
+ * should be queued, however.
+ */
+- (void) generateExposeEvents: (HIShapeRef) shape
{
+ [self generateExposeEvents:shape childrenOnly:0];
+}
+- (void) generateExposeEvents: (HIShapeRef) shape
+ childrenOnly: (int) childrenOnly
+{
TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
unsigned long serial;
CGRect updateBounds;
+ int updatesNeeded;
if (!winPtr) {
return;
}
-
+ /* Generate Tk Expose events. */
HIShapeGetBounds(shape, &updateBounds);
+ /* All of these events will share the same serial number. */
serial = LastKnownRequestProcessed(Tk_Display(winPtr));
- if (GenerateUpdates(shape, &updateBounds, winPtr) &&
- ![[NSRunLoop currentRunLoop] currentMode] &&
- Tcl_GetServiceMode() != TCL_SERVICE_NONE) {
- /*
- * Ensure there are no pending idle-time redraws that could
- * prevent the just posted Expose events from generating
- * new redraws.
- */
-
- while (Tcl_DoOneEvent(TCL_IDLE_EVENTS|TCL_DONT_WAIT)) {}
-
- /*
- * For smoother drawing, process Expose events and resulting
- * redraws immediately instead of at idle time.
- */
-
- ClientData oldArg;
+ updatesNeeded = GenerateUpdates(shape, &updateBounds, winPtr);
+
+ /* Process the Expose events if the service mode is TCL_SERVICE_ALL */
+ if (updatesNeeded && Tcl_GetServiceMode() == TCL_SERVICE_ALL) {
+ ClientData oldArg;
Tk_RestrictProc *oldProc = Tk_RestrictEvents(ExposeRestrictProc,
UINT2PTR(serial), &oldArg);
-
while (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) {}
-
Tk_RestrictEvents(oldProc, oldArg, &oldArg);
-
- while (Tcl_DoOneEvent(TCL_IDLE_EVENTS|TCL_DONT_WAIT)) {}
-
}
-
}
/*
@@ -913,7 +958,6 @@ ExposeRestrictProc(
int x, y;
TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
Tk_Window tkwin = (Tk_Window) winPtr;
-
bzero(&event, sizeof(XVirtualEvent));
event.type = VirtualEvent;
event.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
@@ -935,7 +979,7 @@ ExposeRestrictProc(
{
NSWindow *w = [self window];
- if (opaqueTag != NULL) {
+ if (opaqueTag) {
return YES;
} else {
diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c
index 4f7b066..39990e6 100644
--- a/macosx/tkMacOSXWm.c
+++ b/macosx/tkMacOSXWm.c
@@ -21,6 +21,8 @@
#include "tkMacOSXEvent.h"
#include "tkMacOSXDebug.h"
+#define DEBUG_ZOMBIES 0
+
/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_WINDOWS
@@ -53,7 +55,7 @@
/*Objects for use in setting background color and opacity of window.*/
NSColor *colorName = NULL;
-NSString *opaqueTag = NULL;
+BOOL opaqueTag = FALSE;
static const struct {
const UInt64 validAttrs, defaultAttrs, forceOnAttrs, forceOffAttrs;
@@ -194,6 +196,48 @@ static int tkMacOSXWmAttrNotifyVal = 0;
static Tcl_HashTable windowTable;
static int windowHashInit = false;
+
+
+#pragma mark NSWindow(TKWm)
+
+/*
+ * Conversion of coordinates between window and screen.
+ */
+
+@implementation NSWindow(TKWm)
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
+- (NSPoint) convertPointToScreen: (NSPoint) point
+{
+ return [self convertBaseToScreen:point];
+}
+- (NSPoint) convertPointFromScreen: (NSPoint)point
+{
+ return [self convertScreenToBase:point];
+}
+@end
+#else
+- (NSPoint) convertPointToScreen: (NSPoint) point
+{
+ NSRect pointrect;
+ pointrect.origin = point;
+ pointrect.size.width = 0;
+ pointrect.size.height = 0;
+ return [self convertRectToScreen:pointrect].origin;
+}
+- (NSPoint) convertPointFromScreen: (NSPoint)point
+{
+ NSRect pointrect;
+ pointrect.origin = point;
+ pointrect.size.width = 0;
+ pointrect.size.height = 0;
+ return [self convertRectFromScreen:pointrect].origin;
+}
+@end
+#endif
+
+#pragma mark -
+
+
/*
* Forward declarations for procedures defined in this file:
*/
@@ -342,6 +386,7 @@ static void RemapWindows(TkWindow *winPtr,
@end
@implementation TKWindow(TKWm)
+
- (BOOL) canBecomeKeyWindow
{
TkWindow *winPtr = TkMacOSXGetTkWindow(self);
@@ -350,6 +395,59 @@ static void RemapWindows(TkWindow *winPtr,
kHelpWindowClass || winPtr->wmInfoPtr->attributes &
kWindowNoActivatesAttribute)) ? NO : YES;
}
+
+#if DEBUG_ZOMBIES
+- (id) retain
+{
+ id result = [super retain];
+ const char *title = [[self title] UTF8String];
+ if (title == nil) {
+ title = "unnamed window";
+ }
+ if (DEBUG_ZOMBIES > 1){
+ printf("Retained <%s>. Count is: %lu\n", title, [self retainCount]);
+ }
+ return result;
+}
+
+- (id) autorelease
+{
+ static int xcount = 0;
+ id result = [super autorelease];
+ const char *title = [[self title] UTF8String];
+ if (title == nil) {
+ title = "unnamed window";
+ }
+ if (DEBUG_ZOMBIES > 1){
+ printf("Autoreleased <%s>. Count is %lu\n", title, [self retainCount]);
+ }
+ return result;
+}
+
+- (oneway void) release {
+ const char *title = [[self title] UTF8String];
+ if (title == nil) {
+ title = "unnamed window";
+ }
+ if (DEBUG_ZOMBIES > 1){
+ printf("Releasing <%s>. Count is %lu\n", title, [self retainCount]);
+ }
+ [super release];
+}
+
+- (void) dealloc {
+ const char *title = [[self title] UTF8String];
+ if (title == nil) {
+ title = "unnamed window";
+ }
+ if (DEBUG_ZOMBIES > 0){
+ printf(">>>> Freeing <%s>. Count is %lu\n", title, [self retainCount]);
+ }
+ [super dealloc];
+}
+
+
+#endif
@end
#pragma mark -
@@ -463,25 +561,16 @@ FrontWindowAtPoint(
int x, int y)
{
NSPoint p = NSMakePoint(x, tkMacOSXZeroScreenHeight - y);
- NSWindow *win = nil;
- NSInteger windowCount;
- NSInteger *windowNumbers;
-
- NSCountWindows(&windowCount);
- if (windowCount) {
- windowNumbers = ckalloc(windowCount * sizeof(NSInteger));
- NSWindowList(windowCount, windowNumbers);
- for (NSInteger index = 0; index < windowCount; index++) {
- NSWindow *w = [NSApp windowWithWindowNumber:windowNumbers[index]];
+ NSArray *windows = [NSApp orderedWindows];
+ TkWindow *front = NULL;
+ for (NSWindow *w in windows) {
if (w && NSMouseInRect(p, [w frame], NO)) {
- win = w;
+ front = TkMacOSXGetTkWindow(w);
break;
}
}
- ckfree(windowNumbers);
- }
- return (win ? TkMacOSXGetTkWindow(win) : NULL);
+ return front;
}
/*
@@ -677,6 +766,7 @@ TkWmMapWindow(
*/
XMapWindow(winPtr->display, winPtr->window);
+
}
/*
@@ -699,7 +789,7 @@ TkWmMapWindow(
void
TkWmUnmapWindow(
TkWindow *winPtr) /* Top-level window that's about to be
- * mapped. */
+ * unmapped. */
{
XUnmapWindow(winPtr->display, winPtr->window);
}
@@ -783,16 +873,42 @@ TkWmDeadWindow(
NSWindow *window = wmPtr->window;
if (window && !Tk_IsEmbedded(winPtr) ) {
- [[window parentWindow] removeChildWindow:window];
- [window setExcludedFromWindowsMenu:YES];
+ NSWindow *parent = [window parentWindow];
+ if (parent) {
+ [parent removeChildWindow:window];
+ }
[window close];
TkMacOSXUnregisterMacWindow(window);
- if (winPtr->window) {
- ((MacDrawable *) winPtr->window)->view = nil;
+ if (winPtr->window) {
+ ((MacDrawable *) winPtr->window)->view = nil;
+ }
+#if DEBUG_ZOMBIES > 0
+ {
+ const char *title = [[window title] UTF8String];
+ if (title == nil) {
+ title = "unnamed window";
+ }
+ printf(">>>> Closing <%s>. Count is: %lu\n", title, [window retainCount]);
}
- TkMacOSXMakeCollectableAndRelease(wmPtr->window);
- }
+#endif
+ [window release];
+ wmPtr->window = NULL;
+
+ /* Activate the highest window left on the screen. */
+ NSArray *windows = [NSApp orderedWindows];
+ if ( [windows count] > 0 ) {
+ NSWindow *front = [windows objectAtIndex:0];
+ if ( front && [front canBecomeKeyWindow] ) {
+ [front makeKeyAndOrderFront:NSApp];
+ }
+ }
+ [NSApp _resetAutoreleasePool];
+#if DEBUG_ZOMBIES > 0
+ fprintf(stderr, "================= Pool dump ===================\n");
+ [NSAutoreleasePool showPools];
+#endif
+ }
ckfree(wmPtr);
winPtr->wmInfoPtr = NULL;
}
@@ -1672,6 +1788,11 @@ WmForgetCmd(
TkWmDeadWindow(winPtr);
RemapWindows(winPtr, (MacDrawable *) winPtr->parentPtr->window);
+ /*
+ * Make sure wm no longer manages this window
+ */
+ Tk_ManageGeometry(frameWin, NULL, NULL);
+
winPtr->flags &= ~(TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED);
/*
@@ -5117,7 +5238,7 @@ TkUnsupported1ObjCmd(
colorName = [NSColor clearColor]; //use systemTransparent in Tk scripts to match
}
if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*opacity*")) {
- opaqueTag = @"YES";
+ opaqueTag = YES;
}
}
@@ -5445,7 +5566,6 @@ TkMacOSXMakeRealWindowExist(
* TODO: Here we should handle out of process embedding.
*/
}
-
WindowClass macClass = wmPtr->macClass;
wmPtr->attributes &= (tkAlwaysValidAttributes |
macClassAttrs[macClass].validAttrs);
@@ -5479,11 +5599,10 @@ TkMacOSXMakeRealWindowExist(
NSWindow *window = [[winClass alloc] initWithContentRect:contentRect
styleMask:styleMask backing:NSBackingStoreBuffered defer:YES];
if (!window) {
- Tcl_Panic("couldn't allocate new Mac window");
+ Tcl_Panic("couldn't allocate new Mac window");
}
- TkMacOSXMakeUncollectable(window);
TKContentView *contentView = [[TKContentView alloc]
- initWithFrame:NSZeroRect];
+ initWithFrame:NSZeroRect];
[window setContentView:contentView];
[contentView release];
[window setDelegate:NSApp];
@@ -5508,7 +5627,7 @@ TkMacOSXMakeRealWindowExist(
[window setBackgroundColor: colorName];
}
- if (opaqueTag != NULL) {
+ if (opaqueTag) {
#ifdef TK_GOT_AT_LEAST_SNOW_LEOPARD
[window setOpaque: opaqueTag];
#else
@@ -5518,7 +5637,7 @@ TkMacOSXMakeRealWindowExist(
[window setDocumentEdited:NO];
wmPtr->window = window;
- macWin->view = contentView;
+ macWin->view = window.contentView;
TkMacOSXApplyWindowAttributes(winPtr, window);
NSRect geometry = InitialWindowBounds(winPtr, window);
@@ -5527,7 +5646,6 @@ TkMacOSXMakeRealWindowExist(
geometry.origin.y = tkMacOSXZeroScreenHeight - (geometry.origin.y +
geometry.size.height);
[window setFrame:geometry display:NO];
-
TkMacOSXRegisterOffScreenWindow((Window) macWin, window);
macWin->flags |= TK_HOST_EXISTS;
}
@@ -5916,15 +6034,21 @@ TkpChangeFocus(
* didn't originally belong to topLevelPtr's
* application. */
{
- /*
- * We don't really need to do anything on the Mac. Tk will keep all this
- * state for us.
- */
-
if (winPtr->atts.override_redirect) {
return 0;
}
+ if (Tk_IsTopLevel(winPtr) && !Tk_IsEmbedded(winPtr) ){
+ NSWindow *win = TkMacOSXDrawableWindow(winPtr->window);
+ TkWmRestackToplevel(winPtr, Above, NULL);
+ if (force ) {
+ [NSApp activateIgnoringOtherApps:YES];
+ }
+ if ( win && [win canBecomeKeyWindow] ) {
+ [win makeKeyAndOrderFront:NSApp];
+ }
+ }
+
/*
* Remember the current serial number for the X server and issue a dummy
* server request. This marks the position at which we changed the focus,
@@ -5941,7 +6065,7 @@ TkpChangeFocus(
* WmStackorderToplevelWrapperMap --
*
* This procedure will create a table that maps the reparent wrapper X id
- * for a toplevel to the TkWindow structure that is wraps. Tk keeps track
+ * for a toplevel to the TkWindow structure that it wraps. Tk keeps track
* of a mapping from the window X id to the TkWindow structure but that
* does us no good here since we only get the X id of the wrapper window.
* Only those toplevel windows that are mapped have a position in the
@@ -6004,8 +6128,6 @@ TkWmStackorderToplevel(
Tcl_HashTable table;
Tcl_HashEntry *hPtr;
Tcl_HashSearch search;
- NSInteger windowCount;
- NSInteger *windowNumbers;
/*
* Map mac windows to a TkWindow of the wrapped toplevel.
@@ -6032,31 +6154,26 @@ TkWmStackorderToplevel(
goto done;
}
- NSCountWindows(&windowCount);
+ NSArray *macWindows = [NSApp orderedWindows];
+ NSInteger windowCount = [macWindows count];
+
if (!windowCount) {
ckfree(windows);
windows = NULL;
} else {
windowPtr = windows + table.numEntries;
*windowPtr-- = NULL;
- windowNumbers = ckalloc(windowCount * sizeof(NSInteger));
- NSWindowList(windowCount, windowNumbers);
- for (NSInteger index = 0; index < windowCount; index++) {
- NSWindow *w = [NSApp windowWithWindowNumber:windowNumbers[index]];
-
- if (w) {
- hPtr = Tcl_FindHashEntry(&table, (char*) w);
- if (hPtr != NULL) {
- childWinPtr = Tcl_GetHashValue(hPtr);
- *windowPtr-- = childWinPtr;
- }
+ for (NSWindow *w in macWindows) {
+ hPtr = Tcl_FindHashEntry(&table, (char*) w);
+ if (hPtr != NULL) {
+ childWinPtr = Tcl_GetHashValue(hPtr);
+ *windowPtr-- = childWinPtr;
}
}
if (windowPtr != windows-1) {
Tcl_Panic("num matched toplevel windows does not equal num "
- "children");
+ "children");
}
- ckfree(windowNumbers);
}
done:
@@ -6615,7 +6732,6 @@ RemapWindows(
MacDrawable *parentWin)
{
TkWindow *childPtr;
-
/*
* Remove the OS specific window. It will get rebuilt when the window gets
* Mapped.
diff --git a/macosx/tkMacOSXXStubs.c b/macosx/tkMacOSXXStubs.c
index b16b582..1313c9f 100644
--- a/macosx/tkMacOSXXStubs.c
+++ b/macosx/tkMacOSXXStubs.c
@@ -142,7 +142,7 @@ TkpOpenDisplay(
static NSRect maxBounds = {{0, 0}, {0, 0}};
static char vendor[25] = "";
NSArray *cgVers;
- NSAutoreleasePool *pool;
+ NSAutoreleasePool *pool = [NSAutoreleasePool new];
if (gMacDisplay != NULL) {
if (strcmp(gMacDisplay->display->display_name, display_name) == 0) {
@@ -166,7 +166,6 @@ TkpOpenDisplay(
display->default_screen = 0;
display->display_name = (char *) macScreenName;
- pool = [NSAutoreleasePool new];
cgVers = [[[NSBundle bundleWithIdentifier:@"com.apple.CoreGraphics"]
objectForInfoDictionaryKey:@"CFBundleShortVersionString"]
componentsSeparatedByString:@"."];
@@ -177,12 +176,25 @@ TkpOpenDisplay(
display->proto_minor_version = [[cgVers objectAtIndex:2] integerValue];
}
if (!vendor[0]) {
- snprintf(vendor, sizeof(vendor), "Apple AppKit %s %g",
- ([NSGarbageCollector defaultCollector] ? "GC" : "RR"),
+ snprintf(vendor, sizeof(vendor), "Apple AppKit %g",
NSAppKitVersionNumber);
}
display->vendor = vendor;
- Gestalt(gestaltSystemVersion, (SInt32 *) &display->release);
+ {
+ int major, minor, patch;
+
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 10100
+ Gestalt(gestaltSystemVersionMajor, (SInt32*)&major);
+ Gestalt(gestaltSystemVersionMinor, (SInt32*)&minor);
+ Gestalt(gestaltSystemVersionBugFix, (SInt32*)&patch);
+#else
+ NSOperatingSystemVersion systemVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
+ major = systemVersion.majorVersion;
+ minor = systemVersion.minorVersion;
+ patch = systemVersion.patchVersion;
+#endif
+ display->release = major << 16 | minor << 8 | patch;
+ }
/*
* These screen bits never change
@@ -669,14 +681,6 @@ XForceScreenSaver(
display->request++;
}
-void
-Tk_FreeXId(
- Display *display,
- XID xid)
-{
- /* no-op function needed for stubs implementation. */
-}
-
int
XSync(
Display *display,
@@ -793,6 +797,10 @@ XCreateImage(
ximage->format = format;
ximage->data = data;
ximage->obdata = NULL;
+ /* The default pixelpower is 0. This must be explicitly set to 1 in the
+ * case of an XImage extracted from a Retina display.
+ */
+ ximage->pixelpower = 0;
if (format == ZPixmap) {
ximage->bits_per_pixel = 32;
@@ -844,7 +852,8 @@ XCreateImage(
* Results:
* Returns a newly allocated XImage containing the data from the given
* rectangle of the given drawable, or NULL if the XImage could not be
- * constructed.
+ * constructed. NOTE: If we are copying from a window on a Retina
+ * display, the dimensions of the XImage will be 2*width x 2*height.
*
* Side effects:
* None.
@@ -864,6 +873,7 @@ XGetImage(
int format)
{
NSBitmapImageRep *bitmap_rep;
+ NSUInteger bitmap_fmt;
XImage * imagePtr = NULL;
char * bitmap = NULL;
char * image_data=NULL;
@@ -872,7 +882,19 @@ XGetImage(
int bitmap_pad = 0;
int bytes_per_row = 4*width;
int size;
- TkMacOSXDbgMsg("XGetImage");
+ MacDrawable *macDraw = (MacDrawable *) d;
+ NSWindow *win = TkMacOSXDrawableWindow(d);
+ /* This code assumes that backing scale factors are integers. Currently
+ * Retina displays use a scale factor of 2.0 and normal displays use 1.0.
+ * We do not support any other values here.
+ */
+ int scalefactor = 1;
+ if (win && [win respondsToSelector:@selector(backingScaleFactor)]) {
+ scalefactor = ([win backingScaleFactor] == 2.0) ? 2 : 1;
+ }
+ int scaled_height = height * scalefactor;
+ int scaled_width = width * scalefactor;
+
if (format == ZPixmap) {
if (width == 0 || height == 0) {
/* This happens all the time.
@@ -881,10 +903,11 @@ XGetImage(
return NULL;
}
- bitmap_rep = BitmapRepFromDrawableRect(d, x, y,width, height);
+ bitmap_rep = BitmapRepFromDrawableRect(d, x, y, width, height);
+ bitmap_fmt = [bitmap_rep bitmapFormat];
if ( bitmap_rep == Nil ||
- [bitmap_rep bitmapFormat] != 0 ||
+ (bitmap_fmt != 0 && bitmap_fmt != 1) ||
[bitmap_rep samplesPerPixel] != 4 ||
[bitmap_rep isPlanar] != 0 ) {
TkMacOSXDbgMsg("XGetImage: Failed to construct NSBitmapRep");
@@ -895,33 +918,51 @@ XGetImage(
NSImage* ns_image = [[NSImage alloc]initWithSize:image_size];
[ns_image addRepresentation:bitmap_rep];
- /* Assume premultiplied nonplanar data with 4 bytes per pixel and alpha last.*/
- if ( [bitmap_rep bitmapFormat] == 0 &&
- [bitmap_rep isPlanar ] == 0 &&
+ /* Assume premultiplied nonplanar data with 4 bytes per pixel.*/
+ if ( [bitmap_rep isPlanar ] == 0 &&
[bitmap_rep samplesPerPixel] == 4 ) {
bytes_per_row = [bitmap_rep bytesPerRow];
- size = bytes_per_row*height;
+ assert(bytes_per_row == 4 * scaled_width);
+ assert([bitmap_rep bytesPerPlane] == bytes_per_row * scaled_height);
+ size = bytes_per_row*scaled_height;
image_data = (char*)[bitmap_rep bitmapData];
if ( image_data ) {
int row, n, m;
bitmap = ckalloc(size);
/*
Oddly enough, the bitmap has the top row at the beginning,
- and the pixels are in BGRA format.
+ and the pixels are in BGRA or ABGR format.
*/
- for (row=0, n=0; row<height; row++, n+=bytes_per_row) {
- for (m=n; m<n+bytes_per_row; m+=4) {
- *(bitmap+m) = *(image_data+m+2);
- *(bitmap+m+1) = *(image_data+m+1);
- *(bitmap+m+2) = *(image_data+m);
- *(bitmap+m+3) = *(image_data+m+3);
+ if (bitmap_fmt == 0) {
+ /* BGRA */
+ for (row=0, n=0; row<scaled_height; row++, n+=bytes_per_row) {
+ for (m=n; m<n+bytes_per_row; m+=4) {
+ *(bitmap+m) = *(image_data+m+2);
+ *(bitmap+m+1) = *(image_data+m+1);
+ *(bitmap+m+2) = *(image_data+m);
+ *(bitmap+m+3) = *(image_data+m+3);
+ }
+ }
+ } else {
+ /* ABGR */
+ for (row=0, n=0; row<scaled_height; row++, n+=bytes_per_row) {
+ for (m=n; m<n+bytes_per_row; m+=4) {
+ *(bitmap+m) = *(image_data+m+3);
+ *(bitmap+m+1) = *(image_data+m+2);
+ *(bitmap+m+2) = *(image_data+m+1);
+ *(bitmap+m+3) = *(image_data+m);
+ }
}
}
}
}
if (bitmap) {
imagePtr = XCreateImage(display, NULL, depth, format, offset,
- (char*)bitmap, width, height, bitmap_pad, bytes_per_row);
+ (char*)bitmap, scaled_width, scaled_height,
+ bitmap_pad, bytes_per_row);
+ if (scalefactor == 2) {
+ imagePtr->pixelpower = 1;
+ }
[ns_image removeRepresentation:bitmap_rep]; /*releases the rep*/
[ns_image release];
}
diff --git a/macosx/ttkMacOSXTheme.c b/macosx/ttkMacOSXTheme.c
index 4753a40..f9611c5 100644
--- a/macosx/ttkMacOSXTheme.c
+++ b/macosx/ttkMacOSXTheme.c
@@ -298,7 +298,7 @@ static void TabElementSize(
void *clientData, void *elementRecord, Tk_Window tkwin,
int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
- *heightPtr = GetThemeMetric(kThemeMetricLargeTabHeight, heightPtr);
+ GetThemeMetric(kThemeMetricLargeTabHeight, (SInt32 *)heightPtr);
*paddingPtr = Ttk_MakePadding(0, 0, 0, 2);
}