summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorculler <culler>2024-06-24 20:09:11 (GMT)
committerculler <culler>2024-06-24 20:09:11 (GMT)
commitf8087a27cf185e1321edaf4f8a612a71b99a84e2 (patch)
treefd3fd0c6598d742f9198ebfe443838a7d25dc770
parent63a7ddde3c69911327cd98cd3dbb71ed214c2d8b (diff)
downloadtk-f8087a27cf185e1321edaf4f8a612a71b99a84e2.zip
tk-f8087a27cf185e1321edaf4f8a612a71b99a84e2.tar.gz
tk-f8087a27cf185e1321edaf4f8a612a71b99a84e2.tar.bz2
Avoid redrawing the entire view each time a widget is mapped by the grid manager.
-rw-r--r--macosx/tkMacOSXPrivate.h1
-rw-r--r--macosx/tkMacOSXSubwindows.c51
-rw-r--r--macosx/tkMacOSXWm.c7
3 files changed, 32 insertions, 27 deletions
diff --git a/macosx/tkMacOSXPrivate.h b/macosx/tkMacOSXPrivate.h
index 94b8b3b..c4352a0 100644
--- a/macosx/tkMacOSXPrivate.h
+++ b/macosx/tkMacOSXPrivate.h
@@ -247,6 +247,7 @@ MODULE_SCOPE void TkMacOSXRestoreDrawingContext(
TkMacOSXDrawingContext *dcPtr);
MODULE_SCOPE void TkMacOSXSetColorInContext(GC gc, unsigned long pixel,
CGContextRef context);
+MODULE_SCOPE void TkMacOSXRedrawViewIdleTask(void *clientData);
#define TkMacOSXGetTkWindow(window) ((TkWindow *)Tk_MacOSXGetTkWindow(window))
#define TkMacOSXGetNSWindowForDrawable(drawable) ((NSWindow *)Tk_MacOSXGetNSWindowForDrawable(drawable))
#define TkMacOSXGetNSViewForDrawable(macWin) ((NSView *)Tk_MacOSXGetNSViewForDrawable((Drawable)(macWin)))
diff --git a/macosx/tkMacOSXSubwindows.c b/macosx/tkMacOSXSubwindows.c
index 4ac69eb..3da0492 100644
--- a/macosx/tkMacOSXSubwindows.c
+++ b/macosx/tkMacOSXSubwindows.c
@@ -56,7 +56,8 @@ XDestroyWindow(
Window window) /* Window. */
{
MacDrawable *macWin = (MacDrawable *)window;
- // fprintf(stderr, "XDestroyWindow: %s with parent %s\n",
+ TKContentView *view = (TKContentView *)TkMacOSXGetNSViewForDrawable(macWin);
+ //fprintf(stderr, "XDestroyWindow: %s with parent %s\n",
// Tk_PathName(macWin->winPtr),
// Tk_PathName(macWin->winPtr->parentPtr));
@@ -71,7 +72,9 @@ XDestroyWindow(
if (!Tk_IsTopLevel(macWin->winPtr)) {
if (macWin->winPtr->parentPtr != NULL) {
- TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
+ TkMacOSXInvalClipRgns(macWin->winPtr->parentPtr);
+ Tcl_CancelIdleCall(TkMacOSXRedrawViewIdleTask, (void *) view);
+ Tcl_DoWhenIdle(TkMacOSXRedrawViewIdleTask, (void *) view);
}
if (macWin->visRgn) {
CFRelease(macWin->visRgn);
@@ -149,11 +152,10 @@ XMapWindow(
return BadWindow;
}
MacDrawable *macWin = (MacDrawable *)window;
- TkWindow *winPtr = macWin->winPtr;
- NSWindow *win = TkMacOSXGetNSWindowForDrawable(window);
static Bool initialized = NO;
NSPoint mouse = [NSEvent mouseLocation];
int x = mouse.x, y = TkMacOSXZeroScreenHeight() - mouse.y;
+ //fprintf(stderr, "XMapWindow: %s\n", Tk_PathName(macWin->winPtr));
/*
* Under certain situations it's possible for this function to be called
@@ -167,10 +169,12 @@ XMapWindow(
TkMacOSXMakeRealWindowExist(macWin->toplevel->winPtr);
}
+ TkWindow *winPtr = macWin->winPtr;
+ NSWindow *win = TkMacOSXGetNSWindowForDrawable(window);
+ TKContentView *view = [win contentView];
LastKnownRequestProcessed(display)++;
if (Tk_IsTopLevel(winPtr)) {
if (!Tk_IsEmbedded(winPtr)) {
- TKContentView *view = [win contentView];
/*
* We want to activate Tk when a toplevel is mapped but we must not
@@ -210,7 +214,6 @@ XMapWindow(
TkMacOSXInvalClipRgns(contWinPtr);
}
- TkMacOSXInvalClipRgns((Tk_Window)winPtr);
} else {
/*
@@ -222,20 +225,13 @@ XMapWindow(
}
/*
- * Mark the toplevel as needing to be redrawn, unless the window is being
- * mapped while drawing is taking place.
+ * If a geometry manager is mapping hundreds of windows we
+ * don't want to redraw the view hundreds of times, so do
+ * it in an idle task.
*/
- TKContentView *view = [win contentView];
-
- /*
- * Do not rely on addTkDirtyRect: to generate Expose events
- * (though I’m not sure if this is the place to generate events;
- * or if using generateExposeEvents: is the best way;
- * what does XMapWindow() do on other platforms?)
- */
- // Possibly this only needs to use the widget bounds.
- [view generateExposeEvents:[view bounds]];
+ Tcl_CancelIdleCall(TkMacOSXRedrawViewIdleTask, (void *) view);
+ Tcl_DoWhenIdle(TkMacOSXRedrawViewIdleTask, (void *) view);
/*
* Generate VisibilityNotify events for window and all mapped children.
@@ -365,14 +361,6 @@ XUnmapWindow(
*/
TkMacOSXInvalClipRgns((Tk_Window)winPtr->parentPtr);
- //TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
- // if (parentPtr && parentPtr->privatePtr->visRgn) {
- // TkMacOSXInvalidateViewRegion(
- // TkMacOSXGetNSViewForDrawable(parentPtr->window),
- // parentPtr->privatePtr->visRgn);
- // }
- //TkMacOSXInvalClipRgns((Tk_Window)parentPtr);
- //TkMacOSXUpdateClipRgn(parentPtr);
}
return Success;
}
@@ -1073,6 +1061,15 @@ TkMacOSXInvalidateViewRegion(
*
*----------------------------------------------------------------------
*/
+void
+TkMacOSXRedrawViewIdleTask(
+ void *clientData)
+{
+ TKContentView *view = (TKContentView *) clientData;
+ // fprintf(stderr, "idle redraw for %p\n", view);
+ [view generateExposeEvents:[view bounds]];
+ [view setTkNeedsDisplay:YES];
+}
void
TkMacOSXInvalidateWindow(
@@ -1091,8 +1088,8 @@ TkMacOSXInvalidateWindow(
if ((flag == TK_PARENT_WINDOW) && parent){
TkMacOSXInvalClipRgns(parent);
}
- // Here we should probably be using the damage region.
[view generateExposeEvents:[view bounds]];
+ [view setTkNeedsDisplay:YES];
}
/*
diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c
index 647c2fd..115060d 100644
--- a/macosx/tkMacOSXWm.c
+++ b/macosx/tkMacOSXWm.c
@@ -1314,6 +1314,13 @@ TkWmDeadWindow(
[NSApp _setKeyWindow:nil];
[NSApp _setMainWindow:nil];
}
+
+ /*
+ * Avoid redrawing the view after it is released.
+ */
+
+ Tcl_CancelIdleCall(TkMacOSXRedrawViewIdleTask,
+ (void *) [deadNSWindow contentView]);
[deadNSWindow close];
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];