win_state: move window centering to vo_calc_window_geometry

c4e8c36071 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.
This commit is contained in:
Dudemanguy 2024-09-27 10:54:01 -05:00
parent 8b30a2386f
commit e01eab4385
9 changed files with 23 additions and 14 deletions

View File

@ -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.

View File

@ -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) {

View File

@ -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)

View File

@ -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;

View File

@ -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 ||

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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;