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

Add query and mutation controls for the traffic light window buttons #27

Closed
matthew-carroll opened this issue Jun 23, 2023 · 11 comments
Closed
Assignees
Labels
enhancement New feature or request

Comments

@matthew-carroll
Copy link

Every Mac desktop window has three little window control buttons, often called "traffic lights".

These buttons have a default appearance, but their location can be changed by the developer.

The traffic lights create at least a couple of issues for UI developers.

First, content needs to avoid the traffic lights. If I'm building a custom app bar, or allowing my content to flow to the top of the window, how do I know where those traffic lights are? This requires an ability to query the current size and location of the traffic lights, from the platform.

Second, if I'm building a custom app bar, it's conventional that the traffic light buttons should appear vertically centered in that app bar. Therefore, I'd like to be able to tell the platform where to put the traffic lights.

I recommend approaching this problem as pass-through control of the platform. I don't recommend trying to hide information, or simplify behavior. The platform has an API for these details - making that API available through this package via Dart is the most versatile option available. Simplified behaviors and widgets can be added on top in macos_ui.

@Adrian-Samoticha
Copy link
Member

Adrian-Samoticha commented Jun 24, 2023

First, content needs to avoid the traffic lights. If I'm building a custom app bar, or allowing my content to flow to the top of the window, how do I know where those traffic lights are? This requires an ability to query the current size and location of the traffic lights, from the platform.

macos_window_utils provides the TitlebarSafeArea widget for this very purpose.

When the full-size content view is enabled, it uses WindowManipulator.getTitlebarHeight to retrieve the height of the title bar and accordingly adds padding to its child.


While there is currently no way to freely position the traffic light buttons, you can manipulate their position by changing the window’s toolbar style. (So, when building your own custom app bar, be sure to simply choose a toolbar style with the correct size.)

Personally, I am not aware of any API that allows you to change the position of the window buttons freely. It’s possible that applications that do move them either do it by like this or simply by hiding the “real” traffic light buttons and implementing their own versions of them. I assume Opera GX, for example, does the latter.

@matthew-carroll
Copy link
Author

I'm not sure how to use the toolbar style to achieve the goal I mentioned.

I start with:

WindowManipulator.makeTitlebarTransparent();
WindowManipulator.hideTitle();
WindowManipulator.enableFullSizeContentView();

The above configuration is needed so that I can display tabs at the top of the window, instead of showing the window title.

Then, I tried every toolbar style, and none of them cause the traffic lights to move at all.

WindowManipulator.setToolbarStyle(toolbarStyle: /** I tried every value here **/);

@Adrian-Samoticha
Copy link
Member

Be sure to call WindowManipulator.addToolbar before setting the toolbar style.

@matthew-carroll
Copy link
Author

Ok, using addToolbar() before setToolbarStyle() allowed me to move the traffic lights. In my case, unifiedCompact seemed to be the closest position for what I'm building.

I see now that the docs for setToolbarStyle() mention addToolbar(). I'm curious why those two don't go together? Would it ever be appropriate to call setToolbarStyle() without first adding a toolbar? And when you add a toolbar, is there not an implied style? Could you not pass the style to addToolbar()?

I also found the term addToolbar() to be confusing, because it sounds as if you can keep adding more and more toolbars. Like adding items to a collection. But calling addToolbar() multiple times doesn't seem to have any effect. As far as I can tell, addToolbar() really means something like "show toolbar with default style".

@Adrian-Samoticha
Copy link
Member

I admit that the names aren’t very intuitive, but the reason for this is that I modeled them loosely after the way in which you add to or modify toolbars of an NSWindow in Swift. In Swift, you’d first create an NSToolbar object, then add it to the window, and then set its style.

I suppose having the toolbar be added or removed automatically based on an argument to setToolbarStyle would make the library a little more intuitive to use, but at the same time, if I were to add more customization options to the toolbar, deviating too much from the way things are handled in Swift might make things more difficult in the long run.

@cbenhagen
Copy link
Contributor

Adding an NSToolbar might have unintended side effects like reacting to double clicks everywhere in your custom toolbar created on the Flutter side. See macosui/macos_ui#308 for a discussion about how to avoid that.

@Adrian-Samoticha
Copy link
Member

Adding an NSToolbar might have unintended side effects like reacting to double clicks everywhere in your custom toolbar created on the Flutter side. See macosui/macos_ui#308 for a discussion about how to avoid that.

I’ve been thinking about adding a way to add native buttons to the toolbar to fix that. So far I haven’t really dedicated any time to researching this approach, though.

@cbenhagen
Copy link
Contributor

Having native buttons might work for simple apps but as soon as you need custom behaviors or style you are back to wanting full control from the Flutter side. The approach outlined in the linked issue is the only way to achieve this I have found so far.

@Adrian-Samoticha
Copy link
Member

Having native buttons might work for simple apps but as soon as you need custom behaviors or style you are back to wanting full control from the Flutter side. The approach outlined in the linked issue is the only way to achieve this I have found so far.

True. I’ll look into your code and see if it can be integrated well into macos_window_utils when I have time to do so.

@Adrian-Samoticha
Copy link
Member

Adrian-Samoticha commented Sep 5, 2023

I’ve experimented a little and found that there is indeed a way to move those buttons, however, you cannot move them outside of the title bar area:

image

You can, however, increase the title bar area by adding a toolbar:

image

@Adrian-Samoticha
Copy link
Member

Alright, version 1.3.0 resolves this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants