summaryrefslogtreecommitdiffstats
path: root/generic/ttk
diff options
context:
space:
mode:
authorjenglish <jenglish@flightlab.com>2009-02-09 01:45:45 (GMT)
committerjenglish <jenglish@flightlab.com>2009-02-09 01:45:45 (GMT)
commit469c326d047ae0d60d8da25d61a997bef8d3d749 (patch)
treeec0bae89264b8913a3f30c9c5801cb969400664e /generic/ttk
parenta7f3e6b8652f5d9ea2c4db8a47c14033cb559466 (diff)
downloadtk-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.c4
-rw-r--r--generic/ttk/ttkTrack.c39
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);