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

Alexandre Janniaux ajanni at videolabs.io
Thu Oct 24 16:47:18 CEST 2019


Hi, you shouldn't have to care about the vout_window_cfg_t
object, just mirror the current state in the sys of the
vout_window instance.

At the beginning of WinVoutEventProc, you have:

```
    LONG_PTR p_user_data = GetWindowLongPtr( hwnd, GWLP_USERDATA );
    if( p_user_data == 0 )
        return DefWindowProc(hwnd, message, wParam, lParam);
    vout_window_t *wnd = (vout_window_t *)p_user_data;
```

Then you can get the sys from wnd, which is the module
private data implementation.

If you mirror the fullscreen state here, you can also
handle fullscreen state change from
`vout_window_SetFullscreen` and from other WM events, like
you wrote.

Regards,
--
Alexandre Janniaux
Videolabs


On Thu, Oct 24, 2019 at 10:38:10AM -0400, 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()?
>
> On Thu, Oct 24, 2019 at 9:40 AM Gabriel Luci <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> 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>> 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