[vte] widget: gtk4: Add click event controller
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vte] widget: gtk4: Add click event controller
- Date: Sat, 27 Mar 2021 12:28:34 +0000 (UTC)
commit 37cd326d02c6a66c6fbb7beafd50a9ad42c12399
Author: Christian Persch <chpe src gnome org>
Date: Sat Mar 27 13:28:13 2021 +0100
widget: gtk4: Add click event controller
src/widget.cc | 184 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/widget.hh | 20 +++++++
2 files changed, 204 insertions(+)
---
diff --git a/src/widget.cc b/src/widget.cc
index 9b7f3ca5..4af5322e 100644
--- a/src/widget.cc
+++ b/src/widget.cc
@@ -341,6 +341,64 @@ catch (...)
vte::log_exception();
}
+static void
+click_pressed_cb(GtkGestureClick* gesture,
+ int press_count,
+ double x,
+ double y,
+ Widget* that) noexcept
+try
+{
+ that->gesture_click_pressed(gesture, press_count, x, y);
+}
+catch (...)
+{
+ vte::log_exception();
+}
+
+static void
+click_released_cb(GtkGestureClick* gesture,
+ int press_count,
+ double x,
+ double y,
+ Widget* that) noexcept
+try
+{
+ that->gesture_click_released(gesture, press_count, x, y);
+}
+catch (...)
+{
+ vte::log_exception();
+}
+
+static void
+click_stopped_cb(GtkGestureClick* gesture,
+ Widget* that) noexcept
+try
+{
+ that->gesture_click_stopped(gesture);
+}
+catch (...)
+{
+ vte::log_exception();
+}
+
+static void
+click_unpaired_release_cb(GtkGestureClick* gesture,
+ double x,
+ double y,
+ unsigned button,
+ GdkEventSequence* sequence,
+ Widget* that) noexcept
+try
+{
+ that->gesture_click_unpaired_release(gesture, x, y, button, sequence);
+}
+catch (...)
+{
+ vte::log_exception();
+}
+
#endif /* VTE_GTK == 4 */
Widget::Widget(VteTerminal* t)
@@ -608,6 +666,19 @@ Widget::constructed() noexcept
G_CALLBACK(scroll_decelerate_cb), this);
gtk_widget_add_controller(m_widget, controller.release());
+ auto gesture = vte::glib::take_ref(gtk_gesture_click_new());
+ gtk_gesture_single_set_button(GTK_GESTURE_SINGLE(gesture.get()), 0 /* any button */);
+ gtk_gesture_single_set_exclusive(GTK_GESTURE_SINGLE(gesture.get()), true);
+ g_signal_connect(gesture.get(), "pressed",
+ G_CALLBACK(click_pressed_cb), this);
+ g_signal_connect(gesture.get(), "released",
+ G_CALLBACK(click_released_cb), this);
+ g_signal_connect(gesture.get(), "stopped",
+ G_CALLBACK(click_stopped_cb), this);
+ g_signal_connect(gesture.get(), "unpaired-release",
+ G_CALLBACK(click_unpaired_release_cb), this);
+ gtk_widget_add_controller(m_widget, GTK_EVENT_CONTROLLER(gesture.release()));
+
#endif /* VTE_GTK == 4 */
#if VTE_GTK == 3
@@ -967,6 +1038,92 @@ Widget::event_scroll_decelerate(GtkEventControllerScroll* controller,
// FIXMEgtk4
}
+void
+Widget::gesture_click_pressed(GtkGestureClick* gesture,
+ int press_count,
+ double x,
+ double y)
+{
+ _vte_debug_print(VTE_DEBUG_EVENTS, "Click gesture pressed press_count=%d x=%.3f y=%.3f\n",
+ press_count, x, y);
+
+ // FIXMEgtk4 why does gtk4 not do that automatically?
+ gtk_widget_grab_focus(gtk());
+
+ auto const event = mouse_event_from_gesture_click(EventBase::Type::eMOUSE_PRESS,
+ gesture,
+ press_count,
+ x, y);
+ if (terminal()->widget_mouse_press(event))
+ gtk_gesture_set_state(GTK_GESTURE(gesture), GTK_EVENT_SEQUENCE_CLAIMED);
+ else
+ gtk_gesture_set_state(GTK_GESTURE(gesture), GTK_EVENT_SEQUENCE_DENIED);
+
+ // FIXMEgtk4 GtkLabel does
+ // if (press_count >= 3)
+ // gtk_event_controller_reset(GTK_EVENT_CONTROLLER(gesture));
+ // but this makes triple-click 'sticky'
+}
+
+void
+Widget::gesture_click_released(GtkGestureClick* gesture,
+ int press_count,
+ double x,
+ double y)
+{
+ _vte_debug_print(VTE_DEBUG_EVENTS, "Click gesture released press_count=%d x=%.3f y=%.3f\n",
+ press_count, x, y);
+
+ // FIXMEgtk4 why does gtk4 not do that automatically?
+ gtk_widget_grab_focus(gtk());
+
+ auto const sequence = gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture));
+ if (!gtk_gesture_handles_sequence(GTK_GESTURE(gesture), sequence)) // FIXMEgtk4 why!?
+ return;
+
+ auto const event = mouse_event_from_gesture_click(EventBase::Type::eMOUSE_RELEASE,
+ gesture,
+ press_count,
+ x, y);
+ if (terminal()->widget_mouse_release(event))
+ gtk_gesture_set_state(GTK_GESTURE(gesture), GTK_EVENT_SEQUENCE_CLAIMED);
+}
+
+void
+Widget::gesture_click_stopped(GtkGestureClick* gesture)
+{
+ _vte_debug_print(VTE_DEBUG_EVENTS, "Click gesture stopped\n");
+
+ // FIXMEgtk4 what's the right thing to do here???
+ // Should probably stop selection expansion mode, reset stored buttons, ...?
+}
+
+void
+Widget::gesture_click_unpaired_release(GtkGestureClick* gesture,
+ double x,
+ double y,
+ unsigned button,
+ GdkEventSequence* sequence)
+{
+ _vte_debug_print(VTE_DEBUG_EVENTS, "Click gesture unpaired release button=%d x=%.3f y=%.3f\n",
+ button, x, y);
+
+ // FIXMEgtk4 what's the right thing to do here???
+
+ // FIXMEgtk4 why does gtk4 not do that automatically?
+ gtk_widget_grab_focus(gtk());
+
+ if (!gtk_gesture_handles_sequence(GTK_GESTURE(gesture), sequence)) // why!?
+ return;
+
+ auto const event = mouse_event_from_gesture_click(EventBase::Type::eMOUSE_RELEASE,
+ gesture,
+ 1, // press_count
+ x, y);
+ if (terminal()->widget_mouse_release(event))
+ gtk_gesture_set_state(GTK_GESTURE(gesture), GTK_EVENT_SEQUENCE_CLAIMED);
+}
+
#endif /* VTE_GTK == 4 */
void
@@ -1300,6 +1457,33 @@ Widget::scroll_event_from_gdk(GdkEvent* event) const /* throws */
#endif /* VTE_GTK == 3 */
+#if VTE_GTK == 4
+
+MouseEvent
+Widget::mouse_event_from_gesture_click(EventBase::Type type,
+ GtkGestureClick* gesture,
+ int press_count,
+ double x,
+ double y) const /* throws */
+{
+ auto const gesture_single = GTK_GESTURE_SINGLE(gesture);
+
+ auto const button = gtk_gesture_single_get_current_button(gesture_single);
+ auto const sequence = gtk_gesture_single_get_current_sequence(gesture_single);
+ auto const event = gtk_gesture_get_last_event(GTK_GESTURE(gesture), sequence);
+ if (!event)
+ throw std::runtime_error{"No last event!?"};
+
+ return {type,
+ press_count,
+ gdk_event_get_modifier_state(event),
+ MouseEvent::Button(button),
+ x,
+ y};
+}
+
+#endif /* VTE_GTK == 4 */
+
void
Widget::map() noexcept
{
diff --git a/src/widget.hh b/src/widget.hh
index 9c76f131..828f686c 100644
--- a/src/widget.hh
+++ b/src/widget.hh
@@ -353,6 +353,20 @@ public:
void event_scroll_decelerate(GtkEventControllerScroll* controller,
double vx,
double vy);
+ void gesture_click_pressed(GtkGestureClick* gesture,
+ int press_count,
+ double x,
+ double y);
+ void gesture_click_released(GtkGestureClick* gesture,
+ int press_count,
+ double x,
+ double y);
+ void gesture_click_stopped(GtkGestureClick* gesture);
+ void gesture_click_unpaired_release(GtkGestureClick* gesture,
+ double x,
+ double y,
+ unsigned button,
+ GdkEventSequence* sequence);
#endif /* VTE_GTK == 4 */
void grab_focus() noexcept { gtk_widget_grab_focus(gtk()); }
@@ -540,6 +554,12 @@ private:
unsigned read_modifiers_from_gdk(GdkEvent* event) const noexcept;
MouseEvent mouse_event_from_gdk(GdkEvent* event) const /* throws */;
ScrollEvent scroll_event_from_gdk(GdkEvent* event) const /* throws */;
+#elif VTE_GTK == 4
+ MouseEvent mouse_event_from_gesture_click(EventBase::Type type,
+ GtkGestureClick* gesture,
+ int press_count,
+ double x,
+ double y) const /* throws */;
#endif
void clipboard_request_received_cb(Clipboard const& clipboard,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]