forked from quickshell/quickshell
hyprland/global_shortcuts: add GlobalShortcut
This commit is contained in:
parent
87a884ca36
commit
bba8cb8a7d
|
@ -15,6 +15,8 @@ option(WAYLAND "Enable wayland support" ON)
|
|||
option(WAYLAND_WLR_LAYERSHELL "Support the zwlr_layer_shell_v1 wayland protocol" ON)
|
||||
option(WAYLAND_SESSION_LOCK "Support the ext_session_lock_v1 wayland protocol" ON)
|
||||
option(HYPRLAND "Support hyprland specific features" ON)
|
||||
option(HYPRLAND_GLOBAL_SHORTCUTS "Hyprland Global Shortcuts" ON)
|
||||
option(HYPRLAND_FOCUS_GRAB "Hyprland Focus Grabbing" ON)
|
||||
option(SERVICE_STATUS_NOTIFIER "StatusNotifierItem service" ON)
|
||||
|
||||
message(STATUS "Quickshell configuration")
|
||||
|
@ -29,6 +31,10 @@ endif ()
|
|||
message(STATUS " Services")
|
||||
message(STATUS " StatusNotifier: ${SERVICE_STATUS_NOTIFIER}")
|
||||
message(STATUS " Hyprland: ${HYPRLAND}")
|
||||
if (HYPRLAND)
|
||||
message(STATUS " Focus Grabbing: ${HYPRLAND_FOCUS_GRAB}")
|
||||
message(STATUS " Global Shortcuts: ${HYPRLAND_GLOBAL_SHORTCUTS}")
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED GIT_REVISION)
|
||||
execute_process(
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
add_subdirectory(status_notifier)
|
||||
if (SERVICE_STATUS_NOTIFIER)
|
||||
add_subdirectory(status_notifier)
|
||||
endif()
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
qt_add_library(quickshell-hyprland STATIC)
|
||||
qt_add_qml_module(quickshell-hyprland URI Quickshell.Hyprland VERSION 0.1)
|
||||
|
||||
add_subdirectory(focus_grab)
|
||||
if (HYPRLAND_FOCUS_GRAB)
|
||||
add_subdirectory(focus_grab)
|
||||
endif()
|
||||
|
||||
if (HYPRLAND_GLOBAL_SHORTCUTS)
|
||||
add_subdirectory(global_shortcuts)
|
||||
endif()
|
||||
|
||||
target_link_libraries(quickshell-hyprland PRIVATE ${QT_DEPS})
|
||||
|
||||
|
|
|
@ -4,11 +4,18 @@ qt_add_library(quickshell-hyprland-focus-grab STATIC
|
|||
qml.cpp
|
||||
)
|
||||
|
||||
qt_add_qml_module(quickshell-hyprland-focus-grab URI Quickshell.Hyprland._FocusGrab VERSION 0.1)
|
||||
qt_add_qml_module(quickshell-hyprland-focus-grab
|
||||
URI Quickshell.Hyprland._FocusGrab
|
||||
VERSION 0.1
|
||||
)
|
||||
|
||||
add_library(quickshell-hyprland-focus-grab-init OBJECT init.cpp)
|
||||
|
||||
wl_proto(quickshell-hyprland-focus-grab hyprland-focus-grab-v1 "${CMAKE_CURRENT_SOURCE_DIR}/hyprland-focus-grab-v1.xml")
|
||||
wl_proto(quickshell-hyprland-focus-grab
|
||||
hyprland-focus-grab-v1
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/hyprland-focus-grab-v1.xml"
|
||||
)
|
||||
|
||||
target_link_libraries(quickshell-hyprland-focus-grab PRIVATE ${QT_DEPS} wayland-client)
|
||||
target_link_libraries(quickshell-hyprland-focus-grab-init PRIVATE ${QT_DEPS})
|
||||
|
||||
|
@ -16,4 +23,7 @@ qs_pch(quickshell-hyprland-focus-grab)
|
|||
qs_pch(quickshell-hyprland-focus-grabplugin)
|
||||
qs_pch(quickshell-hyprland-focus-grab-init)
|
||||
|
||||
target_link_libraries(quickshell PRIVATE quickshell-hyprland-focus-grabplugin quickshell-hyprland-focus-grab-init)
|
||||
target_link_libraries(quickshell PRIVATE
|
||||
quickshell-hyprland-focus-grabplugin
|
||||
quickshell-hyprland-focus-grab-init
|
||||
)
|
||||
|
|
29
src/wayland/hyprland/global_shortcuts/CMakeLists.txt
Normal file
29
src/wayland/hyprland/global_shortcuts/CMakeLists.txt
Normal file
|
@ -0,0 +1,29 @@
|
|||
qt_add_library(quickshell-hyprland-global-shortcuts STATIC
|
||||
qml.cpp
|
||||
manager.cpp
|
||||
shortcut.cpp
|
||||
)
|
||||
|
||||
qt_add_qml_module(quickshell-hyprland-global-shortcuts
|
||||
URI Quickshell.Hyprland._GlobalShortcuts
|
||||
VERSION 0.1
|
||||
)
|
||||
|
||||
add_library(quickshell-hyprland-global-shortcuts-init OBJECT init.cpp)
|
||||
|
||||
wl_proto(quickshell-hyprland-global-shortcuts
|
||||
hyprland-global-shortcuts-v1
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/hyprland-global-shortcuts-v1.xml"
|
||||
)
|
||||
|
||||
target_link_libraries(quickshell-hyprland-global-shortcuts PRIVATE ${QT_DEPS} wayland-client)
|
||||
target_link_libraries(quickshell-hyprland-global-shortcuts-init PRIVATE ${QT_DEPS})
|
||||
|
||||
qs_pch(quickshell-hyprland-global-shortcuts)
|
||||
qs_pch(quickshell-hyprland-global-shortcutsplugin)
|
||||
qs_pch(quickshell-hyprland-global-shortcuts-init)
|
||||
|
||||
target_link_libraries(quickshell PRIVATE
|
||||
quickshell-hyprland-global-shortcutsplugin
|
||||
quickshell-hyprland-global-shortcuts-init
|
||||
)
|
|
@ -0,0 +1,112 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="hyprland_global_shortcuts_v1">
|
||||
<copyright>
|
||||
Copyright © 2022 Vaxry
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
</copyright>
|
||||
|
||||
<description summary="registering global shortcuts">
|
||||
This protocol allows a client to register triggerable actions,
|
||||
meant to be global shortcuts.
|
||||
</description>
|
||||
|
||||
<interface name="hyprland_global_shortcuts_manager_v1" version="1">
|
||||
<description summary="manager to register global shortcuts">
|
||||
This object is a manager which offers requests to create global shortcuts.
|
||||
</description>
|
||||
|
||||
<request name="register_shortcut">
|
||||
<description summary="register a shortcut">
|
||||
Register a new global shortcut.
|
||||
|
||||
A global shortcut is anonymous, meaning the app does not know what key(s) trigger it.
|
||||
|
||||
The shortcut's keybinding shall be dealt with by the compositor.
|
||||
|
||||
In the case of a duplicate app_id + id combination, the already_taken protocol error is raised.
|
||||
</description>
|
||||
<arg name="shortcut" type="new_id" interface="hyprland_global_shortcut_v1"/>
|
||||
<arg name="id" type="string" summary="a unique id for the shortcut"/>
|
||||
<arg name="app_id" type="string" summary="the app_id of the application requesting the shortcut"/>
|
||||
<arg name="description" type="string" summary="user-readable text describing what the shortcut does."/>
|
||||
<arg name="trigger_description" type="string" summary="user-readable text describing how to trigger the shortcut for the client to render."/>
|
||||
</request>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the manager">
|
||||
All objects created by the manager will still remain valid, until their
|
||||
appropriate destroy request has been called.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="already_taken" value="0"
|
||||
summary="the app_id + id combination has already been registered."/>
|
||||
</enum>
|
||||
</interface>
|
||||
|
||||
<interface name="hyprland_global_shortcut_v1" version="1">
|
||||
<description summary="a shortcut">
|
||||
This object represents a single shortcut.
|
||||
</description>
|
||||
|
||||
<event name="pressed">
|
||||
<description summary="keystroke pressed">
|
||||
The keystroke was pressed.
|
||||
|
||||
tv_ values hold the timestamp of the occurrence.
|
||||
</description>
|
||||
<arg name="tv_sec_hi" type="uint"
|
||||
summary="high 32 bits of the seconds part of the timestamp"/>
|
||||
<arg name="tv_sec_lo" type="uint"
|
||||
summary="low 32 bits of the seconds part of the timestamp"/>
|
||||
<arg name="tv_nsec" type="uint"
|
||||
summary="nanoseconds part of the timestamp"/>
|
||||
</event>
|
||||
|
||||
<event name="released">
|
||||
<description summary="keystroke released">
|
||||
The keystroke was released.
|
||||
|
||||
tv_ values hold the timestamp of the occurrence.
|
||||
</description>
|
||||
<arg name="tv_sec_hi" type="uint"
|
||||
summary="high 32 bits of the seconds part of the timestamp"/>
|
||||
<arg name="tv_sec_lo" type="uint"
|
||||
summary="low 32 bits of the seconds part of the timestamp"/>
|
||||
<arg name="tv_nsec" type="uint"
|
||||
summary="nanoseconds part of the timestamp"/>
|
||||
</event>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="delete this object, used or not">
|
||||
Destroys the shortcut. Can be sent at any time by the client.
|
||||
</description>
|
||||
</request>
|
||||
</interface>
|
||||
</protocol>
|
20
src/wayland/hyprland/global_shortcuts/init.cpp
Normal file
20
src/wayland/hyprland/global_shortcuts/init.cpp
Normal file
|
@ -0,0 +1,20 @@
|
|||
#include <qqml.h>
|
||||
|
||||
#include "../../../core/plugin.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
class HyprlandFocusGrabPlugin: public QuickshellPlugin {
|
||||
void registerTypes() override {
|
||||
qmlRegisterModuleImport(
|
||||
"Quickshell.Hyprland",
|
||||
QQmlModuleImportModuleAny,
|
||||
"Quickshell.Hyprland._GlobalShortcuts",
|
||||
QQmlModuleImportLatest
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
QS_REGISTER_PLUGIN(HyprlandFocusGrabPlugin);
|
||||
|
||||
} // namespace
|
55
src/wayland/hyprland/global_shortcuts/manager.cpp
Normal file
55
src/wayland/hyprland/global_shortcuts/manager.cpp
Normal file
|
@ -0,0 +1,55 @@
|
|||
#include "manager.hpp"
|
||||
|
||||
#include <qstring.h>
|
||||
#include <qwaylandclientextension.h>
|
||||
|
||||
#include "shortcut.hpp"
|
||||
|
||||
namespace qs::hyprland::global_shortcuts::impl {
|
||||
|
||||
GlobalShortcutManager::GlobalShortcutManager()
|
||||
: QWaylandClientExtensionTemplate<GlobalShortcutManager>(1) {
|
||||
this->initialize();
|
||||
}
|
||||
|
||||
GlobalShortcut* GlobalShortcutManager::registerShortcut(
|
||||
const QString& appid,
|
||||
const QString& name,
|
||||
const QString& description,
|
||||
const QString& triggerDescription
|
||||
) {
|
||||
auto shortcut = this->shortcuts.value({appid, name});
|
||||
|
||||
if (shortcut.second != nullptr) {
|
||||
this->shortcuts.insert({appid, name}, {shortcut.first + 1, shortcut.second});
|
||||
return shortcut.second;
|
||||
} else {
|
||||
auto* shortcutObj = this->register_shortcut(name, appid, description, triggerDescription);
|
||||
auto* managedObj = new GlobalShortcut(shortcutObj);
|
||||
this->shortcuts.insert({appid, name}, {1, managedObj});
|
||||
return managedObj;
|
||||
}
|
||||
}
|
||||
|
||||
void GlobalShortcutManager::unregisterShortcut(const QString& appid, const QString& name) {
|
||||
auto shortcut = this->shortcuts.value({appid, name});
|
||||
|
||||
if (shortcut.first > 1) {
|
||||
this->shortcuts.insert({appid, name}, {shortcut.first - 1, shortcut.second});
|
||||
} else {
|
||||
delete shortcut.second;
|
||||
this->shortcuts.remove({appid, name});
|
||||
}
|
||||
}
|
||||
|
||||
GlobalShortcutManager* GlobalShortcutManager::instance() {
|
||||
static GlobalShortcutManager* instance = nullptr; // NOLINT
|
||||
|
||||
if (instance == nullptr) {
|
||||
instance = new GlobalShortcutManager();
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
} // namespace qs::hyprland::global_shortcuts::impl
|
34
src/wayland/hyprland/global_shortcuts/manager.hpp
Normal file
34
src/wayland/hyprland/global_shortcuts/manager.hpp
Normal file
|
@ -0,0 +1,34 @@
|
|||
#pragma once
|
||||
|
||||
#include <qcontainerfwd.h>
|
||||
#include <qhash.h>
|
||||
#include <qstring.h>
|
||||
#include <qwayland-hyprland-global-shortcuts-v1.h>
|
||||
#include <qwaylandclientextension.h>
|
||||
|
||||
#include "shortcut.hpp"
|
||||
|
||||
namespace qs::hyprland::global_shortcuts::impl {
|
||||
|
||||
class GlobalShortcutManager
|
||||
: public QWaylandClientExtensionTemplate<GlobalShortcutManager>
|
||||
, public QtWayland::hyprland_global_shortcuts_manager_v1 {
|
||||
public:
|
||||
explicit GlobalShortcutManager();
|
||||
|
||||
GlobalShortcut* registerShortcut(
|
||||
const QString& appid,
|
||||
const QString& name,
|
||||
const QString& description,
|
||||
const QString& triggerDescription
|
||||
);
|
||||
|
||||
void unregisterShortcut(const QString& appid, const QString& name);
|
||||
|
||||
static GlobalShortcutManager* instance();
|
||||
|
||||
private:
|
||||
QHash<QPair<QString, QString>, QPair<qint32, GlobalShortcut*>> shortcuts;
|
||||
};
|
||||
|
||||
} // namespace qs::hyprland::global_shortcuts::impl
|
115
src/wayland/hyprland/global_shortcuts/qml.cpp
Normal file
115
src/wayland/hyprland/global_shortcuts/qml.cpp
Normal file
|
@ -0,0 +1,115 @@
|
|||
#include "qml.hpp"
|
||||
#include <utility>
|
||||
|
||||
#include <qlogging.h>
|
||||
#include <qobject.h>
|
||||
#include <qtmetamacros.h>
|
||||
|
||||
#include "manager.hpp"
|
||||
#include "shortcut.hpp"
|
||||
|
||||
namespace qs::hyprland::global_shortcuts {
|
||||
using impl::GlobalShortcutManager;
|
||||
|
||||
GlobalShortcut::~GlobalShortcut() {
|
||||
auto* manager = GlobalShortcutManager::instance();
|
||||
if (manager != nullptr) {
|
||||
manager->unregisterShortcut(this->mAppid, this->mName);
|
||||
}
|
||||
}
|
||||
|
||||
void GlobalShortcut::onPostReload() {
|
||||
if (this->mName.isEmpty()) {
|
||||
qWarning() << "Unable to create GlobalShortcut with empty name.";
|
||||
return;
|
||||
}
|
||||
|
||||
auto* manager = GlobalShortcutManager::instance();
|
||||
if (manager == nullptr) {
|
||||
qWarning() << "The active compositor does not support hyprland_global_shortcuts_v1.";
|
||||
qWarning() << "GlobalShortcut will not work.";
|
||||
return;
|
||||
}
|
||||
|
||||
this->shortcut = manager->registerShortcut(
|
||||
this->mAppid,
|
||||
this->mName,
|
||||
this->mDescription,
|
||||
this->mTriggerDescription
|
||||
);
|
||||
|
||||
QObject::connect(this->shortcut, &ShortcutImpl::pressed, this, &GlobalShortcut::onPressed);
|
||||
QObject::connect(this->shortcut, &ShortcutImpl::released, this, &GlobalShortcut::onReleased);
|
||||
}
|
||||
|
||||
bool GlobalShortcut::isPressed() const { return this->mPressed; }
|
||||
|
||||
QString GlobalShortcut::appid() const { return this->mAppid; }
|
||||
|
||||
void GlobalShortcut::setAppid(QString appid) {
|
||||
if (this->shortcut != nullptr) {
|
||||
qWarning() << "GlobalShortcut cannot be modified after creation.";
|
||||
return;
|
||||
}
|
||||
|
||||
if (appid == this->mAppid) return;
|
||||
|
||||
this->mAppid = std::move(appid);
|
||||
emit this->appidChanged();
|
||||
}
|
||||
|
||||
QString GlobalShortcut::name() const { return this->mName; }
|
||||
|
||||
void GlobalShortcut::setName(QString name) {
|
||||
if (this->shortcut != nullptr) {
|
||||
qWarning() << "GlobalShortcut cannot be modified after creation.";
|
||||
return;
|
||||
}
|
||||
|
||||
if (name == this->mName) return;
|
||||
|
||||
this->mName = std::move(name);
|
||||
emit this->nameChanged();
|
||||
}
|
||||
|
||||
QString GlobalShortcut::description() const { return this->mDescription; }
|
||||
|
||||
void GlobalShortcut::setDescription(QString description) {
|
||||
if (this->shortcut != nullptr) {
|
||||
qWarning() << "GlobalShortcut cannot be modified after creation.";
|
||||
return;
|
||||
}
|
||||
|
||||
if (description == this->mDescription) return;
|
||||
|
||||
this->mDescription = std::move(description);
|
||||
emit this->descriptionChanged();
|
||||
}
|
||||
|
||||
QString GlobalShortcut::triggerDescription() const { return this->mTriggerDescription; }
|
||||
|
||||
void GlobalShortcut::setTriggerDescription(QString triggerDescription) {
|
||||
if (this->shortcut != nullptr) {
|
||||
qWarning() << "GlobalShortcut cannot be modified after creation.";
|
||||
return;
|
||||
}
|
||||
|
||||
if (triggerDescription == this->mTriggerDescription) return;
|
||||
|
||||
this->mTriggerDescription = std::move(triggerDescription);
|
||||
emit this->triggerDescriptionChanged();
|
||||
}
|
||||
|
||||
void GlobalShortcut::onPressed() {
|
||||
this->mPressed = true;
|
||||
emit this->pressed();
|
||||
emit this->pressedChanged();
|
||||
}
|
||||
|
||||
void GlobalShortcut::onReleased() {
|
||||
this->mPressed = false;
|
||||
emit this->released();
|
||||
emit this->pressedChanged();
|
||||
}
|
||||
|
||||
} // namespace qs::hyprland::global_shortcuts
|
108
src/wayland/hyprland/global_shortcuts/qml.hpp
Normal file
108
src/wayland/hyprland/global_shortcuts/qml.hpp
Normal file
|
@ -0,0 +1,108 @@
|
|||
#pragma once
|
||||
|
||||
#include <qobject.h>
|
||||
#include <qqmlintegration.h>
|
||||
#include <qtclasshelpermacros.h>
|
||||
#include <qtmetamacros.h>
|
||||
|
||||
#include "../../../core/reload.hpp"
|
||||
#include "shortcut.hpp"
|
||||
|
||||
namespace qs::hyprland::global_shortcuts {
|
||||
|
||||
///! Hyprland global shortcut.
|
||||
/// Global shortcut implemented with [hyprland_global_shortcuts_v1].
|
||||
///
|
||||
/// You can use this within hyprland as a global shortcut:
|
||||
/// ```
|
||||
/// bind = <modifiers>, <key>, global, <appid>:<name>
|
||||
/// ```
|
||||
/// See [the wiki] for details.
|
||||
///
|
||||
/// > [!WARNING] The shortcuts protocol does not allow duplicate appid + name pairs.
|
||||
/// > Within a single instance of quickshell this is handled internally, and both
|
||||
/// > users will be notified, but multiple instances of quickshell or XDPH may collide.
|
||||
/// >
|
||||
/// > If that happens, whichever client that tries to register the shortcuts last will crash.
|
||||
///
|
||||
/// > [!INFO] This type does *not* use the xdg-desktop-portal global shortcuts protocol,
|
||||
/// > as it is not fully functional without flatpak and would cause a considerably worse
|
||||
/// > user experience from other limitations. It will only work with Hyprland.
|
||||
/// > Note that, as this type bypasses xdg-desktop-portal, XDPH is not required.
|
||||
///
|
||||
/// [hyprland_global_shortcuts_v1]: https://github.com/hyprwm/hyprland-protocols/blob/main/protocols/hyprland-global-shortcuts-v1.xml
|
||||
/// [the wiki]: https://wiki.hyprland.org/Configuring/Binds/#dbus-global-shortcuts
|
||||
class GlobalShortcut
|
||||
: public QObject
|
||||
, public PostReloadHook {
|
||||
using ShortcutImpl = impl::GlobalShortcut;
|
||||
|
||||
Q_OBJECT;
|
||||
// clang-format off
|
||||
/// If the keybind is currently pressed.
|
||||
Q_PROPERTY(bool pressed READ isPressed NOTIFY pressedChanged);
|
||||
/// The appid of the shortcut. Defaults to `quickshell`.
|
||||
/// You cannot change this at runtime.
|
||||
///
|
||||
/// If you have more than one shortcut we recommend subclassing
|
||||
/// GlobalShortcut to set this.
|
||||
Q_PROPERTY(QString appid READ appid WRITE setAppid NOTIFY appidChanged);
|
||||
/// The name of the shortcut.
|
||||
/// You cannot change this at runtime.
|
||||
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged);
|
||||
/// The description of the shortcut that appears in `hyprctl globalshortcuts`.
|
||||
/// You cannot change this at runtime.
|
||||
Q_PROPERTY(QString description READ description WRITE setDescription NOTIFY descriptionChanged);
|
||||
/// Have not seen this used ever, but included for completeness. Safe to ignore.
|
||||
Q_PROPERTY(QString triggerDescription READ triggerDescription WRITE setTriggerDescription NOTIFY triggerDescriptionChanged);
|
||||
// clang-format on
|
||||
QML_ELEMENT;
|
||||
|
||||
public:
|
||||
explicit GlobalShortcut(QObject* parent = nullptr): QObject(parent) {}
|
||||
~GlobalShortcut() override;
|
||||
Q_DISABLE_COPY_MOVE(GlobalShortcut);
|
||||
|
||||
void onPostReload() override;
|
||||
|
||||
[[nodiscard]] bool isPressed() const;
|
||||
|
||||
[[nodiscard]] QString appid() const;
|
||||
void setAppid(QString appid);
|
||||
|
||||
[[nodiscard]] QString name() const;
|
||||
void setName(QString name);
|
||||
|
||||
[[nodiscard]] QString description() const;
|
||||
void setDescription(QString description);
|
||||
|
||||
[[nodiscard]] QString triggerDescription() const;
|
||||
void setTriggerDescription(QString triggerDescription);
|
||||
|
||||
signals:
|
||||
/// Fired when the keybind is pressed.
|
||||
void pressed();
|
||||
/// Fired when the keybind is released.
|
||||
void released();
|
||||
|
||||
void pressedChanged();
|
||||
void appidChanged();
|
||||
void nameChanged();
|
||||
void descriptionChanged();
|
||||
void triggerDescriptionChanged();
|
||||
|
||||
private slots:
|
||||
void onPressed();
|
||||
void onReleased();
|
||||
|
||||
private:
|
||||
impl::GlobalShortcut* shortcut = nullptr;
|
||||
|
||||
bool mPressed = false;
|
||||
QString mAppid = "quickshell";
|
||||
QString mName;
|
||||
QString mDescription;
|
||||
QString mTriggerDescription;
|
||||
};
|
||||
|
||||
} // namespace qs::hyprland::global_shortcuts
|
33
src/wayland/hyprland/global_shortcuts/shortcut.cpp
Normal file
33
src/wayland/hyprland/global_shortcuts/shortcut.cpp
Normal file
|
@ -0,0 +1,33 @@
|
|||
#include "shortcut.hpp"
|
||||
|
||||
#include <qtmetamacros.h>
|
||||
#include <qtypes.h>
|
||||
#include <wayland-hyprland-global-shortcuts-v1-client-protocol.h>
|
||||
|
||||
namespace qs::hyprland::global_shortcuts::impl {
|
||||
|
||||
GlobalShortcut::GlobalShortcut(::hyprland_global_shortcut_v1* shortcut) { this->init(shortcut); }
|
||||
|
||||
GlobalShortcut::~GlobalShortcut() {
|
||||
if (this->isInitialized()) {
|
||||
this->destroy();
|
||||
}
|
||||
}
|
||||
|
||||
void GlobalShortcut::hyprland_global_shortcut_v1_pressed(
|
||||
quint32 /*unused*/,
|
||||
quint32 /*unused*/,
|
||||
quint32 /*unused*/
|
||||
) {
|
||||
emit this->pressed();
|
||||
}
|
||||
|
||||
void GlobalShortcut::hyprland_global_shortcut_v1_released(
|
||||
quint32 /*unused*/,
|
||||
quint32 /*unused*/,
|
||||
quint32 /*unused*/
|
||||
) {
|
||||
emit this->released();
|
||||
}
|
||||
|
||||
} // namespace qs::hyprland::global_shortcuts::impl
|
32
src/wayland/hyprland/global_shortcuts/shortcut.hpp
Normal file
32
src/wayland/hyprland/global_shortcuts/shortcut.hpp
Normal file
|
@ -0,0 +1,32 @@
|
|||
#pragma once
|
||||
|
||||
#include <qobject.h>
|
||||
#include <qtclasshelpermacros.h>
|
||||
#include <qtmetamacros.h>
|
||||
#include <qtypes.h>
|
||||
#include <qwayland-hyprland-global-shortcuts-v1.h>
|
||||
|
||||
namespace qs::hyprland::global_shortcuts::impl {
|
||||
|
||||
class GlobalShortcut
|
||||
: public QObject
|
||||
, public QtWayland::hyprland_global_shortcut_v1 {
|
||||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
explicit GlobalShortcut(::hyprland_global_shortcut_v1* shortcut);
|
||||
~GlobalShortcut() override;
|
||||
Q_DISABLE_COPY_MOVE(GlobalShortcut);
|
||||
|
||||
signals:
|
||||
void pressed();
|
||||
void released();
|
||||
|
||||
private:
|
||||
// clang-format off
|
||||
void hyprland_global_shortcut_v1_pressed(quint32 tvSecHi, quint32 tvSecLo, quint32 tvNsec) override;
|
||||
void hyprland_global_shortcut_v1_released(quint32 tvSecHi, quint32 tvSecLo, quint32 tvNsec) override;
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
} // namespace qs::hyprland::global_shortcuts::impl
|
|
@ -1,6 +1,7 @@
|
|||
name = "Quickshell.Hyprland"
|
||||
description = "Hyprland specific Quickshell types"
|
||||
headers = [
|
||||
"focus_grab/qml.hpp"
|
||||
"focus_grab/qml.hpp",
|
||||
"global_shortcuts/qml.hpp",
|
||||
]
|
||||
-----
|
||||
|
|
Loading…
Reference in a new issue