summaryrefslogtreecommitdiffstats
path: root/macosx/tkMacOSXButton.c
diff options
context:
space:
mode:
authormarc_culler <marc.culler@gmail.com>2020-05-16 18:31:00 (GMT)
committermarc_culler <marc.culler@gmail.com>2020-05-16 18:31:00 (GMT)
commit70edb80093c0a4d1893b1669b9b5d9704b720a4d (patch)
tree850eadce36aa10cd11308890389651f817f53240 /macosx/tkMacOSXButton.c
parent5b8151f29ca6b12d3421c026eae1a994e702f7b5 (diff)
downloadtk-70edb80093c0a4d1893b1669b9b5d9704b720a4d.zip
tk-70edb80093c0a4d1893b1669b9b5d9704b720a4d.tar.gz
tk-70edb80093c0a4d1893b1669b9b5d9704b720a4d.tar.bz2
Fix [40ada90762]: occasional Aqua crash when active button is destroyed - patch from Christopher Chavez.
Diffstat (limited to 'macosx/tkMacOSXButton.c')
-rw-r--r--macosx/tkMacOSXButton.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/macosx/tkMacOSXButton.c b/macosx/tkMacOSXButton.c
index f869350..721dd03 100644
--- a/macosx/tkMacOSXButton.c
+++ b/macosx/tkMacOSXButton.c
@@ -186,9 +186,6 @@ TkpDisplayButton(
DrawParams* dpPtr = &macButtonPtr->drawParams;
int needhighlight = 0;
- if (butPtr->flags & BUTTON_DELETED) {
- return;
- }
butPtr->flags &= ~REDRAW_PENDING;
if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
return;
@@ -1048,7 +1045,14 @@ TkMacOSXComputeButtonParams(
if (drawinfo->state != kThemeStatePressed) {
drawinfo->adornment |= kThemeAdornmentDefault;
}
- if (!mbPtr->defaultPulseHandler) {
+
+ /*
+ * Older macOS systems (10.9 and earlier) use an animation to
+ * indicate the active button. This is simulated by redrawing
+ * the button periodically.
+ */
+
+ if (!mbPtr->defaultPulseHandler && ([NSApp macMinorVersion] <= 9)) {
mbPtr->defaultPulseHandler = Tcl_CreateTimerHandler(
PULSE_TIMER_MSECS, PulseDefaultButtonProc, butPtr);
}
@@ -1178,6 +1182,13 @@ PulseDefaultButtonProc(ClientData clientData)
MacButton *mbPtr = clientData;
TkpDisplayButton(clientData);
+ /*
+ * Fix 40ada90762: any idle calls to TkpDisplayButton need to be canceled
+ * in case the button is destroyed and has its data freed before the idle
+ * event is handled (DestroyButton only cancels calls when REDRAW_PENDING
+ * is set, which is not the case after calling TkpDisplayButton directly).
+ */
+ Tcl_CancelIdleCall(TkpDisplayButton, clientData);
mbPtr->defaultPulseHandler = Tcl_CreateTimerHandler(
PULSE_TIMER_MSECS, PulseDefaultButtonProc, clientData);
}