From 1237732b97fcf21a19aed16f2ef966118a3ca2aa Mon Sep 17 00:00:00 2001 From: Vaxry Date: Fri, 3 May 2024 22:34:10 +0100 Subject: 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. --- src/managers/input/InputManager.cpp | 445 +++++++++++++++--------------------- 1 file changed, 186 insertions(+), 259 deletions(-) (limited to 'src/managers/input/InputManager.cpp') 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>(data)); }); + PROTO::virtualKeyboard->events.newKeyboard.registerListener([this](std::any data) { this->newVirtualKeyboard(std::any_cast>(data)); }); m_sListeners.newVirtualMouse = - PROTO::virtualPointer->events.newPointer.registerListener([this](std::any data) { this->newVirtualMouse(std::any_cast>(data)); }); + PROTO::virtualPointer->events.newPointer.registerListener([this](std::any data) { this->newVirtualMouse(std::any_cast>(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{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 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 keyboard) { - const auto PNEWKEYBOARD = &m_lKeyboards.emplace_back(); - - PNEWKEYBOARD->keyboard = &keyboard->wlr()->base; - PNEWKEYBOARD->isVirtual = true; - PNEWKEYBOARD->virtKeyboard = keyboard; - +void CInputManager::setupKeyboard(SP 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{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{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 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{pKeyboard, (void*)&LAYOUTSTR})); + g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", pKeyboard->hlName + "," + LAYOUTSTR}); + EMIT_HOOK_EVENT("activeLayout", (std::vector{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 mouse) { - const auto PMOUSE = &m_lMice.emplace_back(); +void CInputManager::newVirtualMouse(SP 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 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 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 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 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 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{{"keyboard", pKeyboard}, {"event", e}}; + const auto EMAP = std::unordered_map{{"keyboard", pKeyboard}, {"event", event}}; EMIT_HOOK_EVENT_CANCELLABLE("keyPress", EMAP); static auto PDPMS = CConfigValue("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(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 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{pKeyboard, (void*)&LAYOUT})); + g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", pKeyboard->hlName + "," + LAYOUT}); + EMIT_HOOK_EVENT("activeLayout", (std::vector{pKeyboard, LAYOUT})); } } -bool CInputManager::shouldIgnoreVirtualKeyboard(SKeyboard* pKeyboard) { - if (!pKeyboard->isVirtual) +bool CInputManager::shouldIgnoreVirtualKeyboard(SP 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 dev) { + auto setConfig = [&](SP 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(), -- cgit v1.2.3