summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-09-24 23:48:47 +1000
committerGitHub <noreply@github.com>2025-09-24 23:48:47 +1000
commit57e3989185b8209a11d79bac477479019d515180 (patch)
tree27e94dcaef9f41bb8f294eab1a91a27ce4da03d0
parentplugin: sub namespace modules (diff)
downloadcaelestia-shell-57e3989185b8209a11d79bac477479019d515180.tar.gz
caelestia-shell-57e3989185b8209a11d79bac477479019d515180.tar.bz2
caelestia-shell-57e3989185b8209a11d79bac477479019d515180.zip
plugin: add hypr extras (#690)
* move machine * works * prevent duplicate refreshes * use instead of hyprctl proc
-rw-r--r--modules/areapicker/Picker.qml26
-rw-r--r--modules/bar/popouts/KbLayout.qml2
-rw-r--r--plugin/src/Caelestia/CMakeLists.txt3
-rw-r--r--plugin/src/Caelestia/Internal/CMakeLists.txt3
-rw-r--r--plugin/src/Caelestia/Internal/hyprdevices.cpp129
-rw-r--r--plugin/src/Caelestia/Internal/hyprdevices.hpp72
-rw-r--r--plugin/src/Caelestia/Internal/hyprextras.cpp158
-rw-r--r--plugin/src/Caelestia/Internal/hyprextras.hpp51
-rw-r--r--services/GameMode.qml15
-rw-r--r--services/Hypr.qml48
10 files changed, 445 insertions, 62 deletions
diff --git a/modules/areapicker/Picker.qml b/modules/areapicker/Picker.qml
index d51d1f3..1625ccf 100644
--- a/modules/areapicker/Picker.qml
+++ b/modules/areapicker/Picker.qml
@@ -5,7 +5,6 @@ import qs.services
import qs.config
import Caelestia
import Quickshell
-import Quickshell.Io
import Quickshell.Wayland
import QtQuick
import QtQuick.Effects
@@ -16,13 +15,10 @@ MouseArea {
required property LazyLoader loader
required property ShellScreen screen
- property int borderWidth
- property int rounding
-
property bool onClient
- property real realBorderWidth: onClient ? borderWidth : 2
- property real realRounding: onClient ? rounding : 0
+ property real realBorderWidth: onClient ? (Hypr.options["general:border_size"] ?? 1) : 2
+ property real realRounding: onClient ? (Hypr.options["decoration:rounding"] ?? 0) : 0
property real ssx
property real ssy
@@ -89,6 +85,8 @@ MouseArea {
cursorShape: Qt.CrossCursor
Component.onCompleted: {
+ Hypr.extras.refreshOptions();
+
// Break binding if frozen
if (loader.freeze)
clients = clients;
@@ -186,22 +184,6 @@ MouseArea {
}
}
- Process {
- running: true
- command: ["hyprctl", "-j", "getoption", "general:border_size"]
- stdout: StdioCollector {
- onStreamFinished: root.borderWidth = JSON.parse(text).int
- }
- }
-
- Process {
- running: true
- command: ["hyprctl", "-j", "getoption", "decoration:rounding"]
- stdout: StdioCollector {
- onStreamFinished: root.rounding = JSON.parse(text).int
- }
- }
-
Loader {
id: screencopy
diff --git a/modules/bar/popouts/KbLayout.qml b/modules/bar/popouts/KbLayout.qml
index b12f2ef..4ecea9e 100644
--- a/modules/bar/popouts/KbLayout.qml
+++ b/modules/bar/popouts/KbLayout.qml
@@ -23,6 +23,6 @@ ColumnLayout {
Layout.fillWidth: true
text: qsTr("Switch layout")
- onClicked: Quickshell.execDetached(["hyprctl", "switchxkblayout", "all", "next"])
+ onClicked: Hypr.message("switchxkblayout all next")
}
}
diff --git a/plugin/src/Caelestia/CMakeLists.txt b/plugin/src/Caelestia/CMakeLists.txt
index 9dea712..d344ef7 100644
--- a/plugin/src/Caelestia/CMakeLists.txt
+++ b/plugin/src/Caelestia/CMakeLists.txt
@@ -1,4 +1,4 @@
-find_package(Qt6 REQUIRED COMPONENTS Core Qml Gui Quick Concurrent Sql)
+find_package(Qt6 REQUIRED COMPONENTS Core Qml Gui Quick Concurrent Sql Network)
find_package(PkgConfig REQUIRED)
pkg_check_modules(Qalculate IMPORTED_TARGET libqalculate REQUIRED)
pkg_check_modules(Pipewire IMPORTED_TARGET libpipewire-0.3 REQUIRED)
@@ -49,6 +49,7 @@ qml_module(caelestia
LIBRARIES
Qt::Gui
Qt::Quick
+ Qt::Concurrent
Qt::Sql
PkgConfig::Qalculate
)
diff --git a/plugin/src/Caelestia/Internal/CMakeLists.txt b/plugin/src/Caelestia/Internal/CMakeLists.txt
index 62aa516..96538b8 100644
--- a/plugin/src/Caelestia/Internal/CMakeLists.txt
+++ b/plugin/src/Caelestia/Internal/CMakeLists.txt
@@ -3,8 +3,11 @@ qml_module(caelestia-internal
SOURCES
cachingimagemanager.hpp cachingimagemanager.cpp
circularindicatormanager.hpp circularindicatormanager.cpp
+ hyprdevices.hpp hyprdevices.cpp
+ hyprextras.hpp hyprextras.cpp
LIBRARIES
Qt::Gui
Qt::Quick
Qt::Concurrent
+ Qt::Network
)
diff --git a/plugin/src/Caelestia/Internal/hyprdevices.cpp b/plugin/src/Caelestia/Internal/hyprdevices.cpp
new file mode 100644
index 0000000..8f63d67
--- /dev/null
+++ b/plugin/src/Caelestia/Internal/hyprdevices.cpp
@@ -0,0 +1,129 @@
+#include "hyprdevices.hpp"
+
+#include <qjsonarray.h>
+
+namespace caelestia::internal::hypr {
+
+HyprKeyboard::HyprKeyboard(QJsonObject ipcObject, QObject* parent)
+ : QObject(parent)
+ , m_lastIpcObject(ipcObject) {}
+
+QVariantHash HyprKeyboard::lastIpcObject() const {
+ return m_lastIpcObject.toVariantHash();
+}
+
+QString HyprKeyboard::address() const {
+ return m_lastIpcObject.value("address").toString();
+}
+
+QString HyprKeyboard::name() const {
+ return m_lastIpcObject.value("name").toString();
+}
+
+QString HyprKeyboard::layout() const {
+ return m_lastIpcObject.value("layout").toString();
+}
+
+QString HyprKeyboard::activeKeymap() const {
+ return m_lastIpcObject.value("active_keymap").toString();
+}
+
+bool HyprKeyboard::capsLock() const {
+ return m_lastIpcObject.value("capsLock").toBool();
+}
+
+bool HyprKeyboard::numLock() const {
+ return m_lastIpcObject.value("numLock").toBool();
+}
+
+bool HyprKeyboard::main() const {
+ return m_lastIpcObject.value("main").toBool();
+}
+
+bool HyprKeyboard::updateLastIpcObject(const QJsonObject& object) {
+ if (m_lastIpcObject == object) {
+ return false;
+ }
+
+ const auto last = m_lastIpcObject;
+
+ m_lastIpcObject = object;
+ emit lastIpcObjectChanged();
+
+ bool dirty = false;
+ if (last.value("address") != object.value("address")) {
+ dirty = true;
+ emit addressChanged();
+ }
+ if (last.value("name") != object.value("name")) {
+ dirty = true;
+ emit nameChanged();
+ }
+ if (last.value("layout") != object.value("layout")) {
+ dirty = true;
+ emit layoutChanged();
+ }
+ if (last.value("active_keymap") != object.value("active_keymap")) {
+ dirty = true;
+ emit activeKeymapChanged();
+ }
+ if (last.value("capsLock") != object.value("capsLock")) {
+ dirty = true;
+ emit capsLockChanged();
+ }
+ if (last.value("numLock") != object.value("numLock")) {
+ dirty = true;
+ emit numLockChanged();
+ }
+ if (last.value("main") != object.value("main")) {
+ dirty = true;
+ emit mainChanged();
+ }
+ return dirty;
+}
+
+HyprDevices::HyprDevices(QObject* parent)
+ : QObject(parent) {}
+
+QList<HyprKeyboard*> HyprDevices::keyboards() const {
+ return m_keyboards;
+}
+
+bool HyprDevices::updateLastIpcObject(const QJsonObject& object) {
+ const auto val = object.value("keyboards").toArray();
+ bool dirty = false;
+
+ for (const auto& keyboard : std::as_const(m_keyboards)) {
+ if (std::find_if(val.begin(), val.end(), [keyboard](const QJsonValue& object) {
+ return object.toObject().value("address").toString() == keyboard->address();
+ }) == val.end()) {
+ dirty = true;
+ m_keyboards.removeAll(keyboard);
+ keyboard->deleteLater();
+ }
+ }
+
+ for (const auto& o : val) {
+ const auto obj = o.toObject();
+ const auto addr = obj.value("address").toString();
+
+ auto it = std::find_if(m_keyboards.begin(), m_keyboards.end(), [addr](const HyprKeyboard* keyboard) {
+ return keyboard->address() == addr;
+ });
+
+ if (it != m_keyboards.end()) {
+ dirty |= (*it)->updateLastIpcObject(obj);
+ } else {
+ dirty = true;
+ m_keyboards << new HyprKeyboard(obj, this);
+ }
+ }
+
+ if (dirty) {
+ emit keyboardsChanged();
+ }
+
+ return dirty;
+}
+
+} // namespace caelestia::internal::hypr
diff --git a/plugin/src/Caelestia/Internal/hyprdevices.hpp b/plugin/src/Caelestia/Internal/hyprdevices.hpp
new file mode 100644
index 0000000..ad762b9
--- /dev/null
+++ b/plugin/src/Caelestia/Internal/hyprdevices.hpp
@@ -0,0 +1,72 @@
+#pragma once
+
+#include <qjsonobject.h>
+#include <qobject.h>
+#include <qqmlintegration.h>
+
+namespace caelestia::internal::hypr {
+
+class HyprKeyboard : public QObject {
+ Q_OBJECT
+ QML_ELEMENT
+ QML_UNCREATABLE("HyprKeyboard instances can only be retrieved from a HyprDevices")
+
+ Q_PROPERTY(QVariantHash lastIpcObject READ lastIpcObject NOTIFY lastIpcObjectChanged)
+ Q_PROPERTY(QString address READ address NOTIFY addressChanged)
+ Q_PROPERTY(QString name READ name NOTIFY nameChanged)
+ Q_PROPERTY(QString layout READ layout NOTIFY layoutChanged)
+ Q_PROPERTY(QString activeKeymap READ activeKeymap NOTIFY activeKeymapChanged)
+ Q_PROPERTY(bool capsLock READ capsLock NOTIFY capsLockChanged)
+ Q_PROPERTY(bool numLock READ numLock NOTIFY numLockChanged)
+ Q_PROPERTY(bool main READ main NOTIFY mainChanged)
+
+public:
+ explicit HyprKeyboard(QJsonObject ipcObject, QObject* parent = nullptr);
+
+ [[nodiscard]] QVariantHash lastIpcObject() const;
+ [[nodiscard]] QString address() const;
+ [[nodiscard]] QString name() const;
+ [[nodiscard]] QString layout() const;
+ [[nodiscard]] QString activeKeymap() const;
+ [[nodiscard]] bool capsLock() const;
+ [[nodiscard]] bool numLock() const;
+ [[nodiscard]] bool main() const;
+
+ bool updateLastIpcObject(const QJsonObject& object);
+
+signals:
+ void lastIpcObjectChanged();
+ void addressChanged();
+ void nameChanged();
+ void layoutChanged();
+ void activeKeymapChanged();
+ void capsLockChanged();
+ void numLockChanged();
+ void mainChanged();
+
+private:
+ QJsonObject m_lastIpcObject;
+};
+
+class HyprDevices : public QObject {
+ Q_OBJECT
+ QML_ELEMENT
+ QML_UNCREATABLE("HyprDevices instances can only be retrieved from a HyprExtras")
+
+ Q_PROPERTY(QList<HyprKeyboard*> keyboards READ keyboards NOTIFY keyboardsChanged)
+
+public:
+ explicit HyprDevices(QObject* parent = nullptr);
+
+ [[nodiscard]] QList<HyprKeyboard*> keyboards() const;
+
+ bool updateLastIpcObject(const QJsonObject& object);
+
+signals:
+ void keyboardsChanged();
+
+private:
+ QList<HyprKeyboard*> m_keyboards;
+};
+
+} // namespace caelestia::internal::hypr
diff --git a/plugin/src/Caelestia/Internal/hyprextras.cpp b/plugin/src/Caelestia/Internal/hyprextras.cpp
new file mode 100644
index 0000000..23495b2
--- /dev/null
+++ b/plugin/src/Caelestia/Internal/hyprextras.cpp
@@ -0,0 +1,158 @@
+#include "hyprextras.hpp"
+
+#include <qdir.h>
+#include <qjsonarray.h>
+#include <qlocalsocket.h>
+#include <qvariant.h>
+
+namespace caelestia::internal::hypr {
+
+HyprExtras::HyprExtras(QObject* parent)
+ : QObject(parent)
+ , m_requestSocket("")
+ , m_eventSocket("")
+ , m_socket(nullptr)
+ , m_devices(new HyprDevices(this)) {
+ const auto his = qEnvironmentVariable("HYPRLAND_INSTANCE_SIGNATURE");
+ if (his.isEmpty()) {
+ qWarning()
+ << "HyprExtras::HyprExtras: $HYPRLAND_INSTANCE_SIGNATURE is unset. Unable to connect to Hyprland socket.";
+ return;
+ }
+
+ auto hyprDir = QString("%1/hypr/%2").arg(qEnvironmentVariable("XDG_RUNTIME_DIR"), his);
+ if (!QDir(hyprDir).exists()) {
+ hyprDir = "/tmp/hypr/" + his;
+
+ if (!QDir(hyprDir).exists()) {
+ qWarning() << "HyprExtras::HyprExtras: Hyprland socket directory does not exist. Unable to connect to "
+ "Hyprland socket.";
+ return;
+ }
+ }
+
+ m_requestSocket = hyprDir + "/.socket.sock";
+ m_eventSocket = hyprDir + "/.event.sock";
+
+ refreshOptions();
+ refreshDevices();
+
+ m_socket = new QLocalSocket(this);
+ QObject::connect(m_socket, &QLocalSocket::readyRead, this, &HyprExtras::readEvent);
+ m_socket->connectToServer(m_eventSocket);
+}
+
+QVariantHash HyprExtras::options() const {
+ return m_options;
+}
+
+HyprDevices* HyprExtras::devices() const {
+ return m_devices;
+}
+
+void HyprExtras::message(const QString& message) {
+ makeRequest(message, [](bool, const QByteArray&) {
+ });
+}
+
+void HyprExtras::refreshOptions() {
+ if (!m_optionsRefresh.isNull()) {
+ m_optionsRefresh->close();
+ }
+
+ m_optionsRefresh = makeRequestJson("descriptions", [this](bool success, const QJsonDocument& response) {
+ m_optionsRefresh.reset();
+ if (!success) {
+ return;
+ }
+
+ const auto options = response.array();
+ bool dirty = false;
+
+ for (const auto& o : std::as_const(options)) {
+ const auto obj = o.toObject();
+ const auto key = obj.value("value").toString();
+ const auto value = obj.value("data").toObject().value("current").toVariant();
+ if (m_options.value(key) != value) {
+ dirty = true;
+ m_options.insert(key, value);
+ }
+ }
+
+ if (dirty) {
+ emit optionsChanged();
+ }
+ });
+}
+
+void HyprExtras::refreshDevices() {
+ if (!m_devicesRefresh.isNull()) {
+ m_devicesRefresh->close();
+ }
+
+ m_devicesRefresh = makeRequestJson("devices", [this](bool success, const QJsonDocument& response) {
+ m_devicesRefresh.reset();
+ if (success) {
+ m_devices->updateLastIpcObject(response.object());
+ }
+ });
+}
+
+void HyprExtras::readEvent() {
+ while (true) {
+ auto rawEvent = m_socket->readLine();
+ if (rawEvent.isEmpty()) {
+ break;
+ }
+ rawEvent.truncate(rawEvent.length() - 1); // Remove trailing \n
+ const auto event = QByteArrayView(rawEvent.data(), rawEvent.indexOf(">>"));
+ handleEvent(QString::fromUtf8(event));
+ }
+}
+
+void HyprExtras::handleEvent(const QString& event) {
+ if (event == "configreloaded") {
+ refreshOptions();
+ } else if (event == "activelayout") {
+ refreshDevices();
+ }
+}
+
+HyprExtras::SocketPtr HyprExtras::makeRequestJson(
+ const QString& request, const std::function<void(bool, QJsonDocument)>& callback) {
+ return makeRequest("j/" + request, [callback](bool success, const QByteArray& response) {
+ callback(success, QJsonDocument::fromJson(response));
+ });
+}
+
+HyprExtras::SocketPtr HyprExtras::makeRequest(
+ const QString& request, const std::function<void(bool, QByteArray)>& callback) {
+ if (m_requestSocket.isEmpty()) {
+ return SocketPtr();
+ }
+
+ auto socket = SocketPtr::create(this);
+
+ QObject::connect(socket.data(), &QLocalSocket::connected, this, [=, this]() {
+ QObject::connect(socket.data(), &QLocalSocket::readyRead, this, [socket, callback]() {
+ const auto response = socket->readAll();
+ callback(true, std::move(response));
+ socket->close();
+ });
+
+ socket->write(request.toUtf8());
+ socket->flush();
+ });
+
+ QObject::connect(socket.data(), &QLocalSocket::errorOccurred, this, [=](QLocalSocket::LocalSocketError err) {
+ qWarning() << "HyprExtras::makeRequest: error making request:" << err << "| request:" << request;
+ callback(false, {});
+ socket->close();
+ });
+
+ socket->connectToServer(m_requestSocket);
+
+ return socket;
+}
+
+} // namespace caelestia::internal::hypr
diff --git a/plugin/src/Caelestia/Internal/hyprextras.hpp b/plugin/src/Caelestia/Internal/hyprextras.hpp
new file mode 100644
index 0000000..ca1b2f2
--- /dev/null
+++ b/plugin/src/Caelestia/Internal/hyprextras.hpp
@@ -0,0 +1,51 @@
+#pragma once
+
+#include "hyprdevices.hpp"
+#include <qlocalsocket.h>
+#include <qobject.h>
+#include <qqmlintegration.h>
+
+namespace caelestia::internal::hypr {
+
+class HyprExtras : public QObject {
+ Q_OBJECT
+ QML_ELEMENT
+
+ Q_PROPERTY(QVariantHash options READ options NOTIFY optionsChanged)
+ Q_PROPERTY(HyprDevices* devices READ devices CONSTANT)
+
+public:
+ explicit HyprExtras(QObject* parent = nullptr);
+
+ [[nodiscard]] QVariantHash options() const;
+ [[nodiscard]] HyprDevices* devices() const;
+
+ Q_INVOKABLE void message(const QString& message);
+
+ Q_INVOKABLE void refreshOptions();
+ Q_INVOKABLE void refreshDevices();
+
+signals:
+ void optionsChanged();
+
+private:
+ using SocketPtr = QSharedPointer<QLocalSocket>;
+
+ QString m_requestSocket;
+ QString m_eventSocket;
+ QLocalSocket* m_socket;
+
+ QVariantHash m_options;
+ HyprDevices* const m_devices;
+
+ SocketPtr m_optionsRefresh;
+ SocketPtr m_devicesRefresh;
+
+ void readEvent();
+ void handleEvent(const QString& event);
+
+ SocketPtr makeRequestJson(const QString& request, const std::function<void(bool, QJsonDocument)>& callback);
+ SocketPtr makeRequest(const QString& request, const std::function<void(bool, QByteArray)>& callback);
+};
+
+} // namespace caelestia::internal::hypr
diff --git a/services/GameMode.qml b/services/GameMode.qml
index 6771d59..edd741c 100644
--- a/services/GameMode.qml
+++ b/services/GameMode.qml
@@ -1,5 +1,6 @@
pragma Singleton
+import qs.services
import qs.config
import Caelestia
import Quickshell
@@ -12,7 +13,7 @@ Singleton {
property alias enabled: props.enabled
function setDynamicConfs(): void {
- Quickshell.execDetached(["hyprctl", "--batch", "keyword animations:enabled 0;keyword decoration:shadow:enabled 0;keyword decoration:blur:enabled 0;keyword general:gaps_in 0;keyword general:gaps_out 0;keyword general:border_size 1;keyword decoration:rounding 0;keyword general:allow_tearing 1"]);
+ Hypr.message("[[BATCH]]keyword animations:enabled 0;keyword decoration:shadow:enabled 0;keyword decoration:blur:enabled 0;keyword general:gaps_in 0;keyword general:gaps_out 0;keyword general:border_size 1;keyword decoration:rounding 0;keyword general:allow_tearing 1");
}
onEnabledChanged: {
@@ -21,7 +22,7 @@ Singleton {
if (Config.utilities.toasts.gameModeChanged)
Toaster.toast(qsTr("Game mode enabled"), qsTr("Disabled Hyprland animations, blur, gaps and shadows"), "gamepad");
} else {
- Quickshell.execDetached(["hyprctl", "reload"]);
+ Hypr.message("reload");
if (Config.utilities.toasts.gameModeChanged)
Toaster.toast(qsTr("Game mode disabled"), qsTr("Hyprland settings restored"), "gamepad");
}
@@ -30,7 +31,7 @@ Singleton {
PersistentProperties {
id: props
- property bool enabled
+ property bool enabled: Hypr.options["animations:enabled"] === 0
reloadableId: "gameMode"
}
@@ -44,14 +45,6 @@ Singleton {
}
}
- Process {
- running: true
- command: ["hyprctl", "getoption", "animations:enabled", "-j"]
- stdout: StdioCollector {
- onStreamFinished: props.enabled = JSON.parse(text).int === 0
- }
- }
-
IpcHandler {
target: "gameMode"
diff --git a/services/Hypr.qml b/services/Hypr.qml
index cd68d72..7a17212 100644
--- a/services/Hypr.qml
+++ b/services/Hypr.qml
@@ -3,6 +3,7 @@ pragma Singleton
import qs.components.misc
import qs.config
import Caelestia
+import Caelestia.Internal
import Quickshell
import Quickshell.Hyprland
import Quickshell.Io
@@ -20,16 +21,24 @@ Singleton {
readonly property HyprlandMonitor focusedMonitor: Hyprland.focusedMonitor
readonly property int activeWsId: focusedWorkspace?.id ?? 1
- property var keyboard
+ readonly property HyprKeyboard keyboard: extras.devices.keyboards.find(kb => kb.main) ?? null
readonly property bool capsLock: keyboard?.capsLock ?? false
readonly property bool numLock: keyboard?.numLock ?? false
readonly property string defaultKbLayout: keyboard?.layout.split(",")[0] ?? "??"
- readonly property string kbLayoutFull: keyboard?.active_keymap ?? "Unknown"
+ readonly property string kbLayoutFull: keyboard?.activeKeymap ?? "Unknown"
readonly property string kbLayout: kbMap.get(kbLayoutFull) ?? "??"
readonly property var kbMap: new Map()
+ readonly property alias extras: extras
+ readonly property alias options: extras.options
+ readonly property alias devices: extras.devices
+
signal configReloaded
+ function message(message: string): void {
+ extras.message(message);
+ }
+
function dispatch(request: string): void {
Hyprland.dispatch(request);
}
@@ -68,9 +77,7 @@ Singleton {
if (n === "configreloaded") {
root.configReloaded();
- setDynamicConfsProc.running = true;
- } else if (n === "activelayout") {
- devicesProc.running = true;
+ extras.message("[[BATCH]]keyword bindln ,Caps_Lock,global,caelestia:refreshDevices;keyword bindln ,Num_Lock,global,caelestia:refreshDevices");
} else if (["workspace", "moveworkspace", "activespecial", "focusedmon"].includes(n)) {
Hyprland.refreshWorkspaces();
Hyprland.refreshMonitors();
@@ -104,35 +111,22 @@ Singleton {
}
}
- Process {
- id: devicesProc
-
- running: true
- command: ["hyprctl", "-j", "devices"]
- stdout: StdioCollector {
- onStreamFinished: root.keyboard = JSON.parse(text).keyboards.find(k => k.main)
- }
- }
-
- Process {
- id: setDynamicConfsProc
-
- running: true
- command: ["hyprctl", "--batch", "keyword bindln ,Caps_Lock,global,caelestia:reloadDevices;keyword bindln ,Num_Lock,global,caelestia:reloadDevices"]
- }
-
IpcHandler {
target: "hypr"
- function reloadDevices(): void {
- devicesProc.running = true;
+ function refreshDevices(): void {
+ extras.refreshDevices();
}
}
CustomShortcut {
- name: "reloadDevices"
+ name: "refreshDevices"
description: "Reload devices"
- onPressed: devicesProc.running = true
- onReleased: devicesProc.running = true
+ onPressed: extras.refreshDevices()
+ onReleased: extras.refreshDevices()
+ }
+
+ HyprExtras {
+ id: extras
}
}