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
This commit is contained in:
parent
f1047181cb
commit
2359df0f17
|
@ -92,8 +92,7 @@ struct MouseHandler
|
||||||
Buffer& buffer = context.buffer();
|
Buffer& buffer = context.buffer();
|
||||||
BufferCoord cursor;
|
BufferCoord cursor;
|
||||||
auto& selections = context.selections();
|
auto& selections = context.selections();
|
||||||
const auto key_modifier = (Key::Modifiers)(key.modifiers & Key::Modifiers::MouseEvent);
|
switch (key.modifiers)
|
||||||
switch (key_modifier)
|
|
||||||
{
|
{
|
||||||
case Key::Modifiers::MousePressRight:
|
case Key::Modifiers::MousePressRight:
|
||||||
m_dragging = false;
|
m_dragging = false;
|
||||||
|
@ -137,14 +136,9 @@ struct MouseHandler
|
||||||
selections.sort_and_merge_overlapping();
|
selections.sort_and_merge_overlapping();
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case Key::Modifiers::MouseWheelDown:
|
case Key::Modifiers::Scroll:
|
||||||
m_dragging = false;
|
m_dragging = false;
|
||||||
scroll_window(context, 3);
|
scroll_window(context, static_cast<int32_t>(key.key));
|
||||||
return true;
|
|
||||||
|
|
||||||
case Key::Modifiers::MouseWheelUp:
|
|
||||||
m_dragging = false;
|
|
||||||
scroll_window(context, -3);
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
default: return false;
|
default: return false;
|
||||||
|
@ -232,16 +226,6 @@ public:
|
||||||
kak_assert(m_state != State::PopOnEnabled);
|
kak_assert(m_state != State::PopOnEnabled);
|
||||||
ScopedSetBool set_in_on_key{m_in_on_key};
|
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;
|
bool do_restore_hooks = false;
|
||||||
auto restore_hooks = on_scope_end([&, this]{
|
auto restore_hooks = on_scope_end([&, this]{
|
||||||
if (m_hooks_disabled and enabled() and do_restore_hooks)
|
if (m_hooks_disabled and enabled() and do_restore_hooks)
|
||||||
|
@ -253,8 +237,6 @@ public:
|
||||||
|
|
||||||
const bool transient = context().flags() & Context::Flags::Draft;
|
const bool transient = context().flags() & Context::Flags::Draft;
|
||||||
|
|
||||||
auto cp = key.codepoint();
|
|
||||||
|
|
||||||
if (m_mouse_handler.handle_key(key, context()))
|
if (m_mouse_handler.handle_key(key, context()))
|
||||||
{
|
{
|
||||||
context().print_status({});
|
context().print_status({});
|
||||||
|
@ -264,7 +246,7 @@ public:
|
||||||
if (not transient)
|
if (not transient)
|
||||||
m_idle_timer.set_next_date(Clock::now() + get_idle_timeout(context()));
|
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';
|
long long new_val = (long long)m_params.count * 10 + *cp - '0';
|
||||||
if (new_val > std::numeric_limits<int>::max())
|
if (new_val > std::numeric_limits<int>::max())
|
||||||
|
@ -310,6 +292,15 @@ public:
|
||||||
if (context().has_client())
|
if (context().has_client())
|
||||||
context().client().info_hide();
|
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;
|
do_restore_hooks = true;
|
||||||
if (auto command = get_normal_command(key))
|
if (auto command = get_normal_command(key))
|
||||||
{
|
{
|
||||||
|
|
|
@ -430,13 +430,18 @@ void JsonUI::eval_json(const Value& json)
|
||||||
m_on_key({Key::Modifiers::MouseReleaseLeft, coord});
|
m_on_key({Key::Modifiers::MouseReleaseLeft, coord});
|
||||||
else if (type == "release_right")
|
else if (type == "release_right")
|
||||||
m_on_key({Key::Modifiers::MouseReleaseRight, coord});
|
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
|
else
|
||||||
throw invalid_rpc_request(format("invalid mouse event type: {}", type));
|
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<int>())
|
||||||
|
throw invalid_rpc_request("scroll amount is not an integer");
|
||||||
|
m_on_key({Key::Modifiers::Scroll, (Codepoint)params[0].as<int>()});
|
||||||
|
|
||||||
|
}
|
||||||
else if (method == "menu_select")
|
else if (method == "menu_select")
|
||||||
{
|
{
|
||||||
if (params.size() != 1)
|
if (params.size() != 1)
|
||||||
|
|
42
src/keys.cc
42
src/keys.cc
|
@ -146,32 +146,24 @@ KeyList parse_keys(StringView str)
|
||||||
|
|
||||||
String key_to_str(Key key)
|
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};
|
case Key::Modifiers::MousePos:
|
||||||
switch ((Key::Modifiers)mouse_event)
|
return format("<mouse:move:{}.{}>", coord.line, coord.column);
|
||||||
{
|
case Key::Modifiers::MousePressLeft:
|
||||||
case Key::Modifiers::MousePos:
|
return format("<mouse:press_left:{}.{}>", coord.line, coord.column);
|
||||||
return format("<mouse:move:{}.{}>", coord.line, coord.column);
|
case Key::Modifiers::MousePressRight:
|
||||||
case Key::Modifiers::MousePressLeft:
|
return format("<mouse:press_right:{}.{}>", coord.line, coord.column);
|
||||||
return format("<mouse:press_left:{}.{}>", coord.line, coord.column);
|
case Key::Modifiers::MouseReleaseLeft:
|
||||||
case Key::Modifiers::MousePressRight:
|
return format("<mouse:release_left:{}.{}>", coord.line, coord.column);
|
||||||
return format("<mouse:press_right:{}.{}>", coord.line, coord.column);
|
case Key::Modifiers::MouseReleaseRight:
|
||||||
case Key::Modifiers::MouseReleaseLeft:
|
return format("<mouse:release_right:{}.{}>", coord.line, coord.column);
|
||||||
return format("<mouse:release_left:{}.{}>", coord.line, coord.column);
|
case Key::Modifiers::Scroll:
|
||||||
case Key::Modifiers::MouseReleaseRight:
|
return format("<scroll:{}>", static_cast<int>(key.key));
|
||||||
return format("<mouse:release_right:{}.{}>", coord.line, coord.column);
|
case Key::Modifiers::Resize:
|
||||||
case Key::Modifiers::MouseWheelDown:
|
return format("<resize:{}.{}>", coord.line, coord.column);
|
||||||
return "<mouse:wheel_down>";
|
default: break;
|
||||||
case Key::Modifiers::MouseWheelUp:
|
|
||||||
return "<mouse:wheel_up>";
|
|
||||||
default: kak_assert(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (key.modifiers == Key::Modifiers::Resize)
|
|
||||||
{
|
|
||||||
auto size = key.coord() + DisplayCoord{1,1};
|
|
||||||
return format("<resize:{}.{}>", size.line, size.column);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool named = false;
|
bool named = false;
|
||||||
|
|
11
src/keys.hh
11
src/keys.hh
|
@ -26,14 +26,9 @@ struct Key
|
||||||
MouseReleaseLeft = 1 << 5,
|
MouseReleaseLeft = 1 << 5,
|
||||||
MouseReleaseRight = 1 << 6,
|
MouseReleaseRight = 1 << 6,
|
||||||
MousePos = 1 << 7,
|
MousePos = 1 << 7,
|
||||||
MouseWheelDown = 1 << 8,
|
Scroll = 1 << 8,
|
||||||
MouseWheelUp = 1 << 9,
|
Resize = 1 << 9,
|
||||||
MouseEvent = MousePressLeft | MousePressRight |
|
MenuSelect = 1 << 10,
|
||||||
MouseReleaseLeft | MouseReleaseRight |
|
|
||||||
MousePos | MouseWheelDown | MouseWheelUp,
|
|
||||||
|
|
||||||
Resize = 1 << 10,
|
|
||||||
MenuSelect = 1 << 11,
|
|
||||||
};
|
};
|
||||||
enum NamedKey : Codepoint
|
enum NamedKey : Codepoint
|
||||||
{
|
{
|
||||||
|
|
|
@ -437,6 +437,7 @@ void register_options()
|
||||||
" ncurses_change_colors bool\n"
|
" ncurses_change_colors bool\n"
|
||||||
" ncurses_wheel_up_button int\n"
|
" ncurses_wheel_up_button int\n"
|
||||||
" ncurses_wheel_down_button int\n"
|
" ncurses_wheel_down_button int\n"
|
||||||
|
" ncurses_wheel_scroll_amount int\n"
|
||||||
" ncurses_shift_function_key int\n"
|
" ncurses_shift_function_key int\n"
|
||||||
" ncurses_builtin_key_parser bool\n",
|
" ncurses_builtin_key_parser bool\n",
|
||||||
UserInterface::Options{});
|
UserInterface::Options{});
|
||||||
|
|
|
@ -556,31 +556,28 @@ Optional<Key> NCursesUI::get_next_key()
|
||||||
MEVENT ev;
|
MEVENT ev;
|
||||||
if (getmouse(&ev) == OK)
|
if (getmouse(&ev) == OK)
|
||||||
{
|
{
|
||||||
auto get_modifiers = [this](mmask_t mask) {
|
const auto mask = ev.bstate;
|
||||||
Key::Modifiers res{};
|
auto coord = encode_coord({ ev.y - content_line_offset(), ev.x });
|
||||||
|
|
||||||
if (mask & BUTTON_CTRL)
|
Key::Modifiers mod{};
|
||||||
res |= Key::Modifiers::Control;
|
if (mask & BUTTON_CTRL)
|
||||||
if (mask & BUTTON_ALT)
|
mod |= Key::Modifiers::Control;
|
||||||
res |= Key::Modifiers::Alt;
|
if (mask & BUTTON_ALT)
|
||||||
|
mod |= Key::Modifiers::Alt;
|
||||||
|
|
||||||
if (BUTTON_PRESS(mask, 1))
|
if (BUTTON_PRESS(mask, 1))
|
||||||
return res | Key::Modifiers::MousePressLeft;
|
return Key{mod | Key::Modifiers::MousePressLeft, coord};
|
||||||
if (BUTTON_PRESS(mask, 3))
|
if (BUTTON_PRESS(mask, 3))
|
||||||
return res | Key::Modifiers::MousePressRight;
|
return Key{mod | Key::Modifiers::MousePressRight, coord};
|
||||||
if (BUTTON_RELEASE(mask, 1))
|
if (BUTTON_RELEASE(mask, 1))
|
||||||
return res | Key::Modifiers::MouseReleaseLeft;
|
return Key{mod | Key::Modifiers::MouseReleaseLeft, coord};
|
||||||
if (BUTTON_RELEASE(mask, 3))
|
if (BUTTON_RELEASE(mask, 3))
|
||||||
return res | Key::Modifiers::MouseReleaseRight;
|
return Key{mod | Key::Modifiers::MouseReleaseRight, coord};
|
||||||
if (BUTTON_PRESS(mask, m_wheel_down_button))
|
if (BUTTON_PRESS(mask, m_wheel_down_button))
|
||||||
return res | Key::Modifiers::MouseWheelDown;
|
return Key{mod | Key::Modifiers::Scroll, static_cast<Codepoint>(m_wheel_scroll_amount)};
|
||||||
if (BUTTON_PRESS(mask, m_wheel_up_button))
|
if (BUTTON_PRESS(mask, m_wheel_up_button))
|
||||||
return res | Key::Modifiers::MouseWheelUp;
|
return Key{mod | Key::Modifiers::Scroll, static_cast<Codepoint>(-m_wheel_scroll_amount)};
|
||||||
return res | Key::Modifiers::MousePos;
|
return Key{mod | Key::Modifiers::MousePos, coord};
|
||||||
};
|
|
||||||
|
|
||||||
return Key{ get_modifiers(ev.bstate),
|
|
||||||
encode_coord({ ev.y - content_line_offset(), ev.x }) };
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1278,6 +1275,10 @@ void NCursesUI::set_ui_options(const Options& options)
|
||||||
auto wheel_down_it = options.find("ncurses_wheel_down_button"_sv);
|
auto wheel_down_it = options.find("ncurses_wheel_down_button"_sv);
|
||||||
m_wheel_down_button = wheel_down_it != options.end() ?
|
m_wheel_down_button = wheel_down_it != options.end() ?
|
||||||
str_to_int_ifp(wheel_down_it->value).value_or(5) : 5;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -140,6 +140,7 @@ private:
|
||||||
bool m_mouse_enabled = false;
|
bool m_mouse_enabled = false;
|
||||||
int m_wheel_up_button = 4;
|
int m_wheel_up_button = 4;
|
||||||
int m_wheel_down_button = 5;
|
int m_wheel_down_button = 5;
|
||||||
|
int m_wheel_scroll_amount = 3;
|
||||||
|
|
||||||
static constexpr int default_shift_function_key = 12;
|
static constexpr int default_shift_function_key = 12;
|
||||||
int m_shift_function_key = default_shift_function_key;
|
int m_shift_function_key = default_shift_function_key;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user