Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to set initial window size and position and restore previous values #7592

Open
Tracked by #9139
Shrp77 opened this issue May 29, 2022 · 14 comments
Open
Tracked by #9139
Assignees
Labels
area-controls-window Window delighter platform/windows 🪟 proposal/open t/desktop The issue relates to desktop scenarios (MacOS/MacCatalyst/Windows/WinUI/WinAppSDK)

Comments

@Shrp77
Copy link

Shrp77 commented May 29, 2022

Description

I wish to be able to define a default starting size and position for the MAUI application and to restore the window position and size the next time the application is launched.

While I understand the paradigm of starting MAUI apps as full-screen (or close to full screen), it is very impractical for users to have ultra-wide monitors (in my case a 49" 5440x1440 monitor); I literally have to turn my head to change from the left side to the right side of the monitor.

I have a work-around for the initial window size and position* (except for not being able to determine the screen size, so I cannot do bounds checking to make sure the window is wholly within the screen for different resolutions / monitor sizes) but would prefer to have official support, cross platform to MacOS, for this functionality.

Public API Changes

int initialWidth = 1024;
int initialHeight = 726;

Screen primary = Screen.GetPrimaryScreen(); // New API
RectInt32 sizeAndPosition = new RectInt32(
   primary.Width/2 - initialWidth/2,
   primary.Height/2 - initialHeight/2,
   initialWidth,
   initialHeight);
Window window = new Window(new SomePage(), sizeAndPosition); // New API

Intended Use-Case

My app has two distinct modes of operation; Full mode for Desktop environments (Windows / MacOS) and Player for mobile devices (Android / iOS). On desktop environments (Windows / MacOS), full screen is not a desired initial state for the application.

If the user has resized and positioned the window in a specific location of the screen - as long as that position + size is still valid the application should re-launch to that position and size.

@Eilon Eilon added the legacy-area-desktop Windows / WinUI / Project Reunion & Mac Catalyst / macOS specifics (Menus & other Controls)) label May 31, 2022
@Dbquity
Copy link

Dbquity commented Jun 3, 2022

I am not sure we need API changes to improve significantly :-)
IMHO a very good first, hardcoded solution could be to let the end user resize and move the window and then restore to that size and position the next time the app opens.

@Shrp77
Copy link
Author

Shrp77 commented Jun 3, 2022

Granted - as long as the system is able to do bounds check to validate that the restored position of the window falls within a valid range and doesn't restore to an off-screen location.

Example:

  • Laptop with a second monitor attached.
  • Move the app to the second monitor and close the app.
  • Disconnect the second monitor.
  • Launch the app.

In this case, it would be perfectly acceptable for the app to be opened in the valid screen, then either get its "default sizing" (behavior we see today) or retain the size it had before if the size can be contained within the screen bounds (minus the task bar).

@Redth Redth mentioned this issue Aug 2, 2022
22 tasks
@Redth Redth added the delighter label Aug 2, 2022
@Redth Redth added this to the 7.0-rc1 milestone Aug 2, 2022
@mattleibow
Copy link
Member

I started on this some time ago #4942

@mattleibow mattleibow mentioned this issue Aug 10, 2022
25 tasks
@ghost ghost locked as resolved and limited conversation to collaborators Sep 27, 2022
@mattleibow mattleibow reopened this Apr 3, 2023
@mattleibow
Copy link
Member

I see this issue was closed incorrectly as this was a new automatic feature rather than the support for a manual feature.

@dotnet dotnet unlocked this conversation Apr 3, 2023
@mattleibow
Copy link
Member

One thing I noticed today, mac catalyst already save window size and position. So this is probably more just for windows.

@Redth
Copy link
Member

Redth commented Jul 12, 2023

Given there's now API's to set the window size/position on windows, you can definitely handle saving and restoring this state yourself as a workaround.

@DanJBower
Copy link

Given there's now API's to set the window size/position on windows, you can definitely handle saving and restoring this state yourself as a workaround.

Whilst it would be nice if it worked out the box. If anyone else needs it, I've been using this workaround

