mirror of
https://github.com/zoriya/noctalia-shell.git
synced 2025-12-06 06:36:15 +00:00
Merge branch 'main' of https://github.com/noctalia-dev/noctalia-shell
This commit is contained in:
@@ -1496,11 +1496,11 @@
|
||||
},
|
||||
"panels-attached-to-bar": {
|
||||
"description": "Panels lock to the bar and screen edges, creating a seamless look with stylish inverted corners.",
|
||||
"label": "Snap Panels to Edges"
|
||||
"label": "Snap panels to edges"
|
||||
},
|
||||
"panels-overlay": {
|
||||
"description": "Ensures panels and the bar remain visible, even over fullscreen applications.",
|
||||
"label": "Keep Panels & Bar on Top"
|
||||
"label": "Keep panels & bar on top"
|
||||
},
|
||||
"scaling": {
|
||||
"description": "Changes the size of the general user interface, excluding the bar.",
|
||||
|
||||
@@ -259,7 +259,7 @@ Singleton {
|
||||
property string transitionType: "random"
|
||||
property real transitionEdgeSmoothness: 0.05
|
||||
property list<var> monitors: []
|
||||
property string panelPosition: "folow_bar"
|
||||
property string panelPosition: "follow_bar"
|
||||
}
|
||||
|
||||
// applauncher
|
||||
|
||||
@@ -47,7 +47,16 @@ Item {
|
||||
Loader {
|
||||
id: barContentLoader
|
||||
anchors.fill: parent
|
||||
active: root.screen !== null && root.screen !== undefined
|
||||
active: {
|
||||
if (root.screen === null || root.screen === undefined) {
|
||||
return false
|
||||
}
|
||||
|
||||
var monitors = Settings.data.bar.monitors || []
|
||||
var result = monitors.length === 0 || monitors.includes(root.screen.name)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
sourceComponent: Item {
|
||||
anchors.fill: parent
|
||||
@@ -61,20 +70,20 @@ Item {
|
||||
x: {
|
||||
var baseX = (root.barPosition === "right") ? (parent.width - Style.barHeight - root.barMarginH) : root.barMarginH
|
||||
if (root.barPosition === "right")
|
||||
return baseX + root.attachmentOverlap
|
||||
return baseX - root.attachmentOverlap // Extend left towards panels
|
||||
return baseX
|
||||
}
|
||||
y: {
|
||||
var baseY = (root.barPosition === "bottom") ? (parent.height - Style.barHeight - root.barMarginV) : root.barMarginV
|
||||
if (root.barPosition === "bottom")
|
||||
return baseY + root.attachmentOverlap
|
||||
return baseY - root.attachmentOverlap // Extend up towards panels
|
||||
return baseY
|
||||
}
|
||||
width: {
|
||||
var baseWidth = root.barIsVertical ? Style.barHeight : (parent.width - root.barMarginH * 2)
|
||||
if (!root.barIsVertical)
|
||||
return baseWidth // Horizontal bars extend via height, not width
|
||||
return baseWidth + root.attachmentOverlap
|
||||
return baseWidth + root.attachmentOverlap + 1
|
||||
}
|
||||
height: {
|
||||
var baseHeight = root.barIsVertical ? (parent.height - root.barMarginV * 2) : Style.barHeight
|
||||
|
||||
@@ -10,9 +10,6 @@ import qs.Widgets
|
||||
NPanel {
|
||||
id: root
|
||||
|
||||
preferredWidth: 350 * Style.uiScaleRatio
|
||||
preferredHeight: 210 * Style.uiScaleRatio
|
||||
|
||||
property var optionsModel: []
|
||||
|
||||
function updateOptionsModel() {
|
||||
@@ -33,11 +30,52 @@ NPanel {
|
||||
updateOptionsModel()
|
||||
}
|
||||
|
||||
ButtonGroup {
|
||||
id: batteryGroup
|
||||
}
|
||||
|
||||
Component {
|
||||
id: optionsComponent
|
||||
ColumnLayout {
|
||||
spacing: Style.marginM
|
||||
Repeater {
|
||||
model: root.optionsModel
|
||||
delegate: NRadioButton {
|
||||
ButtonGroup.group: batteryGroup
|
||||
required property var modelData
|
||||
text: I18n.tr(modelData.label, {
|
||||
"percent": BatteryService.getThresholdValue(modelData.id)
|
||||
})
|
||||
checked: BatteryService.chargingMode === modelData.id
|
||||
onClicked: {
|
||||
BatteryService.setChargingMode(modelData.id)
|
||||
}
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: disabledComponent
|
||||
NText {
|
||||
text: I18n.tr("battery.panel.disabled")
|
||||
pointSize: Style.fontSizeL
|
||||
color: Color.mOnSurfaceVariant
|
||||
wrapMode: Text.WordWrap
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
}
|
||||
|
||||
panelContent: Item {
|
||||
anchors.fill: parent
|
||||
property real contentPreferredHeight: mainLayout.implicitHeight + Style.marginM * 2
|
||||
property real contentPreferredWidth: 350 * Style.uiScaleRatio
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
id: mainLayout
|
||||
anchors.centerIn: parent
|
||||
width: parent.contentPreferredWidth - Style.marginM * 2
|
||||
anchors.margins: Style.marginM
|
||||
spacing: Style.marginM
|
||||
|
||||
@@ -78,57 +116,15 @@ NPanel {
|
||||
}
|
||||
}
|
||||
|
||||
ButtonGroup {
|
||||
id: batteryGroup
|
||||
}
|
||||
|
||||
NBox {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.preferredHeight: loader.implicitHeight + Style.marginM * 2
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginM
|
||||
spacing: Style.marginM
|
||||
|
||||
Repeater {
|
||||
model: optionsModel
|
||||
|
||||
NRadioButton {
|
||||
visible: BatteryService.chargingMode !== BatteryService.ChargingMode.Disabled
|
||||
ButtonGroup.group: batteryGroup
|
||||
required property var modelData
|
||||
text: I18n.tr(modelData.label, {
|
||||
"percent": BatteryService.getThresholdValue(modelData.id)
|
||||
})
|
||||
checked: BatteryService.chargingMode === modelData.id
|
||||
onClicked: {
|
||||
BatteryService.setChargingMode(modelData.id)
|
||||
}
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
visible: BatteryService.chargingMode === BatteryService.ChargingMode.Disabled
|
||||
anchors.fill: parent
|
||||
spacing: Style.marginM
|
||||
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
NText {
|
||||
text: I18n.tr("battery.panel.disabled")
|
||||
pointSize: Style.fontSizeL
|
||||
color: Color.mOnSurfaceVariant
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
Loader {
|
||||
id: loader
|
||||
anchors.centerIn: parent
|
||||
width: parent.width - Style.marginM * 2
|
||||
sourceComponent: BatteryService.chargingMode === BatteryService.ChargingMode.Disabled ? disabledComponent : optionsComponent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -611,8 +611,10 @@ NPanel {
|
||||
|
||||
onClicked: {
|
||||
const dateWithSlashes = `${(modelData.month + 1).toString().padStart(2, '0')}/${modelData.day.toString().padStart(2, '0')}/${modelData.year.toString().substring(2)}`
|
||||
Quickshell.execDetached(["gnome-calendar", "--date", dateWithSlashes])
|
||||
root.close()
|
||||
if (ProgramCheckerService.gnomeCalendarAvailable) {
|
||||
Quickshell.execDetached(["gnome-calendar", "--date", dateWithSlashes])
|
||||
root.close()
|
||||
}
|
||||
}
|
||||
|
||||
onExited: {
|
||||
|
||||
@@ -49,12 +49,22 @@ NPanel {
|
||||
|
||||
// Positioning
|
||||
readonly property string controlCenterPosition: Settings.data.controlCenter.position
|
||||
panelAnchorHorizontalCenter: controlCenterPosition !== "close_to_bar_button" && (controlCenterPosition.endsWith("_center") || controlCenterPosition === "center")
|
||||
panelAnchorVerticalCenter: controlCenterPosition === "center"
|
||||
panelAnchorLeft: controlCenterPosition !== "close_to_bar_button" && controlCenterPosition.endsWith("_left")
|
||||
panelAnchorRight: controlCenterPosition !== "close_to_bar_button" && controlCenterPosition.endsWith("_right")
|
||||
panelAnchorBottom: controlCenterPosition !== "close_to_bar_button" && controlCenterPosition.startsWith("bottom_")
|
||||
panelAnchorTop: controlCenterPosition !== "close_to_bar_button" && controlCenterPosition.startsWith("top_")
|
||||
|
||||
// Check if there's a bar on this screen
|
||||
readonly property bool hasBarOnScreen: {
|
||||
var monitors = Settings.data.bar.monitors || []
|
||||
return monitors.length === 0 || monitors.includes(screen?.name)
|
||||
}
|
||||
|
||||
// When position is "close_to_bar_button" but there's no bar, fall back to center
|
||||
readonly property bool shouldCenter: controlCenterPosition === "close_to_bar_button" && !hasBarOnScreen
|
||||
|
||||
panelAnchorHorizontalCenter: shouldCenter || (controlCenterPosition !== "close_to_bar_button" && (controlCenterPosition.endsWith("_center") || controlCenterPosition === "center"))
|
||||
panelAnchorVerticalCenter: shouldCenter || controlCenterPosition === "center"
|
||||
panelAnchorLeft: !shouldCenter && controlCenterPosition !== "close_to_bar_button" && controlCenterPosition.endsWith("_left")
|
||||
panelAnchorRight: !shouldCenter && controlCenterPosition !== "close_to_bar_button" && controlCenterPosition.endsWith("_right")
|
||||
panelAnchorBottom: !shouldCenter && controlCenterPosition !== "close_to_bar_button" && controlCenterPosition.startsWith("bottom_")
|
||||
panelAnchorTop: !shouldCenter && controlCenterPosition !== "close_to_bar_button" && controlCenterPosition.startsWith("top_")
|
||||
|
||||
readonly property int profileHeight: Math.round(64 * Style.uiScaleRatio)
|
||||
readonly property int shortcutsHeight: Math.round(52 * Style.uiScaleRatio)
|
||||
|
||||
@@ -355,21 +355,6 @@ Item {
|
||||
|
||||
// Execute pending callback if any
|
||||
if (pendingCallback) {
|
||||
// Verify we have a NFullScreenWindow for this screen
|
||||
var monitors = Settings.data.bar.monitors || []
|
||||
if (!(monitors.length === 0 || monitors.includes(detectedScreen.name))) {
|
||||
// Fall back to first enabled screen as we can NOT show a panel on a screen without a Bar/NFullScreenWindow
|
||||
if (monitors.length === 0 && Quickshell.screens.length > 0) {
|
||||
detectedScreen = Quickshell.screens[0]
|
||||
} else {
|
||||
for (var i = 0; i < Quickshell.screens.length; i++) {
|
||||
if (monitors.includes(Quickshell.screens[i].name)) {
|
||||
detectedScreen = Quickshell.screens[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Logger.d("IPC", "Executing pending IPC callback on screen:", detectedScreen.name)
|
||||
pendingCallback(detectedScreen)
|
||||
pendingCallback = null
|
||||
|
||||
@@ -24,6 +24,7 @@ Singleton {
|
||||
property bool wlsunsetAvailable: false
|
||||
property bool app2unitAvailable: false
|
||||
property bool codeAvailable: false
|
||||
property bool gnomeCalendarAvailable: false
|
||||
|
||||
// Discord client auto-detection
|
||||
property var availableDiscordClients: []
|
||||
@@ -109,7 +110,8 @@ Singleton {
|
||||
"app2unitAvailable": ["which", "app2unit"],
|
||||
"gpuScreenRecorderAvailable": ["sh", "-c", "command -v gpu-screen-recorder >/dev/null 2>&1 || (command -v flatpak >/dev/null 2>&1 && flatpak list --app | grep -q 'com.dec05eba.gpu_screen_recorder')"],
|
||||
"wlsunsetAvailable": ["which", "wlsunset"],
|
||||
"codeAvailable": ["which", "code"]
|
||||
"codeAvailable": ["which", "code"],
|
||||
"gnomeCalendarAvailable": ["which", "gnome-calendar"]
|
||||
})
|
||||
|
||||
// Internal tracking
|
||||
|
||||
@@ -13,10 +13,6 @@ Item {
|
||||
// Screen property provided by NFullScreenWindow
|
||||
property ShellScreen screen: null
|
||||
|
||||
// A panel can only be a attached to the bar of screen edges if
|
||||
property bool couldAttach: Settings.data.ui.panelsAttachedToBar
|
||||
property bool couldAttachToBar: (Settings.data.ui.panelsAttachedToBar && Settings.data.bar.backgroundOpacity >= 1.0)
|
||||
|
||||
// Edge snapping: if panel is within this distance (in pixels) from a screen edge, snap
|
||||
property real edgeSnapDistance: 50
|
||||
|
||||
@@ -98,16 +94,6 @@ Item {
|
||||
readonly property bool hasExplicitHorizontalAnchor: panelAnchorHorizontalCenter || panelAnchorLeft || panelAnchorRight
|
||||
readonly property bool hasExplicitVerticalAnchor: panelAnchorVerticalCenter || panelAnchorTop || panelAnchorBottom
|
||||
|
||||
// Effective anchor properties
|
||||
// These are true when:
|
||||
// 1. Explicitly anchored, OR
|
||||
// 2. Using button position and bar is on that edge, OR
|
||||
// 3. Attached to bar with no explicit anchors (default centering behavior)
|
||||
readonly property bool effectivePanelAnchorTop: panelAnchorTop || (useButtonPosition && barPosition === "top") || (couldAttach && !hasExplicitVerticalAnchor && barPosition === "top" && !barIsVertical)
|
||||
readonly property bool effectivePanelAnchorBottom: panelAnchorBottom || (useButtonPosition && barPosition === "bottom") || (couldAttach && !hasExplicitVerticalAnchor && barPosition === "bottom" && !barIsVertical)
|
||||
readonly property bool effectivePanelAnchorLeft: panelAnchorLeft || (useButtonPosition && barPosition === "left") || (couldAttach && !hasExplicitHorizontalAnchor && barPosition === "left" && barIsVertical)
|
||||
readonly property bool effectivePanelAnchorRight: panelAnchorRight || (useButtonPosition && barPosition === "right") || (couldAttach && !hasExplicitHorizontalAnchor && barPosition === "right" && barIsVertical)
|
||||
|
||||
signal opened
|
||||
signal closed
|
||||
|
||||
@@ -192,6 +178,30 @@ Item {
|
||||
sourceComponent: Item {
|
||||
anchors.fill: parent
|
||||
|
||||
// Screen-dependent attachment properties (moved from root to avoid race condition)
|
||||
// By the time this Loader is active, screen has been assigned by NFullScreenWindow
|
||||
readonly property bool couldAttach: Settings.data.ui.panelsAttachedToBar
|
||||
readonly property bool couldAttachToBar: {
|
||||
if (!Settings.data.ui.panelsAttachedToBar || Settings.data.bar.backgroundOpacity < 1.0) {
|
||||
return false
|
||||
}
|
||||
|
||||
// A panel can only be attached to a bar if there is a bar on that screen
|
||||
var monitors = Settings.data.bar.monitors || []
|
||||
var result = monitors.length === 0 || monitors.includes(root.screen?.name || "")
|
||||
return result
|
||||
}
|
||||
|
||||
// Effective anchor properties (moved from root, depend on couldAttach)
|
||||
// These are true when:
|
||||
// 1. Explicitly anchored, OR
|
||||
// 2. Using button position and bar is on that edge, OR
|
||||
// 3. Attached to bar with no explicit anchors (default centering behavior)
|
||||
readonly property bool effectivePanelAnchorTop: root.panelAnchorTop || (root.useButtonPosition && root.barPosition === "top") || (couldAttach && !root.hasExplicitVerticalAnchor && root.barPosition === "top" && !root.barIsVertical)
|
||||
readonly property bool effectivePanelAnchorBottom: root.panelAnchorBottom || (root.useButtonPosition && root.barPosition === "bottom") || (couldAttach && !root.hasExplicitVerticalAnchor && root.barPosition === "bottom" && !root.barIsVertical)
|
||||
readonly property bool effectivePanelAnchorLeft: root.panelAnchorLeft || (root.useButtonPosition && root.barPosition === "left") || (couldAttach && !root.hasExplicitHorizontalAnchor && root.barPosition === "left" && root.barIsVertical)
|
||||
readonly property bool effectivePanelAnchorRight: root.panelAnchorRight || (root.useButtonPosition && root.barPosition === "right") || (couldAttach && !root.hasExplicitHorizontalAnchor && root.barPosition === "right" && root.barIsVertical)
|
||||
|
||||
// Expose panelBackground for mask region
|
||||
property alias maskRegion: panelBackground
|
||||
|
||||
@@ -228,8 +238,8 @@ Item {
|
||||
readonly property bool hasInvertedCorners: topLeftInverted || topRightInverted || bottomLeftInverted || bottomRightInverted
|
||||
|
||||
// Determine panel attachment type for animation
|
||||
readonly property bool isAttachedToFloatingBar: hasInvertedCorners && root.barFloating && root.couldAttach
|
||||
readonly property bool isAttachedToNonFloating: hasInvertedCorners && (!root.barFloating || !root.couldAttach)
|
||||
readonly property bool isAttachedToFloatingBar: hasInvertedCorners && root.barFloating && couldAttach
|
||||
readonly property bool isAttachedToNonFloating: hasInvertedCorners && (!root.barFloating || !couldAttach)
|
||||
readonly property bool isDetached: !hasInvertedCorners
|
||||
|
||||
// Determine closest screen edge to slide from (for full slide animation)
|
||||
@@ -355,36 +365,36 @@ Item {
|
||||
// Also invert corners when touching screen edges (non-floating bar only)
|
||||
topLeftInverted: {
|
||||
// Bar attachment: only attach to bar if bar opacity >= 1.0 (no color clash)
|
||||
var barInverted = root.couldAttachToBar && ((root.barPosition === "top" && !root.barIsVertical && root.effectivePanelAnchorTop) || (root.barPosition === "left" && root.barIsVertical && root.effectivePanelAnchorLeft))
|
||||
var barInverted = couldAttachToBar && ((root.barPosition === "top" && !root.barIsVertical && effectivePanelAnchorTop) || (root.barPosition === "left" && root.barIsVertical && effectivePanelAnchorLeft))
|
||||
// Also detect when panel touches bar edge (e.g., centered panel that's too tall)
|
||||
var barTouchInverted = touchingTopBar || touchingLeftBar
|
||||
// Screen edge contact: can attach to screen edges even if bar opacity < 1.0
|
||||
// For horizontal bars: invert when touching left/right edges
|
||||
// For vertical bars: invert when touching top/bottom edges
|
||||
var edgeInverted = root.couldAttach && ((touchingLeftEdge && !root.barIsVertical) || (touchingTopEdge && root.barIsVertical))
|
||||
var edgeInverted = couldAttach && ((touchingLeftEdge && !root.barIsVertical) || (touchingTopEdge && root.barIsVertical))
|
||||
// Also invert when touching screen edge opposite to bar (e.g., bottom edge when bar is at top)
|
||||
var oppositeEdgeInverted = root.couldAttach && (touchingTopEdge && !root.barIsVertical && root.barPosition !== "top")
|
||||
var oppositeEdgeInverted = couldAttach && (touchingTopEdge && !root.barIsVertical && root.barPosition !== "top")
|
||||
return barInverted || barTouchInverted || edgeInverted || oppositeEdgeInverted
|
||||
}
|
||||
topRightInverted: {
|
||||
var barInverted = root.couldAttachToBar && ((root.barPosition === "top" && !root.barIsVertical && root.effectivePanelAnchorTop) || (root.barPosition === "right" && root.barIsVertical && root.effectivePanelAnchorRight))
|
||||
var barInverted = couldAttachToBar && ((root.barPosition === "top" && !root.barIsVertical && effectivePanelAnchorTop) || (root.barPosition === "right" && root.barIsVertical && effectivePanelAnchorRight))
|
||||
var barTouchInverted = touchingTopBar || touchingRightBar
|
||||
var edgeInverted = root.couldAttach && ((touchingRightEdge && !root.barIsVertical) || (touchingTopEdge && root.barIsVertical))
|
||||
var oppositeEdgeInverted = root.couldAttach && (touchingTopEdge && !root.barIsVertical && root.barPosition !== "top")
|
||||
var edgeInverted = couldAttach && ((touchingRightEdge && !root.barIsVertical) || (touchingTopEdge && root.barIsVertical))
|
||||
var oppositeEdgeInverted = couldAttach && (touchingTopEdge && !root.barIsVertical && root.barPosition !== "top")
|
||||
return barInverted || barTouchInverted || edgeInverted || oppositeEdgeInverted
|
||||
}
|
||||
bottomLeftInverted: {
|
||||
var barInverted = root.couldAttachToBar && ((root.barPosition === "bottom" && !root.barIsVertical && root.effectivePanelAnchorBottom) || (root.barPosition === "left" && root.barIsVertical && root.effectivePanelAnchorLeft))
|
||||
var barInverted = couldAttachToBar && ((root.barPosition === "bottom" && !root.barIsVertical && effectivePanelAnchorBottom) || (root.barPosition === "left" && root.barIsVertical && effectivePanelAnchorLeft))
|
||||
var barTouchInverted = touchingBottomBar || touchingLeftBar
|
||||
var edgeInverted = root.couldAttach && ((touchingLeftEdge && !root.barIsVertical) || (touchingBottomEdge && root.barIsVertical))
|
||||
var oppositeEdgeInverted = root.couldAttach && (touchingBottomEdge && !root.barIsVertical && root.barPosition !== "bottom")
|
||||
var edgeInverted = couldAttach && ((touchingLeftEdge && !root.barIsVertical) || (touchingBottomEdge && root.barIsVertical))
|
||||
var oppositeEdgeInverted = couldAttach && (touchingBottomEdge && !root.barIsVertical && root.barPosition !== "bottom")
|
||||
return barInverted || barTouchInverted || edgeInverted || oppositeEdgeInverted
|
||||
}
|
||||
bottomRightInverted: {
|
||||
var barInverted = root.couldAttachToBar && ((root.barPosition === "bottom" && !root.barIsVertical && root.effectivePanelAnchorBottom) || (root.barPosition === "right" && root.barIsVertical && root.effectivePanelAnchorRight))
|
||||
var barInverted = couldAttachToBar && ((root.barPosition === "bottom" && !root.barIsVertical && effectivePanelAnchorBottom) || (root.barPosition === "right" && root.barIsVertical && effectivePanelAnchorRight))
|
||||
var barTouchInverted = touchingBottomBar || touchingRightBar
|
||||
var edgeInverted = root.couldAttach && ((touchingRightEdge && !root.barIsVertical) || (touchingBottomEdge && root.barIsVertical))
|
||||
var oppositeEdgeInverted = root.couldAttach && (touchingBottomEdge && !root.barIsVertical && root.barPosition !== "bottom")
|
||||
var edgeInverted = couldAttach && ((touchingRightEdge && !root.barIsVertical) || (touchingBottomEdge && root.barIsVertical))
|
||||
var oppositeEdgeInverted = couldAttach && (touchingBottomEdge && !root.barIsVertical && root.barPosition !== "bottom")
|
||||
return barInverted || barTouchInverted || edgeInverted || oppositeEdgeInverted
|
||||
}
|
||||
|
||||
@@ -450,16 +460,16 @@ Item {
|
||||
}
|
||||
|
||||
// Detect if panel is touching screen edges
|
||||
readonly property bool touchingLeftEdge: root.couldAttach && x <= 1
|
||||
readonly property bool touchingRightEdge: root.couldAttach && (x + width) >= (parent.width - 1)
|
||||
readonly property bool touchingTopEdge: root.couldAttach && y <= 1
|
||||
readonly property bool touchingBottomEdge: root.couldAttach && (y + height) >= (parent.height - 1)
|
||||
readonly property bool touchingLeftEdge: couldAttach && x <= 1
|
||||
readonly property bool touchingRightEdge: couldAttach && (x + width) >= (parent.width - 1)
|
||||
readonly property bool touchingTopEdge: couldAttach && y <= 1
|
||||
readonly property bool touchingBottomEdge: couldAttach && (y + height) >= (parent.height - 1)
|
||||
|
||||
// Detect if panel is touching bar edges (for cases where centered panels snap to bar due to height constraints)
|
||||
readonly property bool touchingTopBar: root.couldAttachToBar && root.barPosition === "top" && !root.barIsVertical && Math.abs(y - (root.barMarginV + Style.barHeight)) <= 1
|
||||
readonly property bool touchingBottomBar: root.couldAttachToBar && root.barPosition === "bottom" && !root.barIsVertical && Math.abs((y + height) - (parent.height - root.barMarginV - Style.barHeight)) <= 1
|
||||
readonly property bool touchingLeftBar: root.couldAttachToBar && root.barPosition === "left" && root.barIsVertical && Math.abs(x - (root.barMarginH + Style.barHeight)) <= 1
|
||||
readonly property bool touchingRightBar: root.couldAttachToBar && root.barPosition === "right" && root.barIsVertical && Math.abs((x + width) - (parent.width - root.barMarginH - Style.barHeight)) <= 1
|
||||
readonly property bool touchingTopBar: couldAttachToBar && root.barPosition === "top" && !root.barIsVertical && Math.abs(y - (root.barMarginV + Style.barHeight)) <= 1
|
||||
readonly property bool touchingBottomBar: couldAttachToBar && root.barPosition === "bottom" && !root.barIsVertical && Math.abs((y + height) - (parent.height - root.barMarginV - Style.barHeight)) <= 1
|
||||
readonly property bool touchingLeftBar: couldAttachToBar && root.barPosition === "left" && root.barIsVertical && Math.abs(x - (root.barMarginH + Style.barHeight)) <= 1
|
||||
readonly property bool touchingRightBar: couldAttachToBar && root.barPosition === "right" && root.barIsVertical && Math.abs((x + width) - (parent.width - root.barMarginH - Style.barHeight)) <= 1
|
||||
|
||||
// Position the panel using explicit x/y coordinates (no anchors)
|
||||
// This makes coordinates clearer for the click-through mask system
|
||||
@@ -472,7 +482,7 @@ Item {
|
||||
if (root.useButtonPosition && parent.width > 0 && width > 0) {
|
||||
if (root.barIsVertical) {
|
||||
// For vertical bars
|
||||
if (root.couldAttach) {
|
||||
if (couldAttach) {
|
||||
// Attached panels: align with bar edge (left or right side)
|
||||
if (root.barPosition === "left") {
|
||||
// Panel to the right of left bar
|
||||
@@ -508,7 +518,7 @@ Item {
|
||||
var panelX = root.buttonPosition.x + root.buttonWidth / 2 - width / 2
|
||||
// Clamp to bar bounds (account for floating bar margins)
|
||||
// When attached, panel should not extend beyond bar edges
|
||||
if (root.couldAttach) {
|
||||
if (couldAttach) {
|
||||
// Inverted corners with horizontal direction extend left/right by radiusL
|
||||
// When bar is floating, it also has rounded corners, so we need extra insets
|
||||
var cornerInset = root.barFloating ? Style.radiusL * 2 : 0
|
||||
@@ -545,26 +555,26 @@ Item {
|
||||
// For horizontal bars or no bar, center normally
|
||||
calculatedX = (parent.width - width) / 2
|
||||
}
|
||||
} else if (root.effectivePanelAnchorRight) {
|
||||
} else if (effectivePanelAnchorRight) {
|
||||
Logger.d("NPanel", " -> Right anchor")
|
||||
// When attached to right vertical bar, position next to bar (like useButtonPosition does)
|
||||
if (root.couldAttach && root.barIsVertical && root.barPosition === "right") {
|
||||
if (couldAttach && root.barIsVertical && root.barPosition === "right") {
|
||||
var rightBarEdge = parent.width - root.barMarginH - Style.barHeight
|
||||
calculatedX = rightBarEdge - width
|
||||
} else if (root.couldAttach) {
|
||||
} else if (couldAttach) {
|
||||
// Attach to right screen edge
|
||||
calculatedX = parent.width - width
|
||||
} else {
|
||||
// Detached: use margin
|
||||
calculatedX = parent.width - width - Style.marginL
|
||||
}
|
||||
} else if (root.effectivePanelAnchorLeft) {
|
||||
} else if (effectivePanelAnchorLeft) {
|
||||
Logger.d("NPanel", " -> Left anchor")
|
||||
// When attached to left vertical bar, position next to bar (like useButtonPosition does)
|
||||
if (root.couldAttach && root.barIsVertical && root.barPosition === "left") {
|
||||
if (couldAttach && root.barIsVertical && root.barPosition === "left") {
|
||||
var leftBarEdge = root.barMarginH + Style.barHeight
|
||||
calculatedX = leftBarEdge
|
||||
} else if (root.couldAttach) {
|
||||
} else if (couldAttach) {
|
||||
// Attach to left screen edge
|
||||
calculatedX = 0
|
||||
} else {
|
||||
@@ -590,7 +600,7 @@ Item {
|
||||
}
|
||||
} else {
|
||||
// For horizontal bars: center horizontally, respect bar margins if attached
|
||||
if (root.couldAttach) {
|
||||
if (couldAttach) {
|
||||
// When attached, respect bar bounds (like button position does)
|
||||
var cornerInset = Style.radiusL + (root.barFloating ? Style.radiusL : 0)
|
||||
var barLeftEdge = root.barMarginH + cornerInset
|
||||
@@ -605,7 +615,7 @@ Item {
|
||||
}
|
||||
|
||||
// Edge snapping: snap to screen edges if close (only when attached and bar is not floating)
|
||||
if (root.couldAttach && !root.barFloating && parent.width > 0 && width > 0) {
|
||||
if (couldAttach && !root.barFloating && parent.width > 0 && width > 0) {
|
||||
// Calculate edge positions accounting for bar position
|
||||
// For vertical bars (left/right), we need to position panels AFTER the bar, not behind it
|
||||
var leftEdgePos = root.barMarginH
|
||||
@@ -642,7 +652,7 @@ Item {
|
||||
if (root.barPosition === "top") {
|
||||
// Panel below top bar
|
||||
var topBarEdge = root.barMarginV + Style.barHeight
|
||||
if (root.couldAttach) {
|
||||
if (couldAttach) {
|
||||
// Panel sits right at bar edge (inverted corners align perfectly)
|
||||
calculatedY = topBarEdge
|
||||
} else {
|
||||
@@ -651,7 +661,7 @@ Item {
|
||||
} else if (root.barPosition === "bottom") {
|
||||
// Panel above bottom bar
|
||||
var bottomBarEdge = parent.height - root.barMarginV - Style.barHeight
|
||||
if (root.couldAttach) {
|
||||
if (couldAttach) {
|
||||
// Panel sits right at bar edge (inverted corners align perfectly)
|
||||
calculatedY = bottomBarEdge - height
|
||||
} else {
|
||||
@@ -661,8 +671,8 @@ Item {
|
||||
// For vertical bars, center panel on button Y position
|
||||
var panelY = root.buttonPosition.y + root.buttonHeight / 2 - height / 2
|
||||
// Clamp to bar bounds (account for floating bar margins and inverted corners)
|
||||
var extraPadding = (root.couldAttach && root.barFloating) ? Style.radiusL : 0
|
||||
if (root.couldAttach) {
|
||||
var extraPadding = (couldAttach && root.barFloating) ? Style.radiusL : 0
|
||||
if (couldAttach) {
|
||||
// When attached, panel should not extend beyond bar edges (accounting for floating margins)
|
||||
// Inverted corners with vertical direction extend up/down by radiusL
|
||||
// When bar is floating, it also has rounded corners, so we need extra inset
|
||||
@@ -680,7 +690,7 @@ Item {
|
||||
// Standard anchor positioning
|
||||
// Calculate bar offset for detached panels - they should never overlap the bar
|
||||
var barOffset = 0
|
||||
if (!root.couldAttach) {
|
||||
if (!couldAttach) {
|
||||
// For detached panels, always account for bar position
|
||||
if (root.barPosition === "top") {
|
||||
barOffset = root.barMarginV + Style.barHeight + Style.marginM
|
||||
@@ -689,10 +699,10 @@ Item {
|
||||
}
|
||||
} else {
|
||||
// For attached panels with explicit anchors
|
||||
if (root.effectivePanelAnchorTop && root.barPosition === "top") {
|
||||
if (effectivePanelAnchorTop && root.barPosition === "top") {
|
||||
// When attached to top bar: position right at bar edge (inverted corners align perfectly)
|
||||
calculatedY = root.barMarginV + Style.barHeight
|
||||
} else if (root.effectivePanelAnchorBottom && root.barPosition === "bottom") {
|
||||
} else if (effectivePanelAnchorBottom && root.barPosition === "bottom") {
|
||||
// When attached to bottom bar: position right at bar edge (inverted corners align perfectly)
|
||||
calculatedY = parent.height - root.barMarginV - Style.barHeight - height
|
||||
} else if (!root.hasExplicitVerticalAnchor) {
|
||||
@@ -729,18 +739,18 @@ Item {
|
||||
// For vertical bars or no bar, center normally
|
||||
calculatedY = (parent.height - height) / 2
|
||||
}
|
||||
} else if (root.effectivePanelAnchorTop) {
|
||||
} else if (effectivePanelAnchorTop) {
|
||||
// When couldAttach=true, attach to top screen edge; otherwise use margin
|
||||
if (root.couldAttach) {
|
||||
if (couldAttach) {
|
||||
calculatedY = 0
|
||||
} else {
|
||||
// Only apply barOffset if bar is also at top (to avoid overlapping)
|
||||
var topBarOffset = (root.barPosition === "top") ? barOffset : 0
|
||||
calculatedY = topBarOffset + Style.marginL
|
||||
}
|
||||
} else if (root.effectivePanelAnchorBottom) {
|
||||
} else if (effectivePanelAnchorBottom) {
|
||||
// When couldAttach=true, attach to bottom screen edge; otherwise use margin
|
||||
if (root.couldAttach) {
|
||||
if (couldAttach) {
|
||||
calculatedY = parent.height - height
|
||||
} else {
|
||||
// Only apply barOffset if bar is also at bottom (to avoid overlapping)
|
||||
@@ -751,7 +761,7 @@ Item {
|
||||
// No explicit vertical anchor
|
||||
if (root.barIsVertical) {
|
||||
// For vertical bars: center vertically on bar
|
||||
if (root.couldAttach) {
|
||||
if (couldAttach) {
|
||||
// When attached, respect bar bounds
|
||||
var cornerInset = root.barFloating ? Style.radiusL * 2 : 0
|
||||
var barTopEdge = root.barMarginV + cornerInset
|
||||
@@ -763,7 +773,7 @@ Item {
|
||||
}
|
||||
} else {
|
||||
// For horizontal bars: attach to bar edge by default
|
||||
if (root.couldAttach && !root.barIsVertical) {
|
||||
if (couldAttach && !root.barIsVertical) {
|
||||
if (root.barPosition === "top") {
|
||||
calculatedY = root.barMarginV + Style.barHeight
|
||||
} else if (root.barPosition === "bottom") {
|
||||
@@ -785,7 +795,7 @@ Item {
|
||||
}
|
||||
|
||||
// Edge snapping: snap to screen edges if close (only when attached and bar is not floating)
|
||||
if (root.couldAttach && !root.barFloating && parent.height > 0 && height > 0) {
|
||||
if (couldAttach && !root.barFloating && parent.height > 0 && height > 0) {
|
||||
// Calculate edge positions accounting for bar position
|
||||
// For horizontal bars (top/bottom), we need to position panels AFTER the bar, not behind it
|
||||
var topEdgePos = root.barMarginV
|
||||
|
||||
18
shell.qml
18
shell.qml
@@ -214,11 +214,8 @@ ShellRoot {
|
||||
if (!modelData || !modelData.name)
|
||||
return false
|
||||
|
||||
var monitors = Settings.data.bar.monitors || []
|
||||
var result = monitors.length === 0 || monitors.includes(modelData.name)
|
||||
|
||||
Logger.d("Shell", "NFullScreenWindow Loader for", modelData?.name, "- shouldBeActive:", result, "- monitors:", JSON.stringify(monitors))
|
||||
return result
|
||||
Logger.d("Shell", "NFullScreenWindow activated for", modelData?.name)
|
||||
return true
|
||||
}
|
||||
|
||||
property bool windowLoaded: false
|
||||
@@ -289,9 +286,16 @@ ShellRoot {
|
||||
}
|
||||
|
||||
// BarExclusionZone - created after NFullScreenWindow has fully loaded
|
||||
// Must also be disabled when bar is hidden
|
||||
// Disabled when bar is hidden or not configured for this screen
|
||||
Loader {
|
||||
active: parent.windowLoaded && parent.shouldBeActive && BarService.isVisible
|
||||
active: {
|
||||
if (!parent.windowLoaded || !parent.shouldBeActive || !BarService.isVisible)
|
||||
return false
|
||||
|
||||
// Check if bar is configured for this screen
|
||||
var monitors = Settings.data.bar.monitors || []
|
||||
return monitors.length === 0 || monitors.includes(modelData?.name)
|
||||
}
|
||||
asynchronous: false
|
||||
|
||||
sourceComponent: BarExclusionZone {
|
||||
|
||||
Reference in New Issue
Block a user