From aa11ce779eeb479c015121a5f7dea713eee1c44a Mon Sep 17 00:00:00 2001 From: Guido Cella Date: Tue, 31 Dec 2024 10:39:46 +0100 Subject: [PATCH] various: define builtin options and key bindings for images This makes mpv usable as an image viewer out of the box, as it is currently hard to setup. Using mpv as an image viewer has several advantages, the biggest one is that it's the best program at browsing directories of mixed videos and images. This adds a builtin image conditional profile that users can extend in mpv.conf. It is written to not restore and reapply the options on each image change, because that is slow for certain options (e.g. --d3d11-flip=no restarts the VO), and causes visible flicker when options like gamma are unapplied before changing image and reapplied on the next image. But it still restores the previous options after switching to a video or audio file. Default image key bindings are defined in the image input section. sxiv is their main inspiration. Closes #7983, closes #12496. --- DOCS/man/input.rst | 5 +- DOCS/man/mpv.rst | 153 +++++++++++++++++++++++++++++++++++++++++++++ etc/builtin.conf | 14 +++++ etc/input.conf | 69 ++++++++++++++++++++ 4 files changed, 240 insertions(+), 1 deletion(-) diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst index 2e493637865a4..7fc707dca97f6 100644 --- a/DOCS/man/input.rst +++ b/DOCS/man/input.rst @@ -59,7 +59,10 @@ string arguments). To bind commands to the ``#`` key, ``SHARP`` can be used. character), or a symbolic name (as printed by ``--input-keylist``). ``
`` (braced with ``{`` and ``}``) is the input section for this -command. +command. Notably, key bindings can be defined in the builtin ``image`` input +section to enable them only when viewing images. For example: + + SPACE {image} repeatable playlist-next force ```` is the command itself. It consists of the command name and multiple (or none) arguments, all separated by whitespace. String arguments diff --git a/DOCS/man/mpv.rst b/DOCS/man/mpv.rst index 14989b284c98f..db570e1f4a24c 100644 --- a/DOCS/man/mpv.rst +++ b/DOCS/man/mpv.rst @@ -380,6 +380,75 @@ To use this feature, you need to fill the ``menu-data`` property with menu definition data, and add a keybinding to run the ``context-menu`` command, which can be done with a user script. +Image Bindings +-------------- + +Several key bindings are changed when viewing images: + +LEFT, RIGHT, UP, DOWN, h, j, k, l + Pan the image when it is larger than the window. + +Ctrl+LEFT, Ctrl+RIGHT, Ctrl+UP, Ctrl+DOWN, Ctrl+h, Ctrl+j, Ctrl+k, Ctrl+l + Align the image to one of the boundaries of the window when it is larger + than the window. + += and - + Change the zoom. + ++ and _ + Change the zoom slowly. + +0 + Reset the zoom. + +u + Toggle between showing the image unscaled in its original dimensions and + fitting it to the window. + +o + Fill the window with the image. + +r + Rotate counterclockwise. + +R and t + Rotate clockwise. + +v + Rotate by 180 degrees. + +SPACE + Toggle between showing images for 5 seconds in a slideshow and keeping them + open forever. + +[ and ] + Decrease/increase the image display duration by 1. + +{ and } + Halve/double the image display duration. + +n + Go to the next playlist entry. + +p + Go to the previous playlist entry. + +N + Go to the next sub-playlist (e.g. directory or archive). + +P + Go to the previous sub-playlist. + +HOME and g-g + Go to the first playlist entry. + +END and G + Go to the last playlist entry. + +Wheel up/down + Change the zoom while keeping the part of the image hovered by the cursor + under it. + USAGE ===== @@ -1038,6 +1107,90 @@ example, ``math`` is defined and gives access to the Lua standard math library. This feature is subject to change indefinitely. You might be forced to adjust your profiles on mpv updates. +Image profile +------------------- + +mpv has a builtin conditional profile that is automatically applied to images +and restored when switching to a video or audio file. Its options are: + +.. admonition:: Builtin profile definition + + :: + + [image] + script-opt=osc-deadzonesize=1 + prefetch-playlist + video-recenter + video-aspect-override=no + input-preprocess-wheel=no + +It can be extended in mpv.conf without overwriting it completely: + +.. admonition:: Example to loop image playlists + + :: + + [image] + loop-playlist + +You can stop applying it automatically by specifying an empty ``profile-cond``: + +.. admonition:: Example to disable the image conditional profile + + :: + + [image] + profile-cond= + +This profile uses ``--input-commands`` to enable image specific key bindings. +This can be disabled with ``input-commands-clr``. Extra commands should be +specified with ``input-commands-append`` to keep enabling the image key +bindings. Additional image key bindings can be specified in the ``image`` +section in ``input.conf`` - see the `INPUT.CONF`_ section. + +To reset zoom and rotation between images, it is recommended to place +``reset-on-next-file=video-zoom,panscan,video-unscaled,video-rotate`` in the top +level of mpv.conf, as enabling it in a conditional profile makes it take effect +only from the second file. + +To start viewing images and videos bigger than the window from the top left +corner, these options can be set in the top level of mpv.conf: + +.. admonition:: Start from the top left: + + :: + + video-align-x=-1 + video-align-y=-1 + video-recenter + reset-on-next-file=video-align-x,video-align-y + +To enable the screensaver only when images are kept open forever, this can be +added to mpv.conf: + +.. admonition:: Example to enable the screensaver: + + :: + + [screensaver] + profile-cond=p['current-tracks/video'].image and not p['current-tracks/video'].albumart and image_display_duration == math.huge + profile-restore=copy + stop-screensaver=no + +``--vo=gpu-next`` is recommended for better performance on large images, except +images larger than the max texture size of the GPU API, for which a VO with +software rendering can be used as fallback. + +.. admonition:: Example to display huge images on Wayland: + + :: + + [huge] + profile-cond=width > 16384 or height > 16384 + vo=wlshm + +maxImageExtent may be 8192 instead on old iGPUs. + Legacy auto profiles -------------------- diff --git a/etc/builtin.conf b/etc/builtin.conf index 6108cc71d546a..2614e74c26bad 100644 --- a/etc/builtin.conf +++ b/etc/builtin.conf @@ -97,3 +97,17 @@ sub-shadow-offset=4 [box] profile=osd-box profile=sub-box + +[image] +profile-cond=(get('current-tracks/video', {}).image and not get('current-tracks/video', {}).albumart) or (not get('current-tracks/video') and get('user-data/mpv/image')) +profile-restore=copy-equal +input-commands-append=no-osd set user-data/mpv/image 1; enable-section image allow-hide-cursor+allow-vo-dragging +script-opt=osc-deadzonesize=1 +prefetch-playlist +video-recenter +video-aspect-override=no +input-preprocess-wheel=no + +[builtin-non-image] +profile-cond=get('user-data/mpv/image') and (not get('current-tracks/video', {image = true}).image or get('current-tracks/audio')) +input-commands=no-osd del user-data/mpv/image; disable-section image diff --git a/etc/input.conf b/etc/input.conf index ed05bbd4148c6..9547a4e6db8ad 100644 --- a/etc/input.conf +++ b/etc/input.conf @@ -234,3 +234,72 @@ # ? cycle sub-forced-events-only # display only DVD/PGS forced subtitle events # ? stop # stop playback (quit or enter idle mode) + +# +# Image bindings +# +#LEFT {image} script-binding positioning/pan-x -0.1 # pan left +#DOWN {image} script-binding positioning/pan-y 0.1 # pan down +#UP {image} script-binding positioning/pan-y -0.1 # pan up +#RIGHT {image} script-binding positioning/pan-x 0.1 # pan right +#h {image} script-binding positioning/pan-x -0.1 # pan left +#j {image} script-binding positioning/pan-y 0.1 # pan down +#k {image} script-binding positioning/pan-y -0.1 # pan up +#l {image} script-binding positioning/pan-x 0.1 # pan right +#Shift+LEFT {image} script-binding positioning/pan-x -0.01 # pan left slowly +#Shift+DOWN {image} script-binding positioning/pan-y 0.01 # pan down slowly +#Shift+UP {image} script-binding positioning/pan-y -0.01 # pan up slowly +#Shift+RIGHT {image} script-binding positioning/pan-x 0.01 # pan right slowly +#H {image} script-binding positioning/pan-x -0.01 # pan left slowly +#J {image} script-binding positioning/pan-y 0.01 # pan down slowly +#K {image} script-binding positioning/pan-y -0.01 # pan up slowly +#L {image} script-binding positioning/pan-x 0.01 # pan right slowly + +# Recommened on a touchpad: +# WHEEL_UP {image} script-binding positioning/pan-y -0.1 # pan up +# WHEEL_DOWN {image} script-binding positioning/pan-y 0.1 # pan down +# WHEEL_LEFT {image} script-binding positioning/pan-x -0.1 # pan left +# WHEEL_RIGHT {image} script-binding positioning/pan-x 0.1 # pan right + +#Ctrl+LEFT {image} no-osd set video-align-x -1 # align to the left +#Ctrl+DOWN {image} no-osd set video-align-y 1 # align to the bottom +#Ctrl+UP {image} no-osd set video-align-y -1 # align to the top +#Ctrl+RIGHT {image} no-osd set video-align-x 1 # align to the right +#Ctrl+h {image} no-osd set video-align-x -1 # align to the left +#Ctrl+j {image} no-osd set video-align-y 1 # align to the bottom +#Ctrl+k {image} no-osd set video-align-y -1 # align to the top +#Ctrl+l {image} no-osd set video-align-x 1 # align to the right + +#= {image} add video-zoom 0.25 # zoom in +#- {image} add video-zoom -0.25 # zoom out +#+ {image} add video-zoom 0.05 # zoom in slowly +#_ {image} add video-zoom -0.05 # zoom out slowly +#0 {image} no-osd set video-zoom 0; no-osd set panscan 0 # reset zoom + +#WHEEL_UP {image} script-binding cursor-centric-zoom 0.1 # zoom in towards the cursor +#WHEEL_DOWN {image} script-binding cursor-centric-zoom -0.1 # zoom out towards the cursor + +#u {image} no-osd cycle-values video-unscaled yes no; no-osd set video-zoom 0; no-osd set panscan 0 # toggle scaling the image to the window. + +#o {image} no-osd set panscan 1; no-osd set video-unscaled no; no-osd set video-zoom 0 # fill black bars + +#r {image} cycle-values video-rotate 270 180 90 0 # rotate counterclockwise +#R {image} cycle-values video-rotate 90 180 270 0 # rotate clockwise +#t {image} cycle-values video-rotate 90 180 270 0 # rotate clockwise +#v {image} cycle-values video-rotate 0 180 # rotate by 180 degrees + +#SPACE {image} cycle-values image-display-duration inf 5; no-osd set pause no # toggle slideshow +#[ {image} add image-display-duration -1 # decrease the slideshow duration +#] {image} add image-display-duration 1 # increment the slideshow duration +#{ {image} multiply image-display-duration 0.5 # halve the slideshow duration +#} {image} multiply image-display-duration 2 # double the slideshow duration + +#n {image} repeatable playlist-next # go to the next file +#p {image} repeatable playlist-prev # go to the previous file +#N {image} playlist-next-playlist # go to the next sub-playlist +#P {image} playlist-prev-playlist # go to the previous sub-playlist + +#HOME {image} no-osd set playlist-pos 0 # go to the first playlist entry +#g-g {image} no-osd set playlist-pos 0 # go to the first playlist entry +#END {image} no-osd set playlist-pos-1 ${playlist-count} # go to the last playlist entry +#G {image} no-osd set playlist-pos-1 ${playlist-count} # go to the last playlist entry