Files
homelab/dotfiles/quickshell/widgets/launcher/BladeLauncher.qml
T

81 lines
2.3 KiB
QML

pragma ComponentBehavior: Bound
import Quickshell
import Quickshell.Hyprland
import Quickshell.Wayland
import QtQuick
import qs.widgets.theme
// Variant 9 — asymmetric Blade application launcher.
Scope {
id: root
property bool active: false
function toggle() { root.active = !root.active; }
GlobalShortcut {
name: "launcher9"
description: "Toggle app launcher (Blade matrix)"
onPressed: root.toggle()
}
PanelWindow {
id: win
visible: root.active
WlrLayershell.layer: WlrLayer.Overlay
WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive
exclusionMode: ExclusionMode.Ignore
color: Theme.textAlpha(0)
anchors { top: true; left: true; right: true; bottom: true }
property int selectedIndex: 0
function clampSelection(index) {
return model.apps.length === 0 ? 0 : Math.max(0, Math.min(model.apps.length - 1, index));
}
function move(delta) {
const count = model.apps.length;
if (count === 0)
return;
selectedIndex = ((selectedIndex + delta) % count + count) % count;
}
function launch(index) {
if (model.launch(index))
root.active = false;
}
onVisibleChanged: {
if (visible) {
content.clearSearch();
selectedIndex = 0;
content.focusSearch();
}
}
AppModel { id: model; search: content.query }
Rectangle {
anchors.fill: parent
color: Theme.surface
opacity: 0.78
MouseArea { anchors.fill: parent; onClicked: root.active = false }
}
BladeLauncherContent {
id: content
anchors.centerIn: parent
width: 1120
height: 640
scale: Math.min(1, (parent.width - 56) / width, (parent.height - 56) / height)
transformOrigin: Item.Center
apps: model.apps
selectedIndex: win.selectedIndex
onSelectionRequested: index => win.selectedIndex = win.clampSelection(index)
onMoveRequested: delta => win.move(delta)
onLaunchRequested: index => win.launch(index)
onDismissRequested: root.active = false
}
}
}