diff --git a/CMakeLists.txt b/CMakeLists.txt index 61888849..e2357b55 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -215,3 +215,4 @@ protocol("unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml" "linux-dmabuf-unst protocol("unstable/xdg-output/xdg-output-unstable-v1.xml" "xdg-output-unstable-v1" false) protocol("staging/fractional-scale/fractional-scale-v1.xml" "fractional-scale-v1" false) protocol("unstable/text-input/text-input-unstable-v1.xml" "text-input-unstable-v1" false) +protocol("staging/cursor-shape/cursor-shape-v1.xml" "cursor-shape-v1" false) diff --git a/protocols/meson.build b/protocols/meson.build index 29634542..02e0c95a 100644 --- a/protocols/meson.build +++ b/protocols/meson.build @@ -24,6 +24,7 @@ protocols = [ [wl_protocol_dir, 'unstable/text-input/text-input-unstable-v1.xml'], [wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.xml'], [wl_protocol_dir, 'staging/fractional-scale/fractional-scale-v1.xml'], + [wl_protocol_dir, 'staging/cursor-shape/cursor-shape-v1.xml'], ['wlr-foreign-toplevel-management-unstable-v1.xml'], ['wlr-layer-shell-unstable-v1.xml'], ['wlr-output-power-management-unstable-v1.xml'], diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 1c76beeb..1d978aed 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -240,6 +240,8 @@ void CCompositor::initServer() { m_sWLRSessionLockMgr = wlr_session_lock_manager_v1_create(m_sWLDisplay); + m_sWLRCursorShapeMgr = wlr_cursor_shape_manager_v1_create(m_sWLDisplay, 1); + if (!m_sWLRHeadlessBackend) { Debug::log(CRIT, "Couldn't create the headless backend"); throw std::runtime_error("wlr_headless_backend_create() failed!"); @@ -297,6 +299,7 @@ void CCompositor::initAllSignals() { addWLSignal(&m_sWLRActivation->events.request_activate, &Events::listen_activateXDG, m_sWLRActivation, "ActivationV1"); addWLSignal(&m_sWLRSessionLockMgr->events.new_lock, &Events::listen_newSessionLock, m_sWLRSessionLockMgr, "SessionLockMgr"); addWLSignal(&m_sWLRGammaCtrlMgr->events.set_gamma, &Events::listen_setGamma, m_sWLRGammaCtrlMgr, "GammaCtrlMgr"); + addWLSignal(&m_sWLRCursorShapeMgr->events.request_set_shape, &Events::listen_setCursorShape, m_sWLRCursorShapeMgr, "CursorShapeMgr"); if (m_sWRLDRMLeaseMgr) addWLSignal(&m_sWRLDRMLeaseMgr->events.request, &Events::listen_leaseRequest, &m_sWRLDRMLeaseMgr, "DRM"); diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 35b292a9..1be02e62 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -86,6 +86,7 @@ class CCompositor { wlr_backend* m_sWLRHeadlessBackend; wlr_session_lock_manager_v1* m_sWLRSessionLockMgr; wlr_gamma_control_manager_v1* m_sWLRGammaCtrlMgr; + wlr_cursor_shape_manager_v1* m_sWLRCursorShapeMgr; // ------------------------------------------------- // std::string m_szWLDisplaySocket = ""; @@ -101,7 +102,7 @@ class CCompositor { std::vector m_vWindowsFadingOut; std::vector m_vSurfacesFadingOut; - std::unordered_map m_mMonitorIDMap; + std::unordered_map m_mMonitorIDMap; void initServer(); void startCompositor(); diff --git a/src/events/Events.hpp b/src/events/Events.hpp index 35f747cd..e7d6e2ad 100644 --- a/src/events/Events.hpp +++ b/src/events/Events.hpp @@ -170,4 +170,7 @@ namespace Events { // Gamma control LISTENER(setGamma); + + // Cursor shape + LISTENER(setCursorShape); }; diff --git a/src/events/Misc.cpp b/src/events/Misc.cpp index da680a00..eb1a0e81 100644 --- a/src/events/Misc.cpp +++ b/src/events/Misc.cpp @@ -231,3 +231,9 @@ void Events::listener_setGamma(wl_listener* listener, void* data) { g_pCompositor->scheduleFrameForMonitor(PMONITOR); } + +void Events::listener_setCursorShape(wl_listener* listener, void* data) { + const auto E = (wlr_cursor_shape_manager_v1_request_set_shape_event*)data; + + g_pInputManager->processMouseRequest(E); +} diff --git a/src/includes.hpp b/src/includes.hpp index d7792101..62780e95 100644 --- a/src/includes.hpp +++ b/src/includes.hpp @@ -104,6 +104,7 @@ extern "C" { #include #include #include +#include #include diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 3a7a77f2..0b174737 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -464,23 +464,14 @@ void CInputManager::onMouseButton(wlr_pointer_button_event* e) { } void CInputManager::processMouseRequest(wlr_seat_pointer_request_set_cursor_event* e) { - if (!g_pHyprRenderer->shouldRenderCursor()) - return; - if (!e->surface) { + if (!e->surface) g_pHyprRenderer->m_bWindowRequestedCursorHide = true; - } else { + else g_pHyprRenderer->m_bWindowRequestedCursorHide = false; - } - if (m_bCursorImageOverridden) { + if (!cursorImageUnlocked()) return; - } - - if (m_ecbClickBehavior == CLICKMODE_KILL) { - wlr_cursor_set_xcursor(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sWLRXCursorMgr, "crosshair"); - return; - } // cursorSurfaceInfo.pSurface = e->surface; @@ -495,6 +486,34 @@ void CInputManager::processMouseRequest(wlr_seat_pointer_request_set_cursor_even wlr_cursor_set_surface(g_pCompositor->m_sWLRCursor, e->surface, e->hotspot_x, e->hotspot_y); } +void CInputManager::processMouseRequest(wlr_cursor_shape_manager_v1_request_set_shape_event* e) { + if (!g_pHyprRenderer->shouldRenderCursor()) + return; + + if (!g_pCompositor->m_pLastFocus) + return; + + if (wl_resource_get_client(g_pCompositor->m_pLastFocus->resource) != e->seat_client->client) { + Debug::log(ERR, "Disallowing cursor shape request from unfocused"); + return; + } + + wlr_cursor_set_xcursor(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sWLRXCursorMgr, wlr_cursor_shape_v1_name(e->shape)); +} + +bool CInputManager::cursorImageUnlocked() { + if (!g_pHyprRenderer->shouldRenderCursor()) + return false; + + if (m_ecbClickBehavior == CLICKMODE_KILL) + return false; + + if (m_bCursorImageOverridden) + return false; + + return true; +} + eClickBehaviorMode CInputManager::getClickMode() { return m_ecbClickBehavior; } diff --git a/src/managers/input/InputManager.hpp b/src/managers/input/InputManager.hpp index 5c496117..862dc886 100644 --- a/src/managers/input/InputManager.hpp +++ b/src/managers/input/InputManager.hpp @@ -7,18 +7,21 @@ #include "../../helpers/Timer.hpp" #include "InputMethodRelay.hpp" -enum eClickBehaviorMode { +enum eClickBehaviorMode +{ CLICKMODE_DEFAULT = 0, CLICKMODE_KILL }; -enum eMouseBindMode { +enum eMouseBindMode +{ MBIND_INVALID = -1, MBIND_MOVE = 0, MBIND_RESIZE }; -enum eBorderIconDirection { +enum eBorderIconDirection +{ BORDERICON_NONE, BORDERICON_UP, BORDERICON_DOWN, @@ -96,7 +99,8 @@ class CInputManager { void setClickMode(eClickBehaviorMode); eClickBehaviorMode getClickMode(); - void processMouseRequest(wlr_seat_pointer_request_set_cursor_event*); + void processMouseRequest(wlr_seat_pointer_request_set_cursor_event* e); + void processMouseRequest(wlr_cursor_shape_manager_v1_request_set_shape_event* e); void onTouchDown(wlr_touch_down_event*); void onTouchUp(wlr_touch_up_event*); @@ -190,6 +194,8 @@ class CInputManager { void processMouseDownNormal(wlr_pointer_button_event* e); void processMouseDownKill(wlr_pointer_button_event* e); + bool cursorImageUnlocked(); + void disableAllKeyboards(bool virt = false); uint32_t m_uiCapabilities = 0;