Allow safely disabling touch events from a touch event handler
Don't delete the window wxWindowGesturesData when calling EnableTouchEvents(wxTOUCH_NONE) but just free it, to make it safe to call EnableTouchEvents() even from a touch event handler, which later returns to wxGTK code that could still use the gestures data object.
This commit is contained in:
@@ -244,8 +244,21 @@ namespace
|
|||||||
class wxWindowGesturesData
|
class wxWindowGesturesData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
wxWindowGesturesData(wxWindow* win, GtkWidget *widget, int eventsMask);
|
// This class has rather unusual "resurrectable" semantics: it is
|
||||||
~wxWindowGesturesData();
|
// initialized by the ctor as usual, but may then be uninitialized by
|
||||||
|
// calling Free() and re-initialized again by calling Reinit().
|
||||||
|
wxWindowGesturesData(wxWindow* win, GtkWidget *widget, int eventsMask)
|
||||||
|
{
|
||||||
|
Reinit(win, widget, eventsMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
~wxWindowGesturesData()
|
||||||
|
{
|
||||||
|
Free();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reinit(wxWindow* win, GtkWidget *widget, int eventsMask);
|
||||||
|
void Free();
|
||||||
|
|
||||||
unsigned int m_touchCount;
|
unsigned int m_touchCount;
|
||||||
unsigned int m_lastTouchTime;
|
unsigned int m_lastTouchTime;
|
||||||
@@ -3370,9 +3383,9 @@ touch_callback(GtkWidget* WXUNUSED(widget), GdkEventTouch* gdk_event, wxWindowGT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wxWindowGesturesData::wxWindowGesturesData(wxWindowGTK* win,
|
void wxWindowGesturesData::Reinit(wxWindowGTK* win,
|
||||||
GtkWidget *widget,
|
GtkWidget *widget,
|
||||||
int eventsMask)
|
int eventsMask)
|
||||||
{
|
{
|
||||||
m_touchCount = 0;
|
m_touchCount = 0;
|
||||||
m_lastTouchTime = 0;
|
m_lastTouchTime = 0;
|
||||||
@@ -3500,18 +3513,13 @@ wxWindowGesturesData::wxWindowGesturesData(wxWindowGTK* win,
|
|||||||
G_CALLBACK(touch_callback), win);
|
G_CALLBACK(touch_callback), win);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxWindowGesturesData::~wxWindowGesturesData()
|
void wxWindowGesturesData::Free()
|
||||||
{
|
{
|
||||||
if ( m_vertical_pan_gesture )
|
g_clear_object(&m_vertical_pan_gesture);
|
||||||
g_object_unref(m_vertical_pan_gesture);
|
g_clear_object(&m_horizontal_pan_gesture);
|
||||||
if ( m_horizontal_pan_gesture )
|
g_clear_object(&m_zoom_gesture);
|
||||||
g_object_unref(m_horizontal_pan_gesture);
|
g_clear_object(&m_rotate_gesture);
|
||||||
if ( m_zoom_gesture )
|
g_clear_object(&m_long_press_gesture);
|
||||||
g_object_unref(m_zoom_gesture);
|
|
||||||
if ( m_rotate_gesture )
|
|
||||||
g_object_unref(m_rotate_gesture);
|
|
||||||
if ( m_long_press_gesture )
|
|
||||||
g_object_unref(m_long_press_gesture);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // wxGTK_HAS_GESTURES_SUPPORT
|
#endif // wxGTK_HAS_GESTURES_SUPPORT
|
||||||
@@ -3526,17 +3534,30 @@ bool wxWindowGTK::EnableTouchEvents(int eventsMask)
|
|||||||
// Check if gestures support is also available during run-time.
|
// Check if gestures support is also available during run-time.
|
||||||
if ( gtk_check_version(3, 14, 0) == NULL )
|
if ( gtk_check_version(3, 14, 0) == NULL )
|
||||||
{
|
{
|
||||||
|
wxWindowGesturesData* const dataOld = wxWindowGestures::FromObject(this);
|
||||||
|
|
||||||
if ( eventsMask == wxTOUCH_NONE )
|
if ( eventsMask == wxTOUCH_NONE )
|
||||||
{
|
{
|
||||||
wxWindowGestures::EraseForObject(this);
|
// Reset the gestures data used by this object, but don't destroy
|
||||||
|
// it, as we could be called from an event handler, in which case
|
||||||
|
// this object could be still used after the event handler returns.
|
||||||
|
if ( dataOld )
|
||||||
|
dataOld->Free();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wxWindowGestures::StoreForObject
|
GtkWidget* const widget = GetConnectWidget();
|
||||||
(
|
|
||||||
this,
|
if ( dataOld )
|
||||||
new wxWindowGesturesData(this, GetConnectWidget(), eventsMask)
|
{
|
||||||
);
|
dataOld->Reinit(this, widget, eventsMask);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wxWindowGesturesData* const
|
||||||
|
dataNew = new wxWindowGesturesData(this, widget, eventsMask);
|
||||||
|
wxWindowGestures::StoreForObject(this, dataNew);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
Reference in New Issue
Block a user