diff --git a/CHANGELOG.md b/CHANGELOG.md index 915a136fb..6c362977d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Version counting is based on semantic versioning (Major.Feature.Patch) * Add an optional circular magnifying glass, with an optional ring drawn around it. The configured size is kept as a rectangle, so switching back and forth doesn't lose it. * Add optional edge easing for the magnifying glass. The magnified region is pushed toward the edges of the view, so content near the border can be inspected without pushing the cursor all the way into the corner. * Require a full wheel notch before the magnifying glass changes size or zoom, so a light trackpad gesture no longer resizes it. +* Fix showing the go to flow bar asking for permission to control the computer on macOS. Moving the cursor into the bar now works without granting any accessibility permission, where before it was silently doing nothing. ### YACReaderLibrary * Add a library repair function to restore missing covers and rescan files that previously failed to be added. diff --git a/YACReader/viewer.cpp b/YACReader/viewer.cpp index 0050a7f2d..e64c39ce6 100644 --- a/YACReader/viewer.cpp +++ b/YACReader/viewer.cpp @@ -24,6 +24,38 @@ #include +#ifdef Q_OS_MACOS +#include +#endif + +namespace { +// QCursor::setPos moves the pointer by synthesizing a mouse event and injecting +// it into the HID event stream (QCocoaCursor::setPos -> CGEventPost). macOS +// gates that behind the accessibility "control this computer" permission, so on +// a machine that hasn't granted it the call is silently denied and the pointer +// never moves, while the user gets an unexplained permission request. +// +// CGWarpMouseCursorPosition repositions the pointer without injecting an event +// and needs no permission. It doesn't deliver a mouse move to the application, +// which suits the only caller here: the point is to reposition the pointer +// *without* triggering the move handling that would hide the widget again. +// +// Reported upstream as https://qt-project.atlassian.net/browse/QTBUG-148709. +// If Qt switches QCocoaCursor::setPos to the warp, this can go back to being a +// plain QCursor::setPos call once the fixed version is the minimum supported. +void moveCursorTo(const QPoint &globalPos) +{ +#ifdef Q_OS_MACOS + CGWarpMouseCursorPosition(CGPointMake(globalPos.x(), globalPos.y())); + // Warping leaves a short interval where physical mouse movement is filtered + // out; re-associating ends it so the next movement registers immediately. + CGAssociateMouseAndMouseCursorPosition(true); +#else + QCursor::setPos(globalPos); +#endif +} +} + Viewer::Viewer(QWidget *parent) : QScrollArea(parent), fullscreen(false), @@ -1332,7 +1364,7 @@ void Viewer::moveCursoToGoToFlow() cursorX = x1 + 10; if (cursorX >= x2) cursorX = x2 - 10; - cursor().setPos(mapToGlobal(QPoint(cursorX, cursorY))); + moveCursorTo(mapToGlobal(QPoint(cursorX, cursorY))); hideCursorTimer->stop(); showCursor(); }