diff --git a/DOCS/interface-changes/wayland-display.txt b/DOCS/interface-changes/wayland-display.txt new file mode 100644 index 0000000000000..6fc0049a88254 --- /dev/null +++ b/DOCS/interface-changes/wayland-display.txt @@ -0,0 +1 @@ +add `--wayland-display` option to connect to a Wayland display other than the one given by `WAYLAND_DISPLAY` diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index 3f73771f9158a..c53ed457930fe 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -6521,6 +6521,19 @@ them. (default) will automatically switch between telling the compositor the content is a photo, video or possibly none depending on internal heuristics. +``--wayland-display=`` + Connect to this Wayland display instead of the one given by the + ``WAYLAND_DISPLAY`` environment variable (default: unset). This is either + a socket name relative to ``XDG_RUNTIME_DIR`` or an absolute path. Not + setting this or setting it to the empty string uses the environment as + usual. If ``WAYLAND_SOCKET`` is set, it takes precedence over this option. + + This applies to the VO and to the Wayland clipboard backend. It is useful + for applications embedding mpv that proxy its Wayland connection, since it + redirects mpv without changing ``WAYLAND_DISPLAY`` for the whole process. + Changes reconnect the clipboard immediately and take effect for the VO the + next time it is created. + ``--wayland-edge-pixels-pointer=`` Defines the size of an edge border (default: 16) to initiate client side resize events in the wayland contexts with the mouse or tablet. This is only diff --git a/options/options.c b/options/options.c index e8b590af8c04f..fcd72636732ee 100644 --- a/options/options.c +++ b/options/options.c @@ -216,6 +216,7 @@ static const m_option_t mp_vo_opt_list[] = { {"photo", 1}, {"video", 2}, {"game", 3})}, {"wayland-disable-vsync", OPT_BOOL(wl_disable_vsync), .deprecation_message = "replaced by --wayland-internal-vsync=no"}, + {"wayland-display", OPT_STRING(wayland_display), .flags = UPDATE_CLIPBOARD}, {"wayland-internal-vsync", OPT_CHOICE(wl_internal_vsync, {"no", 0}, {"auto", 1}, {"yes", 2})}, {"wayland-edge-pixels-pointer", OPT_INT(wl_edge_pixels_pointer), diff --git a/options/options.h b/options/options.h index 26a791343ffff..7aaf5d3f10c10 100644 --- a/options/options.h +++ b/options/options.h @@ -29,6 +29,7 @@ typedef struct mp_vo_opts { char *winname; char *appid; char *wayland_session; + char *wayland_display; int x11_netwm; int x11_bypass_compositor; int x11_present; diff --git a/player/clipboard/clipboard-wayland.c b/player/clipboard/clipboard-wayland.c index 677a3cd242394..88de18acec5bf 100644 --- a/player/clipboard/clipboard-wayland.c +++ b/player/clipboard/clipboard-wayland.c @@ -336,12 +336,18 @@ static void clipboard_wayland_uninit(struct clipboard_wayland_priv *wl) wl_display_disconnect(wl->display); } -static bool clipboard_wayland_init(struct clipboard_wayland_priv *wl, bool monitor) +static bool clipboard_wayland_init(struct clipboard_wayland_priv *wl, bool monitor, + const char *display_name) { - if (!getenv("WAYLAND_DISPLAY") && !getenv("WAYLAND_SOCKET")) + if (display_name && !display_name[0]) + display_name = NULL; + if (!display_name && !getenv("WAYLAND_DISPLAY") && + !getenv("WAYLAND_SOCKET")) + { goto err; + } - wl->display = wl_display_connect(NULL); + wl->display = wl_display_connect(display_name); if (!wl->display) goto err; @@ -520,7 +526,8 @@ static int init(struct clipboard_ctx *cl, struct clipboard_init_params *params) if (mp_make_wakeup_pipe(priv->message_pipe) < 0) goto pipe_err; - if (!clipboard_wayland_init(priv, params->flags & CLIPBOARD_INIT_ENABLE_MONITORING)) + if (!clipboard_wayland_init(priv, params->flags & CLIPBOARD_INIT_ENABLE_MONITORING, + params->wayland_display)) goto init_err; if (mp_thread_create(&priv->thread, clipboard_thread, cl->priv)) goto thread_err; diff --git a/player/clipboard/clipboard-x11.c b/player/clipboard/clipboard-x11.c index 9b6bc60e9d6ac..313ea2a8aa2d0 100644 --- a/player/clipboard/clipboard-x11.c +++ b/player/clipboard/clipboard-x11.c @@ -67,9 +67,12 @@ static void clipboard_x11_uninit(struct clipboard_x11_priv *x11) XCloseDisplay(x11->display); } -static bool clipboard_x11_init(struct clipboard_x11_priv *x11, bool xwayland, bool monitor) +static bool clipboard_x11_init(struct clipboard_x11_priv *x11, bool xwayland, bool monitor, + const char *wayland_display) { - if (!xwayland && (getenv("WAYLAND_DISPLAY") || getenv("WAYLAND_SOCKET"))) { + bool wayland = (wayland_display && wayland_display[0]) || + getenv("WAYLAND_DISPLAY") || getenv("WAYLAND_SOCKET"); + if (!xwayland && wayland) { MP_VERBOSE(x11, "Stopping init due to suspected wayland environment\n"); goto err; } @@ -279,7 +282,8 @@ static int init(struct clipboard_ctx *cl, struct clipboard_init_params *params) if (mp_make_wakeup_pipe(priv->message_pipe) < 0) goto pipe_err; if (!clipboard_x11_init(priv, params->flags & CLIPBOARD_INIT_ENABLE_XWAYLAND, - params->flags & CLIPBOARD_INIT_ENABLE_MONITORING)) + params->flags & CLIPBOARD_INIT_ENABLE_MONITORING, + params->wayland_display)) goto init_err; if (mp_thread_create(&priv->thread, clipboard_thread, cl->priv)) goto thread_err; diff --git a/player/clipboard/clipboard.c b/player/clipboard/clipboard.c index 7b2f9058a58f3..4a9cadb70e6a6 100644 --- a/player/clipboard/clipboard.c +++ b/player/clipboard/clipboard.c @@ -199,6 +199,7 @@ void reinit_clipboard(struct MPContext *mpctx) struct clipboard_init_params params = { .mpctx = mpctx, .backends = opts->backends, + .wayland_display = mpctx->opts->vo->wayland_display, }; params.flags |= opts->monitor ? CLIPBOARD_INIT_ENABLE_MONITORING : 0; params.flags |= opts->xwayland ? CLIPBOARD_INIT_ENABLE_XWAYLAND : 0; diff --git a/player/clipboard/clipboard.h b/player/clipboard/clipboard.h index 7a30cb9ac6277..5ae882ba2f664 100644 --- a/player/clipboard/clipboard.h +++ b/player/clipboard/clipboard.h @@ -56,6 +56,7 @@ struct clipboard_init_params { int flags; struct MPContext *mpctx; // For clipboard_vo only struct m_obj_settings *backends; + const char *wayland_display; // For clipboard_wayland and clipboard_x11 }; struct clipboard_access_params { diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c index d1bf43e1f48ff..e1b06cd84eab0 100644 --- a/video/out/wayland_common.c +++ b/video/out/wayland_common.c @@ -4528,9 +4528,15 @@ bool vo_wayland_valid_format(struct vo_wayland_state *wl, uint32_t drm_format, u bool vo_wayland_init(struct vo *vo) { - if (vo->probing && !getenv("WAYLAND_DISPLAY") && !getenv("WAYLAND_SOCKET")) { - MP_VERBOSE(vo, "Skipping Wayland because neither WAYLAND_DISPLAY or " - "WAYLAND_SOCKET is set\n"); + const char *display_name = vo->opts->wayland_display; + if (display_name && !display_name[0]) + display_name = NULL; + + if (vo->probing && !display_name && !getenv("WAYLAND_DISPLAY") && + !getenv("WAYLAND_SOCKET")) + { + MP_VERBOSE(vo, "Skipping Wayland because neither --wayland-display, " + "WAYLAND_DISPLAY or WAYLAND_SOCKET is set\n"); goto err; } @@ -4558,7 +4564,13 @@ bool vo_wayland_init(struct vo *vo) wl_list_init(&wl->seat_list); wl_list_init(&wl->tranche_list); - wl->display = wl_display_connect(NULL); + if (display_name && getenv("WAYLAND_SOCKET")) { + MP_WARN(wl, "WAYLAND_SOCKET is set and takes precedence over " + "--wayland-display.\n"); + } + MP_VERBOSE(wl, "Connecting to Wayland display: %s\n", + display_name ? display_name : "(default)"); + wl->display = wl_display_connect(display_name); if (!wl->display) { MP_MSG(wl, vo->probing ? MSGL_V : MSGL_FATAL, "Couldn't connect to Wayland display: %s\n", strerror(errno));