summaryrefslogtreecommitdiffstats
path: root/macosx/tkMacOSXWm.c
diff options
context:
space:
mode:
authorculler <culler>2024-06-01 17:07:55 (GMT)
committerculler <culler>2024-06-01 17:07:55 (GMT)
commit4590ed8c33cec0f721dcf9538b1f5a6bee92a05b (patch)
tree2d25a602b6938842a908bc5b7f6bdd6aa93dcbb7 /macosx/tkMacOSXWm.c
parentbe3f0a1c8edcc9a0964702a80fcdca8289acce4b (diff)
parentf90a1c9c963255657d02c8e5a026a73581631c29 (diff)
downloadtk-4590ed8c33cec0f721dcf9538b1f5a6bee92a05b.zip
tk-4590ed8c33cec0f721dcf9538b1f5a6bee92a05b.tar.gz
tk-4590ed8c33cec0f721dcf9538b1f5a6bee92a05b.tar.bz2
New branch implementing Christopher Chavez's idea for drawing to a CGImage without using drawRect. This is for Tk9
Diffstat (limited to 'macosx/tkMacOSXWm.c')
-rw-r--r--macosx/tkMacOSXWm.c1343
1 files changed, 946 insertions, 397 deletions
diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c
index 2fa9434..3311ded 100644
--- a/macosx/tkMacOSXWm.c
+++ b/macosx/tkMacOSXWm.c
@@ -18,7 +18,7 @@
#include "tkMacOSXPrivate.h"
#include "tkScrollbar.h"
#include "tkMacOSXWm.h"
-#include "tkMacOSXEvent.h"
+#include "tkMacOSXInt.h"
#include "tkMacOSXDebug.h"
#include "tkMacOSXConstants.h"
@@ -37,7 +37,7 @@
*/
/*
- * Window attributes and classes
+ * Carbon window attributes and classes.
*/
#define WM_NSMASK_SHIFT 36
@@ -111,7 +111,8 @@ static const struct {
.defaultAttrs = kWindowHideOnSuspendAttribute,
.forceOnAttrs = kWindowNoTitleBarAttribute |
kWindowDoesNotCycleAttribute,
- .flags = WM_TOPMOST, },
+ .flags = WM_TOPMOST,
+ .styleMask = 0},
[kSheetWindowClass] = {
.validAttrs = kWindowResizableAttribute,
.forceOnAttrs = kWindowNoTitleBarAttribute |
@@ -150,19 +151,161 @@ static const struct {
(macClassAttrs[(class)].forceOnAttrs & ~kWindowResizableAttribute)))
/*
- * Data for [wm attributes] command:
+ * Structures and data for the wm attributes command (macOS 10.13 and later):
*/
+/* Hash tables for attributes which can be set before a window exists */
+static Tcl_HashTable pathnameToSubclass;
+static Tcl_HashTable pathnameToTabbingId;
+static Tcl_HashTable pathnameToTabbingMode;
+
+enum NSWindowSubclass {
+ subclassNSWindow = 0,
+ subclassNSPanel = 1
+};
+/* This array must be indexed by the enum above.*/
+static const char *subclassNames[] = {"nswindow", "nspanel", NULL};
+
+typedef struct buttonField_t {
+ unsigned zoom: 1;
+ unsigned miniaturize: 1;
+ unsigned close: 1;
+} buttonField;
+
+/* The order of these names must match the order of the bits above! */
+static const char *buttonNames[] = {"zoom", "miniaturize", "close", NULL};
+
+typedef union windowButtonState_t {
+ int intvalue;
+ buttonField bits;
+} windowButtonState;
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101300
+enum NSWindowClass {
+ NSWindowClass_any = 0,
+ NSWindowClass_window = 1,
+ NSWindowClass_panel = 2
+};
+typedef struct styleMaskBit_t {
+ const char *bitname;
+ unsigned long bitvalue;
+ enum NSWindowClass allowed;
+} styleMaskBit;
+
+static const styleMaskBit styleMaskBits[] = {
+ /* Make the titlebar visible and use round corners. */
+ {"titled", NSWindowStyleMaskTitled, NSWindowClass_window},
+ /* Enable the close button. */
+ {"closable", NSWindowStyleMaskClosable, NSWindowClass_window},
+ /* Enable the miniaturize button. */
+ {"miniaturizable", NSWindowStyleMaskMiniaturizable, NSWindowClass_window},
+ /* Allow the user to resize the window. */
+ {"resizable", NSWindowStyleMaskResizable, NSWindowClass_window},
+ /*
+ * Make the content view extend under the titlebar. We force
+ * titlebarAppearsTransparent when this bit is set. Otherwise it is
+ * pretty useless.
+ */
+ {"fullsizecontentview", NSWindowStyleMaskFullSizeContentView, NSWindowClass_window},
+ /* Rounded corners, cannot have a titlebar (overrides titled bit). */
+ {"docmodal", NSWindowStyleMaskDocModalWindow, NSWindowClass_any},
+ /* ============================================
+ * The following bits are only valid for panels.
+ */
+ /* Make the title bar thinner. */
+ {"utility", NSWindowStyleMaskUtilityWindow, NSWindowClass_panel},
+ /* Do not activate the app when the window is activated. */
+ {"nonactivatingpanel", NSWindowStyleMaskNonactivatingPanel, NSWindowClass_panel},
+ /*
+ * Requires utility. Cannot be resizable. Close button is an X; no other buttons.
+ * Cannot be a docmodal.
+ */
+ {"HUDwindow", NSWindowStyleMaskHUDWindow, NSWindowClass_panel},
+ {NULL, 0, NSWindowClass_any}
+};
+
+typedef struct tabbingMode_t {
+ const char *modeName;
+ long modeValue;
+} tabbingMode;
+
+static const tabbingMode tabbingModes[] = {
+ {"auto", NSWindowTabbingModeAutomatic},
+ {"disallowed", NSWindowTabbingModeDisallowed},
+ {"preferred", NSWindowTabbingModePreferred},
+ {NULL, -1}
+};
+
+static const char *const appearanceStrings[] = {
+ "aqua", "auto", "darkaqua", NULL
+};
+enum appearances {
+ APPEARANCE_AQUA, APPEARANCE_AUTO, APPEARANCE_DARKAQUA
+};
+
+static Bool wantsToBeTab(NSWindow *macWindow) {
+ Bool result;
+ switch ([macWindow tabbingMode]) {
+ case NSWindowTabbingModeDisallowed:
+ result = False;
+ break;
+ case NSWindowTabbingModePreferred:
+ result = True;
+ break;
+ case NSWindowTabbingModeAutomatic:
+ result = ([NSWindow userTabbingPreference] ==
+ NSWindowUserTabbingPreferenceAlways);
+ break;
+ default:
+ result = False;
+ break;
+ }
+ return result;
+}
+
+/*
+ * Helper for the tkLayoutChanged methods. Synchronizes Tk's understanding of
+ * the bounds of a contentView with the window's. It is needed because there
+ * are situations when the window manager can change the layout of an NSWindow
+ * without having been requested to do so by Tk. Examples are when a window
+ * goes FullScreen or shows a tab bar. NSWindow methods which involve such
+ * layout changes should be overridden or protected by methods which call this.
+ */
+
+static void syncLayout(NSWindow *macWindow)
+{
+ TkWindow *winPtr = TkMacOSXGetTkWindow(macWindow);
+
+ if (winPtr) {
+ // Using screen coordinates with origin at bottom left.
+ NSRect frameRect = [macWindow frame];
+ // This accounts for the tab bar, if there is one.
+ NSRect contentRect = [macWindow contentRectForFrameRect: frameRect];
+ WmInfo *wmPtr = winPtr->wmInfoPtr;
+
+ // The parent includes the title bar, tab bar and window frame.
+ wmPtr->xInParent = frameRect.origin.x - contentRect.origin.x;
+ wmPtr->yInParent = (frameRect.origin.y + frameRect.size.height -
+ contentRect.origin.y - contentRect.size.height);
+ wmPtr->parentWidth = winPtr->changes.width + frameRect.size.width -
+ contentRect.size.width;
+ wmPtr->parentHeight = winPtr->changes.height + frameRect.size.height -
+ contentRect.size.height;
+ }
+}
+#endif
+
typedef enum {
- WMATT_ALPHA, WMATT_FULLSCREEN, WMATT_MODIFIED, WMATT_NOTIFY,
- WMATT_TITLEPATH, WMATT_TOPMOST, WMATT_TRANSPARENT,
- WMATT_TYPE, _WMATT_LAST_ATTRIBUTE
+ WMATT_ALPHA, WMATT_APPEARANCE, WMATT_BUTTONS, WMATT_FULLSCREEN,
+ WMATT_ISDARK, WMATT_MODIFIED, WMATT_NOTIFY, WMATT_TITLEPATH, WMATT_TOPMOST,
+ WMATT_TRANSPARENT, WMATT_STYLEMASK, WMATT_CLASS, WMATT_TABBINGID,
+ WMATT_TABBINGMODE, WMATT_TYPE, _WMATT_LAST_ATTRIBUTE
} WmAttribute;
static const char *const WmAttributeNames[] = {
- "-alpha", "-fullscreen", "-modified", "-notify",
- "-titlepath", "-topmost", "-transparent",
- "-type", NULL
+ "-alpha", "-appearance", "-buttons", "-fullscreen", "-isdark", "-modified",
+ "-notify", "-titlepath", "-topmost", "-transparent", "-stylemask", "-class",
+ "-tabbingid", "-tabbingmode", "-type", NULL
};
/*
@@ -178,12 +321,12 @@ static int wmTracing = 0;
* of top-level windows.
*/
-static void TopLevelReqProc(ClientData dummy, Tk_Window tkwin);
+static void TopLevelReqProc(void *dummy, Tk_Window tkwin);
static const Tk_GeomMgr wmMgrType = {
"wm", /* name */
TopLevelReqProc, /* requestProc */
- NULL, /* lostSlaveProc */
+ NULL, /* lostContentProc */
};
/*
@@ -193,123 +336,124 @@ static const Tk_GeomMgr wmMgrType = {
static int tkMacOSXWmAttrNotifyVal = 0;
/*
- * Forward declarations for procedures defined in this file:
+ * Declarations of static functions defined in this file:
*/
static NSRect InitialWindowBounds(TkWindow *winPtr,
NSWindow *macWindow);
static int ParseGeometry(Tcl_Interp *interp, char *string,
TkWindow *winPtr);
-static void TopLevelEventProc(ClientData clientData,
+static void TopLevelEventProc(void *clientData,
XEvent *eventPtr);
static void WmStackorderToplevelWrapperMap(TkWindow *winPtr,
Display *display, Tcl_HashTable *table);
-static void UpdateGeometryInfo(ClientData clientData);
+static void UpdateGeometryInfo(void *clientData);
static void UpdateSizeHints(TkWindow *winPtr);
static void UpdateVRootGeometry(WmInfo *wmPtr);
static int WmAspectCmd(Tk_Window tkwin, TkWindow *winPtr,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int WmAttributesCmd(Tk_Window tkwin, TkWindow *winPtr,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int WmClientCmd(Tk_Window tkwin, TkWindow *winPtr,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int WmColormapwindowsCmd(Tk_Window tkwin,
- TkWindow *winPtr, Tcl_Interp *interp, int objc,
+ TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int WmCommandCmd(Tk_Window tkwin, TkWindow *winPtr,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int WmDeiconifyCmd(Tk_Window tkwin, TkWindow *winPtr,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int WmFocusmodelCmd(Tk_Window tkwin, TkWindow *winPtr,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int WmForgetCmd(Tk_Window tkwin, TkWindow *winPtr,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int WmFrameCmd(Tk_Window tkwin, TkWindow *winPtr,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int WmGeometryCmd(Tk_Window tkwin, TkWindow *winPtr,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int WmGridCmd(Tk_Window tkwin, TkWindow *winPtr,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int WmGroupCmd(Tk_Window tkwin, TkWindow *winPtr,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
+ Tcl_Obj *const objv[]);
+static int WmIconbadgeCmd(Tk_Window tkwin, TkWindow *winPtr,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int WmIconbitmapCmd(Tk_Window tkwin, TkWindow *winPtr,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int WmIconifyCmd(Tk_Window tkwin, TkWindow *winPtr,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int WmIconmaskCmd(Tk_Window tkwin, TkWindow *winPtr,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int WmIconnameCmd(Tk_Window tkwin, TkWindow *winPtr,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int WmIconphotoCmd(Tk_Window tkwin, TkWindow *winPtr,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int WmIconpositionCmd(Tk_Window tkwin, TkWindow *winPtr,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int WmIconwindowCmd(Tk_Window tkwin, TkWindow *winPtr,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int WmManageCmd(Tk_Window tkwin, TkWindow *winPtr,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int WmMaxsizeCmd(Tk_Window tkwin, TkWindow *winPtr,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int WmMinsizeCmd(Tk_Window tkwin, TkWindow *winPtr,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int WmOverrideredirectCmd(Tk_Window tkwin,
- TkWindow *winPtr, Tcl_Interp *interp, int objc,
+ TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int WmPositionfromCmd(Tk_Window tkwin, TkWindow *winPtr,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int WmProtocolCmd(Tk_Window tkwin, TkWindow *winPtr,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int WmResizableCmd(Tk_Window tkwin, TkWindow *winPtr,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int WmSizefromCmd(Tk_Window tkwin, TkWindow *winPtr,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int WmStackorderCmd(Tk_Window tkwin, TkWindow *winPtr,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int WmStateCmd(Tk_Window tkwin, TkWindow *winPtr,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int WmTitleCmd(Tk_Window tkwin, TkWindow *winPtr,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int WmTransientCmd(Tk_Window tkwin, TkWindow *winPtr,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int WmWithdrawCmd(Tk_Window tkwin, TkWindow *winPtr,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static void WmUpdateGeom(WmInfo *wmPtr, TkWindow *winPtr);
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[]);
+ Tcl_Size objc, Tcl_Obj *const objv[]);
static int WmWinAppearance(Tcl_Interp *interp, TkWindow *winPtr,
- int objc, Tcl_Obj *const objv[]);
+ Tcl_Size objc, Tcl_Obj *const objv[]);
static void ApplyWindowAttributeFlagChanges(TkWindow *winPtr,
NSWindow *macWindow, UInt64 oldAttributes,
int oldFlags, int create, int initial);
@@ -323,6 +467,90 @@ static void RemapWindows(TkWindow *winPtr,
MacDrawable *parentWin);
static void RemoveTransient(TkWindow *winPtr);
+#if MAC_OS_X_VERSION_MAX_ALLOWED > 101300
+
+/*
+ * Add a window as a tab in the group specified by its tabbingid, or
+ * make it a standalone window if it is the only window with that
+ * tabbingid. Adjust the window size if a tab bar appeared or
+ * disappeared.
+ */
+
+static void placeAsTab(TKWindow *macWindow) {
+ TkWindow *winPtr = NULL, *winPtr2 = NULL;
+ TKWindow *target = NULL, *sibling = NULL;
+ NSString *identifier = [macWindow tabbingIdentifier];
+ if (!wantsToBeTab(macWindow)) {
+ [macWindow moveTabToNewWindow:NSApp];
+ [(TKWindow *)target tkLayoutChanged];
+ return;
+ }
+ for (NSWindow *window in [NSApp windows]) {
+ if (window == macWindow) {
+ continue;
+ }
+ if ([identifier isEqualTo: [window tabbingIdentifier]] &&
+ wantsToBeTab(window)) {
+ target = (TKWindow*) window;
+ syncLayout(target);
+ break;
+ }
+ }
+ syncLayout(macWindow);
+ NSArray<NSWindow *> *tabs = [macWindow tabbedWindows];
+ if ([tabs count] == 2) {
+ sibling = tabs[0] == macWindow ? (TKWindow *)tabs[1] : (TKWindow *)tabs[0];
+ syncLayout(sibling);
+ winPtr2 = TkMacOSXGetTkWindow(sibling);
+ }
+ if (target) {
+ CGFloat winHeight = [macWindow contentRectForFrameRect:
+ [macWindow frame]].size.height;
+ CGFloat winDelta = 0, targetHeight, targetDelta = 0;
+ targetHeight = [target contentRectForFrameRect:
+ [target frame]].size.height;
+ [target addTabbedWindow:macWindow ordered:NSWindowAbove];
+ targetDelta = targetHeight - [target contentRectForFrameRect:
+ [target frame]].size.height;
+ winDelta = winHeight - [target contentRectForFrameRect:
+ [target frame]].size.height;
+ if (winDelta) {
+ winPtr = TkMacOSXGetTkWindow(macWindow);
+ XMoveResizeWindow(winPtr->display, winPtr->window,
+ winPtr->changes.x, winPtr->changes.y,
+ winPtr->changes.width, winPtr->changes.height + winDelta );
+ if (sibling) {
+ winPtr = TkMacOSXGetTkWindow(sibling);
+ XMoveResizeWindow(winPtr->display, winPtr->window,
+ winPtr->changes.x, winPtr->changes.y,
+ winPtr->changes.width, winPtr->changes.height - winDelta );
+ }
+ }
+ if (targetDelta) {
+ winPtr = TkMacOSXGetTkWindow(target);
+ XMoveResizeWindow(winPtr->display, winPtr->window,
+ winPtr->changes.x, winPtr->changes.y,
+ winPtr->changes.width, winPtr->changes.height + targetDelta );
+ }
+ } else {
+ CGFloat height = [macWindow contentRectForFrameRect:
+ [macWindow frame]].size.height;
+ [macWindow moveTabToNewWindow:NSApp];
+ CGFloat delta = height - [macWindow contentRectForFrameRect:
+ [macWindow frame]].size.height;
+ winPtr = TkMacOSXGetTkWindow(macWindow);
+ XMoveResizeWindow(winPtr->display, winPtr->window,
+ winPtr->changes.x, winPtr->changes.y,
+ winPtr->changes.width, winPtr->changes.height + delta);
+ if (winPtr2) {
+ XMoveResizeWindow(winPtr2->display, winPtr2->window,
+ winPtr2->changes.x, winPtr2->changes.y,
+ winPtr2->changes.width, winPtr2->changes.height + delta );
+ }
+ }
+}
+#endif
+
#pragma mark NSWindow(TKWm)
@implementation NSWindow(TKWm)
@@ -349,13 +577,18 @@ static void RemoveTransient(TkWindow *winPtr);
return [self convertRectFromScreen:pointrect].origin;
}
#endif
-
@end
#pragma mark -
@implementation TKPanel: NSPanel
@synthesize tkWindow = _tkWindow;
+
+- (void) tkLayoutChanged
+{
+ syncLayout(self);
+}
+
@end
@implementation TKDrawerWindow: NSWindow
@@ -370,44 +603,12 @@ static void RemoveTransient(TkWindow *winPtr);
@implementation TKWindow(TKWm)
-/*
- * This method synchronizes Tk's understanding of the bounds of a contentView
- * with the window's. It is needed because there are situations when the
- * window manager can change the layout of an NSWindow without having been
- * requested to do so by Tk. Examples are when a window goes FullScreen or
- * shows a tab bar. NSWindow methods which involve such layout changes should
- * be overridden or protected by methods which call this.
- */
-
- (void) tkLayoutChanged
{
- TkWindow *winPtr = TkMacOSXGetTkWindow(self);
-
- if (winPtr) {
- NSRect frameRect;
-
- /*
- * This avoids including the title bar for full screen windows
- * but does include it for normal windows.
- */
-
- if ([self styleMask] & NSFullScreenWindowMask) {
- frameRect = [NSWindow frameRectForContentRect:NSZeroRect
- styleMask:[self styleMask]];
- } else {
- frameRect = [self frameRectForContentRect:NSZeroRect];
- }
-
- WmInfo *wmPtr = winPtr->wmInfoPtr;
-
- wmPtr->xInParent = -frameRect.origin.x;
- wmPtr->yInParent = frameRect.origin.y + frameRect.size.height;
- wmPtr->parentWidth = winPtr->changes.width + frameRect.size.width;
- wmPtr->parentHeight = winPtr->changes.height + frameRect.size.height;
- }
+ syncLayout(self);
}
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101300
- (void)toggleTabBar:(id)sender
{
TkWindow *winPtr = TkMacOSXGetTkWindow(self);
@@ -725,6 +926,8 @@ TkWmNewWindow(
wmPtr->window = nil;
winPtr->wmInfoPtr = wmPtr;
+ // initialize wmPtr->NSWindowSubclass here
+
UpdateVRootGeometry(wmPtr);
/*
@@ -1155,7 +1358,7 @@ TkWmSetClass(
int
Tk_WmObjCmd(
- ClientData clientData, /* Main window associated with interpreter. */
+ void *clientData, /* Main window associated with interpreter. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
@@ -1164,7 +1367,7 @@ Tk_WmObjCmd(
static const char *const optionStrings[] = {
"aspect", "attributes", "client", "colormapwindows",
"command", "deiconify", "focusmodel", "forget",
- "frame", "geometry", "grid", "group",
+ "frame", "geometry", "grid", "group", "iconbadge",
"iconbitmap", "iconify", "iconmask", "iconname",
"iconphoto", "iconposition", "iconwindow",
"manage", "maxsize", "minsize", "overrideredirect",
@@ -1174,7 +1377,7 @@ Tk_WmObjCmd(
enum options {
WMOPT_ASPECT, WMOPT_ATTRIBUTES, WMOPT_CLIENT, WMOPT_COLORMAPWINDOWS,
WMOPT_COMMAND, WMOPT_DEICONIFY, WMOPT_FOCUSMODEL, WMOPT_FORGET,
- WMOPT_FRAME, WMOPT_GEOMETRY, WMOPT_GRID, WMOPT_GROUP,
+ WMOPT_FRAME, WMOPT_GEOMETRY, WMOPT_GRID, WMOPT_GROUP, WMOPT_ICONBADGE,
WMOPT_ICONBITMAP, WMOPT_ICONIFY, WMOPT_ICONMASK, WMOPT_ICONNAME,
WMOPT_ICONPHOTO, WMOPT_ICONPOSITION, WMOPT_ICONWINDOW,
WMOPT_MANAGE, WMOPT_MAXSIZE, WMOPT_MINSIZE, WMOPT_OVERRIDEREDIRECT,
@@ -1182,7 +1385,7 @@ Tk_WmObjCmd(
WMOPT_STACKORDER, WMOPT_STATE, WMOPT_TITLE, WMOPT_TRANSIENT,
WMOPT_WITHDRAW };
int index;
- int length;
+ Tcl_Size length;
char *argv1;
TkWindow *winPtr;
@@ -1210,13 +1413,36 @@ Tk_WmObjCmd(
sizeof(char *), "option", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
-
if (objc < 3) {
goto wrongNumArgs;
}
-
- if (TkGetWindowFromObj(interp, tkwin, objv[2], (Tk_Window *) &winPtr)
- != TCL_OK) {
+ if (index == WMOPT_ATTRIBUTES && objc == 5 &&
+ strcmp(Tcl_GetString(objv[3]), "-class") == 0) {
+ if (TkGetWindowFromObj(NULL, tkwin, objv[2], (Tk_Window *) &winPtr)
+ == TCL_OK) {
+ if (winPtr->wmInfoPtr->window != NULL) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "Cannot change the class after the mac window is created.",-1));
+ Tcl_SetErrorCode(interp, "TK", "CLASS_CHANGE", NULL);
+ return TCL_ERROR;
+ }
+ } else {
+ winPtr = NULL;
+ }
+ } else if (index == WMOPT_ATTRIBUTES && objc == 5 &&
+ strcmp(Tcl_GetString(objv[3]), "-tabbingid") == 0) {
+ if (TkGetWindowFromObj(NULL, tkwin, objv[2], (Tk_Window *) &winPtr)
+ != TCL_OK) {
+ winPtr = NULL;
+ }
+ } else if (index == WMOPT_ATTRIBUTES && objc == 5 &&
+ strcmp(Tcl_GetString(objv[3]), "-tabbingmode") == 0) {
+ if (TkGetWindowFromObj(NULL, tkwin, objv[2], (Tk_Window *) &winPtr)
+ != TCL_OK) {
+ winPtr = NULL;
+ }
+ } else if (TkGetWindowFromObj(interp, tkwin, objv[2], (Tk_Window *) &winPtr)
+ != TCL_OK) {
return TCL_ERROR;
}
if (winPtr && !Tk_IsTopLevel(winPtr)
@@ -1253,6 +1479,8 @@ Tk_WmObjCmd(
return WmGridCmd(tkwin, winPtr, interp, objc, objv);
case WMOPT_GROUP:
return WmGroupCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_ICONBADGE:
+ return WmIconbadgeCmd(tkwin, winPtr, interp, objc, objv);
case WMOPT_ICONBITMAP:
return WmIconbitmapCmd(tkwin, winPtr, interp, objc, objv);
case WMOPT_ICONIFY:
@@ -1321,7 +1549,7 @@ WmAspectCmd(
TCL_UNUSED(Tk_Window), /* Main window of the application. */
TkWindow *winPtr, /* Toplevel to work with */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
WmInfo *wmPtr = winPtr->wmInfoPtr;
@@ -1336,10 +1564,10 @@ WmAspectCmd(
if (wmPtr->sizeHintsFlags & PAspect) {
Tcl_Obj *results[4];
- results[0] = Tcl_NewIntObj(wmPtr->minAspect.x);
- results[1] = Tcl_NewIntObj(wmPtr->minAspect.y);
- results[2] = Tcl_NewIntObj(wmPtr->maxAspect.x);
- results[3] = Tcl_NewIntObj(wmPtr->maxAspect.y);
+ results[0] = Tcl_NewWideIntObj(wmPtr->minAspect.x);
+ results[1] = Tcl_NewWideIntObj(wmPtr->minAspect.y);
+ results[2] = Tcl_NewWideIntObj(wmPtr->maxAspect.x);
+ results[3] = Tcl_NewWideIntObj(wmPtr->maxAspect.y);
Tcl_SetObjResult(interp, Tcl_NewListObj(4, results));
}
return TCL_OK;
@@ -1356,7 +1584,7 @@ WmAspectCmd(
if ((numer1 <= 0) || (denom1 <= 0) || (numer2 <= 0) ||
(denom2 <= 0)) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "aspect number can't be <= 0", -1));
+ "aspect number can't be <= 0", TCL_INDEX_NONE));
Tcl_SetErrorCode(interp, "TK", "WM", "ASPECT", NULL);
return TCL_ERROR;
}
@@ -1396,7 +1624,8 @@ WmSetAttribute(
Tcl_Obj *value) /* New value */
{
WmInfo *wmPtr = winPtr->wmInfoPtr;
- int boolean;
+ int boolValue;
+ NSString *identifier;
switch (attribute) {
case WMATT_ALPHA: {
@@ -1418,11 +1647,63 @@ WmSetAttribute(
[macWindow setAlphaValue:dval];
break;
}
+ case WMATT_APPEARANCE: {
+ int index;
+ if (Tcl_GetIndexFromObjStruct(interp, value, appearanceStrings,
+ sizeof(char *), "appearancename", 0, &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ switch ((enum appearances) index) {
+ case APPEARANCE_AQUA:
+ macWindow.appearance = [NSAppearance appearanceNamed:
+ NSAppearanceNameAqua];
+ break;
+ case APPEARANCE_DARKAQUA:
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
+ if (@available(macOS 10.14, *)) {
+ macWindow.appearance = [NSAppearance appearanceNamed:
+ NSAppearanceNameDarkAqua];
+ }
+#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
+ break;
+ default:
+ macWindow.appearance = nil;
+ }
+ break;
+ }
+ case WMATT_BUTTONS: {
+ windowButtonState state = {0};
+ Tcl_Obj **elements;
+ Tcl_Size nElements, i;
+ if (Tcl_ListObjGetElements(interp, value, &nElements, &elements) == TCL_OK) {
+ int index = 0;
+ for (i = 0; i < nElements; i++) {
+ if (Tcl_GetIndexFromObjStruct(interp, elements[i], buttonNames,
+ sizeof(char *), "window button name", 0, &index) != TCL_OK) {
+ return TCL_ERROR;
+ } else {
+ state.intvalue |= (1 << index);
+ }
+ }
+ } else if (Tcl_GetIntFromObj(interp, value, &state.intvalue) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ NSButton *closer = [macWindow standardWindowButton:
+ NSWindowCloseButton];
+ NSButton *miniaturizer = [macWindow standardWindowButton:
+ NSWindowMiniaturizeButton];
+ NSButton *zoomer = [macWindow standardWindowButton:
+ NSWindowZoomButton];
+ closer.enabled = (state.bits.close != 0);
+ miniaturizer.enabled = (state.bits.miniaturize != 0);
+ zoomer.enabled = (state.bits.zoom != 0);
+ break;
+ }
case WMATT_FULLSCREEN:
- if (Tcl_GetBooleanFromObj(interp, value, &boolean) != TCL_OK) {
+ if (Tcl_GetBooleanFromObj(interp, value, &boolValue) != TCL_OK) {
return TCL_ERROR;
}
- if (boolean != (([macWindow styleMask] & NSFullScreenWindowMask) != 0)) {
+ if (boolValue != (([macWindow styleMask] & NSFullScreenWindowMask) != 0)) {
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
[macWindow toggleFullScreen:macWindow];
#else
@@ -1431,30 +1712,145 @@ WmSetAttribute(
}
break;
case WMATT_MODIFIED:
- if (Tcl_GetBooleanFromObj(interp, value, &boolean) != TCL_OK) {
+ if (Tcl_GetBooleanFromObj(interp, value, &boolValue) != TCL_OK) {
return TCL_ERROR;
}
- if (boolean != [macWindow isDocumentEdited]) {
- [macWindow setDocumentEdited:(BOOL)boolean];
+ if (boolValue != [macWindow isDocumentEdited]) {
+ [macWindow setDocumentEdited:(BOOL)boolValue];
}
break;
case WMATT_NOTIFY:
- if (Tcl_GetBooleanFromObj(interp, value, &boolean) != TCL_OK) {
+ if (Tcl_GetBooleanFromObj(interp, value, &boolValue) != TCL_OK) {
return TCL_ERROR;
}
- if (boolean == !tkMacOSXWmAttrNotifyVal) {
+ if (boolValue == !tkMacOSXWmAttrNotifyVal) {
static NSInteger request = -1;
if (request >= 0) {
[NSApp cancelUserAttentionRequest:request];
request = -1;
}
- if (boolean) {
+ if (boolValue) {
request = [NSApp requestUserAttention:NSCriticalRequest];
}
- tkMacOSXWmAttrNotifyVal = boolean;
+ tkMacOSXWmAttrNotifyVal = boolValue;
}
break;
+ case WMATT_STYLEMASK: {
+ unsigned long styleMaskValue = 0;
+ Tcl_Obj **elements;
+ Tcl_Size nElements, i;
+ if (Tcl_ListObjGetElements(interp, value, &nElements, &elements) == TCL_OK) {
+ int index;
+ for (i = 0; i < nElements; i++) {
+ if (Tcl_GetIndexFromObjStruct(interp, elements[i], styleMaskBits,
+ sizeof(styleMaskBit), "styleMask bit", 0, &index) != TCL_OK) {
+ return TCL_ERROR;
+ } else if (![macWindow isKindOfClass: [NSPanel class]] &&
+ styleMaskBits[index].allowed == NSWindowClass_panel) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "styleMask bit \"%s\" can only be used with an NSPanel",
+ styleMaskBits[index].bitname));
+ Tcl_SetErrorCode(interp, "TK", "INVALID_STYLEMASK_BIT", NULL);
+ return TCL_ERROR;
+ } else {
+ styleMaskValue |= styleMaskBits[index].bitvalue;
+ }
+ /*
+ * Be sure not to change the fullscreen bit.
+ */
+ styleMaskValue |= (NSWindowStyleMaskFullScreen & macWindow.styleMask);
+ }
+ /*
+ * A resizable docmodal NSWindow or NSPanel does not work
+ * correctly. It cannot be resized from the top edge. Other bits,
+ * such as titled are ignored for docmodals. To be safe, we clear
+ * all other bits when the docmodal bit is set.
+ */
+ if (styleMaskValue & NSDocModalWindowMask) {
+ styleMaskValue &= ~NSWindowStyleMaskResizable;
+ }
+ if ([macWindow isKindOfClass: [NSPanel class]]) {
+ /*
+ * We always make NSPanels titled, nonactivating utility windows,
+ * even if these bits are not requested in the command.
+ */
+ if (!(styleMaskValue & NSWindowStyleMaskTitled) ) {
+ styleMaskValue |= NSWindowStyleMaskTitled;
+ styleMaskValue |= NSWindowStyleMaskUtilityWindow;
+ styleMaskValue |= NSWindowStyleMaskNonactivatingPanel;
+ }
+ }
+ if (styleMaskValue & NSWindowStyleMaskFullSizeContentView) {
+ macWindow.titlebarAppearsTransparent = YES;
+ } else {
+ macWindow.titlebarAppearsTransparent = NO;
+ }
+ } else {
+ return TCL_ERROR;
+ }
+ NSRect oldFrame = [macWindow frame];
+#ifdef DEBUG
+ fprintf(stderr, "Current styleMask: %lx\n", [macWindow styleMask]);
+ fprintf(stderr, "Setting styleMask to %lx\n", styleMaskValue);
+#endif
+ macWindow.styleMask = (unsigned long) styleMaskValue;
+ NSRect newFrame = [macWindow frame];
+ int heightDiff = newFrame.size.height - oldFrame.size.height;
+ int newHeight = heightDiff < 0 ? newFrame.size.height :
+ newFrame.size.height - heightDiff;
+ [(TKWindow *)macWindow tkLayoutChanged];
+ if (heightDiff) {
+ //Calling XMoveResizeWindow twice is a hack to force a relayout
+ //of the window.
+ XMoveResizeWindow(winPtr->display, winPtr->window,
+ winPtr->changes.x, winPtr->changes.y,
+ newFrame.size.width, newHeight - 1);
+ XMoveResizeWindow(winPtr->display, winPtr->window,
+ winPtr->changes.x, winPtr->changes.y,
+ newFrame.size.width, newHeight);
+ }
+ break;
+ }
+ case WMATT_TABBINGID: {
+ NSString *oldId = [macWindow tabbingIdentifier];
+ char *valueString;
+ Tcl_Size length;
+ if ([NSApp macOSVersion] < 101300) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "Tabbing identifiers require macOS 10.13", TCL_INDEX_NONE));
+ Tcl_SetErrorCode(interp, "TK", "WM", "TABBINGID", NULL);
+ return TCL_ERROR;
+ }
+ valueString = Tcl_GetStringFromObj(value, &length);
+ identifier = [NSString stringWithUTF8String:valueString];
+ [macWindow setTabbingIdentifier: identifier];
+
+ /*
+ * If the tabbingIdentifier of a tab is changed we move it into
+ * the tab group with that identifier.
+ */
+
+ if ([oldId compare:identifier] != NSOrderedSame) {
+ placeAsTab((TKWindow *)macWindow);
+ }
+ break;
+ }
+ case WMATT_TABBINGMODE: {
+ int index;
+ tabbingMode mode;
+ if (Tcl_GetIndexFromObjStruct(interp, value, tabbingModes,
+ sizeof(tabbingMode), "NSWindow Tabbing Mode", 0, &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ mode = tabbingModes[index];
+ [macWindow setTabbingMode: mode.modeValue];
+ placeAsTab((TKWindow *)macWindow);
+ break;
+ }
+ case WMATT_ISDARK: {
+ break;
+ }
case WMATT_TITLEPATH: {
const char *path = (const char *)Tcl_FSGetNativePath(value);
NSString *filename = @"";
@@ -1466,13 +1862,13 @@ WmSetAttribute(
break;
}
case WMATT_TOPMOST:
- if (Tcl_GetBooleanFromObj(interp, value, &boolean) != TCL_OK) {
+ if (Tcl_GetBooleanFromObj(interp, value, &boolValue) != TCL_OK) {
return TCL_ERROR;
}
- if (boolean != ((wmPtr->flags & WM_TOPMOST) != 0)) {
+ if (boolValue != ((wmPtr->flags & WM_TOPMOST) != 0)) {
int oldFlags = wmPtr->flags;
- if (boolean) {
+ if (boolValue) {
wmPtr->flags |= WM_TOPMOST;
} else {
wmPtr->flags &= ~WM_TOPMOST;
@@ -1482,14 +1878,14 @@ WmSetAttribute(
}
break;
case WMATT_TRANSPARENT:
- if (Tcl_GetBooleanFromObj(interp, value, &boolean) != TCL_OK) {
+ if (Tcl_GetBooleanFromObj(interp, value, &boolValue) != TCL_OK) {
return TCL_ERROR;
}
- if (boolean != ((wmPtr->flags & WM_TRANSPARENT) != 0)) {
+ if (boolValue != ((wmPtr->flags & WM_TRANSPARENT) != 0)) {
UInt64 oldAttributes = wmPtr->attributes;
int oldFlags = wmPtr->flags;
- if (boolean) {
+ if (boolValue) {
wmPtr->flags |= WM_TRANSPARENT;
wmPtr->attributes |= kWindowNoShadowAttribute;
} else {
@@ -1498,12 +1894,14 @@ WmSetAttribute(
}
ApplyWindowAttributeFlagChanges(winPtr, macWindow, oldAttributes,
oldFlags, 1, 0);
- [macWindow setBackgroundColor:boolean ? [NSColor clearColor] : nil];
- [macWindow setOpaque:!boolean];
+ [macWindow setBackgroundColor:boolValue ? [NSColor clearColor] : nil];
+ [macWindow setOpaque:!boolValue];
TkMacOSXInvalidateWindow((MacDrawable *)winPtr->window,
TK_PARENT_WINDOW);
}
break;
+ case WMATT_CLASS:
+ break;
case WMATT_TYPE:
TKLog(@"The type attribute is ignored on macOS.");
break;
@@ -1538,18 +1936,91 @@ WmGetAttribute(
case WMATT_ALPHA:
result = Tcl_NewDoubleObj([macWindow alphaValue]);
break;
+ case WMATT_APPEARANCE: {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101300
+ NSAppearanceName appearance;
+#else
+ NSString *appearance;
+#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 101300
+ const char *resultString = "unrecognized";
+ appearance = macWindow.appearance.name;
+ if (appearance == nil) {
+ resultString = appearanceStrings[APPEARANCE_AUTO];
+ } else if (appearance == NSAppearanceNameAqua) {
+ resultString = appearanceStrings[APPEARANCE_AQUA];
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
+ } else if (@available(macOS 10.14, *)) {
+ if (appearance == NSAppearanceNameDarkAqua) {
+ resultString = appearanceStrings[APPEARANCE_DARKAQUA];
+ }
+#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
+ }
+ result = Tcl_NewStringObj(resultString, TCL_INDEX_NONE);
+ break;
+ }
+ case WMATT_BUTTONS: {
+ result = Tcl_NewListObj(3, NULL);
+ if ([macWindow standardWindowButton:NSWindowCloseButton].enabled) {
+ Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj("close", TCL_INDEX_NONE));
+ }
+ if ([macWindow standardWindowButton:NSWindowMiniaturizeButton].enabled) {
+ Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj("miniaturize", TCL_INDEX_NONE));
+ }
+ if ([macWindow standardWindowButton:NSWindowZoomButton].enabled) {
+ Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj("zoom", TCL_INDEX_NONE));
+ }
+ break;
+ }
+ case WMATT_CLASS:
+ if ([macWindow isKindOfClass:[NSPanel class]]) {
+ result = Tcl_NewStringObj(subclassNames[subclassNSPanel], TCL_INDEX_NONE);
+ } else {
+ result = Tcl_NewStringObj(subclassNames[subclassNSWindow], TCL_INDEX_NONE);
+ }
+ break;
case WMATT_FULLSCREEN:
result = Tcl_NewBooleanObj([macWindow styleMask] & NSFullScreenWindowMask);
break;
+ case WMATT_ISDARK:
+ result = Tcl_NewBooleanObj(TkMacOSXInDarkMode((Tk_Window)winPtr));
+ break;
case WMATT_MODIFIED:
result = Tcl_NewBooleanObj([macWindow isDocumentEdited]);
break;
case WMATT_NOTIFY:
result = Tcl_NewBooleanObj(tkMacOSXWmAttrNotifyVal);
break;
+ case WMATT_STYLEMASK: {
+ unsigned long styleMaskValue = [macWindow styleMask];
+ const styleMaskBit *bit;
+ result = Tcl_NewListObj(9, NULL);
+ for (bit = styleMaskBits; bit->bitname != NULL; bit++) {
+ if (styleMaskValue & bit->bitvalue) {
+ Tcl_ListObjAppendElement(NULL, result,
+ Tcl_NewStringObj(bit->bitname, TCL_INDEX_NONE));
+ }
+ }
+ break;
+ }
+ case WMATT_TABBINGID:
+ result = Tcl_NewStringObj([[macWindow tabbingIdentifier] UTF8String],
+ -1);
+ break;
+ case WMATT_TABBINGMODE: {
+ long mode = [macWindow tabbingMode];
+ const char *name = "unrecognized";
+ for (const tabbingMode *m = tabbingModes; m->modeName != NULL; m++) {
+ if (m->modeValue == mode) {
+ name = m->modeName;
+ break;
+ }
+ }
+ result = Tcl_NewStringObj(name, TCL_INDEX_NONE);
+ break;
+ }
case WMATT_TITLEPATH:
result = Tcl_NewStringObj([[macWindow representedFilename] UTF8String],
- -1);
+ TCL_INDEX_NONE);
break;
case WMATT_TOPMOST:
result = Tcl_NewBooleanObj(wmPtr->flags & WM_TOPMOST);
@@ -1558,7 +2029,7 @@ WmGetAttribute(
result = Tcl_NewBooleanObj(wmPtr->flags & WM_TRANSPARENT);
break;
case WMATT_TYPE:
- result = Tcl_NewStringObj("unsupported", -1);
+ result = Tcl_NewStringObj("unsupported", TCL_INDEX_NONE);
break;
case _WMATT_LAST_ATTRIBUTE:
default:
@@ -1589,13 +2060,64 @@ WmAttributesCmd(
TCL_UNUSED(Tk_Window), /* Main window of the application. */
TkWindow *winPtr, /* Toplevel to work with */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
int attribute = 0;
NSWindow *macWindow;
+ if (winPtr == NULL && objc == 5) {
+ int index, isNew = 0;
+ Tcl_Size length;
- if (winPtr->window == None) {
+ /*
+ * If we are setting an atttribute of a future window, save the value
+ * in a hash table so we can look it up when the window is actually
+ * created.
+ */
+
+ if (strcmp(Tcl_GetString(objv[3]), "-class") == 0) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[4], subclassNames,
+ sizeof(char *), "NSWindow subclass", 0, &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ Tcl_HashEntry *hPtr = Tcl_CreateHashEntry(&pathnameToSubclass,
+ Tcl_GetString(objv[2]), &isNew);
+ if (hPtr) {
+ Tcl_SetHashValue(hPtr, INT2PTR(index));
+ return TCL_OK;
+ }
+ } else if (strcmp(Tcl_GetString(objv[3]), "-tabbingid") == 0) {
+ char *identifier = Tcl_GetStringFromObj(objv[4], &length);
+ char *value = (char *)ckalloc(length + 1);
+ strncpy(value, identifier, length + 1);
+ Tcl_HashEntry *hPtr = Tcl_CreateHashEntry(&pathnameToTabbingId,
+ Tcl_GetString(objv[2]), &isNew);
+ if (hPtr) {
+ Tcl_SetHashValue(hPtr, value);
+ return TCL_OK;
+ }
+ } else if (strcmp(Tcl_GetString(objv[3]), "-tabbingmode") == 0) {
+ long value = NSWindowTabbingModeAutomatic;
+ int modeIndex;
+ if (Tcl_GetIndexFromObjStruct(interp, objv[4], tabbingModes,
+ sizeof(tabbingMode), "NSWindow Tabbing Mode", 0, &modeIndex) == TCL_OK) {
+ value = tabbingModes[modeIndex].modeValue;
+ }
+ Tcl_HashEntry *hPtr = Tcl_CreateHashEntry(&pathnameToTabbingMode,
+ Tcl_GetString(objv[2]), &isNew);
+ if (hPtr) {
+ Tcl_SetHashValue(hPtr, value);
+ return TCL_OK;
+ }
+ }
+ }
+ if (!winPtr) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "Only -class, -tabbingid, or -tabbingmode can be set before the window exists."));
+ Tcl_SetErrorCode(interp, "TK", "NO_WINDOW", NULL);
+ return TCL_ERROR;
+ }
+ if (winPtr && winPtr->window == None) {
Tk_MakeWindowExist((Tk_Window)winPtr);
}
if (!TkMacOSXHostToplevelExists(winPtr)) {
@@ -1608,7 +2130,7 @@ WmAttributesCmd(
for (attribute = 0; attribute < _WMATT_LAST_ATTRIBUTE; ++attribute) {
Tcl_ListObjAppendElement(NULL, result,
- Tcl_NewStringObj(WmAttributeNames[attribute], -1));
+ Tcl_NewStringObj(WmAttributeNames[attribute], TCL_INDEX_NONE));
Tcl_ListObjAppendElement(NULL, result,
WmGetAttribute(winPtr, macWindow, (WmAttribute)attribute));
}
@@ -1620,7 +2142,7 @@ WmAttributesCmd(
}
Tcl_SetObjResult(interp, WmGetAttribute(winPtr, macWindow, (WmAttribute)attribute));
} else if ((objc - 3) % 2 == 0) { /* wm attributes $win -att value... */
- int i;
+ Tcl_Size i;
for (i = 3; i < objc; i += 2) {
if (Tcl_GetIndexFromObjStruct(interp, objv[i], WmAttributeNames,
@@ -1661,12 +2183,12 @@ WmClientCmd(
TCL_UNUSED(Tk_Window), /* Main window of the application. */
TkWindow *winPtr, /* Toplevel to work with */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
WmInfo *wmPtr = winPtr->wmInfoPtr;
char *argv3;
- int length;
+ Tcl_Size length;
if ((objc != 3) && (objc != 4)) {
Tcl_WrongNumArgs(interp, 2, objv, "window ?name?");
@@ -1675,7 +2197,7 @@ WmClientCmd(
if (objc == 3) {
if (wmPtr->clientMachine != NULL) {
Tcl_SetObjResult(interp,
- Tcl_NewStringObj(wmPtr->clientMachine, -1));
+ Tcl_NewStringObj(wmPtr->clientMachine, TCL_INDEX_NONE));
}
return TCL_OK;
}
@@ -1717,12 +2239,12 @@ WmColormapwindowsCmd(
Tk_Window tkwin, /* Main window of the application. */
TkWindow *winPtr, /* Toplevel to work with */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
WmInfo *wmPtr = winPtr->wmInfoPtr;
TkWindow **cmapList, *winPtr2;
- int i, windowObjc;
+ Tcl_Size i, windowObjc;
int gotToplevel = 0;
Tcl_Obj **windowObjv, *resultObj;
@@ -1739,7 +2261,7 @@ WmColormapwindowsCmd(
break;
}
Tcl_ListObjAppendElement(NULL, resultObj,
- TkNewWindowObj((Tk_Window)wmPtr->cmapList[i]));
+ Tk_NewWindowObj((Tk_Window)wmPtr->cmapList[i]));
}
Tcl_SetObjResult(interp, resultObj);
return TCL_OK;
@@ -1807,11 +2329,11 @@ WmCommandCmd(
TCL_UNUSED(Tk_Window), /* Main window of the application. */
TkWindow *winPtr, /* Toplevel to work with */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
WmInfo *wmPtr = winPtr->wmInfoPtr;
- int len;
+ Tcl_Size len;
if ((objc != 3) && (objc != 4)) {
Tcl_WrongNumArgs(interp, 2, objv, "window ?value?");
@@ -1864,7 +2386,7 @@ WmDeiconifyCmd(
TCL_UNUSED(Tk_Window), /* Main window of the application. */
TkWindow *winPtr, /* Toplevel to work with */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
WmInfo *wmPtr = winPtr->wmInfoPtr;
@@ -1944,7 +2466,7 @@ WmFocusmodelCmd(
TCL_UNUSED(Tk_Window), /* Main window of the application. */
TkWindow *winPtr, /* Toplevel to work with */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
WmInfo *wmPtr = winPtr->wmInfoPtr;
@@ -1960,7 +2482,7 @@ WmFocusmodelCmd(
}
if (objc == 3) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
- wmPtr->hints.input ? "passive" : "active", -1));
+ wmPtr->hints.input ? "passive" : "active", TCL_INDEX_NONE));
return TCL_OK;
}
@@ -1998,7 +2520,7 @@ WmForgetCmd(
TCL_UNUSED(Tk_Window), /* Main window of the application. */
TkWindow *winPtr, /* Toplevel or Frame to work with */
TCL_UNUSED(Tcl_Interp *), /* Current interpreter. */
- TCL_UNUSED(int), /* Number of arguments. */
+ TCL_UNUSED(Tcl_Size), /* Number of arguments. */
TCL_UNUSED(Tcl_Obj *const *)) /* Argument objects. */
{
Tk_Window frameWin = (Tk_Window)winPtr;
@@ -2064,7 +2586,7 @@ WmFrameCmd(
TCL_UNUSED(Tk_Window), /* Main window of the application. */
TkWindow *winPtr, /* Toplevel to work with */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
WmInfo *wmPtr = winPtr->wmInfoPtr;
@@ -2080,7 +2602,7 @@ WmFrameCmd(
window = Tk_WindowId((Tk_Window)winPtr);
}
snprintf(buf, sizeof(buf), "0x%" TCL_Z_MODIFIER "x", (size_t)window);
- Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, TCL_INDEX_NONE));
return TCL_OK;
}
@@ -2106,7 +2628,7 @@ WmGeometryCmd(
TCL_UNUSED(Tk_Window), /* Main window of the application. */
TkWindow *winPtr, /* Toplevel to work with */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
WmInfo *wmPtr = winPtr->wmInfoPtr;
@@ -2177,7 +2699,7 @@ WmGridCmd(
TCL_UNUSED(Tk_Window), /* Main window of the application. */
TkWindow *winPtr, /* Toplevel to work with */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
WmInfo *wmPtr = winPtr->wmInfoPtr;
@@ -2193,10 +2715,10 @@ WmGridCmd(
if (wmPtr->sizeHintsFlags & PBaseSize) {
Tcl_Obj *results[4];
- results[0] = Tcl_NewIntObj(wmPtr->reqGridWidth);
- results[1] = Tcl_NewIntObj(wmPtr->reqGridHeight);
- results[2] = Tcl_NewIntObj(wmPtr->widthInc);
- results[3] = Tcl_NewIntObj(wmPtr->heightInc);
+ results[0] = Tcl_NewWideIntObj(wmPtr->reqGridWidth);
+ results[1] = Tcl_NewWideIntObj(wmPtr->reqGridHeight);
+ results[2] = Tcl_NewWideIntObj(wmPtr->widthInc);
+ results[3] = Tcl_NewWideIntObj(wmPtr->heightInc);
Tcl_SetObjResult(interp, Tcl_NewListObj(4, results));
}
return TCL_OK;
@@ -2244,7 +2766,7 @@ WmGridCmd(
return TCL_OK;
error:
- Tcl_SetObjResult(interp, Tcl_NewStringObj(errorMsg, -1));
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(errorMsg, TCL_INDEX_NONE));
Tcl_SetErrorCode(interp, "TK", "WM", "GRID", NULL);
return TCL_ERROR;
}
@@ -2271,13 +2793,13 @@ WmGroupCmd(
Tk_Window tkwin, /* Main window of the application. */
TkWindow *winPtr, /* Toplevel to work with */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
WmInfo *wmPtr = winPtr->wmInfoPtr;
Tk_Window tkwin2;
char *argv3;
- int length;
+ Tcl_Size length;
if ((objc != 3) && (objc != 4)) {
Tcl_WrongNumArgs(interp, 2, objv, "window ?pathName?");
@@ -2285,7 +2807,7 @@ WmGroupCmd(
}
if (objc == 3) {
if (wmPtr->hints.flags & WindowGroupHint) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(wmPtr->leaderName, -1));
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(wmPtr->leaderName, TCL_INDEX_NONE));
}
return TCL_OK;
}
@@ -2313,6 +2835,74 @@ WmGroupCmd(
return TCL_OK;
}
+ /*----------------------------------------------------------------------
+ *
+ * WmIconbadgeCmd --
+ *
+ * This procedure is invoked to process the "wm iconbadge" Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WmIconbadgeCmd(
+ TCL_UNUSED(Tk_Window), /* Main window of the application. */
+ TkWindow *winPtr, /* Toplevel to work with */
+ Tcl_Interp *interp, /* Current interpreter. */
+ Tcl_Size objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
+ (void) winPtr;
+ NSString *label;
+
+ if (objc < 4) {
+ Tcl_WrongNumArgs(interp, 2, objv,"window badge");
+ return TCL_ERROR;
+ }
+
+ label = [NSString stringWithUTF8String:Tcl_GetString(objv[3])];
+
+ int number = [label intValue];
+ NSDockTile *dockicon = [NSApp dockTile];
+
+ /*
+ * First, check that the label is not a decimal. If it is,
+ * return an error.
+ */
+
+ if ([label containsString:@"."]) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't use \"%s\" as icon badge", Tcl_GetString(objv[3])));
+ return TCL_ERROR;
+ }
+
+ /*
+ * Next, check that label is an int, empty string, or exclamation
+ * point. If so, set the icon badge on the Dock icon. Otherwise,
+ * return an error.
+ */
+
+ NSArray *array = @[@"", @"!"];
+ if ([array containsObject: label]) {
+ [dockicon setBadgeLabel:label];
+ } else if (number > 0) {
+ NSString *str = [@(number) stringValue];
+ [dockicon setBadgeLabel:str];
+ } else {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't use \"%s\" as icon badge", Tcl_GetString(objv[3])));
+ return TCL_ERROR;
+ }
+ return TCL_OK;
+}
+
/*
*----------------------------------------------------------------------
*
@@ -2335,13 +2925,13 @@ WmIconbitmapCmd(
TCL_UNUSED(Tk_Window), /* Main window of the application. */
TkWindow *winPtr, /* Toplevel to work with */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
WmInfo *wmPtr = winPtr->wmInfoPtr;
Pixmap pixmap;
char *str;
- int len;
+ Tcl_Size len;
if ((objc != 3) && (objc != 4)) {
Tcl_WrongNumArgs(interp, 2, objv, "window ?bitmap?");
@@ -2404,7 +2994,7 @@ WmIconifyCmd(
TCL_UNUSED(Tk_Window), /* Main window of the application. */
TkWindow *winPtr, /* Toplevel to work with */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
WmInfo *wmPtr = winPtr->wmInfoPtr;
@@ -2427,13 +3017,13 @@ WmIconifyCmd(
return TCL_ERROR;
} else if (wmPtr->iconFor != NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "can't iconify %s: it is an icon for %s",
+ "can't iconify \"%s\": it is an icon for \"%s\"",
winPtr->pathName, Tk_PathName(wmPtr->iconFor)));
Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "ICON", NULL);
return TCL_ERROR;
} else if (winPtr->flags & TK_EMBEDDED) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "can't iconify %s: it is an embedded window",
+ "can't iconify \"%s\": it is an embedded window",
winPtr->pathName));
Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "EMBEDDED", NULL);
return TCL_ERROR;
@@ -2485,7 +3075,7 @@ WmIconmaskCmd(
Tk_Window tkwin, /* Main window of the application. */
TkWindow *winPtr, /* Toplevel to work with */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
WmInfo *wmPtr = winPtr->wmInfoPtr;
@@ -2545,12 +3135,12 @@ WmIconnameCmd(
TCL_UNUSED(Tk_Window), /* Main window of the application. */
TkWindow *winPtr, /* Toplevel to work with */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
WmInfo *wmPtr = winPtr->wmInfoPtr;
const char *argv3;
- int length;
+ Tcl_Size length;
if (objc > 4) {
Tcl_WrongNumArgs(interp, 2, objv, "window ?newName?");
@@ -2558,7 +3148,7 @@ WmIconnameCmd(
}
if (objc == 3) {
if (wmPtr->iconName != NULL) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(wmPtr->iconName, -1));
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(wmPtr->iconName, TCL_INDEX_NONE));
}
return TCL_OK;
}
@@ -2598,7 +3188,7 @@ WmIconphotoCmd(
Tk_Window tkwin, /* Main window of the application. */
TkWindow *winPtr, /* Toplevel to work with */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
Tk_Image tk_icon;
@@ -2686,7 +3276,7 @@ WmIconpositionCmd(
TCL_UNUSED(Tk_Window), /* Main window of the application. */
TkWindow *winPtr, /* Toplevel to work with */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
WmInfo *wmPtr = winPtr->wmInfoPtr;
@@ -2701,8 +3291,8 @@ WmIconpositionCmd(
if (wmPtr->hints.flags & IconPositionHint) {
Tcl_Obj *results[2];
- results[0] = Tcl_NewIntObj(wmPtr->hints.icon_x);
- results[1] = Tcl_NewIntObj(wmPtr->hints.icon_y);
+ results[0] = Tcl_NewWideIntObj(wmPtr->hints.icon_x);
+ results[1] = Tcl_NewWideIntObj(wmPtr->hints.icon_y);
Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
}
return TCL_OK;
@@ -2744,7 +3334,7 @@ WmIconwindowCmd(
Tk_Window tkwin, /* Main window of the application. */
TkWindow *winPtr, /* Toplevel to work with */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
WmInfo *wmPtr = winPtr->wmInfoPtr;
@@ -2758,7 +3348,7 @@ WmIconwindowCmd(
if (objc == 3) {
if (wmPtr->icon != NULL) {
- Tcl_SetObjResult(interp, TkNewWindowObj(wmPtr->icon));
+ Tcl_SetObjResult(interp, Tk_NewWindowObj(wmPtr->icon));
}
return TCL_OK;
}
@@ -2847,7 +3437,7 @@ WmManageCmd(
TCL_UNUSED(Tk_Window), /* Main window of the application. */
TkWindow *winPtr, /* Toplevel or Frame to work with */
Tcl_Interp *interp, /* Current interpreter. */
- TCL_UNUSED(int), /* Number of arguments. */
+ TCL_UNUSED(Tcl_Size), /* Number of arguments. */
TCL_UNUSED(Tcl_Obj *const *)) /* Argument objects. */
{
Tk_Window frameWin = (Tk_Window)winPtr;
@@ -2920,10 +3510,10 @@ WmManageCmd(
static int
WmMaxsizeCmd(
- TCL_UNUSED(Tk_Window), /* Main window of the application. */
+ Tk_Window tkwin, /* Main window of the application. */
TkWindow *winPtr, /* Toplevel to work with */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
WmInfo *wmPtr = winPtr->wmInfoPtr;
@@ -2938,14 +3528,14 @@ WmMaxsizeCmd(
Tcl_Obj *results[2];
GetMaxSize(winPtr, &width, &height);
- results[0] = Tcl_NewIntObj(width);
- results[1] = Tcl_NewIntObj(height);
+ results[0] = Tcl_NewWideIntObj(width);
+ results[1] = Tcl_NewWideIntObj(height);
Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
return TCL_OK;
}
- if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK)
- || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) {
+ if ((Tk_GetPixelsFromObj(interp, tkwin, objv[3], &width) != TCL_OK)
+ || (Tk_GetPixelsFromObj(interp, tkwin, objv[4], &height) != TCL_OK)) {
return TCL_ERROR;
}
wmPtr->maxWidth = width;
@@ -2974,10 +3564,10 @@ WmMaxsizeCmd(
static int
WmMinsizeCmd(
- TCL_UNUSED(Tk_Window), /* Main window of the application. */
+ Tk_Window tkwin, /* Main window of the application. */
TkWindow *winPtr, /* Toplevel to work with */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
WmInfo *wmPtr = winPtr->wmInfoPtr;
@@ -2992,14 +3582,14 @@ WmMinsizeCmd(
Tcl_Obj *results[2];
GetMinSize(winPtr, &width, &height);
- results[0] = Tcl_NewIntObj(width);
- results[1] = Tcl_NewIntObj(height);
+ results[0] = Tcl_NewWideIntObj(width);
+ results[1] = Tcl_NewWideIntObj(height);
Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
return TCL_OK;
}
- if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK)
- || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) {
+ if ((Tk_GetPixelsFromObj(interp, tkwin, objv[3], &width) != TCL_OK)
+ || (Tk_GetPixelsFromObj(interp, tkwin, objv[4], &height) != TCL_OK)) {
return TCL_ERROR;
}
wmPtr->minWidth = width;
@@ -3028,13 +3618,13 @@ WmMinsizeCmd(
static int
WmOverrideredirectCmd(
- TCL_UNUSED(Tk_Window), /* Main window of the application. */
+ TCL_UNUSED(Tk_Window), /* Main window of the application. */
TkWindow *winPtr, /* Toplevel to work with */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
- int flag;
+ Bool boolValue;
XSetWindowAttributes atts;
TKWindow *win = (TKWindow *)TkMacOSXGetNSWindowForDrawable(winPtr->window);
@@ -3049,12 +3639,20 @@ WmOverrideredirectCmd(
return TCL_OK;
}
- if (Tcl_GetBooleanFromObj(interp, objv[3], &flag) != TCL_OK) {
+ if (Tcl_GetBooleanFromObj(interp, objv[3], &boolValue) != TCL_OK) {
return TCL_ERROR;
}
- atts.override_redirect = flag ? True : False;
+ atts.override_redirect = boolValue;
Tk_ChangeWindowAttributes((Tk_Window)winPtr, CWOverrideRedirect, &atts);
- ApplyContainerOverrideChanges(winPtr, win);
+ if ([NSApp macOSVersion] >= 101300) {
+ if (boolValue) {
+ win.styleMask |= NSWindowStyleMaskDocModalWindow;
+ } else {
+ win.styleMask &= ~NSWindowStyleMaskDocModalWindow;
+ }
+ } else {
+ ApplyContainerOverrideChanges(winPtr, win);
+ }
return TCL_OK;
}
@@ -3080,7 +3678,7 @@ WmPositionfromCmd(
TCL_UNUSED(Tk_Window), /* Main window of the application. */
TkWindow *winPtr, /* Toplevel to work with */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
WmInfo *wmPtr = winPtr->wmInfoPtr;
@@ -3097,9 +3695,9 @@ WmPositionfromCmd(
if (objc == 3) {
if (wmPtr->sizeHintsFlags & USPosition) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj("user", -1));
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("user", TCL_INDEX_NONE));
} else if (wmPtr->sizeHintsFlags & PPosition) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj("program", -1));
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("program", TCL_INDEX_NONE));
}
return TCL_OK;
}
@@ -3146,14 +3744,14 @@ WmProtocolCmd(
TCL_UNUSED(Tk_Window), /* Main window of the application. */
TkWindow *winPtr, /* Toplevel to work with */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
WmInfo *wmPtr = winPtr->wmInfoPtr;
ProtocolHandler *protPtr, *prevPtr;
Atom protocol;
char *cmd;
- int cmdLength;
+ Tcl_Size cmdLength;
Tcl_Obj *resultObj;
if ((objc < 3) || (objc > 5)) {
@@ -3186,7 +3784,7 @@ WmProtocolCmd(
protPtr = protPtr->nextPtr) {
if (protPtr->protocol == protocol) {
Tcl_SetObjResult(interp,
- Tcl_NewStringObj(protPtr->command, -1));
+ Tcl_NewStringObj(protPtr->command, TCL_INDEX_NONE));
return TCL_OK;
}
}
@@ -3247,7 +3845,7 @@ WmResizableCmd(
TCL_UNUSED(Tk_Window), /* Main window of the application. */
TkWindow *winPtr, /* Toplevel to work with */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
WmInfo *wmPtr = winPtr->wmInfoPtr;
@@ -3324,7 +3922,7 @@ WmSizefromCmd(
TCL_UNUSED(Tk_Window), /* Main window of the application. */
TkWindow *winPtr, /* Toplevel to work with */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
WmInfo *wmPtr = winPtr->wmInfoPtr;
@@ -3341,9 +3939,9 @@ WmSizefromCmd(
if (objc == 3) {
if (wmPtr->sizeHintsFlags & USSize) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj("user", -1));
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("user", TCL_INDEX_NONE));
} else if (wmPtr->sizeHintsFlags & PSize) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj("program", -1));
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("program", TCL_INDEX_NONE));
}
return TCL_OK;
}
@@ -3390,7 +3988,7 @@ WmStackorderCmd(
Tk_Window tkwin, /* Main window of the application. */
TkWindow *winPtr, /* Toplevel to work with */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
TkWindow **windows, **windowPtr;
@@ -3414,7 +4012,7 @@ WmStackorderCmd(
resultObj = Tcl_NewObj();
for (windowPtr = windows; *windowPtr ; windowPtr++) {
Tcl_ListObjAppendElement(NULL, resultObj,
- TkNewWindowObj((Tk_Window)*windowPtr));
+ Tk_NewWindowObj((Tk_Window)*windowPtr));
}
Tcl_SetObjResult(interp, resultObj);
ckfree(windows);
@@ -3459,7 +4057,7 @@ WmStackorderCmd(
windows = TkWmStackorderToplevel(winPtr->mainPtr->winPtr);
if (windows == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "TkWmStackorderToplevel failed", -1));
+ "TkWmStackorderToplevel failed", TCL_INDEX_NONE));
Tcl_SetErrorCode(interp, "TK", "WM", "STACK", "FAIL", NULL);
return TCL_ERROR;
}
@@ -3516,14 +4114,14 @@ WmStateCmd(
TCL_UNUSED(Tk_Window), /* Main window of the application. */
TkWindow *winPtr, /* Toplevel to work with */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
WmInfo *wmPtr = winPtr->wmInfoPtr;
static const char *const optionStrings[] = {
- "normal", "iconic", "withdrawn", "zoomed", NULL };
+ "iconic", "normal", "withdrawn", "zoomed", NULL };
enum options {
- OPT_NORMAL, OPT_ICONIC, OPT_WITHDRAWN, OPT_ZOOMED };
+ OPT_ICONIC, OPT_NORMAL, OPT_WITHDRAWN, OPT_ZOOMED };
int index;
if ((objc < 3) || (objc > 4)) {
@@ -3534,14 +4132,14 @@ WmStateCmd(
if (objc == 4) {
if (wmPtr->iconFor != NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "can't change state of %s: it is an icon for %s",
+ "can't change state of \"%s\": it is an icon for \"%s\"",
Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor)));
Tcl_SetErrorCode(interp, "TK", "WM", "STATE", "ICON", NULL);
return TCL_ERROR;
}
if (winPtr->flags & TK_EMBEDDED) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "can't change state of %s: it is an embedded window",
+ "can't change state of \"%s\": it is an embedded window",
winPtr->pathName));
Tcl_SetErrorCode(interp, "TK", "WM", "STATE", "EMBEDDED", NULL);
return TCL_ERROR;
@@ -3589,7 +4187,7 @@ WmStateCmd(
break;
}
} else if (wmPtr->iconFor != NULL) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj("icon", -1));
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("icon", TCL_INDEX_NONE));
} else {
if (wmPtr->hints.initial_state == NormalState ||
wmPtr->hints.initial_state == ZoomState) {
@@ -3598,16 +4196,16 @@ WmStateCmd(
}
switch (wmPtr->hints.initial_state) {
case NormalState:
- Tcl_SetObjResult(interp, Tcl_NewStringObj("normal", -1));
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("normal", TCL_INDEX_NONE));
break;
case IconicState:
- Tcl_SetObjResult(interp, Tcl_NewStringObj("iconic", -1));
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("iconic", TCL_INDEX_NONE));
break;
case WithdrawnState:
- Tcl_SetObjResult(interp, Tcl_NewStringObj("withdrawn", -1));
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("withdrawn", TCL_INDEX_NONE));
break;
case ZoomState:
- Tcl_SetObjResult(interp, Tcl_NewStringObj("zoomed", -1));
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("zoomed", TCL_INDEX_NONE));
break;
}
}
@@ -3636,12 +4234,12 @@ WmTitleCmd(
TCL_UNUSED(Tk_Window), /* Main window of the application. */
TkWindow *winPtr, /* Toplevel to work with */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
WmInfo *wmPtr = winPtr->wmInfoPtr;
char *argv3;
- int length;
+ Tcl_Size length;
if (objc > 4) {
Tcl_WrongNumArgs(interp, 2, objv, "window ?newTitle?");
@@ -3650,7 +4248,7 @@ WmTitleCmd(
if (objc == 3) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
- wmPtr->titleUid ? wmPtr->titleUid : winPtr->nameUid, -1));
+ wmPtr->titleUid ? wmPtr->titleUid : winPtr->nameUid, TCL_INDEX_NONE));
return TCL_OK;
}
@@ -3684,7 +4282,7 @@ WmTransientCmd(
Tk_Window tkwin, /* Main window of the application. */
TkWindow *winPtr, /* Toplevel to work with */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
WmInfo *wmPtr = winPtr->wmInfoPtr;
@@ -3694,13 +4292,13 @@ WmTransientCmd(
Transient *transient;
if ((objc != 3) && (objc != 4)) {
- Tcl_WrongNumArgs(interp, 2, objv, "window ?master?");
+ Tcl_WrongNumArgs(interp, 2, objv, "window ?window?");
return TCL_ERROR;
}
if (objc == 3) {
if (wmPtr->container != NULL) {
Tcl_SetObjResult(interp,
- Tcl_NewStringObj(Tk_PathName(wmPtr->container), -1));
+ Tcl_NewStringObj(Tk_PathName(wmPtr->container), TCL_INDEX_NONE));
}
return TCL_OK;
}
@@ -3737,7 +4335,7 @@ WmTransientCmd(
if (wmPtr2 != NULL && wmPtr2->iconFor != NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "can't make \"%s\" a master: it is an icon for %s",
+ "can't make \"%s\" a container: it is an icon for %s",
Tcl_GetString(objv[3]), Tk_PathName(wmPtr2->iconFor)));
Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "ICON", NULL);
return TCL_ERROR;
@@ -3747,7 +4345,7 @@ WmTransientCmd(
w = (TkWindow *)w->wmInfoPtr->container) {
if (w == winPtr) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "setting \"%s\" as master creates a transient/master cycle",
+ "can't set \"%s\" as container: would cause management loop",
Tk_PathName(containerPtr)));
Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "SELF", NULL);
return TCL_ERROR;
@@ -3865,7 +4463,7 @@ WmWithdrawCmd(
TCL_UNUSED(Tk_Window), /* Main window of the application. */
TkWindow *winPtr, /* Toplevel to work with */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
WmInfo *wmPtr = winPtr->wmInfoPtr;
@@ -4101,7 +4699,7 @@ Tk_UnsetGrid(
static void
TopLevelEventProc(
- ClientData clientData, /* Window for which event occurred. */
+ void *clientData, /* Window for which event occurred. */
XEvent *eventPtr) /* Event that just happened. */
{
TkWindow *winPtr = (TkWindow *)clientData;
@@ -4188,7 +4786,7 @@ TopLevelReqProc(
static void
UpdateGeometryInfo(
- ClientData clientData) /* Pointer to the window's record. */
+ void *clientData) /* Pointer to the window's record. */
{
TkWindow *winPtr = (TkWindow *)clientData;
WmInfo *wmPtr = winPtr->wmInfoPtr;
@@ -4317,7 +4915,7 @@ UpdateGeometryInfo(
*/
if (Tk_IsEmbedded(winPtr)) {
- TkWindow *contWinPtr = TkpGetOtherWindow(winPtr);
+ Tk_Window contWinPtr = Tk_GetOtherWindow((Tk_Window)winPtr);
/*
* TODO: Here we should handle out of process embedding.
@@ -4334,7 +4932,7 @@ UpdateGeometryInfo(
wmPtr->x = wmPtr->y = 0;
wmPtr->flags &= ~(WM_NEGATIVE_X|WM_NEGATIVE_Y);
- Tk_GeometryRequest((Tk_Window)contWinPtr, width, height);
+ Tk_GeometryRequest(contWinPtr, width, height);
}
return;
}
@@ -4607,29 +5205,8 @@ Tk_GetRootCoords(
break;
}
- otherPtr = TkpGetOtherWindow(winPtr);
+ otherPtr = (TkWindow *)Tk_GetOtherWindow((Tk_Window)winPtr);
if (otherPtr == NULL) {
- if (tkMacOSXEmbedHandler->getOffsetProc != NULL) {
- Point theOffset;
-
- /*
- * We do not require that the changes.x & changes.y for a
- * non-Tk container window be kept up to date. So we
- * first subtract off the possibly bogus values that have
- * been added on at the top of this pass through the
- * loop, and then call out to the getOffsetProc to give
- * us the correct offset.
- */
-
- x -= winPtr->changes.x + winPtr->changes.border_width;
- y -= winPtr->changes.y + winPtr->changes.border_width;
-
- tkMacOSXEmbedHandler->getOffsetProc((Tk_Window)winPtr,
- &theOffset);
-
- x += theOffset.h;
- y += theOffset.v;
- }
break;
}
@@ -4711,7 +5288,7 @@ Tk_CoordsToWindow(
*/
if (Tk_IsContainer(winPtr)) {
- childPtr = TkpGetOtherWindow(winPtr);
+ childPtr = (TkWindow *)Tk_GetOtherWindow((Tk_Window)winPtr);
if (childPtr != NULL) {
if (Tk_IsMapped(childPtr)) {
tmpx = x - childPtr->changes.x;
@@ -4805,7 +5382,7 @@ Tk_TopCoordsToWindow(
*/
if (Tk_IsContainer(winPtr)) {
- childPtr = TkpGetOtherWindow(winPtr);
+ childPtr = (TkWindow *)Tk_GetOtherWindow((Tk_Window)winPtr);
if (childPtr != NULL) {
if (Tk_IsMapped(childPtr) &&
x > childPtr->changes.x &&
@@ -5424,7 +6001,7 @@ TkSetWMName(
return;
}
- NSString *title = [[TKNSString alloc] initWithTclUtfBytes:titleUid length:-1];
+ NSString *title = [[TKNSString alloc] initWithTclUtfBytes:titleUid length:TCL_INDEX_NONE];
[TkMacOSXGetNSWindowForDrawable(winPtr->window) setTitle:title];
[title release];
}
@@ -5617,16 +6194,16 @@ TkMacOSXZoomToplevel(
int
TkUnsupported1ObjCmd(
- ClientData clientData, /* Main window associated with interpreter. */
+ void *clientData, /* Main window associated with interpreter. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
static const char *const subcmds[] = {
- "style", "tabbingid", "appearance", "isdark", NULL
+ "appearance", "isdark", "style", NULL
};
enum SubCmds {
- TKMWS_STYLE, TKMWS_TABID, TKMWS_APPEARANCE, TKMWS_ISDARK
+ TKMWS_APPEARANCE, TKMWS_ISDARK, TKMWS_STYLE
};
Tk_Window tkwin = (Tk_Window)clientData;
TkWindow *winPtr;
@@ -5660,22 +6237,10 @@ TkUnsupported1ObjCmd(
return TCL_ERROR;
}
return WmWinStyle(interp, winPtr, objc, objv);
- case TKMWS_TABID:
- if ([NSApp macOSVersion] < 101200) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "Tabbing identifiers did not exist until OSX 10.12.", -1));
- Tcl_SetErrorCode(interp, "TK", "WINDOWSTYLE", "TABBINGID", NULL);
- return TCL_ERROR;
- }
- if ((objc < 3) || (objc > 4)) {
- Tcl_WrongNumArgs(interp, 2, objv, "window ?newid?");
- return TCL_ERROR;
- }
- return WmWinTabbingId(interp, winPtr, objc, objv);
case TKMWS_APPEARANCE:
if ([NSApp macOSVersion] < 100900) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "Window appearances did not exist until OSX 10.9.", -1));
+ "Window appearances did not exist until OSX 10.9.", TCL_INDEX_NONE));
Tcl_SetErrorCode(interp, "TK", "WINDOWSTYLE", "APPEARANCE", NULL);
return TCL_ERROR;
}
@@ -5726,7 +6291,7 @@ static int
WmWinStyle(
Tcl_Interp *interp, /* Current interpreter. */
TkWindow *winPtr, /* Window to be manipulated. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj * const objv[]) /* Argument objects. */
{
struct StrIntMap {
@@ -5798,7 +6363,7 @@ WmWinStyle(
};
int index;
- int i;
+ Tcl_Size i;
WmInfo *wmPtr = winPtr->wmInfoPtr;
if (objc == 3) {
@@ -5807,7 +6372,7 @@ WmWinStyle(
for (i = 0; classMap[i].strValue != NULL; i++) {
if (wmPtr->macClass == classMap[i].intValue) {
- newResult = Tcl_NewStringObj(classMap[i].strValue, -1);
+ newResult = Tcl_NewStringObj(classMap[i].strValue, TCL_INDEX_NONE);
break;
}
}
@@ -5832,13 +6397,13 @@ WmWinStyle(
for (i = 0; attrMap[i].strValue != NULL; i++) {
if (attributes & attrMap[i].intValue) {
Tcl_ListObjAppendElement(NULL, attributeList,
- Tcl_NewStringObj(attrMap[i].strValue, -1));
+ Tcl_NewStringObj(attrMap[i].strValue, TCL_INDEX_NONE));
}
}
Tcl_ListObjAppendElement(NULL, newResult, attributeList);
Tcl_SetObjResult(interp, newResult);
} else {
- int attrObjc;
+ Tcl_Size attrObjc;
Tcl_Obj **attrObjv = NULL;
WindowClass macClass;
UInt64 oldAttributes = wmPtr->attributes;
@@ -5891,87 +6456,6 @@ WmWinStyle(
/*
*----------------------------------------------------------------------
*
- * WmWinTabbingId --
- *
- * This procedure is invoked to process the
- * "::tk::unsupported::MacWindowStyle tabbingid" subcommand. The command
- * allows you to get or set the tabbingIdentifier for the NSWindow
- * associated with a Tk Window. The syntax is:
- *
- * tk::unsupported::MacWindowStyle tabbingid window ?newId?
- *
- * Results:
- * Returns the tabbingIdentifier of the window prior to calling this
- * function. If the optional newId argument is omitted, the window's
- * tabbingIdentifier is not changed.
- *
- * Side effects:
- * Windows may only be grouped together as tabs if they all have the same
- * tabbingIdentifier. In particular, by giving a window a unique
- * tabbingIdentifier one can prevent it from becoming a tab in any other
- * window. Changing the tabbingIdentifier of a window which is already
- * a tab causes it to become a separate window.
- *
- *----------------------------------------------------------------------
- */
-
-static int
-WmWinTabbingId(
- 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 < 101200
- (void) interp;
- (void) winPtr;
- (void) objc;
- (void) objv;
- return TCL_OK;
-#else
- Tcl_Obj *result = NULL;
- NSString *idString;
- NSWindow *win = TkMacOSXGetNSWindowForDrawable(winPtr->window);
- if (win) {
- idString = win.tabbingIdentifier;
- result = Tcl_NewStringObj(idString.UTF8String, [idString length]);
- }
- if (result == NULL) {
- NSLog(@"Failed to read tabbing identifier; try calling update idletasks"
- " before getting/setting the tabbing identifier of the window.");
- return TCL_OK;
- }
- Tcl_SetObjResult(interp, result);
- if (objc == 3) {
- return TCL_OK;
- } else if (objc == 4) {
- int len;
- char *newId = Tcl_GetStringFromObj(objv[3], &len);
- NSString *newIdString = [NSString stringWithUTF8String:newId];
- [win setTabbingIdentifier: newIdString];
-
- /*
- * If the tabbingIdentifier of a tab is changed we also turn it into a
- * separate window so we don't violate the rule that all tabs in the
- * same frame must have the same tabbingIdentifier.
- */
-
- if ([idString compare:newIdString] != NSOrderedSame
-#if MAC_OS_X_VERSION_MIN_REQUIRED > 101200
- && [win tab]
-#endif
- ) {
- [win moveTabToNewWindow:nil];
- }
- return TCL_OK;
- }
- return TCL_ERROR;
-#endif
-}
-
-/*
- *----------------------------------------------------------------------
- *
* WmWinAppearance --
*
* This procedure is invoked to process the
@@ -6004,7 +6488,7 @@ static int
WmWinAppearance(
Tcl_Interp *interp, /* Current interpreter. */
TkWindow *winPtr, /* Window to be manipulated. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj * const objv[]) /* Argument objects. */
{
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 1090
@@ -6014,12 +6498,6 @@ WmWinAppearance(
(void) objv;
return TCL_OK;
#else
- static const char *const appearanceStrings[] = {
- "aqua", "darkaqua", "auto", NULL
- };
- enum appearances {
- APPEARANCE_AQUA, APPEARANCE_DARKAQUA, APPEARANCE_AUTO
- };
Tcl_Obj *result = NULL;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101300
NSAppearanceName appearance;
@@ -6138,7 +6616,14 @@ TkMacOSXMakeRealWindowExist(
WmInfo *wmPtr = winPtr->wmInfoPtr;
MacDrawable *macWin;
WindowClass macClass;
+ Class winClass = nil;
Bool overrideRedirect = Tk_Attributes((Tk_Window)winPtr)->override_redirect;
+ Tcl_HashEntry *hPtr = NULL;
+ NSUInteger styleMask;
+ NSString *identifier;
+ char *tabbingId = NULL;
+ long tabbingMode = NSWindowTabbingModeAutomatic;
+ static int initialized = 0;
if (TkMacOSXHostToplevelExists(winPtr)) {
return;
@@ -6152,7 +6637,7 @@ TkMacOSXMakeRealWindowExist(
*/
if (Tk_IsEmbedded(winPtr)) {
- TkWindow *contWinPtr = TkpGetOtherWindow(winPtr);
+ TkWindow *contWinPtr = (TkWindow *)Tk_GetOtherWindow((Tk_Window)winPtr);
if (contWinPtr != NULL) {
TkMacOSXMakeRealWindowExist(
@@ -6161,14 +6646,7 @@ TkMacOSXMakeRealWindowExist(
return;
}
- if (tkMacOSXEmbedHandler == NULL) {
- Tcl_Panic("TkMacOSXMakeRealWindowExist could not find container");
- }
- if (tkMacOSXEmbedHandler->containerExistProc &&
- tkMacOSXEmbedHandler->containerExistProc((Tk_Window)winPtr)
- != TCL_OK) {
- Tcl_Panic("ContainerExistProc could not make container");
- }
+ Tcl_Panic("TkMacOSXMakeRealWindowExist could not find container");
return;
/*
@@ -6176,51 +6654,119 @@ TkMacOSXMakeRealWindowExist(
*/
}
- /*
- * If this is an override-redirect window, the NSWindow is created first as
- * a document window then converted to a simple window.
- */
+ if ([NSApp macOSVersion] >= 101300) {
+ /*
+ * Prior to macOS 10.12 the styleMask was readonly. From macOS 10.12
+ * onward, the styleMask can replace the Carbon window classes and
+ * attributes.
+ */
+ int index;
+ if (!initialized) {
+ Tcl_InitHashTable(&pathnameToSubclass, TCL_STRING_KEYS);
+ Tcl_InitHashTable(&pathnameToTabbingId, TCL_STRING_KEYS);
+ Tcl_InitHashTable(&pathnameToTabbingMode, TCL_STRING_KEYS);
+ initialized = 1;
+ }
+ hPtr = Tcl_FindHashEntry(&pathnameToSubclass, Tk_PathName(winPtr));
+ index = hPtr ? PTR2INT(Tcl_GetHashValue(hPtr)) : subclassNSWindow;
+ switch(index) {
+ case subclassNSPanel:
+ winClass = [TKPanel class];
+ styleMask = (NSWindowStyleMaskTitled |
+ NSWindowStyleMaskClosable |
+ NSWindowStyleMaskResizable |
+ NSWindowStyleMaskUtilityWindow |
+ NSWindowStyleMaskNonactivatingPanel );
+ break;
+ default:
+ winClass = [TKWindow class];
+ styleMask = (NSWindowStyleMaskTitled |
+ NSWindowStyleMaskClosable |
+ NSWindowStyleMaskMiniaturizable |
+ NSWindowStyleMaskResizable );
+ break;
+ }
+ if (overrideRedirect) {
+ styleMask |= NSWindowStyleMaskDocModalWindow;
+ }
+ /* Help windows (used for tooltips) should have stylemask 0. */
+ if (wmPtr->macClass == kHelpWindowClass) {
+ styleMask = 0;
+ }
+ if (hPtr) {
+ Tcl_DeleteHashEntry(hPtr);
+ }
+ hPtr = Tcl_FindHashEntry(&pathnameToTabbingId, Tk_PathName(winPtr));
+ if (hPtr) {
+ tabbingId = (char *)Tcl_GetHashValue(hPtr);
+ Tcl_DeleteHashEntry(hPtr);
+ }
+ hPtr = Tcl_FindHashEntry(&pathnameToTabbingMode, Tk_PathName(winPtr));
+ if (hPtr) {
+ tabbingMode = PTR2INT(Tcl_GetHashValue(hPtr));
+ Tcl_DeleteHashEntry(hPtr);
+ }
+ } else {
- if (overrideRedirect) {
- wmPtr->macClass = kDocumentWindowClass;
- }
- macClass = wmPtr->macClass;
- wmPtr->attributes &= (tkAlwaysValidAttributes |
- macClassAttrs[macClass].validAttrs);
- wmPtr->flags |= macClassAttrs[macClass].flags |
+ /*
+ * If this is an override-redirect window, the NSWindow is created first as
+ * a document window then converted to a simple window.
+ */
+
+ if (overrideRedirect) {
+ wmPtr->macClass = kDocumentWindowClass;
+ }
+ macClass = wmPtr->macClass;
+ wmPtr->attributes &= (tkAlwaysValidAttributes |
+ macClassAttrs[macClass].validAttrs);
+ wmPtr->flags |= macClassAttrs[macClass].flags |
((wmPtr->attributes & kWindowResizableAttribute) ? 0 :
- WM_WIDTH_NOT_RESIZABLE|WM_HEIGHT_NOT_RESIZABLE);
- UInt64 attributes = (wmPtr->attributes &
- ~macClassAttrs[macClass].forceOffAttrs) |
+ WM_WIDTH_NOT_RESIZABLE|WM_HEIGHT_NOT_RESIZABLE);
+ UInt64 attributes = (wmPtr->attributes &
+ ~macClassAttrs[macClass].forceOffAttrs) |
macClassAttrs[macClass].forceOnAttrs;
- NSUInteger styleMask = macClassAttrs[macClass].styleMask |
- ((attributes & kWindowNoTitleBarAttribute) ? 0 : NSTitledWindowMask) |
- ((attributes & kWindowCloseBoxAttribute) ? NSClosableWindowMask : 0) |
- ((attributes & kWindowCollapseBoxAttribute) ?
- NSMiniaturizableWindowMask : 0) |
- ((attributes & kWindowResizableAttribute) ? NSResizableWindowMask : 0) |
- ((attributes & kWindowMetalAttribute) ?
- NSTexturedBackgroundWindowMask : 0) |
- ((attributes & kWindowUnifiedTitleAndToolbarAttribute) ?
- NSUnifiedTitleAndToolbarWindowMask : 0) |
- ((attributes & kWindowSideTitlebarAttribute) ? 1 << 9 : 0) |
- (attributes >> WM_NSMASK_SHIFT);
- Class winClass = (macClass == kDrawerWindowClass ? [TKDrawerWindow class] :
- (styleMask & (NSUtilityWindowMask|NSDocModalWindowMask|
- NSNonactivatingPanelMask|NSHUDWindowMask)) ? [TKPanel class] :
- [TKWindow class]);
+ styleMask = macClassAttrs[macClass].styleMask |
+ ((attributes & kWindowNoTitleBarAttribute) ? 0 : NSTitledWindowMask) |
+ ((attributes & kWindowCloseBoxAttribute) ? NSClosableWindowMask : 0) |
+ ((attributes & kWindowCollapseBoxAttribute) ?
+ NSMiniaturizableWindowMask : 0) |
+ ((attributes & kWindowResizableAttribute) ? NSResizableWindowMask : 0) |
+ ((attributes & kWindowMetalAttribute) ?
+ NSTexturedBackgroundWindowMask : 0) |
+ ((attributes & kWindowUnifiedTitleAndToolbarAttribute) ?
+ NSUnifiedTitleAndToolbarWindowMask : 0) |
+ ((attributes & kWindowSideTitlebarAttribute) ? 1 << 9 : 0) |
+ (attributes >> WM_NSMASK_SHIFT);
+ winClass = (macClass == kDrawerWindowClass ? [TKDrawerWindow class] :
+ (styleMask & (NSUtilityWindowMask|NSDocModalWindowMask|
+ NSNonactivatingPanelMask|NSHUDWindowMask)) ?
+ [TKPanel class] : [TKWindow class]);
+ }
NSRect structureRect = [winClass frameRectForContentRect:NSZeroRect
styleMask:styleMask];
NSRect contentRect = NSMakeRect(5 - structureRect.origin.x,
TkMacOSXZeroScreenHeight() - (TkMacOSXZeroScreenTop() + 5 +
structureRect.origin.y + structureRect.size.height + 200), 200, 200);
if (wmPtr->hints.initial_state == WithdrawnState) {
+ //// ???????
}
TKWindow *window = [[winClass alloc] initWithContentRect:contentRect
styleMask:styleMask backing:NSBackingStoreBuffered defer:YES];
if (!window) {
Tcl_Panic("couldn't allocate new Mac window");
}
+#if MAC_OS_X_VERSION_MAX_ALLOWED > 101200
+ if (tabbingId) {
+ identifier = [NSString stringWithUTF8String:tabbingId];
+ } else {
+ identifier = [NSString stringWithUTF8String:Tk_PathName(winPtr)];
+ }
+ [window setTabbingIdentifier: identifier];
+ [window setTabbingMode: tabbingMode];
+#endif
+ if (tabbingId) {
+ ckfree(tabbingId);
+ }
TKContentView *contentView = [[TKContentView alloc]
initWithFrame:NSZeroRect];
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
@@ -6272,7 +6818,11 @@ TkMacOSXMakeRealWindowExist(
atts.override_redirect = True;
Tk_ChangeWindowAttributes((Tk_Window)winPtr, CWOverrideRedirect, &atts);
- ApplyContainerOverrideChanges(winPtr, NULL);
+ if ([NSApp macOSVersion] >= 101300) {
+ window.styleMask |= NSWindowStyleMaskDocModalWindow;
+ } else {
+ ApplyContainerOverrideChanges(winPtr, NULL);
+ }
}
[window display];
}
@@ -6302,9 +6852,6 @@ TkpRedrawWidget(Tk_Window tkwin) {
Rect tkBounds;
NSRect bounds;
- if ([NSApp isDrawing]) {
- return;
- }
w = TkMacOSXGetNSWindowForDrawable(winPtr->window);
if (w) {
TKContentView *view = [w contentView];
@@ -6430,7 +6977,7 @@ TkpGetWrapperWindow(
*----------------------------------------------------------------------
*/
-void
+int
TkpWmSetState(
TkWindow *winPtr, /* Toplevel window to operate on. */
int state) /* One of IconicState, ZoomState, NormalState,
@@ -6441,7 +6988,7 @@ TkpWmSetState(
wmPtr->hints.initial_state = state;
if (wmPtr->flags & WM_NEVER_MAPPED) {
- return;
+ goto setStateEnd;
}
macWin = TkMacOSXGetNSWindowForDrawable(winPtr->window);
@@ -6485,6 +7032,8 @@ TkpWmSetState(
*/
while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)){}
+setStateEnd:
+ return 1;
}
/*