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

Gui: Fix document tree background rendering with overlay (Qt6) #13807

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

kadet1090
Copy link
Contributor

@kadet1090 kadet1090 commented May 2, 2024

Warning

I don't have ability to build FreeCAD with Qt5 right now. So I need someone to test if this solution works with Qt5. To test it use patched OpenLight: obelisk79/OpenTheme#30

You can checkout it from your ~/.local/share/FreeCAD/Mod/OpenTheme directory using:

git fetch origin pull/30/head:qt6-workaround
git checkout qt6-workaround

This aims to fix rendering of tree view items in Qt6. While I don't belive that this is a good way to fix this, I am worried that it is the only way to do it.

BC BREAK: This change introduces artificial QTreeView widget that can be targeted using QSS and can be used in the delegate for painting background of items. QTreeView::item would now be used to render background for the whole row, while each cell can be targeted using #DocumentTreeItems selector.

I managed to find a hacky solution to this problem. To disable rendering of the background I can abuse this if statement in Qt:

        // For compatibility reasons, QTreeView draws different parts of
        // the background of an item row separately, before calling the
        // delegate to draw the item. The row background of an item is
        // however not separately styleable through a style sheet, but
        // only indirectly through the background of the item. To get the
        // same background for all parts drawn by QTreeView, we have to
        // use the background rule for the item here.
        if (renderRule(w, opt, PseudoElement_ViewItem).hasBackground())
            pseudoElement = PseudoElement_ViewItem;

So disabling background for ::item disables rendering of branches and not-wanted background (I'm using qtsass):

  QTreeView::item {
    &, &:selected, &:hover {
      background: none;
      border: none;
    }
  }

This however denies me from defining background in qss. But as a workarond I create artificial QTreeView widget inside the delegate with some well defined object name, DocumentTreeItems in my case:

TreeWidgetItemDelegate::TreeWidgetItemDelegate(QObject* parent)
    : QStyledItemDelegate(parent)
{
    artificial = new QTreeView(qobject_cast<QWidget*>(parent));
    artificial->setObjectName("DocumentTreeItems");
    artificial->setFixedSize(0, 0);
}

Thanks to that I can attach styles to this widget inside qss:

  #DocumentTreeItems::item {
    border: 1px solid transparent;
    border-radius: 2px;
    background-color: $primaryBackground;

    &:hover {
      border: 1px solid $contrastBorder;
      background-color: $controlWidgetBackground;
    }

    &:selected {
      border: 1px solid $accentBorder;
      background-color: $accentBackground;
    }
  }

Then I can repaint the background using style and referring to my artificial widget in the paint method of delegate:

    style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, artificial);

This gives the expected result:

enter image description here

I'm however deeply dissatisfied with this solution, so if anyone knows a better one I'd be glad to hear suggestions.

Fixes: #13760

@github-actions github-actions bot added the Core Issue or PR touches core sections (App, Gui, Base) of FreeCAD label May 2, 2024
@kadet1090 kadet1090 marked this pull request as draft May 2, 2024 22:34
@chennes chennes self-requested a review May 3, 2024 00:18
@kadet1090 kadet1090 force-pushed the qt6-tree-rendering branch 3 times, most recently from 324c988 to f653486 Compare May 5, 2024 20:30
This aims to fix rendering of tree view items in Qt6. While I don't
belive that this is a good way to fix this, I am worried that it is the
only way to do ir.

BC BREAK: This change introduces artificial QTreeView widget that can be
targeted using QSS and can be used in the delegate for painting background of
items. `QTreeView::item` would now be used to render background for the
whole row, while each cell can be targeted using `#DocumentTreeItems`
selector.

More details on implementation:
https://stackoverflow.com/questions/78414383/qt6-disable-drawing-of-default-background-for-qtreeview-items/78421604#78421604

Fixes: FreeCAD#13760
@kadet1090 kadet1090 marked this pull request as ready for review May 5, 2024 20:31
@FEA-eng
Copy link
Contributor

FEA-eng commented May 13, 2024

All those disclaimers and warnings are worrying but if it's the only solution to this nasty issue for now then it might be worth applying it before the next release. If someone finds a better way, it can always be implemented in place of this one.

@chennes
Copy link
Member

chennes commented May 16, 2024

Here's what I see in the tree with this PR on Qt5 (I see basically the same strange truncation regardless of the overlay state or theme applied).

Screenshot 2024-05-16 at 3 03 59 PM

@kadet1090
Copy link
Contributor Author

Ok, I can confirm this issue - I thought that it was present before but it seems not. As a workaround you can extend the first column of the tree view to be big enough to be big enough. Can you test it with the style mentioned in the description of the background gets applied?

I will fix the issue before next merge meeting as I am able to reproduce it.

@chennes
Copy link
Member

chennes commented May 16, 2024

Yes, the background is applied correctly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Core Issue or PR touches core sections (App, Gui, Base) of FreeCAD
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Qt6: Rendering of overlay TreeView is broken
3 participants