From 13988ba2fe8169450b6617c8abcab7e0ca20bbc0 Mon Sep 17 00:00:00 2001 From: Jules Aguillon Date: Sat, 1 Mar 2025 16:34:20 +0100 Subject: [PATCH] Selection mode: Move each ends of selection separately with slider When the selection mode is activated, the space bar sliders change how they affect the selection: - The left side of the slider moves the left position of the selection. To shrink the selection from the left side, the slider must be activated by sliding to the left, extending the selection temporarilly, then by sliding to the right. - The right side of the slider affects the right position if the selection. --- srcs/juloo.keyboard2/KeyEventHandler.java | 60 ++++++++++++++++++----- srcs/juloo.keyboard2/KeyModifier.java | 7 +++ srcs/juloo.keyboard2/KeyValue.java | 8 ++- 3 files changed, 60 insertions(+), 15 deletions(-) diff --git a/srcs/juloo.keyboard2/KeyEventHandler.java b/srcs/juloo.keyboard2/KeyEventHandler.java index 1e384e1..2f4a239 100644 --- a/srcs/juloo.keyboard2/KeyEventHandler.java +++ b/srcs/juloo.keyboard2/KeyEventHandler.java @@ -254,15 +254,17 @@ public final class KeyEventHandler return conn.getExtractedText(_move_cursor_req, 0); } - /** [repeatition] might be negative, in which case the direction is reversed. */ - void handle_slider(KeyValue.Slider s, int repeatition) + /** [r] might be negative, in which case the direction is reversed. */ + void handle_slider(KeyValue.Slider s, int r) { switch (s) { - case Cursor_left: move_cursor(-repeatition); break; - case Cursor_right: move_cursor(repeatition); break; - case Cursor_up: move_cursor_vertical(-repeatition); break; - case Cursor_down: move_cursor_vertical(repeatition); break; + case Cursor_left: move_cursor(-r); break; + case Cursor_right: move_cursor(r); break; + case Cursor_up: move_cursor_vertical(-r); break; + case Cursor_down: move_cursor_vertical(r); break; + case Selection_cursor_left: move_cursor_sel(r, true); break; + case Selection_cursor_right: move_cursor_sel(r, false); break; } } @@ -276,12 +278,7 @@ public final class KeyEventHandler if (conn == null) return; ExtractedText et = get_cursor_pos(conn); - int system_mods = - KeyEvent.META_CTRL_ON | KeyEvent.META_ALT_ON | KeyEvent.META_META_ON; - // Fallback to sending key events if system modifiers are activated or - // ExtractedText is not supported, for example on Termux. - if (!_move_cursor_force_fallback && et != null - && (_meta_state & system_mods) == 0) + if (et != null && can_set_selection(conn)) { int sel_start = et.selectionStart; int sel_end = et.selectionEnd; @@ -300,8 +297,45 @@ public final class KeyEventHandler sel_start = sel_end; } if (conn.setSelection(sel_start, sel_end)) - return; // [setSelection] succeeded, don't fallback to key events + return; // Fallback to sending key events if [setSelection] failed } + move_cursor_fallback(d); + } + + /** Move one of the two side of a selection. If [sel_left] is true, the left + position is moved, otherwise the right position is moved. */ + void move_cursor_sel(int d, boolean sel_left) + { + InputConnection conn = _recv.getCurrentInputConnection(); + if (conn == null) + return; + ExtractedText et = get_cursor_pos(conn); + if (et != null && can_set_selection(conn)) + { + int sel_start = et.selectionStart; + int sel_end = et.selectionEnd; + if (sel_left == (sel_start <= sel_end)) + sel_start += d; + else + sel_end += d; + if (conn.setSelection(sel_start, sel_end)) + return; // Fallback to sending key events if [setSelection] failed + } + move_cursor_fallback(d); + } + + /** Returns whether the selection can be set using [conn.setSelection()]. + This can happen on Termux or when system modifiers are activated for + example. */ + boolean can_set_selection(InputConnection conn) + { + final int system_mods = + KeyEvent.META_CTRL_ON | KeyEvent.META_ALT_ON | KeyEvent.META_META_ON; + return !_move_cursor_force_fallback && (_meta_state & system_mods) == 0; + } + + void move_cursor_fallback(int d) + { if (d < 0) send_key_down_up_repeat(KeyEvent.KEYCODE_DPAD_LEFT, -d); else diff --git a/srcs/juloo.keyboard2/KeyModifier.java b/srcs/juloo.keyboard2/KeyModifier.java index 31a72bc..be3d30c 100644 --- a/srcs/juloo.keyboard2/KeyModifier.java +++ b/srcs/juloo.keyboard2/KeyModifier.java @@ -397,6 +397,13 @@ public final class KeyModifier case ' ': name = "selection_cancel"; break; } break; + case Slider: + switch (k.getSlider()) + { + case Cursor_left: name = "selection_cursor_left"; break; + case Cursor_right: name = "selection_cursor_right"; break; + } + break; case Keyevent: switch (k.getKeyevent()) { diff --git a/srcs/juloo.keyboard2/KeyValue.java b/srcs/juloo.keyboard2/KeyValue.java index 2a686bb..d521b8e 100644 --- a/srcs/juloo.keyboard2/KeyValue.java +++ b/srcs/juloo.keyboard2/KeyValue.java @@ -713,6 +713,9 @@ public final class KeyValue implements Comparable case "cursor_right": return sliderKey(Slider.Cursor_right, 1); case "cursor_up": return sliderKey(Slider.Cursor_up, 1); case "cursor_down": return sliderKey(Slider.Cursor_down, 1); + case "selection_cancel": return editingKey("Esc", Editing.SELECTION_CANCEL, FLAG_SMALLER_FONT); + case "selection_cursor_left": return sliderKey(Slider.Selection_cursor_left, -1); // Move the left side of the selection + case "selection_cursor_right": return sliderKey(Slider.Selection_cursor_right, 1); // These keys are not used case "replaceText": return editingKey("repl", Editing.REPLACE); case "textAssist": return editingKey(0xE038, Editing.ASSIST); @@ -764,7 +767,6 @@ public final class KeyValue implements Comparable /* Internal keys */ case "selection_mode": return makeInternalModifier(Modifier.SELECTION_MODE); - case "selection_cancel": return editingKey("Esc", Editing.SELECTION_CANCEL, FLAG_SMALLER_FONT); default: return null; } @@ -782,7 +784,9 @@ public final class KeyValue implements Comparable Cursor_left(0xE008), Cursor_right(0xE006), Cursor_up(0xE005), - Cursor_down(0xE007); + Cursor_down(0xE007), + Selection_cursor_left(0xE008), + Selection_cursor_right(0xE006); final String symbol;