#if WINDOWS
using Microsoft.Maui.Platform;
using Microsoft.UI.Windowing;
using Windows.Graphics;
#endif

namespace Sample;

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

        MainPage = new MainPage();
    }

#if WINDOWS
    private const string LastWidthPropertyKey = "windows_last_window_width";
    private const string LastHeightPropertyKey = "windows_last_window_height";
    private const string LastXPropertyKey = "windows_last_window_x";
    private const string LastYPropertyKey = "windows_last_window_y";

    protected override Window CreateWindow(IActivationState? activationState)
    {
        var window = base.CreateWindow(activationState);
        AppWindow appWindow = null!;

        window.Created += (_, _) =>
        {
            var nativeWindow = (MauiWinUIWindow)window.Handler!.PlatformView!;
            appWindow = nativeWindow.GetAppWindow()!;

            if (Preferences.Default.ContainsKey(LastWidthPropertyKey) &&
                Preferences.Default.ContainsKey(LastHeightPropertyKey))
            {
                window.Width = Preferences.Default.Get(LastWidthPropertyKey, -1.0);
                window.Height = Preferences.Default.Get(LastHeightPropertyKey, -1.0);
            }

            if (Preferences.Default.ContainsKey(LastXPropertyKey) &&
                Preferences.Default.ContainsKey(LastYPropertyKey))
            {
                // Using appWindow.Move as setting window.X and window.Y was not working properly
                // with monitors where scaling wasn't 100%.
                appWindow.Move(new PointInt32(
                    Preferences.Default.Get(LastXPropertyKey, 0),
                    Preferences.Default.Get(LastYPropertyKey, 0)
                ));
            }
        };

        window.Destroying += (_, _) =>
        {
            Preferences.Default.Set(LastWidthPropertyKey, window.Width);
            Preferences.Default.Set(LastHeightPropertyKey, window.Height);
            Preferences.Default.Set(LastXPropertyKey, appWindow.Position.X);
            Preferences.Default.Set(LastYPropertyKey, appWindow.Position.Y);
        };

        return window;
    }
#endif
}

@Eilon Eilon added t/desktop The issue relates to desktop scenarios (MacOS/MacCatalyst/Windows/WinUI/WinAppSDK) area-controls-window Window and removed legacy-area-desktop Windows / WinUI / Project Reunion & Mac Catalyst / macOS specifics (Menus & other Controls)) labels May 10, 2024
@iascience
Copy link

Given there's now API's to set the window size/position on windows, you can definitely handle saving and restoring this state yourself as a workaround.

This is fine until the layout has changed, e.g. the situation described earlier where an external monitor has been disconnected. My current workaround is to use EnumDisplayMonitors and GetMonitorInfo through P/Invoke, which works fine but obviously only on Windows.

@MartyIX
Copy link
Contributor

MartyIX commented Oct 1, 2024

There is also @dotMorten's WinUIEx and it provides this feature. See the MAUI sample and particularly the configuration. Note that the feature works for Windows packaged apps only.

Useful links

@dotMorten
Copy link
Contributor

@ivanjx
Copy link

ivanjx commented Nov 15, 2024

any idea on how to easily save current window maximize state too?

@dotMorten
Copy link
Contributor

@ivanjx On Windows you can use WinUIEx to do this. See doc here: https://dotmorten.github.io/WinUIEx/concepts/Maui.html#perform-operations-when-windows-are-created
The important bit is the PersistenceId which will remember windows size/position and maximize state and restore next time a window with that ID opens.

@ivanjx
Copy link

ivanjx commented Nov 16, 2024

@dotMorten thank you for the package. it works perfect. however i have read some concerns that on multi monitor when it no longer exists it may create the window outside of the bounds of the connected monitor. is that case also handled with WinUIEx?

@dotMorten
Copy link
Contributor

@ivanjx yes if the monitor layout changes since last app run, it will revert to default start up

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-controls-window Window delighter platform/windows 🪟 proposal/open t/desktop The issue relates to desktop scenarios (MacOS/MacCatalyst/Windows/WinUI/WinAppSDK)
Projects
None yet
Development

No branches or pull requests