From e01eab4385d8fe6a542dd9526f912e37b691f58e Mon Sep 17 00:00:00 2001 From: Dudemanguy Date: Fri, 27 Sep 2024 10:54:01 -0500 Subject: [PATCH] win_state: move window centering to vo_calc_window_geometry c4e8c360719f6e716d1f437c08082022a3b6662f made any usage of --geometry implicitly center the window on the screen after a resize even if the user did not pass any x/y arguments to the option. At the time, this was probably wanted since --geometry was primarily a startup option and likely the window wouldn't be centered on x11 without moving coordinates. Times have changed since then and we support full runtime --geometry changes on all the relevant platforms but it comes with this automatic window centering behavior (except on wayland of course hah). It's better to make such window centering optional and user controllable since it is entirely reasonable that someone wants --geometry=50% to just resize and not move anything. It's already trivial for a person that does want to move the window to just add their coordinates to the --geometry command so there's no reason to continue to force this behavior since it is less flexible. Instead, move the window centering stuff out of m_geometry_apply into vo_calc_window_geometry. We give the power to the caller to whether or not to force centering the window here and all usage of the function is updated to simply call it with false for now. Additionally, --force-window-position being set will also center the window like before. All that is left is for the windowing code to take advantage of this. See subsequent commits. --- DOCS/interface-changes/geometry-behavior.txt | 1 + options/m_option.c | 4 ---- 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 | 18 +++++++++++++++--- video/out/win_state.h | 4 ++-- video/out/x11_common.c | 2 +- 9 files changed, 23 insertions(+), 14 deletions(-) create mode 100644 DOCS/interface-changes/geometry-behavior.txt diff --git a/DOCS/interface-changes/geometry-behavior.txt b/DOCS/interface-changes/geometry-behavior.txt new file mode 100644 index 0000000000..cab61a830a --- /dev/null +++ b/DOCS/interface-changes/geometry-behavior.txt @@ -0,0 +1 @@ +change `--geometry` so that it no longer unconditionally moves the window on platforms where that is possible. Use `--force-window-position` or add `+50%+50%` to your geometry command to get the old behavior back. diff --git a/options/m_option.c b/options/m_option.c index a6f8bcd45c..51e08c21e8 100644 --- a/options/m_option.c +++ b/options/m_option.c @@ -2219,10 +2219,6 @@ void m_geometry_apply(int *xpos, int *ypos, int *widw, int *widh, } else if (!(gm->w > 0) && gm->h > 0) { *widw = *widh * asp; } - // Center window after resize. If valid x:y values are passed to - // geometry, then those values will be overridden. - *xpos += prew / 2 - *widw / 2; - *ypos += preh / 2 - *widh / 2; } if (gm->xy_valid) { diff --git a/video/out/mac/common.swift b/video/out/mac/common.swift index 664665166d..dcab914f2c 100644 --- a/video/out/mac/common.swift +++ b/video/out/mac/common.swift @@ -426,7 +426,7 @@ class Common: NSObject { y1: Int32(originY + rv.size.height)) var geo: vo_win_geometry = vo_win_geometry() - vo_calc_window_geometry(vo, &screenRC, &screenRC, Double(screen.backingScaleFactor), &geo) + vo_calc_window_geometry(vo, &screenRC, &screenRC, Double(screen.backingScaleFactor), false, &geo) 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 6680a7cef8..cce07d3d7d 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, &screenrc, &screenrc, 1.0, &geo); + vo_calc_window_geometry(vo, &screenrc, &screenrc, 1.0, false, &geo); 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 027c542f54..73c0f9f838 100644 --- a/video/out/w32_common.c +++ b/video/out/w32_common.c @@ -1920,7 +1920,7 @@ static void window_reconfig(struct vo_w32_state *w32, bool force) if (w32->dpi_scale == 0) force_update_display_info(w32); - vo_calc_window_geometry(vo, &screen, &mon, w32->dpi_scale, &geo); + vo_calc_window_geometry(vo, &screen, &mon, w32->dpi_scale, false, &geo); 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 e691c957a8..e95730596c 100644 --- a/video/out/wayland_common.c +++ b/video/out/wayland_common.c @@ -2320,7 +2320,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, &screenrc, &screenrc, wl->scaling_factor, &geo); + vo_calc_window_geometry(vo, &screenrc, &screenrc, wl->scaling_factor, false, &geo); 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 c30c257b24..435c9a090f 100644 --- a/video/out/win_state.c +++ b/video/out/win_state.c @@ -74,14 +74,17 @@ static void apply_autofit(int *w, int *h, int scr_w, int scr_h, // monitor: position of the monitor on virtual desktop (used for pixelaspect). // dpi_scale: the DPI multiplier to get from virtual to real coordinates // (>1 for "hidpi") +// 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. // 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 // placement, fullscreen handling, avoiding resize on reconfig() with no // size change, multi-monitor stuff, and possibly more. void vo_calc_window_geometry(struct vo *vo, const struct mp_rect *screen, - const struct mp_rect *monitor, - double dpi_scale, struct vo_win_geometry *out_geo) + const struct mp_rect *monitor, double dpi_scale, + bool force_center, struct vo_win_geometry *out_geo) { struct mp_vo_opts *opts = vo->opts; @@ -121,15 +124,24 @@ void vo_calc_window_geometry(struct vo *vo, const struct mp_rect *screen, out_geo->win.x0 = (int)(scr_w - d_w) / 2; out_geo->win.y0 = (int)(scr_h - d_h) / 2; + + int old_w = d_w; + int old_h = d_h; + m_geometry_apply(&out_geo->win.x0, &out_geo->win.y0, &d_w, &d_h, scr_w, scr_h, &opts->geometry); + if ((opts->force_window_position || force_center) && !opts->geometry.xy_valid) { + out_geo->win.x0 += old_w / 2 - d_w / 2; + out_geo->win.y0 += old_h / 2 - 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; out_geo->win.y1 = out_geo->win.y0 + d_h; - if (opts->geometry.xy_valid || opts->force_window_position) + if (opts->geometry.xy_valid || opts->force_window_position || force_center) out_geo->flags |= VO_WIN_FORCE_POS; } diff --git a/video/out/win_state.h b/video/out/win_state.h index b91e174b18..f19a15618b 100644 --- a/video/out/win_state.h +++ b/video/out/win_state.h @@ -24,8 +24,8 @@ struct vo_win_geometry { }; void vo_calc_window_geometry(struct vo *vo, const struct mp_rect *screen, - const struct mp_rect *monitor, - double dpi_scale, struct vo_win_geometry *out_geo); + const struct mp_rect *monitor, double dpi_scale, + bool force_center, struct vo_win_geometry *out_geo); 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 373c5bd6cb..0bda5ce95c 100644 --- a/video/out/x11_common.c +++ b/video/out/x11_common.c @@ -1809,7 +1809,7 @@ void vo_x11_config_vo_window(struct vo *vo) vo_x11_update_screeninfo(vo); struct vo_win_geometry geo; - vo_calc_window_geometry(vo, &x11->screenrc, &x11->screenrc, x11->dpi_scale, &geo); + vo_calc_window_geometry(vo, &x11->screenrc, &x11->screenrc, x11->dpi_scale, false, &geo); vo_apply_window_geometry(vo, &geo); struct mp_rect rc = geo.win;