feat: input mgr
This commit is contained in:
@@ -28,6 +28,8 @@ top bar:
|
||||
color: #04047C
|
||||
|
||||
settings:
|
||||
offset from top + 9slice: 180
|
||||
|
||||
with 9slice borders:
|
||||
x: 1217
|
||||
y: 767
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import Quickshell
|
||||
import Quickshell.Wayland
|
||||
|
||||
import "Healthbar"
|
||||
|
||||
PanelWindow {
|
||||
@@ -10,9 +11,11 @@ PanelWindow {
|
||||
}
|
||||
|
||||
WlrLayershell.layer: WlrLayer.Top
|
||||
WlrLayershell.focusable: false
|
||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
||||
WlrLayershell.namespace: "deltarune-quickshell-bottom"
|
||||
|
||||
visible: true
|
||||
visible: ShellStateManager.shellOpen
|
||||
exclusionMode: ExclusionMode.Ignore
|
||||
aboveWindows: true
|
||||
focusable: false
|
||||
65
Shell/InputShortcuts.qml
Normal file
65
Shell/InputShortcuts.qml
Normal file
@@ -0,0 +1,65 @@
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Hyprland
|
||||
import "."
|
||||
|
||||
Item {
|
||||
id: shortcuts
|
||||
property var manager: ShellInputManager
|
||||
|
||||
GlobalShortcut {
|
||||
appid: "deltarune"
|
||||
triggerDescription: "Close the menu"
|
||||
name: "shell_close"
|
||||
onReleased: manager.closeShell();
|
||||
}
|
||||
|
||||
GlobalShortcut {
|
||||
appid: "deltarune"
|
||||
triggerDescription: "Open the menu"
|
||||
name: "shell_open"
|
||||
onReleased: manager.openShell();
|
||||
}
|
||||
|
||||
GlobalShortcut {
|
||||
appid: "deltarune"
|
||||
triggerDescription: "Input back"
|
||||
name: "input_back"
|
||||
onReleased: manager.handleKeyInternal(Qt.Key_Shift);
|
||||
}
|
||||
|
||||
GlobalShortcut {
|
||||
appid: "deltarune"
|
||||
triggerDescription: "Input submit"
|
||||
name: "input_enter"
|
||||
onReleased: manager.handleKeyInternal(Qt.Key_Enter);
|
||||
}
|
||||
|
||||
GlobalShortcut {
|
||||
appid: "deltarune"
|
||||
triggerDescription: "Input up"
|
||||
name: "input_up"
|
||||
onReleased: manager.handleKeyInternal(Qt.Key_Up);
|
||||
}
|
||||
|
||||
GlobalShortcut {
|
||||
appid: "deltarune"
|
||||
triggerDescription: "Input down"
|
||||
name: "input_down"
|
||||
onReleased: manager.handleKeyInternal(Qt.Key_Down);
|
||||
}
|
||||
|
||||
GlobalShortcut {
|
||||
appid: "deltarune"
|
||||
triggerDescription: "Input left"
|
||||
name: "input_left"
|
||||
onReleased: manager.handleKeyInternal(Qt.Key_Left);
|
||||
}
|
||||
|
||||
GlobalShortcut {
|
||||
appid: "deltarune"
|
||||
triggerDescription: "Input right"
|
||||
name: "input_right"
|
||||
onReleased: manager.handleKeyInternal(Qt.Key_Right);
|
||||
}
|
||||
}
|
||||
73
Shell/Overlay.qml
Normal file
73
Shell/Overlay.qml
Normal file
@@ -0,0 +1,73 @@
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Wayland
|
||||
import Quickshell.Hyprland
|
||||
|
||||
import "Windows/QuickSettings"
|
||||
|
||||
PanelWindow {
|
||||
id: overlay
|
||||
anchors {
|
||||
top: true
|
||||
left: true
|
||||
right: true
|
||||
bottom: true
|
||||
}
|
||||
|
||||
WlrLayershell.layer: WlrLayer.Overlay
|
||||
WlrLayershell.focusable: true
|
||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive
|
||||
WlrLayershell.namespace: "deltarune-quickshell-overlay"
|
||||
|
||||
visible: ShellStateManager.shellOpen
|
||||
exclusionMode: ExclusionMode.Ignore
|
||||
aboveWindows: true
|
||||
focusable: ShellStateManager.shellOpen
|
||||
color: "#00000000"
|
||||
|
||||
HyprlandFocusGrab {
|
||||
id: grab
|
||||
active: true
|
||||
windows: [overlay]
|
||||
}
|
||||
|
||||
FocusScope {
|
||||
id: overlayFocus
|
||||
anchors.fill: parent
|
||||
focus: ShellStateManager.shellOpen
|
||||
|
||||
Component.onCompleted: {
|
||||
if (ShellStateManager.shellOpen)
|
||||
overlayFocus.forceActiveFocus();
|
||||
}
|
||||
|
||||
onVisibleChanged: if (visible)
|
||||
overlayFocus.forceActiveFocus()
|
||||
|
||||
onFocusChanged: {
|
||||
if (focus && ShellStateManager.shellOpen)
|
||||
overlayFocus.forceActiveFocus();
|
||||
}
|
||||
|
||||
Keys.onReleased: function (event) {
|
||||
if (!ShellStateManager.shellOpen)
|
||||
return;
|
||||
if (ShellInputManager.handleKey(event)) {
|
||||
event.accepted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: ShellStateManager
|
||||
function onShellOpenChanged() {
|
||||
if (ShellStateManager.shellOpen)
|
||||
overlayFocus.forceActiveFocus();
|
||||
}
|
||||
}
|
||||
|
||||
QuickSettings {
|
||||
id: quickSettingsWindow
|
||||
manager: ShellStateManager
|
||||
}
|
||||
}
|
||||
58
Shell/ShellInputManager.qml
Normal file
58
Shell/ShellInputManager.qml
Normal file
@@ -0,0 +1,58 @@
|
||||
pragma Singleton
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Hyprland
|
||||
|
||||
QtObject {
|
||||
id: inputManager
|
||||
|
||||
property var handlers: ({})
|
||||
|
||||
function openShell() {
|
||||
ShellStateManager.openShell();
|
||||
}
|
||||
|
||||
function closeShell() {
|
||||
ShellStateManager.closeShell();
|
||||
}
|
||||
|
||||
function registerHandler(context, handler) {
|
||||
handlers[context] = handler;
|
||||
}
|
||||
|
||||
function unregisterHandler(context) {
|
||||
handlers[context] = undefined;
|
||||
if (handlers.hasOwnProperty(context))
|
||||
delete handlers[context];
|
||||
}
|
||||
|
||||
function handleKeyInternal(key) {
|
||||
if (!ShellStateManager.shellOpen)
|
||||
return false;
|
||||
|
||||
var context = ShellStateManager.quickSettingsOpen ? "quickSettings" : "topbar";
|
||||
var handler = handlers[context];
|
||||
if (handler) {
|
||||
var handled = handler(key);
|
||||
if (handled)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (key === Qt.Key_Escape || key === Qt.Key_Shift || key === Qt.Key_X) {
|
||||
if (context === "quickSettings") {
|
||||
ShellStateManager.closeQuickSettings();
|
||||
} else if (context === "topbar") {
|
||||
ShellStateManager.closeShell();
|
||||
Hyprland.dispatch("submap reset");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function handleKey(event) {
|
||||
handleKeyInternal(event.key);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,20 +1,26 @@
|
||||
pragma Singleton
|
||||
import QtQuick
|
||||
import Quickshell.Hyprland
|
||||
|
||||
QtObject {
|
||||
id: manager
|
||||
|
||||
property bool shellOpen: false
|
||||
property bool quickSettingsOpen: false
|
||||
property var windowRequests: ({})
|
||||
property var quickSettingsPayload: ({})
|
||||
property var globals: ({})
|
||||
|
||||
signal shellOpened
|
||||
signal shellClosed
|
||||
signal quickSettingsOpened
|
||||
signal quickSettingsClosed
|
||||
signal windowRequested(string name, var payload)
|
||||
|
||||
function openShell() {
|
||||
if (!shellOpen) {
|
||||
console.log("ShellStateManager: openShell");
|
||||
Hyprland.dispatch("submap deltarune");
|
||||
shellOpen = true;
|
||||
shellOpened();
|
||||
}
|
||||
@@ -23,13 +29,16 @@ QtObject {
|
||||
function closeShell() {
|
||||
if (shellOpen) {
|
||||
console.log("ShellStateManager: closeShell");
|
||||
Hyprland.dispatch("submap reset");
|
||||
if (quickSettingsOpen) {
|
||||
closeQuickSettings();
|
||||
}
|
||||
shellOpen = false;
|
||||
shellClosed();
|
||||
}
|
||||
}
|
||||
|
||||
function toggleShell() {
|
||||
console.log("ShellStateManager: toggleShell (isOpen " + shellOpen + ")");
|
||||
shellOpen ? closeShell() : openShell();
|
||||
}
|
||||
|
||||
@@ -42,6 +51,29 @@ QtObject {
|
||||
windowRequested(name, payload);
|
||||
}
|
||||
|
||||
function openQuickSettings(payload) {
|
||||
var normalizedPayload = payload || ({});
|
||||
quickSettingsPayload = normalizedPayload;
|
||||
console.log("ShellStateManager: openQuickSettings", normalizedPayload);
|
||||
if (!quickSettingsOpen) {
|
||||
quickSettingsOpen = true;
|
||||
quickSettingsOpened();
|
||||
}
|
||||
requestWindow("quickSettings", normalizedPayload);
|
||||
}
|
||||
|
||||
function closeQuickSettings() {
|
||||
if (quickSettingsOpen) {
|
||||
console.log("ShellStateManager: closeQuickSettings");
|
||||
quickSettingsOpen = false;
|
||||
quickSettingsClosed();
|
||||
}
|
||||
}
|
||||
|
||||
function toggleQuickSettings(payload) {
|
||||
quickSettingsOpen ? closeQuickSettings() : openQuickSettings(payload);
|
||||
}
|
||||
|
||||
function setGlobal(key, value) {
|
||||
globals[key] = value;
|
||||
}
|
||||
|
||||
@@ -11,19 +11,21 @@ PanelWindow {
|
||||
}
|
||||
|
||||
WlrLayershell.layer: WlrLayer.Top
|
||||
WlrLayershell.focusable: true
|
||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand
|
||||
WlrLayershell.focusable: false
|
||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
||||
WlrLayershell.namespace: "deltarune-quickshell"
|
||||
|
||||
mask: Region {}
|
||||
|
||||
visible: true
|
||||
visible: ShellStateManager.shellOpen
|
||||
exclusionMode: ExclusionMode.Ignore
|
||||
aboveWindows: true
|
||||
focusable: true
|
||||
focusable: false
|
||||
|
||||
implicitHeight: 182
|
||||
color: "#000000"
|
||||
|
||||
Topbar {}
|
||||
Topbar {
|
||||
manager: ShellStateManager
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
import "../"
|
||||
|
||||
import "topbar"
|
||||
|
||||
@@ -8,6 +9,8 @@ Item {
|
||||
implicitWidth: 1312
|
||||
implicitHeight: 182
|
||||
|
||||
property var manager: ShellStateManager
|
||||
|
||||
anchors.centerIn: parent
|
||||
|
||||
property var iconSources: ["item.png", "equip.png", "power.png", "config.png"]
|
||||
@@ -28,6 +31,32 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: overlayKeyHandler
|
||||
function handle(key) {
|
||||
if (key === Qt.Key_Left) {
|
||||
moveSelection(-1);
|
||||
return true;
|
||||
}
|
||||
if (key === Qt.Key_Right) {
|
||||
moveSelection(1);
|
||||
return true;
|
||||
}
|
||||
if (key === Qt.Key_Return || key === Qt.Key_Enter || key === Qt.Key_Z) {
|
||||
if (iconSources[selectedIndex] === "config.png") {
|
||||
ShellStateManager.openQuickSettings({
|
||||
source: "Topbar"
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Component.onCompleted: ShellInputManager.registerHandler("topbar", handle)
|
||||
Component.onDestruction: ShellInputManager.unregisterHandler("topbar")
|
||||
}
|
||||
|
||||
DarkDollarsDisplay {}
|
||||
|
||||
Image {
|
||||
@@ -35,14 +64,6 @@ Item {
|
||||
x: -64
|
||||
}
|
||||
|
||||
FocusScope {
|
||||
id: focusScope
|
||||
focus: true
|
||||
anchors.fill: parent
|
||||
Keys.onLeftPressed: topbar.moveSelection(-1)
|
||||
Keys.onRightPressed: topbar.moveSelection(1)
|
||||
Component.onCompleted: forceActiveFocus()
|
||||
|
||||
Row {
|
||||
id: iconRow
|
||||
spacing: 76
|
||||
@@ -63,12 +84,17 @@ Item {
|
||||
anchors.centerIn: parent
|
||||
selected: topbar.selectedIndex == repeatitem.index
|
||||
iconSource: topbar.iconSources[repeatitem.index]
|
||||
showSoul: !topbar.manager.quickSettingsOpen
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
topbar.selectedIndex = repeatitem.index;
|
||||
if (topbar.iconSources[repeatitem.index] === "config.png") {
|
||||
ShellStateManager.openQuickSettings({
|
||||
source: "Topbar"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,42 @@
|
||||
import Quickshell
|
||||
import Quickshell.Wayland
|
||||
import QtQuick
|
||||
|
||||
PanelWindow {
|
||||
WlrLayershell.layer: WlrLayer.Top
|
||||
WlrLayershell.focusable: true
|
||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand
|
||||
WlrLayershell.namespace: "deltarune-quickshell"
|
||||
Item {
|
||||
id: windowFrame
|
||||
property color backgroundColor: "#000000"
|
||||
property int borderSize: 52
|
||||
width: 640
|
||||
height: 360
|
||||
clip: true
|
||||
|
||||
visible: true
|
||||
exclusionMode: ExclusionMode.Ignore
|
||||
aboveWindows: true
|
||||
focusable: true
|
||||
|
||||
implicitWidth: 1217
|
||||
implicitHeight: 767
|
||||
color: "#000000"
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: windowFrame.borderSize
|
||||
color: windowFrame.backgroundColor
|
||||
}
|
||||
|
||||
BorderImage {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 16 + 4
|
||||
anchors.centerIn: parent
|
||||
source: "./border.png"
|
||||
width: 108
|
||||
height: 108
|
||||
|
||||
border {
|
||||
left: windowFrame.borderSize
|
||||
top: windowFrame.borderSize
|
||||
right: windowFrame.borderSize
|
||||
bottom: windowFrame.borderSize
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: contentSlot
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: windowFrame.borderSize
|
||||
}
|
||||
}
|
||||
|
||||
default property alias windowContent: contentSlot.data
|
||||
}
|
||||
|
||||
23
Shell/Windows/QuickSettings/QuickSettings.qml
Normal file
23
Shell/Windows/QuickSettings/QuickSettings.qml
Normal file
@@ -0,0 +1,23 @@
|
||||
import QtQuick
|
||||
import "../.."
|
||||
import "../../Window" as ShellWindow
|
||||
|
||||
ShellWindow.Window {
|
||||
id: quickSettingsWindow
|
||||
property var manager: ShellStateManager
|
||||
|
||||
width: 1217 + 52
|
||||
height: 767 + 52
|
||||
visible: manager ? manager.quickSettingsOpen : false
|
||||
anchors.centerIn: parent
|
||||
|
||||
QtObject {
|
||||
id: quickSettingsKeyHandler
|
||||
function handle(event) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Component.onCompleted: ShellInputManager.registerHandler("quickSettings", handle)
|
||||
Component.onDestruction: ShellInputManager.unregisterHandler("quickSettings")
|
||||
}
|
||||
}
|
||||
53
hyprland.conf
Normal file
53
hyprland.conf
Normal file
@@ -0,0 +1,53 @@
|
||||
#
|
||||
|
||||
layerrule {
|
||||
name = deltarune qs mn
|
||||
match:namespace = deltarune-quickshell
|
||||
animation = slide top
|
||||
above_lock = 2
|
||||
order = -20
|
||||
no_screen_share = off
|
||||
}
|
||||
|
||||
layerrule {
|
||||
name = deltarune qs hb
|
||||
match:namespace = deltarune-quickshell-bottom
|
||||
animation = slide bottom
|
||||
above_lock = 2
|
||||
order = -20
|
||||
no_screen_share = off
|
||||
}
|
||||
|
||||
layerrule {
|
||||
name = deltarune qs db
|
||||
match:namespace = deltarune-quickshell-dialogbox
|
||||
animation = slide bottom
|
||||
order = 100
|
||||
above_lock = 2
|
||||
order = -20
|
||||
no_screen_share = off
|
||||
}
|
||||
|
||||
bind = SUPER, A, global, deltarune:shell_open
|
||||
|
||||
# here goes the dark magic that lets you open this in dletarune (and any other exclusive fullscreen app/game)
|
||||
|
||||
submap = deltarune
|
||||
|
||||
bind = SUPER, A, global, deltarune:shell_close
|
||||
|
||||
bind = , ESCAPE, global, deltarune:input_back
|
||||
bind = , Shift_L, global, deltarune:input_back
|
||||
bind = , Shift_R, global, deltarune:input_back
|
||||
bind = , X, global, deltarune:input_back
|
||||
|
||||
bind = , Z, global, deltarune:input_enter
|
||||
bind = , ENTER, global, deltarune:input_enter
|
||||
bind = , RETURN, global, deltarune:input_enter
|
||||
|
||||
bind = , UP, global, deltarune:input_up
|
||||
bind = , DOWN, global, deltarune:input_down
|
||||
bind = , LEFT, global, deltarune:input_left
|
||||
bind = , RIGHT, global, deltarune:input_right
|
||||
|
||||
submap = reset
|
||||
23
shell.qml
23
shell.qml
@@ -1,30 +1,21 @@
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Hyprland
|
||||
import QtQuick
|
||||
import "Shell"
|
||||
|
||||
ShellRoot {
|
||||
id: baseShell
|
||||
|
||||
// Use the singleton directly; it controls the shell state globally.
|
||||
property bool isOpen: ShellStateManager.shellOpen
|
||||
|
||||
WLRLayerTopbar {
|
||||
visible: baseShell.isOpen
|
||||
}
|
||||
WLRLayerHealthbar {
|
||||
visible: baseShell.isOpen
|
||||
}
|
||||
WLRLayerDialogBox {}
|
||||
Overlay {}
|
||||
|
||||
GlobalShortcut {
|
||||
appid: "deltarune"
|
||||
triggerDescription: "Toggle the menu"
|
||||
name: "shell_toggle"
|
||||
onReleased: {
|
||||
ShellStateManager.toggleShell();
|
||||
}
|
||||
}
|
||||
Topbar {}
|
||||
Healthbar {}
|
||||
DialogBox {}
|
||||
|
||||
InputShortcuts {}
|
||||
|
||||
IpcHandler {
|
||||
target: "deltarune.shell"
|
||||
|
||||
Reference in New Issue
Block a user