enables a mask for the panel which can be used from
transparent panels in order to set their working and
shown area.
It is very important in cases of panels that do not want
to break their animations by changing the panel's size
all the time
Details
- Reviewers
davidedmundson - Group Reviewers
Plasma
Diff Detail
- Repository
- R120 Plasma Workspace
- Branch
- mask2
- Lint
No Linters Available - Unit
No Unit Test Coverage
One thing to be careful of:
The code in Qt is:
void QWindow::setMask(const QRegion ®ion) { Q_D(QWindow); if (!d->platformWindow) return; d->platformWindow->setMask(QHighDpi::toNativeLocalRegion(region, this)); d->mask = region; }
So if you call setMask, before you call show() this will fail.
I'm not sure what order that startup happens, and whether this will break if you have an autohide panel.
You might need to copy the line
QWindow::setMask into PanelView::showEvent
Also, to save anyone else also looking this up
QWindow::setMask does work on Wayland. On the QPA side anyway.
So if you call setMask, before you call show() this will fail.
by fail, you mean it wont work right (not crashing)?
I have tested the code with my dock because i call the setMask many times
during animations.... I will have to see what happens when
it is set only once in the beginning...
I'm not sure what order that startup happens, and whether this will break if you have an autohide panel.
I will check it to see...
So if you call setMask, before you call show() this will fail.
I'm not sure what order that startup happens, and whether this will break if you have an autohide panel.
You might need to copy the line
QWindow::setMask into PanelView::showEvent
David I updated the revision for the showEvent case...
You were right concerning the case that if the user sets the mask before showing the mask didnt make any changes...
I tested it like this:
in my Component.onCompleted of my dock I set a maskArea and I disabled any further updates of the mask
afterwards...
before the new revision this mask was not taken into account...
after the new revision the mask that was set is applied correctly...
concerning the auto-hide panels they are behaving in the same way like the rest (Windows can cover etc...)
I added the check "!m_maskArea.isNull()" in order to protect cases that the mask hasnt be set at all...
i kindof like it (snapping of windows will always be wrong but i don't think there is anything that can be done about) tough i would try passing qregions instead, in case an implementation wants something with a fancy shape
shell/panelview.h | ||
---|---|---|
85 | while you're at you could use a qregion instead (iirc passing both a simple rectangle or an Array of rectangles works with qml |
looking more into it, i see that qregions are not directly supported by qml, it should become a qvariantlist of rectangles, that's quite ugly, so scratch that.
another thing, even if the input mask is correct, it would still not work correctly: both window maximizing and snapping would go to the real geometry of the window, making the "trick" obvious. window maximization could be fixed by setting different struts, but that would *not* work on wayland.
An alternative approach for the parabolic zoom of your dock I tought instead is doing in a similar way of plasma mobile (for its top, pull-down slide panel):
- the panel would have the "real" geometry, always "small"
- when the mouse goes over it, another window that is not the panel appears (i think it would be either a dock window or a bypasswindowmanagerhit one) it may either be a fullscreen window or just the size of the maximum extent the icons would zoom
- the icon list gets reparented in the new window, tough positioned exactly over the panel actual geometry
- now it can animate and zoom where it wants, anywhere in the screen
- when the cursor goes away the icons area, the icons animate to small again, then gets reparented to the real panel again, the second window gets hidden again
Isnt possible for kwin to take into account the mask used in the panel in order to provide correct maximizing and snapping?
One more point, the issue for the maximizing and snapping refers only to "Always Visible" panel state, the other three states "Windows can Cover, Autohide etc." do not have any issue... Most of my dock users do not use at all "Always Visible" state... Most of them use "Below Active" state which is not supported yet (I was hoping that I will make a patch for this in the future) and they live happilly with "Windows Can Cover".
An alternative approach for the parabolic zoom of your dock I tought instead is doing in a similar way of plasma mobile (for its top, pull-down slide panel):
- the panel would have the "real" geometry, always "small"
- when the mouse goes over it, another window that is not the panel appears (i think it would be either a dock window or a bypasswindowmanagerhit one) it may either be a fullscreen window or just the size of the maximum extent the icons would zoom
- the icon list gets reparented in the new window, tough positioned exactly over the panel actual geometry
- now it can animate and zoom where it wants, anywhere in the screen
- when the cursor goes away the icons area, the icons animate to small again, then gets reparented to the real panel again, the second window gets hidden again
I am not that sure about the above...
- how fast can all this be in order to catch up and not create glitches?
- how from my qml container will be able to disable blur and contrast effects for this window and how this window will know the x,y coordinates of the panel(dock) in the screen?
So, do you have concluded that this patch isnt going to be accepted in Plasma?
as far i know, no
One more point, the issue for the maximizing and snapping refers only to "Always Visible" panel state, the other three states "Windows can Cover, Autohide etc." do not have any issue... Most of my dock users do not use at all "Always Visible" state... Most of them use "Below Active" state which is not supported yet (I was hoping that I will make a patch for this in the future) and they live happilly with "Windows Can Cover".
windows can cover have problem with snapping as well.
- now it can animate and zoom where it wants, anywhere in the screen
- when the cursor goes away the icons area, the icons animate to small again, then gets reparented to the real panel again, the second window gets hidden again
I am not that sure about the above...
- how fast can all this be in order to catch up and not create glitches?
I don't know: only way would be trying it (preferably with a small test case before going full scale)
on plasma mobile seems to work quite well. (worst case scenario this external window would be always visible?
- how from my qml container will be able to disable blur and contrast effects for this window and how this window will know the x,y coordinates of the panel(dock) in the screen?
probably you would have to write your own c++ part that would register a c++ based qquickwindow subclass that would do all you need to make the thing seamless enough
(if your c++ implementation has pointers to the object you need to reparent and its normal parent, then tracking the real panel geometry is easy)
So, do you have concluded that this patch isnt going to be accepted in Plasma?
the thing is: in itself kindof makes sense, but i think that following this approach is technically impossible to arrive to something that works well enough, since there is no way to make the window manager to play well enough with windows with a "fake" size.
I think a different way should be tried beforehand.
this is true, I have just checked it...
- now it can animate and zoom where it wants, anywhere in the screen
- when the cursor goes away the icons area, the icons animate to small again, then gets reparented to the real panel again, the second window gets hidden again
I am not that sure about the above...
- how fast can all this be in order to catch up and not create glitches?
I don't know: only way would be trying it (preferably with a small test case before going full scale)
on plasma mobile seems to work quite well. (worst case scenario this external window would be always visible?
I dont think so but I cant even imagine... so many corner cases that I can not think of... Taking the fact that plasmoids are animated and open other windows also e.g. the compact represation case...
- how from my qml container will be able to disable blur and contrast effects for this window and how this window will know the x,y coordinates of the panel(dock) in the screen?
probably you would have to write your own c++ part that would register a c++ based qquickwindow subclass that would do all you need to make the thing seamless enough
(if your c++ implementation has pointers to the object you need to reparent and its normal parent, then tracking the real panel geometry is easy)the thing is: in itself kindof makes sense, but i think that following this approach is technically impossible to arrive to something that works well enough, since there is no way to make the window manager to play well enough with windows with a "fake" size.
I think a different way should be tried beforehand.
I can understand the concerns but being honest... I think that this is a lot above my programming expertise and taking the fact how many things must be adjusted by the fact that this is going to be a fake panel above a real panel, it looks enormous and advance for me... Exhausted only to think it...
I will probably leave it that way if anyone wants to try any future roadmaps...
only advice i can give is, don't get discouraged :)
btw, i tried to hack up very quickly something
http://notmart.org/misc/org.kde.hackypanel.tar.bz2
and seems to work quite good, even if not perfect
the advantage is that would use all the native controls for sizing the panel, sizing the icons in the panel etc, the bigger window would just be a presentation
I am... :) but we will see...
I tried to create my own libnowdock in order to follow your suggestions
but by trying to use it in my qml with:
import org.kde.nowdock 0.1
I get the following error:
file:///usr/share/plasma/plasmoids/org.kde.store.nowdock.panel/contents/ui/main.qml:28:1: plugin cannot be loaded for module "org.kde.nowdock": Plugin verification data mismatch in '/usr/lib64/qt5/qml/org/kde/nowdock/libnowdockplugin.so'
do you have any ideas?
Martin I managed to subclass the QmlWindow and add it in my dock... But the reparenting doesnot work for me as I would like to.. The best way to use it is to use my QmlWindow to show all the time the contents of the panel. But in that case the underneath panel window is messing the experience all the time...
Do you know if there is any way to access the Panel's main QWindow from my c++ code?
not sure about that, in that case its geometry should follow the one of the panel closely except expanding when needed, but i would not recomend that, i would go with reparenting to a fullscreen window and that's it
actuallly things are moving more than satisfying... :) the best solution for me is a window which has always the maximum ever needed geometry (for thickness and length). After that I use the maskArea in order to free up areas that are not needed. When the user unlocks the widgets then a reparenting gets into place and my applets are moved to the original panel in which the user can do anything he wants with them... When the widgets are locked again then a reparenting gets into place and are moved to my so called (magic window :) ) and I take special care is order to hide the plasma's panel.
Special care is also taken in order to provide for the magic Window the various visibility states (Windows can cover, Auto hide etc.) but this wasnt something so difficult, I even added two more states for the magic window (Below Active and Below Maximized) which are my favourites :) with beautiful sliding animations...
My only small problem is that I havent found a way to access the PanelView visibility variable in order to alter it automatically from my qml code or its c++ part. So the user must set correctly the Plasma Panel's visibility and my Magic Window visibility choice, especially in the "Always Visible" case...
when the user does "add panel" it executes a javascript file anyways no? so that js file can set up the needed default
Nice idea! That would help a lot!!
I tried in my layout javascript file to add:
panel.visibilityMode = 2;
//which corresponds to "LetWindowsCover" but didnt work, what did I miss?
things worked more than great for Now Dock with the technique you proposed Martin !!! :)
masking works great and I managed to support six different visibility states:
- Below Active (dock is behind only for the active window)
- Below Maximized (dock is behind only for the active, maximized window)
- Windows Cover
- Windows go Below
- Auto Hide (hiding the dock and its animations are updated even when hidden)
- Always Visible (support snapping with the help of the plasma panel's Always Visible state)
- beautiful sliding animation through qml for hiding/showing the panel when it is needed
the plugin is X centric but I believe when I obtain a Wayland session I will try to make it work also with KWayland with a little help... :)