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;