Hide window on who is on position top left, after restore it is shown downside and so on. When it's on bottom left it start "move" on right Reproducible: Always Steps to Reproduce: 1. Hide window by click on item in systray 2. Restore it 3. It's position is lower Actual Results: Last window posistion is not saved correctly. Expected Results: Restore on las posistion
Systray != Taskbar. The window is destroyed and a new window is created by the client. It has no former position brand new window. The client would have to apply the geometry of the old window to the new one - and it looks like it's doing that wrongly, likely messing with the decorated geometry. Which client in particular?
All apps in systray do it wrong? I don't believe that.
http://tinypic.com/player.php?v=6z08sg%3E&s=9 If not KWin redirect bug to kf, but cannot all clients to have same bugs 'magically'
it does completely not matter what you "believe" and you did not specify "all". the clients destroy and create new windows and demand a new position when closed to the systray, that is fundamentally different from minimize/restore) i will check whether kwin systematically sets off the position (walking windows bug again?, because when adding the decoration), but the window would then immediately walk downright. not down, then right. please log the output of "qdbus org.kde.KWin /KWin supportInformation" so we can see your deco config.
Both walking window tests pass. It's not kwin. => Please provide a complete list of clients where this happens otherwise I won't be able to look what's going on.
Definitly not all, my fault. Kmail, akregator, amarok
No problem, we get "systray does not restore position" bugreports twice a year and it's always the client (so I simply close them - usually it's dropbox or skype ;-) The bug is in void KStatusNotifierItemPrivate::minimizeRestore(bool show) ... associatedWidget->move(info.frameGeometry().topLeft()); // avoid placement policies => the client is supposed to be placed at the client position, not at the decorated position. The WM needs to add the decoration and keep the decorated client where it is (if this is possible by other constraints) => Please move the client to where it is or simply set the Qt::WA_Moved flag (latter should be sufficient, but the Qt5 surface abstraction might have screwed it, didn't recently test)
So - associatedWidget->move(info.frameGeometry().topLeft()); // avoid placement policies + associatedWidget->move(info.geometry().topLeft()); // avoid placement policies ?
Correct it for 5.18, please.
5.18 is already released, 5.19 would be the earliest. @Thomas, is comment #8 all that is needed?
i don't recall the code, but if the wininfo isn't required otherwise, you can omit it. the widget should still have the proper geometry and Qt::WA_Moved will (hopefully still) make Qt ask the WM to not move it elsewhere. in either case qwidget still has the proper geometry. sorry for forgetting to keep myself attached :-(
Actually™ you should not have to explicitly set the current geometry, QWidget::show() should do that automagically if the widget was ever moved (by the client code or the user) - also works for me (but *not* tested on KNotifications explicitly)
Any results here?
> Any results here? No. @Thomas > Actually™ you should not have to explicitly set the current geometry I did some testing - if I remove this call completely, the placement is fully random from what I can tell. if I simply replace info.frameGeometry().topLeft() with info.topLeft(), it still gets restored to a different position. Apparently this is to some extent due to having QT_DEVICE_PIXEL_RATIO=2 as the widget geometry is exactly half of what KWindowInfo reports, therefore simply telling the QWidget to move to KWindowInfo geometry moves it twice as much. But not just that, I've tried something like associatedWidget->move(info.geometry().topLeft().x() / 2, info.geometry().topLeft().y() / 2); but it would still restore it by some random pixels off. What does, however, seems to restore it properly is this: associatedWidget->windowHandle()->setX(info.geometry().topLeft().x() /2); associatedWidget->windowHandle()->setY(info.geometry().topLeft().y() /2); ...where the "/2" should obviously be replaced by QT_DEVICE_PIXEL_RATIO. But now tell me if this is a good and/or valid fix.
What if you explicity associatedWidget->setAttribute(Qt::WA_Moved); (the individual sets will likely cause this whereas the combined one will figure it's no effective change and shortcut exit) The QT_DEVICE_PIXEL_RATIO situation is kinda worrysome. KWindowSystem deals with real pixels (and I doubt we can just change that, we don't know the source of the calculation), so either this is the expected behavior for toplevel widget actions or a bug in Qt (while it makes absolutely sense for internal widgets, global positioning is usually driven by outside values which do not related to the locals environment)
> associatedWidget->setAttribute(Qt::WA_Moved); Should just this be in or with some of the other lines? This standalone puts it always to the bottom-left corner of my screen. > KWindowSystem deals with real pixels Yeah which means that the widget either needs to be move to real pixels (ie. apply the device pixel ratio) or the window needs to be moved externally by something else.
This alone should do (and not even be required), but I guess there there's more to it in the SNI case, like the widget being destroyed and recreated (so you've not moved this widget at all, but just told the WM to believe so) In the latter case you could either carry over the last position (and move it in QWidget geometries, sth. like ie. oldPosition = oldWidget->pos(); .... QWidget *newWidget = new QWidget; newWidget->move(oldPosition); newWidget->show(); --- "Something else™" cannot move the widget as eg. the WM doesn't know that this window has been there before (or that it should restore that former geometry)
How this works correctly before 5.15?
That's very likely some unrelated change, this code hasn't been altered for ages.
Either the window was undecorated or the call to the wininfo was made before it was decorated by the WM (in either case frameGeometry() and geometry() are equal) Why there's this complex code, also preserving the current desktop, is frankly beyond me - QWidget::hide() withdraws the X drawable, but doesn't destroy it - so properties like the VD and the geometry should be preserved; QWidget::hide() / QWidget::show() should™ really just work. The only thing I could imagine is that the client code in addition nukes the widget (destroying the drawable) and adds a new associate (w/o caring about former properties) - however then also the X properties (KWinInfo geometry) should be nonsense... My uninformed suggestion was to explicitly store the position QWidget::pos() like the virtual desktop and restore to that QPoint *shrug*
*** Bug 360826 has been marked as a duplicate of this bug. ***
*** Bug 360948 has been marked as a duplicate of this bug. ***
*** Bug 360949 has been marked as a duplicate of this bug. ***
Git commit 6198841710fb128987c308bd3ef3ff8cbd294ce0 by Anthony Fieroni. Committed on 03/12/2016 at 06:50. Pushed by anthonyfieroni into branch 'master'. [KStatusNotifierItem] Save / restore widget position during hide / restore it window REVIEW: 127216 Signed-off-by: Anthony Fieroni <bvbfan@abv.bg> M +24 -5 src/kstatusnotifieritem.cpp M +1 -0 src/kstatusnotifieritemprivate_p.h https://commits.kde.org/knotifications/6198841710fb128987c308bd3ef3ff8cbd294ce0
*** Bug 372056 has been marked as a duplicate of this bug. ***