summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Walzer <kw@codebykevin.com>2017-04-20 01:47:21 (GMT)
committerKevin Walzer <kw@codebykevin.com>2017-04-20 01:47:21 (GMT)
commit63b6554668963fa5a4b94cd64931e556ad154fcb (patch)
tree5d519469dc3390324b22ee9e4e7d6950d46e4955
parent985621e3f1a0ac065a03f17f846d6004dfc2e827 (diff)
downloadtk-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.c81
-rw-r--r--macosx/tkMacOSXWm.c5
-rw-r--r--macosx/tkMacOSXWm.h4
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