diff options
author | Kevin Walzer <kw@codebykevin.com> | 2017-04-20 01:47:21 (GMT) |
---|---|---|
committer | Kevin Walzer <kw@codebykevin.com> | 2017-04-20 01:47:21 (GMT) |
commit | 63b6554668963fa5a4b94cd64931e556ad154fcb (patch) | |
tree | 5d519469dc3390324b22ee9e4e7d6950d46e4955 | |
parent | 985621e3f1a0ac065a03f17f846d6004dfc2e827 (diff) | |
download | tk-63b6554668963fa5a4b94cd64931e556ad154fcb.zip tk-63b6554668963fa5a4b94cd64931e556ad154fcb.tar.gz tk-63b6554668963fa5a4b94cd64931e556ad154fcb.tar.bz2 |
1. Fix for segfault with latest version of Xcode on macOS 10.12; thanks to Bill Joye for patch. 2. Improvements to HITheme scroller on macOS: smoother scrolling, and scrollbar now correctly highlights when being pressed and during enter/leave events. Thanks to Tortsen Reincke for bug report (061bf93176a5684a4a855f8177b290c59dd39bf2).
-rw-r--r-- | macosx/tkMacOSXScrlbr.c | 81 | ||||
-rw-r--r-- | macosx/tkMacOSXWm.c | 5 | ||||
-rw-r--r-- | macosx/tkMacOSXWm.h | 4 |
3 files changed, 55 insertions, 35 deletions
diff --git a/macosx/tkMacOSXScrlbr.c b/macosx/tkMacOSXScrlbr.c index 91cf112..6253fff 100644 --- a/macosx/tkMacOSXScrlbr.c +++ b/macosx/tkMacOSXScrlbr.c @@ -19,6 +19,13 @@ #define MIN_SCROLLBAR_VALUE 0 +/* + * Minimum slider length, in pixels (designed to make sure that the slider is + * always easy to grab with the mouse). + */ + +#define MIN_SLIDER_LENGTH 5 + /*Borrowed from ttkMacOSXTheme.c to provide appropriate scaling of scrollbar values.*/ #ifdef __LP64__ #define RangeToFactor(maximum) (((double) (INT_MAX >> 1)) / (maximum)) @@ -60,16 +67,14 @@ typedef struct ScrollbarMetrics { } ScrollbarMetrics; static ScrollbarMetrics metrics[2] = { - {15, 54, 26, 14, 14, NSRegularControlSize}, /* kThemeScrollBarMedium */ - {11, 40, 20, 10, 10, NSSmallControlSize}, /* kThemeScrollBarSmall */ + {15, 54, 26, 14, 14, kControlSizeNormal}, /* kThemeScrollBarMedium */ + {11, 40, 20, 10, 10, kControlSizeSmall}, /* kThemeScrollBarSmall */ }; - HIThemeTrackDrawInfo info = { .version = 0, .min = 0.0, .max = 100.0, .attributes = kThemeTrackShowThumb, - .kind = kThemeScrollBarMedium, }; @@ -107,7 +112,7 @@ TkpCreateScrollbar( scrollPtr->troughGC = None; scrollPtr->copyGC = None; - Tk_CreateEventHandler(tkwin,ExposureMask|StructureNotifyMask|FocusChangeMask|ButtonPressMask|VisibilityChangeMask, ScrollbarEventProc, scrollPtr); + Tk_CreateEventHandler(tkwin,ExposureMask|StructureNotifyMask|FocusChangeMask|ButtonPressMask|ButtonReleaseMask|EnterWindowMask|LeaveWindowMask|VisibilityChangeMask, ScrollbarEventProc, scrollPtr); return (TkScrollbar *) scrollPtr; } @@ -212,7 +217,8 @@ TkpDisplayScrollbar( *---------------------------------------------------------------------- */ -extern void + + extern void TkpComputeScrollbarGeometry( register TkScrollbar *scrollPtr) /* Scrollbar whose geometry may have @@ -259,14 +265,12 @@ TkpComputeScrollbarGeometry( if (scrollPtr->sliderLast > fieldLength) { scrollPtr->sliderLast = fieldLength; } - if (!(MOUNTAIN_LION_STYLE)) { - scrollPtr->sliderFirst += scrollPtr->inset + - metrics[variant].topArrowHeight; - scrollPtr->sliderLast += scrollPtr->inset + - metrics[variant].bottomArrowHeight; - } - /* - * Register the desired geometry for the window (leave enough space + + scrollPtr->sliderFirst += scrollPtr->arrowLength + scrollPtr->inset; + scrollPtr->sliderLast += scrollPtr->arrowLength + scrollPtr->inset; + + + /* Register the desired geometry for the window (leave enough space * for the two arrows plus a minimum-size slider, plus border around * the whole window, if any). Then arrange for the window to be * redisplayed. @@ -281,6 +285,9 @@ TkpComputeScrollbarGeometry( } + + + /* *---------------------------------------------------------------------- * @@ -376,21 +383,22 @@ TkpScrollbarPosition( register const int arrowSize = scrollPtr->arrowLength + inset; if (scrollPtr->vertical) { - length = Tk_Height(scrollPtr->tkwin); - fieldlength = length - 2 * arrowSize; - width = Tk_Width(scrollPtr->tkwin); + length = Tk_Height(scrollPtr->tkwin); + fieldlength = length - 2 * arrowSize; + width = Tk_Width(scrollPtr->tkwin); } else { - tmp = x; - x = y; - y = tmp; - length = Tk_Width(scrollPtr->tkwin); - fieldlength = length - 2 * arrowSize; - width = Tk_Height(scrollPtr->tkwin); + tmp = x; + x = y; + y = tmp; + length = Tk_Width(scrollPtr->tkwin); + fieldlength = length - 2 * arrowSize; + width = Tk_Height(scrollPtr->tkwin); } + fieldlength = fieldlength < 0 ? 0 : fieldlength; if (x<inset || x>=width-inset || y<inset || y>=length-inset) { - return OUTSIDE; + return OUTSIDE; } /* @@ -399,18 +407,19 @@ TkpScrollbarPosition( */ if (y < scrollPtr->sliderFirst) { - return TOP_GAP; + return TOP_GAP; } if (y < scrollPtr->sliderLast) { - return SLIDER; + return SLIDER; } if (y < fieldlength){ - return BOTTOM_GAP; + return BOTTOM_GAP; } if (y < fieldlength + arrowSize) { - return TOP_ARROW; + return TOP_ARROW; } return BOTTOM_ARROW; + } /* @@ -458,7 +467,7 @@ UpdateControlValues( width = contrlRect.size.width; height = contrlRect.size.height; - variant = contrlRect.size.width < metrics[0].width ? 1 : 0; + variant = contrlRect.size.width < metrics[0].width ? 1 : 0; /* * Ensure we set scrollbar control bounds only once all size adjustments @@ -514,8 +523,8 @@ UpdateControlValues( * * ScrollbarPress -- * - * This procedure is invoked in response to <ButtonPress> events. - * Enters a modal loop to handle scrollbar interactions. + * This procedure is invoked in response to <ButtonPress>, <ButtonRelease>, + * <EnterNotify>, and <LeaveNotify> events. Scrollbar appearance is modified. * *-------------------------------------------------------------- */ @@ -526,6 +535,13 @@ ScrollbarPress(TkScrollbar *scrollPtr, XEvent *eventPtr) if (eventPtr->type == ButtonPress) { UpdateControlValues(scrollPtr); + info.trackInfo.scrollbar.pressState = 1; + } + if (eventPtr->type == EnterNotify) { + info.trackInfo.scrollbar.pressState = 1; + } + if (eventPtr->type == ButtonRelease || eventPtr->type == LeaveNotify) { + info.trackInfo.scrollbar.pressState = 0; } return TCL_OK; } @@ -566,6 +582,9 @@ ScrollbarEventProc( TkScrollbarEventuallyRedraw(scrollPtr); break; case ButtonPress: + case ButtonRelease: + case EnterNotify: + case LeaveNotify: ScrollbarPress(clientData, eventPtr); break; default: diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c index 39990e6..75473bf 100644 --- a/macosx/tkMacOSXWm.c +++ b/macosx/tkMacOSXWm.c @@ -2893,17 +2893,20 @@ WmProtocolCmd( } else { prevPtr->nextPtr = protPtr->nextPtr; } + if (protPtr->command) + ckfree(protPtr->command); Tcl_EventuallyFree(protPtr, TCL_DYNAMIC); break; } } cmd = Tcl_GetStringFromObj(objv[4], &cmdLength); if (cmdLength > 0) { - protPtr = ckalloc(HANDLER_SIZE(cmdLength)); + protPtr = ckalloc(sizeof(ProtocolHandler)); protPtr->protocol = protocol; protPtr->nextPtr = wmPtr->protPtr; wmPtr->protPtr = protPtr; protPtr->interp = interp; + protPtr->command = ckalloc(cmdLength+1); strcpy(protPtr->command, cmd); } return TCL_OK; diff --git a/macosx/tkMacOSXWm.h b/macosx/tkMacOSXWm.h index 0a128ef..e904f50 100644 --- a/macosx/tkMacOSXWm.h +++ b/macosx/tkMacOSXWm.h @@ -29,15 +29,13 @@ typedef struct ProtocolHandler { * same top-level window, or NULL for end of * list. */ Tcl_Interp *interp; /* Interpreter in which to invoke command. */ - char command[]; /* Tcl command to invoke when a client message + char* command; /* Tcl command to invoke when a client message * for this protocol arrives. The actual size * of the structure varies to accommodate the * needs of the actual command. THIS MUST BE * THE LAST FIELD OF THE STRUCTURE. */ } ProtocolHandler; -#define HANDLER_SIZE(cmdLength) \ -((unsigned) (sizeof(ProtocolHandler) + cmdLength + 1)) /* * A data structure of the following type holds window-manager-related |