diff options
| author | Vaxry <vaxry@vaxry.net> | 2024-05-06 02:15:26 +0100 |
|---|---|---|
| committer | Vaxry <43317083+vaxerski@users.noreply.github.com> | 2024-05-09 13:37:39 +0100 |
| commit | 84e8d1810d57b65a0bc3b5ac2998bc023df880f4 (patch) | |
| tree | cd313a14333c06765dc149c9339d595c13eafd72 /src/managers/input | |
| parent | ed411f53bdcf8d455f9e6ca769693aa84dc8372f (diff) | |
Tablet: move to new impl
Ring and strip are not implemented. Will I implement this? God fucking knows. Nobody seems to have that anyways.
Diffstat (limited to 'src/managers/input')
| -rw-r--r-- | src/managers/input/InputManager.cpp | 131 | ||||
| -rw-r--r-- | src/managers/input/InputManager.hpp | 44 | ||||
| -rw-r--r-- | src/managers/input/Tablets.cpp | 437 |
3 files changed, 331 insertions, 281 deletions
diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 22fc24d4..7e746cfc 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -58,9 +58,9 @@ CInputManager::~CInputManager() { m_vKeyboards.clear(); m_vPointers.clear(); m_vTouches.clear(); - m_lTablets.clear(); - m_lTabletTools.clear(); - m_lTabletPads.clear(); + m_vTablets.clear(); + m_vTabletTools.clear(); + m_vTabletPads.clear(); m_vIdleInhibitors.clear(); m_lSwitches.clear(); } @@ -777,6 +777,8 @@ void CInputManager::newVirtualKeyboard(SP<CVirtualKeyboardV1Resource> keyboard) } void CInputManager::setupKeyboard(SP<IKeyboard> keeb) { + m_vHIDs.push_back(keeb); + try { keeb->hlName = getNameForNewDevice(keeb->wlr()->base.name); } catch (std::exception& e) { @@ -977,6 +979,8 @@ void CInputManager::newMouse(wlr_input_device* mouse) { } void CInputManager::setupMouse(SP<IPointer> mauz) { + m_vHIDs.push_back(mauz); + try { mauz->hlName = getNameForNewDevice(mauz->wlr()->base.name); } catch (std::exception& e) { @@ -1165,6 +1169,11 @@ void CInputManager::setPointerConfigs() { } } +static void removeFromHIDs(WP<IHID> hid) { + std::erase_if(g_pInputManager->m_vHIDs, [hid](const auto& e) { return e.expired() || e == hid; }); + g_pInputManager->updateCapabilities(); +} + void CInputManager::destroyKeyboard(SP<IKeyboard> pKeyboard) { if (pKeyboard->xkbTranslationState) xkb_state_unref(pKeyboard->xkbTranslationState); @@ -1180,6 +1189,8 @@ void CInputManager::destroyKeyboard(SP<IKeyboard> pKeyboard) { g_pCompositor->m_sSeat.keyboard.reset(); wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, nullptr); } + + removeFromHIDs(pKeyboard); } void CInputManager::destroyPointer(SP<IPointer> mouse) { @@ -1189,12 +1200,40 @@ void CInputManager::destroyPointer(SP<IPointer> mouse) { if (!g_pCompositor->m_sSeat.mouse.expired()) unconstrainMouse(); + + removeFromHIDs(mouse); } void CInputManager::destroyTouchDevice(SP<ITouch> touch) { Debug::log(LOG, "Touch device at {:x} removed", (uintptr_t)touch.get()); std::erase_if(m_vTouches, [touch](const auto& other) { return other == touch; }); + + removeFromHIDs(touch); +} + +void CInputManager::destroyTablet(SP<CTablet> tablet) { + Debug::log(LOG, "Tablet device at {:x} removed", (uintptr_t)tablet.get()); + + std::erase_if(m_vTablets, [tablet](const auto& other) { return other == tablet; }); + + removeFromHIDs(tablet); +} + +void CInputManager::destroyTabletTool(SP<CTabletTool> tool) { + Debug::log(LOG, "Tablet tool at {:x} removed", (uintptr_t)tool.get()); + + std::erase_if(m_vTabletTools, [tool](const auto& other) { return other == tool; }); + + removeFromHIDs(tool); +} + +void CInputManager::destroyTabletPad(SP<CTabletPad> pad) { + Debug::log(LOG, "Tablet pad at {:x} removed", (uintptr_t)pad.get()); + + std::erase_if(m_vTabletPads, [pad](const auto& other) { return other == pad; }); + + removeFromHIDs(pad); } void CInputManager::onKeyboardKey(std::any event, SP<IKeyboard> pKeyboard) { @@ -1338,14 +1377,19 @@ bool CInputManager::isConstrained() { void CInputManager::updateCapabilities() { uint32_t caps = 0; - if (!m_vKeyboards.empty()) - caps |= WL_SEAT_CAPABILITY_KEYBOARD; - if (!m_vPointers.empty()) - caps |= WL_SEAT_CAPABILITY_POINTER; - if (!m_vTouches.empty()) - caps |= WL_SEAT_CAPABILITY_TOUCH; - if (!m_lTabletTools.empty()) - caps |= WL_SEAT_CAPABILITY_POINTER; + for (auto& h : m_vHIDs) { + if (h.expired()) + continue; + + auto cap = h->getCapabilities(); + + if (cap & HID_INPUT_CAPABILITY_KEYBOARD) + caps |= WL_SEAT_CAPABILITY_KEYBOARD; + if (cap & HID_INPUT_CAPABILITY_POINTER) + caps |= WL_SEAT_CAPABILITY_POINTER; + if (cap & HID_INPUT_CAPABILITY_TOUCH) + caps |= WL_SEAT_CAPABILITY_TOUCH; + } wlr_seat_set_capabilities(g_pCompositor->m_sSeat.seat, caps); m_uiCapabilities = caps; @@ -1380,6 +1424,7 @@ void CInputManager::disableAllKeyboards(bool virt) { void CInputManager::newTouchDevice(wlr_input_device* pDevice) { const auto PNEWDEV = m_vTouches.emplace_back(CTouchDevice::create(wlr_touch_from_input_device(pDevice))); + m_vHIDs.push_back(PNEWDEV); try { PNEWDEV->hlName = getNameForNewDevice(pDevice->name); @@ -1450,43 +1495,39 @@ void CInputManager::setTouchDeviceConfigs(SP<ITouch> dev) { } void CInputManager::setTabletConfigs() { - for (auto& t : m_lTablets) { - if (wlr_input_device_is_libinput(t.wlrDevice)) { - const auto LIBINPUTDEV = (libinput_device*)wlr_libinput_get_device_handle(t.wlrDevice); + for (auto& t : m_vTablets) { + if (wlr_input_device_is_libinput(&t->wlr()->base)) { + const auto NAME = t->hlName; + const auto LIBINPUTDEV = (libinput_device*)wlr_libinput_get_device_handle(&t->wlr()->base); - const auto RELINPUT = g_pConfigManager->getDeviceInt(t.name, "relative_input", "input:tablet:relative_input"); - t.relativeInput = RELINPUT; + const auto RELINPUT = g_pConfigManager->getDeviceInt(NAME, "relative_input", "input:tablet:relative_input"); + t->relativeInput = RELINPUT; - const int ROTATION = std::clamp(g_pConfigManager->getDeviceInt(t.name, "transform", "input:tablet:transform"), 0, 7); - Debug::log(LOG, "Setting calibration matrix for device {}", t.name); + const int ROTATION = std::clamp(g_pConfigManager->getDeviceInt(NAME, "transform", "input:tablet:transform"), 0, 7); + Debug::log(LOG, "Setting calibration matrix for device {}", NAME); libinput_device_config_calibration_set_matrix(LIBINPUTDEV, MATRICES[ROTATION]); - if (g_pConfigManager->getDeviceInt(t.name, "left_handed", "input:tablet:left_handed") == 0) + if (g_pConfigManager->getDeviceInt(NAME, "left_handed", "input:tablet:left_handed") == 0) libinput_device_config_left_handed_set(LIBINPUTDEV, 0); else libinput_device_config_left_handed_set(LIBINPUTDEV, 1); - const auto OUTPUT = g_pConfigManager->getDeviceString(t.name, "output", "input:tablet:output"); - const auto PMONITOR = g_pCompositor->getMonitorFromString(OUTPUT); - if (!OUTPUT.empty() && OUTPUT != STRVAL_EMPTY && PMONITOR) { - Debug::log(LOG, "Binding tablet {} to output {}", t.name, PMONITOR->szName); - // wlr_cursor_map_input_to_output(g_pCompositor->m_sWLRCursor, t.wlrDevice, PMONITOR->output); - // wlr_cursor_map_input_to_region(g_pCompositor->m_sWLRCursor, t.wlrDevice, nullptr); - t.boundOutput = OUTPUT; - } else if (!PMONITOR) - Debug::log(ERR, "Failed to bind tablet {} to output '{}': monitor not found", t.name, OUTPUT); - - const auto REGION_POS = g_pConfigManager->getDeviceVec(t.name, "region_position", "input:tablet:region_position"); - const auto REGION_SIZE = g_pConfigManager->getDeviceVec(t.name, "region_size", "input:tablet:region_size"); - //auto regionBox = CBox{REGION_POS.x, REGION_POS.y, REGION_SIZE.x, REGION_SIZE.y}; - // if (!regionBox.empty()) - // wlr_cursor_map_input_to_region(g_pCompositor->m_sWLRCursor, t.wlrDevice, regionBox.pWlr()); - - const auto ACTIVE_AREA_SIZE = g_pConfigManager->getDeviceVec(t.name, "active_area_size", "input:tablet:active_area_size"); - const auto ACTIVE_AREA_POS = g_pConfigManager->getDeviceVec(t.name, "active_area_position", "input:tablet:active_area_position"); + const auto OUTPUT = g_pConfigManager->getDeviceString(NAME, "output", "input:tablet:output"); + if (OUTPUT != STRVAL_EMPTY) { + Debug::log(LOG, "Binding tablet {} to output {}", NAME, OUTPUT); + t->boundOutput = OUTPUT; + } else + t->boundOutput = ""; + + const auto REGION_POS = g_pConfigManager->getDeviceVec(NAME, "region_position", "input:tablet:region_position"); + const auto REGION_SIZE = g_pConfigManager->getDeviceVec(NAME, "region_size", "input:tablet:region_size"); + t->boundBox = {REGION_POS, REGION_SIZE}; + + const auto ACTIVE_AREA_SIZE = g_pConfigManager->getDeviceVec(NAME, "active_area_size", "input:tablet:active_area_size"); + const auto ACTIVE_AREA_POS = g_pConfigManager->getDeviceVec(NAME, "active_area_position", "input:tablet:active_area_position"); if (ACTIVE_AREA_SIZE.x != 0 || ACTIVE_AREA_SIZE.y != 0) { - t.activeArea = CBox{ACTIVE_AREA_POS.x / t.wlrTablet->width_mm, ACTIVE_AREA_POS.y / t.wlrTablet->height_mm, - (ACTIVE_AREA_POS.x + ACTIVE_AREA_SIZE.x) / t.wlrTablet->width_mm, (ACTIVE_AREA_POS.y + ACTIVE_AREA_SIZE.y) / t.wlrTablet->height_mm}; + t->activeArea = CBox{ACTIVE_AREA_POS.x / t->wlr()->width_mm, ACTIVE_AREA_POS.y / t->wlr()->height_mm, (ACTIVE_AREA_POS.x + ACTIVE_AREA_SIZE.x) / t->wlr()->width_mm, + (ACTIVE_AREA_POS.y + ACTIVE_AREA_SIZE.y) / t->wlr()->height_mm}; } } } @@ -1575,16 +1616,16 @@ std::string CInputManager::getNameForNewDevice(std::string internalName) { [&](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(), - [&](const STabletPad& other) { return other.name == proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); }) != m_lTabletPads.end()) + while (std::find_if(m_vTabletPads.begin(), m_vTabletPads.end(), + [&](const auto& other) { return other->hlName == proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); }) != m_vTabletPads.end()) dupeno++; - while (std::find_if(m_lTablets.begin(), m_lTablets.end(), - [&](const STablet& other) { return other.name == proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); }) != m_lTablets.end()) + while (std::find_if(m_vTablets.begin(), m_vTablets.end(), + [&](const auto& other) { return other->hlName == proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); }) != m_vTablets.end()) dupeno++; - while (std::find_if(m_lTabletTools.begin(), m_lTabletTools.end(), - [&](const STabletTool& other) { return other.name == proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); }) != m_lTabletTools.end()) + while (std::find_if(m_vTabletTools.begin(), m_vTabletTools.end(), + [&](const auto& other) { return other->hlName == proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); }) != m_vTabletTools.end()) dupeno++; return proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); diff --git a/src/managers/input/InputManager.hpp b/src/managers/input/InputManager.hpp index a2caed46..970d53c8 100644 --- a/src/managers/input/InputManager.hpp +++ b/src/managers/input/InputManager.hpp @@ -9,6 +9,7 @@ #include "../../helpers/signal/Listener.hpp" #include "../../devices/IPointer.hpp" #include "../../devices/ITouch.hpp" +#include "../../devices/Tablet.hpp" class CPointerConstraint; class CWindow; @@ -87,9 +88,15 @@ class CInputManager { void newVirtualMouse(SP<CVirtualPointerV1Resource>); void newTouchDevice(wlr_input_device*); void newSwitch(wlr_input_device*); + void newTabletTool(wlr_tablet_tool*); + void newTabletPad(wlr_input_device*); + void newTablet(wlr_input_device*); void destroyTouchDevice(SP<ITouch>); void destroyKeyboard(SP<IKeyboard>); void destroyPointer(SP<IPointer>); + void destroyTablet(SP<CTablet>); + void destroyTabletTool(SP<CTabletTool>); + void destroyTabletPad(SP<CTabletPad>); void destroySwitch(SSwitchDevice*); void unconstrainMouse(); @@ -116,6 +123,15 @@ class CInputManager { void onTouchUp(ITouch::SUpEvent); void onTouchMove(ITouch::SMotionEvent); + void onSwipeBegin(IPointer::SSwipeBeginEvent); + void onSwipeEnd(IPointer::SSwipeEndEvent); + void onSwipeUpdate(IPointer::SSwipeUpdateEvent); + + void onTabletAxis(CTablet::SAxisEvent); + void onTabletProximity(CTablet::SProximityEvent); + void onTabletTip(CTablet::STipEvent); + void onTabletButton(CTablet::SButtonEvent); + STouchData m_sTouchData; // for dragging floating windows @@ -124,18 +140,17 @@ class CInputManager { bool m_bWasDraggingWindow = false; // for refocus to be forced - PHLWINDOWREF m_pForcedFocus; + PHLWINDOWREF m_pForcedFocus; - SDrag m_sDrag; + SDrag m_sDrag; - 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; + std::vector<SP<IKeyboard>> m_vKeyboards; + std::vector<SP<IPointer>> m_vPointers; + std::vector<SP<ITouch>> m_vTouches; + std::vector<SP<CTablet>> m_vTablets; + std::vector<SP<CTabletTool>> m_vTabletTools; + std::vector<SP<CTabletPad>> m_vTabletPads; + std::vector<WP<IHID>> m_vHIDs; // general container for all HID devices connected to the input manager. // Switches std::list<SSwitchDevice> m_lSwitches; @@ -147,16 +162,9 @@ class CInputManager { std::vector<WP<CPointerConstraint>> m_vConstraints; // - void newTabletTool(wlr_input_device*); - void newTabletPad(wlr_input_device*); - void focusTablet(STablet*, wlr_tablet_tool*, bool motion = false); void newIdleInhibitor(std::any); void recheckIdleInhibitorStatus(); - void onSwipeBegin(IPointer::SSwipeBeginEvent); - void onSwipeEnd(IPointer::SSwipeEndEvent); - void onSwipeUpdate(IPointer::SSwipeUpdateEvent); - SSwipeGesture m_sActiveSwipe; CTimer m_tmrLastCursorMovement; @@ -223,7 +231,7 @@ class CInputManager { void mouseMoveUnified(uint32_t, bool refocus = false); - STabletTool* ensureTabletToolPresent(wlr_tablet_tool*); + SP<CTabletTool> ensureTabletToolPresent(wlr_tablet_tool*); void applyConfigToKeyboard(SP<IKeyboard>); diff --git a/src/managers/input/Tablets.cpp b/src/managers/input/Tablets.cpp index a0bd81ce..cf666ec6 100644 --- a/src/managers/input/Tablets.cpp +++ b/src/managers/input/Tablets.cpp @@ -1,290 +1,291 @@ #include "InputManager.hpp" #include "../../Compositor.hpp" #include "../../protocols/IdleNotify.hpp" +#include "../../protocols/Tablet.hpp" +#include "../../devices/Tablet.hpp" +#include "../../managers/PointerManager.hpp" +#include "../../protocols/PointerConstraints.hpp" + +static void unfocusTool(SP<CTabletTool> tool) { + if (!tool->getSurface()) + return; + + tool->setSurface(nullptr); + if (tool->isDown) + PROTO::tablet->up(tool); + for (auto& b : tool->buttonsDown) { + PROTO::tablet->buttonTool(tool, b, false); + } + PROTO::tablet->proximityOut(tool); +} -void CInputManager::newTabletTool(wlr_input_device* pDevice) { - const auto PNEWTABLET = &m_lTablets.emplace_back(); +static void focusTool(SP<CTabletTool> tool, SP<CTablet> tablet, wlr_surface* surf) { + if (tool->getSurface() == surf || !surf) + return; - try { - PNEWTABLET->name = deviceNameToInternalString(pDevice->name); - } catch (std::exception& e) { - Debug::log(ERR, "Tablet had no name???"); // logic error + if (tool->getSurface() && tool->getSurface() != surf) + unfocusTool(tool); + + tool->setSurface(surf); + PROTO::tablet->proximityIn(tool, tablet, surf); + if (tool->isDown) + PROTO::tablet->down(tool); + for (auto& b : tool->buttonsDown) { + PROTO::tablet->buttonTool(tool, b, true); } +} + +static void refocusTablet(SP<CTablet> tab, SP<CTabletTool> tool, bool motion = false) { + const auto LASTHLSURFACE = CWLSurface::surfaceFromWlr(g_pInputManager->m_pLastMouseSurface); - PNEWTABLET->wlrTablet = wlr_tablet_from_input_device(pDevice); - PNEWTABLET->wlrDevice = pDevice; - PNEWTABLET->wlrTabletV2 = wlr_tablet_create(g_pCompositor->m_sWLRTabletManager, g_pCompositor->m_sSeat.seat, pDevice); - PNEWTABLET->wlrTablet->data = PNEWTABLET; + if (!LASTHLSURFACE || !tool->active) { + if (tool->getSurface()) + unfocusTool(tool); - Debug::log(LOG, "Attaching tablet to cursor!"); + return; + } - // wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, pDevice); + const auto BOX = LASTHLSURFACE->getSurfaceBoxGlobal(); - PNEWTABLET->hyprListener_Destroy.initCallback( - &pDevice->events.destroy, - [](void* owner, void* data) { - const auto PTAB = (STablet*)owner; + if (!BOX.has_value()) { + if (tool->getSurface()) + unfocusTool(tool); - g_pInputManager->m_lTablets.remove(*PTAB); + return; + } - Debug::log(LOG, "Removed a tablet"); - }, - PNEWTABLET, "Tablet"); - - PNEWTABLET->hyprListener_Axis.initCallback( - &wlr_tablet_from_input_device(pDevice)->events.axis, - [](void* owner, void* data) { - const auto EVENT = (wlr_tablet_tool_axis_event*)data; - const auto PTAB = (STablet*)owner; - - switch (EVENT->tool->type) { - case WLR_TABLET_TOOL_TYPE_MOUSE: - // wlr_cursor_move(g_pCompositor->m_sWLRCursor, PTAB->wlrDevice, EVENT->dx, EVENT->dy); - g_pInputManager->simulateMouseMovement(); - g_pInputManager->focusTablet(PTAB, EVENT->tool, true); - g_pInputManager->m_tmrLastCursorMovement.reset(); - break; - default: - double x = (EVENT->updated_axes & WLR_TABLET_TOOL_AXIS_X) ? EVENT->x : NAN; - double dx = (EVENT->updated_axes & WLR_TABLET_TOOL_AXIS_X) ? EVENT->dx : NAN; - double y = (EVENT->updated_axes & WLR_TABLET_TOOL_AXIS_Y) ? EVENT->y : NAN; - double dy = (EVENT->updated_axes & WLR_TABLET_TOOL_AXIS_Y) ? EVENT->dy : NAN; - - // if (PTAB->relativeInput) - // wlr_cursor_move(g_pCompositor->m_sWLRCursor, PTAB->wlrDevice, dx, dy); - // else { - // Calculate transformations if active area is set - // if (!PTAB->activeArea.empty()) { - // x = (x - PTAB->activeArea.x) / (PTAB->activeArea.w - PTAB->activeArea.x); - // y = (y - PTAB->activeArea.y) / (PTAB->activeArea.h - PTAB->activeArea.y); - // } - // wlr_cursor_warp_absolute(g_pCompositor->m_sWLRCursor, PTAB->wlrDevice, x, y); - // } - - g_pInputManager->simulateMouseMovement(); - g_pInputManager->focusTablet(PTAB, EVENT->tool, true); - g_pInputManager->m_tmrLastCursorMovement.reset(); - break; - } + const auto CURSORPOS = g_pInputManager->getMouseCoordsInternal(); - const auto PTOOL = g_pInputManager->ensureTabletToolPresent(EVENT->tool); + focusTool(tool, tab, g_pInputManager->m_pLastMouseSurface); - // TODO: this might be wrong - if (PTOOL->active) { - g_pInputManager->simulateMouseMovement(); + if (!motion) + return; - g_pInputManager->focusTablet(PTAB, EVENT->tool, true); - } + if (LASTHLSURFACE->constraint() && tool->wlr()->type != WLR_TABLET_TOOL_TYPE_MOUSE) { + // cursor logic will completely break here as the cursor will be locked. + // let's just "map" the desired position to the constraint area. - if (EVENT->updated_axes & WLR_TABLET_TOOL_AXIS_PRESSURE) - wlr_tablet_v2_tablet_tool_notify_pressure(PTOOL->wlrTabletToolV2, EVENT->pressure); + Vector2D local; - if (EVENT->updated_axes & WLR_TABLET_TOOL_AXIS_DISTANCE) - wlr_tablet_v2_tablet_tool_notify_distance(PTOOL->wlrTabletToolV2, EVENT->distance); + // yes, this technically ignores any regions set by the app. Too bad! + if (LASTHLSURFACE->getWindow()) + local = tool->absolutePos * LASTHLSURFACE->getWindow()->m_vRealSize.goal(); + else + local = tool->absolutePos * BOX->size(); - if (EVENT->updated_axes & WLR_TABLET_TOOL_AXIS_ROTATION) - wlr_tablet_v2_tablet_tool_notify_rotation(PTOOL->wlrTabletToolV2, EVENT->rotation); + if (LASTHLSURFACE->getWindow() && LASTHLSURFACE->getWindow()->m_bIsX11) + local = local * LASTHLSURFACE->getWindow()->m_fX11SurfaceScaledBy; - if (EVENT->updated_axes & WLR_TABLET_TOOL_AXIS_SLIDER) - wlr_tablet_v2_tablet_tool_notify_slider(PTOOL->wlrTabletToolV2, EVENT->slider); + PROTO::tablet->motion(tool, local); + return; + } - if (EVENT->updated_axes & WLR_TABLET_TOOL_AXIS_WHEEL) - wlr_tablet_v2_tablet_tool_notify_wheel(PTOOL->wlrTabletToolV2, EVENT->wheel_delta, 0); + auto local = CURSORPOS - BOX->pos(); - if (EVENT->updated_axes & WLR_TABLET_TOOL_AXIS_TILT_X) - PTOOL->tiltX = EVENT->tilt_x; + if (LASTHLSURFACE->getWindow() && LASTHLSURFACE->getWindow()->m_bIsX11) + local = local * LASTHLSURFACE->getWindow()->m_fX11SurfaceScaledBy; - if (EVENT->updated_axes & WLR_TABLET_TOOL_AXIS_TILT_Y) - PTOOL->tiltY = EVENT->tilt_y; + PROTO::tablet->motion(tool, local); +} - if (EVENT->updated_axes & (WLR_TABLET_TOOL_AXIS_TILT_X | WLR_TABLET_TOOL_AXIS_TILT_Y)) - wlr_tablet_v2_tablet_tool_notify_tilt(PTOOL->wlrTabletToolV2, PTOOL->tiltX, PTOOL->tiltY); +void CInputManager::onTabletAxis(CTablet::SAxisEvent e) { + const auto PTAB = e.tablet; + const auto PTOOL = ensureTabletToolPresent(e.tool); - PROTO::idle->onActivity(); - }, - PNEWTABLET, "Tablet"); - - PNEWTABLET->hyprListener_Tip.initCallback( - &wlr_tablet_from_input_device(pDevice)->events.tip, - [](void* owner, void* data) { - const auto EVENT = (wlr_tablet_tool_tip_event*)data; - const auto PTAB = (STablet*)owner; - - const auto PTOOL = g_pInputManager->ensureTabletToolPresent(EVENT->tool); - - // TODO: this might be wrong - if (EVENT->state == WLR_TABLET_TOOL_TIP_DOWN) { - g_pInputManager->simulateMouseMovement(); - g_pInputManager->focusTablet(PTAB, EVENT->tool); - wlr_send_tablet_v2_tablet_tool_down(PTOOL->wlrTabletToolV2); - } else { - wlr_send_tablet_v2_tablet_tool_up(PTOOL->wlrTabletToolV2); + if (PTOOL->active && (e.updatedAxes & (CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_X | CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_Y))) { + double x = (e.updatedAxes & CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_X) ? e.axis.x : NAN; + double dx = (e.updatedAxes & CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_X) ? e.axisDelta.x : NAN; + double y = (e.updatedAxes & CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_Y) ? e.axis.y : NAN; + double dy = (e.updatedAxes & CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_Y) ? e.axisDelta.y : NAN; + + Vector2D delta = {std::isnan(dx) ? 0.0 : dx, std::isnan(dy) ? 0.0 : dy}; + + switch (e.tool->type) { + case WLR_TABLET_TOOL_TYPE_MOUSE: { + g_pPointerManager->move(delta); + break; + } + default: { + if (!std::isnan(x)) + PTOOL->absolutePos.x = x; + if (!std::isnan(y)) + PTOOL->absolutePos.y = y; + + if (PTAB->relativeInput) + g_pPointerManager->move(delta); + else { + //Calculate transformations if active area is set + if (!PTAB->activeArea.empty()) { + if (!std::isnan(x)) + x = (x - PTAB->activeArea.x) / (PTAB->activeArea.w - PTAB->activeArea.x); + if (!std::isnan(y)) + y = (y - PTAB->activeArea.y) / (PTAB->activeArea.h - PTAB->activeArea.y); + } + g_pPointerManager->warpAbsolute({x, y}, PTAB); + } + break; } + } - PROTO::idle->onActivity(); - }, - PNEWTABLET, "Tablet"); + refocusTablet(PTAB, PTOOL, true); + m_tmrLastCursorMovement.reset(); + } - PNEWTABLET->hyprListener_Button.initCallback( - &wlr_tablet_from_input_device(pDevice)->events.button, - [](void* owner, void* data) { - const auto EVENT = (wlr_tablet_tool_button_event*)data; + if (e.updatedAxes & CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_PRESSURE) + PROTO::tablet->pressure(PTOOL, e.pressure); - const auto PTOOL = g_pInputManager->ensureTabletToolPresent(EVENT->tool); + if (e.updatedAxes & CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_DISTANCE) + PROTO::tablet->distance(PTOOL, e.distance); - wlr_tablet_v2_tablet_tool_notify_button(PTOOL->wlrTabletToolV2, (zwp_tablet_pad_v2_button_state)EVENT->button, (zwp_tablet_pad_v2_button_state)EVENT->state); - PROTO::idle->onActivity(); - }, - PNEWTABLET, "Tablet"); + if (e.updatedAxes & CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_ROTATION) + PROTO::tablet->rotation(PTOOL, e.rotation); - PNEWTABLET->hyprListener_Proximity.initCallback( - &wlr_tablet_from_input_device(pDevice)->events.proximity, - [](void* owner, void* data) { - const auto EVENT = (wlr_tablet_tool_proximity_event*)data; - const auto PTAB = (STablet*)owner; + if (e.updatedAxes & CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_SLIDER) + PROTO::tablet->slider(PTOOL, e.slider); - const auto PTOOL = g_pInputManager->ensureTabletToolPresent(EVENT->tool); + if (e.updatedAxes & CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_WHEEL) + PROTO::tablet->wheel(PTOOL, e.wheelDelta); - if (EVENT->state == WLR_TABLET_TOOL_PROXIMITY_OUT) { - PTOOL->active = false; + if (e.updatedAxes & CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_TILT_X) + PTOOL->tilt.x = e.tilt.x; - if (PTOOL->pSurface) { - wlr_tablet_v2_tablet_tool_notify_proximity_out(PTOOL->wlrTabletToolV2); - PTOOL->pSurface = nullptr; - } + if (e.updatedAxes & CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_TILT_Y) + PTOOL->tilt.y = e.tilt.y; - } else { - PTOOL->active = true; - g_pInputManager->simulateMouseMovement(); - g_pInputManager->focusTablet(PTAB, EVENT->tool); - } + if (e.updatedAxes & (CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_TILT_X | CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_TILT_Y)) + PROTO::tablet->tilt(PTOOL, PTOOL->tilt); - PROTO::idle->onActivity(); - }, - PNEWTABLET, "Tablet"); + PROTO::idle->onActivity(); +} - setTabletConfigs(); +void CInputManager::onTabletTip(CTablet::STipEvent e) { + const auto PTAB = e.tablet; + const auto PTOOL = ensureTabletToolPresent(e.tool); + + if (e.in) { + simulateMouseMovement(); + refocusTablet(PTAB, PTOOL); + PROTO::tablet->down(PTOOL); + } else + PROTO::tablet->up(PTOOL); + + PTOOL->isDown = e.in; + + PROTO::idle->onActivity(); } -STabletTool* CInputManager::ensureTabletToolPresent(wlr_tablet_tool* pTool) { - if (pTool->data == nullptr) { - const auto PTOOL = &m_lTabletTools.emplace_back(); +void CInputManager::onTabletButton(CTablet::SButtonEvent e) { + const auto PTOOL = ensureTabletToolPresent(e.tool); - Debug::log(LOG, "Creating tablet tool v2 for {:x}", (uintptr_t)pTool); + PROTO::tablet->buttonTool(PTOOL, e.button, e.down); - PTOOL->wlrTabletTool = pTool; - pTool->data = PTOOL; + if (e.down) + PTOOL->buttonsDown.push_back(e.button); + else + std::erase(PTOOL->buttonsDown, e.button); - PTOOL->wlrTabletToolV2 = wlr_tablet_tool_create(g_pCompositor->m_sWLRTabletManager, g_pCompositor->m_sSeat.seat, pTool); + PROTO::idle->onActivity(); +} - PTOOL->hyprListener_TabletToolDestroy.initCallback( - &pTool->events.destroy, - [](void* owner, void* data) { - const auto PTOOL = (STabletTool*)owner; +void CInputManager::onTabletProximity(CTablet::SProximityEvent e) { + const auto PTAB = e.tablet; + const auto PTOOL = ensureTabletToolPresent(e.tool); - PTOOL->wlrTabletTool->data = nullptr; - g_pInputManager->m_lTabletTools.remove(*PTOOL); - }, - PTOOL, "Tablet Tool V1"); + PTOOL->active = e.in; - //TODO: set cursor request + if (!e.in) { + if (PTOOL->getSurface()) + unfocusTool(PTOOL); + } else { + simulateMouseMovement(); + refocusTablet(PTAB, PTOOL); } - return (STabletTool*)pTool->data; + PROTO::idle->onActivity(); } -void CInputManager::newTabletPad(wlr_input_device* pDevice) { - const auto PNEWPAD = &m_lTabletPads.emplace_back(); +void CInputManager::newTablet(wlr_input_device* pDevice) { + const auto PNEWTABLET = m_vTablets.emplace_back(CTablet::create(wlr_tablet_from_input_device(pDevice))); + m_vHIDs.push_back(PNEWTABLET); try { - PNEWPAD->name = deviceNameToInternalString(pDevice->name); + PNEWTABLET->hlName = deviceNameToInternalString(pDevice->name); } catch (std::exception& e) { - Debug::log(ERR, "Pad had no name???"); // logic error + Debug::log(ERR, "Tablet had no name???"); // logic error } - PNEWPAD->wlrTabletPadV2 = wlr_tablet_pad_create(g_pCompositor->m_sWLRTabletManager, g_pCompositor->m_sSeat.seat, pDevice); - PNEWPAD->pWlrDevice = pDevice; + g_pPointerManager->attachTablet(PNEWTABLET); - PNEWPAD->hyprListener_Button.initCallback( - &wlr_tablet_pad_from_input_device(pDevice)->events.button, - [](void* owner, void* data) { - const auto EVENT = (wlr_tablet_pad_button_event*)data; - const auto PPAD = (STabletPad*)owner; - - wlr_tablet_v2_tablet_pad_notify_mode(PPAD->wlrTabletPadV2, EVENT->group, EVENT->mode, EVENT->time_msec); - wlr_tablet_v2_tablet_pad_notify_button(PPAD->wlrTabletPadV2, EVENT->button, EVENT->time_msec, (zwp_tablet_pad_v2_button_state)EVENT->state); + PNEWTABLET->events.destroy.registerStaticListener( + [this](void* owner, std::any d) { + auto TABLET = ((CTablet*)owner)->self; + destroyTablet(TABLET.lock()); }, - PNEWPAD, "Tablet Pad"); - - PNEWPAD->hyprListener_Strip.initCallback( - &wlr_tablet_pad_from_input_device(pDevice)->events.strip, - [](void* owner, void* data) { - const auto EVENT = (wlr_tablet_pad_strip_event*)data; - const auto PPAD = (STabletPad*)owner; + PNEWTABLET.get()); - wlr_tablet_v2_tablet_pad_notify_strip(PPAD->wlrTabletPadV2, EVENT->strip, EVENT->position, EVENT->source == WLR_TABLET_PAD_STRIP_SOURCE_FINGER, EVENT->time_msec); - }, - PNEWPAD, "Tablet Pad"); + setTabletConfigs(); +} - PNEWPAD->hyprListener_Ring.initCallback( - &wlr_tablet_pad_from_input_device(pDevice)->events.strip, - [](void* owner, void* data) { - const auto EVENT = (wlr_tablet_pad_ring_event*)data; - const auto PPAD = (STabletPad*)owner; +SP<CTabletTool> CInputManager::ensureTabletToolPresent(wlr_tablet_tool* pTool) { + if (pTool->data == nullptr) { + const auto PTOOL = m_vTabletTools.emplace_back(CTabletTool::create(pTool)); + m_vHIDs.push_back(PTOOL); - wlr_tablet_v2_tablet_pad_notify_ring(PPAD->wlrTabletPadV2, EVENT->ring, EVENT->position, EVENT->source == WLR_TABLET_PAD_RING_SOURCE_FINGER, EVENT->time_msec); - }, - PNEWPAD, "Tablet Pad"); + PTOOL->events.destroy.registerStaticListener( + [this](void* owner, std::any d) { + auto TOOL = ((CTabletTool*)owner)->self; + destroyTabletTool(TOOL.lock()); + }, + PTOOL.get()); + } - PNEWPAD->hyprListener_Attach.initCallback( - &wlr_tablet_pad_from_input_device(pDevice)->events.strip, - [](void* owner, void* data) { - const auto TABLET = (wlr_tablet_tool*)data; - const auto PPAD = (STabletPad*)owner; + return CTabletTool::fromWlr(pTool); +} - PPAD->pTabletParent = (STablet*)TABLET->data; +void CInputManager::newTabletPad(wlr_input_device* pDevice) { + const auto PNEWPAD = m_vTabletPads.emplace_back(CTabletPad::create(wlr_tablet_pad_from_input_device(pDevice))); + m_vHIDs.push_back(PNEWPAD); - if (!PPAD->pTabletParent) - Debug::log(ERR, "tabletpad got attached to a nullptr tablet!! this might be bad."); - }, - PNEWPAD, "Tablet Pad"); + try { + PNEWPAD->hlName = deviceNameToInternalString(pDevice->name); + } catch (std::exception& e) { + Debug::log(ERR, "Pad had no name???"); // logic error + } - PNEWPAD->hyprListener_Destroy.initCallback( - &pDevice->events.destroy, - [](void* owner, void* data) { - const auto PPAD = (STabletPad*)owner; + // clang-format off + PNEWPAD->events.destroy.registerStaticListener([this](void* owner, std::any d) { + auto PAD = ((CTabletPad*)owner)->self; + destroyTabletPad(PAD.lock()); + }, PNEWPAD.get()); - g_pInputManager->m_lTabletPads.remove(*PPAD); + PNEWPAD->padEvents.button.registerStaticListener([this](void* owner, std::any e) { + const auto E = std::any_cast<CTabletPad::SButtonEvent>(e); + const auto PPAD = ((CTabletPad*)owner)->self.lock(); - Debug::log(LOG, "Removed a tablet pad"); - }, - PNEWPAD, "Tablet Pad"); -} + PROTO::tablet->mode(PPAD, 0, E.mode, E.timeMs); + PROTO::tablet->buttonPad(PPAD, E.button, E.timeMs, E.down); + }, PNEWPAD.get()); -void CInputManager::focusTablet(STablet* pTab, wlr_tablet_tool* pTool, bool motion) { - const auto PTOOL = g_pInputManager->ensureTabletToolPresent(pTool); + PNEWPAD->padEvents.strip.registerStaticListener([this](void* owner, std::any e) { + const auto E = std::any_cast<CTabletPad::SStripEvent>(e); + const auto PPAD = ((CTabletPad*)owner)->self.lock(); - if (const auto PWINDOW = g_pCompositor->m_pLastWindow.lock(); PWINDOW) { - const auto CURSORPOS = g_pInputManager->getMouseCoordsInternal(); + PROTO::tablet->strip(PPAD, E.strip, E.position, E.finger, E.timeMs); + }, PNEWPAD.get()); - if (PTOOL->pSurface != g_pInputManager->m_pLastMouseSurface) - wlr_tablet_v2_tablet_tool_notify_proximity_out(PTOOL->wlrTabletToolV2); + PNEWPAD->padEvents.ring.registerStaticListener([this](void* owner, std::any e) { + const auto E = std::any_cast<CTabletPad::SRingEvent>(e); + const auto PPAD = ((CTabletPad*)owner)->self.lock(); - if (g_pInputManager->m_pLastMouseSurface) { - PTOOL->pSurface = g_pCompositor->m_pLastFocus; - wlr_tablet_v2_tablet_tool_notify_proximity_in(PTOOL->wlrTabletToolV2, pTab->wlrTabletV2, g_pInputManager->m_pLastMouseSurface); - } + PROTO::tablet->ring(PPAD, E.ring, E.position, E.finger, E.timeMs); + }, PNEWPAD.get()); - if (motion) { - auto local = CURSORPOS - PWINDOW->m_vRealPosition.goal(); + PNEWPAD->padEvents.attach.registerStaticListener([this](void* owner, std::any e) { + const auto PPAD = ((CTabletPad*)owner)->self.lock(); + const auto TOOL = std::any_cast<SP<CTabletTool>>(e); - if (PWINDOW->m_bIsX11) - local = local * PWINDOW->m_fX11SurfaceScaledBy; + PPAD->parent = TOOL; + }, PNEWPAD.get()); - wlr_tablet_v2_tablet_tool_notify_motion(PTOOL->wlrTabletToolV2, local.x, local.y); - } - } else { - if (PTOOL->pSurface) - wlr_tablet_v2_tablet_tool_notify_proximity_out(PTOOL->wlrTabletToolV2); - } + // clang-format on } |
