81 lines
2.3 KiB
QML
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
|
|
}
|
|
}
|
|
}
|