[vte] widget: gtk4: Add keyboard input handling



commit 80e45218ab4962f1b0e282de91e9814d45eca7e3
Author: Christian Persch <chpe src gnome org>
Date:   Sat Mar 6 23:08:54 2021 +0100

    widget: gtk4: Add keyboard input handling

 src/app/search-popover-gtk4.ui |  10 ----
 src/app/window-gtk4.ui         |   9 ----
 src/vte.cc                     |  11 +++++
 src/vteinternal.hh             |   3 ++
 src/widget.cc                  | 106 +++++++++++++++++++++++++++++++++++++++++
 src/widget.hh                  |  11 +++++
 6 files changed, 131 insertions(+), 19 deletions(-)
---
diff --git a/src/app/search-popover-gtk4.ui b/src/app/search-popover-gtk4.ui
index 4b187190..0d6f77cd 100644
--- a/src/app/search-popover-gtk4.ui
+++ b/src/app/search-popover-gtk4.ui
@@ -18,10 +18,8 @@
 <interface>
   <requires lib="gtk+" version="3.16"/>
   <template class="VteappSearchPopover" parent="GtkPopover">
-    <property name="can_focus">0</property>
     <property name="child">
       <object class="GtkBox" id="box1">
-        <property name="can_focus">0</property>
         <property name="margin-start">12</property>
         <property name="margin-end">12</property>
         <property name="margin_top">12</property>
@@ -29,12 +27,10 @@
         <property name="orientation">vertical</property>
         <child>
           <object class="GtkBox" id="box2">
-            <property name="can_focus">0</property>
             <property name="spacing">18</property>
             <child>
               <object class="GtkBox" id="box4">
                 <property name="hexpand">1</property>
-                <property name="can_focus">0</property>
                 <child>
                   <object class="GtkSearchEntry" id="search_entry">
                     <property name="hexpand">1</property>
@@ -50,7 +46,6 @@
                     <property name="focus_on_click">0</property>
                     <child>
                       <object class="GtkImage" id="image2">
-                        <property name="can_focus">0</property>
                         <property name="icon_name">go-up-symbolic</property>
                         <property name="use_fallback">1</property>
                       </object>
@@ -64,7 +59,6 @@
                     <property name="focus_on_click">0</property>
                     <child>
                       <object class="GtkImage" id="image3">
-                        <property name="can_focus">0</property>
                         <property name="icon_name">go-down-symbolic</property>
                         <property name="use_fallback">1</property>
                       </object>
@@ -83,7 +77,6 @@
                 <property name="focus_on_click">0</property>
                 <child>
                   <object class="GtkImage" id="image1">
-                    <property name="can_focus">0</property>
                     <property name="icon_name">open-menu-symbolic</property>
                     <property name="use_fallback">1</property>
                   </object>
@@ -101,7 +94,6 @@
                 <property name="focus_on_click">0</property>
                 <child>
                   <object class="GtkImage" id="image4">
-                    <property name="can_focus">0</property>
                     <property name="icon_name">window-close-symbolic</property>
                     <property name="use_fallback">1</property>
                   </object>
@@ -112,12 +104,10 @@
         </child>
         <child>
           <object class="GtkRevealer" id="revealer">
-            <property name="can_focus">0</property>
             <property name="transition_type">none</property>
             <property name="reveal_child">0</property>
             <property name="child">
               <object class="GtkBox" id="box3">
-                <property name="can_focus">0</property>
                 <property name="margin_top">18</property>
                 <property name="orientation">vertical</property>
                 <property name="spacing">6</property>
diff --git a/src/app/window-gtk4.ui b/src/app/window-gtk4.ui
index dc3c33a4..12ad26c7 100644
--- a/src/app/window-gtk4.ui
+++ b/src/app/window-gtk4.ui
@@ -70,11 +70,9 @@
     </section>
   </menu>
   <template class="VteappWindow" parent="GtkApplicationWindow">
-    <property name="can_focus">0</property>
     <property name="icon_name">utilities-terminal</property>
     <child>
       <object class="GtkGrid" id="window_grid">
-        <property name="can_focus">0</property>
         <property name="halign">fill</property>
         <property name="valign">fill</property>
         <property name="hexpand">1</property>
