dotnet / maui

.NET MAUI is the .NET Multi-platform App UI, a framework for building native device applications spanning mobile, tablet, and desktop.
https://dot.net/maui
MIT License
22.2k stars 1.75k forks source link

Add "Topmost" shell/app feature #8198

Open NickNiebling opened 2 years ago

NickNiebling commented 2 years ago

Description

I would love to have "topmost" shell/app/window feature in MAUI.

if you want to build a small app to sit on top of other apps and provide some insights/metrics/features "on top of another app", this would be a nice feature.

It might not be a feature for all platforms? (especially useful with Windows and Mac, might also apply to other platforms where apps can be layered?)

Public API Changes

Shell.SetTopMost(true);   // Set window "top most" at this point in time (other apps might overtake this position afterwards)
Shell.SetOpacity(0.5);    // Set opacity of the app to 50%, to allow better seeing what's going on behind the app (optional extra, to showcase how this feature could be extended later on)

Might not be the correct approach to do it, but just an idea based on how it works in Windows today.

Intended Use-Case

Use cases could be:

  1. Write an app to accompany a video game - to add features (buttons/shortcuts), or statistics or what not (like an "overlay" for the video game)
  2. Write a generic app to always be available (e.g. small clipboard app) - to add features (buttons/shortcuts) to everyday use of the computer
janseris commented 2 years ago

topmost window is one thing but topmost for video game (DirectX etc.) (visible on top of video game) is a different feature, isn't it?

Fabi commented 2 years ago

on windows you can set the window to be always on top already (also works in games)

NickNiebling commented 2 years ago

topmost window is one thing but topmost for video game (DirectX etc.) (visible on top of video game) is a different feature, isn't it?

@janseris It could be something like this: https://ruffk.github.io/ZwiftActivityMonitor/ https://github.com/ruffk/ZwiftActivityMonitor

And actually many games allows a "Windowed" mode: https://www.wikihow.com/Play-League-of-Legends-in-Windowed-Mode

Personally I would be fine with a limitation like that, if that's required - but obviously, it would be even better if it worked in all scenarios.

on windows you can set the window to be always on top already (also works in games)

@Fabi Any chance you can share how that is done? I haven't been able to find documentation, examples or anything (and I hardly know what to search for, as it probably isn't called "topmost" anymore )

Fabi commented 2 years ago

topmost window is one thing but topmost for video game (DirectX etc.) (visible on top of video game) is a different feature, isn't it?

@janseris It could be something like this: https://ruffk.github.io/ZwiftActivityMonitor/ https://github.com/ruffk/ZwiftActivityMonitor

And actually many games allows a "Windowed" mode: https://www.wikihow.com/Play-League-of-Legends-in-Windowed-Mode

Personally I would be fine with a limitation like that, if that's required - but obviously, it would be even better if it worked in all scenarios.

on windows you can set the window to be always on top already (also works in games)

@Fabi Any chance you can share how that is done? I haven't been able to find documentation, examples or anything (and I hardly know what to search for, as it probably isn't called "topmost" anymore )

Something similar to this should work (a snippet from my windows app cs file, so adjust to your need)

lifecycle.AddWindows(windows =>
            {
                windows.OnWindowCreated(xamlWindow =>
                {
                    var window = xamlWindow as MauiWinUIWindow;
                    MainWindowHandle = WinRT.Interop.WindowNative.GetWindowHandle(window);

                    var windowId = Win32Interop.GetWindowIdFromWindow(MainWindowHandle);
                    var appWindow = AppWindow.GetFromWindowId(windowId);
                    var presenter = appWindow.Presenter as OverlappedPresenter;

                    appWindow.SetPresenter(AppWindowPresenterKind.CompactOverlay);
                    presenter.IsAlwaysOnTop = true;
                });

            });
NickNiebling commented 2 years ago

Something similar to this should work (a snippet from my windows app cs file, so adjust to your need)

lifecycle.AddWindows(windows =>
            {
                windows.OnWindowCreated(xamlWindow =>
                {
                    var window = xamlWindow as MauiWinUIWindow;
                    MainWindowHandle = WinRT.Interop.WindowNative.GetWindowHandle(window);

                    var windowId = Win32Interop.GetWindowIdFromWindow(MainWindowHandle);
                    var appWindow = AppWindow.GetFromWindowId(windowId);
                    var presenter = appWindow.Presenter as OverlappedPresenter;

                    appWindow.SetPresenter(AppWindowPresenterKind.CompactOverlay);
                    presenter.IsAlwaysOnTop = true;
                });

            });

@Fabi thanks for taking the time to respond with this! It looks very promising. Do you know which platforms it will work on? Is it Windows only or will it work on any other?

Fabi commented 2 years ago

Something similar to this should work (a snippet from my windows app cs file, so adjust to your need)

lifecycle.AddWindows(windows =>
            {
                windows.OnWindowCreated(xamlWindow =>
                {
                    var window = xamlWindow as MauiWinUIWindow;
                    MainWindowHandle = WinRT.Interop.WindowNative.GetWindowHandle(window);

                    var windowId = Win32Interop.GetWindowIdFromWindow(MainWindowHandle);
                    var appWindow = AppWindow.GetFromWindowId(windowId);
                    var presenter = appWindow.Presenter as OverlappedPresenter;

                    appWindow.SetPresenter(AppWindowPresenterKind.CompactOverlay);
                    presenter.IsAlwaysOnTop = true;
                });

            });

@Fabi thanks for taking the time to respond with this! It looks very promising. Do you know which platforms it will work on? Is it Windows only or will it work on any other?

It's windows specific (win ui window) code as far as I know. Not sure if similar code exist on macOS

NickNiebling commented 2 years ago

It's windows specific (win ui window) code as far as I know. Not sure if similar code exist on macOS

Yhear I thought it looked a little like native windows.. For this to be an existing "MAUI feature" I would love to see it work for at least 2 platforms :) So still hoping for something like this cross platform :) Thanks for you help anyways!

ddobric commented 1 year ago

This is a must-have feature on Windows. If some features do not make sense on other platforms, it is ok to omit them. But feature like topmost is important on Windows

ainotna commented 1 year ago

Hi! Has anyone found a solution to keep the Window always on top in MacOS?

M-Nesti commented 10 months ago

This is a must-have feature on Windows. If some features do not make sense on other platforms, it is ok to omit them. But feature like topmost is important on Windows

Totally agree! For a lot of technical software I need to develop for customers this is a must have feature. Would be nice if this was officially supported.