0
0
mirror of https://github.com/mpv-player/mpv.git synced 2024-09-20 03:52:22 +02:00

osc: rework window control configuration to add auto mode

To aid in discoverability, and to address the most common case
directly, I'm adding an 'auto' mode for the window controls. In
this case, we will show the controls if there is no window border
and hide them if there are borders. This also respects the option
being toggled at runtime.

To ensure that it works in the wayland case, I've also made sure
that the wayland code explicitly forces the option to false if
decoration support is missing.

Based on feedback, I've split the config in two, with one option
for whether controls are active, and one for alignment. These are
new enough that we can get away with ignoring compatibility.
This commit is contained in:
Philip Langdale 2019-12-03 21:48:06 +08:00
parent f8689eff6d
commit 353e4efdef
3 changed files with 61 additions and 19 deletions

View File

@ -344,7 +344,7 @@ Configurable Options
fixed later. fixed later.
``windowcontrols`` ``windowcontrols``
Default: no (Do not show window controls) Default: auto (Show window controls if there is no window border)
Whether to show window management controls over the video, and if so, Whether to show window management controls over the video, and if so,
which side of the window to place them. This may be desirable when the which side of the window to place them. This may be desirable when the
@ -356,6 +356,12 @@ Configurable Options
and ``quit``. Not all platforms implement ``minimize`` and ``maximize``, and ``quit``. Not all platforms implement ``minimize`` and ``maximize``,
but ``quit`` will always work. but ``quit`` will always work.
``windowcontrols_alignment``
Default: right
If window controls are shown, indicates which side should they be aligned
to.
Supports ``left`` and ``right`` which will place the controls on those Supports ``left`` and ``right`` which will place the controls on those
respective sides. respective sides.

View File

