shortcuts-inhibitor: move to new impl

This commit is contained in:
Vaxry 2024-04-25 14:32:35 +01:00
parent ecf282d331
commit 01df3b73d8
12 changed files with 172 additions and 77 deletions

View file

@ -273,6 +273,7 @@ protocolNew("unstable/xdg-decoration/xdg-decoration-unstable-v1.xml" "xdg-decora
protocolNew("staging/alpha-modifier/alpha-modifier-v1.xml" "alpha-modifier-v1" false) protocolNew("staging/alpha-modifier/alpha-modifier-v1.xml" "alpha-modifier-v1" false)
protocolNew("staging/ext-foreign-toplevel-list/ext-foreign-toplevel-list-v1.xml" "ext-foreign-toplevel-list-v1" false) protocolNew("staging/ext-foreign-toplevel-list/ext-foreign-toplevel-list-v1.xml" "ext-foreign-toplevel-list-v1" false)
protocolNew("unstable/pointer-gestures/pointer-gestures-unstable-v1.xml" "pointer-gestures-unstable-v1" false) protocolNew("unstable/pointer-gestures/pointer-gestures-unstable-v1.xml" "pointer-gestures-unstable-v1" false)
protocolNew("unstable/keyboard-shortcuts-inhibit/keyboard-shortcuts-inhibit-unstable-v1.xml" "keyboard-shortcuts-inhibit-unstable-v1" false)
# tools # tools
add_subdirectory(hyprctl) add_subdirectory(hyprctl)

View file

@ -50,6 +50,7 @@ new_protocols = [
[wl_protocol_dir, 'staging/alpha-modifier/alpha-modifier-v1.xml'], [wl_protocol_dir, 'staging/alpha-modifier/alpha-modifier-v1.xml'],
[wl_protocol_dir, 'staging/ext-foreign-toplevel-list/ext-foreign-toplevel-list-v1.xml'], [wl_protocol_dir, 'staging/ext-foreign-toplevel-list/ext-foreign-toplevel-list-v1.xml'],
[wl_protocol_dir, 'unstable/pointer-gestures/pointer-gestures-unstable-v1.xml'], [wl_protocol_dir, 'unstable/pointer-gestures/pointer-gestures-unstable-v1.xml'],
[wl_protocol_dir, 'unstable/keyboard-shortcuts-inhibit/keyboard-shortcuts-inhibit-unstable-v1.xml'],
] ]
wl_protos_src = [] wl_protos_src = []

View file

