summaryrefslogtreecommitdiffstats
path: root/generic/ttk/ttkTrack.c
diff options
context:
space:
mode:
authorhobbs <hobbs>2010-08-26 02:06:08 (GMT)
committerhobbs <hobbs>2010-08-26 02:06:08 (GMT)
commitb29adcfbfc2e03e058536524f1aa3378b948e7ed (patch)
treefa90e1e6d32590addfbb0a1599a40b1f7f99ea3b /generic/ttk/ttkTrack.c
parent7dec1714e5d5efd6b7d095657c1434fa68af0f87 (diff)
downloadtk-b29adcfbfc2e03e058536524f1aa3378b948e7ed.zip
tk-b29adcfbfc2e03e058536524f1aa3378b948e7ed.tar.gz
tk-b29adcfbfc2e03e058536524f1aa3378b948e7ed.tar.bz2
Major backport of 8.6 Ttk for 8.5.9. Most changes were only being
committed to head (8.6), although they could apply for 8.5 as well. This re-sync makes future work easier to maintain and adds some useful work for 8.5 users. Notable changes: - Lots of code cleanup - Some bug fixes never backported - Addition of ttk::spinbox - minor color changes - Improved Vista/7 styling - Move to tile version 0.8.6 (pseudo-package) - ABI and API compatible (even $w identify) - minor new features (extended $w identify)
Diffstat (limited to 'generic/ttk/ttkTrack.c')
-rw-r--r--generic/ttk/ttkTrack.c75
1 files changed, 42 insertions, 33 deletions
diff --git a/generic/ttk/ttkTrack.c b/generic/ttk/ttkTrack.c
index d6e89fa..c129e8b 100644
--- a/generic/ttk/ttkTrack.c
+++ b/generic/ttk/ttkTrack.c
@@ -1,4 +1,4 @@
-/* $Id: ttkTrack.c,v 1.4 2007/12/13 15:26:26 dgp Exp $
+/* $Id: ttkTrack.c,v 1.4.2.1 2010/08/26 02:06:10 hobbs Exp $
* Copyright (c) 2004, Joe English
*
* TtkTrackElementState() -- helper routine for widgets
@@ -27,11 +27,11 @@
#include "ttkTheme.h"
#include "ttkWidget.h"
-typedef struct
-{
- WidgetCore *corePtr; /* Widget to track */
- Ttk_LayoutNode *activeElement; /* element under the mouse cursor */
- Ttk_LayoutNode *pressedElement; /* currently pressed element */
+typedef struct {
+ WidgetCore *corePtr; /* widget to track */
+ Ttk_Layout tracking; /* current layout being tracked */
+ Ttk_Element activeElement; /* element under the mouse cursor */
+ Ttk_Element pressedElement; /* currently pressed element */
} ElementStateTracker;
/*
@@ -42,9 +42,9 @@ typedef struct
* The active element has TTK_STATE_ACTIVE set _unless_
* another element is 'pressed'
*/
-static void ActivateElement(ElementStateTracker *es, Ttk_LayoutNode *node)
+static void ActivateElement(ElementStateTracker *es, Ttk_Element element)
{
- if (es->activeElement == node) {
+ if (es->activeElement == element) {
/* No change */
return;
}
@@ -53,15 +53,15 @@ static void ActivateElement(ElementStateTracker *es, Ttk_LayoutNode *node)
if (es->activeElement) {
/* Deactivate old element */
Ttk_ChangeElementState(es->activeElement, 0,TTK_STATE_ACTIVE);
- }
- if (node) {
+ }
+ if (element) {
/* Activate new element */
- Ttk_ChangeElementState(node, TTK_STATE_ACTIVE,0);
+ Ttk_ChangeElementState(element, TTK_STATE_ACTIVE,0);
}
TtkRedisplayWidget(es->corePtr);
}
- es->activeElement = node;
+ es->activeElement = element;
}
/* ReleaseElement --
@@ -87,18 +87,18 @@ static void ReleaseElement(ElementStateTracker *es)
/* PressElement --
* Presses the specified element.
*/
-static void PressElement(ElementStateTracker *es, Ttk_LayoutNode *node)
+static void PressElement(ElementStateTracker *es, Ttk_Element element)
{
if (es->pressedElement) {
ReleaseElement(es);
}
- if (node) {
+ if (element) {
Ttk_ChangeElementState(
- node, TTK_STATE_PRESSED|TTK_STATE_ACTIVE, 0);
+ element, TTK_STATE_PRESSED|TTK_STATE_ACTIVE, 0);
}
- es->pressedElement = node;
+ es->pressedElement = element;
TtkRedisplayWidget(es->corePtr);
}
@@ -107,10 +107,10 @@ static void PressElement(ElementStateTracker *es, Ttk_LayoutNode *node)
*/
static const unsigned ElementStateMask =
- ButtonPressMask
- | ButtonReleaseMask
- | PointerMotionMask
- | LeaveWindowMask
+ ButtonPressMask
+ | ButtonReleaseMask
+ | PointerMotionMask
+ | LeaveWindowMask
| EnterWindowMask
| StructureNotifyMask
;
@@ -118,15 +118,23 @@ static const unsigned ElementStateMask =
static void
ElementStateEventProc(ClientData clientData, XEvent *ev)
{
- ElementStateTracker *es = (ElementStateTracker *)clientData;
- Ttk_LayoutNode *node;
+ ElementStateTracker *es = clientData;
+ Ttk_Layout layout = es->corePtr->layout;
+ Ttk_Element element;
+
+ /* Guard against dangling pointers [#2431428]
+ */
+ if (es->tracking != layout) {
+ es->pressedElement = es->activeElement = 0;
+ es->tracking = layout;
+ }
switch (ev->type)
{
case MotionNotify :
- node = Ttk_LayoutIdentify(
- es->corePtr->layout,ev->xmotion.x,ev->xmotion.y);
- ActivateElement(es, node);
+ element = Ttk_IdentifyElement(
+ layout, ev->xmotion.x, ev->xmotion.y);
+ ActivateElement(es, element);
break;
case LeaveNotify:
ActivateElement(es, 0);
@@ -134,21 +142,21 @@ ElementStateEventProc(ClientData clientData, XEvent *ev)
PressElement(es, 0);
break;
case EnterNotify:
- node = Ttk_LayoutIdentify(
- es->corePtr->layout,ev->xcrossing.x,ev->xcrossing.y);
- ActivateElement(es, node);
+ element = Ttk_IdentifyElement(
+ layout, ev->xcrossing.x, ev->xcrossing.y);
+ ActivateElement(es, element);
break;
case ButtonPress:
- node = Ttk_LayoutIdentify(
- es->corePtr->layout, ev->xbutton.x, ev->xbutton.y);
- if (node)
- PressElement(es, node);
+ element = Ttk_IdentifyElement(
+ layout, ev->xbutton.x, ev->xbutton.y);
+ if (element)
+ PressElement(es, element);
break;
case ButtonRelease:
ReleaseElement(es);
break;
case DestroyNotify:
- /* Unregister this event handler and free client data.
+ /* Unregister this event handler and free client data.
*/
Tk_DeleteEventHandler(es->corePtr->tkwin,
ElementStateMask, ElementStateEventProc, es);
@@ -167,6 +175,7 @@ void TtkTrackElementState(WidgetCore *corePtr)
{
ElementStateTracker *es = (ElementStateTracker*)ckalloc(sizeof(*es));
es->corePtr = corePtr;
+ es->tracking = 0;
es->activeElement = es->pressedElement = 0;
Tk_CreateEventHandler(corePtr->tkwin,
ElementStateMask,ElementStateEventProc,es);