maui icon indicating copy to clipboard operation
maui copied to clipboard

DeviceDisplay.Current.MainDisplayInfo not available on windows

Open pierre01 opened this issue 3 years ago • 12 comments

Description

DeviceDisplay.Current.MainDisplayInfo not available on windows

Steps to Reproduce

Create a Maui Application and add the following in AppShell Constructor: public AppShell() { InitializeComponent(); var di = DeviceDisplay.Current.MainDisplayInfo; }

The displayInfo does not provide any information about the display

Version with bug

Release Candidate 2 (current)

Last version that worked well

Unknown/Other

Affected platforms

Windows

Affected platform versions

Windows 11 Pro 22000.408

Did you find any workaround?

no

Relevant log output

No response

pierre01 avatar May 10 '22 05:05 pierre01

Confirmed, seems like the population of this data might happen a little bit earlier if possible. In a File > New Project this data is not populated in the AppShell ctor or the MainPage ctor.

If I add this same code to the click of the button on the MainPage then it is populated.

Running the same on Android it is populated from the AppShell ctor right away.

I guess a workaround could be to hook into the DisplayInfoChanged event so you will get the new values as soon as they are available.

jfversluis avatar May 10 '22 07:05 jfversluis

Display information is required as early in the app lifecycle as possible to be able to position and size the app windows for desktop apps. By the way, how can one do this under macOS?

paratype-fonts avatar May 10 '22 09:05 paratype-fonts

@paratype-fonts that seems to be possible right now, albeit maybe values being hardcoded. Come to think of it, maybe because of the same reason that this is bugged right now.

Find code for Windows and macOS here: https://gist.github.com/LanceMcCarthy/c8d23f5ba6157d5d53bee3b1a741f8b5

jfversluis avatar May 10 '22 09:05 jfversluis

This is an issue as we use the window to get display information... Not something that should be done to be honest, but one workaround for now would be to not use MainPage and rather return the window in the Application.CreateWindow(). THis happens after the native window has been set up and all the things are ready.

However, this is a workaround and display information should NOT be coming from windows but instead from the monitor data from the OS. However, this gets interesting as what happens if you have 2 monitors and then move the app? In this case we may need some screen index on the Window so that you know which display the window is running on.

mattleibow avatar May 12 '22 05:05 mattleibow

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

ghost avatar Aug 30 '22 14:08 ghost

When this supposed to be fixed ?! That is one critical i think and simple for my opinion why keep it opened for such a long time ?

arkadym avatar Oct 06 '22 09:10 arkadym

Please have a look at this. @davidortinau provides an example of using DeviceDisplay.Current.MainDisplayInfo.Width in the .NET 7 Release Candidate 1 release notes: to position the screen within the window... but this does not work when it needs to work, i.e. in Application:CreateWindow(IActivationState activationState) This is a key capability to work with WinUI.

v-croft avatar Nov 06 '22 17:11 v-croft

 DeviceDisplay.MainDisplayInfoChanged += DeviceDisplay_MainDisplayInfoChanged; 

and then use something like this:

 private void DeviceDisplay_MainDisplayInfoChanged(object? sender, DisplayInfoChangedEventArgs e)
    {
        MyMainDisplay = DeviceDisplay.Current.MainDisplayInfo;
        NotifyPropertyChanged(nameof(MyMainDisplay );
    }

tonydokun avatar Jan 12 '23 12:01 tonydokun

Test it, still not working, not even the event fire, I couldn't find a workaround, and we need it.

uSafi avatar Jan 18 '23 10:01 uSafi

Same MainDisplayInfoChanged event never fires.

gerneio avatar Jan 26 '23 19:01 gerneio

Not working. I need to set the size of popups which become massive when moving from phone to windows. This feature is needed set a usable width request, unless anyone else can suggest how to do this?

BrianJSavage avatar Feb 15 '23 22:02 BrianJSavage

Any workaround or solution now?

BlyZeDev avatar Mar 10 '23 23:03 BlyZeDev

I also encountered this problem just now. In Application.CreateWindow DisplayInfo properties are all 0. MainDisplayInfoChanged only fires when the window is dragged to another monitor.

wayne-stewart avatar Mar 16 '23 22:03 wayne-stewart

I ended up just using native win32 interop. Example here. https://stackoverflow.com/questions/254197/how-can-i-get-the-active-screen-dimensions

wayne-stewart avatar Mar 16 '23 22:03 wayne-stewart

I ended up just using native win32 interop. Example here. https://stackoverflow.com/questions/254197/how-can-i-get-the-active-screen-dimensions

@wayne-stewart this comment? (Unable to test atm)

gerneio avatar Mar 17 '23 00:03 gerneio

Hello! I just found the same problem. Please would be great if you could fix it in a not too long time. Thank you!

ethedy avatar Apr 04 '23 05:04 ethedy

For those wanting a fix now (since we don't know when this PR will ship yet), here's an actual MAUI specific minimum example using native win32 interop:

App.xaml.cs

public partial class App : Application
{
    public App()
    {
        InitializeComponent();

        MainPage = new MainPage();

#if WINDOWS
        Microsoft.Maui.Handlers.WindowHandler.Mapper.AppendToMapping(nameof(IWindow), (handler, view) =>
        {
            var nativeWindow = handler.PlatformView;
            var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(nativeWindow);
            var windowId = Microsoft.UI.Win32Interop.GetWindowIdFromWindow(hwnd);
            //var appWindow = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(windowId);
            //appWindow.MoveAndResize(new Windows.Graphics.RectInt32(500, 500, 1000, 1000)); // Can also be used to size and move the current window

            var displayArea = Microsoft.UI.Windowing.DisplayArea.GetFromWindowId(windowId, Microsoft.UI.Windowing.DisplayAreaFallback.Nearest);

            if (view is Window window)
                ResizeWindow(window, displayArea.WorkArea.Width, displayArea.WorkArea.Height);
        });
#endif
    }

    private static void ResizeWindow(Window window, int monitorWidth, int monitorHeight)
    {
        window.Width = 450;
        window.Height = 1000;

        var displayDensity = 1;

        // Center
        window.X = (monitorWidth / displayDensity - window.Width) / 2;
        window.Y = (monitorHeight / displayDensity - window.Height) / 2;
    }
}

Derived from @wayne-stewart's comment above as well as these resources:

https://stackoverflow.com/a/36920187 https://github.com/dotnet/maui/discussions/2370#discussioncomment-2367186

gerneio avatar Apr 28 '23 19:04 gerneio

Hello lovely human, thank you for your comment on this issue. Because this issue has been closed for a period of time, please strongly consider opening a new issue linking to this issue instead to ensure better visibility of your comment. Thank you!

ghost avatar Apr 28 '23 19:04 ghost

This still works in a maui windows app: https://www.syncfusion.com/faq/blazor/javascript-interop/how-do-i-get-the-window-dimension-or-size-in-blazor-webassembly

sterneric avatar May 03 '23 19:05 sterneric

This still works in a maui windows app: https://www.syncfusion.com/faq/blazor/javascript-interop/how-do-i-get-the-window-dimension-or-size-in-blazor-webassembly

That's for blazor, so wouldn't really apply unless ur using a BlazorWebView within MAUI, and even then the returned size would be of the web view, not the actual device display.

gerneio avatar May 03 '23 19:05 gerneio