feat: dashboard show on hover, media and weather tabs added

This commit is contained in:
2026-09-30 14:22:22 +02:00
parent d259c6ffbe
commit 2c90339c77
97 changed files with 4480 additions and 990 deletions
+5 -5
View File
@@ -15,7 +15,7 @@ CustomListView {
property string displayText
readonly property string requestedState: stateForText(search.text)
required property SearchBar search
required property PersistentProperties visibilities
required property ScreenState screenState
function resultsForText(text: string): var {
switch (stateForText(text)) {
@@ -44,7 +44,7 @@ CustomListView {
}
function syncDisplayText(): void {
if (visibilities.launcher && requestedState === displayState)
if (screenState.launcher && requestedState === displayState)
displayText = search.text;
}
@@ -55,7 +55,7 @@ CustomListView {
preferredHighlightBegin: 0
preferredHighlightEnd: height
spacing: Tokens.spacing.small
state: visibilities.launcher ? requestedState : displayState
state: screenState.launcher ? requestedState : displayState
verticalLayoutDirection: ListView.BottomToTop
CustomScrollBar.vertical: CustomScrollBar {
@@ -236,7 +236,7 @@ CustomListView {
id: appItem
AppItem {
visibilities: root.visibilities
screenState: root.screenState
}
}
@@ -277,6 +277,6 @@ CustomListView {
root.syncDisplayText();
}
target: root.visibilities
target: root.screenState
}
}
+3 -3
View File
@@ -13,14 +13,14 @@ CarouselView {
readonly property var screen: QsWindow.window?.screen
required property SearchBar search
readonly property var values: Wallpapers.query(root.search.text.split(" ").slice(1).join(" "))
required property var visibilities
required property ScreenState screenState
currentIndex: {
const idx = Wallpapers.list.findIndex(w => w.path === Wallpapers.actualCurrent);
return idx >= 0 ? idx : 0;
}
delegateProperties: ({
visibilities: root.visibilities
screenState: root.screenState
})
focalWidth: Config.launcher.sizes.wallpaperWidth
glideDuration: 250
@@ -32,7 +32,7 @@ CarouselView {
return 0;
const barMargins = Config.bar.border * 2;
let margins = Math.round(screen.width / 6);
if (visibilities.utilities || visibilities.sidebar)
if (screenState.utilities || screenState.sidebar)
margins = Config.sidebar.sizes.width;
return screen.width - (barMargins + margins) * 2 - Config.bar.rounding * 4;
}
+7 -7
View File
@@ -15,7 +15,7 @@ Item {
readonly property int padding: Tokens.padding.largeIncreased / 4
required property var panels
readonly property int rounding: Tokens.rounding.largeIncreased
required property PersistentProperties visibilities
required property ScreenState screenState
implicitHeight: search.height + listWrapper.height + padding * 2
implicitWidth: listWrapper.width + padding * 2
@@ -38,7 +38,7 @@ Item {
panels: root.panels
rounding: root.rounding
search: search
visibilities: root.visibilities
screenState: root.screenState
}
}
@@ -55,7 +55,7 @@ Item {
Component.onCompleted: forceActiveFocus()
Keys.onDownPressed: list.currentList?.decrementCurrentIndex()
Keys.onEscapePressed: root.visibilities.launcher = false
Keys.onEscapePressed: root.screenState.launcher = false
Keys.onPressed: event => {
if (event.modifiers & Qt.ControlModifier) {
if (event.key === Qt.Key_J) {
@@ -81,7 +81,7 @@ Item {
if (Colors.scheme === "dynamic" && currentItem.modelData.path !== Wallpapers.actualCurrent)
Wallpapers.previewColorLock = true;
Wallpapers.setWallpaper(currentItem.modelData.path);
root.visibilities.launcher = false;
root.screenState.launcher = false;
} else if (text.startsWith(Config.launcher.actionPrefix)) {
if (text.startsWith(`${Config.launcher.actionPrefix}calc `))
currentItem.onClicked();
@@ -89,18 +89,18 @@ Item {
currentItem.modelData.onClicked(list.currentList);
} else {
Apps.launch(currentItem.modelData);
root.visibilities.launcher = false;
root.screenState.launcher = false;
}
}
}
Connections {
function onLauncherChanged(): void {
if (!root.visibilities.launcher)
if (!root.screenState.launcher)
search.text = "";
}
target: root.visibilities
target: root.screenState
}
}
}
+5 -5
View File
@@ -20,7 +20,7 @@ Item {
required property int rounding
required property SearchBar search
readonly property bool showWallpapers: search.text.startsWith(`${Config.launcher.actionPrefix}wallpaper `)
required property PersistentProperties visibilities
required property ScreenState screenState
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
@@ -28,7 +28,7 @@ Item {
state: showWallpapers ? "wallpapers" : "apps"
Behavior on implicitHeight {
enabled: root.visibilities.launcher
enabled: root.screenState.launcher
Anim {
duration: Tokens.anim.durations.small
@@ -36,7 +36,7 @@ Item {
}
}
Behavior on implicitWidth {
enabled: root.visibilities.launcher
enabled: root.screenState.launcher
Anim {
duration: Tokens.anim.durations.small
@@ -99,7 +99,7 @@ Item {
sourceComponent: AppList {
search: root.search
visibilities: root.visibilities
screenState: root.screenState
}
}
@@ -115,7 +115,7 @@ Item {
sourceComponent: CarouselView {
panels: root.panels
search: root.search
visibilities: root.visibilities
screenState: root.screenState
}
}
+2 -2
View File
@@ -12,7 +12,7 @@ Item {
id: root
required property DesktopEntry modelData
required property PersistentProperties visibilities
required property ScreenState screenState
anchors.left: parent?.left
anchors.right: parent?.right
@@ -23,7 +23,7 @@ Item {
onClicked: {
Apps.launch(root.modelData);
root.visibilities.launcher = false;
root.screenState.launcher = false;
}
}
+2 -2
View File
@@ -16,7 +16,7 @@ Item {
function onClicked(): void {
Quickshell.execDetached(["wl-copy", Qalculator.eval(math, false)]);
root.list.visibilities.launcher = false;
root.list.screenState.launcher = false;
}
anchors.left: parent?.left
@@ -81,7 +81,7 @@ Item {
onClicked: {
Quickshell.execDetached(["app2unit", "--", ...Config.general.apps.terminal, "fish", "-C", `exec qalc -i '${root.math}'`]);
root.list.visibilities.launcher = false;
root.list.screenState.launcher = false;
}
}
+141
View File
@@ -0,0 +1,141 @@
import QtQuick
import Quickshell
import Quickshell.Widgets
import ZShell.Config
import qs.Components
import qs.Helpers
import qs.Modules.Launcher.Services
import qs.Services
Item {
id: root
required property var list
required property var modelData
anchors.left: parent?.left
anchors.right: parent?.right
implicitHeight: Config.launcher.sizes.itemHeight
function onClicked(): void {
root.list.screenState.launcher = false;
if (root.modelData?.path)
Files.launch(["xdg-open", root.modelData.path]);
}
StateLayer {
id: sLayer
radius: Tokens.rounding.medium
manualHoverOverride: openLocation.hovered
onClicked: {
root.onClicked();
}
}
IconButton {
id: openLocation
anchors.right: parent.right
anchors.rightMargin: Tokens.padding.medium
anchors.verticalCenter: parent.verticalCenter
icon: "open_in_new"
isRound: true
scale: sLayer.containsMouse || sLayer.manualHoverOverride ? 1 : 0.4
opacity: sLayer.containsMouse || sLayer.manualHoverOverride ? 1 : 0
visible: opacity > 0
Behavior on opacity {
Anim {
type: Anim.DefaultEffects
}
}
Behavior on scale {
Anim {
type: Anim.DefaultEffects
}
}
onClicked: {
root.list.screenState.launcher = false;
if (root.modelData?.path)
Files.showInFolder(root.modelData.path);
}
}
Item {
anchors.fill: parent
anchors.leftMargin: Tokens.padding.small
anchors.margins: Tokens.padding.small
anchors.rightMargin: Tokens.padding.small
IconImage {
id: icon
anchors.verticalCenter: parent.verticalCenter
implicitSize: Tokens.font.size.extraLarge
source: Quickshell.iconPath(root.modelData?.icon) ?? ""
visible: !root.modelData?.isImage
}
Loader {
active: opacity > 0
anchors.verticalCenter: parent.verticalCenter
asynchronous: true
opacity: root.modelData?.isImage && image.status === Image.Loading ? 1 : 0
Behavior on opacity {
Anim {
type: Anim.DefaultEffects
}
}
sourceComponent: LoadingIndicator {
color: Colors.palette.m3primaryContainer
implicitSize: Tokens.font.size.extraLarge
}
}
FadeImage {
id: image
property int implicitSize: Tokens.font.size.extraLarge
width: implicitSize
fillMode: Image.PreserveAspectFit
anchors.verticalCenter: parent.verticalCenter
source: root.modelData?.isImage ? root.modelData?.path ?? "" : ""
visible: root.modelData?.isImage
}
Item {
anchors.left: icon.right
anchors.leftMargin: Tokens.spacing.medium
anchors.verticalCenter: icon.verticalCenter
implicitHeight: name.implicitHeight + desc.implicitHeight
implicitWidth: parent.width - icon.width
CustomText {
id: name
font.pointSize: Tokens.font.size.normal
text: root.modelData?.name ?? ""
elide: Text.ElideRight
width: root.width - icon.width - openLocation.implicitWidth - openLocation.anchors.rightMargin - Tokens.spacing.medium - Tokens.rounding.medium * 2
}
CustomText {
id: desc
anchors.top: name.bottom
color: Colors.palette.m3outline
elide: Text.ElideRight
font.pointSize: Tokens.font.size.small
text: root.modelData?.path ?? ""
width: root.width - icon.width - openLocation.implicitWidth - openLocation.anchors.rightMargin - Tokens.spacing.medium - Tokens.rounding.medium * 2
}
}
}
}
+1 -1
View File
@@ -12,7 +12,7 @@ Item {
required property var modelData // FileSystemEntry-like {path, relativePath}
required property real tileHeight
required property real tileWidth
required property PersistentProperties visibilities
required property ScreenState screenState
signal requestActivate
+2 -2
View File
@@ -42,10 +42,10 @@ Searcher {
if (command[0] === "autocomplete" && command.length > 1) {
list.search.text = `${Config.launcher.actionPrefix}${command[1]} `;
} else if (command[0] === "setMode" && command.length > 1) {
list.visibilities.launcher = false;
list.screenState.launcher = false;
Colors.setMode(command[1]);
} else {
list.visibilities.launcher = false;
list.screenState.launcher = false;
Quickshell.execDetached(command);
}
}
+1 -1
View File
@@ -79,7 +79,7 @@ Searcher {
required property string variant
function onClicked(list: AppList): void {
list.visibilities.launcher = false;
list.screenState.launcher = false;
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--scheme", variant]);
Config.colors.schemeType = variant;
}
+4 -4
View File
@@ -12,7 +12,7 @@ Item {
property int contentHeight
readonly property real maxHeight: {
let max = screen.height - Tokens.spacing.largeIncreased * 2;
if (visibilities.resources && panels.resourcesWrapper.x + panels.resourcesWrapper.width > root.x)
if (screenState.resources && panels.resourcesWrapper.x + panels.resourcesWrapper.width > root.x)
max -= panels.resources.nonAnimHeight;
if (panels.popouts.hasCurrent)
if (panels.popouts.current?.x + panels.popouts.current?.width > root.x && panels.popouts.current?.x < root.x + root.width)
@@ -22,8 +22,8 @@ Item {
property real offsetScale: shouldBeActive ? 0 : 1
required property var panels
required property ShellScreen screen
readonly property bool shouldBeActive: visibilities.launcher
required property PersistentProperties visibilities
readonly property bool shouldBeActive: screenState.launcher
required property ScreenState screenState
anchors.bottomMargin: (-implicitHeight - 5) * offsetScale
implicitHeight: content.implicitHeight
@@ -57,7 +57,7 @@ Item {
sourceComponent: Content {
maxHeight: root.maxHeight
panels: root.panels
visibilities: root.visibilities
screenState: root.screenState
}
}
}