summaryrefslogtreecommitdiffstats
path: root/macosx/tkMacOSXWindowEvent.c
diff options
context:
space:
mode:
authorKevin Walzer <kw@codebykevin.com>2015-04-07 01:12:53 (GMT)
committerKevin Walzer <kw@codebykevin.com>2015-04-07 01:12:53 (GMT)
commit991544634825a18479f15f47dbc0f00a5b368505 (patch)
tree613198942a873bcc72239c60dd857e0c8ed72fb4 /macosx/tkMacOSXWindowEvent.c
parent97be0552093b567949f1e78bfc9024dc24fba4e7 (diff)
downloadtk-991544634825a18479f15f47dbc0f00a5b368505.zip
tk-991544634825a18479f15f47dbc0f00a5b368505.tar.gz
tk-991544634825a18479f15f47dbc0f00a5b368505.tar.bz2
Further cleanup of scrolling, drawing, resize in Cocoa; thanks to Marc Culler for patches
Diffstat (limited to 'macosx/tkMacOSXWindowEvent.c')
-rw-r--r--macosx/tkMacOSXWindowEvent.c90
1 files changed, 48 insertions, 42 deletions
diff --git a/macosx/tkMacOSXWindowEvent.c b/macosx/tkMacOSXWindowEvent.c
index d68a933..d0999d1 100644
--- a/macosx/tkMacOSXWindowEvent.c
+++ b/macosx/tkMacOSXWindowEvent.c
@@ -29,7 +29,7 @@
* Declaration of functions used only in this file
*/
-static int GenerateUpdates(HIMutableShapeRef updateRgn,
+static int GenerateUpdates(HIShapeRef updateRgn,
CGRect *updateBounds, TkWindow *winPtr);
static int GenerateActivateEvents(TkWindow *winPtr,
int activeFlag);
@@ -316,7 +316,7 @@ extern BOOL opaqueTag;
static int
GenerateUpdates(
- HIMutableShapeRef updateRgn,
+ HIShapeRef updateRgn,
CGRect *updateBounds,
TkWindow *winPtr)
{
@@ -784,7 +784,8 @@ Tk_MacOSXIsAppInFront(void)
@interface TKContentView(TKWindowEvent)
- (void) drawRect: (NSRect) rect;
-- (void) generateExposeEvents: (HIMutableShapeRef) shape;
+- (void) generateExposeEvents: (HIShapeRef) shape;
+- (void) generateExposeEvents: (HIShapeRef) shape childrenOnly: (int) childrenOnly;
- (void) viewDidEndLiveResize;
- (void) tkToolbarButton: (id) sender;
- (BOOL) isOpaque;
@@ -794,6 +795,8 @@ Tk_MacOSXIsAppInFront(void)
@end
@implementation TKContentView
+NSDate *_resizeStart;
+NSTimeInterval _resizeDuration;
@end
/*Restrict event processing to Expose events.*/
@@ -832,7 +835,7 @@ ExposeRestrictProc(
HIShapeUnionWithRect(drawShape, &r);
}
if (CFRunLoopGetMain() == CFRunLoopGetCurrent()) {
- [self generateExposeEvents:drawShape];
+ [self generateExposeEvents:(HIShapeRef)drawShape];
} else {
[self performSelectorOnMainThread:@selector(generateExposeEvents:)
withObject:(id)drawShape waitUntilDone:NO
@@ -848,25 +851,33 @@ ExposeRestrictProc(
-(void) setFrameSize: (NSSize)newsize
{
if ( [self inLiveResize] ) {
- NSWindow *window = [self window];
- TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
+ 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;
- /* Resize the Tk Window to the requested size.*/
- TkGenWMConfigureEvent(tkwin, Tk_X(tkwin), Tk_Y(tkwin), width, height,
- TK_SIZE_CHANGED | TK_MACOSX_HANDLE_EVENT_IMMEDIATELY);
-
- /* Then resize the NSView to the actual window size*/
- newsize.width = (CGFloat)Tk_Width(tkwin);
- newsize.height = (CGFloat)Tk_Height(tkwin);
+ /* Resize the NSView */
[super setFrameSize: newsize];
- /* Process all pending events to update the window. */
- while (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) {}
- while (Tcl_DoOneEvent(TCL_IDLE_EVENTS|TCL_DONT_WAIT)) {}
+ /* Disable 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);
+ while ( Tk_DoOneEvent(TK_X_EVENTS|TK_DONT_WAIT) ) {}
+
+ /* 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) ) {}
} else {
[super setFrameSize: newsize];
}
@@ -886,48 +897,44 @@ ExposeRestrictProc(
}
-
-/*Core function of this class, generates expose events for redrawing.*/
-- (void) generateExposeEvents: (HIMutableShapeRef) shape
+/* Core method of this class: generates expose events for redrawing.
+ * Whereas drawRect is intended to be called only from the Appkit event
+ * loop, this can be called from Tk. 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));
- if (GenerateUpdates(shape, &updateBounds, winPtr) &&
- ![[NSRunLoop currentRunLoop] currentMode] &&
- Tcl_GetServiceMode() != TCL_SERVICE_NONE) {
- /*
- * Ensure there are no pending idle-time redraws that could
- * prevent the just posted Expose events from generating
- * new redraws.
- */
-
- while (Tcl_DoOneEvent(TCL_IDLE_EVENTS|TCL_DONT_WAIT)) {}
-
- /*
- * For smoother drawing, process Expose events and resulting
- * redraws immediately instead of at idle time.
- */
-
- ClientData oldArg;
+ 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);
-
- while (Tcl_DoOneEvent(TCL_IDLE_EVENTS|TCL_DONT_WAIT)) {}
}
-
}
/*
@@ -943,7 +950,6 @@ ExposeRestrictProc(
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));