diff options
author | jenglish <jenglish@flightlab.com> | 2009-02-09 01:45:45 (GMT) |
---|---|---|
committer | jenglish <jenglish@flightlab.com> | 2009-02-09 01:45:45 (GMT) |
commit | 469c326d047ae0d60d8da25d61a997bef8d3d749 (patch) | |
tree | ec0bae89264b8913a3f30c9c5801cb969400664e /generic/ttk | |
parent | a7f3e6b8652f5d9ea2c4db8a47c14033cb559466 (diff) | |
download | tk-469c326d047ae0d60d8da25d61a997bef8d3d749.zip tk-469c326d047ae0d60d8da25d61a997bef8d3d749.tar.gz tk-469c326d047ae0d60d8da25d61a997bef8d3d749.tar.bz2 |
ElementStateEventProc: Avoid dangling pointers when layout changes
[Fix for #2431428].
Diffstat (limited to 'generic/ttk')
-rw-r--r-- | generic/ttk/ttkLayout.c | 4 | ||||
-rw-r--r-- | generic/ttk/ttkTrack.c | 39 |
2 files changed, 26 insertions, 17 deletions
diff --git a/generic/ttk/ttkLayout.c b/generic/ttk/ttkLayout.c index 7eaf927..7e8ad96 100644 --- a/generic/ttk/ttkLayout.c +++ b/generic/ttk/ttkLayout.c @@ -5,7 +5,7 @@ * * Copyright (c) 2003 Joe English. Freely redistributable. * - * $Id: ttkLayout.c,v 1.15 2009/02/08 19:35:35 jenglish Exp $ + * $Id: ttkLayout.c,v 1.16 2009/02/09 01:45:46 jenglish Exp $ */ #include <string.h> @@ -532,7 +532,7 @@ static Ttk_LayoutNode *Ttk_NewLayoutNode( node->eclass = elementClass; node->state = 0u; node->next = node->child = 0; - /* parcel uninitialized */ + node->parcel = Ttk_MakeBox(0,0,0,0); return node; } diff --git a/generic/ttk/ttkTrack.c b/generic/ttk/ttkTrack.c index 42144d8..a392d94 100644 --- a/generic/ttk/ttkTrack.c +++ b/generic/ttk/ttkTrack.c @@ -1,4 +1,4 @@ -/* $Id: ttkTrack.c,v 1.5 2009/02/08 19:35:35 jenglish Exp $ +/* $Id: ttkTrack.c,v 1.6 2009/02/09 01:45:46 jenglish Exp $ * Copyright (c) 2004, Joe English * * TtkTrackElementState() -- helper routine for widgets @@ -27,9 +27,9 @@ #include "ttkTheme.h" #include "ttkWidget.h" -typedef struct -{ - WidgetCore *corePtr; /* Widget to track */ +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; @@ -53,7 +53,7 @@ static void ActivateElement(ElementStateTracker *es, Ttk_Element element) if (es->activeElement) { /* Deactivate old element */ Ttk_ChangeElementState(es->activeElement, 0,TTK_STATE_ACTIVE); - } + } if (element) { /* Activate new element */ Ttk_ChangeElementState(element, TTK_STATE_ACTIVE,0); @@ -107,10 +107,10 @@ static void PressElement(ElementStateTracker *es, Ttk_Element element) */ static const unsigned ElementStateMask = - ButtonPressMask - | ButtonReleaseMask - | PointerMotionMask - | LeaveWindowMask + ButtonPressMask + | ButtonReleaseMask + | PointerMotionMask + | LeaveWindowMask | EnterWindowMask | StructureNotifyMask ; @@ -118,14 +118,22 @@ static const unsigned ElementStateMask = static void ElementStateEventProc(ClientData clientData, XEvent *ev) { - ElementStateTracker *es = (ElementStateTracker *)clientData; + 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 : element = Ttk_IdentifyElement( - es->corePtr->layout,ev->xmotion.x,ev->xmotion.y); + layout, ev->xmotion.x, ev->xmotion.y); ActivateElement(es, element); break; case LeaveNotify: @@ -135,20 +143,20 @@ ElementStateEventProc(ClientData clientData, XEvent *ev) break; case EnterNotify: element = Ttk_IdentifyElement( - es->corePtr->layout,ev->xcrossing.x,ev->xcrossing.y); + layout, ev->xcrossing.x, ev->xcrossing.y); ActivateElement(es, element); break; case ButtonPress: element = Ttk_IdentifyElement( - es->corePtr->layout, ev->xbutton.x, ev->xbutton.y); - if (element) + 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); |