Import Tk 8.6.10
This commit is contained in:
@@ -31,7 +31,7 @@
|
||||
*/
|
||||
|
||||
static int GenerateUpdates(HIShapeRef updateRgn,
|
||||
CGRect *updateBounds, TkWindow *winPtr);
|
||||
CGRect *updateBounds, TkWindow *winPtr);
|
||||
static int GenerateActivateEvents(TkWindow *winPtr,
|
||||
int activeFlag);
|
||||
static void DoWindowActivate(ClientData clientData);
|
||||
@@ -68,8 +68,7 @@ extern NSString *NSWindowDidOrderOffScreenNotification;
|
||||
TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
|
||||
#endif
|
||||
BOOL movedOnly = [[notification name]
|
||||
isEqualToString:NSWindowDidMoveNotification];
|
||||
|
||||
isEqualToString:NSWindowDidMoveNotification];
|
||||
NSWindow *w = [notification object];
|
||||
TkWindow *winPtr = TkMacOSXGetTkWindow(w);
|
||||
|
||||
@@ -79,8 +78,8 @@ extern NSString *NSWindowDidOrderOffScreenNotification;
|
||||
int x, y, width = -1, height = -1, flags = 0;
|
||||
|
||||
x = bounds.origin.x;
|
||||
y = tkMacOSXZeroScreenHeight - (bounds.origin.y + bounds.size.height);
|
||||
if (winPtr->changes.x != x || winPtr->changes.y != y){
|
||||
y = TkMacOSXZeroScreenHeight() - (bounds.origin.y + bounds.size.height);
|
||||
if (winPtr->changes.x != x || winPtr->changes.y != y) {
|
||||
flags |= TK_LOCATION_CHANGED;
|
||||
} else {
|
||||
x = y = -1;
|
||||
@@ -92,15 +91,16 @@ extern NSString *NSWindowDidOrderOffScreenNotification;
|
||||
flags |= TK_SIZE_CHANGED;
|
||||
}
|
||||
if (Tcl_GetServiceMode() != TCL_SERVICE_NONE) {
|
||||
|
||||
/*
|
||||
* Propagate geometry changes immediately.
|
||||
*/
|
||||
|
||||
flags |= TK_MACOSX_HANDLE_EVENT_IMMEDIATELY;
|
||||
}
|
||||
|
||||
TkGenWMConfigureEvent((Tk_Window) winPtr, x, y, width, height, flags);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- (void) windowExpanded: (NSNotification *) notification
|
||||
@@ -136,6 +136,46 @@ extern NSString *NSWindowDidOrderOffScreenNotification;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSRect)windowWillUseStandardFrame:(NSWindow *)window
|
||||
defaultFrame:(NSRect)newFrame
|
||||
{
|
||||
/*
|
||||
* This method needs to be implemented in order for [NSWindow isZoomed] to
|
||||
* give the correct answer. But it suffices to always validate every
|
||||
* request.
|
||||
*/
|
||||
|
||||
return newFrame;
|
||||
}
|
||||
|
||||
- (NSSize)window:(NSWindow *)window
|
||||
willUseFullScreenContentSize:(NSSize)proposedSize
|
||||
{
|
||||
/*
|
||||
* 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
|
||||
* screen's visibleFrame, leaving black bands at the top and bottom.
|
||||
*/
|
||||
|
||||
return proposedSize;
|
||||
}
|
||||
|
||||
- (void) windowEnteredFullScreen: (NSNotification *) notification
|
||||
{
|
||||
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
|
||||
TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
|
||||
#endif
|
||||
[(TKWindow *)[notification object] tkLayoutChanged];
|
||||
}
|
||||
|
||||
- (void) windowExitedFullScreen: (NSNotification *) notification
|
||||
{
|
||||
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
|
||||
TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
|
||||
#endif
|
||||
[(TKWindow *)[notification object] tkLayoutChanged];
|
||||
}
|
||||
|
||||
- (void) windowCollapsed: (NSNotification *) notification
|
||||
{
|
||||
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
|
||||
@@ -158,21 +198,16 @@ extern NSString *NSWindowDidOrderOffScreenNotification;
|
||||
|
||||
if (winPtr) {
|
||||
TkGenWMDestroyEvent((Tk_Window) winPtr);
|
||||
if (_windowWithMouse == w) {
|
||||
_windowWithMouse = nil;
|
||||
[w release];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If necessary, TkGenWMDestroyEvent() handles [close]ing the window,
|
||||
* so can always return NO from -windowShouldClose: for a Tk window.
|
||||
* If necessary, TkGenWMDestroyEvent() handles [close]ing the window, so
|
||||
* can always return NO from -windowShouldClose: for a Tk window.
|
||||
*/
|
||||
|
||||
return (winPtr ? NO : YES);
|
||||
}
|
||||
|
||||
|
||||
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
|
||||
|
||||
- (void) windowDragStart: (NSNotification *) notification
|
||||
@@ -213,7 +248,6 @@ extern NSString *NSWindowDidOrderOffScreenNotification;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* TK_MAC_DEBUG_NOTIFICATIONS */
|
||||
|
||||
- (void) _setupWindowNotifications
|
||||
@@ -222,12 +256,19 @@ extern NSString *NSWindowDidOrderOffScreenNotification;
|
||||
|
||||
#define observe(n, s) \
|
||||
[nc addObserver:self selector:@selector(s) name:(n) object:nil]
|
||||
|
||||
observe(NSWindowDidBecomeKeyNotification, windowActivation:);
|
||||
observe(NSWindowDidResignKeyNotification, windowActivation:);
|
||||
observe(NSWindowDidMoveNotification, windowBoundsChanged:);
|
||||
observe(NSWindowDidResizeNotification, windowBoundsChanged:);
|
||||
observe(NSWindowDidDeminiaturizeNotification, windowExpanded:);
|
||||
observe(NSWindowDidMiniaturizeNotification, windowCollapsed:);
|
||||
|
||||
#if !(MAC_OS_X_VERSION_MAX_ALLOWED < 1070)
|
||||
observe(NSWindowDidEnterFullScreenNotification, windowEnteredFullScreen:);
|
||||
observe(NSWindowDidExitFullScreenNotification, windowExitedFullScreen:);
|
||||
#endif
|
||||
|
||||
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
|
||||
observe(NSWindowWillMoveNotification, windowDragStart:);
|
||||
observe(NSWindowWillStartLiveResizeNotification, windowLiveResize:);
|
||||
@@ -251,6 +292,22 @@ extern NSString *NSWindowDidOrderOffScreenNotification;
|
||||
TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
|
||||
#endif
|
||||
[NSApp tkCheckPasteboard];
|
||||
|
||||
/*
|
||||
* When the application is activated with Command-Tab it will create a
|
||||
* zombie window for every Tk window which has been withdrawn. So iterate
|
||||
* through the list of windows and order out any withdrawn window.
|
||||
*/
|
||||
|
||||
for (NSWindow *win in [NSApp windows]) {
|
||||
TkWindow *winPtr = TkMacOSXGetTkWindow(win);
|
||||
if (!winPtr || !winPtr->wmInfoPtr) {
|
||||
continue;
|
||||
}
|
||||
if (winPtr->wmInfoPtr->hints.initial_state == WithdrawnState) {
|
||||
[win orderOut:nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) applicationDeactivate: (NSNotification *) notification
|
||||
@@ -260,6 +317,20 @@ extern NSString *NSWindowDidOrderOffScreenNotification;
|
||||
#endif
|
||||
}
|
||||
|
||||
- (BOOL)applicationShouldHandleReopen:(NSApplication *)sender
|
||||
hasVisibleWindows:(BOOL)flag
|
||||
{
|
||||
/*
|
||||
* Allowing the default response means that withdrawn windows will get
|
||||
* displayed on the screen with unresponsive title buttons. We don't
|
||||
* really want that. Besides, we can write our own code to handle this
|
||||
* with ::tk::mac::ReopenApplication. So we just say NO.
|
||||
*/
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
- (void) applicationShowHide: (NSNotification *) notification
|
||||
{
|
||||
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
|
||||
@@ -299,11 +370,11 @@ extern NSString *NSWindowDidOrderOffScreenNotification;
|
||||
*
|
||||
* TkpAppIsDrawing --
|
||||
*
|
||||
* 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.
|
||||
* 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.
|
||||
*
|
||||
* Results:
|
||||
* True only while running the drawRect method of a TKContentView;
|
||||
@@ -313,11 +384,11 @@ extern NSString *NSWindowDidOrderOffScreenNotification;
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
MODULE_SCOPE Bool
|
||||
TkpAppIsDrawing(void) {
|
||||
return [NSApp isDrawing];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -443,7 +514,9 @@ GenerateActivateEvents(
|
||||
int activeFlag)
|
||||
{
|
||||
TkGenerateActivateEvents(winPtr, activeFlag);
|
||||
TkMacOSXGenerateFocusEvent(winPtr, activeFlag);
|
||||
if (activeFlag || ![NSApp isActive]) {
|
||||
TkMacOSXGenerateFocusEvent(winPtr, activeFlag);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -600,17 +673,14 @@ TkGenWMConfigureEvent(
|
||||
if (flags & TK_LOCATION_CHANGED) {
|
||||
wmPtr->x = x;
|
||||
wmPtr->y = y;
|
||||
wmPtr->flags &= ~(WM_NEGATIVE_X | WM_NEGATIVE_Y);
|
||||
}
|
||||
if ((flags & TK_SIZE_CHANGED) && !(wmPtr->flags & WM_SYNC_PENDING) &&
|
||||
((width != Tk_Width(tkwin)) || (height != Tk_Height(tkwin)))) {
|
||||
if ((wmPtr->width == -1) && (width == winPtr->reqWidth)) {
|
||||
|
||||
/*
|
||||
* Don't set external width, since the user didn't change it
|
||||
* from what the widgets asked for.
|
||||
*/
|
||||
|
||||
} else if (wmPtr->gridWin != NULL) {
|
||||
wmPtr->width = wmPtr->reqGridWidth
|
||||
+ (width - winPtr->reqWidth)/wmPtr->widthInc;
|
||||
@@ -622,12 +692,10 @@ TkGenWMConfigureEvent(
|
||||
}
|
||||
|
||||
if ((wmPtr->height == -1) && (height == winPtr->reqHeight)) {
|
||||
|
||||
/*
|
||||
* Don't set external height, since the user didn't change it
|
||||
* from what the widgets asked for.
|
||||
*/
|
||||
|
||||
} else if (wmPtr->gridWin != NULL) {
|
||||
wmPtr->height = wmPtr->reqGridHeight
|
||||
+ (height - winPtr->reqHeight)/wmPtr->heightInc;
|
||||
@@ -800,7 +868,10 @@ Tk_MacOSXIsAppInFront(void)
|
||||
*
|
||||
*/
|
||||
|
||||
/*Restrict event processing to Expose events.*/
|
||||
/*
|
||||
* Restrict event processing to Expose events.
|
||||
*/
|
||||
|
||||
static Tk_RestrictAction
|
||||
ExposeRestrictProc(
|
||||
ClientData arg,
|
||||
@@ -810,7 +881,10 @@ ExposeRestrictProc(
|
||||
? TK_PROCESS_EVENT : TK_DEFER_EVENT);
|
||||
}
|
||||
|
||||
/*Restrict event processing to ConfigureNotify events.*/
|
||||
/*
|
||||
* Restrict event processing to ConfigureNotify events.
|
||||
*/
|
||||
|
||||
static Tk_RestrictAction
|
||||
ConfigureRestrictProc(
|
||||
ClientData arg,
|
||||
@@ -819,6 +893,30 @@ ConfigureRestrictProc(
|
||||
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.
|
||||
*/
|
||||
|
||||
static void
|
||||
RedisplayView(
|
||||
ClientData clientdata)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@implementation TKContentView(TKWindowEvent)
|
||||
|
||||
- (void) drawRect: (NSRect) rect
|
||||
@@ -832,17 +930,15 @@ ConfigureRestrictProc(
|
||||
Tk_PathName(winPtr));
|
||||
#endif
|
||||
|
||||
if ([NSApp simulateDrawing]) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* We do not allow recursive calls to drawRect, but we only log
|
||||
* them on OSX > 10.13, where they should never happen.
|
||||
* We do not allow recursive calls to drawRect, but we only log them on OSX
|
||||
* > 10.13, where they should never happen.
|
||||
*/
|
||||
|
||||
if ([NSApp isDrawing] && [NSApp macMinorVersion] > 13) {
|
||||
TKLog(@"WARNING: a recursive call to drawRect was aborted.");
|
||||
if ([NSApp isDrawing]) {
|
||||
if ([NSApp macMinorVersion] > 13) {
|
||||
TKLog(@"WARNING: a recursive call to drawRect was aborted.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -867,6 +963,11 @@ ConfigureRestrictProc(
|
||||
CFRelease(drawShape);
|
||||
[NSApp setIsDrawing: NO];
|
||||
|
||||
if ([self needsRedisplay]) {
|
||||
[self setNeedsRedisplay:NO];
|
||||
Tcl_DoWhenIdle(RedisplayView, self);
|
||||
}
|
||||
|
||||
#ifdef TK_MAC_DEBUG_DRAWING
|
||||
fprintf(stderr, "drawRect: done.\n");
|
||||
#endif
|
||||
@@ -878,22 +979,22 @@ ConfigureRestrictProc(
|
||||
NSWindow *w = [self window];
|
||||
TkWindow *winPtr = TkMacOSXGetTkWindow(w);
|
||||
Tk_Window tkwin = (Tk_Window) winPtr;
|
||||
|
||||
if (![self inLiveResize] &&
|
||||
[w respondsToSelector: @selector (tkLayoutChanged)]) {
|
||||
[(TKWindow *)w tkLayoutChanged];
|
||||
}
|
||||
|
||||
if (winPtr) {
|
||||
/* On OSX versions below 10.14 setFrame calls drawRect.
|
||||
* On 10.14 it does its own drawing.
|
||||
*/
|
||||
if ([NSApp macMinorVersion] > 13) {
|
||||
[NSApp setIsDrawing:YES];
|
||||
}
|
||||
unsigned int width = (unsigned int)newsize.width;
|
||||
unsigned int height=(unsigned int)newsize.height;
|
||||
ClientData oldArg;
|
||||
Tk_RestrictProc *oldProc;
|
||||
|
||||
/*
|
||||
* This can be called from outside the Tk event loop.
|
||||
* Since it calls Tcl_DoOneEvent, we need to make sure we
|
||||
* don't clobber the AutoreleasePool set up by the caller.
|
||||
* This can be called from outside the Tk event loop. Since it calls
|
||||
* Tcl_DoOneEvent, we need to make sure we don't clobber the
|
||||
* AutoreleasePool set up by the caller.
|
||||
*/
|
||||
|
||||
[NSApp _lockAutoreleasePool];
|
||||
@@ -909,7 +1010,7 @@ ConfigureRestrictProc(
|
||||
*/
|
||||
|
||||
TkGenWMConfigureEvent(tkwin, Tk_X(tkwin), Tk_Y(tkwin), width, height,
|
||||
TK_SIZE_CHANGED | TK_MACOSX_HANDLE_EVENT_IMMEDIATELY);
|
||||
TK_SIZE_CHANGED | TK_MACOSX_HANDLE_EVENT_IMMEDIATELY);
|
||||
oldProc = Tk_RestrictEvents(ConfigureRestrictProc, NULL, &oldArg);
|
||||
Tk_RestrictEvents(oldProc, oldArg, &oldArg);
|
||||
|
||||
@@ -933,7 +1034,7 @@ ConfigureRestrictProc(
|
||||
/*
|
||||
* Finally, unlock the main autoreleasePool.
|
||||
*/
|
||||
|
||||
|
||||
[NSApp _unlockAutoreleasePool];
|
||||
}
|
||||
}
|
||||
@@ -997,16 +1098,15 @@ ConfigureRestrictProc(
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
- (void) viewDidChangeEffectiveAppearance
|
||||
{
|
||||
XVirtualEvent event;
|
||||
int x, y;
|
||||
NSString *osxMode = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"];
|
||||
NSWindow *w = [self window];
|
||||
TkWindow *winPtr = TkMacOSXGetTkWindow(w);
|
||||
Tk_Window tkwin = (Tk_Window) winPtr;
|
||||
@@ -1027,21 +1127,17 @@ ConfigureRestrictProc(
|
||||
&event.x_root, &event.y_root, &x, &y, &event.state);
|
||||
Tk_TopCoordsToWindow(tkwin, x, y, &event.x, &event.y);
|
||||
event.same_screen = true;
|
||||
if (osxMode == nil) {
|
||||
event.name = Tk_GetUid("LightAqua");
|
||||
Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL);
|
||||
return;
|
||||
}
|
||||
if ([osxMode isEqual:@"Dark"]) {
|
||||
if (TkMacOSXInDarkMode(tkwin)) {
|
||||
event.name = Tk_GetUid("DarkAqua");
|
||||
Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL);
|
||||
return;
|
||||
} else {
|
||||
event.name = Tk_GetUid("LightAqua");
|
||||
}
|
||||
Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is no-op on 10.7 and up because Apple has removed this widget,
|
||||
* but we are leaving it here for backwards compatibility.
|
||||
* This is no-op on 10.7 and up because Apple has removed this widget, but we
|
||||
* are leaving it here for backwards compatibility.
|
||||
*/
|
||||
|
||||
- (void) tkToolbarButton: (id) sender
|
||||
@@ -1090,6 +1186,11 @@ ConfigureRestrictProc(
|
||||
return YES;
|
||||
}
|
||||
|
||||
/*
|
||||
* This keyDown method does nothing, which is a huge improvement over the
|
||||
* default keyDown method which beeps every time a key is pressed.
|
||||
*/
|
||||
|
||||
- (void) keyDown: (NSEvent *) theEvent
|
||||
{
|
||||
#ifdef TK_MAC_DEBUG_EVENTS
|
||||
@@ -1097,6 +1198,23 @@ ConfigureRestrictProc(
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* When the services menu is opened this is called for each Responder in
|
||||
* 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.
|
||||
*/
|
||||
|
||||
- (id)validRequestorForSendType:(NSString *)sendType
|
||||
returnType:(NSString *)returnType
|
||||
{
|
||||
if ([sendType isEqualToString:@"NSStringPboardType"] ||
|
||||
[sendType isEqualToString:@"NSPasteboardTypeString"]) {
|
||||
return [NSApp servicesProvider];
|
||||
}
|
||||
return [super validRequestorForSendType:sendType returnType:returnType];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user