diff options
author | Vaxry <[email protected]> | 2023-10-29 18:09:05 +0000 |
---|---|---|
committer | Vaxry <[email protected]> | 2023-10-29 18:09:05 +0000 |
commit | 7a5234a0cca2508b7a5ede1fc60dc3ae8b72a51c (patch) | |
tree | 581626c545765a0f797a4f4681100facb0826b0f /src/managers | |
parent | af9440152e19cee74b675e53087e032b9ccb5459 (diff) | |
download | Hyprland-7a5234a0cca2508b7a5ede1fc60dc3ae8b72a51c.tar.gz Hyprland-7a5234a0cca2508b7a5ede1fc60dc3ae8b72a51c.zip |
input: better cursor image infrastructure
Improves handling of cursor images/surfaces
Fixes an issue with decos and cursors
Fixes #3471
Diffstat (limited to 'src/managers')
-rw-r--r-- | src/managers/input/InputManager.cpp | 78 | ||||
-rw-r--r-- | src/managers/input/InputManager.hpp | 19 |
2 files changed, 76 insertions, 21 deletions
diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 1e8760aa..b19a929c 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -301,9 +301,9 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { if (g_pHyprRenderer->m_bHasARenderedCursor) { // TODO: maybe wrap? if (m_ecbClickBehavior == CLICKMODE_KILL) - g_pHyprRenderer->setCursorFromName("crosshair"); + setCursorImageOverride("crosshair"); else - g_pHyprRenderer->setCursorFromName("left_ptr"); + setCursorImageOverride("left_ptr"); } m_bEmptyFocusCursorSet = true; @@ -355,6 +355,14 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { return; } + if (pFoundWindow && foundSurface == pFoundWindow->m_pWLSurface.wlr() && !m_bCursorImageOverridden) { + const auto BOX = pFoundWindow->getWindowMainSurfaceBox(); + if (!VECINRECT(mouseCoords, BOX.x, BOX.y, BOX.x + BOX.width, BOX.y + BOX.height)) + setCursorImageOverride("left_ptr"); + else + restoreCursorIconToApp(); + } + if (pFoundWindow) { // change cursor icon if hovering over border if (*PRESIZEONBORDER && *PRESIZECURSORICON) { @@ -460,25 +468,65 @@ void CInputManager::processMouseRequest(wlr_seat_pointer_request_set_cursor_even if (!cursorImageUnlocked() || !g_pHyprRenderer->m_bHasARenderedCursor) return; - // cursorSurfaceInfo.pSurface = e->surface; + if (e->seat_client == g_pCompositor->m_sSeat.seat->pointer_state.focused_client) { + m_sCursorSurfaceInfo.wlSurface.unassign(); + + if (e->surface) { + m_sCursorSurfaceInfo.wlSurface.assign(e->surface); + m_sCursorSurfaceInfo.vHotspot = {e->hotspot_x, e->hotspot_y}; + m_sCursorSurfaceInfo.hidden = false; + } else { + m_sCursorSurfaceInfo.vHotspot = {}; + m_sCursorSurfaceInfo.hidden = true; + } - // if (e->surface) { - // hyprListener_CursorSurfaceDestroy.removeCallback(); - // hyprListener_CursorSurfaceDestroy.initCallback( - // &e->surface->events.destroy, [&](void* owner, void* data) { cursorSurfaceInfo.pSurface = nullptr; }, this, "InputManager"); - // cursorSurfaceInfo.vHotspot = {e->hotspot_x, e->hotspot_y}; - // } + m_sCursorSurfaceInfo.name = ""; - if (e->seat_client == g_pCompositor->m_sSeat.seat->pointer_state.focused_client) + m_sCursorSurfaceInfo.inUse = true; g_pHyprRenderer->setCursorSurface(e->surface, e->hotspot_x, e->hotspot_y); + } } void CInputManager::processMouseRequest(wlr_cursor_shape_manager_v1_request_set_shape_event* e) { if (!g_pHyprRenderer->m_bHasARenderedCursor || !cursorImageUnlocked()) return; - if (e->seat_client == g_pCompositor->m_sSeat.seat->pointer_state.focused_client) - g_pHyprRenderer->setCursorFromName(wlr_cursor_shape_v1_name(e->shape)); + if (e->seat_client == g_pCompositor->m_sSeat.seat->pointer_state.focused_client) { + m_sCursorSurfaceInfo.wlSurface.unassign(); + m_sCursorSurfaceInfo.vHotspot = {}; + m_sCursorSurfaceInfo.name = wlr_cursor_shape_v1_name(e->shape); + m_sCursorSurfaceInfo.hidden = false; + + m_sCursorSurfaceInfo.inUse = true; + g_pHyprRenderer->setCursorFromName(m_sCursorSurfaceInfo.name); + } +} + +void CInputManager::restoreCursorIconToApp() { + if (m_sCursorSurfaceInfo.inUse) + return; + + if (m_sCursorSurfaceInfo.hidden) { + g_pHyprRenderer->setCursorSurface(nullptr, 0, 0); + return; + } + + if (m_sCursorSurfaceInfo.name.empty()) { + if (m_sCursorSurfaceInfo.wlSurface.exists()) + g_pHyprRenderer->setCursorSurface(m_sCursorSurfaceInfo.wlSurface.wlr(), m_sCursorSurfaceInfo.vHotspot.x, m_sCursorSurfaceInfo.vHotspot.y); + } else { + g_pHyprRenderer->setCursorFromName(m_sCursorSurfaceInfo.name); + } + + m_sCursorSurfaceInfo.inUse = true; +} + +void CInputManager::setCursorImageOverride(const std::string& name) { + if (m_bCursorImageOverridden) + return; + + m_sCursorSurfaceInfo.inUse = false; + g_pHyprRenderer->setCursorFromName(name); } bool CInputManager::cursorImageUnlocked() { @@ -1487,7 +1535,8 @@ void CInputManager::destroySwitch(SSwitchDevice* pDevice) { void CInputManager::setCursorImageUntilUnset(std::string name) { g_pHyprRenderer->setCursorFromName(name.c_str()); - m_bCursorImageOverridden = true; + m_bCursorImageOverridden = true; + m_sCursorSurfaceInfo.inUse = false; } void CInputManager::unsetCursorImage() { @@ -1495,8 +1544,7 @@ void CInputManager::unsetCursorImage() { return; m_bCursorImageOverridden = false; - if (!g_pHyprRenderer->m_bWindowRequestedCursorHide) - g_pHyprRenderer->setCursorFromName("left_ptr"); + restoreCursorIconToApp(); } std::string CInputManager::deviceNameToInternalString(std::string in) { diff --git a/src/managers/input/InputManager.hpp b/src/managers/input/InputManager.hpp index 670bc4da..b4d365ee 100644 --- a/src/managers/input/InputManager.hpp +++ b/src/managers/input/InputManager.hpp @@ -229,15 +229,22 @@ class CInputManager { void setBorderCursorIcon(eBorderIconDirection); void setCursorIconOnBorder(CWindow* w); + // temporary. Obeys setUntilUnset. + void setCursorImageOverride(const std::string& name); + // cursor surface - // struct cursorSI { - // wlr_surface* pSurface = nullptr; - // Vector2D vHotspot; - // bool bUsed = false; - // } cursorSurfaceInfo; - // DYNLISTENER(CursorSurfaceDestroy); + struct cursorSI { + bool hidden = false; // null surface = hidden + CWLSurface wlSurface; + Vector2D vHotspot; + std::string name; // if not empty, means set by name. + bool inUse = false; + } m_sCursorSurfaceInfo; + + void restoreCursorIconToApp(); // no-op if restored friend class CKeybindManager; + friend class CWLSurface; }; inline std::unique_ptr<CInputManager> g_pInputManager; |