From a5a4ae336abc34e1829a4f4876874a85c312b8e0 Mon Sep 17 00:00:00 2001 From: Victor Tran Date: Thu, 4 Feb 2021 21:32:24 +1100 Subject: [PATCH] Better window handling on macOS --- lib/tcsdtools.cpp | 20 ++++++++++++-------- lib/tcsdtools.h | 2 ++ lib/tcsdtools/csdsizegrip.cpp | 23 +++++++++++------------ lib/tcsdtools/tcsdtools-objc.mm | 16 +++++++++++++++- 4 files changed, 40 insertions(+), 21 deletions(-) diff --git a/lib/tcsdtools.cpp b/lib/tcsdtools.cpp index 7529586..5f40e1a 100644 --- a/lib/tcsdtools.cpp +++ b/lib/tcsdtools.cpp @@ -92,11 +92,7 @@ bool tCsdGlobal::csdsEnabled() { } bool tCsdGlobal::recommendCsdForPlatform() { -#ifdef Q_OS_MAC - return false; -#else return true; -#endif } tCsdTools::tCsdTools(QObject* parent) : QObject(parent) { @@ -188,6 +184,12 @@ void tCsdTools::installResizeAction(QWidget* widget) { connect(widget, &QWidget::destroyed, this, QOverload::of(&tCsdTools::removeResizeAction)); widget->installEventFilter(this); + ResizeWidget* resize = new ResizeWidget(); + resize->widget = widget; + +#ifdef Q_OS_MAC + macInstallResizeAction(widget); +#else if (tCsdGlobal::csdsEnabled()) { int border = CsdSizeGrip::borderWidth(); widget->setContentsMargins(border, border, border, border); @@ -196,15 +198,13 @@ void tCsdTools::installResizeAction(QWidget* widget) { widget->setAttribute(Qt::WA_TranslucentBackground); } - ResizeWidget* resize = new ResizeWidget(); - resize->widget = widget; - for (int i = 0; i < 4; i++) { CsdSizeGrip* grip = new CsdSizeGrip(i, widget); resize->sizeGrips[i] = grip; } d->resizeWidgets.append(resize); +#endif } void tCsdTools::removeResizeAction(QWidget* widget) { @@ -214,9 +214,13 @@ void tCsdTools::removeResizeAction(QWidget* widget) { widget->removeEventFilter(this); disconnect(widget, &QWidget::destroyed, this, QOverload::of(&tCsdTools::removeResizeAction)); +#ifdef Q_OS_MAC + macRemoveResizeAction(widget); +#else for (int i = 0; i < 4; i++) { rw->sizeGrips[i]->deleteLater(); } +#endif d->resizeWidgets.removeOne(rw); delete rw; @@ -345,7 +349,7 @@ bool tCsdTools::eventFilter(QObject* watched, QEvent* event) { //Stop moving the window widget->setProperty("tcsdtools_action", "none"); } - } else if (event->type() == QEvent::Resize) { + } else if (event->type() == QEvent::Resize || event->type() == QEvent::WindowStateChange) { QWidget* widget = qobject_cast(watched); Q_ASSERT(widget); diff --git a/lib/tcsdtools.h b/lib/tcsdtools.h index ed61852..745df8b 100644 --- a/lib/tcsdtools.h +++ b/lib/tcsdtools.h @@ -88,6 +88,8 @@ class THELIBSSHARED_EXPORT tCsdTools : public QObject { #ifdef Q_OS_MAC void macHandleDrag(QPoint screenPos, QWidget* dragWindow); + void macInstallResizeAction(QWidget* widget); + void macRemoveResizeAction(QWidget* widget); #endif bool eventFilter(QObject* watched, QEvent* event) override; diff --git a/lib/tcsdtools/csdsizegrip.cpp b/lib/tcsdtools/csdsizegrip.cpp index 6a44938..a660d31 100644 --- a/lib/tcsdtools/csdsizegrip.cpp +++ b/lib/tcsdtools/csdsizegrip.cpp @@ -26,12 +26,11 @@ #include "tcsdtools.h" #ifdef HAVE_X11 -#include -#include + #include + #include #endif -CsdSizeGrip::CsdSizeGrip(int side, QWidget *parent) : QWidget(parent) -{ +CsdSizeGrip::CsdSizeGrip(int side, QWidget* parent) : QWidget(parent) { connect(tCsdGlobal::instance(), &tCsdGlobal::csdsEnabledChanged, this, &CsdSizeGrip::csdsEnabledChanged); this->side = side; this->parentWidget = parent; @@ -68,14 +67,14 @@ void CsdSizeGrip::resizeGrip() { } } -bool CsdSizeGrip::eventFilter(QObject *watched, QEvent *event) { +bool CsdSizeGrip::eventFilter(QObject* watched, QEvent* event) { if (event->type() == QEvent::Resize || event->type() == QEvent::WindowStateChange) { resizeGrip(); } return false; } -void CsdSizeGrip::paintEvent(QPaintEvent *event) { +void CsdSizeGrip::paintEvent(QPaintEvent* event) { QPainter painter(this); painter.setBrush(Qt::transparent); painter.setBrush(this->palette().color(QPalette::WindowText)); @@ -94,10 +93,10 @@ void CsdSizeGrip::paintEvent(QPaintEvent *event) { } } -void CsdSizeGrip::mousePressEvent(QMouseEvent *e) { +void CsdSizeGrip::mousePressEvent(QMouseEvent* e) { if (e->button() == Qt::LeftButton) { //Resize this window - #ifdef HAVE_X11 +#ifdef HAVE_X11 if (QX11Info::isPlatformX11()) { XEvent event; event.xclient.type = ClientMessage; @@ -141,15 +140,15 @@ void CsdSizeGrip::mousePressEvent(QMouseEvent *e) { XSendEvent(QX11Info::display(), QX11Info::appRootWindow(), False, SubstructureRedirectMask | SubstructureNotifyMask, &event); return; } - #endif +#endif startPoint = e->pos(); moving = true; - qWarning() << "No method to initiate a window move."; + qWarning() << "No method to initiate a window resize."; } } -void CsdSizeGrip::mouseMoveEvent(QMouseEvent *e) { +void CsdSizeGrip::mouseMoveEvent(QMouseEvent* e) { if (moving) { QRect geometry = parentWidget->window()->geometry(); switch (hitTest(startPoint)) { @@ -202,7 +201,7 @@ void CsdSizeGrip::mouseMoveEvent(QMouseEvent *e) { } } -void CsdSizeGrip::mouseReleaseEvent(QMouseEvent *e) { +void CsdSizeGrip::mouseReleaseEvent(QMouseEvent* e) { moving = false; } diff --git a/lib/tcsdtools/tcsdtools-objc.mm b/lib/tcsdtools/tcsdtools-objc.mm index 84952a2..febcb8b 100644 --- a/lib/tcsdtools/tcsdtools-objc.mm +++ b/lib/tcsdtools/tcsdtools-objc.mm @@ -7,7 +7,21 @@ void tCsdTools::macHandleDrag(QPoint screenPos, QWidget* dragWindow) { CGEventRef cgEvent = CGEventCreateMouseEvent(nullptr, kCGEventLeftMouseDown, screenPos.toCGPoint(), kCGMouseButtonLeft); NSEvent* nsEvent = [NSEvent eventWithCGEvent:cgEvent]; - NSView *view = reinterpret_cast(dragWindow->winId()); + NSView* view = reinterpret_cast(dragWindow->winId()); [view.window performWindowDragWithEvent:nsEvent]; CFRelease(cgEvent); } + +void tCsdTools::macInstallResizeAction(QWidget* widget) { + NSView* view = reinterpret_cast(widget->winId()); + + NSWindowStyleMask styleMask = NSWindowStyleMaskFullSizeContentView | NSWindowStyleMaskUnifiedTitleAndToolbar | NSWindowStyleMaskResizable | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable; + [view.window setStyleMask:styleMask]; +} + +void tCsdTools::macRemoveResizeAction(QWidget* widget) { + NSView* view = reinterpret_cast(widget->winId()); + + NSWindowStyleMask styleMask = NSWindowStyleMaskResizable | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable; + [view.window setStyleMask:styleMask]; +}