@@ -84,7 +82,6 @@
         </child>
         <child>
           <object class="GtkScrollbar" id="scrollbar">
-            <property name="can_focus">0</property>
             <property name="orientation">vertical</property>
             <property name="hexpand">0</property>
             <property name="vexpand">1</property>
@@ -98,7 +95,6 @@
     </child>
     <child type="titlebar">
       <object class="GtkHeaderBar" id="headerbar">
-        <property name="can_focus">0</property>
         <property name="decoration_layout">:close</property>
         <child type="start">
           <object class="GtkButton" id="copy_button">
@@ -109,7 +105,6 @@
             <property name="focus_on_click">0</property>
             <child>
               <object class="GtkImage" id="image2">
-                <property name="can_focus">0</property>
                 <property name="icon_name">edit-copy-symbolic</property>
                 <property name="use_fallback">1</property>
               </object>
@@ -124,7 +119,6 @@
             <property name="focus_on_click">0</property>
             <child>
               <object class="GtkImage" id="image3">
-                <property name="can_focus">0</property>
                 <property name="icon_name">edit-paste-symbolic</property>
                 <property name="use_fallback">1</property>
               </object>
@@ -137,7 +131,6 @@
             <property name="focus_on_click">0</property>
             <child>
               <object class="GtkImage" id="image5">
-                <property name="can_focus">0</property>
                 <property name="icon_name">edit-find-symbolic</property>
                 <property name="use_fallback">1</property>
               </object>
@@ -157,7 +150,6 @@
         </child>
         <child type="end">
           <object class="GtkGrid" id="notifications_grid">
-            <property name="can_focus">0</property>
             <property name="column_spacing">6</property>
             <property name="row_spacing">6</property>
             <property name="hexpand">0</property>
@@ -165,7 +157,6 @@
             <child>
               <object class="GtkImage" id="readonly_emblem">
                 <property name="visible">0</property>
-                <property name="can_focus">0</property>
                 <property name="tooltip_text" translatable="yes">Read-only</property>
                 <property name="icon_name">emblem-readonly</property>
                 <property name="use_fallback">1</property>
diff --git a/src/vte.cc b/src/vte.cc
index 534b722c..69dfe113 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -5078,6 +5078,17 @@ Terminal::widget_key_release(vte::platform::KeyEvent const& event)
         return false;
 }
 
+#if VTE_GTK == 4
+
+bool
+Terminal::widget_key_modifiers(unsigned modifiers)
+{
+        m_modifiers = modifiers;
+        return true;
+}
+
+#endif /* VTE_GTK == 4 */
+
 static const guint8 word_char_by_category[] = {
         [G_UNICODE_CONTROL]             = 2,
         [G_UNICODE_FORMAT]              = 2,
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index e5dd7fe3..f2fafe40 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -894,6 +894,9 @@ public:
         void widget_mouse_enter(vte::platform::MouseEvent const& event);
         void widget_mouse_leave(vte::platform::MouseEvent const& event);
         bool widget_mouse_scroll(vte::platform::ScrollEvent const& event);
+#if VTE_GTK == 4
+        bool widget_key_modifiers(unsigned modifiers);
+#endif /* VTE_GTK == 4 */
 #if VTE_GTK == 3
         void widget_draw(cairo_t *cr);
 #endif /* VTE_GTK == 3 */
diff --git a/src/widget.cc b/src/widget.cc
index 6c5ca11c..951189e4 100644
--- a/src/widget.cc
+++ b/src/widget.cc
@@ -146,6 +146,57 @@ catch (...)
         vte::log_exception();
 }
 
