From 73b133d0155d376f35833cd992f821399a42f76b Mon Sep 17 00:00:00 2001 From: Ikalco <73481042+ikalco@users.noreply.github.com> Date: Tue, 28 May 2024 16:35:18 -0500 Subject: [PATCH] hyprctl: Make setcursor better (support XCursor themes, give fail message) (#6097) * add support for changing to X cursor themes * use new hyprcursor abi for options * remove unneeded struct --- src/debug/HyprCtl.cpp | 3 +- src/managers/CursorManager.cpp | 54 ++++++++++++++++++++++++++++------ src/managers/CursorManager.hpp | 2 +- 3 files changed, 48 insertions(+), 11 deletions(-) diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index 795272cc..d1975279 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -1074,7 +1074,8 @@ std::string dispatchSetCursor(eHyprCtlOutputFormat format, std::string request) if (size <= 0) return "size not positive"; - g_pCursorManager->changeTheme(theme, size); + if (!g_pCursorManager->changeTheme(theme, size)) + return "failed to set cursor"; return "ok"; } diff --git a/src/managers/CursorManager.cpp b/src/managers/CursorManager.cpp index c9783844..cb43f0b9 100644 --- a/src/managers/CursorManager.cpp +++ b/src/managers/CursorManager.cpp @@ -267,9 +267,6 @@ void CCursorManager::updateTheme() { highestScale = m->scale; } - if (std::round(highestScale * m_iSize) == m_sCurrentStyleInfo.size) - return; - if (m_sCurrentStyleInfo.size && m_pHyprcursor->valid()) m_pHyprcursor->cursorSurfaceStyleDone(m_sCurrentStyleInfo); @@ -287,13 +284,52 @@ void CCursorManager::updateTheme() { } } -void CCursorManager::changeTheme(const std::string& name, const int size) { - m_pHyprcursor = std::make_unique(name.empty() ? "" : name.c_str(), hcLogger); - m_szTheme = name; - m_iSize = size; +bool CCursorManager::changeTheme(const std::string& name, const int size) { + auto options = Hyprcursor::SManagerOptions(); + options.logFn = hcLogger; + options.allowDefaultFallback = false; - if (!m_pHyprcursor->valid()) - Debug::log(ERR, "Hyprcursor failed loading theme \"{}\", falling back to X.", m_szTheme); + m_pHyprcursor = std::make_unique(name.empty() ? "" : name.c_str(), options); + if (m_pHyprcursor->valid()) { + m_szTheme = name; + m_iSize = size; + updateTheme(); + return true; + } + + Debug::log(ERR, "Hyprcursor failed loading theme \"{}\", falling back to X.", name); + + if (m_pWLRXCursorMgr) + wlr_xcursor_manager_destroy(m_pWLRXCursorMgr); + + m_pWLRXCursorMgr = wlr_xcursor_manager_create(name.empty() ? "" : name.c_str(), size); + bool xSuccess = wlr_xcursor_manager_load(m_pWLRXCursorMgr, 1.0) == 1; + + // this basically checks if xcursor changed used theme to default but better + bool diffTheme = false; + wlr_xcursor_manager_theme* theme; + wl_list_for_each(theme, &m_pWLRXCursorMgr->scaled_themes, link) { + if (std::string{theme->theme->name} != name) { + diffTheme = true; + break; + } + } + + if (xSuccess && !diffTheme) { + m_szTheme = name; + m_iSize = size; + updateTheme(); + return true; + } + + Debug::log(ERR, "X also failed loading theme \"{}\", falling back to previous theme.", name); + + m_pHyprcursor = std::make_unique(m_szTheme.c_str(), hcLogger); + + wlr_xcursor_manager_destroy(m_pWLRXCursorMgr); + m_pWLRXCursorMgr = wlr_xcursor_manager_create(m_szTheme.c_str(), m_iSize); + wlr_xcursor_manager_load(m_pWLRXCursorMgr, 1.0); updateTheme(); + return false; } diff --git a/src/managers/CursorManager.hpp b/src/managers/CursorManager.hpp index 4ff9adeb..e76b6829 100644 --- a/src/managers/CursorManager.hpp +++ b/src/managers/CursorManager.hpp @@ -21,7 +21,7 @@ class CCursorManager { void setCursorSurface(CWLSurface* surf, const Vector2D& hotspot); void setXCursor(const std::string& name); - void changeTheme(const std::string& name, const int size); + bool changeTheme(const std::string& name, const int size); void updateTheme(); SCursorImageData dataFor(const std::string& name); // for xwayland void setXWaylandCursor();