aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rwxr-xr-xCMakeLists.txt2
-rw-r--r--protocols/meson.build2
-rw-r--r--src/Compositor.cpp10
-rw-r--r--src/Compositor.hpp1
-rw-r--r--src/events/Events.hpp3
-rw-r--r--src/events/Misc.cpp6
-rw-r--r--src/includes.hpp1
-rw-r--r--src/managers/ProtocolManager.cpp9
-rw-r--r--src/managers/input/InputManager.cpp40
-rw-r--r--src/managers/input/InputManager.hpp8
-rw-r--r--src/protocols/CursorShape.cpp98
-rw-r--r--src/protocols/CursorShape.hpp42
12 files changed, 181 insertions, 41 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5b88440b..e134f9c6 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -261,10 +261,10 @@ protocol("subprojects/hyprland-protocols/protocols/hyprland-toplevel-export-v1.x
protocol("stable/xdg-shell/xdg-shell.xml" "xdg-shell" false)
protocol("unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml" "linux-dmabuf-unstable-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)
protocolNew("staging/tearing-control/tearing-control-v1.xml" "tearing-control-v1" false)
protocolNew("staging/fractional-scale/fractional-scale-v1.xml" "fractional-scale-v1" false)
protocolNew("unstable/xdg-output/xdg-output-unstable-v1.xml" "xdg-output-unstable-v1" false)
+protocolNew("staging/cursor-shape/cursor-shape-v1.xml" "cursor-shape-v1" false)
# tools
add_subdirectory(hyprctl)
diff --git a/protocols/meson.build b/protocols/meson.build
index 150ea55f..009643f9 100644
--- a/protocols/meson.build
+++ b/protocols/meson.build
@@ -27,7 +27,6 @@ protocols = [
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
[wl_protocol_dir, 'unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml'],
[wl_protocol_dir, 'unstable/text-input/text-input-unstable-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'],
@@ -43,6 +42,7 @@ new_protocols = [
[wl_protocol_dir, 'staging/tearing-control/tearing-control-v1.xml'],
[wl_protocol_dir, 'staging/fractional-scale/fractional-scale-v1.xml'],
[wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.xml'],
+ [wl_protocol_dir, 'staging/cursor-shape/cursor-shape-v1.xml'],
]
wl_protos_src = []
diff --git a/src/Compositor.cpp b/src/Compositor.cpp
index edf7c25d..157a70d6 100644
--- a/src/Compositor.cpp
+++ b/src/Compositor.cpp
@@ -252,8 +252,6 @@ 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");
throwError("wlr_headless_backend_create() failed!");
@@ -309,7 +307,6 @@ 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");
addWLSignal(&m_sWLRKbShInhibitMgr->events.new_inhibitor, &Events::listen_newShortcutInhibitor, m_sWLRKbShInhibitMgr, "ShortcutInhibitMgr");
if (m_sWRLDRMLeaseMgr)
@@ -362,7 +359,6 @@ void CCompositor::removeAllSignals() {
removeWLSignal(&Events::listen_activateXDG);
removeWLSignal(&Events::listen_newSessionLock);
removeWLSignal(&Events::listen_setGamma);
- removeWLSignal(&Events::listen_setCursorShape);
removeWLSignal(&Events::listen_newShortcutInhibitor);
if (m_sWRLDRMLeaseMgr)
@@ -455,6 +451,9 @@ void CCompositor::initManagers(eManagersInitStage stage) {
Debug::log(LOG, "Creating the HookSystem!");
g_pHookSystem = std::make_unique<CHookSystemManager>();
+ Debug::log(LOG, "Creating the ProtocolManager!");
+ g_pProtocolManager = std::make_unique<CProtocolManager>();
+
Debug::log(LOG, "Creating the KeybindManager!");
g_pKeybindManager = std::make_unique<CKeybindManager>();
@@ -492,9 +491,6 @@ void CCompositor::initManagers(eManagersInitStage stage) {
Debug::log(LOG, "Creating the XWaylandManager!");
g_pXWaylandManager = std::make_unique<CHyprXWaylandManager>();
- Debug::log(LOG, "Creating the ProtocolManager!");
- g_pProtocolManager = std::make_unique<CProtocolManager>();
-
Debug::log(LOG, "Creating the SessionLockManager!");
g_pSessionLockManager = std::make_unique<CSessionLockManager>();
diff --git a/src/Compositor.hpp b/src/Compositor.hpp
index 9244c673..8cca11c2 100644
--- a/src/Compositor.hpp
+++ b/src/Compositor.hpp
@@ -81,7 +81,6 @@ 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 = "";
diff --git a/src/events/Events.hpp b/src/events/Events.hpp
index 4c4503ad..445b884c 100644
--- a/src/events/Events.hpp
+++ b/src/events/Events.hpp
@@ -141,9 +141,6 @@ namespace Events {
// Gamma control
LISTENER(setGamma);
- // Cursor shape
- LISTENER(setCursorShape);
-
// Shortcut inhibitor
LISTENER(newShortcutInhibitor);
};
diff --git a/src/events/Misc.cpp b/src/events/Misc.cpp
index 53bd6f9f..3952920a 100644
--- a/src/events/Misc.cpp
+++ b/src/events/Misc.cpp
@@ -239,12 +239,6 @@ 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);
-}
-
void Events::listener_newShortcutInhibitor(wl_listener* listener, void* data) {
const auto INHIBITOR = (wlr_keyboard_shortcuts_inhibitor_v1*)data;
diff --git a/src/includes.hpp b/src/includes.hpp
index c43c2eaf..23e96425 100644
--- a/src/includes.hpp
+++ b/src/includes.hpp
@@ -102,7 +102,6 @@ extern "C" {
#include <wlr/types/wlr_session_lock_v1.h>
#include <wlr/types/wlr_single_pixel_buffer_v1.h>
#include <wlr/types/wlr_idle_notify_v1.h>
-#include <wlr/types/wlr_cursor_shape_v1.h>
#include <wlr/util/box.h>
#include <wlr/util/transform.h>
#include <wlr/render/swapchain.h>
diff --git a/src/managers/ProtocolManager.cpp b/src/managers/ProtocolManager.cpp
index 873d1a17..67b3bdeb 100644
--- a/src/managers/ProtocolManager.cpp
+++ b/src/managers/ProtocolManager.cpp
@@ -3,16 +3,19 @@
#include "../protocols/TearingControl.hpp"
#include "../protocols/FractionalScale.hpp"
#include "../protocols/XDGOutput.hpp"
+#include "../protocols/CursorShape.hpp"
#include "tearing-control-v1.hpp"
#include "fractional-scale-v1.hpp"
#include "xdg-output-unstable-v1.hpp"
+#include "cursor-shape-v1.hpp"
CProtocolManager::CProtocolManager() {
- PROTO::tearing = std::make_unique<CTearingControlProtocol>(&wp_tearing_control_manager_v1_interface, 1, "TearingControl");
- PROTO::fractional = std::make_unique<CFractionalScaleProtocol>(&wp_fractional_scale_manager_v1_interface, 1, "FractionalScale");
- PROTO::xdgOutput = std::make_unique<CXDGOutputProtocol>(&zxdg_output_manager_v1_interface, 3, "XDGOutput");
+ PROTO::tearing = std::make_unique<CTearingControlProtocol>(&wp_tearing_control_manager_v1_interface, 1, "TearingControl");
+ PROTO::fractional = std::make_unique<CFractionalScaleProtocol>(&wp_fractional_scale_manager_v1_interface, 1, "FractionalScale");
+ PROTO::xdgOutput = std::make_unique<CXDGOutputProtocol>(&zxdg_output_manager_v1_interface, 3, "XDGOutput");
+ PROTO::cursorShape = std::make_unique<CCursorShapeProtocol>(&wp_cursor_shape_manager_v1_interface, 1, "CursorShape");
// Old protocol implementations.
// TODO: rewrite them to use hyprwayland-scanner.
diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp
index 60e4270d..4a7fc11a 100644
--- a/src/managers/input/InputManager.cpp
+++ b/src/managers/input/InputManager.cpp
@@ -4,6 +4,29 @@
#include <ranges>
#include "../../config/ConfigValue.hpp"
#include "../../desktop/Window.hpp"
+#include "../../protocols/CursorShape.hpp"
+
+CInputManager::CInputManager() {
+ m_sListeners.setCursorShape = PROTO::cursorShape->events.setShape.registerListener([this](std::any data) {
+ if (!cursorImageUnlocked())
+ return;
+
+ auto event = std::any_cast<CCursorShapeProtocol::SSetShapeEvent>(data);
+
+ if (wl_resource_get_client(event.pMgr->resource()) != g_pCompositor->m_sSeat.seat->pointer_state.focused_client->client)
+ return;
+
+ Debug::log(LOG, "cursorImage request: shape {} -> {}", (uint32_t)event.shape, event.shapeName);
+
+ m_sCursorSurfaceInfo.wlSurface.unassign();
+ m_sCursorSurfaceInfo.vHotspot = {};
+ m_sCursorSurfaceInfo.name = event.shapeName;
+ m_sCursorSurfaceInfo.hidden = false;
+
+ m_sCursorSurfaceInfo.inUse = true;
+ g_pHyprRenderer->setCursorFromName(m_sCursorSurfaceInfo.name);
+ });
+}
CInputManager::~CInputManager() {
m_vConstraints.clear();
@@ -509,23 +532,6 @@ void CInputManager::processMouseRequest(wlr_seat_pointer_request_set_cursor_even
}
}
-void CInputManager::processMouseRequest(wlr_cursor_shape_manager_v1_request_set_shape_event* e) {
- if (!cursorImageUnlocked())
- return;
-
- Debug::log(LOG, "cursorImage request: shape {}", (uint32_t)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;
diff --git a/src/managers/input/InputManager.hpp b/src/managers/input/InputManager.hpp
index f1c322ca..dd8f5c63 100644
--- a/src/managers/input/InputManager.hpp
+++ b/src/managers/input/InputManager.hpp
@@ -5,6 +5,7 @@
#include "../../helpers/WLClasses.hpp"
#include "../../helpers/Timer.hpp"
#include "InputMethodRelay.hpp"
+#include "../../helpers/signal/Listener.hpp"
class CConstraint;
class CWindow;
@@ -63,6 +64,7 @@ class CKeybindManager;
class CInputManager {
public:
+ CInputManager();
~CInputManager();
void onMouseMoved(wlr_pointer_motion_event*);
@@ -102,7 +104,6 @@ class CInputManager {
void setClickMode(eClickBehaviorMode);
eClickBehaviorMode getClickMode();
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*);
@@ -197,6 +198,11 @@ class CInputManager {
bool m_bEmptyFocusCursorSet = false;
private:
+ // Listeners
+ struct {
+ CHyprSignalListener setCursorShape;
+ } m_sListeners;
+
bool m_bCursorImageOverridden = false;
eBorderIconDirection m_eBorderIconDirection = BORDERICON_NONE;
diff --git a/src/protocols/CursorShape.cpp b/src/protocols/CursorShape.cpp
new file mode 100644
index 00000000..da27dbda
--- /dev/null
+++ b/src/protocols/CursorShape.cpp
@@ -0,0 +1,98 @@
+#include "CursorShape.hpp"
+
+// 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) {
+ ;
+}
+
+void CCursorShapeProtocol::onManagerResourceDestroy(wl_resource* res) {
+ std::erase_if(m_vManagers, [&](const auto& other) { return other->resource() == res; });
+}
+
+void CCursorShapeProtocol::onDeviceResourceDestroy(wl_resource* res) {
+ m_mDevices.erase(res);
+}
+
+void CCursorShapeProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
+ const auto RESOURCE = m_vManagers.emplace_back(std::make_unique<CWpCursorShapeManagerV1>(client, ver, id)).get();
+ RESOURCE->setOnDestroy([this](CWpCursorShapeManagerV1* p) { this->onManagerResourceDestroy(p->resource()); });
+
+ RESOURCE->setDestroy([this](CWpCursorShapeManagerV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); });
+ RESOURCE->setGetPointer([this](CWpCursorShapeManagerV1* pMgr, uint32_t id, wl_resource* pointer) { this->onGetPointer(pMgr, id, pointer); });
+ RESOURCE->setGetTabletToolV2([this](CWpCursorShapeManagerV1* pMgr, uint32_t id, wl_resource* tablet) { this->onGetTabletToolV2(pMgr, id, tablet); });
+}
+
+void CCursorShapeProtocol::onGetPointer(CWpCursorShapeManagerV1* pMgr, uint32_t id, wl_resource* pointer) {
+ createCursorShapeDevice(pMgr, id, pointer);
+}
+
+void CCursorShapeProtocol::onGetTabletToolV2(CWpCursorShapeManagerV1* pMgr, uint32_t id, wl_resource* tablet) {
+ createCursorShapeDevice(pMgr, id, tablet);
+}
+
+void CCursorShapeProtocol::createCursorShapeDevice(CWpCursorShapeManagerV1* pMgr, uint32_t id, wl_resource* resource) {
+ if (m_mDevices.contains(resource)) {
+ wl_resource_post_error(resource, 0, "Device already exists");
+ return;
+ }
+
+ const auto CLIENT = wl_resource_get_client(pMgr->resource());
+ const auto RESOURCE = m_mDevices.emplace(resource, std::make_shared<CWpCursorShapeDeviceV1>(CLIENT, wl_resource_get_version(pMgr->resource()), id)).first->second.get();
+ RESOURCE->setOnDestroy([this](CWpCursorShapeDeviceV1* p) { this->onDeviceResourceDestroy(p->resource()); });
+
+ RESOURCE->setDestroy([this](CWpCursorShapeDeviceV1* p) { this->onDeviceResourceDestroy(p->resource()); });
+ RESOURCE->setSetShape([this](CWpCursorShapeDeviceV1* p, uint32_t serial, wpCursorShapeDeviceV1Shape shape) { this->onSetShape(p, serial, shape); });
+}
+
+void CCursorShapeProtocol::onSetShape(CWpCursorShapeDeviceV1* pMgr, uint32_t serial, wpCursorShapeDeviceV1Shape shape) {
+ if ((uint32_t)shape == 0 || (uint32_t)shape > sizeof(SHAPE_NAMES)) {
+ wl_resource_post_error(pMgr->resource(), ERROR_INVALID_SHAPE, "The shape is invalid");
+ return;
+ }
+
+ SSetShapeEvent event;
+ event.pMgr = pMgr;
+ event.shape = shape;
+ event.shapeName = SHAPE_NAMES[shape];
+
+ events.setShape.emit(event);
+} \ No newline at end of file
diff --git a/src/protocols/CursorShape.hpp b/src/protocols/CursorShape.hpp
new file mode 100644
index 00000000..f410bf5b
--- /dev/null
+++ b/src/protocols/CursorShape.hpp
@@ -0,0 +1,42 @@
+#pragma once
+
+#include <memory>
+#include <unordered_map>
+#include "WaylandProtocol.hpp"
+#include "../helpers/signal/Signal.hpp"
+#include "cursor-shape-v1.hpp"
+
+class CCursorShapeProtocol : public IWaylandProtocol {
+ public:
+ CCursorShapeProtocol(const wl_interface* iface, const int& ver, const std::string& name);
+
+ virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);
+
+ void onManagerResourceDestroy(wl_resource* res);
+ void onDeviceResourceDestroy(wl_resource* res);
+
+ void onGetPointer(CWpCursorShapeManagerV1* pMgr, uint32_t id, wl_resource* pointer);
+ void onGetTabletToolV2(CWpCursorShapeManagerV1* pMgr, uint32_t id, wl_resource* tablet);
+
+ void onSetShape(CWpCursorShapeDeviceV1* pMgr, uint32_t serial, wpCursorShapeDeviceV1Shape shape);
+
+ struct SSetShapeEvent {
+ CWpCursorShapeDeviceV1* pMgr = nullptr;
+ wpCursorShapeDeviceV1Shape shape;
+ std::string shapeName;
+ };
+
+ struct {
+ CSignal setShape;
+ } events;
+
+ private:
+ void createCursorShapeDevice(CWpCursorShapeManagerV1* pMgr, uint32_t id, wl_resource* resource);
+
+ std::unordered_map<wl_resource*, SP<CWpCursorShapeDeviceV1>> m_mDevices;
+ std::vector<UP<CWpCursorShapeManagerV1>> m_vManagers;
+};
+
+namespace PROTO {
+ inline UP<CCursorShapeProtocol> cursorShape;
+}; \ No newline at end of file