From 8bf5548589284a95371022cda7b1e9b5f43bc148 Mon Sep 17 00:00:00 2001 From: Guido Cella Date: Tue, 8 Oct 2024 19:34:20 +0200 Subject: [PATCH] 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. --- DOCS/man/mpv.rst | 8 +++--- player/lua/console.lua | 59 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 61 insertions(+), 6 deletions(-) diff --git a/DOCS/man/mpv.rst b/DOCS/man/mpv.rst index 94abca3475..4af515921b 100644 --- a/DOCS/man/mpv.rst +++ b/DOCS/man/mpv.rst @@ -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. diff --git a/player/lua/console.lua b/player/lua/console.lua index bfd19da0e5..83b1fb07c1 100644 --- a/player/lua/console.lua +++ b/player/lua/console.lua @@ -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)