summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2019-11-05 14:06:46 +0100
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2019-12-09 17:43:22 +0100
commitbaed8534bc1dac36a9d0ef4240fc14398076a192 (patch)
tree4f5ddaee3f3af581046d78cb0dabfedef3018ac5 /src/plugins
parent5272c35073aefee01751647dfb265aa3abf49823 (diff)
Move the tooltip out of the way of very large mouse cursors
Users that have large mouse pointers configured in their settings can not see tooltips, as they are obscured by the pointer. Native applications on Windows and macOS have the same problem, which includes the tooltips for the minimize/maximize/close controls in the window frame of e.g. Explorer. Introduce QPlatformCursor::size that returns a value that is based on the user's settings, or a default value. We can then use that value to move the tooltip out of the way. On Windows, the calculation of the cursor size is based on experimenting with the settings, which are in logical independent pixels. The placement of the tooltip attempts to keep existing behavior, and to not end up with a tooltip that's very far away from the tip of the arrow even for very large mouse cursors. [ChangeLog][QtWidgets][QToolTip] Make sure that the tooltip is not obscured by very large mouse pointers on Windows and macOS. Change-Id: I8e13b7a166bfe8b59cef4765c950f90fefeaef9d Fixes: QTBUG-79627 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/platforms/cocoa/qcocoacursor.h3
-rw-r--r--src/plugins/platforms/cocoa/qcocoacursor.mm25
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.cpp25
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.h2
4 files changed, 55 insertions, 0 deletions
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);