From 9bcf9547a9957b3751faade1bfafd4276c043c29 Mon Sep 17 00:00:00 2001 From: andreas Date: Sat, 1 Dec 2018 22:50:03 +0100 Subject: [PATCH] Disable touch zoom if pen is active --- src/control/tools/StrokeHandler.cpp | 3 ++ src/gui/XournalView.cpp | 50 +++++++++++++++++++++++++++++ src/gui/XournalView.h | 17 ++++++++++ src/gui/widgets/XournalWidget.cpp | 18 ++++++----- 4 files changed, 80 insertions(+), 8 deletions(-) diff --git a/src/control/tools/StrokeHandler.cpp b/src/control/tools/StrokeHandler.cpp index 146d4240..d4f4c632 100644 --- a/src/control/tools/StrokeHandler.cpp +++ b/src/control/tools/StrokeHandler.cpp @@ -286,6 +286,9 @@ bool StrokeHandler::getPressureMultiplier(GdkEvent* event, double& pressure) } // This causes some memory corruption + // If touch and pen is active at the same time + // Here are random crashes. It cannot be reproduced + // without touch and pen at the same time // gdouble* axes = event->button.axes; // gdk_device_get_state(device, // gtk_widget_get_parent_window(xournal->getWidget()), diff --git a/src/gui/XournalView.cpp b/src/gui/XournalView.cpp index c468f115..228b4447 100644 --- a/src/gui/XournalView.cpp +++ b/src/gui/XournalView.cpp @@ -49,6 +49,7 @@ XournalView::XournalView(GtkWidget* parent, Control* control) this->margin = 75; this->currentPage = 0; this->lastSelectedPage = -1; + this->lastPenAction = 0; control->getZoomControl()->addZoomListener(this); @@ -360,11 +361,20 @@ bool XournalView::onKeyReleaseEvent(GdkEventKey* event) void XournalView::onRealized(GtkWidget* widget, XournalView* view) { + XOJ_CHECK_TYPE_OBJ(view, XournalView); + view->setEventCompression(view->getControl()->getSettings()->isEventCompression()); } void XournalView::zoom_gesture_begin_cb(GtkGesture* gesture, GdkEventSequence* sequence, XournalView* view) { + XOJ_CHECK_TYPE_OBJ(view, XournalView); + + if (view->shouldIgnoreTouchEvents()) + { + return; + } + Layout* layout = gtk_xournal_get_layout(view->widget); // Save visible rectangle at beginning of gesture view->visRect_gesture_begin = layout->getVisibleRect(); @@ -379,6 +389,8 @@ void XournalView::zoom_gesture_begin_cb(GtkGesture* gesture, GdkEventSequence* s void XournalView::zoom_gesture_end_cb(GtkGesture* gesture, GdkEventSequence* sequence, XournalView* view) { + XOJ_CHECK_TYPE_OBJ(view, XournalView); + ZoomControl* zoom = view->control->getZoomControl(); zoom->zoom_center_x = -1; zoom->zoom_center_y = -1; @@ -387,6 +399,13 @@ void XournalView::zoom_gesture_end_cb(GtkGesture* gesture, GdkEventSequence* seq void XournalView::zoom_gesture_scale_changed_cb(GtkGestureZoom* gesture, gdouble scale, XournalView* view) { + XOJ_CHECK_TYPE_OBJ(view, XournalView); + + if (view->shouldIgnoreTouchEvents()) + { + return; + } + view->setZoom(scale * view->zoom_gesture_begin); } @@ -557,14 +576,45 @@ Rectangle* XournalView::getVisibleRect(size_t page) Rectangle* XournalView::getVisibleRect(XojPageView* redrawable) { + XOJ_CHECK_TYPE(XournalView); + return gtk_xournal_get_visible_area(this->widget, redrawable); } GtkContainer* XournalView::getParent() { + XOJ_CHECK_TYPE(XournalView); + return this->parent; } +/** + * A pen action was detected now, therefore ignore touch events + * for a short time + */ +void XournalView::penActionDetected() +{ + XOJ_CHECK_TYPE(XournalView); + + this->lastPenAction = g_get_monotonic_time() / 1000; +} + +/** + * If the pen was active a short time before, ignore touch events + */ +bool XournalView::shouldIgnoreTouchEvents() +{ + XOJ_CHECK_TYPE(XournalView); + + if ((g_get_monotonic_time() / 1000 - this->lastPenAction) < 1000) + { + // printf("Ignore touch, pen was active\n"); + return true; + } + + return false; +} + GtkWidget* XournalView::getWidget() { XOJ_CHECK_TYPE(XournalView); diff --git a/src/gui/XournalView.h b/src/gui/XournalView.h index 11553975..09808a60 100644 --- a/src/gui/XournalView.h +++ b/src/gui/XournalView.h @@ -105,6 +105,18 @@ public: Rectangle* getVisibleRect(XojPageView* redrawable); GtkContainer* getParent(); + + /** + * A pen action was detected now, therefore ignore touch events + * for a short time + */ + void penActionDetected(); + + /** + * If the pen was active a short time before, ignore touch events + */ + bool shouldIgnoreTouchEvents(); + public: // ZoomListener interface void zoomChanged(double lastZoom); @@ -182,5 +194,10 @@ private: */ int cleanupTimeout; + /** + * Last Pen action, to ignore touch events within a time frame + */ + gint64 lastPenAction; + friend class Layout; }; diff --git a/src/gui/widgets/XournalWidget.cpp b/src/gui/widgets/XournalWidget.cpp index 21a61858..bdfa1aac 100644 --- a/src/gui/widgets/XournalWidget.cpp +++ b/src/gui/widgets/XournalWidget.cpp @@ -535,11 +535,21 @@ gboolean gtk_xournal_button_release_event(GtkWidget* widget, GdkEventButton* eve return res; } +int dummyCounter = 0; + gboolean gtk_xournal_motion_notify_event(GtkWidget* widget, GdkEventMotion* event) { GtkXournal* xournal = GTK_XOURNAL(widget); ToolHandler* h = xournal->view->getControl()->getToolHandler(); + // Workaround to detect if the pen is there + GdkDevice* device = gdk_event_get_device((GdkEvent*)event); + int axesCount = gdk_device_get_n_axes(device); + if (axesCount >= 6) + { + xournal->view->penActionDetected(); + } + if (xournal->view->zoom_gesture_active) { return TRUE; @@ -597,14 +607,6 @@ gboolean gtk_xournal_motion_notify_event(GtkWidget* widget, GdkEventMotion* even } } - // Workaround to detect if the pen is there - GdkDevice* device = gdk_event_get_device((GdkEvent*)event); - GdkInputSource deviceType = gdk_device_get_source(device); - if (deviceType == GDK_SOURCE_PEN || deviceType == GDK_SOURCE_ERASER) - { - printf("pen active\n"); - } - return false; }