Fix missing mouse events when using gesture events in wxGTK

When touch events were enabled, normal mouse move and click events were
not generated any longer. Fix this by doing the following two things:

First, emulate the LeftDown, LeftUp, and Motion events, that are no
longer triggered when using the "touch-event".

In addition, remove GDK_BUTTON1_MASK in the press callback, that is
never set when using a mouse, but that is set for some reason by GTK
when using a touchscreen.

See https://github.com/wxWidgets/wxWidgets/pull/2539

Closes #19265.

Signed-off-by: Thierry Bultel <tbultel@free.fr>
This commit is contained in:
Thierry Bultel
2021-09-27 14:00:16 +02:00
committed by Vadim Zeitlin
parent e2aca9cbd5
commit 746da37c4d

View File

@@ -1594,6 +1594,13 @@ gtk_window_button_press_callback( GtkWidget* WXUNUSED_IN_GTK3(widget),
GdkEventButton *gdk_event,
wxWindowGTK *win )
{
/*
GTK does not set the button1 mask when the event comes from the left
button of a mouse. but for some reason, it sets it when the event comes
from a touchscreen, so we simply remove it here for consistency.
*/
gdk_event->state &= ~GDK_BUTTON1_MASK;
wxPROCESS_EVENT_ONCE(GdkEventButton, gdk_event);
wxCOMMON_CALLBACK_PROLOGUE(gdk_event, win);
@@ -3371,9 +3378,91 @@ wxEmitPressAndTapEvent(GdkEventTouch* gdk_event, wxWindow* win)
win->GTKProcessEvent(event);
}
namespace
{
template <typename EventType>
void
wxEventMouseFromEventTouch(EventType* event,
const GdkEventTouch* gdk_event_touch)
{
event->window = gdk_event_touch->window;
event->send_event = gdk_event_touch->send_event;
event->time = gdk_event_touch->time;
event->x = gdk_event_touch->x;
event->y = gdk_event_touch->y;
event->axes = gdk_event_touch->axes;
event->state = gdk_event_touch->state;
event->device = gdk_event_touch->device;
event->x_root = gdk_event_touch->x_root;
event->y_root = gdk_event_touch->y_root;
}
void
wxEventButtonFromEventTouch(GdkEventButton* gdk_event_button,
const GdkEventTouch* gdk_event_touch)
{
wxEventMouseFromEventTouch(gdk_event_button, gdk_event_touch);
gdk_event_button->type = GDK_BUTTON_PRESS;
gdk_event_button->button = 1; // left button
}
void
wxEventMotionFromEventTouch(GdkEventMotion* gdk_event_motion,
const GdkEventTouch* gdk_event_touch)
{
wxEventMouseFromEventTouch(gdk_event_motion, gdk_event_touch);
gdk_event_motion->type = GDK_MOTION_NOTIFY;
gdk_event_motion->is_hint = true;
}
void
wxEmulateLeftDownEvent(GtkWidget* widget, GdkEventTouch* gdk_event, wxWindow* win)
{
GdkEventButton gdk_event_button;
if (!gdk_event->emulating_pointer)
return;
wxEventButtonFromEventTouch(&gdk_event_button, gdk_event);
gtk_window_button_press_callback( widget,
&gdk_event_button,
win );
}
void
wxEmulateLeftUpEvent(GtkWidget* widget,GdkEventTouch* gdk_event, wxWindow* win)
{
GdkEventButton gdk_event_button;
if (!gdk_event->emulating_pointer)
return;
wxEventButtonFromEventTouch(&gdk_event_button, gdk_event);
gtk_window_button_release_callback( widget,
&gdk_event_button,
win );
}
void
wxEmulateMotionEvent(GtkWidget* widget, GdkEventTouch* gdk_event, wxWindow* win)
{
GdkEventMotion gdk_event_motion;
if (!gdk_event->emulating_pointer)
return;
wxEventMotionFromEventTouch(&gdk_event_motion, gdk_event);
gtk_window_motion_notify_callback(widget, &gdk_event_motion, win);
}
} // anonymous namespace
extern "C" {
static void
touch_callback(GtkWidget* WXUNUSED(widget), GdkEventTouch* gdk_event, wxWindow* win)
touch_callback(GtkWidget* widget, GdkEventTouch* gdk_event, wxWindow* win)
{
wxWindowGesturesData* const data = wxWindowGestures::FromObject(win);
if ( !data )
@@ -3382,6 +3471,7 @@ touch_callback(GtkWidget* WXUNUSED(widget), GdkEventTouch* gdk_event, wxWindow*
switch ( gdk_event->type )
{
case GDK_TOUCH_BEGIN:
wxEmulateLeftDownEvent(widget, gdk_event, win);
data->m_touchCount++;
data->m_allowedGestures &= ~two_finger_tap;
@@ -3411,6 +3501,7 @@ touch_callback(GtkWidget* WXUNUSED(widget), GdkEventTouch* gdk_event, wxWindow*
break;
case GDK_TOUCH_UPDATE:
wxEmulateMotionEvent(widget, gdk_event, win);
// If press and tap gesture is active and touch corresponding to that gesture is moving
if ( (data->m_activeGestures & press_and_tap) && gdk_event->sequence == data->m_touchSequence )
{
@@ -3421,6 +3512,7 @@ touch_callback(GtkWidget* WXUNUSED(widget), GdkEventTouch* gdk_event, wxWindow*
case GDK_TOUCH_END:
case GDK_TOUCH_CANCEL:
wxEmulateLeftUpEvent(widget, gdk_event, win);
data->m_touchCount--;
if ( data->m_touchCount == 1 )