Add accessors for QWindow and QScreen to QWidgetPrivate
Rewrite the existing accessor QWidgetPrivate::windowHandle() to accept a mode enumeration that has an "Any" convenience. Based on that, add QWidgetPrivate::associatedScreen(), which is seful in many places where scaling is performed. Prototypically simplify the code. Task-number: QTBUG-62094 Task-number: QTBUG-73231 Change-Id: I516288363d329bce9bc94e4951106f9357bc6cde Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
parent
cd563b3497
commit
eed9a8fbd3
@ -47,6 +47,7 @@
|
||||
#endif
|
||||
#include <QtWidgets/QAction>
|
||||
#include <qstyle.h>
|
||||
#include <private/qwidget_p.h>
|
||||
|
||||
#ifndef QT_NO_ACCESSIBILITY
|
||||
|
||||
@ -241,15 +242,9 @@ QObject *QAccessibleMenuItem::object() const
|
||||
/*! \reimp */
|
||||
QWindow *QAccessibleMenuItem::window() const
|
||||
{
|
||||
QWindow *result = nullptr;
|
||||
if (!m_owner.isNull()) {
|
||||
result = m_owner->windowHandle();
|
||||
if (!result) {
|
||||
if (const QWidget *nativeParent = m_owner->nativeParentWidget())
|
||||
result = nativeParent->windowHandle();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return m_owner.isNull()
|
||||
? nullptr
|
||||
: qt_widget_private(m_owner.data())->windowHandle(QWidgetPrivate::WindowHandleMode::Closest);
|
||||
}
|
||||
|
||||
QRect QAccessibleMenuItem::rect() const
|
||||
|
@ -2662,14 +2662,9 @@ QPixmap QMessageBoxPrivate::standardIcon(QMessageBox::Icon icon, QMessageBox *mb
|
||||
break;
|
||||
}
|
||||
if (!tmpIcon.isNull()) {
|
||||
QWindow *window = nullptr;
|
||||
if (mb) {
|
||||
window = mb->windowHandle();
|
||||
if (!window) {
|
||||
if (const QWidget *nativeParent = mb->nativeParentWidget())
|
||||
window = nativeParent->windowHandle();
|
||||
}
|
||||
}
|
||||
QWindow *window = mb
|
||||
? qt_widget_private(mb)->windowHandle(QWidgetPrivate::WindowHandleMode::Closest)
|
||||
: nullptr;
|
||||
return tmpIcon.pixmap(window, QSize(iconSize, iconSize));
|
||||
}
|
||||
return QPixmap();
|
||||
|
@ -4461,15 +4461,8 @@ QPixmap QAbstractItemViewPrivate::renderToPixmap(const QModelIndexList &indexes,
|
||||
if (paintPairs.isEmpty())
|
||||
return QPixmap();
|
||||
|
||||
qreal scale = 1.0f;
|
||||
|
||||
Q_Q(const QAbstractItemView);
|
||||
QWidget *window = q->window();
|
||||
if (window) {
|
||||
QWindow *windowHandle = window->windowHandle();
|
||||
if (windowHandle)
|
||||
scale = windowHandle->devicePixelRatio();
|
||||
}
|
||||
QWindow *window = windowHandle(WindowHandleMode::Closest);
|
||||
const qreal scale = window ? window->devicePixelRatio() : qreal(1);
|
||||
|
||||
QPixmap pixmap(r->size() * scale);
|
||||
pixmap.setDevicePixelRatio(scale);
|
||||
|
@ -321,20 +321,12 @@ int QDesktopWidgetPrivate::screenNumber(const QWidget *w)
|
||||
if (screens.isEmpty()) // This should never happen
|
||||
return primaryScreen();
|
||||
|
||||
const QWindow *winHandle = w->windowHandle();
|
||||
if (!winHandle) {
|
||||
if (const QWidget *nativeParent = w->nativeParentWidget())
|
||||
winHandle = nativeParent->windowHandle();
|
||||
}
|
||||
|
||||
// If there is more than one virtual desktop
|
||||
if (screens.count() != screens.constFirst()->virtualSiblings().count()) {
|
||||
// Find the root widget, get a QScreen from it and use the
|
||||
// virtual siblings for checking the window position.
|
||||
if (winHandle) {
|
||||
if (const QScreen *winScreen = winHandle->screen())
|
||||
screens = winScreen->virtualSiblings();
|
||||
}
|
||||
if (const QScreen *winScreen = qt_widget_private(const_cast<QWidget *>(w))->associatedScreen())
|
||||
screens = winScreen->virtualSiblings();
|
||||
}
|
||||
|
||||
// Get the screen number from window position using screen geometry
|
||||
|
@ -1333,11 +1333,8 @@ int QOpenGLWidget::metric(QPaintDevice::PaintDeviceMetric metric) const
|
||||
if (d->inBackingStorePaint)
|
||||
return QWidget::metric(metric);
|
||||
|
||||
QWidget *tlw = window();
|
||||
QWindow *window = tlw ? tlw->windowHandle() : 0;
|
||||
QScreen *screen = tlw && tlw->windowHandle() ? tlw->windowHandle()->screen() : 0;
|
||||
if (!screen && QGuiApplication::primaryScreen())
|
||||
screen = QGuiApplication::primaryScreen();
|
||||
auto window = d->windowHandle(QWidgetPrivate::WindowHandleMode::TopLevel);
|
||||
QScreen *screen = window ? window->screen() : QGuiApplication::primaryScreen();
|
||||
|
||||
const float dpmx = qt_defaultDpiX() * 100. / 2.54;
|
||||
const float dpmy = qt_defaultDpiY() * 100. / 2.54;
|
||||
|
@ -1252,6 +1252,33 @@ void QWidgetPrivate::createRecursively()
|
||||
}
|
||||
}
|
||||
|
||||
QWindow *QWidgetPrivate::windowHandle(WindowHandleMode mode) const
|
||||
{
|
||||
if (mode == WindowHandleMode::Direct || mode == WindowHandleMode::Closest) {
|
||||
if (QTLWExtra *x = maybeTopData())
|
||||
return x->window;
|
||||
}
|
||||
if (mode == WindowHandleMode::Closest) {
|
||||
if (auto nativeParent = q_func()->nativeParentWidget()) {
|
||||
if (auto window = nativeParent->windowHandle())
|
||||
return window;
|
||||
}
|
||||
}
|
||||
if (mode == WindowHandleMode::TopLevel || mode == WindowHandleMode::Closest) {
|
||||
if (auto topLevel = q_func()->topLevelWidget()) {
|
||||
if (auto window = topLevel ->windowHandle())
|
||||
return window;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QScreen *QWidgetPrivate::associatedScreen() const
|
||||
{
|
||||
if (auto window = windowHandle(WindowHandleMode::Closest))
|
||||
return window->screen();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// ### fixme: Qt 6: Remove parameter window from QWidget::create()
|
||||
|
||||
@ -8103,7 +8130,7 @@ void QWidgetPrivate::show_sys()
|
||||
{
|
||||
Q_Q(QWidget);
|
||||
|
||||
QWidgetWindow *window = windowHandle();
|
||||
auto window = qobject_cast<QWidgetWindow *>(windowHandle());
|
||||
|
||||
if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
|
||||
invalidateBackingStore(q->rect());
|
||||
@ -8242,7 +8269,7 @@ void QWidgetPrivate::hide_sys()
|
||||
{
|
||||
Q_Q(QWidget);
|
||||
|
||||
QWidgetWindow *window = windowHandle();
|
||||
auto window = qobject_cast<QWidgetWindow *>(windowHandle());
|
||||
|
||||
if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
|
||||
q->setAttribute(Qt::WA_Mapped, false);
|
||||
|
@ -342,7 +342,15 @@ public:
|
||||
QPainter *sharedPainter() const;
|
||||
void setSharedPainter(QPainter *painter);
|
||||
QWidgetBackingStore *maybeBackingStore() const;
|
||||
QWidgetWindow *windowHandle() const;
|
||||
|
||||
enum class WindowHandleMode {
|
||||
Direct,
|
||||
Closest,
|
||||
TopLevel
|
||||
};
|
||||
QWindow *windowHandle(WindowHandleMode mode = WindowHandleMode::Direct) const;
|
||||
|
||||
QScreen *associatedScreen() const;
|
||||
|
||||
template <typename T>
|
||||
void repaint(T t);
|
||||
@ -1014,13 +1022,6 @@ inline QWidgetBackingStore *QWidgetPrivate::maybeBackingStore() const
|
||||
return x ? x->backingStoreTracker.data() : nullptr;
|
||||
}
|
||||
|
||||
inline QWidgetWindow *QWidgetPrivate::windowHandle() const
|
||||
{
|
||||
if (QTLWExtra *x = maybeTopData())
|
||||
return x->window;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QWIDGET_P_H
|
||||
|
@ -592,10 +592,7 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
|
||||
w->window()->raise();
|
||||
}
|
||||
|
||||
QWindow *win = w->windowHandle();
|
||||
if (!win)
|
||||
win = w->nativeParentWidget()->windowHandle();
|
||||
if (win) {
|
||||
if (auto win = qt_widget_private(w)->windowHandle(QWidgetPrivate::WindowHandleMode::Closest)) {
|
||||
const QRect globalGeometry = win->isTopLevel()
|
||||
? win->geometry()
|
||||
: QRect(win->mapToGlobal(QPoint(0, 0)), win->size());
|
||||
|
@ -380,23 +380,12 @@ int QWindowsStylePrivate::fixedPixelMetric(QStyle::PixelMetric pm)
|
||||
return QWindowsStylePrivate::InvalidMetric;
|
||||
}
|
||||
|
||||
static QWindow *windowOf(const QWidget *w)
|
||||
{
|
||||
QWindow *result = nullptr;
|
||||
if (w) {
|
||||
result = w->windowHandle();
|
||||
if (!result) {
|
||||
if (const QWidget *np = w->nativeParentWidget())
|
||||
result = np->windowHandle();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static QScreen *screenOf(const QWidget *w)
|
||||
{
|
||||
if (const QWindow *window = windowOf(w))
|
||||
return window->screen();
|
||||
if (w) {
|
||||
if (auto screen = qt_widget_private(const_cast<QWidget *>(w))->associatedScreen())
|
||||
return screen;
|
||||
}
|
||||
return QGuiApplication::primaryScreen();
|
||||
}
|
||||
|
||||
|
@ -2838,19 +2838,15 @@ void QComboBox::showPopup()
|
||||
bool startTimer = !container->isVisible();
|
||||
container->raise();
|
||||
container->create();
|
||||
QWindow *containerWindow = container->window()->windowHandle();
|
||||
if (containerWindow) {
|
||||
QWindow *win = window()->windowHandle();
|
||||
if (win) {
|
||||
QScreen *currentScreen = win->screen();
|
||||
if (currentScreen && !currentScreen->virtualSiblings().contains(containerWindow->screen())) {
|
||||
containerWindow->setScreen(currentScreen);
|
||||
if (QWindow *containerWindow = qt_widget_private(container)->windowHandle(QWidgetPrivate::WindowHandleMode::TopLevel)) {
|
||||
QScreen *currentScreen = d->associatedScreen();
|
||||
if (currentScreen && !currentScreen->virtualSiblings().contains(containerWindow->screen())) {
|
||||
containerWindow->setScreen(currentScreen);
|
||||
|
||||
// This seems to workaround an issue in xcb+multi GPU+multiscreen
|
||||
// environment where the window might not always show up when screen
|
||||
// is changed.
|
||||
container->hide();
|
||||
}
|
||||
// This seems to workaround an issue in xcb+multi GPU+multiscreen
|
||||
// environment where the window might not always show up when screen
|
||||
// is changed.
|
||||
container->hide();
|
||||
}
|
||||
}
|
||||
container->show();
|
||||
|
@ -1535,10 +1535,10 @@ bool QDockWidget::event(QEvent *event)
|
||||
d->toggleViewAction->setChecked(true);
|
||||
QPoint parentTopLeft(0, 0);
|
||||
if (isWindow()) {
|
||||
if (const QWindow *window = windowHandle())
|
||||
parentTopLeft = window->screen()->availableVirtualGeometry().topLeft();
|
||||
else
|
||||
parentTopLeft = QGuiApplication::primaryScreen()->availableVirtualGeometry().topLeft();
|
||||
const QScreen *screen = d->associatedScreen();
|
||||
parentTopLeft = screen
|
||||
? screen->availableVirtualGeometry().topLeft()
|
||||
: QGuiApplication::primaryScreen()->availableVirtualGeometry().topLeft();
|
||||
}
|
||||
emit visibilityChanged(geometry().right() >= parentTopLeft.x() && geometry().bottom() >= parentTopLeft.y());
|
||||
}
|
||||
|
@ -355,9 +355,7 @@ QLineEditPrivate *QLineEditIconButton::lineEditPrivate() const
|
||||
void QLineEditIconButton::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter painter(this);
|
||||
QWindow *window = nullptr;
|
||||
if (const QWidget *nativeParent = nativeParentWidget())
|
||||
window = nativeParent->windowHandle();
|
||||
QWindow *window = qt_widget_private(this)->windowHandle(QWidgetPrivate::WindowHandleMode::Closest);
|
||||
QIcon::Mode state = QIcon::Disabled;
|
||||
if (isEnabled())
|
||||
state = isDown() ? QIcon::Active : QIcon::Normal;
|
||||
|
@ -2584,9 +2584,9 @@ void QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mousePos)
|
||||
}
|
||||
}
|
||||
for (QWidget *w : candidates) {
|
||||
QWindow *handle1 = widget->windowHandle();
|
||||
QWindow *handle2 = w->windowHandle();
|
||||
if (handle1 && handle2 && handle1->screen() != handle2->screen())
|
||||
const QScreen *screen1 = qt_widget_private(widget)->associatedScreen();
|
||||
const QScreen *screen2 = qt_widget_private(w)->associatedScreen();
|
||||
if (screen1 && screen2 && screen1 != screen2)
|
||||
continue;
|
||||
if (!w->geometry().contains(mousePos))
|
||||
continue;
|
||||
|
Loading…
x
Reference in New Issue
Block a user