From 8368d55282459dc303ee2d2859917685c2de3ef3 Mon Sep 17 00:00:00 2001 From: nanahi <130121847+na-na-hi@users.noreply.github.com> Date: Fri, 14 Feb 2025 22:20:27 -0500 Subject: [PATCH] clipboard: add --clipboard-backends option This allows specifying a priority list of clipboard backends to use. This is mostly useful on Linux where multiple clipboard backends exist. --- DOCS/interface-changes/clipboard.txt | 1 + DOCS/man/input.rst | 18 +------ DOCS/man/options.rst | 27 +++++++++++ player/clipboard/clipboard.c | 71 +++++++++++++++++++++------- player/clipboard/clipboard.h | 1 + 5 files changed, 84 insertions(+), 34 deletions(-) diff --git a/DOCS/interface-changes/clipboard.txt b/DOCS/interface-changes/clipboard.txt index 53dd1abc41..98c7ec94fc 100644 --- a/DOCS/interface-changes/clipboard.txt +++ b/DOCS/interface-changes/clipboard.txt @@ -1,3 +1,4 @@ add `--clipboard-enable` and `--clipboard-monitor` options add `clipboard` property add `current-clipboard-backend` property +add `--clipboard-backends` option diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst index 13acb73168..30c15beb33 100644 --- a/DOCS/man/input.rst +++ b/DOCS/man/input.rst @@ -4013,23 +4013,7 @@ Property list ``current-clipboard-backend`` A string containing the currently active clipboard backend. - The following clipboard backends are implemented: - - ``win32`` - Windows backend. - - ``mac`` - macOS backend. - - ``wayland`` - Wayland backend. This backend is only available if the compositor - supports the ``ext-data-control-v1`` protocol. - - ``vo`` - VO backend. Requires an active VO window, and support differs across - platforms. Currently, this is used as a fallback for Wayland - compositors without support for the ``ext-data-control-v1`` - protocol. + See ``--clipboard-backends`` option for the list of available backends. ``clock`` diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index c09993d639..03066577a8 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -7939,3 +7939,30 @@ Miscellaneous On Wayland, this option only has effect on the ``wayland`` backend, and not for the ``vo`` backend. See ``current-clipboard-backend`` property for more details. + +``--clipboard-backends=`` + Specify a priority list of the clipboard backends to be used. + You can also pass ``help`` to get a complete list of compiled in backends. + + Note that the default clipboard backends are subject to change, + and must not be relied upon. + + The following clipboard backends are implemented: + + ``win32`` + Windows backend. + + ``mac`` + macOS backend. + + ``wayland`` + Wayland backend. This backend is only available if the compositor + supports the ``ext-data-control-v1`` protocol. + + ``vo`` + VO backend. Requires an active VO window, and support differs across + platforms. Currently, this is used as a fallback for Wayland + compositors without support for the ``ext-data-control-v1`` + protocol, or if the ``wayland`` backend is disabled. + + This is an object settings list option. See `List Options`_ for details. diff --git a/player/clipboard/clipboard.c b/player/clipboard/clipboard.c index ce38e8e743..5cf4580853 100644 --- a/player/clipboard/clipboard.c +++ b/player/clipboard/clipboard.c @@ -25,19 +25,7 @@ struct clipboard_opts { bool enabled; bool monitor; -}; - -#define OPT_BASE_STRUCT struct clipboard_opts -const struct m_sub_options clipboard_conf = { - .opts = (const struct m_option[]) { - {"enable", OPT_BOOL(enabled), .flags = UPDATE_CLIPBOARD}, - {"monitor", OPT_BOOL(monitor), .flags = UPDATE_CLIPBOARD}, - {0} - }, - .defaults = &(const struct clipboard_opts) { - .enabled = true, - }, - .size = sizeof(struct clipboard_opts) + struct m_obj_settings *backends; }; // backend list @@ -59,6 +47,48 @@ static const struct clipboard_backend *const clipboard_backend_list[] = { &clipboard_backend_vo, }; +static bool get_desc(struct m_obj_desc *dst, int index) +{ + if (index >= MP_ARRAY_SIZE(clipboard_backend_list)) + return false; + const struct clipboard_backend *backend = clipboard_backend_list[index]; + *dst = (struct m_obj_desc) { + .name = backend->name, + .description = backend->desc, + }; + return true; +} + +static const struct m_obj_list backend_obj_list = { + .get_desc = get_desc, + .description = "clipboard backends", + .allow_trailer = true, + .disallow_positional_parameters = true, + .use_global_options = true, +}; + +#define OPT_BASE_STRUCT struct clipboard_opts +const struct m_sub_options clipboard_conf = { + .opts = (const struct m_option[]) { + {"enable", OPT_BOOL(enabled), .flags = UPDATE_CLIPBOARD}, + {"monitor", OPT_BOOL(monitor), .flags = UPDATE_CLIPBOARD}, + {"backends", OPT_SETTINGSLIST(backends, &backend_obj_list), + .flags = UPDATE_CLIPBOARD}, + {0} + }, + .defaults = &(const struct clipboard_opts) { + .enabled = true, + .backends = (struct m_obj_settings[]) { + {.name = "win32", .enabled = true}, + {.name = "mac", .enabled = true}, + {.name = "wayland", .enabled = true}, + {.name = "vo", .enabled = true}, + {0} + } + }, + .size = sizeof(struct clipboard_opts) +}; + struct clipboard_ctx *mp_clipboard_create(struct clipboard_init_params *params, struct mpv_global *global) { @@ -68,10 +98,15 @@ struct clipboard_ctx *mp_clipboard_create(struct clipboard_init_params *params, .monitor = params->flags & CLIPBOARD_INIT_ENABLE_MONITORING, }; - for (int i = 0; i < MP_ARRAY_SIZE(clipboard_backend_list); i++) { - const struct clipboard_backend *backend = clipboard_backend_list[i]; - if (backend->init(cl, params) == CLIPBOARD_SUCCESS) { - MP_VERBOSE(cl, "Initialized %s clipboard backend.\n", backend->name); + for (int n = 0; params->backends && params->backends[n].name; n++) { + if (!params->backends[n].enabled) + continue; + for (int i = 0; i < MP_ARRAY_SIZE(clipboard_backend_list); i++) { + const struct clipboard_backend *backend = clipboard_backend_list[i]; + if (strcmp(params->backends[n].name, backend->name)) + continue; + if (backend->init(cl, params) != CLIPBOARD_SUCCESS) + break; cl->backend = backend; goto success; } @@ -81,6 +116,7 @@ struct clipboard_ctx *mp_clipboard_create(struct clipboard_init_params *params, talloc_free(cl); return NULL; success: + MP_VERBOSE(cl, "Initialized %s clipboard backend.\n", cl->backend->name); return cl; } @@ -129,6 +165,7 @@ void reinit_clipboard(struct MPContext *mpctx) struct clipboard_init_params params = { .mpctx = mpctx, .flags = opts->monitor ? CLIPBOARD_INIT_ENABLE_MONITORING : 0, + .backends = opts->backends, }; mpctx->clipboard = mp_clipboard_create(¶ms, mpctx->global); } diff --git a/player/clipboard/clipboard.h b/player/clipboard/clipboard.h index 3c613cb61d..26c2d01875 100644 --- a/player/clipboard/clipboard.h +++ b/player/clipboard/clipboard.h @@ -53,6 +53,7 @@ struct clipboard_data { struct clipboard_init_params { int flags; struct MPContext *mpctx; // For clipboard_vo only + struct m_obj_settings *backends; }; struct clipboard_access_params {