How to: Unified OS X Title Bars?
-
So i was checking out the QtMac and QtMacExtras documentation pages and kept wondering how Spotify archived this kind of unified title bar on osx: Screenshot
The classic QMainWindow::setUnifiedTitleAndToolBarOnMac() method does not seem to do the trick.
So is there any way, to put widgets in the titlebar like the example screenshot shows;
aligned to the middle of the titlebar, along with the window controls?
(for another example, open chrome on os x - same fancy alignment) -
Hey, thank you very much for that hint!
I've ever touched Cocoa and never went beyond Qt's capabilities on OSX before, so this was a total challenge for me.
Yet, this is how far i came:
void Test::createFancyMacWindow() { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSWindow *window = [ [NSWindow alloc] initWithContentRect: NSMakeRect(200, 200, 600, 400) styleMask: NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask |NSTexturedBackgroundWindowMask backing: NSBackingStoreBuffered defer: NO ]; // store pointer nsWindow = &window; // move toolbar where the titlebar used to be [window setTitleVisibility: NSWindowTitleHidden]; // Adjust Cocoa layouts NSView *contentView = [window contentView]; [contentView setAutoresizesSubviews:YES]; QMacNativeWidget *nativeWidget = new QMacNativeWidget(contentView); //nativeWidget->move(0, 0); nativeWidget->setPalette(QPalette(Qt::red)); nativeWidget->setAutoFillBackground(true); NSView *nativeWidgetView = nativeWidget->nativeView(); [contentView addSubview:nativeWidgetView positioned:NSWindowAbove relativeTo:nil]; [nativeWidgetView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; [nativeWidgetView setAutoresizesSubviews:YES]; nativeWidget->show(); // Show the window. [window makeKeyAndOrderFront:window]; [pool release]; QMacToolBar *toolBar = new QMacToolBar(); toolBar->addItem(QIcon(), QStringLiteral("Helloooo")); [window setToolbar: toolBar->nativeToolbar()]; }
There are only 2 issues remaining:
- The documentation of QMacToolBar states that
"The toolbar must be attached to a QWindow using the attachToWindow() method in order to be visible. The toolbar is attached to the native NSWindow and is displayed above the QWindow. QMacToolBar visibility follows window visibility."
Yet i've found no clue on how to cast NSWindow to QWindow. Using QWindow's static fromWinId Method produces a runtime crash as QWindow asks the Objective-C for types that do not exist.
So, as stated in the code, i've tried to add the toolbar via Objective-C++, but this renders the added ToolbarItem nearly invisible (no Text) and when clicking where the item should be located the area around it gets filled with random noise and this message gets printed:
filter:2:47: error: excess elements in vector initializer return img.a * mix(c0, c1, dot(img.rgb, vec3(0,000000e+00, 0,000000e+00, 0,000000e+00))); ^ ~~~~~~~~~~ filter:1:6: error: non-void function should return a value vec4 _falseColor(vec4 img, vec4 c0, vec4 c1) { ^
- The documentation of QMacNativeWidget is very misleading, as the Objective-C++ code snippet produces a very "unwanted" situation of 2 windows where one is "empty" (i fixed that in the code above).
@concept
It basically replaces the titlebar with the toolbar, as far as i understood. -
Update: I managed to get a QWindow involved into the code, yet the toolbar is messed up.
ScreenshotNew code:
void Test::createFancyMacWindow() { QWindow* w = new QWindow(); NSView* mainWindowNSView = (NSView*) w->winId(); NSWindow* window = [mainWindowNSView window]; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // move toolbar where the titlebar used to be [window setTitleVisibility: NSWindowTitleHidden]; // Adjust Cocoa layouts NSView *contentView = [window contentView]; [contentView setAutoresizesSubviews:YES]; QMacNativeWidget *nativeWidget = new QMacNativeWidget(contentView); //nativeWidget->move(0, 0); nativeWidget->setPalette(QPalette(Qt::red)); nativeWidget->setAutoFillBackground(true); NSView *nativeWidgetView = nativeWidget->nativeView(); [contentView addSubview:nativeWidgetView positioned:NSWindowAbove relativeTo:nil]; [nativeWidgetView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; [nativeWidgetView setAutoresizesSubviews:YES]; nativeWidget->show(); // Show the window. [window makeKeyAndOrderFront:window]; [pool release]; QMacToolBar *toolBar = new QMacToolBar(); toolBar->addItem(QIcon(), QStringLiteral("Helloooo")); toolBar->attachToWindow(w); [window setToolbar: toolBar->nativeToolbar()]; w->show(); }