summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-02-02 01:35:46 +0100
committerwm4 <wm4@nowhere>2014-02-12 22:30:23 +0100
commitde6a452039262fdd2700a6319346db744565f8e6 (patch)
treec59f045e30a366cfd3189b3c6592108d25f35629
parent4b764b6cc64e72072b8f8201329570607792f4a1 (diff)
downloadmpv-de6a452039262fdd2700a6319346db744565f8e6.tar.bz2
mpv-de6a452039262fdd2700a6319346db744565f8e6.tar.xz
x11: fix race condition when setting aspect when leaving fullscreen
vo_opengl creates a hidden X11 window to probe the OpenGL context. It must do that before creating a visible window, because VO creation and VO config are separate phases. There's a race condition involving the hidden window: when starting with --fs, and then leaving fullscreen, the unfullscreened window is sometimes set to the aspect ratio of the hidden window. I'm not sure why the window size itself uses the correct size (but corrupted by the wrong aspect), but that's perhaps because the window manager is free to ignore the size hint while honoring the aspect, or something equally messed up. It turns out this happens because x11_common.c thinks the size of the hidden window is the size of the unfullscreened window. This in turn happens because vo_x11_update_geometry() reads the size of the hidden window when called in vo_x11_fullscreen() (called from vo_x11_config_vo_window()) when mapping the fullscreen window. At that point, the window could be mapped, but not necessarily. If it's not mapped, it will get the size of the unfullscreened window... I think. One could fix this by actively waiting until the window is mapped. Try to pick a less hacky approach instead, and never read the window size until MapNotify is received. vo_x11_create_window() needs a hack, because we'd possibly set the VO's size to 0, resulting e.g. in vdpau to fail initialization. (It'll print error messages until a proper resize is received.) Conflicts: video/out/x11_common.c
-rw-r--r--video/out/x11_common.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/video/out/x11_common.c b/video/out/x11_common.c
index 9b5d5cb929..2c29242af6 100644
--- a/video/out/x11_common.c
+++ b/video/out/x11_common.c
@@ -826,6 +826,8 @@ int vo_x11_check_events(struct vo *vo)
break;
}
case MapNotify:
+ x11->window_hidden = false;
+ vo_x11_update_geometry(vo);
x11->vo_hint.win_gravity = x11->old_gravity;
XSetWMNormalHints(display, x11->window, &x11->vo_hint);
x11->fs_flip = 0;
@@ -1129,13 +1131,18 @@ static void vo_x11_create_window(struct vo *vo, XVisualInfo *vis, int x, int y,
vo_x11_set_wm_icon(x11);
vo_x11_update_window_title(vo);
+
+ // The real size is only known when the window is mapped, which
+ // unfortunately happens asynchronous to VO initialization. At least
+ // vdpau needs a _some_ window size, though.
+ x11->win_width = w;
+ x11->win_height = h;
}
static void vo_x11_map_window(struct vo *vo, int x, int y, int w, int h)
{
struct vo_x11_state *x11 = vo->x11;
- x11->window_hidden = false;
vo_x11_move_resize(vo, true, true, x, y, w, h);
if (!vo->opts->border)
vo_x11_decoration(vo, 0);
@@ -1342,6 +1349,8 @@ static void vo_x11_update_geometry(struct vo *vo)
int dummy_int;
Window dummy_win;
Window win = vo->opts->WinID > 0 ? vo->opts->WinID : x11->window;
+ if (x11->window_hidden)
+ return;
XGetGeometry(x11->display, win, &dummy_win, &dummy_int, &dummy_int,
&w, &h, &dummy_int, &dummy_uint);
if (w <= INT_MAX && h <= INT_MAX) {