@ -45,7 +45,8 @@ local user_opts = {
visibility = "auto", -- only used at init to set visibility_mode(...) visibility = "auto", -- only used at init to set visibility_mode(...)
boxmaxchars = 80, -- title crop threshold for box layout boxmaxchars = 80, -- title crop threshold for box layout
boxvideo = false, -- apply osc_param.video_margins to video boxvideo = false, -- apply osc_param.video_margins to video
windowcontrols = "no", -- where to show window controls (or not at all) windowcontrols = "auto", -- whether to show window controls
windowcontrols_alignment = "right" -- which side to show window controls on
} }
-- read_options may modify hidetimeout, so save the original default value in -- read_options may modify hidetimeout, so save the original default value in
@ -58,6 +59,21 @@ if user_opts.hidetimeout < 0 then
msg.warn("hidetimeout cannot be negative. Using " .. user_opts.hidetimeout) msg.warn("hidetimeout cannot be negative. Using " .. user_opts.hidetimeout)
end end
-- validate window control options
if user_opts.windowcontrols ~= "auto" and
user_opts.windowcontrols ~= "yes" and
user_opts.windowcontrols ~= "no" then
msg.warn("windowcontrols cannot be \"" ..
user_opts.windowcontrols .. "\". Ignoring.")
user_opts.windowcontrols = "auto"
end
if user_opts.windowcontrols_alignment ~= "right" and
user_opts.windowcontrols_alignment ~= "left" then
msg.warn("windowcontrols_alignment cannot be \"" ..
user_opts.windowcontrols_alignment .. "\". Ignoring.")
user_opts.windowcontrols_alignment = "right"
end
local osc_param = { -- calculated by osc_init() local osc_param = { -- calculated by osc_init()
playresy = 0, -- canvas size Y playresy = 0, -- canvas size Y
playresx = 0, -- canvas size X playresx = 0, -- canvas size X
@ -117,6 +133,7 @@ local state = {
showhide_enabled = false, showhide_enabled = false,
dmx_cache = 0, dmx_cache = 0,
using_video_margins = false, using_video_margins = false,
border = true,
} }
local window_control_box_width = 80 local window_control_box_width = 80
@ -393,6 +410,19 @@ function get_track(type)
return 0 return 0
end end
-- WindowControl helpers
function window_controls_enabled()
val = user_opts.windowcontrols
if val == "auto" then
return not state.border
else
return val ~= "no"
end
end
function window_controls_alignment()
return user_opts.windowcontrols_alignment
end
-- --
-- Element Management -- Element Management
@ -966,7 +996,7 @@ function add_layout(name)
end end
-- Window Controls -- Window Controls
function window_controls(alignment, topbar) function window_controls(topbar)
local wc_geo = { local wc_geo = {
x = 0, x = 0,
y = 30 + user_opts.barmargin, y = 30 + user_opts.barmargin,
@ -975,6 +1005,7 @@ function window_controls(alignment, topbar)
h = 30, h = 30,
} }
local alignment = window_controls_alignment()
local controlbox_w = window_control_box_width local controlbox_w = window_control_box_width
local titlebox_w = wc_geo.w - controlbox_w local titlebox_w = wc_geo.w - controlbox_w
@ -985,12 +1016,6 @@ function window_controls(alignment, topbar)
if alignment == "left" then if alignment == "left" then
controlbox_left = wc_geo.x controlbox_left = wc_geo.x
titlebox_left = wc_geo.x + controlbox_w + 5 titlebox_left = wc_geo.x + controlbox_w + 5
elseif alignment == "right" or
alignment == "yes" then
-- Already default
else
msg.error("Invalid setting \""..alignment.."\" for windowcontrols")
-- Falls back to "right"
end end
add_area("window-controls", add_area("window-controls",
@ -1367,7 +1392,7 @@ layouts["slimbox"] = function ()
end end
function bar_layout(direction, windowcontrols) function bar_layout(direction)
local osc_geo = { local osc_geo = {
x = -2, x = -2,
y, y,
@ -1386,10 +1411,10 @@ function bar_layout(direction, windowcontrols)
-- Special topbar handling when window controls are present -- Special topbar handling when window controls are present
local padwc_l local padwc_l
local padwc_r local padwc_r
if direction < 0 or windowcontrols == "no" then if direction < 0 or not window_controls_enabled() then
padwc_l = 0 padwc_l = 0
padwc_r = 0 padwc_r = 0
elseif windowcontrols == "left" then elseif window_controls_alignment() == "left" then
padwc_l = window_control_box_width padwc_l = window_control_box_width
padwc_r = 0 padwc_r = 0
else else
@ -1571,11 +1596,11 @@ function bar_layout(direction, windowcontrols)
end end
layouts["bottombar"] = function() layouts["bottombar"] = function()
bar_layout(-1, false) bar_layout(-1)
end end
layouts["topbar"] = function() layouts["topbar"] = function()
bar_layout(1, user_opts.windowcontrols) bar_layout(1)
end end
-- Validate string type user options -- Validate string type user options
@ -1992,9 +2017,8 @@ function osc_init()
layouts[user_opts.layout]() layouts[user_opts.layout]()
-- load window controls -- load window controls
if user_opts.windowcontrols ~= "no" then if window_controls_enabled() then
window_controls(user_opts.windowcontrols, window_controls(user_opts.layout == "topbar")
user_opts.layout == "topbar")
end end
--do something with the elements --do something with the elements
@ -2244,7 +2268,7 @@ function render()
end end
end end
if user_opts.windowcontrols ~= "no" then if osc_param.areas["window-controls"] then
for _,cords in ipairs(osc_param.areas["window-controls"]) do for _,cords in ipairs(osc_param.areas["window-controls"]) do
if state.osc_visible then -- activate only when OSC is actually visible if state.osc_visible then -- activate only when OSC is actually visible
set_virt_mouse_area(cords.x1, cords.y1, cords.x2, cords.y2, "window-controls") set_virt_mouse_area(cords.x1, cords.y1, cords.x2, cords.y2, "window-controls")
@ -2470,6 +2494,11 @@ mp.observe_property("fullscreen", "bool",
request_init() request_init()
end end
) )
mp.observe_property("border", "bool",
function(name, val)
state.border = val
end
)
mp.observe_property("idle-active", "bool", mp.observe_property("idle-active", "bool",
function(name, val) function(name, val)
state.idle = val state.idle = val

View File

@ -1047,8 +1047,12 @@ static int create_xdg_surface(struct vo_wayland_state *wl)
static int set_border_decorations(struct vo_wayland_state *wl, int state) static int set_border_decorations(struct vo_wayland_state *wl, int state)
{ {
if (!wl->xdg_toplevel_decoration) if (!wl->xdg_toplevel_decoration) {
wl->vo_opts->border = false;
m_config_cache_write_opt(wl->vo_opts_cache,
&wl->vo_opts->border);
return VO_NOTIMPL; return VO_NOTIMPL;
}
enum zxdg_toplevel_decoration_v1_mode mode; enum zxdg_toplevel_decoration_v1_mode mode;
if (state) { if (state) {
@ -1131,6 +1135,9 @@ int vo_wayland_init(struct vo *vo)
wl->xdg_toplevel_decoration = zxdg_decoration_manager_v1_get_toplevel_decoration(wl->xdg_decoration_manager, wl->xdg_toplevel); wl->xdg_toplevel_decoration = zxdg_decoration_manager_v1_get_toplevel_decoration(wl->xdg_decoration_manager, wl->xdg_toplevel);
set_border_decorations(wl, wl->vo_opts->border); set_border_decorations(wl, wl->vo_opts->border);
} else { } else {
wl->vo_opts->border = false;
m_config_cache_write_opt(wl->vo_opts_cache,
&wl->vo_opts->border);
MP_VERBOSE(wl, "Compositor doesn't support the %s protocol!\n", MP_VERBOSE(wl, "Compositor doesn't support the %s protocol!\n",
zxdg_decoration_manager_v1_interface.name); zxdg_decoration_manager_v1_interface.name);
} }