diff options
-rw-r--r-- | src/gui/kernel/qplatformcursor.cpp | 8 | ||||
-rw-r--r-- | src/gui/kernel/qplatformcursor.h | 1 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoacursor.h | 3 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoacursor.mm | 25 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowscursor.cpp | 25 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowscursor.h | 2 | ||||
-rw-r--r-- | src/widgets/kernel/qtooltip.cpp | 43 |
7 files changed, 92 insertions, 15 deletions
diff --git a/src/gui/kernel/qplatformcursor.cpp b/src/gui/kernel/qplatformcursor.cpp index 49eff2ad23..aabf28a727 100644 --- a/src/gui/kernel/qplatformcursor.cpp +++ b/src/gui/kernel/qplatformcursor.cpp @@ -131,6 +131,14 @@ void QPlatformCursor::setPos(const QPoint &pos) QWindowSystemInterface::handleMouseEvent(0, pos, pos, Qt::NoButton, Qt::NoButton, QEvent::MouseMove); } +/*! + Returns the size of the cursor, in native pixels. +*/ +QSize QPlatformCursor::size() const +{ + return QSize(16, 16); +} + // End of display and pointer event handling code // Beginning of built-in cursor graphics // from src/gui/embedded/QGraphicsSystemCursorImage_qws.cpp diff --git a/src/gui/kernel/qplatformcursor.h b/src/gui/kernel/qplatformcursor.h index f36a73c861..f3871d8780 100644 --- a/src/gui/kernel/qplatformcursor.h +++ b/src/gui/kernel/qplatformcursor.h @@ -96,6 +96,7 @@ public: #endif // QT_NO_CURSOR virtual QPoint pos() const; virtual void setPos(const QPoint &pos); + virtual QSize size() const; static Capabilities capabilities() { return m_capabilities; } static void setCapabilities(Capabilities c) { m_capabilities = c; } diff --git a/src/plugins/platforms/cocoa/qcocoacursor.h b/src/plugins/platforms/cocoa/qcocoacursor.h index 58b9ef2151..5b008eff35 100644 --- a/src/plugins/platforms/cocoa/qcocoacursor.h +++ b/src/plugins/platforms/cocoa/qcocoacursor.h @@ -56,6 +56,9 @@ public: void changeCursor(QCursor *cursor, QWindow *window) override; QPoint pos() const override; void setPos(const QPoint &position) override; + + QSize size() const override; + private: QHash<Qt::CursorShape, NSCursor *> m_cursors; NSCursor *convertCursor(QCursor *cursor); diff --git a/src/plugins/platforms/cocoa/qcocoacursor.mm b/src/plugins/platforms/cocoa/qcocoacursor.mm index 87a57c78c8..e0d623fc4c 100644 --- a/src/plugins/platforms/cocoa/qcocoacursor.mm +++ b/src/plugins/platforms/cocoa/qcocoacursor.mm @@ -85,6 +85,31 @@ void QCocoaCursor::setPos(const QPoint &position) CFRelease(e); } + +QSize QCocoaCursor::size() const +{ + NSCursor *cocoaCursor = NSCursor.currentSystemCursor; + if (!cocoaCursor) + return QPlatformCursor::size(); + NSImage *cursorImage = cocoaCursor.image; + if (!cursorImage) + return QPlatformCursor::size(); + + QSizeF size = QSizeF::fromCGSize(cursorImage.size); + NSUserDefaults *defaults = NSUserDefaults.standardUserDefaults; + NSDictionary *accessSettings = [defaults persistentDomainForName:@"com.apple.universalaccess"]; + if (accessSettings == nil) + return size.toSize(); + + float sizeScale = [accessSettings[@"mouseDriverCursorSize"] floatValue]; + if (sizeScale > 0) { + size.rwidth() *= sizeScale; + size.rheight() *= sizeScale; + } + + return size.toSize(); +} + NSCursor *QCocoaCursor::convertCursor(QCursor *cursor) { if (!cursor) diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp index 17e8cffb76..59457f1720 100644 --- a/src/plugins/platforms/windows/qwindowscursor.cpp +++ b/src/plugins/platforms/windows/qwindowscursor.cpp @@ -50,6 +50,7 @@ #include <QtGui/qscreen.h> #include <QtGui/private/qguiapplication_p.h> // getPixmapCursor() #include <QtGui/private/qhighdpiscaling_p.h> +#include <QtCore/private/qwinregistry_p.h> #include <QtCore/qdebug.h> #include <QtCore/qscopedpointer.h> @@ -686,6 +687,30 @@ void QWindowsCursor::setPos(const QPoint &pos) SetCursorPos(pos.x() , pos.y()); } +/* + The standard size is 32x32, even though the cursor is actually just + 16 pixels large. If a large cursor is set in the accessibility settings, + then the cursor increases with 8 pixels for each step. +*/ +QSize QWindowsCursor::size() const +{ + const QPair<DWORD,bool> cursorSizeSetting = + QWinRegistryKey(HKEY_CURRENT_USER, LR"(Control Panel\Cursors)") + .dwordValue(L"CursorBaseSize"); + const int baseSize = screenCursorSize(m_screen).width() / 2; + if (!cursorSizeSetting.second) + return QSize(baseSize / 2, baseSize / 2); + + // The registry values are dpi-independent, so we need to scale the result. + int cursorSizeValue = cursorSizeSetting.first * m_screen->logicalDpi().first + / m_screen->logicalBaseDpi().first; + + // map from registry value 32-256 to 0-14, and from there to pixels + cursorSizeValue = (cursorSizeValue - 2 * baseSize) / baseSize; + const int cursorSize = baseSize + cursorSizeValue * (baseSize / 2); + return QSize(cursorSize, cursorSize); +} + QPixmap QWindowsCursor::dragDefaultCursor(Qt::DropAction action) const { switch (action) { diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h index b896f4c7a9..cf3635bd6b 100644 --- a/src/plugins/platforms/windows/qwindowscursor.h +++ b/src/plugins/platforms/windows/qwindowscursor.h @@ -113,6 +113,8 @@ public: QPoint pos() const override; void setPos(const QPoint &pos) override; + QSize size() const override; + static HCURSOR createPixmapCursor(QPixmap pixmap, const QPoint &hotSpot, qreal scaleFactor = 1); static HCURSOR createPixmapCursor(const PixmapCursor &pc, qreal scaleFactor = 1) { return createPixmapCursor(pc.pixmap, pc.hotSpot, scaleFactor); } static PixmapCursor customCursor(Qt::CursorShape cursorShape, const QPlatformScreen *screen = nullptr); diff --git a/src/widgets/kernel/qtooltip.cpp b/src/widgets/kernel/qtooltip.cpp index 97a279d65d..1ec3612457 100644 --- a/src/widgets/kernel/qtooltip.cpp +++ b/src/widgets/kernel/qtooltip.cpp @@ -53,11 +53,14 @@ #endif #include <qtextdocument.h> #include <qdebug.h> +#include <qpa/qplatformscreen.h> +#include <qpa/qplatformcursor.h> #include <private/qstylesheetstyle_p.h> #ifndef QT_NO_TOOLTIP #include <qlabel.h> #include <QtWidgets/private/qlabel_p.h> +#include <QtGui/private/qhighdpiscaling_p.h> #include <qtooltip.h> QT_BEGIN_NAMESPACE @@ -398,24 +401,34 @@ void QTipLabel::placeTip(const QPoint &pos, QWidget *w) } #endif //QT_NO_STYLE_STYLESHEET - - QRect screen = QDesktopWidgetPrivate::screenGeometry(getTipScreen(pos, w)); - QPoint p = pos; - p += QPoint(2, 16); - - if (p.x() + this->width() > screen.x() + screen.width()) + int screenNumber = getTipScreen(pos, w); + QScreen *screen = QGuiApplication::screens().at(screenNumber); + if (screen) { + const QPlatformScreen *platformScreen = screen->handle(); + const QSize cursorSize = QHighDpi::fromNativePixels(platformScreen->cursor()->size(), + platformScreen); + QPoint offset(2, cursorSize.height()); + // assuming an arrow shape, we can just move to the side for very large cursors + if (cursorSize.height() > 2 * this->height()) + offset = QPoint(cursorSize.width() / 2, 0); + + p += offset; + + QRect screenRect = screen->geometry(); + if (p.x() + this->width() > screenRect.x() + screenRect.width()) p.rx() -= 4 + this->width(); - if (p.y() + this->height() > screen.y() + screen.height()) + if (p.y() + this->height() > screenRect.y() + screenRect.height()) p.ry() -= 24 + this->height(); - if (p.y() < screen.y()) - p.setY(screen.y()); - if (p.x() + this->width() > screen.x() + screen.width()) - p.setX(screen.x() + screen.width() - this->width()); - if (p.x() < screen.x()) - p.setX(screen.x()); - if (p.y() + this->height() > screen.y() + screen.height()) - p.setY(screen.y() + screen.height() - this->height()); + if (p.y() < screenRect.y()) + p.setY(screenRect.y()); + if (p.x() + this->width() > screenRect.x() + screenRect.width()) + p.setX(screenRect.x() + screenRect.width() - this->width()); + if (p.x() < screenRect.x()) + p.setX(screenRect.x()); + if (p.y() + this->height() > screenRect.y() + screenRect.height()) + p.setY(screenRect.y() + screenRect.height() - this->height()); + } this->move(p); } |