githubuser0xFFFF / Qt-Advanced-Docking-System

Advanced Docking System for Qt

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Linux: Dark window when dragging if compositing is disabled in window manager

juangburgos opened this issue · comments

Hi,

I am using the library in the QUaModbusClient open source project. I have tested on Windows ans CentOS and all fine. I have tried on Lubuntu and it seems there is some issue when dragging over a detached dock into a Layout.

image

Has something similar happened to anybody? Is it an OS issue or a library issue?

Thanks

Could you please elaborate what the exact issue is? Is the problem reproducible with the demo application.

Which QT version do you use and what are your global dock manager configuration flags?

Hi,

Yes, the issue is reproducible with the latest binary available here (AppImage).

Qt version is 5.12.3. I do not use any specific global dock manager configuration flags, I just ise the library as shipped by the github repo (it is actually included in the project as a Git submodule).

Best,

I mean, is the problem reproducible with thr ADS demo app.?

I would need to deploy it. Will come back to you on that.

@githubuser0xFFFF I can reproduce this issue with the latest code and demo app.
With Linux when dragging the dock I get a black overlay over the whole application. When the dock is docked it goes away.

It is not a generic Linux issue. I tested it on Ubuntu 19.10 an Kubuntu 18.04 and it works. According to another user this problem occurs, if compositing is deactivated in Linux.

@hhslepicka Which Linux distro do you use?

@juangburgos Can you please tell me which Lubuntu version you use?

I use RHEL 6 & 7

This issue is caused by disabled compositing via the window manager.
https://doc.qt.io/qt-5/qwidget.html#creating-translucent-windows

Creating Translucent Windows
Since Qt 4.5, it has been possible to create windows with translucent regions on window systems that support compositing.
To enable this feature in a top-level widget, set its Qt::WA_TranslucentBackground attribute with setAttribute() and ensure that its background is painted with non-opaque colors in the regions you want to be partially transparent.
Platform notes:
X11: This feature relies on the use of an X server that supports ARGB visuals and a compositing window manager.
Windows: The widget needs to have the Qt::FramelessWindowHint window flag set for the translucency to work.

My current setup is running Xfwm4 as a window manager, because it allows me to easily enable/disable compositing via the following command: xfconf-query -c xfwm4 -p /general/use_compositing -s false.
If compositing is disabled, I get the following result in the demo application when dragging around a DockWidget:
issue-95
This behavior is caused by the QWidget background set to be translucent.

Qt allows for checking if compositing is running or not with bool QX11Info::isCompositingManagerRunning() documentation
A workaround could utilize the following statement:

#ifdef Q_WS_X11
    if(QX11Info::isCompositingManagerRunning())
        setAttribute(Qt::WA_TranslucentBackground);
#endif

For now I came up with two workarounds for the disabled compositing issue:

  1. Use QRegion similar as in the Shaped Clock example to not rely on translucent QWidget. A drawback would be the missing transparency on the drop regions. Maybe it is possible to use a different pattern on the QBrush to achieve a sort of see through look.
  2. Use a screenshot of the MainWindow as the background of the DockOverlay. The drawback is that the background would be static as long as the drag operation is ongoing.

Sorry, I was AFK on holidays. My experience looks the same as for @iam-peter on Lubuntu 19.10.

@iam-peter Thank you for the detailed analysis and the two proposed solutions.

The second solution sounds good. Because docking is possible in all floating widgets, I think taking a sceenshot of the MainWindow is not enough. I could imagine the following flow:

  1. Hide the current overlay to prevent its visibility on the screenshot in the next step
  2. Take a screenshot of the whole screen and copy the part that will be covered by the overlay or create a screenshot of just the part the will be covered by the overlay.
  3. Create a bitmap that is a merge of the captured screenshot and the colored overlay.
  4. Set this bitmap as background for the DockOverlay
  5. Show the DockOverlay

For the floating DropPreview I would simply deactivate transparency.

I have thought about the topic again and I think the solution I suggested above does not work that way.

Because the overlay is in front of the dragged widget, the floating widget will be behind the overlay and because the overlay will display a screenshot of the DockContainer beneath it looks like the dragged widget will be behind the DockContainer. In the animated screenshot from above, the dragged widget is not visible and this will not change, if the overlay displays an image.

An option would be, to dynamically make the DockOverlay a child widget of the DockContainer / DockArea for which the overlay is provided. I just created a test. I added the following lines into the constructor of the Qt basiclayouts example:

