diff options
-rw-r--r-- | DOCS/man/en/options.rst | 41 | ||||
-rw-r--r-- | core/cfg-mplayer.h | 3 | ||||
-rw-r--r-- | core/defaultopts.c | 1 | ||||
-rw-r--r-- | core/options.h | 1 | ||||
-rw-r--r-- | video/out/cocoa_common.m | 45 | ||||
-rw-r--r-- | video/out/w32_common.c | 11 | ||||
-rw-r--r-- | video/out/w32_common.h | 1 | ||||
-rw-r--r-- | video/out/x11_common.c | 65 | ||||
-rw-r--r-- | video/out/x11_common.h | 2 |
9 files changed, 111 insertions, 59 deletions
diff --git a/DOCS/man/en/options.rst b/DOCS/man/en/options.rst index 14548f807c..fcab7ae8e0 100644 --- a/DOCS/man/en/options.rst +++ b/DOCS/man/en/options.rst @@ -649,6 +649,21 @@ --fullscreen, --fs Fullscreen playback (centers movie, and paints black bands around it). + +--fs-screen=<all|current|0-32> + In multi-monitor configurations (i.e. a single desktop that spans across + multiple displays) this option tells mpv which screen to go fullscreen to. + If ``default`` is provided mpv will fallback to using the behaviour + depending on what the user provided with the ``screen`` option. + + *NOTE (X11)*: this option does not work properly with all window managers. + ``all`` in particular will usually only work with ``--fstype=-fullscreen`` + or ``--fstype=none``, and even then only with some window managers. + + *NOTE (OSX)*: ``all`` doesn't work on OSX and will behave like ``current``. + + See also ``--screen``. + --fsmode-dontuse=<0-31> OBSOLETE, use the ``--fs`` option. Try this option if you still experience fullscreen problems. @@ -734,6 +749,8 @@ located on the the bottom-left corner. For instance, ``0:0`` will place the window at the bottom-left of the screen. + *NOTE (X11)*: this option does not work properly with all window managers. + *EXAMPLE*: ``50:40`` @@ -1710,6 +1727,18 @@ Seek to byte position. Useful for playback from CD-ROM images or VOB files with junk at the beginning. See also ``--start``. +--screen=<default|0-32> + In multi-monitor configurations (i.e. a single desktop that spans across + multiple displays) this option tells mpv which screen to display the + movie on. + + This option doesn't always work. In these cases, try to use ``--geometry`` + to position the window explicitly. + + *NOTE (X11)*: this option does not work properly with all window managers. + + See also ``--fs-screen``. + --screenshot-format=<type> Set the image file type used for saving screenshots. @@ -2327,15 +2356,3 @@ --wid=<ID> (X11 and win32 only) This tells mpv to attach to an existing window.See ``--slave-broken``. - ---screen=<all|current|0-32> - In multi-monitor configurations (i.e. a single desktop that spans across - multiple displays) this option tells mpv which screen to display the - movie on. A value of ``all`` means fullscreen across the whole virtual display - (in this case system provided information is completely ignored), ``current`` means - fullscreen on the display the window currently is on. The initial position - set via the ``--geometry`` option is relative to the specified screen. - Will usually only work with ``--fstype=-fullscreen`` or ``--fstype=none``. - This option is not suitable to only set the startup screen (because it - will always display on the given screen in fullscreen mode), - ``--geometry`` is the best that is available for that purpose currently. diff --git a/core/cfg-mplayer.h b/core/cfg-mplayer.h index 23c4bedee8..3a79702959 100644 --- a/core/cfg-mplayer.h +++ b/core/cfg-mplayer.h @@ -613,6 +613,9 @@ const m_option_t mplayer_opts[]={ {"mouseinput", &vo_nomouse_input, CONF_TYPE_FLAG, 0, 1, 0, NULL}, OPT_CHOICE_OR_INT("screen", vo_screen_id, 0, 0, 32, + ({"default", -1})), + + OPT_CHOICE_OR_INT("fs-screen", vo_fsscreen_id, 0, 0, 32, ({"all", -2}, {"current", -1})), OPT_INTRANGE("brightness", vo_gamma_brightness, 0, -100, 100), diff --git a/core/defaultopts.c b/core/defaultopts.c index b6e7f28524..a3c315b186 100644 --- a/core/defaultopts.c +++ b/core/defaultopts.c @@ -23,6 +23,7 @@ void set_default_mplayer_options(struct MPOpts *opts) .vo_panscanrange = 1.0, .cursor_autohide_delay = 1000, .vo_screen_id = -1, + .vo_fsscreen_id = -1, .vo_gamma_gamma = 1000, .vo_gamma_brightness = 1000, .vo_gamma_contrast = 1000, diff --git a/core/options.h b/core/options.h index 8e64c07723..254af2e241 100644 --- a/core/options.h +++ b/core/options.h @@ -19,6 +19,7 @@ typedef struct MPOpts { int vo_screenwidth; int vo_screenheight; int vo_screen_id; + int vo_fsscreen_id; struct m_geometry vo_geometry; struct m_geometry vo_autofit; struct m_geometry vo_autofit_larger; diff --git a/video/out/cocoa_common.m b/video/out/cocoa_common.m index 77b9d0c96f..4f61ffe29e 100644 --- a/video/out/cocoa_common.m +++ b/video/out/cocoa_common.m @@ -108,8 +108,8 @@ struct vo_cocoa_state { NSSize previous_video_size; NSRect screen_frame; + NSRect fsscreen_frame; NSScreen *screen_handle; - NSArray *screen_array; NSInteger windowed_mask; NSInteger fullscreen_mask; @@ -253,26 +253,39 @@ static int current_screen_has_dock_or_menubar(struct vo *vo) return f.size.height > vf.size.height || f.size.width > vf.size.width; } +static int get_screen_handle(int identifier, NSWindow *window, NSScreen **screen) { + NSArray *screens = [NSScreen screens]; + int n_of_displays = [screens count]; + + if (identifier >= n_of_displays) { // check if the identifier is out of bounds + mp_msg(MSGT_VO, MSGL_INFO, "[cocoa] Screen ID %d does not exist, " + "falling back to main device\n", identifier); + identifier = -1; + } + + if (identifier < 0) { + // default behaviour gets either the window screen or the main screen + // if window is not available + if (! (*screen = [window screen]) ) + *screen = [screens objectAtIndex:0]; + return 0; + } else { + *screen = [screens objectAtIndex:(identifier)]; + return 1; + } +} + static void update_screen_info(struct vo *vo) { struct vo_cocoa_state *s = vo->cocoa; struct MPOpts *opts = vo->opts; - int screen_id = opts->vo_screen_id; - s->screen_array = [NSScreen screens]; - if (screen_id >= (int)[s->screen_array count]) { - mp_msg(MSGT_VO, MSGL_INFO, "[cocoa] Device ID %d does not exist, " - "falling back to main device\n", screen_id); - screen_id = -1; - } + NSScreen *ws, *fss; - if (screen_id < 0) { // default behaviour - if (! (s->screen_handle = [s->window screen]) ) - s->screen_handle = [s->screen_array objectAtIndex:0]; - } else { - s->screen_handle = [s->screen_array objectAtIndex:(screen_id)]; - } + get_screen_handle(opts->vo_screen_id, s->window, &ws); + s->screen_frame = [ws frame]; - s->screen_frame = [s->screen_handle frame]; + get_screen_handle(opts->vo_fsscreen_id, s->window, &fss); + s->fsscreen_frame = [fss frame]; } void vo_cocoa_update_xinerama_info(struct vo *vo) @@ -642,7 +655,7 @@ void create_menu() s->windowed_frame = [self frame]; [self setHasShadow:NO]; [self setStyleMask:s->fullscreen_mask]; - [self setFrame:s->screen_frame display:YES animate:NO]; + [self setFrame:s->fsscreen_frame display:YES animate:NO]; vo_fs = VO_TRUE; vo_cocoa_display_cursor(_vo, 0); [self setMovableByWindowBackground: NO]; diff --git a/video/out/w32_common.c b/video/out/w32_common.c index 6b92066860..54620bdec6 100644 --- a/video/out/w32_common.c +++ b/video/out/w32_common.c @@ -312,13 +312,12 @@ static BOOL CALLBACK mon_enum(HMONITOR hmon, HDC hdc, LPRECT r, LPARAM p) { struct vo *vo = (void*)p; struct vo_w32_state *w32 = vo->w32; - struct MPOpts *opts = vo->opts; // this defaults to the last screen if specified number does not exist xinerama_x = r->left; xinerama_y = r->top; vo->opts->vo_screenwidth = r->right - r->left; vo->opts->vo_screenheight = r->bottom - r->top; - if (w32->mon_cnt == opts->vo_screen_id) + if (w32->mon_cnt == w32->mon_id) return FALSE; w32->mon_cnt++; return TRUE; @@ -342,8 +341,9 @@ void w32_update_xinerama_info(struct vo *vo) { struct vo_w32_state *w32 = vo->w32; struct MPOpts *opts = vo->opts; + int screen = vo_fs ? opts->vo_fsscreen_id : opts->vo_screen_id; xinerama_x = xinerama_y = 0; - if (opts->vo_screen_id < -1) { + if (vo_fs && screen == -2) { int tmp; xinerama_x = GetSystemMetrics(SM_XVIRTUALSCREEN); xinerama_y = GetSystemMetrics(SM_YVIRTUALSCREEN); @@ -351,7 +351,7 @@ void w32_update_xinerama_info(struct vo *vo) if (tmp) vo->opts->vo_screenwidth = tmp; tmp = GetSystemMetrics(SM_CYVIRTUALSCREEN); if (tmp) vo->opts->vo_screenheight = tmp; - } else if (opts->vo_screen_id == -1) { + } else if (screen == -1) { MONITORINFO mi; HMONITOR m = MonitorFromWindow(w32->window, MONITOR_DEFAULTTOPRIMARY); mi.cbSize = sizeof(mi); @@ -360,8 +360,9 @@ void w32_update_xinerama_info(struct vo *vo) xinerama_y = mi.rcMonitor.top; vo->opts->vo_screenwidth = mi.rcMonitor.right - mi.rcMonitor.left; vo->opts->vo_screenheight = mi.rcMonitor.bottom - mi.rcMonitor.top; - } else if (opts->vo_screen_id > 0) { + } else if (screen >= 0) { w32->mon_cnt = 0; + w32->mon_id = screen; EnumDisplayMonitors(NULL, NULL, mon_enum, (LONG_PTR)vo); } aspect_save_screenres(vo, vo->opts->vo_screenwidth, diff --git a/video/out/w32_common.h b/video/out/w32_common.h index cd74ae17ac..57997dd67b 100644 --- a/video/out/w32_common.h +++ b/video/out/w32_common.h @@ -50,6 +50,7 @@ struct vo_w32_state { int event_flags; int mon_cnt; + int mon_id; }; int vo_w32_init(struct vo *vo); diff --git a/video/out/x11_common.c b/video/out/x11_common.c index a3bf5c10cf..a78ca11402 100644 --- a/video/out/x11_common.c +++ b/video/out/x11_common.c @@ -374,10 +374,17 @@ static void init_atoms(struct vo_x11_state *x11) void vo_x11_update_screeninfo(struct vo *vo) { struct MPOpts *opts = vo->opts; + bool all_screens = vo_fs && opts->vo_fsscreen_id == -2; xinerama_x = xinerama_y = 0; + if (all_screens) { + opts->vo_screenwidth = vo->x11->ws_width; + opts->vo_screenheight = vo->x11->ws_height; + } #ifdef CONFIG_XINERAMA - if (opts->vo_screen_id >= -1 && XineramaIsActive(vo->x11->display)) { - int screen = opts->vo_screen_id; + if (opts->vo_screen_id >= -1 && XineramaIsActive(vo->x11->display) && + !all_screens) + { + int screen = vo_fs ? opts->vo_fsscreen_id : opts->vo_screen_id; XineramaScreenInfo *screens; int num_screens; @@ -450,23 +457,16 @@ int vo_x11_init(struct vo *vo) init_atoms(vo->x11); -#ifdef CONFIG_XF86VM - { - int clock; - XF86VidModeModeLine modeline; - - XF86VidModeGetModeLine(x11->display, x11->screen, &clock, &modeline); - if (!opts->vo_screenwidth) - opts->vo_screenwidth = modeline.hdisplay; - if (!opts->vo_screenheight) - opts->vo_screenheight = modeline.vdisplay; - } -#endif + x11->ws_width = opts->vo_screenwidth; + x11->ws_height = opts->vo_screenheight; + + if (!x11->ws_width) + x11->ws_width = DisplayWidth(x11->display, x11->screen); + if (!x11->ws_height) + x11->ws_height = DisplayHeight(x11->display, x11->screen); - if (!opts->vo_screenwidth) - opts->vo_screenwidth = DisplayWidth(x11->display, x11->screen); - if (!opts->vo_screenheight) - opts->vo_screenheight = DisplayHeight(x11->display, x11->screen); + opts->vo_screenwidth = x11->ws_width; + opts->vo_screenheight = x11->ws_height; if (strncmp(dispName, "unix:", 5) == 0) dispName += 4; @@ -1297,6 +1297,10 @@ void vo_x11_fullscreen(struct vo *vo) if (vo_fs) { vo_x11_ewmh_fullscreen(x11, _NET_WM_STATE_REMOVE); // removes fullscreen state if wm supports EWMH + if ((x11->fs_type & vo_wm_FULLSCREEN) && opts->vo_fsscreen_id != -1) { + XMoveResizeWindow(x11->display, x11->window, x, y, w, h); + vo_x11_sizehint(vo, x, y, w, h, 0); + } vo_fs = VO_FALSE; if (x11->size_changed_during_fs && (x11->fs_type & vo_wm_FULLSCREEN)) { vo_x11_nofs_sizepos(vo, vo->dx, vo->dy, x11->last_video_width, @@ -1305,20 +1309,29 @@ void vo_x11_fullscreen(struct vo *vo) x11->size_changed_during_fs = false; } else { // win->fs - vo_x11_ewmh_fullscreen(x11, _NET_WM_STATE_ADD); // sends fullscreen state to be added if wm supports EWMH - vo_fs = VO_TRUE; - if (!(x11->fs_type & vo_wm_FULLSCREEN)) { // not needed with EWMH fs - x11->vo_old_x = vo->dx; - x11->vo_old_y = vo->dy; - x11->vo_old_width = vo->dwidth; - x11->vo_old_height = vo->dheight; - } + + x11->vo_old_x = vo->dx; + x11->vo_old_y = vo->dy; + x11->vo_old_width = vo->dwidth; + x11->vo_old_height = vo->dheight; + vo_x11_update_screeninfo(vo); + x = xinerama_x; y = xinerama_y; w = opts->vo_screenwidth; h = opts->vo_screenheight; + + if ((x11->fs_type & vo_wm_FULLSCREEN) && opts->vo_fsscreen_id != -1) { + // The EWMH fullscreen hint always works on the current screen, so + // change the current screen forcibly. + // This was observed to work under IceWM, but not Unity/Compiz and + // awesome (but --screen etc. doesn't really work on these either). + XMoveResizeWindow(x11->display, x11->window, x, y, w, h); + } + + vo_x11_ewmh_fullscreen(x11, _NET_WM_STATE_ADD); // sends fullscreen state to be added if wm supports EWMH } { long dummy; diff --git a/video/out/x11_common.h b/video/out/x11_common.h index d638d6b15f..5553c070f5 100644 --- a/video/out/x11_common.h +++ b/video/out/x11_common.h @@ -34,6 +34,8 @@ struct vo_x11_state { Window rootwin; int screen; int display_is_local; + int ws_width; + int ws_height; int screensaver_off; int dpms_disabled; |