@ -211,8 +211,6 @@ void CCompositor::initServer() {
m_sWLROutputMgr = wlr_output_manager_v1_create(m_sWLDisplay); m_sWLROutputMgr = wlr_output_manager_v1_create(m_sWLDisplay);
m_sWLRKbShInhibitMgr = wlr_keyboard_shortcuts_inhibit_v1_create(m_sWLDisplay);
m_sWLRPointerConstraints = wlr_pointer_constraints_v1_create(m_sWLDisplay); m_sWLRPointerConstraints = wlr_pointer_constraints_v1_create(m_sWLDisplay);
m_sWLRVKeyboardMgr = wlr_virtual_keyboard_manager_v1_create(m_sWLDisplay); m_sWLRVKeyboardMgr = wlr_virtual_keyboard_manager_v1_create(m_sWLDisplay);
@ -294,7 +292,6 @@ void CCompositor::initAllSignals() {
addWLSignal(&m_sWLRTextInputMgr->events.text_input, &Events::listen_newTextInput, m_sWLRTextInputMgr, "TextInputMgr"); addWLSignal(&m_sWLRTextInputMgr->events.text_input, &Events::listen_newTextInput, m_sWLRTextInputMgr, "TextInputMgr");
addWLSignal(&m_sWLRActivation->events.request_activate, &Events::listen_activateXDG, m_sWLRActivation, "ActivationV1"); addWLSignal(&m_sWLRActivation->events.request_activate, &Events::listen_activateXDG, m_sWLRActivation, "ActivationV1");
addWLSignal(&m_sWLRSessionLockMgr->events.new_lock, &Events::listen_newSessionLock, m_sWLRSessionLockMgr, "SessionLockMgr"); addWLSignal(&m_sWLRSessionLockMgr->events.new_lock, &Events::listen_newSessionLock, m_sWLRSessionLockMgr, "SessionLockMgr");
addWLSignal(&m_sWLRKbShInhibitMgr->events.new_inhibitor, &Events::listen_newShortcutInhibitor, m_sWLRKbShInhibitMgr, "ShortcutInhibitMgr");
if (m_sWRLDRMLeaseMgr) if (m_sWRLDRMLeaseMgr)
addWLSignal(&m_sWRLDRMLeaseMgr->events.request, &Events::listen_leaseRequest, &m_sWRLDRMLeaseMgr, "DRM"); addWLSignal(&m_sWRLDRMLeaseMgr->events.request, &Events::listen_leaseRequest, &m_sWRLDRMLeaseMgr, "DRM");
@ -343,7 +340,6 @@ void CCompositor::removeAllSignals() {
removeWLSignal(&Events::listen_newTextInput); removeWLSignal(&Events::listen_newTextInput);
removeWLSignal(&Events::listen_activateXDG); removeWLSignal(&Events::listen_activateXDG);
removeWLSignal(&Events::listen_newSessionLock); removeWLSignal(&Events::listen_newSessionLock);
removeWLSignal(&Events::listen_newShortcutInhibitor);
if (m_sWRLDRMLeaseMgr) if (m_sWRLDRMLeaseMgr)
removeWLSignal(&Events::listen_leaseRequest); removeWLSignal(&Events::listen_leaseRequest);

View file

@ -40,41 +40,40 @@ class CCompositor {
~CCompositor(); ~CCompositor();
// ------------------ WLR BASICS ------------------ // // ------------------ WLR BASICS ------------------ //
wl_display* m_sWLDisplay; wl_display* m_sWLDisplay;
wl_event_loop* m_sWLEventLoop; wl_event_loop* m_sWLEventLoop;
wlr_backend* m_sWLRBackend; wlr_backend* m_sWLRBackend;
wlr_session* m_sWLRSession; wlr_session* m_sWLRSession;
wlr_renderer* m_sWLRRenderer; wlr_renderer* m_sWLRRenderer;
wlr_allocator* m_sWLRAllocator; wlr_allocator* m_sWLRAllocator;
wlr_compositor* m_sWLRCompositor; wlr_compositor* m_sWLRCompositor;
wlr_subcompositor* m_sWLRSubCompositor; wlr_subcompositor* m_sWLRSubCompositor;
wlr_data_device_manager* m_sWLRDataDevMgr; wlr_data_device_manager* m_sWLRDataDevMgr;
wlr_drm* m_sWRLDRM; wlr_drm* m_sWRLDRM;
wlr_drm_lease_v1_manager* m_sWRLDRMLeaseMgr; wlr_drm_lease_v1_manager* m_sWRLDRMLeaseMgr;
wlr_xdg_activation_v1* m_sWLRXDGActivation; wlr_xdg_activation_v1* m_sWLRXDGActivation;
wlr_output_layout* m_sWLROutputLayout; wlr_output_layout* m_sWLROutputLayout;
wlr_idle_notifier_v1* m_sWLRIdleNotifier; wlr_idle_notifier_v1* m_sWLRIdleNotifier;
wlr_layer_shell_v1* m_sWLRLayerShell; wlr_layer_shell_v1* m_sWLRLayerShell;
wlr_xdg_shell* m_sWLRXDGShell; wlr_xdg_shell* m_sWLRXDGShell;
wlr_cursor* m_sWLRCursor; wlr_cursor* m_sWLRCursor;
wlr_virtual_keyboard_manager_v1* m_sWLRVKeyboardMgr; wlr_virtual_keyboard_manager_v1* m_sWLRVKeyboardMgr;
wlr_output_manager_v1* m_sWLROutputMgr; wlr_output_manager_v1* m_sWLROutputMgr;
wlr_presentation* m_sWLRPresentation; wlr_presentation* m_sWLRPresentation;
wlr_keyboard_shortcuts_inhibit_manager_v1* m_sWLRKbShInhibitMgr; wlr_egl* m_sWLREGL;
wlr_egl* m_sWLREGL; int m_iDRMFD;
int m_iDRMFD; wlr_pointer_constraints_v1* m_sWLRPointerConstraints;
wlr_pointer_constraints_v1* m_sWLRPointerConstraints; wlr_server_decoration_manager* m_sWLRServerDecoMgr;
wlr_server_decoration_manager* m_sWLRServerDecoMgr; wlr_virtual_pointer_manager_v1* m_sWLRVirtPtrMgr;
wlr_virtual_pointer_manager_v1* m_sWLRVirtPtrMgr; wlr_tablet_manager_v2* m_sWLRTabletManager;
wlr_tablet_manager_v2* m_sWLRTabletManager; wlr_xdg_foreign_registry* m_sWLRForeignRegistry;
wlr_xdg_foreign_registry* m_sWLRForeignRegistry; wlr_output_power_manager_v1* m_sWLROutputPowerMgr;
wlr_output_power_manager_v1* m_sWLROutputPowerMgr; wlr_input_method_manager_v2* m_sWLRIMEMgr;
wlr_input_method_manager_v2* m_sWLRIMEMgr; wlr_text_input_manager_v3* m_sWLRTextInputMgr;
wlr_text_input_manager_v3* m_sWLRTextInputMgr; wlr_xdg_activation_v1* m_sWLRActivation;
wlr_xdg_activation_v1* m_sWLRActivation; wlr_linux_dmabuf_v1* m_sWLRLinuxDMABuf;
wlr_linux_dmabuf_v1* m_sWLRLinuxDMABuf; wlr_backend* m_sWLRHeadlessBackend;
wlr_backend* m_sWLRHeadlessBackend; wlr_session_lock_manager_v1* m_sWLRSessionLockMgr;
wlr_session_lock_manager_v1* m_sWLRSessionLockMgr;
// ------------------------------------------------- // // ------------------------------------------------- //
std::string m_szWLDisplaySocket = ""; std::string m_szWLDisplaySocket = "";

View file

@ -132,7 +132,4 @@ namespace Events {
// Session Lock // Session Lock
LISTENER(newSessionLock); LISTENER(newSessionLock);
// Shortcut inhibitor
LISTENER(newShortcutInhibitor);
}; };

View file

@ -221,20 +221,3 @@ void Events::listener_newSessionLock(wl_listener* listener, void* data) {
g_pSessionLockManager->onNewSessionLock((wlr_session_lock_v1*)data); g_pSessionLockManager->onNewSessionLock((wlr_session_lock_v1*)data);
} }
void Events::listener_newShortcutInhibitor(wl_listener* listener, void* data) {
const auto INHIBITOR = (wlr_keyboard_shortcuts_inhibitor_v1*)data;
const auto PINH = &g_pKeybindManager->m_lShortcutInhibitors.emplace_back();
PINH->hyprListener_destroy.initCallback(
&INHIBITOR->events.destroy,
[](void* owner, void* data) {
const auto OWNER = (SShortcutInhibitor*)owner;
g_pKeybindManager->m_lShortcutInhibitors.remove(*OWNER);
},
PINH, "ShortcutInhibitor");
PINH->pWlrInhibitor = INHIBITOR;
Debug::log(LOG, "New shortcut inhibitor for surface {:x}", (uintptr_t)INHIBITOR->surface);
}

View file

@ -316,13 +316,3 @@ struct SSwitchDevice {
return pWlrDevice == other.pWlrDevice; return pWlrDevice == other.pWlrDevice;
} }
}; };
struct SShortcutInhibitor {
wlr_keyboard_shortcuts_inhibitor_v1* pWlrInhibitor = nullptr;
DYNLISTENER(destroy);
bool operator==(const SShortcutInhibitor& other) const {
return pWlrInhibitor == other.pWlrInhibitor;
}
};

