Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug when using CDockManager within CDockWidget #685

Closed
cshnik opened this issue Dec 10, 2024 · 5 comments
Closed

Bug when using CDockManager within CDockWidget #685

cshnik opened this issue Dec 10, 2024 · 5 comments

Comments

@cshnik
Copy link

cshnik commented Dec 10, 2024

There is a bug we found in our project when using dock panes (aka CDockWidget) as a parent for CDockManager.
Please consider the following scenario:

  1. Dock pane (on top level of application, aka TLDP) represent specific object and contains corresponding set of tools (which are actually nested dock panes, aka NDP).
  2. User is allowed to switch between TLDPs when working with different objects which activates its NDPs.
  3. Floating NDPs are also get shown/hidden when switching between TLDPs. This was addressed in Hide the DockManager does not hide the floating widgets #380

The actual problem is: when user activate floating NDP, switch to foreign TLDP2 and then switch back to TLDP1 QtAds subsystem get broken:

  1. Floating NDP is displayed incorrectly as a child of TLDP1 in wrong position (out of visible area, need to scroll to find it) and is not available for relocation.
  2. Overlay objects are not displayed when trying to move foreign NDPs in the same TLDP1 (available areas are not highlighted on the screen).
  3. There are multiple errors displayed in the output:
UpdateLayeredWindowIndirect failed for ptDst=(666, 182), size=(647x684), dirty=(647x684 0, 0) (The parameter is incorrect.)

The actual reason is incorrect switching between TLDPs within CDockAreaWidget::setCurrentIndex:

            LayoutItem->widget()->setParent(nullptr);

This code internally caused changing of the top-level parent for floating dock panes (CFloatingDockContainer) and overlay objects (CDockOverlay).
We locally patched the code by replacing this line and the issue has gone:

            m_ParentLayout->removeWidget(LayoutItem->widget());

Probably the same issue may occur due to the line LayoutItem->widget()->setParent(nullptr) in CDockAreaWidget::removeWidget(QWidget* Widget) but we don't have such a use case in our project.

Demo for the issue:

nestedmanager-bug.mp4

Behavior with the patched QtAds build:

nestedmanager-fixed-QtAds.mp4
cshnik added a commit to cshnik/Qt-Advanced-Docking-System that referenced this issue Dec 10, 2024
@cshnik
Copy link
Author

cshnik commented Dec 10, 2024

We also created nestedmanagers example project to let you easily reproduce the issue.
Please confirm if this use-case and the fix looks reasonable for you.

@githubuser0xFFFF
Copy link
Owner

Thank you for reporting a bug. Nesting dock managers or adding a dock manager to a dock widget is not an official feature of ADS. The nestedmanagers example is just a proof of concept what it is possible. If you would like to nest dock managers or use it this way, then you need to fix any issues by yourself - sorry.

@cshnik
Copy link
Author

cshnik commented Dec 11, 2024

Please note the following: QtAds is currently not compatible with layered widgets created within dock panes since the problem will be absolutely the same.

Here are some points:

  1. Applying hidden state for dock pane in ‎CDockAreaLayout::setCurrentIndex via
    setParent(nullptr) will internally reset transient parent for layered widget:

image

  1. Once this dock pane will be activated again the widgets hierarchy get broken when assigning new parent for this layered widget (due to internal Qt reparenting logic):

image

  1. Here is the difference on the layered widget position in the windows hierarchy before and after steps 1 & 2 which explain the reason of the incorrect behavior:

image

@githubuser0xFFFF
Copy link
Owner

What do you mean with layered widgets? Could you please elaborate?

@cshnik
Copy link
Author

cshnik commented Dec 11, 2024

Assume someone would love to use fancy semitransparent top-level widget to display some info. This widget is tied to specific dockpane/widget.
Here is an example how it works with regular tabs:

fancy-ticket-in-tabs.mp4

And how it works with dockpanes in QtAds:

fancy-ticket-in-docks.mp4

The following test demonstrates how the patch from above affects QtAds behavior:

fancy-ticket-in-fixed-docks.mp4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants