[vte/wip/egmont/bidi: 72/87] keyboard arrow swapping mode



commit 0c4a31fff5d2705c96d96eb2c7af114bedd6b236
Author: Egmont Koblinger <egmont gmail com>
Date:   Thu Nov 15 23:18:27 2018 +0100

    keyboard arrow swapping mode

 BIDI-STATUS          |  4 +++-
 src/modes-private.hh |  8 ++++++++
 src/modes.hh         |  1 +
 src/vte.cc           | 33 +++++++++++++++++++++++++++++++++
 4 files changed, 45 insertions(+), 1 deletion(-)
---
diff --git a/BIDI-STATUS b/BIDI-STATUS
index ff78efb6..aea647ee 100644
--- a/BIDI-STATUS
+++ b/BIDI-STATUS
@@ -12,6 +12,7 @@ Done:
 - VTE_DEBUG=bidi highlights characters with resolved RTL directionality.
 - Test file.
 - Configure flag.
+- Keyboard arrow swapping.
 
 Bugs:
 - Upon a reset, the directionality of cells isn't properly restored.
@@ -37,7 +38,6 @@ Planned future improvements:
 - Play with other possibilities for placing the cursor (especially when it's
   at the end of the logical line).
 - Play with better placement of the preedit box.
-- Keyboard arrow swapping.
 - Remember some lines that are no longer user-accessible as they scroll out,
   to properly BiDi the still remaining part of that paragraph.
 - Possibility for default RTL directionality?
@@ -60,3 +60,5 @@ Useful aliases:
   alias box-normal='echo -ne "\e[?2500l"'
   alias auto='echo -ne "\e[?2501h"'
   alias noauto='echo -ne "\e[?2501l"'
+  alias kbdswap='echo -ne "\e[?2502h"'
+  alias nokbdswap='echo -ne "\e[?2502l"'
diff --git a/src/modes-private.hh b/src/modes-private.hh
index d4a9feba..e0ee078e 100644
--- a/src/modes-private.hh
+++ b/src/modes-private.hh
@@ -160,6 +160,14 @@ MODE(VTE_BOX_DRAWING_MIRROR, 2500)
  */
 MODE(VTE_BIDI_AUTO, 2501)
 
+/*
+ * Whether to swap the Left and Right arrow keys if the cursor
+ * stands over an RTL paragraphs.
+ *
+ * The number choice is temporary.
+ */
+MODE(VTE_BIDI_SWAP_ARROW_KEYS, 2502)
+
 /* Not supported modes: */
 
 /* DEC */
diff --git a/src/modes.hh b/src/modes.hh
index c50f944a..af218622 100644
--- a/src/modes.hh
+++ b/src/modes.hh
@@ -227,6 +227,7 @@ public:
 
         constexpr Private() : Self{eDEC_AUTOWRAP,
                                    eDEC_TEXT_CURSOR,
+                                   eVTE_BIDI_SWAP_ARROW_KEYS,
                                    eXTERM_ALTBUF_SCROLL,
                                    eXTERM_META_SENDS_ESCAPE} { }
 
diff --git a/src/vte.cc b/src/vte.cc
index 41a48eb1..301122be 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -4959,6 +4959,39 @@ Terminal::widget_key_press(GdkEventKey *event)
                /* If the above switch statement didn't do the job, try mapping
                 * it to a literal or capability name. */
                 if (handled == FALSE) {
+                        /* In keyboard arrow swapping mode, the left and right arrows
+                         * are swapped if the cursor stands inside an RTL paragraph. */
+                        if (m_modes_private.VTE_BIDI_SWAP_ARROW_KEYS() &&
+                            (keyval == GDK_KEY_Left ||
+                             keyval == GDK_KEY_Right ||
+                             keyval == GDK_KEY_KP_Left ||
+                             keyval == GDK_KEY_KP_Right)) {
+                                /* m_ringview is for the onscreen contents and the cursor
+                                 * may be offscreen, so use a temporary ringview. */
+                                vte::base::RingView *ringview = new vte::base::RingView();
+                                ringview->set_ring(m_screen->row_data);
+                                ringview->set_rows(m_screen->cursor.row, 1);
+                                ringview->set_width(m_column_count);
+                                ringview->update();
+                                if (ringview->get_row_map(m_screen->cursor.row)->base_is_rtl()) {
+                                        switch (keyval) {
+                                        case GDK_KEY_Left:
+                                                keyval = GDK_KEY_Right;
+                                                break;
+                                        case GDK_KEY_Right:
+                                                keyval = GDK_KEY_Left;
+                                                break;
+                                        case GDK_KEY_KP_Left:
+                                                keyval = GDK_KEY_KP_Right;
+                                                break;
+                                        case GDK_KEY_KP_Right:
+                                                keyval = GDK_KEY_KP_Left;
+                                                break;
+                                        }
+                                }
+                                delete ringview;
+                        }
+
                        _vte_keymap_map(keyval, m_modifiers,
                                         m_modes_private.DEC_APPLICATION_CURSOR_KEYS(),
                                         m_modes_private.DEC_APPLICATION_KEYPAD(),


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