mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
Merge branch 'noctalia-dev:main' into pr/networking-refactor-pt2
This commit is contained in:
+42
-64
@@ -741,7 +741,12 @@ Loader {
|
||||
onExited: {
|
||||
peekHovered = false;
|
||||
showTimer.stop();
|
||||
if (!hidden && !dockHovered && !anyAppHovered && !menuHovered) {
|
||||
if (isStaticMode) {
|
||||
// Start hideTimer which checks panel.isDockHovered before closing
|
||||
if (!dockHovered && !anyAppHovered && !menuHovered) {
|
||||
hideTimer.restart();
|
||||
}
|
||||
} else if (!hidden && !dockHovered && !anyAppHovered && !menuHovered) {
|
||||
hideTimer.restart();
|
||||
}
|
||||
}
|
||||
@@ -765,30 +770,8 @@ Loader {
|
||||
focusable: false
|
||||
color: "transparent"
|
||||
|
||||
property real targetIndicatorOffsetX: peekCenterOffsetX
|
||||
property real targetIndicatorOffsetY: peekCenterOffsetY
|
||||
property real animatedIndicatorOffsetX: targetIndicatorOffsetX
|
||||
property real animatedIndicatorOffsetY: targetIndicatorOffsetY
|
||||
|
||||
onTargetIndicatorOffsetXChanged: animatedIndicatorOffsetX = targetIndicatorOffsetX
|
||||
onTargetIndicatorOffsetYChanged: animatedIndicatorOffsetY = targetIndicatorOffsetY
|
||||
|
||||
Behavior on animatedIndicatorOffsetX {
|
||||
NumberAnimation {
|
||||
duration: Style.animationNormal
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on animatedIndicatorOffsetY {
|
||||
NumberAnimation {
|
||||
duration: Style.animationNormal
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
|
||||
margins.top: animatedIndicatorOffsetY
|
||||
margins.left: animatedIndicatorOffsetX
|
||||
margins.top: peekCenterOffsetY
|
||||
margins.left: peekCenterOffsetX
|
||||
|
||||
WlrLayershell.namespace: "noctalia-dock-indicator-" + (screen?.name || "unknown")
|
||||
WlrLayershell.layer: WlrLayer.Top
|
||||
@@ -797,19 +780,6 @@ Loader {
|
||||
implicitHeight: isVertical ? peekEdgeLength : indicatorThickness
|
||||
implicitWidth: isVertical ? indicatorThickness : peekEdgeLength
|
||||
|
||||
Behavior on implicitWidth {
|
||||
NumberAnimation {
|
||||
duration: Style.animationNormal
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
Behavior on implicitHeight {
|
||||
NumberAnimation {
|
||||
duration: Style.animationNormal
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: indicatorRect
|
||||
anchors.fill: parent
|
||||
@@ -863,21 +833,37 @@ Loader {
|
||||
WlrLayershell.namespace: "noctalia-dock-" + (screen?.name || "unknown")
|
||||
WlrLayershell.exclusionMode: exclusive ? ExclusionMode.Auto : ExclusionMode.Ignore
|
||||
|
||||
// Blur behind dock (User Interface → Blur behind)
|
||||
// Slide animation: content slides inside a fixed window, no margin animation
|
||||
property int slideDistance: (isVertical ? dockContainerWrapper.contentWidth : dockContainerWrapper.contentHeight) + floatingMargin + 10
|
||||
property real slideOffset: hidden ? slideDistance : 0
|
||||
|
||||
Behavior on slideOffset {
|
||||
NumberAnimation {
|
||||
duration: hidden ? hideAnimationDuration : showAnimationDuration
|
||||
easing.type: hidden ? Easing.InCubic : Easing.OutCubic
|
||||
}
|
||||
}
|
||||
|
||||
// Signed slide: positive pushes content toward its edge (off-screen)
|
||||
readonly property real slideX: dockPosition === "left" ? -slideOffset : dockPosition === "right" ? slideOffset : 0
|
||||
readonly property real slideY: dockPosition === "top" ? -slideOffset : dockPosition === "bottom" ? slideOffset : 0
|
||||
|
||||
// Blur behind dock — offset by slide so it follows the content
|
||||
BackgroundEffect.blurRegion: Settings.data.general.enableBlurBehind ? dockBlurRegion : null
|
||||
Region {
|
||||
id: dockBlurRegion
|
||||
Region {
|
||||
x: Math.round(dockContainerWrapper.mapFromItem(dockContent.dockContainer, 0, 0).x)
|
||||
y: Math.round(dockContainerWrapper.mapFromItem(dockContent.dockContainer, 0, 0).y)
|
||||
x: Math.round(dockContainerWrapper.x + dockContent.dockContainer.x + dockWindow.slideX)
|
||||
y: Math.round(dockContainerWrapper.y + dockContent.dockContainer.y + dockWindow.slideY)
|
||||
width: Math.round(dockContent.dockContainer.width)
|
||||
height: Math.round(dockContent.dockContainer.height)
|
||||
radius: Style.radiusL
|
||||
}
|
||||
}
|
||||
|
||||
implicitWidth: dockContainerWrapper.width
|
||||
implicitHeight: dockContainerWrapper.height
|
||||
// Window sized to fit content + slide distance so content can slide off-edge
|
||||
implicitWidth: dockContainerWrapper.width + (isVertical ? slideDistance : 0)
|
||||
implicitHeight: dockContainerWrapper.height + (!isVertical ? slideDistance : 0)
|
||||
|
||||
// Position based on dock setting
|
||||
anchors.top: dockPosition === "top"
|
||||
@@ -885,7 +871,7 @@ Loader {
|
||||
anchors.left: dockPosition === "left"
|
||||
anchors.right: dockPosition === "right"
|
||||
|
||||
// Offset past bar when at same edge (skip bar offset if dock is exclusive - exclusion zones stack)
|
||||
// Static margins — no animation, window stays put
|
||||
margins.top: dockPosition === "top" ? (barAtSameEdge && !exclusive ? barHeight + (Settings.data.bar.floating ? Settings.data.bar.marginVertical : 0) + floatingMargin : floatingMargin) : 0
|
||||
margins.bottom: dockPosition === "bottom" ? (barAtSameEdge && !exclusive ? barHeight + (Settings.data.bar.floating ? Settings.data.bar.marginVertical : 0) + floatingMargin : floatingMargin) : 0
|
||||
margins.left: dockPosition === "left" ? (barAtSameEdge && !exclusive ? barHeight + (Settings.data.bar.floating ? Settings.data.bar.marginHorizontal : 0) + floatingMargin : floatingMargin) : 0
|
||||
@@ -908,9 +894,13 @@ Loader {
|
||||
readonly property int extraLeft: (!isVertical && !exclusive && barOnLeft) ? barHeight : 0
|
||||
readonly property int extraRight: (!isVertical && !exclusive && barOnRight) ? barHeight : 0
|
||||
|
||||
// Expose content size for window sizing (before slide padding)
|
||||
readonly property int contentWidth: dockContent.dockContainer.width + extraLeft + extraRight + 2
|
||||
readonly property int contentHeight: dockContent.dockContainer.height + extraTop + extraBottom + 2
|
||||
|
||||
// Add +2 buffer for fractional scaling issues
|
||||
width: dockContent.dockContainer.width + extraLeft + extraRight + 2
|
||||
height: dockContent.dockContainer.height + extraTop + extraBottom + 2
|
||||
width: contentWidth
|
||||
height: contentHeight
|
||||
|
||||
anchors.horizontalCenter: isVertical ? undefined : parent.horizontalCenter
|
||||
anchors.verticalCenter: isVertical ? parent.verticalCenter : undefined
|
||||
@@ -920,27 +910,15 @@ Loader {
|
||||
anchors.left: dockPosition === "left" ? parent.left : undefined
|
||||
anchors.right: dockPosition === "right" ? parent.right : undefined
|
||||
|
||||
// Slide content inside the fixed window
|
||||
transform: Translate {
|
||||
x: dockWindow.slideX
|
||||
y: dockWindow.slideY
|
||||
}
|
||||
|
||||
// Enable layer caching to reduce GPU usage from continuous animations
|
||||
layer.enabled: true
|
||||
|
||||
opacity: hidden ? 0 : 1
|
||||
scale: hidden ? 0.85 : 1
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: hidden ? hideAnimationDuration : showAnimationDuration
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on scale {
|
||||
NumberAnimation {
|
||||
duration: hidden ? hideAnimationDuration : showAnimationDuration
|
||||
easing.type: hidden ? Easing.InQuad : Easing.OutBack
|
||||
easing.overshoot: hidden ? 0 : 1.05
|
||||
}
|
||||
}
|
||||
|
||||
DockContent {
|
||||
id: dockContent
|
||||
anchors.fill: parent
|
||||
|
||||
@@ -70,9 +70,9 @@ SmartPanel {
|
||||
}
|
||||
|
||||
onOpened: {
|
||||
if (!panelHovered && !menuHovered) {
|
||||
hoverCloseTimer.restart();
|
||||
}
|
||||
// Don't auto-start close timer here — the peek zone's onExited in Dock.qml
|
||||
// starts hideTimer which checks panel.isDockHovered, giving the user time
|
||||
// to move into the panel without it closing prematurely.
|
||||
}
|
||||
|
||||
panelAnchorTop: dockPosition === "top"
|
||||
|
||||
@@ -255,7 +255,7 @@ Variants {
|
||||
|
||||
ShapePath {
|
||||
strokeWidth: -1
|
||||
fillColor: Qt.alpha(Color.mSurfaceVariant, Color.panelBackgroundOpacity)
|
||||
fillColor: Qt.alpha(Color.mSurface, Color.panelBackgroundOpacity)
|
||||
|
||||
// Offset by radius to account for Shape's extended bounds
|
||||
startX: panelShape.radius + panelShape.radius * panelShape.tlMultX
|
||||
|
||||
@@ -318,20 +318,20 @@ Singleton {
|
||||
|
||||
function setAppStreamVolume(appKey: string, volume: real): void {
|
||||
if (!appKey)
|
||||
return;
|
||||
return;
|
||||
var o = appVolumeOverrides;
|
||||
if (!o[appKey])
|
||||
o[appKey] = {};
|
||||
o[appKey] = {};
|
||||
o[appKey].volume = volume;
|
||||
appVolumeOverrides = o;
|
||||
}
|
||||
|
||||
function setAppStreamMuted(appKey: string, muted: bool): void {
|
||||
if (!appKey)
|
||||
return;
|
||||
return;
|
||||
var o = appVolumeOverrides;
|
||||
if (!o[appKey])
|
||||
o[appKey] = {};
|
||||
o[appKey] = {};
|
||||
o[appKey].muted = muted;
|
||||
appVolumeOverrides = o;
|
||||
}
|
||||
@@ -343,18 +343,18 @@ Singleton {
|
||||
function _applyAppOverrides(): void {
|
||||
var streams = root.appStreams;
|
||||
if (!streams)
|
||||
return;
|
||||
return;
|
||||
var currentIds = {};
|
||||
_isApplyingAppOverride = true;
|
||||
for (var i = 0; i < streams.length; i++) {
|
||||
var s = streams[i];
|
||||
if (!s)
|
||||
continue;
|
||||
continue;
|
||||
currentIds[s.id] = true;
|
||||
var key = getAppKey(s);
|
||||
var ov = key ? appVolumeOverrides[key] : null;
|
||||
if (!ov || !s.audio)
|
||||
continue;
|
||||
continue;
|
||||
if (ov.volume !== undefined && Math.abs(s.audio.volume - ov.volume) > root.epsilon) {
|
||||
s.audio.volume = ov.volume;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user