+#if VTE_GTK == 4
+
+/* Callbacks for event controllers */
+
+static gboolean
+key_pressed_cb(GtkEventControllerKey* controller,
+               unsigned key,
+               unsigned keycode,
+               unsigned modifiers,
+               Widget* that) noexcept
+try
+{
+        return that->event_key_pressed(controller, key, keycode, modifiers);
+}
+catch (...)
+{
+        vte::log_exception();
+        return false;
+}
+
+static void
+key_released_cb(GtkEventControllerKey* controller,
+                unsigned key,
+                unsigned keycode,
+                unsigned modifiers,
+                Widget* that) noexcept
+try
+{
+        that->event_key_released(controller, key, keycode, modifiers);
+}
+catch (...)
+{
+        vte::log_exception();
+}
+
+static gboolean
+key_modifiers_cb(GtkEventControllerKey* controller,
+                 unsigned modifiers,
+                 Widget* that) noexcept
+try
+{
+        return that->event_key_modifiers(controller, modifiers);
+}
+catch (...)
+{
+        vte::log_exception();
+        return false;
+}
+
+#endif /* VTE_GTK == 4 */
+
 Widget::Widget(VteTerminal* t)
         : m_widget{&t->widget},
           m_hscroll_policy{GTK_SCROLL_NATURAL},
@@ -362,6 +413,16 @@ Widget::constructed() noexcept
 
         connect_settings();
 
+        /* Add event controllers */
+        auto controller = vte::glib::take_ref(gtk_event_controller_key_new());
+        g_signal_connect(controller.get(), "key-pressed",
+                         G_CALLBACK(key_pressed_cb), this);
+        g_signal_connect(controller.get(), "key-released",
+                         G_CALLBACK(key_released_cb), this);
+        g_signal_connect(controller.get(), "modifiers",
+                         G_CALLBACK(key_modifiers_cb), this);
+        gtk_widget_add_controller(m_widget, controller.release());
+
 #endif /* VTE_GTK == 4 */
 
 #if VTE_GTK == 3
@@ -543,6 +604,51 @@ Widget::event_motion_notify(GdkEventMotion *event)
 
 #endif /* VTE_GTK == 3 */
 
+#if VTE_GTK == 4
+
+bool
+Widget::event_key_pressed(GtkEventControllerKey* controller,
+                          unsigned key,
+                          unsigned keycode,
+                          unsigned modifiers)
+{
+       _vte_debug_print(VTE_DEBUG_EVENTS, "Key press key=%x keycode=%x modifiers=%x\n",
+                         key, keycode, modifiers);
+
+        auto event = gtk_event_controller_get_current_event(GTK_EVENT_CONTROLLER(controller));
+        if (!event)
+                return false;
+
+        return terminal()->widget_key_press(key_event_from_gdk(event));
+}
+
+void
+Widget::event_key_released(GtkEventControllerKey* controller,
+                           unsigned key,
+                           unsigned keycode,
+                           unsigned modifiers)
+{
+       _vte_debug_print(VTE_DEBUG_EVENTS, "Key release key=%x keycode=%x modifiers=%x\n",
+                         key, keycode, modifiers);
+
+        auto event = gtk_event_controller_get_current_event(GTK_EVENT_CONTROLLER(controller));
+        if (!event)
+                return;
+
+        terminal()->widget_key_release(key_event_from_gdk(event));
+}
+
+bool
+Widget::event_key_modifiers(GtkEventControllerKey* controller,
+                            unsigned modifiers)
+{
+       _vte_debug_print(VTE_DEBUG_EVENTS, "Key modifiers=%x\n", modifiers);
+
+        return terminal()->widget_key_modifiers(modifiers);
+}
+
+#endif /* VTE_GTK == 4 */
+
 void
 Widget::im_focus_in() noexcept
 {
diff --git a/src/widget.hh b/src/widget.hh
index 813b3625..e644fca5 100644
--- a/src/widget.hh
+++ b/src/widget.hh
@@ -323,6 +323,17 @@ public:
         bool contains(double x,
                       double y);
         void display_changed() noexcept;
+
+        bool event_key_pressed(GtkEventControllerKey* controller,
+                               unsigned key,
+                               unsigned keycode,
+                               unsigned modifiers);
+        void event_key_released(GtkEventControllerKey* controller,
+                                unsigned key,
+                                unsigned keycode,
+                                unsigned modifiers);
+        bool event_key_modifiers(GtkEventControllerKey* controller,
+                                 unsigned modifiers);
 #endif /* VTE_GTK == 4 */
 
         void grab_focus() noexcept { gtk_widget_grab_focus(gtk()); }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]