feat: settings is now json, refactor panels to be able to dismiss by clicking outside

This commit is contained in:
ferreo 2025-07-18 15:43:22 +01:00
parent 8a3d610d22
commit a498671ef1
36 changed files with 1282 additions and 1300 deletions

View file

@ -59,7 +59,7 @@ Scope {
SystemInfo {
anchors.verticalCenter: parent.verticalCenter
}
Media {
anchors.verticalCenter: parent.verticalCenter
}
@ -83,8 +83,7 @@ Scope {
anchors.rightMargin: 18
spacing: 12
NotificationHistory {
id: notificationHistoryWin
NotificationIcon {
anchors.verticalCenter: parent.verticalCenter
}
@ -132,20 +131,22 @@ Scope {
}
PanelWindow {
id: topCornerPanel
id: topLeftPanel
anchors.top: true
anchors.left: true
anchors.right: true
color: "transparent"
screen: modelData
margins.top: 36
WlrLayershell.exclusionMode: ExclusionMode.Ignore
visible: true
WlrLayershell.layer: WlrLayer.Background
aboveWindows: false
WlrLayershell.namespace: "swww-daemon"
implicitHeight: 24
Corners {
id: topleftCorner
id: topLeftCorner
position: "bottomleft"
size: 1.3
fillColor: (Theme.backgroundPrimary !== undefined && Theme.backgroundPrimary !== null) ? Theme.backgroundPrimary : "#222"
@ -153,9 +154,25 @@ Scope {
offsetY: 0
anchors.top: parent.top
}
}
PanelWindow {
id: topRightPanel
anchors.top: true
anchors.right: true
color: "transparent"
screen: modelData
margins.top: 36
WlrLayershell.exclusionMode: ExclusionMode.Ignore
visible: true
WlrLayershell.layer: WlrLayer.Background
aboveWindows: false
WlrLayershell.namespace: "swww-daemon"
implicitHeight: 24
Corners {
id: toprightCorner
id: topRightCorner
position: "bottomright"
size: 1.3
fillColor: (Theme.backgroundPrimary !== undefined && Theme.backgroundPrimary !== null) ? Theme.backgroundPrimary : "#222"
@ -173,6 +190,9 @@ Scope {
screen: modelData
WlrLayershell.exclusionMode: ExclusionMode.Ignore
visible: true
WlrLayershell.layer: WlrLayer.Background
aboveWindows: false
WlrLayershell.namespace: "swww-daemon"
implicitHeight: 24
@ -188,13 +208,16 @@ Scope {
}
PanelWindow {
id: bottomRightCornerPanel
id: bottomRightPanel
anchors.bottom: true
anchors.right: true
color: "transparent"
screen: modelData
WlrLayershell.exclusionMode: ExclusionMode.Ignore
visible: true
WlrLayershell.layer: WlrLayer.Background
aboveWindows: false
WlrLayershell.namespace: "swww-daemon"
implicitHeight: 24
@ -208,13 +231,8 @@ Scope {
anchors.top: parent.top
}
}
Loader {
id: tabViewerLoader
}
}
}
}
// This alias exposes the visual bar's visibility to the outside world

View file

@ -12,10 +12,11 @@ PanelWindow {
anchors.top: true
anchors.left: true
anchors.right: true
focusable: false
margins.top: barHeight
visible: !activeWindowWrapper.finallyHidden
implicitHeight: activeWindowTitleContainer.height
implicitWidth: activeWindowTitleContainer.x
implicitWidth: 0
property int barHeight: 36
color: "transparent"
@ -104,7 +105,7 @@ PanelWindow {
bottomLeftRadius: Math.max(0, width / 2)
bottomRightRadius: Math.max(0, width / 2)
width: Math.min(barBackground.width - 200, activeWindowTitle.implicitWidth + (Settings.showActiveWindowIcon ? 28 : 22))
width: Math.min(barBackground.width - 200, activeWindowTitle.implicitWidth + (Settings.settings.showActiveWindowIcon ? 28 : 22))
height: activeWindowTitle.implicitHeight + 12
anchors.top: parent.top
@ -118,7 +119,7 @@ PanelWindow {
anchors.leftMargin: 6
anchors.verticalCenter: parent.verticalCenter
source: ToplevelManager?.activeToplevel ? getIcon() : ""
visible: Settings.showActiveWindowIcon
visible: Settings.settings.showActiveWindowIcon
anchors.verticalCenterOffset: -3
}
@ -129,12 +130,12 @@ PanelWindow {
color: Theme.textSecondary
elide: Text.ElideRight
anchors.left: icon.right
anchors.leftMargin: Settings.showActiveWindowIcon ? 4 : 6
anchors.leftMargin: Settings.settings.showActiveWindowIcon ? 4 : 6
anchors.right: parent.right
anchors.rightMargin: 6
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: -3
horizontalAlignment: Settings.showActiveWindowIcon ? Text.AlignRight : Text.AlignHCenter
horizontalAlignment: Settings.settings.showActiveWindowIcon ? Text.AlignRight : Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
maximumLineCount: 1
}

View file

@ -5,380 +5,422 @@ import Quickshell
import Quickshell.Io
import qs.Components
import qs.Settings
import Qt5Compat.GraphicalEffects
import Quickshell.Wayland
import "../../Helpers/Fuzzysort.js" as Fuzzysort
PanelWindow {
PanelWithOverlay {
id: appLauncherPanel
implicitWidth: 460
implicitHeight: 640
color: "transparent"
visible: false
WlrLayershell.exclusionMode: ExclusionMode.Ignore
WlrLayershell.keyboardFocus: visible ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
screen: (typeof modelData !== 'undefined' ? modelData : null)
property bool shouldBeVisible: false
anchors.top: true
margins.top: 36
function showAt() {
visible = true;
shouldBeVisible = true;
searchField.forceActiveFocus()
root.selectedIndex = 0;
root.appModel = DesktopEntries.applications.values;
root.updateFilter();
appLauncherPanelRect.showAt();
}
function hidePanel() {
shouldBeVisible = false;
searchField.text = "";
root.selectedIndex = 0;
appLauncherPanelRect.hidePanel();
}
function show() {
appLauncherPanelRect.showAt();
}
function dismiss() {
appLauncherPanelRect.hidePanel();
}
Rectangle {
id: root
width: 400
height: 640
x: (parent.width - width) / 2
color: Theme.backgroundPrimary
bottomLeftRadius: 28
bottomRightRadius: 28
id: appLauncherPanelRect
implicitWidth: 460
implicitHeight: 640
color: "transparent"
visible: parent.visible
property bool shouldBeVisible: false
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
property var appModel: DesktopEntries.applications.values
property var filteredApps: []
property int selectedIndex: 0
property int targetY: (parent.height - height) / 2
y: appLauncherPanel.shouldBeVisible ? targetY : -height
Behavior on y {
NumberAnimation { duration: 300; easing.type: Easing.OutCubic }
function showAt() {
appLauncherPanel.visible = true;
shouldBeVisible = true;
searchField.forceActiveFocus();
root.selectedIndex = 0;
root.appModel = DesktopEntries.applications.values;
root.updateFilter();
}
scale: appLauncherPanel.shouldBeVisible ? 1 : 0
Behavior on scale {
NumberAnimation { duration: 200; easing.type: Easing.InOutCubic }
}
onScaleChanged: {
if (scale === 0 && !appLauncherPanel.shouldBeVisible) {
appLauncherPanel.visible = false;
}
}
function isMathExpression(str) {
return /^[-+*/().0-9\s]+$/.test(str);
}
function safeEval(expr) {
try {
return Function('return (' + expr + ')')();
} catch (e) {
return undefined;
}
}
function updateFilter() {
var query = searchField.text ? searchField.text.toLowerCase() : "";
var apps = root.appModel.slice();
var results = [];
// Calculator mode: starts with '='
if (query.startsWith("=")) {
var expr = searchField.text.slice(1).trim();
if (expr && isMathExpression(expr)) {
var value = safeEval(expr);
if (value !== undefined && value !== null && value !== "") {
results.push({
isCalculator: true,
name: `Calculator: ${expr} = ${value}`,
result: value,
expr: expr,
icon: "calculate"
});
}
}
}
if (!query || query.startsWith("=")) {
results = results.concat(apps.sort(function(a, b) {
return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
}));
} else {
var fuzzyResults = Fuzzysort.go(query, apps, { keys: ["name", "comment", "genericName"] });
results = results.concat(fuzzyResults.map(function(r) { return r.obj; }));
}
root.filteredApps = results;
function hidePanel() {
shouldBeVisible = false;
searchField.text = "";
root.selectedIndex = 0;
}
function selectNext() {
if (filteredApps.length > 0)
selectedIndex = Math.min(selectedIndex + 1, filteredApps.length - 1);
}
function selectPrev() {
if (filteredApps.length > 0)
selectedIndex = Math.max(selectedIndex - 1, 0);
}
function activateSelected() {
if (filteredApps.length === 0)
return;
Rectangle {
id: root
width: 460
height: 640
x: (parent.width - width) / 2
color: Theme.backgroundPrimary
bottomLeftRadius: 28
bottomRightRadius: 28
var modelData = filteredApps[selectedIndex];
if (modelData.isCalculator) {
Qt.callLater(function() {
Quickshell.clipboardText = String(modelData.result);
Quickshell.execDetached([
"notify-send",
"Calculator Result",
`${modelData.expr} = ${modelData.result} (copied to clipboard)`
]);
});
} else if (modelData.execute) {
modelData.execute();
} else {
var execCmd = modelData.execString || modelData.exec || "";
if (execCmd) {
execCmd = execCmd.replace(/\s?%[fFuUdDnNiCkvm]/g, '');
Quickshell.execDetached(["sh", "-c", execCmd.trim()]);
property var appModel: DesktopEntries.applications.values
property var filteredApps: []
property int selectedIndex: 0
property int targetY: (parent.height - height) / 2
y: appLauncherPanelRect.shouldBeVisible ? targetY : -height
Behavior on y {
NumberAnimation {
duration: 300
easing.type: Easing.OutCubic
}
}
appLauncherPanel.hidePanel();
searchField.text = "";
}
Component.onCompleted: updateFilter()
ColumnLayout {
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.margins: 32
spacing: 18
// Search Bar
Rectangle {
id: searchBar
color: Theme.surfaceVariant
radius: 22
height: 48
Layout.fillWidth: true
border.color: searchField.activeFocus ? Theme.accentPrimary : Theme.outline
border.width: searchField.activeFocus ? 2 : 1
RowLayout {
anchors.left: parent.left
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: 14
anchors.rightMargin: 14
spacing: 10
Text {
text: "search"
font.family: "Material Symbols Outlined"
font.pixelSize: Theme.fontSizeHeader
color: searchField.activeFocus ? Theme.accentPrimary : Theme.textSecondary
verticalAlignment: Text.AlignVCenter
Layout.alignment: Qt.AlignVCenter
}
TextField {
id: searchField
placeholderText: "Search apps..."
color: Theme.textPrimary
placeholderTextColor: Theme.textSecondary
background: null
font.family: Theme.fontFamily
font.pixelSize: Theme.fontSizeBody
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
onTextChanged: root.updateFilter()
selectedTextColor: Theme.onAccent
selectionColor: Theme.accentPrimary
padding: 0
verticalAlignment: TextInput.AlignVCenter
leftPadding: 0
rightPadding: 0
topPadding: 0
bottomPadding: 0
font.bold: true
Component.onCompleted: contentItem.cursorColor = Theme.textPrimary
onActiveFocusChanged: contentItem.cursorColor = Theme.textPrimary
Keys.onDownPressed: root.selectNext()
Keys.onUpPressed: root.selectPrev()
Keys.onEnterPressed: root.activateSelected()
Keys.onReturnPressed: root.activateSelected()
Keys.onEscapePressed: appLauncherPanel.hidePanel()
scale: appLauncherPanelRect.shouldBeVisible ? 1 : 0
Behavior on scale {
NumberAnimation {
duration: 200
easing.type: Easing.InOutCubic
}
}
onScaleChanged: {
if (scale === 0 && !appLauncherPanelRect.shouldBeVisible) {
appLauncherPanel.visible = false;
}
}
function isMathExpression(str) {
return /^[-+*/().0-9\s]+$/.test(str);
}
function safeEval(expr) {
try {
return Function('return (' + expr + ')')();
} catch (e) {
return undefined;
}
}
function updateFilter() {
var query = searchField.text ? searchField.text.toLowerCase() : "";
var apps = root.appModel.slice();
var results = [];
// Calculator mode: starts with '='
if (query.startsWith("=")) {
var expr = searchField.text.slice(1).trim();
if (expr && isMathExpression(expr)) {
var value = safeEval(expr);
if (value !== undefined && value !== null && value !== "") {
results.push({
isCalculator: true,
name: `Calculator: ${expr} = ${value}`,
result: value,
expr: expr,
icon: "calculate"
});
}
}
}
Behavior on border.color { ColorAnimation { duration: 120 } }
Behavior on border.width { NumberAnimation { duration: 120 } }
if (!query || query.startsWith("=")) {
results = results.concat(apps.sort(function (a, b) {
return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
}));
} else {
var fuzzyResults = Fuzzysort.go(query, apps, {
keys: ["name", "comment", "genericName"]
});
results = results.concat(fuzzyResults.map(function (r) {
return r.obj;
}));
}
root.filteredApps = results;
root.selectedIndex = 0;
}
function selectNext() {
if (filteredApps.length > 0)
selectedIndex = Math.min(selectedIndex + 1, filteredApps.length - 1);
}
function selectPrev() {
if (filteredApps.length > 0)
selectedIndex = Math.max(selectedIndex - 1, 0);
}
// App List Card
Rectangle {
color: Theme.surface
radius: 20
Layout.fillWidth: true
Layout.fillHeight: true
clip: true
anchors.margins: 0
property int innerPadding: 16
function activateSelected() {
if (filteredApps.length === 0)
return;
Item {
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
height: parent.innerPadding
visible: false
var modelData = filteredApps[selectedIndex];
if (modelData.isCalculator) {
Qt.callLater(function () {
Quickshell.clipboardText = String(modelData.result);
Quickshell.execDetached(["notify-send", "Calculator Result", `${modelData.expr} = ${modelData.result} (copied to clipboard)`]);
});
} else if (modelData.execute) {
modelData.execute();
} else {
var execCmd = modelData.execString || modelData.exec || "";
if (execCmd) {
execCmd = execCmd.replace(/\s?%[fFuUdDnNiCkvm]/g, '');
Quickshell.execDetached(["sh", "-c", execCmd.trim()]);
}
}
ListView {
id: appList
anchors.fill: parent
anchors.margins: parent.innerPadding
spacing: 2
model: root.filteredApps
currentIndex: root.selectedIndex
delegate: Item {
id: appDelegate
width: appList.width
height: 48
property bool hovered: mouseArea.containsMouse
property bool isSelected: index === root.selectedIndex
appLauncherPanel.hidePanel();
searchField.text = "";
}
Rectangle {
anchors.fill: parent
color: hovered || isSelected ? Theme.accentPrimary : "transparent"
radius: 12
border.color: hovered || isSelected ? Theme.accentPrimary : "transparent"
border.width: hovered || isSelected ? 2 : 0
Behavior on color { ColorAnimation { duration: 120 } }
Behavior on border.color { ColorAnimation { duration: 120 } }
Behavior on border.width { NumberAnimation { duration: 120 } }
Component.onCompleted: updateFilter()
ColumnLayout {
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.margins: 32
spacing: 18
// Search Bar
Rectangle {
id: searchBar
color: Theme.surfaceVariant
radius: 22
height: 48
Layout.fillWidth: true
border.color: searchField.activeFocus ? Theme.accentPrimary : Theme.outline
border.width: searchField.activeFocus ? 2 : 1
RowLayout {
anchors.left: parent.left
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: 14
anchors.rightMargin: 14
spacing: 10
Text {
text: "search"
font.family: "Material Symbols Outlined"
font.pixelSize: Theme.fontSizeHeader
color: searchField.activeFocus ? Theme.accentPrimary : Theme.textSecondary
verticalAlignment: Text.AlignVCenter
Layout.alignment: Qt.AlignVCenter
}
TextField {
id: searchField
placeholderText: "Search apps..."
color: Theme.textPrimary
placeholderTextColor: Theme.textSecondary
background: null
font.family: Theme.fontFamily
font.pixelSize: Theme.fontSizeBody
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
onTextChanged: root.updateFilter()
selectedTextColor: Theme.onAccent
selectionColor: Theme.accentPrimary
padding: 0
verticalAlignment: TextInput.AlignVCenter
leftPadding: 0
rightPadding: 0
topPadding: 0
bottomPadding: 0
font.bold: true
Component.onCompleted: contentItem.cursorColor = Theme.textPrimary
onActiveFocusChanged: contentItem.cursorColor = Theme.textPrimary
RowLayout {
anchors.fill: parent
anchors.leftMargin: 10
anchors.rightMargin: 10
spacing: 10
Item {
width: 28; height: 28
property bool iconLoaded: !modelData.isCalculator && iconImg.status === Image.Ready && iconImg.source !== "" && iconImg.status !== Image.Error
Image {
id: iconImg
anchors.fill: parent
fillMode: Image.PreserveAspectFit
smooth: true
cache: false
asynchronous: true
source: modelData.isCalculator ? "qrc:/icons/calculate.svg" : Quickshell.iconPath(modelData.icon, "application-x-executable")
visible: modelData.isCalculator || parent.iconLoaded
}
Text {
anchors.centerIn: parent
visible: !modelData.isCalculator && !parent.iconLoaded
text: "broken_image"
font.family: "Material Symbols Outlined"
font.pixelSize: Theme.fontSizeHeader
color: Theme.accentPrimary
}
}
ColumnLayout {
Layout.fillWidth: true
spacing: 1
Text {
text: modelData.name
color: hovered || isSelected ? Theme.onAccent : Theme.textPrimary
font.family: Theme.fontFamily
font.pixelSize: Theme.fontSizeSmall
font.bold: hovered || isSelected
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
Layout.fillWidth: true
}
Text {
text: modelData.isCalculator ? (modelData.expr + " = " + modelData.result)
: (modelData.comment || modelData.genericName || "No description available")
color: hovered || isSelected ? Theme.onAccent : Theme.textSecondary
font.family: Theme.fontFamily
font.pixelSize: Theme.fontSizeCaption
font.italic: !(modelData.comment || modelData.genericName)
opacity: (modelData.comment || modelData.genericName) ? 1.0 : 0.6
elide: Text.ElideRight
Layout.fillWidth: true
}
}
Item { Layout.fillWidth: true }
Text {
text: modelData.isCalculator ? "content_copy" : "chevron_right"
font.family: "Material Symbols Outlined"
font.pixelSize: Theme.fontSizeBody
color: hovered || isSelected ? Theme.onAccent : Theme.textSecondary
verticalAlignment: Text.AlignVCenter
}
Keys.onDownPressed: root.selectNext()
Keys.onUpPressed: root.selectPrev()
Keys.onEnterPressed: root.activateSelected()
Keys.onReturnPressed: root.activateSelected()
Keys.onEscapePressed: appLauncherPanel.hidePanel()
}
Rectangle {
id: ripple
anchors.fill: parent
color: Theme.onAccent
opacity: 0.0
}
Behavior on border.color {
ColorAnimation {
duration: 120
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: {
ripple.opacity = 0.18
rippleNumberAnimation.start()
root.selectedIndex = index
root.activateSelected()
}
onPressed: ripple.opacity = 0.18
onReleased: ripple.opacity = 0.0
}
}
Behavior on border.width {
NumberAnimation {
id: rippleNumberAnimation
target: ripple
property: "opacity"
to: 0.0
duration: 320
duration: 120
}
}
}
Rectangle {
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
height: 1
color: Theme.outline
opacity: index === appList.count - 1 ? 0 : 0.10
// App List Card
Rectangle {
color: Theme.surface
radius: 20
Layout.fillWidth: true
Layout.fillHeight: true
clip: true
property int innerPadding: 16
Item {
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
height: parent.innerPadding
visible: false
}
ListView {
id: appList
anchors.fill: parent
anchors.margins: parent.innerPadding
spacing: 2
model: root.filteredApps
currentIndex: root.selectedIndex
delegate: Item {
id: appDelegate
width: appList.width
height: 48
property bool hovered: mouseArea.containsMouse
property bool isSelected: index === root.selectedIndex
Rectangle {
anchors.fill: parent
color: hovered || isSelected ? Theme.accentPrimary : "transparent"
radius: 12
border.color: hovered || isSelected ? Theme.accentPrimary : "transparent"
border.width: hovered || isSelected ? 2 : 0
Behavior on color {
ColorAnimation {
duration: 120
}
}
Behavior on border.color {
ColorAnimation {
duration: 120
}
}
Behavior on border.width {
NumberAnimation {
duration: 120
}
}
}
RowLayout {
anchors.fill: parent
anchors.leftMargin: 10
anchors.rightMargin: 10
spacing: 10
Item {
width: 28
height: 28
property bool iconLoaded: !modelData.isCalculator && iconImg.status === Image.Ready && iconImg.source !== "" && iconImg.status !== Image.Error
Image {
id: iconImg
anchors.fill: parent
fillMode: Image.PreserveAspectFit
smooth: true
cache: false
asynchronous: true
source: modelData.isCalculator ? "qrc:/icons/calculate.svg" : Quickshell.iconPath(modelData.icon, "application-x-executable")
visible: modelData.isCalculator || parent.iconLoaded
}
Text {
anchors.centerIn: parent
visible: !modelData.isCalculator && !parent.iconLoaded
text: "broken_image"
font.family: "Material Symbols Outlined"
font.pixelSize: Theme.fontSizeHeader
color: Theme.accentPrimary
}
}
ColumnLayout {
Layout.fillWidth: true
spacing: 1
Text {
text: modelData.name
color: hovered || isSelected ? Theme.onAccent : Theme.textPrimary
font.family: Theme.fontFamily
font.pixelSize: Theme.fontSizeSmall
font.bold: hovered || isSelected
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
Layout.fillWidth: true
}
Text {
text: modelData.isCalculator ? (modelData.expr + " = " + modelData.result) : (modelData.comment || modelData.genericName || "No description available")
color: hovered || isSelected ? Theme.onAccent : Theme.textSecondary
font.family: Theme.fontFamily
font.pixelSize: Theme.fontSizeCaption
font.italic: !(modelData.comment || modelData.genericName)
opacity: (modelData.comment || modelData.genericName) ? 1.0 : 0.6
elide: Text.ElideRight
Layout.fillWidth: true
}
}
Item {
Layout.fillWidth: true
}
Text {
text: modelData.isCalculator ? "content_copy" : "chevron_right"
font.family: "Material Symbols Outlined"
font.pixelSize: Theme.fontSizeBody
color: hovered || isSelected ? Theme.onAccent : Theme.textSecondary
verticalAlignment: Text.AlignVCenter
}
}
Rectangle {
id: ripple
anchors.fill: parent
color: Theme.onAccent
opacity: 0.0
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: {
ripple.opacity = 0.18;
rippleNumberAnimation.start();
root.selectedIndex = index;
root.activateSelected();
}
onPressed: ripple.opacity = 0.18
onReleased: ripple.opacity = 0.0
}
NumberAnimation {
id: rippleNumberAnimation
target: ripple
property: "opacity"
to: 0.0
duration: 320
}
Rectangle {
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
height: 1
color: Theme.outline
opacity: index === appList.count - 1 ? 0 : 0.10
}
}
}
}
}
}
}
Corners {
id: launcherCornerRight
position: "bottomleft"
size: 1.1
fillColor: Theme.backgroundPrimary
anchors.top: root.top
offsetX: 396
offsetY: 0
}
Corners {
id: launcherCornerRight
position: "bottomleft"
size: 1.1
fillColor: Theme.backgroundPrimary
anchors.top: root.top
offsetX: 416
offsetY: 0
}
Corners {
id: launcherCornerLeft
position: "bottomright"
size: 1.1
fillColor: Theme.backgroundPrimary
anchors.top: root.top
offsetX: -396
offsetY: 0
Corners {
id: launcherCornerLeft
position: "bottomright"
size: 1.1
fillColor: Theme.backgroundPrimary
anchors.top: root.top
offsetX: -416
offsetY: 0
}
}
}
}

View file

@ -1,6 +1,6 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Qt5Compat.GraphicalEffects
import qs.Settings
import qs.Services
@ -10,7 +10,7 @@ Item {
id: mediaControl
width: visible ? mediaRow.width : 0
height: 36
visible: Settings.showMediaInBar && MusicManager.currentPlayer
visible: Settings.settings.showMediaInBar && MusicManager.currentPlayer
RowLayout {
id: mediaRow

View file

@ -6,7 +6,7 @@ import qs.Services
Row {
id: layout
spacing: 10
visible: Settings.showSystemInfoInBar
visible: Settings.settings.showSystemInfoInBar
Row {
id: cpuUsageLayout