[gnome-text-editor] page: work around GtkTextView ctrl+page_up/down



commit 20ac0963760dd76f3291c97a99ba4714f9aaff7f
Author: Christian Hergert <chergert redhat com>
Date:   Tue Jun 29 15:14:50 2021 -0700

    page: work around GtkTextView ctrl+page_up/down
    
    We would rather have this for controlling the tabs in the tab view to feel
    like what people are used to in other places (Nautilus, Terminal, Firefox,
    etc).
    
    Related to https://gitlab.gnome.org/GNOME/libadwaita/-/issues/222

 src/editor-page.c           |  2 +
 src/editor-page.ui          |  2 +-
 src/editor-source-view.c    | 91 +++++++++++++++++++++++++++++++++++++++++++++
 src/editor-source-view.h    | 31 +++++++++++++++
 src/editor-window-actions.c | 20 ++++++++++
 src/editor-window.c         |  2 -
 src/meson.build             |  1 +
 7 files changed, 146 insertions(+), 3 deletions(-)
---
diff --git a/src/editor-page.c b/src/editor-page.c
index 620d2b9..ae24544 100644
--- a/src/editor-page.c
+++ b/src/editor-page.c
@@ -29,6 +29,7 @@
 #include "editor-page-private.h"
 #include "editor-sidebar-model-private.h"
 #include "editor-session-private.h"
+#include "editor-source-view.h"
 #include "editor-spell-menu.h"
 #include "editor-utils-private.h"
 
@@ -597,6 +598,7 @@ editor_page_class_init (EditorPageClass *klass)
 
   g_type_ensure (EDITOR_TYPE_INFO_BAR);
   g_type_ensure (EDITOR_TYPE_SEARCH_BAR);
+  g_type_ensure (EDITOR_TYPE_SOURCE_VIEW);
 }
 
 static void
diff --git a/src/editor-page.ui b/src/editor-page.ui
index f6a0591..8d7c38d 100644
--- a/src/editor-page.ui
+++ b/src/editor-page.ui
@@ -20,7 +20,7 @@
                     <property name="hexpand">true</property>
                     <property name="vexpand">true</property>
                     <child>
-                      <object class="GtkSourceView" id="view">
+                      <object class="EditorSourceView" id="view">
                         <style>
                           <class name="editor"/>
                         </style>
