Use wxExternalField for gestures data in wxGTK too

Don't waste memory on gesture data in all windows.
This commit is contained in:
Vadim Zeitlin
2017-11-22 00:14:09 +01:00
parent 6fd435b83f
commit 1863f494f3
2 changed files with 44 additions and 25 deletions

View File

@@ -358,11 +358,6 @@ public:
wxRegion m_nativeUpdateRegion; // not transformed for RTL wxRegion m_nativeUpdateRegion; // not transformed for RTL
#if defined(__WXGTK3__)
// Data used for gesture support, if available.
class wxWindowGesturesData* m_gesturesData;
#endif // __WXGTK3__
protected: protected:
// implement the base class pure virtuals // implement the base class pure virtuals
virtual void DoGetTextExtent(const wxString& string, virtual void DoGetTextExtent(const wxString& string,

View File

@@ -234,6 +234,12 @@ static bool gs_inSizeAllocate;
#ifdef wxGTK_HAS_GESTURES_SUPPORT #ifdef wxGTK_HAS_GESTURES_SUPPORT
#include "wx/hashmap.h"
#include "wx/private/extfield.h"
namespace
{
// Per-window data for gestures support. // Per-window data for gestures support.
class wxWindowGesturesData class wxWindowGesturesData
{ {
@@ -256,6 +262,16 @@ public:
GtkGesture* m_long_press_gesture; GtkGesture* m_long_press_gesture;
}; };
WX_DECLARE_HASH_MAP(wxWindow*, wxWindowGesturesData*,
wxPointerHash, wxPointerEqual,
wxWindowGesturesMap);
typedef wxExternalField<wxWindow,
wxWindowGesturesData,
wxWindowGesturesMap> wxWindowGestures;
} // anonymous namespace
// This is true when the gesture has just started (currently used for pan gesture only) // This is true when the gesture has just started (currently used for pan gesture only)
static bool gs_gestureStart = false; static bool gs_gestureStart = false;
@@ -2475,10 +2491,6 @@ void wxWindowGTK::Init()
m_imKeyEvent = NULL; m_imKeyEvent = NULL;
m_dirtyTabOrder = false; m_dirtyTabOrder = false;
#ifdef wxGTK_HAS_GESTURES_SUPPORT
m_gesturesData = NULL;
#endif // wxGTK_HAS_GESTURES_SUPPORT
} }
wxWindowGTK::wxWindowGTK() wxWindowGTK::wxWindowGTK()
@@ -2675,7 +2687,7 @@ wxWindowGTK::~wxWindowGTK()
#endif #endif
#ifdef wxGTK_HAS_GESTURES_SUPPORT #ifdef wxGTK_HAS_GESTURES_SUPPORT
delete m_gesturesData; wxWindowGestures::EraseForWindow(this);
#endif // wxGTK_HAS_GESTURES_SUPPORT #endif // wxGTK_HAS_GESTURES_SUPPORT
if (m_widget) if (m_widget)
@@ -2911,7 +2923,9 @@ pan_gesture_begin_callback(GtkGesture* WXUNUSED(gesture), GdkEventSequence* WXUN
static void static void
horizontal_pan_gesture_end_callback(GtkGesture* gesture, GdkEventSequence* sequence, wxWindowGTK* win) horizontal_pan_gesture_end_callback(GtkGesture* gesture, GdkEventSequence* sequence, wxWindowGTK* win)
{ {
wxWindowGesturesData* const data = win->m_gesturesData; wxWindowGesturesData* const data = wxWindowGestures::FromWindow(win);
if ( !data )
return;
// Do not process horizontal pan, if there was no "pan" signal for it. // Do not process horizontal pan, if there was no "pan" signal for it.
if ( !(data->m_allowedGestures & horizontal_pan) ) if ( !(data->m_allowedGestures & horizontal_pan) )
@@ -2940,7 +2954,9 @@ horizontal_pan_gesture_end_callback(GtkGesture* gesture, GdkEventSequence* seque
static void static void
vertical_pan_gesture_end_callback(GtkGesture* gesture, GdkEventSequence* sequence, wxWindowGTK* win) vertical_pan_gesture_end_callback(GtkGesture* gesture, GdkEventSequence* sequence, wxWindowGTK* win)
{ {
wxWindowGesturesData* const data = win->m_gesturesData; wxWindowGesturesData* const data = wxWindowGestures::FromWindow(win);
if ( !data )
return;
// Do not process vertical pan, if there was no "pan" signal for it. // Do not process vertical pan, if there was no "pan" signal for it.
if ( !(data->m_allowedGestures & vertical_pan) ) if ( !(data->m_allowedGestures & vertical_pan) )
@@ -2990,7 +3006,9 @@ pan_gesture_callback(GtkGesture* gesture, GtkPanDirection direction, gdouble off
event.SetEventObject(win); event.SetEventObject(win);
event.SetPosition(wxPoint(wxRound(x), wxRound(y))); event.SetPosition(wxPoint(wxRound(x), wxRound(y)));
wxWindowGesturesData* const data = win->m_gesturesData; wxWindowGesturesData* const data = wxWindowGestures::FromWindow(win);
if ( !data )
return;
// This is the difference between this and the last pan gesture event in the current sequence // This is the difference between this and the last pan gesture event in the current sequence
int delta = wxRound(offset - gs_lastOffset); int delta = wxRound(offset - gs_lastOffset);
@@ -3052,7 +3070,9 @@ zoom_gesture_callback(GtkGesture* gesture, gdouble scale, wxWindowGTK* win)
event.SetPosition(wxPoint(wxRound(x), wxRound(y))); event.SetPosition(wxPoint(wxRound(x), wxRound(y)));
event.SetZoomFactor(scale); event.SetZoomFactor(scale);
wxWindowGesturesData* const data = win->m_gesturesData; wxWindowGesturesData* const data = wxWindowGestures::FromWindow(win);
if ( !data )
return;
// Cancel "Two FInger Tap Event" if scale has changed // Cancel "Two FInger Tap Event" if scale has changed
if ( wxRound(scale * 1000) != wxRound(gs_lastScale * 1000) ) if ( wxRound(scale * 1000) != wxRound(gs_lastScale * 1000) )
@@ -3190,7 +3210,9 @@ wxEmitTwoFingerTapEvent(GdkEventTouch* gdk_event, wxWindowGTK* win)
event.SetEventObject(win); event.SetEventObject(win);
wxWindowGesturesData* const data = win->m_gesturesData; wxWindowGesturesData* const data = wxWindowGestures::FromWindow(win);
if ( !data )
return;
double lastX = data->m_lastTouchPoint.x; double lastX = data->m_lastTouchPoint.x;
double lastY = data->m_lastTouchPoint.y; double lastY = data->m_lastTouchPoint.y;
@@ -3219,7 +3241,9 @@ wxEmitPressAndTapEvent(GdkEventTouch* gdk_event, wxWindowGTK* win)
event.SetEventObject(win); event.SetEventObject(win);
wxWindowGesturesData* const data = win->m_gesturesData; wxWindowGesturesData* const data = wxWindowGestures::FromWindow(win);
if ( !data )
return;
switch ( data->m_gestureState ) switch ( data->m_gestureState )
{ {
@@ -3249,7 +3273,9 @@ wxEmitPressAndTapEvent(GdkEventTouch* gdk_event, wxWindowGTK* win)
static void static void
touch_callback(GtkWidget* WXUNUSED(widget), GdkEventTouch* gdk_event, wxWindowGTK* win) touch_callback(GtkWidget* WXUNUSED(widget), GdkEventTouch* gdk_event, wxWindowGTK* win)
{ {
wxWindowGesturesData* const data = win->m_gesturesData; wxWindowGesturesData* const data = wxWindowGestures::FromWindow(win);
if ( !data )
return;
switch ( gdk_event->type ) switch ( gdk_event->type )
{ {
@@ -3502,16 +3528,14 @@ bool wxWindowGTK::EnableTouchEvents(int eventsMask)
{ {
if ( eventsMask == wxTOUCH_NONE ) if ( eventsMask == wxTOUCH_NONE )
{ {
delete m_gesturesData; wxWindowGestures::EraseForWindow(this);
m_gesturesData = NULL;
} }
else else
{ {
m_gesturesData = new wxWindowGesturesData wxWindowGestures::StoreForWindow
( (
this, this,
GetConnectWidget(), new wxWindowGesturesData(this, GetConnectWidget(), eventsMask)
eventsMask
); );
} }