summaryrefslogtreecommitdiffstats
path: root/video/out/x11_common.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-02-02 01:35:46 +0100
committerwm4 <wm4@nowhere>2014-02-02 01:35:46 +0100
commitfc04be708c0c2a27907df7e95cdbdb1f3a2ae18d (patch)
tree47cc38e6e6641aeb0d5cdb78487b0e5c2112af52 /video/out/x11_common.c
parentfc541ab4f5932294b292f189731af880825547af (diff)
downloadmpv-fc04be708c0c2a27907df7e95cdbdb1f3a2ae18d.tar.bz2
mpv-fc04be708c0c2a27907df7e95cdbdb1f3a2ae18d.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.)
Diffstat (limited to '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 4498dd34dd..4fb9e40c1e 100644
--- a/video/out/x11_common.c
+++ b/video/out/x11_common.c
@@ -967,6 +967,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;
@@ -1275,13 +1277,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);
vo_x11_dnd_init_window(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);
@@ -1490,6 +1497,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) {