summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorculler <culler>2019-03-18 15:36:31 (GMT)
committerculler <culler>2019-03-18 15:36:31 (GMT)
commit446875a3bad587fe6e6388f6576d12246df14154 (patch)
tree25519b0e932e500f442ffa5f3f93a1998c680313
parentf357757e215618b09711c710048d925db11c2125 (diff)
downloadtk-446875a3bad587fe6e6388f6576d12246df14154.zip
tk-446875a3bad587fe6e6388f6576d12246df14154.tar.gz
tk-446875a3bad587fe6e6388f6576d12246df14154.tar.bz2
Added ::tk::unsupported::MacWindowStyle appearance to control which appearances are allowed
on a per-window basis.
-rw-r--r--macosx/README10
-rw-r--r--macosx/tkMacOSXWm.c117
2 files changed, 121 insertions, 6 deletions
diff --git a/macosx/README b/macosx/README
index adc709c..c79c372 100644
--- a/macosx/README
+++ b/macosx/README
@@ -189,6 +189,16 @@ tk::unsupported::MacWindowStyle tabbingid window ?newId? which can be used to
get or set the tabbingIdentifier for the NSWindow associated with a Tk Window.
See section 3 for details.
+- A command tk::unsupported::MacWindowStyle appearance window ?newAappearance?
+is available when Tk is built and run on macOS 10.14 (Mojave) or later. In
+that case the Ttk widgets all support the "Dark Mode" appearance which was
+introduced in 10.14. The command accepts the following values for the optional
+newAppearance option: "aqua", "darkaqua", or "auto". If the appearance is set
+to aqua or darkaqua then the window will be displayed with the corresponding
+appearance independent of any preferences settings. If it is set to "auto"
+the appearance will be determined by the preferences. This command can be
+used to opt out of Dark Mode on a per-window basis.
+
- If you want to use Remote Debugging with Xcode, you need to set the
environment variable XCNOSTDIN to 1 in the Executable editor for Wish. That will
cause us to force closing stdin & stdout. Otherwise, given how Xcode launches
diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c
index 67d6ecb..1d31fe1 100644
--- a/macosx/tkMacOSXWm.c
+++ b/macosx/tkMacOSXWm.c
@@ -311,6 +311,8 @@ static int WmWinStyle(Tcl_Interp *interp, TkWindow *winPtr,
int objc, Tcl_Obj *const objv[]);
static int WmWinTabbingId(Tcl_Interp *interp, TkWindow *winPtr,
int objc, Tcl_Obj *const objv[]);
+static int WmWinAppearance(Tcl_Interp *interp, TkWindow *winPtr,
+ int objc, Tcl_Obj *const objv[]);
static void ApplyWindowAttributeFlagChanges(TkWindow *winPtr,
NSWindow *macWindow, UInt64 oldAttributes,
int oldFlags, int create, int initial);
@@ -5509,10 +5511,10 @@ TkUnsupported1ObjCmd(
Tcl_Obj *const objv[]) /* Argument objects. */
{
static const char *const subcmds[] = {
- "style", "tabbingid", NULL
+ "style", "tabbingid", "appearance", NULL
};
enum SubCmds {
- TKMWS_STYLE, TKMWS_TABID
+ TKMWS_STYLE, TKMWS_TABID, TKMWS_APPEARANCE
};
Tk_Window tkwin = clientData;
TkWindow *winPtr;
@@ -5540,13 +5542,14 @@ TkUnsupported1ObjCmd(
sizeof(char *), "option", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
- if (((enum SubCmds) index) == TKMWS_STYLE) {
+ switch((enum SubCmds) index) {
+ case TKMWS_STYLE:
if ((objc < 3) || (objc > 5)) {
Tcl_WrongNumArgs(interp, 2, objv, "window ?class attributes?");
return TCL_ERROR;
}
return WmWinStyle(interp, winPtr, objc, objv);
- } else if (((enum SubCmds) index) == TKMWS_TABID) {
+ case TKMWS_TABID:
if ([NSApp macMinorVersion] < 12) {
Tcl_AddErrorInfo(interp,
"\n (TabbingIdentifiers only exist on OSX 10.12 or later)");
@@ -5557,9 +5560,20 @@ TkUnsupported1ObjCmd(
return TCL_ERROR;
}
return WmWinTabbingId(interp, winPtr, objc, objv);
+ case TKMWS_APPEARANCE:
+ if ([NSApp macMinorVersion] < 12) {
+ Tcl_AddErrorInfo(interp,
+ "\n (The appearance command requires OSX 10.14 or later)");
+ return TCL_ERROR;
+ }
+ if ((objc < 3) || (objc > 4)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "appearance window ?appearancename?");
+ return TCL_ERROR;
+ }
+ return WmWinAppearance(interp, winPtr, objc, objv);
+ default:
+ return TCL_ERROR;
}
- /* won't be reached */
- return TCL_ERROR;
}
/*
@@ -5817,6 +5831,97 @@ WmWinTabbingId(
/*
*----------------------------------------------------------------------
*
+ * WmWinAppearance --
+ *
+ * This procedure is invoked to process the
+ * "::tk::unsupported::MacWindowStyle appearance" subcommand. The command
+ * allows you to get or set the appearance for the NSWindow
+ * associated with a Tk Window. The syntax is:
+ * tk::unsupported::MacWindowStyle tabbingid window ?newAppearance?
+ * Allowed appearance names are "aqua", "darkaqua", and "auto".
+ *
+ * Results:
+ * Returns the appearance setting of the window prior to calling this
+ * function.
+ *
+ * Side effects:
+ * The underlying NSWindow's appearance property is set to the specified
+ * value if the optional newAppearance argument is supplied. Otherwise
+ * the window's appearance property is not changed. If the appearance is
+ * set to aqua or darkaqua then the window will use the associated
+ * NSAppearance even if the user has selected a different appearance with
+ * the system preferences. If it is set to auto then the appearance
+ * property is set to nil, meaning that the preferences will determine the
+ * appearance.
+ *
+ *
+ *----------------------------------------------------------------------
+ */
+
+ static int
+WmWinAppearance(
+ Tcl_Interp *interp, /* Current interpreter. */
+ TkWindow *winPtr, /* Window to be manipulated. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj * const objv[]) /* Argument objects. */
+{
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
+ static const char *const appearanceStrings[] = {
+ "aqua", "darkaqua", "auto", NULL
+ };
+ enum appearances {
+ APPEARANCE_AQUA, APPEARANCE_DARKAQUA, APPEARANCE_AUTO
+ };
+ Tcl_Obj *result = NULL;
+ NSAppearanceName appearance;
+ const char *resultString;
+ NSWindow *win = TkMacOSXDrawableWindow(winPtr->window);
+ if (win) {
+ appearance = win.appearance.name;
+ if (appearance == nil) {
+ resultString = appearanceStrings[APPEARANCE_AUTO];
+ } else if (appearance == NSAppearanceNameAqua) {
+ resultString = appearanceStrings[APPEARANCE_AQUA];
+ } else if (appearance == NSAppearanceNameDarkAqua) {
+ resultString = appearanceStrings[APPEARANCE_DARKAQUA];
+ } else {
+ resultString = "unrecognized";
+ }
+ result = Tcl_NewStringObj(resultString, strlen(resultString));
+ }
+ if (result == NULL) {
+ Tcl_Panic("Failed to read appearance name.");
+ }
+ Tcl_SetObjResult(interp, result);
+ if (objc == 3) {
+ return TCL_OK;
+ } else if (objc == 4) {
+ int index;
+ if (Tcl_GetIndexFromObjStruct(interp, objv[3], appearanceStrings,
+ sizeof(char *), "appearancename", 0, &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ switch ((enum appearances) index) {
+ case APPEARANCE_AQUA:
+ win.appearance = [NSAppearance appearanceNamed:
+ NSAppearanceNameAqua];
+ break;
+ case APPEARANCE_DARKAQUA:
+ win.appearance = [NSAppearance appearanceNamed:
+ NSAppearanceNameDarkAqua];
+ break;
+ default:
+ win.appearance = nil;
+ }
+ return TCL_OK;
+ }
+#endif
+ return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* TkpMakeMenuWindow --
*
* Configure the window to be either a undecorated pull-down (or pop-up)