Skip to content

Instantly share code, notes, and snippets.

@jbltx
Last active July 26, 2023 08:28
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jbltx/1ebabb73d3974ec127578c7f9ebc3819 to your computer and use it in GitHub Desktop.
Save jbltx/1ebabb73d3974ec127578c7f9ebc3819 to your computer and use it in GitHub Desktop.
Custom OSX TitleBar Size with QML
#ifndef MACWINDOW_H
#define MACWINDOW_H
#include <QObject>
class MacWindow : public QObject
{
Q_OBJECT
public:
explicit MacWindow(QObject *parent = nullptr) : QObject(parent) {}
virtual ~MacWindow() = default;
Q_INVOKABLE void handleDestroy(QObject* appWindow);
Q_INVOKABLE void handleInit(QObject* appWindow);
private:
};
#endif // MACWINDOW_H
#include "MacWindow.h"
#include <QWindow>
#import <Cocoa/Cocoa.h>
#import <Foundation/Foundation.h>
#define TITLEBAR_HEIGHT 40
static void moveTrafficLights(const NSWindow* window)
{
// get title bar buttons
NSButton* minBtn = [window standardWindowButton:NSWindowMiniaturizeButton];
NSButton* maxBtn = [window standardWindowButton:NSWindowZoomButton];
NSButton* closeBtn = [window standardWindowButton:NSWindowCloseButton];
// move buttons
int q = (TITLEBAR_HEIGHT / 4);
[minBtn setFrameOrigin:NSPoint{minBtn.frame.origin.x+q, minBtn.frame.origin.y - q}];
[maxBtn setFrameOrigin:NSPoint{maxBtn.frame.origin.x+q, maxBtn.frame.origin.y - q}];
[closeBtn setFrameOrigin:NSPoint{closeBtn.frame.origin.x+q, closeBtn.frame.origin.y - q}];
}
static void windowDidResize(CFNotificationCenterRef /*center*/, void* /*observer*/, CFStringRef /*name*/, const void* object, CFDictionaryRef /*userInfo*/)
{
NSWindow* window = reinterpret_cast<NSWindow*>(object);
moveTrafficLights(window);
}
void MacWindow::handleDestroy(QObject* /*appWindow*/)
{
CFNotificationCenterRemoveEveryObserver(CFNotificationCenterGetLocalCenter(), this);
}
void MacWindow::handleInit(QObject* appWindow)
{
QWindow* win = qobject_cast<QWindow*>(appWindow);
NSView* view = reinterpret_cast<NSView*>(win->winId());
NSWindow* window = [view window];
// imersive title bar
[window setStyleMask:[window styleMask] | NSFullSizeContentViewWindowMask];
[window setTitlebarAppearsTransparent:YES];
[window setTitleVisibility:NSWindowTitleHidden];
// resize title bar
NSView* dummyView = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 20, TITLEBAR_HEIGHT-20)];
NSTitlebarAccessoryViewController* dummyCtrl = [NSTitlebarAccessoryViewController new];
dummyCtrl.view = dummyView;
dummyCtrl.fullScreenMinHeight = TITLEBAR_HEIGHT;
[window addTitlebarAccessoryViewController:dummyCtrl];
// need to bind resize signal to move buttons
CFNotificationCenterAddObserver(
CFNotificationCenterGetLocalCenter(),
this,
&windowDidResize,
CFSTR("NSWindowDidResizeNotification"),
window,
CFNotificationSuspensionBehaviorDeliverImmediately);
moveTrafficLights(window);
}
[...]
QQmlApplicationEngine engine;
#if __APPLE__
MacWindow windowEx;
#endif
engine.rootContext()->setContextProperty("WindowEx", &windowEx);
[...]
import QtQuick 2.12
import QtQuick.Window 2.12
ApplicationWindow {
[...]
onVisibilityChanged: {
if (visible)
WindowEx.handleInit(this)
else
WindowEx.handleDestroy(this)
}
}
@Pinton
Copy link

Pinton commented Jan 19, 2022

Wow, so great!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment