diff --git a/components/controls/CollapsibleSection.qml b/components/controls/CollapsibleSection.qml index a338d412..0e4c3dcf 100644 --- a/components/controls/CollapsibleSection.qml +++ b/components/controls/CollapsibleSection.qml @@ -15,6 +15,8 @@ ColumnLayout { property bool showBackground: false property bool nested: false + default property alias content: contentColumn.data + signal toggleRequested spacing: Appearance.spacing.small @@ -61,19 +63,18 @@ ColumnLayout { } StateLayer { - anchors.fill: parent - color: Colours.palette.m3onSurface - radius: Appearance.rounding.normal - showHoverBackground: false function onClicked(): void { root.toggleRequested(); root.expanded = !root.expanded; } + + anchors.fill: parent + color: Colours.palette.m3onSurface + radius: Appearance.rounding.normal + showHoverBackground: false } } - default property alias content: contentColumn.data - Item { id: contentWrapper diff --git a/components/controls/CustomSpinBox.qml b/components/controls/CustomSpinBox.qml index 438dc080..eaf2eb59 100644 --- a/components/controls/CustomSpinBox.qml +++ b/components/controls/CustomSpinBox.qml @@ -15,13 +15,13 @@ RowLayout { property real step: 1 property alias repeatRate: timer.interval + property bool isEditing: false + property string displayText: root.value.toString() + signal valueModified(value: real) spacing: Appearance.spacing.small - property bool isEditing: false - property string displayText: root.value.toString() - onValueChanged: { if (!root.isEditing) { root.displayText = root.value.toString(); @@ -94,11 +94,6 @@ RowLayout { StateLayer { id: upState - color: Colours.palette.m3onPrimary - - onPressAndHold: timer.start() - onReleased: timer.stop() - function onClicked(): void { let newValue = Math.min(root.max, root.value + root.step); // Round to avoid floating point precision errors @@ -108,6 +103,11 @@ RowLayout { root.displayText = newValue.toString(); root.valueModified(newValue); } + + color: Colours.palette.m3onPrimary + + onPressAndHold: timer.start() + onReleased: timer.stop() } MaterialIcon { @@ -129,11 +129,6 @@ RowLayout { StateLayer { id: downState - color: Colours.palette.m3onPrimary - - onPressAndHold: timer.start() - onReleased: timer.stop() - function onClicked(): void { let newValue = Math.max(root.min, root.value - root.step); // Round to avoid floating point precision errors @@ -143,6 +138,11 @@ RowLayout { root.displayText = newValue.toString(); root.valueModified(newValue); } + + color: Colours.palette.m3onPrimary + + onPressAndHold: timer.start() + onReleased: timer.stop() } MaterialIcon { diff --git a/components/controls/IconButton.qml b/components/controls/IconButton.qml index ffb1d066..2e5f4a3d 100644 --- a/components/controls/IconButton.qml +++ b/components/controls/IconButton.qml @@ -53,14 +53,14 @@ StyledRect { StateLayer { id: stateLayer - color: root.internalChecked ? root.activeOnColour : root.inactiveOnColour - disabled: root.disabled - function onClicked(): void { if (root.toggle) root.internalChecked = !root.internalChecked; root.clicked(); } + + color: root.internalChecked ? root.activeOnColour : root.inactiveOnColour + disabled: root.disabled } MaterialIcon { diff --git a/components/controls/IconTextButton.qml b/components/controls/IconTextButton.qml index b2bb96cc..74c8cf2b 100644 --- a/components/controls/IconTextButton.qml +++ b/components/controls/IconTextButton.qml @@ -45,13 +45,13 @@ StyledRect { StateLayer { id: stateLayer - color: root.internalChecked ? root.activeOnColour : root.inactiveOnColour - function onClicked(): void { if (root.toggle) root.internalChecked = !root.internalChecked; root.clicked(); } + + color: root.internalChecked ? root.activeOnColour : root.inactiveOnColour } RowLayout { diff --git a/components/controls/Menu.qml b/components/controls/Menu.qml index 3e834aec..b5a672df 100644 --- a/components/controls/Menu.qml +++ b/components/controls/Menu.qml @@ -52,14 +52,14 @@ Elevation { color: Qt.alpha(Colours.palette.m3secondaryContainer, active ? 1 : 0) StateLayer { - color: item.active ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface - disabled: !root.expanded - function onClicked(): void { root.itemSelected(item.modelData); root.active = item.modelData; root.expanded = false; } + + color: item.active ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface + disabled: !root.expanded } RowLayout { diff --git a/components/controls/SplitButton.qml b/components/controls/SplitButton.qml index c91474ea..d8d256bf 100644 --- a/components/controls/SplitButton.qml +++ b/components/controls/SplitButton.qml @@ -47,14 +47,14 @@ Row { StateLayer { id: stateLayer + function onClicked(): void { + root.active?.clicked(); + } + rect.topRightRadius: parent.topRightRadius rect.bottomRightRadius: parent.bottomRightRadius color: root.textColour disabled: root.disabled - - function onClicked(): void { - root.active?.clicked(); - } } RowLayout { @@ -109,14 +109,14 @@ Row { StateLayer { id: expandStateLayer + function onClicked(): void { + root.expanded = !root.expanded; + } + rect.topLeftRadius: parent.topLeftRadius rect.bottomLeftRadius: parent.bottomLeftRadius color: root.textColour disabled: root.disabled - - function onClicked(): void { - root.expanded = !root.expanded; - } } MaterialIcon { diff --git a/components/controls/StyledRadioButton.qml b/components/controls/StyledRadioButton.qml index b72fc77f..d0a242bf 100644 --- a/components/controls/StyledRadioButton.qml +++ b/components/controls/StyledRadioButton.qml @@ -24,13 +24,13 @@ RadioButton { anchors.verticalCenter: parent.verticalCenter StateLayer { - anchors.margins: -Appearance.padding.smaller - color: root.checked ? Colours.palette.m3onSurface : Colours.palette.m3primary - z: -1 - function onClicked(): void { root.click(); } + + anchors.margins: -Appearance.padding.smaller + color: root.checked ? Colours.palette.m3onSurface : Colours.palette.m3primary + z: -1 } StyledRect { diff --git a/components/controls/StyledScrollBar.qml b/components/controls/StyledScrollBar.qml index de8b679c..c2831da4 100644 --- a/components/controls/StyledScrollBar.qml +++ b/components/controls/StyledScrollBar.qml @@ -11,6 +11,8 @@ ScrollBar { property bool shouldBeActive property real nonAnimPosition property bool animating + property bool _updatingFromFlickable: false + property bool _updatingFromUser: false onHoveredChanged: { if (hovered) @@ -19,9 +21,6 @@ ScrollBar { shouldBeActive = flickable.moving; } - property bool _updatingFromFlickable: false - property bool _updatingFromUser: false - // Sync nonAnimPosition with Qt's automatic position binding onPositionChanged: { if (_updatingFromUser) { @@ -118,6 +117,29 @@ ScrollBar { CustomMouseArea { id: fullMouse + function onWheel(event: WheelEvent): void { + root.animating = true; + root._updatingFromUser = true; + let newPos = root.nonAnimPosition; + if (event.angleDelta.y > 0) + newPos = Math.max(0, root.nonAnimPosition - 0.1); + else if (event.angleDelta.y < 0) + newPos = Math.min(1 - root.size, root.nonAnimPosition + 0.1); + root.nonAnimPosition = newPos; + // Update flickable position + // Map scrollbar position [0, 1-size] to contentY [0, maxContentY] + if (root.flickable) { + const contentHeight = root.flickable.contentHeight; + const height = root.flickable.height; + if (contentHeight > height) { + const maxContentY = contentHeight - height; + const maxPos = 1 - root.size; + const contentY = maxPos > 0 ? (newPos / maxPos) * maxContentY : 0; + root.flickable.contentY = Math.max(0, Math.min(maxContentY, contentY)); + } + } + } + anchors.fill: parent preventStealing: true @@ -157,29 +179,6 @@ ScrollBar { } } } - - function onWheel(event: WheelEvent): void { - root.animating = true; - root._updatingFromUser = true; - let newPos = root.nonAnimPosition; - if (event.angleDelta.y > 0) - newPos = Math.max(0, root.nonAnimPosition - 0.1); - else if (event.angleDelta.y < 0) - newPos = Math.min(1 - root.size, root.nonAnimPosition + 0.1); - root.nonAnimPosition = newPos; - // Update flickable position - // Map scrollbar position [0, 1-size] to contentY [0, maxContentY] - if (root.flickable) { - const contentHeight = root.flickable.contentHeight; - const height = root.flickable.height; - if (contentHeight > height) { - const maxContentY = contentHeight - height; - const maxPos = 1 - root.size; - const contentY = maxPos > 0 ? (newPos / maxPos) * maxContentY : 0; - root.flickable.contentY = Math.max(0, Math.min(maxContentY, contentY)); - } - } - } } Behavior on position { diff --git a/components/controls/TextButton.qml b/components/controls/TextButton.qml index ecf7eb13..40419e48 100644 --- a/components/controls/TextButton.qml +++ b/components/controls/TextButton.qml @@ -56,13 +56,13 @@ StyledRect { StateLayer { id: stateLayer - color: root.internalChecked ? root.activeOnColour : root.inactiveOnColour - function onClicked(): void { if (root.toggle) root.internalChecked = !root.internalChecked; root.clicked(); } + + color: root.internalChecked ? root.activeOnColour : root.inactiveOnColour } StyledText { diff --git a/components/controls/ToggleButton.qml b/components/controls/ToggleButton.qml index dd42af25..8286ccae 100644 --- a/components/controls/ToggleButton.qml +++ b/components/controls/ToggleButton.qml @@ -46,11 +46,11 @@ StyledRect { StateLayer { id: toggleStateLayer - color: root.toggled ? Colours.palette[`m3on${root.accent}`] : Colours.palette[`m3on${root.accent}Container`] - function onClicked(): void { root.clicked(); } + + color: root.toggled ? Colours.palette[`m3on${root.accent}`] : Colours.palette[`m3on${root.accent}Container`] } RowLayout { diff --git a/components/controls/Tooltip.qml b/components/controls/Tooltip.qml index b129a37b..8d16fd48 100644 --- a/components/controls/Tooltip.qml +++ b/components/controls/Tooltip.qml @@ -24,6 +24,43 @@ Popup { onTriggered: root.tooltipVisible = false } + function updatePosition() { + if (!target || !parent) + return; + + // Wait for tooltipRect to have its size calculated + Qt.callLater(() => { + if (!target || !parent || !tooltipRect) + return; + + // Get target position in parent's coordinate system + const targetPos = target.mapToItem(parent, 0, 0); + const targetCenterX = targetPos.x + target.width / 2; + + // Get tooltip size (use width/height if available, otherwise implicit) + const tooltipWidth = tooltipRect.width > 0 ? tooltipRect.width : tooltipRect.implicitWidth; + const tooltipHeight = tooltipRect.height > 0 ? tooltipRect.height : tooltipRect.implicitHeight; + + // Center tooltip horizontally on target + let newX = targetCenterX - tooltipWidth / 2; + + // Position tooltip above target + let newY = targetPos.y - tooltipHeight - Appearance.spacing.small; + + // Keep within bounds + const padding = Appearance.padding.normal; + if (newX < padding) { + newX = padding; + } else if (newX + tooltipWidth > (parent.width - padding)) { + newX = parent.width - tooltipWidth - padding; + } + + // Update popup position + x = newX; + y = newY; + }); + } + // Popup properties - doesn't affect layout parent: { let p = target; @@ -73,43 +110,6 @@ Popup { } } - function updatePosition() { - if (!target || !parent) - return; - - // Wait for tooltipRect to have its size calculated - Qt.callLater(() => { - if (!target || !parent || !tooltipRect) - return; - - // Get target position in parent's coordinate system - const targetPos = target.mapToItem(parent, 0, 0); - const targetCenterX = targetPos.x + target.width / 2; - - // Get tooltip size (use width/height if available, otherwise implicit) - const tooltipWidth = tooltipRect.width > 0 ? tooltipRect.width : tooltipRect.implicitWidth; - const tooltipHeight = tooltipRect.height > 0 ? tooltipRect.height : tooltipRect.implicitHeight; - - // Center tooltip horizontally on target - let newX = targetCenterX - tooltipWidth / 2; - - // Position tooltip above target - let newY = targetPos.y - tooltipHeight - Appearance.spacing.small; - - // Keep within bounds - const padding = Appearance.padding.normal; - if (newX < padding) { - newX = padding; - } else if (newX + tooltipWidth > (parent.width - padding)) { - newX = parent.width - tooltipWidth - padding; - } - - // Update popup position - x = newX; - y = newY; - }); - } - enter: Transition { Anim { property: "opacity" diff --git a/components/filedialog/DialogButtons.qml b/components/filedialog/DialogButtons.qml index bde9ac27..ff24efdb 100644 --- a/components/filedialog/DialogButtons.qml +++ b/components/filedialog/DialogButtons.qml @@ -49,11 +49,11 @@ StyledRect { implicitHeight: cancelText.implicitHeight + Appearance.padding.normal * 2 StateLayer { - disabled: !root.dialog.selectionValid - function onClicked(): void { root.dialog.accepted(root.folder.currentItem.modelData.path); } + + disabled: !root.dialog.selectionValid } StyledText { diff --git a/components/filedialog/HeaderBar.qml b/components/filedialog/HeaderBar.qml index 43184bfd..40471164 100644 --- a/components/filedialog/HeaderBar.qml +++ b/components/filedialog/HeaderBar.qml @@ -28,12 +28,12 @@ StyledRect { implicitHeight: upIcon.implicitHeight + Appearance.padding.small * 2 StateLayer { - radius: Appearance.rounding.small - disabled: root.dialog.cwd.length === 1 - function onClicked(): void { root.dialog.cwd.pop(); } + + radius: Appearance.rounding.small + disabled: root.dialog.cwd.length === 1 } MaterialIcon { @@ -94,11 +94,11 @@ StyledRect { anchors.fill: parent active: folder.index < root.dialog.cwd.length - 1 sourceComponent: StateLayer { - radius: Appearance.rounding.small - function onClicked(): void { root.dialog.cwd = root.dialog.cwd.slice(0, folder.index + 1); } + + radius: Appearance.rounding.small } } diff --git a/components/filedialog/Sidebar.qml b/components/filedialog/Sidebar.qml index b55d7b37..4e83318b 100644 --- a/components/filedialog/Sidebar.qml +++ b/components/filedialog/Sidebar.qml @@ -51,14 +51,14 @@ StyledRect { color: Qt.alpha(Colours.palette.m3secondaryContainer, selected ? 1 : 0) StateLayer { - color: place.selected ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface - function onClicked(): void { if (place.modelData === "Home") root.dialog.cwd = ["Home"]; else root.dialog.cwd = ["Home", place.modelData]; } + + color: place.selected ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface } RowLayout { diff --git a/modules/background/Wallpaper.qml b/modules/background/Wallpaper.qml index 67511d86..ba9677cf 100644 --- a/modules/background/Wallpaper.qml +++ b/modules/background/Wallpaper.qml @@ -79,12 +79,12 @@ Item { } StateLayer { - radius: parent.radius - color: Colours.palette.m3onPrimary - function onClicked(): void { dialog.open(); } + + radius: parent.radius + color: Colours.palette.m3onPrimary } StyledText { diff --git a/modules/bar/popouts/ActiveWindow.qml b/modules/bar/popouts/ActiveWindow.qml index fe89c9e8..9f0162d3 100644 --- a/modules/bar/popouts/ActiveWindow.qml +++ b/modules/bar/popouts/ActiveWindow.qml @@ -65,11 +65,11 @@ Item { Layout.alignment: Qt.AlignVCenter StateLayer { - radius: Appearance.rounding.normal - function onClicked(): void { root.wrapper.detach("winfo"); } + + radius: Appearance.rounding.normal } MaterialIcon { diff --git a/modules/bar/popouts/Battery.qml b/modules/bar/popouts/Battery.qml index 78bd324e..7c68f4d3 100644 --- a/modules/bar/popouts/Battery.qml +++ b/modules/bar/popouts/Battery.qml @@ -205,12 +205,12 @@ Column { implicitHeight: icon.implicitHeight + Appearance.padding.small * 2 StateLayer { - radius: Appearance.rounding.full - color: profiles.current === parent.icon ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface - function onClicked(): void { PowerProfiles.profile = parent.profile; } + + radius: Appearance.rounding.full + color: profiles.current === parent.icon ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface } MaterialIcon { diff --git a/modules/bar/popouts/Bluetooth.qml b/modules/bar/popouts/Bluetooth.qml index 91ac5604..4201ad30 100644 --- a/modules/bar/popouts/Bluetooth.qml +++ b/modules/bar/popouts/Bluetooth.qml @@ -117,12 +117,12 @@ ColumnLayout { } StateLayer { - color: device.modelData.state === BluetoothDeviceState.Connected ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface - disabled: device.loading - function onClicked(): void { device.modelData.connected = !device.modelData.connected; } + + color: device.modelData.state === BluetoothDeviceState.Connected ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface + disabled: device.loading } MaterialIcon { @@ -149,11 +149,11 @@ ColumnLayout { implicitHeight: connectBtn.implicitHeight StateLayer { - radius: Appearance.rounding.full - function onClicked(): void { device.modelData.forget(); } + + radius: Appearance.rounding.full } MaterialIcon { diff --git a/modules/bar/popouts/Network.qml b/modules/bar/popouts/Network.qml index 5b32e4a6..367b9ab8 100644 --- a/modules/bar/popouts/Network.qml +++ b/modules/bar/popouts/Network.qml @@ -123,9 +123,6 @@ ColumnLayout { } StateLayer { - color: networkItem.modelData.active ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface - disabled: networkItem.loading || !Nmcli.wifiEnabled - function onClicked(): void { if (networkItem.modelData.active) { Nmcli.disconnectFromNetwork(); @@ -142,6 +139,9 @@ ColumnLayout { // This is handled by the onActiveChanged connection below } } + + color: networkItem.modelData.active ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface + disabled: networkItem.loading || !Nmcli.wifiEnabled } MaterialIcon { @@ -173,12 +173,12 @@ ColumnLayout { color: Colours.palette.m3primaryContainer StateLayer { - color: Colours.palette.m3onPrimaryContainer - disabled: Nmcli.scanning || !Nmcli.wifiEnabled - function onClicked(): void { Nmcli.rescanWifi(); } + + color: Colours.palette.m3onPrimaryContainer + disabled: Nmcli.scanning || !Nmcli.wifiEnabled } RowLayout { @@ -303,9 +303,6 @@ ColumnLayout { } StateLayer { - color: ethernetItem.modelData.connected ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface - disabled: ethernetItem.loading - function onClicked(): void { if (ethernetItem.modelData.connected && ethernetItem.modelData.connection) { Nmcli.disconnectEthernet(ethernetItem.modelData.connection, () => {}); @@ -313,6 +310,9 @@ ColumnLayout { Nmcli.connectEthernet(ethernetItem.modelData.connection || "", ethernetItem.modelData.interface || "", () => {}); } } + + color: ethernetItem.modelData.connected ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface + disabled: ethernetItem.loading } MaterialIcon { diff --git a/modules/bar/popouts/TrayMenu.qml b/modules/bar/popouts/TrayMenu.qml index a6680f44..eac73eeb 100644 --- a/modules/bar/popouts/TrayMenu.qml +++ b/modules/bar/popouts/TrayMenu.qml @@ -91,13 +91,6 @@ StackView { implicitHeight: label.implicitHeight StateLayer { - anchors.margins: -Appearance.padding.small / 2 - anchors.leftMargin: -Appearance.padding.smaller - anchors.rightMargin: -Appearance.padding.smaller - - radius: item.radius - disabled: !item.modelData.enabled - function onClicked(): void { const entry = item.modelData; if (entry.hasChildren) @@ -110,6 +103,13 @@ StackView { root.popouts.hasCurrent = false; } } + + anchors.margins: -Appearance.padding.small / 2 + anchors.leftMargin: -Appearance.padding.smaller + anchors.rightMargin: -Appearance.padding.smaller + + radius: item.radius + disabled: !item.modelData.enabled } Loader { @@ -191,12 +191,12 @@ StackView { color: Colours.palette.m3secondaryContainer StateLayer { - radius: parent.radius - color: Colours.palette.m3onSecondaryContainer - function onClicked(): void { root.pop(); } + + radius: parent.radius + color: Colours.palette.m3onSecondaryContainer } } diff --git a/modules/bar/popouts/WirelessPassword.qml b/modules/bar/popouts/WirelessPassword.qml index 54e635da..c6b37b63 100644 --- a/modules/bar/popouts/WirelessPassword.qml +++ b/modules/bar/popouts/WirelessPassword.qml @@ -18,6 +18,57 @@ ColumnLayout { readonly property bool shouldBeVisible: root.wrapper.currentName === "wirelesspassword" + function checkConnectionStatus(): void { + if (!root.shouldBeVisible || !connectButton.connecting) { + return; + } + + // Check if we're connected to the target network (case-insensitive SSID comparison) + const isConnected = root.network && Nmcli.active && Nmcli.active.ssid && Nmcli.active.ssid.toLowerCase().trim() === root.network.ssid.toLowerCase().trim(); + + if (isConnected) { + // Successfully connected - give it a moment for network list to update + // Use Timer for actual delay + connectionSuccessTimer.start(); + return; + } + + // Check for connection failures - if pending connection was cleared but we're not connected + if (Nmcli.pendingConnection === null && connectButton.connecting) { + // Wait a bit more before giving up (allow time for connection to establish) + if (connectionMonitor.repeatCount > 10) { + connectionMonitor.stop(); + connectButton.connecting = false; + connectButton.hasError = true; + connectButton.enabled = true; + connectButton.text = qsTr("Connect"); + passwordContainer.passwordBuffer = ""; + // Delete the failed connection + if (root.network && root.network.ssid) { + Nmcli.forgetNetwork(root.network.ssid); + } + } + } + } + + function closeDialog(): void { + if (isClosing) { + return; + } + + isClosing = true; + passwordContainer.passwordBuffer = ""; + connectButton.connecting = false; + connectButton.hasError = false; + connectButton.text = qsTr("Connect"); + connectionMonitor.stop(); + + // Return to network popout + if (root.wrapper.currentName === "wirelesspassword") { + root.wrapper.currentName = "network"; + } + } + Connections { target: root.wrapper function onCurrentNameChanged() { @@ -305,13 +356,13 @@ ColumnLayout { } StateLayer { - hoverEnabled: false - cursorShape: Qt.IBeamCursor - radius: Appearance.rounding.normal - function onClicked(): void { passwordContainer.forceActiveFocus(); } + + hoverEnabled: false + cursorShape: Qt.IBeamCursor + radius: Appearance.rounding.normal } StyledText { @@ -495,39 +546,6 @@ ColumnLayout { } } - function checkConnectionStatus(): void { - if (!root.shouldBeVisible || !connectButton.connecting) { - return; - } - - // Check if we're connected to the target network (case-insensitive SSID comparison) - const isConnected = root.network && Nmcli.active && Nmcli.active.ssid && Nmcli.active.ssid.toLowerCase().trim() === root.network.ssid.toLowerCase().trim(); - - if (isConnected) { - // Successfully connected - give it a moment for network list to update - // Use Timer for actual delay - connectionSuccessTimer.start(); - return; - } - - // Check for connection failures - if pending connection was cleared but we're not connected - if (Nmcli.pendingConnection === null && connectButton.connecting) { - // Wait a bit more before giving up (allow time for connection to establish) - if (connectionMonitor.repeatCount > 10) { - connectionMonitor.stop(); - connectButton.connecting = false; - connectButton.hasError = true; - connectButton.enabled = true; - connectButton.text = qsTr("Connect"); - passwordContainer.passwordBuffer = ""; - // Delete the failed connection - if (root.network && root.network.ssid) { - Nmcli.forgetNetwork(root.network.ssid); - } - } - } - } - Timer { id: connectionMonitor @@ -590,22 +608,4 @@ ColumnLayout { } } } - - function closeDialog(): void { - if (isClosing) { - return; - } - - isClosing = true; - passwordContainer.passwordBuffer = ""; - connectButton.connecting = false; - connectButton.hasError = false; - connectButton.text = qsTr("Connect"); - connectionMonitor.stop(); - - // Return to network popout - if (root.wrapper.currentName === "wirelesspassword") { - root.wrapper.currentName = "network"; - } - } } diff --git a/modules/bar/popouts/kblayout/KbLayout.qml b/modules/bar/popouts/kblayout/KbLayout.qml index aea25ceb..aba6e0cd 100644 --- a/modules/bar/popouts/kblayout/KbLayout.qml +++ b/modules/bar/popouts/kblayout/KbLayout.qml @@ -16,18 +16,19 @@ ColumnLayout { required property Item wrapper + function refresh() { + kb.refresh(); + } + spacing: Appearance.spacing.small width: Config.bar.sizes.kbLayoutWidth + Component.onCompleted: kb.start() + KbLayoutModel { id: kb } - function refresh() { - kb.refresh(); - } - Component.onCompleted: kb.start() - StyledText { Layout.topMargin: Appearance.padding.normal Layout.rightMargin: Appearance.padding.small @@ -97,6 +98,11 @@ ColumnLayout { StateLayer { id: layer + function onClicked(): void { + if (!isDisabled) + kb.switchTo(layoutIndex); + } + anchors.left: parent.left anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter @@ -104,11 +110,6 @@ ColumnLayout { radius: Appearance.rounding.full enabled: !isDisabled - - function onClicked(): void { - if (!isDisabled) - kb.switchTo(layoutIndex); - } } StyledText { diff --git a/modules/bar/popouts/kblayout/KbLayoutModel.qml b/modules/bar/popouts/kblayout/KbLayoutModel.qml index 0d95b7a8..02042195 100644 --- a/modules/bar/popouts/kblayout/KbLayoutModel.qml +++ b/modules/bar/popouts/kblayout/KbLayoutModel.qml @@ -36,33 +36,6 @@ Item { _switchProc.running = true; } - ListModel { - id: _layoutsModel - } - - property var _xkbMap: ({}) - property bool _notifiedLimit: false - - Process { - id: _xkbXmlBase - - command: ["xmllint", "--xpath", "//layout/configItem[name and description]", "/usr/share/X11/xkb/rules/base.xml"] - stdout: StdioCollector { - onStreamFinished: _buildXmlMap(text) - } - onRunningChanged: if (!running && (typeof exitCode !== "undefined") && exitCode !== 0) - _xkbXmlEvdev.running = true - } - - Process { - id: _xkbXmlEvdev - - command: ["xmllint", "--xpath", "//layout/configItem[name and description]", "/usr/share/X11/xkb/rules/evdev.xml"] - stdout: StdioCollector { - onStreamFinished: _buildXmlMap(text) - } - } - function _buildXmlMap(xml) { const map = {}; @@ -108,6 +81,78 @@ Item { return `${lang} (${code})`; } + function _setLayouts(raw) { + const parts = raw.split(",").map(s => s.trim()).filter(Boolean); + _layoutsModel.clear(); + + const seen = new Set(); + let idx = 0; + + for (const p of parts) { + if (seen.has(p)) + continue; + seen.add(p); + _layoutsModel.append({ + layoutIndex: idx, + token: p, + label: _pretty(p) + }); + idx++; + } + } + + function _rebuildVisible() { + _visibleModel.clear(); + + let arr = []; + for (let i = 0; i < _layoutsModel.count; i++) + arr.push(_layoutsModel.get(i)); + + arr = arr.filter(i => i.layoutIndex !== activeIndex); + arr.forEach(i => _visibleModel.append(i)); + + if (!Config.utilities.toasts.kbLimit) + return; + + if (_layoutsModel.count > 4) { + Toaster.toast(qsTr("Keyboard layout limit"), qsTr("XKB supports only 4 layouts at a time"), "warning"); + } + } + + function _pretty(token) { + const code = token.replace(/\(.*\)$/, "").trim(); + if (_xkbMap[code]) + return code.toUpperCase() + " - " + _xkbMap[code]; + return code.toUpperCase() + " - " + code; + } + + ListModel { + id: _layoutsModel + } + + property var _xkbMap: ({}) + property bool _notifiedLimit: false + + Process { + id: _xkbXmlBase + + command: ["xmllint", "--xpath", "//layout/configItem[name and description]", "/usr/share/X11/xkb/rules/base.xml"] + stdout: StdioCollector { + onStreamFinished: _buildXmlMap(text) + } + onRunningChanged: if (!running && (typeof exitCode !== "undefined") && exitCode !== 0) + _xkbXmlEvdev.running = true + } + + Process { + id: _xkbXmlEvdev + + command: ["xmllint", "--xpath", "//layout/configItem[name and description]", "/usr/share/X11/xkb/rules/evdev.xml"] + stdout: StdioCollector { + onStreamFinished: _buildXmlMap(text) + } + } + Process { id: _getKbLayoutOpt @@ -175,49 +220,4 @@ Item { onRunningChanged: if (!running) _fetchActiveLayouts.running = true } - - function _setLayouts(raw) { - const parts = raw.split(",").map(s => s.trim()).filter(Boolean); - _layoutsModel.clear(); - - const seen = new Set(); - let idx = 0; - - for (const p of parts) { - if (seen.has(p)) - continue; - seen.add(p); - _layoutsModel.append({ - layoutIndex: idx, - token: p, - label: _pretty(p) - }); - idx++; - } - } - - function _rebuildVisible() { - _visibleModel.clear(); - - let arr = []; - for (let i = 0; i < _layoutsModel.count; i++) - arr.push(_layoutsModel.get(i)); - - arr = arr.filter(i => i.layoutIndex !== activeIndex); - arr.forEach(i => _visibleModel.append(i)); - - if (!Config.utilities.toasts.kbLimit) - return; - - if (_layoutsModel.count > 4) { - Toaster.toast(qsTr("Keyboard layout limit"), qsTr("XKB supports only 4 layouts at a time"), "warning"); - } - } - - function _pretty(token) { - const code = token.replace(/\(.*\)$/, "").trim(); - if (_xkbMap[code]) - return code.toUpperCase() + " - " + _xkbMap[code]; - return code.toUpperCase() + " - " + code; - } } diff --git a/modules/controlcenter/NavRail.qml b/modules/controlcenter/NavRail.qml index ef338b20..1de1e19c 100644 --- a/modules/controlcenter/NavRail.qml +++ b/modules/controlcenter/NavRail.qml @@ -59,8 +59,6 @@ Item { StateLayer { id: normalWinState - color: Colours.palette.m3onPrimaryContainer - function onClicked(): void { root.session.root.close(); WindowFactory.create(null, { @@ -68,6 +66,8 @@ Item { navExpanded: root.session.navExpanded }); } + + color: Colours.palette.m3onPrimaryContainer } MaterialIcon { @@ -175,8 +175,6 @@ Item { implicitHeight: icon.implicitHeight + Appearance.padding.small StateLayer { - color: item.active ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface - function onClicked(): void { // Prevent tab switching during initial opening animation to avoid blank pages if (!root.initialOpeningComplete) { @@ -184,6 +182,8 @@ Item { } root.session.active = item.label; } + + color: item.active ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface } MaterialIcon { diff --git a/modules/controlcenter/Panes.qml b/modules/controlcenter/Panes.qml index a05e6aa6..5aacd89d 100644 --- a/modules/controlcenter/Panes.qml +++ b/modules/controlcenter/Panes.qml @@ -101,10 +101,6 @@ ClippingRectangle { required property int paneIndex required property string componentPath - - implicitWidth: root.width - implicitHeight: root.height - property bool hasBeenLoaded: false function updateActive(): void { @@ -127,6 +123,9 @@ ClippingRectangle { loader.active = shouldBeActive; } + implicitWidth: root.width + implicitHeight: root.height + Loader { id: loader diff --git a/modules/controlcenter/WindowTitle.qml b/modules/controlcenter/WindowTitle.qml index fb716089..0364fab4 100644 --- a/modules/controlcenter/WindowTitle.qml +++ b/modules/controlcenter/WindowTitle.qml @@ -34,11 +34,11 @@ StyledRect { implicitHeight: closeIcon.implicitHeight + Appearance.padding.small StateLayer { - radius: Appearance.rounding.full - function onClicked(): void { QsWindow.window.destroy(); } + + radius: Appearance.rounding.full } MaterialIcon { diff --git a/modules/controlcenter/appearance/AppearancePane.qml b/modules/controlcenter/appearance/AppearancePane.qml index 94ca1cb7..2b32ec03 100644 --- a/modules/controlcenter/appearance/AppearancePane.qml +++ b/modules/controlcenter/appearance/AppearancePane.qml @@ -54,8 +54,6 @@ Item { property real visualiserRounding: Config.background.visualiser.rounding ?? 1 property real visualiserSpacing: Config.background.visualiser.spacing ?? 1 - anchors.fill: parent - function saveConfig() { Config.appearance.anim.durations.scale = root.animDurationsScale; @@ -97,6 +95,8 @@ Item { Config.save(); } + anchors.fill: parent + Component { id: appearanceRightContentComponent @@ -167,14 +167,13 @@ Item { ColumnLayout { id: sidebarLayout + readonly property var rootPane: sidebarFlickable.rootPane + readonly property bool allSectionsExpanded: themeModeSection.expanded && colorVariantSection.expanded && colorSchemeSection.expanded && animationsSection.expanded && fontsSection.expanded && scalesSection.expanded && transparencySection.expanded && borderSection.expanded && backgroundSection.expanded + anchors.left: parent.left anchors.right: parent.right spacing: Appearance.spacing.small - readonly property var rootPane: sidebarFlickable.rootPane - - readonly property bool allSectionsExpanded: themeModeSection.expanded && colorVariantSection.expanded && colorSchemeSection.expanded && animationsSection.expanded && fontsSection.expanded && scalesSection.expanded && transparencySection.expanded && borderSection.expanded && backgroundSection.expanded - RowLayout { spacing: Appearance.spacing.smaller diff --git a/modules/controlcenter/appearance/sections/BackgroundSection.qml b/modules/controlcenter/appearance/sections/BackgroundSection.qml index 9d6bc6eb..08186d03 100644 --- a/modules/controlcenter/appearance/sections/BackgroundSection.qml +++ b/modules/controlcenter/appearance/sections/BackgroundSection.qml @@ -55,9 +55,6 @@ CollapsibleSection { SectionContainer { id: posContainer - contentSpacing: Appearance.spacing.small - z: 1 - readonly property var pos: (rootPane.desktopClockPosition || "top-left").split('-') readonly property string currentV: pos[0] readonly property string currentH: pos[1] @@ -67,6 +64,9 @@ CollapsibleSection { rootPane.saveConfig(); } + contentSpacing: Appearance.spacing.small + z: 1 + StyledText { text: qsTr("Positioning") font.pointSize: Appearance.font.size.larger diff --git a/modules/controlcenter/bluetooth/Details.qml b/modules/controlcenter/bluetooth/Details.qml index cb216ce2..9b728fcf 100644 --- a/modules/controlcenter/bluetooth/Details.qml +++ b/modules/controlcenter/bluetooth/Details.qml @@ -241,13 +241,13 @@ StyledFlickable { scale: root.session.bt.editingDeviceName ? 1 : 0.5 StateLayer { - color: Colours.palette.m3onSecondaryContainer - disabled: !root.session.bt.editingDeviceName - function onClicked(): void { root.session.bt.editingDeviceName = false; deviceNameEdit.text = Qt.binding(() => root.device?.name ?? ""); } + + color: Colours.palette.m3onSecondaryContainer + disabled: !root.session.bt.editingDeviceName } MaterialIcon { @@ -279,8 +279,6 @@ StyledFlickable { color: Qt.alpha(Colours.palette.m3primary, root.session.bt.editingDeviceName ? 1 : 0) StateLayer { - color: root.session.bt.editingDeviceName ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface - function onClicked(): void { root.session.bt.editingDeviceName = !root.session.bt.editingDeviceName; if (root.session.bt.editingDeviceName) @@ -288,6 +286,8 @@ StyledFlickable { else deviceNameEdit.accepted(); } + + color: root.session.bt.editingDeviceName ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface } MaterialIcon { @@ -630,11 +630,11 @@ StyledFlickable { StateLayer { id: fabState - color: root.session.bt.fabMenuOpen ? Colours.palette.m3onPrimary : Colours.palette.m3onPrimaryContainer - function onClicked(): void { root.session.bt.fabMenuOpen = !root.session.bt.fabMenuOpen; } + + color: root.session.bt.fabMenuOpen ? Colours.palette.m3onPrimary : Colours.palette.m3onPrimaryContainer } MaterialIcon { diff --git a/modules/controlcenter/bluetooth/DeviceList.qml b/modules/controlcenter/bluetooth/DeviceList.qml index 2a2bde93..a943f280 100644 --- a/modules/controlcenter/bluetooth/DeviceList.qml +++ b/modules/controlcenter/bluetooth/DeviceList.qml @@ -222,9 +222,6 @@ DeviceList { } StateLayer { - color: device.connected ? Colours.palette.m3onPrimaryContainer : Colours.palette.m3onSurface - disabled: device.loading - function onClicked(): void { if (device.loading) return; @@ -239,6 +236,9 @@ DeviceList { } } } + + color: device.connected ? Colours.palette.m3onPrimaryContainer : Colours.palette.m3onSurface + disabled: device.loading } MaterialIcon { diff --git a/modules/controlcenter/bluetooth/Settings.qml b/modules/controlcenter/bluetooth/Settings.qml index c5472406..557e671b 100644 --- a/modules/controlcenter/bluetooth/Settings.qml +++ b/modules/controlcenter/bluetooth/Settings.qml @@ -131,11 +131,11 @@ ColumnLayout { implicitHeight: adapterPicker.implicitHeight + Appearance.padding.smaller * 2 StateLayer { - radius: Appearance.rounding.small - function onClicked(): void { adapterPickerButton.expanded = !adapterPickerButton.expanded; } + + radius: Appearance.rounding.small } RowLayout { @@ -210,12 +210,12 @@ ColumnLayout { implicitHeight: adapterInner.implicitHeight + Appearance.padding.normal * 2 StateLayer { - disabled: !adapterPickerButton.expanded - function onClicked(): void { adapterPickerButton.expanded = false; root.session.bt.currentAdapter = adapter.modelData; } + + disabled: !adapterPickerButton.expanded } RowLayout { @@ -381,13 +381,13 @@ ColumnLayout { scale: root.session.bt.editingAdapterName ? 1 : 0.5 StateLayer { - color: Colours.palette.m3onSecondaryContainer - disabled: !root.session.bt.editingAdapterName - function onClicked(): void { root.session.bt.editingAdapterName = false; adapterNameEdit.text = Qt.binding(() => root.session.bt.currentAdapter?.name ?? ""); } + + color: Colours.palette.m3onSecondaryContainer + disabled: !root.session.bt.editingAdapterName } MaterialIcon { @@ -419,8 +419,6 @@ ColumnLayout { color: Qt.alpha(Colours.palette.m3primary, root.session.bt.editingAdapterName ? 1 : 0) StateLayer { - color: root.session.bt.editingAdapterName ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface - function onClicked(): void { root.session.bt.editingAdapterName = !root.session.bt.editingAdapterName; if (root.session.bt.editingAdapterName) @@ -428,6 +426,8 @@ ColumnLayout { else adapterNameEdit.accepted(); } + + color: root.session.bt.editingAdapterName ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface } MaterialIcon { diff --git a/modules/controlcenter/components/WallpaperGrid.qml b/modules/controlcenter/components/WallpaperGrid.qml index 8b71809e..500dd821 100644 --- a/modules/controlcenter/components/WallpaperGrid.qml +++ b/modules/controlcenter/components/WallpaperGrid.qml @@ -41,16 +41,16 @@ GridView { readonly property real itemRadius: Appearance.rounding.normal StateLayer { + function onClicked(): void { + Wallpapers.setWallpaper(modelData.path); + } + anchors.fill: parent anchors.leftMargin: itemMargin anchors.rightMargin: itemMargin anchors.topMargin: itemMargin anchors.bottomMargin: itemMargin radius: itemRadius - - function onClicked(): void { - Wallpapers.setWallpaper(modelData.path); - } } StyledClippingRect { diff --git a/modules/controlcenter/dashboard/DashboardPane.qml b/modules/controlcenter/dashboard/DashboardPane.qml index 489af781..d7186a79 100644 --- a/modules/controlcenter/dashboard/DashboardPane.qml +++ b/modules/controlcenter/dashboard/DashboardPane.qml @@ -40,8 +40,6 @@ Item { property bool showStorage: Config.dashboard.performance.showStorage ?? true property bool showNetwork: Config.dashboard.performance.showNetwork ?? true - anchors.fill: parent - function saveConfig() { Config.dashboard.enabled = root.enabled; Config.dashboard.showOnHover = root.showOnHover; @@ -62,6 +60,8 @@ Item { Config.save(); } + anchors.fill: parent + ClippingRectangle { id: dashboardClippingRect diff --git a/modules/controlcenter/launcher/LauncherPane.qml b/modules/controlcenter/launcher/LauncherPane.qml index 17e89aae..5ce5139d 100644 --- a/modules/controlcenter/launcher/LauncherPane.qml +++ b/modules/controlcenter/launcher/LauncherPane.qml @@ -25,21 +25,8 @@ Item { property var selectedApp: root.session.launcher.active property bool hideFromLauncherChecked: false property bool favouriteChecked: false - - anchors.fill: parent - - onSelectedAppChanged: { - root.session.launcher.active = root.selectedApp; - updateToggleState(); - } - - Connections { - target: root.session.launcher - function onActiveChanged() { - root.selectedApp = root.session.launcher.active; - updateToggleState(); - } - } + property string searchText: "" + property list filteredApps: [] function updateToggleState() { if (!root.selectedApp) { @@ -78,16 +65,6 @@ Item { Config.save(); } - AppDb { - id: allAppsDb - - path: `${Paths.state}/apps.sqlite` - favouriteApps: Config.launcher.favouriteApps - entries: DesktopEntries.applications.values - } - - property string searchText: "" - function filterApps(search: string): list { if (!search || search.trim() === "") { const apps = []; @@ -120,12 +97,33 @@ Item { return results.sort((a, b) => b._score - a._score).map(r => r.obj._item); } - property list filteredApps: [] - function updateFilteredApps() { filteredApps = filterApps(searchText); } + anchors.fill: parent + + onSelectedAppChanged: { + root.session.launcher.active = root.selectedApp; + updateToggleState(); + } + + Connections { + target: root.session.launcher + function onActiveChanged() { + root.selectedApp = root.session.launcher.active; + updateToggleState(); + } + } + + AppDb { + id: allAppsDb + + path: `${Paths.state}/apps.sqlite` + favouriteApps: Config.launcher.favouriteApps + entries: DesktopEntries.applications.values + } + onSearchTextChanged: { updateFilteredApps(); } @@ -308,11 +306,11 @@ Item { delegate: StyledRect { required property var modelData - width: parent ? parent.width : 0 - implicitHeight: 40 - readonly property bool isSelected: root.selectedApp === modelData + width: parent ? parent.width : 0 + implicitHeight: 40 + color: isSelected ? Colours.layer(Colours.palette.m3surfaceContainer, 2) : "transparent" radius: Appearance.rounding.normal @@ -418,6 +416,8 @@ Item { Loader { id: rightLauncherLoader + property var displayedApp: rightLauncherPane.displayedApp + anchors.fill: parent asynchronous: true @@ -429,8 +429,6 @@ Item { sourceComponent: rightLauncherPane.targetComponent active: true - property var displayedApp: rightLauncherPane.displayedApp - onItemChanged: { if (item && rightLauncherPane.pane && rightLauncherPane.displayedApp !== rightLauncherPane.pane) { rightLauncherPane.displayedApp = rightLauncherPane.pane; @@ -515,10 +513,9 @@ Item { ColumnLayout { id: appDetailsLayout - anchors.fill: parent - readonly property var displayedApp: parent && parent.displayedApp !== undefined ? parent.displayedApp : null + anchors.fill: parent spacing: Appearance.spacing.normal SettingsHeader { diff --git a/modules/controlcenter/network/EthernetList.qml b/modules/controlcenter/network/EthernetList.qml index d1eb9579..87e00015 100644 --- a/modules/controlcenter/network/EthernetList.qml +++ b/modules/controlcenter/network/EthernetList.qml @@ -147,8 +147,6 @@ DeviceList { color: Qt.alpha(Colours.palette.m3primaryContainer, modelData.connected ? 1 : 0) StateLayer { - color: modelData.connected ? Colours.palette.m3onPrimaryContainer : Colours.palette.m3onSurface - function onClicked(): void { if (modelData.connected && modelData.connection) { Nmcli.disconnectEthernet(modelData.connection, () => {}); @@ -156,6 +154,8 @@ DeviceList { Nmcli.connectEthernet(modelData.connection || "", modelData.interface || "", () => {}); } } + + color: modelData.connected ? Colours.palette.m3onPrimaryContainer : Colours.palette.m3onSurface } MaterialIcon { diff --git a/modules/controlcenter/network/VpnDetails.qml b/modules/controlcenter/network/VpnDetails.qml index dd41dde5..23e4010b 100644 --- a/modules/controlcenter/network/VpnDetails.qml +++ b/modules/controlcenter/network/VpnDetails.qml @@ -201,6 +201,10 @@ DeviceDetails { property string displayName: "" property string interfaceName: "" + function closeWithAnimation(): void { + close(); + } + parent: Overlay.overlay anchors.centerIn: parent width: Math.min(400, parent.width - Appearance.padding.large * 2) @@ -246,10 +250,6 @@ DeviceDetails { } } - function closeWithAnimation(): void { - close(); - } - Overlay.modal: Rectangle { color: Qt.rgba(0, 0, 0, 0.4 * editVpnDialog.opacity) } diff --git a/modules/controlcenter/network/VpnList.qml b/modules/controlcenter/network/VpnList.qml index 0d09001e..9c336674 100644 --- a/modules/controlcenter/network/VpnList.qml +++ b/modules/controlcenter/network/VpnList.qml @@ -181,7 +181,6 @@ ColumnLayout { color: Qt.alpha(Colours.palette.m3primaryContainer, VPN.connected && modelData.enabled ? 1 : 0) StateLayer { - enabled: !VPN.connecting function onClicked(): void { const clickedIndex = modelData.index; @@ -216,6 +215,8 @@ ColumnLayout { } } } + + enabled: !VPN.connecting } MaterialIcon { @@ -271,6 +272,43 @@ ColumnLayout { property string displayName: "" property string interfaceName: "" + function showProviderSelection(): void { + currentState = "selection"; + open(); + } + + function closeWithAnimation(): void { + close(); + } + + function showAddForm(providerType: string, defaultDisplayName: string): void { + editIndex = -1; + providerName = providerType; + displayName = defaultDisplayName; + interfaceName = ""; + + if (currentState === "selection") { + transitionToForm.start(); + } else { + currentState = "form"; + isClosing = false; + open(); + } + } + + function showEditForm(index: int): void { + const provider = Config.utilities.vpn.provider[index]; + const isObject = typeof provider === "object"; + + editIndex = index; + providerName = isObject ? (provider.name || "custom") : String(provider); + displayName = isObject ? (provider.displayName || providerName) : providerName; + interfaceName = isObject ? (provider.interface || "") : ""; + + currentState = "form"; + open(); + } + parent: Overlay.overlay x: Math.round((parent.width - width) / 2) y: Math.round((parent.height - height) / 2) @@ -321,43 +359,6 @@ ColumnLayout { } } - function showProviderSelection(): void { - currentState = "selection"; - open(); - } - - function closeWithAnimation(): void { - close(); - } - - function showAddForm(providerType: string, defaultDisplayName: string): void { - editIndex = -1; - providerName = providerType; - displayName = defaultDisplayName; - interfaceName = ""; - - if (currentState === "selection") { - transitionToForm.start(); - } else { - currentState = "form"; - isClosing = false; - open(); - } - } - - function showEditForm(index: int): void { - const provider = Config.utilities.vpn.provider[index]; - const isObject = typeof provider === "object"; - - editIndex = index; - providerName = isObject ? (provider.name || "custom") : String(provider); - displayName = isObject ? (provider.displayName || providerName) : providerName; - interfaceName = isObject ? (provider.interface || "") : ""; - - currentState = "form"; - open(); - } - Overlay.modal: Rectangle { color: Qt.rgba(0, 0, 0, 0.4 * vpnDialog.opacity) } diff --git a/modules/controlcenter/network/WirelessPasswordDialog.qml b/modules/controlcenter/network/WirelessPasswordDialog.qml index 7a666f33..09d6a826 100644 --- a/modules/controlcenter/network/WirelessPasswordDialog.qml +++ b/modules/controlcenter/network/WirelessPasswordDialog.qml @@ -29,6 +29,47 @@ Item { } property bool isClosing: false + + function checkConnectionStatus(): void { + if (!root.visible || !connectButton.connecting) { + return; + } + + const isConnected = root.network && Nmcli.active && Nmcli.active.ssid && Nmcli.active.ssid.toLowerCase().trim() === root.network.ssid.toLowerCase().trim(); + + if (isConnected) { + connectionSuccessTimer.start(); + return; + } + + if (Nmcli.pendingConnection === null && connectButton.connecting) { + if (connectionMonitor.repeatCount > 10) { + connectionMonitor.stop(); + connectButton.connecting = false; + connectButton.hasError = true; + connectButton.enabled = true; + connectButton.text = qsTr("Connect"); + passwordContainer.passwordBuffer = ""; + if (root.network && root.network.ssid) { + Nmcli.forgetNetwork(root.network.ssid); + } + } + } + } + + function closeDialog(): void { + if (isClosing) { + return; + } + + isClosing = true; + passwordContainer.passwordBuffer = ""; + connectButton.connecting = false; + connectButton.hasError = false; + connectButton.text = qsTr("Connect"); + connectionMonitor.stop(); + } + visible: session.network.showPasswordDialog || isClosing enabled: session.network.showPasswordDialog && !isClosing focus: enabled @@ -238,12 +279,12 @@ Item { } StateLayer { - hoverEnabled: false - cursorShape: Qt.IBeamCursor - function onClicked(): void { passwordContainer.forceActiveFocus(); } + + hoverEnabled: false + cursorShape: Qt.IBeamCursor } StyledText { @@ -416,33 +457,6 @@ Item { } } - function checkConnectionStatus(): void { - if (!root.visible || !connectButton.connecting) { - return; - } - - const isConnected = root.network && Nmcli.active && Nmcli.active.ssid && Nmcli.active.ssid.toLowerCase().trim() === root.network.ssid.toLowerCase().trim(); - - if (isConnected) { - connectionSuccessTimer.start(); - return; - } - - if (Nmcli.pendingConnection === null && connectButton.connecting) { - if (connectionMonitor.repeatCount > 10) { - connectionMonitor.stop(); - connectButton.connecting = false; - connectButton.hasError = true; - connectButton.enabled = true; - connectButton.text = qsTr("Connect"); - passwordContainer.passwordBuffer = ""; - if (root.network && root.network.ssid) { - Nmcli.forgetNetwork(root.network.ssid); - } - } - } - } - Timer { id: connectionMonitor @@ -499,17 +513,4 @@ Item { } } } - - function closeDialog(): void { - if (isClosing) { - return; - } - - isClosing = true; - passwordContainer.passwordBuffer = ""; - connectButton.connecting = false; - connectButton.hasError = false; - connectButton.text = qsTr("Connect"); - connectionMonitor.stop(); - } } diff --git a/modules/controlcenter/taskbar/TaskbarPane.qml b/modules/controlcenter/taskbar/TaskbarPane.qml index f18ac894..7fcdec9e 100644 --- a/modules/controlcenter/taskbar/TaskbarPane.qml +++ b/modules/controlcenter/taskbar/TaskbarPane.qml @@ -53,21 +53,6 @@ Item { property list monitorNames: Hypr.monitorNames() property list excludedScreens: Config.bar.excludedScreens ?? [] - anchors.fill: parent - - Component.onCompleted: { - if (Config.bar.entries) { - entriesModel.clear(); - for (let i = 0; i < Config.bar.entries.length; i++) { - const entry = Config.bar.entries[i]; - entriesModel.append({ - id: entry.id, - enabled: entry.enabled !== false - }); - } - } - } - function saveConfig(entryIndex, entryEnabled) { Config.bar.activeWindow.compact = root.activeWindowCompact; Config.bar.activeWindow.inverted = root.activeWindowInverted; @@ -118,6 +103,21 @@ Item { Config.save(); } + anchors.fill: parent + + Component.onCompleted: { + if (Config.bar.entries) { + entriesModel.clear(); + for (let i = 0; i < Config.bar.entries.length; i++) { + const entry = Config.bar.entries[i]; + entriesModel.append({ + id: entry.id, + enabled: entry.enabled !== false + }); + } + } + } + ListModel { id: entriesModel } diff --git a/modules/dashboard/LyricMenu.qml b/modules/dashboard/LyricMenu.qml index fe984299..868eb8d3 100644 --- a/modules/dashboard/LyricMenu.qml +++ b/modules/dashboard/LyricMenu.qml @@ -12,16 +12,16 @@ StyledRect { required property real contentHeight - implicitHeight: contentHeight - - radius: Appearance.rounding.large - color: Colours.tPalette.m3surfaceContainer - function searchCandidates(title, artist) { LyricsService.currentRequestId++; LyricsService.fetchNetEaseCandidates(title, artist, LyricsService.currentRequestId); } + implicitHeight: contentHeight + + radius: Appearance.rounding.large + color: Colours.tPalette.m3surfaceContainer + Loader { asynchronous: true anchors.fill: parent diff --git a/modules/dashboard/Tabs.qml b/modules/dashboard/Tabs.qml index 6e09e767..d1c78cbd 100644 --- a/modules/dashboard/Tabs.qml +++ b/modules/dashboard/Tabs.qml @@ -111,6 +111,13 @@ Item { contentItem: CustomMouseArea { id: mouse + function onWheel(event: WheelEvent): void { + if (event.angleDelta.y < 0) + root.state.currentTab = Math.min(root.state.currentTab + 1, bar.count - 1); + else if (event.angleDelta.y > 0) + root.state.currentTab = Math.max(root.state.currentTab - 1, 0); + } + implicitWidth: Math.max(icon.width, label.width) implicitHeight: icon.height + label.height @@ -129,13 +136,6 @@ Item { rippleAnim.restart(); } - function onWheel(event: WheelEvent): void { - if (event.angleDelta.y < 0) - root.state.currentTab = Math.min(root.state.currentTab + 1, bar.count - 1); - else if (event.angleDelta.y > 0) - root.state.currentTab = Math.max(root.state.currentTab - 1, 0); - } - SequentialAnimation { id: rippleAnim diff --git a/modules/dashboard/dash/Calendar.qml b/modules/dashboard/dash/Calendar.qml index 56c04938..bf64ac5f 100644 --- a/modules/dashboard/dash/Calendar.qml +++ b/modules/dashboard/dash/Calendar.qml @@ -17,13 +17,6 @@ CustomMouseArea { readonly property int currMonth: state.currentDate.getMonth() readonly property int currYear: state.currentDate.getFullYear() - anchors.left: parent.left - anchors.right: parent.right - implicitHeight: inner.implicitHeight + inner.anchors.margins * 2 - - acceptedButtons: Qt.MiddleButton - onClicked: root.state.currentDate = new Date() - function onWheel(event: WheelEvent): void { if (event.angleDelta.y > 0) root.state.currentDate = new Date(root.currYear, root.currMonth - 1, 1); @@ -31,6 +24,13 @@ CustomMouseArea { root.state.currentDate = new Date(root.currYear, root.currMonth + 1, 1); } + anchors.left: parent.left + anchors.right: parent.right + implicitHeight: inner.implicitHeight + inner.anchors.margins * 2 + + acceptedButtons: Qt.MiddleButton + onClicked: root.state.currentDate = new Date() + ColumnLayout { id: inner @@ -51,11 +51,11 @@ CustomMouseArea { StateLayer { id: prevMonthStateLayer - radius: Appearance.rounding.full - function onClicked(): void { root.state.currentDate = new Date(root.currYear, root.currMonth - 1, 1); } + + radius: Appearance.rounding.full } MaterialIcon { @@ -76,6 +76,10 @@ CustomMouseArea { implicitHeight: monthYearDisplay.implicitHeight + Appearance.padding.small * 2 StateLayer { + function onClicked(): void { + root.state.currentDate = new Date(); + } + anchors.fill: monthYearDisplay anchors.margins: -Appearance.padding.small anchors.leftMargin: -Appearance.padding.normal @@ -86,10 +90,6 @@ CustomMouseArea { const now = new Date(); return root.currMonth === now.getMonth() && root.currYear === now.getFullYear(); } - - function onClicked(): void { - root.state.currentDate = new Date(); - } } StyledText { @@ -111,11 +111,11 @@ CustomMouseArea { StateLayer { id: nextMonthStateLayer - radius: Appearance.rounding.full - function onClicked(): void { root.state.currentDate = new Date(root.currYear, root.currMonth + 1, 1); } + + radius: Appearance.rounding.full } MaterialIcon { diff --git a/modules/dashboard/dash/Media.qml b/modules/dashboard/dash/Media.qml index d6506695..2891bd55 100644 --- a/modules/dashboard/dash/Media.qml +++ b/modules/dashboard/dash/Media.qml @@ -231,12 +231,12 @@ Item { implicitHeight: implicitWidth StateLayer { - disabled: !control.canUse - radius: Appearance.rounding.full - function onClicked(): void { control.onClicked(); } + + disabled: !control.canUse + radius: Appearance.rounding.full } MaterialIcon { diff --git a/modules/dashboard/dash/User.qml b/modules/dashboard/dash/User.qml index 5ede24bb..518ec8aa 100644 --- a/modules/dashboard/dash/User.qml +++ b/modules/dashboard/dash/User.qml @@ -71,12 +71,12 @@ Row { opacity: parent.containsMouse ? 1 : 0 StateLayer { - color: Colours.palette.m3onPrimary - function onClicked(): void { root.visibilities.launcher = false; root.facePicker.open(); } + + color: Colours.palette.m3onPrimary } MaterialIcon { diff --git a/modules/launcher/items/ActionItem.qml b/modules/launcher/items/ActionItem.qml index e1580290..c3cd48a0 100644 --- a/modules/launcher/items/ActionItem.qml +++ b/modules/launcher/items/ActionItem.qml @@ -16,11 +16,11 @@ Item { anchors.right: parent?.right StateLayer { - radius: Appearance.rounding.normal - function onClicked(): void { root.modelData?.onClicked(root.list); } + + radius: Appearance.rounding.normal } Item { diff --git a/modules/launcher/items/AppItem.qml b/modules/launcher/items/AppItem.qml index 75c03a19..84ee06a6 100644 --- a/modules/launcher/items/AppItem.qml +++ b/modules/launcher/items/AppItem.qml @@ -19,12 +19,12 @@ Item { anchors.right: parent?.right StateLayer { - radius: Appearance.rounding.normal - function onClicked(): void { Apps.launch(root.modelData); root.visibilities.launcher = false; } + + radius: Appearance.rounding.normal } Item { diff --git a/modules/launcher/items/CalcItem.qml b/modules/launcher/items/CalcItem.qml index 28a05327..4c27c5c7 100644 --- a/modules/launcher/items/CalcItem.qml +++ b/modules/launcher/items/CalcItem.qml @@ -12,27 +12,27 @@ Item { required property var list readonly property string math: list.search.text.slice(`${Config.launcher.actionPrefix}calc `.length) - onMathChanged: { - if (math.length > 0) - Qalculator.evalAsync(math); - } - function onClicked(): void { Quickshell.execDetached(["wl-copy", Qalculator.rawResult]); root.list.visibilities.launcher = false; } + onMathChanged: { + if (math.length > 0) + Qalculator.evalAsync(math); + } + implicitHeight: Config.launcher.sizes.itemHeight anchors.left: parent?.left anchors.right: parent?.right StateLayer { - radius: Appearance.rounding.normal - function onClicked(): void { root.onClicked(); } + + radius: Appearance.rounding.normal } RowLayout { @@ -80,12 +80,12 @@ Item { StateLayer { id: stateLayer - color: Colours.palette.m3onTertiary - function onClicked(): void { Quickshell.execDetached(["app2unit", "--", ...Config.general.apps.terminal, "fish", "-C", `exec qalc -i '${root.math}'`]); root.list.visibilities.launcher = false; } + + color: Colours.palette.m3onTertiary } StyledText { diff --git a/modules/launcher/items/SchemeItem.qml b/modules/launcher/items/SchemeItem.qml index aade35f2..65bd6526 100644 --- a/modules/launcher/items/SchemeItem.qml +++ b/modules/launcher/items/SchemeItem.qml @@ -16,11 +16,11 @@ Item { anchors.right: parent?.right StateLayer { - radius: Appearance.rounding.normal - function onClicked(): void { root.modelData?.onClicked(root.list); } + + radius: Appearance.rounding.normal } Item { diff --git a/modules/launcher/items/VariantItem.qml b/modules/launcher/items/VariantItem.qml index 34cc87fa..53bffe15 100644 --- a/modules/launcher/items/VariantItem.qml +++ b/modules/launcher/items/VariantItem.qml @@ -16,11 +16,11 @@ Item { anchors.right: parent?.right StateLayer { - radius: Appearance.rounding.normal - function onClicked(): void { root.modelData?.onClicked(root.list); } + + radius: Appearance.rounding.normal } Item { diff --git a/modules/launcher/items/WallpaperItem.qml b/modules/launcher/items/WallpaperItem.qml index 9fdac3f3..1a2eda5f 100644 --- a/modules/launcher/items/WallpaperItem.qml +++ b/modules/launcher/items/WallpaperItem.qml @@ -26,12 +26,12 @@ Item { implicitHeight: image.height + label.height + Appearance.spacing.small / 2 + Appearance.padding.large + Appearance.padding.normal StateLayer { - radius: Appearance.rounding.normal - function onClicked(): void { Wallpapers.setWallpaper(root.modelData.path); root.visibilities.launcher = false; } + + radius: Appearance.rounding.normal } Elevation { diff --git a/modules/lock/Center.qml b/modules/lock/Center.qml index 07b80d3b..5d4dec85 100644 --- a/modules/lock/Center.qml +++ b/modules/lock/Center.qml @@ -135,12 +135,12 @@ ColumnLayout { } StateLayer { - hoverEnabled: false - cursorShape: Qt.IBeamCursor - function onClicked(): void { parent.forceActiveFocus(); } + + hoverEnabled: false + cursorShape: Qt.IBeamCursor } RowLayout { @@ -194,11 +194,11 @@ ColumnLayout { radius: Appearance.rounding.full StateLayer { - color: root.lock.pam.buffer ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface - function onClicked(): void { root.lock.pam.passwd.start(); } + + color: root.lock.pam.buffer ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface } MaterialIcon { diff --git a/modules/lock/Media.qml b/modules/lock/Media.qml index b7e58bbc..07ec8c5b 100644 --- a/modules/lock/Media.qml +++ b/modules/lock/Media.qml @@ -171,11 +171,11 @@ Item { StateLayer { id: controlState - color: control.active ? Colours.palette[`m3on${control.colour}`] : Colours.palette[`m3on${control.colour}Container`] - function onClicked(): void { control.onClicked(); } + + color: control.active ? Colours.palette[`m3on${control.colour}`] : Colours.palette[`m3on${control.colour}Container`] } MaterialIcon { diff --git a/modules/lock/NotifGroup.qml b/modules/lock/NotifGroup.qml index 2e8ca542..7f2b62fb 100644 --- a/modules/lock/NotifGroup.qml +++ b/modules/lock/NotifGroup.qml @@ -176,11 +176,11 @@ StyledRect { Layout.preferredWidth: root.notifs.length > Config.notifs.groupPreviewNum ? implicitWidth : 0 StateLayer { - color: root.urgency === "critical" ? Colours.palette.m3onError : Colours.palette.m3onSurface - function onClicked(): void { root.expanded = !root.expanded; } + + color: root.urgency === "critical" ? Colours.palette.m3onError : Colours.palette.m3onSurface } RowLayout { diff --git a/modules/notifications/Notification.qml b/modules/notifications/Notification.qml index 1208f025..a1bf97d8 100644 --- a/modules/notifications/Notification.qml +++ b/modules/notifications/Notification.qml @@ -361,12 +361,12 @@ StyledRect { implicitHeight: expandIcon.height StateLayer { - radius: Appearance.rounding.full - color: root.modelData.urgency === NotificationUrgency.Critical ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface - function onClicked() { root.expanded = !root.expanded; } + + radius: Appearance.rounding.full + color: root.modelData.urgency === NotificationUrgency.Critical ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface } MaterialIcon { @@ -491,12 +491,12 @@ StyledRect { implicitHeight: actionText.height + Appearance.padding.small * 2 StateLayer { - radius: Appearance.rounding.full - color: root.modelData.urgency === NotificationUrgency.Critical ? Colours.palette.m3onSecondary : Colours.palette.m3onSurface - function onClicked(): void { action.modelData.invoke(); } + + radius: Appearance.rounding.full + color: root.modelData.urgency === NotificationUrgency.Critical ? Colours.palette.m3onSecondary : Colours.palette.m3onSurface } StyledText { diff --git a/modules/session/Content.qml b/modules/session/Content.qml index 45152e28..06e6c85f 100644 --- a/modules/session/Content.qml +++ b/modules/session/Content.qml @@ -115,12 +115,12 @@ Column { } StateLayer { - radius: parent.radius - color: button.activeFocus ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface - function onClicked(): void { Quickshell.execDetached(button.command); } + + radius: parent.radius + color: button.activeFocus ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface } MaterialIcon { diff --git a/modules/sidebar/NotifGroup.qml b/modules/sidebar/NotifGroup.qml index 6bd2f55c..6a92ce05 100644 --- a/modules/sidebar/NotifGroup.qml +++ b/modules/sidebar/NotifGroup.qml @@ -204,11 +204,11 @@ StyledRect { radius: Appearance.rounding.full StateLayer { - color: root.urgency === NotificationUrgency.Critical ? Colours.palette.m3onError : Colours.palette.m3onSurface - function onClicked(): void { root.toggleExpand(!root.expanded); } + + color: root.urgency === NotificationUrgency.Critical ? Colours.palette.m3onError : Colours.palette.m3onSurface } RowLayout { diff --git a/modules/windowinfo/Buttons.qml b/modules/windowinfo/Buttons.qml index b7561247..7854045c 100644 --- a/modules/windowinfo/Buttons.qml +++ b/modules/windowinfo/Buttons.qml @@ -35,11 +35,11 @@ ColumnLayout { implicitHeight: moveToWsIcon.implicitHeight + Appearance.padding.small StateLayer { - color: Colours.palette.m3onPrimary - function onClicked(): void { root.moveToWsExpanded = !root.moveToWsExpanded; } + + color: Colours.palette.m3onPrimary } MaterialIcon { @@ -161,11 +161,11 @@ ColumnLayout { StateLayer { id: stateLayer - color: parent.onColor - function onClicked(): void { parent.onClicked(); } + + color: parent.onColor } StyledText { diff --git a/services/Notifs.qml b/services/Notifs.qml index aff2dfc6..86b906dd 100644 --- a/services/Notifs.qml +++ b/services/Notifs.qml @@ -148,30 +148,6 @@ Singleton { property date time: new Date() property string timeStr: qsTr("now") - function updateTimeStr(): void { - const diff = Date.now() - time.getTime(); - const m = Math.floor(diff / 60000); - - if (m < 1) { - timeStr = qsTr("now"); - timeStrTimer.interval = 5000; - } else { - const h = Math.floor(m / 60); - const d = Math.floor(h / 24); - - if (d > 0) { - timeStr = `${d}d`; - timeStrTimer.interval = 3600000; - } else if (h > 0) { - timeStr = `${h}h`; - timeStrTimer.interval = 300000; - } else { - timeStr = `${m}m`; - timeStrTimer.interval = m < 10 ? 30000 : 60000; - } - } - } - readonly property Timer timeStrTimer: Timer { running: !notif.closed repeat: true @@ -308,6 +284,30 @@ Singleton { } } + function updateTimeStr(): void { + const diff = Date.now() - time.getTime(); + const m = Math.floor(diff / 60000); + + if (m < 1) { + timeStr = qsTr("now"); + timeStrTimer.interval = 5000; + } else { + const h = Math.floor(m / 60); + const d = Math.floor(h / 24); + + if (d > 0) { + timeStr = `${d}d`; + timeStrTimer.interval = 3600000; + } else if (h > 0) { + timeStr = `${h}h`; + timeStrTimer.interval = 300000; + } else { + timeStr = `${m}m`; + timeStrTimer.interval = m < 10 ? 30000 : 60000; + } + } + } + function lock(item: Item): void { locks.add(item); }