Make sure size is final after showEvent
ClosedPublic

Authored by mart on Jun 13 2017, 4:11 PM.

Details

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

Diff Detail

Repository
R242 Plasma Framework (Library)
Branch
master
Lint
No Linters Available
Unit
No Unit Test Coverage
mart created this revision.Jun 13 2017, 4:11 PM
Restricted Application added projects: Plasma, Frameworks. · View Herald TranscriptJun 13 2017, 4:11 PM
Restricted Application added subscribers: Frameworks, plasma-devel. · View Herald Transcript
davidedmundson requested changes to this revision.Jun 13 2017, 4:40 PM
davidedmundson added a subscriber: davidedmundson.
davidedmundson added inline comments.
src/plasmaquick/dialog.cpp
1361–1363

this is already done in updateVisibility which is effectively called from

QQuickWindow::setVisible(visible);

So we're just doing things twice.

You've not really said what problem we're trying to solve with this patch.

If a subclass wants to do custom positioning (like krunner) they've got the virtual method they can use.

If you want a hook between us updating our size and the platform showing the window we've got ShowEvent.

This revision now requires changes to proceed.Jun 13 2017, 4:40 PM
mart added inline comments.Jun 13 2017, 5:31 PM
src/plasmaquick/dialog.cpp
1361–1363

You've not really said what problem we're trying to solve with this patch.

having a pointt in which we are 100% sure of the final size of the dialog to correctly position it.
if visualparent is set, this is done internally and all works fine, but for users that do a manual positioning, there are currently no hooks from client code to do so, this is in part the reason for the big ugly custom notifications positioning code

this is already done in updateVisibility which is effectively called from

i think it should be safe to remove it from updatevisibility

If you want a hook between us updating our size and the platform showing the window we've got ShowEvent.

yes, exactly. The idea is for it to be usable from qml, so can't rely on subclassing. which would be ok for notifications but not for simplemenu

hein added a subscriber: hein.Jun 13 2017, 5:37 PM

I used to subclass in Simple Menu, but then eliminated the C++ plugin so I could put it on the Store, so this is important for now.

mart added inline comments.Jun 14 2017, 9:17 AM
src/plasmaquick/dialog.cpp
1361–1363
this is already done in updateVisibility which is effectively called from

i think it should be safe to remove it from updatevisibility

hmm, actually not, seems sometimes it needs to be called from updatevisibility, so both seem to be needed

sebas added a subscriber: sebas.Jun 14 2017, 9:20 AM

I like this, and I'll likely need it in my kscreen OSD code aswell (positioning there is unreliable, and my best guess is that this is the exact same problem @mart is trying to solve here).

+1

davidedmundson added inline comments.Jun 14 2017, 9:40 AM
src/plasmaquick/dialog.cpp
1361–1363

You can't move the code from updateVisibility as we need it to work with an upcasted QQuickWindow::setVisible .
That's probably the main reason you ended up having to change the pointer type in the other patch you did.

That doesn't explain this patch:

  • if you did shuffle the code to be this way, you don't need a new signal. QQuickWindow would emit its visibleChanged before we send platform stuff
  • if you didn't shuffle the code, you could have made this whole patch a one liner in updateVisibility

but I still don't see what problem this solves.

QML clients have widthChanged heightChanged emitted so they can bind X/Y in a declarative way. They're currently emitted after we update our size but before we update the platform. Any setX setY calls here will still be at the right time.

mart updated this revision to Diff 15446.Jun 14 2017, 11:11 AM
mart edited edge metadata.

don't update the size twice

only update the size in setvisible, not in updatevisibility.

if this is done in the showEvent instead, it's too late and
is possible to see a resize on screen

mart added inline comments.Jun 14 2017, 2:27 PM
src/plasmaquick/dialog.cpp
1361–1363

between the showeventand the expose event, there is a resize event that resizes the dialog to the wrong size: that event doesn't come from a acoreapplication::postevern, nobody calls resize, nobody calls setgeometry, i'm at loss where it comes from, but doesn't make things work as they should

mart updated this revision to Diff 15462.Jun 15 2017, 2:39 PM

update size in showevent

update size in showevent, get rid of aboutToShow signal
showing and hiding mainItem (as opposed to its window)
had repercussions on the size calculation, giving it
a stuttering appearance when windows appeared.
if we want to position the window when we are sure the size is final
and the window is not shown yet (but about to) we can
do it in the signal handler of visibleChanged (when visible is true)
we are assured we are right before the expose event

mart retitled this revision from Introduce aboutToShow() signal to Make sure size is final after showEvent.Jun 15 2017, 2:43 PM
mart edited the summary of this revision. (Show Details)
mart marked an inline comment as done.
davidedmundson requested changes to this revision.Jun 16 2017, 1:31 PM

Ok so in summary there's two changes here:

  • updating our window geometry regardless of whether we're visible or not

Makes total sense, there's no bandwidth overhead the platform won't send anything if the window isn't mapped; but it means it has the right info for when we want it.

  • not setting mainItem to invisible when the dialog is hidden.

We can see in gammaray all the contents now think they're visible. I'm quite wary of this as it was added for a reason.

The window doesn't render but we do have some code paths that release resources, and I'm pretty sure Animations (not Animators) will continue running.


But most crucially with this patch I don't get notifications (running unpatched p-w on XCB )
Can you test that combo please.

This revision now requires changes to proceed.Jun 16 2017, 1:31 PM

Relavent follow up to the unanswer question from yesterday:

why does the implicit height change when we show it

