From a34ecb5284e45fa7b72ca9774f0d2bbf257906c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= Date: Wed, 8 Oct 2025 07:28:37 +0200 Subject: [PATCH] video/out/win_state: allow internal size constraint for window_geometry Will be useful to limit the size directly based on platform requirement. --- video/out/mac/common.swift | 2 +- video/out/vo_sdl.c | 2 +- video/out/w32_common.c | 2 +- video/out/wayland_common.c | 2 +- video/out/win_state.c | 17 ++++++++++++++++- video/out/win_state.h | 4 +++- video/out/x11_common.c | 2 +- 7 files changed, 24 insertions(+), 7 deletions(-) diff --git a/video/out/mac/common.swift b/video/out/mac/common.swift index 49f46e884b..07b9f83149 100644 --- a/video/out/mac/common.swift +++ b/video/out/mac/common.swift @@ -428,7 +428,7 @@ class Common: NSObject { y1: Int32(originY + rv.size.height)) var geo: vo_win_geometry = vo_win_geometry() - vo_calc_window_geometry(vo, vo.pointee.opts, &screenRC, &screenRC, Double(screen.backingScaleFactor), false, &geo) + vo_calc_window_geometry(vo, vo.pointee.opts, &screenRC, &screenRC, Double(screen.backingScaleFactor), false, &geo, nil) vo_apply_window_geometry(vo, &geo) let height = CGFloat(geo.win.y1 - geo.win.y0) diff --git a/video/out/vo_sdl.c b/video/out/vo_sdl.c index ecfc6e753a..5ba12b20cb 100644 --- a/video/out/vo_sdl.c +++ b/video/out/vo_sdl.c @@ -453,7 +453,7 @@ static int reconfig(struct vo *vo, struct mp_image_params *params) struct mp_rect screenrc; update_screeninfo(vo, &screenrc); - vo_calc_window_geometry(vo, vc->opts_cache->opts, &screenrc, &screenrc, 1.0, false, &geo); + vo_calc_window_geometry(vo, vc->opts_cache->opts, &screenrc, &screenrc, 1.0, false, &geo, NULL); vo_apply_window_geometry(vo, &geo); int win_w = vo->dwidth; diff --git a/video/out/w32_common.c b/video/out/w32_common.c index 11bfec5f36..f0db266306 100644 --- a/video/out/w32_common.c +++ b/video/out/w32_common.c @@ -1963,7 +1963,7 @@ static void window_reconfig(struct vo_w32_state *w32, bool force) force_update_display_info(w32); vo_calc_window_geometry(vo, w32->opts, &screen, &mon, w32->dpi_scale, - !w32->window_bounds_initialized, &geo); + !w32->window_bounds_initialized, &geo, NULL); vo_apply_window_geometry(vo, &geo); bool reset_size = ((w32->o_dwidth != vo->dwidth || diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c index 19d376f221..75703956a0 100644 --- a/video/out/wayland_common.c +++ b/video/out/wayland_common.c @@ -3781,7 +3781,7 @@ static void set_geometry(struct vo_wayland_state *wl, bool resize) struct vo_win_geometry geo; struct mp_rect screenrc = wl->current_output->geometry; - vo_calc_window_geometry(vo, wl->opts, &screenrc, &screenrc, wl->scaling_factor, false, &geo); + vo_calc_window_geometry(vo, wl->opts, &screenrc, &screenrc, wl->scaling_factor, false, &geo, NULL); vo_apply_window_geometry(vo, &geo); int gcd = greatest_common_divisor(vo->dwidth, vo->dheight); diff --git a/video/out/win_state.c b/video/out/win_state.c index 9cd4239fc8..3ca22fecf3 100644 --- a/video/out/win_state.c +++ b/video/out/win_state.c @@ -77,6 +77,9 @@ static void apply_autofit(int *w, int *h, int scr_w, int scr_h, // force_center: force centering x/y in the middle of the given screen even if // opts->force_window_position is not set. ignored if the user // supplies valid x/y coordinates on their own. +// size_constraint: if non-NULL, the resulting size will be limited by the size +// specified in this geometry. This applies to both autofit +// and geometry options. // Use vo_apply_window_geometry() to copy the result into the vo. // NOTE: currently, all windowing backends do their own handling of window // geometry additional to this code. This is to deal with initial window @@ -85,7 +88,8 @@ static void apply_autofit(int *w, int *h, int scr_w, int scr_h, void vo_calc_window_geometry(struct vo *vo, struct mp_vo_opts *opts, const struct mp_rect *screen, const struct mp_rect *monitor, double dpi_scale, - bool force_center, struct vo_win_geometry *out_geo) + bool force_center, struct vo_win_geometry *out_geo, + struct m_geometry *size_constraint) { *out_geo = (struct vo_win_geometry){0}; @@ -120,6 +124,8 @@ void vo_calc_window_geometry(struct vo *vo, struct mp_vo_opts *opts, apply_autofit(&d_w, &d_h, scr_w, scr_h, &opts->autofit, true, true); apply_autofit(&d_w, &d_h, scr_w, scr_h, &opts->autofit_smaller, true, false); apply_autofit(&d_w, &d_h, scr_w, scr_h, &opts->autofit_larger, false, true); + if (size_constraint) + apply_autofit(&d_w, &d_h, scr_w, scr_h, size_constraint, false, true); out_geo->win.x0 = (int)(scr_w - d_w) / 2; out_geo->win.y0 = (int)(scr_h - d_h) / 2; @@ -128,6 +134,15 @@ void vo_calc_window_geometry(struct vo *vo, struct mp_vo_opts *opts, m_geometry_apply(&out_geo->win.x0, &out_geo->win.y0, &d_w, &d_h, scr_w, scr_h, center, &opts->geometry); + if (size_constraint) { + int old_w = d_w, old_h = d_h; + apply_autofit(&d_w, &d_h, scr_w, scr_h, size_constraint, false, true); + if (!opts->geometry.xy_valid) { + out_geo->win.x0 += (old_w - d_w) / 2; + out_geo->win.y0 += (old_h - d_h) / 2; + } + } + out_geo->win.x0 += screen->x0; out_geo->win.y0 += screen->y0; out_geo->win.x1 = out_geo->win.x0 + d_w; diff --git a/video/out/win_state.h b/video/out/win_state.h index 3652bc376c..59dc98e08c 100644 --- a/video/out/win_state.h +++ b/video/out/win_state.h @@ -24,11 +24,13 @@ struct vo_win_geometry { }; struct mp_vo_opts; +struct m_geometry; void vo_calc_window_geometry(struct vo *vo, struct mp_vo_opts *opts, const struct mp_rect *screen, const struct mp_rect *monitor, double dpi_scale, - bool force_center, struct vo_win_geometry *out_geo); + bool force_center, struct vo_win_geometry *out_geo, + struct m_geometry *size_constraint); void vo_apply_window_geometry(struct vo *vo, const struct vo_win_geometry *geo); #endif diff --git a/video/out/x11_common.c b/video/out/x11_common.c index 4b6fec2961..d03cc20b1d 100644 --- a/video/out/x11_common.c +++ b/video/out/x11_common.c @@ -1806,7 +1806,7 @@ void vo_x11_config_vo_window(struct vo *vo) struct vo_win_geometry geo; vo_calc_window_geometry(vo, opts, &x11->screenrc, &x11->screenrc, x11->dpi_scale, - !x11->pseudo_mapped, &geo); + !x11->pseudo_mapped, &geo, NULL); vo_apply_window_geometry(vo, &geo); struct mp_rect rc = !x11->pseudo_mapped || opts->auto_window_resize || opts->geometry.wh_valid ||