Make sure size is final after showEvent

Summary:
* make sure after a showevent the size is final and the
dialog can be safely repositioned.
* set mainItem visible in :setVisible() so that is executed before showEvent:
   resizing windows in their show event is definitely not enough, causes events to arrive to
   reset to the old geometry in race with the setgeometry done there, don't know yet
   if it's the qpa, qwindow, or the windowmanager
* make synctomaintem and updatelayoutparameters working even if
the dialog is not visible as we need to resize beforehand
* move the plasmasurface window also in the show event as if there was no moveevent
  after an hide/show, its position would be resetted to 0,0

Test Plan:
current dialog users behave the same (like pre-D6216 notifications applet), tests still pass
notifications applet reworked to use this works as expected

Reviewers: #plasma, davidedmundson

Reviewed By: #plasma, davidedmundson

Subscribers: sebas, hein, davidedmundson, plasma-devel, #frameworks

Tags: #plasma, #frameworks

Differential Revision: https://phabricator.kde.org/D6215
This commit is contained in:
Marco Martin 2017-06-21 13:29:14 +02:00
parent 7051018577
commit eab4aa9909
2 changed files with 25 additions and 19 deletions

View File

@ -157,7 +157,7 @@ void ToolTip::showToolTip()
dlg->setVisualParent(this);
dlg->setMainItem(mainItem());
dlg->setInteractive(m_interactive);
dlg->show();
dlg->setVisible(true);
}
QString ToolTip::mainText() const

View File

@ -273,7 +273,6 @@ void DialogPrivate::updateVisibility(bool visible)
if (mainItem) {
mainItem->setVisible(visible);
}
if (visible) {
if (visualParent && visualParent->window()) {
q->setTransientParent(visualParent->window());
@ -304,6 +303,12 @@ void DialogPrivate::updateVisibility(bool visible)
if (mainItemLayout) {
updateLayoutParameters();
}
//if is a wayland window that was hidden, we need
//to set its position again as there won't be any move event to sync QWindow::position and shellsurface::position
if (shellSurface) {
shellSurface->setPosition(q->position());
}
}
}
@ -354,7 +359,7 @@ void DialogPrivate::updateMinimumWidth()
Q_ASSERT(mainItem);
Q_ASSERT(mainItemLayout);
if (!componentComplete || !q->isVisible()) {
if (!componentComplete) {
return;
}
@ -380,7 +385,7 @@ void DialogPrivate::updateMinimumHeight()
Q_ASSERT(mainItem);
Q_ASSERT(mainItemLayout);
if (!componentComplete || !q->isVisible()) {
if (!componentComplete) {
return;
}
@ -406,7 +411,7 @@ void DialogPrivate::updateMaximumWidth()
Q_ASSERT(mainItem);
Q_ASSERT(mainItemLayout);
if (!componentComplete || !q->isVisible()) {
if (!componentComplete) {
return;
}
@ -428,7 +433,7 @@ void DialogPrivate::updateMaximumHeight()
Q_ASSERT(mainItem);
Q_ASSERT(mainItemLayout);
if (!componentComplete || !q->isVisible()) {
if (!componentComplete) {
return;
}
@ -447,7 +452,7 @@ void DialogPrivate::updateMaximumHeight()
void DialogPrivate::getSizeHints(QSize &min, QSize &max) const
{
if (!componentComplete || !mainItem || !q->isVisible() || !mainItemLayout) {
if (!componentComplete || !mainItem || !mainItemLayout) {
return;
}
Q_ASSERT(mainItem);
@ -481,7 +486,7 @@ void DialogPrivate::getSizeHints(QSize &min, QSize &max) const
void DialogPrivate::updateLayoutParameters()
{
if (!componentComplete || !mainItem || !q->isVisible() || !mainItemLayout) {
if (!componentComplete || !mainItem || !mainItemLayout) {
return;
}
@ -598,7 +603,7 @@ void DialogPrivate::syncToMainItemSize()
{
Q_ASSERT(mainItem);
if (!componentComplete || !q->isVisible()) {
if (!componentComplete) {
return;
}
if (mainItem->width() <= 0 || mainItem->height() <= 0) {
@ -1037,7 +1042,7 @@ void Dialog::resizeEvent(QResizeEvent* re)
QQuickWindow::resizeEvent(re);
//A dialog can be resized even if no mainItem has ever been set
if (!isVisible() || !d->mainItem) {
if (!d->mainItem) {
return;
}
@ -1048,6 +1053,7 @@ void Dialog::resizeEvent(QResizeEvent* re)
auto margin = d->frameSvgItem->fixedMargins();
d->mainItem->setPosition(QPointF(margin->left(),
margin->top()));
d->mainItem->setSize(QSize(re->size().width() - margin->left() - margin->right(),
re->size().height() - margin->top() - margin->bottom()));
@ -1164,10 +1170,13 @@ bool Dialog::event(QEvent *event)
* see https://phabricator.kde.org/T6064
*/
#if HAVE_KWAYLAND
if (!d->shellSurface) {
//sometimes non null regions arrive even for non visible windows
//for which surface creation would fail
if (!d->shellSurface && isVisible()) {
KWindowSystem::setState(winId(), NET::SkipTaskbar | NET::SkipPager);
d->setupWaylandIntegration();
d->updateVisibility(true);
d->updateTheme();
}
#endif
#if (QT_VERSION > QT_VERSION_CHECK(5, 5, 0))
@ -1311,14 +1320,6 @@ void Dialog::componentComplete()
KWindowSystem::setState(winId(), NET::SkipTaskbar | NET::SkipPager);
}
d->updateTheme();
if (d->mainItem) {
d->syncToMainItemSize();
}
if (d->mainItemLayout) {
d->updateLayoutParameters();
}
}
bool Dialog::hideOnWindowDeactivate() const
@ -1359,6 +1360,11 @@ void Dialog::setVisible(bool visible)
if (visible && d->visualParent) {
setPosition(popupPosition(d->visualParent, size()));
}
//setting the main item visible before the show event arrives
//makes positioning work better
if (visible && d->mainItem) {
d->mainItem->setVisible(true);
}
QQuickWindow::setVisible(visible);
if (visible) {
// FIXME TODO: We can remove this once we depend on Qt 5.6.1+.