diff --git a/src/editor-source-view.c b/src/editor-source-view.c
new file mode 100644
index 0000000..07ad7ac
--- /dev/null
+++ b/src/editor-source-view.c
@@ -0,0 +1,91 @@
+/* editor-source-view.c
+ *
+ * Copyright 2021 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "config.h"
+
+#include "editor-source-view.h"
+
+struct _EditorSourceView
+{
+  GtkSourceView parent_instance;
+};
+
+G_DEFINE_TYPE (EditorSourceView, editor_source_view, GTK_SOURCE_TYPE_VIEW)
+
+static gboolean
+on_key_pressed_cb (GtkEventControllerKey *key,
+                   guint                  keyval,
+                   guint                  keycode,
+                   GdkModifierType        state,
+                   GtkWidget             *widget)
+{
+  /* This seems to be the easiest way to reliably override the keybindings
+   * from GtkTextView into something we want (which is to use them for moving
+   * through the tabs.
+   */
+
+  if ((state & GDK_CONTROL_MASK) == 0)
+    return FALSE;
+
+  if (state & ~(GDK_CONTROL_MASK|GDK_SHIFT_MASK))
+    return FALSE;
+
+  switch (keyval)
+    {
+    case GDK_KEY_Page_Up:
+    case GDK_KEY_KP_Page_Up:
+      if (state & GDK_SHIFT_MASK)
+        gtk_widget_activate_action (widget, "page.move-left", NULL);
+      else
+        gtk_widget_activate_action (widget, "win.focus-neighbor", "i", -1);
+      return TRUE;
+
+    case GDK_KEY_Page_Down:
+    case GDK_KEY_KP_Page_Down:
+      if (state & GDK_SHIFT_MASK)
+        gtk_widget_activate_action (widget, "page.move-right", NULL);
+      else
+        gtk_widget_activate_action (widget, "win.focus-neighbor", "i", 1);
+      return TRUE;
+
+    default:
+      break;
+    }
+
+  return FALSE;
+}
+
+static void
+editor_source_view_class_init (EditorSourceViewClass *klass)
+{
+}
+
+static void
+editor_source_view_init (EditorSourceView *self)
+{
+  GtkEventController *controller;
+
+  controller = gtk_event_controller_key_new ();
+  g_signal_connect (controller,
+                    "key-pressed",
+                    G_CALLBACK (on_key_pressed_cb),
+                    self);
+  gtk_widget_add_controller (GTK_WIDGET (self), controller);
+}
diff --git a/src/editor-source-view.h b/src/editor-source-view.h
new file mode 100644
index 0000000..e7fb0d2
--- /dev/null
+++ b/src/editor-source-view.h
@@ -0,0 +1,31 @@
+/* editor-source-view.h
+ *
+ * Copyright 2021 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "editor-types.h"
+
+G_BEGIN_DECLS
+
+#define EDITOR_TYPE_SOURCE_VIEW (editor_source_view_get_type())
+
+G_DECLARE_FINAL_TYPE (EditorSourceView, editor_source_view, EDITOR, SOURCE_VIEW, GtkSourceView)
+
+G_END_DECLS
diff --git a/src/editor-window-actions.c b/src/editor-window-actions.c
index 8eaa153..21bdda3 100644
--- a/src/editor-window-actions.c
+++ b/src/editor-window-actions.c
@@ -485,6 +485,21 @@ editor_window_actions_begin_replace_cb (GtkWidget  *widget,
     _editor_page_begin_replace (page);
 }
 
+static void
+editor_window_actions_focus_neighbor_cb (GtkWidget  *widget,
+                                         const char *action_name,
+                                         GVariant   *param)
+{
+  EditorWindow *self = (EditorWindow *)widget;
+
+  g_assert (EDITOR_IS_WINDOW (self));
+
+  if (g_variant_get_int32 (param) == -1)
+    adw_tab_view_select_previous_page (self->tab_view);
+  else
+    adw_tab_view_select_next_page (self->tab_view);
+}
+
 void
 _editor_window_class_actions_init (EditorWindowClass *klass)
 {
@@ -514,6 +529,10 @@ _editor_window_class_actions_init (EditorWindowClass *klass)
                                    "win.focus-search",
                                    NULL,
                                    editor_window_actions_focus_search_cb);
+  gtk_widget_class_install_action (widget_class,
+                                   "win.focus-neighbor",
+                                   "i",
+                                   editor_window_actions_focus_neighbor_cb);
   gtk_widget_class_install_action (widget_class,
                                    "page.save",
                                    NULL,
@@ -635,4 +654,5 @@ _editor_window_actions_update (EditorWindow *self,
   gtk_widget_action_set_enabled (GTK_WIDGET (self), "page.copy-all", has_page);
   gtk_widget_action_set_enabled (GTK_WIDGET (self), "page.begin-replace", has_page);
   gtk_widget_action_set_enabled (GTK_WIDGET (self), "page.begin-search", has_page);
+  gtk_widget_action_set_enabled (GTK_WIDGET (self), "win.focus-neighbor", has_page);
 }
diff --git a/src/editor-window.c b/src/editor-window.c
index 675f3b5..69eb5c6 100644
--- a/src/editor-window.c
+++ b/src/editor-window.c
@@ -429,8 +429,6 @@ editor_window_class_init (EditorWindowClass *klass)
   gtk_widget_class_add_binding_action (widget_class, GDK_KEY_7, GDK_ALT_MASK, "page.change", "i", 7);
   gtk_widget_class_add_binding_action (widget_class, GDK_KEY_8, GDK_ALT_MASK, "page.change", "i", 8);
   gtk_widget_class_add_binding_action (widget_class, GDK_KEY_9, GDK_ALT_MASK, "page.change", "i", 9);
-  gtk_widget_class_add_binding_action (widget_class, GDK_KEY_Page_Up, GDK_CONTROL_MASK | GDK_ALT_MASK | 
GDK_SHIFT_MASK, "page.move-left", NULL);
-  gtk_widget_class_add_binding_action (widget_class, GDK_KEY_Page_Down, GDK_CONTROL_MASK | GDK_ALT_MASK | 
GDK_SHIFT_MASK, "page.move-right", NULL);
   gtk_widget_class_add_binding_action (widget_class, GDK_KEY_n, GDK_CONTROL_MASK | GDK_SHIFT_MASK, 
"page.move-to-new-window", NULL);
   gtk_widget_class_add_binding_action (widget_class, GDK_KEY_f, GDK_CONTROL_MASK, "page.begin-search", NULL);
   gtk_widget_class_add_binding_action (widget_class, GDK_KEY_h, GDK_CONTROL_MASK, "page.begin-replace", 
NULL);
diff --git a/src/meson.build b/src/meson.build
index cc438dc..dd63965 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -32,6 +32,7 @@ editor_sources = [
   'editor-sidebar-model.c',
   'editor-sidebar-row.c',
   'editor-signal-group.c',
+  'editor-source-view.c',
   'editor-spell-checker.c',
   'editor-spell-cursor.c',
   'editor-spell-language.c',


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