diff --git a/examples/mainwindow/TitleBar.ui b/examples/mainwindow/TitleBar.ui
index 29686ec..25a5b01 100644
--- a/examples/mainwindow/TitleBar.ui
+++ b/examples/mainwindow/TitleBar.ui
@@ -126,7 +126,7 @@
- Segoe UI
+ Arial
9
@@ -283,6 +283,8 @@
+
+
diff --git a/examples/mainwindow/mainwindow.cpp b/examples/mainwindow/mainwindow.cpp
index ea4461f..47a0e7e 100644
--- a/examples/mainwindow/mainwindow.cpp
+++ b/examples/mainwindow/mainwindow.cpp
@@ -107,6 +107,7 @@ void MainWindow::showEvent(QShowEvent *event)
titleBarWidget->maximizeButton->hide();
titleBarWidget->closeButton->hide();
Utilities::showMacWindowButton(windowHandle());
+ Utilities::setStandardWindowButtonsOffset(win, QPoint(0, -5));
#endif // Q_OS_MAC
inited = true;
}
@@ -172,4 +173,4 @@ void MainWindow::paintEvent(QPaintEvent *event)
painter.restore();
}
}
-#endif // Q_OS_MAC
\ No newline at end of file
+#endif // Q_OS_MAC
diff --git a/examples/minimal/flwindow.cpp b/examples/minimal/flwindow.cpp
index a32beb3..c5d6a95 100644
--- a/examples/minimal/flwindow.cpp
+++ b/examples/minimal/flwindow.cpp
@@ -37,6 +37,7 @@ void FLWindow::initFramelessWindow()
m_maximizeButton->hide();
m_closeButton->hide();
Utilities::showMacWindowButton(windowHandle());
+ Utilities::setStandardWindowButtonsOffset(windowHandle(), QPoint(10, 10));
#endif
}
@@ -64,6 +65,18 @@ bool FLWindow::nativeEvent(const QByteArray &eventType, void *message, long *res
}
#endif // Q_OS_WIN
+#ifdef Q_OS_MAC
+void FLWindow::resizeEvent(QResizeEvent *event)
+{
+ auto win = windowHandle();
+ if (win) {
+ Utilities::setStandardWindowButtonsOffset(win, QPoint(10, 10));
+ }
+
+ QWidget::resizeEvent(event);
+}
+#endif // Q_OS_MAC
+
void FLWindow::setupUi()
{
resize(800, 600);
diff --git a/examples/minimal/flwindow.h b/examples/minimal/flwindow.h
index 5d1bb19..b599d71 100644
--- a/examples/minimal/flwindow.h
+++ b/examples/minimal/flwindow.h
@@ -18,6 +18,10 @@ protected:
bool nativeEvent(const QByteArray &eventType, void *message, long *result) override;
#endif // Q_OS_WIN
+#ifdef Q_OS_MAC
+ void resizeEvent(QResizeEvent *event) override;
+#endif // Q_OS_MAC
+
private:
void initFramelessWindow();
void setupUi();
@@ -28,4 +32,4 @@ private:
QPushButton *m_minimizeButton = nullptr;
QPushButton *m_maximizeButton = nullptr;
QPushButton *m_closeButton = nullptr;
-};
\ No newline at end of file
+};
diff --git a/src/core/framelesshelper.cpp b/src/core/framelesshelper.cpp
index 07355d5..59153dd 100644
--- a/src/core/framelesshelper.cpp
+++ b/src/core/framelesshelper.cpp
@@ -496,7 +496,6 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
resizeWindow(re->size());
break;
}
-
case QEvent::NonClientAreaMouseMove:
case QEvent::MouseMove:
{
diff --git a/src/core/utilities.h b/src/core/utilities.h
index 05b264e..d131665 100644
--- a/src/core/utilities.h
+++ b/src/core/utilities.h
@@ -76,6 +76,11 @@ FRAMELESSHELPER_API bool unsetMacWindowFrameless(QWindow* w);
FRAMELESSHELPER_API bool startMacDrag(QWindow* w, const QPoint& pos);
FRAMELESSHELPER_API Qt::MouseButtons getMacMouseButtons();
FRAMELESSHELPER_API bool showMacWindowButton(QWindow *w);
+FRAMELESSHELPER_API bool isMacKeyWindow(QWindow *w);
+FRAMELESSHELPER_API bool isMacMainWindow(QWindow *w);
+FRAMELESSHELPER_API bool makeMacKeyWindow(QWindow *w);
+FRAMELESSHELPER_API bool makeMacMainWindow(QWindow *w);
+FRAMELESSHELPER_API bool setStandardWindowButtonsOffset(QWindow *w, const QPoint &offset);
#endif // Q_OS_MAC
}
diff --git a/src/core/utilities_macos.mm b/src/core/utilities_macos.mm
index 6141aad..12e5ea3 100644
--- a/src/core/utilities_macos.mm
+++ b/src/core/utilities_macos.mm
@@ -30,6 +30,7 @@
#include
#include
+#include
FRAMELESSHELPER_BEGIN_NAMESPACE
@@ -191,6 +192,19 @@ static void __sendEvent(id obj, SEL sel, NSEvent* event)
QGuiApplication::processEvents();
}
+typedef BOOL (*isFlippedType)(id, SEL);
+static isFlippedType gOrigIsFlipped = nullptr;
+static BOOL __isFlipped(id obj, SEL sel)
+{
+ if (!gFlsWindows.contains(reinterpret_cast(obj)))
+ return true;
+
+ if (gOrigIsFlipped != nullptr)
+ return gOrigIsFlipped(obj, sel);
+
+ return false;
+}
+
/*!
Replace origin method \a origSEL of class \a cls with new one \a newIMP ,
then return old method as function pointer.
@@ -227,6 +241,8 @@ static void overrideNSWindowMethods(NSWindow* window)
cls, @selector(canBecomeMainWindow), (IMP) __canBecomeMainWindow);
gOrigSendEvent = (sendEventType) replaceMethod(
cls, @selector(sendEvent:), (IMP) __sendEvent);
+ gOrigIsFlipped = (isFlippedType) replaceMethod(
+ cls, @selector (isFlipped), (IMP) __isFlipped);
gNSWindowOverrode = true;
}
@@ -255,6 +271,9 @@ static void restoreNSWindowMethods(NSWindow* window)
restoreMethod(cls, @selector(sendEvent:), (IMP) gOrigSendEvent);
gOrigSendEvent = nullptr;
+ restoreMethod(cls, @selector(isFlipped), (IMP) gOrigIsFlipped);
+ gOrigIsFlipped = nullptr;
+
gNSWindowOverrode = false;
}
@@ -265,9 +284,17 @@ static QHash gQWindowToNSWindow;
static NSWindow* getNSWindow(QWindow* w)
{
NSView* view = reinterpret_cast(w->winId());
- if (view == nullptr)
+ if (view == nullptr) {
+ qWarning() << "Unable to get NSView.";
return nullptr;
- return [view window];
+ }
+ NSWindow* nswindow = [view window];
+ if (nswindow == nullptr) {
+ qWarning() << "Unable to get NSWindow.";
+ return nullptr;
+ }
+
+ return nswindow;
}
bool setMacWindowHook(QWindow* w)
@@ -350,10 +377,7 @@ bool unsetMacWindowFrameless(QWindow* w)
bool showMacWindowButton(QWindow *w)
{
- NSView* view = reinterpret_cast(w->winId());
- if (view == nullptr)
- return false;
- NSWindow* nswindow = [view window];
+ NSWindow* nswindow = getNSWindow(w);
if (nswindow == nullptr)
return false;
@@ -367,10 +391,7 @@ bool showMacWindowButton(QWindow *w)
bool startMacDrag(QWindow* w, const QPoint& pos)
{
- NSView* view = reinterpret_cast(w->winId());
- if (view == nullptr)
- return false;
- NSWindow* nswindow = [view window];
+ NSWindow* nswindow = getNSWindow(w);
if (nswindow == nullptr)
return false;
@@ -387,6 +408,85 @@ Qt::MouseButtons getMacMouseButtons()
return static_cast((uint)(NSEvent.pressedMouseButtons & Qt::MouseButtonMask));
}
+bool isMacKeyWindow(QWindow *w)
+{
+ NSWindow* nswindow = getNSWindow(w);
+ if (nswindow == nullptr) {
+ qWarning() << "Unable to get NSView.";
+ return false;
+ }
+
+ return [nswindow isKeyWindow];
+}
+
+bool isMacMainWindow(QWindow *w)
+{
+ NSWindow* nswindow = getNSWindow(w);
+ if (nswindow == nullptr)
+ return false;
+
+ return [nswindow isMainWindow];
+}
+
+bool makeMacKeyWindow(QWindow *w)
+{
+ NSWindow* nswindow = getNSWindow(w);
+ if (nswindow == nullptr)
+ return false;
+
+ [nswindow makeKeyWindow];
+ return true;
+}
+
+bool makeMacMainWindow(QWindow *w)
+{
+ NSWindow* nswindow = getNSWindow(w);
+ if (nswindow == nullptr)
+ return false;
+
+ [nswindow makeMainWindow];
+ return true;
+}
+
+static void setButtonLocation(NSButton * btn, const QPoint &offset, NSView *contentview)
+{
+ if (btn.superview != contentview) {
+ [btn.superview willRemoveSubview:btn];
+ [btn removeFromSuperview];
+ [btn viewWillMoveToSuperview:contentview];
+ [contentview addSubview:btn];
+ [btn viewDidMoveToSuperview];
+ }
+
+ auto frame = btn.frame;
+ btn.frame = NSMakeRect(
+ frame.origin.x + offset.x(),
+ frame.origin.y + offset.y(),
+ frame.size.width, frame.size.height);
+}
+
+/*! The origin of AppKit coordinate system is bottom-left. */
+bool setStandardWindowButtonsOffset(QWindow *w, const QPoint &offset)
+{
+ NSWindow* nswindow = getNSWindow(w);
+ if (nswindow == nullptr)
+ return false;
+
+ NSView* contentview = nswindow.contentView;
+ if (contentview == nullptr)
+ return false;
+
+ auto close = [nswindow standardWindowButton:NSWindowCloseButton];
+ auto min = [nswindow standardWindowButton:NSWindowMiniaturizeButton];
+ auto zoom = [nswindow standardWindowButton:NSWindowZoomButton];
+
+ setButtonLocation(close, offset, contentview);
+ setButtonLocation(min, offset, contentview);
+ setButtonLocation(zoom, offset, contentview);
+
+ return true;
+}
+
} // namespace Utilities
FRAMELESSHELPER_END_NAMESPACE