waffles: ctrl alt del menu

This commit is contained in:
end-4
2025-12-06 23:14:08 +01:00
parent 80a7804ade
commit 13968db31c
29 changed files with 578 additions and 90 deletions
@@ -153,6 +153,7 @@ Singleton {
property JsonObject apps: JsonObject { property JsonObject apps: JsonObject {
property string bluetooth: "kcmshell6 kcm_bluetooth" property string bluetooth: "kcmshell6 kcm_bluetooth"
property string changePassword: "kitty -1 --hold=yes fish -i -c 'passwd'"
property string network: "kcmshell6 kcm_networkmanagement" property string network: "kcmshell6 kcm_networkmanagement"
property string manageUser: "kcmshell6 kcm_users" property string manageUser: "kcmshell6 kcm_users"
property string networkEthernet: "kcmshell6 kcm_networkmanagement" property string networkEthernet: "kcmshell6 kcm_networkmanagement"
@@ -12,6 +12,10 @@ Singleton {
}); });
} }
function changePassword() {
Quickshell.execDetached(["bash", "-c", `${Config.options.apps.changePassword}`]);
}
function lock() { function lock() {
Quickshell.execDetached(["loginctl", "lock-session"]); Quickshell.execDetached(["loginctl", "lock-session"]);
} }
@@ -14,61 +14,13 @@ import Quickshell.Hyprland
Scope { Scope {
id: root id: root
property var focusedScreen: Quickshell.screens.find(s => s.name === Hyprland.focusedMonitor?.name) property var focusedScreen: Quickshell.screens.find(s => s.name === Hyprland.focusedMonitor?.name)
property bool packageManagerRunning: false
property bool downloadRunning: false
component DescriptionLabel: Rectangle {
id: descriptionLabel
property string text
property color textColor: Appearance.colors.colOnTooltip
color: Appearance.colors.colTooltip
clip: true
radius: Appearance.rounding.normal
implicitHeight: descriptionLabelText.implicitHeight + 10 * 2
implicitWidth: descriptionLabelText.implicitWidth + 15 * 2
Behavior on implicitWidth {
animation: Appearance.animation.elementMove.numberAnimation.createObject(this)
}
StyledText {
id: descriptionLabelText
anchors.centerIn: parent
color: descriptionLabel.textColor
text: descriptionLabel.text
}
}
function detectRunningStuff() {
packageManagerRunning = false;
downloadRunning = false;
detectPackageManagerProc.running = false;
detectPackageManagerProc.running = true;
detectDownloadProc.running = false;
detectDownloadProc.running = true;
}
Process {
id: detectPackageManagerProc
command: ["bash", "-c", "pidof pacman yay paru dnf zypper apt apx xbps flatpak snap apk yum epsi pikman"]
onExited: (exitCode, exitStatus) => {
root.packageManagerRunning = (exitCode === 0);
}
}
Process {
id: detectDownloadProc
command: ["bash", "-c", "pidof curl wget aria2c yt-dlp || ls ~/Downloads | grep -E '\.crdownload$|\.part$'"]
onExited: (exitCode, exitStatus) => {
root.downloadRunning = (exitCode === 0);
}
}
Loader { Loader {
id: sessionLoader id: sessionLoader
active: GlobalStates.sessionOpen active: GlobalStates.sessionOpen
onActiveChanged: { onActiveChanged: {
if (sessionLoader.active) root.detectRunningStuff(); if (sessionLoader.active)
SessionWarnings.refresh();
} }
Connections { Connections {
@@ -84,7 +36,7 @@ Scope {
id: sessionRoot id: sessionRoot
visible: sessionLoader.active visible: sessionLoader.active
property string subtitle property string subtitle
function hide() { function hide() {
GlobalStates.sessionOpen = false; GlobalStates.sessionOpen = false;
} }
@@ -110,7 +62,7 @@ Scope {
id: sessionMouseArea id: sessionMouseArea
anchors.fill: parent anchors.fill: parent
onClicked: { onClicked: {
sessionRoot.hide() sessionRoot.hide();
} }
} }
@@ -119,7 +71,7 @@ Scope {
anchors.centerIn: parent anchors.centerIn: parent
spacing: 15 spacing: 15
Keys.onPressed: (event) => { Keys.onPressed: event => {
if (event.key === Qt.Key_Escape) { if (event.key === Qt.Key_Escape) {
sessionRoot.hide(); sessionRoot.hide();
} }
@@ -128,7 +80,8 @@ Scope {
ColumnLayout { ColumnLayout {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
spacing: 0 spacing: 0
StyledText { // Title StyledText {
// Title
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
font { font {
@@ -139,7 +92,8 @@ Scope {
text: Translation.tr("Session") text: Translation.tr("Session")
} }
StyledText { // Small instruction StyledText {
// Small instruction
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
font.pixelSize: Appearance.font.pixelSize.normal font.pixelSize: Appearance.font.pixelSize.normal
@@ -157,8 +111,14 @@ Scope {
focus: sessionRoot.visible focus: sessionRoot.visible
buttonIcon: "lock" buttonIcon: "lock"
buttonText: Translation.tr("Lock") buttonText: Translation.tr("Lock")
onClicked: { Session.lock(); sessionRoot.hide() } onClicked: {
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText } Session.lock();
sessionRoot.hide();
}
onFocusChanged: {
if (focus)
sessionRoot.subtitle = buttonText;
}
KeyNavigation.right: sessionSleep KeyNavigation.right: sessionSleep
KeyNavigation.down: sessionHibernate KeyNavigation.down: sessionHibernate
} }
@@ -166,8 +126,14 @@ Scope {
id: sessionSleep id: sessionSleep
buttonIcon: "dark_mode" buttonIcon: "dark_mode"
buttonText: Translation.tr("Sleep") buttonText: Translation.tr("Sleep")
onClicked: { Session.suspend(); sessionRoot.hide() } onClicked: {
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText } Session.suspend();
sessionRoot.hide();
}
onFocusChanged: {
if (focus)
sessionRoot.subtitle = buttonText;
}
KeyNavigation.left: sessionLock KeyNavigation.left: sessionLock
KeyNavigation.right: sessionLogout KeyNavigation.right: sessionLogout
KeyNavigation.down: sessionShutdown KeyNavigation.down: sessionShutdown
@@ -176,8 +142,14 @@ Scope {
id: sessionLogout id: sessionLogout
buttonIcon: "logout" buttonIcon: "logout"
buttonText: Translation.tr("Logout") buttonText: Translation.tr("Logout")
onClicked: { Session.logout(); sessionRoot.hide() } onClicked: {
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText } Session.logout();
sessionRoot.hide();
}
onFocusChanged: {
if (focus)
sessionRoot.subtitle = buttonText;
}
KeyNavigation.left: sessionSleep KeyNavigation.left: sessionSleep
KeyNavigation.right: sessionTaskManager KeyNavigation.right: sessionTaskManager
KeyNavigation.down: sessionReboot KeyNavigation.down: sessionReboot
@@ -186,8 +158,14 @@ Scope {
id: sessionTaskManager id: sessionTaskManager
buttonIcon: "browse_activity" buttonIcon: "browse_activity"
buttonText: Translation.tr("Task Manager") buttonText: Translation.tr("Task Manager")
onClicked: { Session.launchTaskManager(); sessionRoot.hide() } onClicked: {
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText } Session.launchTaskManager();
sessionRoot.hide();
}
onFocusChanged: {
if (focus)
sessionRoot.subtitle = buttonText;
}
KeyNavigation.left: sessionLogout KeyNavigation.left: sessionLogout
KeyNavigation.down: sessionFirmwareReboot KeyNavigation.down: sessionFirmwareReboot
} }
@@ -196,8 +174,14 @@ Scope {
id: sessionHibernate id: sessionHibernate
buttonIcon: "downloading" buttonIcon: "downloading"
buttonText: Translation.tr("Hibernate") buttonText: Translation.tr("Hibernate")
onClicked: { Session.hibernate(); sessionRoot.hide() } onClicked: {
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText } Session.hibernate();
sessionRoot.hide();
}
onFocusChanged: {
if (focus)
sessionRoot.subtitle = buttonText;
}
KeyNavigation.up: sessionLock KeyNavigation.up: sessionLock
KeyNavigation.right: sessionShutdown KeyNavigation.right: sessionShutdown
} }
@@ -205,8 +189,14 @@ Scope {
id: sessionShutdown id: sessionShutdown
buttonIcon: "power_settings_new" buttonIcon: "power_settings_new"
buttonText: Translation.tr("Shutdown") buttonText: Translation.tr("Shutdown")
onClicked: { Session.poweroff(); sessionRoot.hide() } onClicked: {
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText } Session.poweroff();
sessionRoot.hide();
}
onFocusChanged: {
if (focus)
sessionRoot.subtitle = buttonText;
}
KeyNavigation.left: sessionHibernate KeyNavigation.left: sessionHibernate
KeyNavigation.right: sessionReboot KeyNavigation.right: sessionReboot
KeyNavigation.up: sessionSleep KeyNavigation.up: sessionSleep
@@ -215,8 +205,14 @@ Scope {
id: sessionReboot id: sessionReboot
buttonIcon: "restart_alt" buttonIcon: "restart_alt"
buttonText: Translation.tr("Reboot") buttonText: Translation.tr("Reboot")
onClicked: { Session.reboot(); sessionRoot.hide() } onClicked: {
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText } Session.reboot();
sessionRoot.hide();
}
onFocusChanged: {
if (focus)
sessionRoot.subtitle = buttonText;
}
KeyNavigation.left: sessionShutdown KeyNavigation.left: sessionShutdown
KeyNavigation.right: sessionFirmwareReboot KeyNavigation.right: sessionFirmwareReboot
KeyNavigation.up: sessionLogout KeyNavigation.up: sessionLogout
@@ -225,8 +221,14 @@ Scope {
id: sessionFirmwareReboot id: sessionFirmwareReboot
buttonIcon: "settings_applications" buttonIcon: "settings_applications"
buttonText: Translation.tr("Reboot to firmware settings") buttonText: Translation.tr("Reboot to firmware settings")
onClicked: { Session.rebootToFirmware(); sessionRoot.hide() } onClicked: {
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText } Session.rebootToFirmware();
sessionRoot.hide();
}
onFocusChanged: {
if (focus)
sessionRoot.subtitle = buttonText;
}
KeyNavigation.up: sessionTaskManager KeyNavigation.up: sessionTaskManager
KeyNavigation.left: sessionReboot KeyNavigation.left: sessionReboot
} }
@@ -247,7 +249,7 @@ Scope {
spacing: 10 spacing: 10
Loader { Loader {
active: root.packageManagerRunning active: SessionWarnings.packageManagerRunning
visible: active visible: active
sourceComponent: DescriptionLabel { sourceComponent: DescriptionLabel {
text: Translation.tr("Your package manager is running") text: Translation.tr("Your package manager is running")
@@ -256,7 +258,7 @@ Scope {
} }
} }
Loader { Loader {
active: root.downloadRunning active: SessionWarnings.downloadRunning
visible: active visible: active
sourceComponent: DescriptionLabel { sourceComponent: DescriptionLabel {
text: Translation.tr("There might be a download in progress") text: Translation.tr("There might be a download in progress")
@@ -268,6 +270,28 @@ Scope {
} }
} }
component DescriptionLabel: Rectangle {
id: descriptionLabel
property string text
property color textColor: Appearance.colors.colOnTooltip
color: Appearance.colors.colTooltip
clip: true
radius: Appearance.rounding.normal
implicitHeight: descriptionLabelText.implicitHeight + 10 * 2
implicitWidth: descriptionLabelText.implicitWidth + 15 * 2
Behavior on implicitWidth {
animation: Appearance.animation.elementMove.numberAnimation.createObject(this)
}
StyledText {
id: descriptionLabelText
anchors.centerIn: parent
color: descriptionLabel.textColor
text: descriptionLabel.text
}
}
IpcHandler { IpcHandler {
target: "session" target: "session"
@@ -276,11 +300,11 @@ Scope {
} }
function close(): void { function close(): void {
GlobalStates.sessionOpen = false GlobalStates.sessionOpen = false;
} }
function open(): void { function open(): void {
GlobalStates.sessionOpen = true GlobalStates.sessionOpen = true;
} }
} }
@@ -298,7 +322,7 @@ Scope {
description: "Opens session screen on press" description: "Opens session screen on press"
onPressed: { onPressed: {
GlobalStates.sessionOpen = true GlobalStates.sessionOpen = true;
} }
} }
@@ -307,8 +331,7 @@ Scope {
description: "Closes session screen on press" description: "Closes session screen on press"
onPressed: { onPressed: {
GlobalStates.sessionOpen = false GlobalStates.sessionOpen = false;
} }
} }
} }
@@ -99,7 +99,7 @@ Item {
WPanelSeparator {} WPanelSeparator {}
FooterRectangle { FooterRectangle {
FooterMoreButton { WTextButton {
anchors { anchors {
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
left: parent.left left: parent.left
@@ -89,7 +89,7 @@ Item {
WPanelSeparator {} WPanelSeparator {}
FooterRectangle { FooterRectangle {
FooterMoreButton { WTextButton {
anchors { anchors {
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
left: parent.left left: parent.left
@@ -66,6 +66,10 @@ Menu {
} }
} }
Component.onCompleted: {
menuListView.itemAtIndex(0)?.forceActiveFocus();
}
contentItem: Item { contentItem: Item {
implicitWidth: menuListView.implicitWidth implicitWidth: menuListView.implicitWidth
implicitHeight: menuListView.implicitHeight implicitHeight: menuListView.implicitHeight
@@ -0,0 +1,15 @@
import QtQuick
import QtQuick.Effects
import qs.modules.common
import qs.modules.common.widgets
Item {
default property Item contentItem
property Item shadow: WRectangularShadow {
target: contentItem
}
implicitWidth: contentItem.implicitWidth
implicitHeight: contentItem.implicitHeight
children: [shadow, contentItem]
}
@@ -0,0 +1,189 @@
import qs
import qs.services
import qs.modules.common
import qs.modules.common.widgets
import qs.modules.common.functions
import qs.modules.waffle.looks
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import Quickshell.Io
Item {
id: root
Component.onCompleted: {
lockButton.forceActiveFocus();
}
ColumnLayout {
anchors.centerIn: parent
spacing: 4
WSessionScreenTextButton {
id: lockButton
focus: true
text: Translation.tr("Lock")
onClicked: {
GlobalStates.sessionOpen = false;
Session.lock();
}
KeyNavigation.up: powerButton
KeyNavigation.down: signOutButton
}
WSessionScreenTextButton {
id: signOutButton
focus: true
text: Translation.tr("Sign out")
onClicked: {
GlobalStates.sessionOpen = false;
Session.logout();
}
KeyNavigation.up: lockButton
KeyNavigation.down: changePasswordButton
}
WSessionScreenTextButton {
id: changePasswordButton
focus: true
text: Translation.tr("Change password")
onClicked: {
GlobalStates.sessionOpen = false;
Session.changePassword();
}
KeyNavigation.up: signOutButton
KeyNavigation.down: taskManagerButton
}
WSessionScreenTextButton {
id: taskManagerButton
focus: true
text: Translation.tr("Task Manager")
onClicked: {
GlobalStates.sessionOpen = false;
Session.launchTaskManager();
}
KeyNavigation.up: signOutButton
KeyNavigation.down: cancelButton
}
CancelButton {
id: cancelButton
Layout.fillWidth: true
Layout.leftMargin: 5
Layout.rightMargin: 5
Layout.topMargin: 38
onClicked: GlobalStates.sessionOpen = false
KeyNavigation.up: taskManagerButton
KeyNavigation.down: powerButton
}
}
RowLayout {
anchors {
bottom: parent.bottom
right: parent.right
bottomMargin: 21
rightMargin: 31
}
PowerButton {
id: powerButton
KeyNavigation.up: cancelButton
KeyNavigation.down: lockButton
}
}
component PowerButton: WSessionScreenTextButton {
id: root
implicitWidth: 40
implicitHeight: 40
focusRingRadius: Looks.radius.large
colBackgroundHover: Looks.colors.bg2Hover
colBackgroundActive: Looks.colors.bg2Active
property color color: {
if (root.down) {
return root.colBackgroundActive;
} else if (root.hovered) {
return root.colBackgroundHover;
} else {
return root.colBackground;
}
}
background: Rectangle {
id: background
radius: Looks.radius.medium
color: root.color
}
contentItem: Item {
FluentIcon {
anchors.centerIn: parent
implicitSize: 20
icon: "power"
}
}
onClicked: {
powerMenu.visible = !powerMenu.visible;
}
WMenu {
id: powerMenu
x: -powerMenu.implicitWidth / 2 + root.implicitWidth / 2
y: -powerMenu.implicitHeight
Action {
icon.name: "power"
text: Translation.tr("Shut down")
onTriggered: Session.poweroff()
}
Action {
icon.name: "arrow-counterclockwise"
text: Translation.tr("Restart")
onTriggered: Session.reboot()
}
}
}
component CancelButton: WBorderlessButton {
id: root
implicitHeight: 32
colBackground: Looks.colors.bg1Base
colBackgroundHover: Qt.lighter(Looks.colors.bg1Base, 1.2)
colBackgroundActive: Qt.lighter(Looks.colors.bg1Base, 1.1)
property bool keyboardDown: false
Keys.onPressed: event => {
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
keyboardDown = true;
event.accepted = true;
}
}
Keys.onReleased: event => {
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
keyboardDown = false;
root.clicked();
event.accepted = true;
}
}
contentItem: WText {
text: Translation.tr("Cancel")
horizontalAlignment: Text.AlignHCenter
font.pixelSize: Looks.font.pixelSize.large
}
Rectangle {
visible: cancelButton.focus
anchors {
fill: parent
margins: -3
}
radius: cancelButton.background.radius + 4
color: "transparent"
border.width: 2
border.color: "#ffffff"
}
}
}
@@ -0,0 +1,54 @@
pragma ComponentBehavior: Bound
import QtQuick
import qs
import qs.modules.waffle.looks
WTextButton {
id: root
implicitWidth: 135
implicitHeight: 40
horizontalPadding: 5
property bool keyboardDown: false
property alias focusRingRadius: focusRing.radius
Keys.onPressed: event => {
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
keyboardDown = true;
event.accepted = true;
}
}
Keys.onReleased: event => {
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
keyboardDown = false;
root.clicked();
event.accepted = true;
}
}
contentItem: Item {
id: contentItem
implicitWidth: buttonText.implicitWidth
WText {
id: buttonText
anchors.fill: parent
color: (root.pressed || root.keyboardDown) ? Looks.colors.fg1 : Looks.colors.fg
text: root.text
font.pixelSize: Looks.font.pixelSize.large
}
}
Rectangle {
id: focusRing
visible: root.focus
anchors {
fill: parent
margins: -4
}
color: "transparent"
border.width: 2
border.color: "#ffffff"
}
}
@@ -0,0 +1,117 @@
import qs
import qs.services
import qs.modules.common
import qs.modules.common.widgets
import qs.modules.common.functions
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import Quickshell.Io
import Quickshell.Wayland
import Quickshell.Hyprland
Scope {
id: root
property var focusedScreen: Quickshell.screens.find(s => s.name === Hyprland.focusedMonitor?.name)
Loader {
id: sessionLoader
active: GlobalStates.sessionOpen
onActiveChanged: {
if (sessionLoader.active) SessionWarnings.refresh();
}
Connections {
target: GlobalStates
function onScreenLockedChanged() {
if (GlobalStates.screenLocked) {
GlobalStates.sessionOpen = false;
}
}
}
sourceComponent: PanelWindow { // Session menu
id: sessionRoot
visible: sessionLoader.active
property string subtitle
function hide() {
GlobalStates.sessionOpen = false;
}
exclusionMode: ExclusionMode.Ignore
WlrLayershell.namespace: "quickshell:session"
WlrLayershell.layer: WlrLayer.Overlay
WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive
// This is a big surface so we needa carefully choose the transparency,
// or we'll get a large scary rgb blob
color: "#000000"
anchors {
top: true
left: true
right: true
bottom: true
}
Item {
anchors.fill: parent
focus: true
Keys.onPressed: (event) => {
if (event.key === Qt.Key_Escape) {
sessionRoot.hide();
}
}
SessionScreenContent {
anchors.fill: parent
}
}
}
}
IpcHandler {
target: "session"
function toggle(): void {
GlobalStates.sessionOpen = !GlobalStates.sessionOpen;
}
function close(): void {
GlobalStates.sessionOpen = false
}
function open(): void {
GlobalStates.sessionOpen = true
}
}
GlobalShortcut {
name: "sessionToggle"
description: "Toggles session screen on press"
onPressed: {
GlobalStates.sessionOpen = !GlobalStates.sessionOpen;
}
}
GlobalShortcut {
name: "sessionOpen"
description: "Opens session screen on press"
onPressed: {
GlobalStates.sessionOpen = true
}
}
GlobalShortcut {
name: "sessionClose"
description: "Closes session screen on press"
onPressed: {
GlobalStates.sessionOpen = false
}
}
}
@@ -9,6 +9,8 @@ import qs.services
import qs.modules.common import qs.modules.common
import qs.modules.common.functions import qs.modules.common.functions
import qs.modules.waffle.looks import qs.modules.waffle.looks
import qs.modules.waffle.startMenu.startPage
import qs.modules.waffle.startMenu.searchPage
WBarAttachedPanelContent { WBarAttachedPanelContent {
id: root id: root
@@ -70,6 +70,19 @@ Scope {
} }
} }
function toggleClipboard() {
if (LauncherSearch.query.startsWith(Config.options.search.prefix.clipboard) || !GlobalStates.searchOpen) {
GlobalStates.searchOpen = !GlobalStates.searchOpen;
}
LauncherSearch.ensurePrefix(Config.options.search.prefix.clipboard);
}
function toggleEmojis() {
if (LauncherSearch.query.startsWith(Config.options.search.prefix.emojis) || !GlobalStates.searchOpen) {
GlobalStates.searchOpen = !GlobalStates.searchOpen;
}
LauncherSearch.ensurePrefix(Config.options.search.prefix.emojis);
}
IpcHandler { IpcHandler {
target: "search" target: "search"
@@ -119,4 +132,22 @@ Scope {
GlobalStates.superReleaseMightTrigger = false; GlobalStates.superReleaseMightTrigger = false;
} }
} }
GlobalShortcut {
name: "overviewClipboardToggle"
description: "Toggle clipboard query on overview widget"
onPressed: {
root.toggleClipboard();
}
}
GlobalShortcut {
name: "overviewEmojiToggle"
description: "Toggle emoji query on overview widget"
onPressed: {
root.toggleEmojis();
}
}
} }
@@ -5,6 +5,7 @@ import qs.modules.common
import qs.modules.waffle.looks import qs.modules.waffle.looks
import qs.modules.common.functions import qs.modules.common.functions
import qs.modules.common.models import qs.modules.common.models
import qs.modules.waffle.startMenu
import Quickshell import Quickshell
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Controls import QtQuick.Controls
@@ -119,7 +120,7 @@ RowLayout {
onModelChanged: { onModelChanged: {
root.focusFirstItem(); root.focusFirstItem();
} }
delegate: WSearchResultButton { delegate: SearchResultButton {
required property int index required property int index
required property var modelData required property var modelData
entry: modelData entry: modelData
@@ -8,6 +8,7 @@ import qs.services
import qs.modules.common import qs.modules.common
import qs.modules.common.functions import qs.modules.common.functions
import qs.modules.waffle.looks import qs.modules.waffle.looks
import qs.modules.waffle.startMenu
RowLayout { RowLayout {
id: root id: root
@@ -90,7 +90,7 @@ Rectangle {
NumberAnimation { NumberAnimation {
target: categoryFolderPopup target: categoryFolderPopup
property: "x" property: "x"
from: categoryFolderPopup.originPoint.x - categoryOpenButtonLoader.width * 3 / 2 from: categoryFolderPopup.originPoint.x - categoryOpenButtonLoader.width * 5 / 2
to: categoryFolderPopup.windowCenterPoint.x - categoryFolderPopup.width / 2 to: categoryFolderPopup.windowCenterPoint.x - categoryFolderPopup.width / 2
duration: 300 duration: 300
easing.type: Easing.BezierSpline easing.type: Easing.BezierSpline
@@ -99,7 +99,7 @@ Rectangle {
NumberAnimation { NumberAnimation {
target: categoryFolderPopup target: categoryFolderPopup
property: "y" property: "y"
from: categoryFolderPopup.originPoint.y - categoryOpenButtonLoader.height / 2 from: categoryFolderPopup.originPoint.y - categoryOpenButtonLoader.height * 3 / 2
to: categoryFolderPopup.windowCenterPoint.y - categoryFolderPopup.height / 2 to: categoryFolderPopup.windowCenterPoint.y - categoryFolderPopup.height / 2
duration: 300 duration: 300
easing.type: Easing.BezierSpline easing.type: Easing.BezierSpline
@@ -120,7 +120,7 @@ Rectangle {
NumberAnimation { NumberAnimation {
target: categoryFolderPopup target: categoryFolderPopup
property: "x" property: "x"
to: categoryFolderPopup.originPoint.x - categoryOpenButtonLoader.width * 3 / 2 to: categoryFolderPopup.originPoint.x - categoryOpenButtonLoader.width * 5 / 2
duration: 200 duration: 200
easing.type: Easing.BezierSpline easing.type: Easing.BezierSpline
easing.bezierCurve: Looks.transition.easing.bezierCurve.easeOut easing.bezierCurve: Looks.transition.easing.bezierCurve.easeOut
@@ -128,7 +128,7 @@ Rectangle {
NumberAnimation { NumberAnimation {
target: categoryFolderPopup target: categoryFolderPopup
property: "y" property: "y"
to: categoryFolderPopup.originPoint.y - categoryOpenButtonLoader.height / 2 to: categoryFolderPopup.originPoint.y - categoryOpenButtonLoader.height * 3 / 2
duration: 200 duration: 200
easing.type: Easing.BezierSpline easing.type: Easing.BezierSpline
easing.bezierCurve: Looks.transition.easing.bezierCurve.easeOut easing.bezierCurve: Looks.transition.easing.bezierCurve.easeOut
@@ -147,10 +147,13 @@ Rectangle {
background: null background: null
Loader { Loader {
id: folderContentLoader
active: categoryFolderPopup.visible active: categoryFolderPopup.visible
sourceComponent: CategoryFolderContent { sourceComponent: WRectangularShadowThis {
title: root.aggregatedCategory.name CategoryFolderContent {
desktopEntries: root.desktopEntries title: root.aggregatedCategory.name
desktopEntries: root.desktopEntries
}
} }
} }
} }
@@ -44,6 +44,8 @@ BodyRectangle {
component AllApps: PageSection { component AllApps: PageSection {
title: Translation.tr("All") title: Translation.tr("All")
// TODO: Do we wanna also implement list view and grid view?
// (instead of only category view)
AllAppsGrid { AllAppsGrid {
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
@@ -0,0 +1,39 @@
pragma Singleton
import qs.modules.common
import qs.modules.common.functions
import QtQuick
import Quickshell
import Quickshell.Io
Singleton {
id: root
property bool packageManagerRunning: false
property bool downloadRunning: false
function refresh() {
packageManagerRunning = false;
downloadRunning = false;
detectPackageManagerProc.running = false;
detectPackageManagerProc.running = true;
detectDownloadProc.running = false;
detectDownloadProc.running = true;
}
Process {
id: detectPackageManagerProc
command: ["bash", "-c", "pidof pacman yay paru dnf zypper apt apx xbps snap apk yum epsi pikman"]
onExited: (exitCode, exitStatus) => {
root.packageManagerRunning = (exitCode === 0);
}
}
Process {
id: detectDownloadProc
command: ["bash", "-c", "pidof curl wget aria2c yt-dlp || ls ~/Downloads | grep -E '\.crdownload$|\.part$'"]
onExited: (exitCode, exitStatus) => {
root.downloadRunning = (exitCode === 0);
}
}
}
@@ -13,6 +13,7 @@ Singleton {
id: root id: root
property bool available: false property bool available: false
property alias checking: checkUpdatesProc.running
property int count: 0 property int count: 0
readonly property bool updateAdvised: available && count > Config.options.updates.adviseUpdateThreshold readonly property bool updateAdvised: available && count > Config.options.updates.adviseUpdateThreshold
+3 -2
View File
@@ -6,7 +6,6 @@
// Adjust this to make the shell smaller or larger // Adjust this to make the shell smaller or larger
//@ pragma Env QT_SCALE_FACTOR=1 //@ pragma Env QT_SCALE_FACTOR=1
import qs.modules.common import qs.modules.common
import qs.modules.ii.background import qs.modules.ii.background
import qs.modules.ii.bar import qs.modules.ii.bar
@@ -34,6 +33,7 @@ import qs.modules.waffle.bar
import qs.modules.waffle.notificationCenter import qs.modules.waffle.notificationCenter
import qs.modules.waffle.onScreenDisplay import qs.modules.waffle.onScreenDisplay
import qs.modules.waffle.startMenu import qs.modules.waffle.startMenu
import qs.modules.waffle.sessionScreen
import QtQuick import QtQuick
import QtQuick.Window import QtQuick.Window
@@ -85,6 +85,7 @@ ShellRoot {
PanelLoader { identifier: "wNotificationCenter"; component: WaffleNotificationCenter {} } PanelLoader { identifier: "wNotificationCenter"; component: WaffleNotificationCenter {} }
PanelLoader { identifier: "wOnScreenDisplay"; component: WaffleOSD {} } PanelLoader { identifier: "wOnScreenDisplay"; component: WaffleOSD {} }
PanelLoader { identifier: "wStartMenu"; component: WaffleStartMenu {} } PanelLoader { identifier: "wStartMenu"; component: WaffleStartMenu {} }
PanelLoader { identifier: "wSessionScreen"; component: WaffleSessionScreen {} }
ReloadPopup {} ReloadPopup {}
component PanelLoader: LazyLoader { component PanelLoader: LazyLoader {
@@ -97,7 +98,7 @@ ShellRoot {
property list<string> families: ["ii", "waffle"] property list<string> families: ["ii", "waffle"]
property var panelFamilies: ({ property var panelFamilies: ({
"ii": ["iiBar", "iiBackground", "iiCheatsheet", "iiDock", "iiLock", "iiMediaControls", "iiNotificationPopup", "iiOnScreenDisplay", "iiOnScreenKeyboard", "iiOverlay", "iiOverview", "iiPolkit", "iiRegionSelector", "iiScreenCorners", "iiSessionScreen", "iiSidebarLeft", "iiSidebarRight", "iiVerticalBar", "iiWallpaperSelector"], "ii": ["iiBar", "iiBackground", "iiCheatsheet", "iiDock", "iiLock", "iiMediaControls", "iiNotificationPopup", "iiOnScreenDisplay", "iiOnScreenKeyboard", "iiOverlay", "iiOverview", "iiPolkit", "iiRegionSelector", "iiScreenCorners", "iiSessionScreen", "iiSidebarLeft", "iiSidebarRight", "iiVerticalBar", "iiWallpaperSelector"],
"waffle": ["wActionCenter", "wBar", "wBackground", "wNotificationCenter", "wOnScreenDisplay", "wStartMenu", "iiCheatsheet", "iiLock", "iiNotificationPopup", "iiOnScreenKeyboard", "iiOverlay", "iiPolkit", "iiRegionSelector", "iiSessionScreen", "iiWallpaperSelector"], "waffle": ["wActionCenter", "wBar", "wBackground", "wNotificationCenter", "wOnScreenDisplay", "wStartMenu", "iiCheatsheet", "iiLock", "iiNotificationPopup", "iiOnScreenKeyboard", "iiOverlay", "iiPolkit", "iiRegionSelector", "wSessionScreen", "iiWallpaperSelector"],
}) })
function cyclePanelFamily() { function cyclePanelFamily() {
const currentIndex = families.indexOf(Config.options.panelFamily) const currentIndex = families.indexOf(Config.options.panelFamily)