mirror of https://github.com/mpv-player/mpv
x11: pseudo HiDPI scaling
Scale the window by the assumed DPI scaling factor, using 96 DPI as base. For example, a screen that reports 192 DPI is assumed to have a DPI scale factor 2. The window will then be created with twice the size. For robustness reasons, we accept only integer DPI scales between 1 and 9. We also error out if the X and Y scales are very different, as this most likely indicates a multiscreen system with botched size reporting. I'm not sure if reading the X server's DPI is such a good idea - maybe the Xrdb "Xft.dpi" value should be used instead. The current method follows what xdpyinfo does. This can be disabled with --hidpi-window-scale=no.
This commit is contained in:
parent
4adfde5dd1
commit
a35a5bb5f3
|
@ -2343,7 +2343,7 @@ Window
|
|||
- ``--monitoraspect=16:9`` or ``--monitoraspect=1.7777``
|
||||
|
||||
``--hidpi-window-scale``, ``--no-hidpi-window-scale``
|
||||
(OS X only)
|
||||
(OS X and X11 only)
|
||||
Scale the window size according to the backing scale factor (default: yes).
|
||||
On regular HiDPI resolutions the window opens with double the size but appears
|
||||
as having the same size as on none-HiDPI resolutions. This is the default OS X
|
||||
|
|
|
@ -67,13 +67,17 @@ static void apply_autofit(int *w, int *h, int scr_w, int scr_h,
|
|||
// Compute the "suggested" window size and position and return it in *out_geo.
|
||||
// screen is the bounding box of the current screen within the virtual desktop.
|
||||
// Does not change *vo.
|
||||
// screen: position of the screen on virtual desktop on which the window
|
||||
// should be placed
|
||||
// dpi_scale: the DPI multiplier to get from virtual to real coordinates
|
||||
// (>1 for "hidpi")
|
||||
// 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,
|
||||
struct vo_win_geometry *out_geo)
|
||||
void vo_calc_window_geometry2(struct vo *vo, const struct mp_rect *screen,
|
||||
double dpi_scale, struct vo_win_geometry *out_geo)
|
||||
{
|
||||
struct mp_vo_opts *opts = vo->opts;
|
||||
|
||||
|
@ -86,12 +90,15 @@ void vo_calc_window_geometry(struct vo *vo, const struct mp_rect *screen,
|
|||
if (vo->params)
|
||||
params = *vo->params;
|
||||
|
||||
if (!opts->hidpi_window_scale)
|
||||
dpi_scale = 1;
|
||||
|
||||
int d_w, d_h;
|
||||
mp_image_params_get_dsize(¶ms, &d_w, &d_h);
|
||||
if ((vo->driver->caps & VO_CAP_ROTATE90) && params.rotate % 180 == 90)
|
||||
MPSWAP(int, d_w, d_h);
|
||||
d_w = MPCLAMP(d_w * opts->window_scale, 1, 16000);
|
||||
d_h = MPCLAMP(d_h * opts->window_scale, 1, 16000);
|
||||
d_w = MPCLAMP(d_w * opts->window_scale * dpi_scale, 1, 16000);
|
||||
d_h = MPCLAMP(d_h * opts->window_scale * dpi_scale, 1, 16000);
|
||||
|
||||
int scr_w = screen->x1 - screen->x0;
|
||||
int scr_h = screen->y1 - screen->y0;
|
||||
|
@ -118,6 +125,12 @@ void vo_calc_window_geometry(struct vo *vo, const struct mp_rect *screen,
|
|||
out_geo->flags |= VO_WIN_FORCE_POS;
|
||||
}
|
||||
|
||||
void vo_calc_window_geometry(struct vo *vo, const struct mp_rect *screen,
|
||||
struct vo_win_geometry *out_geo)
|
||||
{
|
||||
vo_calc_window_geometry2(vo, screen, 1.0, out_geo);
|
||||
}
|
||||
|
||||
// Copy the parameters in *geo to the vo fields.
|
||||
// (Doesn't do anything else - windowing backends should trigger VO_EVENT_RESIZE
|
||||
// to ensure that the VO reinitializes rendering properly.)
|
||||
|
|
|
@ -25,6 +25,8 @@ struct vo_win_geometry {
|
|||
|
||||
void vo_calc_window_geometry(struct vo *vo, const struct mp_rect *screen,
|
||||
struct vo_win_geometry *out_geo);
|
||||
void vo_calc_window_geometry2(struct vo *vo, const struct mp_rect *screen,
|
||||
double dpi_scale, struct vo_win_geometry *out_geo);
|
||||
void vo_apply_window_geometry(struct vo *vo, const struct vo_win_geometry *geo);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -544,6 +544,7 @@ int vo_x11_init(struct vo *vo)
|
|||
.screensaver_enabled = true,
|
||||
.xrandr_event = -1,
|
||||
.wakeup_pipe = {-1, -1},
|
||||
.dpi_scale = 1,
|
||||
};
|
||||
vo->x11 = x11;
|
||||
|
||||
|
@ -595,6 +596,22 @@ int vo_x11_init(struct vo *vo)
|
|||
x11->ws_width, x11->ws_height, dispName,
|
||||
x11->display_is_local ? "local" : "remote");
|
||||
|
||||
int w_mm = DisplayWidthMM(x11->display, x11->screen);
|
||||
int h_mm = DisplayHeightMM(x11->display, x11->screen);
|
||||
double dpi_x = x11->ws_width * 25.4 / w_mm;
|
||||
double dpi_y = x11->ws_height * 25.4 / h_mm;
|
||||
double base_dpi = 96;
|
||||
if (isfinite(dpi_x) && isfinite(dpi_y)) {
|
||||
int s_x = lrint(MPCLAMP(dpi_x / base_dpi, 0, 10));
|
||||
int s_y = lrint(MPCLAMP(dpi_y / base_dpi, 0, 10));
|
||||
if (s_x == s_y && s_x > 1 && s_x < 10) {
|
||||
x11->dpi_scale = s_x;
|
||||
MP_VERBOSE(x11, "Assuming DPI scale %d for prescaling. This can "
|
||||
"be disabled with --hidpi-window-scale=no.\n",
|
||||
x11->dpi_scale);
|
||||
}
|
||||
}
|
||||
|
||||
x11->wm_type = vo_wm_detect(vo);
|
||||
|
||||
x11->event_fd = ConnectionNumber(x11->display);
|
||||
|
@ -1604,7 +1621,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, &geo);
|
||||
vo_calc_window_geometry2(vo, &x11->screenrc, x11->dpi_scale, &geo);
|
||||
vo_apply_window_geometry(vo, &geo);
|
||||
|
||||
struct mp_rect rc = geo.win;
|
||||
|
|
|
@ -54,6 +54,7 @@ struct vo_x11_state {
|
|||
int display_is_local;
|
||||
int ws_width;
|
||||
int ws_height;
|
||||
int dpi_scale;
|
||||
struct mp_rect screenrc;
|
||||
char *window_title;
|
||||
|
||||
|
|
Loading…
Reference in New Issue