From 0c74df4f9efa0efe6ff1e73c74999acc217f68bb Mon Sep 17 00:00:00 2001 From: dusanx Date: Mon, 18 Dec 2023 16:06:06 +0000 Subject: [PATCH] renderer: cursor hiding logic improvements (#4184) Co-authored-by: Dusan Popovic --- src/managers/input/InputManager.cpp | 19 ++++++--------- src/render/Renderer.cpp | 37 +++++++++++++++++++---------- src/render/Renderer.hpp | 14 ++++++----- 3 files changed, 39 insertions(+), 31 deletions(-) diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index c6904a82..db06de55 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -324,13 +324,11 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { unsetCursorImage(); } - if (g_pHyprRenderer->m_bHasARenderedCursor) { - // TODO: maybe wrap? - if (m_ecbClickBehavior == CLICKMODE_KILL) - setCursorImageOverride("crosshair"); - else - setCursorImageOverride("left_ptr"); - } + // TODO: maybe wrap? + if (m_ecbClickBehavior == CLICKMODE_KILL) + setCursorImageOverride("crosshair"); + else + setCursorImageOverride("left_ptr"); m_bEmptyFocusCursorSet = true; } @@ -490,7 +488,7 @@ void CInputManager::processMouseRequest(wlr_seat_pointer_request_set_cursor_even else g_pHyprRenderer->m_bWindowRequestedCursorHide = false; - if (!cursorImageUnlocked() || !g_pHyprRenderer->m_bHasARenderedCursor) + if (!cursorImageUnlocked()) return; if (e->seat_client == g_pCompositor->m_sSeat.seat->pointer_state.focused_client) { @@ -513,7 +511,7 @@ void CInputManager::processMouseRequest(wlr_seat_pointer_request_set_cursor_even } void CInputManager::processMouseRequest(wlr_cursor_shape_manager_v1_request_set_shape_event* e) { - if (!g_pHyprRenderer->m_bHasARenderedCursor || !cursorImageUnlocked()) + if (!cursorImageUnlocked()) return; if (e->seat_client == g_pCompositor->m_sSeat.seat->pointer_state.focused_client) { @@ -555,9 +553,6 @@ void CInputManager::setCursorImageOverride(const std::string& name) { } bool CInputManager::cursorImageUnlocked() { - if (!g_pHyprRenderer->m_bHasARenderedCursor) - return false; - if (m_ecbClickBehavior == CLICKMODE_KILL) return false; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 43d7584c..6136ff9d 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -2026,10 +2026,13 @@ void CHyprRenderer::setCursorSurface(wlr_surface* surf, int hotspotX, int hotspo if (surf == m_sLastCursorData.surf) return; - m_sLastCursorData.name = ""; - m_sLastCursorData.surf = surf; + m_sLastCursorData.name = ""; + m_sLastCursorData.surf = surf; + m_sLastCursorData.hotspotX = hotspotX; + m_sLastCursorData.hotspotY = hotspotY; - wlr_cursor_set_surface(g_pCompositor->m_sWLRCursor, surf, hotspotX, hotspotY); + if (shouldRenderCursor()) + wlr_cursor_set_surface(g_pCompositor->m_sWLRCursor, surf, hotspotX, hotspotY); } void CHyprRenderer::setCursorFromName(const std::string& name) { m_bCursorHasSurface = true; @@ -2040,7 +2043,8 @@ void CHyprRenderer::setCursorFromName(const std::string& name) { m_sLastCursorData.name = name; m_sLastCursorData.surf.reset(); - wlr_cursor_set_xcursor(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sWLRXCursorMgr, name.c_str()); + if (shouldRenderCursor()) + wlr_cursor_set_xcursor(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sWLRXCursorMgr, name.c_str()); } void CHyprRenderer::ensureCursorRenderingMode() { @@ -2052,20 +2056,27 @@ void CHyprRenderer::ensureCursorRenderingMode() { if (*PCURSORTIMEOUT > 0 || *PHIDEONTOUCH) { const bool HIDE = (*PCURSORTIMEOUT > 0 && *PCURSORTIMEOUT < PASSEDCURSORSECONDS) || (g_pInputManager->m_bLastInputTouch && *PHIDEONTOUCH); - if (HIDE && m_bHasARenderedCursor) { - m_bHasARenderedCursor = false; + if (HIDE && !m_bTimeoutRequestedCursorHide) { + m_bTimeoutRequestedCursorHide = true; - setCursorSurface(nullptr, 0, 0); // hide + wlr_cursor_set_surface(g_pCompositor->m_sWLRCursor, nullptr, 0, 0); // hide without saving surface Debug::log(LOG, "Hiding the cursor (timeout)"); for (auto& m : g_pCompositor->m_vMonitors) g_pHyprRenderer->damageMonitor(m.get()); // TODO: maybe just damage the cursor area? - } else if (!HIDE && !m_bHasARenderedCursor) { - m_bHasARenderedCursor = true; + } else if (!HIDE && m_bTimeoutRequestedCursorHide) { + m_bTimeoutRequestedCursorHide = false; - if (!m_bWindowRequestedCursorHide) + if (m_bCursorHasSurface) { // restore last used name or surface, fallback to left_ptr if we don't have one + if (m_sLastCursorData.name == "") { + wlr_cursor_set_surface(g_pCompositor->m_sWLRCursor, m_sLastCursorData.surf.value_or(nullptr), m_sLastCursorData.hotspotX, m_sLastCursorData.hotspotY); + } else { + wlr_cursor_set_xcursor(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sWLRXCursorMgr, m_sLastCursorData.name.c_str()); + } + } else { setCursorFromName("left_ptr"); + } Debug::log(LOG, "Showing the cursor (timeout)"); @@ -2073,12 +2084,12 @@ void CHyprRenderer::ensureCursorRenderingMode() { g_pHyprRenderer->damageMonitor(m.get()); // TODO: maybe just damage the cursor area? } } else { - m_bHasARenderedCursor = true; + m_bTimeoutRequestedCursorHide = false; } } bool CHyprRenderer::shouldRenderCursor() { - return m_bHasARenderedCursor && m_bCursorHasSurface; + return !m_bTimeoutRequestedCursorHide && !m_bWindowRequestedCursorHide && m_bCursorHasSurface; } std::tuple CHyprRenderer::getRenderTimes(CMonitor* pMonitor) { @@ -2353,4 +2364,4 @@ CRenderbuffer* CHyprRenderer::getCurrentRBO() { bool CHyprRenderer::isNvidia() { return m_bNvidia; -} \ No newline at end of file +} diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index a832802e..5e7b05d6 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -99,6 +99,8 @@ class CHyprRenderer { CTimer m_tRenderTimer; struct { + int hotspotX; + int hotspotY; std::optional surf = nullptr; std::string name; } m_sLastCursorData; @@ -115,12 +117,12 @@ class CHyprRenderer { void renderWorkspace(CMonitor* pMonitor, CWorkspace* pWorkspace, timespec* now, const CBox& geometry); void renderAllClientsForWorkspace(CMonitor* pMonitor, CWorkspace* pWorkspace, timespec* now, const Vector2D& translate = {0, 0}, const float& scale = 1.f); - bool m_bHasARenderedCursor = true; - bool m_bCursorHasSurface = false; - CRenderbuffer* m_pCurrentRenderbuffer = nullptr; - wlr_buffer* m_pCurrentWlrBuffer = nullptr; - eRenderMode m_eRenderMode = RENDER_MODE_NORMAL; - int m_iLastBufferAge = 0; + bool m_bTimeoutRequestedCursorHide = false; + bool m_bCursorHasSurface = false; + CRenderbuffer* m_pCurrentRenderbuffer = nullptr; + wlr_buffer* m_pCurrentWlrBuffer = nullptr; + eRenderMode m_eRenderMode = RENDER_MODE_NORMAL; + int m_iLastBufferAge = 0; bool m_bNvidia = false;