28
votes

I want to create a custom Window Toolbar but without using an actual NSToolbar (because it doesn't behaves right in some cases for my needs and I can't style it the way I want), therefore I need to add a subview to the Window titlebar. It should look like the following: Screenshot of custom Toolbar

A posible way would be:

[[[_window contentView] superview] addSubview:_titlebarView];

but this has the problem, that it causes a warning on Yosemite (NSWindow warning: adding an unknown subview: <NSView: 0x608000122b20>) so this doesn't seem to be the right way to do it.

Currently I am adding the toolbar view to the titlebar view:

[[[_window standardWindowButton:NSWindowCloseButton]
    superview] addSubview:_titlebarView];

but this feels wrong too.

Since my App only targets OS X 10.10 (Yosemite) it would be fine for me to use Yosemite-only API's, so I had a look to NSTitlebarAccessoryViewController and I managed to successfully subclass it and using it with NSWindow's addTitlebarAccessoryViewController: method. With this approach there remains one problem, the possible values for layoutAttribute are:

  • NSLayoutAttributeBottom
    Adds the view to the bottom of the window's titlebar, while preserving the view's height.
  • NSLayoutAttributeRight
    Adds the view to the right of the window's titlebar, clipping the view to the height of the titlebar.

The NSLayoutAttributeBottom is not suitable for me, since I need to position things right at the top of the window titlebar (see screenshot above) and center the traffic lights. NSLayoutAttributeRight would be exactly what I need, but I can't find a way to increase the titlebar height, so the view is clipped to the titlebar height, making it useless for me. (Note: Using a textured Window and changing the content border doesn't work, since it will not change the actual titlebar height)

What is the recommended way to do this? I would prefer to go with the official API's and use the AccessoryViewController approach, if it would be possible to have a view larger than the default titlebar.

4
Arrgh! This is bugging me as well...SevenBits
FYI, you can still use the approach that you are currently using... but it will just generate a warning.SevenBits
@SevenBits I know that I can use it, but there was a clear note in the release notes: “Applications doing this will need to fix this problem, as it prevents new features on 10.10 from working properly.” on Mac OS X Developer Release NoteePirat
There's another problem I see when using the new titlebar accessory view: core graphics behavior changes somehow, which creates trouble for 3rd party code I use (warnings for EDSidebar, cocoacontrols.com/controls/edsidebar, and rendering calls with a null context, CorePlot, github.com/core-plot/core-plot). I can reliably reproduce that. Happens when I add the accessory view and disappears when I remove it.Mike Lischke
@MikeLischke What warnings for example? And how are you adding it? (Which layoutAttribute?)ePirat

4 Answers

6
votes

it just a NSToolBar. in Yosemite, when window.title.titleVisibility = .Hidden, the NSToolBar will become the titlebar

4
votes

WAYAppStoreWindow might accomplish what you're looking for. It was build explicitly to avoid the subview warning in Yosemite, specify a custom window titlebar height and add subviews to the titlebar.

1
votes

Thanks @ePirat

Adding subviews to their titlebarView, would be the same as doing

[[[_window standardWindowButton:NSWindowCloseButton] superview] addSubview:_customTitlebarView];
0
votes

Assign your Window to self view. and then add the subview with frame later provide required functionality