QFrame* Overlay = new QFrame(this);
QColor color = this->palette().highlight().color();
color.setAlpha(64);
Overlay->setStyleSheet(QString("background: %1; border: 1px solid %2;").arg(color.name(QColor::HexArgb)).arg(color.name()));
Overlay->setGeometry(0, 0, this->width() / 2, this->height());
Overlay->show();

This is the result:
DockOverlay

This works without Qt::WA_TranslucentBackground.

Here comes the problem of this solution: the DockOverlayCross and the drop icons will be behind the dragged FloatingWidget. That means, if you drag the widget, it will hide the DockOverlayCross. But because the mouse position is almost in the top left corner of teh FloatingWidget, it should be possible to hit the right position.

@githubuser0xFFFF this seems like a good escape route in case composition is not available for the OS.
I would be more than happy to test a candidate fix for that.

@hhslepicka @iam-peter I create a new branch linux_no_compositing to implement a proof of concept of the idea I described above. You can checkout this branch, compile it and test the demo application. The branch shows, that the docking is not working as intended. Here are the problems:

  1. Because the dock overlay is now a child of the dock container / dock area, the dock overlay cross is limited by the geometry of the dock area. That means, for small dock areas, the dock area cross can not overlab the dock area:

DockOverlay

  1. If the target dock area is in a floating window, then the floating window will be stacked over the dragged window as soon as the dock overlay will be reparented to the floating dock area. That means the dragged window is behind the floating window - that looks really strange:

NoCompositingDock

So to summarize the results: making the dock overlay a child of the target dock area works partly but has to many issues to be a good workaround for linux systems with compositing disabled.

@githubuser0xFFFF thank you for pursuing the fix for this issue.
I just tested it in here and here are my findings:

Good Findings:

  • The black screen is gone

Bad Findings:

  • The main screen at the demo gets gray now instead of black and only sometimes I can see the docking areas but docking works.
  • When the screen is floating I can dock successfully into it as long as it is not over the main screen of the demo.

Other than the two items above the fix seems to be moving in the right direction I would say.

@githubuser0xFFFF did you have a chance to look at this issue some more?
Please let me know if you would like me to help with tests.

This issue ist not easy fixable and requires a lot of work. At the moment I do not have the time to fix this and I'm also not really happy to spend that much time because somewhere in some Linux distribution is compositing disabled.

I find that understandable. Maybe just mention a caveat in the main README of the repo for Linux mentioning that compositing must be enabled with some links on where to find information about enabling?

Then leave the issue open for help if somebody steps up with a contribution.

This is a good idea. But I cannot tell, how to enable compositing because I don'k know it and because I think it is different for different Linux distributions - or is there a generic way?

@githubuser0xFFFF I completely understand your point. No problem at all. We will look at our side how to enable Compositing. Feel free to close the issue.

Hi

I have the same issue with black screen on CentOS 6. The problem is because the overlay window is created as a borderless top level system window. It is probably the reason you rely on composite extension. Actually, I think the better approach is to create the overlay window (and cross window) as a child of the parent window. In this case parent window contents will appear as the background of the overlay window like it seems to be transparent. I tried to do it in my project and it seems I suceeded to fix it.

Hi,

great to hear that you suceeded fixing the issue. Would be great, if you could create a pull request for your changes so that I can test it. I already tested several solutions by myself like you can see in the messages above.

Hi,

Yes, but I have to fix a positional issue related to the change the parent of overlay widget. I briefly went through some comments. What you are proposed to use the screenshot of the background - it is a good way but you shouldn't do it yourself. Actually Qt already does it and there will be no issue with static background.

Hi,

Yes, but I have to fix a positional issue related to the change the parent of overlay widget. I briefly went through some comments. What you are proposed to use the screenshot of the background - it is a good way but you shouldn't do it yourself. Actually Qt already does it and there will be no issue with static background.

Merge request, merge request, merge request! 🙂

@juangburgos Vitaly created pull request #217 to fix this issue. Could you please test his fix?

@vitcpp Thank you Vitaly for the pull request

@juangburgos Have you tested the changes from Vitaly?

@iam-peter Hi Henning. Vitaly created pull request #217 to fix this issue. Would be great, if you could test this and give me some feedback if his solution works.

@iam-peter Hi Henning. Vitaly created pull request #217 to fix this issue. Would be great, if you could test this and give me some feedback if his solution works.

@githubuser0xFFFF I pulled the fork from Vitaly, deactivated compositing and it works.

I compiled QUaModbusClient with the master branch, and it is still rather un-usable in most Linux virtual machines:

func_error2

Yes, I know. Vitaly promised to fix this, but obviously he didn't succeed.

I close this issue because I'm not able to fix this and it does not seem important for other people to fix this.