aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorVaxry <[email protected]>2024-05-03 22:34:10 +0100
committerVaxry <[email protected]>2024-05-03 22:40:27 +0100
commit1237732b97fcf21a19aed16f2ef966118a3ca2aa (patch)
tree15a3a29377af7f0ce3dd428229587e476ce92db3
parent1d2acbe19355c8640d54a4b6cba225c6f4370c85 (diff)
downloadHyprland-1237732b97fcf21a19aed16f2ef966118a3ca2aa.tar.gz
Hyprland-1237732b97fcf21a19aed16f2ef966118a3ca2aa.zip
input: Introduce basic hyprland HID classes
Implements an intermediary HID class for mice, keyboards and touch devices, removing the old structs from WLClasses.hpp Yes, virtual ones are duplicated a bit, but will likely be de-duped once wlr_input_device is not used anymore.
-rw-r--r--src/Compositor.cpp5
-rw-r--r--src/debug/HyprCtl.cpp53
-rw-r--r--src/desktop/LayerSurface.cpp6
-rw-r--r--src/devices/IHID.hpp26
-rw-r--r--src/devices/IKeyboard.cpp134
-rw-r--r--src/devices/IKeyboard.hpp61
-rw-r--r--src/devices/IPointer.cpp5
-rw-r--r--src/devices/IPointer.hpp110
-rw-r--r--src/devices/ITouch.cpp5
-rw-r--r--src/devices/ITouch.hpp50
-rw-r--r--src/devices/Keyboard.cpp64
-rw-r--r--src/devices/Keyboard.hpp24
-rw-r--r--src/devices/Mouse.cpp169
-rw-r--r--src/devices/Mouse.hpp36
-rw-r--r--src/devices/TouchDevice.cpp85
-rw-r--r--src/devices/TouchDevice.hpp25
-rw-r--r--src/devices/VirtualKeyboard.cpp71
-rw-r--r--src/devices/VirtualKeyboard.hpp28
-rw-r--r--src/devices/VirtualPointer.cpp170
-rw-r--r--src/devices/VirtualPointer.hpp38
-rw-r--r--src/events/Devices.cpp23
-rw-r--r--src/events/Events.hpp5
-rw-r--r--src/events/Windows.cpp2
-rw-r--r--src/helpers/Monitor.cpp9
-rw-r--r--src/helpers/WLClasses.cpp77
-rw-r--r--src/helpers/WLClasses.hpp100
-rw-r--r--src/helpers/signal/Listener.cpp8
-rw-r--r--src/helpers/signal/Listener.hpp16
-rw-r--r--src/helpers/signal/Signal.cpp8
-rw-r--r--src/helpers/signal/Signal.hpp7
-rw-r--r--src/managers/KeybindManager.cpp31
-rw-r--r--src/managers/KeybindManager.hpp3
-rw-r--r--src/managers/input/InputManager.cpp445
-rw-r--r--src/managers/input/InputManager.hpp47
-rw-r--r--src/managers/input/Touch.cpp7
-rw-r--r--src/protocols/VirtualKeyboard.cpp14
-rw-r--r--src/protocols/VirtualKeyboard.hpp12
-rw-r--r--src/protocols/VirtualPointer.cpp16
-rw-r--r--src/protocols/VirtualPointer.hpp14
39 files changed, 1443 insertions, 566 deletions
diff --git a/src/Compositor.cpp b/src/Compositor.cpp
index e28d86c7..9609cbd1 100644
--- a/src/Compositor.cpp
+++ b/src/Compositor.cpp
@@ -2418,10 +2418,7 @@ void CCompositor::warpCursorTo(const Vector2D& pos, bool force) {
if (*PNOWARPS && !force)
return;
- if (!m_sSeat.mouse)
- return;
-
- wlr_cursor_warp(m_sWLRCursor, m_sSeat.mouse->mouse, pos.x, pos.y);
+ wlr_cursor_warp(m_sWLRCursor, nullptr, pos.x, pos.y);
const auto PMONITORNEW = getMonitorFromVector(pos);
if (PMONITORNEW != m_pLastMonitor)
diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp
index d4e1164a..7f034570 100644
--- a/src/debug/HyprCtl.cpp
+++ b/src/debug/HyprCtl.cpp
@@ -19,6 +19,9 @@
#include "../config/ConfigValue.hpp"
#include "../managers/CursorManager.hpp"
#include "../hyprerror/HyprError.hpp"
+#include "../devices/IPointer.hpp"
+#include "../devices/IKeyboard.hpp"
+#include "../devices/ITouch.hpp"
static void trimTrailingComma(std::string& str) {
if (!str.empty() && str.back() == ',')
@@ -514,23 +517,24 @@ std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) {
result += "{\n";
result += "\"mice\": [\n";
- for (auto& m : g_pInputManager->m_lMice) {
+ for (auto& m : g_pInputManager->m_vPointers) {
result += std::format(
R"#( {{
"address": "0x{:x}",
"name": "{}",
"defaultSpeed": {:.5f}
}},)#",
- (uintptr_t)&m, escapeJSONStrings(m.name),
- wlr_input_device_is_libinput(m.mouse) ? libinput_device_config_accel_get_default_speed((libinput_device*)wlr_libinput_get_device_handle(m.mouse)) : 0.f);
+ (uintptr_t)m.get(), escapeJSONStrings(m->hlName),
+ wlr_input_device_is_libinput(&m->wlr()->base) ? libinput_device_config_accel_get_default_speed((libinput_device*)wlr_libinput_get_device_handle(&m->wlr()->base)) :
+ 0.f);
}
trimTrailingComma(result);
result += "\n],\n";
result += "\"keyboards\": [\n";
- for (auto& k : g_pInputManager->m_lKeyboards) {
- const auto KM = g_pInputManager->getActiveLayoutForKeyboard(&k);
+ for (auto& k : g_pInputManager->m_vKeyboards) {
+ const auto KM = k->getActiveLayout();
result += std::format(
R"#( {{
"address": "0x{:x}",
@@ -543,9 +547,9 @@ std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) {
"active_keymap": "{}",
"main": {}
}},)#",
- (uintptr_t)&k, escapeJSONStrings(k.name), escapeJSONStrings(k.currentRules.rules), escapeJSONStrings(k.currentRules.model),
- escapeJSONStrings(k.currentRules.layout), escapeJSONStrings(k.currentRules.variant), escapeJSONStrings(k.currentRules.options), escapeJSONStrings(KM),
- (k.active ? "true" : "false"));
+ (uintptr_t)k.get(), escapeJSONStrings(k->hlName), escapeJSONStrings(k->currentRules.rules), escapeJSONStrings(k->currentRules.model),
+ escapeJSONStrings(k->currentRules.layout), escapeJSONStrings(k->currentRules.variant), escapeJSONStrings(k->currentRules.options), escapeJSONStrings(KM),
+ (k->active ? "true" : "false"));
}
trimTrailingComma(result);
@@ -590,13 +594,13 @@ std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) {
result += "\"touch\": [\n";
- for (auto& d : g_pInputManager->m_lTouchDevices) {
+ for (auto& d : g_pInputManager->m_vTouches) {
result += std::format(
R"#( {{
"address": "0x{:x}",
"name": "{}"
}},)#",
- (uintptr_t)&d, escapeJSONStrings(d.name));
+ (uintptr_t)d.get(), escapeJSONStrings(d->hlName));
}
trimTrailingComma(result);
@@ -621,19 +625,20 @@ std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) {
} else {
result += "mice:\n";
- for (auto& m : g_pInputManager->m_lMice) {
- result += std::format(
- "\tMouse at {:x}:\n\t\t{}\n\t\t\tdefault speed: {:.5f}\n", (uintptr_t)&m, m.name,
- (wlr_input_device_is_libinput(m.mouse) ? libinput_device_config_accel_get_default_speed((libinput_device*)wlr_libinput_get_device_handle(m.mouse)) : 0.f));
+ for (auto& m : g_pInputManager->m_vPointers) {
+ result += std::format("\tMouse at {:x}:\n\t\t{}\n\t\t\tdefault speed: {:.5f}\n", (uintptr_t)m.get(), m->hlName,
+ (wlr_input_device_is_libinput(&m->wlr()->base) ?
+ libinput_device_config_accel_get_default_speed((libinput_device*)wlr_libinput_get_device_handle(&m->wlr()->base)) :
+ 0.f));
}
result += "\n\nKeyboards:\n";
- for (auto& k : g_pInputManager->m_lKeyboards) {
- const auto KM = g_pInputManager->getActiveLayoutForKeyboard(&k);
+ for (auto& k : g_pInputManager->m_vKeyboards) {
+ const auto KM = k->getActiveLayout();
result += std::format("\tKeyboard at {:x}:\n\t\t{}\n\t\t\trules: r \"{}\", m \"{}\", l \"{}\", v \"{}\", o \"{}\"\n\t\t\tactive keymap: {}\n\t\t\tmain: {}\n",
- (uintptr_t)&k, k.name, k.currentRules.rules, k.currentRules.model, k.currentRules.layout, k.currentRules.variant, k.currentRules.options, KM,
- (k.active ? "yes" : "no"));
+ (uintptr_t)k.get(), k->hlName, k->currentRules.rules, k->currentRules.model, k->currentRules.layout, k->currentRules.variant,
+ k->currentRules.options, KM, (k->active ? "yes" : "no"));
}
result += "\n\nTablets:\n";
@@ -652,8 +657,8 @@ std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) {
result += "\n\nTouch:\n";
- for (auto& d : g_pInputManager->m_lTouchDevices) {
- result += std::format("\tTouch Device at {:x}:\n\t\t{}\n", (uintptr_t)&d, d.name);
+ for (auto& d : g_pInputManager->m_vTouches) {
+ result += std::format("\tTouch Device at {:x}:\n\t\t{}\n", (uintptr_t)d.get(), d->hlName);
}
result += "\n\nSwitches:\n";
@@ -1069,13 +1074,13 @@ std::string switchXKBLayoutRequest(eHyprCtlOutputFormat format, std::string requ
const auto CMD = vars[2];
// get kb
- const auto PKEYBOARD = std::find_if(g_pInputManager->m_lKeyboards.begin(), g_pInputManager->m_lKeyboards.end(),
- [&](const SKeyboard& other) { return other.name == g_pInputManager->deviceNameToInternalString(KB); });
+ const auto PKEYBOARD = std::find_if(g_pInputManager->m_vKeyboards.begin(), g_pInputManager->m_vKeyboards.end(),
+ [&](const auto& other) { return other->hlName == g_pInputManager->deviceNameToInternalString(KB); });
- if (PKEYBOARD == g_pInputManager->m_lKeyboards.end())
+ if (PKEYBOARD == g_pInputManager->m_vKeyboards.end())
return "device not found";
- const auto PWLRKEYBOARD = wlr_keyboard_from_input_device(PKEYBOARD->keyboard);
+ const auto PWLRKEYBOARD = (*PKEYBOARD)->wlr();
const auto LAYOUTS = xkb_keymap_num_layouts(PWLRKEYBOARD->keymap);
xkb_layout_index_t activeLayout = 0;
while (activeLayout < LAYOUTS) {
diff --git a/src/desktop/LayerSurface.cpp b/src/desktop/LayerSurface.cpp
index ec899dd1..dd2cfb7d 100644
--- a/src/desktop/LayerSurface.cpp
+++ b/src/desktop/LayerSurface.cpp
@@ -196,7 +196,7 @@ void CLayerSurface::onMap() {
const bool GRABSFOCUS = layerSurface->current.keyboard_interactive != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE &&
// don't focus if constrained
- (!g_pCompositor->m_sSeat.mouse || !g_pInputManager->isConstrained());
+ (g_pCompositor->m_sSeat.mouse.expired() || !g_pInputManager->isConstrained());
if (GRABSFOCUS) {
g_pInputManager->releaseAllMouseButtons();
@@ -383,7 +383,7 @@ void CLayerSurface::onCommit() {
realSize.setValueAndWarp(geometry.size());
}
- if (layerSurface->current.keyboard_interactive && (!g_pCompositor->m_sSeat.mouse || !g_pInputManager->isConstrained()) // don't focus if constrained
+ if (layerSurface->current.keyboard_interactive && (g_pCompositor->m_sSeat.mouse.expired() || !g_pInputManager->isConstrained()) // don't focus if constrained
&& !keyboardExclusive && mapped) {
g_pCompositor->focusSurface(layerSurface->surface);
@@ -391,7 +391,7 @@ void CLayerSurface::onCommit() {
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, layerSurface->surface, LOCAL.x, LOCAL.y);
wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, 0, LOCAL.x, LOCAL.y);
g_pInputManager->m_bEmptyFocusCursorSet = false;
- } else if (!layerSurface->current.keyboard_interactive && (!g_pCompositor->m_sSeat.mouse || !g_pInputManager->isConstrained()) && keyboardExclusive) {
+ } else if (!layerSurface->current.keyboard_interactive && (g_pCompositor->m_sSeat.mouse.expired() || !g_pInputManager->isConstrained()) && keyboardExclusive) {
g_pInputManager->refocus();
}
diff --git a/src/devices/IHID.hpp b/src/devices/IHID.hpp
new file mode 100644
index 00000000..c2b397c7
--- /dev/null
+++ b/src/devices/IHID.hpp
@@ -0,0 +1,26 @@
+#pragma once
+
+#include <cstdint>
+#include <string>
+#include "../helpers/signal/Signal.hpp"
+
+enum eHIDCapabilityType : uint32_t {
+ HID_INPUT_CAPABILITY_KEYBOARD = (1 << 0),
+ HID_INPUT_CAPABILITY_POINTER = (1 << 1),
+ HID_INPUT_CAPABILITY_TOUCH = (1 << 2),
+};
+
+/*
+ Base class for a HID device.
+ This could be a keyboard, a mouse, or a touchscreen.
+*/
+class IHID {
+ public:
+ virtual uint32_t getCapabilities() = 0;
+
+ struct {
+ CSignal destroy;
+ } events;
+
+ std::string deviceName;
+}; \ No newline at end of file
diff --git a/src/devices/IKeyboard.cpp b/src/devices/IKeyboard.cpp
new file mode 100644
index 00000000..790766bc
--- /dev/null
+++ b/src/devices/IKeyboard.cpp
@@ -0,0 +1,134 @@
+#include "IKeyboard.hpp"
+#include "../defines.hpp"
+#include "../helpers/VarList.hpp"
+#include "../managers/input/InputManager.hpp"
+
+uint32_t IKeyboard::getCapabilities() {
+ return HID_INPUT_CAPABILITY_KEYBOARD;
+}
+
+IKeyboard::~IKeyboard() {
+ events.destroy.emit();
+
+ if (!xkbTranslationState)
+ return;
+
+ xkb_state_unref(xkbTranslationState);
+ xkbTranslationState = nullptr;
+}
+
+void IKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) {
+
+ if (xkbTranslationState)
+ xkb_state_unref(xkbTranslationState);
+
+ if (keymap) {
+ Debug::log(LOG, "Updating keyboard {:x}'s translation state from a provided keymap", (uintptr_t)this);
+ xkbTranslationState = xkb_state_new(keymap);
+ return;
+ }
+
+ const auto WLRKB = wlr();
+ const auto KEYMAP = WLRKB->keymap;
+ const auto STATE = WLRKB->xkb_state;
+ const auto LAYOUTSNUM = xkb_keymap_num_layouts(KEYMAP);
+
+ const auto PCONTEXT = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
+
+ for (uint32_t i = 0; i < LAYOUTSNUM; ++i) {
+ if (xkb_state_layout_index_is_active(STATE, i, XKB_STATE_LAYOUT_EFFECTIVE)) {
+ Debug::log(LOG, "Updating keyboard {:x}'s translation state from an active index {}", (uintptr_t)this, i);
+
+ CVarList keyboardLayouts(currentRules.layout, 0, ',');
+ CVarList keyboardModels(currentRules.model, 0, ',');
+ CVarList keyboardVariants(currentRules.variant, 0, ',');
+
+ xkb_rule_names rules = {.rules = "", .model = "", .layout = "", .variant = "", .options = ""};
+
+ std::string layout, model, variant;
+ layout = keyboardLayouts[i % keyboardLayouts.size()];
+ model = keyboardModels[i % keyboardModels.size()];
+ variant = keyboardVariants[i % keyboardVariants.size()];
+
+ rules.layout = layout.c_str();
+ rules.model = model.c_str();
+ rules.variant = variant.c_str();
+
+ auto KEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
+
+ if (!KEYMAP) {
+ Debug::log(ERR, "updateXKBTranslationState: keymap failed 1, fallback without model/variant");
+ rules.model = "";
+ rules.variant = "";
+ KEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
+ }
+
+ if (!KEYMAP) {
+ Debug::log(ERR, "updateXKBTranslationState: keymap failed 2, fallback to us");
+ rules.layout = "us";
+ KEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
+ }
+
+ xkbTranslationState = xkb_state_new(KEYMAP);
+
+ xkb_keymap_unref(KEYMAP);
+ xkb_context_unref(PCONTEXT);
+
+ return;
+ }
+ }
+
+ Debug::log(LOG, "Updating keyboard {:x}'s translation state from an unknown index", (uintptr_t)this);
+
+ xkb_rule_names rules = {
+ .rules = currentRules.rules.c_str(),
+ .model = currentRules.model.c_str(),
+ .layout = currentRules.layout.c_str(),
+ .variant = currentRules.variant.c_str(),
+ .options = currentRules.options.c_str(),
+ };
+
+ const auto NEWKEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
+
+ xkbTranslationState = xkb_state_new(NEWKEYMAP);
+
+ xkb_keymap_unref(NEWKEYMAP);
+ xkb_context_unref(PCONTEXT);
+}
+
+std::string IKeyboard::getActiveLayout() {
+ const auto WLRKB = wlr();
+ const auto KEYMAP = WLRKB->keymap;
+ const auto STATE = WLRKB->xkb_state;
+ const auto LAYOUTSNUM = xkb_keymap_num_layouts(KEYMAP);
+
+ for (uint32_t i = 0; i < LAYOUTSNUM; ++i) {
+ if (xkb_state_layout_index_is_active(STATE, i, XKB_STATE_LAYOUT_EFFECTIVE)) {
+ const auto LAYOUTNAME = xkb_keymap_layout_get_name(KEYMAP, i);
+
+ if (LAYOUTNAME)
+ return std::string(LAYOUTNAME);
+ return "error";
+ }
+ }
+
+ return "none";
+}
+
+void IKeyboard::updateLEDs() {
+ auto keyboard = wlr();
+
+ if (keyboard->xkb_state == nullptr)
+ return;
+
+ uint32_t leds = 0;
+ for (uint32_t i = 0; i < WLR_LED_COUNT; ++i) {
+ if (xkb_state_led_index_is_active(keyboard->xkb_state, keyboard->led_indexes[i]))
+ leds |= (1 << i);
+ }
+
+ if (isVirtual() && g_pInputManager->shouldIgnoreVirtualKeyboard(self.lock()))
+ return;
+
+ wlr_keyboard_led_update(wlr(), leds);
+}
diff --git a/src/devices/IKeyboard.hpp b/src/devices/IKeyboard.hpp
new file mode 100644
index 00000000..35ccd8cb
--- /dev/null
+++ b/src/devices/IKeyboard.hpp
@@ -0,0 +1,61 @@
+#pragma once
+
+#include "IHID.hpp"
+#include "../helpers/WLListener.hpp"
+#include "../macros.hpp"
+#include "../helpers/Vector2D.hpp"
+
+#include <xkbcommon/xkbcommon.h>
+
+struct wlr_keyboard;
+
+class IKeyboard : public IHID {
+ public:
+ virtual ~IKeyboard();
+ virtual uint32_t getCapabilities();
+ virtual bool isVirtual() = 0;
+ virtual wlr_keyboard* wlr() = 0;
+
+ struct SKeyEvent {
+ uint32_t timeMs = 0;
+ uint32_t keycode = 0;
+ bool updateMods = false;
+ wl_keyboard_key_state state = WL_KEYBOARD_KEY_STATE_PRESSED;
+ };
+
+ struct {
+ CSignal key;
+ CSignal modifiers;
+ CSignal keymap;
+ CSignal repeatInfo;
+ } keyboardEvents;
+
+ struct SStringRuleNames {
+ std::string layout = "";
+ std::string model = "";
+ std::string variant = "";
+ std::string options = "";
+ std::string rules = "";
+ };
+
+ void updateXKBTranslationState(xkb_keymap* const keymap = nullptr);
+ std::string getActiveLayout();
+ void updateLEDs();
+
+ bool active = false;
+ bool enabled = true;
+
+ xkb_layout_index_t activeLayout = 0;
+ xkb_state* xkbTranslationState = nullptr;
+
+ std::string hlName = "";
+ std::string xkbFilePath = "";
+
+ SStringRuleNames currentRules;
+ int repeatRate = 0;
+ int repeatDelay = 0;
+ int numlockOn = -1;
+ bool resolveBindsBySym = false;
+
+ WP<IKeyboard> self;
+};
diff --git a/src/devices/IPointer.cpp b/src/devices/IPointer.cpp
new file mode 100644
index 00000000..9eb507b2
--- /dev/null
+++ b/src/devices/IPointer.cpp
@@ -0,0 +1,5 @@
+#include "IPointer.hpp"
+
+uint32_t IPointer::getCapabilities() {
+ return HID_INPUT_CAPABILITY_POINTER;
+}
diff --git a/src/devices/IPointer.hpp b/src/devices/IPointer.hpp
new file mode 100644
index 00000000..eda7da2c
--- /dev/null
+++ b/src/devices/IPointer.hpp
@@ -0,0 +1,110 @@
+#pragma once
+
+#include "IHID.hpp"
+#include "../helpers/WLListener.hpp"
+#include "../macros.hpp"
+#include "../helpers/Vector2D.hpp"
+
+struct wlr_pointer;
+
+/*
+ Base class for a pointer.
+*/
+class IPointer : public IHID {
+ public:
+ virtual uint32_t getCapabilities();
+ virtual bool isVirtual() = 0;
+ virtual wlr_pointer* wlr() = 0;
+
+ struct SMotionEvent {
+ uint32_t timeMs = 0;
+ Vector2D delta, unaccel;
+ };
+
+ struct SMotionAbsoluteEvent {
+ uint32_t timeMs = 0;
+ Vector2D absolute; // 0.0 - 1.0
+ };
+
+ struct SButtonEvent {
+ uint32_t timeMs = 0;
+ uint32_t button = 0;
+ wl_pointer_button_state state = WL_POINTER_BUTTON_STATE_PRESSED;
+ };
+
+ struct SAxisEvent {
+ uint32_t timeMs = 0;
+ wl_pointer_axis_source source = WL_POINTER_AXIS_SOURCE_WHEEL;
+ wl_pointer_axis axis = WL_POINTER_AXIS_VERTICAL_SCROLL;
+ wl_pointer_axis_relative_direction relativeDirection = WL_POINTER_AXIS_RELATIVE_DIRECTION_IDENTICAL;
+ double delta = 0.0;
+ int32_t deltaDiscrete = 0;
+ };
+
+ struct SSwipeBeginEvent {
+ uint32_t timeMs = 0;
+ uint32_t fingers = 0;
+ };
+
+ struct SSwipeUpdateEvent {
+ uint32_t timeMs = 0;
+ uint32_t fingers = 0;
+ Vector2D delta;
+ };
+
+ struct SSwipeEndEvent {
+ uint32_t timeMs = 0;
+ bool cancelled = false;
+ };
+
+ struct SPinchBeginEvent {
+ uint32_t timeMs = 0;
+ uint32_t fingers = 0;
+ };
+
+ struct SPinchUpdateEvent {
+ uint32_t timeMs = 0;
+ uint32_t fingers = 0;
+ Vector2D delta;
+ double scale = 1.0, rotation = 0.0;
+ };
+
+ struct SPinchEndEvent {
+ uint32_t timeMs = 0;
+ bool cancelled = false;
+ };
+
+ struct SHoldBeginEvent {
+ uint32_t timeMs = 0;
+ uint32_t fingers = 0;
+ };
+
+ struct SHoldEndEvent {
+ uint32_t timeMs = 0;
+ bool cancelled = false;
+ };
+
+ struct {
+ CSignal motion;
+ CSignal motionAbsolute;
+ CSignal button;
+ CSignal axis;
+ CSignal frame;
+
+ CSignal swipeBegin;
+ CSignal swipeEnd;
+ CSignal swipeUpdate;
+
+ CSignal pinchBegin;
+ CSignal pinchEnd;
+ CSignal pinchUpdate;
+
+ CSignal holdBegin;
+ CSignal holdEnd;
+ } pointerEvents;
+
+ std::string hlName;
+ bool connected = false; // means connected to the cursor
+
+ WP<IPointer> self;
+};
diff --git a/src/devices/ITouch.cpp b/src/devices/ITouch.cpp
new file mode 100644
index 00000000..3fa347fd
--- /dev/null
+++ b/src/devices/ITouch.cpp
@@ -0,0 +1,5 @@
+#include "ITouch.hpp"
+
+uint32_t ITouch::getCapabilities() {
+ return HID_INPUT_CAPABILITY_TOUCH;
+} \ No newline at end of file
diff --git a/src/devices/ITouch.hpp b/src/devices/ITouch.hpp
new file mode 100644
index 00000000..7a109bec
--- /dev/null
+++ b/src/devices/ITouch.hpp
@@ -0,0 +1,50 @@
+#pragma once
+
+#include "IHID.hpp"
+#include "../helpers/WLListener.hpp"
+#include "../macros.hpp"
+#include "../helpers/Vector2D.hpp"
+
+struct wlr_touch;
+
+class ITouch : public IHID {
+ public:
+ virtual uint32_t getCapabilities();
+ virtual bool isVirtual() = 0;
+ virtual wlr_touch* wlr() = 0;
+
+ struct SDownEvent {
+ uint32_t timeMs = 0;
+ int32_t touchID = 0;
+ Vector2D pos;
+ };
+
+ struct SUpEvent {
+ uint32_t timeMs = 0;
+ int32_t touchID = 0;
+ };
+
+ struct SMotionEvent {
+ uint32_t timeMs = 0;
+ int32_t touchID = 0;
+ Vector2D pos;
+ };
+
+ struct SCancelEvent {
+ uint32_t timeMs = 0;
+ int32_t touchID = 0;
+ };
+
+ struct {
+ CSignal down;
+ CSignal up;
+ CSignal motion;
+ CSignal cancel;
+ CSignal frame;
+ } touchEvents;
+
+ std::string hlName = "";
+ std::string boundOutput = "";
+
+ WP<ITouch> self;
+}; \ No newline at end of file
diff --git a/src/devices/Keyboard.cpp b/src/devices/Keyboard.cpp
new file mode 100644
index 00000000..11257a74
--- /dev/null
+++ b/src/devices/Keyboard.cpp
@@ -0,0 +1,64 @@
+#include "Keyboard.hpp"
+#include "../defines.hpp"
+
+SP<CKeyboard> CKeyboard::create(wlr_keyboard* keeb) {
+ SP<CKeyboard> pKeeb = SP<CKeyboard>(new CKeyboard(keeb));
+
+ pKeeb->self = pKeeb;
+
+ return pKeeb;
+}
+
+bool CKeyboard::isVirtual() {
+ return false;
+}
+
+wlr_keyboard* CKeyboard::wlr() {
+ return keyboard;
+}
+
+CKeyboard::CKeyboard(wlr_keyboard* keeb) : keyboard(keeb) {
+ if (!keeb)
+ return;
+
+ // clang-format off
+ hyprListener_destroy.initCallback(&keeb->base.events.destroy, [this] (void* owner, void* data) {
+ events.destroy.emit();
+ disconnectCallbacks();
+ keyboard = nullptr;
+ }, this, "CKeyboard");
+
+ hyprListener_key.initCallback(&keeb->events.key, [this] (void* owner, void* data) {
+ auto E = (wlr_keyboard_key_event*)data;
+
+ keyboardEvents.key.emit(SKeyEvent{
+ .timeMs = E->time_msec,
+ .keycode = E->keycode,
+ .updateMods = E->update_state,
+ .state = E->state,
+ });
+ }, this, "CKeyboard");
+
+ hyprListener_keymap.initCallback(&keeb->events.keymap, [this] (void* owner, void* data) {
+ keyboardEvents.keymap.emit();
+ }, this, "CKeyboard");
+
+ hyprListener_modifiers.initCallback(&keeb->events.modifiers, [this] (void* owner, void* data) {
+ keyboardEvents.modifiers.emit();
+ }, this, "CKeyboard");
+
+ hyprListener_repeatInfo.initCallback(&keeb->events.repeat_info, [this] (void* owner, void* data) {
+ keyboardEvents.repeatInfo.emit();
+ }, this, "CKeyboard");
+ // clang-format on
+
+ deviceName = keeb->base.name ? keeb->base.name : "UNKNOWN";
+}
+
+void CKeyboard::disconnectCallbacks() {
+ hyprListener_destroy.removeCallback();
+ hyprListener_key.removeCallback();
+ hyprListener_keymap.removeCallback();
+ hyprListener_repeatInfo.removeCallback();
+ hyprListener_modifiers.removeCallback();
+}
diff --git a/src/devices/Keyboard.hpp b/src/devices/Keyboard.hpp
new file mode 100644
index 00000000..cf01a9a7
--- /dev/null
+++ b/src/devices/Keyboard.hpp
@@ -0,0 +1,24 @@
+#pragma once
+
+#include "IKeyboard.hpp"
+
+class CKeyboard : public IKeyboard {
+ public:
+ static SP<CKeyboard> create(wlr_keyboard* keeb);
+
+ virtual bool isVirtual();
+ virtual wlr_keyboard* wlr();
+
+ private:
+ CKeyboard(wlr_keyboard* keeb);
+
+ wlr_keyboard* keyboard = nullptr;
+
+ void disconnectCallbacks();
+
+ DYNLISTENER(destroy);
+ DYNLISTENER(key);
+ DYNLISTENER(modifiers);
+ DYNLISTENER(keymap);
+ DYNLISTENER(repeatInfo);
+}; \ No newline at end of file
diff --git a/src/devices/Mouse.cpp b/src/devices/Mouse.cpp
new file mode 100644
index 00000000..e2a6f4ed
--- /dev/null
+++ b/src/devices/Mouse.cpp
@@ -0,0 +1,169 @@
+#include "Mouse.hpp"
+#include "../defines.hpp"
+
+SP<CMouse> CMouse::create(wlr_pointer* mouse) {
+ SP<CMouse> pMouse = SP<CMouse>(new CMouse(mouse));
+
+ pMouse->self = pMouse;
+
+ return pMouse;
+}
+
+CMouse::CMouse(wlr_pointer* mouse_) : mouse(mouse_) {
+ if (!mouse)
+ return;
+
+ // clang-format off
+ hyprListener_destroy.initCallback(&mouse->base.events.destroy, [this] (void* owner, void* data) {
+ disconnectCallbacks();
+ mouse = nullptr;
+ events.destroy.emit();
+ }, this, "CMouse");
+
+ hyprListener_motion.initCallback(&mouse->events.motion, [this] (void* owner, void* data) {
+ auto E = (wlr_pointer_motion_event*)data;
+
+ pointerEvents.motion.emit(SMotionEvent{
+ .timeMs = E->time_msec,
+ .delta = {E->delta_x, E->delta_y},
+ .unaccel = {E->unaccel_dx, E->unaccel_dy},
+ });
+ }, this, "CMouse");
+
+ hyprListener_motionAbsolute.initCallback(&mouse->events.motion_absolute, [this] (void* owner, void* data) {
+ auto E = (wlr_pointer_motion_absolute_event*)data;
+
+ pointerEvents.motionAbsolute.emit(SMotionAbsoluteEvent{
+ .timeMs = E->time_msec,
+ .absolute = {E->x, E->y},
+ });
+ }, this, "CMouse");
+
+ hyprListener_button.initCallback(&mouse->events.button, [this] (void* owner, void* data) {
+ auto E = (wlr_pointer_button_event*)data;
+
+ pointerEvents.button.emit(SButtonEvent{
+ .timeMs = E->time_msec,
+ .button = E->button,
+ .state = (wl_pointer_button_state)E->state,
+ });
+ }, this, "CMouse");
+
+ hyprListener_axis.initCallback(&mouse->events.axis, [this] (void* owner, void* data) {
+ auto E = (wlr_pointer_axis_event*)data;
+
+ pointerEvents.axis.emit(SAxisEvent{
+ .timeMs = E->time_msec,
+ .source = E->source,
+ .axis = E->orientation,
+ .relativeDirection = E->relative_direction,
+ .delta = E->delta,
+ .deltaDiscrete = E->delta_discrete,
+ });
+ }, this, "CMouse");
+
+ hyprListener_swipeBegin.initCallback(&mouse->events.swipe_begin, [this] (void* owner, void* data) {
+ auto E = (wlr_pointer_swipe_begin_event*)data;
+
+ pointerEvents.swipeBegin.emit(SSwipeBeginEvent{
+ .timeMs = E->time_msec,
+ .fingers = E->fingers,
+ });
+ }, this, "CMouse");
+
+ hyprListener_swipeEnd.initCallback(&mouse->events.swipe_end, [this] (void* owner, void* data) {
+ auto E = (wlr_pointer_swipe_end_event*)data;
+
+ pointerEvents.swipeEnd.emit(SSwipeEndEvent{
+ .timeMs = E->time_msec,
+ .cancelled = E->cancelled,
+ });
+ }, this, "CMouse");
+
+ hyprListener_swipeUpdate.initCallback(&mouse->events.swipe_update, [this] (void* owner, void* data) {
+ auto E = (wlr_pointer_swipe_update_event*)data;
+
+ pointerEvents.swipeUpdate.emit(SSwipeUpdateEvent{
+ .timeMs = E->time_msec,
+ .fingers = E->fingers,
+ .delta = {E->dx, E->dy},
+ });
+ }, this, "CMouse");
+
+ hyprListener_pinchBegin.initCallback(&mouse->events.pinch_begin, [this] (void* owner, void* data) {
+ auto E = (wlr_pointer_pinch_begin_event*)data;
+
+ pointerEvents.pinchBegin.emit(SPinchBeginEvent{
+ .timeMs = E->time_msec,
+ .fingers = E->fingers,
+ });
+ }, this, "CMouse");
+
+ hyprListener_pinchEnd.initCallback(&mouse->events.pinch_end, [this] (void* owner, void* data) {
+ auto E = (wlr_pointer_pinch_end_event*)data;
+
+ pointerEvents.pinchEnd.emit(SPinchEndEvent{
+ .timeMs = E->time_msec,
+ .cancelled = E->cancelled,
+ });
+ }, this, "CMouse");
+
+ hyprListener_pinchUpdate.initCallback(&mouse->events.pinch_update, [this] (void* owner, void* data) {
+ auto E = (wlr_pointer_pinch_update_event*)data;
+
+ pointerEvents.pinchUpdate.emit(SPinchUpdateEvent{
+ .timeMs = E->time_msec,
+ .fingers = E->fingers,
+ .delta = {E->dx, E->dy},
+ .scale = E->scale,
+ .rotation = E->rotation,
+ });
+ }, this, "CMouse");
+
+ hyprListener_holdBegin.initCallback(&mouse->events.hold_begin, [this] (void* owner, void* data) {
+ auto E = (wlr_pointer_hold_begin_event*)data;
+
+ pointerEvents.holdBegin.emit(SHoldBeginEvent{
+ .timeMs = E->time_msec,
+ .fingers = E->fingers,
+ });
+ }, this, "CMouse");
+
+ hyprListener_holdEnd.initCallback(&mouse->events.hold_end, [this] (void* owner, void* data) {
+ auto E = (wlr_pointer_hold_end_event*)data;
+
+ pointerEvents.holdEnd.emit(SHoldEndEvent{
+ .timeMs = E->time_msec,
+ .cancelled = E->cancelled,
+ });
+ }, this, "CMouse");
+
+ // clang-format on
+
+ deviceName = mouse->base.name ? mouse->base.name : "UNKNOWN";
+}
+
+void CMouse::disconnectCallbacks() {
+ hyprListener_destroy.removeCallback();
+ hyprListener_motion.removeCallback();
+ hyprListener_motionAbsolute.removeCallback();
+ hyprListener_button.removeCallback();
+ hyprListener_axis.removeCallback();
+ hyprListener_frame.removeCallback();
+ hyprListener_swipeBegin.removeCallback();
+ hyprListener_swipeEnd.removeCallback();
+ hyprListener_swipeUpdate.removeCallback();
+ hyprListener_pinchBegin.removeCallback();
+ hyprListener_pinchEnd.removeCallback();
+ hyprListener_pinchUpdate.removeCallback();
+ hyprListener_holdBegin.removeCallback();
+ hyprListener_holdEnd.removeCallback();
+}
+
+bool CMouse::isVirtual() {
+ return false;
+}
+
+wlr_pointer* CMouse::wlr() {
+ return mouse;
+}
diff --git a/src/devices/Mouse.hpp b/src/devices/Mouse.hpp
new file mode 100644
index 00000000..40a65ca8
--- /dev/null
+++ b/src/devices/Mouse.hpp
@@ -0,0 +1,36 @@
+#pragma once
+
+#include "IPointer.hpp"
+
+class CMouse : public IPointer {
+ public:
+ static SP<CMouse> create(wlr_pointer* mouse);
+
+ virtual bool isVirtual();
+ virtual wlr_pointer* wlr();
+
+ private:
+ CMouse(wlr_pointer* mouse);
+
+ wlr_pointer* mouse = nullptr;
+
+ void disconnectCallbacks();
+
+ DYNLISTENER(destroy);
+ DYNLISTENER(motion);
+ DYNLISTENER(motionAbsolute);
+ DYNLISTENER(button);
+ DYNLISTENER(axis);
+ DYNLISTENER(frame);
+
+ DYNLISTENER(swipeBegin);
+ DYNLISTENER(swipeEnd);
+ DYNLISTENER(swipeUpdate);
+
+ DYNLISTENER(pinchBegin);
+ DYNLISTENER(pinchEnd);
+ DYNLISTENER(pinchUpdate);
+
+ DYNLISTENER(holdBegin);
+ DYNLISTENER(holdEnd);
+};
diff --git a/src/devices/TouchDevice.cpp b/src/devices/TouchDevice.cpp
new file mode 100644
index 00000000..e8e52dc2
--- /dev/null
+++ b/src/devices/TouchDevice.cpp
@@ -0,0 +1,85 @@
+#include "TouchDevice.hpp"
+#include "../defines.hpp"
+
+SP<CTouchDevice> CTouchDevice::create(wlr_touch* touch) {
+ SP<CTouchDevice> pTouch = SP<CTouchDevice>(new CTouchDevice(touch));
+
+ pTouch->self = pTouch;
+
+ return pTouch;
+}
+
+CTouchDevice::CTouchDevice(wlr_touch* touch_) : touch(touch_) {
+ if (!touch)
+ return;
+
+ // clang-format off
+ hyprListener_destroy.initCallback(&touch->base.events.destroy, [this] (void* owner, void* data) {
+ events.destroy.emit();
+ disconnectCallbacks();
+ touch = nullptr;
+ }, this, "CTouchDevice");
+
+ hyprListener_down.initCallback(&touch->events.down, [this] (void* owner, void* data) {
+ auto E = (wlr_touch_down_event*)data;
+
+ touchEvents.down.emit(SDownEvent{
+ .timeMs = E->time_msec,
+ .touchID = E->touch_id,
+ .pos = {E->x, E->y},
+ });
+ }, this, "CTouchDevice");
+
+ hyprListener_up.initCallback(&touch->events.up, [this] (void* owner, void* data) {
+ auto E = (wlr_touch_up_event*)data;
+
+ touchEvents.up.emit(SUpEvent{
+ .timeMs = E->time_msec,
+ .touchID = E->touch_id
+ });
+ }, this, "CTouchDevice");
+
+ hyprListener_motion.initCallback(&touch->events.motion, [this] (void* owner, void* data) {
+ auto E = (wlr_touch_motion_event*)data;
+
+ touchEvents.motion.emit(SMotionEvent{
+ .timeMs = E->time_msec,
+ .touchID = E->touch_id,
+ .pos = {E->x, E->y},
+ });
+ }, this, "CTouchDevice");
+
+ hyprListener_cancel.initCallback(&touch->events.cancel, [this] (void* owner, void* data) {
+ auto E = (wlr_touch_cancel_event*)data;
+
+ touchEvents.cancel.emit(SCancelEvent{
+ .timeMs = E->time_msec,
+ .touchID = E->touch_id
+ });
+ }, this, "CTouchDevice");
+
+ hyprListener_frame.initCallback(&touch->events.frame, [this] (void* owner, void* data) {
+ touchEvents.frame.emit();
+ }, this, "CTouchDevice");
+
+ // clang-format on
+
+ deviceName = touch->base.name ? touch->base.name : "UNKNOWN";
+}
+
+bool CTouchDevice::isVirtual() {
+ return false;
+}
+
+wlr_touch* CTouchDevice::wlr() {
+ return touch;
+}
+
+void CTouchDevice::disconnectCallbacks() {
+ hyprListener_destroy.removeCallback();
+ hyprListener_down.removeCallback();
+ hyprListener_up.removeCallback();
+ hyprListener_motion.removeCallback();
+ hyprListener_cancel.removeCallback();
+ hyprListener_frame.removeCallback();
+}
diff --git a/src/devices/TouchDevice.hpp b/src/devices/TouchDevice.hpp
new file mode 100644
index 00000000..51eb76d4
--- /dev/null
+++ b/src/devices/TouchDevice.hpp
@@ -0,0 +1,25 @@
+#pragma once
+
+#include "ITouch.hpp"
+
+class CTouchDevice : public ITouch {
+ public:
+ static SP<CTouchDevice> create(wlr_touch* touch);
+
+ virtual bool isVirtual();
+ virtual wlr_touch* wlr();
+
+ private:
+ CTouchDevice(wlr_touch* touch);
+
+ wlr_touch* touch = nullptr;
+
+ void disconnectCallbacks();
+
+ DYNLISTENER(destroy);
+ DYNLISTENER(down);
+ DYNLISTENER(up);
+ DYNLISTENER(motion);
+ DYNLISTENER(cancel);
+ DYNLISTENER(frame);
+}; \ No newline at end of file
diff --git a/src/devices/VirtualKeyboard.cpp b/src/devices/VirtualKeyboard.cpp
new file mode 100644
index 00000000..ca6156b7
--- /dev/null
+++ b/src/devices/VirtualKeyboard.cpp
@@ -0,0 +1,71 @@
+#include "VirtualKeyboard.hpp"
+#include "../defines.hpp"
+#include "../protocols/VirtualKeyboard.hpp"
+
+SP<CVirtualKeyboard> CVirtualKeyboard::create(SP<CVirtualKeyboardV1Resource> keeb) {
+ SP<CVirtualKeyboard> pKeeb = SP<CVirtualKeyboard>(new CVirtualKeyboard(keeb));
+
+ pKeeb->self = pKeeb;
+
+ return pKeeb;
+}
+
+CVirtualKeyboard::CVirtualKeyboard(SP<CVirtualKeyboardV1Resource> keeb_) : keyboard(keeb_) {
+ if (!keeb_)
+ return;
+
+ auto keeb = keeb_->wlr();
+
+ // clang-format off
+ hyprListener_destroy.initCallback(&keeb->base.events.destroy, [this] (void* owner, void* data) {
+ events.destroy.emit();
+ disconnectCallbacks();
+ keyboard.reset();
+ }, this, "CVirtualKeyboard");
+
+ hyprListener_key.initCallback(&keeb->events.key, [this] (void* owner, void* data) {
+ auto E = (wlr_keyboard_key_event*)data;
+
+ keyboardEvents.key.emit(SKeyEvent{
+ .timeMs = E->time_msec,
+ .keycode = E->keycode,
+ .updateMods = E->update_state,
+ .state = E->state,
+ });
+ }, this, "CVirtualKeyboard");
+
+ hyprListener_keymap.initCallback(&keeb->events.keymap, [this] (void* owner, void* data) {
+ keyboardEvents.keymap.emit();
+ }, this, "CVirtualKeyboard");
+
+ hyprListener_modifiers.initCallback(&keeb->events.modifiers, [this] (void* owner, void* data) {
+ keyboardEvents.modifiers.emit();
+ }, this, "CVirtualKeyboard");
+
+ hyprListener_repeatInfo.initCallback(&keeb->events.repeat_info, [this] (void* owner, void* data) {
+ keyboardEvents.repeatInfo.emit();
+ }, this, "CVirtualKeyboard");
+ // clang-format on
+
+ deviceName = keeb->base.name ? keeb->base.name : "UNKNOWN";
+}
+
+bool CVirtualKeyboard::isVirtual() {
+ return true;
+}
+
+wlr_keyboard* CVirtualKeyboard::wlr() {
+ return keyboard.lock()->wlr();
+}
+
+void CVirtualKeyboard::disconnectCallbacks() {
+ hyprListener_destroy.removeCallback();
+ hyprListener_key.removeCallback();
+ hyprListener_keymap.removeCallback();
+ hyprListener_repeatInfo.removeCallback();
+ hyprListener_modifiers.removeCallback();
+}
+
+wl_client* CVirtualKeyboard::getClient() {
+ return keyboard.lock()->client();
+}
diff --git a/src/devices/VirtualKeyboard.hpp b/src/devices/VirtualKeyboard.hpp
new file mode 100644
index 00000000..5ef88dd3
--- /dev/null
+++ b/src/devices/VirtualKeyboard.hpp
@@ -0,0 +1,28 @@
+#pragma once
+
+#include "IKeyboard.hpp"
+
+class CVirtualKeyboardV1Resource;
+
+class CVirtualKeyboard : public IKeyboard {
+ public:
+ static SP<CVirtualKeyboard> create(SP<CVirtualKeyboardV1Resource> keeb);
+
+ virtual bool isVirtual();
+ virtual wlr_keyboard* wlr();
+
+ wl_client* getClient();
+
+ private:
+ CVirtualKeyboard(SP<CVirtualKeyboardV1Resource> keeb);
+
+ WP<CVirtualKeyboardV1Resource> keyboard;
+
+ void disconnectCallbacks();
+
+ DYNLISTENER(destroy);
+ DYNLISTENER(key);
+ DYNLISTENER(modifiers);
+ DYNLISTENER(keymap);
+ DYNLISTENER(repeatInfo);
+};
diff --git a/src/devices/VirtualPointer.cpp b/src/devices/VirtualPointer.cpp
new file mode 100644
index 00000000..8f8699a2
--- /dev/null
+++ b/src/devices/VirtualPointer.cpp
@@ -0,0 +1,170 @@
+#include "VirtualPointer.hpp"
+#include "../protocols/VirtualPointer.hpp"
+
+SP<CVirtualPointer> CVirtualPointer::create(SP<CVirtualPointerV1Resource> resource) {
+ SP<CVirtualPointer> pPointer = SP<CVirtualPointer>(new CVirtualPointer(resource));
+
+ pPointer->self = pPointer;
+
+ return pPointer;
+}
+
+CVirtualPointer::CVirtualPointer(SP<CVirtualPointerV1Resource> resource) : pointer(resource) {
+ if (!resource->good())
+ return;
+
+ auto mouse = resource->wlr();
+
+ // clang-format off
+ hyprListener_destroy.initCallback(&mouse->base.events.destroy, [this] (void* owner, void* data) {
+ disconnectCallbacks();
+ events.destroy.emit();
+ }, this, "CVirtualPointer");
+
+ hyprListener_motion.initCallback(&mouse->events.motion, [this] (void* owner, void* data) {
+ auto E = (wlr_pointer_motion_event*)data;
+
+ pointerEvents.motion.emit(SMotionEvent{
+ .timeMs = E->time_msec,
+ .delta = {E->delta_x, E->delta_y},
+ .unaccel = {E->unaccel_dx, E->unaccel_dy},
+ });
+ }, this, "CVirtualPointer");
+
+ hyprListener_motionAbsolute.initCallback(&mouse->events.motion_absolute, [this] (void* owner, void* data) {
+ auto E = (wlr_pointer_motion_absolute_event*)data;
+
+ pointerEvents.motionAbsolute.emit(SMotionAbsoluteEvent{
+ .timeMs = E->time_msec,
+ .absolute = {E->x, E->y},
+ });
+ }, this, "CVirtualPointer");
+
+ hyprListener_button.initCallback(&mouse->events.button, [this] (void* owner, void* data) {
+ auto E = (wlr_pointer_button_event*)data;
+
+ pointerEvents.button.emit(SButtonEvent{
+ .timeMs = E->time_msec,
+ .button = E->button,
+ .state = (wl_pointer_button_state)E->state,
+ });
+ }, this, "CVirtualPointer");
+
+ hyprListener_axis.initCallback(&mouse->events.axis, [this] (void* owner, void* data) {
+ auto E = (wlr_pointer_axis_event*)data;
+
+ pointerEvents.axis.emit(SAxisEvent{
+ .timeMs = E->time_msec,
+ .source = E->source,
+ .axis = E->orientation,
+ .relativeDirection = E->relative_direction,
+ .delta = E->delta,
+ .deltaDiscrete = E->delta_discrete,
+ });
+ }, this, "CVirtualPointer");
+
+ hyprListener_swipeBegin.initCallback(&mouse->events.swipe_begin, [this] (void* owner, void* data) {
+ auto E = (wlr_pointer_swipe_begin_event*)data;
+
+ pointerEvents.swipeBegin.emit(SSwipeBeginEvent{
+ .timeMs = E->time_msec,
+ .fingers = E->fingers,
+ });
+ }, this, "CVirtualPointer");
+
+ hyprListener_swipeEnd.initCallback(&mouse->events.swipe_end, [this] (void* owner, void* data) {
+ auto E = (wlr_pointer_swipe_end_event*)data;
+
+ pointerEvents.swipeEnd.emit(SSwipeEndEvent{
+ .timeMs = E->time_msec,
+ .cancelled = E->cancelled,
+ });
+ }, this, "CVirtualPointer");
+
+ hyprListener_swipeUpdate.initCallback(&mouse->events.swipe_update, [this] (void* owner, void* data) {
+ auto E = (wlr_pointer_swipe_update_event*)data;
+
+ pointerEvents.swipeUpdate.emit(SSwipeUpdateEvent{
+ .timeMs = E->time_msec,
+ .fingers = E->fingers,
+ .delta = {E->dx, E->dy},
+ });
+ }, this, "CVirtualPointer");
+
+ hyprListener_pinchBegin.initCallback(&mouse->events.pinch_begin, [this] (void* owner, void* data) {
+ auto E = (wlr_pointer_pinch_begin_event*)data;
+
+ pointerEvents.pinchBegin.emit(SPinchBeginEvent{
+ .timeMs = E->time_msec,
+ .fingers = E->fingers,
+ });
+ }, this, "CVirtualPointer");
+
+ hyprListener_pinchEnd.initCallback(&mouse->events.pinch_end, [this] (void* owner, void* data) {
+ auto E = (wlr_pointer_pinch_end_event*)data;
+
+ pointerEvents.pinchEnd.emit(SPinchEndEvent{
+ .timeMs = E->time_msec,
+ .cancelled = E->cancelled,
+ });
+ }, this, "CVirtualPointer");
+
+ hyprListener_pinchUpdate.initCallback(&mouse->events.pinch_update, [this] (void* owner, void* data) {
+ auto E = (wlr_pointer_pinch_update_event*)data;
+
+ pointerEvents.pinchUpdate.emit(SPinchUpdateEvent{
+ .timeMs = E->time_msec,
+ .fingers = E->fingers,
+ .delta = {E->dx, E->dy},
+ .scale = E->scale,
+ .rotation = E->rotation,
+ });
+ }, this, "CVirtualPointer");
+
+ hyprListener_holdBegin.initCallback(&mouse->events.hold_begin, [this] (void* owner, void* data) {
+ auto E = (wlr_pointer_hold_begin_event*)data;
+
+ pointerEvents.holdBegin.emit(SHoldBeginEvent{
+ .timeMs = E->time_msec,
+ .fingers = E->fingers,
+ });
+ }, this, "CVirtualPointer");
+
+ hyprListener_holdEnd.initCallback(&mouse->events.hold_end, [this] (void* owner, void* data) {
+ auto E = (wlr_pointer_hold_end_event*)data;
+
+ pointerEvents.holdEnd.emit(SHoldEndEvent{
+ .timeMs = E->time_msec,
+ .cancelled = E->cancelled,
+ });
+ }, this, "CVirtualPointer");
+
+ // clang-format on
+
+ deviceName = mouse->base.name ? mouse->base.name : "UNKNOWN";
+}
+
+bool CVirtualPointer::isVirtual() {
+ return true;
+}
+
+void CVirtualPointer::disconnectCallbacks() {
+ hyprListener_destroy.removeCallback();
+ hyprListener_motion.removeCallback();
+ hyprListener_motionAbsolute.removeCallback();
+ hyprListener_button.removeCallback();
+ hyprListener_axis.removeCallback();
+ hyprListener_frame.removeCallback();
+ hyprListener_swipeBegin.removeCallback();
+ hyprListener_swipeEnd.removeCallback();
+ hyprListener_swipeUpdate.removeCallback();
+ hyprListener_pinchBegin.removeCallback();
+ hyprListener_pinchEnd.removeCallback();
+ hyprListener_pinchUpdate.removeCallback();
+ hyprListener_holdBegin.removeCallback();
+ hyprListener_holdEnd.removeCallback();
+}
+
+wlr_pointer* CVirtualPointer::wlr() {
+ return pointer.lock()->wlr();
+}
diff --git a/src/devices/VirtualPointer.hpp b/src/devices/VirtualPointer.hpp
new file mode 100644
index 00000000..b22c8bf2
--- /dev/null
+++ b/src/devices/VirtualPointer.hpp
@@ -0,0 +1,38 @@
+#pragma once
+
+#include "IPointer.hpp"
+
+class CVirtualPointerV1Resource;
+
+class CVirtualPointer : public IPointer {
+ public:
+ static SP<CVirtualPointer> create(SP<CVirtualPointerV1Resource> resource);
+
+ virtual bool isVirtual();
+ virtual wlr_pointer* wlr();
+
+ private:
+ CVirtualPointer(SP<CVirtualPointerV1Resource>);
+
+ WP<CVirtualPointerV1Resource> pointer;
+
+ void disconnectCallbacks();
+
+ DYNLISTENER(destroy);
+ DYNLISTENER(motion);
+ DYNLISTENER(motionAbsolute);
+ DYNLISTENER(button);
+ DYNLISTENER(axis);
+ DYNLISTENER(frame);
+
+ DYNLISTENER(swipeBegin);
+ DYNLISTENER(swipeEnd);
+ DYNLISTENER(swipeUpdate);
+
+ DYNLISTENER(pinchBegin);
+ DYNLISTENER(pinchEnd);
+ DYNLISTENER(pinchUpdate);
+
+ DYNLISTENER(holdBegin);
+ DYNLISTENER(holdEnd);
+}; \ No newline at end of file
diff --git a/src/events/Devices.cpp b/src/events/Devices.cpp
index ec0b14c4..1de1b768 100644
--- a/src/events/Devices.cpp
+++ b/src/events/Devices.cpp
@@ -16,23 +16,6 @@
// //
// ---------------------------------------------------- //
-void Events::listener_keyboardDestroy(void* owner, void* data) {
- SKeyboard* PKEYBOARD = (SKeyboard*)owner;
- g_pInputManager->destroyKeyboard(PKEYBOARD);
-
- Debug::log(LOG, "Destroyed keyboard {:x}", (uintptr_t)PKEYBOARD);
-}
-
-void Events::listener_keyboardKey(void* owner, void* data) {
- SKeyboard* PKEYBOARD = (SKeyboard*)owner;
- g_pInputManager->onKeyboardKey((wlr_keyboard_key_event*)data, PKEYBOARD);
-}
-
-void Events::listener_keyboardMod(void* owner, void* data) {
- SKeyboard* PKEYBOARD = (SKeyboard*)owner;
- g_pInputManager->onKeyboardMod(data, PKEYBOARD);
-}
-
void Events::listener_mouseFrame(wl_listener* listener, void* data) {
wlr_seat_pointer_notify_frame(g_pCompositor->m_sSeat.seat);
}
@@ -93,12 +76,6 @@ void Events::listener_newInput(wl_listener* listener, void* data) {
g_pInputManager->updateCapabilities();
}
-void Events::listener_destroyMouse(void* owner, void* data) {
- const auto PMOUSE = (SMouse*)owner;
-
- g_pInputManager->destroyMouse(PMOUSE->mouse);
-}
-
void Events::listener_swipeBegin(wl_listener* listener, void* data) {
const auto EVENT = (wlr_pointer_swipe_begin_event*)data;
diff --git a/src/events/Events.hpp b/src/events/Events.hpp
index 5fa93c49..830ca8d1 100644
--- a/src/events/Events.hpp
+++ b/src/events/Events.hpp
@@ -54,11 +54,6 @@ namespace Events {
// Virt Ptr
LISTENER(newVirtPtr);
- DYNLISTENFUNC(destroyMouse);
-
- DYNLISTENFUNC(keyboardKey);
- DYNLISTENFUNC(keyboardMod);
- DYNLISTENFUNC(keyboardDestroy);
// Various
LISTENER(requestMouse);
diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp
index dfc694c0..e3d06691 100644
--- a/src/events/Windows.cpp
+++ b/src/events/Windows.cpp
@@ -667,7 +667,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
g_pCompositor->setPreferredScaleForSurface(PWINDOW->m_pWLSurface.wlr(), PMONITOR->scale);
g_pCompositor->setPreferredTransformForSurface(PWINDOW->m_pWLSurface.wlr(), PMONITOR->transform);
- if (!g_pCompositor->m_sSeat.mouse || !g_pInputManager->isConstrained())
+ if (g_pCompositor->m_sSeat.mouse.expired() || !g_pInputManager->isConstrained())
g_pInputManager->sendMotionEventsToFocused();
// fix some xwayland apps that don't behave nicely
diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp
index ffa8b7d8..1369244d 100644
--- a/src/helpers/Monitor.cpp
+++ b/src/helpers/Monitor.cpp
@@ -3,6 +3,7 @@
#include "../Compositor.hpp"
#include "../config/ConfigValue.hpp"
#include "../protocols/GammaControl.hpp"
+#include "../devices/ITouch.hpp"
int ratHandler(void* data) {
g_pHyprRenderer->renderMonitor((CMonitor*)data);
@@ -145,10 +146,10 @@ void CMonitor::onConnect(bool noRule) {
if (!noRule)
g_pHyprRenderer->applyMonitorRule(this, &monitorRule, true);
- for (const auto& PTOUCHDEV : g_pInputManager->m_lTouchDevices) {
- if (matchesStaticSelector(PTOUCHDEV.boundOutput)) {
- Debug::log(LOG, "Binding touch device {} to output {}", PTOUCHDEV.name, szName);
- wlr_cursor_map_input_to_output(g_pCompositor->m_sWLRCursor, PTOUCHDEV.pWlrDevice, output);
+ for (const auto& PTOUCHDEV : g_pInputManager->m_vTouches) {
+ if (matchesStaticSelector(PTOUCHDEV->boundOutput)) {
+ Debug::log(LOG, "Binding touch device {} to output {}", PTOUCHDEV->hlName, szName);
+ wlr_cursor_map_input_to_output(g_pCompositor->m_sWLRCursor, &PTOUCHDEV->wlr()->base, output);
}
}
diff --git a/src/helpers/WLClasses.cpp b/src/helpers/WLClasses.cpp
index 4cdde4a0..61ab1133 100644
--- a/src/helpers/WLClasses.cpp
+++ b/src/helpers/WLClasses.cpp
@@ -1,78 +1 @@
#include "WLClasses.hpp"
-
-void SKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) {
- xkb_state_unref(xkbTranslationState);
-
- if (keymap) {
- Debug::log(LOG, "Updating keyboard {:x}'s translation state from a provided keymap", (uintptr_t)this);
- xkbTranslationState = xkb_state_new(keymap);
- return;
- }
-
- const auto WLRKB = wlr_keyboard_from_input_device(keyboard);
- const auto KEYMAP = WLRKB->keymap;
- const auto STATE = WLRKB->xkb_state;
- const auto LAYOUTSNUM = xkb_keymap_num_layouts(KEYMAP);
-
- const auto PCONTEXT = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
-
- for (uint32_t i = 0; i < LAYOUTSNUM; ++i) {
- if (xkb_state_layout_index_is_active(STATE, i, XKB_STATE_LAYOUT_EFFECTIVE)) {
- Debug::log(LOG, "Updating keyboard {:x}'s translation state from an active index {}", (uintptr_t)this, i);
-
- CVarList keyboardLayouts(currentRules.layout, 0, ',');
- CVarList keyboardModels(currentRules.model, 0, ',');
- CVarList keyboardVariants(currentRules.variant, 0, ',');
-
- xkb_rule_names rules = {.rules = "", .model = "", .layout = "", .variant = "", .options = ""};
-
- std::string layout, model, variant;
- layout = keyboardLayouts[i % keyboardLayouts.size()];
- model = keyboardModels[i % keyboardModels.size()];
- variant = keyboardVariants[i % keyboardVariants.size()];
-
- rules.layout = layout.c_str();
- rules.model = model.c_str();
- rules.variant = variant.c_str();
-
- auto KEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
-
- if (!KEYMAP) {
- Debug::log(ERR, "updateXKBTranslationState: keymap failed 1, fallback without model/variant");
- rules.model = "";
- rules.variant = "";
- KEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
- }
-
- if (!KEYMAP) {
- Debug::log(ERR, "updateXKBTranslationState: keymap failed 2, fallback to us");
- rules.layout = "us";
- KEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
- }
-
- xkbTranslationState = xkb_state_new(KEYMAP);
-
- xkb_keymap_unref(KEYMAP);
- xkb_context_unref(PCONTEXT);
-
- return;
- }
- }
-
- Debug::log(LOG, "Updating keyboard {:x}'s translation state from an unknown index", (uintptr_t)this);
-
- xkb_rule_names rules = {
- .rules = currentRules.rules.c_str(),
- .model = currentRules.model.c_str(),
- .layout = currentRules.layout.c_str(),
- .variant = currentRules.variant.c_str(),
- .options = currentRules.options.c_str(),
- };
-
- const auto NEWKEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
-
- xkbTranslationState = xkb_state_new(NEWKEYMAP);
-
- xkb_keymap_unref(NEWKEYMAP);
- xkb_context_unref(PCONTEXT);
-}
diff --git a/src/helpers/WLClasses.hpp b/src/helpers/WLClasses.hpp
index c625aae0..bed2b915 100644
--- a/src/helpers/WLClasses.hpp
+++ b/src/helpers/WLClasses.hpp
@@ -11,8 +11,8 @@
#include "Region.hpp"
class CMonitor;
-class CVirtualKeyboard;
-class CVirtualPointer;
+class IPointer;
+class IKeyboard;
struct SRenderData {
CMonitor* pMonitor;
@@ -58,86 +58,12 @@ struct SExtensionFindingData {
wlr_surface** found;
};
-struct SStringRuleNames {
- std::string layout = "";
- std::string model = "";
- std::string variant = "";
- std::string options = "";
- std::string rules = "";
-};
-
-struct SKeyboard {
- wlr_input_device* keyboard;
-
- DYNLISTENER(keyboardMod);
- DYNLISTENER(keyboardKey);
- DYNLISTENER(keyboardKeymap);
- DYNLISTENER(keyboardDestroy);
-
- bool isVirtual = false;
- bool active = false;
- bool enabled = true;
-
- WP<CVirtualKeyboard> virtKeyboard;
-
- xkb_layout_index_t activeLayout = 0;
- xkb_state* xkbTranslationState = nullptr;
-
- std::string name = "";
- std::string xkbFilePath = "";
-
- SStringRuleNames currentRules;
- int repeatRate = 0;
- int repeatDelay = 0;
- int numlockOn = -1;
- bool resolveBindsBySym = false;
-
- void updateXKBTranslationState(xkb_keymap* const keymap = nullptr);
-
- struct {
- CHyprSignalListener destroyVKeyboard;
- } listeners;
-
- // For the list lookup
- bool operator==(const SKeyboard& rhs) const {
- return keyboard == rhs.keyboard;
- }
-
- ~SKeyboard() {
- if (xkbTranslationState)
- xkb_state_unref(xkbTranslationState);
- }
-};
-
-struct SMouse {
- wlr_input_device* mouse = nullptr;
-
- std::string name = "";
-
- bool virt = false;
-
- bool connected = false; // means connected to the cursor
-
- WP<CVirtualPointer> virtualPointer;
-
- struct {
- CHyprSignalListener destroyMouse;
- } listeners;
-
- DYNLISTENER(destroyMouse);
-
- bool operator==(const SMouse& b) const {
- return mouse == b.mouse;
- }
-};
-
-class CMonitor;
-
struct SSeat {
- wlr_seat* seat = nullptr;
- wl_client* exclusiveClient = nullptr;
+ wlr_seat* seat = nullptr;
+ wl_client* exclusiveClient = nullptr;
- SMouse* mouse = nullptr;
+ WP<IPointer> mouse;
+ WP<IKeyboard> keyboard;
};
struct SDrag {
@@ -238,20 +164,6 @@ struct SSwipeGesture {
CMonitor* pMonitor = nullptr;
};
-struct STouchDevice {
- wlr_input_device* pWlrDevice = nullptr;
-
- std::string name = "";
-
- std::string boundOutput = "";
-
- DYNLISTENER(destroy);
-
- bool operator==(const STouchDevice& other) const {
- return pWlrDevice == other.pWlrDevice;
- }
-};
-
struct SSwitchDevice {
wlr_input_device* pWlrDevice = nullptr;
diff --git a/src/helpers/signal/Listener.cpp b/src/helpers/signal/Listener.cpp
index ae506343..4023477f 100644
--- a/src/helpers/signal/Listener.cpp
+++ b/src/helpers/signal/Listener.cpp
@@ -11,3 +11,11 @@ void CSignalListener::emit(std::any data) {
m_fHandler(data);
}
+
+CStaticSignalListener::CStaticSignalListener(std::function<void(void*, std::any)> handler, void* owner) : m_pOwner(owner), m_fHandler(handler) {
+ ;
+}
+
+void CStaticSignalListener::emit(std::any data) {
+ m_fHandler(m_pOwner, data);
+}
diff --git a/src/helpers/signal/Listener.hpp b/src/helpers/signal/Listener.hpp
index d2edb253..7ca96e87 100644
--- a/src/helpers/signal/Listener.hpp
+++ b/src/helpers/signal/Listener.hpp
@@ -22,3 +22,19 @@ class CSignalListener {
};
typedef std::shared_ptr<CSignalListener> CHyprSignalListener;
+
+class CStaticSignalListener {
+ public:
+ CStaticSignalListener(std::function<void(void*, std::any)> handler, void* owner);
+
+ CStaticSignalListener(CStaticSignalListener&&) = delete;
+ CStaticSignalListener(CStaticSignalListener&) = delete;
+ CStaticSignalListener(const CStaticSignalListener&) = delete;
+ CStaticSignalListener(const CStaticSignalListener&&) = delete;
+
+ void emit(std::any data);
+
+ private:
+ void* m_pOwner = nullptr;
+ std::function<void(void*, std::any)> m_fHandler;
+}; \ No newline at end of file
diff --git a/src/helpers/signal/Signal.cpp b/src/helpers/signal/Signal.cpp
index 204aaf00..d105eb78 100644
--- a/src/helpers/signal/Signal.cpp
+++ b/src/helpers/signal/Signal.cpp
@@ -11,6 +11,10 @@ void CSignal::emit(std::any data) {
dirty = true;
}
+ for (auto& l : m_vStaticListeners) {
+ l->emit(data);
+ }
+
if (dirty)
std::erase_if(m_vListeners, [](const auto& other) { return other.expired(); });
}
@@ -20,3 +24,7 @@ CHyprSignalListener CSignal::registerListener(std::function<void(std::any)> hand
m_vListeners.emplace_back(std::weak_ptr<CSignalListener>(listener));
return listener;
}
+
+void CSignal::registerStaticListener(std::function<void(void*, std::any)> handler, void* owner) {
+ m_vStaticListeners.emplace_back(std::make_unique<CStaticSignalListener>(handler, owner));
+} \ No newline at end of file
diff --git a/src/helpers/signal/Signal.hpp b/src/helpers/signal/Signal.hpp
index f12d0dc4..8938a70c 100644
--- a/src/helpers/signal/Signal.hpp
+++ b/src/helpers/signal/Signal.hpp
@@ -14,6 +14,11 @@ class CSignal {
//
[[nodiscard("Listener is unregistered when the ptr is lost")]] CHyprSignalListener registerListener(std::function<void(std::any)> handler);
+ // this is for static listeners. They die with this signal.
+ // TODO: can we somehow rid of the void* data and make it a custom this?
+ void registerStaticListener(std::function<void(void*, std::any)> handler, void* owner);
+
private:
- std::vector<std::weak_ptr<CSignalListener>> m_vListeners;
+ std::vector<std::weak_ptr<CSignalListener>> m_vListeners;
+ std::vector<std::unique_ptr<CStaticSignalListener>> m_vStaticListeners;
};
diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp
index 4e98a301..7708a77a 100644
--- a/src/managers/KeybindManager.cpp
+++ b/src/managers/KeybindManager.cpp
@@ -5,6 +5,7 @@
#include "../config/ConfigValue.hpp"
#include "TokenManager.hpp"
#include "../protocols/ShortcutsInhibit.hpp"
+#include "../devices/IKeyboard.hpp"
#include <regex>
#include <tuple>
@@ -323,7 +324,7 @@ void CKeybindManager::switchToWindow(PHLWINDOW PWINDOWTOCHANGETO) {
}
};
-bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard) {
+bool CKeybindManager::onKeyEvent(std::any event, SP<IKeyboard> pKeyboard) {
if (!g_pCompositor->m_bSessionActive || g_pCompositor->m_bUnsafeState) {
m_dPressedKeys.clear();
return true;
@@ -337,17 +338,19 @@ bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard
return true;
}
- const auto KEYCODE = e->keycode + 8; // Because to xkbcommon it's +8 from libinput
+ auto e = std::any_cast<IKeyboard::SKeyEvent>(event);
+
+ const auto KEYCODE = e.keycode + 8; // Because to xkbcommon it's +8 from libinput
const xkb_keysym_t keysym = xkb_state_key_get_one_sym(pKeyboard->resolveBindsBySym ? pKeyboard->xkbTranslationState : m_pXKBTranslationState, KEYCODE);
- const xkb_keysym_t internalKeysym = xkb_state_key_get_one_sym(wlr_keyboard_from_input_device(pKeyboard->keyboard)->xkb_state, KEYCODE);
+ const xkb_keysym_t internalKeysym = xkb_state_key_get_one_sym(pKeyboard->wlr()->xkb_state, KEYCODE);
if (handleInternalKeybinds(internalKeysym))
return true;
const auto MODS = g_pInputManager->accumulateModsFromAllKBs();
- m_uTimeLastMs = e->time_msec;
+ m_uTimeLastMs = e.timeMs;
m_uLastCode = KEYCODE;
m_uLastMouseCode = 0;
@@ -368,7 +371,7 @@ bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard
}
bool suppressEvent = false;
- if (e->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
+ if (e.state == WL_KEYBOARD_KEY_STATE_PRESSED) {
m_dPressedKeys.push_back(KEY);
@@ -521,7 +524,7 @@ void CKeybindManager::onSwitchOffEvent(const std::string& switchName) {
int repeatKeyHandler(void* data) {
SKeybind** ppActiveKeybind = (SKeybind**)data;
- if (!*ppActiveKeybind)
+ if (!*ppActiveKeybind || g_pCompositor->m_sSeat.keyboard.expired())
return 0;
const auto DISPATCHER = g_pKeybindManager->m_mDispatchers.find((*ppActiveKeybind)->handler);
@@ -529,7 +532,7 @@ int repeatKeyHandler(void* data) {
Debug::log(LOG, "Keybind repeat triggered, calling dispatcher.");
DISPATCHER->second((*ppActiveKeybind)->arg);
- wl_event_source_timer_update(g_pKeybindManager->m_pActiveKeybindEventSource, 1000 / g_pInputManager->m_pActiveKeyboard->repeatRate);
+ wl_event_source_timer_update(g_pKeybindManager->m_pActiveKeybindEventSource, 1000 / g_pCompositor->m_sSeat.keyboard.lock()->repeatRate);
return 0;
}
@@ -650,7 +653,7 @@ bool CKeybindManager::handleKeybinds(const uint32_t modmask, const SPressedKeyWi
m_pActiveKeybind = &k;
m_pActiveKeybindEventSource = wl_event_loop_add_timer(g_pCompositor->m_sWLEventLoop, repeatKeyHandler, &m_pActiveKeybind);
- const auto PACTIVEKEEB = g_pInputManager->m_pActiveKeyboard;
+ const auto PACTIVEKEEB = g_pCompositor->m_sSeat.keyboard.lock();
wl_event_source_timer_update(m_pActiveKeybindEventSource, PACTIVEKEEB->repeatDelay);
}
@@ -1440,22 +1443,20 @@ void CKeybindManager::moveCursorToCorner(std::string arg) {
switch (CORNER) {
case 0:
// bottom left
- wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, PWINDOW->m_vRealPosition.value().x,
- PWINDOW->m_vRealPosition.value().y + PWINDOW->m_vRealSize.value().y);
+ wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, PWINDOW->m_vRealPosition.value().x, PWINDOW->m_vRealPosition.value().y + PWINDOW->m_vRealSize.value().y);
break;
case 1:
// bottom right
- wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, PWINDOW->m_vRealPosition.value().x + PWINDOW->m_vRealSize.value().x,
+ wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, PWINDOW->m_vRealPosition.value().x + PWINDOW->m_vRealSize.value().x,
PWINDOW->m_vRealPosition.value().y + PWINDOW->m_vRealSize.value().y);
break;
case 2:
// top right
- wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, PWINDOW->m_vRealPosition.value().x + PWINDOW->m_vRealSize.value().x,
- PWINDOW->m_vRealPosition.value().y);
+ wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, PWINDOW->m_vRealPosition.value().x + PWINDOW->m_vRealSize.value().x, PWINDOW->m_vRealPosition.value().y);
break;
case 3:
// top left
- wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, PWINDOW->m_vRealPosition.value().x, PWINDOW->m_vRealPosition.value().y);
+ wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, PWINDOW->m_vRealPosition.value().x, PWINDOW->m_vRealPosition.value().y);
break;
}
}
@@ -1485,7 +1486,7 @@ void CKeybindManager::moveCursor(std::string args) {
x = std::stoi(x_str);
y = std::stoi(y_str);
- wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, x, y);
+ wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, x, y);
}
void CKeybindManager::workspaceOpt(std::string args) {
diff --git a/src/managers/KeybindManager.hpp b/src/managers/KeybindManager.hpp
index 24e71c6a..c382f3eb 100644
--- a/src/managers/KeybindManager.hpp
+++ b/src/managers/KeybindManager.hpp
@@ -9,6 +9,7 @@
class CInputManager;
class CConfigManager;
class CPluginSystem;
+class IKeyboard;
struct SKeybind {
std::string key = "";
@@ -60,7 +61,7 @@ class CKeybindManager {
CKeybindManager();
~CKeybindManager();
- bool onKeyEvent(wlr_keyboard_key_event*, SKeyboard*);
+ bool onKeyEvent(std::any, SP<IKeyboard>);
bool onAxisEvent(wlr_pointer_axis_event*);
bool onMouseEvent(wlr_pointer_button_event*);
void resizeWithBorder(wlr_pointer_button_event*);
diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp
index fb9d2b8a..10b12404 100644
--- a/src/managers/input/InputManager.cpp
+++ b/src/managers/input/InputManager.cpp
@@ -14,6 +14,12 @@
#include "../../protocols/VirtualKeyboard.hpp"
#include "../../protocols/VirtualPointer.hpp"
+#include "../../devices/Mouse.hpp"
+#include "../../devices/VirtualPointer.hpp"
+#include "../../devices/Keyboard.hpp"
+#include "../../devices/VirtualKeyboard.hpp"
+#include "../../devices/TouchDevice.hpp"
+
CInputManager::CInputManager() {
m_sListeners.setCursorShape = PROTO::cursorShape->events.setShape.registerListener([this](std::any data) {
if (!cursorImageUnlocked())
@@ -40,20 +46,20 @@ CInputManager::CInputManager() {
m_sListeners.newIdleInhibitor = PROTO::idleInhibit->events.newIdleInhibitor.registerListener([this](std::any data) { this->newIdleInhibitor(data); });
m_sListeners.newVirtualKeyboard =
- PROTO::virtualKeyboard->events.newKeyboard.registerListener([this](std::any data) { this->newVirtualKeyboard(std::any_cast<SP<CVirtualKeyboard>>(data)); });
+ PROTO::virtualKeyboard->events.newKeyboard.registerListener([this](std::any data) { this->newVirtualKeyboard(std::any_cast<SP<CVirtualKeyboardV1Resource>>(data)); });
m_sListeners.newVirtualMouse =
- PROTO::virtualPointer->events.newPointer.registerListener([this](std::any data) { this->newVirtualMouse(std::any_cast<SP<CVirtualPointer>>(data)); });
+ PROTO::virtualPointer->events.newPointer.registerListener([this](std::any data) { this->newVirtualMouse(std::any_cast<SP<CVirtualPointerV1Resource>>(data)); });
}
CInputManager::~CInputManager() {
m_vConstraints.clear();
- m_lKeyboards.clear();
- m_lMice.clear();
+ m_vKeyboards.clear();
+ m_vPointers.clear();
+ m_vTouches.clear();
m_lTablets.clear();
m_lTabletTools.clear();
m_lTabletPads.clear();
m_vIdleInhibitors.clear();
- m_lTouchDevices.clear();
m_lSwitches.clear();
}
@@ -181,7 +187,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
}
// constraints
- if (g_pCompositor->m_sSeat.mouse && isConstrained()) {
+ if (!g_pCompositor->m_sSeat.mouse.expired() && isConstrained()) {
const auto SURF = CWLSurface::surfaceFromWlr(g_pCompositor->m_pLastFocus);
const auto CONSTRAINT = SURF->constraint();
@@ -651,7 +657,7 @@ void CInputManager::processMouseDownNormal(wlr_pointer_button_event* e) {
if (*PFOLLOWMOUSE == 3) // don't refocus on full loose
break;
- if ((!g_pCompositor->m_sSeat.mouse || !isConstrained()) /* No constraints */
+ if ((g_pCompositor->m_sSeat.mouse.expired() || !isConstrained()) /* No constraints */
&& (w && g_pCompositor->m_pLastWindow.lock() != w) /* window should change */) {
// a bit hacky
// if we only pressed one button, allow us to refocus. m_lCurrentlyHeldButtons.size() > 0 will stick the focus
@@ -754,105 +760,84 @@ Vector2D CInputManager::getMouseCoordsInternal() {
}
void CInputManager::newKeyboard(wlr_input_device* keyboard) {
- const auto PNEWKEYBOARD = &m_lKeyboards.emplace_back();
-
- PNEWKEYBOARD->keyboard = keyboard;
-
- try {
- PNEWKEYBOARD->name = getNameForNewDevice(keyboard->name);
- } catch (std::exception& e) {
- Debug::log(ERR, "Keyboard had no name???"); // logic error
- }
-
- PNEWKEYBOARD->hyprListener_keyboardMod.initCallback(&wlr_keyboard_from_input_device(keyboard)->events.modifiers, &Events::listener_keyboardMod, PNEWKEYBOARD, "Keyboard");
- PNEWKEYBOARD->hyprListener_keyboardKey.initCallback(&wlr_keyboard_from_input_device(keyboard)->events.key, &Events::listener_keyboardKey, PNEWKEYBOARD, "Keyboard");
- PNEWKEYBOARD->hyprListener_keyboardDestroy.initCallback(&keyboard->events.destroy, &Events::listener_keyboardDestroy, PNEWKEYBOARD, "Keyboard");
-
- PNEWKEYBOARD->hyprListener_keyboardKeymap.initCallback(
- &wlr_keyboard_from_input_device(keyboard)->events.keymap,
- [&](void* owner, void* data) {
- const auto PKEYBOARD = (SKeyboard*)owner;
- const auto LAYOUT = getActiveLayoutForKeyboard(PKEYBOARD);
+ const auto PNEWKEYBOARD = m_vKeyboards.emplace_back(CKeyboard::create(wlr_keyboard_from_input_device(keyboard)));
- g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", PKEYBOARD->name + "," + LAYOUT});
- EMIT_HOOK_EVENT("activeLayout", (std::vector<void*>{PKEYBOARD, (void*)&LAYOUT}));
- },
- PNEWKEYBOARD, "Keyboard");
-
- disableAllKeyboards(false);
+ setupKeyboard(PNEWKEYBOARD);
- m_pActiveKeyboard = PNEWKEYBOARD;
-
- PNEWKEYBOARD->active = true;
+ Debug::log(LOG, "New keyboard created, pointers Hypr: {:x} and WLR: {:x}", (uintptr_t)PNEWKEYBOARD.get(), (uintptr_t)keyboard);
+}
- applyConfigToKeyboard(PNEWKEYBOARD);
+void CInputManager::newVirtualKeyboard(SP<CVirtualKeyboardV1Resource> keyboard) {
+ const auto PNEWKEYBOARD = m_vKeyboards.emplace_back(CVirtualKeyboard::create(keyboard));
- wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, wlr_keyboard_from_input_device(keyboard));
+ setupKeyboard(PNEWKEYBOARD);
- Debug::log(LOG, "New keyboard created, pointers Hypr: {:x} and WLR: {:x}", (uintptr_t)PNEWKEYBOARD, (uintptr_t)keyboard);
+ Debug::log(LOG, "New virtual keyboard created, pointers Hypr: {:x} and WLR: {:x}", (uintptr_t)PNEWKEYBOARD.get(), (uintptr_t)keyboard->wlr());
}
-void CInputManager::newVirtualKeyboard(SP<CVirtualKeyboard> keyboard) {
- const auto PNEWKEYBOARD = &m_lKeyboards.emplace_back();
-
- PNEWKEYBOARD->keyboard = &keyboard->wlr()->base;
- PNEWKEYBOARD->isVirtual = true;
- PNEWKEYBOARD->virtKeyboard = keyboard;
-
+void CInputManager::setupKeyboard(SP<IKeyboard> keeb) {
try {
- PNEWKEYBOARD->name = getNameForNewDevice(keyboard->wlr()->base.name);
+ keeb->hlName = getNameForNewDevice(keeb->wlr()->base.name);
} catch (std::exception& e) {
Debug::log(ERR, "Keyboard had no name???"); // logic error
}
- PNEWKEYBOARD->hyprListener_keyboardMod.initCallback(&keyboard->wlr()->events.modifiers, &Events::listener_keyboardMod, PNEWKEYBOARD, "VKeyboard");
- PNEWKEYBOARD->hyprListener_keyboardKey.initCallback(&keyboard->wlr()->events.key, &Events::listener_keyboardKey, PNEWKEYBOARD, "VKeyboard");
- PNEWKEYBOARD->hyprListener_keyboardDestroy.initCallback(&keyboard->wlr()->base.events.destroy, &Events::listener_keyboardDestroy, PNEWKEYBOARD, "VKeyboard");
- PNEWKEYBOARD->hyprListener_keyboardKeymap.initCallback(
- &keyboard->wlr()->events.keymap,
- [&](void* owner, void* data) {
- const auto PKEYBOARD = (SKeyboard*)owner;
- const auto LAYOUT = getActiveLayoutForKeyboard(PKEYBOARD);
+ keeb->events.destroy.registerStaticListener(
+ [this](void* owner, std::any data) {
+ auto PKEEB = ((IKeyboard*)owner)->self.lock();
+ destroyKeyboard(PKEEB);
+ Debug::log(LOG, "Destroyed keyboard {:x}", (uintptr_t)owner);
+ },
+ keeb.get());
- g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", PKEYBOARD->name + "," + LAYOUT});
- EMIT_HOOK_EVENT("activeLayout", (std::vector<void*>{PKEYBOARD, (void*)&LAYOUT}));
+ keeb->keyboardEvents.key.registerStaticListener(
+ [this](void* owner, std::any data) {
+ auto PKEEB = ((IKeyboard*)owner)->self.lock();
+ onKeyboardKey(data, PKEEB);
},
- PNEWKEYBOARD, "VKeyboard");
+ keeb.get());
- // TODO: this pointer pass sucks.
- PNEWKEYBOARD->listeners.destroyVKeyboard = keyboard->events.destroy.registerListener([this, PNEWKEYBOARD](std::any data) { destroyKeyboard(PNEWKEYBOARD); });
+ keeb->keyboardEvents.modifiers.registerStaticListener(
+ [this](void* owner, std::any data) {
+ auto PKEEB = ((IKeyboard*)owner)->self.lock();
+ onKeyboardMod(PKEEB);
+ },
+ keeb.get());
- disableAllKeyboards(true);
+ keeb->keyboardEvents.keymap.registerStaticListener(
+ [this](void* owner, std::any data) {
+ auto PKEEB = ((IKeyboard*)owner)->self.lock();
+ const auto LAYOUT = PKEEB->getActiveLayout();
- m_pActiveKeyboard = PNEWKEYBOARD;
+ g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", PKEEB->hlName + "," + LAYOUT});
+ EMIT_HOOK_EVENT("activeLayout", (std::vector<std::any>{PKEEB, LAYOUT}));
+ },
+ keeb.get());
+
+ disableAllKeyboards(false);
- PNEWKEYBOARD->active = true;
+ g_pCompositor->m_sSeat.keyboard = keeb;
- applyConfigToKeyboard(PNEWKEYBOARD);
+ keeb->active = true;
- wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, keyboard->wlr());
+ applyConfigToKeyboard(keeb);
- Debug::log(LOG, "New virtual keyboard created, pointers Hypr: {:x} and WLR: {:x}", (uintptr_t)PNEWKEYBOARD, (uintptr_t)keyboard->wlr());
+ wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, keeb->wlr());
}
void CInputManager::setKeyboardLayout() {
- for (auto& k : m_lKeyboards)
- applyConfigToKeyboard(&k);
+ for (auto& k : m_vKeyboards)
+ applyConfigToKeyboard(k);
g_pKeybindManager->updateXKBTranslationState();
}
-void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
- auto devname = pKeyboard->name;
+void CInputManager::applyConfigToKeyboard(SP<IKeyboard> pKeyboard) {
+ auto devname = pKeyboard->hlName;
const auto HASCONFIG = g_pConfigManager->deviceConfigExists(devname);
- Debug::log(LOG, "ApplyConfigToKeyboard for \"{}\", hasconfig: {}", pKeyboard->name, (int)HASCONFIG);
-
- ASSERT(pKeyboard);
-
- if (!wlr_keyboard_from_input_device(pKeyboard->keyboard))
- return;
+ Debug::log(LOG, "ApplyConfigToKeyboard for \"{}\", hasconfig: {}", devname, (int)HASCONFIG);
const auto REPEATRATE = g_pConfigManager->getDeviceInt(devname, "repeat_rate", "input:repeat_rate");
const auto REPEATDELAY = g_pConfigManager->getDeviceInt(devname, "repeat_delay", "input:repeat_delay");
@@ -884,7 +869,7 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
// we can ignore those and just apply
}
- wlr_keyboard_set_repeat_info(wlr_keyboard_from_input_device(pKeyboard->keyboard), std::max(0, REPEATRATE), std::max(0, REPEATDELAY));
+ wlr_keyboard_set_repeat_info(pKeyboard->wlr(), std::max(0, REPEATRATE), std::max(0, REPEATDELAY));
pKeyboard->repeatDelay = REPEATDELAY;
pKeyboard->repeatRate = REPEATRATE;
@@ -942,7 +927,7 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
KEYMAP = xkb_keymap_new_from_names(CONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
}
- wlr_keyboard_set_keymap(wlr_keyboard_from_input_device(pKeyboard->keyboard), KEYMAP);
+ wlr_keyboard_set_keymap(pKeyboard->wlr(), KEYMAP);
pKeyboard->updateXKBTranslationState();
@@ -957,105 +942,87 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
}
if (wlrMods.locked != 0)
- wlr_keyboard_notify_modifiers(wlr_keyboard_from_input_device(pKeyboard->keyboard), 0, 0, wlrMods.locked, 0);
+ wlr_keyboard_notify_modifiers(pKeyboard->wlr(), 0, 0, wlrMods.locked, 0);
xkb_keymap_unref(KEYMAP);
xkb_context_unref(CONTEXT);
- const auto LAYOUTSTR = getActiveLayoutForKeyboard(pKeyboard);
+ const auto LAYOUTSTR = pKeyboard->getActiveLayout();
- g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", pKeyboard->name + "," + LAYOUTSTR});
- EMIT_HOOK_EVENT("activeLayout", (std::vector<void*>{pKeyboard, (void*)&LAYOUTSTR}));
+ g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", pKeyboard->hlName + "," + LAYOUTSTR});
+ EMIT_HOOK_EVENT("activeLayout", (std::vector<std::any>{pKeyboard, LAYOUTSTR}));
- Debug::log(LOG, "Set the keyboard layout to {} and variant to {} for keyboard \"{}\"", pKeyboard->currentRules.layout, pKeyboard->currentRules.variant,
- pKeyboard->keyboard->name);
+ Debug::log(LOG, "Set the keyboard layout to {} and variant to {} for keyboard \"{}\"", pKeyboard->currentRules.layout, pKeyboard->currentRules.variant, pKeyboard->hlName);
}
-void CInputManager::newVirtualMouse(SP<CVirtualPointer> mouse) {
- const auto PMOUSE = &m_lMice.emplace_back();
+void CInputManager::newVirtualMouse(SP<CVirtualPointerV1Resource> mouse) {
+ const auto PMOUSE = m_vPointers.emplace_back(CVirtualPointer::create(mouse));
- PMOUSE->mouse = &mouse->wlr()->base;
- PMOUSE->virtualPointer = mouse;
- PMOUSE->virt = true;
- try {
- PMOUSE->name = getNameForNewDevice(mouse->wlr()->base.name);
- } catch (std::exception& e) {
- Debug::log(ERR, "Mouse had no name???"); // logic error
- }
-
- wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, &mouse->wlr()->base);
-
- PMOUSE->connected = true;
-
- setPointerConfigs();
-
- PMOUSE->hyprListener_destroyMouse.initCallback(&mouse->wlr()->base.events.destroy, &Events::listener_destroyMouse, PMOUSE, "Mouse");
-
- // TODO: this pointer pass sucks.
- PMOUSE->listeners.destroyMouse = mouse->events.destroy.registerListener([this, PMOUSE](std::any data) { destroyMouse(PMOUSE->mouse); });
-
- g_pCompositor->m_sSeat.mouse = PMOUSE;
-
- m_tmrLastCursorMovement.reset();
+ setupMouse(PMOUSE);
Debug::log(LOG, "New virtual mouse created, pointer WLR: {:x}", (uintptr_t)mouse->wlr());
}
void CInputManager::newMouse(wlr_input_device* mouse) {
- m_lMice.emplace_back();
- const auto PMOUSE = &m_lMice.back();
+ const auto PMOUSE = m_vPointers.emplace_back(CMouse::create(wlr_pointer_from_input_device(mouse)));
- PMOUSE->mouse = mouse;
+ setupMouse(PMOUSE);
+
+ Debug::log(LOG, "New mouse created, pointer WLR: {:x}", (uintptr_t)mouse);
+}
+
+void CInputManager::setupMouse(SP<IPointer> mauz) {
try {
- PMOUSE->name = getNameForNewDevice(mouse->name);
+ mauz->hlName = getNameForNewDevice(mauz->wlr()->base.name);
} catch (std::exception& e) {
Debug::log(ERR, "Mouse had no name???"); // logic error
}
- if (wlr_input_device_is_libinput(mouse)) {
- const auto LIBINPUTDEV = (libinput_device*)wlr_libinput_get_device_handle(mouse);
+ if (wlr_input_device_is_libinput(&mauz->wlr()->base)) {
+ const auto LIBINPUTDEV = (libinput_device*)wlr_libinput_get_device_handle(&mauz->wlr()->base);
Debug::log(LOG, "New mouse has libinput sens {:.2f} ({:.2f}) with accel profile {} ({})", libinput_device_config_accel_get_speed(LIBINPUTDEV),
libinput_device_config_accel_get_default_speed(LIBINPUTDEV), (int)libinput_device_config_accel_get_profile(LIBINPUTDEV),
(int)libinput_device_config_accel_get_default_profile(LIBINPUTDEV));
}
- wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, mouse);
+ wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, &mauz->wlr()->base);
- PMOUSE->connected = true;
+ mauz->connected = true;
setPointerConfigs();
- PMOUSE->hyprListener_destroyMouse.initCallback(&mouse->events.destroy, &Events::listener_destroyMouse, PMOUSE, "Mouse");
+ mauz->events.destroy.registerStaticListener(
+ [this](void* mouse, std::any data) {
+ const auto PMOUSE = (IPointer*)mouse;
+ destroyPointer(PMOUSE->self.lock());
+ },
+ mauz.get());
- g_pCompositor->m_sSeat.mouse = PMOUSE;
+ g_pCompositor->m_sSeat.mouse = mauz;
m_tmrLastCursorMovement.reset();
-
- Debug::log(LOG, "New mouse created, pointer WLR: {:x}", (uintptr_t)mouse);
}
void CInputManager::setPointerConfigs() {
- for (auto& m : m_lMice) {
- const auto PPOINTER = &m;
-
- auto devname = PPOINTER->name;
+ for (auto& m : m_vPointers) {
+ auto devname = m->hlName;
const auto HASCONFIG = g_pConfigManager->deviceConfigExists(devname);
if (HASCONFIG) {
const auto ENABLED = g_pConfigManager->getDeviceInt(devname, "enabled");
- if (ENABLED && !m.connected) {
- wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, m.mouse);
- m.connected = true;
- } else if (!ENABLED && m.connected) {
- wlr_cursor_detach_input_device(g_pCompositor->m_sWLRCursor, m.mouse);
- m.connected = false;
+ if (ENABLED && !m->connected) {
+ wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, &m->wlr()->base);
+ m->connected = true;
+ } else if (!ENABLED && m->connected) {
+ wlr_cursor_detach_input_device(g_pCompositor->m_sWLRCursor, &m->wlr()->base);
+ m->connected = false;
}
}
- if (wlr_input_device_is_libinput(m.mouse)) {
- const auto LIBINPUTDEV = (libinput_device*)wlr_libinput_get_device_handle(m.mouse);
+ if (wlr_input_device_is_libinput(&m->wlr()->base)) {
+ const auto LIBINPUTDEV = (libinput_device*)wlr_libinput_get_device_handle(&m->wlr()->base);
double touchw = 0, touchh = 0;
const auto ISTOUCHPAD = libinput_device_has_capability(LIBINPUTDEV, LIBINPUT_DEVICE_CAP_POINTER) &&
@@ -1184,73 +1151,50 @@ void CInputManager::setPointerConfigs() {
libinput_device_config_scroll_set_button_lock(LIBINPUTDEV,
SCROLLBUTTONLOCK == 0 ? LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_DISABLED : LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_ENABLED);
- Debug::log(LOG, "Applied config to mouse {}, sens {:.2f}", m.name, LIBINPUTSENS);
+ Debug::log(LOG, "Applied config to mouse {}, sens {:.2f}", m->hlName, LIBINPUTSENS);
}
}
}
-void CInputManager::destroyKeyboard(SKeyboard* pKeyboard) {
- pKeyboard->hyprListener_keyboardDestroy.removeCallback();
- pKeyboard->hyprListener_keyboardMod.removeCallback();
- pKeyboard->hyprListener_keyboardKey.removeCallback();
-
- xkb_state_unref(pKeyboard->xkbTranslationState);
+void CInputManager::destroyKeyboard(SP<IKeyboard> pKeyboard) {
+ if (pKeyboard->xkbTranslationState)
+ xkb_state_unref(pKeyboard->xkbTranslationState);
pKeyboard->xkbTranslationState = nullptr;
- m_lKeyboards.remove(*pKeyboard);
+ std::erase_if(m_vKeyboards, [pKeyboard](const auto& other) { return other == pKeyboard; });
- if (m_lKeyboards.size() > 0) {
- m_pActiveKeyboard = &m_lKeyboards.back();
- m_pActiveKeyboard->active = true;
- wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, wlr_keyboard_from_input_device(m_pActiveKeyboard->keyboard));
+ if (m_vKeyboards.size() > 0) {
+ g_pCompositor->m_sSeat.keyboard = m_vKeyboards.back();
+ g_pCompositor->m_sSeat.keyboard.lock()->active = true;
+ wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, g_pCompositor->m_sSeat.keyboard.lock()->wlr());
} else {
- m_pActiveKeyboard = nullptr;
+ g_pCompositor->m_sSeat.keyboard.reset();
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, nullptr);
}
}
-void CInputManager::destroyMouse(wlr_input_device* mouse) {
- for (auto& m : m_lMice) {
- if (m.mouse == mouse) {
- m_lMice.remove(m);
- break;
- }
- }
+void CInputManager::destroyPointer(SP<IPointer> mouse) {
+ std::erase_if(m_vPointers, [mouse](const auto& other) { return other == mouse; });
- g_pCompositor->m_sSeat.mouse = m_lMice.size() > 0 ? &m_lMice.front() : nullptr;
+ g_pCompositor->m_sSeat.mouse = m_vPointers.size() > 0 ? m_vPointers.front() : nullptr;
- if (g_pCompositor->m_sSeat.mouse)
+ if (!g_pCompositor->m_sSeat.mouse.expired())
unconstrainMouse();
}
-void CInputManager::updateKeyboardsLeds(wlr_input_device* pKeyboard) {
- auto keyboard = wlr_keyboard_from_input_device(pKeyboard);
-
- if (keyboard->xkb_state == NULL) {
- return;
- }
-
- uint32_t leds = 0;
- for (uint32_t i = 0; i < WLR_LED_COUNT; ++i) {
- if (xkb_state_led_index_is_active(keyboard->xkb_state, keyboard->led_indexes[i]))
- leds |= (1 << i);
- }
+void CInputManager::destroyTouchDevice(SP<ITouch> touch) {
+ Debug::log(LOG, "Touch device at {:x} removed", (uintptr_t)touch.get());
- for (auto& kb : m_lKeyboards) {
- if ((kb.isVirtual && shouldIgnoreVirtualKeyboard(&kb)) || kb.keyboard == pKeyboard)
- continue;
-
- wlr_keyboard_led_update(wlr_keyboard_from_input_device(kb.keyboard), leds);
- }
+ std::erase_if(m_vTouches, [touch](const auto& other) { return other == touch; });
}
-void CInputManager::onKeyboardKey(wlr_keyboard_key_event* e, SKeyboard* pKeyboard) {
+void CInputManager::onKeyboardKey(std::any event, SP<IKeyboard> pKeyboard) {
if (!pKeyboard->enabled)
return;
- const bool DISALLOWACTION = pKeyboard->isVirtual && shouldIgnoreVirtualKeyboard(pKeyboard);
+ const bool DISALLOWACTION = pKeyboard->isVirtual() && shouldIgnoreVirtualKeyboard(pKeyboard);
- const auto EMAP = std::unordered_map<std::string, std::any>{{"keyboard", pKeyboard}, {"event", e}};
+ const auto EMAP = std::unordered_map<std::string, std::any>{{"keyboard", pKeyboard}, {"event", event}};
EMIT_HOOK_EVENT_CANCELLABLE("keyPress", EMAP);
static auto PDPMS = CConfigValue<Hyprlang::INT>("misc:key_press_enables_dpms");
@@ -1259,7 +1203,9 @@ void CInputManager::onKeyboardKey(wlr_keyboard_key_event* e, SKeyboard* pKeyboar
g_pKeybindManager->dpms("on");
}
- bool passEvent = DISALLOWACTION || g_pKeybindManager->onKeyEvent(e, pKeyboard);
+ bool passEvent = DISALLOWACTION || g_pKeybindManager->onKeyEvent(event, pKeyboard);
+
+ auto e = std::any_cast<IKeyboard::SKeyEvent>(event);
PROTO::idle->onActivity();
@@ -1267,59 +1213,64 @@ void CInputManager::onKeyboardKey(wlr_keyboard_key_event* e, SKeyboard* pKeyboar
const auto IME = m_sIMERelay.m_pIME.lock();
if (IME && IME->hasGrab() && !DISALLOWACTION) {
- IME->setKeyboard(wlr_keyboard_from_input_device(pKeyboard->keyboard));
- IME->sendKey(e->time_msec, e->keycode, e->state);
+ IME->setKeyboard(pKeyboard->wlr());
+ IME->sendKey(e.timeMs, e.keycode, e.state);
} else {
- wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, wlr_keyboard_from_input_device(pKeyboard->keyboard));
- wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, e->time_msec, e->keycode, e->state);
+ wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, pKeyboard->wlr());
+ wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, e.timeMs, e.keycode, e.state);
}
- updateKeyboardsLeds(pKeyboard->keyboard);
+ for (auto& k : m_vKeyboards) {
+ k->updateLEDs();
+ }
}
}
-void CInputManager::onKeyboardMod(void* data, SKeyboard* pKeyboard) {
+void CInputManager::onKeyboardMod(SP<IKeyboard> pKeyboard) {
if (!pKeyboard->enabled)
return;
- const bool DISALLOWACTION = pKeyboard->isVirtual && shouldIgnoreVirtualKeyboard(pKeyboard);
+ const bool DISALLOWACTION = pKeyboard->isVirtual() && shouldIgnoreVirtualKeyboard(pKeyboard);
const auto ALLMODS = accumulateModsFromAllKBs();
+ const auto PWLRKB = pKeyboard->wlr();
- auto MODS = wlr_keyboard_from_input_device(pKeyboard->keyboard)->modifiers;
+ auto MODS = PWLRKB->modifiers;
MODS.depressed = ALLMODS;
const auto IME = m_sIMERelay.m_pIME.lock();
if (IME && IME->hasGrab() && !DISALLOWACTION) {
- IME->setKeyboard(wlr_keyboard_from_input_device(pKeyboard->keyboard));
+ IME->setKeyboard(PWLRKB);
IME->sendMods(MODS.depressed, MODS.latched, MODS.locked, MODS.group);
} else {
- wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, wlr_keyboard_from_input_device(pKeyboard->keyboard));
+ wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, PWLRKB);
wlr_seat_keyboard_notify_modifiers(g_pCompositor->m_sSeat.seat, &MODS);
}
- updateKeyboardsLeds(pKeyboard->keyboard);
-
- const auto PWLRKB = wlr_keyboard_from_input_device(pKeyboard->keyboard);
+ for (auto& k : m_vKeyboards) {
+ k->updateLEDs();
+ }
if (PWLRKB->modifiers.group != pKeyboard->activeLayout) {
pKeyboard->activeLayout = PWLRKB->modifiers.group;
- const auto LAYOUT = getActiveLayoutForKeyboard(pKeyboard);
+ const auto LAYOUT = pKeyboard->getActiveLayout();
pKeyboard->updateXKBTranslationState();
- g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", pKeyboard->name + "," + LAYOUT});
- EMIT_HOOK_EVENT("activeLayout", (std::vector<void*>{pKeyboard, (void*)&LAYOUT}));
+ g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", pKeyboard->hlName + "," + LAYOUT});
+ EMIT_HOOK_EVENT("activeLayout", (std::vector<std::any>{pKeyboard, LAYOUT}));
}
}
-bool CInputManager::shouldIgnoreVirtualKeyboard(SKeyboard* pKeyboard) {
- if (!pKeyboard->isVirtual)
+bool CInputManager::shouldIgnoreVirtualKeyboard(SP<IKeyboard> pKeyboard) {
+ if (!pKeyboard->isVirtual())
return false;
- return !pKeyboard || (!m_sIMERelay.m_pIME.expired() && m_sIMERelay.m_pIME.lock()->grabClient() == pKeyboard->virtKeyboard.lock()->client());
+ CVirtualKeyboard* vk = (CVirtualKeyboard*)pKeyboard.get();
+
+ return !pKeyboard || (!m_sIMERelay.m_pIME.expired() && m_sIMERelay.m_pIME.lock()->grabClient() == vk->getClient());
}
void CInputManager::refocus() {
@@ -1343,7 +1294,7 @@ void CInputManager::updateDragIcon() {
}
void CInputManager::unconstrainMouse() {
- if (!g_pCompositor->m_sSeat.mouse)
+ if (g_pCompositor->m_sSeat.mouse.expired())
return;
for (auto& c : m_vConstraints) {
@@ -1378,11 +1329,11 @@ bool CInputManager::isConstrained() {
void CInputManager::updateCapabilities() {
uint32_t caps = 0;
- if (!m_lKeyboards.empty())
+ if (!m_vKeyboards.empty())
caps |= WL_SEAT_CAPABILITY_KEYBOARD;
- if (!m_lMice.empty())
+ if (!m_vPointers.empty())
caps |= WL_SEAT_CAPABILITY_POINTER;
- if (!m_lTouchDevices.empty())
+ if (!m_vTouches.empty())
caps |= WL_SEAT_CAPABILITY_TOUCH;
if (!m_lTabletTools.empty())
caps |= WL_SEAT_CAPABILITY_POINTER;
@@ -1395,54 +1346,34 @@ uint32_t CInputManager::accumulateModsFromAllKBs() {
uint32_t finalMask = 0;
- for (auto& kb : m_lKeyboards) {
- if (kb.isVirtual && shouldIgnoreVirtualKeyboard(&kb))
+ for (auto& kb : m_vKeyboards) {
+ if (kb->isVirtual() && shouldIgnoreVirtualKeyboard(kb))
continue;
- if (!kb.enabled)
+ if (!kb->enabled)
continue;
- finalMask |= wlr_keyboard_get_modifiers(wlr_keyboard_from_input_device(kb.keyboard));
+ finalMask |= wlr_keyboard_get_modifiers(kb->wlr());
}
return finalMask;
}
-std::string CInputManager::getActiveLayoutForKeyboard(SKeyboard* pKeyboard) {
- const auto WLRKB = wlr_keyboard_from_input_device(pKeyboard->keyboard);
- const auto KEYMAP = WLRKB->keymap;
- const auto STATE = WLRKB->xkb_state;
- const auto LAYOUTSNUM = xkb_keymap_num_layouts(KEYMAP);
-
- for (uint32_t i = 0; i < LAYOUTSNUM; ++i) {
- if (xkb_state_layout_index_is_active(STATE, i, XKB_STATE_LAYOUT_EFFECTIVE)) {
- const auto LAYOUTNAME = xkb_keymap_layout_get_name(KEYMAP, i);
-
- if (LAYOUTNAME)
- return std::string(LAYOUTNAME);
- return "error";
- }
- }
-
- return "none";
-}
-
void CInputManager::disableAllKeyboards(bool virt) {
- for (auto& k : m_lKeyboards) {
- if (k.isVirtual != virt)
+ for (auto& k : m_vKeyboards) {
+ if (k->isVirtual() != virt)
continue;
- k.active = false;
+ k->active = false;
}
}
void CInputManager::newTouchDevice(wlr_input_device* pDevice) {
- const auto PNEWDEV = &m_lTouchDevices.emplace_back();
- PNEWDEV->pWlrDevice = pDevice;
+ const auto PNEWDEV = m_vTouches.emplace_back(CTouchDevice::create(wlr_touch_from_input_device(pDevice)));
try {
- PNEWDEV->name = getNameForNewDevice(pDevice->name);
+ PNEWDEV->hlName = getNameForNewDevice(pDevice->name);
} catch (std::exception& e) {
Debug::log(ERR, "Touch Device had no name???"); // logic error
}
@@ -1450,32 +1381,36 @@ void CInputManager::newTouchDevice(wlr_input_device* pDevice) {
setTouchDeviceConfigs(PNEWDEV);
wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, pDevice);
- Debug::log(LOG, "New touch device added at {:x}", (uintptr_t)PNEWDEV);
+ PNEWDEV->events.destroy.registerStaticListener(
+ [this](void* owner, std::any data) {
+ auto PDEV = ((ITouch*)owner)->self.lock();
+ destroyTouchDevice(PDEV);
+ },
+ PNEWDEV.get());
- PNEWDEV->hyprListener_destroy.initCallback(
- &pDevice->events.destroy, [&](void* owner, void* data) { destroyTouchDevice((STouchDevice*)data); }, PNEWDEV, "TouchDevice");
+ Debug::log(LOG, "New touch device added at {:x}", (uintptr_t)PNEWDEV.get());
}
-void CInputManager::setTouchDeviceConfigs(STouchDevice* dev) {
- auto setConfig = [&](STouchDevice* const PTOUCHDEV) -> void {
- if (wlr_input_device_is_libinput(PTOUCHDEV->pWlrDevice)) {
- const auto LIBINPUTDEV = (libinput_device*)wlr_libinput_get_device_handle(PTOUCHDEV->pWlrDevice);
+void CInputManager::setTouchDeviceConfigs(SP<ITouch> dev) {
+ auto setConfig = [&](SP<ITouch> PTOUCHDEV) -> void {
+ if (wlr_input_device_is_libinput(&PTOUCHDEV->wlr()->base)) {
+ const auto LIBINPUTDEV = (libinput_device*)wlr_libinput_get_device_handle(&PTOUCHDEV->wlr()->base);
- const auto ENABLED = g_pConfigManager->getDeviceInt(PTOUCHDEV->name, "enabled", "input:touchdevice:enabled");
+ const auto ENABLED = g_pConfigManager->getDeviceInt(PTOUCHDEV->hlName, "enabled", "input:touchdevice:enabled");
const auto mode = ENABLED ? LIBINPUT_CONFIG_SEND_EVENTS_ENABLED : LIBINPUT_CONFIG_SEND_EVENTS_DISABLED;
if (libinput_device_config_send_events_get_mode(LIBINPUTDEV) != mode)
libinput_device_config_send_events_set_mode(LIBINPUTDEV, mode);
- const int ROTATION = std::clamp(g_pConfigManager->getDeviceInt(PTOUCHDEV->name, "transform", "input:touchdevice:transform"), 0, 7);
- Debug::log(LOG, "Setting calibration matrix for device {}", PTOUCHDEV->name);
+ const int ROTATION = std::clamp(g_pConfigManager->getDeviceInt(PTOUCHDEV->hlName, "transform", "input:touchdevice:transform"), 0, 7);
+ Debug::log(LOG, "Setting calibration matrix for device {}", PTOUCHDEV->hlName);
if (libinput_device_config_calibration_has_matrix(LIBINPUTDEV))
libinput_device_config_calibration_set_matrix(LIBINPUTDEV, MATRICES[ROTATION]);
- auto output = g_pConfigManager->getDeviceString(PTOUCHDEV->name, "output", "input:touchdevice:output");
+ auto output = g_pConfigManager->getDeviceString(PTOUCHDEV->hlName, "output", "input:touchdevice:output");
bool bound = !output.empty() && output != STRVAL_EMPTY;
const bool AUTODETECT = output == "[[Auto]]";
if (!bound && AUTODETECT) {
- const auto DEFAULTOUTPUT = wlr_touch_from_input_device(PTOUCHDEV->pWlrDevice)->output_name;
+ const auto DEFAULTOUTPUT = PTOUCHDEV->wlr()->output_name;
if (DEFAULTOUTPUT) {
output = DEFAULTOUTPUT;
bound = true;
@@ -1484,10 +1419,10 @@ void CInputManager::setTouchDeviceConfigs(STouchDevice* dev) {
PTOUCHDEV->boundOutput = bound ? output : "";
const auto PMONITOR = bound ? g_pCompositor->getMonitorFromName(output) : nullptr;
if (PMONITOR) {
- Debug::log(LOG, "Binding touch device {} to output {}", PTOUCHDEV->name, PMONITOR->szName);
- wlr_cursor_map_input_to_output(g_pCompositor->m_sWLRCursor, PTOUCHDEV->pWlrDevice, PMONITOR->output);
+ Debug::log(LOG, "Binding touch device {} to output {}", PTOUCHDEV->hlName, PMONITOR->szName);
+ wlr_cursor_map_input_to_output(g_pCompositor->m_sWLRCursor, &PTOUCHDEV->wlr()->base, PMONITOR->output);
} else if (bound)
- Debug::log(ERR, "Failed to bind touch device {} to output '{}': monitor not found", PTOUCHDEV->name, output);
+ Debug::log(ERR, "Failed to bind touch device {} to output '{}': monitor not found", PTOUCHDEV->hlName, output);
}
};
@@ -1496,10 +1431,8 @@ void CInputManager::setTouchDeviceConfigs(STouchDevice* dev) {
return;
}
- for (auto& m : m_lTouchDevices) {
- const auto PTOUCHDEV = &m;
-
- setConfig(PTOUCHDEV);
+ for (auto& m : m_vTouches) {
+ setConfig(m);
}
}
@@ -1546,12 +1479,6 @@ void CInputManager::setTabletConfigs() {
}
}
-void CInputManager::destroyTouchDevice(STouchDevice* pDevice) {
- Debug::log(LOG, "Touch device at {:x} removed", (uintptr_t)pDevice);
-
- m_lTouchDevices.remove(*pDevice);
-}
-
void CInputManager::newSwitch(wlr_input_device* pDevice) {
const auto PNEWDEV = &m_lSwitches.emplace_back();
PNEWDEV->pWlrDevice = pDevice;
@@ -1623,16 +1550,16 @@ std::string CInputManager::getNameForNewDevice(std::string internalName) {
auto proposedNewName = deviceNameToInternalString(internalName);
int dupeno = 0;
- while (std::find_if(m_lKeyboards.begin(), m_lKeyboards.end(),
- [&](const SKeyboard& other) { return other.name == proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); }) != m_lKeyboards.end())
+ while (std::find_if(m_vKeyboards.begin(), m_vKeyboards.end(),
+ [&](const auto& other) { return other->hlName == proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); }) != m_vKeyboards.end())
dupeno++;
- while (std::find_if(m_lMice.begin(), m_lMice.end(), [&](const SMouse& other) { return other.name == proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); }) !=
- m_lMice.end())
+ while (std::find_if(m_vPointers.begin(), m_vPointers.end(),
+ [&](const auto& other) { return other->hlName == proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); }) != m_vPointers.end())
dupeno++;
- while (std::find_if(m_lTouchDevices.begin(), m_lTouchDevices.end(),
- [&](const STouchDevice& other) { return other.name == proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); }) != m_lTouchDevices.end())
+ while (std::find_if(m_vTouches.begin(), m_vTouches.end(),
+ [&](const auto& other) { return other->hlName == proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); }) != m_vTouches.end())
dupeno++;
while (std::find_if(m_lTabletPads.begin(), m_lTabletPads.end(),
diff --git a/src/managers/input/InputManager.hpp b/src/managers/input/InputManager.hpp
index 6a338088..98032dd4 100644
--- a/src/managers/input/InputManager.hpp
+++ b/src/managers/input/InputManager.hpp
@@ -11,8 +11,11 @@
class CPointerConstraint;
class CWindow;
class CIdleInhibitor;
-class CVirtualKeyboard;
-class CVirtualPointer;
+class CVirtualKeyboardV1Resource;
+class CVirtualPointerV1Resource;
+class IPointer;
+class IKeyboard;
+class ITouch;
enum eClickBehaviorMode {
CLICKMODE_DEFAULT = 0,
@@ -75,23 +78,22 @@ class CInputManager {
void onMouseWarp(wlr_pointer_motion_absolute_event*);
void onMouseButton(wlr_pointer_button_event*);
void onMouseWheel(wlr_pointer_axis_event*);
- void onKeyboardKey(wlr_keyboard_key_event*, SKeyboard*);
- void onKeyboardMod(void*, SKeyboard*);
+ void onKeyboardKey(std::any, SP<IKeyboard>);
+ void onKeyboardMod(SP<IKeyboard>);
void newKeyboard(wlr_input_device*);
- void newVirtualKeyboard(SP<CVirtualKeyboard>);
+ void newVirtualKeyboard(SP<CVirtualKeyboardV1Resource>);
void newMouse(wlr_input_device*);
- void newVirtualMouse(SP<CVirtualPointer>);
+ void newVirtualMouse(SP<CVirtualPointerV1Resource>);
void newTouchDevice(wlr_input_device*);
void newSwitch(wlr_input_device*);
- void destroyTouchDevice(STouchDevice*);
- void destroyKeyboard(SKeyboard*);
- void destroyMouse(wlr_input_device*);
+ void destroyTouchDevice(SP<ITouch>);
+ void destroyKeyboard(SP<IKeyboard>);
+ void destroyPointer(SP<IPointer>);
void destroySwitch(SSwitchDevice*);
void unconstrainMouse();
bool isConstrained();
- std::string getActiveLayoutForKeyboard(SKeyboard*);
Vector2D getMouseCoordsInternal();
void refocus();
@@ -100,7 +102,7 @@ class CInputManager {
void setKeyboardLayout();
void setPointerConfigs();
- void setTouchDeviceConfigs(STouchDevice* dev = nullptr);
+ void setTouchDeviceConfigs(SP<ITouch> dev = nullptr);
void setTabletConfigs();
void updateDragIcon();
@@ -122,21 +124,19 @@ class CInputManager {
bool m_bWasDraggingWindow = false;
// for refocus to be forced
- PHLWINDOWREF m_pForcedFocus;
+ PHLWINDOWREF m_pForcedFocus;
- SDrag m_sDrag;
+ SDrag m_sDrag;
- std::list<SKeyboard> m_lKeyboards;
- std::list<SMouse> m_lMice;
+ std::vector<SP<IKeyboard>> m_vKeyboards;
+ std::vector<SP<IPointer>> m_vPointers;
+ std::vector<SP<ITouch>> m_vTouches;
// tablets
std::list<STablet> m_lTablets;
std::list<STabletTool> m_lTabletTools;
std::list<STabletPad> m_lTabletPads;
- // Touch devices
- std::list<STouchDevice> m_lTouchDevices;
-
// Switches
std::list<SSwitchDevice> m_lSwitches;
@@ -159,19 +159,15 @@ class CInputManager {
SSwipeGesture m_sActiveSwipe;
- SKeyboard* m_pActiveKeyboard = nullptr;
-
CTimer m_tmrLastCursorMovement;
CInputMethodRelay m_sIMERelay;
- void updateKeyboardsLeds(wlr_input_device* pKeyboard);
-
// for shared mods
uint32_t accumulateModsFromAllKBs();
// for virtual keyboards: whether we should respect them as normal ones
- bool shouldIgnoreVirtualKeyboard(SKeyboard*);
+ bool shouldIgnoreVirtualKeyboard(SP<IKeyboard>);
// for special cursors that we choose
void setCursorImageUntilUnset(std::string);
@@ -213,6 +209,9 @@ class CInputManager {
eClickBehaviorMode m_ecbClickBehavior = CLICKMODE_DEFAULT;
Vector2D m_vLastCursorPosFloored = Vector2D();
+ void setupKeyboard(SP<IKeyboard> keeb);
+ void setupMouse(SP<IPointer> mauz);
+
void processMouseDownNormal(wlr_pointer_button_event* e);
void processMouseDownKill(wlr_pointer_button_event* e);
@@ -226,7 +225,7 @@ class CInputManager {
STabletTool* ensureTabletToolPresent(wlr_tablet_tool*);
- void applyConfigToKeyboard(SKeyboard*);
+ void applyConfigToKeyboard(SP<IKeyboard>);
// this will be set after a refocus()
wlr_surface* m_pFoundSurfaceToFocus = nullptr;
diff --git a/src/managers/input/Touch.cpp b/src/managers/input/Touch.cpp
index 91f4ada6..8f6e2226 100644
--- a/src/managers/input/Touch.cpp
+++ b/src/managers/input/Touch.cpp
@@ -2,6 +2,7 @@
#include "../../Compositor.hpp"
#include "../../config/ConfigValue.hpp"
#include "../../protocols/IdleNotify.hpp"
+#include "../../devices/ITouch.hpp"
void CInputManager::onTouchDown(wlr_touch_down_event* e) {
static auto PSWIPETOUCH = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_touch");
@@ -15,10 +16,10 @@ void CInputManager::onTouchDown(wlr_touch_down_event* e) {
auto PMONITOR = g_pCompositor->getMonitorFromName(e->touch->output_name ? e->touch->output_name : "");
- const auto PDEVIT = std::find_if(m_lTouchDevices.begin(), m_lTouchDevices.end(), [&](const STouchDevice& other) { return other.pWlrDevice == &e->touch->base; });
+ const auto PDEVIT = std::find_if(m_vTouches.begin(), m_vTouches.end(), [&](const auto& other) { return other->wlr() == e->touch; });
- if (PDEVIT != m_lTouchDevices.end() && !PDEVIT->boundOutput.empty())
- PMONITOR = g_pCompositor->getMonitorFromName(PDEVIT->boundOutput);
+ if (PDEVIT != m_vTouches.end() && !(*PDEVIT)->boundOutput.empty())
+ PMONITOR = g_pCompositor->getMonitorFromName((*PDEVIT)->boundOutput);
PMONITOR = PMONITOR ? PMONITOR : g_pCompositor->m_pLastMonitor;
diff --git a/src/protocols/VirtualKeyboard.cpp b/src/protocols/VirtualKeyboard.cpp
index fa364a96..1cc76447 100644
--- a/src/protocols/VirtualKeyboard.cpp
+++ b/src/protocols/VirtualKeyboard.cpp
@@ -7,7 +7,7 @@ static const struct wlr_keyboard_impl virtualKeyboardImpl = {
.name = "virtual-keyboard",
};
-CVirtualKeyboard::CVirtualKeyboard(SP<CZwpVirtualKeyboardV1> resource_) : resource(resource_) {
+CVirtualKeyboardV1Resource::CVirtualKeyboardV1Resource(SP<CZwpVirtualKeyboardV1> resource_) : resource(resource_) {
if (!good())
return;
@@ -84,20 +84,20 @@ CVirtualKeyboard::CVirtualKeyboard(SP<CZwpVirtualKeyboardV1> resource_) : resour
wlr_keyboard_init(&keyboard, &virtualKeyboardImpl, "CVirtualKeyboard");
}
-CVirtualKeyboard::~CVirtualKeyboard() {
+CVirtualKeyboardV1Resource::~CVirtualKeyboardV1Resource() {
wlr_keyboard_finish(&keyboard);
events.destroy.emit();
}
-bool CVirtualKeyboard::good() {
+bool CVirtualKeyboardV1Resource::good() {
return resource->resource();
}
-wlr_keyboard* CVirtualKeyboard::wlr() {
+wlr_keyboard* CVirtualKeyboardV1Resource::wlr() {
return &keyboard;
}
-wl_client* CVirtualKeyboard::client() {
+wl_client* CVirtualKeyboardV1Resource::client() {
return resource->client();
}
@@ -116,13 +116,13 @@ void CVirtualKeyboardProtocol::onManagerResourceDestroy(wl_resource* res) {
std::erase_if(m_vManagers, [&](const auto& other) { return other->resource() == res; });
}
-void CVirtualKeyboardProtocol::destroyResource(CVirtualKeyboard* keeb) {
+void CVirtualKeyboardProtocol::destroyResource(CVirtualKeyboardV1Resource* keeb) {
std::erase_if(m_vKeyboards, [&](const auto& other) { return other.get() == keeb; });
}
void CVirtualKeyboardProtocol::onCreateKeeb(CZwpVirtualKeyboardManagerV1* pMgr, wl_resource* seat, uint32_t id) {
- const auto RESOURCE = m_vKeyboards.emplace_back(std::make_shared<CVirtualKeyboard>(std::make_shared<CZwpVirtualKeyboardV1>(pMgr->client(), pMgr->version(), id)));
+ const auto RESOURCE = m_vKeyboards.emplace_back(std::make_shared<CVirtualKeyboardV1Resource>(std::make_shared<CZwpVirtualKeyboardV1>(pMgr->client(), pMgr->version(), id)));
if (!RESOURCE->good()) {
pMgr->noMemory();
diff --git a/src/protocols/VirtualKeyboard.hpp b/src/protocols/VirtualKeyboard.hpp
index b922b0c5..5ce3d748 100644
--- a/src/protocols/VirtualKeyboard.hpp
+++ b/src/protocols/VirtualKeyboard.hpp
@@ -7,10 +7,10 @@
#include "virtual-keyboard-unstable-v1.hpp"
#include "../helpers/signal/Signal.hpp"
-class CVirtualKeyboard {
+class CVirtualKeyboardV1Resource {
public:
- CVirtualKeyboard(SP<CZwpVirtualKeyboardV1> resource_);
- ~CVirtualKeyboard();
+ CVirtualKeyboardV1Resource(SP<CZwpVirtualKeyboardV1> resource_);
+ ~CVirtualKeyboardV1Resource();
struct {
CSignal destroy;
@@ -39,14 +39,14 @@ class CVirtualKeyboardProtocol : public IWaylandProtocol {
private:
void onManagerResourceDestroy(wl_resource* res);
- void destroyResource(CVirtualKeyboard* keeb);
+ void destroyResource(CVirtualKeyboardV1Resource* keeb);
void onCreateKeeb(CZwpVirtualKeyboardManagerV1* pMgr, wl_resource* seat, uint32_t id);
//
std::vector<UP<CZwpVirtualKeyboardManagerV1>> m_vManagers;
- std::vector<SP<CVirtualKeyboard>> m_vKeyboards;
+ std::vector<SP<CVirtualKeyboardV1Resource>> m_vKeyboards;
- friend class CVirtualKeyboard;
+ friend class CVirtualKeyboardV1Resource;
};
namespace PROTO {
diff --git a/src/protocols/VirtualPointer.cpp b/src/protocols/VirtualPointer.cpp
index 287e7bad..cad8af67 100644
--- a/src/protocols/VirtualPointer.cpp
+++ b/src/protocols/VirtualPointer.cpp
@@ -6,7 +6,7 @@ static const wlr_pointer_impl pointerImpl = {
.name = "virtual-pointer-v1",
};
-CVirtualPointer::CVirtualPointer(SP<CZwlrVirtualPointerV1> resource_) : resource(resource_) {
+CVirtualPointerV1Resource::CVirtualPointerV1Resource(SP<CZwlrVirtualPointerV1> resource_) : resource(resource_) {
if (!good())
return;
@@ -19,7 +19,7 @@ CVirtualPointer::CVirtualPointer(SP<CZwlrVirtualPointerV1> resource_) : resource
PROTO::virtualPointer->destroyResource(this);
});
- wlr_pointer_init(&pointer, &pointerImpl, "CVirtualPointer");
+ wlr_pointer_init(&pointer, &pointerImpl, "CVirtualPointerV1Resource");
resource->setMotion([this](CZwlrVirtualPointerV1* r, uint32_t timeMs, wl_fixed_t dx, wl_fixed_t dy) {
wlr_pointer_motion_event event = {
@@ -108,20 +108,20 @@ CVirtualPointer::CVirtualPointer(SP<CZwlrVirtualPointerV1> resource_) : resource
});
}
-CVirtualPointer::~CVirtualPointer() {
+CVirtualPointerV1Resource::~CVirtualPointerV1Resource() {
wlr_pointer_finish(&pointer);
events.destroy.emit();
}
-bool CVirtualPointer::good() {
+bool CVirtualPointerV1Resource::good() {
return resource->resource();
}
-wlr_pointer* CVirtualPointer::wlr() {
+wlr_pointer* CVirtualPointerV1Resource::wlr() {
return &pointer;
}
-wl_client* CVirtualPointer::client() {
+wl_client* CVirtualPointerV1Resource::client() {
return resource->client();
}
@@ -145,13 +145,13 @@ void CVirtualPointerProtocol::onManagerResourceDestroy(wl_resource* res) {
std::erase_if(m_vManagers, [&](const auto& other) { return other->resource() == res; });
}
-void CVirtualPointerProtocol::destroyResource(CVirtualPointer* pointer) {
+void CVirtualPointerProtocol::destroyResource(CVirtualPointerV1Resource* pointer) {
std::erase_if(m_vPointers, [&](const auto& other) { return other.get() == pointer; });
}
void CVirtualPointerProtocol::onCreatePointer(CZwlrVirtualPointerManagerV1* pMgr, wl_resource* seat, uint32_t id) {
- const auto RESOURCE = m_vPointers.emplace_back(std::make_shared<CVirtualPointer>(std::make_shared<CZwlrVirtualPointerV1>(pMgr->client(), pMgr->version(), id)));
+ const auto RESOURCE = m_vPointers.emplace_back(std::make_shared<CVirtualPointerV1Resource>(std::make_shared<CZwlrVirtualPointerV1>(pMgr->client(), pMgr->version(), id)));
if (!RESOURCE->good()) {
pMgr->noMemory();
diff --git a/src/protocols/VirtualPointer.hpp b/src/protocols/VirtualPointer.hpp
index 4528b491..59a7e739 100644
--- a/src/protocols/VirtualPointer.hpp
+++ b/src/protocols/VirtualPointer.hpp
@@ -8,10 +8,10 @@
#include "wlr-virtual-pointer-unstable-v1.hpp"
#include "../helpers/signal/Signal.hpp"
-class CVirtualPointer {
+class CVirtualPointerV1Resource {
public:
- CVirtualPointer(SP<CZwlrVirtualPointerV1> resource_);
- ~CVirtualPointer();
+ CVirtualPointerV1Resource(SP<CZwlrVirtualPointerV1> resource_);
+ ~CVirtualPointerV1Resource();
struct {
CSignal destroy;
@@ -37,19 +37,19 @@ class CVirtualPointerProtocol : public IWaylandProtocol {
virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);
struct {
- CSignal newPointer; // SP<CVirtualPointer>
+ CSignal newPointer; // SP<CVirtualPointerV1Resource>
} events;
private:
void onManagerResourceDestroy(wl_resource* res);
- void destroyResource(CVirtualPointer* pointer);
+ void destroyResource(CVirtualPointerV1Resource* pointer);
void onCreatePointer(CZwlrVirtualPointerManagerV1* pMgr, wl_resource* seat, uint32_t id);
//
std::vector<UP<CZwlrVirtualPointerManagerV1>> m_vManagers;
- std::vector<SP<CVirtualPointer>> m_vPointers;
+ std::vector<SP<CVirtualPointerV1Resource>> m_vPointers;
- friend class CVirtualPointer;
+ friend class CVirtualPointerV1Resource;
};
namespace PROTO {