summaryrefslogtreecommitdiff
path: root/main.lua
diff options
context:
space:
mode:
authorDavid Vazgenovich Shakaryan <dvshakaryan@gmail.com>2026-01-21 12:52:15 -0800
committerDavid Vazgenovich Shakaryan <dvshakaryan@gmail.com>2026-01-21 12:52:15 -0800
commit15198eb77727b4277d5b5d80fb3ae4b25b3c8ef8 (patch)
treef16471159acb70601dc90d83147a1596c9b5a983 /main.lua
parent9b863cad505d01017ee980e16d072fb7cffcd029 (diff)
downloadmpv-iptv-menu-15198eb77727b4277d5b5d80fb3ae4b25b3c8ef8.tar.gz
mpv-iptv-menu-15198eb77727b4277d5b5d80fb3ae4b25b3c8ef8.tar.xz
move mouse state to osd; add scrollbar hover
Diffstat (limited to 'main.lua')
-rw-r--r--main.lua86
1 files changed, 36 insertions, 50 deletions
diff --git a/main.lua b/main.lua
index 04e86fc..7b649ba 100644
--- a/main.lua
+++ b/main.lua
@@ -16,7 +16,7 @@ local script_name = mp.get_script_name()
local state = _state.new()
local binding_state = {mappings = {}, active = {}}
-local mouse_state = {click = {}}
+local click_state = {}
local osc_visibility
local downloader = _downloader.new({limit = 5})
@@ -1000,16 +1000,14 @@ end
-- second click event, we can implement double-click detection ourselves for
-- more control and to bypass some mpv inconsistencies.
local function handle_mouse_click(ev, id)
- local ms = mouse_state
-
if ev.canceled then
- ms.click = {}
+ click_state = {}
return
end
local time = mp.get_time()
- local clk = ms.click
- local mpos = ms.pos
+ local clk = click_state
+ local mpos = osd.mpos
if ev.event == 'down' then
clk.ct, clk.ck = time, ev.key_name
@@ -1024,14 +1022,14 @@ local function handle_mouse_click(ev, id)
if time - clk.ct > config.click_timeout or
clk.ck ~= ev.key_name or clk.ci ~= id or
mouse_has_drifted(mpos.x, mpos.y, clk.cx, clk.cy) then
- ms.click = {}
+ click_state = {}
return
end
local dbl = clk.pt and clk.ct - clk.pt <= config.click_dbl_time and
clk.pk == ev.key_name and clk.pi == id and
not mouse_has_drifted(clk.cx, clk.cy, clk.px, clk.py)
- ms.click = dbl and {} or
+ click_state = dbl and {} or
{
pt = clk.ct, pk = ev.key_name,
px = clk.cx, py = clk.cy, pi = id,
@@ -1040,20 +1038,19 @@ local function handle_mouse_click(ev, id)
end
local function process_mouse_click(ev)
- if not mouse_state.pos then
+ local ms = osd.mstate
+ if not ms then
return
end
local area
- local val = osd:mouse_scrollbar_ratio(mouse_state.pos)
- if val then
+ local val
+ if ms.target == 'scrollbar' then
area = 'scrollbar'
- else
- local line = osd:mouse_menu_line(mouse_state.pos)
- if line then
- area = 'menu'
- val = line - (osd.lines - osd:menu_lines(state))
- end
+ val = ms.ratio
+ elseif ms.target == 'menu' then
+ area = 'menu'
+ val = ms.option_line
end
local key, dbl = handle_mouse_click(ev, area == 'menu' and val or nil)
@@ -1322,13 +1319,10 @@ local function unbind_click()
mp.command_native({'disable-section', 'click-nodrag'})
end
-local menu_button_timer
-menu_button_timer = mp.add_periodic_timer(0.1, function()
- if mouse_state.pos and
- mp.get_time() - mouse_state.pos_time >
- config.menu_button_timeout then
- osd:show_menu_button(false)
- menu_button_timer:kill()
+local btn_timer; btn_timer = mp.add_periodic_timer(0.1, function()
+ if osd.mpos and mp.get_time() - osd.mpos_time > config.btn_timeout then
+ osd:show_menu_btn(false)
+ btn_timer:kill()
end
end, true) -- disabled
mp.observe_property('mouse-pos', 'native', function(_, mpos)
@@ -1336,49 +1330,40 @@ mp.observe_property('mouse-pos', 'native', function(_, mpos)
return
end
- local ms = mouse_state
-
- -- mpv sends (0, 0) on startup if the mouse hasn't moved yet. don't
- -- trigger display of the button until the mouse has actually moved.
- if not ms.pos and mpos.x == 0 and mpos.y == 0 then
+ local ps = osd.mstate or {}
+ local ms = osd:set_mpos(mpos)
+ if not ms then
return
end
- ms.pos = mpos
- ms.pos_time = mp.get_time()
-
-- mpv normally sends a cancel event when the mouse drifts before a
-- click is released, but only for a first click and not for the second
-- click of what mpv internally considers a double-click. this
-- replicates that drift detection behaviour, allowing for consistency
-- on double-clicks.
- local clk = ms.click
+ local clk = click_state
if clk.ct and mouse_has_drifted(mpos.x, mpos.y, clk.cx, clk.cy) then
- ms.click = {}
+ click_state = {}
end
- local over_button_area = osd:mouse_over_button_area(mpos)
- if not over_button_area ~= not ms.over_button_area then
- ms.over_button_area = over_button_area
- osd:show_menu_button(over_button_area)
- elseif over_button_area and osd.menu_button.hidden then
- osd:show_menu_button(true)
+ if not ms.over_btn_area ~= not ps.over_btn_area then
+ osd:show_menu_btn(ms.over_btn_area)
+ elseif ms.over_btn_area and osd.menu_btn.hidden then
+ osd:show_menu_btn(true)
end
- local over_menu_button = osd:mouse_over_menu_button(mpos)
- if not over_menu_button ~= not ms.over_menu_button then
- ms.over_menu_button = over_menu_button
- if over_menu_button then
+ if (ms.target == 'menu_btn') ~= (ps.target == 'menu_btn') then
+ if ms.target == 'menu_btn' then
bind_click(toggle_menu)
else
unbind_click()
end
end
- if over_button_area and not over_menu_button then
- menu_button_timer:resume()
+ if ms.over_btn_area and ms.target ~= 'menu_btn' then
+ btn_timer:resume()
else
- menu_button_timer:kill()
+ btn_timer:kill()
end
end)
@@ -1397,10 +1382,11 @@ mp.observe_property('osd-dimensions', 'native', function(_, val)
-- and we do nothing, a click would trigger that element regardless of
-- mouse position. since we cannot get the new position, we instead
-- wipe mouse state on resize, clearing it until the next move.
- osd:show_menu_button(false)
- mouse_state = {click = {}}
+ osd:show_menu_btn(false)
+ osd:set_mpos(nil)
+ click_state = {}
unbind_click()
- menu_button_timer:kill()
+ btn_timer:kill()
end)
mp.register_event('start-file', function()