diff options
Diffstat (limited to 'generic/ttk/ttkTrack.c')
-rw-r--r-- | generic/ttk/ttkTrack.c | 75 |
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); |