It's from some code in NotificationItem.qml

ColumnLayout {
    id: mainLayout
    anchors {
         left: appIconItem.visible || imageItem.visible ? appIconItem.right : parent.left

This changes when we show the popup, the width available show the text, that changes the implicitHeight of the dialog, which changes the actual height.

I /think/ changing them to check whether the image is loaded rather than visible will fix that issue.
I commented it out and gammaray no longer shows the implicitHeight changing

mart added a comment.Jun 16 2017, 5:45 PM

with patch applied on plasma-framework and notifications applet from master all seems to still work ok.

so, if i understand correctly, to try with notifiaction applet with your D6237 on top, and this patch that keeps updating the visibility of the main item.

mart added a comment.Jun 16 2017, 5:54 PM
In D6215#116837, @mart wrote:

with patch applied on plasma-framework and notifications applet from master all seems to still work ok.

so, if i understand correctly, to try with notifiaction applet with your D6237 on top, and this patch that keeps updating the visibility of the main item.

doesn't seem to work on wayland :/

mart added a comment.Jun 19 2017, 8:47 AM

this is how it looks under wayland, keeping the visibility change of the mainitem in plasma-framework and your patch in the notifications applet

mart added a comment.Jun 19 2017, 8:52 AM

it's maybe due to the layout of actions buttons that changes (in the notification applet, populatepopup) but this (columnLayout computed height) doesn't really have effect until it's visible.

mart added a comment.Jun 19 2017, 8:58 AM
In D6215#117370, @mart wrote:

it's maybe due to the layout of actions buttons that changes (in the notification applet, populatepopup) but this (columnLayout computed height) doesn't really have effect until it's visible.

in fact, if in the notification applet i do, right before setVisible():
popup->property("mainItem").value<QQuickItem*>()->setVisible(true);

making mainitem visible just before the showevent,
then the look is correct.

if i do that right in the showevent handler, it's too late and i get wrongly calculate sizes and spurious extra resize events

mart added a comment.Jun 19 2017, 9:25 AM

with this, that removes most of the properties depending from visible, i usually get properly sized notifications, tough every now and then the size still fails and a reposition is always visible right after the notification appears
https://pastebin.com/ia8nLGiw

mart updated this revision to Diff 15579.Jun 19 2017, 12:56 PM
mart edited edge metadata.

hide again mainitem when not visible

show it in setVisible, that is before show.
this will work only when the Dialog' version of setvisible is called,
so must be paid attention when using dialog directly from C++,
but it covers all QML usage

this will work only when the Dialog' version of setvisible is called,

So this will break released Plasma?

mart added a comment.Jun 19 2017, 1:20 PM

this will work only when the Dialog' version of setvisible is called,

So this will break released Plasma?

no, it just means that who calls show() or the wrong setVisible() would just get the previous behavior of mainItem being shown only at showevent, so with the potential resize/position glitch that is already in now, but setvisible gets called both there and in the showevent, so it wouldn't significantly break (just in most common case, the second setvisible would be a noop)

no, it just means that who calls show() or the wrong setVisible() would just get the previous behavior of mainItem being shown only at showevent,

Ok, great


It's somewhat confusing as you have multiple completely independent attempts to solve the same problem.

We have a patch now consists of:

  1. an early mainItem->setVisible()
  2. always updating the platform window size regardless of whether it's visible
  3. some other wayland changes (which aren't in your commit message)

And we have another patch that:

  1. removes use of item::visible in working out window size
  2. inhibits resizing whilst we re-populate actions whilst invisible

I'm after some explanation of what the problem(s) each one of those is solving.

If 1 works, I don't see what 2 accomplishes, you're setting the platform window size earlier, but to something that we know is wrong.

Also if 1 works, we don't need 4 or 5? Unless it's because notification does is doing the positioning before the show event? At which point we could just fix that more normally.

src/plasmaquick/dialog.cpp
1179

what's this about?

mart added a comment.Jun 21 2017, 11:11 AM

so, on the 5 points:

  1. yes, is necessary, 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, if it's the qpa, if it's qwindow, if it's the windowmanager doing that i have no idea, i have spent a week looking into that and really don't want to dive more in that spaghetti, more than accepting "qt wants sizes set before the showevent, move is fine" as a fact and adapting to it
  2. no it's not doing that anymore, all it changes is having syncToMainItemSize/updateLayoutParameters actually work when they are called with the window not visible, exactly because of 1)
  3. yeah, perhaps it should do it in a separate commit, and should be done everywhere a plasmashellsurface is used, or you will have wrong positions after hide/show that don't cause a moveevent
  4. as i explained in D6216, not strictly necessary, but avoids many bindings and resizes that happen when the window gets shown and hidden, that shouldn't be seen by the user anyways but useless never the less
  5. is done for a specific scenario (that is seen in the dbusnotificationtest manual test in knotifications) A notification is visible, and its content is replaced while still visible, so the actions gets removed, the window gets resized, all notifications gets rearranged, then actions populated again, window resized again, all notifications resized again. it is not strictly a bug, the whole procedure looks ugly and glitchy, especially if the number of actions after repopulating is the same, no resize or reposition of notifications should happen at all.
davidedmundson accepted this revision.Jun 21 2017, 11:15 AM
This revision is now accepted and ready to land.Jun 21 2017, 11:15 AM
mart edited the summary of this revision. (Show Details)Jun 21 2017, 11:26 AM
mart edited the test plan for this revision. (Show Details)
This revision was automatically updated to reflect the committed changes.