Skip to content

Commit d34b765

Browse files
committed
Fix: Optimize tooltip positioning logic.
Log: The Popup is rendered on the window's Overlay layer and is not part of the content visual tree. As a result, the tooltip does not follow its anchor item during scrolling or window resizing, causing positional drift. To resolve this, AlertToolTip has been changed from a ToolTip (which uses Popup) to a regular Item, making it part of the content visual tree. This ensures it naturally scrolls with its parent, respects container clipping, and maintains correct positioning at all times. PMS: bug-341973
1 parent 95a2c37 commit d34b765

2 files changed

Lines changed: 64 additions & 47 deletions

File tree

qt6/src/qml/AlertToolTip.qml

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,35 @@ import QtQuick
66
import org.deepin.dtk 1.0 as D
77
import org.deepin.dtk.style 1.0 as DS
88

9-
ToolTip {
9+
// Use Item instead of ToolTip(Popup) so it stays in the visual tree,
10+
// scrolls with content and gets clipped properly.
11+
Item {
1012
id: control
1113
property Item target
14+
property string text
15+
property alias font: contentText.font
16+
property int timeout: 0
1217

1318
x: 0
1419
y: target ? target.height + DS.Style.control.spacing : 0
15-
topPadding: DS.Style.alertToolTip.verticalPadding
16-
bottomPadding: DS.Style.alertToolTip.verticalPadding
17-
leftPadding: DS.Style.alertToolTip.horizontalPadding
18-
rightPadding: DS.Style.alertToolTip.horizontalPadding
19-
implicitWidth: Math.min(DS.Style.control.implicitWidth(control), target.width)
20-
implicitHeight: DS.Style.control.implicitHeight(control)
21-
margins: 0
22-
closePolicy: Popup.NoAutoClose
20+
z: D.DTK.TopOrder
2321

24-
background: FloatingPanel {
22+
readonly property real __naturalWidth: Math.max(DS.Style.alertToolTip.width,
23+
contentText.implicitWidth + DS.Style.alertToolTip.horizontalPadding * 2)
24+
implicitWidth: target ? Math.min(__naturalWidth, target.width) : __naturalWidth
25+
implicitHeight: Math.max(DS.Style.alertToolTip.height,
26+
contentText.implicitHeight + DS.Style.alertToolTip.verticalPadding * 2)
27+
width: implicitWidth
28+
height: implicitHeight
29+
30+
Timer {
31+
interval: control.timeout
32+
running: control.timeout > 0 && control.visible
33+
onTriggered: control.visible = false
34+
}
35+
36+
FloatingPanel {
37+
anchors.fill: parent
2538
radius: DS.Style.alertToolTip.radius
2639
implicitWidth: DS.Style.alertToolTip.width
2740
implicitHeight: DS.Style.alertToolTip.height
@@ -30,33 +43,27 @@ ToolTip {
3043
outsideBorderColor: DS.Style.alertToolTip.outsideBorder
3144
}
3245

33-
contentItem: Text {
46+
Text {
47+
id: contentText
3448
property D.Palette textColor: DS.Style.alertToolTip.text
49+
anchors.fill: parent
50+
anchors.topMargin: DS.Style.alertToolTip.verticalPadding
51+
anchors.bottomMargin: DS.Style.alertToolTip.verticalPadding
52+
anchors.leftMargin: DS.Style.alertToolTip.horizontalPadding
53+
anchors.rightMargin: DS.Style.alertToolTip.horizontalPadding
3554
horizontalAlignment: Text.AlignLeft
3655
verticalAlignment: Text.AlignVCenter
3756
text: control.text
38-
font: control.font
3957
color: D.ColorSelector.textColor
4058
wrapMode: Text.Wrap
4159
}
4260

43-
enter: Transition {
44-
// TODO: Transparency causes tooltips to appear through the window background - temporarily removed
45-
// NumberAnimation { properties: "opacity"; from: 0.0; to: 1.0; duration: 200 }
46-
NumberAnimation { properties: "y"; from: control.target.height; to: control.target.height + DS.Style.control.spacing; duration: 200 }
47-
}
48-
49-
exit: Transition {
50-
// NumberAnimation { properties: "opacity"; from: 1.0; to: 0.0 }
51-
NumberAnimation { properties: "y"; from: control.target.height + DS.Style.control.spacing ; to: control.target.height }
52-
}
53-
5461
BoxShadow {
5562
id: line
5663
property D.Palette dropShadowColor: DS.Style.alertToolTip.connecterdropShadow
5764
property D.Palette backgroundColor: DS.Style.alertToolTip.connecterBackground
5865
property D.Palette borderColor: DS.Style.control.border
59-
y: - height * (0.75) - control.topMargin - control.topPadding
66+
y: - height * (0.75)
6067
width: DS.Style.alertToolTip.connectorWidth
6168
height: DS.Style.alertToolTip.connectorHeight
6269
shadowBlur: 4

src/qml/AlertToolTip.qml

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,36 @@ import QtQuick 2.11
66
import org.deepin.dtk.impl 1.0 as D
77
import org.deepin.dtk.style 1.0 as DS
88

9-
ToolTip {
9+
// Use Item instead of ToolTip(Popup) so it stays in the visual tree,
10+
// scrolls with content and gets clipped properly.
11+
Item {
1012
id: control
1113
property Item target
14+
property string text
15+
property alias font: contentText.font
16+
property int timeout: 0
1217

1318
x: 0
14-
topPadding: DS.Style.alertToolTip.verticalPadding
15-
bottomPadding: DS.Style.alertToolTip.verticalPadding
16-
leftPadding: DS.Style.alertToolTip.horizontalPadding
17-
rightPadding: DS.Style.alertToolTip.horizontalPadding
18-
implicitWidth: Math.min(DS.Style.control.implicitWidth(control), target.width)
19-
implicitHeight: DS.Style.control.implicitHeight(control)
20-
margins: 0
21-
closePolicy: Popup.NoAutoClose
19+
y: target ? target.height + DS.Style.control.spacing : 0
20+
z: 100
21+
22+
readonly property real __naturalWidth: Math.max(DS.Style.alertToolTip.width,
23+
contentText.implicitWidth + DS.Style.alertToolTip.horizontalPadding * 2)
24+
implicitWidth: target ? Math.min(__naturalWidth, target.width) : __naturalWidth
25+
implicitHeight: Math.max(DS.Style.alertToolTip.height,
26+
contentText.implicitHeight + DS.Style.alertToolTip.verticalPadding * 2)
27+
width: implicitWidth
28+
height: implicitHeight
29+
30+
Timer {
31+
interval: control.timeout
32+
running: control.timeout > 0 && control.visible
33+
onTriggered: control.visible = false
34+
}
35+
36+
Item {
37+
anchors.fill: parent
2238

23-
background: Item {
2439
BoxShadow {
2540
anchors.fill: _background
2641
shadowBlur: 20
@@ -40,30 +55,25 @@ ToolTip {
4055
}
4156
}
4257

43-
contentItem: Text {
58+
Text {
59+
id: contentText
4460
property D.Palette textColor: DS.Style.alertToolTip.text
61+
anchors.fill: parent
62+
anchors.topMargin: DS.Style.alertToolTip.verticalPadding
63+
anchors.bottomMargin: DS.Style.alertToolTip.verticalPadding
64+
anchors.leftMargin: DS.Style.alertToolTip.horizontalPadding
65+
anchors.rightMargin: DS.Style.alertToolTip.horizontalPadding
4566
horizontalAlignment: Text.AlignLeft
4667
verticalAlignment: Text.AlignVCenter
4768
text: control.text
48-
font: control.font
4969
color: D.ColorSelector.textColor
5070
wrapMode: Text.Wrap
5171
}
5272

53-
enter: Transition {
54-
NumberAnimation { properties: "opacity"; from: 0.0; to: 1.0; duration: 200 }
55-
NumberAnimation { properties: "y"; from: control.target.height; to: control.target.height + DS.Style.control.spacing; duration: 200 }
56-
}
57-
58-
exit: Transition {
59-
NumberAnimation { properties: "opacity"; from: 1.0; to: 0.0 }
60-
NumberAnimation { properties: "y"; from: control.target.height + DS.Style.control.spacing ; to: control.target.height }
61-
}
62-
6373
BoxShadow {
6474
property D.Palette dropShadowColor: DS.Style.alertToolTip.connecterdropShadow
6575
property D.Palette backgroundColor: DS.Style.alertToolTip.connecterBackground
66-
y: - height * (0.75) - control.topMargin - control.topPadding
76+
y: - height * (0.75)
6777
width: DS.Style.alertToolTip.connectorWidth
6878
height: DS.Style.alertToolTip.connectorHeight
6979
shadowBlur: 4

0 commit comments

Comments
 (0)