From 02491a39495148ff68cc07145bc7275a0370600d Mon Sep 17 00:00:00 2001 From: Guido Cella Date: Wed, 20 May 2026 23:05:42 +0200 Subject: [PATCH] osc.lua: don't reinit on duration changes It can be avoided by extracting just the code to update the seekbar and its chapter markers. This avoids log spam and is more efficient for DVD and Blu-ray menus which continously update duration and have chapter markers. The livemarkers option is removed since updating the chapter markers is no longer expensive like reiniting. --- DOCS/interface-changes/osc-livemarkers.txt | 2 + DOCS/man/osc.rst | 6 - player/lua/osc.lua | 198 ++++++++++----------- 3 files changed, 100 insertions(+), 106 deletions(-) create mode 100644 DOCS/interface-changes/osc-livemarkers.txt diff --git a/DOCS/interface-changes/osc-livemarkers.txt b/DOCS/interface-changes/osc-livemarkers.txt new file mode 100644 index 0000000000..c1e7c22c50 --- /dev/null +++ b/DOCS/interface-changes/osc-livemarkers.txt @@ -0,0 +1,2 @@ +remove `osc-livemarkers` script-opt because chapter markers are now updated +without reiniting the OSC diff --git a/DOCS/man/osc.rst b/DOCS/man/osc.rst index ba7eeeab7b..04494d0bd9 100644 --- a/DOCS/man/osc.rst +++ b/DOCS/man/osc.rst @@ -499,12 +499,6 @@ Configurable Options Set to ``yes`` to reduce festivity (i.e. disable santa hat in December.) -``livemarkers`` - Default: yes - - Update chapter markers positions on duration changes, e.g. live streams. - The updates are unoptimized - consider disabling it on very low-end systems. - ``chapter_fmt`` Default: ``Chapter: %s`` diff --git a/player/lua/osc.lua b/player/lua/osc.lua index 609e2f6b16..c5bd1c46ee 100644 --- a/player/lua/osc.lua +++ b/player/lua/osc.lua @@ -61,7 +61,6 @@ local user_opts = { floatingalpha = 105, -- alpha of the floating layout background tracknumberswidth = 35, -- width for track number labels (0 = icon only) greenandgrumpy = false, -- disable santa hat - livemarkers = true, -- update seekbar chapter markers on duration change chapter_fmt = "Chapter: %s", -- chapter print format for seekbar-hover. "no" to disable unicodeminus = false, -- whether to use the Unicode minus sign character icon_style = "layout", -- icon style: layout/classic/fluent @@ -789,6 +788,98 @@ end local elements = {} +local function update_slider(element) + local elem_geo = element.layout.geometry + local r1 = 0 + local r2 = 0 + local slider_lo = element.layout.slider + -- offset between element outline and drag-area + local foV = slider_lo.border + slider_lo.gap + + -- calculate positions of min and max points + if slider_lo.stype ~= "bar" then + r1 = elem_geo.h / 2 + element.slider.min.ele_pos = elem_geo.h / 2 + element.slider.max.ele_pos = elem_geo.w - (elem_geo.h / 2) + if slider_lo.stype == "diamond" then + r2 = (elem_geo.h - 2 * slider_lo.border) / 2 + elseif slider_lo.stype == "knob" then + r2 = r1 + end + else + element.slider.min.ele_pos = slider_lo.border + slider_lo.gap + element.slider.max.ele_pos = elem_geo.w - (slider_lo.border + slider_lo.gap) + end + + element.slider.min.glob_pos = + element.hitbox.x1 + element.slider.min.ele_pos + element.slider.max.glob_pos = + element.hitbox.x1 + element.slider.max.ele_pos + + local static_ass = assdraw.ass_new() + static_ass:draw_start() + + -- the box + ass_draw_rr_h_cw(static_ass, 0, 0, elem_geo.w, elem_geo.h, r1, + slider_lo.stype == "diamond") + + -- the "hole" + ass_draw_rr_h_ccw(static_ass, slider_lo.border, slider_lo.border, + elem_geo.w - slider_lo.border, elem_geo.h - slider_lo.border, + r2, slider_lo.stype == "diamond") + + -- marker nibbles + if element.slider.markerF ~= nil and slider_lo.gap > 0 then + local markers = element.slider.markerF() + for _,marker in pairs(markers) do + if marker > element.slider.min.value and + marker < element.slider.max.value then + + local s = get_slider_ele_pos_for(element, marker) + + if slider_lo.gap > 1 then -- draw triangles + + local a = slider_lo.gap / 0.5 --0.866 + + --top + if slider_lo.nibbles_top then + static_ass:move_to(s - (a / 2), slider_lo.border) + static_ass:line_to(s + (a / 2), slider_lo.border) + static_ass:line_to(s, foV) + end + + --bottom + if slider_lo.nibbles_bottom then + static_ass:move_to(s - (a / 2), + elem_geo.h - slider_lo.border) + static_ass:line_to(s, + elem_geo.h - foV) + static_ass:line_to(s + (a / 2), + elem_geo.h - slider_lo.border) + end + + else -- draw 2x1px nibbles + + --top + if slider_lo.nibbles_top then + static_ass:rect_cw(s - 1, slider_lo.border, + s + 1, slider_lo.border + slider_lo.gap); + end + + --bottom + if slider_lo.nibbles_bottom then + static_ass:rect_cw(s - 1, + elem_geo.h - slider_lo.border - slider_lo.gap, + s + 1, elem_geo.h - slider_lo.border); + end + end + end + end + end + + element.static_ass = static_ass +end + local function prepare_elements() -- remove elements without layout or invisible @@ -834,113 +925,19 @@ local function prepare_elements() element.style_ass = style_ass - local static_ass = assdraw.ass_new() - - if element.type == "box" then --draw box + local static_ass = assdraw.ass_new() static_ass:draw_start() ass_draw_rr_h_cw(static_ass, 0, 0, elem_geo.w, elem_geo.h, element.layout.box.radius, element.layout.box.hexagon) static_ass:draw_stop() + element.static_ass = static_ass elseif element.type == "slider" then - --draw static slider parts - - local r1 = 0 - local r2 = 0 - local slider_lo = element.layout.slider - -- offset between element outline and drag-area - local foV = slider_lo.border + slider_lo.gap - - -- calculate positions of min and max points - if slider_lo.stype ~= "bar" then - r1 = elem_geo.h / 2 - element.slider.min.ele_pos = elem_geo.h / 2 - element.slider.max.ele_pos = elem_geo.w - (elem_geo.h / 2) - if slider_lo.stype == "diamond" then - r2 = (elem_geo.h - 2 * slider_lo.border) / 2 - elseif slider_lo.stype == "knob" then - r2 = r1 - end - else - element.slider.min.ele_pos = - slider_lo.border + slider_lo.gap - element.slider.max.ele_pos = - elem_geo.w - (slider_lo.border + slider_lo.gap) - end - - element.slider.min.glob_pos = - element.hitbox.x1 + element.slider.min.ele_pos - element.slider.max.glob_pos = - element.hitbox.x1 + element.slider.max.ele_pos - - -- -- -- - - static_ass:draw_start() - - -- the box - ass_draw_rr_h_cw(static_ass, 0, 0, elem_geo.w, elem_geo.h, r1, - slider_lo.stype == "diamond") - - -- the "hole" - ass_draw_rr_h_ccw(static_ass, slider_lo.border, slider_lo.border, - elem_geo.w - slider_lo.border, elem_geo.h - slider_lo.border, - r2, slider_lo.stype == "diamond") - - -- marker nibbles - if element.slider.markerF ~= nil and slider_lo.gap > 0 then - local markers = element.slider.markerF() - for _,marker in pairs(markers) do - if marker > element.slider.min.value and - marker < element.slider.max.value then - - local s = get_slider_ele_pos_for(element, marker) - - if slider_lo.gap > 1 then -- draw triangles - - local a = slider_lo.gap / 0.5 --0.866 - - --top - if slider_lo.nibbles_top then - static_ass:move_to(s - (a / 2), slider_lo.border) - static_ass:line_to(s + (a / 2), slider_lo.border) - static_ass:line_to(s, foV) - end - - --bottom - if slider_lo.nibbles_bottom then - static_ass:move_to(s - (a / 2), - elem_geo.h - slider_lo.border) - static_ass:line_to(s, - elem_geo.h - foV) - static_ass:line_to(s + (a / 2), - elem_geo.h - slider_lo.border) - end - - else -- draw 2x1px nibbles - - --top - if slider_lo.nibbles_top then - static_ass:rect_cw(s - 1, slider_lo.border, - s + 1, slider_lo.border + slider_lo.gap); - end - - --bottom - if slider_lo.nibbles_bottom then - static_ass:rect_cw(s - 1, - elem_geo.h -slider_lo.border -slider_lo.gap, - s + 1, elem_geo.h - slider_lo.border); - end - end - end - end - end + update_slider(element) end - element.static_ass = static_ass - - -- if the element is supposed to be disabled, -- style it accordingly and kill the eventresponders if not element.enabled then @@ -3206,8 +3203,9 @@ observe_cached("chapter-list", function () request_init() end) observe_cached("duration", function () - if user_opts.livemarkers and state.chapter_list[1] then - request_init() + if state.chapter_list[1] and state.slider_element then + update_slider(state.slider_element) + request_tick() end end)