From 001308891ffe9dc8b3e8c94900284bc948bcc4d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= Date: Tue, 10 Mar 2026 13:01:12 +0100 Subject: [PATCH 1/5] DOCS/man/osc: fix boxvideo description --- DOCS/man/osc.rst | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/DOCS/man/osc.rst b/DOCS/man/osc.rst index 104e04bb58e2f..fff97ce87b014 100644 --- a/DOCS/man/osc.rst +++ b/DOCS/man/osc.rst @@ -392,13 +392,10 @@ Configurable Options if this option is set. Separately, if window controls are present (see below), they will be affected regardless of which osc layout is in use. - The border is static and appears even if the OSC is configured to appear - only on mouse interaction. If the OSC is invisible, the border is simply - filled with the background color (black by default). - - This currently still makes the OSC overlap with subtitles (if the - ``--sub-use-margins`` option is set to ``yes``, the default). This may be - fixed later. + Subtitles may still overlap with the OSC when ``--sub-use-margins`` is set + to ``yes`` (the default), as they are allowed to extend into the margin + area. Setting ``--sub-use-margins=no`` confines subtitles to the video + area. This does not work correctly with video outputs like ``--vo=xv``, which render OSD into the unscaled video. From 8ba8a27fd18509f9647225e7717750c015f1e33e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= Date: Tue, 10 Mar 2026 13:26:50 +0100 Subject: [PATCH 2/5] osc.lua: fix always visibility --- player/lua/osc.lua | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/player/lua/osc.lua b/player/lua/osc.lua index bf11c9634051b..e239585b9eea9 100644 --- a/player/lua/osc.lua +++ b/player/lua/osc.lua @@ -2413,8 +2413,16 @@ local function process_event(source, what) ) ) then if window_controls_enabled() and user_opts.windowcontrols_independent then - if mouse_in_area("showhide_wc") then show_wc() else hide_wc() end - if mouse_in_area("showhide") then show_osc() else hide_osc() end + if mouse_in_area("showhide_wc") then + show_wc() + elseif user_opts.visibility ~= "always" then + hide_wc() + end + if mouse_in_area("showhide") then + show_osc() + elseif user_opts.visibility ~= "always" then + hide_osc() + end else show_osc() if window_controls_enabled() then show_wc() end From 8adf359eed3380e5d3705093fbbef2373e164960 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= Date: Tue, 10 Mar 2026 13:25:55 +0100 Subject: [PATCH 3/5] osc.lua: add `dynamic_margins` option --- DOCS/interface-changes/osc-margins.txt | 1 + DOCS/man/osc.rst | 12 ++++++++++-- player/lua/osc.lua | 27 +++++++++++++------------- 3 files changed, 25 insertions(+), 15 deletions(-) create mode 100644 DOCS/interface-changes/osc-margins.txt diff --git a/DOCS/interface-changes/osc-margins.txt b/DOCS/interface-changes/osc-margins.txt new file mode 100644 index 0000000000000..1f73b171d79d5 --- /dev/null +++ b/DOCS/interface-changes/osc-margins.txt @@ -0,0 +1 @@ +add `osc-dynamic_margins` option diff --git a/DOCS/man/osc.rst b/DOCS/man/osc.rst index fff97ce87b014..e75b281b5a904 100644 --- a/DOCS/man/osc.rst +++ b/DOCS/man/osc.rst @@ -384,8 +384,9 @@ Configurable Options within the areas not covered by the osc (``yes``). If this option is set, the osc may overwrite the ``--video-margin-ratio-*`` options, even if the user has set them. (It will not overwrite them if all of them are set to - default values.) Additionally, ``visibility`` must be set to ``always``. - Otherwise, this option does nothing. + default values.) By default, ``visibility`` must be set to ``always``. + Use ``dynamic_margins`` to allow margins to update with OSC visibility + instead. Currently, this is supported for the ``bottombar``, ``slimbottombar``, ``topbar`` and ``slimtopbar`` layouts only. The other layouts do not change @@ -400,6 +401,13 @@ Configurable Options This does not work correctly with video outputs like ``--vo=xv``, which render OSD into the unscaled video. +``dynamic_margins`` + Default: no + + When set to ``yes``, margins follow the actual OSC visibility: they are + applied when the OSC appears and removed when it hides. Without this + option, margins are only applied when ``visibility`` is set to ``always``. + ``windowcontrols`` Default: auto (Show window controls if there is no window border) diff --git a/player/lua/osc.lua b/player/lua/osc.lua index e239585b9eea9..ffbf85248fa71 100644 --- a/player/lua/osc.lua +++ b/player/lua/osc.lua @@ -48,6 +48,7 @@ local user_opts = { visibility_modes = "never_auto_always", -- visibility modes to cycle through boxmaxchars = 80, -- title crop threshold for box layout boxvideo = false, -- apply osc_param.video_margins to video + dynamic_margins = false, -- update margins dynamically with OSC visibility windowcontrols = "auto", -- whether to show window controls windowcontrols_alignment = "right", -- which side to show window controls on windowcontrols_title = "${media-title}", -- same as title but for windowcontrols @@ -550,15 +551,15 @@ local function reset_margins() end local function update_margins() - local margins = osc_param.video_margins - - -- Don't use margins if it's visible only temporarily. - if not state.osc_visible or get_hidetimeout() >= 0 or - (state.fullscreen and not user_opts.showfullscreen) or - (not state.fullscreen and not user_opts.showwindowed) - then - margins = {l = 0, r = 0, t = 0, b = 0} - end + local use_margins = get_hidetimeout() < 0 or user_opts.dynamic_margins + local top_vis = (user_opts.layout:find("top") and state.osc_visible) or state.wc_visible + local bottom_vis = user_opts.layout:find("bottom") and state.osc_visible + local margins = { + l = use_margins and osc_param.video_margins.l or 0, + r = use_margins and osc_param.video_margins.r or 0, + t = (use_margins and top_vis) and osc_param.video_margins.t or 0, + b = (use_margins and bottom_vis) and osc_param.video_margins.b or 0, + } if user_opts.boxvideo then -- check whether any margin option has a non-default value @@ -2241,20 +2242,20 @@ local function osc_init() update_margins() end -local function set_bar_visible(visible_key, visible, with_margins) +local function set_bar_visible(visible_key, visible) if state[visible_key] ~= visible then state[visible_key] = visible - if with_margins then update_margins() end + update_margins() end request_tick() end local function osc_visible(visible) - set_bar_visible("osc_visible", visible, true) + set_bar_visible("osc_visible", visible) end local function set_wc_visible(visible) - set_bar_visible("wc_visible", visible, false) + set_bar_visible("wc_visible", visible) end local function show_bar(label, showtime_key, visible_key, anitype_key, set_visible) From 71cbbeb8aa30397b07514fecad1ff60eef49e284 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= Date: Tue, 10 Mar 2026 13:29:43 +0100 Subject: [PATCH 4/5] osc.lua: add `sub-margin` option --- DOCS/interface-changes/osc-margins.txt | 1 + DOCS/man/osc.rst | 12 ++++++++++ player/lua/osc.lua | 31 ++++++++++++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/DOCS/interface-changes/osc-margins.txt b/DOCS/interface-changes/osc-margins.txt index 1f73b171d79d5..64f7a36038091 100644 --- a/DOCS/interface-changes/osc-margins.txt +++ b/DOCS/interface-changes/osc-margins.txt @@ -1 +1,2 @@ add `osc-dynamic_margins` option +add `osc-sub-margin` option diff --git a/DOCS/man/osc.rst b/DOCS/man/osc.rst index e75b281b5a904..bd32443f7c2ec 100644 --- a/DOCS/man/osc.rst +++ b/DOCS/man/osc.rst @@ -408,6 +408,18 @@ Configurable Options applied when the OSC appears and removed when it hides. Without this option, margins are only applied when ``visibility`` is set to ``always``. +``sub_margins`` + Default: yes + + Whether to adjust ``--sub-margin-y`` so that subtitles do not overlap + with the OSC. The offset is derived from the bottom OSC margin and added + on top of the current ``--sub-margin-y`` value. Requires + ``dynamic_margins`` or ``visibility=always`` to take effect. + + With ``boxvideo`` enabled and ``--sub-use-margins=no``, subtitles are + already confined to the video area and this option has no additional + effect. + ``windowcontrols`` Default: auto (Show window controls if there is no window border) diff --git a/player/lua/osc.lua b/player/lua/osc.lua index ffbf85248fa71..ace10c384f210 100644 --- a/player/lua/osc.lua +++ b/player/lua/osc.lua @@ -49,6 +49,7 @@ local user_opts = { boxmaxchars = 80, -- title crop threshold for box layout boxvideo = false, -- apply osc_param.video_margins to video dynamic_margins = false, -- update margins dynamically with OSC visibility + sub_margins = true, -- adjust sub-margin-y to not overlap with OSC windowcontrols = "auto", -- whether to show window controls windowcontrols_alignment = "right", -- which side to show window controls on windowcontrols_title = "${media-title}", -- same as title but for windowcontrols @@ -541,6 +542,18 @@ local function cache_enabled() return state.cache_state and #state.cache_state["seekable-ranges"] > 0 end +local function set_margin_offset(prop, offset) + if offset > 0 then + if not state[prop] then + state[prop] = mp.get_property_number(prop) + end + mp.set_property_number(prop, state[prop] + offset) + elseif state[prop] then + mp.set_property_number(prop, state[prop]) + state[prop] = nil + end +end + local function reset_margins() if state.using_video_margins then for _, mopt in ipairs(margins_opts) do @@ -548,6 +561,7 @@ local function reset_margins() end state.using_video_margins = false end + set_margin_offset("sub-margin-y", 0) end local function update_margins() @@ -586,6 +600,23 @@ local function update_margins() reset_margins() end + local function get_margin(ent) + local margin = 0 + if user_opts[ent .. "_margins"] then + local align = mp.get_property(ent .. "-align-y") + if align == "top" and top_vis then + margin = margins.t + elseif align == "bottom" and bottom_vis then + margin = margins.b + end + end + if ent == "sub" and user_opts.boxvideo and mp.get_property_bool("sub-use-margins") then + margin = 0 + end + return margin * osc_param.playresy + end + set_margin_offset("sub-margin-y", get_margin("sub")) + mp.set_property_native("user-data/osc/margins", margins) end From 66d774a2569acc6af4c89e3a0532a0edf0894c28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= Date: Tue, 10 Mar 2026 13:30:11 +0100 Subject: [PATCH 5/5] osc.lua: add `osd-margin` option Fixes: #17539 --- DOCS/interface-changes/osc-margins.txt | 1 + DOCS/man/osc.rst | 9 +++++++++ player/lua/osc.lua | 3 +++ 3 files changed, 13 insertions(+) diff --git a/DOCS/interface-changes/osc-margins.txt b/DOCS/interface-changes/osc-margins.txt index 64f7a36038091..f4e61422ccee6 100644 --- a/DOCS/interface-changes/osc-margins.txt +++ b/DOCS/interface-changes/osc-margins.txt @@ -1,2 +1,3 @@ add `osc-dynamic_margins` option add `osc-sub-margin` option +add `osc-osd-margin` option diff --git a/DOCS/man/osc.rst b/DOCS/man/osc.rst index bd32443f7c2ec..5981416761916 100644 --- a/DOCS/man/osc.rst +++ b/DOCS/man/osc.rst @@ -420,6 +420,15 @@ Configurable Options already confined to the video area and this option has no additional effect. +``osd_margins`` + Default: yes + + Whether to adjust ``--osd-margin-y`` so that OSD text does not overlap + with the OSC. The offset is derived from the top OSC margin (including + window controls when present) and added on top of the current + ``--osd-margin-y`` value. Requires ``dynamic_margins`` or + ``visibility=always`` to take effect. + ``windowcontrols`` Default: auto (Show window controls if there is no window border) diff --git a/player/lua/osc.lua b/player/lua/osc.lua index ace10c384f210..36db44e790402 100644 --- a/player/lua/osc.lua +++ b/player/lua/osc.lua @@ -50,6 +50,7 @@ local user_opts = { boxvideo = false, -- apply osc_param.video_margins to video dynamic_margins = false, -- update margins dynamically with OSC visibility sub_margins = true, -- adjust sub-margin-y to not overlap with OSC + osd_margins = true, -- adjust osd-margin-y to not overlap with OSC windowcontrols = "auto", -- whether to show window controls windowcontrols_alignment = "right", -- which side to show window controls on windowcontrols_title = "${media-title}", -- same as title but for windowcontrols @@ -562,6 +563,7 @@ local function reset_margins() state.using_video_margins = false end set_margin_offset("sub-margin-y", 0) + set_margin_offset("osd-margin-y", 0) end local function update_margins() @@ -616,6 +618,7 @@ local function update_margins() return margin * osc_param.playresy end set_margin_offset("sub-margin-y", get_margin("sub")) + set_margin_offset("osd-margin-y", get_margin("osd")) mp.set_property_native("user-data/osc/margins", margins) end