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

[RFC] Add Window.CanMinimize/CanMaximize #18117

Open
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

MrJul
Copy link
Member

@MrJul MrJul commented Feb 4, 2025

What does the pull request do?

This PR adds two new properties to Window to enable or disable the minimize (CanMinimize) and maximize (CanMaximize) buttons of a window.

They're implemented on all three desktop platforms: Windows, macOS and X11.

Notes

General

  • Both properties are true by default.
  • CanMaximize is automatically coerced to false when CanResize is false.
  • Even if CanMaximize is false, the restore button stays enabled if the window is somehow already maximized (and is resizable).

Both Qt and Wine have been used as reference implementations for X11 and macOS.

Windows

On Windows, the two properties work exactly as one would expect. They map to the WS_MINIMIZEBOX and WS_MAXIMIZEBOX window styles.

Linux

On X11, the two properties are effectively hints (_MOTIF_WM_HINTS).
Maybe we should prefer names such as CanMinimizeHint and CanMaximizeHint?

In my tests, GNOME respects them, and while the buttons aren't visually disabled (at least on Ubuntu 24.04 with the default theme), they aren't clickable.

KDE (KWin) completely ignores them.

macOS

CanMinimize disables the minimize button, as expected.

CanMaximize disables both the zoom/maximize gesture (titlebar double click) and the green full screen button.
I went this route because I believe that's what most users would expect: that each property effectively corresponds to one traffic light button. Plus, clicking the green button with pressed effectively zooms so the two behaviors aren't easily dissociated.

If that isn't acceptable, we could easily split that into CanMaximize and CanSwitchToFullScreen (naming TBD).

New API

namespace Avalonia.Controls
{
    public class Window
    {
        public static readonly StyledProperty<bool> CanMinimizeProperty;
        public static readonly StyledProperty<bool> CanMaximizeProperty;
        public bool CanMinimize { get; set; }
        public bool CanMaximize { get; set; }
    }
}

Fixed issues

@MrJul MrJul added feature os-macos os-linux os-windows needs-api-review The PR adds new public APIs that should be reviewed. labels Feb 4, 2025
@avaloniaui-bot
Copy link

You can test this PR using the following package version. 11.3.999-cibuild0054759-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

Copy link
Contributor

@rabbitism rabbitism left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the linked issue really resolved? CaptionButtons are still visible.

@MrJul
Copy link
Member Author

MrJul commented Feb 4, 2025

Is the linked issue really resolved? CaptionButtons are still visible.

We're just supporting what the various platforms are exposing here.

On Windows, if Maximize and Minimize are both disabled, the system automatically hides both buttons.
On macOS, the traffic lights are kept, but disabled (see the "about this mac" system window).
On Linux, it totally depends on the window manager and its configuration.

To do more, it's always possible for users to use a custom chrome.

style &= ~WindowStyles.WS_MINIMIZEBOX;

if (newProperties.IsMaximizable || (newProperties.WindowState == WindowState.Maximized && newProperties.IsResizable))
style |= WindowStyles.WS_MAXIMIZEBOX;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it's annoying, but we need integration tests for win/mac :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I completely agree that we need more tests overall!
However, in this case, I don't really see a good way to test this with the current infrastructure.

Should we find the position of the maximize/minimize buttons and try to click them? (Can we even access the non-client area buttons via Appium?) Did you have another approach in mind?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wrote these extension methods before for window-decoration tests: https://github.com/AvaloniaUI/Avalonia/blob/master/tests/Avalonia.IntegrationTests.Appium/ElementExtensions.cs#L40

It might be enough to check enabled/visible state of these elements via appium apis.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetSystemChromeButtons for system titlebar. And GetClientChromeButtons for client titlebar (which also is properly recognized as an accessible titlebar, at least on windows).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the pointers! I really need to familiarize myself with the integration tests infrastructure.

@avaloniaui-bot
Copy link

You can test this PR using the following package version. 11.3.999-cibuild0054781-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

@thevortexcloud
Copy link
Contributor

I think hint in the name makes more sense and follows the existing pattern of things that may or may not work.

@robloo
Copy link
Contributor

robloo commented Feb 7, 2025

Couple thoughts:

  1. Have you considered a higher level of abstraction like with WPF? WPF has the WindowStyle enum to control this. It might help here in some cases:
    • Do we really need to support maximize but not minimize? Usually a window is resisable or it is not.
    • A WindowStyle could have a value such as NotResizeable. On windows that would remove the minimize/maximize buttons completely but on macOS would just disable them. So this generic naming doesn't imply how the actual buttons are shown which allows the platforms to handle it natively.
  2. For some reason I'm not a fan of "Hint" in this context. But I also agree it is more of a "Hint" on the platforms such as Linux that don't support all cases. I guess my justification is the main platforms support these properties just fine so its a shame to use less-than-ideal naming just because of limitations of a minor platform.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature needs-api-review The PR adds new public APIs that should be reviewed. os-linux os-macos os-windows
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add support to hide Minimize / Maximize window buttons
7 participants