[vlc-devel] [PATCH 4/4] win32: Send fullscreen to specific monitor

Steve Lhomme robux4 at ycbcr.xyz
Thu Oct 24 17:10:15 CEST 2019


On 2019-10-24 16:38, Gabriel Luci wrote:
> Ok, yeah, it's just a problem with my breakpoints. I added a debug 
> message on WM_MOVE and I see it when using Win+Shift+Arrows. My bad.
> 
> The only issue I see is finding out if we are currently in fullscreen 
> mode. There is no reference to the vout_window_cfg_t object 
> in WinVoutEventProc (where we could just look at is_fullscreen). Can we 
> get that object from there? Or will we have to store our own 
> is_fullscreen variable and toggle it in SetFullscreen() 
> and UnsetFullscreen()?

sys->window_placement.length should tell you whether you're in 
fullscreen or not, not that I reset it when leaving fullscreen.

> On Thu, Oct 24, 2019 at 9:40 AM Gabriel Luci <github at luci.ca 
> <mailto:github at luci.ca>> wrote:
> 
>     Well I just set a breakpoint at the start of WinVoutEventProc and it
>     wasn't hit, but maybe it's not being hit for other reasons. It seems
>     inconsistent. Spy++ does show WM_MOVE and WM_WINDOWPOSCHANGED. I'll
>     add a case to the switch block for WM_MOVE and see what happens.
> 
>     On Thu, Oct 24, 2019 at 9:11 AM Steve Lhomme <robux4 at ycbcr.xyz
>     <mailto:robux4 at ycbcr.xyz>> wrote:
> 
>         On 2019-10-24 15:01, Gabriel Luci wrote:
>          > I think this depends on what value is going to be in whatever
>         setting we
>          > end up deciding to use. If we store the device name (like
>          > "\\.\DISPLAY2"), then you have to enumerate the displays to
>         figure out
>          > which one has that name, since there isn't any GetMonitorByName
>          > function. But once you find it, you already have the
>         MONITORINFOEX
>          > struct that you need to go fullscreen. That's why I did what
>         I did.
>          >
>          > If you want to use the SetFullscreenOnMonitor, then the
>         enumeration
>          > would have to pass back just the handle to the monitor
>          > and SetFullscreenOnMonitor would have to use the handle to go
>         find the
>          > monitor info again.
> 
>         I guess you could pass the MONITORINFOEX to
>         SetFullscreenOnMonitor then.
>         We should read it in the current code as well.
> 
>          > To Alexandre's point about switching monitors: This is a bug
>         that exists
>          > in VLC 3 too. I'm just testing this now in the current v4
>         code, and I
>          > don't see any message at all sent to WinVoutEventProc when using
>          > Win+Shift+Arrow. I would have expected to see WM_MOVE and
>         figured we
>          > could just check if we're in fullscreen mode and resize to
>         the new
>          > monitor. But as it is, I don't see VLC being notified at all
>         that the
>          > window moved. Any idea why?
> 
>         This is weird and unexpected. Did you log all the messages
>         received at
>         the beginning of WinVoutEventProc() ? You may also check with
>         Spy++ (or
>         Spy32++?)
> 
>          > If you move from a larger resolution monitor to a smaller
>         one, you see
>          > WM_SIZE because Windows resizes the window to the new
>         display, but minus
>          > the taskbar. But you see no notifications at all if you move
>         from a
>          > smaller monitor to a larger one.
>          >
>          > On Thu, Oct 24, 2019 at 7:32 AM Steve Lhomme
>         <robux4 at ycbcr.xyz <mailto:robux4 at ycbcr.xyz>
>          > <mailto:robux4 at ycbcr.xyz <mailto:robux4 at ycbcr.xyz>>> wrote:
>          >
>          >     Here's a patch that allows going fullscreen on a given
>         HMONITOR. Thats'
>          >     what this patch should use in the end and the
>         logo+shift+arrow patch.
>          >
>          >     On 2019-10-24 13:17, Steve Lhomme wrote:
>          >      > On 2019-10-24 13:14, Steve Lhomme wrote:
>          >      >> On 2019-10-24 12:21, Alexandre Janniaux wrote:
>          >      >>> When in fullscreen, the window can be moved to another
>          >      >>> screen by using logo+shift+arrow key. When doing so on
>          >      >>> screens which are not the same size, the window is not
>          >      >>> resized and keep the size from the former screen. It
>         should
>          >      >>> probably keep the resize state somewhere and resize
>          >      >>> adequatly while using vout_window_ReportSize() so that
>          >      >>> video outputs can be resized too.
>          >      >>>
>          >      >>> I don't know if you want to add this to your patch
>         too, as
>          >      >>> the behaviour is already present without yours, but
>         maybe
>          >      >>> Windows dev here can provide advice for this?
>          >      >>
>          >      >> I should be able to fix it. We probably need to
>         handle the WM_MOVE
>          >      >> and, when in fullscreen, adapt the size of the window
>         if the
>          >     monitor
>          >      >> changed.
>          >      >>
>          >      >> It's probably better to apply a fix after this change
>         as it would
>          >      >> impact how we apply the fullscreen based on the selected
>          >     monitor. In
>          >      >> this case it wouldn't come the core anymore but from
>         the local
>          >      >> detection of the monitor. That means the monitor from
>         the core
>          >     should
>          >      >> return just a
>          >      >
>          >      > the monitor *selection* (based on the screen from the
>         core)
>          >      >
>          >      >> HMONITOR, which is always what we'll use when we use
>         the one
>          >     forced by
>          >      >> the OS.
>          >      >>
>          >      >>> PS: just for giving context, I used your patch in a
>         VR demo
>          >      >>> so as to force a VR sidebyside output to the HMD
>         screen and
>          >      >>> a classic 360° pano output to the main screen.
>          >      >>>
>          >      >>> On Sat, Oct 12, 2019 at 11:58:31PM -0400, Gabriel
>         Luci wrote:
>          >      >>>> This reads the id parameter as the name of the
>         monitor that
>          >     should be
>          >      >>>> used. If anything goes wrong, it will fall back to
>         the monitor the
>          >      >>>> window is already on (which is what it always did
>         before).
>          >      >>>>
>          >      >>>> ---
>          >      >>>>   modules/video_output/win32/window.c | 72
>          >      >>>> +++++++++++++++++++++++++++++++++----
>          >      >>>>   1 file changed, 65 insertions(+), 7 deletions(-)
>          >      >>>>
>          >      >>>> diff --git a/modules/video_output/win32/window.c
>          >      >>>> b/modules/video_output/win32/window.c
>          >      >>>> index 50e172b9b4..eefaed256e 100644
>          >      >>>> --- a/modules/video_output/win32/window.c
>          >      >>>> +++ b/modules/video_output/win32/window.c
>          >      >>>> @@ -37,6 +37,7 @@
>          >      >>>>   #include <vlc_actions.h>
>          >      >>>>
>          >      >>>>   #include
>          >     <shellapi.h>                                         /*
>          >      >>>> ExtractIcon */
>          >      >>>> +#include
>         <vlc_charset.h>                                      /*
>          >      >>>> FromWide */
>          >      >>>>
>          >      >>>>   #define RECTWidth(r)   (LONG)((r).right - (r).left)
>          >      >>>>   #define RECTHeight(r)  (LONG)((r).bottom - (r).top)
>          >      >>>> @@ -153,9 +154,37 @@ static void
>         SetTitle(vout_window_t *wnd,
>          >     const
>          >      >>>> char *title)
>          >      >>>>       PostMessage( sys->hwnd, WM_VLC_CHANGE_TEXT,
>         0, 0 );
>          >      >>>>   }
>          >      >>>>
>          >      >>>> +typedef struct enum_monitors_callback_params_t {
>          >      >>>> +    bool is_monitor_found;
>          >      >>>> +    const char *psz_name_to_find;
>          >      >>>> +    MONITORINFOEX *found_monitor_info;
>          >      >>>> +} enum_monitors_callback_params_t;
>          >      >>>> +
>          >      >>>> +static BOOL CALLBACK
>         EnumDisplayMonitorsCallback(HMONITOR
>          >     hMonitor,
>          >      >>>> HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
>          >      >>>> +{
>          >      >>>> +    /* this is called for each active monitor */
>          >      >>>> +
>          >      >>>> +    VLC_UNUSED(hdcMonitor);
>          >      >>>> +    VLC_UNUSED(lprcMonitor);
>          >      >>>> +
>          >      >>>> +    MONITORINFOEX mi;
>          >      >>>> +    mi.cbSize = sizeof(MONITORINFOEX);
>          >      >>>> +    if (!GetMonitorInfo(hMonitor, (LPMONITORINFO)
>         &mi))
>          >     return true;
>          >      >>>> +
>          >      >>>> +    enum_monitors_callback_params_t *params =
>          >      >>>> (enum_monitors_callback_params_t*) dwData;
>          >      >>>> +    char *psz_monitor_name = FromWide(mi.szDevice);
>          >      >>>> +    if (!strcmp(psz_monitor_name,
>         params->psz_name_to_find))
>          >      >>>> +    {
>          >      >>>> +        /* the monitor name matches what we're
>         looking for */
>          >      >>>> +        params->is_monitor_found = true;
>          >      >>>> +        params->found_monitor_info = &mi;
>          >      >>>> +    }
>          >      >>>> +    free(psz_monitor_name);
>          >      >>>> +    return !params->is_monitor_found;
>          >      >>>> +}
>          >      >>>> +
>          >      >>>>   static void SetFullscreen(vout_window_t *wnd,
>         const char *id)
>          >      >>>>   {
>          >      >>>> -    VLC_UNUSED(id);
>          >      >>>>       msg_Dbg(wnd, "entering fullscreen mode");
>          >      >>>>       vout_window_sys_t *sys = wnd->sys;
>          >      >>>>
>          >      >>>> @@ -167,12 +196,41 @@ static void
>         SetFullscreen(vout_window_t
>          >     *wnd,
>          >      >>>> const char *id)
>          >      >>>>       /* Change window style, no borders and no
>         title bar */
>          >      >>>>       SetWindowLong(sys->hwnd, GWL_STYLE,
>         WS_CLIPCHILDREN |
>          >      >>>> WS_VISIBLE);
>          >      >>>>
>          >      >>>> -    /* Retrieve current window position so
>         fullscreen will happen
>          >      >>>> -     * on the right screen */
>          >      >>>> -    HMONITOR hmon = MonitorFromWindow(sys->hwnd,
>          >      >>>> MONITOR_DEFAULTTONEAREST);
>          >      >>>> -    MONITORINFO mi;
>          >      >>>> -    mi.cbSize = sizeof(MONITORINFO);
>          >      >>>> -    if (GetMonitorInfo(hmon, &mi))
>          >      >>>> +    /* Figure out which monitor we should be using */
>          >      >>>> +    MONITORINFOEX mi;
>          >      >>>> +    bool is_monitor_found = false;
>          >      >>>> +
>          >      >>>> +    if (id)
>          >      >>>> +    {
>          >      >>>> +        /* We're being told to use a specific
>         monitor, so see
>          >     if we
>          >      >>>> can find an
>          >      >>>> +         * active monitor with the same name */
>          >      >>>> +        enum_monitors_callback_params_t params = {
>          >      >>>> +            .is_monitor_found = false,
>          >      >>>> +            .psz_name_to_find = id
>          >      >>>> +        };
>          >      >>>> +        EnumDisplayMonitors(NULL, NULL,
>          >      >>>> &EnumDisplayMonitorsCallback, (LPARAM) &params);
>          >      >>>> +
>          >      >>>> +        if (params.is_monitor_found)
>          >      >>>> +        {
>          >      >>>> +            is_monitor_found = true;
>          >      >>>> +            mi = *(params.found_monitor_info);
>          >      >>>> +        }
>          >      >>>> +        else
>          >      >>>> +        {
>          >      >>>> +            msg_Dbg(wnd, "display device with name
>         \"%s\" was
>          >      >>>> requested, but no such device exists. Falling back to
>          >     primary", id);
>          >      >>>> +        }
>          >      >>>> +    }
>          >      >>>> +
>          >      >>>> +    if (!is_monitor_found)
>          >      >>>> +    {
>          >      >>>> +        /* fall back to using the screen the
>         window is currently
>          >      >>>> mostly on */
>          >      >>>> +        HMONITOR hmon;
>          >      >>>> +        hmon = MonitorFromWindow(sys->hwnd,
>          >     MONITOR_DEFAULTTONEAREST);
>          >      >>>> +        mi.cbSize = sizeof(MONITORINFOEX);
>          >      >>>> +        is_monitor_found = GetMonitorInfo(hmon,
>          >     (LPMONITORINFO) &mi);
>          >      >>>> +    }
>          >      >>>> +
>          >      >>>> +    if (is_monitor_found)
>          >      >>>>           SetWindowPos(sys->hwnd, 0,
>          >      >>>>                        mi.rcMonitor.left,
>          >      >>>>                        mi.rcMonitor.top,
>          >      >>>> --
>          >      >>>> 2.11.0
>          >      >>>>
>          >      >>>> _______________________________________________
>          >      >>>> vlc-devel mailing list
>          >      >>>> To unsubscribe or modify your subscription options:
>          >      >>>> https://mailman.videolan.org/listinfo/vlc-devel
>          >      >>> _______________________________________________
>          >      >>> vlc-devel mailing list
>          >      >>> To unsubscribe or modify your subscription options:
>          >      >>> https://mailman.videolan.org/listinfo/vlc-devel
>          >      >>>
>          >      >> _______________________________________________
>          >      >> vlc-devel mailing list
>          >      >> To unsubscribe or modify your subscription options:
>          >      >> https://mailman.videolan.org/listinfo/vlc-devel
>          >      > _______________________________________________
>          >      > vlc-devel mailing list
>          >      > To unsubscribe or modify your subscription options:
>          >      > https://mailman.videolan.org/listinfo/vlc-devel
>          >     _______________________________________________
>          >     vlc-devel mailing list
>          >     To unsubscribe or modify your subscription options:
>          > https://mailman.videolan.org/listinfo/vlc-devel
>          >
>          >
>          > _______________________________________________
>          > vlc-devel mailing list
>          > To unsubscribe or modify your subscription options:
>          > https://mailman.videolan.org/listinfo/vlc-devel
>          >
>         _______________________________________________
>         vlc-devel mailing list
>         To unsubscribe or modify your subscription options:
>         https://mailman.videolan.org/listinfo/vlc-devel
> 
> 
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel
> 


More information about the vlc-devel mailing list