diff options
author | William Joye <wjoye@cfa.harvard.edu> | 2018-01-02 20:34:49 (GMT) |
---|---|---|
committer | William Joye <wjoye@cfa.harvard.edu> | 2018-01-02 20:34:49 (GMT) |
commit | 89c1ac99d375fbd73892aa659f06ef5e2c5ea56e (patch) | |
tree | e76ce80d68d11f1ea137bc33a42f71a1d1f32028 /tk8.6/macosx/tkMacOSXWindowEvent.c | |
parent | 01e4cd2ef2ff59418766b2259fbc99771646aba6 (diff) | |
download | blt-89c1ac99d375fbd73892aa659f06ef5e2c5ea56e.zip blt-89c1ac99d375fbd73892aa659f06ef5e2c5ea56e.tar.gz blt-89c1ac99d375fbd73892aa659f06ef5e2c5ea56e.tar.bz2 |
upgrade to tcl/tk 8.6.8
Diffstat (limited to 'tk8.6/macosx/tkMacOSXWindowEvent.c')
-rw-r--r-- | tk8.6/macosx/tkMacOSXWindowEvent.c | 1018 |
1 files changed, 0 insertions, 1018 deletions
diff --git a/tk8.6/macosx/tkMacOSXWindowEvent.c b/tk8.6/macosx/tkMacOSXWindowEvent.c deleted file mode 100644 index 137ba31..0000000 --- a/tk8.6/macosx/tkMacOSXWindowEvent.c +++ /dev/null @@ -1,1018 +0,0 @@ -/* - * tkMacOSXWindowEvent.c -- - * - * This file defines the routines for both creating and handling Window - * Manager class events for Tk. - * - * Copyright 2001-2009, Apple Inc. - * Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net> - * Copyright (c) 2015 Kevin Walzer/WordTech Communications LLC. - * Copyright (c) 2015 Marc Culler. - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tkMacOSXPrivate.h" -#include "tkMacOSXWm.h" -#include "tkMacOSXEvent.h" -#include "tkMacOSXDebug.h" -#include "tkMacOSXConstants.h" - -/* -#ifdef TK_MAC_DEBUG -#define TK_MAC_DEBUG_EVENTS -#define TK_MAC_DEBUG_DRAWING -#endif -*/ - -/* - * Declaration of functions used only in this file - */ - -static int GenerateUpdates(HIShapeRef updateRgn, - CGRect *updateBounds, TkWindow *winPtr); -static int GenerateActivateEvents(TkWindow *winPtr, - int activeFlag); -static void DoWindowActivate(ClientData clientData); - -#pragma mark TKApplication(TKWindowEvent) - -#ifdef TK_MAC_DEBUG_NOTIFICATIONS -extern NSString *NSWindowWillOrderOnScreenNotification; -extern NSString *NSWindowDidOrderOnScreenNotification; -extern NSString *NSWindowDidOrderOffScreenNotification; - -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 -#define NSWindowWillStartLiveResizeNotification @"NSWindowWillStartLiveResizeNotification" -#define NSWindowDidEndLiveResizeNotification @"NSWindowDidEndLiveResizeNotification" -#endif -#endif - -extern BOOL opaqueTag; - -@implementation TKApplication(TKWindowEvent) - -- (void) windowActivation: (NSNotification *) notification -{ -#ifdef TK_MAC_DEBUG_NOTIFICATIONS - TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification); -#endif - BOOL activate = [[notification name] - isEqualToString:NSWindowDidBecomeKeyNotification]; - NSWindow *w = [notification object]; - TkWindow *winPtr = TkMacOSXGetTkWindow(w); - - if (winPtr && Tk_IsMapped(winPtr)) { - GenerateActivateEvents(winPtr, activate); - } -} - -- (void) windowBoundsChanged: (NSNotification *) notification -{ -#ifdef TK_MAC_DEBUG_NOTIFICATIONS - TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification); -#endif - BOOL movedOnly = [[notification name] - isEqualToString:NSWindowDidMoveNotification]; - - if (movedOnly) { - /* constraining to screen after move not needed with AppKit */ - } - - NSWindow *w = [notification object]; - TkWindow *winPtr = TkMacOSXGetTkWindow(w); - - if (winPtr) { - WmInfo *wmPtr = winPtr->wmInfoPtr; - NSRect bounds = [w frame]; - 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){ - flags |= TK_LOCATION_CHANGED; - } else { - x = y = -1; - } - if (!movedOnly && (winPtr->changes.width != bounds.size.width || - winPtr->changes.height != bounds.size.height)) { - width = bounds.size.width - wmPtr->xInParent; - height = bounds.size.height - wmPtr->yInParent; - 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 -{ -#ifdef TK_MAC_DEBUG_NOTIFICATIONS - TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification); -#endif - NSWindow *w = [notification object]; - TkWindow *winPtr = TkMacOSXGetTkWindow(w); - - if (winPtr) { - winPtr->wmInfoPtr->hints.initial_state = - TkMacOSXIsWindowZoomed(winPtr) ? ZoomState : NormalState; - Tk_MapWindow((Tk_Window) winPtr); - if (Tcl_GetServiceMode() != TCL_SERVICE_NONE) { - /* - * Process all Tk events generated by Tk_MapWindow(). - */ - - while (Tcl_ServiceEvent(0)) {} - while (Tcl_DoOneEvent(TCL_IDLE_EVENTS|TCL_DONT_WAIT)) {} - - /* - * NSWindowDidDeminiaturizeNotification is received after - * NSWindowDidBecomeKeyNotification, so activate manually - */ - - GenerateActivateEvents(winPtr, 1); - } else { - Tcl_DoWhenIdle(DoWindowActivate, winPtr); - } - } -} - -- (void) windowCollapsed: (NSNotification *) notification -{ -#ifdef TK_MAC_DEBUG_NOTIFICATIONS - TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification); -#endif - NSWindow *w = [notification object]; - TkWindow *winPtr = TkMacOSXGetTkWindow(w); - - if (winPtr) { - Tk_UnmapWindow((Tk_Window) winPtr); - } -} - -- (BOOL) windowShouldClose: (NSWindow *) w -{ -#ifdef TK_MAC_DEBUG_NOTIFICATIONS - TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, w); -#endif - TkWindow *winPtr = TkMacOSXGetTkWindow(w); - - 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. - */ - - return (winPtr ? NO : YES); -} - -#ifdef TK_MAC_DEBUG_NOTIFICATIONS - -- (void) windowDragStart: (NSNotification *) notification -{ - TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification); -} - -- (void) windowLiveResize: (NSNotification *) notification -{ - TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification); - //BOOL start = [[notification name] isEqualToString:NSWindowWillStartLiveResizeNotification]; -} - -- (void) windowMapped: (NSNotification *) notification -{ - TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification); - NSWindow *w = [notification object]; - TkWindow *winPtr = TkMacOSXGetTkWindow(w); - - if (winPtr) { - //Tk_MapWindow((Tk_Window) winPtr); - } -} - -- (void) windowBecameVisible: (NSNotification *) notification -{ - TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification); -} - -- (void) windowUnmapped: (NSNotification *) notification -{ - TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification); - NSWindow *w = [notification object]; - TkWindow *winPtr = TkMacOSXGetTkWindow(w); - - if (winPtr) { - //Tk_UnmapWindow((Tk_Window) winPtr); - } -} -#endif /* TK_MAC_DEBUG_NOTIFICATIONS */ - -- (void) _setupWindowNotifications -{ - NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; - -#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:); -#ifdef TK_MAC_DEBUG_NOTIFICATIONS - observe(NSWindowWillMoveNotification, windowDragStart:); - observe(NSWindowWillStartLiveResizeNotification, windowLiveResize:); - observe(NSWindowDidEndLiveResizeNotification, windowLiveResize:); - observe(NSWindowWillOrderOnScreenNotification, windowMapped:); - observe(NSWindowDidOrderOnScreenNotification, windowBecameVisible:); - observe(NSWindowDidOrderOffScreenNotification, windowUnmapped:); -#endif -#undef observe -} -@end - -#pragma mark TKApplication(TKApplicationEvent) - -@implementation TKApplication(TKApplicationEvent) - -- (void) applicationActivate: (NSNotification *) notification -{ -#ifdef TK_MAC_DEBUG_NOTIFICATIONS - TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification); -#endif - [NSApp tkCheckPasteboard]; -} - -- (void) applicationDeactivate: (NSNotification *) notification -{ -#ifdef TK_MAC_DEBUG_NOTIFICATIONS - TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification); -#endif - TkSuspendClipboard(); -} - -- (void) applicationShowHide: (NSNotification *) notification -{ -#ifdef TK_MAC_DEBUG_NOTIFICATIONS - TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification); -#endif - const char *cmd = ([[notification name] isEqualToString: - NSApplicationDidUnhideNotification] ? - "::tk::mac::OnShow" : "::tk::mac::OnHide"); - - if (_eventInterp && Tcl_FindCommand(_eventInterp, cmd, NULL, 0)) { - int code = Tcl_EvalEx(_eventInterp, cmd, -1, TCL_EVAL_GLOBAL); - - if (code != TCL_OK) { - Tcl_BackgroundException(_eventInterp, code); - } - Tcl_ResetResult(_eventInterp); - } -} - -- (void) displayChanged: (NSNotification *) notification -{ -#ifdef TK_MAC_DEBUG_NOTIFICATIONS - TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification); -#endif - TkDisplay *dispPtr = TkGetDisplayList(); - - if (dispPtr) { - TkMacOSXDisplayChanged(dispPtr->display); - } -} -@end - -#pragma mark - - -/* - *---------------------------------------------------------------------- - * - * GenerateUpdates -- - * - * Given a Macintosh update region and a Tk window this function geneates - * a X Expose event for the window if it is within the update region. The - * function will then recursivly have each damaged window generate Expose - * events for its child windows. - * - * Results: - * True if event(s) are generated - false otherwise. - * - * Side effects: - * Additional events may be place on the Tk event queue. - * - *---------------------------------------------------------------------- - */ - -static int -GenerateUpdates( - HIShapeRef updateRgn, - CGRect *updateBounds, - TkWindow *winPtr) -{ - TkWindow *childPtr; - XEvent event; - CGRect bounds, damageBounds; - HIShapeRef boundsRgn, damageRgn; - - TkMacOSXWinCGBounds(winPtr, &bounds); - if (!CGRectIntersectsRect(bounds, *updateBounds)) { - return 0; - } - if (!HIShapeIntersectsRect(updateRgn, &bounds)) { - return 0; - } - - /* - * Compute the bounding box of the area that the damage occured in. - */ - - boundsRgn = HIShapeCreateWithRect(&bounds); - damageRgn = HIShapeCreateIntersection(updateRgn, boundsRgn); - if (HIShapeIsEmpty(damageRgn)) { - CFRelease(damageRgn); - CFRelease(boundsRgn); - return 0; - } - HIShapeGetBounds(damageRgn, &damageBounds); - - CFRelease(damageRgn); - CFRelease(boundsRgn); - - event.xany.serial = LastKnownRequestProcessed(Tk_Display(winPtr)); - event.xany.send_event = false; - event.xany.window = Tk_WindowId(winPtr); - event.xany.display = Tk_Display(winPtr); - event.type = Expose; - event.xexpose.x = damageBounds.origin.x - bounds.origin.x; - event.xexpose.y = damageBounds.origin.y - bounds.origin.y; - event.xexpose.width = damageBounds.size.width; - event.xexpose.height = damageBounds.size.height; - event.xexpose.count = 0; - Tk_HandleEvent(&event); - -#ifdef TK_MAC_DEBUG_DRAWING - NSLog(@"Expose %p {{%d, %d}, {%d, %d}}", event.xany.window, event.xexpose.x, - event.xexpose.y, event.xexpose.width, event.xexpose.height); -#endif - - /* - * Generate updates for the children of this window - */ - - for (childPtr = winPtr->childList; childPtr != NULL; - childPtr = childPtr->nextPtr) { - if (!Tk_IsMapped(childPtr) || Tk_IsTopLevel(childPtr)) { - continue; - } - GenerateUpdates(updateRgn, updateBounds, childPtr); - } - - /* - * Generate updates for any contained windows - */ - - if (Tk_IsContainer(winPtr)) { - childPtr = TkpGetOtherWindow(winPtr); - if (childPtr != NULL && Tk_IsMapped(childPtr)) { - GenerateUpdates(updateRgn, updateBounds, childPtr); - } - - /* - * TODO: Here we should handle out of process embedding. - */ - } - - return 1; -} - -/* - *---------------------------------------------------------------------- - * - * GenerateActivateEvents -- - * - * Given a Macintosh window activate event this function generates all the - * X Activate events needed by Tk. - * - * Results: - * True if event(s) are generated - false otherwise. - * - * Side effects: - * Additional events may be place on the Tk event queue. - * - *---------------------------------------------------------------------- - */ - -int -GenerateActivateEvents( - TkWindow *winPtr, - int activeFlag) -{ - TkGenerateActivateEvents(winPtr, activeFlag); - TkMacOSXGenerateFocusEvent(winPtr, activeFlag); - return true; -} - -/* - *---------------------------------------------------------------------- - * - * DoWindowActivate -- - * - * Idle handler that calls GenerateActivateEvents(). - * - * Results: - * None. - * - * Side effects: - * Additional events may be place on the Tk event queue. - * - *---------------------------------------------------------------------- - */ - -void -DoWindowActivate( - ClientData clientData) -{ - GenerateActivateEvents(clientData, 1); -} - -/* - *---------------------------------------------------------------------- - * - * TkMacOSXGenerateFocusEvent -- - * - * Given a Macintosh window activate event this function generates all - * the X Focus events needed by Tk. - * - * Results: - * True if event(s) are generated - false otherwise. - * - * Side effects: - * Additional events may be place on the Tk event queue. - * - *---------------------------------------------------------------------- - */ - -MODULE_SCOPE int -TkMacOSXGenerateFocusEvent( - TkWindow *winPtr, /* Root X window for event. */ - int activeFlag) -{ - XEvent event; - - /* - * Don't send focus events to windows of class help or to windows with the - * kWindowNoActivatesAttribute. - */ - - if (winPtr->wmInfoPtr && (winPtr->wmInfoPtr->macClass == kHelpWindowClass || - winPtr->wmInfoPtr->attributes & kWindowNoActivatesAttribute)) { - return false; - } - - /* - * Generate FocusIn and FocusOut events. This event is only sent to the - * toplevel window. - */ - - if (activeFlag) { - event.xany.type = FocusIn; - } else { - event.xany.type = FocusOut; - } - - event.xany.serial = LastKnownRequestProcessed(Tk_Display(winPtr)); - event.xany.send_event = False; - event.xfocus.display = Tk_Display(winPtr); - event.xfocus.window = winPtr->window; - event.xfocus.mode = NotifyNormal; - event.xfocus.detail = NotifyDetailNone; - - Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); - return true; -} - -/* - *---------------------------------------------------------------------- - * - * TkGenWMConfigureEvent -- - * - * Generate a ConfigureNotify event for Tk. Depending on the value of flag - * the values of width/height, x/y, or both may be changed. - * - * Results: - * None. - * - * Side effects: - * A ConfigureNotify event is sent to Tk. - * - *---------------------------------------------------------------------- - */ - -void -TkGenWMConfigureEvent( - Tk_Window tkwin, - int x, int y, - int width, int height, - int flags) -{ - XEvent event; - WmInfo *wmPtr; - TkWindow *winPtr = (TkWindow *) tkwin; - - if (tkwin == NULL) { - return; - } - - event.type = ConfigureNotify; - event.xconfigure.serial = LastKnownRequestProcessed(Tk_Display(tkwin)); - event.xconfigure.send_event = False; - event.xconfigure.display = Tk_Display(tkwin); - event.xconfigure.event = Tk_WindowId(tkwin); - event.xconfigure.window = Tk_WindowId(tkwin); - event.xconfigure.border_width = winPtr->changes.border_width; - event.xconfigure.override_redirect = winPtr->atts.override_redirect; - if (winPtr->changes.stack_mode == Above) { - event.xconfigure.above = winPtr->changes.sibling; - } else { - event.xconfigure.above = None; - } - - if (!(flags & TK_LOCATION_CHANGED)) { - x = Tk_X(tkwin); - y = Tk_Y(tkwin); - } - if (!(flags & TK_SIZE_CHANGED)) { - width = Tk_Width(tkwin); - height = Tk_Height(tkwin); - } - event.xconfigure.x = x; - event.xconfigure.y = y; - event.xconfigure.width = width; - event.xconfigure.height = height; - - if (flags & TK_MACOSX_HANDLE_EVENT_IMMEDIATELY) { - Tk_HandleEvent(&event); - } else { - Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); - } - - /* - * Update window manager information. - */ - - if (Tk_IsTopLevel(winPtr)) { - wmPtr = winPtr->wmInfoPtr; - 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; - if (wmPtr->width < 0) { - wmPtr->width = 0; - } - } else { - wmPtr->width = width; - } - - 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; - if (wmPtr->height < 0) { - wmPtr->height = 0; - } - } else { - wmPtr->height = height; - } - - wmPtr->configWidth = width; - wmPtr->configHeight = height; - } - } - - /* - * Now set up the changes structure. Under X we wait for the - * ConfigureNotify to set these values. On the Mac we know imediatly that - * this is what we want - so we just set them. However, we need to make - * sure the windows clipping region is marked invalid so the change is - * visible to the subwindow. - */ - - winPtr->changes.x = x; - winPtr->changes.y = y; - winPtr->changes.width = width; - winPtr->changes.height = height; - TkMacOSXInvalClipRgns(tkwin); -} - -/* - *---------------------------------------------------------------------- - * - * TkGenWMDestroyEvent -- - * - * Generate a WM Destroy event for Tk. - * - * Results: - * None. - * - * Side effects: - * A WM_PROTOCOL/WM_DELETE_WINDOW event is sent to Tk. - * - *---------------------------------------------------------------------- - */ - -void -TkGenWMDestroyEvent( - Tk_Window tkwin) -{ - XEvent event; - - event.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin)); - event.xany.send_event = False; - event.xany.display = Tk_Display(tkwin); - - event.xclient.window = Tk_WindowId(tkwin); - event.xclient.type = ClientMessage; - event.xclient.message_type = Tk_InternAtom(tkwin, "WM_PROTOCOLS"); - event.xclient.format = 32; - event.xclient.data.l[0] = Tk_InternAtom(tkwin, "WM_DELETE_WINDOW"); - Tk_HandleEvent(&event); -} - -/* - *---------------------------------------------------------------------- - * - * TkWmProtocolEventProc -- - * - * This procedure is called by the Tk_HandleEvent whenever a ClientMessage - * event arrives whose type is "WM_PROTOCOLS". This procedure handles the - * message from the window manager in an appropriate fashion. - * - * Results: - * None. - * - * Side effects: - * Depends on what sort of handler, if any, was set up for the protocol. - * - *---------------------------------------------------------------------- - */ - -void -TkWmProtocolEventProc( - TkWindow *winPtr, /* Window to which the event was sent. */ - XEvent *eventPtr) /* X event. */ -{ - WmInfo *wmPtr; - ProtocolHandler *protPtr; - Tcl_Interp *interp; - Atom protocol; - int result; - - wmPtr = winPtr->wmInfoPtr; - if (wmPtr == NULL) { - return; - } - protocol = (Atom) eventPtr->xclient.data.l[0]; - for (protPtr = wmPtr->protPtr; protPtr != NULL; - protPtr = protPtr->nextPtr) { - if (protocol == protPtr->protocol) { - Tcl_Preserve(protPtr); - interp = protPtr->interp; - Tcl_Preserve(interp); - result = Tcl_EvalEx(interp, protPtr->command, -1, TCL_EVAL_GLOBAL); - if (result != TCL_OK) { - Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf( - "\n (command for \"%s\" window manager protocol)", - Tk_GetAtomName((Tk_Window) winPtr, protocol))); - Tcl_BackgroundException(interp, result); - } - Tcl_Release(interp); - Tcl_Release(protPtr); - return; - } - } - - /* - * No handler was present for this protocol. If this is a WM_DELETE_WINDOW - * message then just destroy the window. - */ - - if (protocol == Tk_InternAtom((Tk_Window) winPtr, "WM_DELETE_WINDOW")) { - Tk_DestroyWindow((Tk_Window) winPtr); - } -} - -/* - *---------------------------------------------------------------------- - * - * Tk_MacOSXIsAppInFront -- - * - * Returns 1 if this app is the foreground app. - * - * Results: - * 1 if app is in front, 0 otherwise. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -Tk_MacOSXIsAppInFront(void) -{ - Boolean isFrontProcess = true; -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - ProcessSerialNumber frontPsn, ourPsn = {0, kCurrentProcess}; - - if (noErr == GetFrontProcess(&frontPsn)){ - SameProcess(&frontPsn, &ourPsn, &isFrontProcess); - } -#else - isFrontProcess = [NSRunningApplication currentApplication].active; -#endif - return (isFrontProcess == true); -} - -#pragma mark TKContentView - -#import <ApplicationServices/ApplicationServices.h> - -/* - * Custom content view for use in Tk NSWindows. - * - * Since Tk handles all drawing of widgets, we only use the AppKit event loop - * as a source of input events. To do this, we overload the NSView drawRect - * method with a method which generates Expose events for Tk but does no - * drawing. The redrawing operations are then done when Tk processes these - * events. - * - * Earlier versions of Mac Tk used subclasses of NSView, e.g. NSButton, as the - * basis for Tk widgets. These would then appear as subviews of the - * TKContentView. To prevent the AppKit from redrawing and corrupting the Tk - * Widgets it was necessary to use Apple private API calls. In order to avoid - * using private API calls, the NSView-based widgets have been replaced with - * normal Tk widgets which draw themselves as native widgets by using the - * HITheme API. - * - */ - -/*Restrict event processing to Expose events.*/ -static Tk_RestrictAction -ExposeRestrictProc( - ClientData arg, - XEvent *eventPtr) -{ - return (eventPtr->type==Expose && eventPtr->xany.serial==PTR2UINT(arg) - ? TK_PROCESS_EVENT : TK_DEFER_EVENT); -} - -/*Restrict event processing to ConfigureNotify events.*/ -static Tk_RestrictAction -ConfigureRestrictProc( - ClientData arg, - XEvent *eventPtr) -{ - return (eventPtr->type==ConfigureNotify ? TK_PROCESS_EVENT : TK_DEFER_EVENT); -} - -@implementation TKContentView(TKWindowEvent) - -- (void) drawRect: (NSRect) rect -{ - const NSRect *rectsBeingDrawn; - NSInteger rectsBeingDrawnCount; - - [self getRectsBeingDrawn:&rectsBeingDrawn count:&rectsBeingDrawnCount]; - -#ifdef TK_MAC_DEBUG_DRAWING - TKLog(@"-[%@(%p) %s%@]", [self class], self, _cmd, NSStringFromRect(rect)); - [[NSColor colorWithDeviceRed:0.0 green:1.0 blue:0.0 alpha:.1] setFill]; - NSRectFillListUsingOperation(rectsBeingDrawn, rectsBeingDrawnCount, - NSCompositeSourceOver); -#endif - - CGFloat height = [self bounds].size.height; - HIMutableShapeRef drawShape = HIShapeCreateMutable(); - - while (rectsBeingDrawnCount--) { - CGRect r = NSRectToCGRect(*rectsBeingDrawn++); - r.origin.y = height - (r.origin.y + r.size.height); - HIShapeUnionWithRect(drawShape, &r); - } - if (CFRunLoopGetMain() == CFRunLoopGetCurrent()) { - [self generateExposeEvents:(HIShapeRef)drawShape]; - } else { - [self performSelectorOnMainThread:@selector(generateExposeEvents:) - withObject:(id)drawShape waitUntilDone:NO - modes:[NSArray arrayWithObjects:NSRunLoopCommonModes, - - NSEventTrackingRunLoopMode, NSModalPanelRunLoopMode, - nil]]; - } - - CFRelease(drawShape); -} - --(void) setFrameSize: (NSSize)newsize -{ - [super setFrameSize: newsize]; - if ([self inLiveResize]) { - NSWindow *w = [self window]; - TkWindow *winPtr = TkMacOSXGetTkWindow(w); - Tk_Window tkwin = (Tk_Window) winPtr; - unsigned int width = (unsigned int)newsize.width; - unsigned int height=(unsigned int)newsize.height; - ClientData oldArg; - Tk_RestrictProc *oldProc; - - /* This can be called from outside the Tk event loop. - * Since it calls Tcl_DoOneEvent, we need to make sure we - * don't clobber the AutoreleasePool set up by the caller. - */ - [NSApp _lockAutoreleasePool]; - - /* - * Try to prevent flickers and flashes. - */ - [w disableFlushWindow]; - NSDisableScreenUpdates(); - - /* Disable Tk drawing until the window has been completely configured.*/ - TkMacOSXSetDrawingEnabled(winPtr, 0); - - /* Generate and handle a ConfigureNotify event for the new size.*/ - TkGenWMConfigureEvent(tkwin, Tk_X(tkwin), Tk_Y(tkwin), width, height, - TK_SIZE_CHANGED | TK_MACOSX_HANDLE_EVENT_IMMEDIATELY); - oldProc = Tk_RestrictEvents(ConfigureRestrictProc, NULL, &oldArg); - while (Tk_DoOneEvent(TK_X_EVENTS|TK_DONT_WAIT)) {} - Tk_RestrictEvents(oldProc, oldArg, &oldArg); - - /* Now that Tk has configured all subwindows we can create the clip regions. */ - TkMacOSXSetDrawingEnabled(winPtr, 1); - TkMacOSXInvalClipRgns(tkwin); - TkMacOSXUpdateClipRgn(winPtr); - - /* Finally, generate and process expose events to redraw the window. */ - HIRect bounds = NSRectToCGRect([self bounds]); - HIShapeRef shape = HIShapeCreateWithRect(&bounds); - [self generateExposeEvents: shape]; - while (Tk_DoOneEvent(TK_ALL_EVENTS|TK_DONT_WAIT)) {} - [w enableFlushWindow]; - [w flushWindowIfNeeded]; - NSEnableScreenUpdates(); - [NSApp _unlockAutoreleasePool]; - } -} - -/* - * As insurance against bugs that might cause layout glitches during a live - * resize, we redraw the window one more time at the end of the resize - * operation. - */ - -- (void)viewDidEndLiveResize -{ - HIRect bounds = NSRectToCGRect([self bounds]); - HIShapeRef shape = HIShapeCreateWithRect(&bounds); - [super viewDidEndLiveResize]; - [self generateExposeEvents: shape]; -} - -/* Core method of this class: generates expose events for redrawing. If the - * Tcl_ServiceMode is set to TCL_SERVICE_ALL then the expose events will be - * immediately removed from the Tcl event loop and processed. Typically, they - * should be queued, however. - */ -- (void) generateExposeEvents: (HIShapeRef) shape -{ - [self generateExposeEvents:shape childrenOnly:0]; -} - -- (void) generateExposeEvents: (HIShapeRef) shape - childrenOnly: (int) childrenOnly -{ - TkWindow *winPtr = TkMacOSXGetTkWindow([self window]); - unsigned long serial; - CGRect updateBounds; - int updatesNeeded; - - if (!winPtr) { - return; - } - - /* Generate Tk Expose events. */ - HIShapeGetBounds(shape, &updateBounds); - /* All of these events will share the same serial number. */ - serial = LastKnownRequestProcessed(Tk_Display(winPtr)); - updatesNeeded = GenerateUpdates(shape, &updateBounds, winPtr); - - /* Process the Expose events if the service mode is TCL_SERVICE_ALL */ - if (updatesNeeded && Tcl_GetServiceMode() == TCL_SERVICE_ALL) { - ClientData oldArg; - Tk_RestrictProc *oldProc = Tk_RestrictEvents(ExposeRestrictProc, - UINT2PTR(serial), &oldArg); - while (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) {} - Tk_RestrictEvents(oldProc, oldArg, &oldArg); - } -} - -/* - * 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 -{ -#ifdef TK_MAC_DEBUG_EVENTS - TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd); -#endif - XVirtualEvent event; - int x, y; - TkWindow *winPtr = TkMacOSXGetTkWindow([self window]); - Tk_Window tkwin = (Tk_Window) winPtr; - bzero(&event, sizeof(XVirtualEvent)); - event.type = VirtualEvent; - event.serial = LastKnownRequestProcessed(Tk_Display(tkwin)); - event.send_event = false; - event.display = Tk_Display(tkwin); - event.event = Tk_WindowId(tkwin); - event.root = XRootWindow(Tk_Display(tkwin), 0); - event.subwindow = None; - event.time = TkpGetMS(); - XQueryPointer(NULL, winPtr->window, NULL, NULL, - &event.x_root, &event.y_root, &x, &y, &event.state); - Tk_TopCoordsToWindow(tkwin, x, y, &event.x, &event.y); - event.same_screen = true; - event.name = Tk_GetUid("ToolbarButton"); - Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL); -} - -- (BOOL) isOpaque -{ - NSWindow *w = [self window]; - - if (opaqueTag) { - return YES; - } else { - - return (w && (([w styleMask] & NSTexturedBackgroundWindowMask) || - ![w isOpaque]) ? NO : YES); - } -} - -- (BOOL) wantsDefaultClipping -{ - return NO; -} - -- (BOOL) acceptsFirstResponder -{ - return YES; -} - -- (void) keyDown: (NSEvent *) theEvent -{ -#ifdef TK_MAC_DEBUG_EVENTS - TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent); -#endif -} - -@end - -/* - * Local Variables: - * mode: objc - * c-basic-offset: 4 - * fill-column: 79 - * coding: utf-8 - * End: - */ |