Attachment "idle_curiosity_2.diff" to
ticket [06d8246b]
added by
chrstphrchvz
2020-05-24 16:02:56.
diff --git macosx/tkMacOSXDraw.c macosx/tkMacOSXDraw.c
index e56e6665d..728033464 100644
--- macosx/tkMacOSXDraw.c
+++ macosx/tkMacOSXDraw.c
@@ -1649,18 +1649,14 @@ TkMacOSXSetupDrawingContext(
if (![NSApp isDrawing] || view != [NSView focusView]) {
NSRect bounds = [view bounds];
NSRect dirtyNS = bounds;
- if ([NSEvent pressedMouseButtons]) {
- [view setNeedsDisplay:YES];
- } else {
- CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1, .tx = 0,
- .ty = dirtyNS.size.height};
- if (dc.clipRgn) {
- CGRect dirtyCG = NSRectToCGRect(dirtyNS);
- HIShapeGetBounds(dc.clipRgn, &dirtyCG);
- dirtyNS = NSRectToCGRect(CGRectApplyAffineTransform(dirtyCG, t));
- }
- [view setNeedsDisplayInRect:dirtyNS];
- }
+ CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1, .tx = 0,
+ .ty = dirtyNS.size.height};
+ if (dc.clipRgn) {
+ CGRect dirtyCG;
+ HIShapeGetBounds(dc.clipRgn, &dirtyCG);
+ dirtyNS = NSRectToCGRect(CGRectApplyAffineTransform(dirtyCG, t));
+ }
+ [view setNeedsDisplayInRect:dirtyNS];
canDraw = false;
goto end;
}
diff --git macosx/tkMacOSXNotify.c macosx/tkMacOSXNotify.c
index 985d7bcb0..00331166c 100644
--- macosx/tkMacOSXNotify.c
+++ macosx/tkMacOSXNotify.c
@@ -32,6 +32,15 @@ static void TkMacOSXNotifyExitHandler(ClientData clientData);
static void TkMacOSXEventsSetupProc(ClientData clientData, int flags);
static void TkMacOSXEventsCheckProc(ClientData clientData, int flags);
+/*
+ * Flag that is set by the first drawRect call, just to have a way to know when
+ * Tk is sufficiently initialized to begin using temoprary idle event loops in
+ * TkMacOSXEventsSetupProc and TkMacOSXEventsCheckProc. Enabling the temporary
+ * loops too early may lead to an empty toplevel appearing for about one second
+ * when Tk is started. See ticket 06d8246baf.
+ */
+bool tkMacOSXHasEnteredDrawRectAtLeastOnce = false;
+
#ifdef TK_MAC_DEBUG_EVENTS
static const char *Tk_EventName[39] = {
"",
@@ -335,10 +344,17 @@ TkMacOSXEventsSetupProc(
[NSApp _resetAutoreleasePool];
/*
- * Call this with dequeue=NO -- just checking if the queue is empty.
+ * Temporary idle event loop (1 of 3): queued idle events are
+ * handled now in order to avoid handling them during drawRect;
+ * otherwise widgets can fail to redraw. See ticket 06d8246baf.
*/
+ if (tkMacOSXHasEnteredDrawRectAtLeastOnce) {
+ while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {}
+ }
- while (Tcl_DoOneEvent(TCL_IDLE_EVENTS|TCL_DONT_WAIT)) {}
+ /*
+ * Call this with dequeue=NO -- just checking if the queue is empty.
+ */
NSEvent *currentEvent =
[NSApp nextEventMatchingMask:NSAnyEventMask
untilDate:[NSDate distantPast]
@@ -408,7 +424,16 @@ TkMacOSXEventsCheckProc(
[NSApp _lockAutoreleasePool];
do {
- while (Tcl_DoOneEvent(TCL_IDLE_EVENTS|TCL_DONT_WAIT)) {}
+
+ /*
+ * Temporary idle event loop (2 of 3): queued idle events are
+ * handled now in order to avoid handling them during drawRect;
+ * otherwise widgets can fail to redraw. See ticket 06d8246baf.
+ */
+ if (tkMacOSXHasEnteredDrawRectAtLeastOnce) {
+ while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {}
+ }
+
modalSession = TkMacOSXGetModalSession();
testEvent = [NSApp nextEventMatchingMask:NSAnyEventMask
untilDate:[NSDate distantPast]
@@ -422,7 +447,16 @@ TkMacOSXEventsCheckProc(
if (testEvent && [[testEvent window] inLiveResize]) {
break;
}
- while (Tcl_DoOneEvent(TCL_IDLE_EVENTS|TCL_DONT_WAIT)) {}
+
+ /*
+ * Temporary idle event loop (3 of 3): queued idle events are
+ * handled now in order to avoid handling them during drawRect;
+ * otherwise widgets can fail to redraw. See ticket 06d8246baf.
+ */
+ if (tkMacOSXHasEnteredDrawRectAtLeastOnce) {
+ while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {}
+ }
+
currentEvent = [NSApp nextEventMatchingMask:NSAnyEventMask
untilDate:[NSDate distantPast]
inMode:GetRunLoopMode(modalSession)
diff --git macosx/tkMacOSXPrivate.h macosx/tkMacOSXPrivate.h
index a0645f785..cd5ccca13 100644
--- macosx/tkMacOSXPrivate.h
+++ macosx/tkMacOSXPrivate.h
@@ -210,6 +210,7 @@ typedef struct TkMacOSXDrawingContext {
*/
MODULE_SCOPE long tkMacOSXMacOSXVersion;
+MODULE_SCOPE bool tkMacOSXHasEnteredDrawRectAtLeastOnce;
/*
* Prototypes for TkMacOSXRegion.c.
diff --git macosx/tkMacOSXWindowEvent.c macosx/tkMacOSXWindowEvent.c
index cb4ffd193..5ea82dcd0 100644
--- macosx/tkMacOSXWindowEvent.c
+++ macosx/tkMacOSXWindowEvent.c
@@ -938,6 +938,7 @@ RedisplayView(
{
const NSRect *rectsBeingDrawn;
NSInteger rectsBeingDrawnCount;
+ tkMacOSXHasEnteredDrawRectAtLeastOnce = true;
#ifdef TK_MAC_DEBUG_DRAWING
TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);