mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-22 19:45:58 +01:00
cursor-shape: move to new impl
This commit is contained in:
parent
a141bbbea5
commit
30e4b404f2
12 changed files with 181 additions and 41 deletions
|
@ -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)
|
||||
|
|
|
@ -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 = []
|
||||
|
|
|
@ -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>();
|
||||
|
||||
|
|
|
@ -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 = "";
|
||||
|
|
|
@ -141,9 +141,6 @@ namespace Events {
|
|||
// Gamma control
|
||||
LISTENER(setGamma);
|
||||
|
||||
// Cursor shape
|
||||
LISTENER(setCursorShape);
|
||||
|
||||
// Shortcut inhibitor
|
||||
LISTENER(newShortcutInhibitor);
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
98
src/protocols/CursorShape.cpp
Normal file
98
src/protocols/CursorShape.cpp
Normal 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);
|
||||
}
|
42
src/protocols/CursorShape.hpp
Normal file
42
src/protocols/CursorShape.hpp
Normal 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;
|
||||
};
|
Loading…
Reference in a new issue