init implementation of MacOS window btn location

This commit is contained in:
Altair Wei 2021-10-07 19:29:45 +08:00
parent 50dafa0c5e
commit c8cfefb3ca
7 changed files with 138 additions and 14 deletions

View File

@ -126,7 +126,7 @@
</property>
<property name="font">
<font>
<family>Segoe UI</family>
<family>Arial</family>
<pointsize>9</pointsize>
</font>
</property>
@ -283,6 +283,8 @@
<layoutdefault spacing="6" margin="11"/>
<resources>
<include location="../images.qrc"/>
<include location="../images.qrc"/>
<include location="../images.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -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
#endif // Q_OS_MAC

View File

@ -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);

View File

@ -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;
};
};

View File

@ -496,7 +496,6 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
resizeWindow(re->size());
break;
}
case QEvent::NonClientAreaMouseMove:
case QEvent::MouseMove:
{

View File

@ -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
}

View File

@ -30,6 +30,7 @@
#include <QtGui/qguiapplication.h>
#include <QtCore/qlist.h>
#include <QtCore/qdebug.h>
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<NSWindow *>(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<QWindow*, NSWindow*> gQWindowToNSWindow;
static NSWindow* getNSWindow(QWindow* w)
{
NSView* view = reinterpret_cast<NSView *>(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<NSView *>(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<NSView *>(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<Qt::MouseButtons>((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