console.lua: allow clicking selectable items

This adds click support for the select menu. Scrolling with the wheel
already worked.

If a custom OSC binds a button to a select.lua script-binding, this lets
users keep using the mouse to select an item.

While the OSC and the select menu are open at the same time, you can no
longer click the OSC's buttons. By using mp.add_key_binding instead of
add_forced_key_binding you could click both, but the console's binding
would be shadowed by MBTN_LEFT bindings in input.conf.
This commit is contained in:
Guido Cella 2024-10-08 19:34:20 +02:00 committed by Kacper Michajłow
parent 6871304029
commit 8bf5548589
2 changed files with 61 additions and 6 deletions

View File

@ -274,10 +274,10 @@ Command + f (macOS only)
Toggle fullscreen (see also ``--fs``).
(The following keybindings open a selector in the console that lets you choose
from a list of items by typing part of the desired item and/or by navigating
them with keybindings: ``Down`` and ``Ctrl+n`` go down, ``Up`` and ``Ctrl+p`` go
up, ``Page down`` and ``Ctrl+f`` scroll down one page, and ``Page up`` and
``Ctrl+b`` scroll up one page.)
from a list of items by typing part of the desired item, by clicking the desired
item, or by navigating them with keybindings: ``Down`` and ``Ctrl+n`` go down,
``Up`` and ``Ctrl+p`` go up, ``Page down`` and ``Ctrl+f`` scroll down one page,
and ``Page up`` and ``Ctrl+b`` scroll up one page.)
g-p
Select a playlist entry.

View File

@ -791,6 +791,11 @@ local function help_command(param)
log_add(output:sub(1, -2))
end
local function unbind_mouse()
mp.remove_key_binding('_console_mouse_move')
mp.remove_key_binding('_console_mbtn_left')
end
-- Run the current command and clear the line (Enter)
local function handle_enter()
if searching_history then
@ -800,6 +805,7 @@ local function handle_enter()
cursor = #line + 1
log_buffers[id] = {}
update()
unbind_mouse()
return
end
@ -833,6 +839,46 @@ local function handle_enter()
clear()
end
local function highlight_hovered_line()
local height = mp.get_property_native('osd-height')
if height == 0 then
return
end
local y = mp.get_property_native('mouse-pos').y - global_margins.t * height
-- Calculate how many lines could be printed without decreasing them for
-- the input line and OSC.
local max_lines = height / mp.get_property_native('display-hidpi-scale')
/ opts.font_size
local clicked_line = math.floor(y / height * max_lines + .5)
-- Subtract 1 line for "n hidden items" when necessary.
local offset = first_match_to_print == 1 and 0 or first_match_to_print - 2
max_lines = calculate_max_log_lines()
if #matches < max_lines then
clicked_line = clicked_line - (max_lines - #matches)
max_lines = #matches
elseif offset + max_lines < #matches then
-- Subtract 1 line for "n hidden items".
max_lines = max_lines - 1
end
if selected_match ~= offset + clicked_line
and clicked_line > 0 and clicked_line <= max_lines then
selected_match = offset + clicked_line
update()
end
end
local function bind_mouse()
mp.add_forced_key_binding('MOUSE_MOVE', '_console_mouse_move', highlight_hovered_line)
mp.add_forced_key_binding('MBTN_LEFT', '_console_mbtn_left', function()
highlight_hovered_line()
handle_enter()
end)
end
-- Go to the specified position in the command history
local function go_history(new_pos)
local old_pos = history_pos
@ -932,6 +978,7 @@ local function search_history()
end
update()
bind_mouse()
end
local function page_up_or_prev_char()
@ -1082,7 +1129,12 @@ end
-- Paste text from the window-system's clipboard. 'clip' determines whether the
-- clipboard or the primary selection buffer is used (on X11 and Wayland only.)
local function paste(clip)
local function paste(clip, is_wheel)
if is_wheel and selectable_items then
handle_enter()
return
end
local text = get_clipboard(clip)
local before_cur = line:sub(1, cursor - 1)
local after_cur = line:sub(cursor)
@ -1567,7 +1619,7 @@ local function get_bindings()
{ 'shift+del', handle_del },
{ 'ins', handle_ins },
{ 'shift+ins', function() paste(false) end },
{ 'mbtn_mid', function() paste(false) end },
{ 'mbtn_mid', function() paste(false, true) end },
{ 'left', function() prev_char() end },
{ 'ctrl+b', function() page_up_or_prev_char() end },
{ 'right', function() next_char() end },
@ -1665,6 +1717,7 @@ set_active = function (active)
cursor = 1
selectable_items = nil
log_buffers[id] = {}
unbind_mouse()
else
repl_active = false
suggestion_buffer = {}
@ -1679,6 +1732,7 @@ set_active = function (active)
cursor = 1
selectable_items = nil
dont_bind_up_down = false
unbind_mouse()
end
collectgarbage()
end
@ -1754,6 +1808,7 @@ mp.register_script_message('get-input', function (script_name, args)
for i, item in ipairs(selectable_items) do
matches[i] = { index = i, text = item }
end
bind_mouse()
end
set_active(true)