minimize dialog resizes/moves

Summary:
take into account size hints also when adjusting with synctomainitemsize
which sometimes has to be executed right before adjusting from the layout
hints, giving one wrong resize

introduce geometryUpdatesBlocked, which stops the dialog
from syncing which is useful when both visual parent and item
contents gets updated in one go (the tooltip) it is not
yet exported to qml and it shouldn't as is dangerous, but
kicker may make use of it between changing the submenu model and
the visualparent

alternative implementations may be:
* a method that takes both main item and visual parent
* delaying with a timer setGeometry (ouch)
this part can also be left behind for now and see if the rest is good enough

Test Plan:
no visual glitches visible anymore in wayland when moving the tooltip
in the taskbar, x11 ok too

Reviewers: #plasma, hein, davidedmundson

Reviewed By: #plasma, hein, davidedmundson

Subscribers: broulik, davidedmundson, plasma-devel, #frameworks

Tags: #plasma, #frameworks

Differential Revision: https://phabricator.kde.org/D5912
This commit is contained in:
Marco Martin 2017-05-25 11:21:13 +02:00
parent 6622a8c713
commit 32e67a591e
2 changed files with 37 additions and 13 deletions

View File

@ -36,12 +36,8 @@ ToolTipDialog::ToolTipDialog(QQuickItem *parent)
m_interactive(false),
m_owner(nullptr)
{
Qt::WindowFlags flags = Qt::ToolTip;
if (KWindowSystem::isPlatformX11()) {
flags = flags | Qt::BypassWindowManagerHint;
}
setFlags(flags);
setLocation(Plasma::Types::Floating);
setType(Dialog::WindowType::Tooltip);
m_showTimer = new QTimer(this);
m_showTimer->setSingleShot(true);

View File

@ -111,6 +111,11 @@ public:
void updateMaximumWidth();
void updateMaximumHeight();
/**
* Gets the maximum and minimum size hints for the window based on the contents. it doesn't actually resize anything
*/
void getSizeHints(QSize &min, QSize &max) const;
/**
* This function is an optimized version of updateMaximumHeight,
* updateMaximumWidth,updateMinimumWidth and updateMinimumHeight.
@ -292,6 +297,7 @@ void DialogPrivate::updateVisibility(bool visible)
}
cachedGeometry = QRect();
}
if (mainItem) {
syncToMainItemSize();
}
@ -439,7 +445,7 @@ void DialogPrivate::updateMaximumHeight()
hintsCommitTimer.start();
}
void DialogPrivate::updateLayoutParameters()
void DialogPrivate::getSizeHints(QSize &min, QSize &max) const
{
if (!componentComplete || !mainItem || !q->isVisible() || !mainItemLayout) {
return;
@ -447,8 +453,6 @@ void DialogPrivate::updateLayoutParameters()
Q_ASSERT(mainItem);
Q_ASSERT(mainItemLayout);
mainItem->disconnect(q);
auto margin = frameSvgItem->fixedMargins();
int minimumHeight = mainItemLayout->property("minimumHeight").toInt();
@ -471,8 +475,25 @@ void DialogPrivate::updateLayoutParameters()
maximumHeight = qMin(q->screen()->availableGeometry().height(), maximumHeight);
}
const QSize finalSize(qBound(minimumWidth, q->width(), maximumWidth),
qBound(minimumHeight, q->height(), maximumHeight));
min = QSize(minimumWidth, minimumHeight);
max = QSize(maximumWidth, maximumHeight);
}
void DialogPrivate::updateLayoutParameters()
{
if (!componentComplete || !mainItem || !q->isVisible() || !mainItemLayout) {
return;
}
mainItem->disconnect(q);
auto margin = frameSvgItem->fixedMargins();
QSize min;
QSize max(DIALOGSIZE_MAX, DIALOGSIZE_MAX);
getSizeHints(min, max);
const QSize finalSize(qBound(min.width(), q->width(), max.width()),
qBound(min.height(), q->height(), max.height()));
if (visualParent) {
//it's important here that we're using re->size() as size, we don't want to do recursive resizeEvents
@ -496,8 +517,8 @@ void DialogPrivate::updateLayoutParameters()
//FIXME: this seems to interfere with the geometry change that
//sometimes is still going on, causing flicker (this one is two repositions happening in quick succession).
//it may have to be delayed further
q->setMinimumSize(QSize(minimumWidth, minimumHeight));
q->setMaximumSize(QSize(maximumWidth, maximumHeight));
q->setMinimumSize(min);
q->setMaximumSize(max);
QObject::connect(mainItem, SIGNAL(widthChanged()), q, SLOT(slotMainItemSizeChanged()));
QObject::connect(mainItem, SIGNAL(heightChanged()), q, SLOT(slotMainItemSizeChanged()));
@ -607,10 +628,16 @@ void DialogPrivate::syncToMainItemSize()
syncBorders(q->geometry());
}
const QSize s = QSize(mainItem->width(), mainItem->height()) +
QSize s = QSize(mainItem->width(), mainItem->height()) +
QSize(frameSvgItem->fixedMargins()->left() + frameSvgItem->fixedMargins()->right(),
frameSvgItem->fixedMargins()->top() + frameSvgItem->fixedMargins()->bottom());
QSize min;
QSize max(DIALOGSIZE_MAX, DIALOGSIZE_MAX);
getSizeHints(min, max);
s = QSize(qBound(min.width(), s.width(), max.width()),
qBound(min.height(), s.height(), max.height()));
q->contentItem()->setSize(s);
frameSvgItem->setSize(s);
@ -621,6 +648,7 @@ void DialogPrivate::syncToMainItemSize()
if (geom == q->geometry()) {
return;
}
q->adjustGeometry(geom);
// The borders will instantly be updated but the geometry might take a
// while as sub-classes can reimplement adjustGeometry and animate it.