cursor-shape: move to new impl

This commit is contained in:
Vaxry 2024-04-21 01:47:38 +01:00
parent a141bbbea5
commit 30e4b404f2
12 changed files with 181 additions and 41 deletions

View file

@ -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)

View file

@ -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 = []

View file

@ -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>();

View file

@ -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 = "";

View file

@ -141,9 +141,6 @@ namespace Events {
// Gamma control
LISTENER(setGamma);
// Cursor shape
LISTENER(setCursorShape);
// Shortcut inhibitor
LISTENER(newShortcutInhibitor);
};

View file

@ -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;

View file

@ -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>

View file

@ -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::cursorShape = std::make_unique<CCursorShapeProtocol>(&wp_cursor_shape_manager_v1_interface, 1, "CursorShape");
// Old protocol implementations.
// TODO: rewrite them to use hyprwayland-scanner.

View file

@ -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;

View file

@ -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;

View file

@ -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);
}

View file

@ -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;
};