QHighDpi: Add screenForPosition()
Implement support for using the screen at a given position when determining the scale factor and origin. Add QHighDpiScaling::screenForPosition(), which searches for a screen at the specified device independent or native coordinates. The function returns the QScreen or nullptr if no screen was found. Add QHighDpiScaling::Point, used for representing an invalid, device independent, or native point. Change-Id: I58e4e3eebb8cdd5171e59f97833a00e7f8d9ecd6 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
This commit is contained in:
parent
210128cc0e
commit
b8f5ed0d5a
@ -649,34 +649,77 @@ QDpi QHighDpiScaling::logicalDpi(const QScreen *screen)
|
||||
return effectiveLogicalDpi(screen->handle(), scaleFactor, roundedScaleFactor);
|
||||
}
|
||||
|
||||
QHighDpiScaling::ScaleAndOrigin QHighDpiScaling::scaleAndOrigin(const QPlatformScreen *platformScreen, QPoint *nativePosition)
|
||||
// Returns the screen containing \a position, using \a guess as a starting point
|
||||
// for the search. \a guess might be nullptr. Returns nullptr if \a position is outside
|
||||
// of all screens.
|
||||
QScreen *QHighDpiScaling::screenForPosition(QHighDpiScaling::Point position, QScreen *guess)
|
||||
{
|
||||
if (position.kind == QHighDpiScaling::Point::Invalid)
|
||||
return nullptr;
|
||||
|
||||
auto getPlatformScreenGuess = [](QScreen *maybeScreen) -> QPlatformScreen * {
|
||||
if (maybeScreen)
|
||||
return maybeScreen->handle();
|
||||
if (QScreen *primary = QGuiApplication::primaryScreen())
|
||||
return primary->handle();
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
QPlatformScreen *platformGuess = getPlatformScreenGuess(guess);
|
||||
if (!platformGuess)
|
||||
return nullptr;
|
||||
|
||||
auto onScreen = [](QHighDpiScaling::Point position, const QPlatformScreen *platformScreen) -> bool {
|
||||
return position.kind == Point::Native
|
||||
? platformScreen->geometry().contains(position.point)
|
||||
: platformScreen->screen()->geometry().contains(position.point);
|
||||
};
|
||||
|
||||
// is the guessed screen correct?
|
||||
if (onScreen(position, platformGuess))
|
||||
return platformGuess->screen();
|
||||
|
||||
// search sibling screens
|
||||
const auto screens = platformGuess->virtualSiblings();
|
||||
for (const QPlatformScreen *screen : screens) {
|
||||
if (onScreen(position, screen))
|
||||
return screen->screen();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QHighDpiScaling::ScaleAndOrigin QHighDpiScaling::scaleAndOrigin(const QPlatformScreen *platformScreen, QHighDpiScaling::Point position)
|
||||
{
|
||||
Q_UNUSED(position)
|
||||
if (!m_active)
|
||||
return { qreal(1), QPoint() };
|
||||
if (!platformScreen)
|
||||
return { m_factor, QPoint() }; // the global factor
|
||||
const QPlatformScreen *actualScreen = nativePosition ?
|
||||
platformScreen->screenForPosition(*nativePosition) : platformScreen;
|
||||
return { m_factor * screenSubfactor(actualScreen), actualScreen->geometry().topLeft() };
|
||||
return { m_factor * screenSubfactor(platformScreen), platformScreen->geometry().topLeft() };
|
||||
}
|
||||
|
||||
QHighDpiScaling::ScaleAndOrigin QHighDpiScaling::scaleAndOrigin(const QScreen *screen, QPoint *nativePosition)
|
||||
QHighDpiScaling::ScaleAndOrigin QHighDpiScaling::scaleAndOrigin(const QScreen *screen, QHighDpiScaling::Point position)
|
||||
{
|
||||
Q_UNUSED(position)
|
||||
if (!m_active)
|
||||
return { qreal(1), QPoint() };
|
||||
if (!screen)
|
||||
return { m_factor, QPoint() }; // the global factor
|
||||
return scaleAndOrigin(screen->handle(), nativePosition);
|
||||
return scaleAndOrigin(screen->handle(), position);
|
||||
}
|
||||
|
||||
QHighDpiScaling::ScaleAndOrigin QHighDpiScaling::scaleAndOrigin(const QWindow *window, QPoint *nativePosition)
|
||||
QHighDpiScaling::ScaleAndOrigin QHighDpiScaling::scaleAndOrigin(const QWindow *window, QHighDpiScaling::Point position)
|
||||
{
|
||||
if (!m_active)
|
||||
return { qreal(1), QPoint() };
|
||||
|
||||
// Determine correct screen; use the screen which contains the given
|
||||
// position if a valid position is passed.
|
||||
QScreen *screen = window ? window->screen() : QGuiApplication::primaryScreen();
|
||||
const bool searchScreen = !window || window->isTopLevel();
|
||||
return scaleAndOrigin(screen, searchScreen ? nativePosition : nullptr);
|
||||
QScreen *overrideScreen = QHighDpiScaling::screenForPosition(position, screen);
|
||||
QScreen *targetScreen = overrideScreen ? overrideScreen : screen;
|
||||
return scaleAndOrigin(targetScreen, position);
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -96,18 +96,29 @@ public:
|
||||
|
||||
static bool isActive() { return m_active; }
|
||||
|
||||
struct Point {
|
||||
enum Kind {
|
||||
Invalid,
|
||||
DeviceIndependent,
|
||||
Native
|
||||
};
|
||||
Kind kind;
|
||||
QPoint point;
|
||||
};
|
||||
|
||||
struct ScaleAndOrigin
|
||||
{
|
||||
qreal factor;
|
||||
QPoint origin;
|
||||
};
|
||||
static ScaleAndOrigin scaleAndOrigin(const QPlatformScreen *platformScreen, QPoint *nativePosition = nullptr);
|
||||
static ScaleAndOrigin scaleAndOrigin(const QScreen *screen, QPoint *nativePosition = nullptr);
|
||||
static ScaleAndOrigin scaleAndOrigin(const QWindow *platformScreen, QPoint *nativePosition = nullptr);
|
||||
|
||||
static ScaleAndOrigin scaleAndOrigin(const QPlatformScreen *platformScreen, Point position = Point{ Point::Invalid, QPoint() });
|
||||
static ScaleAndOrigin scaleAndOrigin(const QScreen *screen, Point position = Point{ Point::Invalid, QPoint() });
|
||||
static ScaleAndOrigin scaleAndOrigin(const QWindow *platformScreen, Point position = Point{ Point::Invalid, QPoint() });
|
||||
|
||||
template<typename C>
|
||||
static qreal factor(C *context, QPoint *nativePosition = nullptr) {
|
||||
return scaleAndOrigin(context, nativePosition).factor;
|
||||
static qreal factor(C *context) {
|
||||
return scaleAndOrigin(context).factor;
|
||||
}
|
||||
|
||||
static QPoint mapPositionFromNative(const QPoint &pos, const QPlatformScreen *platformScreen);
|
||||
@ -121,6 +132,7 @@ private:
|
||||
static qreal roundScaleFactor(qreal rawFactor);
|
||||
static QDpi effectiveLogicalDpi(const QPlatformScreen *screen, qreal rawFactor, qreal roundedFactor);
|
||||
static qreal screenSubfactor(const QPlatformScreen *screen);
|
||||
static QScreen *screenForPosition(Point position, QScreen *guess);
|
||||
|
||||
static qreal m_factor;
|
||||
static bool m_active;
|
||||
@ -209,11 +221,21 @@ inline QRegion scale(const QRegion ®ion, qreal scaleFactor, QPoint origin = Q
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline QPoint position(T) { return QPoint(); }
|
||||
inline QPoint position(QPoint point) { return point; }
|
||||
inline QPoint position(QPointF point) { return point.toPoint(); }
|
||||
inline QPoint position(QRect rect) { return rect.center(); }
|
||||
inline QPoint position(QRectF rect) { return rect.center().toPoint(); }
|
||||
inline QHighDpiScaling::Point position(T, QHighDpiScaling::Point::Kind) {
|
||||
return QHighDpiScaling::Point{ QHighDpiScaling::Point::Invalid, QPoint() };
|
||||
}
|
||||
inline QHighDpiScaling::Point position(QPoint point, QHighDpiScaling::Point::Kind kind) {
|
||||
return QHighDpiScaling::Point{ kind, point };
|
||||
}
|
||||
inline QHighDpiScaling::Point position(QPointF point, QHighDpiScaling::Point::Kind kind) {
|
||||
return QHighDpiScaling::Point{ kind, point.toPoint() };
|
||||
}
|
||||
inline QHighDpiScaling::Point position(QRect rect, QHighDpiScaling::Point::Kind kind) {
|
||||
return QHighDpiScaling::Point{ kind, rect.topLeft() };
|
||||
}
|
||||
inline QHighDpiScaling::Point position(QRectF rect, QHighDpiScaling::Point::Kind kind) {
|
||||
return QHighDpiScaling::Point{ kind, rect.topLeft().toPoint() };
|
||||
}
|
||||
|
||||
template <typename T, typename C>
|
||||
T fromNativePixels(const T &value, const C *context)
|
||||
|
Loading…
Reference in New Issue
Block a user