Windows: Fix tooltip flicker on GL surfaces

QPlatformWindow::initialGeometry() would assign a default height to
the initial geometry of the QRollEffectClassWindow since it has height
of 0. This causes the obtained geometry to not match and subsequently
a geometry change being sent synchronously.

Introduce a new flag QWindowPrivate::resizeAutomatic similar to the
existing QWindowPrivate::positionAutomatic to prevent assigning a
default size and pass through the geometry as is where required.

Fixes: QTBUG-74176
Change-Id: I70c66490838a2c4dfe200ec86094d28bd984dd03
Reviewed-by: Kati Kankaanpaa <kati.kankaanpaa@qt.io>
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
bb10
Friedemann Kleint 2019-03-13 11:24:48 +01:00
parent c45f2eab85
commit a1c37462ee
4 changed files with 16 additions and 5 deletions

View File

@ -708,10 +708,11 @@ QRect QPlatformWindow::initialGeometry(const QWindow *w,
const QScreen *screen = effectiveScreen(w);
if (!screen)
return initialGeometry;
const auto *wp = qt_window_private(const_cast<QWindow*>(w));
QRect rect(QHighDpi::fromNativePixels(initialGeometry, w));
rect.setSize(fixInitialSize(rect.size(), w, defaultWidth, defaultHeight));
if (qt_window_private(const_cast<QWindow*>(w))->positionAutomatic
&& w->type() != Qt::Popup) {
if (wp->resizeAutomatic)
rect.setSize(fixInitialSize(rect.size(), w, defaultWidth, defaultHeight));
if (wp->positionAutomatic && w->type() != Qt::Popup) {
const QRect availableGeometry = screen->availableGeometry();
// Center unless the geometry ( + unknown window frame) is too large for the screen).
if (rect.height() < (availableGeometry.height() * 8) / 9

View File

@ -90,6 +90,7 @@ public:
, receivedExpose(false)
, positionPolicy(WindowFrameExclusive)
, positionAutomatic(true)
, resizeAutomatic(true)
, contentOrientation(Qt::PrimaryOrientation)
, opacity(qreal(1.0))
, minimumSize(0, 0)
@ -155,6 +156,8 @@ public:
virtual void processSafeAreaMarginsChanged() {};
bool isPopup() const { return (windowFlags & Qt::WindowType_Mask) == Qt::Popup; }
void setAutomaticPositionAndResizeEnabled(bool a)
{ positionAutomatic = resizeAutomatic = a; }
static QWindowPrivate *get(QWindow *window) { return window->d_func(); }
@ -178,6 +181,7 @@ public:
bool receivedExpose;
PositionPolicy positionPolicy;
bool positionAutomatic;
bool resizeAutomatic;
Qt::ScreenOrientation contentOrientation;
qreal opacity;
QRegion mask;

View File

@ -1132,7 +1132,8 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w,
// TODO: No concept of WA_wasMoved yet that would indicate a
// CW_USEDEFAULT unless set. For now, assume that 0,0 means 'default'
// for toplevels.
if (geometry.isValid()) {
if (geometry.isValid()
|| !qt_window_private(const_cast<QWindow *>(w))->resizeAutomatic) {
frameX = geometry.x();
frameY = geometry.y();
const QMargins effectiveMargins = margins + customMargins;

View File

@ -1543,14 +1543,19 @@ void QWidgetPrivate::createTLSysExtra()
extra->topextra->window->setMaximumSize(QSize(extra->maxw, extra->maxh));
if (extra->topextra->opacity != 255 && q->isWindow())
extra->topextra->window->setOpacity(qreal(extra->topextra->opacity) / qreal(255));
const bool isTipLabel = q->inherits("QTipLabel");
const bool isAlphaWidget = !isTipLabel && q->inherits("QAlphaWidget");
#ifdef Q_OS_WIN
// Pass on native parent handle for Widget embedded into Active X.
const QVariant activeXNativeParentHandle = q->property(activeXNativeParentHandleProperty);
if (activeXNativeParentHandle.isValid())
extra->topextra->window->setProperty(activeXNativeParentHandleProperty, activeXNativeParentHandle);
if (q->inherits("QTipLabel") || q->inherits("QAlphaWidget"))
if (isTipLabel || isAlphaWidget)
extra->topextra->window->setProperty("_q_windowsDropShadow", QVariant(true));
#endif
if (isTipLabel || isAlphaWidget || q->inherits("QRollEffect"))
qt_window_private(extra->topextra->window)->setAutomaticPositionAndResizeEnabled(false);
}
}