Unable to get transparent title bar in macOS since Qt 6.4
-
Hi,
You might want to add the macOS version as well.
-
@SGaist Hi,
I just uploaded an example using QMainWindow (based on mainwindow example) and QWebEngineView as CentralWidget https://we.tl/t-6Nr9CuOpxu in the order that my actual code use that.
If I execute, the title bar is not transparent
But if I move
hideWindowTitleBar(*this);
aftersetCentralWidget
It works as expected again, Im trying to understand what Im doing in my code after setting
setCentralWidget
because the trick doesnt behave the same that in QtCreator evenhideWindowTitleBar(*this);
is the last thing I do before showing the window and modifying the contentI will post here some findings, thanks for your time @SGaist.
-
Reducing the code to something minimal, it is working setting the central widget either before or after the call to
hideWindowTitleBar
.
main.cpp
#include "mainwindow.h" #include <QApplication> int main(int argc, char **argv) { QApplication app(argc, argv); MainWindow mainWin; mainWin.resize(800, 600); mainWin.show(); return app.exec(); }
mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); }; #endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h" #include "mainwindowmac.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { setWindowTitle("Qt Transparent"); QWidget *centralWidget = new QWidget(); centralWidget->setStyleSheet("background: yellow"); hideWindowTitleBar(this); setCentralWidget(centralWidget); }
mainwindowmac.h
#ifndef MAINWINDOWMAC_H #define MAINWINDOWMAC_H class QMainWindow; void hideWindowTitleBar(QMainWindow *window); #endif // MAINWINDOWMAC_H
mainwindowmac.mm
#include "mainwindowmac.h" #include <Cocoa/Cocoa.h> #include <QMainWindow> void hideWindowTitleBar(QMainWindow *window) { window->setUnifiedTitleAndToolBarOnMac(true); NSView* nativeView = reinterpret_cast<NSView*>(window->winId()); NSWindow* nativeWindow = [nativeView window]; [nativeWindow setStyleMask:[nativeWindow styleMask] | NSWindowStyleMaskFullSizeContentView | NSWindowTitleHidden]; [nativeWindow setTitlebarAppearsTransparent:YES]; [nativeWindow center]; }
-
#import "mac_manager.h" #import <Cocoa/Cocoa.h> // Declare a custom NSView subclass @interface DraggableTitleView : NSView @end @implementation DraggableTitleView // Handle mouse click events - (void)mouseDown:(NSEvent *)event { // double-click to zoom if ([event clickCount] == 2) { [self.window zoom:nil]; } else { // drag Window [self.window performWindowDragWithEvent:event]; } } @end void MacManager::removeTitleBarFromWindow() { // The position of the native buttons CGPoint nativeButtonPoint = CGPointMake(100, 7); // The height of the custom title bar, Dragging the title bar will move the window int titleBarViewHeight = 52; QWindowList windows = QGuiApplication::allWindows(); auto item = windows.first(); auto winId = item->winId(); auto *nativeView = reinterpret_cast<NSView *>(winId); NSWindow *nativeWindow = [nativeView window]; // Hide standard title bar [nativeWindow setTitlebarAppearsTransparent:YES]; [nativeWindow setTitleVisibility:NSWindowTitleHidden]; [nativeWindow setStyleMask:[nativeWindow styleMask] | NSWindowStyleMaskFullSizeContentView]; // Gets the dimensions of the window contents view NSRect contentViewBounds = nativeWindow.contentView.bounds; // Create a custom Title Bar view DraggableTitleView *titleBarView = [[DraggableTitleView alloc] initWithFrame:NSMakeRect(0, 0, contentViewBounds.size.width, titleBarViewHeight)]; titleBarView.autoresizingMask = NSViewWidthSizable; titleBarView.wantsLayer = YES; titleBarView.layer.backgroundColor = [[NSColor clearColor] CGColor]; // Add a custom title bar view to the window's contents view [nativeWindow.contentView addSubview:titleBarView]; // Adjust the native button positions to fit in the new title bar NSButton *closeButton = [nativeWindow standardWindowButton:NSWindowCloseButton]; NSButton *minimizeButton = [nativeWindow standardWindowButton:NSWindowMiniaturizeButton]; NSButton *zoomButton = [nativeWindow standardWindowButton:NSWindowZoomButton]; closeButton.translatesAutoresizingMaskIntoConstraints = NO; minimizeButton.translatesAutoresizingMaskIntoConstraints = NO; zoomButton.translatesAutoresizingMaskIntoConstraints = NO; NSLayoutConstraint *closeButtonLeftContain = [NSLayoutConstraint constraintWithItem:closeButton attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:closeButton.superview attribute:NSLayoutAttributeLeft multiplier:1.0 constant:nativeButtonPoint.x]; NSLayoutConstraint *closeButtonTopContain = [NSLayoutConstraint constraintWithItem:closeButton attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:closeButton.superview attribute:NSLayoutAttributeTop multiplier:1.0 constant:nativeButtonPoint.y]; closeButtonLeftContain.active = YES; closeButtonTopContain.active = YES; NSLayoutConstraint *minimizeButtonLeftContain = [NSLayoutConstraint constraintWithItem:minimizeButton attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:minimizeButton.superview attribute:NSLayoutAttributeLeft multiplier:1.0 constant:20 + nativeButtonPoint.x]; NSLayoutConstraint *minimizeButtonTopContain = [NSLayoutConstraint constraintWithItem:minimizeButton attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:minimizeButton.superview attribute:NSLayoutAttributeTop multiplier:1.0 constant:nativeButtonPoint.y]; minimizeButtonLeftContain.active = YES; minimizeButtonTopContain.active = YES; NSLayoutConstraint *zoomButtonLeftContain = [NSLayoutConstraint constraintWithItem:zoomButton attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:zoomButton.superview attribute:NSLayoutAttributeLeft multiplier:1.0 constant:40 + nativeButtonPoint.x]; NSLayoutConstraint *zoomButtonTopContain = [NSLayoutConstraint constraintWithItem:zoomButton attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:zoomButton.superview attribute:NSLayoutAttributeTop multiplier:1.0 constant:nativeButtonPoint.y]; zoomButtonLeftContain.active = YES; zoomButtonTopContain.active = YES; }
Help more people by implementing a fully customizable title bar here, supporting movable buttons, and retaining double-click to maximize and long-press drag events.
Have fun !
-
After testing it with Qt6.5.3 I found that it does not work with Qt6.8.2.
https://bugreports.qt.io/browse/QTBUG-134797