From bd16bd9e35981f09b970702e4ca954bef3458231 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Fri, 5 Jul 2024 23:22:20 +0200 Subject: [PATCH] xcursor stuff --- src/managers/CursorManager.cpp | 39 +++++++++++++++++++++++++++++---- src/managers/CursorManager.hpp | 11 ++++++---- src/protocols/CursorShape.cpp | 40 ---------------------------------- 3 files changed, 42 insertions(+), 48 deletions(-) diff --git a/src/managers/CursorManager.cpp b/src/managers/CursorManager.cpp index 176caaa5..9545201e 100644 --- a/src/managers/CursorManager.cpp +++ b/src/managers/CursorManager.cpp @@ -4,6 +4,7 @@ #include "PointerManager.hpp" #include "../xwayland/XWayland.hpp" #include +#include "../helpers/CursorShapes.hpp" extern "C" { #include @@ -139,9 +140,14 @@ void CCursorManager::setXCursor(const std::string& name) { return; } - m_vCursorBuffers.emplace_back(makeShared(xcursor.defaultCursor->pixels.data(), xcursor.defaultCursor->size, xcursor.defaultCursor->hotspot)); + auto& icon = xcursor.defaultCursor; + // try to get an icon we know if we have one + if (xcursor.cursors.contains(name)) + icon = xcursor.cursors.at(name); - g_pPointerManager->setCursorBuffer(getCursorBuffer(), xcursor.defaultCursor->hotspot / scale, scale); + m_vCursorBuffers.emplace_back(makeShared(icon->pixels.data(), icon->size, icon->hotspot)); + + g_pPointerManager->setCursorBuffer(getCursorBuffer(), icon->hotspot / scale, scale); if (m_vCursorBuffers.size() > 1) dropBufferRef(m_vCursorBuffers.at(0).get()); @@ -300,8 +306,12 @@ bool CCursorManager::changeTheme(const std::string& name, const int size) { } void CCursorManager::SXCursorManager::loadTheme(const std::string& name, int size) { - themeLoaded = false; - themeName = name.empty() ? "default" : name; + if (lastLoadSize == size && themeName == name) + return; + + lastLoadSize = size; + themeLoaded = false; + themeName = name.empty() ? "default" : name; auto img = XcursorShapeLoadImage(1, name.c_str(), size); @@ -323,4 +333,25 @@ void CCursorManager::SXCursorManager::loadTheme(const std::string& name, int siz std::memcpy(defaultCursor->pixels.data(), img->pixels, img->width * img->height); themeLoaded = true; + + // gather as many shapes as we can find. + cursors.clear(); + + for (auto& shape : CURSOR_SHAPE_NAMES) { + auto xImage = XcursorShapeLoadImage(1, shape, size); + + if (!xImage) { + Debug::log(LOG, "XCursor failed to find a shape with name {}, skipping", shape); + continue; + } + + auto xcursor = makeShared(); + xcursor->size = {(int)xImage->width, (int)xImage->height}; + xcursor->hotspot = {(int)xImage->xhot, (int)xImage->yhot}; + + xcursor->pixels.resize(xImage->width * xImage->height); + std::memcpy(xcursor->pixels.data(), xImage->pixels, xImage->width * xImage->height); + + cursors.emplace(std::string{shape}, xcursor); + } } diff --git a/src/managers/CursorManager.hpp b/src/managers/CursorManager.hpp index 67e8d970..eeb57197 100644 --- a/src/managers/CursorManager.hpp +++ b/src/managers/CursorManager.hpp @@ -81,11 +81,14 @@ class CCursorManager { }; struct SXCursorManager { - void loadTheme(const std::string& name, int size); + void loadTheme(const std::string& name, int size); - bool themeLoaded = false; - std::string themeName = ""; - SP defaultCursor; + int lastLoadSize = 0; + + bool themeLoaded = false; + std::string themeName = ""; + SP defaultCursor; + std::unordered_map> cursors; } xcursor; }; diff --git a/src/protocols/CursorShape.cpp b/src/protocols/CursorShape.cpp index 2f25b22b..9b76b767 100644 --- a/src/protocols/CursorShape.cpp +++ b/src/protocols/CursorShape.cpp @@ -3,46 +3,6 @@ #define LOGM PROTO::cursorShape->protoLog -// clang-format off -constexpr const char* SHAPE_NAMES[] = { - "invalid", - "default", - "context-menu", - "help", - "pointer", - "progress", - "wait", - "cell", - "crosshair", - "text", - "vertical-text", - "alias", - "copy", - "move", - "no-drop", - "not-allowed", - "grab", - "grabbing", - "e-resize", - "n-resize", - "ne-resize", - "nw-resize", - "s-resize", - "se-resize", - "sw-resize", - "w-resize", - "ew-resize", - "ns-resize", - "nesw-resize", - "nwse-resize", - "col-resize", - "row-resize", - "all-scroll", - "zoom-in", - "zoom-out", -}; -// clang-format on - CCursorShapeProtocol::CCursorShapeProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { ; }