-
Task
-
Resolution: Unresolved
-
P4: Low
-
None
-
None
QHighDpiScaling implements the scaling between the device independent and native coordinate systems.
Today, this is implemented in lower level QtGui / upper level of QPA (more details in option 0 below). The implementation has the following characteristics:
- It's possible to maintain a platform plugin without specific knowledge about QHighDpiScaling
- It's possible to maintain upper layers of Qt Gui (and above) without specific knowledge about QHighDpiScaling
- The implementation is cross-platform, and can be tested/simulated on any platform.
The code is isolated to a specific layer in the QtGui stack - at least to a certain degree. Is it possible to isolate it further?
Option 0: (the current implementation)
- Insert scaling calls when calling QPlatform* API
- Insert scaling calls when creating QWindowSystemInterface events
- Implement event handling code (related to QHighDpiScaling) in QGuiApplication
Example pseudo-code:
QRect QWindow::geometry() {
return QHighDpiScaling::fromNative(
platformWindow->geometry(), this);
}
void QWindow::setGeometry(QRect geometry) {
platformWindow->setGeometry(
QHighDpiScaling::toNative(geometry, this));
}
{code:java}
QT_DEFINE_QPA_EVENT_HANDLER(bool, handleMouseEvent, window, pos) {
auto *event = new QWindowSystemInterfacePrivate::MouseEvent(
window, QHighDpi::fromNative(pos, window));
}
Option 1: Move QHighDpiScaling calls down to the QPA level
- QPlatform* API returns geometry in device independent pixels - no scaling calls in QWindow.
- Insert scaling calls when creating QWindowSystemInterface events
- Implement event handling code (related to QHighDpiScaling) in the QWindowSystemInterface::handle* functions, instead of in QGuiApplication
This creates a conflict: QPlatformWindow::geometry() now needs to perform the scaling, but is at the same time overridden by the platforms. One way to resolve this is to add new "public" QPlatformWindow API:
QRect QPlatformWindow::deviceIndependentGeometry() {
return QHighDpi::fromNative(this->geometry(), this);
}
QWindow then becomes:
QRect QWindow::geometry() {
return platformWindow->deviceIndependentGeometry();
}
Option 2: Move QHighDpiScaling calls down to the QPA level and leave geometry() untouched
- QPlatform* API returns geometry in device independent pixels - no scaling calls in QWindow.
- Limits dealing with scaling to platforms that need it
QRect QWindowsWindow::geometry() {
return QHighDpi::fromNative(m_nativeHandle->geometry(), this); // scaling needed
}
QRect QCocoaWindow::geometry() {
return m_nativeHandle->geometry(); // no scaling needed
}
QRect QWindow::geometry() {
return platformWindow->geometry(); // no need to think about scaling, platform layer always reports device independent pixels, isolating the logic
}