From 2359df0f1754a29a451e86f6835d572fcd7fe393 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Mon, 19 Aug 2019 22:16:39 +1000 Subject: [PATCH] Make scrolling speed configurable The UI now can send a 'Scroll' key, whose value is the scrolling amount encoded as a signed integer. This replaces the MouseWheelUp and MouseWheelDown keys. The NCursesUI now has a ncurses_wheel_scroll_amount ui_option that controls that amount, it can be negative to swap scrolling direction. Fixes #3045 --- src/input_handler.cc | 35 ++++++++++++--------------------- src/json_ui.cc | 13 ++++++++---- src/keys.cc | 42 ++++++++++++++++----------------------- src/keys.hh | 11 +++-------- src/main.cc | 1 + src/ncurses_ui.cc | 47 ++++++++++++++++++++++---------------------- src/ncurses_ui.hh | 1 + 7 files changed, 68 insertions(+), 82 deletions(-) diff --git a/src/input_handler.cc b/src/input_handler.cc index 6e6b1e20..07211c30 100644 --- a/src/input_handler.cc +++ b/src/input_handler.cc @@ -92,8 +92,7 @@ struct MouseHandler Buffer& buffer = context.buffer(); BufferCoord cursor; auto& selections = context.selections(); - const auto key_modifier = (Key::Modifiers)(key.modifiers & Key::Modifiers::MouseEvent); - switch (key_modifier) + switch (key.modifiers) { case Key::Modifiers::MousePressRight: m_dragging = false; @@ -137,14 +136,9 @@ struct MouseHandler selections.sort_and_merge_overlapping(); return true; - case Key::Modifiers::MouseWheelDown: + case Key::Modifiers::Scroll: m_dragging = false; - scroll_window(context, 3); - return true; - - case Key::Modifiers::MouseWheelUp: - m_dragging = false; - scroll_window(context, -3); + scroll_window(context, static_cast(key.key)); return true; default: return false; @@ -232,16 +226,6 @@ public: kak_assert(m_state != State::PopOnEnabled); ScopedSetBool set_in_on_key{m_in_on_key}; - // Hack to parse keys sent by terminals using the 8th bit to mark the - // meta key. In normal mode, give priority to a potential alt-key than - // the accentuated character. - if (not (key.modifiers & Key::Modifiers::MouseEvent) and - key.key >= 127 and key.key < 256) - { - key.modifiers |= Key::Modifiers::Alt; - key.key &= 0x7f; - } - bool do_restore_hooks = false; auto restore_hooks = on_scope_end([&, this]{ if (m_hooks_disabled and enabled() and do_restore_hooks) @@ -253,8 +237,6 @@ public: const bool transient = context().flags() & Context::Flags::Draft; - auto cp = key.codepoint(); - if (m_mouse_handler.handle_key(key, context())) { context().print_status({}); @@ -264,7 +246,7 @@ public: if (not transient) m_idle_timer.set_next_date(Clock::now() + get_idle_timeout(context())); } - else if (cp and isdigit(*cp)) + else if (auto cp = key.codepoint(); cp and isdigit(*cp)) { long long new_val = (long long)m_params.count * 10 + *cp - '0'; if (new_val > std::numeric_limits::max()) @@ -310,6 +292,15 @@ public: if (context().has_client()) context().client().info_hide(); + // Hack to parse keys sent by terminals using the 8th bit to mark the + // meta key. In normal mode, give priority to a potential alt-key than + // the accentuated character. + if (key.key >= 127 and key.key < 256) + { + key.modifiers |= Key::Modifiers::Alt; + key.key &= 0x7f; + } + do_restore_hooks = true; if (auto command = get_normal_command(key)) { diff --git a/src/json_ui.cc b/src/json_ui.cc index b8acd6ad..ebb3b7bf 100644 --- a/src/json_ui.cc +++ b/src/json_ui.cc @@ -430,13 +430,18 @@ void JsonUI::eval_json(const Value& json) m_on_key({Key::Modifiers::MouseReleaseLeft, coord}); else if (type == "release_right") m_on_key({Key::Modifiers::MouseReleaseRight, coord}); - else if (type == "wheel_up") - m_on_key({Key::Modifiers::MouseWheelUp, coord}); - else if (type == "wheel_down") - m_on_key({Key::Modifiers::MouseWheelDown, coord}); else throw invalid_rpc_request(format("invalid mouse event type: {}", type)); } + else if (method == "scroll") + { + if (params.size() != 1) + throw invalid_rpc_request("scroll needs an amount"); + else if (not params[0].is_a()) + throw invalid_rpc_request("scroll amount is not an integer"); + m_on_key({Key::Modifiers::Scroll, (Codepoint)params[0].as()}); + + } else if (method == "menu_select") { if (params.size() != 1) diff --git a/src/keys.cc b/src/keys.cc index 927baed9..8254f6cb 100644 --- a/src/keys.cc +++ b/src/keys.cc @@ -146,32 +146,24 @@ KeyList parse_keys(StringView str) String key_to_str(Key key) { - if (auto mouse_event = (key.modifiers & Key::Modifiers::MouseEvent)) + const auto coord = key.coord() + DisplayCoord{1,1}; + switch (key.modifiers) { - const auto coord = key.coord() + DisplayCoord{1,1}; - switch ((Key::Modifiers)mouse_event) - { - case Key::Modifiers::MousePos: - return format("", coord.line, coord.column); - case Key::Modifiers::MousePressLeft: - return format("", coord.line, coord.column); - case Key::Modifiers::MousePressRight: - return format("", coord.line, coord.column); - case Key::Modifiers::MouseReleaseLeft: - return format("", coord.line, coord.column); - case Key::Modifiers::MouseReleaseRight: - return format("", coord.line, coord.column); - case Key::Modifiers::MouseWheelDown: - return ""; - case Key::Modifiers::MouseWheelUp: - return ""; - default: kak_assert(false); - } - } - else if (key.modifiers == Key::Modifiers::Resize) - { - auto size = key.coord() + DisplayCoord{1,1}; - return format("", size.line, size.column); + case Key::Modifiers::MousePos: + return format("", coord.line, coord.column); + case Key::Modifiers::MousePressLeft: + return format("", coord.line, coord.column); + case Key::Modifiers::MousePressRight: + return format("", coord.line, coord.column); + case Key::Modifiers::MouseReleaseLeft: + return format("", coord.line, coord.column); + case Key::Modifiers::MouseReleaseRight: + return format("", coord.line, coord.column); + case Key::Modifiers::Scroll: + return format("", static_cast(key.key)); + case Key::Modifiers::Resize: + return format("", coord.line, coord.column); + default: break; } bool named = false; diff --git a/src/keys.hh b/src/keys.hh index 74d1b545..84707faf 100644 --- a/src/keys.hh +++ b/src/keys.hh @@ -26,14 +26,9 @@ struct Key MouseReleaseLeft = 1 << 5, MouseReleaseRight = 1 << 6, MousePos = 1 << 7, - MouseWheelDown = 1 << 8, - MouseWheelUp = 1 << 9, - MouseEvent = MousePressLeft | MousePressRight | - MouseReleaseLeft | MouseReleaseRight | - MousePos | MouseWheelDown | MouseWheelUp, - - Resize = 1 << 10, - MenuSelect = 1 << 11, + Scroll = 1 << 8, + Resize = 1 << 9, + MenuSelect = 1 << 10, }; enum NamedKey : Codepoint { diff --git a/src/main.cc b/src/main.cc index 620a3da8..b724f122 100644 --- a/src/main.cc +++ b/src/main.cc @@ -437,6 +437,7 @@ void register_options() " ncurses_change_colors bool\n" " ncurses_wheel_up_button int\n" " ncurses_wheel_down_button int\n" + " ncurses_wheel_scroll_amount int\n" " ncurses_shift_function_key int\n" " ncurses_builtin_key_parser bool\n", UserInterface::Options{}); diff --git a/src/ncurses_ui.cc b/src/ncurses_ui.cc index 5b6c4bad..58680546 100644 --- a/src/ncurses_ui.cc +++ b/src/ncurses_ui.cc @@ -556,31 +556,28 @@ Optional NCursesUI::get_next_key() MEVENT ev; if (getmouse(&ev) == OK) { - auto get_modifiers = [this](mmask_t mask) { - Key::Modifiers res{}; + const auto mask = ev.bstate; + auto coord = encode_coord({ ev.y - content_line_offset(), ev.x }); - if (mask & BUTTON_CTRL) - res |= Key::Modifiers::Control; - if (mask & BUTTON_ALT) - res |= Key::Modifiers::Alt; + Key::Modifiers mod{}; + if (mask & BUTTON_CTRL) + mod |= Key::Modifiers::Control; + if (mask & BUTTON_ALT) + mod |= Key::Modifiers::Alt; - if (BUTTON_PRESS(mask, 1)) - return res | Key::Modifiers::MousePressLeft; - if (BUTTON_PRESS(mask, 3)) - return res | Key::Modifiers::MousePressRight; - if (BUTTON_RELEASE(mask, 1)) - return res | Key::Modifiers::MouseReleaseLeft; - if (BUTTON_RELEASE(mask, 3)) - return res | Key::Modifiers::MouseReleaseRight; - if (BUTTON_PRESS(mask, m_wheel_down_button)) - return res | Key::Modifiers::MouseWheelDown; - if (BUTTON_PRESS(mask, m_wheel_up_button)) - return res | Key::Modifiers::MouseWheelUp; - return res | Key::Modifiers::MousePos; - }; - - return Key{ get_modifiers(ev.bstate), - encode_coord({ ev.y - content_line_offset(), ev.x }) }; + if (BUTTON_PRESS(mask, 1)) + return Key{mod | Key::Modifiers::MousePressLeft, coord}; + if (BUTTON_PRESS(mask, 3)) + return Key{mod | Key::Modifiers::MousePressRight, coord}; + if (BUTTON_RELEASE(mask, 1)) + return Key{mod | Key::Modifiers::MouseReleaseLeft, coord}; + if (BUTTON_RELEASE(mask, 3)) + return Key{mod | Key::Modifiers::MouseReleaseRight, coord}; + if (BUTTON_PRESS(mask, m_wheel_down_button)) + return Key{mod | Key::Modifiers::Scroll, static_cast(m_wheel_scroll_amount)}; + if (BUTTON_PRESS(mask, m_wheel_up_button)) + return Key{mod | Key::Modifiers::Scroll, static_cast(-m_wheel_scroll_amount)}; + return Key{mod | Key::Modifiers::MousePos, coord}; } } @@ -1278,6 +1275,10 @@ void NCursesUI::set_ui_options(const Options& options) auto wheel_down_it = options.find("ncurses_wheel_down_button"_sv); m_wheel_down_button = wheel_down_it != options.end() ? str_to_int_ifp(wheel_down_it->value).value_or(5) : 5; + + auto wheel_scroll_amount_it = options.find("ncurses_wheel_scroll_amount"_sv); + m_wheel_scroll_amount = wheel_scroll_amount_it != options.end() ? + str_to_int_ifp(wheel_scroll_amount_it->value).value_or(3) : 3; } { diff --git a/src/ncurses_ui.hh b/src/ncurses_ui.hh index c16b6b99..f858db84 100644 --- a/src/ncurses_ui.hh +++ b/src/ncurses_ui.hh @@ -140,6 +140,7 @@ private: bool m_mouse_enabled = false; int m_wheel_up_button = 4; int m_wheel_down_button = 5; + int m_wheel_scroll_amount = 3; static constexpr int default_shift_function_key = 12; int m_shift_function_key = default_shift_function_key;