diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst index 23e71b3a2d..7fc9b0b5c5 100644 --- a/DOCS/interface-changes.rst +++ b/DOCS/interface-changes.rst @@ -59,6 +59,14 @@ Interface changes setting the properties to non-existing tracks may report it as selected track for a small time window, until it's forced back to "no". The exact details how this is handled may change in the future. + - x11 VOs now update --geometry at runtime according to the current window + position, and will react to writes to the option/property at runtime and + resize the window accordingly. This changes behavior when playing multiple + videos with different size: the first video initializes the window size + and thus overwrites --geometry, and the second video will obviously use + the size provided in --geometry, so the second video will not change the + window size. You can use --reset-on-next-file=geometry to get the old + behavior. --- mpv 0.30.0 --- - add `--d3d11-output-format` to enable explicit selection of a D3D11 swap chain format. diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index f31173a8ee..7ec39afad8 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -2703,6 +2703,12 @@ Window The coordinates are relative to the screen given with ``--screen`` for the video output drivers that fully support ``--screen``. + Some backends update this option at runtime (like all options, it's exposed + as property, in this case ``geometry``), and resize their window if the user + sets the property. This means the window size is not reset when playing a + video with different file. Use ``--reset-on-next-file=geometry`` to get + the old behavior. + .. note:: Generally only supported by GUI VOs. Ignored for encoding. diff --git a/video/out/x11_common.c b/video/out/x11_common.c index 38fdca73df..dd5ce0fcdf 100644 --- a/video/out/x11_common.c +++ b/video/out/x11_common.c @@ -1730,14 +1730,32 @@ static void vo_x11_update_geometry(struct vo *vo) Window dummy_win; Window win = x11->parent ? x11->parent : x11->window; x11->winrc = (struct mp_rect){0, 0, 0, 0}; + x11->last_geometry = (struct m_geometry){0}; if (win) { - XGetGeometry(x11->display, win, &dummy_win, &dummy_int, &dummy_int, + int r_x = 0, r_y = 0; + XGetGeometry(x11->display, win, &dummy_win, &r_x, &r_y, &w, &h, &dummy_int, &dummy_uint); if (w > INT_MAX || h > INT_MAX) w = h = 0; XTranslateCoordinates(x11->display, win, x11->rootwin, 0, 0, &x, &y, &dummy_win); x11->winrc = (struct mp_rect){x, y, x + w, y + h}; + if (!x11->window_hidden) { + // Ah, the pain of X11. + long params[4] = {0}; + x11_get_property_copy(x11, win, XA(x11, _NET_FRAME_EXTENTS), + XA_CARDINAL, 32, params, sizeof(params)); + x11->last_geometry = (struct m_geometry){ + .x = x - params[0], + .y = y - params[2], + .w = w, + .h = h, + .xy_valid = 1, + .wh_valid = w > 0 && h > 0, + }; + x11->opts->geometry = x11->last_geometry; + m_config_cache_write_opt(x11->opts_cache, &x11->opts->geometry); + } } double fps = 1000.0; for (int n = 0; n < x11->num_displays; n++) { @@ -1844,6 +1862,24 @@ static void vo_x11_minimize(struct vo *vo) } } +static void vo_x11_set_geometry(struct vo *vo) +{ + struct vo_x11_state *x11 = vo->x11; + struct m_geometry geo = x11->last_geometry; + + if (x11->window_hidden || !geo.wh_valid || !geo.xy_valid) + return; + + int s_w = mp_rect_w(x11->screenrc), s_h = mp_rect_h(x11->screenrc); + int nx = geo.x, ny = geo.y, nw = geo.w, nh = geo.h; + m_geometry_apply(&nx, &ny, &nw, &nh, s_w, s_h, &x11->opts->geometry); + + MP_VERBOSE(vo, "Setting geometry: %d:%d %dx%d -> %d:%d %dx%d\n", + geo.x, geo.y, geo.w, geo.h, nx, ny, nw, nh); + if (nx != geo.x || ny != geo.y || nw != geo.w || nh != geo.h) + XMoveResizeWindow(x11->display, x11->window, nx, ny, nw, nh); +} + int vo_x11_control(struct vo *vo, int *events, int request, void *arg) { struct vo_x11_state *x11 = vo->x11; @@ -1877,6 +1913,8 @@ int vo_x11_control(struct vo *vo, int *events, int request, void *arg) vo_x11_minimize(vo); if (opt == &opts->window_maximized) vo_x11_maximize(vo); + if (opt == &opts->geometry) + vo_x11_set_geometry(vo); } return VO_TRUE; } diff --git a/video/out/x11_common.h b/video/out/x11_common.h index fffc5be294..ae038bc3cf 100644 --- a/video/out/x11_common.h +++ b/video/out/x11_common.h @@ -24,6 +24,7 @@ #include #include +#include "options/m_option.h" #include "osdep/atomic.h" #include "osdep/semaphore.h" @@ -100,6 +101,7 @@ struct vo_x11_state { // Current actual window position (updated on window move/resize events). struct mp_rect winrc; double current_display_fps; + struct m_geometry last_geometry; int pending_vo_events;