mirror of
https://github.com/zoriya/noctalia-shell.git
synced 2026-08-15 18:43:59 +00:00
New windowing system
Large commit that totally refactor of the way we handle the bar and panels. Testing should focus on Panels, Bar, Keyboard Focus, IPC calls. Changes brief: - One NFullScreenWindow per screen which handle it's bar and dedicated panels. - Added shadows - Reintroduced dimming - New panels animations - Proper Z ordering - Panels on overlay laywer is not reimplemented, if we do it then the bar will be on the Overlay too - Panel dragging was not reimplemented, to be discussed before reimplementing - Still a WIP, need to work more on shadows and polishing + debugging.
This commit is contained in:
@@ -18,7 +18,6 @@ NPanel {
|
||||
|
||||
preferredWidth: 380 * Style.uiScaleRatio
|
||||
preferredHeight: 500 * Style.uiScaleRatio
|
||||
panelKeyboardFocus: true
|
||||
|
||||
// Connections to update local volumes when AudioService changes
|
||||
Connections {
|
||||
|
||||
+247
-192
@@ -10,60 +10,92 @@ import qs.Widgets
|
||||
import qs.Modules.Notification
|
||||
import qs.Modules.Bar.Extras
|
||||
|
||||
Variants {
|
||||
model: Quickshell.screens
|
||||
// Bar Component
|
||||
Item {
|
||||
id: root
|
||||
|
||||
delegate: Loader {
|
||||
id: root
|
||||
// This property will be set by NFullScreenWindow
|
||||
property ShellScreen screen: null
|
||||
|
||||
required property ShellScreen modelData
|
||||
// Expose bar region for click-through mask
|
||||
readonly property var barRegion: barContentLoader.item?.children[0] || null
|
||||
|
||||
active: BarService.isVisible && modelData && modelData.name ? (Settings.data.bar.monitors.includes(modelData.name) || (Settings.data.bar.monitors.length === 0)) : false
|
||||
// Bar positioning properties
|
||||
readonly property string barPosition: Settings.data.bar.position || "top"
|
||||
readonly property bool barIsVertical: barPosition === "left" || barPosition === "right"
|
||||
readonly property bool barFloating: Settings.data.bar.floating || false
|
||||
readonly property real barMarginH: barFloating ? Settings.data.bar.marginHorizontal * Style.marginXL : 0
|
||||
readonly property real barMarginV: barFloating ? Settings.data.bar.marginVertical * Style.marginXL : 0
|
||||
|
||||
sourceComponent: PanelWindow {
|
||||
screen: modelData || null
|
||||
// Fill the parent (the Loader)
|
||||
anchors.fill: parent
|
||||
|
||||
WlrLayershell.namespace: "noctalia-bar"
|
||||
// Register bar when screen becomes available
|
||||
onScreenChanged: {
|
||||
if (screen && screen.name) {
|
||||
Logger.d("Bar", "Bar screen set to:", screen.name)
|
||||
Logger.d("Bar", " Position:", barPosition, "Floating:", barFloating)
|
||||
Logger.d("Bar", " Margins - H:", barMarginH, "V:", barMarginV)
|
||||
BarService.registerBar(screen.name)
|
||||
}
|
||||
}
|
||||
|
||||
implicitHeight: (Settings.data.bar.position === "left" || Settings.data.bar.position === "right") ? screen.height : Style.barHeight
|
||||
implicitWidth: (Settings.data.bar.position === "left" || Settings.data.bar.position === "right") ? Style.barHeight : screen.width
|
||||
color: Color.transparent
|
||||
// Wait for screen to be set before loading bar content
|
||||
Loader {
|
||||
id: barContentLoader
|
||||
anchors.fill: parent
|
||||
active: root.screen !== null && root.screen !== undefined
|
||||
|
||||
anchors {
|
||||
top: Settings.data.bar.position === "top" || Settings.data.bar.position === "left" || Settings.data.bar.position === "right"
|
||||
bottom: Settings.data.bar.position === "bottom" || Settings.data.bar.position === "left" || Settings.data.bar.position === "right"
|
||||
left: Settings.data.bar.position === "left" || Settings.data.bar.position === "top" || Settings.data.bar.position === "bottom"
|
||||
right: Settings.data.bar.position === "right" || Settings.data.bar.position === "top" || Settings.data.bar.position === "bottom"
|
||||
}
|
||||
sourceComponent: Item {
|
||||
anchors.fill: parent
|
||||
|
||||
// Floating bar margins - only apply when floating is enabled
|
||||
// Also don't apply margin on the opposite side ot the bar orientation, ex: if bar is floating on top, margin is only applied on top, not bottom.
|
||||
margins {
|
||||
top: Settings.data.bar.floating && Settings.data.bar.position !== "bottom" ? Settings.data.bar.marginVertical * Style.marginXL : 0
|
||||
bottom: Settings.data.bar.floating && Settings.data.bar.position !== "top" ? Settings.data.bar.marginVertical * Style.marginXL : 0
|
||||
left: Settings.data.bar.floating && Settings.data.bar.position !== "right" ? Settings.data.bar.marginHorizontal * Style.marginXL : 0
|
||||
right: Settings.data.bar.floating && Settings.data.bar.position !== "left" ? Settings.data.bar.marginHorizontal * Style.marginXL : 0
|
||||
}
|
||||
// Background fill with shadow
|
||||
NShapedRectangle {
|
||||
id: bar
|
||||
|
||||
Component.onCompleted: {
|
||||
if (modelData && modelData.name) {
|
||||
BarService.registerBar(modelData.name)
|
||||
}
|
||||
}
|
||||
// Position and size the bar based on orientation and floating margins
|
||||
x: (root.barPosition === "right") ? (parent.width - Style.barHeight - root.barMarginH) : root.barMarginH
|
||||
y: (root.barPosition === "bottom") ? (parent.height - Style.barHeight - root.barMarginV) : root.barMarginV
|
||||
width: root.barIsVertical ? Style.barHeight : (parent.width - root.barMarginH * 2)
|
||||
height: root.barIsVertical ? (parent.height - root.barMarginV * 2) : Style.barHeight
|
||||
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
clip: true
|
||||
backgroundColor: Qt.alpha(Color.mSurface, Settings.data.bar.backgroundOpacity)
|
||||
|
||||
// Background fill with shadow
|
||||
Rectangle {
|
||||
id: bar
|
||||
// Floating bar rounded corners
|
||||
topLeftRadius: Settings.data.bar.floating || topLeftInverted ? Style.radiusL : 0
|
||||
topRightRadius: Settings.data.bar.floating || topRightInverted ? Style.radiusL : 0
|
||||
bottomLeftRadius: Settings.data.bar.floating || bottomLeftInverted ? Style.radiusL : 0
|
||||
bottomRightRadius: Settings.data.bar.floating || bottomRightInverted ? Style.radiusL : 0
|
||||
|
||||
anchors.fill: parent
|
||||
color: Qt.alpha(Color.mSurface, Settings.data.bar.backgroundOpacity)
|
||||
topLeftInverted: Settings.data.bar.outerCorners && (barPosition === "bottom" || barPosition === "right")
|
||||
topLeftInvertedDirection: barIsVertical ? "horizontal" : "vertical"
|
||||
topRightInverted: Settings.data.bar.outerCorners && (barPosition === "bottom" || barPosition === "left")
|
||||
topRightInvertedDirection: barIsVertical ? "horizontal" : "vertical"
|
||||
|
||||
// Floating bar rounded corners
|
||||
radius: Settings.data.bar.floating ? Style.radiusL : 0
|
||||
bottomLeftInverted: Settings.data.bar.outerCorners && (barPosition === "top" || barPosition === "right")
|
||||
bottomLeftInvertedDirection: barIsVertical ? "horizontal" : "vertical"
|
||||
bottomRightInverted: Settings.data.bar.outerCorners && (barPosition === "top" || barPosition === "left")
|
||||
bottomRightInvertedDirection: barIsVertical ? "horizontal" : "vertical"
|
||||
|
||||
// No border on the bar
|
||||
borderWidth: 0
|
||||
|
||||
// Shadow configuration
|
||||
shadowEnabled: true
|
||||
shadowBlur: 0.5
|
||||
// Fade shadow progressively when a panel is attached to the bar to avoid visual disconnection
|
||||
// shadowOpacity: {
|
||||
// if (PanelService.openedPanel && PanelService.openedPanel.attachedToBar) {
|
||||
// // Fade shadow out as panel opens (animationProgress goes from 0 to 1)
|
||||
// return 1.0 - PanelService.openedPanel.animationProgress
|
||||
// }
|
||||
// return 1.0
|
||||
// }
|
||||
Behavior on shadowOpacity {
|
||||
NumberAnimation {
|
||||
duration: Style.animationFast
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
@@ -73,8 +105,11 @@ Variants {
|
||||
preventStealing: true
|
||||
onClicked: function (mouse) {
|
||||
if (mouse.button === Qt.RightButton) {
|
||||
// Important to pass the screen here so we get the right widget for the actual bar that was clicked.
|
||||
controlCenterPanel.toggle(BarService.lookupWidget("ControlCenter", screen.name))
|
||||
// Look up for any ControlCenter button on this bar
|
||||
var widget = BarService.lookupWidget("ControlCenter", root.screen.name)
|
||||
|
||||
// Open the panel near the button if any
|
||||
PanelService.getPanel("controlCenterPanel", root.screen)?.toggle(widget)
|
||||
mouse.accepted = true
|
||||
}
|
||||
}
|
||||
@@ -84,168 +119,188 @@ Variants {
|
||||
anchors.fill: parent
|
||||
sourceComponent: (Settings.data.bar.position === "left" || Settings.data.bar.position === "right") ? verticalBarComponent : horizontalBarComponent
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For vertical bars
|
||||
Component {
|
||||
id: verticalBarComponent
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
// For vertical bars
|
||||
Component {
|
||||
id: verticalBarComponent
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
clip: true
|
||||
|
||||
// Top section (left widgets)
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Style.marginM
|
||||
spacing: Style.marginS
|
||||
// Top section (left widgets)
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Style.marginM
|
||||
spacing: Style.marginS
|
||||
|
||||
Repeater {
|
||||
model: Settings.data.bar.widgets.left
|
||||
delegate: BarWidgetLoader {
|
||||
widgetId: (modelData.id !== undefined ? modelData.id : "")
|
||||
barDensity: Settings.data.bar.density
|
||||
widgetProps: {
|
||||
"screen": root.modelData || null,
|
||||
"widgetId": modelData.id,
|
||||
"section": "left",
|
||||
"sectionWidgetIndex": index,
|
||||
"sectionWidgetsCount": Settings.data.bar.widgets.left.length
|
||||
}
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
Repeater {
|
||||
model: Settings.data.bar.widgets.left
|
||||
delegate: BarWidgetLoader {
|
||||
required property var modelData
|
||||
required property int index
|
||||
|
||||
// Center section (center widgets)
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Style.marginS
|
||||
|
||||
Repeater {
|
||||
model: Settings.data.bar.widgets.center
|
||||
delegate: BarWidgetLoader {
|
||||
widgetId: (modelData.id !== undefined ? modelData.id : "")
|
||||
barDensity: Settings.data.bar.density
|
||||
widgetProps: {
|
||||
"screen": root.modelData || null,
|
||||
"widgetId": modelData.id,
|
||||
"section": "center",
|
||||
"sectionWidgetIndex": index,
|
||||
"sectionWidgetsCount": Settings.data.bar.widgets.center.length
|
||||
}
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bottom section (right widgets)
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: Style.marginM
|
||||
spacing: Style.marginS
|
||||
|
||||
Repeater {
|
||||
model: Settings.data.bar.widgets.right
|
||||
delegate: BarWidgetLoader {
|
||||
widgetId: (modelData.id !== undefined ? modelData.id : "")
|
||||
barDensity: Settings.data.bar.density
|
||||
widgetProps: {
|
||||
"screen": root.modelData || null,
|
||||
"widgetId": modelData.id,
|
||||
"section": "right",
|
||||
"sectionWidgetIndex": index,
|
||||
"sectionWidgetsCount": Settings.data.bar.widgets.right.length
|
||||
}
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
widgetId: modelData.id || ""
|
||||
barDensity: Settings.data.bar.density
|
||||
widgetScreen: root.screen
|
||||
widgetProps: ({
|
||||
"widgetId": modelData.id,
|
||||
"section": "left",
|
||||
"sectionWidgetIndex": index,
|
||||
"sectionWidgetsCount": Settings.data.bar.widgets.left.length
|
||||
})
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For horizontal bars
|
||||
Component {
|
||||
id: horizontalBarComponent
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
// Center section (center widgets)
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Style.marginS
|
||||
|
||||
// Left Section
|
||||
RowLayout {
|
||||
id: leftSection
|
||||
objectName: "leftSection"
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Style.marginS
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Style.marginS
|
||||
Repeater {
|
||||
model: Settings.data.bar.widgets.center
|
||||
delegate: BarWidgetLoader {
|
||||
required property var modelData
|
||||
required property int index
|
||||
|
||||
Repeater {
|
||||
model: Settings.data.bar.widgets.left
|
||||
delegate: BarWidgetLoader {
|
||||
widgetId: (modelData.id !== undefined ? modelData.id : "")
|
||||
barDensity: Settings.data.bar.density
|
||||
widgetProps: {
|
||||
"screen": root.modelData || null,
|
||||
"widgetId": modelData.id,
|
||||
"section": "left",
|
||||
"sectionWidgetIndex": index,
|
||||
"sectionWidgetsCount": Settings.data.bar.widgets.left.length
|
||||
}
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
widgetId: modelData.id || ""
|
||||
barDensity: Settings.data.bar.density
|
||||
widgetScreen: root.screen
|
||||
widgetProps: ({
|
||||
"widgetId": modelData.id,
|
||||
"section": "center",
|
||||
"sectionWidgetIndex": index,
|
||||
"sectionWidgetsCount": Settings.data.bar.widgets.center.length
|
||||
})
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Center Section
|
||||
RowLayout {
|
||||
id: centerSection
|
||||
objectName: "centerSection"
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Style.marginS
|
||||
// Bottom section (right widgets)
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: Style.marginM
|
||||
spacing: Style.marginS
|
||||
|
||||
Repeater {
|
||||
model: Settings.data.bar.widgets.center
|
||||
delegate: BarWidgetLoader {
|
||||
widgetId: (modelData.id !== undefined ? modelData.id : "")
|
||||
barDensity: Settings.data.bar.density
|
||||
widgetProps: {
|
||||
"screen": root.modelData || null,
|
||||
"widgetId": modelData.id,
|
||||
"section": "center",
|
||||
"sectionWidgetIndex": index,
|
||||
"sectionWidgetsCount": Settings.data.bar.widgets.center.length
|
||||
}
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
Repeater {
|
||||
model: Settings.data.bar.widgets.right
|
||||
delegate: BarWidgetLoader {
|
||||
required property var modelData
|
||||
required property int index
|
||||
|
||||
// Right Section
|
||||
RowLayout {
|
||||
id: rightSection
|
||||
objectName: "rightSection"
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Style.marginS
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Style.marginS
|
||||
widgetId: modelData.id || ""
|
||||
barDensity: Settings.data.bar.density
|
||||
widgetScreen: root.screen
|
||||
widgetProps: ({
|
||||
"widgetId": modelData.id,
|
||||
"section": "right",
|
||||
"sectionWidgetIndex": index,
|
||||
"sectionWidgetsCount": Settings.data.bar.widgets.right.length
|
||||
})
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: Settings.data.bar.widgets.right
|
||||
delegate: BarWidgetLoader {
|
||||
widgetId: (modelData.id !== undefined ? modelData.id : "")
|
||||
barDensity: Settings.data.bar.density
|
||||
widgetProps: {
|
||||
"screen": root.modelData || null,
|
||||
"widgetId": modelData.id,
|
||||
"section": "right",
|
||||
"sectionWidgetIndex": index,
|
||||
"sectionWidgetsCount": Settings.data.bar.widgets.right.length
|
||||
}
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
// For horizontal bars
|
||||
Component {
|
||||
id: horizontalBarComponent
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
clip: true
|
||||
|
||||
// Left Section
|
||||
RowLayout {
|
||||
id: leftSection
|
||||
objectName: "leftSection"
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Style.marginS
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Style.marginS
|
||||
|
||||
Repeater {
|
||||
model: Settings.data.bar.widgets.left
|
||||
delegate: BarWidgetLoader {
|
||||
required property var modelData
|
||||
required property int index
|
||||
|
||||
widgetId: modelData.id || ""
|
||||
barDensity: Settings.data.bar.density
|
||||
widgetScreen: root.screen
|
||||
widgetProps: ({
|
||||
"widgetId": modelData.id,
|
||||
"section": "left",
|
||||
"sectionWidgetIndex": index,
|
||||
"sectionWidgetsCount": Settings.data.bar.widgets.left.length
|
||||
})
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Center Section
|
||||
RowLayout {
|
||||
id: centerSection
|
||||
objectName: "centerSection"
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Style.marginS
|
||||
|
||||
Repeater {
|
||||
model: Settings.data.bar.widgets.center
|
||||
delegate: BarWidgetLoader {
|
||||
required property var modelData
|
||||
required property int index
|
||||
|
||||
widgetId: modelData.id || ""
|
||||
barDensity: Settings.data.bar.density
|
||||
widgetScreen: root.screen
|
||||
widgetProps: ({
|
||||
"widgetId": modelData.id,
|
||||
"section": "center",
|
||||
"sectionWidgetIndex": index,
|
||||
"sectionWidgetsCount": Settings.data.bar.widgets.center.length
|
||||
})
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Right Section
|
||||
RowLayout {
|
||||
id: rightSection
|
||||
objectName: "rightSection"
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Style.marginS
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Style.marginS
|
||||
|
||||
Repeater {
|
||||
model: Settings.data.bar.widgets.right
|
||||
delegate: BarWidgetLoader {
|
||||
required property var modelData
|
||||
required property int index
|
||||
|
||||
widgetId: modelData.id || ""
|
||||
barDensity: Settings.data.bar.density
|
||||
widgetScreen: root.screen
|
||||
widgetProps: ({
|
||||
"widgetId": modelData.id,
|
||||
"section": "right",
|
||||
"sectionWidgetIndex": index,
|
||||
"sectionWidgetsCount": Settings.data.bar.widgets.right.length
|
||||
})
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,7 @@ NPanel {
|
||||
id: root
|
||||
|
||||
preferredWidth: 350 * Style.uiScaleRatio
|
||||
preferredHeight: 250 * Style.uiScaleRatio
|
||||
panelKeyboardFocus: true
|
||||
preferredHeight: 210 * Style.uiScaleRatio
|
||||
|
||||
property var optionsModel: []
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ NPanel {
|
||||
|
||||
preferredWidth: 420 * Style.uiScaleRatio
|
||||
preferredHeight: 500 * Style.uiScaleRatio
|
||||
panelKeyboardFocus: true
|
||||
|
||||
panelContent: Rectangle {
|
||||
color: Color.transparent
|
||||
|
||||
@@ -14,7 +14,8 @@ NPanel {
|
||||
property ShellScreen screen
|
||||
readonly property var now: Time.date
|
||||
|
||||
panelKeyboardFocus: true
|
||||
preferredWidth: 500
|
||||
preferredHeight: 700
|
||||
|
||||
// Helper function to calculate ISO week number
|
||||
function getISOWeekNumber(date) {
|
||||
@@ -44,7 +45,8 @@ NPanel {
|
||||
return numWeeks * rowHeight
|
||||
}
|
||||
|
||||
property real contentPreferredHeight: banner.height + calendar.height + weatherLoader.height + Style.marginM * 4 + (Settings.data.location.weatherEnabled && Settings.data.location.showCalendarWeather) * Style.marginM
|
||||
// Use implicitHeight from content + margins to avoid binding loops
|
||||
property real contentPreferredHeight: content.implicitHeight + Style.marginL * 2
|
||||
|
||||
ColumnLayout {
|
||||
id: content
|
||||
@@ -65,20 +67,6 @@ NPanel {
|
||||
isCurrentMonth = checkIsCurrentMonth()
|
||||
}
|
||||
|
||||
Shortcut {
|
||||
sequence: "Escape"
|
||||
onActivated: {
|
||||
if (timerActive) {
|
||||
cancelTimer()
|
||||
} else {
|
||||
cancelTimer()
|
||||
root.close()
|
||||
}
|
||||
}
|
||||
context: Qt.WidgetShortcut
|
||||
enabled: root.opened
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Time
|
||||
function onDateChanged() {
|
||||
@@ -623,7 +611,7 @@ 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])
|
||||
PanelService.getPanel("calendarPanel").toggle(null)
|
||||
root.close()
|
||||
}
|
||||
|
||||
onExited: {
|
||||
|
||||
@@ -6,15 +6,17 @@ import qs.Commons
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property string widgetId: ""
|
||||
property var widgetProps: ({})
|
||||
property string screenName: widgetProps && widgetProps.screen ? widgetProps.screen.name : ""
|
||||
property string section: widgetProps && widgetProps.section || ""
|
||||
property int sectionIndex: widgetProps && widgetProps.sectionWidgetIndex || 0
|
||||
required property string widgetId
|
||||
required property var widgetScreen
|
||||
required property var widgetProps
|
||||
|
||||
property string barDensity: "default"
|
||||
readonly property real scaling: barDensity === "mini" ? 0.8 : (barDensity === "compact" ? 0.9 : 1.0)
|
||||
|
||||
// Extract section info from widgetProps
|
||||
readonly property string section: widgetProps.section || ""
|
||||
readonly property int sectionIndex: widgetProps.sectionWidgetIndex || 0
|
||||
|
||||
// Don't reserve space unless the loaded widget is really visible
|
||||
implicitWidth: getImplicitSize(loader.item, "implicitWidth")
|
||||
implicitHeight: getImplicitSize(loader.item, "implicitHeight")
|
||||
@@ -26,56 +28,54 @@ Item {
|
||||
Loader {
|
||||
id: loader
|
||||
anchors.fill: parent
|
||||
active: widgetId !== ""
|
||||
asynchronous: false
|
||||
sourceComponent: {
|
||||
if (!active) {
|
||||
return null
|
||||
}
|
||||
return BarWidgetRegistry.getWidget(widgetId)
|
||||
}
|
||||
sourceComponent: BarWidgetRegistry.getWidget(widgetId)
|
||||
|
||||
onLoaded: {
|
||||
if (item && widgetProps) {
|
||||
// Apply properties to loaded widget
|
||||
for (var prop in widgetProps) {
|
||||
if (item.hasOwnProperty(prop)) {
|
||||
item[prop] = widgetProps[prop]
|
||||
}
|
||||
}
|
||||
// Explicitly set scaling property
|
||||
if (item.hasOwnProperty("scaling")) {
|
||||
item.scaling = Qt.binding(function () {
|
||||
return root.scaling
|
||||
})
|
||||
if (!item)
|
||||
return
|
||||
|
||||
Logger.d("BarWidgetLoader", "Loading widget", widgetId, "on screen:", widgetScreen.name)
|
||||
|
||||
// Apply properties to loaded widget
|
||||
for (var prop in widgetProps) {
|
||||
if (item.hasOwnProperty(prop)) {
|
||||
item[prop] = widgetProps[prop]
|
||||
}
|
||||
}
|
||||
|
||||
// Set screen property
|
||||
if (item.hasOwnProperty("screen")) {
|
||||
item.screen = widgetScreen
|
||||
}
|
||||
|
||||
// Set scaling property
|
||||
if (item.hasOwnProperty("scaling")) {
|
||||
item.scaling = Qt.binding(function () {
|
||||
return root.scaling
|
||||
})
|
||||
}
|
||||
|
||||
// Register this widget instance with BarService
|
||||
if (screenName && section) {
|
||||
BarService.registerWidget(screenName, section, widgetId, sectionIndex, item)
|
||||
}
|
||||
BarService.registerWidget(widgetScreen.name, section, widgetId, sectionIndex, item)
|
||||
|
||||
// Call custom onLoaded if it exists
|
||||
if (item.hasOwnProperty("onLoaded")) {
|
||||
item.onLoaded()
|
||||
}
|
||||
|
||||
//Logger.i("BarWidgetLoader", "Loaded", widgetId, "on screen", item.screen.name)
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
// Unregister when destroyed
|
||||
if (screenName && section) {
|
||||
BarService.unregisterWidget(screenName, section, widgetId, sectionIndex)
|
||||
if (widgetScreen && section) {
|
||||
BarService.unregisterWidget(widgetScreen.name, section, widgetId, sectionIndex)
|
||||
}
|
||||
// Explicitly clear references
|
||||
widgetProps = null
|
||||
}
|
||||
}
|
||||
|
||||
// Error handling
|
||||
onWidgetIdChanged: {
|
||||
if (widgetId && !BarWidgetRegistry.hasWidget(widgetId)) {
|
||||
Component.onCompleted: {
|
||||
if (!BarWidgetRegistry.hasWidget(widgetId)) {
|
||||
Logger.w("BarWidgetLoader", "Widget not found in registry:", widgetId)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ NPanel {
|
||||
|
||||
preferredWidth: 420 * Style.uiScaleRatio
|
||||
preferredHeight: 500 * Style.uiScaleRatio
|
||||
panelKeyboardFocus: true
|
||||
|
||||
property string passwordSsid: ""
|
||||
property string passwordInput: ""
|
||||
|
||||
@@ -94,7 +94,7 @@ Item {
|
||||
autoHide: false
|
||||
forceOpen: isReady && (testMode || battery.isLaptopBattery) && displayMode === "alwaysShow"
|
||||
forceClose: displayMode === "alwaysHide" || !isReady || (!testMode && !battery.isLaptopBattery)
|
||||
onClicked: PanelService.getPanel("batteryPanel")?.toggle(this)
|
||||
onClicked: PanelService.getPanel("batteryPanel", screen)?.toggle(this)
|
||||
tooltipText: {
|
||||
let lines = []
|
||||
if (testMode) {
|
||||
|
||||
@@ -54,8 +54,8 @@ Item {
|
||||
autoHide: false
|
||||
forceOpen: !isBarVertical && root.displayMode === "alwaysShow"
|
||||
forceClose: isBarVertical || root.displayMode === "alwaysHide" || BluetoothService.connectedDevices.length === 0
|
||||
onClicked: PanelService.getPanel("bluetoothPanel")?.toggle(this)
|
||||
onRightClicked: PanelService.getPanel("bluetoothPanel")?.toggle(this)
|
||||
onClicked: PanelService.getPanel("bluetoothPanel", screen)?.toggle(this)
|
||||
onRightClicked: PanelService.getPanel("bluetoothPanel", screen)?.toggle(this)
|
||||
tooltipText: {
|
||||
if (pill.text !== "") {
|
||||
return pill.text
|
||||
|
||||
@@ -108,13 +108,13 @@ Item {
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
var settingsPanel = PanelService.getPanel("settingsPanel")
|
||||
var settingsPanel = PanelService.getPanel("settingsPanel", screen)
|
||||
settingsPanel.requestedTab = SettingsPanel.Tab.Display
|
||||
settingsPanel.open()
|
||||
}
|
||||
|
||||
onRightClicked: {
|
||||
var settingsPanel = PanelService.getPanel("settingsPanel")
|
||||
var settingsPanel = PanelService.getPanel("settingsPanel", screen)
|
||||
settingsPanel.requestedTab = SettingsPanel.Tab.Display
|
||||
settingsPanel.open()
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ Rectangle {
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
hoverEnabled: true
|
||||
onEntered: {
|
||||
if (!PanelService.getPanel("calendarPanel")?.active) {
|
||||
if (!PanelService.getPanel("calendarPanel", screen)?.active) {
|
||||
TooltipService.show(Screen, root, I18n.tr("clock.tooltip"), BarService.getTooltipDirection())
|
||||
}
|
||||
}
|
||||
@@ -130,7 +130,7 @@ Rectangle {
|
||||
}
|
||||
onClicked: {
|
||||
TooltipService.hide()
|
||||
PanelService.getPanel("calendarPanel")?.toggle(this)
|
||||
PanelService.getPanel("calendarPanel", screen)?.toggle(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,8 +44,8 @@ NIconButton {
|
||||
colorBgHover: useDistroLogo ? Color.mSurfaceVariant : Color.mHover
|
||||
colorBorder: Color.transparent
|
||||
colorBorderHover: useDistroLogo ? Color.mHover : Color.transparent
|
||||
onClicked: PanelService.getPanel("controlCenterPanel")?.toggle(this)
|
||||
onRightClicked: PanelService.getPanel("settingsPanel")?.toggle()
|
||||
onClicked: PanelService.getPanel("controlCenterPanel", screen)?.toggle(this)
|
||||
onRightClicked: PanelService.getPanel("settingsPanel", screen)?.toggle()
|
||||
|
||||
IconImage {
|
||||
id: customOrDistroLogo
|
||||
|
||||
@@ -184,7 +184,7 @@ Item {
|
||||
Logger.i("CustomButton", `Executing command: ${leftClickExec}`)
|
||||
} else if (!hasExec) {
|
||||
// No script was defined, open settings
|
||||
var settingsPanel = PanelService.getPanel("settingsPanel")
|
||||
var settingsPanel = PanelService.getPanel("settingsPanel", screen)
|
||||
settingsPanel.requestedTab = SettingsPanel.Tab.Bar
|
||||
settingsPanel.open()
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ Item {
|
||||
}
|
||||
}
|
||||
onClicked: {
|
||||
PanelService.getPanel("audioPanel")?.toggle(this)
|
||||
PanelService.getPanel("audioPanel", screen)?.toggle(this)
|
||||
}
|
||||
onRightClicked: {
|
||||
AudioService.setInputMuted(!AudioService.inputMuted)
|
||||
|
||||
@@ -43,7 +43,7 @@ NIconButton {
|
||||
}
|
||||
|
||||
onRightClicked: {
|
||||
var settingsPanel = PanelService.getPanel("settingsPanel")
|
||||
var settingsPanel = PanelService.getPanel("settingsPanel", screen)
|
||||
settingsPanel.requestedTab = SettingsPanel.Tab.Display
|
||||
settingsPanel.open()
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ NIconButton {
|
||||
colorBorderHover: Color.transparent
|
||||
|
||||
onClicked: {
|
||||
var panel = PanelService.getPanel("notificationHistoryPanel")
|
||||
var panel = PanelService.getPanel("notificationHistoryPanel", screen)
|
||||
panel?.toggle(this)
|
||||
}
|
||||
|
||||
|
||||
@@ -20,5 +20,5 @@ NIconButton {
|
||||
colorFg: Color.mError
|
||||
colorBorder: Color.transparent
|
||||
colorBorderHover: Color.transparent
|
||||
onClicked: PanelService.getPanel("sessionMenuPanel")?.toggle()
|
||||
onClicked: PanelService.getPanel("sessionMenuPanel", screen)?.toggle()
|
||||
}
|
||||
|
||||
@@ -279,7 +279,6 @@ Rectangle {
|
||||
|
||||
function open() {
|
||||
visible = true
|
||||
PanelService.willOpenPanel(trayPanel)
|
||||
}
|
||||
|
||||
function close() {
|
||||
|
||||
@@ -90,7 +90,7 @@ Item {
|
||||
}
|
||||
}
|
||||
onClicked: {
|
||||
PanelService.getPanel("audioPanel")?.toggle(this)
|
||||
PanelService.getPanel("audioPanel", screen)?.toggle(this)
|
||||
}
|
||||
onRightClicked: {
|
||||
AudioService.setOutputMuted(!AudioService.muted)
|
||||
|
||||
@@ -20,5 +20,5 @@ NIconButton {
|
||||
colorFg: Color.mOnSurface
|
||||
colorBorder: Color.transparent
|
||||
colorBorderHover: Color.transparent
|
||||
onClicked: PanelService.getPanel("wallpaperPanel")?.toggle(this)
|
||||
onClicked: PanelService.getPanel("wallpaperPanel", screen)?.toggle(this)
|
||||
}
|
||||
|
||||
@@ -76,8 +76,8 @@ Item {
|
||||
autoHide: false
|
||||
forceOpen: !isBarVertical && root.displayMode === "alwaysShow"
|
||||
forceClose: isBarVertical || root.displayMode === "alwaysHide" || !pill.text
|
||||
onClicked: PanelService.getPanel("wifiPanel")?.toggle(this)
|
||||
onRightClicked: PanelService.getPanel("wifiPanel")?.toggle(this)
|
||||
onClicked: PanelService.getPanel("wifiPanel", screen)?.toggle(this)
|
||||
onRightClicked: PanelService.getPanel("wifiPanel", screen)?.toggle(this)
|
||||
tooltipText: {
|
||||
if (pill.text !== "") {
|
||||
return pill.text
|
||||
|
||||
Reference in New Issue
Block a user