quickshell/launcher/Launcher.qml
2025-09-09 12:03:05 +02:00

137 lines
3.3 KiB
QML

import Quickshell
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Quickshell.Wayland
import Quickshell.Hyprland
import "root:/singeltons"
PanelWindow {
id: root
property bool show: true
implicitWidth: 600
implicitHeight: 400
visible: show
focusable: true
color: "transparent"
WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive
WlrLayershell.layer: WlrLayer.Top
HyprlandWindow.opacity: 0.9
// Main window
Rectangle {
anchors.fill: parent
anchors.centerIn: parent
color: Qt.hsla(0, 0, 1, 0.5)
border.color: Qt.hsla(0, 0, 1, 0.2)
border.width: 2
radius: 12
// Main window layout
ColumnLayout {
anchors.fill: parent
anchors.margins: 16
spacing: 20
// Search bar
RowLayout {
Layout.fillWidth: true
Layout.preferredHeight: 40
spacing: 8
TextField {
id: searchInput
Layout.fillWidth: true
focus: true
placeholderText: "Search..."
font.pixelSize: 20
background: null
color: "white"
selectByMouse: true
Keys.onPressed: (event) => {
switch (event.key){
case (Qt.Key_Escape):
root.show = false
event.accepted = true
break
case (Qt.Key_Return):
case (Qt.Key_Enter):
if (resultsList.currentIndex >= 0) {
const item = resultsList.model[resultsList.currentIndex]
DesktopApps.launch(item)
}
root.show = false
event.accepted = true
break
case (Qt.Key_Down):
case (Qt.Key_Tab):
resultsList.currentIndex = Math.min(resultsList.count - 1, resultsList.currentIndex + 1)
event.accepted = true
break
case (Qt.Key_Up):
case (Qt.Key_Backtab):
resultsList.currentIndex = Math.max(0, resultsList.currentIndex - 1)
break
}
}
}
}
// Results
ListView {
id: resultsList
model: DesktopApps.fuzzySearch(searchInput.text)
Layout.fillWidth: true
Layout.fillHeight: true
spacing: 4
keyNavigationWraps: true
// Result item
delegate: Rectangle {
required property DesktopEntry modelData
width: parent.width
height: 50
radius: 6
color: ListView.isCurrentItem ? "#3a3a3c" : "transparent"
RowLayout {
anchors.fill: parent
anchors.margins: 8
spacing: 8
Image {
source: parent.parent.modelData.icon !== "" ? Quickshell.iconPath(parent.parent.modelData.icon,true) : ""
visible: parent.parent.modelData.icon !== ""
fillMode: Image.PreserveAspectFit
sourceSize.width: 30
sourceSize.height: 30
}
Text {
text: parent.parent.modelData.name
Layout.fillWidth: true
font.pixelSize: 18
color: "white"
}
}
}
}
}
}
}