Import Tk 8.6.11
This commit is contained in:
24
macosx/Credits.html.in
Normal file
24
macosx/Credits.html.in
Normal file
@@ -0,0 +1,24 @@
|
||||
<!doctype htmL>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body style="font-size:120%;font-family:Arial,sans-serif;">
|
||||
<p>
|
||||
Tcl and Tk are distributed under a modified BSD license:<br>
|
||||
<a href="https:www.tcl.tk/software/tcltk/license.html">
|
||||
https:www.tcl.tk/software/tcltk/license.html
|
||||
</a>
|
||||
</p>
|
||||
<ul style="list-style-type:none;">
|
||||
<li>© 1987-@TK_YEAR@ Tcl Core Team and Contributers.</li>
|
||||
<li>© 2011-@TK_YEAR@ Kevin Walzer/WordTech Communications LLC.</li>
|
||||
<li>© 2014-@TK_YEAR@ Marc Culler.</li>
|
||||
<li>© 2002-2012 Daniel A. Steffen.</li>
|
||||
<li>© 2001-2009 Apple Inc.</li>
|
||||
<li>© 2001-2002 Jim Ingham & Ian Reid.</li>
|
||||
<li>© 1998-2000 Jim Ingham & Ray Johnson.</li>
|
||||
<li>© 1998-2000 Scriptics Inc.</li>
|
||||
<li>© 1996-1997 Sun Microsystems Inc.</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
@@ -25,6 +25,7 @@ EXTRA_CONFIGURE_ARGS ?=
|
||||
EXTRA_MAKE_ARGS ?=
|
||||
|
||||
INSTALL_PATH ?= /Library/Frameworks
|
||||
TCL_INSTALL_PATH ?= ${INSTALL_PATH}/Tcl.framework
|
||||
APPLICATION_INSTALL_PATH ?= /Applications/Utilities
|
||||
PREFIX ?= /usr/local
|
||||
BINDIR ?= ${PREFIX}/bin
|
||||
@@ -43,6 +44,18 @@ INSTALL_MANPAGES ?=
|
||||
# set to non-empty value to build TkX11 instead of TkAqua:
|
||||
TK_X11 ?=
|
||||
|
||||
# Checks and overrides for subframework builds
|
||||
ifeq (${SUBFRAMEWORK}_${TK_X11},1_)
|
||||
ifeq (${DYLIB_INSTALL_DIR},)
|
||||
@echo "Cannot install subframework with empty DYLIB_INSTALL_DIR !" && false
|
||||
endif
|
||||
ifeq (${DESTDIR},)
|
||||
@echo "Cannot install subframework with empty DESTDIR !" && false
|
||||
endif
|
||||
override BUILD_DIR = ${DESTDIR}/build
|
||||
override INSTALL_PATH = /Frameworks
|
||||
endif
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
# meta targets
|
||||
|
||||
@@ -107,7 +120,7 @@ TCL_VERSION := ${VERSION}
|
||||
wish := wish
|
||||
WISH = wish${VERSION}
|
||||
|
||||
BUILD_TARGET := all tktest
|
||||
BUILD_TARGET := binaries libraries tktest
|
||||
INSTALL_TARGET := install
|
||||
|
||||
ifneq ($(wildcard $(subst ${space},\ ,${TCL_BUILD_DIR})/tclConfig.sh),)
|
||||
@@ -115,7 +128,7 @@ TCL_DIR := ${TCL_BUILD_DIR}
|
||||
TCL_FRAMEWORK_DIR := ${TCL_BUILD_DIR}/..
|
||||
MAKE_VARS :=
|
||||
else
|
||||
TCL_DIR := ${TCL_FRAMEWORK_DIR}/Tcl.framework
|
||||
TCL_DIR := ${TCL_INSTALL_PATH}
|
||||
TCL_EXE := ${TCLSH_DIR}/tclsh${TCL_VERSION}
|
||||
MAKE_VARS := TCL_EXE
|
||||
export DYLD_FRAMEWORK_PATH := ${TCL_FRAMEWORK_DIR}
|
||||
@@ -210,8 +223,14 @@ install-${PROJECT}: build-${PROJECT}
|
||||
ifeq (${EMBEDDED_BUILD}_${INSTALL_ROOT},1_)
|
||||
@echo "Cannot install-embedded with empty INSTALL_ROOT !" && false
|
||||
endif
|
||||
ifeq (${SUBFRAMEWORK}_${DYLIB_INSTALL_DIR},1_)
|
||||
@echo "Cannot install subframework with empty DYLIB_INSTALL_DIR !" && false
|
||||
endif
|
||||
ifeq (${EMBEDDED_BUILD},1)
|
||||
@rm -rf "${INSTALL_ROOT}/${LIBDIR}/Tk.framework"
|
||||
endif
|
||||
ifeq (${SUBFRAMEWORK},1)
|
||||
@rm -rf "${INSTALL_ROOT}/Frameworks/Tk.framework"
|
||||
endif
|
||||
${DO_MAKE}
|
||||
ifeq (${EMBEDDED_BUILD}_${TK_X11},1_)
|
||||
@@ -227,8 +246,8 @@ ifeq (${EMBEDDED_BUILD},1)
|
||||
else
|
||||
# install wish symbolic link
|
||||
@ln -fs ${WISH} "${INSTALL_ROOT}${BINDIR}/${wish}"
|
||||
endif
|
||||
endif
|
||||
endif # embedded
|
||||
endif # install
|
||||
ifeq (${BUILD_STYLE}_${EMBEDDED_BUILD},Development_)
|
||||
# keep copy of debug library around, so that
|
||||
# Deployment build can be installed on top
|
||||
@@ -236,8 +255,9 @@ ifeq (${BUILD_STYLE}_${EMBEDDED_BUILD},Development_)
|
||||
# the debug library
|
||||
@cd "${INSTALL_ROOT}${LIBDIR}/${PRODUCT_NAME}.framework/Versions/${VERSION}" && \
|
||||
ln -f "${PRODUCT_NAME}" "${PRODUCT_NAME}_debug"
|
||||
endif
|
||||
endif # Development, not embedded
|
||||
ifeq (${TK_X11},)
|
||||
ifeq (${SUBFRAMEWORK},)
|
||||
ifeq (${EMBEDDED_BUILD},)
|
||||
# install Wish.app link in APPLICATION_INSTALL_PATH and setup 'Wish Shell' compatibility links
|
||||
@cd "${TOP_DIR}" && if [ -n "${APP_DIR}" ]; then mkdir -p "./${APP_DIR}" && rm -rf "./${APP_DIR}/Wish.app" && \
|
||||
@@ -271,9 +291,10 @@ else
|
||||
fix_install_name MacOS/Wish Tcl && fix_install_name MacOS/Wish Tk
|
||||
ifeq (${INSTALL_BUILD},1)
|
||||
@cd "${TOP_DIR}" && rm -rf "./${FMWK_DIR}"/T{cl,k}.framework && rmdir -p "./${FMWK_DIR}" 2>&- || true
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif # install not subframework
|
||||
endif # embedded
|
||||
endif # not subframework
|
||||
endif # not X11
|
||||
|
||||
clean-${PROJECT}: %-${PROJECT}:
|
||||
${DO_MAKE}
|
||||
|
||||
@@ -275,9 +275,9 @@ but rather refers to the context in which the color should be used.
|
||||
Tk now provides the following semantic colors as system colors:
|
||||
systemTextColor, systemTextBackgroundColor, systemSelectedTextColor,
|
||||
systemSelectedTextBackgroundColor, systemControlTextColor,
|
||||
systemDisabledControlTextColor, systemLabelColor, and
|
||||
systemControlAccentColor. All of these except the last two were
|
||||
present in OSX 10.0 (and those two are simulated in systems where they
|
||||
systemDisabledControlTextColor, systemLabelColor, systemLinkColor, and
|
||||
systemControlAccentColor. All of these except the last three were
|
||||
present in OSX 10.0 (and those three are simulated in systems where they
|
||||
do not exist). The change in 10.14 was that the RGB color value of
|
||||
these colors became dynamic, meaning that the color value can change
|
||||
when the application appearance changes. In particular, when a user
|
||||
@@ -455,6 +455,20 @@ make overrides to the tk/macosx GNUmakefile, e.g.
|
||||
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.
|
||||
|
||||
- To build a Tcl.framework and Tk.framework for use as subframeworks in another
|
||||
framework, use the install-embedded target and set SUBFRAMEWORK=1. Set the
|
||||
DYLIB_INSTALL_DIR variable to the path which should be the install_name path of
|
||||
the shared library and set the DESTDIR variable to the pathname of a staging
|
||||
directory where the frameworks will be written. The Tcl framework must be
|
||||
built first.
|
||||
For example, running the commands:
|
||||
make -C ../tcl8.6/macosx install-embedded SUBFRAMEWORK=1 DESTDIR=/tmp/tcltk \
|
||||
DYLIB_INSTALL_DIR=/Library/Frameworks/Some.framework/Versions/X.Y/Frameworks/Tcl.framework
|
||||
make -C macosx install-embedded SUBFRAMEWORK=1 DESTDIR=/tmp/tcltk \
|
||||
DYLIB_INSTALL_DIR=/Library/Frameworks/Some.framework/Versions/X.Y/Frameworks/Tk.framework
|
||||
will produce a Tcl.framework and a Tk.framework usable as subframeworks of
|
||||
Some.framework. The frameworks will be found in /tmp/tcltk/Frameworks/
|
||||
|
||||
5. Details regarding the macOS port of Tk.
|
||||
-------------------------------------------
|
||||
|
||||
@@ -662,15 +676,35 @@ source and destination rectangles for the scrolling. The embedded
|
||||
windows are redrawn within the DisplayText function by some
|
||||
conditional code which is only used for macOS.
|
||||
|
||||
6.0 Virtual events on 10.14
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
6.0 Virtual events on macOS 10.14 and later
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The 10.14 release added support for system appearance changes,
|
||||
including a "Dark Mode" that renders all window frames and menus in
|
||||
dark colors. Tk 8.6.11 provides three virtual events <<LightAqua>>,
|
||||
<<DarkAqua>> and <<AppearanceChanged>>, to allow you to update your Tk
|
||||
app's appearance when the system appearance changes. These events are
|
||||
generated in [NSView effectiveAppearanceChanged], which is called by
|
||||
the Apple window manager when the General Preferences is changed
|
||||
either by switching between Light Mode and Dark Mode or by changing
|
||||
the Accent Color or Highlight Color.
|
||||
|
||||
The <<AppearanceChanged>> virtual event has a data string which can be
|
||||
accessed with the %d substitution. The format of the data string is
|
||||
that it consists of 6 words:
|
||||
"Appearance XXXX Accent YYYY Highlight ZZZZ"
|
||||
For example, the following code will print the current appearance
|
||||
name, accent color and highlight color when the <<AppearanceChanged>>
|
||||
virtual event fires:
|
||||
|
||||
bind . <<AppearanceChanged>> {
|
||||
array set data [split %d]
|
||||
puts " Appearance: $data(Appearance)"
|
||||
puts " Accent: $data(Accent)"
|
||||
puts " Highlight: $data(Highlight)\n"
|
||||
}
|
||||
|
||||
|
||||
10.14 supports system appearance changes, and has added a "Dark Mode"
|
||||
that casts all window frames and menus as black. Tk 8.6.9 has added two
|
||||
virtual events, <<LightAqua>> and <<DarkAqua>>, to allow you to update
|
||||
your Tk app's appearance when the system appearance changes. Just bind
|
||||
your appearance-updating code to these virtual events and you will see
|
||||
it triggered when the system appearance toggles between dark and light.
|
||||
|
||||
7.0 Mac Services
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -1411,7 +1411,7 @@
|
||||
F96D3E1F08F272A5004A47F5 /* CrtInterp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtInterp.3; sourceTree = "<group>"; };
|
||||
F96D3E2008F272A5004A47F5 /* CrtMathFnc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtMathFnc.3; sourceTree = "<group>"; };
|
||||
F96D3E2108F272A5004A47F5 /* CrtObjCmd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtObjCmd.3; sourceTree = "<group>"; };
|
||||
F96D3E2208F272A5004A47F5 /* CrtSlave.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtSlave.3; sourceTree = "<group>"; };
|
||||
F96D3E2208F272A5004A47F5 /* CrtAlias.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtAlias.3; sourceTree = "<group>"; };
|
||||
F96D3E2308F272A5004A47F5 /* CrtTimerHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtTimerHdlr.3; sourceTree = "<group>"; };
|
||||
F96D3E2408F272A5004A47F5 /* CrtTrace.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtTrace.3; sourceTree = "<group>"; };
|
||||
F96D3E2508F272A5004A47F5 /* dde.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = dde.n; sourceTree = "<group>"; };
|
||||
@@ -3078,7 +3078,7 @@
|
||||
F96D3E1F08F272A5004A47F5 /* CrtInterp.3 */,
|
||||
F96D3E2008F272A5004A47F5 /* CrtMathFnc.3 */,
|
||||
F96D3E2108F272A5004A47F5 /* CrtObjCmd.3 */,
|
||||
F96D3E2208F272A5004A47F5 /* CrtSlave.3 */,
|
||||
F96D3E2208F272A5004A47F5 /* CrtAlias.3 */,
|
||||
F96D3E2308F272A5004A47F5 /* CrtTimerHdlr.3 */,
|
||||
F96D3E2408F272A5004A47F5 /* CrtTrace.3 */,
|
||||
F96D3E2508F272A5004A47F5 /* dde.n */,
|
||||
|
||||
@@ -1411,7 +1411,7 @@
|
||||
F96D3E1F08F272A5004A47F5 /* CrtInterp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtInterp.3; sourceTree = "<group>"; };
|
||||
F96D3E2008F272A5004A47F5 /* CrtMathFnc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtMathFnc.3; sourceTree = "<group>"; };
|
||||
F96D3E2108F272A5004A47F5 /* CrtObjCmd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtObjCmd.3; sourceTree = "<group>"; };
|
||||
F96D3E2208F272A5004A47F5 /* CrtSlave.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtSlave.3; sourceTree = "<group>"; };
|
||||
F96D3E2208F272A5004A47F5 /* CrtAlias.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtAlias.3; sourceTree = "<group>"; };
|
||||
F96D3E2308F272A5004A47F5 /* CrtTimerHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtTimerHdlr.3; sourceTree = "<group>"; };
|
||||
F96D3E2408F272A5004A47F5 /* CrtTrace.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtTrace.3; sourceTree = "<group>"; };
|
||||
F96D3E2508F272A5004A47F5 /* dde.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = dde.n; sourceTree = "<group>"; };
|
||||
@@ -3078,7 +3078,7 @@
|
||||
F96D3E1F08F272A5004A47F5 /* CrtInterp.3 */,
|
||||
F96D3E2008F272A5004A47F5 /* CrtMathFnc.3 */,
|
||||
F96D3E2108F272A5004A47F5 /* CrtObjCmd.3 */,
|
||||
F96D3E2208F272A5004A47F5 /* CrtSlave.3 */,
|
||||
F96D3E2208F272A5004A47F5 /* CrtAlias.3 */,
|
||||
F96D3E2308F272A5004A47F5 /* CrtTimerHdlr.3 */,
|
||||
F96D3E2408F272A5004A47F5 /* CrtTrace.3 */,
|
||||
F96D3E2508F272A5004A47F5 /* dde.n */,
|
||||
|
||||
68
macosx/configure
vendored
68
macosx/configure
vendored
@@ -2287,7 +2287,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
TK_VERSION=8.6
|
||||
TK_MAJOR_VERSION=8
|
||||
TK_MINOR_VERSION=6
|
||||
TK_PATCH_LEVEL=".10"
|
||||
TK_PATCH_LEVEL=".11"
|
||||
VERSION=${TK_VERSION}
|
||||
LOCALES="cs da de el en en_gb eo es fr hu it nl pl pt ru sv"
|
||||
|
||||
@@ -2432,10 +2432,6 @@ $as_echo "loading" >&6; }
|
||||
$as_echo "could not find ${TCL_BIN_DIR}/tclConfig.sh" >&6; }
|
||||
fi
|
||||
|
||||
# eval is required to do the TCL_DBGX substitution
|
||||
eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
|
||||
eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
|
||||
|
||||
# If the TCL_BIN_DIR is the build directory (not the install directory),
|
||||
# then set the common variable name to the value of the build variables.
|
||||
# For example, the variable TCL_LIB_SPEC will be set to the value
|
||||
@@ -2469,12 +2465,6 @@ $as_echo "could not find ${TCL_BIN_DIR}/tclConfig.sh" >&6; }
|
||||
esac
|
||||
fi
|
||||
|
||||
# eval is required to do the TCL_DBGX substitution
|
||||
eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
|
||||
eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
|
||||
eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
|
||||
eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4286,14 +4276,6 @@ else
|
||||
tcl_ok=yes
|
||||
fi
|
||||
|
||||
|
||||
if test "${enable_shared+set}" = set; then
|
||||
enableval="$enable_shared"
|
||||
tcl_ok=$enableval
|
||||
else
|
||||
tcl_ok=yes
|
||||
fi
|
||||
|
||||
if test "$tcl_ok" = "yes" ; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: shared" >&5
|
||||
$as_echo "shared" >&6; }
|
||||
@@ -4607,7 +4589,7 @@ fi
|
||||
if test "$GCC" = yes; then :
|
||||
|
||||
CFLAGS_OPTIMIZE=-O2
|
||||
CFLAGS_WARNING="-Wall"
|
||||
CFLAGS_WARNING="-Wall -Wpointer-arith"
|
||||
|
||||
else
|
||||
|
||||
@@ -4875,7 +4857,7 @@ fi
|
||||
CC_SEARCH_FLAGS=""
|
||||
LD_SEARCH_FLAGS=""
|
||||
;;
|
||||
CYGWIN_*|MINGW32*)
|
||||
CYGWIN_*|MINGW32_*|MSYS_*)
|
||||
SHLIB_CFLAGS=""
|
||||
SHLIB_LD='${CC} -shared'
|
||||
SHLIB_SUFFIX=".dll"
|
||||
@@ -4886,7 +4868,7 @@ fi
|
||||
CC_SEARCH_FLAGS=""
|
||||
LD_SEARCH_FLAGS=""
|
||||
TCL_NEEDS_EXP_FILE=1
|
||||
TCL_EXPORT_FILE_SUFFIX='${VERSION}\$\{DBGX\}.dll.a'
|
||||
TCL_EXPORT_FILE_SUFFIX='${VERSION}.dll.a'
|
||||
SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,--out-implib,\$@.a"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Cygwin version of gcc" >&5
|
||||
$as_echo_n "checking for Cygwin version of gcc... " >&6; }
|
||||
@@ -5092,7 +5074,7 @@ fi
|
||||
SHLIB_LD='${CC} -shared'
|
||||
if test $doRpath = yes; then :
|
||||
|
||||
CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
|
||||
CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
|
||||
fi
|
||||
LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
|
||||
;;
|
||||
@@ -5182,7 +5164,7 @@ esac
|
||||
|
||||
if test $doRpath = yes; then :
|
||||
|
||||
CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
|
||||
CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
|
||||
LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
|
||||
fi
|
||||
;;
|
||||
@@ -5200,7 +5182,7 @@ esac
|
||||
|
||||
if test $doRpath = yes; then :
|
||||
|
||||
CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
|
||||
CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
|
||||
LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
|
||||
fi
|
||||
if test "$GCC" = yes; then :
|
||||
@@ -5237,7 +5219,7 @@ esac
|
||||
|
||||
if test $doRpath = yes; then :
|
||||
|
||||
CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
|
||||
CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
|
||||
LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
|
||||
fi
|
||||
|
||||
@@ -5277,7 +5259,7 @@ fi
|
||||
LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
|
||||
if test $doRpath = yes; then :
|
||||
|
||||
CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
|
||||
CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
|
||||
fi
|
||||
LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
|
||||
if test "`uname -m`" = "alpha"; then :
|
||||
@@ -5344,8 +5326,8 @@ fi
|
||||
LD_FLAGS="-Wl,--export-dynamic"
|
||||
if test $doRpath = yes; then :
|
||||
|
||||
CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
|
||||
LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
|
||||
CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
|
||||
LD_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
|
||||
fi
|
||||
;;
|
||||
MP-RAS-02*)
|
||||
@@ -5385,7 +5367,7 @@ fi
|
||||
DL_LIBS=""
|
||||
if test $doRpath = yes; then :
|
||||
|
||||
CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
|
||||
CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
|
||||
fi
|
||||
LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
|
||||
SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}'
|
||||
@@ -5413,7 +5395,7 @@ fi
|
||||
LDFLAGS="$LDFLAGS -export-dynamic"
|
||||
if test $doRpath = yes; then :
|
||||
|
||||
CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
|
||||
CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
|
||||
fi
|
||||
LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
|
||||
if test "${TCL_THREADS}" = "1"; then :
|
||||
@@ -5433,11 +5415,10 @@ fi
|
||||
SHLIB_SUFFIX=".so"
|
||||
DL_OBJS="tclLoadDl.o"
|
||||
DL_LIBS=""
|
||||
LDFLAGS=""
|
||||
if test $doRpath = yes; then :
|
||||
|
||||
CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
|
||||
LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
|
||||
CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
|
||||
LD_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
|
||||
fi
|
||||
if test "${TCL_THREADS}" = "1"; then :
|
||||
|
||||
@@ -5640,6 +5621,7 @@ fi
|
||||
|
||||
$as_echo "#define MODULE_SCOPE __private_extern__" >>confdefs.h
|
||||
|
||||
tcl_cv_cc_visibility_hidden=yes
|
||||
|
||||
fi
|
||||
CC_SEARCH_FLAGS=""
|
||||
@@ -5830,7 +5812,7 @@ fi
|
||||
DL_LIBS=""
|
||||
if test $doRpath = yes; then :
|
||||
|
||||
CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
|
||||
CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
|
||||
LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
|
||||
fi
|
||||
if test "$GCC" = yes; then :
|
||||
@@ -6233,7 +6215,7 @@ fi
|
||||
case $system in
|
||||
AIX-*) ;;
|
||||
BSD/OS*) ;;
|
||||
CYGWIN_*|MINGW32_*) ;;
|
||||
CYGWIN_*|MINGW32_*|MSYS_*) ;;
|
||||
IRIX*) ;;
|
||||
NetBSD-*|DragonFly-*|FreeBSD-*|OpenBSD-*) ;;
|
||||
Darwin-*) ;;
|
||||
@@ -6263,7 +6245,7 @@ fi
|
||||
if test "${SHARED_BUILD}" = 1 -a "${SHLIB_SUFFIX}" != ""; then :
|
||||
|
||||
LIB_SUFFIX=${SHARED_LIB_SUFFIX}
|
||||
MAKE_LIB='${SHLIB_LD} -o $@ ${OBJS} ${SHLIB_LD_LIBS} ${TCL_SHLIB_LD_EXTRAS} ${TK_SHLIB_LD_EXTRAS} ${LD_SEARCH_FLAGS}'
|
||||
MAKE_LIB='${SHLIB_LD} -o $@ ${OBJS} ${LDFLAGS} ${SHLIB_LD_LIBS} ${TCL_SHLIB_LD_EXTRAS} ${TK_SHLIB_LD_EXTRAS} ${LD_SEARCH_FLAGS}'
|
||||
if test "${SHLIB_SUFFIX}" = ".dll"; then :
|
||||
|
||||
INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(BIN_INSTALL_DIR)/$(LIB_FILE)";if test -f $(LIB_FILE).a; then $(INSTALL_DATA) $(LIB_FILE).a "$(LIB_INSTALL_DIR)"; fi;'
|
||||
@@ -6404,7 +6386,6 @@ else
|
||||
fi
|
||||
|
||||
# FIXME: Currently, LDFLAGS_DEFAULT is not used, it should work like CFLAGS_DEFAULT.
|
||||
DBGX=""
|
||||
if test "$tcl_ok" = "no"; then
|
||||
CFLAGS_DEFAULT='$(CFLAGS_OPTIMIZE)'
|
||||
LDFLAGS_DEFAULT='$(LDFLAGS_OPTIMIZE)'
|
||||
@@ -7384,7 +7365,7 @@ else
|
||||
int
|
||||
main ()
|
||||
{
|
||||
struct passwd pwd; pwd.pw_gecos;
|
||||
struct passwd pwd; (void)pwd.pw_gecos;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
@@ -8668,8 +8649,12 @@ $as_echo "static library" >&6; }
|
||||
echo "$LDFLAGS " | grep -q -- '-prebind ' && TK_SHLIB_LD_EXTRAS="${TK_SHLIB_LD_EXTRAS}"' -seg1addr 0xb000000'
|
||||
TK_SHLIB_LD_EXTRAS="${TK_SHLIB_LD_EXTRAS}"' -sectcreate __TEXT __info_plist Tk-Info.plist'
|
||||
EXTRA_WISH_LIBS='-sectcreate __TEXT __info_plist Wish-Info.plist'
|
||||
EXTRA_WISH_LIBS=${EXTRA_WISH_LIBS}' -sectcreate __TEXT __credits_html Credits.html'
|
||||
if test "${SHARED_BUILD}" = "0"; then
|
||||
EXTRA_WISH_LIBS=${EXTRA_WISH_LIBS}' -ObjC'
|
||||
fi
|
||||
EXTRA_APP_CC_SWITCHES="${EXTRA_APP_CC_SWITCHES}"' -mdynamic-no-pic'
|
||||
ac_config_files="$ac_config_files Tk-Info.plist:../macosx/Tk-Info.plist.in Wish-Info.plist:../macosx/Wish-Info.plist.in"
|
||||
ac_config_files="$ac_config_files Tk-Info.plist:../macosx/Tk-Info.plist.in Wish-Info.plist:../macosx/Wish-Info.plist.in Credits.html:../macosx/Credits.html.in"
|
||||
|
||||
for l in ${LOCALES}; do CFBUNDLELOCALIZATIONS="${CFBUNDLELOCALIZATIONS}<string>$l</string>"; done
|
||||
TK_YEAR="`date +%Y`"
|
||||
@@ -8703,6 +8688,7 @@ $as_echo "#define TK_FRAMEWORK 1" >>confdefs.h
|
||||
EXTRA_INSTALL="install-private-headers html-tk"
|
||||
EXTRA_BUILD_HTML='@ln -fs contents.htm "$(HTML_INSTALL_DIR)"/TkTOC.html'
|
||||
EXTRA_INSTALL_BINARIES='@echo "Installing Info.plist to $(LIB_INSTALL_DIR)/Resources/" && $(INSTALL_DATA_DIR) "$(LIB_INSTALL_DIR)/Resources" && $(INSTALL_DATA) Tk-Info.plist "$(LIB_INSTALL_DIR)/Resources/Info.plist"'
|
||||
EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Credits.html to $(LIB_INSTALL_DIR)/Resources/" && $(INSTALL_DATA_DIR) "$(LIB_INSTALL_DIR)/Resources" && $(INSTALL_DATA) Credits.html "$(LIB_INSTALL_DIR)/Resources"'
|
||||
EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing license.terms to $(LIB_INSTALL_DIR)/Resources/" && $(INSTALL_DATA) "$(TOP_DIR)/license.terms" "$(LIB_INSTALL_DIR)/Resources"'
|
||||
if test $tk_aqua = yes; then
|
||||
EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Images to $(LIB_INSTALL_DIR)/Resources/" && $(INSTALL_DATA_DIR) "$(LIB_INSTALL_DIR)/Resources" && for i in Tk.tiff Tk.icns; do $(INSTALL_DATA) "$(MAC_OSX_DIR)/$$i" "$(LIB_INSTALL_DIR)/Resources"; done'
|
||||
@@ -8712,6 +8698,7 @@ $as_echo "#define TK_FRAMEWORK 1" >>confdefs.h
|
||||
EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Wish.icns to $(BIN_INSTALL_DIR)/../Resources" && $(INSTALL_DATA_DIR) "$(BIN_INSTALL_DIR)/../Resources"'
|
||||
EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && $(INSTALL_DATA) "$(MAC_OSX_DIR)/Tk.icns" "$(BIN_INSTALL_DIR)/../Resources/Wish.icns"'
|
||||
EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Wish.sdef to $(BIN_INSTALL_DIR)/../Resources" && $(INSTALL_DATA) "$(MAC_OSX_DIR)/Wish.sdef" "$(BIN_INSTALL_DIR)/../Resources"'
|
||||
EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Credits.html to $(BIN_INSTALL_DIR)/../Resources" && $(INSTALL_DATA) Credits.html "$(BIN_INSTALL_DIR)/../Resources"'
|
||||
fi
|
||||
EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Finalizing Tk.framework" && rm -f "$(LIB_INSTALL_DIR)/../Current" && ln -s "$(VERSION)" "$(LIB_INSTALL_DIR)/../Current" && for f in "$(LIB_FILE)" tkConfig.sh Resources Headers PrivateHeaders; do rm -f "$(LIB_INSTALL_DIR)/../../$$f" && ln -s "Versions/Current/$$f" "$(LIB_INSTALL_DIR)/../.."; done && f="$(STUB_LIB_FILE)" && rm -f "$(LIB_INSTALL_DIR)/../../$$f" && ln -s "Versions/$(VERSION)/$$f" "$(LIB_INSTALL_DIR)/../.."'
|
||||
# Don't use AC_DEFINE for the following as the framework version define
|
||||
@@ -9525,6 +9512,7 @@ do
|
||||
"tkConfig.h") CONFIG_HEADERS="$CONFIG_HEADERS tkConfig.h:../unix/tkConfig.h.in" ;;
|
||||
"Tk-Info.plist") CONFIG_FILES="$CONFIG_FILES Tk-Info.plist:../macosx/Tk-Info.plist.in" ;;
|
||||
"Wish-Info.plist") CONFIG_FILES="$CONFIG_FILES Wish-Info.plist:../macosx/Wish-Info.plist.in" ;;
|
||||
"Credits.html") CONFIG_FILES="$CONFIG_FILES Credits.html:../macosx/Credits.html.in" ;;
|
||||
"Tk.framework") CONFIG_COMMANDS="$CONFIG_COMMANDS Tk.framework" ;;
|
||||
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile:../unix/Makefile.in" ;;
|
||||
"tkConfig.sh") CONFIG_FILES="$CONFIG_FILES tkConfig.sh:../unix/tkConfig.sh.in" ;;
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
typedef int (Tk_MacOSXEmbedRegisterWinProc) (long winID, Tk_Window window);
|
||||
typedef void* (Tk_MacOSXEmbedGetGrafPortProc) (Tk_Window window);
|
||||
typedef int (Tk_MacOSXEmbedMakeContainerExistProc) (Tk_Window window);
|
||||
typedef void (Tk_MacOSXEmbedGetClipProc) (Tk_Window window, TkRegion rgn);
|
||||
typedef void (Tk_MacOSXEmbedGetClipProc) (Tk_Window window, void *rgn);
|
||||
typedef void (Tk_MacOSXEmbedGetOffsetInParentProc) (Tk_Window window, void *ulCorner);
|
||||
|
||||
#include "tkPlatDecls.h"
|
||||
|
||||
@@ -44,7 +44,7 @@ static BuiltInIcon builtInIcons[] = {
|
||||
{"stop", kAlertStopIcon},
|
||||
{"note", kAlertNoteIcon},
|
||||
{"caution", kAlertCautionIcon},
|
||||
{NULL}
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
#define builtInIconSize 32
|
||||
@@ -100,7 +100,7 @@ TkpDefineNativeBitmaps(void)
|
||||
name = Tk_GetUid(builtInPtr->name);
|
||||
predefHashPtr = Tcl_CreateHashEntry(tablePtr, name, &isNew);
|
||||
if (isNew) {
|
||||
TkPredefBitmap *predefPtr = ckalloc(sizeof(TkPredefBitmap));
|
||||
TkPredefBitmap *predefPtr = (TkPredefBitmap *)ckalloc(sizeof(TkPredefBitmap));
|
||||
|
||||
predefPtr->source = UINT2PTR(builtInPtr->iconType);
|
||||
predefPtr->width = builtInIconSize;
|
||||
@@ -136,15 +136,13 @@ PixmapFromImage(
|
||||
Pixmap pixmap;
|
||||
|
||||
pixmap = Tk_GetPixmap(display, None, size.width, size.height, 0);
|
||||
if (TkMacOSXSetupDrawingContext(pixmap, NULL, 1, &dc)) {
|
||||
if (TkMacOSXSetupDrawingContext(pixmap, NULL, &dc)) {
|
||||
if (dc.context) {
|
||||
CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1,
|
||||
.tx = 0, .ty = size.height};
|
||||
CGContextConcatCTM(dc.context, t);
|
||||
[NSGraphicsContext saveGraphicsState];
|
||||
[NSGraphicsContext setCurrentContext:[NSGraphicsContext
|
||||
graphicsContextWithGraphicsPort:dc.context
|
||||
flipped:NO]];
|
||||
[NSGraphicsContext setCurrentContext:GET_NSCONTEXT(dc.context, NO)];
|
||||
[image drawAtPoint:NSZeroPoint fromRect:NSZeroRect
|
||||
operation:NSCompositeCopy fraction:1.0];
|
||||
[NSGraphicsContext restoreGraphicsState];
|
||||
@@ -180,7 +178,7 @@ TkpCreateNativeBitmap(
|
||||
NSImage *iconImage = [[NSWorkspace sharedWorkspace]
|
||||
iconForFileType: iconUTI];
|
||||
CGSize size = CGSizeMake(builtInIconSize, builtInIconSize);
|
||||
Pixmap pixmap = PixmapFromImage(display, iconImage, NSSizeToCGSize(size));
|
||||
Pixmap pixmap = PixmapFromImage(display, iconImage, size);
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
@@ -317,7 +315,6 @@ TkpGetNativeAppBitmap(
|
||||
OSType iconType;
|
||||
if (OSTypeFromString(name, &iconType) == TCL_OK) {
|
||||
NSString *iconUTI = OSTYPE_TO_UTI(iconType);
|
||||
printf("Found image for UTI %s\n", iconUTI.UTF8String);
|
||||
NSImage *iconImage = [[NSWorkspace sharedWorkspace]
|
||||
iconForFileType: iconUTI];
|
||||
pixmap = PixmapFromImage(display, iconImage, NSSizeToCGSize(size));
|
||||
@@ -344,7 +341,7 @@ TkpGetNativeAppBitmap(
|
||||
|
||||
int
|
||||
TkMacOSXIconBitmapObjCmd(
|
||||
ClientData clientData, /* Unused. */
|
||||
TCL_UNUSED(void *),
|
||||
Tcl_Interp *interp, /* Current interpreter. */
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
@@ -399,7 +396,7 @@ TkMacOSXIconBitmapObjCmd(
|
||||
}
|
||||
}
|
||||
#endif
|
||||
ib.value = ckalloc(len + 1);
|
||||
ib.value = (char *)ckalloc(len + 1);
|
||||
strcpy(ib.value, value);
|
||||
if (!iconBitmapTable.buckets) {
|
||||
Tcl_InitHashTable(&iconBitmapTable, TCL_STRING_KEYS);
|
||||
@@ -409,7 +406,7 @@ TkMacOSXIconBitmapObjCmd(
|
||||
iconBitmap = Tcl_GetHashValue(hPtr);
|
||||
ckfree(iconBitmap->value);
|
||||
} else {
|
||||
iconBitmap = ckalloc(sizeof(IconBitmap));
|
||||
iconBitmap = (IconBitmap *)ckalloc(sizeof(IconBitmap));
|
||||
Tcl_SetHashValue(hPtr, iconBitmap);
|
||||
}
|
||||
*iconBitmap = ib;
|
||||
|
||||
@@ -95,6 +95,8 @@ static void PulseDefaultButtonProc(ClientData clientData);
|
||||
const Tk_ClassProcs tkpButtonProcs = {
|
||||
sizeof(Tk_ClassProcs), /* size */
|
||||
TkButtonWorldChanged, /* worldChangedProc */
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
static int bCount;
|
||||
@@ -143,7 +145,7 @@ TkButton *
|
||||
TkpCreateButton(
|
||||
Tk_Window tkwin)
|
||||
{
|
||||
MacButton *macButtonPtr = ckalloc(sizeof(MacButton));
|
||||
MacButton *macButtonPtr = (MacButton *)ckalloc(sizeof(MacButton));
|
||||
|
||||
Tk_CreateEventHandler(tkwin, ActivateMask,
|
||||
ButtonEventProc, macButtonPtr);
|
||||
@@ -186,22 +188,12 @@ TkpDisplayButton(
|
||||
DrawParams* dpPtr = &macButtonPtr->drawParams;
|
||||
int needhighlight = 0;
|
||||
|
||||
if (butPtr->flags & BUTTON_DELETED) {
|
||||
return;
|
||||
}
|
||||
butPtr->flags &= ~REDRAW_PENDING;
|
||||
if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
|
||||
return;
|
||||
}
|
||||
pixmap = (Pixmap) Tk_WindowId(tkwin);
|
||||
|
||||
/*
|
||||
* Set up clipping region. Make sure the we are using the port
|
||||
* for this button, or we will set the wrong window's clip.
|
||||
*/
|
||||
|
||||
TkMacOSXSetUpClippingRgn(Tk_WindowId(tkwin));
|
||||
|
||||
if (TkMacOSXComputeButtonDrawParams(butPtr, dpPtr)) {
|
||||
macButtonPtr->useTkText = 0;
|
||||
} else {
|
||||
@@ -332,39 +324,40 @@ TkpComputeButtonGeometry(
|
||||
haveText = 1;
|
||||
}
|
||||
|
||||
if (haveImage && haveText) { /* Image and Text */
|
||||
switch ((enum compound) butPtr->compound) {
|
||||
case COMPOUND_TOP:
|
||||
case COMPOUND_BOTTOM:
|
||||
/*
|
||||
* Image is above or below text.
|
||||
*/
|
||||
if (haveImage) {
|
||||
if (haveText) { /* Image and Text */
|
||||
switch ((enum compound) butPtr->compound) {
|
||||
case COMPOUND_TOP:
|
||||
case COMPOUND_BOTTOM:
|
||||
/*
|
||||
* Image is above or below text.
|
||||
*/
|
||||
|
||||
height += txtHeight + butPtr->padY;
|
||||
width = (width > txtWidth ? width : txtWidth);
|
||||
break;
|
||||
case COMPOUND_LEFT:
|
||||
case COMPOUND_RIGHT:
|
||||
/*
|
||||
* Image is left or right of text.
|
||||
*/
|
||||
height += txtHeight + butPtr->padY;
|
||||
width = (width > txtWidth ? width : txtWidth);
|
||||
break;
|
||||
case COMPOUND_LEFT:
|
||||
case COMPOUND_RIGHT:
|
||||
/*
|
||||
* Image is left or right of text.
|
||||
*/
|
||||
|
||||
width += txtWidth + 2*butPtr->padX;
|
||||
height = (height > txtHeight ? height : txtHeight);
|
||||
break;
|
||||
case COMPOUND_CENTER:
|
||||
/*
|
||||
* Image and text are superimposed.
|
||||
*/
|
||||
width += txtWidth + 2*butPtr->padX;
|
||||
height = (height > txtHeight ? height : txtHeight);
|
||||
break;
|
||||
case COMPOUND_CENTER:
|
||||
/*
|
||||
* Image and text are superimposed.
|
||||
*/
|
||||
|
||||
width = (width > txtWidth ? width : txtWidth);
|
||||
height = (height > txtHeight ? height : txtHeight);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
width = (width > txtWidth ? width : txtWidth);
|
||||
height = (height > txtHeight ? height : txtHeight);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
width += butPtr->indicatorSpace;
|
||||
} else if (haveImage) { /* Image only */
|
||||
/* Image with or without text */
|
||||
width = butPtr->width > 0 ? butPtr->width : width + butPtr->indicatorSpace;
|
||||
height = butPtr->height > 0 ? butPtr->height : height;
|
||||
if (butPtr->type == TYPE_BUTTON) {
|
||||
@@ -399,7 +392,7 @@ TkpComputeButtonGeometry(
|
||||
|
||||
width += butPtr->inset*2;
|
||||
height += butPtr->inset*2;
|
||||
if ([NSApp macMinorVersion] == 6) {
|
||||
if ([NSApp macOSVersion] == 100600) {
|
||||
width += 12;
|
||||
}
|
||||
if (mbPtr->btnkind == kThemePushButton) {
|
||||
@@ -465,7 +458,7 @@ DrawButtonImageAndText(
|
||||
|
||||
pixmap = (Pixmap) Tk_WindowId(tkwin);
|
||||
|
||||
if (butPtr->image != None) {
|
||||
if (butPtr->image != NULL) {
|
||||
Tk_SizeOfImage(butPtr->image, &width, &height);
|
||||
haveImage = 1;
|
||||
} else if (butPtr->bitmap != None) {
|
||||
@@ -481,7 +474,7 @@ DrawButtonImageAndText(
|
||||
}
|
||||
|
||||
haveText = (butPtr->textWidth != 0 && butPtr->textHeight != 0);
|
||||
if (haveImage && haveText) { /* Image and Text */
|
||||
if (butPtr->compound != COMPOUND_NONE && haveImage && haveText) { /* Image and Text */
|
||||
int x, y;
|
||||
|
||||
switch ((enum compound) butPtr->compound) {
|
||||
@@ -726,7 +719,7 @@ TkpDestroyButton(
|
||||
static void
|
||||
TkMacOSXDrawButton(
|
||||
MacButton *mbPtr, /* Mac button. */
|
||||
GC gc, /* The GC we are drawing into - needed for
|
||||
TCL_UNUSED(GC), /* The GC we are drawing into - needed for
|
||||
* the bevel button */
|
||||
Pixmap pixmap) /* The pixmap we are drawing into - needed
|
||||
* for the bevel button */
|
||||
@@ -751,7 +744,7 @@ TkMacOSXDrawButton(
|
||||
|
||||
ButtonBackgroundDrawCB(&cntrRect, mbPtr, 32, true);
|
||||
|
||||
if (!TkMacOSXSetupDrawingContext(pixmap, dpPtr->gc, 1, &dc)) {
|
||||
if (!TkMacOSXSetupDrawingContext(pixmap, dpPtr->gc, &dc)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -784,7 +777,7 @@ TkMacOSXDrawButton(
|
||||
ButtonContentDrawCB(&contHIRec, mbPtr->btnkind, &mbPtr->drawinfo,
|
||||
(MacButton *) mbPtr, 32, true);
|
||||
} else {
|
||||
if (!TkMacOSXSetupDrawingContext(pixmap, dpPtr->gc, 1, &dc)) {
|
||||
if (!TkMacOSXSetupDrawingContext(pixmap, dpPtr->gc, &dc)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -812,10 +805,10 @@ TkMacOSXDrawButton(
|
||||
|
||||
static void
|
||||
ButtonBackgroundDrawCB(
|
||||
const HIRect *btnbounds,
|
||||
TCL_UNUSED(const HIRect *),
|
||||
MacButton *ptr,
|
||||
SInt16 depth,
|
||||
Boolean isColorDev)
|
||||
TCL_UNUSED(SInt16),
|
||||
TCL_UNUSED(Boolean))
|
||||
{
|
||||
MacButton *mbPtr = (MacButton *) ptr;
|
||||
TkButton *butPtr = (TkButton *) mbPtr;
|
||||
@@ -864,12 +857,12 @@ ButtonBackgroundDrawCB(
|
||||
*/
|
||||
static void
|
||||
ButtonContentDrawCB (
|
||||
const HIRect * btnbounds,
|
||||
ThemeButtonKind kind,
|
||||
const HIThemeButtonDrawInfo *drawinfo,
|
||||
TCL_UNUSED(const HIRect *),
|
||||
TCL_UNUSED(ThemeButtonKind),
|
||||
TCL_UNUSED(const HIThemeButtonDrawInfo *),
|
||||
MacButton *ptr,
|
||||
SInt16 depth,
|
||||
Boolean isColorDev)
|
||||
TCL_UNUSED(SInt16),
|
||||
TCL_UNUSED(Boolean))
|
||||
{
|
||||
TkButton *butPtr = (TkButton *) ptr;
|
||||
Tk_Window tkwin = butPtr->tkwin;
|
||||
@@ -1047,7 +1040,14 @@ TkMacOSXComputeButtonParams(
|
||||
if (drawinfo->state != kThemeStatePressed) {
|
||||
drawinfo->adornment |= kThemeAdornmentDefault;
|
||||
}
|
||||
if (!mbPtr->defaultPulseHandler) {
|
||||
|
||||
/*
|
||||
* Older macOS systems (10.9 and earlier) use an animation to
|
||||
* indicate the active button. This is simulated by redrawing
|
||||
* the button periodically.
|
||||
*/
|
||||
|
||||
if (!mbPtr->defaultPulseHandler && ([NSApp macOSVersion] <= 100900)) {
|
||||
mbPtr->defaultPulseHandler = Tcl_CreateTimerHandler(
|
||||
PULSE_TIMER_MSECS, PulseDefaultButtonProc, butPtr);
|
||||
}
|
||||
@@ -1177,6 +1177,13 @@ PulseDefaultButtonProc(ClientData clientData)
|
||||
MacButton *mbPtr = clientData;
|
||||
|
||||
TkpDisplayButton(clientData);
|
||||
/*
|
||||
* Fix 40ada90762: any idle calls to TkpDisplayButton need to be canceled
|
||||
* in case the button is destroyed and has its data freed before the idle
|
||||
* event is handled (DestroyButton only cancels calls when REDRAW_PENDING
|
||||
* is set, which is not the case after calling TkpDisplayButton directly).
|
||||
*/
|
||||
Tcl_CancelIdleCall(TkpDisplayButton, clientData);
|
||||
mbPtr->defaultPulseHandler = Tcl_CreateTimerHandler(
|
||||
PULSE_TIMER_MSECS, PulseDefaultButtonProc, clientData);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,9 @@ static Tk_Window clipboardOwner = NULL;
|
||||
targetPtr->type == dispPtr->utf8Atom) {
|
||||
for (TkClipboardBuffer *cbPtr = targetPtr->firstBufferPtr;
|
||||
cbPtr; cbPtr = cbPtr->nextPtr) {
|
||||
NSString *s = TclUniToNSString(cbPtr->buffer, cbPtr->length);
|
||||
NSString *s = [[TKNSString alloc]
|
||||
initWithTclUtfBytes:cbPtr->buffer
|
||||
length:cbPtr->length];
|
||||
[string appendString:s];
|
||||
[s release];
|
||||
}
|
||||
@@ -135,26 +137,19 @@ TkSelGetSelection(
|
||||
string = [pb stringForType:type];
|
||||
}
|
||||
if (string) {
|
||||
|
||||
/*
|
||||
* Encode the string using the encoding which is used in Tcl
|
||||
* when TCL_UTF_MAX = 3. This replaces each UTF-16 surrogate with
|
||||
* a 3-byte sequence generated using the UTF-8 algorithm. (Even
|
||||
* though UTF-8 does not allow encoding surrogates, the algorithm
|
||||
* does produce a 3-byte sequence.)
|
||||
*/
|
||||
|
||||
char *bytes = NSStringToTclUni(string, NULL);
|
||||
result = proc(clientData, interp, bytes);
|
||||
if (bytes) {
|
||||
ckfree(bytes);
|
||||
if (target == dispPtr->utf8Atom) {
|
||||
result = proc(clientData, interp, string.UTF8String);
|
||||
} else if (target == XA_STRING) {
|
||||
const char *latin1 = [string
|
||||
cStringUsingEncoding:NSISOLatin1StringEncoding];
|
||||
result = proc(clientData, interp, latin1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"%s selection doesn't exist or form \"%s\" not defined",
|
||||
Tk_GetAtomName(tkwin, selection),
|
||||
Tk_GetAtomName(tkwin, target)));
|
||||
"%s selection doesn't exist or form \"%s\" not defined",
|
||||
Tk_GetAtomName(tkwin, selection),
|
||||
Tk_GetAtomName(tkwin, target)));
|
||||
Tcl_SetErrorCode(interp, "TK", "SELECTION", "EXISTS", NULL);
|
||||
}
|
||||
return result;
|
||||
@@ -182,7 +177,7 @@ XSetSelectionOwner(
|
||||
Display *display, /* X Display. */
|
||||
Atom selection, /* What selection to own. */
|
||||
Window owner, /* Window to be the owner. */
|
||||
Time time) /* The current time? */
|
||||
TCL_UNUSED(Time)) /* The current time? */
|
||||
{
|
||||
TkDisplay *dispPtr = TkGetDisplayList();
|
||||
|
||||
@@ -242,8 +237,8 @@ TkMacOSXSelDeadWindow(
|
||||
|
||||
void
|
||||
TkSelUpdateClipboard(
|
||||
TkWindow *winPtr, /* Window associated with clipboard. */
|
||||
TkClipboardTarget *targetPtr)
|
||||
TCL_UNUSED(TkWindow *), /* Window associated with clipboard. */
|
||||
TCL_UNUSED(TkClipboardTarget *))
|
||||
/* Info about the content. */
|
||||
{
|
||||
NSPasteboard *pb = [NSPasteboard generalPasteboard];
|
||||
@@ -271,7 +266,7 @@ TkSelUpdateClipboard(
|
||||
void
|
||||
TkSelEventProc(
|
||||
Tk_Window tkwin, /* Window for which event was targeted. */
|
||||
register XEvent *eventPtr) /* X event: either SelectionClear,
|
||||
XEvent *eventPtr) /* X event: either SelectionClear,
|
||||
* SelectionRequest, or SelectionNotify. */
|
||||
{
|
||||
if (eventPtr->type == SelectionClear) {
|
||||
@@ -299,7 +294,7 @@ TkSelEventProc(
|
||||
|
||||
void
|
||||
TkSelPropProc(
|
||||
register XEvent *eventPtr) /* X PropertyChange event. */
|
||||
TCL_UNUSED(XEvent *)) /* X PropertyChange event. */
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
264
macosx/tkMacOSXColor.h
Normal file
264
macosx/tkMacOSXColor.h
Normal file
@@ -0,0 +1,264 @@
|
||||
#ifndef MACOSXCOLOR_H
|
||||
#define MACOSXCOLOR_H
|
||||
/*
|
||||
* The generic Tk code uses the X11 GC type to describe a graphics context.
|
||||
* (A GC is a pointer to a struct XGCValues). The foreground and background
|
||||
* colors in a GC are unsigned longs. These are meant to be used as indexes
|
||||
* into a table of XColors, where an XColor is declared in Xlib.h as:
|
||||
* typedef struct {
|
||||
* unsigned long pixel;
|
||||
* unsigned short red, green, blue;
|
||||
* char flags;
|
||||
* char pad;
|
||||
* } XColor;
|
||||
*
|
||||
* The xlib function XParseColor creates XColors from strings. It recognizes
|
||||
* literal hexadecimal color specifications such as "#RRGGBB" as well as the
|
||||
* standard X11 color names. When XParseColor creates an XColor it fills in
|
||||
* all of the fields except for the pixel field, and then passes the XColor
|
||||
* to TkpGetPixel to get a value to use for the pixel field. Since TkpGetPixel
|
||||
* is platform specific, each platform is free to choose a value which can
|
||||
* be used to set the foreground or background color in the platform's graphics
|
||||
* context.
|
||||
*
|
||||
* Tk represents a color by a struct TkColor, which extends the XColor struct.
|
||||
* Tk provides a mapping from color names to TkColors which extends the mapping
|
||||
* provided by XParseColor but also allows for platform specific color names.
|
||||
* By convention, these platform specific color names begin with the string
|
||||
* "system". The mapping from names to TkColors is implemented by the function
|
||||
* TkpGetColor defined for the Macintosh in this file. The pixel field in the
|
||||
* XColor contained in a TkColor will be stored in the X11 graphics context.
|
||||
* In X11 the pixel field is used as an index into a colormap. On the Mac
|
||||
* the high order byte of the pixel is used to indicate a color type and
|
||||
* the low 24 bits are either used as an rgb value (if the type is rgbColor)
|
||||
* or as an index into a table of color descriptions.
|
||||
*/
|
||||
|
||||
enum colorType {
|
||||
rgbColor, /* The 24 bit value is an rgb color. */
|
||||
clearColor, /* The unique rgba color with all channels 0. */
|
||||
HIBrush, /* A HITheme brush color.*/
|
||||
HIText, /* A HITheme text color. */
|
||||
HIBackground, /* A HITheme background color. */
|
||||
ttkBackground, /* A background color which indicates nesting level.*/
|
||||
semantic, /* A semantic NSColor.*/
|
||||
};
|
||||
|
||||
typedef struct xpixel_t {
|
||||
unsigned value: 24; /* Either RGB or an index into systemColorMap. */
|
||||
unsigned colortype: 8;
|
||||
} xpixel;
|
||||
|
||||
typedef union MacPixel_t {
|
||||
unsigned long ulong;
|
||||
xpixel pixel;
|
||||
} MacPixel;
|
||||
|
||||
/*
|
||||
* We maintain two colormaps, one for the LightAqua appearance and one for the
|
||||
* DarkAqua appearance.
|
||||
*/
|
||||
|
||||
enum macColormap {
|
||||
noColormap,
|
||||
lightColormap,
|
||||
darkColormap,
|
||||
};
|
||||
|
||||
/*
|
||||
* In TkMacOSXColor.c a Tk hash table is constructed from the static data
|
||||
* below to map system color names to CGColors.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
enum colorType type;
|
||||
int value;
|
||||
const char *macName;
|
||||
/* Fields below are filled in after or during construction of the hash table. */
|
||||
int index;
|
||||
NSString *selector;
|
||||
} SystemColorDatum;
|
||||
|
||||
/*
|
||||
* WARNING: Semantic colors which are not supported on all systems must be
|
||||
* preceded by a backup color with the same name which *is* supported. Systems
|
||||
* which do support the color will replace the backup value when the table is
|
||||
* constructed. Failing to ensure this will result in a Tcl_Panic abort.
|
||||
*/
|
||||
|
||||
static SystemColorDatum systemColorData[] = {
|
||||
{"Pixel", rgbColor, 0, NULL, 0, NULL },
|
||||
{"Transparent", clearColor, 0, NULL, 0, NULL },
|
||||
|
||||
{"Highlight", HIBrush, kThemeBrushPrimaryHighlightColor, NULL, 0, NULL },
|
||||
{"HighlightSecondary", HIBrush, kThemeBrushSecondaryHighlightColor, NULL, 0, NULL },
|
||||
{"HighlightText", HIBrush, kThemeBrushBlack, NULL, 0, NULL },
|
||||
{"HighlightAlternate", HIBrush, kThemeBrushAlternatePrimaryHighlightColor, NULL, 0, NULL },
|
||||
{"PrimaryHighlightColor", HIBrush, kThemeBrushPrimaryHighlightColor, NULL, 0, NULL },
|
||||
{"ButtonFace", HIBrush, kThemeBrushButtonFaceActive, NULL, 0, NULL },
|
||||
{"SecondaryHighlightColor", HIBrush, kThemeBrushSecondaryHighlightColor, NULL, 0, NULL },
|
||||
{"ButtonFrame", HIBrush, kThemeBrushButtonFrameActive, NULL, 0, NULL },
|
||||
{"AlternatePrimaryHighlightColor", HIBrush, kThemeBrushAlternatePrimaryHighlightColor, NULL, 0, NULL },
|
||||
{"WindowBody", HIBrush, kThemeBrushDocumentWindowBackground, NULL, 0, NULL },
|
||||
{"SheetBackground", HIBrush, kThemeBrushSheetBackground, NULL, 0, NULL },
|
||||
{"MenuActive", HIBrush, kThemeBrushMenuBackgroundSelected, NULL, 0, NULL },
|
||||
{"Menu", HIBrush, kThemeBrushMenuBackground, NULL, 0, NULL },
|
||||
{"DialogBackgroundInactive", HIBrush, kThemeBrushDialogBackgroundInactive, NULL, 0, NULL },
|
||||
{"DialogBackgroundActive", HIBrush, kThemeBrushDialogBackgroundActive, NULL, 0, NULL },
|
||||
{"AlertBackgroundActive", HIBrush, kThemeBrushAlertBackgroundActive, NULL, 0, NULL },
|
||||
{"AlertBackgroundInactive", HIBrush, kThemeBrushAlertBackgroundInactive, NULL, 0, NULL },
|
||||
{"ModelessDialogBackgroundActive", HIBrush, kThemeBrushModelessDialogBackgroundActive, NULL, 0, NULL },
|
||||
{"ModelessDialogBackgroundInactive", HIBrush, kThemeBrushModelessDialogBackgroundInactive, NULL, 0, NULL },
|
||||
{"UtilityWindowBackgroundActive", HIBrush, kThemeBrushUtilityWindowBackgroundActive, NULL, 0, NULL },
|
||||
{"UtilityWindowBackgroundInactive", HIBrush, kThemeBrushUtilityWindowBackgroundInactive, NULL, 0, NULL },
|
||||
{"ListViewSortColumnBackground", HIBrush, kThemeBrushListViewSortColumnBackground, NULL, 0, NULL },
|
||||
{"ListViewBackground", HIBrush, kThemeBrushListViewBackground, NULL, 0, NULL },
|
||||
{"IconLabelBackground", HIBrush, kThemeBrushIconLabelBackground, NULL, 0, NULL },
|
||||
{"ListViewSeparator", HIBrush, kThemeBrushListViewSeparator, NULL, 0, NULL },
|
||||
{"ChasingArrows", HIBrush, kThemeBrushChasingArrows, NULL, 0, NULL },
|
||||
{"DragHilite", HIBrush, kThemeBrushDragHilite, NULL, 0, NULL },
|
||||
{"DocumentWindowBackground", HIBrush, kThemeBrushDocumentWindowBackground, NULL, 0, NULL },
|
||||
{"FinderWindowBackground", HIBrush, kThemeBrushFinderWindowBackground, NULL, 0, NULL },
|
||||
{"ScrollBarDelimiterActive", HIBrush, kThemeBrushScrollBarDelimiterActive, NULL, 0, NULL },
|
||||
{"ScrollBarDelimiterInactive", HIBrush, kThemeBrushScrollBarDelimiterInactive, NULL, 0, NULL },
|
||||
{"FocusHighlight", HIBrush, kThemeBrushFocusHighlight, NULL, 0, NULL },
|
||||
{"PopupArrowActive", HIBrush, kThemeBrushPopupArrowActive, NULL, 0, NULL },
|
||||
{"PopupArrowPressed", HIBrush, kThemeBrushPopupArrowPressed, NULL, 0, NULL },
|
||||
{"PopupArrowInactive", HIBrush, kThemeBrushPopupArrowInactive, NULL, 0, NULL },
|
||||
{"AppleGuideCoachmark", HIBrush, kThemeBrushAppleGuideCoachmark, NULL, 0, NULL },
|
||||
{"IconLabelBackgroundSelected", HIBrush, kThemeBrushIconLabelBackgroundSelected, NULL, 0, NULL },
|
||||
{"StaticAreaFill", HIBrush, kThemeBrushStaticAreaFill, NULL, 0, NULL },
|
||||
{"ActiveAreaFill", HIBrush, kThemeBrushActiveAreaFill, NULL, 0, NULL },
|
||||
{"ButtonFrameActive", HIBrush, kThemeBrushButtonFrameActive, NULL, 0, NULL },
|
||||
{"ButtonFrameInactive", HIBrush, kThemeBrushButtonFrameInactive, NULL, 0, NULL },
|
||||
{"ButtonFaceActive", HIBrush, kThemeBrushButtonFaceActive, NULL, 0, NULL },
|
||||
{"ButtonFaceInactive", HIBrush, kThemeBrushButtonFaceInactive, NULL, 0, NULL },
|
||||
{"ButtonFacePressed", HIBrush, kThemeBrushButtonFacePressed, NULL, 0, NULL },
|
||||
{"ButtonActiveDarkShadow", HIBrush, kThemeBrushButtonActiveDarkShadow, NULL, 0, NULL },
|
||||
{"ButtonActiveDarkHighlight", HIBrush, kThemeBrushButtonActiveDarkHighlight, NULL, 0, NULL },
|
||||
{"ButtonActiveLightShadow", HIBrush, kThemeBrushButtonActiveLightShadow, NULL, 0, NULL },
|
||||
{"ButtonActiveLightHighlight", HIBrush, kThemeBrushButtonActiveLightHighlight, NULL, 0, NULL },
|
||||
{"ButtonInactiveDarkShadow", HIBrush, kThemeBrushButtonInactiveDarkShadow, NULL, 0, NULL },
|
||||
{"ButtonInactiveDarkHighlight", HIBrush, kThemeBrushButtonInactiveDarkHighlight, NULL, 0, NULL },
|
||||
{"ButtonInactiveLightShadow", HIBrush, kThemeBrushButtonInactiveLightShadow, NULL, 0, NULL },
|
||||
{"ButtonInactiveLightHighlight", HIBrush, kThemeBrushButtonInactiveLightHighlight, NULL, 0, NULL },
|
||||
{"ButtonPressedDarkShadow", HIBrush, kThemeBrushButtonPressedDarkShadow, NULL, 0, NULL },
|
||||
{"ButtonPressedDarkHighlight", HIBrush, kThemeBrushButtonPressedDarkHighlight, NULL, 0, NULL },
|
||||
{"ButtonPressedLightShadow", HIBrush, kThemeBrushButtonPressedLightShadow, NULL, 0, NULL },
|
||||
{"ButtonPressedLightHighlight", HIBrush, kThemeBrushButtonPressedLightHighlight, NULL, 0, NULL },
|
||||
{"BevelActiveLight", HIBrush, kThemeBrushBevelActiveLight, NULL, 0, NULL },
|
||||
{"BevelActiveDark", HIBrush, kThemeBrushBevelActiveDark, NULL, 0, NULL },
|
||||
{"BevelInactiveLight", HIBrush, kThemeBrushBevelInactiveLight, NULL, 0, NULL },
|
||||
{"BevelInactiveDark", HIBrush, kThemeBrushBevelInactiveDark, NULL, 0, NULL },
|
||||
{"NotificationWindowBackground", HIBrush, kThemeBrushNotificationWindowBackground, NULL, 0, NULL },
|
||||
{"MovableModalBackground", HIBrush, kThemeBrushMovableModalBackground, NULL, 0, NULL },
|
||||
{"SheetBackgroundOpaque", HIBrush, kThemeBrushSheetBackgroundOpaque, NULL, 0, NULL },
|
||||
{"DrawerBackground", HIBrush, kThemeBrushDrawerBackground, NULL, 0, NULL },
|
||||
{"ToolbarBackground", HIBrush, kThemeBrushToolbarBackground, NULL, 0, NULL },
|
||||
{"SheetBackgroundTransparent", HIBrush, kThemeBrushSheetBackgroundTransparent, NULL, 0, NULL },
|
||||
{"MenuBackground", HIBrush, kThemeBrushMenuBackground, NULL, 0, NULL },
|
||||
{"MenuBackgroundSelected", HIBrush, kThemeBrushMenuBackgroundSelected, NULL, 0, NULL },
|
||||
{"ListViewOddRowBackground", HIBrush, kThemeBrushListViewOddRowBackground, NULL, 0, NULL },
|
||||
{"ListViewEvenRowBackground", HIBrush, kThemeBrushListViewEvenRowBackground, NULL, 0, NULL },
|
||||
{"ListViewColumnDivider", HIBrush, kThemeBrushListViewColumnDivider, NULL, 0, NULL },
|
||||
|
||||
{"ButtonText", HIText, kThemeTextColorPushButtonActive, NULL, 0, NULL },
|
||||
{"MenuActiveText", HIText, kThemeTextColorMenuItemSelected, NULL, 0, NULL },
|
||||
{"MenuDisabled", HIText, kThemeTextColorMenuItemDisabled, NULL, 0, NULL },
|
||||
{"MenuText", HIText, kThemeTextColorMenuItemActive, NULL, 0, NULL },
|
||||
{"BlackText", HIText, kThemeTextColorBlack, NULL, 0, NULL },
|
||||
{"DialogActiveText", HIText, kThemeTextColorDialogActive, NULL, 0, NULL },
|
||||
{"DialogInactiveText", HIText, kThemeTextColorDialogInactive, NULL, 0, NULL },
|
||||
{"AlertActiveText", HIText, kThemeTextColorAlertActive, NULL, 0, NULL },
|
||||
{"AlertInactiveText", HIText, kThemeTextColorAlertInactive, NULL, 0, NULL },
|
||||
{"ModelessDialogActiveText", HIText, kThemeTextColorModelessDialogActive, NULL, 0, NULL },
|
||||
{"ModelessDialogInactiveText", HIText, kThemeTextColorModelessDialogInactive, NULL, 0, NULL },
|
||||
{"WindowHeaderActiveText", HIText, kThemeTextColorWindowHeaderActive, NULL, 0, NULL },
|
||||
{"WindowHeaderInactiveText", HIText, kThemeTextColorWindowHeaderInactive, NULL, 0, NULL },
|
||||
{"PlacardActiveText", HIText, kThemeTextColorPlacardActive, NULL, 0, NULL },
|
||||
{"PlacardInactiveText", HIText, kThemeTextColorPlacardInactive, NULL, 0, NULL },
|
||||
{"PlacardPressedText", HIText, kThemeTextColorPlacardPressed, NULL, 0, NULL },
|
||||
{"PushButtonActiveText", HIText, kThemeTextColorPushButtonActive, NULL, 0, NULL },
|
||||
{"PushButtonInactiveText", HIText, kThemeTextColorPushButtonInactive, NULL, 0, NULL },
|
||||
{"PushButtonPressedText", HIText, kThemeTextColorPushButtonPressed, NULL, 0, NULL },
|
||||
{"BevelButtonActiveText", HIText, kThemeTextColorBevelButtonActive, NULL, 0, NULL },
|
||||
{"BevelButtonInactiveText", HIText, kThemeTextColorBevelButtonInactive, NULL, 0, NULL },
|
||||
{"BevelButtonPressedText", HIText, kThemeTextColorBevelButtonPressed, NULL, 0, NULL },
|
||||
{"PopupButtonActiveText", HIText, kThemeTextColorPopupButtonActive, NULL, 0, NULL },
|
||||
{"PopupButtonInactiveText", HIText, kThemeTextColorPopupButtonInactive, NULL, 0, NULL },
|
||||
{"PopupButtonPressedText", HIText, kThemeTextColorPopupButtonPressed, NULL, 0, NULL },
|
||||
{"IconLabelText", HIText, kThemeTextColorIconLabel, NULL, 0, NULL },
|
||||
{"ListViewText", HIText, kThemeTextColorListView, NULL, 0, NULL },
|
||||
{"DocumentWindowTitleActiveText", HIText, kThemeTextColorDocumentWindowTitleActive, NULL, 0, NULL },
|
||||
{"DocumentWindowTitleInactiveText", HIText, kThemeTextColorDocumentWindowTitleInactive, NULL, 0, NULL },
|
||||
{"MovableModalWindowTitleActiveText", HIText, kThemeTextColorMovableModalWindowTitleActive, NULL, 0, NULL },
|
||||
{"MovableModalWindowTitleInactiveText", HIText, kThemeTextColorMovableModalWindowTitleInactive, NULL, 0, NULL },
|
||||
{"UtilityWindowTitleActiveText", HIText, kThemeTextColorUtilityWindowTitleActive, NULL, 0, NULL },
|
||||
{"UtilityWindowTitleInactiveText", HIText, kThemeTextColorUtilityWindowTitleInactive, NULL, 0, NULL },
|
||||
{"PopupWindowTitleActiveText", HIText, kThemeTextColorPopupWindowTitleActive, NULL, 0, NULL },
|
||||
{"PopupWindowTitleInactiveText", HIText, kThemeTextColorPopupWindowTitleInactive, NULL, 0, NULL },
|
||||
{"RootMenuActiveText", HIText, kThemeTextColorRootMenuActive, NULL, 0, NULL },
|
||||
{"RootMenuSelectedText", HIText, kThemeTextColorRootMenuSelected, NULL, 0, NULL },
|
||||
{"RootMenuDisabledText", HIText, kThemeTextColorRootMenuDisabled, NULL, 0, NULL },
|
||||
{"MenuItemActiveText", HIText, kThemeTextColorMenuItemActive, NULL, 0, NULL },
|
||||
{"MenuItemSelectedText", HIText, kThemeTextColorMenuItemSelected, NULL, 0, NULL },
|
||||
{"MenuItemDisabledText", HIText, kThemeTextColorMenuItemDisabled, NULL, 0, NULL },
|
||||
{"PopupLabelActiveText", HIText, kThemeTextColorPopupLabelActive, NULL, 0, NULL },
|
||||
{"PopupLabelInactiveText", HIText, kThemeTextColorPopupLabelInactive, NULL, 0, NULL },
|
||||
{"TabFrontActiveText", HIText, kThemeTextColorTabFrontActive, NULL, 0, NULL },
|
||||
{"TabNonFrontActiveText", HIText, kThemeTextColorTabNonFrontActive, NULL, 0, NULL },
|
||||
{"TabNonFrontPressedText", HIText, kThemeTextColorTabNonFrontPressed, NULL, 0, NULL },
|
||||
{"TabFrontInactiveText", HIText, kThemeTextColorTabFrontInactive, NULL, 0, NULL },
|
||||
{"TabNonFrontInactiveText", HIText, kThemeTextColorTabNonFrontInactive, NULL, 0, NULL },
|
||||
{"IconLabelSelectedText", HIText, kThemeTextColorIconLabelSelected, NULL, 0, NULL },
|
||||
{"BevelButtonStickyActiveText", HIText, kThemeTextColorBevelButtonStickyActive, NULL, 0, NULL },
|
||||
{"BevelButtonStickyInactiveText", HIText, kThemeTextColorBevelButtonStickyInactive, NULL, 0, NULL },
|
||||
{"NotificationText", HIText, kThemeTextColorNotification, NULL, 0, NULL },
|
||||
{"SystemDetailText", HIText, kThemeTextColorSystemDetail, NULL, 0, NULL },
|
||||
{"PlacardBackground", HIBackground, kThemeBackgroundPlacard, NULL, 0, NULL },
|
||||
{"WindowHeaderBackground", HIBackground, kThemeBackgroundWindowHeader, NULL, 0, NULL },
|
||||
{"ListViewWindowHeaderBackground", HIBackground, kThemeBackgroundListViewWindowHeader, NULL, 0, NULL },
|
||||
{"MetalBackground", HIBackground, kThemeBackgroundMetal, NULL, 0, NULL },
|
||||
|
||||
{"SecondaryGroupBoxBackground", HIBackground, kThemeBackgroundSecondaryGroupBox, NULL, 0, NULL },
|
||||
{"TabPaneBackground", HIBackground, kThemeBackgroundTabPane, NULL, 0, NULL },
|
||||
{"WhiteText", HIText, kThemeTextColorWhite, NULL, 0, NULL },
|
||||
{"Black", HIBrush, kThemeBrushBlack, NULL, 0, NULL },
|
||||
{"White", HIBrush, kThemeBrushWhite, NULL, 0, NULL },
|
||||
|
||||
/*
|
||||
* Dynamic Colors
|
||||
*/
|
||||
|
||||
{"WindowBackgroundColor", ttkBackground, 0, NULL, 0, NULL },
|
||||
{"WindowBackgroundColor1", ttkBackground, 1, NULL, 0, NULL },
|
||||
{"WindowBackgroundColor2", ttkBackground, 2, NULL, 0, NULL },
|
||||
{"WindowBackgroundColor3", ttkBackground, 3, NULL, 0, NULL },
|
||||
{"WindowBackgroundColor4", ttkBackground, 4, NULL, 0, NULL },
|
||||
{"WindowBackgroundColor5", ttkBackground, 5, NULL, 0, NULL },
|
||||
{"WindowBackgroundColor6", ttkBackground, 6, NULL, 0, NULL },
|
||||
{"WindowBackgroundColor7", ttkBackground, 7, NULL, 0, NULL },
|
||||
/* Apple's SecondaryLabelColor is the same as their LabelColor so we roll our own. */
|
||||
{"SecondaryLabelColor", ttkBackground, 14, NULL, 0, NULL },
|
||||
/* Color to use for notebook tab labels -- depends on OS version. */
|
||||
{"SelectedTabTextColor", semantic, 0, "textColor", 0, NULL },
|
||||
/* Semantic colors that we simulate on older systems which don't supoort them. */
|
||||
{"ControlAccentColor", semantic, 0, "controlAccentColor", 0, NULL },
|
||||
{"LabelColor", semantic, 0, "blackColor", 0, NULL },
|
||||
{"LinkColor", semantic, 0, "blueColor", 0, NULL },
|
||||
{"PlaceholderTextColor", semantic, 0, "grayColor", 0, NULL },
|
||||
{"SeparatorColor", semantic, 0, "grayColor", 0, NULL },
|
||||
{"UnemphasizedSelectedTextBackgroundColor", semantic, 0, "grayColor", 0, NULL },
|
||||
{NULL, 0, 0, NULL, 0, NULL }
|
||||
};
|
||||
|
||||
#endif
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: objc
|
||||
* c-basic-offset: 4
|
||||
* fill-column: 79
|
||||
* coding: utf-8
|
||||
* End:
|
||||
*/
|
||||
@@ -19,6 +19,10 @@
|
||||
#define NSFullScreenWindowMask (1 << 14)
|
||||
#endif
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1090
|
||||
typedef NSInteger NSModalResponse;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Let's raise a glass for the project manager who improves our lives by
|
||||
* generating deprecation warnings about pointless changes of the names
|
||||
@@ -98,10 +102,18 @@
|
||||
#define NSStringPboardType NSPasteboardTypeString
|
||||
#define NSOnState NSControlStateValueOn
|
||||
#define NSOffState NSControlStateValueOff
|
||||
// Now we are also changing names of methods!
|
||||
#define graphicsContextWithGraphicsPort graphicsContextWithCGContext
|
||||
#endif
|
||||
|
||||
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 110000
|
||||
#define NSWindowStyleMaskTexturedBackground 0
|
||||
#endif
|
||||
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED < 101000
|
||||
#define GET_NSCONTEXT(context, flip) [NSGraphicsContext \
|
||||
graphicsContextWithGraphicsPort:context flipped:flip]
|
||||
#else
|
||||
#define GET_NSCONTEXT(context, flip) [NSGraphicsContext \
|
||||
graphicsContextWithCGContext:context flipped:NO]
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -54,131 +54,131 @@ struct CursorName {
|
||||
#define MacXCursorData(n) ((id)tkMacOSXXCursors[TK_MAC_XCURSOR_##n])
|
||||
|
||||
static const struct CursorName cursorNames[] = {
|
||||
{"none", NONE, nil},
|
||||
{"arrow", SELECTOR, @"arrowCursor"},
|
||||
{"top_left_arrow", SELECTOR, @"arrowCursor"},
|
||||
{"left_ptr", SELECTOR, @"arrowCursor"},
|
||||
{"copyarrow", SELECTOR, @"dragCopyCursor", @"_copyDragCursor"},
|
||||
{"aliasarrow", SELECTOR, @"dragLinkCursor", @"_linkDragCursor"},
|
||||
{"contextualmenuarrow", SELECTOR, @"contextualMenuCursor"},
|
||||
{"movearrow", SELECTOR, @"_moveCursor"},
|
||||
{"ibeam", SELECTOR, @"IBeamCursor"},
|
||||
{"text", SELECTOR, @"IBeamCursor"},
|
||||
{"xterm", SELECTOR, @"IBeamCursor"},
|
||||
{"cross", SELECTOR, @"crosshairCursor"},
|
||||
{"crosshair", SELECTOR, @"crosshairCursor"},
|
||||
{"cross-hair", SELECTOR, @"crosshairCursor"},
|
||||
{"tcross", SELECTOR, @"crosshairCursor"},
|
||||
{"hand", SELECTOR, @"openHandCursor"},
|
||||
{"openhand", SELECTOR, @"openHandCursor"},
|
||||
{"closedhand", SELECTOR, @"closedHandCursor"},
|
||||
{"fist", SELECTOR, @"closedHandCursor"},
|
||||
{"pointinghand", SELECTOR, @"pointingHandCursor"},
|
||||
{"resize", SELECTOR, @"arrowCursor"},
|
||||
{"resizeleft", SELECTOR, @"resizeLeftCursor"},
|
||||
{"resizeright", SELECTOR, @"resizeRightCursor"},
|
||||
{"resizeleftright", SELECTOR, @"resizeLeftRightCursor"},
|
||||
{"resizeup", SELECTOR, @"resizeUpCursor"},
|
||||
{"resizedown", SELECTOR, @"resizeDownCursor"},
|
||||
{"resizeupdown", SELECTOR, @"resizeUpDownCursor"},
|
||||
{"resizebottomleft", SELECTOR, @"_bottomLeftResizeCursor"},
|
||||
{"resizetopleft", SELECTOR, @"_topLeftResizeCursor"},
|
||||
{"resizebottomright", SELECTOR, @"_bottomRightResizeCursor"},
|
||||
{"resizetopright", SELECTOR, @"_topRightResizeCursor"},
|
||||
{"notallowed", SELECTOR, @"operationNotAllowedCursor"},
|
||||
{"poof", SELECTOR, @"disappearingItemCursor"},
|
||||
{"wait", SELECTOR, @"busyButClickableCursor"},
|
||||
{"spinning", SELECTOR, @"busyButClickableCursor"},
|
||||
{"countinguphand", SELECTOR, @"busyButClickableCursor"},
|
||||
{"countingdownhand", SELECTOR, @"busyButClickableCursor"},
|
||||
{"countingupanddownhand", SELECTOR, @"busyButClickableCursor"},
|
||||
{"none", NONE, nil, nil, {0, 0}},
|
||||
{"arrow", SELECTOR, @"arrowCursor", nil, {0, 0}},
|
||||
{"top_left_arrow", SELECTOR, @"arrowCursor", nil, {0, 0}},
|
||||
{"left_ptr", SELECTOR, @"arrowCursor", nil, {0, 0}},
|
||||
{"copyarrow", SELECTOR, @"dragCopyCursor", @"_copyDragCursor", {0, 0}},
|
||||
{"aliasarrow", SELECTOR, @"dragLinkCursor", @"_linkDragCursor", {0, 0}},
|
||||
{"contextualmenuarrow", SELECTOR, @"contextualMenuCursor", nil, {0, 0}},
|
||||
{"movearrow", SELECTOR, @"_moveCursor", nil, {0, 0}},
|
||||
{"ibeam", SELECTOR, @"IBeamCursor", nil, {0, 0}},
|
||||
{"text", SELECTOR, @"IBeamCursor", nil, {0, 0}},
|
||||
{"xterm", SELECTOR, @"IBeamCursor", nil, {0, 0}},
|
||||
{"cross", SELECTOR, @"crosshairCursor", nil, {0, 0}},
|
||||
{"crosshair", SELECTOR, @"crosshairCursor", nil, {0, 0}},
|
||||
{"cross-hair", SELECTOR, @"crosshairCursor", nil, {0, 0}},
|
||||
{"tcross", SELECTOR, @"crosshairCursor", nil, {0, 0}},
|
||||
{"hand", SELECTOR, @"openHandCursor", nil, {0, 0}},
|
||||
{"openhand", SELECTOR, @"openHandCursor", nil, {0, 0}},
|
||||
{"closedhand", SELECTOR, @"closedHandCursor", nil, {0, 0}},
|
||||
{"fist", SELECTOR, @"closedHandCursor", nil, {0, 0}},
|
||||
{"pointinghand", SELECTOR, @"pointingHandCursor", nil, {0, 0}},
|
||||
{"resize", SELECTOR, @"arrowCursor", nil, {0, 0}},
|
||||
{"resizeleft", SELECTOR, @"resizeLeftCursor", nil, {0, 0}},
|
||||
{"resizeright", SELECTOR, @"resizeRightCursor", nil, {0, 0}},
|
||||
{"resizeleftright", SELECTOR, @"resizeLeftRightCursor", nil, {0, 0}},
|
||||
{"resizeup", SELECTOR, @"resizeUpCursor", nil, {0, 0}},
|
||||
{"resizedown", SELECTOR, @"resizeDownCursor", nil, {0, 0}},
|
||||
{"resizeupdown", SELECTOR, @"resizeUpDownCursor", nil, {0, 0}},
|
||||
{"resizebottomleft", SELECTOR, @"_bottomLeftResizeCursor", nil, {0, 0}},
|
||||
{"resizetopleft", SELECTOR, @"_topLeftResizeCursor", nil, {0, 0}},
|
||||
{"resizebottomright", SELECTOR, @"_bottomRightResizeCursor", nil, {0, 0}},
|
||||
{"resizetopright", SELECTOR, @"_topRightResizeCursor", nil, {0, 0}},
|
||||
{"notallowed", SELECTOR, @"operationNotAllowedCursor", nil, {0, 0}},
|
||||
{"poof", SELECTOR, @"disappearingItemCursor", nil, {0, 0}},
|
||||
{"wait", SELECTOR, @"busyButClickableCursor", nil, {0, 0}},
|
||||
{"spinning", SELECTOR, @"busyButClickableCursor", nil, {0, 0}},
|
||||
{"countinguphand", SELECTOR, @"busyButClickableCursor", nil, {0, 0}},
|
||||
{"countingdownhand", SELECTOR, @"busyButClickableCursor", nil, {0, 0}},
|
||||
{"countingupanddownhand", SELECTOR, @"busyButClickableCursor", nil, {0, 0}},
|
||||
{"help", IMAGENAMED, @"NSHelpCursor", nil, {8, 8}},
|
||||
// {"hand", IMAGEBITMAP, MacCursorData(hand)},
|
||||
{"bucket", IMAGEBITMAP, MacCursorData(bucket)},
|
||||
{"cancel", IMAGEBITMAP, MacCursorData(cancel)},
|
||||
// {"resize", IMAGEBITMAP, MacCursorData(resize)},
|
||||
{"eyedrop", IMAGEBITMAP, MacCursorData(eyedrop)},
|
||||
{"eyedrop-full", IMAGEBITMAP, MacCursorData(eyedrop_full)},
|
||||
{"zoom-in", IMAGEBITMAP, MacCursorData(zoom_in)},
|
||||
{"zoom-out", IMAGEBITMAP, MacCursorData(zoom_out)},
|
||||
{"X_cursor", IMAGEBITMAP, MacXCursorData(X_cursor)},
|
||||
// {"arrow", IMAGEBITMAP, MacXCursorData(arrow)},
|
||||
{"based_arrow_down", IMAGEBITMAP, MacXCursorData(based_arrow_down)},
|
||||
{"based_arrow_up", IMAGEBITMAP, MacXCursorData(based_arrow_up)},
|
||||
{"boat", IMAGEBITMAP, MacXCursorData(boat)},
|
||||
{"bogosity", IMAGEBITMAP, MacXCursorData(bogosity)},
|
||||
{"bottom_left_corner", IMAGEBITMAP, MacXCursorData(bottom_left_corner)},
|
||||
{"bottom_right_corner", IMAGEBITMAP, MacXCursorData(bottom_right_corner)},
|
||||
{"bottom_side", IMAGEBITMAP, MacXCursorData(bottom_side)},
|
||||
{"bottom_tee", IMAGEBITMAP, MacXCursorData(bottom_tee)},
|
||||
{"box_spiral", IMAGEBITMAP, MacXCursorData(box_spiral)},
|
||||
{"center_ptr", IMAGEBITMAP, MacXCursorData(center_ptr)},
|
||||
{"circle", IMAGEBITMAP, MacXCursorData(circle)},
|
||||
{"clock", IMAGEBITMAP, MacXCursorData(clock)},
|
||||
{"coffee_mug", IMAGEBITMAP, MacXCursorData(coffee_mug)},
|
||||
// {"cross", IMAGEBITMAP, MacXCursorData(cross)},
|
||||
{"cross_reverse", IMAGEBITMAP, MacXCursorData(cross_reverse)},
|
||||
// {"crosshair", IMAGEBITMAP, MacXCursorData(crosshair)},
|
||||
{"diamond_cross", IMAGEBITMAP, MacXCursorData(diamond_cross)},
|
||||
{"dot", IMAGEBITMAP, MacXCursorData(dot)},
|
||||
{"dotbox", IMAGEBITMAP, MacXCursorData(dotbox)},
|
||||
{"double_arrow", IMAGEBITMAP, MacXCursorData(double_arrow)},
|
||||
{"draft_large", IMAGEBITMAP, MacXCursorData(draft_large)},
|
||||
{"draft_small", IMAGEBITMAP, MacXCursorData(draft_small)},
|
||||
{"draped_box", IMAGEBITMAP, MacXCursorData(draped_box)},
|
||||
{"exchange", IMAGEBITMAP, MacXCursorData(exchange)},
|
||||
{"fleur", IMAGEBITMAP, MacXCursorData(fleur)},
|
||||
{"gobbler", IMAGEBITMAP, MacXCursorData(gobbler)},
|
||||
{"gumby", IMAGEBITMAP, MacXCursorData(gumby)},
|
||||
{"hand1", IMAGEBITMAP, MacXCursorData(hand1)},
|
||||
{"hand2", IMAGEBITMAP, MacXCursorData(hand2)},
|
||||
{"heart", IMAGEBITMAP, MacXCursorData(heart)},
|
||||
{"icon", IMAGEBITMAP, MacXCursorData(icon)},
|
||||
{"iron_cross", IMAGEBITMAP, MacXCursorData(iron_cross)},
|
||||
// {"left_ptr", IMAGEBITMAP, MacXCursorData(left_ptr)},
|
||||
{"left_side", IMAGEBITMAP, MacXCursorData(left_side)},
|
||||
{"left_tee", IMAGEBITMAP, MacXCursorData(left_tee)},
|
||||
{"leftbutton", IMAGEBITMAP, MacXCursorData(leftbutton)},
|
||||
{"ll_angle", IMAGEBITMAP, MacXCursorData(ll_angle)},
|
||||
{"lr_angle", IMAGEBITMAP, MacXCursorData(lr_angle)},
|
||||
{"man", IMAGEBITMAP, MacXCursorData(man)},
|
||||
{"middlebutton", IMAGEBITMAP, MacXCursorData(middlebutton)},
|
||||
{"mouse", IMAGEBITMAP, MacXCursorData(mouse)},
|
||||
{"pencil", IMAGEBITMAP, MacXCursorData(pencil)},
|
||||
{"pirate", IMAGEBITMAP, MacXCursorData(pirate)},
|
||||
{"plus", IMAGEBITMAP, MacXCursorData(plus)},
|
||||
{"question_arrow", IMAGEBITMAP, MacXCursorData(question_arrow)},
|
||||
{"right_ptr", IMAGEBITMAP, MacXCursorData(right_ptr)},
|
||||
{"right_side", IMAGEBITMAP, MacXCursorData(right_side)},
|
||||
{"right_tee", IMAGEBITMAP, MacXCursorData(right_tee)},
|
||||
{"rightbutton", IMAGEBITMAP, MacXCursorData(rightbutton)},
|
||||
{"rtl_logo", IMAGEBITMAP, MacXCursorData(rtl_logo)},
|
||||
{"sailboat", IMAGEBITMAP, MacXCursorData(sailboat)},
|
||||
{"sb_down_arrow", IMAGEBITMAP, MacXCursorData(sb_down_arrow)},
|
||||
{"sb_h_double_arrow", IMAGEBITMAP, MacXCursorData(sb_h_double_arrow)},
|
||||
{"sb_left_arrow", IMAGEBITMAP, MacXCursorData(sb_left_arrow)},
|
||||
{"sb_right_arrow", IMAGEBITMAP, MacXCursorData(sb_right_arrow)},
|
||||
{"sb_up_arrow", IMAGEBITMAP, MacXCursorData(sb_up_arrow)},
|
||||
{"sb_v_double_arrow", IMAGEBITMAP, MacXCursorData(sb_v_double_arrow)},
|
||||
{"shuttle", IMAGEBITMAP, MacXCursorData(shuttle)},
|
||||
{"sizing", IMAGEBITMAP, MacXCursorData(sizing)},
|
||||
{"spider", IMAGEBITMAP, MacXCursorData(spider)},
|
||||
{"spraycan", IMAGEBITMAP, MacXCursorData(spraycan)},
|
||||
{"star", IMAGEBITMAP, MacXCursorData(star)},
|
||||
{"target", IMAGEBITMAP, MacXCursorData(target)},
|
||||
// {"tcross", IMAGEBITMAP, MacXCursorData(tcross)},
|
||||
// {"top_left_arrow", IMAGEBITMAP, MacXCursorData(top_left_arrow)},
|
||||
{"top_left_corner", IMAGEBITMAP, MacXCursorData(top_left_corner)},
|
||||
{"top_right_corner", IMAGEBITMAP, MacXCursorData(top_right_corner)},
|
||||
{"top_side", IMAGEBITMAP, MacXCursorData(top_side)},
|
||||
{"top_tee", IMAGEBITMAP, MacXCursorData(top_tee)},
|
||||
{"trek", IMAGEBITMAP, MacXCursorData(trek)},
|
||||
{"ul_angle", IMAGEBITMAP, MacXCursorData(ul_angle)},
|
||||
{"umbrella", IMAGEBITMAP, MacXCursorData(umbrella)},
|
||||
{"ur_angle", IMAGEBITMAP, MacXCursorData(ur_angle)},
|
||||
{"watch", IMAGEBITMAP, MacXCursorData(watch)},
|
||||
// {"xterm", IMAGEBITMAP, MacXCursorData(xterm)},
|
||||
{NULL}
|
||||
// {"hand", IMAGEBITMAP, MacCursorData(hand), nil, {0, 0}},
|
||||
{"bucket", IMAGEBITMAP, MacCursorData(bucket), nil, {0, 0}},
|
||||
{"cancel", IMAGEBITMAP, MacCursorData(cancel), nil, {0, 0}},
|
||||
// {"resize", IMAGEBITMAP, MacCursorData(resize), nil, {0, 0}},
|
||||
{"eyedrop", IMAGEBITMAP, MacCursorData(eyedrop), nil, {0, 0}},
|
||||
{"eyedrop-full", IMAGEBITMAP, MacCursorData(eyedrop_full), nil, {0, 0}},
|
||||
{"zoom-in", IMAGEBITMAP, MacCursorData(zoom_in), nil, {0, 0}},
|
||||
{"zoom-out", IMAGEBITMAP, MacCursorData(zoom_out), nil, {0, 0}},
|
||||
{"X_cursor", IMAGEBITMAP, MacXCursorData(X_cursor), nil, {0, 0}},
|
||||
// {"arrow", IMAGEBITMAP, MacXCursorData(arrow), nil, {0, 0}},
|
||||
{"based_arrow_down", IMAGEBITMAP, MacXCursorData(based_arrow_down), nil, {0, 0}},
|
||||
{"based_arrow_up", IMAGEBITMAP, MacXCursorData(based_arrow_up), nil, {0, 0}},
|
||||
{"boat", IMAGEBITMAP, MacXCursorData(boat), nil, {0, 0}},
|
||||
{"bogosity", IMAGEBITMAP, MacXCursorData(bogosity), nil, {0, 0}},
|
||||
{"bottom_left_corner", IMAGEBITMAP, MacXCursorData(bottom_left_corner), nil, {0, 0}},
|
||||
{"bottom_right_corner", IMAGEBITMAP, MacXCursorData(bottom_right_corner), nil, {0, 0}},
|
||||
{"bottom_side", IMAGEBITMAP, MacXCursorData(bottom_side), nil, {0, 0}},
|
||||
{"bottom_tee", IMAGEBITMAP, MacXCursorData(bottom_tee), nil, {0, 0}},
|
||||
{"box_spiral", IMAGEBITMAP, MacXCursorData(box_spiral), nil, {0, 0}},
|
||||
{"center_ptr", IMAGEBITMAP, MacXCursorData(center_ptr), nil, {0, 0}},
|
||||
{"circle", IMAGEBITMAP, MacXCursorData(circle), nil, {0, 0}},
|
||||
{"clock", IMAGEBITMAP, MacXCursorData(clock), nil, {0, 0}},
|
||||
{"coffee_mug", IMAGEBITMAP, MacXCursorData(coffee_mug), nil, {0, 0}},
|
||||
// {"cross", IMAGEBITMAP, MacXCursorData(cross), nil, {0, 0}},
|
||||
{"cross_reverse", IMAGEBITMAP, MacXCursorData(cross_reverse), nil, {0, 0}},
|
||||
// {"crosshair", IMAGEBITMAP, MacXCursorData(crosshair), nil, {0, 0}},
|
||||
{"diamond_cross", IMAGEBITMAP, MacXCursorData(diamond_cross), nil, {0, 0}},
|
||||
{"dot", IMAGEBITMAP, MacXCursorData(dot), nil, {0, 0}},
|
||||
{"dotbox", IMAGEBITMAP, MacXCursorData(dotbox), nil, {0, 0}},
|
||||
{"double_arrow", IMAGEBITMAP, MacXCursorData(double_arrow), nil, {0, 0}},
|
||||
{"draft_large", IMAGEBITMAP, MacXCursorData(draft_large), nil, {0, 0}},
|
||||
{"draft_small", IMAGEBITMAP, MacXCursorData(draft_small), nil, {0, 0}},
|
||||
{"draped_box", IMAGEBITMAP, MacXCursorData(draped_box), nil, {0, 0}},
|
||||
{"exchange", IMAGEBITMAP, MacXCursorData(exchange), nil, {0, 0}},
|
||||
{"fleur", IMAGEBITMAP, MacXCursorData(fleur), nil, {0, 0}},
|
||||
{"gobbler", IMAGEBITMAP, MacXCursorData(gobbler), nil, {0, 0}},
|
||||
{"gumby", IMAGEBITMAP, MacXCursorData(gumby), nil, {0, 0}},
|
||||
{"hand1", IMAGEBITMAP, MacXCursorData(hand1), nil, {0, 0}},
|
||||
{"hand2", IMAGEBITMAP, MacXCursorData(hand2), nil, {0, 0}},
|
||||
{"heart", IMAGEBITMAP, MacXCursorData(heart), nil, {0, 0}},
|
||||
{"icon", IMAGEBITMAP, MacXCursorData(icon), nil, {0, 0}},
|
||||
{"iron_cross", IMAGEBITMAP, MacXCursorData(iron_cross), nil, {0, 0}},
|
||||
// {"left_ptr", IMAGEBITMAP, MacXCursorData(left_ptr), nil, {0, 0}},
|
||||
{"left_side", IMAGEBITMAP, MacXCursorData(left_side), nil, {0, 0}},
|
||||
{"left_tee", IMAGEBITMAP, MacXCursorData(left_tee), nil, {0, 0}},
|
||||
{"leftbutton", IMAGEBITMAP, MacXCursorData(leftbutton), nil, {0, 0}},
|
||||
{"ll_angle", IMAGEBITMAP, MacXCursorData(ll_angle), nil, {0, 0}},
|
||||
{"lr_angle", IMAGEBITMAP, MacXCursorData(lr_angle), nil, {0, 0}},
|
||||
{"man", IMAGEBITMAP, MacXCursorData(man), nil, {0, 0}},
|
||||
{"middlebutton", IMAGEBITMAP, MacXCursorData(middlebutton), nil, {0, 0}},
|
||||
{"mouse", IMAGEBITMAP, MacXCursorData(mouse), nil, {0, 0}},
|
||||
{"pencil", IMAGEBITMAP, MacXCursorData(pencil), nil, {0, 0}},
|
||||
{"pirate", IMAGEBITMAP, MacXCursorData(pirate), nil, {0, 0}},
|
||||
{"plus", IMAGEBITMAP, MacXCursorData(plus), nil, {0, 0}},
|
||||
{"question_arrow", IMAGEBITMAP, MacXCursorData(question_arrow), nil, {0, 0}},
|
||||
{"right_ptr", IMAGEBITMAP, MacXCursorData(right_ptr), nil, {0, 0}},
|
||||
{"right_side", IMAGEBITMAP, MacXCursorData(right_side), nil, {0, 0}},
|
||||
{"right_tee", IMAGEBITMAP, MacXCursorData(right_tee), nil, {0, 0}},
|
||||
{"rightbutton", IMAGEBITMAP, MacXCursorData(rightbutton), nil, {0, 0}},
|
||||
{"rtl_logo", IMAGEBITMAP, MacXCursorData(rtl_logo), nil, {0, 0}},
|
||||
{"sailboat", IMAGEBITMAP, MacXCursorData(sailboat), nil, {0, 0}},
|
||||
{"sb_down_arrow", IMAGEBITMAP, MacXCursorData(sb_down_arrow), nil, {0, 0}},
|
||||
{"sb_h_double_arrow", IMAGEBITMAP, MacXCursorData(sb_h_double_arrow), nil, {0, 0}},
|
||||
{"sb_left_arrow", IMAGEBITMAP, MacXCursorData(sb_left_arrow), nil, {0, 0}},
|
||||
{"sb_right_arrow", IMAGEBITMAP, MacXCursorData(sb_right_arrow), nil, {0, 0}},
|
||||
{"sb_up_arrow", IMAGEBITMAP, MacXCursorData(sb_up_arrow), nil, {0, 0}},
|
||||
{"sb_v_double_arrow", IMAGEBITMAP, MacXCursorData(sb_v_double_arrow), nil, {0, 0}},
|
||||
{"shuttle", IMAGEBITMAP, MacXCursorData(shuttle), nil, {0, 0}},
|
||||
{"sizing", IMAGEBITMAP, MacXCursorData(sizing), nil, {0, 0}},
|
||||
{"spider", IMAGEBITMAP, MacXCursorData(spider), nil, {0, 0}},
|
||||
{"spraycan", IMAGEBITMAP, MacXCursorData(spraycan), nil, {0, 0}},
|
||||
{"star", IMAGEBITMAP, MacXCursorData(star), nil, {0, 0}},
|
||||
{"target", IMAGEBITMAP, MacXCursorData(target), nil, {0, 0}},
|
||||
// {"tcross", IMAGEBITMAP, MacXCursorData(tcross), nil, {0, 0}},
|
||||
// {"top_left_arrow", IMAGEBITMAP, MacXCursorData(top_left_arrow), nil, {0, 0}},
|
||||
{"top_left_corner", IMAGEBITMAP, MacXCursorData(top_left_corner), nil, {0, 0}},
|
||||
{"top_right_corner", IMAGEBITMAP, MacXCursorData(top_right_corner), nil, {0, 0}},
|
||||
{"top_side", IMAGEBITMAP, MacXCursorData(top_side), nil, {0, 0}},
|
||||
{"top_tee", IMAGEBITMAP, MacXCursorData(top_tee), nil, {0, 0}},
|
||||
{"trek", IMAGEBITMAP, MacXCursorData(trek), nil, {0, 0}},
|
||||
{"ul_angle", IMAGEBITMAP, MacXCursorData(ul_angle), nil, {0, 0}},
|
||||
{"umbrella", IMAGEBITMAP, MacXCursorData(umbrella), nil, {0, 0}},
|
||||
{"ur_angle", IMAGEBITMAP, MacXCursorData(ur_angle), nil, {0, 0}},
|
||||
{"watch", IMAGEBITMAP, MacXCursorData(watch), nil, {0, 0}},
|
||||
// {"xterm", IMAGEBITMAP, MacXCursorData(xterm), nil, {0, 0}},
|
||||
{NULL, 0, nil, nil, {0, 0}}
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -271,7 +271,7 @@ FindCursorByName(
|
||||
break;
|
||||
case IMAGEBITMAP: {
|
||||
unsigned char *bitmap = (unsigned char *)(cursorNames[idx].id1);
|
||||
NSBitmapImageRep *bitmapImageRep = NULL;
|
||||
NSBitmapImageRep *bitmapImageRep = nil;
|
||||
CGImageRef img = NULL, mask = NULL, maskedImg = NULL;
|
||||
static const CGFloat decodeWB[] = {1, 0};
|
||||
CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(
|
||||
@@ -312,6 +312,7 @@ FindCursorByName(
|
||||
if (bitmapImageRep) {
|
||||
image = [[NSImage alloc] initWithSize:NSMakeSize(pix, pix)];
|
||||
[image addRepresentation:bitmapImageRep];
|
||||
[image setTemplate:YES];
|
||||
[bitmapImageRep release];
|
||||
}
|
||||
|
||||
@@ -374,7 +375,7 @@ FindCursorByName(
|
||||
TkCursor *
|
||||
TkGetCursorByName(
|
||||
Tcl_Interp *interp, /* Interpreter to use for error reporting. */
|
||||
Tk_Window tkwin, /* Window in which cursor will be used. */
|
||||
TCL_UNUSED(Tk_Window), /* Window in which cursor will be used. */
|
||||
Tk_Uid string) /* Description of cursor. See manual entry
|
||||
* for details on legal syntax. */
|
||||
{
|
||||
@@ -389,7 +390,7 @@ TkGetCursorByName(
|
||||
|
||||
if (Tcl_SplitList(interp, string, &argc, &argv) == TCL_OK) {
|
||||
if (argc) {
|
||||
macCursorPtr = ckalloc(sizeof(TkMacOSXCursor));
|
||||
macCursorPtr = (TkMacOSXCursor *)ckalloc(sizeof(TkMacOSXCursor));
|
||||
macCursorPtr->info.cursor = (Tk_Cursor) macCursorPtr;
|
||||
macCursorPtr->macCursor = nil;
|
||||
macCursorPtr->type = 0;
|
||||
@@ -428,13 +429,15 @@ TkGetCursorByName(
|
||||
|
||||
TkCursor *
|
||||
TkCreateCursorFromData(
|
||||
Tk_Window tkwin, /* Window in which cursor will be used. */
|
||||
const char *source, /* Bitmap data for cursor shape. */
|
||||
const char *mask, /* Bitmap data for cursor mask. */
|
||||
int width, int height, /* Dimensions of cursor. */
|
||||
int xHot, int yHot, /* Location of hot-spot in cursor. */
|
||||
XColor fgColor, /* Foreground color for cursor. */
|
||||
XColor bgColor) /* Background color for cursor. */
|
||||
TCL_UNUSED(Tk_Window), /* Window in which cursor will be used. */
|
||||
TCL_UNUSED(const char *), /* Bitmap data for cursor shape. */
|
||||
TCL_UNUSED(const char *), /* Bitmap data for cursor mask. */
|
||||
TCL_UNUSED(int), /* Dimensions of cursor. */
|
||||
TCL_UNUSED(int),
|
||||
TCL_UNUSED(int), /* Location of hot-spot in cursor. */
|
||||
TCL_UNUSED(int),
|
||||
TCL_UNUSED(XColor), /* Foreground color for cursor. */
|
||||
TCL_UNUSED(XColor)) /* Background color for cursor. */
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -463,7 +466,7 @@ TkpFreeCursor(
|
||||
TkMacOSXCursor *macCursorPtr = (TkMacOSXCursor *) cursorPtr;
|
||||
|
||||
[macCursorPtr->macCursor release];
|
||||
macCursorPtr->macCursor = NULL;
|
||||
macCursorPtr->macCursor = nil;
|
||||
if (macCursorPtr == gCurrentCursor) {
|
||||
gCurrentCursor = NULL;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ TkMacOSXGetNamedDebugSymbol(
|
||||
for (i = 0; i < n; i++) {
|
||||
if (module && *module) {
|
||||
/* Find image with given module name */
|
||||
char *name;
|
||||
const char *name;
|
||||
const char *path = _dyld_get_image_name(i);
|
||||
|
||||
if (!path) {
|
||||
|
||||
@@ -42,10 +42,11 @@
|
||||
#define ACTIVE_FG "systemTextColor"
|
||||
#define SELECT_BG "systemSelectedTextBackgroundColor"
|
||||
#define SELECT_FG "systemSelectedTextColor"
|
||||
#define INACTIVE_SELECT_BG "systemSelectedTextBackgroundColor"
|
||||
#define INACTIVE_SELECT_BG "systemUnemphasizedSelectedTextBackgroundColor"
|
||||
#define TROUGH "#c3c3c3"
|
||||
#define INDICATOR "#b03060"
|
||||
#define DISABLED "#a3a3a3"
|
||||
#define IGNORED "#abcdef"
|
||||
|
||||
/*
|
||||
* Defaults for labels, buttons, checkbuttons, and radiobuttons:
|
||||
@@ -88,19 +89,9 @@
|
||||
#define DEF_BUTTON_ON_VALUE "1"
|
||||
#define DEF_BUTTON_TRISTATE_VALUE ""
|
||||
#define DEF_BUTTON_OVER_RELIEF ""
|
||||
//#if TK_MAC_BUTTON_USE_COMPATIBILITY_METRICS
|
||||
//#define DEF_BUTTON_PADX "12"
|
||||
//#define DEF_BUTTON_PADX_NOCM "1"
|
||||
//#else
|
||||
#define DEF_BUTTON_PADX "1"
|
||||
//#endif
|
||||
#define DEF_LABCHKRAD_PADX "1"
|
||||
//#if TK_MAC_BUTTON_USE_COMPATIBILITY_METRICS
|
||||
//#define DEF_BUTTON_PADY "3"
|
||||
//#define DEF_BUTTON_PADY_NOCM "1"
|
||||
//#else
|
||||
#define DEF_BUTTON_PADY "1"
|
||||
//#endif
|
||||
#define DEF_LABCHKRAD_PADY "1"
|
||||
#define DEF_BUTTON_RELIEF "flat"
|
||||
#define DEF_LABCHKRAD_RELIEF "flat"
|
||||
@@ -307,23 +298,23 @@
|
||||
* Defaults for menus overall:
|
||||
*/
|
||||
|
||||
#define DEF_MENU_ACTIVE_BG_COLOR "systemMenuActive"
|
||||
#define DEF_MENU_ACTIVE_BG_MONO BLACK
|
||||
#define DEF_MENU_ACTIVE_BG_COLOR IGNORED
|
||||
#define DEF_MENU_ACTIVE_BG_MONO IGNORED
|
||||
#define DEF_MENU_ACTIVE_BORDER_WIDTH "0"
|
||||
#define DEF_MENU_ACTIVE_FG_COLOR "systemMenuActiveText"
|
||||
#define DEF_MENU_ACTIVE_FG_MONO WHITE
|
||||
#define DEF_MENU_BG_COLOR "systemMenu"
|
||||
#define DEF_MENU_BG_MONO WHITE
|
||||
#define DEF_MENU_ACTIVE_FG_COLOR IGNORED
|
||||
#define DEF_MENU_ACTIVE_FG_MONO IGNORED
|
||||
#define DEF_MENU_BG_COLOR "#000001" /* Detects custom bg. */
|
||||
#define DEF_MENU_BG_MONO IGNORED
|
||||
#define DEF_MENU_BORDER_WIDTH "0"
|
||||
#define DEF_MENU_CURSOR "arrow"
|
||||
#define DEF_MENU_DISABLED_FG_COLOR "systemMenuDisabled"
|
||||
#define DEF_MENU_DISABLED_FG_COLOR IGNORED
|
||||
#define DEF_MENU_DISABLED_FG_MONO ""
|
||||
#define DEF_MENU_FONT "menu" /* special: see tkMacOSXMenu.c */
|
||||
#define DEF_MENU_FG "systemMenuText"
|
||||
#define DEF_MENU_FG "#010000" /* Detects custom fg. */
|
||||
#define DEF_MENU_POST_COMMAND ""
|
||||
#define DEF_MENU_RELIEF "flat"
|
||||
#define DEF_MENU_SELECT_COLOR "systemMenuActive"
|
||||
#define DEF_MENU_SELECT_MONO BLACK
|
||||
#define DEF_MENU_SELECT_COLOR IGNORED
|
||||
#define DEF_MENU_SELECT_MONO IGNORED
|
||||
#define DEF_MENU_TAKE_FOCUS "0"
|
||||
#define DEF_MENU_TEAROFF "0"
|
||||
#define DEF_MENU_TEAROFF_CMD NULL
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#define modalOK NSModalResponseOK
|
||||
#define modalCancel NSModalResponseCancel
|
||||
#endif // MAC_OS_X_VERSION_MIN_REQUIRED < 1090
|
||||
#define modalOther -1
|
||||
#define modalOther -1 // indicates that the -command option was used.
|
||||
#define modalError -2
|
||||
|
||||
/*
|
||||
@@ -52,6 +52,10 @@ typedef struct {
|
||||
* filter. */
|
||||
} filepanelFilterInfo;
|
||||
|
||||
/*
|
||||
* Only one of these is needed for the application, so they can be static.
|
||||
*/
|
||||
|
||||
static filepanelFilterInfo filterInfo;
|
||||
static NSOpenPanel *openpanel;
|
||||
static NSSavePanel *savepanel;
|
||||
@@ -198,19 +202,24 @@ getFileURL(
|
||||
@implementation TKApplication(TKDialog)
|
||||
|
||||
- (BOOL)panel:(id)sender shouldEnableURL:(NSURL *)url {
|
||||
(void)sender;
|
||||
(void)url;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)panel:(id)sender didChangeToDirectoryURL:(NSURL *)url {
|
||||
(void)sender; (void)url;
|
||||
}
|
||||
|
||||
- (BOOL)panel:(id)sender validateURL:(NSURL *)url error:(NSError **)outError {
|
||||
(void)sender; (void)url;
|
||||
*outError = nil;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void) tkFilePanelDidEnd: (NSSavePanel *) panel
|
||||
returnCode: (NSInteger) returnCode contextInfo: (void *) contextInfo
|
||||
returnCode: (NSModalResponse) returnCode
|
||||
contextInfo: (void *) contextInfo
|
||||
{
|
||||
FilePanelCallbackInfo *callbackInfo = contextInfo;
|
||||
|
||||
@@ -232,7 +241,7 @@ getFileURL(
|
||||
callbackInfo->cmdObj, &objc, &objv);
|
||||
|
||||
if (result == TCL_OK && objc) {
|
||||
tmpv = ckalloc(sizeof(Tcl_Obj *) * (objc + 2));
|
||||
tmpv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * (objc + 2));
|
||||
memcpy(tmpv, objv, sizeof(Tcl_Obj *) * objc);
|
||||
tmpv[objc] = resultObj;
|
||||
TkBackgroundEvalObjv(callbackInfo->interp, objc + 1, tmpv,
|
||||
@@ -245,13 +254,13 @@ getFileURL(
|
||||
} else if (returnCode == modalCancel) {
|
||||
Tcl_ResetResult(callbackInfo->interp);
|
||||
}
|
||||
if (panel == [NSApp modalWindow]) {
|
||||
[NSApp stopModalWithCode:returnCode];
|
||||
}
|
||||
if (callbackInfo->cmdObj) {
|
||||
Tcl_DecrRefCount(callbackInfo->cmdObj);
|
||||
}
|
||||
if (callbackInfo) {
|
||||
ckfree(callbackInfo);
|
||||
}
|
||||
[NSApp stopModalWithCode:returnCode];
|
||||
}
|
||||
|
||||
- (void) tkAlertDidEnd: (NSAlert *) alert returnCode: (NSInteger) returnCode
|
||||
@@ -270,7 +279,7 @@ getFileURL(
|
||||
callbackInfo->cmdObj, &objc, &objv);
|
||||
|
||||
if (result == TCL_OK && objc) {
|
||||
tmpv = ckalloc(sizeof(Tcl_Obj *) * (objc + 2));
|
||||
tmpv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * (objc + 2));
|
||||
memcpy(tmpv, objv, sizeof(Tcl_Obj *) * objc);
|
||||
tmpv[objc] = resultObj;
|
||||
TkBackgroundEvalObjv(callbackInfo->interp, objc + 1, tmpv,
|
||||
@@ -293,7 +302,6 @@ getFileURL(
|
||||
- (void)selectFormat:(id)sender {
|
||||
NSPopUpButton *button = (NSPopUpButton *)sender;
|
||||
filterInfo.fileTypeIndex = [button indexOfSelectedItem];
|
||||
|
||||
if ([[filterInfo.fileTypeAllowsAll objectAtIndex:filterInfo.fileTypeIndex] boolValue]) {
|
||||
[openpanel setAllowsOtherFileTypes:YES];
|
||||
|
||||
@@ -343,21 +351,50 @@ static NSInteger showOpenSavePanel(
|
||||
{
|
||||
NSInteger modalReturnCode;
|
||||
|
||||
if (parent && ![parent attachedSheet] && [NSApp macMinorVersion] < 15) {
|
||||
if (parent && ![parent attachedSheet]) {
|
||||
[panel beginSheetModalForWindow:parent
|
||||
completionHandler:^(NSInteger returnCode) {
|
||||
completionHandler:^(NSModalResponse returnCode) {
|
||||
[NSApp tkFilePanelDidEnd:panel
|
||||
returnCode:returnCode
|
||||
contextInfo:callbackInfo ];
|
||||
}];
|
||||
modalReturnCode = callbackInfo->cmdObj ? modalOther :
|
||||
[NSApp runModalForWindow:panel];
|
||||
|
||||
/*
|
||||
* The sheet has been prepared, so now we have to run it as a modal
|
||||
* window. Using [NSApp runModalForWindow:] on macOS 10.15 or later
|
||||
* generates warnings on stderr. But using [NSOpenPanel runModal] or
|
||||
* [NSSavePanel runModal] on 10.14 or earler does not cause the
|
||||
* completion handler to run when the panel is closed.
|
||||
*/
|
||||
|
||||
if ([NSApp macOSVersion] > 101400) {
|
||||
modalReturnCode = [panel runModal];
|
||||
} else {
|
||||
modalReturnCode = [NSApp runModalForWindow:panel];
|
||||
}
|
||||
} else {
|
||||
modalReturnCode = [panel runModal];
|
||||
[NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode
|
||||
contextInfo:callbackInfo];
|
||||
|
||||
/*
|
||||
* For the standalone file dialog, completion handlers do not work
|
||||
* at all on macOS 10.14 and earlier.
|
||||
*/
|
||||
|
||||
if ([NSApp macOSVersion] > 101400) {
|
||||
[panel beginWithCompletionHandler:^(NSModalResponse returnCode) {
|
||||
[NSApp tkFilePanelDidEnd:panel
|
||||
returnCode:returnCode
|
||||
contextInfo:callbackInfo ];
|
||||
}];
|
||||
modalReturnCode = [panel runModal];
|
||||
} else {
|
||||
modalReturnCode = [panel runModal];
|
||||
[NSApp tkFilePanelDidEnd:panel
|
||||
returnCode:modalReturnCode
|
||||
contextInfo:callbackInfo ];
|
||||
[panel close];
|
||||
}
|
||||
}
|
||||
return modalReturnCode;
|
||||
return callbackInfo->cmdObj ? modalOther : modalReturnCode;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -654,8 +691,6 @@ Tk_GetOpenFileObjCmd(
|
||||
NSInteger modalReturnCode = modalError;
|
||||
BOOL parentIsKey = NO;
|
||||
|
||||
[openpanel setDelegate:NSApp];
|
||||
|
||||
for (i = 1; i < objc; i += 2) {
|
||||
if (Tcl_GetIndexFromObjStruct(interp, objv[i], openOptionStrings,
|
||||
sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
|
||||
@@ -725,7 +760,7 @@ Tk_GetOpenFileObjCmd(
|
||||
* panel. Prepend the title to the message in this case.
|
||||
*/
|
||||
|
||||
if ([NSApp macMinorVersion] > 10) {
|
||||
if ([NSApp macOSVersion] > 101000) {
|
||||
if (message) {
|
||||
NSString *fullmessage =
|
||||
[[NSString alloc] initWithFormat:@"%@\n%@", title, message];
|
||||
@@ -763,6 +798,7 @@ Tk_GetOpenFileObjCmd(
|
||||
[label setBezeled:NO];
|
||||
[label setDrawsBackground:NO];
|
||||
[popupButton addItemsWithTitles:filterInfo.fileTypeLabels];
|
||||
[popupButton setTarget:NSApp];
|
||||
[popupButton setAction:@selector(selectFormat:)];
|
||||
[accessoryView addSubview:label];
|
||||
[accessoryView addSubview:popupButton];
|
||||
@@ -804,7 +840,7 @@ Tk_GetOpenFileObjCmd(
|
||||
}
|
||||
Tcl_IncrRefCount(cmdObj);
|
||||
}
|
||||
callbackInfo = ckalloc(sizeof(FilePanelCallbackInfo));
|
||||
callbackInfo = (FilePanelCallbackInfo *)ckalloc(sizeof(FilePanelCallbackInfo));
|
||||
callbackInfo->cmdObj = cmdObj;
|
||||
callbackInfo->interp = interp;
|
||||
callbackInfo->multiple = multiple;
|
||||
@@ -814,7 +850,7 @@ Tk_GetOpenFileObjCmd(
|
||||
[openpanel setDirectoryURL:fileURL];
|
||||
}
|
||||
if (haveParentOption) {
|
||||
parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
|
||||
parent = TkMacOSXGetNSWindowForDrawable(((TkWindow *)tkwin)->window);
|
||||
parentIsKey = parent && [parent isKeyWindow];
|
||||
} else {
|
||||
parent = nil;
|
||||
@@ -866,15 +902,15 @@ Tk_GetOpenFileObjCmd(
|
||||
selectedFilterIndex = filterInfo.fileTypeIndex; // The preselection from the typevariable
|
||||
selectedFilter = [filterInfo.fileTypeNames objectAtIndex:selectedFilterIndex];
|
||||
} else {
|
||||
NSUInteger i;
|
||||
NSUInteger j;
|
||||
|
||||
for (i = 0; i < [filterInfo.fileTypeNames count]; i++) {
|
||||
if (filterCompatible(extension, i)) {
|
||||
selectedFilterIndex = i;
|
||||
for (j = 0; j < [filterInfo.fileTypeNames count]; j++) {
|
||||
if (filterCompatible(extension, j)) {
|
||||
selectedFilterIndex = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == selectedFilterIndex) {
|
||||
if (j == selectedFilterIndex) {
|
||||
selectedFilter = [filterInfo.fileTypeNames objectAtIndex:selectedFilterIndex];
|
||||
} else {
|
||||
selectedFilter = @"";
|
||||
@@ -913,7 +949,7 @@ Tk_GetSaveFileObjCmd(
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
{
|
||||
Tk_Window tkwin = clientData;
|
||||
Tk_Window tkwin = (Tk_Window)clientData;
|
||||
char *str;
|
||||
int i, result = TCL_ERROR, haveParentOption = 0;
|
||||
int confirmOverwrite = 1;
|
||||
@@ -928,8 +964,6 @@ Tk_GetSaveFileObjCmd(
|
||||
NSInteger modalReturnCode = modalError;
|
||||
BOOL parentIsKey = NO;
|
||||
|
||||
[savepanel setDelegate:NSApp];
|
||||
|
||||
for (i = 1; i < objc; i += 2) {
|
||||
if (Tcl_GetIndexFromObjStruct(interp, objv[i], saveOptionStrings,
|
||||
sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
|
||||
@@ -1050,8 +1084,8 @@ Tk_GetSaveFileObjCmd(
|
||||
|
||||
[popupButton addItemsWithTitles:filterInfo.fileTypeLabels];
|
||||
[popupButton selectItemAtIndex:filterInfo.fileTypeIndex];
|
||||
[popupButton setTarget:NSApp];
|
||||
[popupButton setAction:@selector(saveFormat:)];
|
||||
|
||||
[accessoryView addSubview:label];
|
||||
[accessoryView addSubview:popupButton];
|
||||
|
||||
@@ -1082,7 +1116,7 @@ Tk_GetSaveFileObjCmd(
|
||||
}
|
||||
Tcl_IncrRefCount(cmdObj);
|
||||
}
|
||||
callbackInfo = ckalloc(sizeof(FilePanelCallbackInfo));
|
||||
callbackInfo = (FilePanelCallbackInfo *)ckalloc(sizeof(FilePanelCallbackInfo));
|
||||
callbackInfo->cmdObj = cmdObj;
|
||||
callbackInfo->interp = interp;
|
||||
callbackInfo->multiple = 0;
|
||||
@@ -1102,7 +1136,7 @@ Tk_GetSaveFileObjCmd(
|
||||
[savepanel setNameFieldStringValue:@""];
|
||||
}
|
||||
if (haveParentOption) {
|
||||
parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
|
||||
parent = TkMacOSXGetNSWindowForDrawable(((TkWindow *)tkwin)->window);
|
||||
parentIsKey = parent && [parent isKeyWindow];
|
||||
} else {
|
||||
parent = nil;
|
||||
@@ -1157,7 +1191,7 @@ Tk_ChooseDirectoryObjCmd(
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
{
|
||||
Tk_Window tkwin = clientData;
|
||||
Tk_Window tkwin = (Tk_Window)clientData;
|
||||
char *str;
|
||||
int i, result = TCL_ERROR, haveParentOption = 0;
|
||||
int index, len, mustexist = 0;
|
||||
@@ -1171,8 +1205,6 @@ Tk_ChooseDirectoryObjCmd(
|
||||
NSInteger modalReturnCode = modalError;
|
||||
BOOL parentIsKey = NO;
|
||||
|
||||
[panel setDelegate:NSApp];
|
||||
|
||||
for (i = 1; i < objc; i += 2) {
|
||||
if (Tcl_GetIndexFromObjStruct(interp, objv[i], chooseOptionStrings,
|
||||
sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
|
||||
@@ -1233,7 +1265,7 @@ Tk_ChooseDirectoryObjCmd(
|
||||
}
|
||||
Tcl_IncrRefCount(cmdObj);
|
||||
}
|
||||
callbackInfo = ckalloc(sizeof(FilePanelCallbackInfo));
|
||||
callbackInfo = (FilePanelCallbackInfo *)ckalloc(sizeof(FilePanelCallbackInfo));
|
||||
callbackInfo->cmdObj = cmdObj;
|
||||
callbackInfo->interp = interp;
|
||||
callbackInfo->multiple = 0;
|
||||
@@ -1246,10 +1278,10 @@ Tk_ChooseDirectoryObjCmd(
|
||||
if (!directory) {
|
||||
directory = @"/";
|
||||
}
|
||||
parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
|
||||
parent = TkMacOSXGetNSWindowForDrawable(((TkWindow *)tkwin)->window);
|
||||
[panel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]];
|
||||
if (haveParentOption) {
|
||||
parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
|
||||
parent = TkMacOSXGetNSWindowForDrawable(((TkWindow *)tkwin)->window);
|
||||
parentIsKey = parent && [parent isKeyWindow];
|
||||
} else {
|
||||
parent = nil;
|
||||
@@ -1283,64 +1315,9 @@ Tk_ChooseDirectoryObjCmd(
|
||||
void
|
||||
TkAboutDlg(void)
|
||||
{
|
||||
NSImage *image;
|
||||
NSString *path = [NSApp tkFrameworkImagePath: @"Tk.tiff"];
|
||||
|
||||
if (path) {
|
||||
image = [[[NSImage alloc] initWithContentsOfFile:path] autorelease];
|
||||
} else {
|
||||
image = [NSApp applicationIconImage];
|
||||
}
|
||||
|
||||
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
|
||||
|
||||
[dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
|
||||
[dateFormatter setDateFormat:@"Y"];
|
||||
|
||||
NSString *year = [dateFormatter stringFromDate:[NSDate date]];
|
||||
|
||||
[dateFormatter release];
|
||||
|
||||
/*
|
||||
* This replaces the old about dialog with a standard alert that displays
|
||||
* correctly on 10.14.
|
||||
*/
|
||||
|
||||
NSString *version = @"Tcl " TCL_PATCH_LEVEL " & Tk " TCL_PATCH_LEVEL;
|
||||
NSString *url = @"www.tcl-lang.org";
|
||||
NSTextView *credits = [[NSTextView alloc] initWithFrame:NSMakeRect(0,0,300,300)];
|
||||
NSFont *font = [NSFont systemFontOfSize:[NSFont systemFontSize]];
|
||||
NSDictionary *textAttributes = [NSDictionary dictionaryWithObject:font
|
||||
forKey:NSFontAttributeName];
|
||||
|
||||
[credits insertText: [[NSAttributedString alloc]
|
||||
initWithString:[NSString stringWithFormat: @"\n"
|
||||
"Tcl and Tk are distributed under a modified BSD license: "
|
||||
"www.tcl.tk/software/tcltk/license.html\n\n"
|
||||
"%1$C 1987-%2$@ Tcl Core Team and Contributers.\n\n"
|
||||
"%1$C 2011-%2$@ Kevin Walzer/WordTech Communications LLC.\n\n"
|
||||
"%1$C 2014-%2$@ Marc Culler.\n\n"
|
||||
"%1$C 2002-2012 Daniel A. Steffen.\n\n"
|
||||
"%1$C 2001-2009 Apple Inc.\n\n"
|
||||
"%1$C 2001-2002 Jim Ingham & Ian Reid\n\n"
|
||||
"%1$C 1998-2000 Jim Ingham & Ray Johnson\n\n"
|
||||
"%1$C 1998-2000 Scriptics Inc.\n\n"
|
||||
"%1$C 1996-1997 Sun Microsystems Inc.", 0xA9, year]
|
||||
attributes:textAttributes]
|
||||
replacementRange:NSMakeRange(0,0)];
|
||||
[credits setDrawsBackground:NO];
|
||||
[credits setEditable:NO];
|
||||
|
||||
NSAlert *about = [[NSAlert alloc] init];
|
||||
|
||||
[[about window] setTitle:@"About Tcl & Tk"];
|
||||
[about setMessageText: version];
|
||||
[about setInformativeText:url];
|
||||
about.accessoryView = credits;
|
||||
[about runModal];
|
||||
[about release];
|
||||
[NSApp orderFrontStandardAboutPanel:nil];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -1359,7 +1336,7 @@ TkAboutDlg(void)
|
||||
|
||||
int
|
||||
TkMacOSXStandardAboutPanelObjCmd(
|
||||
ClientData clientData, /* Unused. */
|
||||
TCL_UNUSED(void *),
|
||||
Tcl_Interp *interp, /* Current interpreter. */
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
@@ -1368,7 +1345,7 @@ TkMacOSXStandardAboutPanelObjCmd(
|
||||
Tcl_WrongNumArgs(interp, 1, objv, NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
TkAboutDlg();
|
||||
[NSApp orderFrontStandardAboutPanel:nil];
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -1395,7 +1372,7 @@ Tk_MessageBoxObjCmd(
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
{
|
||||
Tk_Window tkwin = clientData;
|
||||
Tk_Window tkwin = (Tk_Window)clientData;
|
||||
char *str;
|
||||
int i, result = TCL_ERROR, haveParentOption = 0;
|
||||
int index, typeIndex, iconIndex, indexDefaultOption = 0;
|
||||
@@ -1529,11 +1506,11 @@ Tk_MessageBoxObjCmd(
|
||||
}
|
||||
Tcl_IncrRefCount(cmdObj);
|
||||
}
|
||||
callbackInfo = ckalloc(sizeof(AlertCallbackInfo));
|
||||
callbackInfo = (AlertCallbackInfo *)ckalloc(sizeof(AlertCallbackInfo));
|
||||
callbackInfo->cmdObj = cmdObj;
|
||||
callbackInfo->interp = interp;
|
||||
callbackInfo->typeIndex = typeIndex;
|
||||
parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
|
||||
parent = TkMacOSXGetNSWindowForDrawable(((TkWindow *)tkwin)->window);
|
||||
if (haveParentOption && parent && ![parent attachedSheet]) {
|
||||
parentIsKey = [parent isKeyWindow];
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
|
||||
@@ -1630,6 +1607,7 @@ enum FontchooserOption {
|
||||
- (void) changeFont: (id) sender
|
||||
{
|
||||
NSFontManager *fm = [NSFontManager sharedFontManager];
|
||||
(void)sender;
|
||||
|
||||
if ([fm currentFontAction] == NSViaPanelFontAction) {
|
||||
NSFont *font = [fm convertFont:fontPanelFont];
|
||||
@@ -1653,14 +1631,16 @@ enum FontchooserOption {
|
||||
}
|
||||
}
|
||||
|
||||
- (NSUInteger) validModesForFontPanel: (NSFontPanel *) fontPanel
|
||||
- (NSUInteger) validModesForFontPanel: (NSFontPanel *)fontPanel
|
||||
{
|
||||
(void)fontPanel;
|
||||
|
||||
return (NSFontPanelStandardModesMask & ~NSFontPanelAllEffectsModeMask) |
|
||||
NSFontPanelUnderlineEffectModeMask |
|
||||
NSFontPanelStrikethroughEffectModeMask;
|
||||
}
|
||||
|
||||
- (void) windowDidOrderOffScreen: (NSNotification *) notification
|
||||
- (void) windowDidOrderOffScreen: (NSNotification *)notification
|
||||
{
|
||||
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
|
||||
TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
|
||||
@@ -1684,7 +1664,7 @@ enum FontchooserOption {
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Additional events may be place on the Tk event queue.
|
||||
* Additional events may be placed on the Tk event queue.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
@@ -1718,7 +1698,7 @@ FontchooserEvent(
|
||||
result = Tcl_ListObjGetElements(fontchooserInterp,
|
||||
fcdPtr->cmdObj, &objc, &objv);
|
||||
if (result == TCL_OK) {
|
||||
tmpv = ckalloc(sizeof(Tcl_Obj *) * (objc + 2));
|
||||
tmpv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * (objc + 2));
|
||||
memcpy(tmpv, objv, sizeof(Tcl_Obj *) * objc);
|
||||
tmpv[objc] = fontObj;
|
||||
TkBackgroundEvalObjv(fontchooserInterp, objc + 1, tmpv,
|
||||
@@ -1760,7 +1740,7 @@ FontchooserCget(
|
||||
case FontchooserParent:
|
||||
if (fcdPtr->parent != None) {
|
||||
resObj = Tcl_NewStringObj(
|
||||
((TkWindow *) fcdPtr->parent)->pathName, -1);
|
||||
((TkWindow *)fcdPtr->parent)->pathName, -1);
|
||||
} else {
|
||||
resObj = Tcl_NewStringObj(".", 1);
|
||||
}
|
||||
@@ -1981,14 +1961,14 @@ static int
|
||||
FontchooserShowCmd(
|
||||
ClientData clientData, /* Main window */
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *const objv[])
|
||||
TCL_UNUSED(int),
|
||||
TCL_UNUSED(Tcl_Obj *const *))
|
||||
{
|
||||
FontchooserData *fcdPtr = Tcl_GetAssocData(interp, "::tk::fontchooser",
|
||||
NULL);
|
||||
|
||||
if (fcdPtr->parent == None) {
|
||||
fcdPtr->parent = (Tk_Window) clientData;
|
||||
fcdPtr->parent = (Tk_Window)clientData;
|
||||
Tk_CreateEventHandler(fcdPtr->parent, StructureNotifyMask,
|
||||
FontchooserParentEventHandler, fcdPtr);
|
||||
}
|
||||
@@ -2027,10 +2007,10 @@ FontchooserShowCmd(
|
||||
|
||||
static int
|
||||
FontchooserHideCmd(
|
||||
ClientData clientData, /* Main window */
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *const objv[])
|
||||
TCL_UNUSED(void *), /* Main window */
|
||||
TCL_UNUSED(Tcl_Interp *),
|
||||
TCL_UNUSED(int),
|
||||
TCL_UNUSED(Tcl_Obj *const *))
|
||||
{
|
||||
NSFontPanel *fp = [[NSFontManager sharedFontManager] fontPanel:NO];
|
||||
|
||||
@@ -2129,9 +2109,9 @@ DeleteFontchooserData(
|
||||
MODULE_SCOPE int
|
||||
TkInitFontchooser(
|
||||
Tcl_Interp *interp,
|
||||
ClientData clientData)
|
||||
TCL_UNUSED(void *))
|
||||
{
|
||||
FontchooserData *fcdPtr = ckalloc(sizeof(FontchooserData));
|
||||
FontchooserData *fcdPtr = (FontchooserData *)ckalloc(sizeof(FontchooserData));
|
||||
|
||||
bzero(fcdPtr, sizeof(FontchooserData));
|
||||
Tcl_SetAssocData(interp, "::tk::fontchooser", DeleteFontchooserData,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -446,7 +446,7 @@ TkMacOSXContainerId(
|
||||
for (containerPtr = firstContainerPtr; containerPtr != NULL;
|
||||
containerPtr = containerPtr->nextPtr) {
|
||||
if (containerPtr->embeddedPtr == winPtr) {
|
||||
return (MacDrawable *) containerPtr->parent;
|
||||
return (MacDrawable *)containerPtr->parent;
|
||||
}
|
||||
}
|
||||
Tcl_Panic("TkMacOSXContainerId couldn't find window");
|
||||
@@ -853,7 +853,7 @@ ContainerEventProc(
|
||||
* Here we are following unix, by destroying the container.
|
||||
*/
|
||||
|
||||
Tk_DestroyWindow((Tk_Window) winPtr);
|
||||
Tk_DestroyWindow((Tk_Window)winPtr);
|
||||
}
|
||||
Tk_DeleteErrorHandler(errHandler);
|
||||
}
|
||||
@@ -902,8 +902,8 @@ EmbedStructureProc(
|
||||
|
||||
errHandler = Tk_CreateErrorHandler(eventPtr->xfocus.display, -1,
|
||||
-1, -1, NULL, NULL);
|
||||
Tk_MoveResizeWindow((Tk_Window) containerPtr->embeddedPtr, 0, 0,
|
||||
(unsigned) Tk_Width((Tk_Window) containerPtr->parentPtr),
|
||||
Tk_MoveResizeWindow((Tk_Window)containerPtr->embeddedPtr, 0, 0,
|
||||
(unsigned) Tk_Width((Tk_Window)containerPtr->parentPtr),
|
||||
(unsigned) Tk_Height((Tk_Window)containerPtr->parentPtr));
|
||||
Tk_DeleteErrorHandler(errHandler);
|
||||
}
|
||||
@@ -1048,10 +1048,8 @@ EmbedGeometryRequest(
|
||||
* if the window's size didn't change then generate a configure event.
|
||||
*/
|
||||
|
||||
Tk_GeometryRequest((Tk_Window) winPtr, width, height);
|
||||
while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {
|
||||
/* Empty loop body. */
|
||||
}
|
||||
Tk_GeometryRequest((Tk_Window)winPtr, width, height);
|
||||
while (Tcl_DoOneEvent(TCL_IDLE_EVENTS|TCL_TIMER_EVENTS|TCL_DONT_WAIT)) {}
|
||||
if ((winPtr->changes.width != width)
|
||||
|| (winPtr->changes.height != height)) {
|
||||
EmbedSendConfigure(containerPtr);
|
||||
|
||||
@@ -92,7 +92,7 @@ TkpDrawEntryBorderAndFocus(
|
||||
GC bgGC;
|
||||
Tk_Window tkwin = entryPtr->tkwin;
|
||||
int oldWidth = 0;
|
||||
MacDrawable *macDraw = (MacDrawable *) d;
|
||||
MacDrawable *macDraw = (MacDrawable *)d;
|
||||
const HIThemeFrameDrawInfo info = {
|
||||
.version = 0,
|
||||
.kind = kHIThemeFrameTextFieldSquare,
|
||||
@@ -155,7 +155,7 @@ TkpDrawEntryBorderAndFocus(
|
||||
bounds.origin.y = macDraw->yOff + MAC_OSX_FOCUS_WIDTH;
|
||||
bounds.size.width = Tk_Width(tkwin) - 2*MAC_OSX_FOCUS_WIDTH;
|
||||
bounds.size.height = Tk_Height(tkwin) - 2*MAC_OSX_FOCUS_WIDTH;
|
||||
if (!TkMacOSXSetupDrawingContext(d, NULL, 1, &dc)) {
|
||||
if (!TkMacOSXSetupDrawingContext(d, NULL, &dc)) {
|
||||
|
||||
/*
|
||||
* No graphics context is available. If the widget is a Spinbox, we
|
||||
@@ -208,7 +208,7 @@ TkpDrawSpinboxButtons(
|
||||
TkMacOSXDrawingContext dc;
|
||||
XRectangle rects[1];
|
||||
GC bgGC;
|
||||
MacDrawable *macDraw = (MacDrawable *) d;
|
||||
MacDrawable *macDraw = (MacDrawable *)d;
|
||||
HIThemeButtonDrawInfo info = {
|
||||
.version = 0,
|
||||
.adornment = kThemeAdornmentNone,
|
||||
@@ -265,7 +265,7 @@ TkpDrawSpinboxButtons(
|
||||
rects[0].height = Tk_Height(tkwin);
|
||||
XFillRectangles(Tk_Display(tkwin), d, bgGC, rects, 1);
|
||||
|
||||
if (!TkMacOSXSetupDrawingContext(d, NULL, 1, &dc)) {
|
||||
if (!TkMacOSXSetupDrawingContext(d, NULL, &dc)) {
|
||||
return 0;
|
||||
}
|
||||
ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation, NULL);
|
||||
|
||||
@@ -104,43 +104,8 @@ enum {
|
||||
return processedEvent;
|
||||
}
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TkMacOSXFlushWindows --
|
||||
*
|
||||
* This routine is a stub called by XSync, which is called during the Tk
|
||||
* update command. The language specification does not require that the
|
||||
* update command be synchronous but many of the tests implicitly assume
|
||||
* that it is. It is definitely asynchronous on macOS since many idle
|
||||
* tasks are run inside of the drawRect method of a window's contentView,
|
||||
* which will not be called until after this function returns.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects: Processes all pending idle events then calls the display
|
||||
* method of each visible window.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
MODULE_SCOPE void
|
||||
TkMacOSXFlushWindows(void)
|
||||
{
|
||||
if (Tk_GetNumMainWindows() == 0) {
|
||||
return;
|
||||
}
|
||||
while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)){}
|
||||
for (NSWindow *w in [NSApp orderedWindows]) {
|
||||
[w display];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: objc
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#include "tkMacOSXInt.h"
|
||||
#endif
|
||||
|
||||
MODULE_SCOPE void TkMacOSXFlushWindows(void);
|
||||
/*
|
||||
* Currently nothing needs to be declared here.
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
@@ -56,25 +56,25 @@ struct SystemFontMapEntry {
|
||||
#define ThemeFont(n, ...) { kTheme##n##Font, "system" #n "Font", ##__VA_ARGS__ }
|
||||
static const struct SystemFontMapEntry systemFontMap[] = {
|
||||
ThemeFont(System, "TkDefaultFont", "TkIconFont"),
|
||||
ThemeFont(EmphasizedSystem, "TkCaptionFont"),
|
||||
ThemeFont(EmphasizedSystem, "TkCaptionFont", NULL),
|
||||
ThemeFont(SmallSystem, "TkHeadingFont", "TkTooltipFont"),
|
||||
ThemeFont(SmallEmphasizedSystem),
|
||||
ThemeFont(Application, "TkTextFont"),
|
||||
ThemeFont(Label, "TkSmallCaptionFont"),
|
||||
ThemeFont(Views),
|
||||
ThemeFont(MenuTitle),
|
||||
ThemeFont(MenuItem, "TkMenuFont"),
|
||||
ThemeFont(MenuItemMark),
|
||||
ThemeFont(MenuItemCmdKey),
|
||||
ThemeFont(WindowTitle),
|
||||
ThemeFont(PushButton),
|
||||
ThemeFont(UtilityWindowTitle),
|
||||
ThemeFont(AlertHeader),
|
||||
ThemeFont(Toolbar),
|
||||
ThemeFont(MiniSystem),
|
||||
{ kThemeSystemFontDetail, "systemDetailSystemFont" },
|
||||
{ kThemeSystemFontDetailEmphasized, "systemDetailEmphasizedSystemFont" },
|
||||
{ -1, NULL }
|
||||
ThemeFont(SmallEmphasizedSystem, NULL, NULL),
|
||||
ThemeFont(Application, "TkTextFont", NULL),
|
||||
ThemeFont(Label, "TkSmallCaptionFont", NULL),
|
||||
ThemeFont(Views, NULL, NULL),
|
||||
ThemeFont(MenuTitle, NULL, NULL),
|
||||
ThemeFont(MenuItem, "TkMenuFont", NULL),
|
||||
ThemeFont(MenuItemMark, NULL, NULL),
|
||||
ThemeFont(MenuItemCmdKey, NULL, NULL),
|
||||
ThemeFont(WindowTitle, NULL, NULL),
|
||||
ThemeFont(PushButton, NULL, NULL),
|
||||
ThemeFont(UtilityWindowTitle, NULL, NULL),
|
||||
ThemeFont(AlertHeader, NULL, NULL),
|
||||
ThemeFont(Toolbar, NULL, NULL),
|
||||
ThemeFont(MiniSystem, NULL, NULL),
|
||||
{ kThemeSystemFontDetail, "systemDetailSystemFont", NULL, NULL },
|
||||
{ kThemeSystemFontDetailEmphasized, "systemDetailEmphasizedSystemFont", NULL, NULL },
|
||||
{ -1, NULL, NULL, NULL }
|
||||
};
|
||||
#undef ThemeFont
|
||||
|
||||
@@ -93,155 +93,89 @@ static void InitFont(NSFont *nsFont,
|
||||
static int CreateNamedSystemFont(Tcl_Interp *interp,
|
||||
Tk_Window tkwin, const char *name,
|
||||
TkFontAttributes *faPtr);
|
||||
static void DrawCharsInContext(Display *display, Drawable drawable,
|
||||
GC gc, Tk_Font tkfont, const char *source,
|
||||
int numBytes, int rangeStart, int rangeLength,
|
||||
int x, int y, double angle);
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Font Helpers:
|
||||
|
||||
/*
|
||||
*---------------------------------------------------------------------------
|
||||
*
|
||||
* TclUniToNSString --
|
||||
*
|
||||
* When Tcl is compiled with TCL_UTF_MAX = 3 (the default for 8.6) it cannot
|
||||
* deal directly with UTF-8 encoded non-BMP characters, since their UTF-8
|
||||
* encoding requires 4 bytes.
|
||||
*
|
||||
* As a workaround, these versions of Tcl encode non-BMP characters as a string
|
||||
* of length 6 in which the high and low UTF-16 surrogates have been encoded
|
||||
* using the UTF-8 algorithm. The UTF-8 encoding does not allow encoding
|
||||
* surrogates, so these 6-byte strings are not valid UTF-8, and hence Apple's
|
||||
* NString class will refuse to instantiate an NSString from the 6-byte
|
||||
* encoding. This function allows creating an NSString from a C-string which
|
||||
* has been encoded using this scheme.
|
||||
*
|
||||
* Results:
|
||||
* An NSString, which may be nil.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*---------------------------------------------------------------------------
|
||||
* To avoid an extra copy, a TKNSString object wraps a Tcl_DString with an
|
||||
* NSString that uses the DString's buffer as its character buffer. It can be
|
||||
* constructed from a Tcl_DString and it has a DString property that handles
|
||||
* converting from an NSString to a Tcl_DString.
|
||||
*/
|
||||
|
||||
MODULE_SCOPE NSString*
|
||||
TclUniToNSString(
|
||||
const char *source,
|
||||
int numBytes)
|
||||
@implementation TKNSString
|
||||
|
||||
- (instancetype)initWithTclUtfBytes:(const void *)bytes
|
||||
length:(NSUInteger)len
|
||||
{
|
||||
NSString *string = [[NSString alloc] initWithBytesNoCopy:(void *)source
|
||||
length:numBytes
|
||||
encoding:NSUTF8StringEncoding
|
||||
freeWhenDone:NO];
|
||||
if (!string) {
|
||||
const unichar *characters = ckalloc(numBytes*sizeof(unichar));
|
||||
const char *in = source;
|
||||
unichar *out = (unichar *) characters;
|
||||
while (in < source + numBytes) {
|
||||
in += Tcl_UtfToUniChar(in, out++);
|
||||
self = [self init];
|
||||
if (self) {
|
||||
Tcl_DStringInit(&_ds);
|
||||
Tcl_UtfToUniCharDString(bytes, len, &_ds);
|
||||
_string = [[NSString alloc]
|
||||
initWithCharactersNoCopy:(unichar *)Tcl_DStringValue(&_ds)
|
||||
length:Tcl_DStringLength(&_ds)>>1
|
||||
freeWhenDone:NO];
|
||||
self.UTF8String = _string.UTF8String;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithString:(NSString *)aString
|
||||
{
|
||||
self = [self init];
|
||||
if (self) {
|
||||
_string = [[NSString alloc] initWithString:aString];
|
||||
_UTF8String = _string.UTF8String;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
Tcl_DStringFree(&_ds);
|
||||
[_string release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSUInteger)length
|
||||
{
|
||||
return _string.length;
|
||||
}
|
||||
|
||||
- (unichar)characterAtIndex:(NSUInteger)index
|
||||
{
|
||||
return [_string characterAtIndex:index];
|
||||
}
|
||||
|
||||
- (Tcl_DString)DString
|
||||
{
|
||||
if ( _ds.string == NULL) {
|
||||
|
||||
/*
|
||||
* The DString has not been initialized. Construct it from
|
||||
* our string's unicode characters.
|
||||
*/
|
||||
char *p;
|
||||
NSUInteger index;
|
||||
|
||||
Tcl_DStringInit(&_ds);
|
||||
Tcl_DStringSetLength(&_ds, 3 * [_string length]);
|
||||
p = Tcl_DStringValue(&_ds);
|
||||
for (index = 0; index < [_string length]; index++) {
|
||||
p += Tcl_UniCharToUtf([_string characterAtIndex: index], p);
|
||||
}
|
||||
string = [[NSString alloc] initWithCharacters:characters
|
||||
length:(out - characters)];
|
||||
ckfree(characters);
|
||||
Tcl_DStringSetLength(&_ds, p - Tcl_DStringValue(&_ds));
|
||||
}
|
||||
return string;
|
||||
return _ds;
|
||||
}
|
||||
|
||||
/*
|
||||
*---------------------------------------------------------------------------
|
||||
*
|
||||
* TclUniAtIndex --
|
||||
*
|
||||
* Write a sequence of bytes up to length 6 which is an encoding of a UTF-16
|
||||
* character in an NSString. Also record the unicode code point of the character.
|
||||
* this may be a non-BMP character constructed by reading two surrogates from
|
||||
* the NSString.
|
||||
*
|
||||
* Results:
|
||||
* Returns the number of bytes written.
|
||||
*
|
||||
* Side effects:
|
||||
* Bytes are written to the char array referenced by the pointer uni and
|
||||
* the unicode code point is written to the integer referenced by the
|
||||
* pointer code.
|
||||
*
|
||||
*/
|
||||
|
||||
MODULE_SCOPE int
|
||||
TclUniAtIndex(
|
||||
NSString *string,
|
||||
int index,
|
||||
char *uni,
|
||||
unsigned int *code)
|
||||
{
|
||||
char *ptr = uni;
|
||||
UniChar uniChar = [string characterAtIndex: index];
|
||||
if (CFStringIsSurrogateHighCharacter(uniChar)) {
|
||||
UniChar lowChar = [string characterAtIndex: ++index];
|
||||
*code = CFStringGetLongCharacterForSurrogatePair(
|
||||
uniChar, lowChar);
|
||||
ptr += Tcl_UniCharToUtf(uniChar, ptr);
|
||||
ptr += Tcl_UniCharToUtf(lowChar, ptr);
|
||||
return ptr - uni;
|
||||
} else {
|
||||
*code = (int) uniChar;
|
||||
[[string substringWithRange: NSMakeRange(index, 1)]
|
||||
getCString: uni
|
||||
maxLength: XMaxTransChars
|
||||
encoding: NSUTF8StringEncoding];
|
||||
return strlen(uni);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*---------------------------------------------------------------------------
|
||||
*
|
||||
* NSStringToTclUni --
|
||||
*
|
||||
* Encodes the unicode string represented by an NSString object with the
|
||||
* internal encoding that Tcl uses when TCL_UTF_MAX = 3. This encoding
|
||||
* is similar to UTF-8 except that non-BMP characters are encoded as two
|
||||
* successive 3-byte sequences which are constructed from UTF-16 surrogates
|
||||
* by applying the UTF-8 algorithm. Even though the UTF-8 encoding does not
|
||||
* allow encoding surrogates, the algorithm does produce a well-defined
|
||||
* 3-byte sequence.
|
||||
*
|
||||
* Results:
|
||||
* Returns a pointer to a null-terminated byte array which encodes the
|
||||
* NSString.
|
||||
*
|
||||
* Side effects:
|
||||
* Memory is allocated to hold the byte array, which must be freed with
|
||||
* ckalloc. If the pointer numBytes is not NULL the number of non-null
|
||||
* bytes written to the array is stored in the integer it references.
|
||||
*/
|
||||
|
||||
MODULE_SCOPE char*
|
||||
NSStringToTclUni(
|
||||
NSString *string,
|
||||
int *numBytes)
|
||||
{
|
||||
unsigned int code;
|
||||
int i;
|
||||
char *ptr, *bytes = ckalloc(6*[string length] + 1);
|
||||
|
||||
ptr = bytes;
|
||||
if (ptr) {
|
||||
for (i = 0; i < [string length]; i++) {
|
||||
ptr += TclUniAtIndex(string, i, ptr, &code);
|
||||
if (code > 0xffff){
|
||||
i++;
|
||||
}
|
||||
}
|
||||
*ptr = '\0';
|
||||
}
|
||||
if (numBytes) {
|
||||
*numBytes = ptr - bytes;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
#ifndef __clang__
|
||||
@synthesize UTF8String = _UTF8String;
|
||||
@synthesize DString = _ds;
|
||||
#endif
|
||||
@end
|
||||
|
||||
#define GetNSFontTraitsFromTkFontAttributes(faPtr) \
|
||||
((faPtr)->weight == TK_FW_BOLD ? NSBoldFontMask : NSUnboldFontMask) | \
|
||||
@@ -514,7 +448,7 @@ TkpFontPkgInit(
|
||||
TkMainInfo *mainPtr) /* The application being created. */
|
||||
{
|
||||
Tcl_Interp *interp = mainPtr->interp;
|
||||
Tk_Window tkwin = (Tk_Window) mainPtr->winPtr;
|
||||
Tk_Window tkwin = (Tk_Window)mainPtr->winPtr;
|
||||
const struct SystemFontMapEntry *systemFont = systemFontMap;
|
||||
NSFont *nsFont;
|
||||
TkFontAttributes fa;
|
||||
@@ -613,7 +547,7 @@ TkpFontPkgInit(
|
||||
|
||||
TkFont *
|
||||
TkpGetNativeFont(
|
||||
Tk_Window tkwin, /* For display where font will be used. */
|
||||
TCL_UNUSED(Tk_Window), /* For display where font will be used. */
|
||||
const char *name) /* Platform-specific font name. */
|
||||
{
|
||||
MacFont *fontPtr = NULL;
|
||||
@@ -632,7 +566,7 @@ TkpGetNativeFont(
|
||||
ctFont = CTFontCreateUIFontForLanguage(
|
||||
HIThemeGetUIFontType(themeFontId), 0, NULL);
|
||||
if (ctFont) {
|
||||
fontPtr = ckalloc(sizeof(MacFont));
|
||||
fontPtr = (MacFont *)ckalloc(sizeof(MacFont));
|
||||
InitFont((NSFont*) ctFont, NULL, fontPtr);
|
||||
}
|
||||
|
||||
@@ -700,7 +634,7 @@ TkpGetFontFromAttributes(
|
||||
Tcl_Panic("Could not determine NSFont from TkFontAttributes");
|
||||
}
|
||||
if (tkFontPtr == NULL) {
|
||||
fontPtr = ckalloc(sizeof(MacFont));
|
||||
fontPtr = (MacFont *)ckalloc(sizeof(MacFont));
|
||||
} else {
|
||||
fontPtr = (MacFont *) tkFontPtr;
|
||||
TkpDeleteFont(tkFontPtr);
|
||||
@@ -762,7 +696,7 @@ TkpDeleteFont(
|
||||
void
|
||||
TkpGetFontFamilies(
|
||||
Tcl_Interp *interp, /* Interp to hold result. */
|
||||
Tk_Window tkwin) /* For display to query. */
|
||||
TCL_UNUSED(Tk_Window)) /* For display to query. */
|
||||
{
|
||||
Tcl_Obj *resultPtr = Tcl_NewListObj(0, NULL);
|
||||
NSArray *list = [[NSFontManager sharedFontManager] availableFontFamilies];
|
||||
@@ -835,7 +769,7 @@ TkpGetSubFonts(
|
||||
|
||||
void
|
||||
TkpGetFontAttrsForChar(
|
||||
Tk_Window tkwin, /* Window on the font's display */
|
||||
TCL_UNUSED(Tk_Window), /* Window on the font's display */
|
||||
Tk_Font tkfont, /* Font to query */
|
||||
int c, /* Character of interest */
|
||||
TkFontAttributes* faPtr) /* Output: Font attributes */
|
||||
@@ -986,7 +920,7 @@ TkpMeasureCharsInContext(
|
||||
if (maxLength > 32767) {
|
||||
maxLength = 32767;
|
||||
}
|
||||
string = TclUniToNSString((const char *)source, numBytes);
|
||||
string = [[TKNSString alloc] initWithTclUtfBytes:source length:numBytes];
|
||||
if (!string) {
|
||||
length = 0;
|
||||
fit = rangeLength;
|
||||
@@ -1098,7 +1032,7 @@ TkpMeasureCharsInContext(
|
||||
[attributedString release];
|
||||
[string release];
|
||||
length = ceil(width - offset);
|
||||
fit = (Tcl_UtfAtIndex(source, index) - source) - rangeStart;
|
||||
fit = (TkUtfAtIndex(source, index) - source) - rangeStart;
|
||||
done:
|
||||
#ifdef TK_MAC_DEBUG_FONTS
|
||||
TkMacOSXDbgMsg("measure: source=\"%s\" range=\"%.*s\" maxLength=%d "
|
||||
@@ -1122,7 +1056,7 @@ done:
|
||||
* Draw a string of characters on the screen.
|
||||
*
|
||||
* With ATSUI we need the line context to do this right, so we have the
|
||||
* actual implementation in TkpDrawCharsInContext().
|
||||
* actual implementation in TkpDrawAngledCharsInContext().
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
@@ -1151,7 +1085,7 @@ Tk_DrawChars(
|
||||
int x, int y) /* Coordinates at which to place origin of the
|
||||
* string when drawing. */
|
||||
{
|
||||
DrawCharsInContext(display, drawable, gc, tkfont, source, numBytes,
|
||||
TkpDrawAngledCharsInContext(display, drawable, gc, tkfont, source, numBytes,
|
||||
0, numBytes, x, y, 0.0);
|
||||
}
|
||||
|
||||
@@ -1174,7 +1108,7 @@ TkDrawAngledChars(
|
||||
* string when drawing. */
|
||||
double angle) /* What angle to put text at, in degrees. */
|
||||
{
|
||||
DrawCharsInContext(display, drawable, gc, tkfont, source, numBytes,
|
||||
TkpDrawAngledCharsInContext(display, drawable, gc, tkfont, source, numBytes,
|
||||
0, numBytes, x, y, angle);
|
||||
}
|
||||
|
||||
@@ -1219,13 +1153,13 @@ TkpDrawCharsInContext(
|
||||
* whole (not just the range) string when
|
||||
* drawing. */
|
||||
{
|
||||
DrawCharsInContext(display, drawable, gc, tkfont, source, numBytes,
|
||||
TkpDrawAngledCharsInContext(display, drawable, gc, tkfont, source, numBytes,
|
||||
rangeStart, rangeLength, x, y, 0.0);
|
||||
}
|
||||
|
||||
static void
|
||||
DrawCharsInContext(
|
||||
Display *display, /* Display on which to draw. */
|
||||
void
|
||||
TkpDrawAngledCharsInContext(
|
||||
TCL_UNUSED(Display *), /* Display on which to draw. */
|
||||
Drawable drawable, /* Window or pixmap in which to draw. */
|
||||
GC gc, /* Graphics context for drawing characters. */
|
||||
Tk_Font tkfont, /* Font in which characters will be drawn; must
|
||||
@@ -1240,71 +1174,77 @@ DrawCharsInContext(
|
||||
int numBytes, /* Number of bytes in string. */
|
||||
int rangeStart, /* Index of first byte to draw. */
|
||||
int rangeLength, /* Length of range to draw in bytes. */
|
||||
int x, int y, /* Coordinates at which to place origin of the
|
||||
double x, double y, /* Coordinates at which to place origin of the
|
||||
* whole (not just the range) string when
|
||||
* drawing. */
|
||||
double angle)
|
||||
double angle) /* What angle to put text at, in degrees. */
|
||||
{
|
||||
const MacFont *fontPtr = (const MacFont *) tkfont;
|
||||
NSString *string;
|
||||
NSMutableDictionary *attributes;
|
||||
NSAttributedString *attributedString;
|
||||
CTTypesetterRef typesetter;
|
||||
CFIndex start, len;
|
||||
CTLineRef line;
|
||||
MacDrawable *macWin = (MacDrawable *) drawable;
|
||||
CFIndex start, length;
|
||||
CTLineRef line, full=nil;
|
||||
MacDrawable *macWin = (MacDrawable *)drawable;
|
||||
TkMacOSXDrawingContext drawingContext;
|
||||
CGContextRef context;
|
||||
CGColorRef fg;
|
||||
NSFont *nsFont;
|
||||
CGAffineTransform t;
|
||||
int h;
|
||||
CGFloat width, height, textX = (CGFloat) x, textY = (CGFloat) y;
|
||||
|
||||
if (rangeStart < 0 || rangeLength <= 0 ||
|
||||
rangeStart + rangeLength > numBytes ||
|
||||
!TkMacOSXSetupDrawingContext(drawable, gc, 1, &drawingContext)) {
|
||||
if (rangeStart < 0 || rangeLength <= 0 ||
|
||||
rangeStart + rangeLength > numBytes ||
|
||||
!TkMacOSXSetupDrawingContext(drawable, gc, &drawingContext)) {
|
||||
return;
|
||||
}
|
||||
string = TclUniToNSString((const char *)source, numBytes);
|
||||
string = [[TKNSString alloc] initWithTclUtfBytes:source length:numBytes];
|
||||
if (!string) {
|
||||
return;
|
||||
}
|
||||
|
||||
context = drawingContext.context;
|
||||
fg = TkMacOSXCreateCGColor(gc, gc->foreground);
|
||||
TkSetMacColor(gc->foreground, &fg);
|
||||
attributes = [fontPtr->nsAttributes mutableCopy];
|
||||
[attributes setObject:(id)fg forKey:(id)kCTForegroundColorAttributeName];
|
||||
CFRelease(fg);
|
||||
nsFont = [attributes objectForKey:NSFontAttributeName];
|
||||
[nsFont setInContext:[NSGraphicsContext graphicsContextWithGraphicsPort:
|
||||
context flipped:NO]];
|
||||
[nsFont setInContext:GET_NSCONTEXT(context, NO)];
|
||||
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
|
||||
attributedString = [[NSAttributedString alloc] initWithString:string
|
||||
attributes:attributes];
|
||||
typesetter = CTTypesetterCreateWithAttributedString(
|
||||
(CFAttributedStringRef)attributedString);
|
||||
x += macWin->xOff;
|
||||
y += macWin->yOff;
|
||||
h = drawingContext.portBounds.size.height;
|
||||
y = h - y;
|
||||
t = CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0.0, h);
|
||||
textX += (CGFloat) macWin->xOff;
|
||||
textY += (CGFloat) macWin->yOff;
|
||||
height = drawingContext.portBounds.size.height;
|
||||
textY = height - textY;
|
||||
t = CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0.0, height);
|
||||
if (angle != 0.0) {
|
||||
t = CGAffineTransformTranslate(CGAffineTransformRotate(
|
||||
CGAffineTransformTranslate(t, x, y), angle*PI/180.0), -x, -y);
|
||||
t = CGAffineTransformTranslate(
|
||||
CGAffineTransformRotate(
|
||||
CGAffineTransformTranslate(t, textX, textY), angle*PI/180.0),
|
||||
-textX, -textY);
|
||||
}
|
||||
CGContextConcatCTM(context, t);
|
||||
CGContextSetTextPosition(context, x, y);
|
||||
start = Tcl_NumUtfChars(source, rangeStart);
|
||||
len = Tcl_NumUtfChars(source, rangeStart + rangeLength);
|
||||
length = Tcl_NumUtfChars(source, rangeStart + rangeLength) - start;
|
||||
line = CTTypesetterCreateLine(typesetter, CFRangeMake(start, length));
|
||||
if (start > 0) {
|
||||
CGRect clipRect = CGRectInfinite, startBounds;
|
||||
|
||||
line = CTTypesetterCreateLine(typesetter, CFRangeMake(0, start));
|
||||
startBounds = CTLineGetImageBounds(line, context);
|
||||
CFRelease(line);
|
||||
clipRect.origin.x = startBounds.origin.x + startBounds.size.width;
|
||||
CGContextClipToRect(context, clipRect);
|
||||
/*
|
||||
* We are only drawing part of the string. To compute the x coordinate
|
||||
* of the part we are drawing we subtract its typographical length from
|
||||
* the typographical length of the full string. This accounts for the
|
||||
* kerning after the initial part of the string.
|
||||
*/
|
||||
|
||||
full = CTTypesetterCreateLine(typesetter, CFRangeMake(0, start + length));
|
||||
width = CTLineGetTypographicBounds(full, NULL, NULL, NULL);
|
||||
CFRelease(full);
|
||||
textX += (width - CTLineGetTypographicBounds(line, NULL, NULL, NULL));
|
||||
}
|
||||
line = CTTypesetterCreateLine(typesetter, CFRangeMake(0, len));
|
||||
CGContextSetTextPosition(context, textX, textY);
|
||||
CTLineDraw(line, context);
|
||||
CFRelease(line);
|
||||
CFRelease(typesetter);
|
||||
@@ -1382,8 +1322,8 @@ TkMacOSXNSFontAttributesForFont(
|
||||
|
||||
int
|
||||
TkMacOSXIsCharacterMissing(
|
||||
Tk_Font tkfont, /* The font we are looking in. */
|
||||
unsigned int searchChar) /* The character we are looking for. */
|
||||
TCL_UNUSED(Tk_Font), /* The font we are looking in. */
|
||||
TCL_UNUSED(unsigned int)) /* The character we are looking for. */
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -1422,8 +1362,8 @@ TkMacOSXFontDescriptionForNSFontAndNSFontAttributes(
|
||||
NSStrikethroughStyleAttributeName];
|
||||
|
||||
objv[i++] = Tcl_NewStringObj(familyName, -1);
|
||||
objv[i++] = Tcl_NewIntObj([nsFont pointSize]);
|
||||
#define S(s) Tcl_NewStringObj(STRINGIFY(s),(int)(sizeof(STRINGIFY(s))-1))
|
||||
objv[i++] = Tcl_NewWideIntObj([nsFont pointSize]);
|
||||
#define S(s) Tcl_NewStringObj(STRINGIFY(s), (sizeof(STRINGIFY(s))-1))
|
||||
objv[i++] = (traits & NSBoldFontMask) ? S(bold) : S(normal);
|
||||
objv[i++] = (traits & NSItalicFontMask) ? S(italic) : S(roman);
|
||||
if ([underline respondsToSelector:@selector(intValue)] &&
|
||||
|
||||
@@ -39,6 +39,7 @@ typedef struct AppleEventInfo {
|
||||
const char *procedure;
|
||||
Tcl_DString command;
|
||||
NSAppleEventDescriptor *replyEvent; /* Only used for DoScriptText. */
|
||||
int retryCount;
|
||||
} AppleEventInfo;
|
||||
|
||||
/*
|
||||
@@ -67,6 +68,11 @@ static const char *scriptTextProc = "::tk::mac::DoScriptText";
|
||||
[self handleQuitApplicationEvent:Nil withReplyEvent:Nil];
|
||||
}
|
||||
|
||||
- (void) superTerminate: (id) sender
|
||||
{
|
||||
[super terminate:nil];
|
||||
}
|
||||
|
||||
- (void) preferences: (id) sender
|
||||
{
|
||||
[self handleShowPreferencesEvent:Nil withReplyEvent:Nil];
|
||||
@@ -148,6 +154,7 @@ static const char *scriptTextProc = "::tk::mac::DoScriptText";
|
||||
AEKeyword keyword;
|
||||
Tcl_DString pathName;
|
||||
|
||||
|
||||
/*
|
||||
* Do nothing if we don't have an interpreter.
|
||||
*/
|
||||
@@ -215,7 +222,13 @@ static const char *scriptTextProc = "::tk::mac::DoScriptText";
|
||||
AEInfo->interp = _eventInterp;
|
||||
AEInfo->procedure = openDocumentProc;
|
||||
AEInfo->replyEvent = nil;
|
||||
Tcl_DoWhenIdle(ProcessAppleEvent, (ClientData)AEInfo);
|
||||
AEInfo->retryCount = 0;
|
||||
|
||||
if (Tcl_FindCommand(_eventInterp, "::tk::mac::OpenDocuments", NULL, 0)){
|
||||
ProcessAppleEvent((ClientData)AEInfo);
|
||||
} else {
|
||||
Tcl_CreateTimerHandler(500, ProcessAppleEvent, (ClientData)AEInfo);
|
||||
}
|
||||
}
|
||||
|
||||
- (void) handlePrintDocumentsEvent: (NSAppleEventDescriptor *)event
|
||||
@@ -232,7 +245,8 @@ static const char *scriptTextProc = "::tk::mac::DoScriptText";
|
||||
AEInfo->interp = _eventInterp;
|
||||
AEInfo->procedure = printDocProc;
|
||||
AEInfo->replyEvent = nil;
|
||||
Tcl_DoWhenIdle(ProcessAppleEvent, (ClientData)AEInfo);
|
||||
AEInfo->retryCount = 0;
|
||||
ProcessAppleEvent((ClientData)AEInfo);
|
||||
}
|
||||
|
||||
- (void) handleDoScriptEvent: (NSAppleEventDescriptor *)event
|
||||
@@ -293,7 +307,8 @@ static const char *scriptTextProc = "::tk::mac::DoScriptText";
|
||||
AEInfo->interp = _eventInterp;
|
||||
AEInfo->procedure = scriptFileProc;
|
||||
AEInfo->replyEvent = nil;
|
||||
Tcl_DoWhenIdle(ProcessAppleEvent, (ClientData)AEInfo);
|
||||
AEInfo->retryCount = 0;
|
||||
ProcessAppleEvent((ClientData)AEInfo);
|
||||
}
|
||||
}
|
||||
} else if (noErr == AEGetParamPtr(theDesc, keyDirectObject, typeUTF8Text, &type,
|
||||
@@ -309,6 +324,7 @@ static const char *scriptTextProc = "::tk::mac::DoScriptText";
|
||||
if (noErr == AEGetParamPtr(theDesc, keyDirectObject,
|
||||
typeUTF8Text, &type,
|
||||
data, actual, NULL)) {
|
||||
data[actual] = '\0';
|
||||
AppleEventInfo *AEInfo = ckalloc(sizeof(AppleEventInfo));
|
||||
Tcl_DString *scriptTextCommand = &AEInfo->command;
|
||||
Tcl_DStringInit(scriptTextCommand);
|
||||
@@ -316,12 +332,13 @@ static const char *scriptTextProc = "::tk::mac::DoScriptText";
|
||||
Tcl_DStringAppendElement(scriptTextCommand, data);
|
||||
AEInfo->interp = _eventInterp;
|
||||
AEInfo->procedure = scriptTextProc;
|
||||
AEInfo->retryCount = 0;
|
||||
if (Tcl_FindCommand(AEInfo->interp, AEInfo->procedure, NULL, 0)) {
|
||||
AEInfo->replyEvent = replyEvent;
|
||||
ProcessAppleEvent((ClientData)AEInfo);
|
||||
} else {
|
||||
AEInfo->replyEvent = nil;
|
||||
Tcl_DoWhenIdle(ProcessAppleEvent, (ClientData)AEInfo);
|
||||
ProcessAppleEvent((ClientData)AEInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -342,7 +359,8 @@ static const char *scriptTextProc = "::tk::mac::DoScriptText";
|
||||
AEInfo->interp = _eventInterp;
|
||||
AEInfo->procedure = launchURLProc;
|
||||
AEInfo->replyEvent = nil;
|
||||
Tcl_DoWhenIdle(ProcessAppleEvent, (ClientData)AEInfo);
|
||||
AEInfo->retryCount = 0;
|
||||
ProcessAppleEvent((ClientData)AEInfo);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -377,15 +395,30 @@ static void ProcessAppleEvent(
|
||||
{
|
||||
int code;
|
||||
AppleEventInfo *AEInfo = (AppleEventInfo*) clientData;
|
||||
if (!AEInfo->interp ||
|
||||
!Tcl_FindCommand(AEInfo->interp, AEInfo->procedure, NULL, 0)) {
|
||||
|
||||
if (!AEInfo->interp) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Apple events that are delivered during the app startup can arrive
|
||||
* before the Tcl procedure for handling the events has been defined.
|
||||
* If the command is not found we create a timer handler to process
|
||||
* the event later, hopefully after the command has been created.
|
||||
* We retry up to 2 times before giving up.
|
||||
*/
|
||||
|
||||
if (!Tcl_FindCommand(AEInfo->interp, AEInfo->procedure, NULL, 0)) {
|
||||
if (AEInfo->retryCount < 2) {
|
||||
AEInfo->retryCount++;
|
||||
Tcl_CreateTimerHandler(200, ProcessAppleEvent, clientData);
|
||||
} else {
|
||||
ckfree(clientData);
|
||||
}
|
||||
return;
|
||||
}
|
||||
code = Tcl_EvalEx(AEInfo->interp, Tcl_DStringValue(&AEInfo->command),
|
||||
Tcl_DStringLength(&AEInfo->command), TCL_EVAL_GLOBAL);
|
||||
if (code != TCL_OK) {
|
||||
Tcl_BackgroundException(AEInfo->interp, code);
|
||||
}
|
||||
|
||||
if (AEInfo->replyEvent && code >= 0) {
|
||||
int reslen;
|
||||
@@ -400,7 +433,10 @@ static void ProcessAppleEvent(
|
||||
AEPutParamPtr((AppleEvent*)[AEInfo->replyEvent aeDesc],
|
||||
keyErrorNumber, typeSInt32, (Ptr) &code, sizeof(int));
|
||||
}
|
||||
} else if (code != TCL_OK) {
|
||||
Tcl_BackgroundException(AEInfo->interp, code);
|
||||
}
|
||||
|
||||
Tcl_DStringFree(&AEInfo->command);
|
||||
ckfree(clientData);
|
||||
}
|
||||
@@ -534,13 +570,18 @@ TkMacOSXDoHLEvent(
|
||||
static int
|
||||
ReallyKillMe(
|
||||
Tcl_Event *eventPtr,
|
||||
int flags)
|
||||
TCL_UNUSED(int))
|
||||
{
|
||||
Tcl_Interp *interp = ((KillEvent *) eventPtr)->interp;
|
||||
int quit = Tcl_FindCommand(interp, "::tk::mac::Quit", NULL, 0)!=NULL;
|
||||
int code = Tcl_EvalEx(interp, quit ? "::tk::mac::Quit" : "exit", -1, TCL_EVAL_GLOBAL);
|
||||
|
||||
if (!quit) {
|
||||
Tcl_Exit(0);
|
||||
}
|
||||
|
||||
int code = Tcl_EvalEx(interp, "::tk::mac::Quit", -1, TCL_EVAL_GLOBAL);
|
||||
if (code != TCL_OK) {
|
||||
|
||||
/*
|
||||
* Should be never reached...
|
||||
*/
|
||||
|
||||
@@ -6,7 +6,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 2017-2018 Marc Culler.
|
||||
* Copyright (c) 2017-2020 Marc Culler.
|
||||
*
|
||||
* See the file "license.terms" for information on usage and redistribution
|
||||
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
@@ -15,6 +15,10 @@
|
||||
#include "tkMacOSXPrivate.h"
|
||||
#include "xbytes.h"
|
||||
|
||||
static CGImageRef CreateCGImageFromPixmap(Drawable pixmap);
|
||||
static CGImageRef CreateCGImageFromDrawableRect( Drawable drawable,
|
||||
int x, int y, unsigned int width, unsigned int height);
|
||||
|
||||
#pragma mark XImage handling
|
||||
|
||||
int
|
||||
@@ -128,141 +132,6 @@ TkMacOSXCreateCGImageWithXImage(
|
||||
return img;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* XGetImage --
|
||||
*
|
||||
* This function copies data from a pixmap or window into an XImage. It
|
||||
* is essentially never used. At one time it was called by
|
||||
* pTkImgPhotoDisplay, but that is no longer the case. Currently it is
|
||||
* called two places, one of which is requesting an XY image which we do
|
||||
* not support. It probably does not work correctly -- see the comments
|
||||
* for TkMacOSXBitmapRepFromDrawableRect.
|
||||
*
|
||||
* 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. 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.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
struct pixel_fmt {int r; int g; int b; int a;};
|
||||
static struct pixel_fmt bgra = {2, 1, 0, 3};
|
||||
static struct pixel_fmt abgr = {3, 2, 1, 0};
|
||||
|
||||
XImage *
|
||||
XGetImage(
|
||||
Display *display,
|
||||
Drawable drawable,
|
||||
int x,
|
||||
int y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
unsigned long plane_mask,
|
||||
int format)
|
||||
{
|
||||
NSBitmapImageRep* bitmap_rep = NULL;
|
||||
NSUInteger bitmap_fmt = 0;
|
||||
XImage* imagePtr = NULL;
|
||||
char* bitmap = NULL;
|
||||
char R, G, B, A;
|
||||
int depth = 32, offset = 0, bitmap_pad = 0;
|
||||
unsigned int bytes_per_row, size, row, n, m;
|
||||
unsigned int scalefactor=1, scaled_height=height, scaled_width=width;
|
||||
NSWindow *win = TkMacOSXDrawableWindow(drawable);
|
||||
static enum {unknown, no, yes} has_retina = unknown;
|
||||
|
||||
if (win && has_retina == unknown) {
|
||||
#ifdef __clang__
|
||||
has_retina = [win respondsToSelector:@selector(backingScaleFactor)] ?
|
||||
yes : no;
|
||||
#else
|
||||
has_retina = no;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (has_retina == yes) {
|
||||
/*
|
||||
* We only allow scale factors 1 or 2, as Apple currently does.
|
||||
*/
|
||||
|
||||
#ifdef __clang__
|
||||
scalefactor = [win backingScaleFactor] == 2.0 ? 2 : 1;
|
||||
#endif
|
||||
scaled_height *= scalefactor;
|
||||
scaled_width *= scalefactor;
|
||||
}
|
||||
|
||||
if (format == ZPixmap) {
|
||||
if (width == 0 || height == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bitmap_rep = TkMacOSXBitmapRepFromDrawableRect(drawable,
|
||||
x, y, width, height);
|
||||
if (!bitmap_rep) {
|
||||
TkMacOSXDbgMsg("XGetImage: Failed to construct NSBitmapRep");
|
||||
return NULL;
|
||||
}
|
||||
bitmap_fmt = [bitmap_rep bitmapFormat];
|
||||
size = [bitmap_rep bytesPerPlane];
|
||||
bytes_per_row = [bitmap_rep bytesPerRow];
|
||||
bitmap = ckalloc(size);
|
||||
if (!bitmap
|
||||
|| (bitmap_fmt != 0 && bitmap_fmt != 1)
|
||||
|| [bitmap_rep samplesPerPixel] != 4
|
||||
|| [bitmap_rep isPlanar] != 0
|
||||
|| bytes_per_row < 4 * scaled_width
|
||||
|| size != bytes_per_row * scaled_height) {
|
||||
TkMacOSXDbgMsg("XGetImage: Unrecognized bitmap format");
|
||||
CFRelease(bitmap_rep);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(bitmap, (char *)[bitmap_rep bitmapData], size);
|
||||
CFRelease(bitmap_rep);
|
||||
|
||||
/*
|
||||
* When Apple extracts a bitmap from an NSView, it may be in either
|
||||
* BGRA or ABGR format. For an XImage we need RGBA.
|
||||
*/
|
||||
|
||||
struct pixel_fmt pixel = bitmap_fmt == 0 ? bgra : abgr;
|
||||
|
||||
for (row = 0, n = 0; row < scaled_height; row++, n += bytes_per_row) {
|
||||
for (m = n; m < n + 4*scaled_width; m += 4) {
|
||||
R = *(bitmap + m + pixel.r);
|
||||
G = *(bitmap + m + pixel.g);
|
||||
B = *(bitmap + m + pixel.b);
|
||||
A = *(bitmap + m + pixel.a);
|
||||
|
||||
*(bitmap + m) = R;
|
||||
*(bitmap + m + 1) = G;
|
||||
*(bitmap + m + 2) = B;
|
||||
*(bitmap + m + 3) = A;
|
||||
}
|
||||
}
|
||||
imagePtr = XCreateImage(display, NULL, depth, format, offset,
|
||||
(char*) bitmap, scaled_width, scaled_height,
|
||||
bitmap_pad, bytes_per_row);
|
||||
if (scalefactor == 2) {
|
||||
imagePtr->pixelpower = 1;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* There are some calls to XGetImage in the generic Tk code which pass
|
||||
* an XYPixmap rather than a ZPixmap. XYPixmaps should be handled
|
||||
* here.
|
||||
*/
|
||||
TkMacOSXDbgMsg("XGetImage does not handle XYPixmaps at the moment.");
|
||||
}
|
||||
return imagePtr;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -300,7 +169,11 @@ DestroyImage(
|
||||
* Get a single pixel from an image.
|
||||
*
|
||||
* Results:
|
||||
* Returns the 32 bit pixel value.
|
||||
* The XColor structure contains an unsigned long field named pixel which
|
||||
* identifies the color. This function returns the unsigned long that
|
||||
* would be used as the pixel value of an XColor that has the same red
|
||||
* green and blue components as the XImage pixel at the specified
|
||||
* location.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
@@ -316,13 +189,18 @@ ImageGetPixel(
|
||||
{
|
||||
unsigned char r = 0, g = 0, b = 0;
|
||||
|
||||
/*
|
||||
* Compute 8 bit red green and blue values, which are passed as inputs to
|
||||
* TkMacOSXRGBPixel to produce the pixel value.
|
||||
*/
|
||||
|
||||
if (image && image->data) {
|
||||
unsigned char *srcPtr = ((unsigned char*) image->data)
|
||||
+ (y * image->bytes_per_line)
|
||||
+ (((image->xoffset + x) * image->bits_per_pixel) / NBBY);
|
||||
|
||||
switch (image->bits_per_pixel) {
|
||||
case 32:
|
||||
case 32: /* 8 bits per channel */
|
||||
r = (*((unsigned int*) srcPtr) >> 16) & 0xff;
|
||||
g = (*((unsigned int*) srcPtr) >> 8) & 0xff;
|
||||
b = (*((unsigned int*) srcPtr) ) & 0xff;
|
||||
@@ -332,12 +210,12 @@ ImageGetPixel(
|
||||
r = srcPtr[1]; g = srcPtr[2]; b = srcPtr[3];
|
||||
}*/
|
||||
break;
|
||||
case 16:
|
||||
case 16: /* 5 bits per channel */
|
||||
r = (*((unsigned short*) srcPtr) >> 7) & 0xf8;
|
||||
g = (*((unsigned short*) srcPtr) >> 2) & 0xf8;
|
||||
b = (*((unsigned short*) srcPtr) << 3) & 0xf8;
|
||||
break;
|
||||
case 8:
|
||||
case 8: /* 2 bits per channel */
|
||||
r = (*srcPtr << 2) & 0xc0;
|
||||
g = (*srcPtr << 4) & 0xc0;
|
||||
b = (*srcPtr << 6) & 0xc0;
|
||||
@@ -345,7 +223,7 @@ ImageGetPixel(
|
||||
g |= g >> 2 | g >> 4 | g >> 6;
|
||||
b |= b >> 2 | b >> 4 | b >> 6;
|
||||
break;
|
||||
case 4: {
|
||||
case 4: { /* 1 bit per channel */
|
||||
unsigned char c = (x % 2) ? *srcPtr : (*srcPtr >> 4);
|
||||
|
||||
r = (c & 0x04) ? 0xff : 0;
|
||||
@@ -353,12 +231,13 @@ ImageGetPixel(
|
||||
b = (c & 0x01) ? 0xff : 0;
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
case 1: /* Black-white bitmap. */
|
||||
r = g = b = ((*srcPtr) & (0x80 >> (x % 8))) ? 0xff : 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (PIXEL_MAGIC << 24) | (r << 16) | (g << 8) | b;
|
||||
|
||||
return TkMacOSXRGBPixel(r, g, b);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -463,13 +342,6 @@ XCreateImage(
|
||||
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;
|
||||
ximage->bitmap_unit = 32;
|
||||
@@ -542,13 +414,13 @@ XPutImage(
|
||||
int dest_x, /* Destination X & Y. */
|
||||
int dest_y,
|
||||
unsigned int width, /* Same width & height for both */
|
||||
unsigned int height) /* distination and source. */
|
||||
unsigned int height) /* destination and source. */
|
||||
{
|
||||
TkMacOSXDrawingContext dc;
|
||||
MacDrawable *macDraw = (MacDrawable *) drawable;
|
||||
MacDrawable *macDraw = (MacDrawable *)drawable;
|
||||
|
||||
display->request++;
|
||||
if (!TkMacOSXSetupDrawingContext(drawable, gc, 1, &dc)) {
|
||||
if (!TkMacOSXSetupDrawingContext(drawable, gc, &dc)) {
|
||||
return BadDrawable;
|
||||
}
|
||||
if (dc.context) {
|
||||
@@ -564,17 +436,8 @@ XPutImage(
|
||||
}
|
||||
if (img) {
|
||||
|
||||
/*
|
||||
* If the XImage has big pixels, the source is rescaled to reflect
|
||||
* the actual pixel dimensions. This is not currently used, but
|
||||
* could arise if the image were copied from a retina monitor and
|
||||
* redrawn on an ordinary monitor.
|
||||
*/
|
||||
|
||||
int pp = image->pixelpower;
|
||||
|
||||
bounds = CGRectMake(0, 0, image->width, image->height);
|
||||
srcRect = CGRectMake(src_x<<pp, src_y<<pp, width<<pp, height<<pp);
|
||||
srcRect = CGRectMake(src_x, src_y, width, height);
|
||||
dstRect = CGRectMake(dest_x, dest_y, width, height);
|
||||
TkMacOSXDrawCGImage(drawable, gc, dc.context,
|
||||
img, gc->foreground, gc->background,
|
||||
@@ -607,6 +470,454 @@ TkPutImage(
|
||||
return XPutImage(display, d, gc, image, src_x, src_y, dest_x, dest_y, width, height);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* CreateCGImageFromDrawableRect
|
||||
*
|
||||
* Extract image data from a MacOSX drawable as a CGImage.
|
||||
*
|
||||
* This is only called by XGetImage and XCopyArea. The Tk core uses
|
||||
* these functions on some platforms, but on macOS the core does not
|
||||
* call them with a source drawable which is a window. Such calls are
|
||||
* used only for double-buffered drawing. Since macOS defines the
|
||||
* macro TK_NO_DOUBLE_BUFFERING, the generic code never calls XGetImage
|
||||
* or XCopyArea on macOS. Nonetheless, these function are in the stubs
|
||||
* table and therefore could be used by extensions.
|
||||
*
|
||||
* This implementation does not work correctly. Originally it relied on
|
||||
* [NSBitmapImageRep initWithFocusedViewRect:view_rect] which was
|
||||
* deprecated by Apple in OSX 10.14 and also required the use of other
|
||||
* deprecated functions such as [NSView lockFocus]. Apple's suggested
|
||||
* replacement is [NSView cacheDisplayInRect: toBitmapImageRep:] and that
|
||||
* is what is being used here. However, that method only works when the
|
||||
* view has a valid CGContext, and a view is only guaranteed to have a
|
||||
* valid context during a call to [NSView drawRect]. To further complicate
|
||||
* matters, cacheDisplayInRect calls [NSView drawRect]. Essentially it is
|
||||
* asking the view to draw a subrectangle of itself using a special
|
||||
* graphics context which is linked to the BitmapImageRep. But our
|
||||
* implementation of [NSView drawRect] does not allow recursive calls. If
|
||||
* called recursively it returns immediately without doing any drawing.
|
||||
* So the bottom line is that this function either returns a NULL pointer
|
||||
* or a black image. To make it useful would require a significant amount
|
||||
* of rewriting of the drawRect method. Perhaps the next release of OSX
|
||||
* will include some more helpful ways of doing this.
|
||||
*
|
||||
* Results:
|
||||
* Returns an NSBitmapRep representing the image of the given rectangle of
|
||||
* the given drawable. This object is retained. The caller is responsible
|
||||
* for releasing it.
|
||||
*
|
||||
* NOTE: The x,y coordinates should be relative to a coordinate system
|
||||
* with origin at the top left, as used by XImage and CGImage, not bottom
|
||||
* left as used by NSView.
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static CGImageRef
|
||||
CreateCGImageFromDrawableRect(
|
||||
Drawable drawable,
|
||||
int x,
|
||||
int y,
|
||||
unsigned int width,
|
||||
unsigned int height)
|
||||
{
|
||||
MacDrawable *mac_drawable = (MacDrawable *)drawable;
|
||||
CGContextRef cg_context = NULL;
|
||||
CGImageRef cg_image = NULL, result = NULL;
|
||||
NSBitmapImageRep *bitmapRep = nil;
|
||||
NSView *view = nil;
|
||||
if (mac_drawable->flags & TK_IS_PIXMAP) {
|
||||
/*
|
||||
* This MacDrawable is a bitmap, so its view is NULL.
|
||||
*/
|
||||
|
||||
CGRect image_rect = CGRectMake(x, y, width, height);
|
||||
|
||||
cg_context = TkMacOSXGetCGContextForDrawable(drawable);
|
||||
cg_image = CGBitmapContextCreateImage((CGContextRef) cg_context);
|
||||
if (cg_image) {
|
||||
result = CGImageCreateWithImageInRect(cg_image, image_rect);
|
||||
CGImageRelease(cg_image);
|
||||
}
|
||||
} else if (TkMacOSXGetNSViewForDrawable(mac_drawable) != nil) {
|
||||
|
||||
/*
|
||||
* Convert Tk top-left to NSView bottom-left coordinates.
|
||||
*/
|
||||
|
||||
int view_height = [view bounds].size.height;
|
||||
NSRect view_rect = NSMakeRect(x + mac_drawable->xOff,
|
||||
view_height - height - y - mac_drawable->yOff,
|
||||
width, height);
|
||||
|
||||
/*
|
||||
* Attempt to copy from the view to a bitmapImageRep. If the view does
|
||||
* not have a valid CGContext, doing this will silently corrupt memory
|
||||
* and make a big mess. So, in that case, we just return NULL.
|
||||
*/
|
||||
|
||||
if (view == [NSView focusView]) {
|
||||
bitmapRep = [view bitmapImageRepForCachingDisplayInRect: view_rect];
|
||||
[view cacheDisplayInRect:view_rect toBitmapImageRep:bitmapRep];
|
||||
result = [bitmapRep CGImage];
|
||||
CFRelease(bitmapRep);
|
||||
} else {
|
||||
TkMacOSXDbgMsg("No CGContext - cannot copy from screen to bitmap.");
|
||||
result = NULL;
|
||||
}
|
||||
} else {
|
||||
TkMacOSXDbgMsg("Invalid source drawable");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* CreateCGImageFromPixmap --
|
||||
*
|
||||
* Create a CGImage from an X Pixmap.
|
||||
*
|
||||
* Results:
|
||||
* CGImage, release after use.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static CGImageRef
|
||||
CreateCGImageFromPixmap(
|
||||
Drawable pixmap)
|
||||
{
|
||||
CGImageRef img = NULL;
|
||||
CGContextRef context = TkMacOSXGetCGContextForDrawable(pixmap);
|
||||
|
||||
if (context) {
|
||||
img = CGBitmapContextCreateImage(context);
|
||||
}
|
||||
return img;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* XGetImage --
|
||||
*
|
||||
* This function copies data from a pixmap or window into an XImage. It
|
||||
* is essentially never used. At one time it was called by
|
||||
* pTkImgPhotoDisplay, but that is no longer the case. Currently it is
|
||||
* called two places, one of which is requesting an XY image which we do
|
||||
* not support. It probably does not work correctly -- see the comments
|
||||
* for CGImageFromDrawableRect.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
struct pixel_fmt {int r; int g; int b; int a;};
|
||||
static struct pixel_fmt bgra = {2, 1, 0, 3};
|
||||
static struct pixel_fmt abgr = {3, 2, 1, 0};
|
||||
|
||||
XImage *
|
||||
XGetImage(
|
||||
Display *display,
|
||||
Drawable drawable,
|
||||
int x,
|
||||
int y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
unsigned long plane_mask,
|
||||
int format)
|
||||
{
|
||||
NSBitmapImageRep* bitmapRep = nil;
|
||||
NSUInteger bitmap_fmt = 0;
|
||||
XImage* imagePtr = NULL;
|
||||
char* bitmap = NULL;
|
||||
char R, G, B, A;
|
||||
int depth = 32, offset = 0, bitmap_pad = 0;
|
||||
unsigned int bytes_per_row, size, row, n, m;
|
||||
|
||||
if (format == ZPixmap) {
|
||||
CGImageRef cgImage;
|
||||
if (width == 0 || height == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cgImage = CreateCGImageFromDrawableRect(drawable, x, y, width, height);
|
||||
if (cgImage) {
|
||||
bitmapRep = [NSBitmapImageRep alloc];
|
||||
[bitmapRep initWithCGImage:cgImage];
|
||||
CFRelease(cgImage);
|
||||
} else {
|
||||
TkMacOSXDbgMsg("XGetImage: Failed to construct CGImage");
|
||||
return NULL;
|
||||
}
|
||||
bitmap_fmt = [bitmapRep bitmapFormat];
|
||||
size = [bitmapRep bytesPerPlane];
|
||||
bytes_per_row = [bitmapRep bytesPerRow];
|
||||
bitmap = ckalloc(size);
|
||||
if (!bitmap
|
||||
|| (bitmap_fmt != 0 && bitmap_fmt != 1)
|
||||
|| [bitmapRep samplesPerPixel] != 4
|
||||
|| [bitmapRep isPlanar] != 0
|
||||
|| bytes_per_row < 4 * width
|
||||
|| size != bytes_per_row * height) {
|
||||
TkMacOSXDbgMsg("XGetImage: Unrecognized bitmap format");
|
||||
CFRelease(bitmapRep);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(bitmap, (char *)[bitmapRep bitmapData], size);
|
||||
CFRelease(bitmapRep);
|
||||
|
||||
/*
|
||||
* When Apple extracts a bitmap from an NSView, it may be in either
|
||||
* BGRA or ABGR format. For an XImage we need RGBA.
|
||||
*/
|
||||
|
||||
struct pixel_fmt pixel = bitmap_fmt == 0 ? bgra : abgr;
|
||||
|
||||
for (row = 0, n = 0; row < height; row++, n += bytes_per_row) {
|
||||
for (m = n; m < n + 4*width; m += 4) {
|
||||
R = *(bitmap + m + pixel.r);
|
||||
G = *(bitmap + m + pixel.g);
|
||||
B = *(bitmap + m + pixel.b);
|
||||
A = *(bitmap + m + pixel.a);
|
||||
|
||||
*(bitmap + m) = R;
|
||||
*(bitmap + m + 1) = G;
|
||||
*(bitmap + m + 2) = B;
|
||||
*(bitmap + m + 3) = A;
|
||||
}
|
||||
}
|
||||
imagePtr = XCreateImage(display, NULL, depth, format, offset,
|
||||
(char*) bitmap, width, height,
|
||||
bitmap_pad, bytes_per_row);
|
||||
} else {
|
||||
/*
|
||||
* There are some calls to XGetImage in the generic Tk code which pass
|
||||
* an XYPixmap rather than a ZPixmap. XYPixmaps should be handled
|
||||
* here.
|
||||
*/
|
||||
TkMacOSXDbgMsg("XGetImage does not handle XYPixmaps at the moment.");
|
||||
}
|
||||
return imagePtr;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* XCopyArea --
|
||||
*
|
||||
* Copies image data from one drawable to another.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Image data is moved from a window or bitmap to a second window or bitmap.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
XCopyArea(
|
||||
Display *display, /* Display. */
|
||||
Drawable src, /* Source drawable. */
|
||||
Drawable dst, /* Destination drawable. */
|
||||
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 height,
|
||||
int dest_x, /* Dest X & Y on dest rect. */
|
||||
int dest_y)
|
||||
{
|
||||
TkMacOSXDrawingContext dc;
|
||||
MacDrawable *srcDraw = (MacDrawable *)src;
|
||||
CGImageRef img = NULL;
|
||||
CGRect bounds, srcRect, dstRect;
|
||||
|
||||
display->request++;
|
||||
if (!width || !height) {
|
||||
return BadDrawable;
|
||||
}
|
||||
|
||||
if (!TkMacOSXSetupDrawingContext(dst, gc, &dc)) {
|
||||
TkMacOSXDbgMsg("Failed to setup drawing context.");
|
||||
return BadDrawable;
|
||||
}
|
||||
|
||||
if (!dc.context) {
|
||||
TkMacOSXDbgMsg("Invalid destination drawable - no context.");
|
||||
return BadDrawable;
|
||||
}
|
||||
|
||||
if (srcDraw->flags & TK_IS_PIXMAP) {
|
||||
img = CreateCGImageFromPixmap(src);
|
||||
} else if (TkMacOSXGetNSWindowForDrawable(src)) {
|
||||
img = CreateCGImageFromDrawableRect(src, src_x, src_y, width, height);
|
||||
} else {
|
||||
TkMacOSXDbgMsg("Invalid source drawable - neither window nor pixmap.");
|
||||
}
|
||||
|
||||
if (img) {
|
||||
bounds = CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height);
|
||||
srcRect = CGRectMake(src_x, src_y, width, height);
|
||||
dstRect = CGRectMake(dest_x, dest_y, width, height);
|
||||
TkMacOSXDrawCGImage(dst, gc, dc.context, img,
|
||||
gc->foreground, gc->background, bounds, srcRect, dstRect);
|
||||
CFRelease(img);
|
||||
} else {
|
||||
TkMacOSXDbgMsg("Failed to construct CGImage.");
|
||||
}
|
||||
|
||||
TkMacOSXRestoreDrawingContext(&dc);
|
||||
return Success;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* XCopyPlane --
|
||||
*
|
||||
* Copies a bitmap from a source drawable to a destination drawable. The
|
||||
* plane argument specifies which bit plane of the source contains the
|
||||
* bitmap. Note that this implementation ignores the gc->function.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Changes the destination drawable.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
XCopyPlane(
|
||||
Display *display, /* Display. */
|
||||
Drawable src, /* Source drawable. */
|
||||
Drawable dst, /* Destination drawable. */
|
||||
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 height,
|
||||
int dest_x, /* Dest X & Y on dest rect. */
|
||||
int dest_y,
|
||||
unsigned long plane) /* Which plane to copy. */
|
||||
{
|
||||
TkMacOSXDrawingContext dc;
|
||||
MacDrawable *srcDraw = (MacDrawable *)src;
|
||||
MacDrawable *dstDraw = (MacDrawable *)dst;
|
||||
CGRect bounds, srcRect, dstRect;
|
||||
display->request++;
|
||||
if (!width || !height) {
|
||||
/* TkMacOSXDbgMsg("Drawing of empty area requested"); */
|
||||
return BadDrawable;
|
||||
}
|
||||
if (plane != 1) {
|
||||
Tcl_Panic("Unexpected plane specified for XCopyPlane");
|
||||
}
|
||||
if (srcDraw->flags & TK_IS_PIXMAP) {
|
||||
if (!TkMacOSXSetupDrawingContext(dst, gc, &dc)) {
|
||||
return BadDrawable;
|
||||
}
|
||||
|
||||
CGContextRef context = dc.context;
|
||||
|
||||
if (context) {
|
||||
CGImageRef img = CreateCGImageFromPixmap(src);
|
||||
|
||||
if (img) {
|
||||
TkpClipMask *clipPtr = (TkpClipMask *) gc->clip_mask;
|
||||
unsigned long imageBackground = gc->background;
|
||||
|
||||
if (clipPtr && clipPtr->type == TKP_CLIP_PIXMAP) {
|
||||
srcRect = CGRectMake(src_x, src_y, width, height);
|
||||
CGImageRef mask = CreateCGImageFromPixmap(
|
||||
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 {
|
||||
bounds = CGRectMake(0, 0,
|
||||
srcDraw->size.width, srcDraw->size.height);
|
||||
srcRect = CGRectMake(src_x, src_y, width, height);
|
||||
dstRect = CGRectMake(dest_x, dest_y, width, height);
|
||||
TkMacOSXDrawCGImage(dst, gc, dc.context, img,
|
||||
gc->foreground, imageBackground, bounds,
|
||||
srcRect, dstRect);
|
||||
CGImageRelease(img);
|
||||
}
|
||||
} else {
|
||||
/* no image */
|
||||
TkMacOSXDbgMsg("Invalid source drawable");
|
||||
}
|
||||
} else {
|
||||
TkMacOSXDbgMsg("Invalid destination drawable - "
|
||||
"could not get a bitmap context.");
|
||||
}
|
||||
TkMacOSXRestoreDrawingContext(&dc);
|
||||
return Success;
|
||||
} else {
|
||||
/*
|
||||
* Source drawable is a Window, not a Pixmap.
|
||||
*/
|
||||
|
||||
return XCopyArea(display, src, dst, gc, src_x, src_y, width, height,
|
||||
dest_x, dest_y);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: objc
|
||||
|
||||
@@ -14,10 +14,9 @@
|
||||
*/
|
||||
|
||||
#include "tkMacOSXPrivate.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <dlfcn.h>
|
||||
#include <objc/objc-auto.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
static char tkLibPath[PATH_MAX + 1] = "";
|
||||
|
||||
@@ -28,12 +27,20 @@ static char tkLibPath[PATH_MAX + 1] = "";
|
||||
|
||||
static char scriptPath[PATH_MAX + 1] = "";
|
||||
|
||||
/*
|
||||
* Forward declarations...
|
||||
*/
|
||||
|
||||
static int TkMacOSXGetAppPathCmd(ClientData cd, Tcl_Interp *ip,
|
||||
int objc, Tcl_Obj *const objv[]);
|
||||
|
||||
#pragma mark TKApplication(TKInit)
|
||||
|
||||
@implementation TKApplication
|
||||
@synthesize poolLock = _poolLock;
|
||||
@synthesize macMinorVersion = _macMinorVersion;
|
||||
@synthesize macOSVersion = _macOSVersion;
|
||||
@synthesize isDrawing = _isDrawing;
|
||||
@synthesize needsToDraw = _needsToDraw;
|
||||
@end
|
||||
|
||||
/*
|
||||
@@ -75,7 +82,7 @@ static char scriptPath[PATH_MAX + 1] = "";
|
||||
#define observe(n, s) \
|
||||
[nc addObserver:self selector:@selector(s) name:(n) object:nil]
|
||||
observe(NSApplicationDidBecomeActiveNotification, applicationActivate:);
|
||||
observe(NSApplicationDidResignActiveNotification, applicationDeactivate:);
|
||||
observe(NSApplicationWillResignActiveNotification, applicationDeactivate:);
|
||||
observe(NSApplicationDidUnhideNotification, applicationShowHide:);
|
||||
observe(NSApplicationDidHideNotification, applicationShowHide:);
|
||||
observe(NSApplicationDidChangeScreenParametersNotification, displayChanged:);
|
||||
@@ -85,6 +92,7 @@ static char scriptPath[PATH_MAX + 1] = "";
|
||||
|
||||
-(void)applicationWillFinishLaunching:(NSNotification *)aNotification
|
||||
{
|
||||
(void)aNotification;
|
||||
|
||||
/*
|
||||
* Initialize notifications.
|
||||
@@ -95,16 +103,16 @@ static char scriptPath[PATH_MAX + 1] = "";
|
||||
#endif
|
||||
[self _setupWindowNotifications];
|
||||
[self _setupApplicationNotifications];
|
||||
}
|
||||
|
||||
/*
|
||||
* Construct the menu bar.
|
||||
*/
|
||||
_defaultMainMenu = nil;
|
||||
[self _setupMenus];
|
||||
-(void)applicationDidFinishLaunching:(NSNotification *)notification
|
||||
{
|
||||
(void)notification;
|
||||
|
||||
/*
|
||||
* Initialize event processing.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Initialize event processing.
|
||||
*/
|
||||
TkMacOSXInitAppleEvents(_eventInterp);
|
||||
|
||||
/*
|
||||
@@ -112,22 +120,24 @@ static char scriptPath[PATH_MAX + 1] = "";
|
||||
*/
|
||||
TkMacOSXUseAntialiasedText(_eventInterp, -1);
|
||||
TkMacOSXInitCGDrawing(_eventInterp, TRUE, 0);
|
||||
}
|
||||
|
||||
-(void)applicationDidFinishLaunching:(NSNotification *)notification
|
||||
{
|
||||
/*
|
||||
* Construct the menu bar.
|
||||
*/
|
||||
|
||||
_defaultMainMenu = nil;
|
||||
[self _setupMenus];
|
||||
|
||||
/*
|
||||
* It is not safe to force activation of the NSApp until this method is
|
||||
* called. Activating too early can cause the menu bar to be unresponsive.
|
||||
* The call to activateIgnoringOtherApps was moved here to avoid this.
|
||||
* However, with the release of macOS 10.15 (Catalina) this was no longer
|
||||
* sufficient. (See ticket bf93d098d7.) Apparently apps were being
|
||||
* activated automatically, and this was sometimes being done too early.
|
||||
* As a workaround we deactivate and then reactivate the app, even though
|
||||
* Apple says that "Normally, you shouldn’t invoke this method".
|
||||
* However, with the release of macOS 10.15 (Catalina) that was no longer
|
||||
* sufficient. (See ticket bf93d098d7.) The call to setActivationPolicy
|
||||
* needed to be moved into this function as well.
|
||||
*/
|
||||
|
||||
[NSApp deactivate];
|
||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||
[NSApp activateIgnoringOtherApps: YES];
|
||||
|
||||
/*
|
||||
@@ -136,7 +146,7 @@ static char scriptPath[PATH_MAX + 1] = "";
|
||||
*/
|
||||
|
||||
[NSApp _lockAutoreleasePool];
|
||||
while (Tcl_DoOneEvent(TCL_WINDOW_EVENTS| TCL_DONT_WAIT)) {}
|
||||
while (Tcl_DoOneEvent(TCL_WINDOW_EVENTS|TCL_DONT_WAIT)) {}
|
||||
[NSApp _unlockAutoreleasePool];
|
||||
}
|
||||
|
||||
@@ -156,15 +166,18 @@ static char scriptPath[PATH_MAX + 1] = "";
|
||||
/*
|
||||
* Record the OS version we are running on.
|
||||
*/
|
||||
int minorVersion;
|
||||
|
||||
int minorVersion, majorVersion;
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101000
|
||||
Gestalt(gestaltSystemVersionMinor, (SInt32*)&minorVersion);
|
||||
majorVersion = 10;
|
||||
#else
|
||||
NSOperatingSystemVersion systemVersion;
|
||||
systemVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
|
||||
majorVersion = systemVersion.majorVersion;
|
||||
minorVersion = systemVersion.minorVersion;
|
||||
#endif
|
||||
[NSApp setMacMinorVersion: minorVersion];
|
||||
[NSApp setMacOSVersion: 10000*majorVersion + 100*minorVersion];
|
||||
|
||||
/*
|
||||
* We are not drawing right now.
|
||||
@@ -178,12 +191,6 @@ static char scriptPath[PATH_MAX + 1] = "";
|
||||
|
||||
[self setDelegate:self];
|
||||
|
||||
/*
|
||||
* Make sure we are allowed to open windows.
|
||||
*/
|
||||
|
||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||
|
||||
/*
|
||||
* If no icon has been set from an Info.plist file, use the Wish icon from
|
||||
* the Tk framework.
|
||||
@@ -265,6 +272,80 @@ static char scriptPath[PATH_MAX + 1] = "";
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* Helper function which closes the shared NSFontPanel and NSColorPanel.
|
||||
*/
|
||||
|
||||
static void closePanels(
|
||||
void)
|
||||
{
|
||||
if ([NSFontPanel sharedFontPanelExists]) {
|
||||
[[NSFontPanel sharedFontPanel] orderOut:nil];
|
||||
}
|
||||
if ([NSColorPanel sharedColorPanelExists]) {
|
||||
[[NSColorPanel sharedColorPanel] orderOut:nil];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This custom exit procedure is called by Tcl_Exit in place of the exit
|
||||
* function from the C runtime. It calls the terminate method of the
|
||||
* NSApplication class (superTerminate for a TKApplication). The purpose of
|
||||
* doing this is to ensure that the NSFontPanel and the NSColorPanel are closed
|
||||
* before the process exits, and that the application state is recorded
|
||||
* correctly for all termination scenarios.
|
||||
*
|
||||
* TkpWantsExitProc tells Tcl_AppInit whether to install our custom exit proc,
|
||||
* which terminates the process by calling [NSApplication terminate]. This
|
||||
* does not work correctly if the process is part of an exec pipeline, so it is
|
||||
* only done if the process was launched by the launcher or if both stdin and
|
||||
* stdout are ttys. To disable using the custom exit proc altogether, undefine
|
||||
* USE_CUSTOM_EXIT_PROC.
|
||||
*/
|
||||
|
||||
#if defined(USE_CUSTOM_EXIT_PROC)
|
||||
static Bool doCleanupFromExit = NO;
|
||||
|
||||
int TkpWantsExitProc(void) {
|
||||
return doCleanupFromExit == YES;
|
||||
}
|
||||
|
||||
TCL_NORETURN void TkpExitProc(
|
||||
void *clientdata)
|
||||
{
|
||||
Bool doCleanup = doCleanupFromExit;
|
||||
if (doCleanupFromExit) {
|
||||
doCleanupFromExit = NO; /* prevent possible recursive call. */
|
||||
closePanels();
|
||||
}
|
||||
|
||||
/*
|
||||
* Tcl_Exit does not call Tcl_Finalize if there is an exit proc installed.
|
||||
*/
|
||||
|
||||
Tcl_Finalize();
|
||||
if (doCleanup == YES) {
|
||||
[(TKApplication *)NSApp superTerminate:nil]; /* Should not return. */
|
||||
}
|
||||
exit((long)clientdata); /* Convince the compiler that we don't return. */
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This signal handler is installed for the SIGINT, SIGHUP and SIGTERM signals
|
||||
* so that normal finalization occurs when a Tk app is killed by one of these
|
||||
* signals (e.g when ^C is pressed while running Wish in the shell). It calls
|
||||
* Tcl_Exit instead of the C runtime exit function called by the default handler.
|
||||
* This is consistent with the Tcl_Exit manual page, which says that Tcl_Exit
|
||||
* should always be called instead of exit. When Tk is killed by a signal we
|
||||
* return exit status 1.
|
||||
*/
|
||||
|
||||
static void TkMacOSXSignalHandler(TCL_UNUSED(int)) {
|
||||
|
||||
Tcl_Exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
TkpInit(
|
||||
Tcl_Interp *interp)
|
||||
@@ -272,15 +353,15 @@ TkpInit(
|
||||
static int initialized = 0;
|
||||
|
||||
/*
|
||||
* Since it is possible for TkInit to be called multiple times and we
|
||||
* don't want to do the following initialization multiple times we protect
|
||||
* against doing it more than once.
|
||||
* TkpInit can be called multiple times with different interpreters. But
|
||||
* The application initialization should only be done onece.
|
||||
*/
|
||||
|
||||
if (!initialized) {
|
||||
struct stat st;
|
||||
|
||||
initialized = 1;
|
||||
Bool shouldOpenConsole = NO;
|
||||
Bool stdinIsNullish = (!isatty(0) &&
|
||||
(fstat(0, &st) || (S_ISCHR(st.st_mode) && st.st_blocks == 0)));
|
||||
|
||||
/*
|
||||
* Initialize/check OS version variable for runtime checks.
|
||||
@@ -290,7 +371,10 @@ TkpInit(
|
||||
# error Mac OS X 10.6 required
|
||||
#endif
|
||||
|
||||
initialized = 1;
|
||||
|
||||
#ifdef TK_FRAMEWORK
|
||||
|
||||
/*
|
||||
* When Tk is in a framework, force tcl_findLibrary to look in the
|
||||
* framework scripts directory.
|
||||
@@ -306,16 +390,6 @@ TkpInit(
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* FIXME: Close stdin & stdout for remote debugging otherwise we will
|
||||
* fight with gdb for stdin & stdout
|
||||
*/
|
||||
|
||||
if (getenv("XCNOSTDIN") != NULL) {
|
||||
close(0);
|
||||
close(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Instantiate our NSApplication object. This needs to be done before
|
||||
* we check whether to open a console window.
|
||||
@@ -331,20 +405,20 @@ TkpInit(
|
||||
nil]];
|
||||
[TKApplication sharedApplication];
|
||||
[pool drain];
|
||||
[NSApp _setup:interp];
|
||||
|
||||
/*
|
||||
* WARNING: The finishLaunching method runs asynchronously, apparently
|
||||
* in a separate thread. This creates a race between the
|
||||
* initialization of the NSApplication and the initialization of Tk.
|
||||
* If Tk wins the race bad things happen with the root window (see
|
||||
* below). If the NSApplication wins then an AppleEvent created during
|
||||
* launch, e.g. by dropping a file icon on the application icon, will
|
||||
* be delivered before the procedure meant to to handle the AppleEvent
|
||||
* has been defined. This is now handled by processing the AppleEvent
|
||||
* as an idle task. See tkMacOSXHLEvents.c.
|
||||
* WARNING: The finishLaunching method runs asynchronously. This
|
||||
* creates a race between the initialization of the NSApplication and
|
||||
* the initialization of Tk. If Tk wins the race bad things happen
|
||||
* with the root window (see below). If the NSApplication wins then an
|
||||
* AppleEvent created during launch, e.g. by dropping a file icon on
|
||||
* the application icon, will be delivered before the procedure meant
|
||||
* to to handle the AppleEvent has been defined. This is handled in
|
||||
* tkMacOSXHLEvents.c by scheduling a timer event to handle the
|
||||
* ApplEvent later, after the required procedure has been defined.
|
||||
*/
|
||||
|
||||
[NSApp _setup:interp];
|
||||
[NSApp finishLaunching];
|
||||
|
||||
/*
|
||||
@@ -371,36 +445,60 @@ TkpInit(
|
||||
Tcl_DoOneEvent(TCL_WINDOW_EVENTS | TCL_DONT_WAIT);
|
||||
|
||||
/*
|
||||
* If we don't have a TTY and stdin is a special character file of
|
||||
* length 0, (e.g. /dev/null, which is what Finder sets when double
|
||||
* clicking Wish) then use the Tk based console interpreter.
|
||||
* Decide whether to open a console window. If the TK_CONSOLE
|
||||
* environment variable is not defined we only show the console if
|
||||
* stdin is not a tty and there is no startup script.
|
||||
*/
|
||||
|
||||
if (getenv("TK_CONSOLE") ||
|
||||
(!isatty(0) && (fstat(0, &st) ||
|
||||
(S_ISCHR(st.st_mode) && st.st_blocks == 0)))) {
|
||||
if (getenv("TK_CONSOLE")) {
|
||||
shouldOpenConsole = YES;
|
||||
} else if (stdinIsNullish && Tcl_GetStartupScript(NULL) == NULL) {
|
||||
const char *intvar = Tcl_GetVar2(interp, "tcl_interactive",
|
||||
NULL, TCL_GLOBAL_ONLY);
|
||||
if (intvar == NULL) {
|
||||
Tcl_SetVar2(interp, "tcl_interactive", NULL, "1",
|
||||
TCL_GLOBAL_ONLY);
|
||||
}
|
||||
|
||||
#if defined(USE_CUSTOM_EXIT_PROC)
|
||||
doCleanupFromExit = YES;
|
||||
#endif
|
||||
|
||||
shouldOpenConsole = YES;
|
||||
}
|
||||
if (shouldOpenConsole) {
|
||||
Tk_InitConsoleChannels(interp);
|
||||
Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDIN));
|
||||
Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDOUT));
|
||||
Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDERR));
|
||||
|
||||
/*
|
||||
* Only show the console if we don't have a startup script and
|
||||
* tcl_interactive hasn't been set already.
|
||||
*/
|
||||
|
||||
if (Tcl_GetStartupScript(NULL) == NULL) {
|
||||
const char *intvar = Tcl_GetVar2(interp,
|
||||
"tcl_interactive", NULL, TCL_GLOBAL_ONLY);
|
||||
|
||||
if (intvar == NULL) {
|
||||
Tcl_SetVar2(interp, "tcl_interactive", NULL, "1",
|
||||
TCL_GLOBAL_ONLY);
|
||||
}
|
||||
}
|
||||
if (Tk_CreateConsoleWindow(interp) == TCL_ERROR) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
} else if (stdinIsNullish) {
|
||||
|
||||
/*
|
||||
* When launched as a macOS application with no console,
|
||||
* redirect stderr and stdout to /dev/null. This avoids waiting
|
||||
* forever for those files to become writable if the underlying
|
||||
* Tcl program tries to write to them with a puts command.
|
||||
*/
|
||||
|
||||
FILE *null = fopen("/dev/null", "w");
|
||||
dup2(fileno(null), STDOUT_FILENO);
|
||||
dup2(fileno(null), STDERR_FILENO);
|
||||
#if defined(USE_CUSTOM_EXIT_PROC)
|
||||
doCleanupFromExit = YES;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: Close stdin & stdout for remote debugging if XCNOSTDIN is
|
||||
* set. Otherwise we will fight with gdb for stdin & stdout
|
||||
*/
|
||||
|
||||
if (getenv("XCNOSTDIN") != NULL) {
|
||||
close(0);
|
||||
close(1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -410,8 +508,46 @@ TkpInit(
|
||||
*/
|
||||
|
||||
TkMacOSXServices_Init(interp);
|
||||
|
||||
/*
|
||||
* The root window has been created and mapped, but XMapWindow deferred its
|
||||
* call to makeKeyAndOrderFront because the first call to XMapWindow
|
||||
* occurs too early in the initialization process for that. Process idle
|
||||
* tasks now, so the root window is configured, then order it front.
|
||||
*/
|
||||
|
||||
while(Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {};
|
||||
for (NSWindow *window in [NSApp windows]) {
|
||||
TkWindow *winPtr = TkMacOSXGetTkWindow(window);
|
||||
if (winPtr && Tk_IsMapped(winPtr)) {
|
||||
[window makeKeyAndOrderFront:NSApp];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
# if defined(USE_CUSTOM_EXIT_PROC)
|
||||
|
||||
if ((isatty(0) && isatty(1))) {
|
||||
doCleanupFromExit = YES;
|
||||
}
|
||||
|
||||
# endif
|
||||
|
||||
/*
|
||||
* Install a signal handler for SIGINT, SIGHUP and SIGTERM which uses
|
||||
* Tcl_Exit instead of exit so that normal cleanup takes place if a TK
|
||||
* application is killed with one of these signals.
|
||||
*/
|
||||
|
||||
signal(SIGINT, TkMacOSXSignalHandler);
|
||||
signal(SIGHUP, TkMacOSXSignalHandler);
|
||||
signal(SIGTERM, TkMacOSXSignalHandler);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialization steps that are needed for all interpreters.
|
||||
*/
|
||||
|
||||
if (tkLibPath[0] != '\0') {
|
||||
Tcl_SetVar2(interp, "tk_library", NULL, tkLibPath, TCL_GLOBAL_ONLY);
|
||||
}
|
||||
@@ -425,7 +561,9 @@ TkpInit(
|
||||
TkMacOSXStandardAboutPanelObjCmd, NULL, NULL);
|
||||
Tcl_CreateObjCommand(interp, "::tk::mac::iconBitmap",
|
||||
TkMacOSXIconBitmapObjCmd, NULL, NULL);
|
||||
Tcl_CreateObjCommand(interp, "::tk::mac::GetAppPath", TkMacOSXGetAppPath, NULL, NULL);
|
||||
Tcl_CreateObjCommand(interp, "::tk::mac::GetAppPath",
|
||||
TkMacOSXGetAppPathCmd, NULL, NULL);
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -465,11 +603,11 @@ TkpGetAppName(
|
||||
}
|
||||
Tcl_DStringAppend(namePtr, name, -1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TkMacOSXGetAppPath --
|
||||
* TkMacOSXGetAppPathCmd --
|
||||
*
|
||||
* Returns the path of the Wish application bundle.
|
||||
*
|
||||
@@ -481,42 +619,39 @@ TkpGetAppName(
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
int TkMacOSXGetAppPath(
|
||||
ClientData cd,
|
||||
Tcl_Interp *ip,
|
||||
int objc,
|
||||
Tcl_Obj *const objv[])
|
||||
|
||||
static int
|
||||
TkMacOSXGetAppPathCmd(
|
||||
TCL_UNUSED(void *),
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *const objv[])
|
||||
{
|
||||
if (objc != 1) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
CFURLRef mainBundleURL = CFBundleCopyBundleURL(CFBundleGetMainBundle());
|
||||
/*
|
||||
* Get the application path URL and convert it to a string path reference.
|
||||
*/
|
||||
|
||||
CFURLRef mainBundleURL = CFBundleCopyBundleURL(CFBundleGetMainBundle());
|
||||
CFStringRef appPath =
|
||||
CFURLCopyFileSystemPath(mainBundleURL, kCFURLPOSIXPathStyle);
|
||||
|
||||
/*
|
||||
* Convert the URL reference into a string reference.
|
||||
*/
|
||||
/*
|
||||
* Convert (and copy) the string reference into a Tcl result.
|
||||
*/
|
||||
|
||||
CFStringRef appPath = CFURLCopyFileSystemPath(mainBundleURL, kCFURLPOSIXPathStyle);
|
||||
|
||||
/*
|
||||
* Get the system encoding method.
|
||||
*/
|
||||
|
||||
CFStringEncoding encodingMethod = CFStringGetSystemEncoding();
|
||||
|
||||
/*
|
||||
* Convert the string reference into a C string.
|
||||
*/
|
||||
|
||||
char *path = (char *) CFStringGetCStringPtr(appPath, encodingMethod);
|
||||
|
||||
Tcl_SetResult(ip, path, NULL);
|
||||
|
||||
CFRelease(mainBundleURL);
|
||||
CFRelease(appPath);
|
||||
return TCL_OK;
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
CFStringGetCStringPtr(appPath, CFStringGetSystemEncoding()), -1));
|
||||
|
||||
CFRelease(mainBundleURL);
|
||||
CFRelease(appPath);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -583,7 +718,7 @@ TkMacOSXDefaultStartupScript(void)
|
||||
CFURLRef scriptFldrURL;
|
||||
char startupScript[PATH_MAX + 1];
|
||||
|
||||
if (CFURLGetFileSystemRepresentation (appMainURL, true,
|
||||
if (CFURLGetFileSystemRepresentation(appMainURL, true,
|
||||
(unsigned char *) startupScript, PATH_MAX)) {
|
||||
Tcl_SetStartupScript(Tcl_NewStringObj(startupScript,-1), NULL);
|
||||
scriptFldrURL = CFURLCreateCopyDeletingLastPathComponent(NULL,
|
||||
@@ -620,56 +755,17 @@ TkMacOSXDefaultStartupScript(void)
|
||||
|
||||
MODULE_SCOPE void*
|
||||
TkMacOSXGetNamedSymbol(
|
||||
const char* module,
|
||||
const char* symbol)
|
||||
TCL_UNUSED(const char *),
|
||||
const char *symbol)
|
||||
{
|
||||
void *addr = dlsym(RTLD_NEXT, symbol);
|
||||
|
||||
if (!addr) {
|
||||
(void) dlerror(); /* Clear dlfcn error state */
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TkMacOSXGetStringObjFromCFString --
|
||||
*
|
||||
* Get a string object from a CFString as efficiently as possible.
|
||||
*
|
||||
* Results:
|
||||
* New string object or NULL if conversion failed.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
MODULE_SCOPE Tcl_Obj*
|
||||
TkMacOSXGetStringObjFromCFString(
|
||||
CFStringRef str)
|
||||
{
|
||||
Tcl_Obj *obj = NULL;
|
||||
const char *c = CFStringGetCStringPtr(str, kCFStringEncodingUTF8);
|
||||
|
||||
if (c) {
|
||||
obj = Tcl_NewStringObj(c, -1);
|
||||
} else {
|
||||
CFRange all = CFRangeMake(0, CFStringGetLength(str));
|
||||
CFIndex len;
|
||||
|
||||
if (CFStringGetBytes(str, all, kCFStringEncodingUTF8, 0, false, NULL,
|
||||
0, &len) > 0 && len < INT_MAX) {
|
||||
obj = Tcl_NewObj();
|
||||
Tcl_SetObjLength(obj, len);
|
||||
CFStringGetBytes(str, all, kCFStringEncodingUTF8, 0, false,
|
||||
(UInt8*) obj->bytes, len, NULL);
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: objc
|
||||
|
||||
@@ -116,21 +116,6 @@ typedef struct {
|
||||
|
||||
MODULE_SCOPE TkMacOSXEmbedHandler *tkMacOSXEmbedHandler;
|
||||
|
||||
/*
|
||||
* GC CGColorRef cache for tkMacOSXColor.c
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
unsigned long cachedForeground;
|
||||
CGColorRef cachedForegroundColor;
|
||||
unsigned long cachedBackground;
|
||||
CGColorRef cachedBackgroundColor;
|
||||
} TkpGCCache;
|
||||
|
||||
MODULE_SCOPE TkpGCCache *TkpGetGCCache(GC gc);
|
||||
MODULE_SCOPE void TkpInitGCCache(GC gc);
|
||||
MODULE_SCOPE void TkpFreeGCCache(GC gc);
|
||||
|
||||
/*
|
||||
* Undef compatibility platform types defined above.
|
||||
*/
|
||||
@@ -180,7 +165,7 @@ MODULE_SCOPE void TkpFreeGCCache(GC gc);
|
||||
#define TK_MACOSX_HANDLE_EVENT_IMMEDIATELY 1024
|
||||
|
||||
/*
|
||||
* Defines for tkTextDisp.c
|
||||
* Defines for tkTextDisp.c and tkFont.c
|
||||
*/
|
||||
|
||||
#define TK_LAYOUT_WITH_BASE_CHUNKS 1
|
||||
@@ -191,19 +176,10 @@ MODULE_SCOPE void TkpFreeGCCache(GC gc);
|
||||
*/
|
||||
|
||||
MODULE_SCOPE void TkMacOSXDefaultStartupScript(void);
|
||||
#if 0
|
||||
MODULE_SCOPE int XSetClipRectangles(Display *d, GC gc, int clip_x_origin,
|
||||
int clip_y_origin, XRectangle* rectangles, int n, int ordering);
|
||||
#endif
|
||||
MODULE_SCOPE void TkpClipDrawableToRect(Display *display, Drawable d, int x,
|
||||
int y, int width, int height);
|
||||
MODULE_SCOPE void TkpRetainRegion(TkRegion r);
|
||||
MODULE_SCOPE void TkpReleaseRegion(TkRegion r);
|
||||
MODULE_SCOPE void TkpShiftButton(NSButton *button, NSPoint delta);
|
||||
MODULE_SCOPE Bool TkpAppIsDrawing(void);
|
||||
MODULE_SCOPE void TkpDisplayWindow(Tk_Window tkwin);
|
||||
MODULE_SCOPE Bool TkTestLogDisplay(void);
|
||||
MODULE_SCOPE Bool TkMacOSXInDarkMode(Tk_Window tkwin);
|
||||
MODULE_SCOPE Bool TkTestLogDisplay(Drawable drawable);
|
||||
|
||||
/*
|
||||
* Include the stubbed internal platform-specific API.
|
||||
|
||||
@@ -7,7 +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-2019 Marc Culler.
|
||||
* Copyright 2015-2020 Marc Culler.
|
||||
*
|
||||
* See the file "license.terms" for information on usage and redistribution of
|
||||
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
@@ -16,28 +16,29 @@
|
||||
#include "tkMacOSXPrivate.h"
|
||||
#include "tkMacOSXInt.h"
|
||||
#include "tkMacOSXConstants.h"
|
||||
#include "tkMacOSXWm.h"
|
||||
|
||||
/*
|
||||
* See tkMacOSXPrivate.h for macros related to key event processing.
|
||||
*/
|
||||
|
||||
/*
|
||||
#ifdef TK_MAC_DEBUG
|
||||
#define TK_MAC_DEBUG_KEYBOARD
|
||||
#endif
|
||||
*/
|
||||
#define NS_KEYLOG 0
|
||||
|
||||
static Tk_Window keyboardGrabWinPtr = NULL;
|
||||
/* Current keyboard grab window. */
|
||||
static NSWindow *keyboardGrabNSWindow = nil;
|
||||
/* NSWindow for the current keyboard grab
|
||||
* window. */
|
||||
#define NS_KEYLOG 0
|
||||
#define XEVENT_MOD_MASK (ControlMask | Mod1Mask | Mod3Mask | Mod4Mask)
|
||||
static Tk_Window keyboardGrabWinPtr = NULL; /* Current keyboard grab window. */
|
||||
static NSWindow *keyboardGrabNSWindow = nil; /* Its underlying NSWindow.*/
|
||||
static NSModalSession modalSession = nil;
|
||||
static BOOL processingCompose = NO;
|
||||
static Tk_Window composeWin = NULL;
|
||||
static int caret_x = 0, caret_y = 0, caret_height = 0;
|
||||
static unsigned short releaseCode;
|
||||
|
||||
static void setupXEvent(XEvent *xEvent, NSWindow *w, unsigned int state);
|
||||
static unsigned isFunctionKey(unsigned int code);
|
||||
|
||||
static void setupXEvent(XEvent *xEvent, Tk_Window tkwin, NSUInteger modifiers);
|
||||
static void setXEventPoint(XEvent *xEvent, Tk_Window tkwin, NSWindow *w);
|
||||
static NSUInteger textInputModifiers;
|
||||
|
||||
#pragma mark TKApplication(TKKeyEvent)
|
||||
|
||||
@@ -48,233 +49,226 @@ static unsigned isFunctionKey(unsigned int code);
|
||||
#ifdef TK_MAC_DEBUG_EVENTS
|
||||
TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent);
|
||||
#endif
|
||||
NSWindow *w;
|
||||
NSWindow *w = [theEvent window];
|
||||
TkWindow *winPtr = TkMacOSXGetTkWindow(w), *grabWinPtr, *focusWinPtr;
|
||||
Tk_Window tkwin = (Tk_Window)winPtr;
|
||||
NSEventType type = [theEvent type];
|
||||
NSUInteger virtual = [theEvent keyCode];
|
||||
NSUInteger modifiers = ([theEvent modifierFlags] &
|
||||
NSDeviceIndependentModifierFlagsMask);
|
||||
NSUInteger len = 0;
|
||||
BOOL repeat = NO;
|
||||
unsigned short keyCode = [theEvent keyCode];
|
||||
NSString *characters = nil, *charactersIgnoringModifiers = nil;
|
||||
XEvent xEvent;
|
||||
MacKeycode macKC;
|
||||
UniChar keychar = 0;
|
||||
Bool can_input_text, has_modifiers = NO, use_text_input = NO;
|
||||
static NSUInteger savedModifiers = 0;
|
||||
static NSMutableArray *nsEvArray;
|
||||
static NSMutableArray *nsEvArray = nil;
|
||||
|
||||
if (nsEvArray == nil) {
|
||||
nsEvArray = [[NSMutableArray alloc] initWithCapacity: 1];
|
||||
processingCompose = NO;
|
||||
}
|
||||
|
||||
w = [theEvent window];
|
||||
TkWindow *winPtr = TkMacOSXGetTkWindow(w);
|
||||
Tk_Window tkwin = (Tk_Window) winPtr;
|
||||
XEvent xEvent;
|
||||
|
||||
if (!winPtr) {
|
||||
return theEvent;
|
||||
}
|
||||
|
||||
/*
|
||||
* Control-Tab and Control-Shift-Tab are used to switch tabs in a tabbed
|
||||
* window. We do not want to generate an Xevent for these since that might
|
||||
* cause the deselected tab to be reactivated.
|
||||
* If a local grab is in effect, key events for windows in the
|
||||
* grabber's application are redirected to the grabber. Key events
|
||||
* for other applications are delivered normally. If a global
|
||||
* grab is in effect all key events are redirected to the grabber.
|
||||
*/
|
||||
|
||||
if (keyCode == 48 && (modifiers & NSControlKeyMask) == NSControlKeyMask) {
|
||||
return theEvent;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case NSKeyUp:
|
||||
/*Fix for bug #1ba71a86bb: key release firing on key press.*/
|
||||
setupXEvent(&xEvent, w, 0);
|
||||
xEvent.xany.type = KeyRelease;
|
||||
xEvent.xkey.keycode = releaseCode;
|
||||
xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
|
||||
case NSKeyDown:
|
||||
repeat = [theEvent isARepeat];
|
||||
characters = [theEvent characters];
|
||||
charactersIgnoringModifiers = [theEvent charactersIgnoringModifiers];
|
||||
len = [charactersIgnoringModifiers length];
|
||||
case NSFlagsChanged:
|
||||
|
||||
#if defined(TK_MAC_DEBUG_EVENTS) || NS_KEYLOG == 1
|
||||
TKLog(@"-[%@(%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; /* Unrecognized key event. */
|
||||
grabWinPtr = winPtr->dispPtr->grabWinPtr;
|
||||
if (grabWinPtr) {
|
||||
if (winPtr->dispPtr->grabFlags || /* global grab */
|
||||
grabWinPtr->mainPtr == winPtr->mainPtr){ /* same application */
|
||||
winPtr =winPtr->dispPtr->focusPtr;
|
||||
tkwin = (Tk_Window)winPtr;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Create an Xevent to add to the Tk queue.
|
||||
* Extract the unicode character from KeyUp and KeyDown events.
|
||||
*/
|
||||
|
||||
if (!processingCompose) {
|
||||
unsigned int state = 0;
|
||||
|
||||
if (modifiers & NSAlphaShiftKeyMask) {
|
||||
state |= LockMask;
|
||||
}
|
||||
if (modifiers & NSShiftKeyMask) {
|
||||
state |= ShiftMask;
|
||||
}
|
||||
if (modifiers & NSControlKeyMask) {
|
||||
state |= ControlMask;
|
||||
}
|
||||
if (modifiers & NSCommandKeyMask) {
|
||||
state |= Mod1Mask; /* command key */
|
||||
}
|
||||
if (modifiers & NSAlternateKeyMask) {
|
||||
state |= Mod2Mask; /* option key */
|
||||
}
|
||||
if (modifiers & NSNumericPadKeyMask) {
|
||||
state |= Mod3Mask;
|
||||
}
|
||||
if (modifiers & NSFunctionKeyMask) {
|
||||
state |= Mod4Mask;
|
||||
}
|
||||
|
||||
/*
|
||||
* Key events are only received for the front Window on the Macintosh. So
|
||||
* to build an XEvent we look up the Tk window associated to the Front
|
||||
* window.
|
||||
*/
|
||||
|
||||
TkWindow *winPtr = TkMacOSXGetTkWindow(w);
|
||||
Tk_Window tkwin = (Tk_Window) winPtr;
|
||||
|
||||
if (tkwin) {
|
||||
TkWindow *grabWinPtr = winPtr->dispPtr->grabWinPtr;
|
||||
if (type == NSKeyUp || type == NSKeyDown) {
|
||||
if ([[theEvent characters] length] > 0) {
|
||||
keychar = [[theEvent characters] characterAtIndex:0];
|
||||
|
||||
/*
|
||||
* If a local grab is in effect, key events for windows in the
|
||||
* grabber's application are redirected to the grabber. Key events
|
||||
* for other applications are delivered normally. If a global
|
||||
* grab is in effect all key events are redirected to the grabber.
|
||||
* Currently, real keys always send BMP characters, but who knows?
|
||||
*/
|
||||
|
||||
if (grabWinPtr) {
|
||||
if (winPtr->dispPtr->grabFlags || /* global grab */
|
||||
grabWinPtr->mainPtr == winPtr->mainPtr){ /* same appl. */
|
||||
tkwin = (Tk_Window) winPtr->dispPtr->focusPtr;
|
||||
}
|
||||
if (CFStringIsSurrogateHighCharacter(keychar)) {
|
||||
UniChar lowChar = [[theEvent characters] characterAtIndex:1];
|
||||
keychar = CFStringGetLongCharacterForSurrogatePair(
|
||||
keychar, lowChar);
|
||||
}
|
||||
} else {
|
||||
tkwin = (Tk_Window) winPtr->dispPtr->focusPtr;
|
||||
}
|
||||
if (!tkwin) {
|
||||
TkMacOSXDbgMsg("tkwin == NULL");
|
||||
return theEvent; /* Give up. No window for this event. */
|
||||
}
|
||||
|
||||
/*
|
||||
* If it's a function key, or we have modifiers other than Shift or
|
||||
* Alt, pass it straight to Tk. Otherwise we'll send for input
|
||||
* processing.
|
||||
*/
|
||||
/*
|
||||
* This is a dead key, such as Option-e, so it should go to the
|
||||
* TextInputClient.
|
||||
*/
|
||||
|
||||
int code = (len == 0) ? 0 :
|
||||
[charactersIgnoringModifiers characterAtIndex: 0];
|
||||
if (type != NSKeyDown || isFunctionKey(code)
|
||||
|| (len > 0 && state & (ControlMask | Mod1Mask | Mod3Mask | Mod4Mask))) {
|
||||
XEvent xEvent;
|
||||
|
||||
setupXEvent(&xEvent, w, state);
|
||||
if (type == NSFlagsChanged) {
|
||||
if (savedModifiers > modifiers) {
|
||||
xEvent.xany.type = KeyRelease;
|
||||
} else {
|
||||
xEvent.xany.type = KeyPress;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use special '-1' to signify a special keycode to our
|
||||
* platform specific code in tkMacOSXKeyboard.c. This is rather
|
||||
* like what happens on Windows.
|
||||
*/
|
||||
|
||||
xEvent.xany.send_event = -1;
|
||||
|
||||
/*
|
||||
* Set keycode (which was zero) to the changed modifier
|
||||
*/
|
||||
|
||||
xEvent.xkey.keycode = (modifiers ^ savedModifiers);
|
||||
} else {
|
||||
if (type == NSKeyUp || repeat) {
|
||||
xEvent.xany.type = KeyRelease;
|
||||
} else {
|
||||
xEvent.xany.type = KeyPress;
|
||||
}
|
||||
|
||||
if ([characters length] > 0) {
|
||||
xEvent.xkey.keycode = (keyCode << 16) |
|
||||
(UInt16) [characters characterAtIndex:0];
|
||||
if (![characters getCString:xEvent.xkey.trans_chars
|
||||
maxLength:XMaxTransChars encoding:NSUTF8StringEncoding]) {
|
||||
/* prevent SF bug 2907388 (crash on some composite chars) */
|
||||
//PENDING: we might not need this anymore
|
||||
TkMacOSXDbgMsg("characters too long");
|
||||
return theEvent;
|
||||
}
|
||||
}
|
||||
|
||||
if (repeat) {
|
||||
Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
|
||||
xEvent.xany.type = KeyPress;
|
||||
xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
|
||||
}
|
||||
}
|
||||
Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
|
||||
savedModifiers = modifiers;
|
||||
return theEvent;
|
||||
} /* if this is a function key or has modifiers */
|
||||
} /* if not processing compose */
|
||||
|
||||
if (type == NSKeyDown) {
|
||||
if (NS_KEYLOG) {
|
||||
TKLog(@"keyDown: %s compose sequence.\n",
|
||||
processingCompose == YES ? "Continue" : "Begin");
|
||||
use_text_input = YES;
|
||||
}
|
||||
|
||||
/*
|
||||
* Call the interpretKeyEvents method to interpret composition key
|
||||
* strokes. When it detects a complete composition sequence it will
|
||||
* call our implementation of insertText: replacementRange, which
|
||||
* generates a key down XEvent with the appropriate character. In IME
|
||||
* when multiple characters have the same composition sequence and the
|
||||
* chosen character is not the default it may be necessary to hit the
|
||||
* enter key multiple times before the character is accepted and
|
||||
* rendered. We send enter key events until inputText has cleared
|
||||
* the processingCompose flag.
|
||||
* Apple uses 0x10 for unrecognized keys.
|
||||
*/
|
||||
|
||||
processingCompose = YES;
|
||||
while(processingCompose) {
|
||||
if (keychar == 0x10) {
|
||||
keychar = UNKNOWN_KEYCHAR;
|
||||
}
|
||||
|
||||
#if defined(TK_MAC_DEBUG_EVENTS) || NS_KEYLOG == 1
|
||||
TKLog(@"-[%@(%p) %s] repeat=%d mods=%x char=%x code=%lu c=%d type=%d",
|
||||
[self class], self, _cmd,
|
||||
(type == NSKeyDown) && [theEvent isARepeat], modifiers, keychar,
|
||||
virtual, w, type);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Build a skeleton XEvent. We need to build it here, even if we will not
|
||||
* send it, so we can pass it to TkFocusKeyEvent to determine whether the
|
||||
* target widget can input text.
|
||||
*/
|
||||
|
||||
setupXEvent(&xEvent, tkwin, modifiers);
|
||||
has_modifiers = xEvent.xkey.state & XEVENT_MOD_MASK;
|
||||
focusWinPtr = TkFocusKeyEvent(winPtr, &xEvent);
|
||||
if (focusWinPtr == NULL) {
|
||||
TKContentView *contentView = [w contentView];
|
||||
|
||||
/*
|
||||
* This NSEvent is being sent to a window which does not have focus.
|
||||
* This could mean, for example, that the user deactivated the Tk app
|
||||
* while the NSTextInputClient's popup character selection window was
|
||||
* still open. We attempt to abandon any ongoing composition operation
|
||||
* and discard the event.
|
||||
*/
|
||||
|
||||
[contentView cancelComposingText];
|
||||
return theEvent;
|
||||
}
|
||||
can_input_text = ((focusWinPtr->flags & TK_CAN_INPUT_TEXT) != 0);
|
||||
|
||||
#if (NS_KEYLOG)
|
||||
TKLog(@"keyDown: %s compose sequence.\n",
|
||||
processingCompose == YES ? "Continue" : "Begin");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Decide whether this event should be processed with the NSTextInputClient
|
||||
* protocol.
|
||||
*/
|
||||
|
||||
if (processingCompose ||
|
||||
(type == NSKeyDown && can_input_text && !has_modifiers &&
|
||||
IS_PRINTABLE(keychar))
|
||||
) {
|
||||
use_text_input = YES;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we are processing this KeyDown event as an NSTextInputClient we do
|
||||
* not queue an XEvent. We pass the NSEvent to our interpretKeyEvents
|
||||
* method. When the composition sequence is complete, the callback method
|
||||
* insertText: replacementRange will be called. That method generates a
|
||||
* keyPress XEvent with the selected character.
|
||||
*/
|
||||
|
||||
if (use_text_input) {
|
||||
textInputModifiers = modifiers;
|
||||
|
||||
/*
|
||||
* In IME the Enter key is used to terminate a composition sequence.
|
||||
* When there are multiple choices of input text available, and the
|
||||
* user's selected choice is not the default, it may be necessary to
|
||||
* hit the Enter key multiple times before the text is accepted and
|
||||
* rendered (See ticket 39de9677aa]). So when sending an Enter key
|
||||
* during composition, we continue sending Enter keys until the
|
||||
* inputText method has cleared the processingCompose flag.
|
||||
*/
|
||||
|
||||
if (processingCompose && [theEvent keyCode] == 36) {
|
||||
[nsEvArray addObject: theEvent];
|
||||
while(processingCompose) {
|
||||
[[w contentView] interpretKeyEvents: nsEvArray];
|
||||
}
|
||||
[nsEvArray removeObject: theEvent];
|
||||
} else {
|
||||
[nsEvArray addObject: theEvent];
|
||||
[[w contentView] interpretKeyEvents: nsEvArray];
|
||||
[nsEvArray removeObject: theEvent];
|
||||
if ([theEvent keyCode] != 36) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return theEvent;
|
||||
}
|
||||
savedModifiers = modifiers;
|
||||
|
||||
/*
|
||||
* We are not handling this event as an NSTextInputClient, so we need to
|
||||
* finish constructing the XEvent and queue it.
|
||||
*/
|
||||
|
||||
macKC.v.o_s = ((modifiers & NSShiftKeyMask ? INDEX_SHIFT : 0) |
|
||||
(modifiers & NSAlternateKeyMask ? INDEX_OPTION : 0));
|
||||
macKC.v.virtual = virtual;
|
||||
switch (type) {
|
||||
case NSFlagsChanged:
|
||||
|
||||
/*
|
||||
* This XEvent is a simulated KeyPress or KeyRelease event for a
|
||||
* modifier key. To determine the type, note that the highest bit
|
||||
* where the flags differ is 1 if and only if it is a KeyPress. The
|
||||
* modifiers are saved so we can detect the next flag change.
|
||||
*/
|
||||
|
||||
xEvent.xany.type = modifiers > savedModifiers ? KeyPress : KeyRelease;
|
||||
savedModifiers = modifiers;
|
||||
|
||||
/*
|
||||
* Set the keychar to MOD_KEYCHAR as a signal to TkpGetKeySym (see
|
||||
* tkMacOSXKeyboard.c) that this is a modifier key event.
|
||||
*/
|
||||
|
||||
keychar = MOD_KEYCHAR;
|
||||
break;
|
||||
case NSKeyUp:
|
||||
xEvent.xany.type = KeyRelease;
|
||||
break;
|
||||
case NSKeyDown:
|
||||
xEvent.xany.type = KeyPress;
|
||||
break;
|
||||
default:
|
||||
return theEvent; /* Unrecognized key event. */
|
||||
}
|
||||
macKC.v.keychar = keychar;
|
||||
xEvent.xkey.keycode = macKC.uint;
|
||||
setXEventPoint(&xEvent, tkwin, w);
|
||||
|
||||
/*
|
||||
* Finally we can queue the XEvent, inserting a KeyRelease before a
|
||||
* repeated KeyPress.
|
||||
*/
|
||||
|
||||
if (type == NSKeyDown && [theEvent isARepeat]) {
|
||||
|
||||
xEvent.xany.type = KeyRelease;
|
||||
Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
|
||||
xEvent.xany.type = KeyPress;
|
||||
}
|
||||
Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
|
||||
return theEvent;
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
@implementation TKContentView
|
||||
|
||||
-(id)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_needsRedisplay = NO;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@synthesize tkDirtyRect = _tkDirtyRect;
|
||||
@synthesize tkNeedsDisplay = _tkNeedsDisplay;
|
||||
|
||||
/*
|
||||
* Implementation of the NSTextInputClient protocol.
|
||||
@@ -282,15 +276,18 @@ static unsigned isFunctionKey(unsigned int code);
|
||||
|
||||
/* [NSTextInputClient inputText: replacementRange:] is called by
|
||||
* interpretKeyEvents when a composition sequence is complete. It is also
|
||||
* called when we delete over working text. In that case the call is followed
|
||||
* called when we delete working text. In that case the call is followed
|
||||
* immediately by doCommandBySelector: deleteBackward:
|
||||
*/
|
||||
- (void)insertText: (id)aString
|
||||
replacementRange: (NSRange)repRange
|
||||
{
|
||||
int i, len;
|
||||
int i, len, state;
|
||||
XEvent xEvent;
|
||||
NSString *str;
|
||||
NSString *str, *keystr, *lower;
|
||||
TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
|
||||
Tk_Window tkwin = (Tk_Window)winPtr;
|
||||
Bool sendingIMEText = NO;
|
||||
|
||||
str = ([aString isKindOfClass: [NSAttributedString class]]) ?
|
||||
[aString string] : aString;
|
||||
@@ -300,13 +297,12 @@ static unsigned isFunctionKey(unsigned int code);
|
||||
TKLog(@"insertText '%@'\tlen = %d", aString, len);
|
||||
}
|
||||
|
||||
processingCompose = NO;
|
||||
|
||||
/*
|
||||
* Clear any working text.
|
||||
*/
|
||||
|
||||
if (privateWorkingText != nil) {
|
||||
sendingIMEText = YES;
|
||||
[self deleteWorkingText];
|
||||
}
|
||||
|
||||
@@ -314,7 +310,8 @@ static unsigned isFunctionKey(unsigned int code);
|
||||
* Insert the string as a sequence of keystrokes.
|
||||
*/
|
||||
|
||||
setupXEvent(&xEvent, [self window], 0);
|
||||
setupXEvent(&xEvent, tkwin, textInputModifiers);
|
||||
setXEventPoint(&xEvent, tkwin, [self window]);
|
||||
xEvent.xany.type = KeyPress;
|
||||
|
||||
/*
|
||||
@@ -325,37 +322,54 @@ static unsigned isFunctionKey(unsigned int code);
|
||||
*/
|
||||
|
||||
if (repRange.location == 0) {
|
||||
TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
|
||||
Tk_Window focusWin = (Tk_Window) winPtr->dispPtr->focusPtr;
|
||||
Tk_Window focusWin = (Tk_Window)winPtr->dispPtr->focusPtr;
|
||||
TkSendVirtualEvent(focusWin, "TkAccentBackspace", NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Next we generate an XEvent for each unicode character in our string.
|
||||
* This string could contain non-BMP characters, for example if the
|
||||
* emoji palette was used.
|
||||
*
|
||||
* NSString uses UTF-16 internally, which means that a non-BMP character is
|
||||
* represented by a sequence of two 16-bit "surrogates". In principle we
|
||||
* could record this in the XEvent by setting the keycode to the 32-bit
|
||||
* unicode code point and setting the trans_chars string to the 4-byte
|
||||
* UTF-8 string for the non-BMP character. However, that will not work
|
||||
* when TCL_UTF_MAX is set to 3, as is the case for Tcl 8.6. A workaround
|
||||
* used internally by Tcl 8.6 is to encode each surrogate as a 3-byte
|
||||
* sequence using the UTF-8 algorithm (ignoring the fact that the UTF-8
|
||||
* encoding specification does not allow encoding UTF-16 surrogates).
|
||||
* This gives a 6-byte encoding of the non-BMP character which we write into
|
||||
* the trans_chars field of the XEvent.
|
||||
* represented by a sequence of two 16-bit "surrogates". We record this in
|
||||
* the XEvent by setting the low order 21-bits of the keycode to the UCS-32
|
||||
* value value of the character and the virtual keycode in the high order
|
||||
* byte to the special value NON_BMP.
|
||||
*/
|
||||
|
||||
state = xEvent.xkey.state;
|
||||
for (i = 0; i < len; i++) {
|
||||
xEvent.xkey.nbytes = TclUniAtIndex(str, i, xEvent.xkey.trans_chars,
|
||||
&xEvent.xkey.keycode);
|
||||
if (xEvent.xkey.keycode > 0xffff){
|
||||
i++;
|
||||
UniChar keychar;
|
||||
MacKeycode macKC = {0};
|
||||
|
||||
keychar = [str characterAtIndex:i];
|
||||
macKC.v.keychar = keychar;
|
||||
if (CFStringIsSurrogateHighCharacter(keychar)) {
|
||||
UniChar lowChar = [str characterAtIndex:++i];
|
||||
macKC.v.keychar = CFStringGetLongCharacterForSurrogatePair(
|
||||
(UniChar)keychar, lowChar);
|
||||
macKC.v.virtual = NON_BMP_VIRTUAL;
|
||||
} else if (repRange.location == 0 || sendingIMEText) {
|
||||
macKC.v.virtual = REPLACEMENT_VIRTUAL;
|
||||
} else {
|
||||
macKC.uint = TkMacOSXAddVirtual(macKC.uint);
|
||||
xEvent.xkey.state |= INDEX2STATE(macKC.x.xvirtual);
|
||||
}
|
||||
keystr = [[NSString alloc] initWithCharacters:&keychar length:1];
|
||||
lower = [keystr lowercaseString];
|
||||
if (![keystr isEqual: lower]) {
|
||||
macKC.v.o_s |= INDEX_SHIFT;
|
||||
xEvent.xkey.state |= ShiftMask;
|
||||
}
|
||||
if (xEvent.xkey.state & Mod2Mask) {
|
||||
macKC.v.o_s |= INDEX_OPTION;
|
||||
}
|
||||
xEvent.xkey.keycode = macKC.uint;
|
||||
xEvent.xany.type = KeyPress;
|
||||
Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
|
||||
xEvent.xkey.state = state;
|
||||
}
|
||||
releaseCode = (UInt16) [str characterAtIndex: 0];
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -379,13 +393,12 @@ static unsigned isFunctionKey(unsigned int code);
|
||||
replacementRange: (NSRange)repRange
|
||||
{
|
||||
TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
|
||||
Tk_Window focusWin = (Tk_Window) winPtr->dispPtr->focusPtr;
|
||||
Tk_Window focusWin = (Tk_Window)winPtr->dispPtr->focusPtr;
|
||||
NSString *temp;
|
||||
NSString *str;
|
||||
|
||||
str = ([aString isKindOfClass: [NSAttributedString class]]) ?
|
||||
[aString string] : aString;
|
||||
|
||||
if (focusWin) {
|
||||
|
||||
/*
|
||||
@@ -416,10 +429,10 @@ static unsigned isFunctionKey(unsigned int code);
|
||||
*/
|
||||
|
||||
TkSendVirtualEvent(focusWin, "TkStartIMEMarkedText", NULL);
|
||||
processingCompose = YES;
|
||||
temp = [str copy];
|
||||
[self insertText: temp replacementRange:repRange];
|
||||
privateWorkingText = temp;
|
||||
processingCompose = YES;
|
||||
TkSendVirtualEvent(focusWin, "TkEndIMEMarkedText", NULL);
|
||||
}
|
||||
|
||||
@@ -428,7 +441,6 @@ static unsigned isFunctionKey(unsigned int code);
|
||||
return privateWorkingText != nil;
|
||||
}
|
||||
|
||||
|
||||
- (NSRange)markedRange
|
||||
{
|
||||
NSRange rng = privateWorkingText != nil
|
||||
@@ -441,15 +453,6 @@ static unsigned isFunctionKey(unsigned int code);
|
||||
return rng;
|
||||
}
|
||||
|
||||
- (void)cancelComposingText
|
||||
{
|
||||
if (NS_KEYLOG) {
|
||||
TKLog(@"cancelComposingText");
|
||||
}
|
||||
[self deleteWorkingText];
|
||||
processingCompose = NO;
|
||||
}
|
||||
|
||||
- (void)unmarkText
|
||||
{
|
||||
if (NS_KEYLOG) {
|
||||
@@ -459,7 +462,6 @@ static unsigned isFunctionKey(unsigned int code);
|
||||
processingCompose = NO;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Called by the system to get a position for popup character selection windows
|
||||
* such as a Character Palette, or a selection menu for IME.
|
||||
@@ -496,7 +498,7 @@ static unsigned isFunctionKey(unsigned int code);
|
||||
processingCompose = NO;
|
||||
if (aSelector == @selector (deleteBackward:)) {
|
||||
TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
|
||||
Tk_Window focusWin = (Tk_Window) winPtr->dispPtr->focusPtr;
|
||||
Tk_Window focusWin = (Tk_Window)winPtr->dispPtr->focusPtr;
|
||||
TkSendVirtualEvent(focusWin, "TkAccentBackspace", NULL);
|
||||
}
|
||||
}
|
||||
@@ -543,7 +545,6 @@ static unsigned isFunctionKey(unsigned int code);
|
||||
}
|
||||
/* End of NSTextInputClient implementation. */
|
||||
|
||||
@synthesize needsRedisplay = _needsRedisplay;
|
||||
@end
|
||||
|
||||
|
||||
@@ -573,6 +574,16 @@ static unsigned isFunctionKey(unsigned int code);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)cancelComposingText
|
||||
{
|
||||
if (NS_KEYLOG) {
|
||||
TKLog(@"cancelComposingText");
|
||||
}
|
||||
[self deleteWorkingText];
|
||||
processingCompose = NO;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
/*
|
||||
@@ -580,21 +591,29 @@ static unsigned isFunctionKey(unsigned int code);
|
||||
*/
|
||||
|
||||
static void
|
||||
setupXEvent(XEvent *xEvent, NSWindow *w, unsigned int state)
|
||||
setupXEvent(XEvent *xEvent, Tk_Window tkwin, NSUInteger modifiers)
|
||||
{
|
||||
TkWindow *winPtr = TkMacOSXGetTkWindow(w);
|
||||
Tk_Window tkwin = (Tk_Window) winPtr;
|
||||
unsigned int state = 0;
|
||||
Display *display = Tk_Display(tkwin);
|
||||
|
||||
if (!winPtr) {
|
||||
if (tkwin == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (modifiers) {
|
||||
state = (modifiers & NSAlphaShiftKeyMask ? LockMask : 0) |
|
||||
(modifiers & NSShiftKeyMask ? ShiftMask : 0) |
|
||||
(modifiers & NSControlKeyMask ? ControlMask : 0) |
|
||||
(modifiers & NSCommandKeyMask ? Mod1Mask : 0) |
|
||||
(modifiers & NSAlternateKeyMask ? Mod2Mask : 0) |
|
||||
(modifiers & NSNumericPadKeyMask ? Mod3Mask : 0) |
|
||||
(modifiers & NSFunctionKeyMask ? Mod4Mask : 0) ;
|
||||
}
|
||||
memset(xEvent, 0, sizeof(XEvent));
|
||||
xEvent->xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
|
||||
xEvent->xany.serial = LastKnownRequestProcessed(display);
|
||||
xEvent->xany.display = Tk_Display(tkwin);
|
||||
xEvent->xany.window = Tk_WindowId(tkwin);
|
||||
|
||||
xEvent->xkey.root = XRootWindow(Tk_Display(tkwin), 0);
|
||||
xEvent->xkey.root = XRootWindow(display, 0);
|
||||
xEvent->xkey.time = TkpGetMS();
|
||||
xEvent->xkey.state = state;
|
||||
xEvent->xkey.same_screen = true;
|
||||
@@ -602,6 +621,41 @@ setupXEvent(XEvent *xEvent, NSWindow *w, unsigned int state)
|
||||
* because of the memset() above. */
|
||||
}
|
||||
|
||||
static void
|
||||
setXEventPoint(
|
||||
XEvent *xEvent,
|
||||
Tk_Window tkwin,
|
||||
NSWindow *w)
|
||||
{
|
||||
TkWindow *winPtr = (TkWindow *) tkwin;
|
||||
NSPoint local = [w mouseLocationOutsideOfEventStream];
|
||||
NSPoint global = [w tkConvertPointToScreen: local];
|
||||
int win_x, win_y;
|
||||
|
||||
if (Tk_IsEmbedded(winPtr)) {
|
||||
TkWindow *contPtr = TkpGetOtherWindow(winPtr);
|
||||
if (Tk_IsTopLevel(contPtr)) {
|
||||
local.x -= contPtr->wmInfoPtr->xInParent;
|
||||
local.y -= contPtr->wmInfoPtr->yInParent;
|
||||
} else {
|
||||
TkWindow *topPtr = TkMacOSXGetHostToplevel(winPtr)->winPtr;
|
||||
local.x -= (topPtr->wmInfoPtr->xInParent + contPtr->changes.x);
|
||||
local.y -= (topPtr->wmInfoPtr->yInParent + contPtr->changes.y);
|
||||
}
|
||||
} else if (winPtr->wmInfoPtr != NULL) {
|
||||
local.x -= winPtr->wmInfoPtr->xInParent;
|
||||
local.y -= winPtr->wmInfoPtr->yInParent;
|
||||
}
|
||||
tkwin = Tk_TopCoordsToWindow(tkwin, local.x, local.y, &win_x, &win_y);
|
||||
local.x = win_x;
|
||||
local.y = win_y;
|
||||
global.y = TkMacOSXZeroScreenHeight() - global.y;
|
||||
xEvent->xbutton.x = local.x;
|
||||
xEvent->xbutton.y = local.y;
|
||||
xEvent->xbutton.x_root = global.x;
|
||||
xEvent->xbutton.y_root = global.y;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
/*
|
||||
@@ -633,8 +687,8 @@ XGrabKeyboard(
|
||||
TkWindow *captureWinPtr = (TkWindow *) TkpGetCapture();
|
||||
|
||||
if (keyboardGrabWinPtr && captureWinPtr) {
|
||||
NSWindow *w = TkMacOSXDrawableWindow(grab_window);
|
||||
MacDrawable *macWin = (MacDrawable *) grab_window;
|
||||
NSWindow *w = TkMacOSXGetNSWindowForDrawable(grab_window);
|
||||
MacDrawable *macWin = (MacDrawable *)grab_window;
|
||||
|
||||
if (w && macWin->toplevel->winPtr == (TkWindow *) captureWinPtr) {
|
||||
if (modalSession) {
|
||||
@@ -706,15 +760,22 @@ TkMacOSXGetModalSession(void)
|
||||
*
|
||||
* Tk_SetCaretPos --
|
||||
*
|
||||
* This enables correct placement of the XIM caret. This is called by
|
||||
* widgets to indicate their cursor placement, and the caret location is
|
||||
* used by TkpGetString to place the XIM caret.
|
||||
* This enables correct placement of the popups used for character
|
||||
* selection by the NSTextInputClient. It gets called by text entry
|
||||
* widgets whenever the cursor is drawn. It does nothing if the widget's
|
||||
* NSWindow is not the current KeyWindow. Otherwise it updates the
|
||||
* display's caret structure and records the caret geometry in static
|
||||
* variables for use by the NSTextInputClient implementation. Any
|
||||
* widget passed to this function will be marked as being able to input
|
||||
* text by setting the TK_CAN_INPUT_TEXT flag.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
* Sets the CAN_INPUT_TEXT flag on the widget passed as tkwin. May update
|
||||
* the display's caret structure as well as the static variables caret_x,
|
||||
* caret_y and caret_height.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
@@ -726,27 +787,40 @@ Tk_SetCaretPos(
|
||||
int y,
|
||||
int height)
|
||||
{
|
||||
TkCaret *caretPtr = &(((TkWindow *) tkwin)->dispPtr->caret);
|
||||
TkWindow *winPtr = (TkWindow *) tkwin;
|
||||
TkCaret *caretPtr = &(winPtr->dispPtr->caret);
|
||||
NSWindow *w = TkMacOSXGetNSWindowForDrawable(Tk_WindowId(tkwin));
|
||||
|
||||
/*
|
||||
* Prevent processing anything if the values haven't changed. Windows only
|
||||
* has one display, so we can do this with statics.
|
||||
* Register this widget as being capable of text input, so we know we
|
||||
* should process (appropriate) key events for this window with the
|
||||
* NSTextInputClient protocol.
|
||||
*/
|
||||
|
||||
if ((caretPtr->winPtr == ((TkWindow *) tkwin))
|
||||
&& (caretPtr->x == x) && (caretPtr->y == y)) {
|
||||
winPtr->flags |= TK_CAN_INPUT_TEXT;
|
||||
if (w && ![w isKeyWindow]) {
|
||||
return;
|
||||
}
|
||||
if ((caretPtr->winPtr == winPtr
|
||||
&& caretPtr->x == x) && (caretPtr->y == y)) {
|
||||
return;
|
||||
}
|
||||
|
||||
caretPtr->winPtr = ((TkWindow *) tkwin);
|
||||
/*
|
||||
* Update the display's caret information.
|
||||
*/
|
||||
|
||||
caretPtr->winPtr = winPtr;
|
||||
caretPtr->x = x;
|
||||
caretPtr->y = y;
|
||||
caretPtr->height = height;
|
||||
|
||||
/*
|
||||
* As in Windows, adjust to the toplevel to get the coords right.
|
||||
* Record the caret geometry in static variables for use when processing
|
||||
* key events. We use the TKContextView coordinate system for this.
|
||||
*/
|
||||
|
||||
caret_height = height;
|
||||
while (!Tk_IsTopLevel(tkwin)) {
|
||||
x += Tk_X(tkwin);
|
||||
y += Tk_Y(tkwin);
|
||||
@@ -755,94 +829,8 @@ Tk_SetCaretPos(
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* But adjust for fact that NS uses flipped view.
|
||||
*/
|
||||
|
||||
y = Tk_Height(tkwin) - y;
|
||||
|
||||
caret_x = x;
|
||||
caret_y = y;
|
||||
caret_height = height;
|
||||
}
|
||||
|
||||
|
||||
static unsigned convert_ns_to_X_keysym[] =
|
||||
{
|
||||
NSHomeFunctionKey, 0x50,
|
||||
NSLeftArrowFunctionKey, 0x51,
|
||||
NSUpArrowFunctionKey, 0x52,
|
||||
NSRightArrowFunctionKey, 0x53,
|
||||
NSDownArrowFunctionKey, 0x54,
|
||||
NSPageUpFunctionKey, 0x55,
|
||||
NSPageDownFunctionKey, 0x56,
|
||||
NSEndFunctionKey, 0x57,
|
||||
NSBeginFunctionKey, 0x58,
|
||||
NSSelectFunctionKey, 0x60,
|
||||
NSPrintFunctionKey, 0x61,
|
||||
NSExecuteFunctionKey, 0x62,
|
||||
NSInsertFunctionKey, 0x63,
|
||||
NSUndoFunctionKey, 0x65,
|
||||
NSRedoFunctionKey, 0x66,
|
||||
NSMenuFunctionKey, 0x67,
|
||||
NSFindFunctionKey, 0x68,
|
||||
NSHelpFunctionKey, 0x6A,
|
||||
NSBreakFunctionKey, 0x6B,
|
||||
|
||||
NSF1FunctionKey, 0xBE,
|
||||
NSF2FunctionKey, 0xBF,
|
||||
NSF3FunctionKey, 0xC0,
|
||||
NSF4FunctionKey, 0xC1,
|
||||
NSF5FunctionKey, 0xC2,
|
||||
NSF6FunctionKey, 0xC3,
|
||||
NSF7FunctionKey, 0xC4,
|
||||
NSF8FunctionKey, 0xC5,
|
||||
NSF9FunctionKey, 0xC6,
|
||||
NSF10FunctionKey, 0xC7,
|
||||
NSF11FunctionKey, 0xC8,
|
||||
NSF12FunctionKey, 0xC9,
|
||||
NSF13FunctionKey, 0xCA,
|
||||
NSF14FunctionKey, 0xCB,
|
||||
NSF15FunctionKey, 0xCC,
|
||||
NSF16FunctionKey, 0xCD,
|
||||
NSF17FunctionKey, 0xCE,
|
||||
NSF18FunctionKey, 0xCF,
|
||||
NSF19FunctionKey, 0xD0,
|
||||
NSF20FunctionKey, 0xD1,
|
||||
NSF21FunctionKey, 0xD2,
|
||||
NSF22FunctionKey, 0xD3,
|
||||
NSF23FunctionKey, 0xD4,
|
||||
NSF24FunctionKey, 0xD5,
|
||||
|
||||
NSBackspaceCharacter, 0x08, /* 8: Not on some KBs. */
|
||||
NSDeleteCharacter, 0xFF, /* 127: Big 'delete' key upper right. */
|
||||
NSDeleteFunctionKey, 0x9F, /* 63272: Del forw key off main array. */
|
||||
|
||||
NSTabCharacter, 0x09,
|
||||
0x19, 0x09, /* left tab->regular since pass shift */
|
||||
NSCarriageReturnCharacter, 0x0D,
|
||||
NSNewlineCharacter, 0x0D,
|
||||
NSEnterCharacter, 0x8D,
|
||||
|
||||
0x1B, 0x1B /* escape */
|
||||
};
|
||||
|
||||
|
||||
static unsigned
|
||||
isFunctionKey(
|
||||
unsigned code)
|
||||
{
|
||||
const unsigned last_keysym = (sizeof(convert_ns_to_X_keysym)
|
||||
/ sizeof(convert_ns_to_X_keysym[0]));
|
||||
unsigned keysym;
|
||||
|
||||
for (keysym = 0; keysym < last_keysym; keysym += 2) {
|
||||
if (code == convert_ns_to_X_keysym[keysym]) {
|
||||
return 0xFF00 | convert_ns_to_X_keysym[keysym + 1];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
caret_y = Tk_Height(tkwin) - y;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
1308
macosx/tkMacOSXKeysyms.h
Normal file
1308
macosx/tkMacOSXKeysyms.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -36,19 +36,19 @@
|
||||
#define SPECIALMENU(n, f) {.name = "." #n, .len = sl(#n) + 1, \
|
||||
.flag = ENTRY_##f##_MENU }
|
||||
static const struct {
|
||||
const char *name; const size_t len; const int flag;
|
||||
const char *name; size_t len; int flag;
|
||||
} specialMenus[] = {
|
||||
SPECIALMENU(help, HELP),
|
||||
SPECIALMENU(apple, APPLE),
|
||||
SPECIALMENU(window, WINDOWS),
|
||||
{NULL}
|
||||
{NULL, 0, 0}
|
||||
};
|
||||
#undef SPECIALMENU
|
||||
|
||||
#define MODIFIER(n, f) {.name = #n, .len = sl(#n), .mask = f }
|
||||
static const struct {
|
||||
const char *name; const size_t len; const NSUInteger mask;
|
||||
} modifiers[] = {
|
||||
const char *name; size_t len; NSUInteger mask;
|
||||
} allModifiers[] = {
|
||||
MODIFIER(Control, NSControlKeyMask),
|
||||
MODIFIER(Ctrl, NSControlKeyMask),
|
||||
MODIFIER(Option, NSAlternateKeyMask),
|
||||
@@ -58,13 +58,13 @@ static const struct {
|
||||
MODIFIER(Command, NSCommandKeyMask),
|
||||
MODIFIER(Cmd, NSCommandKeyMask),
|
||||
MODIFIER(Meta, NSCommandKeyMask),
|
||||
{NULL}
|
||||
{NULL, 0, 0}
|
||||
};
|
||||
#undef MODIFIER
|
||||
|
||||
#define ACCEL(n, c) {.name = #n, .len = sl(#n), .ch = c }
|
||||
static const struct {
|
||||
const char *name; const size_t len; const UniChar ch;
|
||||
const char *name; size_t len; UniChar ch;
|
||||
} specialAccelerators[] = {
|
||||
ACCEL(PageUp, NSPageUpFunctionKey),
|
||||
ACCEL(PageDown, NSPageDownFunctionKey),
|
||||
@@ -86,7 +86,7 @@ static const struct {
|
||||
ACCEL(Help, NSHelpFunctionKey),
|
||||
ACCEL(Power, 0x233d),
|
||||
ACCEL(Eject, 0xf804),
|
||||
{NULL}
|
||||
{NULL, 0, 0}
|
||||
};
|
||||
#undef ACCEL
|
||||
#undef sl
|
||||
@@ -95,7 +95,6 @@ static int gNoTkMenus = 0; /* This is used by Tk_MacOSXTurnOffMenus as
|
||||
* the flag that Tk is not to draw any
|
||||
* menus. */
|
||||
static int inPostMenu = 0;
|
||||
static unsigned long defaultBg = 0, defaultFg = 0;
|
||||
static SInt32 menuMarkColumnWidth = 0, menuIconTrailingEdgeMargin = 0;
|
||||
static SInt32 menuTextLeadingEdgeMargin = 0, menuTextTrailingEdgeMargin = 0;
|
||||
static SInt16 menuItemExtraHeight = 0, menuItemExtraWidth = 0;
|
||||
@@ -108,6 +107,67 @@ static void MenuSelectEvent(TkMenu *menuPtr);
|
||||
static void RecursivelyClearActiveMenu(TkMenu *menuPtr);
|
||||
static int ModifierCharWidth(Tk_Font tkfont);
|
||||
|
||||
#pragma mark TkBackgroundLoop
|
||||
|
||||
/*
|
||||
* The function TkMacOSXEventsCheckProc (in tkMacOSXNotify.c) is the "check
|
||||
* proc" for the macOS event source. Its job is to remove NSEvents from the
|
||||
* default event queue of the NSApplication. It does this by calling the
|
||||
* method [NSApp nextEventMatchingMask: untilDate: inMode: dequeue:]. As a
|
||||
* rule, when the untilDate is set to the distant past this method returns
|
||||
* immediately. An exception to that rule is when the next event is the button
|
||||
* press on a menu button. In that case, the method starts running a nested
|
||||
* event loop in the mode NSEventTrackingRunLoopMode which does not return
|
||||
* until the menu has been dismissed. In Tk 8.6.10 and earlier, this meant
|
||||
* that the Tk event loop would block in its call to the check proc as long as
|
||||
* the menu was posted. For example, opening a menu during the Rube Goldberg
|
||||
* demo would cause the animation to stop. This was also the case for
|
||||
* menubuttons.
|
||||
*
|
||||
* The TKBackground object below works around this problem, and allows a Tk
|
||||
* event loop to run while a menu is open. It is a subclass of NSThread which
|
||||
* inserts requests to call [NSApp _runBackgroundLoop] onto the queue
|
||||
* associated with the NSEventTrackingRunLoopMode. One of these threads gets
|
||||
* started in the callback [NSApp menuBeginTracking] and cancelled in [NSApp
|
||||
* menuEndTracking].
|
||||
*/
|
||||
|
||||
@interface TKBackgroundLoop: NSThread
|
||||
@end
|
||||
|
||||
@implementation TKBackgroundLoop
|
||||
- (void) main
|
||||
{
|
||||
NSAutoreleasePool *pool = [NSAutoreleasePool new];
|
||||
NSArray *modeArray = [NSArray arrayWithObjects: NSEventTrackingRunLoopMode,
|
||||
nil];
|
||||
while(1) {
|
||||
|
||||
/*
|
||||
* Queue a request to process Tk events during event tracking.
|
||||
*/
|
||||
|
||||
[NSApp performSelectorOnMainThread:@selector(_runBackgroundLoop)
|
||||
withObject:nil
|
||||
waitUntilDone:true
|
||||
modes:modeArray];
|
||||
if ([self isCancelled]) {
|
||||
[NSThread exit];
|
||||
}
|
||||
|
||||
/*
|
||||
* Allow the tracked events to be processed too.
|
||||
*/
|
||||
|
||||
[NSThread sleepForTimeInterval:0.001];
|
||||
}
|
||||
[pool drain];
|
||||
}
|
||||
@end
|
||||
|
||||
TKBackgroundLoop *backgroundLoop = nil;
|
||||
|
||||
|
||||
#pragma mark TKMenu
|
||||
|
||||
/*
|
||||
@@ -259,12 +319,6 @@ 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.
|
||||
*/
|
||||
|
||||
//Tcl_Sleep(100);
|
||||
Tcl_Preserve(interp);
|
||||
Tcl_Preserve(menuPtr);
|
||||
|
||||
@@ -287,6 +341,8 @@ static int ModifierCharWidth(Tk_Font tkfont);
|
||||
- (BOOL) menuHasKeyEquivalent: (NSMenu *) menu forEvent: (NSEvent *) event
|
||||
target: (id *) target action: (SEL *) action
|
||||
{
|
||||
(void)menu;
|
||||
|
||||
/*
|
||||
* Use lowercaseString when comparing keyEquivalents since the notion of
|
||||
* a shifted upper case letter does not make much sense.
|
||||
@@ -343,6 +399,8 @@ static int ModifierCharWidth(Tk_Font tkfont);
|
||||
|
||||
- (void) menuWillOpen: (NSMenu *) menu
|
||||
{
|
||||
(void)menu;
|
||||
|
||||
if (_tkMenu) {
|
||||
//RecursivelyClearActiveMenu(_tkMenu);
|
||||
GenerateMenuSelectEvent((TKMenu *)[self supermenu],
|
||||
@@ -352,6 +410,8 @@ static int ModifierCharWidth(Tk_Font tkfont);
|
||||
|
||||
- (void) menuDidClose: (NSMenu *) menu
|
||||
{
|
||||
(void)menu;
|
||||
|
||||
if (_tkMenu) {
|
||||
RecursivelyClearActiveMenu(_tkMenu);
|
||||
}
|
||||
@@ -359,6 +419,8 @@ static int ModifierCharWidth(Tk_Font tkfont);
|
||||
|
||||
- (void) menu: (NSMenu *) menu willHighlightItem: (NSMenuItem *) item
|
||||
{
|
||||
(void)menu;
|
||||
|
||||
if (_tkMenu) {
|
||||
GenerateMenuSelectEvent(self, item);
|
||||
}
|
||||
@@ -367,6 +429,7 @@ static int ModifierCharWidth(Tk_Font tkfont);
|
||||
- (void) menuNeedsUpdate: (NSMenu *) menu
|
||||
{
|
||||
TkMenu *menuPtr = (TkMenu *) _tkMenu;
|
||||
(void)menu;
|
||||
|
||||
if (menuPtr) {
|
||||
Tcl_Interp *interp = menuPtr->interp;
|
||||
@@ -392,18 +455,31 @@ static int ModifierCharWidth(Tk_Font tkfont);
|
||||
|
||||
- (void) menuBeginTracking: (NSNotification *) notification
|
||||
{
|
||||
(void)notification;
|
||||
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
|
||||
TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
|
||||
#endif
|
||||
if (backgroundLoop) {
|
||||
[backgroundLoop cancel];
|
||||
[backgroundLoop release];
|
||||
}
|
||||
backgroundLoop = [[TKBackgroundLoop alloc] init];
|
||||
[backgroundLoop start];
|
||||
//TkMacOSXClearMenubarActive();
|
||||
//TkMacOSXPreprocessMenu();
|
||||
}
|
||||
|
||||
- (void) menuEndTracking: (NSNotification *) notification
|
||||
{
|
||||
(void)notification;
|
||||
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
|
||||
TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
|
||||
#endif
|
||||
if (backgroundLoop) {
|
||||
[backgroundLoop cancel];
|
||||
[backgroundLoop release];
|
||||
backgroundLoop = nil;
|
||||
}
|
||||
if (!inPostMenu) {
|
||||
TkMacOSXClearMenubarActive();
|
||||
}
|
||||
@@ -610,7 +686,6 @@ TkpConfigureMenuEntry(
|
||||
NSString *keyEquivalent = @"";
|
||||
NSUInteger modifierMask = NSCommandKeyMask;
|
||||
NSMenu *submenu = nil;
|
||||
NSDictionary *attributes;
|
||||
int imageWidth, imageHeight;
|
||||
GC gc = (mePtr->textGC ? mePtr->textGC : mePtr->menuPtr->textGC);
|
||||
Tcl_Obj *fontPtr = (mePtr->fontPtr ? mePtr->fontPtr :
|
||||
@@ -618,7 +693,7 @@ TkpConfigureMenuEntry(
|
||||
|
||||
if (mePtr->image) {
|
||||
Tk_SizeOfImage(mePtr->image, &imageWidth, &imageHeight);
|
||||
image = TkMacOSXGetNSImageWithTkImage(mePtr->menuPtr->display,
|
||||
image = TkMacOSXGetNSImageFromTkImage(mePtr->menuPtr->display,
|
||||
mePtr->image, imageWidth, imageHeight);
|
||||
} else if (mePtr->bitmapPtr != None) {
|
||||
Pixmap bitmap = Tk_GetBitmapFromObj(mePtr->menuPtr->tkwin,
|
||||
@@ -626,12 +701,9 @@ TkpConfigureMenuEntry(
|
||||
|
||||
Tk_SizeOfBitmap(mePtr->menuPtr->display, bitmap, &imageWidth,
|
||||
&imageHeight);
|
||||
image = TkMacOSXGetNSImageWithBitmap(mePtr->menuPtr->display, bitmap,
|
||||
image = TkMacOSXGetNSImageFromBitmap(mePtr->menuPtr->display, bitmap,
|
||||
gc, imageWidth, imageHeight);
|
||||
if (gc->foreground == defaultFg) {
|
||||
// Use a semantic foreground color by default
|
||||
[image setTemplate:YES];
|
||||
}
|
||||
[image setTemplate:YES];
|
||||
}
|
||||
[menuItem setImage:image];
|
||||
if ((!image || mePtr->compound != COMPOUND_NONE) && mePtr->labelPtr &&
|
||||
@@ -645,25 +717,50 @@ TkpConfigureMenuEntry(
|
||||
}
|
||||
}
|
||||
[menuItem setTitle:title];
|
||||
if (strcmp(Tcl_GetString(fontPtr), "menu") || gc->foreground != defaultFg
|
||||
|| gc->background != defaultBg) {
|
||||
attributes = TkMacOSXNSFontAttributesForFont(Tk_GetFontFromObj(
|
||||
mePtr->menuPtr->tkwin, fontPtr));
|
||||
if (gc->foreground != defaultFg || gc->background != defaultBg) {
|
||||
NSColor *color = TkMacOSXGetNSColor(gc,
|
||||
gc->foreground!=defaultFg? gc->foreground:gc->background);
|
||||
|
||||
attributes = [[attributes mutableCopy] autorelease];
|
||||
[(NSMutableDictionary *) attributes setObject:color
|
||||
forKey:NSForegroundColorAttributeName];
|
||||
}
|
||||
if (attributes) {
|
||||
attributedTitle = [[[NSAttributedString alloc]
|
||||
initWithString:title attributes:attributes] autorelease];
|
||||
}
|
||||
#if 0
|
||||
|
||||
/*
|
||||
* The -background and -foreground options are now ignored in Aqua.
|
||||
* See ticket [635167af14].
|
||||
*/
|
||||
|
||||
NSDictionary fontAttributes = TkMacOSXNSFontAttributesForFont(
|
||||
Tk_GetFontFromObj(mePtr->menuPtr->tkwin, fontPtr));
|
||||
NSMutableDictionary *attributes = [fontAttributes mutableCopy];
|
||||
static unsigned long defaultBg = 0, defaultFg = 0;
|
||||
if (defaultBg == 0) {
|
||||
tkColor *tkColPtr = TkpGetColor(NULL, DEF_MENU_BG_COLOR);
|
||||
defaultBg = tkColPtr->color.pixel;
|
||||
ckfree(tkColPtr);
|
||||
}
|
||||
if (defaultFg == 0) {
|
||||
tkColor *tkColPtr = TkpGetColor(NULL, DEF_MENU_FG);
|
||||
defaultFg = tkColPtr->color.pixel;
|
||||
ckfree(tkColPtr);
|
||||
}
|
||||
if (gc->foreground != defaultFg) {
|
||||
NSColor *fgcolor = TkMacOSXGetNSColor(gc, gc->foreground);
|
||||
[attributes setObject:fgcolor
|
||||
forKey:NSForegroundColorAttributeName];
|
||||
}
|
||||
if (gc->background != defaultBg) {
|
||||
NSColor *bgcolor = TkMacOSXGetNSColor(gc, gc->background);
|
||||
[attributes setObject:bgcolor
|
||||
forKey:NSBackgroundColorAttributeName];
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
NSDictionary *attributes = TkMacOSXNSFontAttributesForFont(
|
||||
Tk_GetFontFromObj(mePtr->menuPtr->tkwin, fontPtr));
|
||||
|
||||
#endif
|
||||
|
||||
attributedTitle = [[NSAttributedString alloc] initWithString:title
|
||||
attributes:attributes];
|
||||
[menuItem setAttributedTitle:attributedTitle];
|
||||
[menuItem setEnabled:!(mePtr->state == ENTRY_DISABLED)];
|
||||
[menuItem setEnabled:(mePtr->state != ENTRY_DISABLED)];
|
||||
[menuItem setState:((mePtr->type == CHECK_BUTTON_ENTRY ||
|
||||
mePtr->type == RADIO_BUTTON_ENTRY) && mePtr->indicatorOn &&
|
||||
(mePtr->entryFlags & ENTRY_SELECTED) ? NSOnState : NSOffState)];
|
||||
@@ -696,27 +793,17 @@ TkpConfigureMenuEntry(
|
||||
if ([menuItem isEnabled]) {
|
||||
|
||||
/*
|
||||
* This menuItem might have been previously disabled (XXX:
|
||||
* track this), which would have disabled entries; we must
|
||||
* re-enable the entries here.
|
||||
* This menuItem might have been previously disabled which
|
||||
* would have disabled all of its entries; we must re-enable the
|
||||
* entries here. It is important to iterate though the Tk
|
||||
* entries, not the NSMenuItems, since some NSMenuItems may
|
||||
* have been added by the system. See [7185d26cf4].
|
||||
*/
|
||||
|
||||
int i = 0;
|
||||
NSArray *itemArray = [submenu itemArray];
|
||||
|
||||
for (NSMenuItem *item in itemArray) {
|
||||
for (int i = 0; i < menuRefPtr->menuPtr->numEntries; i++) {
|
||||
TkMenuEntry *submePtr = menuRefPtr->menuPtr->entries[i];
|
||||
|
||||
/*
|
||||
* Work around an apparent bug where itemArray can have
|
||||
* more items than the menu's entries[] array.
|
||||
*/
|
||||
|
||||
if (i >= (int) menuRefPtr->menuPtr->numEntries) {
|
||||
break;
|
||||
}
|
||||
[item setEnabled: !(submePtr->state == ENTRY_DISABLED)];
|
||||
i++;
|
||||
NSMenuItem *item = (NSMenuItem *) submePtr->platformEntryData;
|
||||
[item setEnabled:(submePtr->state != ENTRY_DISABLED)];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -785,7 +872,7 @@ TkpDestroyMenuEntry(
|
||||
|
||||
int
|
||||
TkpPostMenu(
|
||||
Tcl_Interp *interp, /* The interpreter this menu lives in */
|
||||
TCL_UNUSED(Tcl_Interp *), /* The interpreter this menu lives in */
|
||||
TkMenu *menuPtr, /* The menu we are posting */
|
||||
int x, int y, /* The screen coordinates where the top left
|
||||
* corner of the menu, or of the specified
|
||||
@@ -809,7 +896,7 @@ TkpPostMenu(
|
||||
* rather than the appearance of the root window.
|
||||
*/
|
||||
realWinPtr = (TkWindow*) realWin;
|
||||
realWinView = TkMacOSXDrawableView(realWinPtr->privatePtr);
|
||||
realWinView = TkMacOSXGetNSViewForDrawable(realWinPtr->privatePtr);
|
||||
if (realWinView != nil) {
|
||||
break;
|
||||
}
|
||||
@@ -882,7 +969,7 @@ TkpPostMenu(
|
||||
|
||||
int
|
||||
TkpPostTearoffMenu(
|
||||
Tcl_Interp *interp, /* The interpreter this menu lives in */
|
||||
TCL_UNUSED(Tcl_Interp *), /* The interpreter this menu lives in */
|
||||
TkMenu *menuPtr, /* The menu we are posting */
|
||||
int x, int y, int index) /* The screen coordinates where the top left
|
||||
* corner of the menu, or of the specified
|
||||
@@ -1093,12 +1180,12 @@ CheckForSpecialMenu(
|
||||
cascadeEntryPtr = cascadeEntryPtr->nextCascadePtr) {
|
||||
if (cascadeEntryPtr->menuPtr->menuType == MENUBAR
|
||||
&& cascadeEntryPtr->menuPtr->masterMenuPtr->tkwin) {
|
||||
TkMenu *masterMenuPtr = cascadeEntryPtr->menuPtr->masterMenuPtr;
|
||||
TkMenu *mainMenuPtr = cascadeEntryPtr->menuPtr->masterMenuPtr;
|
||||
int i = 0;
|
||||
Tcl_DString ds;
|
||||
|
||||
Tcl_DStringInit(&ds);
|
||||
Tcl_DStringAppend(&ds, Tk_PathName(masterMenuPtr->tkwin), -1);
|
||||
Tcl_DStringAppend(&ds, Tk_PathName(mainMenuPtr->tkwin), -1);
|
||||
while (specialMenus[i].name) {
|
||||
Tcl_DStringAppend(&ds, specialMenus[i].name,
|
||||
specialMenus[i].len);
|
||||
@@ -1145,18 +1232,18 @@ ParseAccelerator(
|
||||
*maskPtr = 0;
|
||||
while (1) {
|
||||
i = 0;
|
||||
while (modifiers[i].name) {
|
||||
int l = modifiers[i].len;
|
||||
while (allModifiers[i].name) {
|
||||
int l = allModifiers[i].len;
|
||||
|
||||
if (!strncasecmp(accel, modifiers[i].name, l) &&
|
||||
if (!strncasecmp(accel, allModifiers[i].name, l) &&
|
||||
(accel[l] == '-' || accel[l] == '+')) {
|
||||
*maskPtr |= modifiers[i].mask;
|
||||
*maskPtr |= allModifiers[i].mask;
|
||||
accel += l+1;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (!modifiers[i].name || !*accel) {
|
||||
if (!allModifiers[i].name || !*accel) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1380,14 +1467,14 @@ TkpComputeStandardMenuGeometry(
|
||||
}
|
||||
} else {
|
||||
NSUInteger modifMask = [menuItem keyEquivalentModifierMask];
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
|
||||
while (modifiers[i].name) {
|
||||
if (modifMask & modifiers[i].mask) {
|
||||
modifMask &= ~modifiers[i].mask;
|
||||
while (allModifiers[j].name) {
|
||||
if (modifMask & allModifiers[j].mask) {
|
||||
modifMask &= ~allModifiers[j].mask;
|
||||
modifierWidth += modifierCharWidth;
|
||||
}
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
accelWidth = [[menuItem keyEquivalent] sizeWithAttributes:
|
||||
TkMacOSXNSFontAttributesForFont(tkfont)].width;
|
||||
@@ -1613,8 +1700,6 @@ Tk_MacOSXTurnOffMenus(void)
|
||||
void
|
||||
TkpMenuInit(void)
|
||||
{
|
||||
TkColor *tkColPtr;
|
||||
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
|
||||
#define observe(n, s) \
|
||||
@@ -1624,13 +1709,6 @@ TkpMenuInit(void)
|
||||
#undef observe
|
||||
|
||||
[NSMenuItem setUsesUserKeyEquivalents:NO];
|
||||
tkColPtr = TkpGetColor(NULL, DEF_MENU_BG_COLOR);
|
||||
defaultBg = tkColPtr->color.pixel;
|
||||
ckfree(tkColPtr);
|
||||
tkColPtr = TkpGetColor(NULL, DEF_MENU_FG);
|
||||
defaultFg = tkColPtr->color.pixel;
|
||||
ckfree(tkColPtr);
|
||||
|
||||
ChkErr(GetThemeMetric, kThemeMetricMenuMarkColumnWidth,
|
||||
&menuMarkColumnWidth);
|
||||
ChkErr(GetThemeMetric, kThemeMetricMenuTextLeadingEdgeMargin,
|
||||
@@ -1691,8 +1769,8 @@ TkpMenuThreadInit(void)
|
||||
|
||||
void
|
||||
TkpMenuNotifyToplevelCreate(
|
||||
Tcl_Interp *interp, /* The interp the menu lives in. */
|
||||
const char *menuName) /* The name of the menu to reconfigure. */
|
||||
TCL_UNUSED(Tcl_Interp *), /* The interp the menu lives in. */
|
||||
TCL_UNUSED(const char *)) /* The name of the menu to reconfigure. */
|
||||
{
|
||||
/*
|
||||
* Nothing to do.
|
||||
@@ -1720,8 +1798,8 @@ TkpMenuNotifyToplevelCreate(
|
||||
|
||||
void
|
||||
TkpInitializeMenuBindings(
|
||||
Tcl_Interp *interp, /* The interpreter to set. */
|
||||
Tk_BindingTable bindingTable)
|
||||
TCL_UNUSED(Tcl_Interp *), /* The interpreter to set. */
|
||||
TCL_UNUSED(Tk_BindingTable))
|
||||
/* The table to add to. */
|
||||
{
|
||||
/*
|
||||
@@ -1761,30 +1839,34 @@ TkpComputeMenubarGeometry(
|
||||
* TkpDrawMenuEntry --
|
||||
*
|
||||
* Draws the given menu entry at the given coordinates with the given
|
||||
* attributes.
|
||||
* attributes. This is a no-op on macOS since the menus are drawn by
|
||||
* the Apple window manager, which also handles all events related to
|
||||
* selecting menu items. This function is only called for tearoff
|
||||
* menus, which are not supported on macOS but do get drawn as nearly
|
||||
* invisible 1 pixel wide windows on macOS
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* X Server commands are executed to display the menu entry.
|
||||
* None
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
TkpDrawMenuEntry(
|
||||
TkMenuEntry *mePtr, /* The entry to draw */
|
||||
Drawable d, /* What to draw into */
|
||||
Tk_Font tkfont, /* Precalculated font for menu */
|
||||
const Tk_FontMetrics *menuMetricsPtr,
|
||||
TCL_UNUSED(TkMenuEntry *), /* The entry to draw */
|
||||
TCL_UNUSED(Drawable), /* What to draw into */
|
||||
TCL_UNUSED(Tk_Font), /* Precalculated font for menu */
|
||||
TCL_UNUSED(const Tk_FontMetrics *),
|
||||
/* Precalculated metrics for menu */
|
||||
int x, /* X-coordinate of topleft of entry */
|
||||
int y, /* Y-coordinate of topleft of entry */
|
||||
int width, /* Width of the entry rectangle */
|
||||
int height, /* Height of the current rectangle */
|
||||
int strictMotif, /* Boolean flag */
|
||||
int drawArrow) /* Whether or not to draw the cascade arrow
|
||||
TCL_UNUSED(int), /* X-coordinate of topleft of entry */
|
||||
TCL_UNUSED(int), /* Y-coordinate of topleft of entry */
|
||||
TCL_UNUSED(int), /* Width of the entry rectangle */
|
||||
TCL_UNUSED(int), /* Height of the current rectangle */
|
||||
TCL_UNUSED(int), /* Boolean flag */
|
||||
TCL_UNUSED(int)) /* Whether or not to draw the cascade arrow
|
||||
* for cascade items. */
|
||||
{
|
||||
}
|
||||
@@ -1833,7 +1915,7 @@ TkMacOSXPreprocessMenu(void)
|
||||
|
||||
int
|
||||
TkMacOSXUseMenuID(
|
||||
short macID) /* The id to take out of the table */
|
||||
TCL_UNUSED(short)) /* The id to take out of the table */
|
||||
{
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -1856,8 +1938,8 @@ TkMacOSXUseMenuID(
|
||||
|
||||
int
|
||||
TkMacOSXDispatchMenuEvent(
|
||||
int menuID, /* The menu id of the menu we are invoking */
|
||||
int index) /* The one-based index of the item that was
|
||||
TCL_UNUSED(int), /* The menu id of the menu we are invoking */
|
||||
TCL_UNUSED(int)) /* The one-based index of the item that was
|
||||
* selected. */
|
||||
{
|
||||
return TCL_ERROR;
|
||||
|
||||
@@ -76,6 +76,8 @@ static void DrawMenuButtonImageAndText(TkMenuButton *butPtr);
|
||||
Tk_ClassProcs tkpMenubuttonClass = {
|
||||
sizeof(Tk_ClassProcs), /* size */
|
||||
TkMenuButtonWorldChanged, /* worldChangedProc */
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -133,7 +135,7 @@ TkMenuButton *
|
||||
TkpCreateMenuButton(
|
||||
Tk_Window tkwin)
|
||||
{
|
||||
MacMenuButton *mbPtr = (MacMenuButton *) ckalloc(sizeof(MacMenuButton));
|
||||
MacMenuButton *mbPtr = (MacMenuButton *)ckalloc(sizeof(MacMenuButton));
|
||||
|
||||
Tk_CreateEventHandler(tkwin, ActivateMask, MenuButtonEventProc, mbPtr);
|
||||
mbPtr->flags = FIRST_DRAW;
|
||||
@@ -178,13 +180,6 @@ TkpDisplayMenuButton(
|
||||
|
||||
TkMacOSXComputeMenuButtonDrawParams(butPtr, dpPtr);
|
||||
|
||||
/*
|
||||
* Set up clipping region. Make sure the we are using the port for this
|
||||
* button, or we will set the wrong window's clip.
|
||||
*/
|
||||
|
||||
TkMacOSXSetUpClippingRgn(pixmap);
|
||||
|
||||
/*
|
||||
* Draw the native portion of the buttons.
|
||||
*/
|
||||
@@ -222,7 +217,7 @@ TkpDisplayMenuButton(
|
||||
|
||||
void
|
||||
TkpDestroyMenuButton(
|
||||
TkMenuButton *mbPtr)
|
||||
TCL_UNUSED(TkMenuButton *))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -246,7 +241,7 @@ TkpDestroyMenuButton(
|
||||
|
||||
void
|
||||
TkpComputeMenuButtonGeometry(butPtr)
|
||||
register TkMenuButton *butPtr; /* Widget record for menu button. */
|
||||
TkMenuButton *butPtr; /* Widget record for menu button. */
|
||||
{
|
||||
int width, height, avgWidth, haveImage = 0, haveText = 0;
|
||||
int txtWidth, txtHeight;
|
||||
@@ -362,7 +357,7 @@ TkpComputeMenuButtonGeometry(butPtr)
|
||||
*
|
||||
* DrawMenuButtonImageAndText --
|
||||
*
|
||||
* Draws the image and text associated witha button or label.
|
||||
* Draws the image and text associated with a button or label.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
@@ -393,7 +388,7 @@ DrawMenuButtonImageAndText(
|
||||
DrawParams *dpPtr = &mbPtr->drawParams;
|
||||
pixmap = (Pixmap) Tk_WindowId(tkwin);
|
||||
|
||||
if (butPtr->image != None) {
|
||||
if (butPtr->image != NULL) {
|
||||
Tk_SizeOfImage(butPtr->image, &width, &height);
|
||||
haveImage = 1;
|
||||
} else if (butPtr->bitmap != None) {
|
||||
@@ -544,8 +539,7 @@ DrawMenuButtonImageAndText(
|
||||
static void
|
||||
TkMacOSXDrawMenuButton(
|
||||
MacMenuButton *mbPtr, /* Mac menubutton. */
|
||||
GC gc, /* The GC we are drawing into - needed for the bevel
|
||||
* button */
|
||||
TCL_UNUSED(GC), /* The GC we are drawing into - not used */
|
||||
Pixmap pixmap) /* The pixmap we are drawing into - needed for the
|
||||
* bevel button */
|
||||
{
|
||||
@@ -566,7 +560,7 @@ TkMacOSXDrawMenuButton(
|
||||
static HIThemeButtonDrawInfo hiinfo;
|
||||
|
||||
MenuButtonBackgroundDrawCB(mbPtr, 32, true);
|
||||
if (!TkMacOSXSetupDrawingContext(pixmap, dpPtr->gc, 1, &dc)) {
|
||||
if (!TkMacOSXSetupDrawingContext(pixmap, dpPtr->gc, &dc)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -597,7 +591,7 @@ TkMacOSXDrawMenuButton(
|
||||
MenuButtonContentDrawCB(mbPtr->btnkind, &mbPtr->drawinfo,
|
||||
mbPtr, 32, true);
|
||||
} else {
|
||||
if (!TkMacOSXSetupDrawingContext(pixmap, dpPtr->gc, 1, &dc)) {
|
||||
if (!TkMacOSXSetupDrawingContext(pixmap, dpPtr->gc, &dc)) {
|
||||
return;
|
||||
}
|
||||
TkMacOSXRestoreDrawingContext(&dc);
|
||||
@@ -625,8 +619,8 @@ TkMacOSXDrawMenuButton(
|
||||
static void
|
||||
MenuButtonBackgroundDrawCB (
|
||||
MacMenuButton *ptr,
|
||||
SInt16 depth,
|
||||
Boolean isColorDev)
|
||||
TCL_UNUSED(SInt16),
|
||||
TCL_UNUSED(Boolean))
|
||||
{
|
||||
TkMenuButton* butPtr = (TkMenuButton *) ptr;
|
||||
Tk_Window tkwin = butPtr->tkwin;
|
||||
@@ -658,11 +652,11 @@ MenuButtonBackgroundDrawCB (
|
||||
|
||||
static void
|
||||
MenuButtonContentDrawCB (
|
||||
ThemeButtonKind kind,
|
||||
const HIThemeButtonDrawInfo *drawinfo,
|
||||
TCL_UNUSED(ThemeButtonKind),
|
||||
TCL_UNUSED(const HIThemeButtonDrawInfo *),
|
||||
MacMenuButton *ptr,
|
||||
SInt16 depth,
|
||||
Boolean isColorDev)
|
||||
TCL_UNUSED(SInt16),
|
||||
TCL_UNUSED(Boolean))
|
||||
{
|
||||
TkMenuButton *butPtr = (TkMenuButton *) ptr;
|
||||
Tk_Window tkwin = butPtr->tkwin;
|
||||
@@ -709,7 +703,7 @@ MenuButtonEventProc(
|
||||
mbPtr->flags &= ~ACTIVE;
|
||||
}
|
||||
if ((buttonPtr->flags & REDRAW_PENDING) == 0) {
|
||||
Tcl_DoWhenIdle(TkpDisplayMenuButton, (ClientData) buttonPtr);
|
||||
Tcl_DoWhenIdle(TkpDisplayMenuButton, buttonPtr);
|
||||
buttonPtr->flags |= REDRAW_PENDING;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ static Tcl_Obj * GetWidgetDemoPath(Tcl_Interp *interp);
|
||||
* On OS X 10.12 we get duplicate tab control items if we create them here.
|
||||
*/
|
||||
|
||||
if ([NSApp macMinorVersion] > 12) {
|
||||
if ([NSApp macOSVersion] > 101200) {
|
||||
_defaultWindowsMenuItems = [_defaultWindowsMenuItems
|
||||
arrayByAddingObjectsFromArray:
|
||||
[NSArray arrayWithObjects:
|
||||
@@ -201,7 +201,7 @@ static Tcl_Obj * GetWidgetDemoPath(Tcl_Interp *interp);
|
||||
{
|
||||
if (!_eventInterp || !Tcl_FindCommand(_eventInterp, "tkAboutDialog",
|
||||
NULL, 0) || (GetCurrentEventKeyModifiers() & optionKey)) {
|
||||
TkAboutDlg();
|
||||
[super orderFrontStandardAboutPanel:nil];
|
||||
} else {
|
||||
int code = Tcl_EvalEx(_eventInterp, "tkAboutDialog", -1,
|
||||
TCL_EVAL_GLOBAL);
|
||||
@@ -415,7 +415,7 @@ GenerateEditEvent(
|
||||
if (!winPtr) {
|
||||
return;
|
||||
}
|
||||
tkwin = (Tk_Window) winPtr->dispPtr->focusPtr;
|
||||
tkwin = (Tk_Window)winPtr->dispPtr->focusPtr;
|
||||
if (!tkwin) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ typedef struct {
|
||||
Point global;
|
||||
Point local;
|
||||
} MouseEventData;
|
||||
|
||||
static Tk_Window captureWinPtr = NULL; /* Current capture window; may be
|
||||
* NULL. */
|
||||
|
||||
@@ -42,9 +43,9 @@ enum {
|
||||
* 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.
|
||||
* attribute until the mouse returned to the window. In 11.1 it changed again.
|
||||
* The window attribute can be non-nil, but referencing a window which does not
|
||||
* belong to the application.
|
||||
*/
|
||||
|
||||
@implementation TKApplication(TKMouseEvent)
|
||||
@@ -52,134 +53,164 @@ enum {
|
||||
{
|
||||
NSWindow *eventWindow = [theEvent window];
|
||||
NSEventType eventType = [theEvent type];
|
||||
NSRect viewFrame = [[eventWindow contentView] frame];
|
||||
NSPoint location = [theEvent locationInWindow];
|
||||
TkWindow *winPtr = NULL, *grabWinPtr;
|
||||
Tk_Window tkwin;
|
||||
Tk_Window tkwin = None, capture, target;
|
||||
NSPoint local, global;
|
||||
#if 0
|
||||
NSTrackingArea *trackingArea = nil;
|
||||
NSInteger eventNumber, clickCount, buttonNumber;
|
||||
#endif
|
||||
[NSEvent stopPeriodicEvents];
|
||||
NSInteger button;
|
||||
Bool inTitleBar = NO;
|
||||
int win_x, win_y;
|
||||
unsigned int buttonState = 0;
|
||||
static int validPresses = 0, ignoredPresses = 0;
|
||||
|
||||
#ifdef TK_MAC_DEBUG_EVENTS
|
||||
TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent);
|
||||
#endif
|
||||
switch (eventType) {
|
||||
case NSMouseEntered:
|
||||
case NSMouseExited:
|
||||
case NSCursorUpdate:
|
||||
case NSLeftMouseDown:
|
||||
case NSLeftMouseUp:
|
||||
case NSRightMouseDown:
|
||||
case NSRightMouseUp:
|
||||
case NSOtherMouseDown:
|
||||
case NSOtherMouseUp:
|
||||
case NSLeftMouseDragged:
|
||||
case NSRightMouseDragged:
|
||||
case NSOtherMouseDragged:
|
||||
case NSMouseMoved:
|
||||
case NSTabletPoint:
|
||||
case NSTabletProximity:
|
||||
case NSScrollWheel:
|
||||
break;
|
||||
default: /* Unrecognized mouse event. */
|
||||
return theEvent;
|
||||
|
||||
/*
|
||||
* If this event is not for a Tk toplevel, it should just be passed up the
|
||||
* responder chain. However, there is an exception for synthesized events,
|
||||
* which are used in testing. Those events are recognized by having their
|
||||
* both the windowNumber and the eventNumber set to -1.
|
||||
*/
|
||||
|
||||
if (eventWindow && ![eventWindow isMemberOfClass:[TKWindow class]]) {
|
||||
if ([theEvent windowNumber] != -1 || [theEvent eventNumber] != -1)
|
||||
return theEvent;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the mouse position in Tk screen coordinates (global) and in the
|
||||
* Tk coordinates of its containing Tk Window (local). If a grab is in effect,
|
||||
* the local coordinates should be relative to the grab window.
|
||||
* Check if the event is located in the titlebar.
|
||||
*/
|
||||
|
||||
if (eventWindow) {
|
||||
local = [theEvent locationInWindow];
|
||||
global = [eventWindow tkConvertPointToScreen: local];
|
||||
tkwin = TkMacOSXGetCapture();
|
||||
if (tkwin) {
|
||||
winPtr = (TkWindow *) tkwin;
|
||||
eventWindow = TkMacOSXDrawableWindow(winPtr->window);
|
||||
if (eventWindow) {
|
||||
local = [eventWindow tkConvertPointFromScreen: global];
|
||||
} else {
|
||||
return theEvent;
|
||||
}
|
||||
}
|
||||
local.y = [eventWindow frame].size.height - local.y;
|
||||
global.y = TkMacOSXZeroScreenHeight() - global.y;
|
||||
} else {
|
||||
|
||||
/*
|
||||
* If the event has no NSWindow, the location is in screen coordinates.
|
||||
*/
|
||||
|
||||
global = [theEvent locationInWindow];
|
||||
tkwin = TkMacOSXGetCapture();
|
||||
if (tkwin) {
|
||||
winPtr = (TkWindow *) tkwin;
|
||||
eventWindow = TkMacOSXDrawableWindow(winPtr->window);
|
||||
} else {
|
||||
eventWindow = [NSApp mainWindow];
|
||||
}
|
||||
if (!eventWindow) {
|
||||
return theEvent;
|
||||
}
|
||||
local = [eventWindow tkConvertPointFromScreen: global];
|
||||
local.y = [eventWindow frame].size.height - local.y;
|
||||
global.y = TkMacOSXZeroScreenHeight() - global.y;
|
||||
inTitleBar = viewFrame.size.height < location.y;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we still don't have a window, try using the toplevel that
|
||||
* manages the NSWindow.
|
||||
*/
|
||||
|
||||
if (!tkwin) {
|
||||
winPtr = TkMacOSXGetTkWindow(eventWindow);
|
||||
tkwin = (Tk_Window) winPtr;
|
||||
}
|
||||
if (!tkwin) {
|
||||
|
||||
/*
|
||||
* We can't find a window for this event. We have to ignore it.
|
||||
*/
|
||||
|
||||
#ifdef TK_MAC_DEBUG_EVENTS
|
||||
TkMacOSXDbgMsg("tkwin == NULL");
|
||||
button = [theEvent buttonNumber] + Button1;
|
||||
switch (eventType) {
|
||||
case NSRightMouseUp:
|
||||
case NSOtherMouseUp:
|
||||
buttonState &= ~TkGetButtonMask(button);
|
||||
break;
|
||||
case NSLeftMouseDragged:
|
||||
case NSRightMouseDragged:
|
||||
case NSOtherMouseDragged:
|
||||
case NSRightMouseDown:
|
||||
case NSOtherMouseDown:
|
||||
buttonState |= TkGetButtonMask(button);
|
||||
break;
|
||||
case NSMouseEntered:
|
||||
if ([eventWindow respondsToSelector:@selector(mouseInResizeArea)] &&
|
||||
!inTitleBar) {
|
||||
[(TKWindow *)eventWindow setMouseInResizeArea:YES];
|
||||
}
|
||||
break;
|
||||
case NSMouseExited:
|
||||
if ([eventWindow respondsToSelector:@selector(mouseInResizeArea)]) {
|
||||
[(TKWindow *)eventWindow setMouseInResizeArea:NO];
|
||||
break;
|
||||
}
|
||||
case NSLeftMouseUp:
|
||||
case NSLeftMouseDown:
|
||||
case NSMouseMoved:
|
||||
case NSScrollWheel:
|
||||
#if 0
|
||||
case NSCursorUpdate:
|
||||
case NSTabletPoint:
|
||||
case NSTabletProximity:
|
||||
#endif
|
||||
break;
|
||||
default: /* This type of event is ignored. */
|
||||
return theEvent;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ignore the event if a local grab is in effect and the Tk event window is
|
||||
* not in the grabber's subtree.
|
||||
* Update the button state. We ignore left button presses that start a
|
||||
* resize or occur in the title bar. See tickets [d72abe6b54] and
|
||||
* [39cbacb9e8].
|
||||
*/
|
||||
|
||||
grabWinPtr = winPtr->dispPtr->grabWinPtr;
|
||||
if (grabWinPtr && /* There is a grab in effect ... */
|
||||
!winPtr->dispPtr->grabFlags && /* and it is a local grab ... */
|
||||
grabWinPtr->mainPtr == winPtr->mainPtr){ /* in the same application. */
|
||||
Tk_Window tkwin2, tkEventWindow = Tk_CoordsToWindow(global.x, global.y, tkwin);
|
||||
if (!tkEventWindow) {
|
||||
if (eventType == NSLeftMouseDown) {
|
||||
if ([eventWindow respondsToSelector:@selector(mouseInResizeArea)] &&
|
||||
[(TKWindow *) eventWindow mouseInResizeArea]) {
|
||||
|
||||
/*
|
||||
* When the left button is pressed in the resize area, we receive
|
||||
* NSMouseDown, but when it is released we do not receive
|
||||
* NSMouseUp. So ignore the event and clear the button state but
|
||||
* do not change the ignoredPresses count.
|
||||
*/
|
||||
|
||||
buttonState &= ~TkGetButtonMask(Button1);
|
||||
return theEvent;
|
||||
}
|
||||
for (tkwin2 = tkEventWindow;
|
||||
!Tk_IsTopLevel(tkwin2);
|
||||
tkwin2 = Tk_Parent(tkwin2)) {
|
||||
if (tkwin2 == (Tk_Window) grabWinPtr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tkwin2 != (Tk_Window) grabWinPtr) {
|
||||
if (inTitleBar) {
|
||||
ignoredPresses++;
|
||||
return theEvent;
|
||||
}
|
||||
validPresses++;
|
||||
buttonState |= TkGetButtonMask(Button1);
|
||||
}
|
||||
if (eventType == NSLeftMouseUp) {
|
||||
if (ignoredPresses > 0) {
|
||||
ignoredPresses--;
|
||||
} else if (validPresses > 0) {
|
||||
validPresses--;
|
||||
}
|
||||
if (validPresses == 0) {
|
||||
buttonState &= ~TkGetButtonMask(Button1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert local from NSWindow flipped coordinates to the toplevel's
|
||||
* coordinates.
|
||||
* Find an appropriate NSWindow to attach to this event, and its
|
||||
* associated Tk window.
|
||||
*/
|
||||
|
||||
capture = TkMacOSXGetCapture();
|
||||
if (capture) {
|
||||
winPtr = (TkWindow *) capture;
|
||||
eventWindow = TkMacOSXGetNSWindowForDrawable(winPtr->window);
|
||||
if (!eventWindow) {
|
||||
return theEvent;
|
||||
}
|
||||
} else {
|
||||
if (eventWindow) {
|
||||
winPtr = TkMacOSXGetTkWindow(eventWindow);
|
||||
}
|
||||
if (!winPtr) {
|
||||
eventWindow = [NSApp mainWindow];
|
||||
winPtr = TkMacOSXGetTkWindow(eventWindow);
|
||||
}
|
||||
}
|
||||
if (!winPtr) {
|
||||
|
||||
/*
|
||||
* We couldn't find a Tk window for this event. We have to ignore it.
|
||||
*/
|
||||
|
||||
#ifdef TK_MAC_DEBUG_EVENTS
|
||||
TkMacOSXDbgMsg("Event received with no Tk window.");
|
||||
#endif
|
||||
return theEvent;
|
||||
}
|
||||
tkwin = (Tk_Window) winPtr;
|
||||
|
||||
/*
|
||||
* Compute the mouse position in local (window) and global (screen)
|
||||
* coordinates. These are Tk coordinates, meaning that the local origin is
|
||||
* at the top left corner of the containing toplevel and the global origin
|
||||
* is at top left corner of the primary screen.
|
||||
*/
|
||||
|
||||
global = [NSEvent mouseLocation];
|
||||
local = [eventWindow tkConvertPointFromScreen: global];
|
||||
global.x = floor(global.x);
|
||||
global.y = floor(TkMacOSXZeroScreenHeight() - global.y);
|
||||
local.x = floor(local.x);
|
||||
local.y = floor([eventWindow frame].size.height - local.y);
|
||||
if (Tk_IsEmbedded(winPtr)) {
|
||||
TkWindow *contPtr = TkpGetOtherWindow(winPtr);
|
||||
if (Tk_IsTopLevel(contPtr)) {
|
||||
@@ -196,43 +227,44 @@ enum {
|
||||
}
|
||||
|
||||
/*
|
||||
* Use the toplevel coordinates to find the containing Tk window. Then
|
||||
* convert local into the coordinates of that window. (The converted
|
||||
* local coordinates are only needed for scrollwheel events.)
|
||||
* Use the local coordinates to find the Tk window which should receive
|
||||
* this event. Also convert local into the coordinates of that window.
|
||||
* (The converted local coordinates are only needed for scrollwheel
|
||||
* events.)
|
||||
*/
|
||||
|
||||
int win_x, win_y;
|
||||
tkwin = Tk_TopCoordsToWindow(tkwin, local.x, local.y, &win_x, &win_y);
|
||||
local.x = win_x;
|
||||
local.y = win_y;
|
||||
target = Tk_TopCoordsToWindow(tkwin, local.x, local.y, &win_x, &win_y);
|
||||
|
||||
/*
|
||||
* Ignore the event if a local grab is in effect and the Tk window is
|
||||
* not in the grabber's subtree.
|
||||
*/
|
||||
|
||||
grabWinPtr = winPtr->dispPtr->grabWinPtr;
|
||||
if (grabWinPtr && /* There is a grab in effect ... */
|
||||
!winPtr->dispPtr->grabFlags && /* and it is a local grab ... */
|
||||
grabWinPtr->mainPtr == winPtr->mainPtr){ /* in the same application. */
|
||||
Tk_Window tkwin2;
|
||||
if (!target) {
|
||||
return theEvent;
|
||||
}
|
||||
for (tkwin2 = target;
|
||||
!Tk_IsTopLevel(tkwin2);
|
||||
tkwin2 = Tk_Parent(tkwin2)) {
|
||||
if (tkwin2 == (Tk_Window)grabWinPtr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tkwin2 != (Tk_Window)grabWinPtr) {
|
||||
return theEvent;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate an XEvent for this mouse event.
|
||||
*/
|
||||
|
||||
unsigned int state = 0;
|
||||
int button = [theEvent buttonNumber] + Button1;
|
||||
EventRef eventRef = (EventRef)[theEvent eventRef];
|
||||
UInt32 buttons;
|
||||
OSStatus err = GetEventParameter(eventRef, kEventParamMouseChord,
|
||||
typeUInt32, NULL, sizeof(UInt32), NULL, &buttons);
|
||||
|
||||
if (err == noErr) {
|
||||
state |= (buttons & 0x1F) * Button1Mask;
|
||||
} else if (button <= Button5) {
|
||||
switch (eventType) {
|
||||
case NSLeftMouseDown:
|
||||
case NSRightMouseDown:
|
||||
case NSLeftMouseDragged:
|
||||
case NSRightMouseDragged:
|
||||
case NSOtherMouseDown:
|
||||
state |= TkGetButtonMask(button);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int state = buttonState;
|
||||
NSUInteger modifiers = [theEvent modifierFlags];
|
||||
|
||||
if (modifiers & NSAlphaShiftKeyMask) {
|
||||
@@ -260,32 +292,34 @@ enum {
|
||||
if (eventType != NSScrollWheel) {
|
||||
|
||||
/*
|
||||
* For normal mouse events, Tk_UpdatePointer will send the XEvent.
|
||||
* For normal mouse events, Tk_UpdatePointer will send the appropriate
|
||||
* XEvents using its cached state information. Unfortunately, it will
|
||||
* also recompute the local coordinates.
|
||||
*/
|
||||
|
||||
#ifdef TK_MAC_DEBUG_EVENTS
|
||||
TKLog(@"UpdatePointer %p x %f.0 y %f.0 %d",
|
||||
tkwin, global.x, global.y, state);
|
||||
TKLog(@"UpdatePointer %p x %.1f y %.1f %d",
|
||||
target, global.x, global.y, state);
|
||||
#endif
|
||||
Tk_UpdatePointer(tkwin, global.x, global.y, state);
|
||||
|
||||
Tk_UpdatePointer(target, global.x, global.y, state);
|
||||
} else {
|
||||
CGFloat delta;
|
||||
int coarseDelta;
|
||||
XEvent xEvent;
|
||||
|
||||
/*
|
||||
* For scroll wheel events we need to send the XEvent here.
|
||||
*/
|
||||
|
||||
CGFloat delta;
|
||||
int coarseDelta;
|
||||
XEvent xEvent;
|
||||
|
||||
xEvent.type = MouseWheelEvent;
|
||||
xEvent.xbutton.x = local.x;
|
||||
xEvent.xbutton.y = local.y;
|
||||
xEvent.xbutton.x = win_x;
|
||||
xEvent.xbutton.y = win_y;
|
||||
xEvent.xbutton.x_root = global.x;
|
||||
xEvent.xbutton.y_root = global.y;
|
||||
xEvent.xany.send_event = false;
|
||||
xEvent.xany.display = Tk_Display(tkwin);
|
||||
xEvent.xany.window = Tk_WindowId(tkwin);
|
||||
xEvent.xany.display = Tk_Display(target);
|
||||
xEvent.xany.window = Tk_WindowId(target);
|
||||
|
||||
delta = [theEvent deltaY];
|
||||
if (delta != 0.0) {
|
||||
@@ -312,34 +346,6 @@ enum {
|
||||
|
||||
#pragma mark -
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TkMacOSXKeyModifiers --
|
||||
*
|
||||
* Returns the current state of the modifier keys.
|
||||
*
|
||||
* Results:
|
||||
* An OS Modifier state.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
EventModifiers
|
||||
TkMacOSXModifierState(void)
|
||||
{
|
||||
UInt32 keyModifiers;
|
||||
int isFrontProcess = (GetCurrentEvent() && Tk_MacOSXIsAppInFront());
|
||||
|
||||
keyModifiers = isFrontProcess ? GetCurrentEventKeyModifiers() :
|
||||
GetCurrentKeyModifiers();
|
||||
|
||||
return (EventModifiers) (keyModifiers & USHRT_MAX);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -464,8 +470,8 @@ XQueryPointer(
|
||||
NSPoint global = [NSEvent mouseLocation];
|
||||
|
||||
if (getLocal) {
|
||||
MacDrawable *macWin = (MacDrawable *) w;
|
||||
NSWindow *win = TkMacOSXDrawableWindow(w);
|
||||
MacDrawable *macWin = (MacDrawable *)w;
|
||||
NSWindow *win = TkMacOSXGetNSWindowForDrawable(w);
|
||||
|
||||
if (win) {
|
||||
NSPoint local;
|
||||
@@ -503,7 +509,7 @@ XQueryPointer(
|
||||
* True if event(s) are generated - false otherwise.
|
||||
*
|
||||
* Side effects:
|
||||
* Additional events may be place on the Tk event queue. Grab state may
|
||||
* Additional events may be placed on the Tk event queue. Grab state may
|
||||
* also change.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -541,7 +547,7 @@ TkGenerateButtonEventForXPointer(
|
||||
* True if event(s) are generated, false otherwise.
|
||||
*
|
||||
* Side effects:
|
||||
* Additional events may be place on the Tk event queue. Grab state may
|
||||
* Additional events may be placed on the Tk event queue. Grab state may
|
||||
* also change.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -554,8 +560,8 @@ TkGenerateButtonEvent(
|
||||
Window window, /* X Window containing button event. */
|
||||
unsigned int state) /* Button Key state suitable for X event. */
|
||||
{
|
||||
MacDrawable *macWin = (MacDrawable *) window;
|
||||
NSWindow *win = TkMacOSXDrawableWindow(window);
|
||||
MacDrawable *macWin = (MacDrawable *)window;
|
||||
NSWindow *win = TkMacOSXGetNSWindowForDrawable(window);
|
||||
MouseEventData med;
|
||||
|
||||
bzero(&med, sizeof(MouseEventData));
|
||||
@@ -593,7 +599,7 @@ TkGenerateButtonEvent(
|
||||
* True if event(s) are generated - false otherwise.
|
||||
*
|
||||
* Side effects:
|
||||
* Additional events may be place on the Tk event queue. Grab state may
|
||||
* Additional events may be placed on the Tk event queue. Grab state may
|
||||
* also change.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -636,51 +642,40 @@ GenerateButtonEvent(
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TkpWarpPointer --
|
||||
*
|
||||
* Move the mouse cursor to the screen location specified by the warpX and
|
||||
* warpY fields of a TkDisplay.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* The mouse cursor is moved.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
TkpWarpPointer(
|
||||
TkDisplay *dispPtr)
|
||||
{
|
||||
CGPoint pt;
|
||||
NSPoint loc;
|
||||
int wNum;
|
||||
|
||||
if (dispPtr->warpWindow) {
|
||||
int x, y;
|
||||
TkWindow *winPtr = (TkWindow *) dispPtr->warpWindow;
|
||||
TkWindow *topPtr = winPtr->privatePtr->toplevel->winPtr;
|
||||
NSWindow *w = TkMacOSXDrawableWindow(winPtr->window);
|
||||
wNum = [w windowNumber];
|
||||
Tk_GetRootCoords(dispPtr->warpWindow, &x, &y);
|
||||
pt.x = x + dispPtr->warpX;
|
||||
pt.y = y + dispPtr->warpY;
|
||||
loc.x = dispPtr->warpX;
|
||||
loc.y = Tk_Height(topPtr) - dispPtr->warpY;
|
||||
} else {
|
||||
wNum = 0;
|
||||
pt.x = loc.x = dispPtr->warpX;
|
||||
pt.x = dispPtr->warpX;
|
||||
pt.y = dispPtr->warpY;
|
||||
loc.y = TkMacOSXZeroScreenHeight() - pt.y;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate an NSEvent of type NSMouseMoved.
|
||||
*
|
||||
* It is not clear why this is necessary. For example, calling
|
||||
* event generate $w <Motion> -warp 1 -x $X -y $Y
|
||||
* will cause two <Motion> events to be added to the Tcl queue.
|
||||
*/
|
||||
|
||||
CGWarpMouseCursorPosition(pt);
|
||||
NSEvent *warpEvent = [NSEvent mouseEventWithType:NSMouseMoved
|
||||
location:loc
|
||||
modifierFlags:0
|
||||
timestamp:GetCurrentEventTime()
|
||||
windowNumber:wNum
|
||||
context:nil
|
||||
eventNumber:0
|
||||
clickCount:1
|
||||
pressure:0.0];
|
||||
[NSApp postEvent:warpEvent atStart:NO];
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -708,8 +703,7 @@ TkpSetCapture(
|
||||
while (winPtr && !Tk_IsTopLevel(winPtr)) {
|
||||
winPtr = winPtr->parentPtr;
|
||||
}
|
||||
[NSEvent stopPeriodicEvents];
|
||||
captureWinPtr = (Tk_Window) winPtr;
|
||||
captureWinPtr = (Tk_Window)winPtr;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -141,12 +141,57 @@ void DebugPrintQueue(void)
|
||||
*/
|
||||
- (void) sendEvent: (NSEvent *) theEvent
|
||||
{
|
||||
|
||||
/*
|
||||
* Workaround for an Apple bug. When an accented character is selected
|
||||
* from an NSTextInputClient popup character viewer with the mouse, Apple
|
||||
* sends an event of type NSAppKitDefined and subtype 21. If that event is
|
||||
* sent up the responder chain it causes Apple to print a warning to the
|
||||
* console log and, extremely obnoxiously, also to stderr, which says
|
||||
* "Window move completed without beginning." Apparently they are sending
|
||||
* the "move completed" event without having sent the "move began" event of
|
||||
* subtype 20, and then announcing their error on our stderr. Also, of
|
||||
* course, no movement is occurring. The popup is not movable and is just
|
||||
* being closed. The bug has been reported to Apple. If they ever fix it,
|
||||
* this block should be removed.
|
||||
*/
|
||||
|
||||
# if MAC_OS_X_VERSION_MAX_ALLOWED >= 101500
|
||||
if ([theEvent type] == NSAppKitDefined) {
|
||||
static Bool aWindowIsMoving = NO;
|
||||
switch([theEvent subtype]) {
|
||||
case 20:
|
||||
aWindowIsMoving = YES;
|
||||
break;
|
||||
case 21:
|
||||
if (aWindowIsMoving) {
|
||||
aWindowIsMoving = NO;
|
||||
break;
|
||||
} else {
|
||||
// printf("Bug!!!!\n");
|
||||
return;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
[super sendEvent:theEvent];
|
||||
[NSApp tkCheckPasteboard];
|
||||
|
||||
#ifdef TK_MAC_DEBUG_EVENTS
|
||||
fprintf(stderr, "Sending event of type %d\n", (int)[theEvent type]);
|
||||
DebugPrintQueue();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
- (void) _runBackgroundLoop
|
||||
{
|
||||
while(Tcl_DoOneEvent(TCL_IDLE_EVENTS|TCL_TIMER_EVENTS|TCL_DONT_WAIT)){
|
||||
TkMacOSXDrawAllViews(NULL);
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
||||
@@ -166,15 +211,13 @@ void DebugPrintQueue(void)
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
NSString *
|
||||
static NSString *
|
||||
GetRunLoopMode(NSModalSession modalSession)
|
||||
{
|
||||
NSString *runLoopMode = nil;
|
||||
|
||||
if (modalSession) {
|
||||
runLoopMode = NSModalPanelRunLoopMode;
|
||||
} else if (TkMacOSXGetCapture()) {
|
||||
runLoopMode = NSEventTrackingRunLoopMode;
|
||||
}
|
||||
if (!runLoopMode) {
|
||||
runLoopMode = [[NSRunLoop currentRunLoop] currentMode];
|
||||
@@ -226,7 +269,6 @@ Tk_MacOSXSetupTkNotifier(void)
|
||||
Tcl_CreateEventSource(TkMacOSXEventsSetupProc,
|
||||
TkMacOSXEventsCheckProc, NULL);
|
||||
TkCreateExitHandler(TkMacOSXNotifyExitHandler, NULL);
|
||||
Tcl_SetServiceMode(TCL_SERVICE_ALL);
|
||||
TclMacOSXNotifierAddRunLoopMode(NSEventTrackingRunLoopMode);
|
||||
TclMacOSXNotifierAddRunLoopMode(NSModalPanelRunLoopMode);
|
||||
}
|
||||
@@ -261,13 +303,93 @@ TkMacOSXNotifyExitHandler(
|
||||
tsdPtr->initialized = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TkMacOSXDrawAllViews --
|
||||
*
|
||||
* This static function is meant to be run as an idle task. It attempts
|
||||
* to redraw all views which have the tkNeedsDisplay property set to YES.
|
||||
* This relies on a feature of [NSApp nextEventMatchingMask: ...] which
|
||||
* is undocumented, namely that it sometimes blocks and calls drawRect
|
||||
* for all views that need display before it returns. We call it with
|
||||
* deQueue=NO so that it will not change anything on the AppKit event
|
||||
* queue, because we only want the side effect that it runs drawRect. The
|
||||
* only time when any NSViews have the needsDisplay property set to YES
|
||||
* is during execution of this function.
|
||||
*
|
||||
* The reason for running this function as an idle task is to try to
|
||||
* arrange that all widgets will be fully configured before they are
|
||||
* drawn. Any idle tasks that might reconfigure them should be higher on
|
||||
* the idle queue, so they should be run before the display procs are run
|
||||
* by drawRect.
|
||||
*
|
||||
* If this function is called directly with non-NULL clientData parameter
|
||||
* then the int which it references will be set to the number of windows
|
||||
* that need display, but the needsDisplay property of those windows will
|
||||
* not be changed.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Parts of windows may get redrawn.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
TkMacOSXDrawAllViews(
|
||||
ClientData clientData)
|
||||
{
|
||||
int count = 0, *dirtyCount = (int *)clientData;
|
||||
|
||||
for (NSWindow *window in [NSApp windows]) {
|
||||
if ([[window contentView] isMemberOfClass:[TKContentView class]]) {
|
||||
TKContentView *view = [window contentView];
|
||||
if ([view tkNeedsDisplay]) {
|
||||
count++;
|
||||
if (dirtyCount) {
|
||||
continue;
|
||||
}
|
||||
[view setNeedsDisplayInRect:[view tkDirtyRect]];
|
||||
}
|
||||
} else {
|
||||
[window displayIfNeeded];
|
||||
}
|
||||
}
|
||||
if (dirtyCount) {
|
||||
*dirtyCount = count;
|
||||
}
|
||||
[NSApp nextEventMatchingMask:NSAnyEventMask
|
||||
untilDate:[NSDate distantPast]
|
||||
inMode:GetRunLoopMode(TkMacOSXGetModalSession())
|
||||
dequeue:NO];
|
||||
for (NSWindow *window in [NSApp windows]) {
|
||||
if ([[window contentView] isMemberOfClass:[TKContentView class]]) {
|
||||
TKContentView *view = [window contentView];
|
||||
|
||||
/*
|
||||
* If we did not run drawRect, we set needsDisplay back to NO.
|
||||
* Note that if drawRect did run it may have added to Tk's dirty
|
||||
* rect, due to attempts to draw outside of drawRect's dirty rect.
|
||||
*/
|
||||
|
||||
if ([view needsDisplay]) {
|
||||
[view setNeedsDisplay: NO];
|
||||
}
|
||||
}
|
||||
}
|
||||
[NSApp setNeedsToDraw:NO];
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TkMacOSXEventsSetupProc --
|
||||
*
|
||||
* This procedure implements the setup part of the MacOSX event source. It
|
||||
* is invoked by Tcl_DoOneEvent before calling TkMacOSXEventsProc to
|
||||
* is invoked by Tcl_DoOneEvent before calling TkMacOSXEventsCheckProc 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.
|
||||
@@ -277,18 +399,33 @@ TkMacOSXNotifyExitHandler(
|
||||
*
|
||||
* Side effects:
|
||||
*
|
||||
* If NSEvents are queued, then the maximum block time will be set to 0 to
|
||||
* ensure that control returns immediately to Tcl.
|
||||
* If NSEvents are queued, or if there is any drawing that needs to be
|
||||
* done, then the maximum block time will be set to 0 to ensure that
|
||||
* Tcl_WaitForEvent returns immediately.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#define TICK 200
|
||||
static Tcl_TimerToken ticker = NULL;
|
||||
|
||||
static void
|
||||
Heartbeat(
|
||||
ClientData clientData)
|
||||
{
|
||||
|
||||
if (ticker) {
|
||||
ticker = Tcl_CreateTimerHandler(TICK, Heartbeat, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static const Tcl_Time zeroBlockTime = { 0, 0 };
|
||||
|
||||
static void
|
||||
TkMacOSXEventsSetupProc(
|
||||
ClientData clientData,
|
||||
int flags)
|
||||
{
|
||||
static Bool havePeriodicEvents = NO;
|
||||
NSString *runloopMode = [[NSRunLoop currentRunLoop] currentMode];
|
||||
|
||||
/*
|
||||
@@ -296,35 +433,39 @@ TkMacOSXEventsSetupProc(
|
||||
*/
|
||||
|
||||
if (flags & TCL_WINDOW_EVENTS && !runloopMode) {
|
||||
static const Tcl_Time zeroBlockTime = { 0, 0 };
|
||||
|
||||
[NSApp _resetAutoreleasePool];
|
||||
|
||||
/*
|
||||
* Call this with dequeue=NO -- just checking if the queue is empty.
|
||||
*/
|
||||
/*
|
||||
* After calling this setup proc, Tcl_DoOneEvent will call
|
||||
* Tcl_WaitForEvent. Then it will call check proc to collect the
|
||||
* events and translate them into XEvents.
|
||||
*
|
||||
* If we have any events waiting or if there is any drawing to be done
|
||||
* we want Tcl_WaitForEvent to return immediately. So we set the block
|
||||
* time to 0 and stop the heartbeat.
|
||||
*/
|
||||
|
||||
NSEvent *currentEvent =
|
||||
[NSApp nextEventMatchingMask:NSAnyEventMask
|
||||
untilDate:[NSDate distantPast]
|
||||
inMode:GetRunLoopMode(TkMacOSXGetModalSession())
|
||||
dequeue:NO];
|
||||
if (currentEvent) {
|
||||
if (currentEvent.type > 0) {
|
||||
Tcl_SetMaxBlockTime(&zeroBlockTime);
|
||||
[NSEvent stopPeriodicEvents];
|
||||
havePeriodicEvents = NO;
|
||||
}
|
||||
} else if (!havePeriodicEvents){
|
||||
if ((currentEvent) || [NSApp needsToDraw] ) {
|
||||
Tcl_SetMaxBlockTime(&zeroBlockTime);
|
||||
Tcl_DeleteTimerHandler(ticker);
|
||||
ticker = NULL;
|
||||
} else if (ticker == NULL) {
|
||||
|
||||
/*
|
||||
* When the user is not generating events we schedule a "hearbeat"
|
||||
* event to fire every 0.1 seconds. This helps to make the vwait
|
||||
* command more responsive when there is no user input, e.g. when
|
||||
* running the test suite.
|
||||
* When the user is not generating events we schedule a "heartbeat"
|
||||
* TimerHandler to fire every 200 milliseconds. The handler does
|
||||
* nothing, but when its timer fires it causes Tcl_WaitForEvent to
|
||||
* return. This helps avoid hangs when calling vwait during the
|
||||
* non-regression tests.
|
||||
*/
|
||||
|
||||
havePeriodicEvents = YES;
|
||||
[NSEvent startPeriodicEventsAfterDelay:0.0 withPeriod:0.1];
|
||||
ticker = Tcl_CreateTimerHandler(TICK, Heartbeat, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -352,6 +493,7 @@ TkMacOSXEventsCheckProc(
|
||||
int flags)
|
||||
{
|
||||
NSString *runloopMode = [[NSRunLoop currentRunLoop] currentMode];
|
||||
int eventsFound = 0;
|
||||
|
||||
/*
|
||||
* runloopMode will be nil if we are in a Tcl event loop.
|
||||
@@ -390,17 +532,19 @@ TkMacOSXEventsCheckProc(
|
||||
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) {
|
||||
eventsFound++;
|
||||
|
||||
#ifdef TK_MAC_DEBUG_EVENTS
|
||||
TKLog(@" event: %@", currentEvent);
|
||||
#endif
|
||||
|
||||
if (modalSession) {
|
||||
[NSApp _modalSession:modalSession sendEvent:currentEvent];
|
||||
} else {
|
||||
@@ -417,6 +561,25 @@ TkMacOSXEventsCheckProc(
|
||||
*/
|
||||
|
||||
[NSApp _unlockAutoreleasePool];
|
||||
|
||||
/*
|
||||
* Add an idle task to the end of the idle queue which will redisplay
|
||||
* all of our dirty windows. We want this to happen after all other
|
||||
* idle tasks have run so that all widgets will be configured before
|
||||
* they are displayed. The drawRect method "borrows" the idle queue
|
||||
* while drawing views. That is, it sends expose events which cause
|
||||
* display procs to be posted as idle tasks and then runs an inner
|
||||
* event loop to processes those idle tasks. We are trying to arrange
|
||||
* for the idle queue to be empty when it starts that process and empty
|
||||
* when it finishes.
|
||||
*/
|
||||
|
||||
int dirtyCount = 0;
|
||||
TkMacOSXDrawAllViews(&dirtyCount);
|
||||
if (dirtyCount > 0) {
|
||||
Tcl_CancelIdleCall(TkMacOSXDrawAllViews, NULL);
|
||||
Tcl_DoWhenIdle(TkMacOSXDrawAllViews, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* tkMacOSXPort.h --
|
||||
*
|
||||
* This file is included by all of the Tk C files. It contains
|
||||
* This file is included by all of the Tk C files. It contains
|
||||
* information that may be configuration-dependent, such as
|
||||
* #includes for system include files and a few other things.
|
||||
*
|
||||
@@ -17,14 +17,15 @@
|
||||
#define _TKMACPORT
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <pwd.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/file.h>
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
@@ -158,29 +159,38 @@
|
||||
*/
|
||||
|
||||
#define TK_NO_DOUBLE_BUFFERING 1
|
||||
#define TK_HAS_DYNAMIC_COLORS 1
|
||||
#define TK_DYNAMIC_COLORMAP 0x0fffffff
|
||||
|
||||
/*
|
||||
* Magic pixel code values for system colors.
|
||||
*
|
||||
* NOTE: values must be kept in sync with indices into the
|
||||
* systemColorMap array in tkMacOSXColor.c !
|
||||
* Inform tkImgPhInstance.c that our tkPutImage can render an image with an
|
||||
* alpha channel directly into a window.
|
||||
*/
|
||||
|
||||
#define TRANSPARENT_PIXEL 30
|
||||
#define APPEARANCE_PIXEL 52
|
||||
#define PIXEL_MAGIC ((unsigned char) 0x69)
|
||||
#define TKPUTIMAGE_CAN_BLEND
|
||||
|
||||
/*
|
||||
* The following macro returns the pixel value that corresponds to the
|
||||
* 16-bit RGB values in the given XColor structure.
|
||||
* The format is: (PIXEL_MAGIC <<< 24) | (R << 16) | (G << 8) | B
|
||||
* where each of R, G and B is the high order byte of a 16-bit component.
|
||||
* Used by xcolor.c
|
||||
*/
|
||||
|
||||
#define TkpGetPixel(p) ((((((PIXEL_MAGIC << 8) \
|
||||
| (((p)->red >> 8) & 0xff)) << 8) \
|
||||
| (((p)->green >> 8) & 0xff)) << 8) \
|
||||
| (((p)->blue >> 8) & 0xff))
|
||||
MODULE_SCOPE unsigned long TkMacOSXRGBPixel(unsigned long red, unsigned long green,
|
||||
unsigned long blue);
|
||||
#define TkpGetPixel(p) (TkMacOSXRGBPixel(p->red >> 8, p->green >> 8, p->blue >> 8))
|
||||
|
||||
/*
|
||||
* Used by tkWindow.c
|
||||
*/
|
||||
|
||||
MODULE_SCOPE void TkMacOSXHandleMapOrUnmap(Tk_Window tkwin, XEvent *event);
|
||||
|
||||
#define TkpHandleMapOrUnmap(tkwin, event) TkMacOSXHandleMapOrUnmap(tkwin, event)
|
||||
|
||||
/*
|
||||
* Used by tkAppInit
|
||||
*/
|
||||
|
||||
#define USE_CUSTOM_EXIT_PROC
|
||||
EXTERN int TkpWantsExitProc(void);
|
||||
EXTERN TCL_NORETURN void TkpExitProc(void *);
|
||||
|
||||
#endif /* _TKMACPORT */
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
* Macros and declarations that are purely internal & private to TkAqua.
|
||||
*
|
||||
* Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
|
||||
* Copyright 2008-2009, Apple Inc.
|
||||
* Copyright (c) 2008-2009 Apple Inc.
|
||||
* Copyright (c) 2020 Marc Culler
|
||||
*
|
||||
* See the file "license.terms" for information on usage and redistribution
|
||||
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
@@ -19,6 +20,10 @@
|
||||
#error Objective-C compiler required
|
||||
#endif
|
||||
|
||||
#ifndef __clang__
|
||||
#define instancetype id
|
||||
#endif
|
||||
|
||||
#define TextStyle MacTextStyle
|
||||
#import <ApplicationServices/ApplicationServices.h>
|
||||
#import <Cocoa/Cocoa.h>
|
||||
@@ -98,11 +103,11 @@
|
||||
* debug message in case of failure.
|
||||
*/
|
||||
#define ChkErr(f, ...) ({ \
|
||||
OSStatus err = f(__VA_ARGS__); \
|
||||
if (err != noErr) { \
|
||||
TkMacOSXDbgOSErr(f, err); \
|
||||
OSStatus err_ = f(__VA_ARGS__); \
|
||||
if (err_ != noErr) { \
|
||||
TkMacOSXDbgOSErr(f, err_); \
|
||||
} \
|
||||
err;})
|
||||
err_;})
|
||||
|
||||
#else /* TK_MAC_DEBUG */
|
||||
#define TKLog(f, ...)
|
||||
@@ -122,6 +127,74 @@
|
||||
STRINGIFY(symbol)); \
|
||||
}
|
||||
|
||||
/*
|
||||
* The structure of a 32-bit XEvent keycode on macOS. It may be viewed as
|
||||
* an unsigned int or as having either two or three bitfields.
|
||||
*/
|
||||
|
||||
typedef struct keycode_v_t {
|
||||
unsigned keychar: 22; /* UCS-32 character */
|
||||
unsigned o_s: 2; /* State of Option and Shift keys. */
|
||||
unsigned virtual: 8; /* 8-bit virtual keycode - identifies a key. */
|
||||
} keycode_v;
|
||||
|
||||
typedef struct keycode_x_t {
|
||||
unsigned keychar: 22; /* UCS-32 character */
|
||||
unsigned xvirtual: 10; /* Combines o_s and virtual. This 10-bit integer
|
||||
* is used as a key for looking up the character
|
||||
* produced when pressing a key with a particular
|
||||
* Shift and Option modifier state. */
|
||||
} keycode_x;
|
||||
|
||||
typedef union MacKeycode_t {
|
||||
unsigned int uint;
|
||||
keycode_v v;
|
||||
keycode_x x;
|
||||
} MacKeycode;
|
||||
|
||||
/*
|
||||
* Macros used in tkMacOSXKeyboard.c and tkMacOSXKeyEvent.c.
|
||||
* Note that 0x7f is del and 0xF8FF is the Apple Logo character.
|
||||
*/
|
||||
|
||||
#define ON_KEYPAD(virtual) ((virtual >= 0x41) && (virtual <= 0x5C))
|
||||
#define IS_PRINTABLE(keychar) ((keychar >= 0x20) && (keychar != 0x7f) && \
|
||||
((keychar < 0xF700) || keychar >= 0xF8FF))
|
||||
|
||||
/*
|
||||
* An "index" is 2-bit bitfield showing the state of the Option and Shift
|
||||
* keys. It is used as an index when building the keymaps and it
|
||||
* is the value of the o_s bitfield of a keycode_v.
|
||||
*/
|
||||
|
||||
#define INDEX_SHIFT 1
|
||||
#define INDEX_OPTION 2
|
||||
#define INDEX2STATE(index) ((index & INDEX_SHIFT ? ShiftMask : 0) | \
|
||||
(index & INDEX_OPTION ? Mod2Mask : 0))
|
||||
#define INDEX2CARBON(index) ((index & INDEX_SHIFT ? shiftKey : 0) | \
|
||||
(index & INDEX_OPTION ? optionKey : 0))
|
||||
#define STATE2INDEX(state) ((state & ShiftMask ? INDEX_SHIFT : 0) | \
|
||||
(state & Mod2Mask ? INDEX_OPTION : 0))
|
||||
|
||||
/*
|
||||
* Special values for the virtual bitfield. Actual virtual keycodes are < 128.
|
||||
*/
|
||||
|
||||
#define NO_VIRTUAL 0xFF /* Not generated by a key or the NSText"InputClient. */
|
||||
#define REPLACEMENT_VIRTUAL 0x80 /* A BMP char sent by the NSTextInputClient. */
|
||||
#define NON_BMP_VIRTUAL 0x81 /* A non-BMP char sent by the NSTextInputClient. */
|
||||
|
||||
/*
|
||||
* A special character is used in the keycode for simulated modifier KeyPress
|
||||
* or KeyRelease XEvents. It is near the end of the private-use range but
|
||||
* different from the UniChar 0xF8FF which Apple uses for their logo character.
|
||||
* A different special character is used for keys, like the Menu key, which do
|
||||
* not appear on Macintosh keyboards.
|
||||
*/
|
||||
|
||||
#define MOD_KEYCHAR 0xF8FE
|
||||
#define UNKNOWN_KEYCHAR 0xF8FD
|
||||
|
||||
/*
|
||||
* Structure encapsulating current drawing environment.
|
||||
*/
|
||||
@@ -143,24 +216,15 @@ MODULE_SCOPE long tkMacOSXMacOSXVersion;
|
||||
* Prototypes for TkMacOSXRegion.c.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
MODULE_SCOPE void TkMacOSXEmtpyRegion(TkRegion r);
|
||||
MODULE_SCOPE int TkMacOSXIsEmptyRegion(TkRegion r);
|
||||
#endif
|
||||
MODULE_SCOPE HIShapeRef TkMacOSXGetNativeRegion(TkRegion r);
|
||||
MODULE_SCOPE void TkMacOSXSetWithNativeRegion(TkRegion r,
|
||||
HIShapeRef rgn);
|
||||
MODULE_SCOPE void TkMacOSXOffsetRegion(TkRegion r, short dx, short dy);
|
||||
MODULE_SCOPE HIShapeRef TkMacOSXHIShapeCreateEmpty(void);
|
||||
MODULE_SCOPE HIMutableShapeRef TkMacOSXHIShapeCreateMutableWithRect(
|
||||
const CGRect *inRect);
|
||||
MODULE_SCOPE OSStatus TkMacOSXHIShapeSetWithShape(
|
||||
HIMutableShapeRef inDestShape,
|
||||
HIShapeRef inSrcShape);
|
||||
#if 0
|
||||
MODULE_SCOPE OSStatus TkMacOSXHIShapeSetWithRect(HIMutableShapeRef inShape,
|
||||
const CGRect *inRect);
|
||||
#endif
|
||||
MODULE_SCOPE OSStatus TkMacOSHIShapeDifferenceWithRect(
|
||||
HIMutableShapeRef inShape, const CGRect *inRect);
|
||||
MODULE_SCOPE OSStatus TkMacOSHIShapeUnionWithRect(HIMutableShapeRef inShape,
|
||||
@@ -181,46 +245,31 @@ MODULE_SCOPE int TkMacOSXUseAntialiasedText(Tcl_Interp *interp,
|
||||
int enable);
|
||||
MODULE_SCOPE int TkMacOSXInitCGDrawing(Tcl_Interp *interp, int enable,
|
||||
int antiAlias);
|
||||
MODULE_SCOPE int TkMacOSXGenerateFocusEvent(TkWindow *winPtr,
|
||||
int activeFlag);
|
||||
MODULE_SCOPE WindowClass TkMacOSXWindowClass(TkWindow *winPtr);
|
||||
MODULE_SCOPE int TkMacOSXIsWindowZoomed(TkWindow *winPtr);
|
||||
MODULE_SCOPE int TkGenerateButtonEventForXPointer(Window window);
|
||||
MODULE_SCOPE EventModifiers TkMacOSXModifierState(void);
|
||||
MODULE_SCOPE NSBitmapImageRep* TkMacOSXBitmapRepFromDrawableRect(Drawable drawable,
|
||||
int x, int y, unsigned int width, unsigned int height);
|
||||
MODULE_SCOPE CGImageRef TkMacOSXCreateCGImageWithXImage(XImage *image);
|
||||
MODULE_SCOPE void TkMacOSXDrawCGImage(Drawable d, GC gc, CGContextRef context,
|
||||
CGImageRef image, unsigned long imageForeground,
|
||||
unsigned long imageBackground, CGRect imageBounds,
|
||||
CGRect srcBounds, CGRect dstBounds);
|
||||
MODULE_SCOPE int TkMacOSXSetupDrawingContext(Drawable d, GC gc,
|
||||
int useCG, TkMacOSXDrawingContext *dcPtr);
|
||||
TkMacOSXDrawingContext *dcPtr);
|
||||
MODULE_SCOPE void TkMacOSXRestoreDrawingContext(
|
||||
TkMacOSXDrawingContext *dcPtr);
|
||||
MODULE_SCOPE void TkMacOSXSetColorInContext(GC gc, unsigned long pixel,
|
||||
CGContextRef context);
|
||||
MODULE_SCOPE int TkMacOSXMakeFullscreen(TkWindow *winPtr,
|
||||
NSWindow *window, int fullscreen,
|
||||
Tcl_Interp *interp);
|
||||
MODULE_SCOPE void TkMacOSXEnterExitFullscreen(TkWindow *winPtr,
|
||||
int active);
|
||||
MODULE_SCOPE NSWindow* TkMacOSXDrawableWindow(Drawable drawable);
|
||||
MODULE_SCOPE NSView* TkMacOSXDrawableView(MacDrawable *macWin);
|
||||
#define TkMacOSXGetTkWindow(window) (TkWindow *)Tk_MacOSXGetTkWindow(window)
|
||||
#define TkMacOSXGetNSWindowForDrawable(drawable) ((NSWindow*)TkMacOSXDrawable(drawable))
|
||||
#define TkMacOSXGetNSViewForDrawable(macWin) (NSView *)Tk_MacOSXGetNSViewForDrawable((Drawable)(macWin))
|
||||
MODULE_SCOPE void TkMacOSXWinCGBounds(TkWindow *winPtr, CGRect *bounds);
|
||||
MODULE_SCOPE HIShapeRef TkMacOSXGetClipRgn(Drawable drawable);
|
||||
MODULE_SCOPE void TkMacOSXInvalidateViewRegion(NSView *view,
|
||||
HIShapeRef rgn);
|
||||
MODULE_SCOPE CGContextRef TkMacOSXGetCGContextForDrawable(Drawable drawable);
|
||||
MODULE_SCOPE CGImageRef TkMacOSXCreateCGImageWithDrawable(Drawable drawable);
|
||||
MODULE_SCOPE NSImage* TkMacOSXGetNSImageWithTkImage(Display *display,
|
||||
MODULE_SCOPE NSImage* TkMacOSXGetNSImageFromTkImage(Display *display,
|
||||
Tk_Image image, int width, int height);
|
||||
MODULE_SCOPE NSImage* TkMacOSXGetNSImageWithBitmap(Display *display,
|
||||
MODULE_SCOPE NSImage* TkMacOSXGetNSImageFromBitmap(Display *display,
|
||||
Pixmap bitmap, GC gc, int width, int height);
|
||||
MODULE_SCOPE CGColorRef TkMacOSXCreateCGColor(GC gc, unsigned long pixel);
|
||||
MODULE_SCOPE NSColor* TkMacOSXGetNSColor(GC gc, unsigned long pixel);
|
||||
MODULE_SCOPE Tcl_Obj * TkMacOSXGetStringObjFromCFString(CFStringRef str);
|
||||
MODULE_SCOPE TkWindow* TkMacOSXGetTkWindow(NSWindow *w);
|
||||
MODULE_SCOPE NSFont* TkMacOSXNSFontForFont(Tk_Font tkfont);
|
||||
MODULE_SCOPE NSDictionary* TkMacOSXNSFontAttributesForFont(Tk_Font tkfont);
|
||||
MODULE_SCOPE NSModalSession TkMacOSXGetModalSession(void);
|
||||
@@ -237,12 +286,13 @@ MODULE_SCOPE void TkMacOSXDrawSolidBorder(Tk_Window tkwin, GC gc,
|
||||
int inset, int thickness);
|
||||
MODULE_SCOPE int TkMacOSXServices_Init(Tcl_Interp *interp);
|
||||
MODULE_SCOPE int TkMacOSXRegisterServiceWidgetObjCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
MODULE_SCOPE NSString* TclUniToNSString(const char *source, int numBytes);
|
||||
MODULE_SCOPE int TclUniAtIndex(NSString *string, int index, char *uni,
|
||||
unsigned int *code);
|
||||
MODULE_SCOPE char* NSStringToTclUni(NSString *string, int *numBytes);
|
||||
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
|
||||
MODULE_SCOPE unsigned TkMacOSXAddVirtual(unsigned int keycode);
|
||||
MODULE_SCOPE void TkMacOSXWinNSBounds(TkWindow *winPtr, NSView *view,
|
||||
NSRect *bounds);
|
||||
MODULE_SCOPE Bool TkMacOSXInDarkMode(Tk_Window tkwin);
|
||||
MODULE_SCOPE void TkMacOSXDrawAllViews(ClientData clientData);
|
||||
MODULE_SCOPE unsigned long TkMacOSXClearPixel(void);
|
||||
|
||||
#pragma mark Private Objective-C Classes
|
||||
|
||||
@@ -273,16 +323,21 @@ VISIBILITY_HIDDEN
|
||||
NSArray *_defaultApplicationMenuItems, *_defaultWindowsMenuItems;
|
||||
NSArray *_defaultHelpMenuItems, *_defaultFileMenuItems;
|
||||
NSAutoreleasePool *_mainPool;
|
||||
NSThread *_backgoundLoop;
|
||||
|
||||
#ifdef __i386__
|
||||
/* The Objective C runtime used on i386 requires this. */
|
||||
int _poolLock;
|
||||
int _macMinorVersion;
|
||||
int _macOSVersion; /* 10000 * major + 100*minor */
|
||||
Bool _isDrawing;
|
||||
Bool _needsToDraw;
|
||||
#endif
|
||||
|
||||
}
|
||||
@property int poolLock;
|
||||
@property int macMinorVersion;
|
||||
@property int macOSVersion;
|
||||
@property Bool isDrawing;
|
||||
@property Bool needsToDraw;
|
||||
|
||||
@end
|
||||
@interface TKApplication(TKInit)
|
||||
@@ -308,6 +363,7 @@ VISIBILITY_HIDDEN
|
||||
@interface NSApplication(TKNotify)
|
||||
/* We need to declare this hidden method. */
|
||||
- (void) _modalSession: (NSModalSession) session sendEvent: (NSEvent *) event;
|
||||
- (void) _runBackgroundLoop;
|
||||
@end
|
||||
@interface TKApplication(TKEvent)
|
||||
- (NSEvent *)tkProcessEvent:(NSEvent *)theEvent;
|
||||
@@ -324,6 +380,7 @@ VISIBILITY_HIDDEN
|
||||
@end
|
||||
@interface TKApplication(TKHLEvents)
|
||||
- (void) terminate: (id) sender;
|
||||
- (void) superTerminate: (id) sender;
|
||||
- (void) preferences: (id) sender;
|
||||
- (void) handleQuitApplicationEvent: (NSAppleEventDescriptor *)event
|
||||
withReplyEvent: (NSAppleEventDescriptor *)replyEvent;
|
||||
@@ -353,17 +410,22 @@ VISIBILITY_HIDDEN
|
||||
{
|
||||
@private
|
||||
NSString *privateWorkingText;
|
||||
Bool _needsRedisplay;
|
||||
Bool _tkNeedsDisplay;
|
||||
NSRect _tkDirtyRect;
|
||||
}
|
||||
@property Bool needsRedisplay;
|
||||
@property Bool tkNeedsDisplay;
|
||||
@property NSRect tkDirtyRect;
|
||||
@end
|
||||
|
||||
@interface TKContentView(TKKeyEvent)
|
||||
- (void) deleteWorkingText;
|
||||
- (void) cancelComposingText;
|
||||
@end
|
||||
|
||||
@interface TKContentView(TKWindowEvent)
|
||||
- (void) generateExposeEvents: (HIShapeRef) shape;
|
||||
- (void) addTkDirtyRect: (NSRect) rect;
|
||||
- (void) clearTkDirtyRect;
|
||||
- (void) generateExposeEvents: (NSRect) rect;
|
||||
- (void) tkToolbarButton: (id) sender;
|
||||
@end
|
||||
|
||||
@@ -374,16 +436,40 @@ VISIBILITY_HIDDEN
|
||||
|
||||
VISIBILITY_HIDDEN
|
||||
@interface TKWindow : NSWindow
|
||||
{
|
||||
#ifdef __i386__
|
||||
/* The Objective C runtime used on i386 requires this. */
|
||||
Bool _mouseInResizeArea;
|
||||
Window _tkWindow;
|
||||
#endif
|
||||
}
|
||||
@property Bool mouseInResizeArea;
|
||||
@property Window tkWindow;
|
||||
@end
|
||||
|
||||
@interface TKWindow(TKWm)
|
||||
- (void) tkLayoutChanged;
|
||||
@end
|
||||
|
||||
@interface NSDrawerWindow : NSWindow
|
||||
@interface TKDrawerWindow : NSWindow
|
||||
{
|
||||
id _i1, _i2;
|
||||
#ifdef __i386__
|
||||
/* The Objective C runtime used on i386 requires this. */
|
||||
Window _tkWindow;
|
||||
#endif
|
||||
}
|
||||
@property Window tkWindow;
|
||||
@end
|
||||
|
||||
@interface TKPanel : NSPanel
|
||||
{
|
||||
#ifdef __i386__
|
||||
/* The Objective C runtime used on i386 requires this. */
|
||||
Window _tkWindow;
|
||||
#endif
|
||||
}
|
||||
@property Window tkWindow;
|
||||
@end
|
||||
|
||||
#pragma mark NSMenu & NSMenuItem Utilities
|
||||
@@ -433,10 +519,54 @@ VISIBILITY_HIDDEN
|
||||
- (void) setAppleMenu: (NSMenu *) menu;
|
||||
@end
|
||||
|
||||
/*
|
||||
* These methods are exposed because they are needed to prevent zombie windows
|
||||
* on systems with a TouchBar. The TouchBar Key-Value observer holds a
|
||||
* reference to the key window, which prevents deallocation of the key window
|
||||
* when it is closed.
|
||||
*/
|
||||
|
||||
@interface NSApplication(TkWm)
|
||||
- (id) _setKeyWindow: (NSWindow *) window;
|
||||
- (id) _setMainWindow: (NSWindow *) window;
|
||||
@end
|
||||
|
||||
|
||||
/*
|
||||
*---------------------------------------------------------------------------
|
||||
*
|
||||
* TKNSString --
|
||||
*
|
||||
* When Tcl is compiled with TCL_UTF_MAX = 3 (the default for 8.6) it cannot
|
||||
* deal directly with UTF-8 encoded non-BMP characters, since their UTF-8
|
||||
* encoding requires 4 bytes. Instead, when using these versions of Tcl, Tk
|
||||
* uses the CESU-8 encoding internally. This encoding is similar to UTF-8
|
||||
* except that it allows encoding surrogate characters as 3-byte sequences
|
||||
* using the same algorithm which UTF-8 uses for non-surrogates. This means
|
||||
* that a non-BMP character is encoded as a string of length 6. Apple's
|
||||
* NSString class does not provide a constructor which accepts a CESU-8 encoded
|
||||
* byte sequence as initial data. So we add a new class which does provide
|
||||
* such a constructor. It also has a DString property which is a DString whose
|
||||
* string pointer is a byte sequence encoding the NSString with the current Tk
|
||||
* encoding, namely UTF-8 if TCL_UTF_MAX >= 4 or CESU-8 if TCL_UTF_MAX = 3.
|
||||
*
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@interface TKNSString:NSString {
|
||||
@private
|
||||
Tcl_DString _ds;
|
||||
NSString *_string;
|
||||
const char *_UTF8String;
|
||||
}
|
||||
@property const char *UTF8String;
|
||||
@property (readonly) Tcl_DString DString;
|
||||
- (instancetype)initWithTclUtfBytes:(const void *)bytes
|
||||
length:(NSUInteger)len;
|
||||
@end
|
||||
|
||||
#endif /* _TKMACPRIV */
|
||||
|
||||
int TkMacOSXGetAppPath(ClientData cd, Tcl_Interp *ip, int objc, Tcl_Obj *const objv[]);
|
||||
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: objc
|
||||
|
||||
@@ -12,6 +12,16 @@
|
||||
*/
|
||||
|
||||
#include "tkMacOSXPrivate.h"
|
||||
static void RetainRegion(TkRegion r);
|
||||
static void ReleaseRegion(TkRegion r);
|
||||
|
||||
#ifdef DEBUG
|
||||
static int totalRegions = 0;
|
||||
static int totalRegionRetainCount = 0;
|
||||
#define DebugLog(msg, ...) fprintf(stderr, (msg), ##__VA_ARGS__)
|
||||
#else
|
||||
#define DebugLog(msg, ...)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
@@ -34,7 +44,10 @@
|
||||
TkRegion
|
||||
TkCreateRegion(void)
|
||||
{
|
||||
return (TkRegion) HIShapeCreateMutable();
|
||||
TkRegion region = (TkRegion) HIShapeCreateMutable();
|
||||
DebugLog("Created region: total regions = %d\n", ++totalRegions);
|
||||
RetainRegion(region);
|
||||
return region;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -59,7 +72,8 @@ TkDestroyRegion(
|
||||
TkRegion r)
|
||||
{
|
||||
if (r) {
|
||||
CFRelease(r);
|
||||
DebugLog("Destroyed region: total regions = %d\n", --totalRegions);
|
||||
ReleaseRegion(r);
|
||||
}
|
||||
return Success;
|
||||
}
|
||||
@@ -175,7 +189,7 @@ TkUnionRectWithRegion(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
static int
|
||||
TkMacOSXIsEmptyRegion(
|
||||
TkRegion r)
|
||||
{
|
||||
@@ -320,7 +334,7 @@ TkpBuildRegionFromAlphaData(
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TkpRetainRegion --
|
||||
* RetainRegion --
|
||||
*
|
||||
* Increases reference count of region.
|
||||
*
|
||||
@@ -333,17 +347,18 @@ TkpBuildRegionFromAlphaData(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
TkpRetainRegion(
|
||||
static void
|
||||
RetainRegion(
|
||||
TkRegion r)
|
||||
{
|
||||
CFRetain(r);
|
||||
DebugLog("Retained region: total count is %d\n", ++totalRegionRetainCount);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TkpReleaseRegion --
|
||||
* ReleaseRegion --
|
||||
*
|
||||
* Decreases reference count of region.
|
||||
*
|
||||
@@ -356,11 +371,12 @@ TkpRetainRegion(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
TkpReleaseRegion(
|
||||
static void
|
||||
ReleaseRegion(
|
||||
TkRegion r)
|
||||
{
|
||||
CFRelease(r);
|
||||
DebugLog("Released region: total count is %d\n", --totalRegionRetainCount);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -436,7 +452,7 @@ TkMacOSXSetWithNativeRegion(
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TkMacOSXOffsetRegion --
|
||||
* XOffsetRegion --
|
||||
*
|
||||
* Offsets region by given distances.
|
||||
*
|
||||
@@ -449,20 +465,21 @@ TkMacOSXSetWithNativeRegion(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
TkMacOSXOffsetRegion(
|
||||
TkRegion r,
|
||||
short dx,
|
||||
short dy)
|
||||
int
|
||||
XOffsetRegion(
|
||||
void *r,
|
||||
int dx,
|
||||
int dy)
|
||||
{
|
||||
ChkErr(HIShapeOffset, (HIMutableShapeRef) r, dx, dy);
|
||||
return Success;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TkMacOSXHIShapeCreateEmpty, TkMacOSXHIShapeCreateMutableWithRect,
|
||||
* TkMacOSXHIShapeSetWithShape, TkMacOSXHIShapeSetWithRect,
|
||||
* TkMacOSXHIShapeSetWithShape,
|
||||
* TkMacOSHIShapeDifferenceWithRect, TkMacOSHIShapeUnionWithRect,
|
||||
* TkMacOSHIShapeUnion --
|
||||
*
|
||||
@@ -501,22 +518,6 @@ TkMacOSXHIShapeSetWithShape(
|
||||
return result;
|
||||
}
|
||||
|
||||
#if 0
|
||||
OSStatus
|
||||
TkMacOSXHIShapeSetWithRect(
|
||||
HIMutableShapeRef inShape,
|
||||
const CGRect *inRect)
|
||||
{
|
||||
OSStatus result;
|
||||
HIShapeRef rgn = HIShapeCreateWithRect(inRect);
|
||||
|
||||
result = TkMacOSXHIShapeSetWithShape(inShape, rgn);
|
||||
CFRelease(rgn);
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
OSStatus
|
||||
TkMacOSHIShapeDifferenceWithRect(
|
||||
HIMutableShapeRef inShape,
|
||||
|
||||
@@ -76,7 +76,7 @@ TkScale *
|
||||
TkpCreateScale(
|
||||
Tk_Window tkwin)
|
||||
{
|
||||
MacScale *macScalePtr = ckalloc(sizeof(MacScale));
|
||||
MacScale *macScalePtr = (MacScale *)ckalloc(sizeof(MacScale));
|
||||
|
||||
macScalePtr->scaleHandle = NULL;
|
||||
if (scaleActionProc == NULL) {
|
||||
@@ -149,8 +149,6 @@ TkpDisplayScale(
|
||||
MacScale *macScalePtr = clientData;
|
||||
Rect r;
|
||||
WindowRef windowRef;
|
||||
CGrafPtr destPort, savePort;
|
||||
Boolean portChanged;
|
||||
MacDrawable *macDraw;
|
||||
SInt32 initialValue, minValue, maxValue;
|
||||
UInt16 numTicks;
|
||||
@@ -179,7 +177,7 @@ TkpDisplayScale(
|
||||
Tcl_DStringAppend(&buf, scalePtr->command, -1);
|
||||
Tcl_DStringAppend(&buf, " ", -1);
|
||||
Tcl_DStringAppend(&buf, string, -1);
|
||||
result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, 0);
|
||||
result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, TCL_EVAL_GLOBAL);
|
||||
Tcl_DStringFree(&buf);
|
||||
if (result != TCL_OK) {
|
||||
Tcl_AddErrorInfo(interp, "\n (command executed by scale)");
|
||||
@@ -215,11 +213,8 @@ TkpDisplayScale(
|
||||
* Set up port for drawing Macintosh control.
|
||||
*/
|
||||
|
||||
macDraw = (MacDrawable *) Tk_WindowId(tkwin);
|
||||
destPort = TkMacOSXGetDrawablePort(Tk_WindowId(tkwin));
|
||||
windowRef = TkMacOSXDrawableWindow(Tk_WindowId(tkwin));
|
||||
portChanged = QDSwapPort(destPort, &savePort);
|
||||
TkMacOSXSetUpClippingRgn(Tk_WindowId(tkwin));
|
||||
macDraw = (MacDrawable *)Tk_WindowId(tkwin);
|
||||
windowRef = TkMacOSXGetNSWindowForDrawable(Tk_WindowId(tkwin));
|
||||
|
||||
/*
|
||||
* Create Macintosh control.
|
||||
@@ -292,10 +287,6 @@ TkpDisplayScale(
|
||||
SetControlVisibility(macScalePtr->scaleHandle, true, true);
|
||||
HiliteControl(macScalePtr->scaleHandle, 0);
|
||||
Draw1Control(macScalePtr->scaleHandle);
|
||||
|
||||
if (portChanged) {
|
||||
QDSwapPort(savePort, NULL);
|
||||
}
|
||||
done:
|
||||
scalePtr->flags &= ~REDRAW_ALL;
|
||||
}
|
||||
@@ -327,14 +318,10 @@ TkpScaleElement(
|
||||
ControlPartCode part;
|
||||
Point where;
|
||||
Rect bounds;
|
||||
CGrafPtr destPort, savePort;
|
||||
Boolean portChanged;
|
||||
|
||||
#ifdef TK_MAC_DEBUG_SCALE
|
||||
TkMacOSXDbgMsg("TkpScaleElement");
|
||||
#endif
|
||||
destPort = TkMacOSXGetDrawablePort(Tk_WindowId(scalePtr->tkwin));
|
||||
portChanged = QDSwapPort(destPort, &savePort);
|
||||
|
||||
/*
|
||||
* All of the calculations in this procedure mirror those in
|
||||
@@ -346,10 +333,6 @@ TkpScaleElement(
|
||||
where.v = y + bounds.top;
|
||||
part = TestControl(macScalePtr->scaleHandle, where);
|
||||
|
||||
if (portChanged) {
|
||||
QDSwapPort(savePort, NULL);
|
||||
}
|
||||
|
||||
#ifdef TK_MAC_DEBUG_SCALE
|
||||
fprintf (stderr,"ScalePart %d, pos ( %d %d )\n", part, where.h, where.v );
|
||||
#endif
|
||||
@@ -401,23 +384,11 @@ MacScaleEventProc(
|
||||
Point where;
|
||||
Rect bounds;
|
||||
int part;
|
||||
CGrafPtr destPort, savePort;
|
||||
Boolean portChanged;
|
||||
|
||||
#ifdef TK_MAC_DEBUG_SCALE
|
||||
fprintf(stderr,"MacScaleEventProc\n" );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* To call Macintosh control routines we must have the port set to the
|
||||
* window containing the control. We will then test which part of the
|
||||
* control was hit and act accordingly.
|
||||
*/
|
||||
|
||||
destPort = TkMacOSXGetDrawablePort(Tk_WindowId(macScalePtr->info.tkwin));
|
||||
portChanged = QDSwapPort(destPort, &savePort);
|
||||
TkMacOSXSetUpClippingRgn(Tk_WindowId(macScalePtr->info.tkwin));
|
||||
|
||||
TkMacOSXWinBounds((TkWindow *) macScalePtr->info.tkwin, &bounds);
|
||||
where.h = eventPtr->xbutton.x + bounds.left;
|
||||
where.v = eventPtr->xbutton.y + bounds.top;
|
||||
@@ -447,10 +418,6 @@ MacScaleEventProc(
|
||||
*/
|
||||
|
||||
TkGenerateButtonEventForXPointer(Tk_WindowId(macScalePtr->info.tkwin));
|
||||
|
||||
if (portChanged) {
|
||||
QDSwapPort(savePort, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -121,7 +121,7 @@ TkScrollbar *
|
||||
TkpCreateScrollbar(
|
||||
Tk_Window tkwin)
|
||||
{
|
||||
MacScrollbar *scrollPtr = ckalloc(sizeof(MacScrollbar));
|
||||
MacScrollbar *scrollPtr = (MacScrollbar *)ckalloc(sizeof(MacScrollbar));
|
||||
|
||||
scrollPtr->troughGC = NULL;
|
||||
scrollPtr->copyGC = NULL;
|
||||
@@ -174,8 +174,8 @@ static void drawMacScrollbar(
|
||||
MacScrollbar *msPtr,
|
||||
CGContextRef context)
|
||||
{
|
||||
MacDrawable *macWin = (MacDrawable *) Tk_WindowId(scrollPtr->tkwin);
|
||||
NSView *view = TkMacOSXDrawableView(macWin);
|
||||
Drawable d = Tk_WindowId(scrollPtr->tkwin);
|
||||
NSView *view = TkMacOSXGetNSViewForDrawable(d);
|
||||
CGPathRef path;
|
||||
CGPoint inner[2], outer[2], thumbOrigin;
|
||||
CGSize thumbSize;
|
||||
@@ -246,9 +246,9 @@ void
|
||||
TkpDisplayScrollbar(
|
||||
ClientData clientData) /* Information about window. */
|
||||
{
|
||||
register TkScrollbar *scrollPtr = clientData;
|
||||
TkScrollbar *scrollPtr = clientData;
|
||||
MacScrollbar *msPtr = (MacScrollbar *) scrollPtr;
|
||||
register Tk_Window tkwin = scrollPtr->tkwin;
|
||||
Tk_Window tkwin = scrollPtr->tkwin;
|
||||
TkWindow *winPtr = (TkWindow *) tkwin;
|
||||
TkMacOSXDrawingContext dc;
|
||||
|
||||
@@ -258,12 +258,12 @@ TkpDisplayScrollbar(
|
||||
return;
|
||||
}
|
||||
|
||||
MacDrawable *macWin = (MacDrawable *) winPtr->window;
|
||||
NSView *view = TkMacOSXDrawableView(macWin);
|
||||
MacDrawable *macWin = (MacDrawable *)winPtr->window;
|
||||
NSView *view = TkMacOSXGetNSViewForDrawable(macWin);
|
||||
|
||||
if ((view == NULL)
|
||||
|| (macWin->flags & TK_DO_NOT_DRAW)
|
||||
|| !TkMacOSXSetupDrawingContext((Drawable) macWin, NULL, 1, &dc)) {
|
||||
|| !TkMacOSXSetupDrawingContext((Drawable)macWin, NULL, &dc)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -316,7 +316,7 @@ TkpDisplayScrollbar(
|
||||
if (SNOW_LEOPARD_STYLE) {
|
||||
HIThemeDrawTrack(&msPtr->info, 0, dc.context,
|
||||
kHIThemeOrientationInverted);
|
||||
} else if ([NSApp macMinorVersion] <= 8) {
|
||||
} else if ([NSApp macOSVersion] <= 100800) {
|
||||
HIThemeDrawTrack(&msPtr->info, 0, dc.context,
|
||||
kHIThemeOrientationNormal);
|
||||
} else {
|
||||
@@ -354,7 +354,7 @@ TkpDisplayScrollbar(
|
||||
|
||||
extern void
|
||||
TkpComputeScrollbarGeometry(
|
||||
register TkScrollbar *scrollPtr)
|
||||
TkScrollbar *scrollPtr)
|
||||
/* Scrollbar whose geometry may have
|
||||
* changed. */
|
||||
{
|
||||
@@ -377,7 +377,7 @@ TkpComputeScrollbarGeometry(
|
||||
scrollPtr->highlightWidth = 0;
|
||||
}
|
||||
scrollPtr->inset = scrollPtr->highlightWidth + scrollPtr->borderWidth;
|
||||
if ([NSApp macMinorVersion] == 6) {
|
||||
if ([NSApp macOSVersion] == 100600) {
|
||||
scrollPtr->arrowLength = scrollPtr->width;
|
||||
} else {
|
||||
scrollPtr->arrowLength = 0;
|
||||
@@ -484,7 +484,7 @@ TkpDestroyScrollbar(
|
||||
|
||||
void
|
||||
TkpConfigureScrollbar(
|
||||
register TkScrollbar *scrollPtr)
|
||||
TkScrollbar *scrollPtr)
|
||||
{
|
||||
/* empty */
|
||||
}
|
||||
@@ -509,7 +509,7 @@ TkpConfigureScrollbar(
|
||||
|
||||
int
|
||||
TkpScrollbarPosition(
|
||||
register TkScrollbar *scrollPtr,
|
||||
TkScrollbar *scrollPtr,
|
||||
/* Scrollbar widget record. */
|
||||
int x, int y) /* Coordinates within scrollPtr's window. */
|
||||
{
|
||||
@@ -519,7 +519,7 @@ TkpScrollbarPosition(
|
||||
*/
|
||||
|
||||
int length, width, tmp;
|
||||
register const int inset = scrollPtr->inset;
|
||||
const int inset = scrollPtr->inset;
|
||||
|
||||
if (scrollPtr->vertical) {
|
||||
length = Tk_Height(scrollPtr->tkwin);
|
||||
@@ -589,12 +589,12 @@ UpdateControlValues(
|
||||
{
|
||||
MacScrollbar *msPtr = (MacScrollbar *) scrollPtr;
|
||||
Tk_Window tkwin = scrollPtr->tkwin;
|
||||
MacDrawable *macWin = (MacDrawable *) Tk_WindowId(scrollPtr->tkwin);
|
||||
MacDrawable *macWin = (MacDrawable *)Tk_WindowId(scrollPtr->tkwin);
|
||||
double dViewSize;
|
||||
HIRect contrlRect;
|
||||
short width, height;
|
||||
|
||||
NSView *view = TkMacOSXDrawableView(macWin);
|
||||
NSView *view = TkMacOSXGetNSViewForDrawable(macWin);
|
||||
CGFloat viewHeight = [view bounds].size.height;
|
||||
NSRect frame;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file provides procedures that implement the "send" command,
|
||||
* allowing commands to be passed from interpreter to interpreter. This
|
||||
* current implementation for the Mac has most functionality stubed out.
|
||||
* current implementation for the Mac has most functionality stubbed out.
|
||||
*
|
||||
* The current plan, which we have not had time to implement, is for the
|
||||
* first Wish app to create a gestalt of type 'WIsH'. This gestalt will
|
||||
|
||||
@@ -20,10 +20,11 @@
|
||||
|
||||
static int
|
||||
ServicesEventProc(
|
||||
Tcl_Event *event,
|
||||
int flags)
|
||||
TCL_UNUSED(Tcl_Event *),
|
||||
TCL_UNUSED(int))
|
||||
{
|
||||
TkMainInfo *info = TkGetMainInfoList();
|
||||
|
||||
Tcl_GlobalEval(info->interp, "::tk::mac::PerformService");
|
||||
return 1;
|
||||
}
|
||||
@@ -43,8 +44,8 @@ ServicesEventProc(
|
||||
- (void) provideService:(NSPasteboard *)pboard
|
||||
userData:(NSString *)data
|
||||
error:(NSString **)error;
|
||||
- (BOOL)writeSelectionToPasteboard:(NSPasteboard *)pboard
|
||||
types:(NSArray *)types;
|
||||
- (BOOL) writeSelectionToPasteboard:(NSPasteboard *)pboard
|
||||
types:(NSArray *)types;
|
||||
|
||||
@end
|
||||
|
||||
@@ -104,6 +105,8 @@ ServicesEventProc(
|
||||
NSString *pboardString = nil, *pboardType = nil;
|
||||
NSArray *types = [pboard types];
|
||||
Tcl_Event *event;
|
||||
(void)data;
|
||||
(void)error;
|
||||
|
||||
/*
|
||||
* Get a string from the private pasteboard and copy it to the general
|
||||
@@ -123,7 +126,7 @@ ServicesEventProc(
|
||||
[generalpasteboard declareTypes:[NSArray arrayWithObjects:pboardType, nil]
|
||||
owner:nil];
|
||||
[generalpasteboard setString:pboardString forType:pboardType];
|
||||
event = ckalloc(sizeof(Tcl_Event));
|
||||
event = (Tcl_Event *)ckalloc(sizeof(Tcl_Event));
|
||||
event->proc = ServicesEventProc;
|
||||
Tcl_QueueEvent((Tcl_Event *)event, TCL_QUEUE_TAIL);
|
||||
}
|
||||
@@ -137,7 +140,7 @@ ServicesEventProc(
|
||||
|
||||
int
|
||||
TkMacOSXServices_Init(
|
||||
Tcl_Interp *interp)
|
||||
TCL_UNUSED(Tcl_Interp *))
|
||||
{
|
||||
/*
|
||||
* Initialize an instance of TkService and register it with the NSApp.
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "tkMacOSXPrivate.h"
|
||||
#include "tkMacOSXDebug.h"
|
||||
#include "tkMacOSXWm.h"
|
||||
#include "tkMacOSXConstants.h"
|
||||
|
||||
/*
|
||||
#ifdef TK_MAC_DEBUG
|
||||
@@ -38,7 +39,7 @@ static void NotifyVisibility(TkWindow *winPtr, XEvent *eventPtr);
|
||||
*
|
||||
* XDestroyWindow --
|
||||
*
|
||||
* Dealocates the given X Window.
|
||||
* Deallocates the given X Window.
|
||||
*
|
||||
* Results:
|
||||
* The window id is returned.
|
||||
@@ -51,10 +52,10 @@ static void NotifyVisibility(TkWindow *winPtr, XEvent *eventPtr);
|
||||
|
||||
int
|
||||
XDestroyWindow(
|
||||
Display *display, /* Display. */
|
||||
TCL_UNUSED(Display *), /* Display. */
|
||||
Window window) /* Window. */
|
||||
{
|
||||
MacDrawable *macWin = (MacDrawable *) window;
|
||||
MacDrawable *macWin = (MacDrawable *)window;
|
||||
|
||||
/*
|
||||
* Remove any dangling pointers that may exist if the window we are
|
||||
@@ -68,7 +69,7 @@ XDestroyWindow(
|
||||
if (!Tk_IsTopLevel(macWin->winPtr)) {
|
||||
TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
|
||||
if (macWin->winPtr->parentPtr != NULL) {
|
||||
TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr->parentPtr);
|
||||
TkMacOSXInvalClipRgns((Tk_Window)macWin->winPtr->parentPtr);
|
||||
}
|
||||
if (macWin->visRgn) {
|
||||
CFRelease(macWin->visRgn);
|
||||
@@ -119,14 +120,18 @@ XDestroyWindow(
|
||||
*
|
||||
* XMapWindow --
|
||||
*
|
||||
* Map the given X Window to the screen. See X window documentation for
|
||||
* more details.
|
||||
* This X11 stub maps the given X11 Window but does not update any of
|
||||
* the Tk structures describing the window. Tk applications should
|
||||
* never call this directly, but it is called by Tk_MapWindow and
|
||||
* Tk_WmMapWindow.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
* Returns Success or BadWindow.
|
||||
*
|
||||
* Side effects:
|
||||
* The subwindow or toplevel may appear on the screen.
|
||||
* The subwindow or toplevel may appear on the screen. VisibilityNotify
|
||||
* events are generated.
|
||||
*
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
@@ -136,10 +141,13 @@ XMapWindow(
|
||||
Display *display, /* Display. */
|
||||
Window window) /* Window. */
|
||||
{
|
||||
MacDrawable *macWin = (MacDrawable *) window;
|
||||
if (!window) {
|
||||
return BadWindow;
|
||||
}
|
||||
MacDrawable *macWin = (MacDrawable *)window;
|
||||
TkWindow *winPtr = macWin->winPtr;
|
||||
NSWindow *win = TkMacOSXDrawableWindow(window);
|
||||
XEvent event;
|
||||
NSWindow *win = TkMacOSXGetNSWindowForDrawable(window);
|
||||
static Bool initialized = NO;
|
||||
|
||||
/*
|
||||
* Under certain situations it's possible for this function to be called
|
||||
@@ -154,9 +162,9 @@ XMapWindow(
|
||||
}
|
||||
|
||||
display->request++;
|
||||
winPtr->flags |= TK_MAPPED;
|
||||
if (Tk_IsTopLevel(winPtr)) {
|
||||
if (!Tk_IsEmbedded(winPtr)) {
|
||||
TKContentView *view = [win contentView];
|
||||
|
||||
/*
|
||||
* We want to activate Tk when a toplevel is mapped but we must not
|
||||
@@ -168,12 +176,14 @@ XMapWindow(
|
||||
|
||||
TkMacOSXApplyWindowAttributes(winPtr, win);
|
||||
[win setExcludedFromWindowsMenu:NO];
|
||||
[NSApp activateIgnoringOtherApps:NO];
|
||||
[[win contentView] setNeedsDisplay:YES];
|
||||
if ([win canBecomeKeyWindow]) {
|
||||
[win makeKeyAndOrderFront:NSApp];
|
||||
} else {
|
||||
[win orderFrontRegardless];
|
||||
[NSApp activateIgnoringOtherApps:initialized];
|
||||
[view addTkDirtyRect: [view bounds]];
|
||||
if (initialized) {
|
||||
if ([win canBecomeKeyWindow]) {
|
||||
[win makeKeyAndOrderFront:NSApp];
|
||||
} else {
|
||||
[win orderFrontRegardless];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
TkWindow *contWinPtr = TkpGetOtherWindow(winPtr);
|
||||
@@ -183,25 +193,10 @@ XMapWindow(
|
||||
* the window.
|
||||
*/
|
||||
|
||||
TkMacOSXInvalClipRgns((Tk_Window) contWinPtr);
|
||||
TkMacOSXInvalClipRgns((Tk_Window)contWinPtr);
|
||||
TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
|
||||
}
|
||||
|
||||
TkMacOSXInvalClipRgns((Tk_Window) winPtr);
|
||||
|
||||
/*
|
||||
* We only need to send the MapNotify event for toplevel windows.
|
||||
*/
|
||||
|
||||
event.xany.serial = LastKnownRequestProcessed(display);
|
||||
event.xany.send_event = False;
|
||||
event.xany.display = display;
|
||||
|
||||
event.xmap.window = window;
|
||||
event.xmap.type = MapNotify;
|
||||
event.xmap.event = window;
|
||||
event.xmap.override_redirect = winPtr->atts.override_redirect;
|
||||
Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
|
||||
TkMacOSXInvalClipRgns((Tk_Window)winPtr);
|
||||
} else {
|
||||
|
||||
/*
|
||||
@@ -209,24 +204,33 @@ XMapWindow(
|
||||
* and redisplay the window.
|
||||
*/
|
||||
|
||||
TkMacOSXInvalClipRgns((Tk_Window) winPtr->parentPtr);
|
||||
TkMacOSXInvalClipRgns((Tk_Window)winPtr->parentPtr);
|
||||
}
|
||||
|
||||
if ([NSApp isDrawing]) {
|
||||
[[win contentView] setNeedsRedisplay:YES];
|
||||
} else {
|
||||
[[win contentView] setNeedsDisplay:YES];
|
||||
/*
|
||||
* Mark the toplevel as needing to be redrawn, unless the window is being
|
||||
* mapped while drawing is taking place.
|
||||
*/
|
||||
|
||||
TKContentView *view = [win contentView];
|
||||
if (view != [NSView focusView]) {
|
||||
[view addTkDirtyRect:[view bounds]];
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate VisibilityNotify events for window and all mapped children.
|
||||
*/
|
||||
|
||||
event.xany.send_event = False;
|
||||
event.xany.display = display;
|
||||
event.xvisibility.type = VisibilityNotify;
|
||||
event.xvisibility.state = VisibilityUnobscured;
|
||||
NotifyVisibility(winPtr, &event);
|
||||
if (initialized) {
|
||||
XEvent event;
|
||||
event.xany.send_event = False;
|
||||
event.xany.display = display;
|
||||
event.xvisibility.type = VisibilityNotify;
|
||||
event.xvisibility.state = VisibilityUnobscured;
|
||||
NotifyVisibility(winPtr, &event);
|
||||
} else {
|
||||
initialized = YES;
|
||||
}
|
||||
return Success;
|
||||
}
|
||||
|
||||
@@ -269,11 +273,13 @@ NotifyVisibility(
|
||||
*
|
||||
* XUnmapWindow --
|
||||
*
|
||||
* Unmap the given X Window to the screen. See X window documentation for
|
||||
* more details.
|
||||
* This X11 stub maps the given X11 Window but does not update any of
|
||||
* The Tk structures describing the window. Tk applications should
|
||||
* never call this directly, but it is called by Tk_UnmapWindow and
|
||||
* Tk_WmUnmapWindow.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
* Always returns Success or BadWindow.
|
||||
*
|
||||
* Side effects:
|
||||
* The subwindow or toplevel may be removed from the screen.
|
||||
@@ -286,33 +292,22 @@ XUnmapWindow(
|
||||
Display *display, /* Display. */
|
||||
Window window) /* Window. */
|
||||
{
|
||||
MacDrawable *macWin = (MacDrawable *) window;
|
||||
MacDrawable *macWin = (MacDrawable *)window;
|
||||
TkWindow *winPtr = macWin->winPtr;
|
||||
TkWindow *parentPtr = winPtr->parentPtr;
|
||||
NSWindow *win = TkMacOSXDrawableWindow(window);
|
||||
XEvent event;
|
||||
NSWindow *win = TkMacOSXGetNSWindowForDrawable(window);
|
||||
|
||||
if (!window) {
|
||||
return BadWindow;
|
||||
}
|
||||
display->request++;
|
||||
if (Tk_IsTopLevel(winPtr)) {
|
||||
if (!Tk_IsEmbedded(winPtr) &&
|
||||
winPtr->wmInfoPtr->hints.initial_state!=IconicState) {
|
||||
[win orderOut:nil];
|
||||
[win setExcludedFromWindowsMenu:YES];
|
||||
}
|
||||
TkMacOSXInvalClipRgns((Tk_Window) winPtr);
|
||||
|
||||
/*
|
||||
* We only need to send the UnmapNotify event for toplevel windows.
|
||||
*/
|
||||
|
||||
event.xany.serial = LastKnownRequestProcessed(display);
|
||||
event.xany.send_event = False;
|
||||
event.xany.display = display;
|
||||
|
||||
event.xunmap.type = UnmapNotify;
|
||||
event.xunmap.window = window;
|
||||
event.xunmap.event = window;
|
||||
event.xunmap.from_configure = false;
|
||||
Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
|
||||
TkMacOSXInvalClipRgns((Tk_Window)winPtr);
|
||||
} else {
|
||||
/*
|
||||
* Rebuild the visRgn clip region for the parent so it will be allowed
|
||||
@@ -322,17 +317,15 @@ XUnmapWindow(
|
||||
|
||||
if (parentPtr && parentPtr->privatePtr->visRgn) {
|
||||
TkMacOSXInvalidateViewRegion(
|
||||
TkMacOSXDrawableView(parentPtr->privatePtr),
|
||||
TkMacOSXGetNSViewForDrawable(parentPtr->privatePtr),
|
||||
parentPtr->privatePtr->visRgn);
|
||||
}
|
||||
TkMacOSXInvalClipRgns((Tk_Window) parentPtr);
|
||||
TkMacOSXInvalClipRgns((Tk_Window)parentPtr);
|
||||
TkMacOSXUpdateClipRgn(parentPtr);
|
||||
}
|
||||
winPtr->flags &= ~TK_MAPPED;
|
||||
if ([NSApp isDrawing]) {
|
||||
[[win contentView] setNeedsRedisplay:YES];
|
||||
} else {
|
||||
[[win contentView] setNeedsDisplay:YES];
|
||||
TKContentView *view = [win contentView];
|
||||
if (view != [NSView focusView]) {
|
||||
[view addTkDirtyRect:[view bounds]];
|
||||
}
|
||||
return Success;
|
||||
}
|
||||
@@ -361,19 +354,23 @@ XResizeWindow(
|
||||
unsigned int width,
|
||||
unsigned int height)
|
||||
{
|
||||
MacDrawable *macWin = (MacDrawable *) window;
|
||||
MacDrawable *macWin = (MacDrawable *)window;
|
||||
|
||||
display->request++;
|
||||
if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
|
||||
NSWindow *w = macWin->winPtr->wmInfoPtr->window;
|
||||
TKWindow *w = (TKWindow *)macWin->winPtr->wmInfoPtr->window;
|
||||
|
||||
if (w) {
|
||||
NSRect r = [w contentRectForFrameRect:[w frame]];
|
||||
if ([w styleMask] & NSFullScreenWindowMask) {
|
||||
[w tkLayoutChanged];
|
||||
} else {
|
||||
NSRect r = [w contentRectForFrameRect:[w frame]];
|
||||
|
||||
r.origin.y += r.size.height - height;
|
||||
r.size.width = width;
|
||||
r.size.height = height;
|
||||
[w setFrame:[w frameRectForContentRect:r] display:YES];
|
||||
r.origin.y += r.size.height - height;
|
||||
r.size.width = width;
|
||||
r.size.height = height;
|
||||
[w setFrame:[w frameRectForContentRect:r] display:NO];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
MoveResizeWindow(macWin);
|
||||
@@ -406,7 +403,7 @@ XMoveResizeWindow(
|
||||
unsigned int width,
|
||||
unsigned int height)
|
||||
{
|
||||
MacDrawable *macWin = (MacDrawable *) window;
|
||||
MacDrawable *macWin = (MacDrawable *)window;
|
||||
|
||||
display->request++;
|
||||
if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
|
||||
@@ -429,7 +426,7 @@ XMoveResizeWindow(
|
||||
X + XOff, TkMacOSXZeroScreenHeight() - Y - YOff - Height,
|
||||
Width, Height);
|
||||
|
||||
[w setFrame:[w frameRectForContentRect:r] display:YES];
|
||||
[w setFrame:[w frameRectForContentRect:r] display:NO];
|
||||
}
|
||||
} else {
|
||||
MoveResizeWindow(macWin);
|
||||
@@ -459,7 +456,7 @@ XMoveWindow(
|
||||
Window window, /* Window. */
|
||||
int x, int y)
|
||||
{
|
||||
MacDrawable *macWin = (MacDrawable *) window;
|
||||
MacDrawable *macWin = (MacDrawable *)window;
|
||||
|
||||
display->request++;
|
||||
if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
|
||||
@@ -497,7 +494,7 @@ MoveResizeWindow(
|
||||
{
|
||||
int deltaX = 0, deltaY = 0, parentBorderwidth = 0;
|
||||
MacDrawable *macParent = NULL;
|
||||
NSWindow *macWindow = TkMacOSXDrawableWindow((Drawable) macWin);
|
||||
NSWindow *macWindow = TkMacOSXGetNSWindowForDrawable((Drawable)macWin);
|
||||
|
||||
/*
|
||||
* Find the Parent window, for an embedded window it will be its container.
|
||||
@@ -534,7 +531,7 @@ MoveResizeWindow(
|
||||
if (macWindow) {
|
||||
TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
|
||||
if (macParent) {
|
||||
TkMacOSXInvalClipRgns((Tk_Window) macParent->winPtr);
|
||||
TkMacOSXInvalClipRgns((Tk_Window)macParent->winPtr);
|
||||
}
|
||||
}
|
||||
UpdateOffsets(macWin->winPtr, deltaX, deltaY);
|
||||
@@ -602,7 +599,7 @@ XRaiseWindow(
|
||||
Display *display, /* Display. */
|
||||
Window window) /* Window. */
|
||||
{
|
||||
MacDrawable *macWin = (MacDrawable *) window;
|
||||
MacDrawable *macWin = (MacDrawable *)window;
|
||||
|
||||
display->request++;
|
||||
if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
|
||||
@@ -615,7 +612,6 @@ XRaiseWindow(
|
||||
return Success;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -632,23 +628,23 @@ XRaiseWindow(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
int
|
||||
XLowerWindow(
|
||||
Display *display, /* Display. */
|
||||
Window window) /* Window. */
|
||||
{
|
||||
MacDrawable *macWin = (MacDrawable *) window;
|
||||
MacDrawable *macWin = (MacDrawable *)window;
|
||||
|
||||
display->request++;
|
||||
if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
|
||||
TkWmRestackToplevel(macWin->winPtr, Below, NULL);
|
||||
} else {
|
||||
/*
|
||||
/*
|
||||
* TODO: this should generate damage
|
||||
*/
|
||||
}
|
||||
return Success;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -673,9 +669,9 @@ XConfigureWindow(
|
||||
Display *display, /* Display. */
|
||||
Window w, /* Window. */
|
||||
unsigned int value_mask,
|
||||
XWindowChanges *values)
|
||||
TCL_UNUSED(XWindowChanges *))
|
||||
{
|
||||
MacDrawable *macWin = (MacDrawable *) w;
|
||||
MacDrawable *macWin = (MacDrawable *)w;
|
||||
TkWindow *winPtr = macWin->winPtr;
|
||||
|
||||
display->request++;
|
||||
@@ -697,17 +693,11 @@ XConfigureWindow(
|
||||
*/
|
||||
|
||||
if (value_mask & CWStackMode) {
|
||||
NSView *view = TkMacOSXDrawableView(macWin);
|
||||
Rect bounds;
|
||||
NSRect r;
|
||||
NSView *view = TkMacOSXGetNSViewForDrawable(macWin);
|
||||
|
||||
if (view) {
|
||||
TkMacOSXInvalClipRgns((Tk_Window) winPtr->parentPtr);
|
||||
TkMacOSXWinBounds(winPtr, &bounds);
|
||||
r = NSMakeRect(bounds.left,
|
||||
[view bounds].size.height - bounds.bottom,
|
||||
bounds.right - bounds.left, bounds.bottom - bounds.top);
|
||||
[view setNeedsDisplayInRect:r];
|
||||
TkMacOSXInvalClipRgns((Tk_Window)winPtr->parentPtr);
|
||||
TkpRedrawWidget((Tk_Window)winPtr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -826,7 +816,7 @@ TkMacOSXUpdateClipRgn(
|
||||
|
||||
/*
|
||||
* Clip away the area of any windows that may obscure this window.
|
||||
* For a non-toplevel window, first, clip to the parents visible
|
||||
* For a non-toplevel window, first, clip to the parent's visible
|
||||
* clip region. Second, clip away any siblings that are higher in
|
||||
* the stacking order. For an embedded toplevel, just clip to the
|
||||
* container's visible clip region. Remember, we only allow one
|
||||
@@ -859,11 +849,11 @@ TkMacOSXUpdateClipRgn(
|
||||
TkRegion r = TkCreateRegion();
|
||||
HIShapeRef visRgn;
|
||||
|
||||
tkMacOSXEmbedHandler->getClipProc((Tk_Window) winPtr, r);
|
||||
tkMacOSXEmbedHandler->getClipProc((Tk_Window)winPtr, r);
|
||||
visRgn = TkMacOSXGetNativeRegion(r);
|
||||
ChkErr(HIShapeIntersect, visRgn, rgn, rgn);
|
||||
CFRelease(visRgn);
|
||||
TkpReleaseRegion(r);
|
||||
TkDestroyRegion(r);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -987,12 +977,13 @@ TkMacOSXVisableClipRgn(
|
||||
static OSStatus
|
||||
InvalViewRect(
|
||||
int msg,
|
||||
HIShapeRef rgn,
|
||||
TCL_UNUSED(HIShapeRef),
|
||||
const CGRect *rect,
|
||||
void *ref)
|
||||
{
|
||||
static CGAffineTransform t;
|
||||
NSView *view = ref;
|
||||
TKContentView *view = ref;
|
||||
NSRect dirtyRect;
|
||||
|
||||
if (!view) {
|
||||
return paramErr;
|
||||
@@ -1003,8 +994,8 @@ InvalViewRect(
|
||||
NSHeight([view bounds]));
|
||||
break;
|
||||
case kHIShapeEnumerateRect:
|
||||
[view setNeedsDisplayInRect:NSRectFromCGRect(
|
||||
CGRectApplyAffineTransform(*rect, t))];
|
||||
dirtyRect = NSRectFromCGRect(CGRectApplyAffineTransform(*rect, t));
|
||||
[view addTkDirtyRect:dirtyRect];
|
||||
break;
|
||||
}
|
||||
return noErr;
|
||||
@@ -1050,14 +1041,14 @@ TkMacOSXInvalidateWindow(
|
||||
if (macWin->flags & TK_CLIP_INVALID) {
|
||||
TkMacOSXUpdateClipRgn(macWin->winPtr);
|
||||
}
|
||||
TkMacOSXInvalidateViewRegion(TkMacOSXDrawableView(macWin),
|
||||
TkMacOSXInvalidateViewRegion(TkMacOSXGetNSViewForDrawable(macWin),
|
||||
(flag == TK_WINDOW_ONLY) ? macWin->visRgn : macWin->aboveVisRgn);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TkMacOSXDrawableWindow --
|
||||
* TkMacOSXGetNSWindowForDrawable --
|
||||
*
|
||||
* This function returns the NSWindow for a given X drawable.
|
||||
*
|
||||
@@ -1070,11 +1061,11 @@ TkMacOSXInvalidateWindow(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
NSWindow *
|
||||
TkMacOSXDrawableWindow(
|
||||
void *
|
||||
TkMacOSXDrawable(
|
||||
Drawable drawable)
|
||||
{
|
||||
MacDrawable *macWin = (MacDrawable *) drawable;
|
||||
MacDrawable *macWin = (MacDrawable *)drawable;
|
||||
NSWindow *result = nil;
|
||||
|
||||
if (!macWin || macWin->flags & TK_IS_PIXMAP) {
|
||||
@@ -1090,25 +1081,19 @@ TkMacOSXDrawableWindow(
|
||||
TkWindow *contWinPtr = TkpGetOtherWindow(macWin->toplevel->winPtr);
|
||||
|
||||
if (contWinPtr) {
|
||||
result = TkMacOSXDrawableWindow((Drawable) contWinPtr->privatePtr);
|
||||
result = TkMacOSXGetNSWindowForDrawable((Drawable)contWinPtr->privatePtr);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void *
|
||||
TkMacOSXDrawable(
|
||||
Drawable drawable)
|
||||
{
|
||||
return TkMacOSXDrawableWindow(drawable);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TkMacOSXGetDrawablePort --
|
||||
*
|
||||
* This function returns the Graphics Port for a given X drawable.
|
||||
* This function only exists because it is listed in the stubs table.
|
||||
* It is useless.
|
||||
*
|
||||
* Results:
|
||||
* NULL.
|
||||
@@ -1121,7 +1106,7 @@ TkMacOSXDrawable(
|
||||
|
||||
void *
|
||||
TkMacOSXGetDrawablePort(
|
||||
Drawable drawable)
|
||||
TCL_UNUSED(Drawable))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -1129,9 +1114,16 @@ TkMacOSXGetDrawablePort(
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TkMacOSXDrawableView --
|
||||
* TkMacOSXGetNSViewForDrawable/TkMacOSXGetRootControl --
|
||||
*
|
||||
* This function returns the NSView for a given X drawable.
|
||||
* The function name TkMacOSXGetRootControl is being preserved only
|
||||
* because it exists in a stubs table. Nobody knows what it means to
|
||||
* get a "RootControl". The macro TkMacOSXGetNSViewForDrawable calls
|
||||
* this function and should always be used rather than directly using
|
||||
* the obscure official name of this function.
|
||||
*
|
||||
* It returns the NSView for a given X drawable in the case that the
|
||||
* drawable is a window. If the drawable is a pixmap it returns nil.
|
||||
*
|
||||
* Results:
|
||||
* A NSView* or nil.
|
||||
@@ -1142,53 +1134,27 @@ TkMacOSXGetDrawablePort(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
NSView *
|
||||
TkMacOSXDrawableView(
|
||||
MacDrawable *macWin)
|
||||
{
|
||||
NSView *result = nil;
|
||||
|
||||
if (!macWin) {
|
||||
result = nil;
|
||||
} else if (!macWin->toplevel) {
|
||||
result = macWin->view;
|
||||
} else if (!(macWin->toplevel->flags & TK_EMBEDDED)) {
|
||||
result = macWin->toplevel->view;
|
||||
} else {
|
||||
TkWindow *contWinPtr = TkpGetOtherWindow(macWin->toplevel->winPtr);
|
||||
|
||||
if (contWinPtr) {
|
||||
result = TkMacOSXDrawableView(contWinPtr->privatePtr);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TkMacOSXGetRootControl --
|
||||
*
|
||||
* This function returns the NSView for a given X drawable.
|
||||
*
|
||||
* Results:
|
||||
* A NSView* .
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void *
|
||||
TkMacOSXGetRootControl(
|
||||
Drawable drawable)
|
||||
{
|
||||
/*
|
||||
* will probably need to fix this up for embedding
|
||||
*/
|
||||
void *result = NULL;
|
||||
MacDrawable *macWin = (MacDrawable *)drawable;
|
||||
|
||||
return TkMacOSXDrawableView((MacDrawable *) drawable);
|
||||
if (!macWin) {
|
||||
result = NULL;
|
||||
} else if (!macWin->toplevel) {
|
||||
result = macWin->view;
|
||||
} else if (!(macWin->toplevel->flags & TK_EMBEDDED)) {
|
||||
result = macWin->toplevel->view;
|
||||
} else {
|
||||
TkWindow *contWinPtr = TkpGetOtherWindow(macWin->toplevel->winPtr);
|
||||
|
||||
if (contWinPtr) {
|
||||
result = TkMacOSXGetRootControl((Drawable)contWinPtr->privatePtr);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1254,7 +1220,7 @@ TkMacOSXInvalClipRgns(
|
||||
childPtr = winPtr->childList;
|
||||
while (childPtr) {
|
||||
if (!Tk_IsTopLevel(childPtr)) {
|
||||
TkMacOSXInvalClipRgns((Tk_Window) childPtr);
|
||||
TkMacOSXInvalClipRgns((Tk_Window)childPtr);
|
||||
}
|
||||
childPtr = childPtr->nextPtr;
|
||||
}
|
||||
@@ -1267,7 +1233,7 @@ TkMacOSXInvalClipRgns(
|
||||
childPtr = TkpGetOtherWindow(winPtr);
|
||||
|
||||
if (childPtr) {
|
||||
TkMacOSXInvalClipRgns((Tk_Window) childPtr);
|
||||
TkMacOSXInvalClipRgns((Tk_Window)childPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1281,7 +1247,7 @@ TkMacOSXInvalClipRgns(
|
||||
*
|
||||
* TkMacOSXWinBounds --
|
||||
*
|
||||
* Given a Tk window this function determines the windows bounds in
|
||||
* Given a Tk window this function determines the window's bounds in
|
||||
* relation to the Macintosh window's coordinate system. This is also the
|
||||
* same coordinate system as the Tk toplevel window in which this window
|
||||
* is contained.
|
||||
@@ -1290,7 +1256,7 @@ TkMacOSXInvalClipRgns(
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
* Fills in a Rect.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
@@ -1313,16 +1279,15 @@ TkMacOSXWinBounds(
|
||||
*
|
||||
* TkMacOSXWinCGBounds --
|
||||
*
|
||||
* Given a Tk window this function determines the windows bounds in
|
||||
* relation to the Macintosh window's coordinate system. This is also the
|
||||
* same coordinate system as the Tk toplevel window in which this window
|
||||
* is contained.
|
||||
* Given a Tk window this function determines the window's bounds in
|
||||
* the coordinate system of the Tk toplevel window in which this window
|
||||
* is contained. This fills in a CGRect struct.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
* Fill in a CGRect.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
@@ -1337,6 +1302,39 @@ TkMacOSXWinCGBounds(
|
||||
bounds->size.width = winPtr->changes.width;
|
||||
bounds->size.height = winPtr->changes.height;
|
||||
}
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TkMacOSXWinNSBounds --
|
||||
*
|
||||
* Given a Tk window this function determines the window's bounds in
|
||||
* the coordinate system of the TKContentView in which this Tk window
|
||||
* is contained, which has the origin at the lower left corner. This
|
||||
* fills in an NSRect struct and requires the TKContentView as a
|
||||
* parameter
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Fills in an NSRect.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
TkMacOSXWinNSBounds(
|
||||
TkWindow *winPtr,
|
||||
NSView *view,
|
||||
NSRect *bounds)
|
||||
{
|
||||
bounds->size.width = winPtr->changes.width;
|
||||
bounds->size.height = winPtr->changes.height;
|
||||
bounds->origin.x = winPtr->privatePtr->xOff;
|
||||
bounds->origin.y = ([view bounds].size.height -
|
||||
bounds->size.height -
|
||||
winPtr->privatePtr->yOff);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -1417,7 +1415,7 @@ UpdateOffsets(
|
||||
Pixmap
|
||||
Tk_GetPixmap(
|
||||
Display *display, /* Display for new pixmap (can be null). */
|
||||
Drawable d, /* Drawable where pixmap will be used (ignored). */
|
||||
TCL_UNUSED(Drawable), /* Drawable where pixmap will be used (ignored). */
|
||||
int width, /* Dimensions of pixmap. */
|
||||
int height,
|
||||
int depth) /* Bits per pixel for pixmap. */
|
||||
@@ -1427,7 +1425,7 @@ Tk_GetPixmap(
|
||||
if (display != NULL) {
|
||||
display->request++;
|
||||
}
|
||||
macPix = ckalloc(sizeof(MacDrawable));
|
||||
macPix = (MacDrawable *)ckalloc(sizeof(MacDrawable));
|
||||
macPix->winPtr = NULL;
|
||||
macPix->xOff = 0;
|
||||
macPix->yOff = 0;
|
||||
@@ -1465,7 +1463,7 @@ Tk_FreePixmap(
|
||||
Display *display, /* Display. */
|
||||
Pixmap pixmap) /* Pixmap to destroy */
|
||||
{
|
||||
MacDrawable *macPix = (MacDrawable *) pixmap;
|
||||
MacDrawable *macPix = (MacDrawable *)pixmap;
|
||||
|
||||
display->request++;
|
||||
if (macPix->context) {
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
#include "tkMacOSXPrivate.h"
|
||||
#include "tkMacOSXConstants.h"
|
||||
#include "tkMacOSXWm.h"
|
||||
|
||||
|
||||
/*
|
||||
* Forward declarations of procedures defined later in this file:
|
||||
@@ -24,7 +26,11 @@ static int DebuggerObjCmd (ClientData dummy, Tcl_Interp *interp,
|
||||
int objc, Tcl_Obj *const objv[]);
|
||||
#endif
|
||||
static int PressButtonObjCmd (ClientData dummy, Tcl_Interp *interp,
|
||||
int objc, Tcl_Obj *const objv[]);
|
||||
int objc, Tcl_Obj *const *objv);
|
||||
static int InjectKeyEventObjCmd (ClientData dummy, Tcl_Interp *interp,
|
||||
int objc, Tcl_Obj *const *objv);
|
||||
static int MenuBarHeightObjCmd (ClientData dummy, Tcl_Interp *interp,
|
||||
int objc, Tcl_Obj *const *objv);
|
||||
|
||||
|
||||
/*
|
||||
@@ -56,7 +62,8 @@ TkplatformtestInit(
|
||||
Tcl_CreateObjCommand(interp, "debugger", DebuggerObjCmd, NULL, NULL);
|
||||
#endif
|
||||
Tcl_CreateObjCommand(interp, "pressbutton", PressButtonObjCmd, NULL, NULL);
|
||||
|
||||
Tcl_CreateObjCommand(interp, "injectkeyevent", InjectKeyEventObjCmd, NULL, NULL);
|
||||
Tcl_CreateObjCommand(interp, "menubarheight", MenuBarHeightObjCmd, NULL, NULL);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -93,45 +100,86 @@ DebuggerObjCmd(
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TkTestLogDisplay --
|
||||
* MenuBarHeightObjCmd --
|
||||
*
|
||||
* The test image display procedure calls this to determine whether it
|
||||
* should write a log message recording that it has being run. On OSX
|
||||
* 10.14 and later, only calls to the display procedure which occur inside
|
||||
* of the drawRect method should be logged, since those are the only ones
|
||||
* which actually draw anything. On earlier systems the opposite is true.
|
||||
* The calls from within the drawRect method are redundant, since the
|
||||
* first time the display procedure is run it will do the drawing and that
|
||||
* first call will usually not occur inside of drawRect.
|
||||
*
|
||||
* Results:
|
||||
* On OSX 10.14 and later, returns true if and only if called from
|
||||
* within [NSView drawRect]. On earlier systems returns false if
|
||||
* and only if called from with [NSView drawRect].
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
MODULE_SCOPE Bool
|
||||
TkTestLogDisplay(void) {
|
||||
if ([NSApp macMinorVersion] >= 14) {
|
||||
return [NSApp isDrawing];
|
||||
} else {
|
||||
return ![NSApp isDrawing];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* PressButtonObjCmd --
|
||||
*
|
||||
* This Tcl command simulates a button press at a specific screen
|
||||
* location. It injects NSEvents into the NSApplication event queue,
|
||||
* as opposed to adding events to the Tcl queue as event generate
|
||||
* would do. One application is for testing the grab command.
|
||||
* This procedure calls [NSMenu menuBarHeight] and returns the result
|
||||
* as an integer. Windows can never be placed to overlap the MenuBar,
|
||||
* so tests need to be aware of its size.
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl result.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
MenuBarHeightObjCmd(
|
||||
TCL_UNUSED(void *), /* Not used. */
|
||||
Tcl_Interp *interp, /* Not used. */
|
||||
TCL_UNUSED(int), /* Not used. */
|
||||
TCL_UNUSED(Tcl_Obj *const *)) /* Not used. */
|
||||
{
|
||||
static int height = 0;
|
||||
if (height == 0) {
|
||||
height = (int) [[NSApp mainMenu] menuBarHeight];
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(height));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TkTestLogDisplay --
|
||||
*
|
||||
* The test image display procedure calls this to determine whether it
|
||||
* should write a log message recording that it has being run.
|
||||
*
|
||||
* Results:
|
||||
* Returns true if and only if the NSView of the drawable is the
|
||||
* current focusView, which on 10.14 and newer systems can only be the
|
||||
* case when within [NSView drawRect].
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
MODULE_SCOPE Bool
|
||||
TkTestLogDisplay(
|
||||
Drawable drawable)
|
||||
{
|
||||
MacDrawable *macWin = (MacDrawable *)drawable;
|
||||
NSWindow *win = nil;
|
||||
if (macWin->toplevel && macWin->toplevel->winPtr &&
|
||||
macWin->toplevel->winPtr->wmInfoPtr &&
|
||||
macWin->toplevel->winPtr->wmInfoPtr->window) {
|
||||
win = macWin->toplevel->winPtr->wmInfoPtr->window;
|
||||
} else if (macWin->winPtr && macWin->winPtr->wmInfoPtr &&
|
||||
macWin->winPtr->wmInfoPtr->window) {
|
||||
win = macWin->winPtr->wmInfoPtr->window;
|
||||
}
|
||||
if (win) {
|
||||
return ([win contentView] == [NSView focusView]);
|
||||
} else {
|
||||
return True;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* PressButtonObjCmd --
|
||||
*
|
||||
* This Tcl command simulates a button press at a specific screen
|
||||
* location. It injects NSEvents into the NSApplication event queue, as
|
||||
* opposed to adding events to the Tcl queue as event generate would do.
|
||||
* One application is for testing the grab command. These events have
|
||||
* their unused context property set to 1 as a signal indicating that they
|
||||
* should not be ignored by [NSApp tkProcessMouseEvent].
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl result.
|
||||
@@ -142,15 +190,15 @@ TkTestLogDisplay(void) {
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
PressButtonObjCmd(
|
||||
ClientData clientData,
|
||||
TCL_UNUSED(void *),
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *const objv[])
|
||||
{
|
||||
int x, y, i, value, wNum;
|
||||
int x = 0, y = 0, i, value;
|
||||
NSInteger signal = -1;
|
||||
CGPoint pt;
|
||||
NSPoint loc;
|
||||
NSEvent *motion, *press, *release;
|
||||
@@ -184,15 +232,20 @@ PressButtonObjCmd(
|
||||
pt.x = loc.x = x;
|
||||
pt.y = y;
|
||||
loc.y = ScreenHeight - y;
|
||||
wNum = 0;
|
||||
|
||||
/*
|
||||
* We set the window number and the eventNumber to -1 as a signal to
|
||||
* processMouseEvent.
|
||||
*/
|
||||
|
||||
CGWarpMouseCursorPosition(pt);
|
||||
motion = [NSEvent mouseEventWithType:NSMouseMoved
|
||||
location:loc
|
||||
modifierFlags:0
|
||||
timestamp:GetCurrentEventTime()
|
||||
windowNumber:wNum
|
||||
windowNumber:signal
|
||||
context:nil
|
||||
eventNumber:0
|
||||
eventNumber:signal
|
||||
clickCount:1
|
||||
pressure:0.0];
|
||||
[NSApp postEvent:motion atStart:NO];
|
||||
@@ -200,9 +253,9 @@ PressButtonObjCmd(
|
||||
location:loc
|
||||
modifierFlags:0
|
||||
timestamp:GetCurrentEventTime()
|
||||
windowNumber:wNum
|
||||
windowNumber:signal
|
||||
context:nil
|
||||
eventNumber:1
|
||||
eventNumber:signal
|
||||
clickCount:1
|
||||
pressure:0.0];
|
||||
[NSApp postEvent:press atStart:NO];
|
||||
@@ -210,16 +263,123 @@ PressButtonObjCmd(
|
||||
location:loc
|
||||
modifierFlags:0
|
||||
timestamp:GetCurrentEventTime()
|
||||
windowNumber:wNum
|
||||
windowNumber:signal
|
||||
context:nil
|
||||
eventNumber:2
|
||||
eventNumber:signal
|
||||
clickCount:1
|
||||
pressure:0.0];
|
||||
pressure:-1.0];
|
||||
[NSApp postEvent:release atStart:NO];
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
InjectKeyEventObjCmd(
|
||||
TCL_UNUSED(void *),
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *const objv[])
|
||||
{
|
||||
static const char *const optionStrings[] = {
|
||||
"press", "release", "flagschanged", NULL};
|
||||
NSUInteger types[3] = {NSKeyDown, NSKeyUp, NSFlagsChanged};
|
||||
static const char *const argStrings[] = {
|
||||
"-shift", "-control", "-option", "-command", "-function", "-x", "-y", NULL};
|
||||
enum args {KEYEVENT_SHIFT, KEYEVENT_CONTROL, KEYEVENT_OPTION, KEYEVENT_COMMAND,
|
||||
KEYEVENT_FUNCTION, KEYEVENT_X, KEYEVENT_Y};
|
||||
int i, index, keysym, mods = 0, x = 0, y = 0;
|
||||
NSString *chars = nil, *unmod = nil, *upper, *lower;
|
||||
NSEvent *keyEvent;
|
||||
NSUInteger type;
|
||||
MacKeycode macKC;
|
||||
|
||||
if (objc < 3) {
|
||||
wrongArgs:
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "option keysym ?arg?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
|
||||
&index) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
type = types[index];
|
||||
if (Tcl_GetIntFromObj(interp, objv[2], &keysym) != TCL_OK) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"keysym must be an integer"));
|
||||
Tcl_SetErrorCode(interp, "TK", "TEST", "INJECT", "KEYSYM", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
macKC.uint = XKeysymToKeycode(NULL, keysym);
|
||||
for (i = 3; i < objc; i++) {
|
||||
if (Tcl_GetIndexFromObjStruct(interp, objv[i], argStrings,
|
||||
sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
switch ((enum args) index) {
|
||||
case KEYEVENT_SHIFT:
|
||||
mods |= NSShiftKeyMask;
|
||||
break;
|
||||
case KEYEVENT_CONTROL:
|
||||
mods |= NSControlKeyMask;
|
||||
break;
|
||||
case KEYEVENT_OPTION:
|
||||
mods |= NSAlternateKeyMask;
|
||||
break;
|
||||
case KEYEVENT_COMMAND:
|
||||
mods |= NSCommandKeyMask;
|
||||
break;
|
||||
case KEYEVENT_FUNCTION:
|
||||
mods |= NSFunctionKeyMask;
|
||||
break;
|
||||
case KEYEVENT_X:
|
||||
if (++i >= objc) {
|
||||
goto wrongArgs;
|
||||
}
|
||||
if (Tcl_GetIntFromObj(interp,objv[i], &x) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
break;
|
||||
case KEYEVENT_Y:
|
||||
if (++i >= objc) {
|
||||
goto wrongArgs;
|
||||
}
|
||||
if (Tcl_GetIntFromObj(interp,objv[i], &y) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (type != NSFlagsChanged) {
|
||||
UniChar keychar = macKC.v.keychar;
|
||||
chars = [[NSString alloc] initWithCharacters: &keychar length:1];
|
||||
upper = [chars uppercaseString];
|
||||
lower = [chars lowercaseString];
|
||||
if (![upper isEqual: lower] && [chars isEqual: upper]) {
|
||||
mods |= NSShiftKeyMask;
|
||||
}
|
||||
if (mods & NSShiftKeyMask) {
|
||||
chars = upper;
|
||||
unmod = lower;
|
||||
macKC.v.o_s |= INDEX_SHIFT;
|
||||
} else {
|
||||
unmod = chars;
|
||||
}
|
||||
if (macKC.v.o_s & INDEX_OPTION) {
|
||||
mods |= NSAlternateKeyMask;
|
||||
}
|
||||
}
|
||||
keyEvent = [NSEvent keyEventWithType:type
|
||||
location:NSMakePoint(x, y)
|
||||
modifierFlags:mods
|
||||
timestamp:GetCurrentEventTime()
|
||||
windowNumber:0
|
||||
context:nil
|
||||
characters:chars
|
||||
charactersIgnoringModifiers:unmod
|
||||
isARepeat:NO
|
||||
keyCode:macKC.v.virtual];
|
||||
[NSApp postEvent:keyEvent atStart:NO];
|
||||
return TCL_OK;
|
||||
}
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: objc
|
||||
|
||||
@@ -30,17 +30,17 @@
|
||||
* Declaration of functions used only in this file
|
||||
*/
|
||||
|
||||
static int GenerateUpdates(HIShapeRef updateRgn,
|
||||
CGRect *updateBounds, TkWindow *winPtr);
|
||||
static int GenerateUpdates(
|
||||
CGRect *updateBounds, TkWindow *winPtr);
|
||||
static int GenerateActivateEvents(TkWindow *winPtr,
|
||||
int activeFlag);
|
||||
static void DoWindowActivate(ClientData clientData);
|
||||
|
||||
#pragma mark TKApplication(TKWindowEvent)
|
||||
|
||||
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
|
||||
extern NSString *NSWindowWillOrderOnScreenNotification;
|
||||
extern NSString *NSWindowDidOrderOnScreenNotification;
|
||||
extern NSString *NSWindowWillOrderOnScreenNotification;
|
||||
|
||||
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
|
||||
extern NSString *NSWindowDidOrderOffScreenNotification;
|
||||
#endif
|
||||
|
||||
@@ -90,15 +90,12 @@ extern NSString *NSWindowDidOrderOffScreenNotification;
|
||||
height = bounds.size.height - wmPtr->yInParent;
|
||||
flags |= TK_SIZE_CHANGED;
|
||||
}
|
||||
if (Tcl_GetServiceMode() != TCL_SERVICE_NONE) {
|
||||
/*
|
||||
* Propagate geometry changes immediately.
|
||||
*/
|
||||
/*
|
||||
* Propagate geometry changes immediately.
|
||||
*/
|
||||
|
||||
flags |= TK_MACOSX_HANDLE_EVENT_IMMEDIATELY;
|
||||
}
|
||||
|
||||
TkGenWMConfigureEvent((Tk_Window) winPtr, x, y, width, height, flags);
|
||||
flags |= TK_MACOSX_HANDLE_EVENT_IMMEDIATELY;
|
||||
TkGenWMConfigureEvent((Tk_Window)winPtr, x, y, width, height, flags);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -114,31 +111,29 @@ extern NSString *NSWindowDidOrderOffScreenNotification;
|
||||
if (winPtr) {
|
||||
winPtr->wmInfoPtr->hints.initial_state =
|
||||
TkMacOSXIsWindowZoomed(winPtr) ? ZoomState : NormalState;
|
||||
Tk_MapWindow((Tk_Window) winPtr);
|
||||
if (Tcl_GetServiceMode() != TCL_SERVICE_NONE) {
|
||||
Tk_MapWindow((Tk_Window)winPtr);
|
||||
|
||||
/*
|
||||
* Process all Tk events generated by Tk_MapWindow().
|
||||
*/
|
||||
/*
|
||||
* Process all Tk events generated by Tk_MapWindow().
|
||||
*/
|
||||
|
||||
while (Tcl_ServiceEvent(0)) {}
|
||||
while (Tcl_DoOneEvent(TCL_IDLE_EVENTS|TCL_DONT_WAIT)) {}
|
||||
while (Tcl_ServiceEvent(0)) {}
|
||||
while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {}
|
||||
|
||||
/*
|
||||
* NSWindowDidDeminiaturizeNotification is received after
|
||||
* NSWindowDidBecomeKeyNotification, so activate manually
|
||||
*/
|
||||
/*
|
||||
* NSWindowDidDeminiaturizeNotification is received after
|
||||
* NSWindowDidBecomeKeyNotification, so activate manually
|
||||
*/
|
||||
|
||||
GenerateActivateEvents(winPtr, 1);
|
||||
} else {
|
||||
Tcl_DoWhenIdle(DoWindowActivate, winPtr);
|
||||
}
|
||||
GenerateActivateEvents(winPtr, 1);
|
||||
}
|
||||
}
|
||||
|
||||
- (NSRect)windowWillUseStandardFrame:(NSWindow *)window
|
||||
defaultFrame:(NSRect)newFrame
|
||||
{
|
||||
(void)window;
|
||||
|
||||
/*
|
||||
* This method needs to be implemented in order for [NSWindow isZoomed] to
|
||||
* give the correct answer. But it suffices to always validate every
|
||||
@@ -151,6 +146,8 @@ extern NSString *NSWindowDidOrderOffScreenNotification;
|
||||
- (NSSize)window:(NSWindow *)window
|
||||
willUseFullScreenContentSize:(NSSize)proposedSize
|
||||
{
|
||||
(void)window;
|
||||
|
||||
/*
|
||||
* We don't need to change the proposed size, but we do need to implement
|
||||
* this method. Otherwise the full screen window will be sized to the
|
||||
@@ -185,7 +182,7 @@ extern NSString *NSWindowDidOrderOffScreenNotification;
|
||||
TkWindow *winPtr = TkMacOSXGetTkWindow(w);
|
||||
|
||||
if (winPtr) {
|
||||
Tk_UnmapWindow((Tk_Window) winPtr);
|
||||
Tk_UnmapWindow((Tk_Window)winPtr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,7 +194,7 @@ extern NSString *NSWindowDidOrderOffScreenNotification;
|
||||
TkWindow *winPtr = TkMacOSXGetTkWindow(w);
|
||||
|
||||
if (winPtr) {
|
||||
TkGenWMDestroyEvent((Tk_Window) winPtr);
|
||||
TkGenWMDestroyEvent((Tk_Window)winPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -208,6 +205,34 @@ extern NSString *NSWindowDidOrderOffScreenNotification;
|
||||
return (winPtr ? NO : YES);
|
||||
}
|
||||
|
||||
- (void) windowBecameVisible: (NSNotification *) notification
|
||||
{
|
||||
NSWindow *window = [notification object];
|
||||
TkWindow *winPtr = TkMacOSXGetTkWindow(window);
|
||||
if (winPtr) {
|
||||
TKContentView *view = [window contentView];
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101500
|
||||
if (@available(macOS 10.15, *)) {
|
||||
[view viewDidChangeEffectiveAppearance];
|
||||
}
|
||||
#endif
|
||||
[view addTkDirtyRect:[view bounds]];
|
||||
Tcl_CancelIdleCall(TkMacOSXDrawAllViews, NULL);
|
||||
Tcl_DoWhenIdle(TkMacOSXDrawAllViews, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
- (void) windowMapped: (NSNotification *) notification
|
||||
{
|
||||
NSWindow *w = [notification object];
|
||||
TkWindow *winPtr = TkMacOSXGetTkWindow(w);
|
||||
|
||||
if (winPtr) {
|
||||
while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
|
||||
|
||||
- (void) windowDragStart: (NSNotification *) notification
|
||||
@@ -221,22 +246,6 @@ extern NSString *NSWindowDidOrderOffScreenNotification;
|
||||
//BOOL start = [[notification name] isEqualToString:NSWindowWillStartLiveResizeNotification];
|
||||
}
|
||||
|
||||
- (void) windowMapped: (NSNotification *) notification
|
||||
{
|
||||
TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
|
||||
NSWindow *w = [notification object];
|
||||
TkWindow *winPtr = TkMacOSXGetTkWindow(w);
|
||||
|
||||
if (winPtr) {
|
||||
//Tk_MapWindow((Tk_Window) winPtr);
|
||||
}
|
||||
}
|
||||
|
||||
- (void) windowBecameVisible: (NSNotification *) notification
|
||||
{
|
||||
TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
|
||||
}
|
||||
|
||||
- (void) windowUnmapped: (NSNotification *) notification
|
||||
{
|
||||
TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
|
||||
@@ -244,7 +253,7 @@ extern NSString *NSWindowDidOrderOffScreenNotification;
|
||||
TkWindow *winPtr = TkMacOSXGetTkWindow(w);
|
||||
|
||||
if (winPtr) {
|
||||
//Tk_UnmapWindow((Tk_Window) winPtr);
|
||||
//Tk_UnmapWindow((Tk_Window)winPtr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,6 +272,8 @@ extern NSString *NSWindowDidOrderOffScreenNotification;
|
||||
observe(NSWindowDidResizeNotification, windowBoundsChanged:);
|
||||
observe(NSWindowDidDeminiaturizeNotification, windowExpanded:);
|
||||
observe(NSWindowDidMiniaturizeNotification, windowCollapsed:);
|
||||
observe(NSWindowWillOrderOnScreenNotification, windowMapped:);
|
||||
observe(NSWindowDidOrderOnScreenNotification, windowBecameVisible:);
|
||||
|
||||
#if !(MAC_OS_X_VERSION_MAX_ALLOWED < 1070)
|
||||
observe(NSWindowDidEnterFullScreenNotification, windowEnteredFullScreen:);
|
||||
@@ -273,8 +284,6 @@ extern NSString *NSWindowDidOrderOffScreenNotification;
|
||||
observe(NSWindowWillMoveNotification, windowDragStart:);
|
||||
observe(NSWindowWillStartLiveResizeNotification, windowLiveResize:);
|
||||
observe(NSWindowDidEndLiveResizeNotification, windowLiveResize:);
|
||||
observe(NSWindowWillOrderOnScreenNotification, windowMapped:);
|
||||
observe(NSWindowDidOrderOnScreenNotification, windowBecameVisible:);
|
||||
observe(NSWindowDidOrderOffScreenNotification, windowUnmapped:);
|
||||
#endif
|
||||
#undef observe
|
||||
@@ -288,6 +297,8 @@ extern NSString *NSWindowDidOrderOffScreenNotification;
|
||||
|
||||
- (void) applicationActivate: (NSNotification *) notification
|
||||
{
|
||||
(void)notification;
|
||||
|
||||
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
|
||||
TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
|
||||
#endif
|
||||
@@ -312,14 +323,33 @@ extern NSString *NSWindowDidOrderOffScreenNotification;
|
||||
|
||||
- (void) applicationDeactivate: (NSNotification *) notification
|
||||
{
|
||||
(void)notification;
|
||||
|
||||
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
|
||||
TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* To prevent zombie windows on systems with a TouchBar, set the key window
|
||||
* to nil if the current key window is not visible. This allows a closed
|
||||
* Help or About window to be deallocated so it will not reappear as a
|
||||
* zombie when the app is reactivated.
|
||||
*/
|
||||
|
||||
NSWindow *keywindow = [NSApp keyWindow];
|
||||
if (keywindow && ![keywindow isVisible]) {
|
||||
[NSApp _setKeyWindow:nil];
|
||||
[NSApp _setMainWindow:nil];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- (BOOL)applicationShouldHandleReopen:(NSApplication *)sender
|
||||
hasVisibleWindows:(BOOL)flag
|
||||
{
|
||||
(void)sender;
|
||||
(void)flag;
|
||||
|
||||
/*
|
||||
* Allowing the default response means that withdrawn windows will get
|
||||
* displayed on the screen with unresponsive title buttons. We don't
|
||||
@@ -352,6 +382,8 @@ extern NSString *NSWindowDidOrderOffScreenNotification;
|
||||
|
||||
- (void) displayChanged: (NSNotification *) notification
|
||||
{
|
||||
(void)notification;
|
||||
|
||||
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
|
||||
TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
|
||||
#endif
|
||||
@@ -368,26 +400,53 @@ extern NSString *NSWindowDidOrderOffScreenNotification;
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TkpAppIsDrawing --
|
||||
* TkpWillDrawWidget --
|
||||
*
|
||||
* A widget display procedure can call this to determine whether it is
|
||||
* being run inside of the drawRect method. This is needed for some tests,
|
||||
* especially of the Text widget, which record data in a global Tcl
|
||||
* variable and assume that display procedures will be run in a
|
||||
* predictable sequence as Tcl idle tasks.
|
||||
* being run inside of the drawRect method. If not, it may be desirable
|
||||
* for the display procedure to simply clear the REDRAW_PENDING flag
|
||||
* and return. The widget can be recorded in order to schedule a
|
||||
* redraw, via and Expose event, from within drawRect.
|
||||
*
|
||||
* This is also needed for some tests, especially of the Text widget,
|
||||
* which record data in a global Tcl variable and assume that display
|
||||
* procedures will be run in a predictable sequence as Tcl idle tasks.
|
||||
*
|
||||
* Results:
|
||||
* True only while running the drawRect method of a TKContentView;
|
||||
* True if called from the drawRect method of a TKContentView with
|
||||
* tkwin NULL or pointing to a widget in the current focusView.
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
* Currently none. One day the tkwin parameter may be recorded to
|
||||
* handle redrawing the widget later.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
MODULE_SCOPE Bool
|
||||
TkpAppIsDrawing(void) {
|
||||
return [NSApp isDrawing];
|
||||
int
|
||||
TkpWillDrawWidget(Tk_Window tkwin) {
|
||||
int result;
|
||||
if (tkwin) {
|
||||
TkWindow *winPtr = (TkWindow *)tkwin;
|
||||
TKContentView *view = (TKContentView *)TkMacOSXGetNSViewForDrawable(
|
||||
(Drawable)winPtr->privatePtr);
|
||||
result = ([NSApp isDrawing] && view == [NSView focusView]);
|
||||
#if 0
|
||||
printf("TkpWillDrawWidget: %s %d %d \n", Tk_PathName(tkwin),
|
||||
[NSApp isDrawing], (view == [NSView focusView]));
|
||||
if (!result) {
|
||||
NSRect dirtyRect;
|
||||
TkMacOSXWinNSBounds(winPtr, view, &dirtyRect);
|
||||
printf("TkpAppCanDraw: dirtyRect for %s is %s\n",
|
||||
Tk_PathName(tkwin),
|
||||
NSStringFromRect(dirtyRect).UTF8String);
|
||||
[view addTkDirtyRect:dirtyRect];
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
result = [NSApp isDrawing];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -395,55 +454,39 @@ TkpAppIsDrawing(void) {
|
||||
*
|
||||
* GenerateUpdates --
|
||||
*
|
||||
* Given a Macintosh update region and a Tk window this function geneates
|
||||
* Given an update rectangle and a Tk window, this function generates
|
||||
* an X Expose event for the window if it meets the update region. The
|
||||
* function will then recursivly have each damaged window generate Expose
|
||||
* function will then recursively have each damaged window generate Expose
|
||||
* events for its child windows.
|
||||
*
|
||||
* Results:
|
||||
* True if event(s) are generated - false otherwise.
|
||||
*
|
||||
* Side effects:
|
||||
* Additional events may be place on the Tk event queue.
|
||||
* Additional events may be placed on the Tk event queue.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
GenerateUpdates(
|
||||
HIShapeRef updateRgn,
|
||||
CGRect *updateBounds,
|
||||
TkWindow *winPtr)
|
||||
{
|
||||
TkWindow *childPtr;
|
||||
XEvent event;
|
||||
CGRect bounds, damageBounds;
|
||||
HIShapeRef boundsRgn, damageRgn;
|
||||
|
||||
TkMacOSXWinCGBounds(winPtr, &bounds);
|
||||
if (!CGRectIntersectsRect(bounds, *updateBounds)) {
|
||||
return 0;
|
||||
}
|
||||
if (!HIShapeIntersectsRect(updateRgn, &bounds)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the bounding box of the area that the damage occured in.
|
||||
* Compute the bounding box of the area that the damage occurred in.
|
||||
*/
|
||||
|
||||
boundsRgn = HIShapeCreateWithRect(&bounds);
|
||||
damageRgn = HIShapeCreateIntersection(updateRgn, boundsRgn);
|
||||
if (HIShapeIsEmpty(damageRgn)) {
|
||||
CFRelease(damageRgn);
|
||||
CFRelease(boundsRgn);
|
||||
return 0;
|
||||
}
|
||||
HIShapeGetBounds(damageRgn, &damageBounds);
|
||||
|
||||
CFRelease(damageRgn);
|
||||
CFRelease(boundsRgn);
|
||||
|
||||
damageBounds = CGRectIntersection(bounds, *updateBounds);
|
||||
event.xany.serial = LastKnownRequestProcessed(Tk_Display(winPtr));
|
||||
event.xany.send_event = false;
|
||||
event.xany.window = Tk_WindowId(winPtr);
|
||||
@@ -457,7 +500,7 @@ GenerateUpdates(
|
||||
Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
|
||||
|
||||
#ifdef TK_MAC_DEBUG_DRAWING
|
||||
TKLog(@"Expose %p {{%d, %d}, {%d, %d}}", event.xany.window, event.xexpose.x,
|
||||
TKLog(@"Exposed %p {{%d, %d}, {%d, %d}}", event.xany.window, event.xexpose.x,
|
||||
event.xexpose.y, event.xexpose.width, event.xexpose.height);
|
||||
#endif
|
||||
|
||||
@@ -470,7 +513,7 @@ GenerateUpdates(
|
||||
if (!Tk_IsMapped(childPtr) || Tk_IsTopLevel(childPtr)) {
|
||||
continue;
|
||||
}
|
||||
GenerateUpdates(updateRgn, updateBounds, childPtr);
|
||||
GenerateUpdates(updateBounds, childPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -480,7 +523,7 @@ GenerateUpdates(
|
||||
if (Tk_IsContainer(winPtr)) {
|
||||
childPtr = TkpGetOtherWindow(winPtr);
|
||||
if (childPtr != NULL && Tk_IsMapped(childPtr)) {
|
||||
GenerateUpdates(updateRgn, updateBounds, childPtr);
|
||||
GenerateUpdates(updateBounds, childPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -491,58 +534,6 @@ GenerateUpdates(
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* GenerateActivateEvents --
|
||||
*
|
||||
* Given a Macintosh window activate event this function generates all the
|
||||
* X Activate events needed by Tk.
|
||||
*
|
||||
* Results:
|
||||
* True if event(s) are generated - false otherwise.
|
||||
*
|
||||
* Side effects:
|
||||
* Additional events may be place on the Tk event queue.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
GenerateActivateEvents(
|
||||
TkWindow *winPtr,
|
||||
int activeFlag)
|
||||
{
|
||||
TkGenerateActivateEvents(winPtr, activeFlag);
|
||||
if (activeFlag || ![NSApp isActive]) {
|
||||
TkMacOSXGenerateFocusEvent(winPtr, activeFlag);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* DoWindowActivate --
|
||||
*
|
||||
* Idle handler that calls GenerateActivateEvents().
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Additional events may be place on the Tk event queue.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
DoWindowActivate(
|
||||
ClientData clientData)
|
||||
{
|
||||
GenerateActivateEvents(clientData, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -555,12 +546,12 @@ DoWindowActivate(
|
||||
* True if event(s) are generated - false otherwise.
|
||||
*
|
||||
* Side effects:
|
||||
* Additional events may be place on the Tk event queue.
|
||||
* Additional events may be placed on the Tk event queue.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
MODULE_SCOPE int
|
||||
static int
|
||||
TkMacOSXGenerateFocusEvent(
|
||||
TkWindow *winPtr, /* Root X window for event. */
|
||||
int activeFlag)
|
||||
@@ -599,6 +590,35 @@ TkMacOSXGenerateFocusEvent(
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* GenerateActivateEvents --
|
||||
*
|
||||
* Given a Macintosh window activate event this function generates all the
|
||||
* X Activate events needed by Tk.
|
||||
*
|
||||
* Results:
|
||||
* True if event(s) are generated - false otherwise.
|
||||
*
|
||||
* Side effects:
|
||||
* Additional events may be placed on the Tk event queue.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
GenerateActivateEvents(
|
||||
TkWindow *winPtr,
|
||||
int activeFlag)
|
||||
{
|
||||
TkGenerateActivateEvents(winPtr, activeFlag);
|
||||
if (activeFlag || ![NSApp isActive]) {
|
||||
TkMacOSXGenerateFocusEvent(winPtr, activeFlag);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -713,7 +733,7 @@ TkGenWMConfigureEvent(
|
||||
|
||||
/*
|
||||
* Now set up the changes structure. Under X we wait for the
|
||||
* ConfigureNotify to set these values. On the Mac we know imediatly that
|
||||
* ConfigureNotify to set these values. On the Mac we know immediately that
|
||||
* this is what we want - so we just set them. However, we need to make
|
||||
* sure the windows clipping region is marked invalid so the change is
|
||||
* visible to the subwindow.
|
||||
@@ -804,7 +824,7 @@ TkWmProtocolEventProc(
|
||||
if (result != TCL_OK) {
|
||||
Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
|
||||
"\n (command for \"%s\" window manager protocol)",
|
||||
Tk_GetAtomName((Tk_Window) winPtr, protocol)));
|
||||
Tk_GetAtomName((Tk_Window)winPtr, protocol)));
|
||||
Tcl_BackgroundException(interp, result);
|
||||
}
|
||||
Tcl_Release(interp);
|
||||
@@ -818,8 +838,8 @@ TkWmProtocolEventProc(
|
||||
* message then just destroy the window.
|
||||
*/
|
||||
|
||||
if (protocol == Tk_InternAtom((Tk_Window) winPtr, "WM_DELETE_WINDOW")) {
|
||||
Tk_DestroyWindow((Tk_Window) winPtr);
|
||||
if (protocol == Tk_InternAtom((Tk_Window)winPtr, "WM_DELETE_WINDOW")) {
|
||||
Tk_DestroyWindow((Tk_Window)winPtr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -887,47 +907,38 @@ ExposeRestrictProc(
|
||||
|
||||
static Tk_RestrictAction
|
||||
ConfigureRestrictProc(
|
||||
ClientData arg,
|
||||
TCL_UNUSED(void *),
|
||||
XEvent *eventPtr)
|
||||
{
|
||||
return (eventPtr->type==ConfigureNotify ? TK_PROCESS_EVENT : TK_DEFER_EVENT);
|
||||
}
|
||||
|
||||
/*
|
||||
* If a window gets mapped inside the drawRect method, this will be run as an
|
||||
* idle task, after drawRect returns, to clean up the mess.
|
||||
*/
|
||||
@implementation TKContentView(TKWindowEvent)
|
||||
|
||||
static void
|
||||
RedisplayView(
|
||||
ClientData clientdata)
|
||||
- (void) addTkDirtyRect: (NSRect) rect
|
||||
{
|
||||
NSView *view = (NSView *) clientdata;
|
||||
|
||||
/*
|
||||
* Make sure that we are not trying to displaying a view that no longer
|
||||
* exists.
|
||||
*/
|
||||
|
||||
for (NSWindow *w in [NSApp orderedWindows]) {
|
||||
if ([w contentView] == view) {
|
||||
[view setNeedsDisplay:YES];
|
||||
break;
|
||||
}
|
||||
}
|
||||
_tkNeedsDisplay = YES;
|
||||
_tkDirtyRect = NSUnionRect(_tkDirtyRect, rect);
|
||||
[NSApp setNeedsToDraw:YES];
|
||||
}
|
||||
|
||||
@implementation TKContentView(TKWindowEvent)
|
||||
- (void) clearTkDirtyRect
|
||||
{
|
||||
_tkNeedsDisplay = NO;
|
||||
_tkDirtyRect = NSZeroRect;
|
||||
[NSApp setNeedsToDraw:NO];
|
||||
}
|
||||
|
||||
- (void) drawRect: (NSRect) rect
|
||||
{
|
||||
const NSRect *rectsBeingDrawn;
|
||||
NSInteger rectsBeingDrawnCount;
|
||||
(void)rect;
|
||||
|
||||
#ifdef TK_MAC_DEBUG_DRAWING
|
||||
TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
|
||||
if (winPtr) fprintf(stderr, "drawRect: drawing %s\n",
|
||||
Tk_PathName(winPtr));
|
||||
if (winPtr) {
|
||||
fprintf(stderr, "drawRect: drawing %s in %s\n",
|
||||
Tk_PathName(winPtr), NSStringFromRect(rect).UTF8String);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -936,37 +947,16 @@ RedisplayView(
|
||||
*/
|
||||
|
||||
if ([NSApp isDrawing]) {
|
||||
if ([NSApp macMinorVersion] > 13) {
|
||||
if ([NSApp macOSVersion] > 101300) {
|
||||
TKLog(@"WARNING: a recursive call to drawRect was aborted.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
[NSApp setIsDrawing: YES];
|
||||
|
||||
[self getRectsBeingDrawn:&rectsBeingDrawn count:&rectsBeingDrawnCount];
|
||||
CGFloat height = [self bounds].size.height;
|
||||
HIMutableShapeRef drawShape = HIShapeCreateMutable();
|
||||
|
||||
while (rectsBeingDrawnCount--) {
|
||||
CGRect r = NSRectToCGRect(*rectsBeingDrawn++);
|
||||
|
||||
#ifdef TK_MAC_DEBUG_DRAWING
|
||||
fprintf(stderr, "drawRect: %dx%d@(%d,%d)\n", (int)r.size.width,
|
||||
(int)r.size.height, (int)r.origin.x, (int)r.origin.y);
|
||||
#endif
|
||||
|
||||
r.origin.y = height - (r.origin.y + r.size.height);
|
||||
HIShapeUnionWithRect(drawShape, &r);
|
||||
}
|
||||
[self generateExposeEvents:(HIShapeRef)drawShape];
|
||||
CFRelease(drawShape);
|
||||
[NSApp setIsDrawing: NO];
|
||||
|
||||
if ([self needsRedisplay]) {
|
||||
[self setNeedsRedisplay:NO];
|
||||
Tcl_DoWhenIdle(RedisplayView, self);
|
||||
}
|
||||
[self clearTkDirtyRect];
|
||||
[self generateExposeEvents:rect];
|
||||
[NSApp setIsDrawing:NO];
|
||||
|
||||
#ifdef TK_MAC_DEBUG_DRAWING
|
||||
fprintf(stderr, "drawRect: done.\n");
|
||||
@@ -978,7 +968,7 @@ RedisplayView(
|
||||
[super setFrameSize: newsize];
|
||||
NSWindow *w = [self window];
|
||||
TkWindow *winPtr = TkMacOSXGetTkWindow(w);
|
||||
Tk_Window tkwin = (Tk_Window) winPtr;
|
||||
Tk_Window tkwin = (Tk_Window)winPtr;
|
||||
|
||||
if (![self inLiveResize] &&
|
||||
[w respondsToSelector: @selector (tkLayoutChanged)]) {
|
||||
@@ -1023,13 +1013,14 @@ RedisplayView(
|
||||
TkMacOSXUpdateClipRgn(winPtr);
|
||||
|
||||
/*
|
||||
* Generate and process expose events to redraw the window.
|
||||
* Generate and process expose events to redraw the window. To avoid
|
||||
* crashes, only do this if we are being called from drawRect. See
|
||||
* ticket [1fa8c3ed8d].
|
||||
*/
|
||||
|
||||
HIRect bounds = NSRectToCGRect([self bounds]);
|
||||
HIShapeRef shape = HIShapeCreateWithRect(&bounds);
|
||||
[self generateExposeEvents: shape];
|
||||
[w displayIfNeeded];
|
||||
if([NSApp isDrawing] || [self inLiveResize]) {
|
||||
[self generateExposeEvents: [self bounds]];
|
||||
}
|
||||
|
||||
/*
|
||||
* Finally, unlock the main autoreleasePool.
|
||||
@@ -1046,11 +1037,11 @@ RedisplayView(
|
||||
* pending idle events are processed so the drawing will actually take place.
|
||||
*/
|
||||
|
||||
- (void) generateExposeEvents: (HIShapeRef) shape
|
||||
- (void) generateExposeEvents: (NSRect) rect
|
||||
{
|
||||
unsigned long serial;
|
||||
CGRect updateBounds;
|
||||
int updatesNeeded;
|
||||
CGRect updateBounds;
|
||||
TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
|
||||
ClientData oldArg;
|
||||
Tk_RestrictProc *oldProc;
|
||||
@@ -1059,26 +1050,25 @@ RedisplayView(
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate Tk Expose events.
|
||||
* Generate Tk Expose events. All of these events will share the same
|
||||
* serial number.
|
||||
*/
|
||||
|
||||
HIShapeGetBounds(shape, &updateBounds);
|
||||
|
||||
/*
|
||||
* All of these events will share the same serial number.
|
||||
*/
|
||||
|
||||
serial = LastKnownRequestProcessed(Tk_Display(winPtr));
|
||||
updatesNeeded = GenerateUpdates(shape, &updateBounds, winPtr);
|
||||
|
||||
updateBounds = NSRectToCGRect(rect);
|
||||
updateBounds.origin.y = ([self bounds].size.height - updateBounds.origin.y
|
||||
- updateBounds.size.height);
|
||||
updatesNeeded = GenerateUpdates(&updateBounds, winPtr);
|
||||
if (updatesNeeded) {
|
||||
|
||||
serial = LastKnownRequestProcessed(Tk_Display(winPtr));
|
||||
|
||||
/*
|
||||
* First process all of the Expose events.
|
||||
* Use the ExposeRestrictProc to process only the expose events. This
|
||||
* will create idle drawing tasks, which we handle before we return.
|
||||
*/
|
||||
|
||||
oldProc = Tk_RestrictEvents(ExposeRestrictProc, UINT2PTR(serial), &oldArg);
|
||||
while (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) {};
|
||||
while (Tcl_ServiceEvent(TCL_WINDOW_EVENTS|TCL_DONT_WAIT)) {};
|
||||
Tk_RestrictEvents(oldProc, oldArg, &oldArg);
|
||||
|
||||
/*
|
||||
@@ -1090,51 +1080,104 @@ RedisplayView(
|
||||
* effect.)
|
||||
*
|
||||
* Fortunately, Tk schedules all drawing to be done while Tcl is idle.
|
||||
* So we can do the drawing by processing all of the idle events that
|
||||
* were created when the expose events were processed.
|
||||
* So to run any display procs which were scheduled by the expose
|
||||
* events we process all idle events before returning.
|
||||
*/
|
||||
|
||||
while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This method is called when a user changes between light and dark mode. The
|
||||
* implementation here generates a Tk virtual event which can be bound to a
|
||||
* function that redraws the window in an appropriate style.
|
||||
* In macOS 10.14 and later this method is called when a user changes between
|
||||
* light and dark mode or changes the accent color. The implementation
|
||||
* generates two virtual events. The first is either <<LightAqua>> or
|
||||
* <<DarkAqua>>, depending on the view's current effective appearance. The
|
||||
* second is <<AppearnceChanged>> and has a data string describing the
|
||||
* effective appearance of the view and the current accent and highlight
|
||||
* colors.
|
||||
*/
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
|
||||
|
||||
static const char *const accentNames[] = {
|
||||
"Graphite",
|
||||
"Red",
|
||||
"Orange",
|
||||
"Yellow",
|
||||
"Green",
|
||||
"Blue",
|
||||
"Purple",
|
||||
"Pink"
|
||||
};
|
||||
|
||||
- (void) viewDidChangeEffectiveAppearance
|
||||
{
|
||||
XVirtualEvent event;
|
||||
int x, y;
|
||||
NSWindow *w = [self window];
|
||||
TkWindow *winPtr = TkMacOSXGetTkWindow(w);
|
||||
Tk_Window tkwin = (Tk_Window) winPtr;
|
||||
|
||||
if (!winPtr) {
|
||||
Tk_Window tkwin = (Tk_Window)TkMacOSXGetTkWindow([self window]);
|
||||
if (!tkwin) {
|
||||
return;
|
||||
}
|
||||
bzero(&event, sizeof(XVirtualEvent));
|
||||
event.type = VirtualEvent;
|
||||
event.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
|
||||
event.send_event = false;
|
||||
event.display = Tk_Display(tkwin);
|
||||
event.event = Tk_WindowId(tkwin);
|
||||
event.root = XRootWindow(Tk_Display(tkwin), 0);
|
||||
event.subwindow = None;
|
||||
event.time = TkpGetMS();
|
||||
XQueryPointer(NULL, winPtr->window, NULL, NULL,
|
||||
&event.x_root, &event.y_root, &x, &y, &event.state);
|
||||
Tk_TopCoordsToWindow(tkwin, x, y, &event.x, &event.y);
|
||||
event.same_screen = true;
|
||||
if (TkMacOSXInDarkMode(tkwin)) {
|
||||
event.name = Tk_GetUid("DarkAqua");
|
||||
} else {
|
||||
event.name = Tk_GetUid("LightAqua");
|
||||
NSAppearanceName effectiveAppearanceName = [[self effectiveAppearance] name];
|
||||
NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];
|
||||
static const char *defaultColor = NULL;
|
||||
|
||||
if (effectiveAppearanceName == NSAppearanceNameAqua) {
|
||||
TkSendVirtualEvent(tkwin, "LightAqua", NULL);
|
||||
} else if (effectiveAppearanceName == NSAppearanceNameDarkAqua) {
|
||||
TkSendVirtualEvent(tkwin, "DarkAqua", NULL);
|
||||
}
|
||||
Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL);
|
||||
if ([NSApp macOSVersion] < 101500) {
|
||||
|
||||
/*
|
||||
* Mojave cannot handle the KVO shenanigans that we need for the
|
||||
* highlight and accent color notifications.
|
||||
*/
|
||||
|
||||
return;
|
||||
}
|
||||
if (!defaultColor) {
|
||||
defaultColor = [NSApp macOSVersion] < 110000 ? "Blue" : "Multicolor";
|
||||
preferences = [[NSUserDefaults standardUserDefaults] retain];
|
||||
|
||||
/*
|
||||
* AppKit calls this method when the user changes the Accent Color
|
||||
* but not when the user changes the Highlight Color. So we register
|
||||
* to receive KVO notifications for Highlight Color as well.
|
||||
*/
|
||||
|
||||
[preferences addObserver:self
|
||||
forKeyPath:@"AppleHighlightColor"
|
||||
options:NSKeyValueObservingOptionNew
|
||||
context:NULL];
|
||||
}
|
||||
NSString *accent = [preferences stringForKey:@"AppleAccentColor"];
|
||||
NSArray *words = [[preferences stringForKey:@"AppleHighlightColor"]
|
||||
componentsSeparatedByString: @" "];
|
||||
NSString *highlight = [words count] > 3 ? [words objectAtIndex:3] : nil;
|
||||
const char *accentName = accent ? accentNames[1 + accent.intValue] : defaultColor;
|
||||
const char *highlightName = highlight ? highlight.UTF8String: defaultColor;
|
||||
char data[256];
|
||||
snprintf(data, 256, "Appearance %s Accent %s Highlight %s",
|
||||
effectiveAppearanceName.UTF8String, accentName,
|
||||
highlightName);
|
||||
TkSendVirtualEvent(tkwin, "AppearanceChanged", Tcl_NewStringObj(data, -1));
|
||||
}
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath
|
||||
ofObject:(id)object
|
||||
change:(NSDictionary *)change
|
||||
context:(void *)context
|
||||
{
|
||||
NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];
|
||||
if (object == preferences && [keyPath isEqualToString:@"AppleHighlightColor"]) {
|
||||
if (@available(macOS 10.14, *)) {
|
||||
[self viewDidChangeEffectiveAppearance];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is no-op on 10.7 and up because Apple has removed this widget, but we
|
||||
* are leaving it here for backwards compatibility.
|
||||
@@ -1148,7 +1191,9 @@ RedisplayView(
|
||||
XVirtualEvent event;
|
||||
int x, y;
|
||||
TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
|
||||
Tk_Window tkwin = (Tk_Window) winPtr;
|
||||
Tk_Window tkwin = (Tk_Window)winPtr;
|
||||
(void)sender;
|
||||
|
||||
if (!winPtr){
|
||||
return;
|
||||
}
|
||||
@@ -1169,12 +1214,10 @@ RedisplayView(
|
||||
Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL);
|
||||
}
|
||||
|
||||
- (BOOL) isOpaque
|
||||
{
|
||||
NSWindow *w = [self window];
|
||||
return (w && (([w styleMask] & NSTexturedBackgroundWindowMask) ||
|
||||
![w isOpaque]) ? NO : YES);
|
||||
}
|
||||
/*
|
||||
* On Catalina this is never called and drawRect clips to the rect that
|
||||
* is passed to it by AppKit.
|
||||
*/
|
||||
|
||||
- (BOOL) wantsDefaultClipping
|
||||
{
|
||||
@@ -1193,6 +1236,8 @@ RedisplayView(
|
||||
|
||||
- (void) keyDown: (NSEvent *) theEvent
|
||||
{
|
||||
(void)theEvent;
|
||||
|
||||
#ifdef TK_MAC_DEBUG_EVENTS
|
||||
TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent);
|
||||
#endif
|
||||
@@ -1200,7 +1245,7 @@ RedisplayView(
|
||||
|
||||
/*
|
||||
* When the services menu is opened this is called for each Responder in
|
||||
* the Responder chain until a service provider is found. The TkContentView
|
||||
* the Responder chain until a service provider is found. The TKContentView
|
||||
* should be the first (and generally only) Responder in the chain. We
|
||||
* return the TkServices object that was created in TkpInit.
|
||||
*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -37,7 +37,7 @@ typedef struct ProtocolHandler {
|
||||
} ProtocolHandler;
|
||||
|
||||
/* The following data structure is used in the TkWmInfo to maintain a list of all of the
|
||||
* transient windows belonging to a given master.
|
||||
* transient windows belonging to a given container.
|
||||
*/
|
||||
|
||||
typedef struct Transient {
|
||||
@@ -46,6 +46,7 @@ typedef struct Transient {
|
||||
struct Transient *nextPtr;
|
||||
} Transient;
|
||||
|
||||
#define WITHDRAWN_BY_CONTAINER 0x1
|
||||
#define WITHDRAWN_BY_MASTER 0x1
|
||||
|
||||
/*
|
||||
@@ -65,8 +66,8 @@ typedef struct TkWmInfo {
|
||||
Tk_Uid titleUid; /* Title to display in window caption. If NULL,
|
||||
* use name of widget. */
|
||||
char *iconName; /* Name to display in icon. */
|
||||
Tk_Window master; /* Master window for TRANSIENT_FOR property, or
|
||||
* None. */
|
||||
Tk_Window container; /* Container window for TRANSIENT_FOR property,
|
||||
* or None. */
|
||||
XWMHints hints; /* Various pieces of information for window
|
||||
* manager. */
|
||||
char *leaderName; /* Path name of leader of window group
|
||||
|
||||
@@ -201,8 +201,8 @@ TkpOpenDisplay(
|
||||
}
|
||||
}
|
||||
|
||||
display = ckalloc(sizeof(Display));
|
||||
screen = ckalloc(sizeof(Screen));
|
||||
display = (Display *)ckalloc(sizeof(Display));
|
||||
screen = (Screen *)ckalloc(sizeof(Screen));
|
||||
bzero(display, sizeof(Display));
|
||||
bzero(screen, sizeof(Screen));
|
||||
|
||||
@@ -250,11 +250,11 @@ TkpOpenDisplay(
|
||||
*/
|
||||
screen->root = ROOT_ID;
|
||||
screen->display = display;
|
||||
screen->black_pixel = 0x00000000 | PIXEL_MAGIC << 24;
|
||||
screen->white_pixel = 0x00FFFFFF | PIXEL_MAGIC << 24;
|
||||
screen->black_pixel = 0x00000000;
|
||||
screen->white_pixel = 0x00FFFFFF;
|
||||
screen->ext_data = (XExtData *) &maxBounds;
|
||||
|
||||
screen->root_visual = ckalloc(sizeof(Visual));
|
||||
screen->root_visual = (Visual *)ckalloc(sizeof(Visual));
|
||||
screen->root_visual->visualid = 0;
|
||||
screen->root_visual->c_class = TrueColor;
|
||||
screen->root_visual->red_mask = 0x00FF0000;
|
||||
@@ -269,7 +269,7 @@ TkpOpenDisplay(
|
||||
|
||||
TkMacOSXDisplayChanged(display);
|
||||
|
||||
gMacDisplay = ckalloc(sizeof(TkDisplay));
|
||||
gMacDisplay = (TkDisplay *)ckalloc(sizeof(TkDisplay));
|
||||
|
||||
/*
|
||||
* This is the quickest way to make sure that all the *Init flags get
|
||||
@@ -387,7 +387,7 @@ TkClipCleanup(
|
||||
|
||||
static XID
|
||||
MacXIdAlloc(
|
||||
Display *display) /* Display for which to allocate. */
|
||||
TCL_UNUSED(Display *)) /* Display for which to allocate. */
|
||||
{
|
||||
static long int cur_id = 100;
|
||||
/*
|
||||
@@ -417,8 +417,8 @@ MacXIdAlloc(
|
||||
|
||||
static int
|
||||
DefaultErrorHandler(
|
||||
Display* display,
|
||||
XErrorEvent* err_evt)
|
||||
TCL_UNUSED(Display *),
|
||||
TCL_UNUSED(XErrorEvent *))
|
||||
{
|
||||
/*
|
||||
* This call should never be called. Tk replaces it with its own error
|
||||
@@ -431,8 +431,8 @@ DefaultErrorHandler(
|
||||
|
||||
char *
|
||||
XGetAtomName(
|
||||
Display * display,
|
||||
Atom atom)
|
||||
Display *display,
|
||||
TCL_UNUSED(Atom))
|
||||
{
|
||||
display->request++;
|
||||
return NULL;
|
||||
@@ -440,7 +440,7 @@ XGetAtomName(
|
||||
|
||||
XErrorHandler
|
||||
XSetErrorHandler(
|
||||
XErrorHandler handler)
|
||||
TCL_UNUSED(XErrorHandler))
|
||||
{
|
||||
return DefaultErrorHandler;
|
||||
}
|
||||
@@ -448,7 +448,7 @@ XSetErrorHandler(
|
||||
Window
|
||||
XRootWindow(
|
||||
Display *display,
|
||||
int screen_number)
|
||||
TCL_UNUSED(int))
|
||||
{
|
||||
display->request++;
|
||||
return ROOT_ID;
|
||||
@@ -466,7 +466,7 @@ XGetGeometry(
|
||||
unsigned int *border_width_return,
|
||||
unsigned int *depth_return)
|
||||
{
|
||||
TkWindow *winPtr = ((MacDrawable *) d)->winPtr;
|
||||
TkWindow *winPtr = ((MacDrawable *)d)->winPtr;
|
||||
|
||||
display->request++;
|
||||
*root_return = ROOT_ID;
|
||||
@@ -478,7 +478,7 @@ XGetGeometry(
|
||||
*border_width_return = winPtr->changes.border_width;
|
||||
*depth_return = Tk_Depth(winPtr);
|
||||
} else {
|
||||
CGSize size = ((MacDrawable *) d)->size;
|
||||
CGSize size = ((MacDrawable *)d)->size;
|
||||
*x_return = 0;
|
||||
*y_return = 0;
|
||||
*width_return = size.width;
|
||||
@@ -491,14 +491,14 @@ XGetGeometry(
|
||||
|
||||
int
|
||||
XChangeProperty(
|
||||
Display* display,
|
||||
Window w,
|
||||
Atom property,
|
||||
Atom type,
|
||||
int format,
|
||||
int mode,
|
||||
_Xconst unsigned char* data,
|
||||
int nelements)
|
||||
TCL_UNUSED(Display *),
|
||||
TCL_UNUSED(Window),
|
||||
TCL_UNUSED(Atom),
|
||||
TCL_UNUSED(Atom),
|
||||
TCL_UNUSED(int),
|
||||
TCL_UNUSED(int),
|
||||
TCL_UNUSED(_Xconst unsigned char *),
|
||||
TCL_UNUSED(int))
|
||||
{
|
||||
Debugger();
|
||||
return Success;
|
||||
@@ -506,9 +506,9 @@ XChangeProperty(
|
||||
|
||||
int
|
||||
XSelectInput(
|
||||
Display* display,
|
||||
Window w,
|
||||
long event_mask)
|
||||
TCL_UNUSED(Display *),
|
||||
TCL_UNUSED(Window),
|
||||
TCL_UNUSED(long))
|
||||
{
|
||||
Debugger();
|
||||
return Success;
|
||||
@@ -516,40 +516,16 @@ XSelectInput(
|
||||
|
||||
int
|
||||
XBell(
|
||||
Display* display,
|
||||
int percent)
|
||||
TCL_UNUSED(Display *),
|
||||
TCL_UNUSED(int))
|
||||
{
|
||||
NSBeep();
|
||||
return Success;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
XSetWMNormalHints(
|
||||
Display* display,
|
||||
Window w,
|
||||
XSizeHints* hints)
|
||||
{
|
||||
/*
|
||||
* Do nothing. Shouldn't even be called.
|
||||
*/
|
||||
}
|
||||
|
||||
XSizeHints *
|
||||
XAllocSizeHints(void)
|
||||
{
|
||||
/*
|
||||
* Always return NULL. Tk code checks to see if NULL is returned & does
|
||||
* nothing if it is.
|
||||
*/
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
GContext
|
||||
XGContextFromGC(
|
||||
GC gc)
|
||||
TCL_UNUSED(GC))
|
||||
{
|
||||
/*
|
||||
* TODO: currently a no-op
|
||||
@@ -560,11 +536,11 @@ XGContextFromGC(
|
||||
|
||||
Status
|
||||
XSendEvent(
|
||||
Display* display,
|
||||
Window w,
|
||||
Bool propagate,
|
||||
long event_mask,
|
||||
XEvent* event_send)
|
||||
TCL_UNUSED(Display *),
|
||||
TCL_UNUSED(Window),
|
||||
TCL_UNUSED(Bool),
|
||||
TCL_UNUSED(long),
|
||||
TCL_UNUSED(XEvent *))
|
||||
{
|
||||
Debugger();
|
||||
return 0;
|
||||
@@ -572,56 +548,31 @@ XSendEvent(
|
||||
|
||||
int
|
||||
XClearWindow(
|
||||
Display* display,
|
||||
Window w)
|
||||
TCL_UNUSED(Display *),
|
||||
TCL_UNUSED(Window))
|
||||
{
|
||||
return Success;
|
||||
}
|
||||
|
||||
/*
|
||||
int
|
||||
XDrawPoint(
|
||||
Display* display,
|
||||
Drawable d,
|
||||
GC gc,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
return Success;
|
||||
}
|
||||
|
||||
int
|
||||
XDrawPoints(
|
||||
Display* display,
|
||||
Drawable d,
|
||||
GC gc,
|
||||
XPoint* points,
|
||||
int npoints,
|
||||
int mode)
|
||||
{
|
||||
return Success;
|
||||
}
|
||||
*/
|
||||
|
||||
int
|
||||
XWarpPointer(
|
||||
Display* display,
|
||||
Window src_w,
|
||||
Window dest_w,
|
||||
int src_x,
|
||||
int src_y,
|
||||
unsigned int src_width,
|
||||
unsigned int src_height,
|
||||
int dest_x,
|
||||
int dest_y)
|
||||
TCL_UNUSED(Display *),
|
||||
TCL_UNUSED(Window),
|
||||
TCL_UNUSED(Window),
|
||||
TCL_UNUSED(int),
|
||||
TCL_UNUSED(int),
|
||||
TCL_UNUSED(unsigned int),
|
||||
TCL_UNUSED(unsigned int),
|
||||
TCL_UNUSED(int),
|
||||
TCL_UNUSED(int))
|
||||
{
|
||||
return Success;
|
||||
}
|
||||
|
||||
int
|
||||
XQueryColor(
|
||||
Display* display,
|
||||
Colormap colormap,
|
||||
TCL_UNUSED(Display *),
|
||||
TCL_UNUSED(Colormap),
|
||||
XColor* def_in_out)
|
||||
{
|
||||
unsigned long p;
|
||||
@@ -642,8 +593,8 @@ XQueryColor(
|
||||
|
||||
int
|
||||
XQueryColors(
|
||||
Display* display,
|
||||
Colormap colormap,
|
||||
TCL_UNUSED(Display *),
|
||||
TCL_UNUSED(Colormap),
|
||||
XColor* defs_in_out,
|
||||
int ncolors)
|
||||
{
|
||||
@@ -667,14 +618,13 @@ XQueryColors(
|
||||
}
|
||||
|
||||
int
|
||||
XQueryTree(display, w, root_return, parent_return, children_return,
|
||||
nchildren_return)
|
||||
Display* display;
|
||||
Window w;
|
||||
Window* root_return;
|
||||
Window* parent_return;
|
||||
Window** children_return;
|
||||
unsigned int* nchildren_return;
|
||||
XQueryTree(
|
||||
TCL_UNUSED(Display *),
|
||||
TCL_UNUSED(Window),
|
||||
TCL_UNUSED(Window *),
|
||||
TCL_UNUSED(Window *),
|
||||
TCL_UNUSED(Window **),
|
||||
TCL_UNUSED(unsigned int *))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -683,17 +633,17 @@ XQueryTree(display, w, root_return, parent_return, children_return,
|
||||
int
|
||||
XGetWindowProperty(
|
||||
Display *display,
|
||||
Window w,
|
||||
Atom property,
|
||||
long long_offset,
|
||||
long long_length,
|
||||
Bool delete,
|
||||
Atom req_type,
|
||||
TCL_UNUSED(Window),
|
||||
TCL_UNUSED(Atom),
|
||||
TCL_UNUSED(long),
|
||||
TCL_UNUSED(long),
|
||||
TCL_UNUSED(Bool),
|
||||
TCL_UNUSED(Atom),
|
||||
Atom *actual_type_return,
|
||||
int *actual_format_return,
|
||||
unsigned long *nitems_return,
|
||||
unsigned long *bytes_after_return,
|
||||
unsigned char ** prop_return)
|
||||
TCL_UNUSED(unsigned char **))
|
||||
{
|
||||
display->request++;
|
||||
*actual_type_return = None;
|
||||
@@ -704,7 +654,7 @@ XGetWindowProperty(
|
||||
|
||||
int
|
||||
XRefreshKeyboardMapping(
|
||||
XMappingEvent *x)
|
||||
TCL_UNUSED(XMappingEvent *))
|
||||
{
|
||||
/* used by tkXEvent.c */
|
||||
Debugger();
|
||||
@@ -714,8 +664,8 @@ XRefreshKeyboardMapping(
|
||||
int
|
||||
XSetIconName(
|
||||
Display* display,
|
||||
Window w,
|
||||
const char *icon_name)
|
||||
TCL_UNUSED(Window),
|
||||
TCL_UNUSED(const char *))
|
||||
{
|
||||
/*
|
||||
* This is a no-op, no icon name for Macs.
|
||||
@@ -727,7 +677,7 @@ XSetIconName(
|
||||
int
|
||||
XForceScreenSaver(
|
||||
Display* display,
|
||||
int mode)
|
||||
TCL_UNUSED(int))
|
||||
{
|
||||
/*
|
||||
* This function is just a no-op. It is defined to reset the screen saver.
|
||||
@@ -741,8 +691,8 @@ XForceScreenSaver(
|
||||
|
||||
void
|
||||
Tk_FreeXId(
|
||||
Display *display,
|
||||
XID xid)
|
||||
TCL_UNUSED(Display *),
|
||||
TCL_UNUSED(XID))
|
||||
{
|
||||
/* no-op function needed for stubs implementation. */
|
||||
}
|
||||
@@ -750,14 +700,24 @@ Tk_FreeXId(
|
||||
int
|
||||
XSync(
|
||||
Display *display,
|
||||
Bool discard)
|
||||
TCL_UNUSED(Bool))
|
||||
{
|
||||
TkMacOSXFlushWindows();
|
||||
/*
|
||||
* The main use of XSync is by the update command, which alternates
|
||||
* between running an event loop to process all events without waiting and
|
||||
* calling XSync on all displays until no events are left. There is
|
||||
* nothing for the mac to do with respect to syncing its one display but
|
||||
* it can (and, during regression testing, frequently does) happen that
|
||||
* timer events fire during the event loop. Processing those here seems
|
||||
* to make the update command work in a way that is more consistent with
|
||||
* its behavior on other platforms.
|
||||
*/
|
||||
|
||||
while (Tcl_DoOneEvent(TCL_TIMER_EVENTS|TCL_DONT_WAIT)){}
|
||||
display->request++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int
|
||||
XSetClipRectangles(
|
||||
Display *d,
|
||||
@@ -771,19 +731,17 @@ XSetClipRectangles(
|
||||
TkRegion clipRgn = TkCreateRegion();
|
||||
|
||||
while (n--) {
|
||||
XRectangle rect = *rectangles;
|
||||
XRectangle rect = *rectangles;
|
||||
|
||||
rect.x += clip_x_origin;
|
||||
rect.y += clip_y_origin;
|
||||
TkUnionRectWithRegion(&rect, clipRgn, clipRgn);
|
||||
rectangles++;
|
||||
rect.x += clip_x_origin;
|
||||
rect.y += clip_y_origin;
|
||||
TkUnionRectWithRegion(&rect, clipRgn, clipRgn);
|
||||
rectangles++;
|
||||
}
|
||||
TkSetRegion(d, gc, clipRgn);
|
||||
TkDestroyRegion(clipRgn);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -842,64 +800,64 @@ TkGetServerInfo(
|
||||
|
||||
int
|
||||
XChangeWindowAttributes(
|
||||
Display *display,
|
||||
Window w,
|
||||
unsigned long value_mask,
|
||||
XSetWindowAttributes *attributes)
|
||||
TCL_UNUSED(Display *),
|
||||
TCL_UNUSED(Window),
|
||||
TCL_UNUSED(unsigned long),
|
||||
TCL_UNUSED(XSetWindowAttributes *))
|
||||
{
|
||||
return Success;
|
||||
}
|
||||
|
||||
int
|
||||
XSetWindowBackground(
|
||||
Display *display,
|
||||
Window window,
|
||||
unsigned long value)
|
||||
TCL_UNUSED(Display *),
|
||||
TCL_UNUSED(Window),
|
||||
TCL_UNUSED(unsigned long))
|
||||
{
|
||||
return Success;
|
||||
}
|
||||
|
||||
int
|
||||
XSetWindowBackgroundPixmap(
|
||||
Display *display,
|
||||
Window w,
|
||||
Pixmap background_pixmap)
|
||||
TCL_UNUSED(Display *),
|
||||
TCL_UNUSED(Window),
|
||||
TCL_UNUSED(Pixmap))
|
||||
{
|
||||
return Success;
|
||||
}
|
||||
|
||||
int
|
||||
XSetWindowBorder(
|
||||
Display *display,
|
||||
Window w,
|
||||
unsigned long border_pixel)
|
||||
TCL_UNUSED(Display *),
|
||||
TCL_UNUSED(Window),
|
||||
TCL_UNUSED(unsigned long))
|
||||
{
|
||||
return Success;
|
||||
}
|
||||
|
||||
int
|
||||
XSetWindowBorderPixmap(
|
||||
Display *display,
|
||||
Window w,
|
||||
Pixmap border_pixmap)
|
||||
TCL_UNUSED(Display *),
|
||||
TCL_UNUSED(Window),
|
||||
TCL_UNUSED(Pixmap))
|
||||
{
|
||||
return Success;
|
||||
}
|
||||
|
||||
int
|
||||
XSetWindowBorderWidth(
|
||||
Display *display,
|
||||
Window w,
|
||||
unsigned int width)
|
||||
TCL_UNUSED(Display *),
|
||||
TCL_UNUSED(Window),
|
||||
TCL_UNUSED(unsigned int))
|
||||
{
|
||||
return Success;
|
||||
}
|
||||
|
||||
int
|
||||
XSetWindowColormap(
|
||||
Display *display,
|
||||
Window w,
|
||||
Colormap colormap)
|
||||
TCL_UNUSED(Display *),
|
||||
TCL_UNUSED(Window),
|
||||
TCL_UNUSED(Colormap))
|
||||
{
|
||||
Debugger();
|
||||
return Success;
|
||||
@@ -907,25 +865,25 @@ XSetWindowColormap(
|
||||
|
||||
Status
|
||||
XStringListToTextProperty(
|
||||
char **list,
|
||||
int count,
|
||||
XTextProperty *text_prop_return)
|
||||
TCL_UNUSED(char **),
|
||||
TCL_UNUSED(int),
|
||||
TCL_UNUSED(XTextProperty *))
|
||||
{
|
||||
Debugger();
|
||||
return (Status) 0;
|
||||
return Success;
|
||||
}
|
||||
|
||||
void
|
||||
XSetWMClientMachine(
|
||||
Display *display,
|
||||
Window w,
|
||||
XTextProperty *text_prop)
|
||||
TCL_UNUSED(Display *),
|
||||
TCL_UNUSED(Window),
|
||||
TCL_UNUSED(XTextProperty *))
|
||||
{
|
||||
Debugger();
|
||||
}
|
||||
|
||||
XIC
|
||||
XCreateIC(XIM xim, ...)
|
||||
XCreateIC(TCL_UNUSED(XIM), ...)
|
||||
{
|
||||
Debugger();
|
||||
return (XIC) 0;
|
||||
@@ -943,16 +901,16 @@ XVisualIDFromVisual(
|
||||
XAfterFunction
|
||||
XSynchronize(
|
||||
Display *display,
|
||||
Bool onoff)
|
||||
TCL_UNUSED(Bool))
|
||||
{
|
||||
display->request++;
|
||||
display->request++;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#undef XUngrabServer
|
||||
int
|
||||
XUngrabServer(
|
||||
Display *display)
|
||||
TCL_UNUSED(Display *))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -969,7 +927,7 @@ XNoOp(
|
||||
#undef XGrabServer
|
||||
int
|
||||
XGrabServer(
|
||||
Display *display)
|
||||
TCL_UNUSED(Display *))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -987,7 +945,7 @@ XFree(
|
||||
#undef XFlush
|
||||
int
|
||||
XFlush(
|
||||
Display *display)
|
||||
TCL_UNUSED(Display *))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -1011,7 +969,7 @@ XFlush(
|
||||
|
||||
const char *
|
||||
TkGetDefaultScreenName(
|
||||
Tcl_Interp *interp, /* Not used. */
|
||||
TCL_UNUSED(Tcl_Interp *),
|
||||
const char *screenName) /* If NULL, use default string. */
|
||||
{
|
||||
if ((screenName == NULL) || (screenName[0] == '\0')) {
|
||||
@@ -1038,7 +996,7 @@ TkGetDefaultScreenName(
|
||||
|
||||
long
|
||||
Tk_GetUserInactiveTime(
|
||||
Display *dpy)
|
||||
TCL_UNUSED(Display *))
|
||||
{
|
||||
io_registry_entry_t regEntry;
|
||||
CFMutableDictionaryRef props = NULL;
|
||||
@@ -1047,7 +1005,7 @@ Tk_GetUserInactiveTime(
|
||||
uint64_t time;
|
||||
IOReturn result;
|
||||
|
||||
regEntry = IOServiceGetMatchingService(kIOMasterPortDefault,
|
||||
regEntry = IOServiceGetMatchingService(0,
|
||||
IOServiceMatching("IOHIDSystem"));
|
||||
|
||||
if (regEntry == 0) {
|
||||
@@ -1104,7 +1062,7 @@ Tk_GetUserInactiveTime(
|
||||
|
||||
void
|
||||
Tk_ResetUserInactiveTime(
|
||||
Display *dpy)
|
||||
TCL_UNUSED(Display *))
|
||||
{
|
||||
lastInactivityReset = TkpGetMS();
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user