mirror of https://github.com/mpv-player/mpv
x11: correct position coordinates if mpv was launched with --fs
If mpv is launched with --fs, the x11 code tries to reset the size and position of the window when the fullscreen exits. This has bad behavior with multiple monitors because the saved nofsrc is not reliable in many situations. Particularly if the window manager moves the fullscreen window somewhere else while mpv is fullscreen. The result will be that exiting fullscreen always goes back to screen 0. Fix this by translating the rc coordinates of the nofsrc rc to the new monitor when we're leaving fullscreen from an initial --fs case. By giving get_current_display a specific rc, we can return what xrandr display the coordinates are associated with and decide if the nofsrc should be translated to its new location. After that bit of math, the usual move/resize logic takes care of the rest but this time it actually works off of the correct position. Fixes #14226.
This commit is contained in:
parent
7ff6cf807c
commit
52bdeb07a1
|
@ -578,13 +578,13 @@ static void vo_x11_update_screeninfo(struct vo *vo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct xrandr_display *get_current_display(struct vo *vo)
|
static struct xrandr_display *get_xrandr_display(struct vo *vo, struct mp_rect rc)
|
||||||
{
|
{
|
||||||
struct vo_x11_state *x11 = vo->x11;
|
struct vo_x11_state *x11 = vo->x11;
|
||||||
struct xrandr_display *selected_disp = NULL;
|
struct xrandr_display *selected_disp = NULL;
|
||||||
for (int n = 0; n < x11->num_displays; n++) {
|
for (int n = 0; n < x11->num_displays; n++) {
|
||||||
struct xrandr_display *disp = &x11->displays[n];
|
struct xrandr_display *disp = &x11->displays[n];
|
||||||
disp->overlaps = rc_overlaps(disp->rc, x11->winrc);
|
disp->overlaps = rc_overlaps(disp->rc, rc);
|
||||||
if (disp->overlaps && (!selected_disp || disp->fps < selected_disp->fps))
|
if (disp->overlaps && (!selected_disp || disp->fps < selected_disp->fps))
|
||||||
selected_disp = disp;
|
selected_disp = disp;
|
||||||
}
|
}
|
||||||
|
@ -1262,6 +1262,7 @@ void vo_x11_check_events(struct vo *vo)
|
||||||
if (x11->window == None)
|
if (x11->window == None)
|
||||||
break;
|
break;
|
||||||
vo_x11_update_geometry(vo);
|
vo_x11_update_geometry(vo);
|
||||||
|
vo_x11_update_screeninfo(vo);
|
||||||
if (x11->parent && Event.xconfigure.window == x11->parent) {
|
if (x11->parent && Event.xconfigure.window == x11->parent) {
|
||||||
MP_TRACE(x11, "adjusting embedded window position\n");
|
MP_TRACE(x11, "adjusting embedded window position\n");
|
||||||
XMoveResizeWindow(x11->display, x11->window,
|
XMoveResizeWindow(x11->display, x11->window,
|
||||||
|
@ -1665,6 +1666,7 @@ static void vo_x11_map_window(struct vo *vo, struct mp_rect rc)
|
||||||
XChangeProperty(x11->display, x11->window, XA(x11, _NET_WM_STATE), XA_ATOM,
|
XChangeProperty(x11->display, x11->window, XA(x11, _NET_WM_STATE), XA_ATOM,
|
||||||
32, PropModeAppend, (unsigned char *)&state, 1);
|
32, PropModeAppend, (unsigned char *)&state, 1);
|
||||||
x11->fs = 1;
|
x11->fs = 1;
|
||||||
|
x11->init_fs = true;
|
||||||
// The "saved" positions are bogus, so reset them when leaving FS again.
|
// The "saved" positions are bogus, so reset them when leaving FS again.
|
||||||
x11->size_changed_during_fs = true;
|
x11->size_changed_during_fs = true;
|
||||||
x11->pos_changed_during_fs = true;
|
x11->pos_changed_during_fs = true;
|
||||||
|
@ -1932,7 +1934,7 @@ static void vo_x11_update_geometry(struct vo *vo)
|
||||||
&x, &y, &dummy_win);
|
&x, &y, &dummy_win);
|
||||||
x11->winrc = (struct mp_rect){x, y, x + w, y + h};
|
x11->winrc = (struct mp_rect){x, y, x + w, y + h};
|
||||||
}
|
}
|
||||||
struct xrandr_display *disp = get_current_display(vo);
|
struct xrandr_display *disp = get_xrandr_display(vo, x11->winrc);
|
||||||
// Try to fallback to something reasonable if we have no disp yet
|
// Try to fallback to something reasonable if we have no disp yet
|
||||||
if (!disp) {
|
if (!disp) {
|
||||||
int screen = vo_x11_select_screen(vo);
|
int screen = vo_x11_select_screen(vo);
|
||||||
|
@ -1985,6 +1987,26 @@ static void vo_x11_fullscreen(struct vo *vo)
|
||||||
rc.x1 -= 1;
|
rc.x1 -= 1;
|
||||||
rc.y1 -= 1;
|
rc.y1 -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If launched with --fs and the fs screen is different than
|
||||||
|
// nofsrc, try to translate nofsrc to the fs screen.
|
||||||
|
if (x11->init_fs) {
|
||||||
|
struct xrandr_display *fs_disp = get_xrandr_display(vo, x11->winrc);
|
||||||
|
struct xrandr_display *nofs_disp = get_xrandr_display(vo, x11->nofsrc);
|
||||||
|
if (fs_disp && nofs_disp && fs_disp->screen != nofs_disp->screen) {
|
||||||
|
int old_w = mp_rect_w(x11->nofsrc);
|
||||||
|
int old_h = mp_rect_h(x11->nofsrc);
|
||||||
|
int new_x = (mp_rect_w(fs_disp->rc) - old_w) / 2 + fs_disp->rc.x0;
|
||||||
|
int new_y = (mp_rect_h(fs_disp->rc) - old_h) / 2 + fs_disp->rc.y0;
|
||||||
|
x11->nofsrc.x0 = new_x;
|
||||||
|
x11->nofsrc.x1 = new_x + old_w;
|
||||||
|
x11->nofsrc.y0 = new_y;
|
||||||
|
x11->nofsrc.y1 = new_y + old_h;
|
||||||
|
rc = x11->nofsrc;
|
||||||
|
}
|
||||||
|
x11->init_fs = false;
|
||||||
|
}
|
||||||
|
|
||||||
vo_x11_move_resize(vo, x11->pos_changed_during_fs,
|
vo_x11_move_resize(vo, x11->pos_changed_during_fs,
|
||||||
x11->size_changed_during_fs, rc);
|
x11->size_changed_during_fs, rc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,6 +93,8 @@ struct vo_x11_state {
|
||||||
bool pseudo_mapped; // not necessarily mapped, but known window size
|
bool pseudo_mapped; // not necessarily mapped, but known window size
|
||||||
int fs; // whether we assume the window is in fullscreen mode
|
int fs; // whether we assume the window is in fullscreen mode
|
||||||
|
|
||||||
|
bool init_fs; // whether mpv was launched with --fs
|
||||||
|
|
||||||
bool mouse_cursor_visible; // whether we want the cursor to be visible (only
|
bool mouse_cursor_visible; // whether we want the cursor to be visible (only
|
||||||
// takes effect when the window is focused)
|
// takes effect when the window is focused)
|
||||||
bool mouse_cursor_set; // whether the cursor is *currently* *hidden*
|
bool mouse_cursor_set; // whether the cursor is *currently* *hidden*
|
||||||
|
|
Loading…
Reference in New Issue