View file

@ -4,6 +4,7 @@
#include "helpers/VarList.hpp" #include "helpers/VarList.hpp"
#include "../config/ConfigValue.hpp" #include "../config/ConfigValue.hpp"
#include "TokenManager.hpp" #include "TokenManager.hpp"
#include "../protocols/ShortcutsInhibit.hpp"
#include <regex> #include <regex>
#include <tuple> #include <tuple>
@ -539,13 +540,9 @@ bool CKeybindManager::handleKeybinds(const uint32_t modmask, const SPressedKeyWi
static auto PDISABLEINHIBIT = CConfigValue<Hyprlang::INT>("binds:disable_keybind_grabbing"); static auto PDISABLEINHIBIT = CConfigValue<Hyprlang::INT>("binds:disable_keybind_grabbing");
if (!*PDISABLEINHIBIT && !m_lShortcutInhibitors.empty()) { if (!*PDISABLEINHIBIT && PROTO::shortcutsInhibit->isInhibited()) {
for (auto& i : m_lShortcutInhibitors) { Debug::log(LOG, "Keybind handling is disabled due to an inhibitor");
if (i.pWlrInhibitor->surface == g_pCompositor->m_pLastFocus) { return false;
Debug::log(LOG, "Keybind handling is disabled due to an inhibitor for surface {:x}", (uintptr_t)i.pWlrInhibitor->surface);
return false;
}
}
} }
for (auto& k : m_lKeybinds) { for (auto& k : m_lKeybinds) {

View file

@ -81,7 +81,6 @@ class CKeybindManager {
bool m_bGroupsLocked = false; bool m_bGroupsLocked = false;
std::list<SKeybind> m_lKeybinds; std::list<SKeybind> m_lKeybinds;
std::list<SShortcutInhibitor> m_lShortcutInhibitors;
private: private:
std::deque<SPressedKeyWithMods> m_dPressedKeys; std::deque<SPressedKeyWithMods> m_dPressedKeys;

View file

@ -12,6 +12,7 @@
#include "../protocols/ForeignToplevel.hpp" #include "../protocols/ForeignToplevel.hpp"
#include "../protocols/PointerGestures.hpp" #include "../protocols/PointerGestures.hpp"
#include "../protocols/ForeignToplevelWlr.hpp" #include "../protocols/ForeignToplevelWlr.hpp"
#include "../protocols/ShortcutsInhibit.hpp"
#include "tearing-control-v1.hpp" #include "tearing-control-v1.hpp"
#include "fractional-scale-v1.hpp" #include "fractional-scale-v1.hpp"
@ -25,6 +26,7 @@
#include "ext-foreign-toplevel-list-v1.hpp" #include "ext-foreign-toplevel-list-v1.hpp"
#include "pointer-gestures-unstable-v1.hpp" #include "pointer-gestures-unstable-v1.hpp"
#include "wlr-foreign-toplevel-management-unstable-v1.hpp" #include "wlr-foreign-toplevel-management-unstable-v1.hpp"
#include "keyboard-shortcuts-inhibit-unstable-v1.hpp"
CProtocolManager::CProtocolManager() { CProtocolManager::CProtocolManager() {
@ -40,6 +42,7 @@ CProtocolManager::CProtocolManager() {
PROTO::foreignToplevel = std::make_unique<CForeignToplevelProtocol>(&ext_foreign_toplevel_list_v1_interface, 1, "ForeignToplevel"); PROTO::foreignToplevel = std::make_unique<CForeignToplevelProtocol>(&ext_foreign_toplevel_list_v1_interface, 1, "ForeignToplevel");
PROTO::pointerGestures = std::make_unique<CPointerGesturesProtocol>(&zwp_pointer_gestures_v1_interface, 3, "PointerGestures"); PROTO::pointerGestures = std::make_unique<CPointerGesturesProtocol>(&zwp_pointer_gestures_v1_interface, 3, "PointerGestures");
PROTO::foreignToplevelWlr = std::make_unique<CForeignToplevelWlrProtocol>(&zwlr_foreign_toplevel_manager_v1_interface, 3, "ForeignToplevelWlr"); PROTO::foreignToplevelWlr = std::make_unique<CForeignToplevelWlrProtocol>(&zwlr_foreign_toplevel_manager_v1_interface, 3, "ForeignToplevelWlr");
PROTO::shortcutsInhibit = std::make_unique<CKeyboardShortcutsInhibitProtocol>(&zwp_keyboard_shortcuts_inhibit_manager_v1_interface, 1, "ShortcutsInhibit");
// Old protocol implementations. // Old protocol implementations.
// TODO: rewrite them to use hyprwayland-scanner. // TODO: rewrite them to use hyprwayland-scanner.

View file

@ -0,0 +1,85 @@
#include "ShortcutsInhibit.hpp"
#include <algorithm>
#include "../Compositor.hpp"
#define LOGM PROTO::shortcutsInhibit->protoLog
CKeyboardShortcutsInhibitor::CKeyboardShortcutsInhibitor(SP<CZwpKeyboardShortcutsInhibitorV1> resource_, wlr_surface* surf) : resource(resource_), pSurface(surf) {
if (!resource->resource())
return;
resource->setDestroy([this](CZwpKeyboardShortcutsInhibitorV1* pMgr) { PROTO::shortcutsInhibit->destroyInhibitor(this); });
resource->setOnDestroy([this](CZwpKeyboardShortcutsInhibitorV1* pMgr) { PROTO::shortcutsInhibit->destroyInhibitor(this); });
// I don't really care about following the spec here that much,
// let's make the app believe it's always active
resource->sendActive();
}
wlr_surface* CKeyboardShortcutsInhibitor::surface() {
return pSurface;
}
bool CKeyboardShortcutsInhibitor::good() {
return resource->resource();
}
CKeyboardShortcutsInhibitProtocol::CKeyboardShortcutsInhibitProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
;
}
void CKeyboardShortcutsInhibitProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
const auto RESOURCE = m_vManagers.emplace_back(std::make_unique<CZwpKeyboardShortcutsInhibitManagerV1>(client, ver, id)).get();
RESOURCE->setOnDestroy([this](CZwpKeyboardShortcutsInhibitManagerV1* p) { this->onManagerResourceDestroy(p->resource()); });
RESOURCE->setDestroy([this](CZwpKeyboardShortcutsInhibitManagerV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); });
RESOURCE->setInhibitShortcuts(
[this](CZwpKeyboardShortcutsInhibitManagerV1* pMgr, uint32_t id, wl_resource* surface, wl_resource* seat) { this->onInhibit(pMgr, id, surface, seat); });
}
void CKeyboardShortcutsInhibitProtocol::onManagerResourceDestroy(wl_resource* res) {
std::erase_if(m_vManagers, [&](const auto& other) { return other->resource() == res; });
}
void CKeyboardShortcutsInhibitProtocol::destroyInhibitor(CKeyboardShortcutsInhibitor* inhibitor) {
std::erase_if(m_vInhibitors, [&](const auto& other) { return other.get() == inhibitor; });
}
void CKeyboardShortcutsInhibitProtocol::onInhibit(CZwpKeyboardShortcutsInhibitManagerV1* pMgr, uint32_t id, wl_resource* surface, wl_resource* seat) {
wlr_surface* surf = wlr_surface_from_resource(surface);
const auto CLIENT = wl_resource_get_client(pMgr->resource());
for (auto& in : m_vInhibitors) {
if (in->surface() != surf)
continue;
wl_resource_post_error(pMgr->resource(), ZWP_KEYBOARD_SHORTCUTS_INHIBIT_MANAGER_V1_ERROR_ALREADY_INHIBITED, "Already inhibited for surface resource");
return;
}
const auto RESOURCE = m_vInhibitors
.emplace_back(std::make_unique<CKeyboardShortcutsInhibitor>(
std::make_shared<CZwpKeyboardShortcutsInhibitorV1>(CLIENT, wl_resource_get_version(pMgr->resource()), id), surf))
.get();
if (!RESOURCE->good()) {
wl_resource_post_no_memory(pMgr->resource());
m_vInhibitors.pop_back();
LOGM(ERR, "Failed to create an inhibitor resource");
return;
}
}
bool CKeyboardShortcutsInhibitProtocol::isInhibited() {
if (!g_pCompositor->m_pLastFocus)
return false;
for (auto& in : m_vInhibitors) {
if (in->surface() != g_pCompositor->m_pLastFocus)
continue;
return true;
}
return false;
}

View file

@ -0,0 +1,44 @@
#pragma once
#include <memory>
#include <vector>
#include <cstdint>
#include "WaylandProtocol.hpp"
#include "keyboard-shortcuts-inhibit-unstable-v1.hpp"
class CKeyboardShortcutsInhibitor {
public:
CKeyboardShortcutsInhibitor(SP<CZwpKeyboardShortcutsInhibitorV1> resource_, wlr_surface* surf);
// read-only pointer, may be invalid
wlr_surface* surface();
bool good();
private:
SP<CZwpKeyboardShortcutsInhibitorV1> resource;
wlr_surface* pSurface = nullptr;
};
class CKeyboardShortcutsInhibitProtocol : public IWaylandProtocol {
public:
CKeyboardShortcutsInhibitProtocol(const wl_interface* iface, const int& ver, const std::string& name);
virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);
bool isInhibited();
private:
void onManagerResourceDestroy(wl_resource* res);
void destroyInhibitor(CKeyboardShortcutsInhibitor* pointer);
void onInhibit(CZwpKeyboardShortcutsInhibitManagerV1* pMgr, uint32_t id, wl_resource* surface, wl_resource* seat);
//
std::vector<UP<CZwpKeyboardShortcutsInhibitManagerV1>> m_vManagers;
std::vector<UP<CKeyboardShortcutsInhibitor>> m_vInhibitors;
friend class CKeyboardShortcutsInhibitor;
};
namespace PROTO {
inline UP<CKeyboardShortcutsInhibitProtocol> shortcutsInhibit;
};