virtual-pointer: move to new impl
This commit is contained in:
parent
7d49819b5e
commit
2755297670
13 changed files with 428 additions and 21 deletions
|
|
@ -245,8 +245,6 @@ void CCompositor::initServer() {
|
|||
|
||||
m_sWLROutputMgr = wlr_output_manager_v1_create(m_sWLDisplay);
|
||||
|
||||
m_sWLRVirtPtrMgr = wlr_virtual_pointer_manager_v1_create(m_sWLDisplay);
|
||||
|
||||
m_sWRLDRMLeaseMgr = wlr_drm_lease_v1_manager_create(m_sWLDisplay, m_sWLRBackend);
|
||||
if (!m_sWRLDRMLeaseMgr) {
|
||||
Debug::log(INFO, "Failed to create wlr_drm_lease_v1_manager");
|
||||
|
|
@ -305,7 +303,6 @@ void CCompositor::initAllSignals() {
|
|||
addWLSignal(&m_sWLROutputLayout->events.change, &Events::listen_change, m_sWLROutputLayout, "OutputLayout");
|
||||
addWLSignal(&m_sWLROutputMgr->events.apply, &Events::listen_outputMgrApply, m_sWLROutputMgr, "OutputMgr");
|
||||
addWLSignal(&m_sWLROutputMgr->events.test, &Events::listen_outputMgrTest, m_sWLROutputMgr, "OutputMgr");
|
||||
addWLSignal(&m_sWLRVirtPtrMgr->events.new_virtual_pointer, &Events::listen_newVirtPtr, m_sWLRVirtPtrMgr, "VirtPtrMgr");
|
||||
addWLSignal(&m_sWLRRenderer->events.destroy, &Events::listen_RendererDestroy, m_sWLRRenderer, "WLRRenderer");
|
||||
|
||||
if (m_sWRLDRMLeaseMgr)
|
||||
|
|
@ -346,7 +343,6 @@ void CCompositor::removeAllSignals() {
|
|||
removeWLSignal(&Events::listen_change);
|
||||
removeWLSignal(&Events::listen_outputMgrApply);
|
||||
removeWLSignal(&Events::listen_outputMgrTest);
|
||||
removeWLSignal(&Events::listen_newVirtPtr);
|
||||
removeWLSignal(&Events::listen_RendererDestroy);
|
||||
|
||||
if (m_sWRLDRMLeaseMgr)
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@ class CCompositor {
|
|||
wlr_egl* m_sWLREGL;
|
||||
int m_iDRMFD;
|
||||
wlr_server_decoration_manager* m_sWLRServerDecoMgr;
|
||||
wlr_virtual_pointer_manager_v1* m_sWLRVirtPtrMgr;
|
||||
wlr_tablet_manager_v2* m_sWLRTabletManager;
|
||||
wlr_xdg_foreign_registry* m_sWLRForeignRegistry;
|
||||
wlr_linux_dmabuf_v1* m_sWLRLinuxDMABuf;
|
||||
|
|
|
|||
|
|
@ -93,14 +93,6 @@ void Events::listener_newInput(wl_listener* listener, void* data) {
|
|||
g_pInputManager->updateCapabilities();
|
||||
}
|
||||
|
||||
void Events::listener_newVirtPtr(wl_listener* listener, void* data) {
|
||||
const auto EV = (wlr_virtual_pointer_v1_new_pointer_event*)data;
|
||||
const auto POINTER = EV->new_pointer;
|
||||
const auto DEVICE = &POINTER->pointer.base;
|
||||
|
||||
g_pInputManager->newMouse(DEVICE, true);
|
||||
}
|
||||
|
||||
void Events::listener_destroyMouse(void* owner, void* data) {
|
||||
const auto PMOUSE = (SMouse*)owner;
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
class CMonitor;
|
||||
class CVirtualKeyboard;
|
||||
class CVirtualPointer;
|
||||
|
||||
struct SRenderData {
|
||||
CMonitor* pMonitor;
|
||||
|
|
@ -104,13 +105,19 @@ struct SKeyboard {
|
|||
};
|
||||
|
||||
struct SMouse {
|
||||
wlr_input_device* mouse = nullptr;
|
||||
wlr_input_device* mouse = nullptr;
|
||||
|
||||
std::string name = "";
|
||||
std::string name = "";
|
||||
|
||||
bool virt = false;
|
||||
bool virt = false;
|
||||
|
||||
bool connected = false; // means connected to the cursor
|
||||
bool connected = false; // means connected to the cursor
|
||||
|
||||
WP<CVirtualPointer> virtualPointer;
|
||||
|
||||
struct {
|
||||
CHyprSignalListener destroyMouse;
|
||||
} listeners;
|
||||
|
||||
DYNLISTENER(destroyMouse);
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,6 @@ extern "C" {
|
|||
#include <wlr/types/wlr_subcompositor.h>
|
||||
#include <wlr/types/wlr_damage_ring.h>
|
||||
#include <wlr/types/wlr_keyboard_shortcuts_inhibit_v1.h>
|
||||
#include <wlr/types/wlr_virtual_pointer_v1.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include <wlr/util/region.h>
|
||||
#include <wlr/util/edges.h>
|
||||
|
|
@ -79,6 +78,7 @@ extern "C" {
|
|||
#include <wlr/render/gles2.h>
|
||||
#include <wlr/render/wlr_texture.h>
|
||||
#include <wlr/interfaces/wlr_keyboard.h>
|
||||
#include <wlr/interfaces/wlr_pointer.h>
|
||||
#include <wlr/types/wlr_xdg_foreign_registry.h>
|
||||
#include <wlr/types/wlr_xdg_foreign_v1.h>
|
||||
#include <wlr/types/wlr_xdg_foreign_v2.h>
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include "../protocols/SessionLock.hpp"
|
||||
#include "../protocols/InputMethodV2.hpp"
|
||||
#include "../protocols/VirtualKeyboard.hpp"
|
||||
#include "../protocols/VirtualPointer.hpp"
|
||||
|
||||
CProtocolManager::CProtocolManager() {
|
||||
|
||||
|
|
@ -45,6 +46,7 @@ CProtocolManager::CProtocolManager() {
|
|||
PROTO::sessionLock = std::make_unique<CSessionLockProtocol>(&ext_session_lock_manager_v1_interface, 1, "SessionLock");
|
||||
PROTO::ime = std::make_unique<CInputMethodV2Protocol>(&zwp_input_method_manager_v2_interface, 1, "IMEv2");
|
||||
PROTO::virtualKeyboard = std::make_unique<CVirtualKeyboardProtocol>(&zwp_virtual_keyboard_manager_v1_interface, 1, "VirtualKeyboard");
|
||||
PROTO::virtualPointer = std::make_unique<CVirtualPointerProtocol>(&zwlr_virtual_pointer_manager_v1_interface, 2, "VirtualPointer");
|
||||
|
||||
// Old protocol implementations.
|
||||
// TODO: rewrite them to use hyprwayland-scanner.
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include "../../protocols/SessionLock.hpp"
|
||||
#include "../../protocols/InputMethodV2.hpp"
|
||||
#include "../../protocols/VirtualKeyboard.hpp"
|
||||
#include "../../protocols/VirtualPointer.hpp"
|
||||
|
||||
CInputManager::CInputManager() {
|
||||
m_sListeners.setCursorShape = PROTO::cursorShape->events.setShape.registerListener([this](std::any data) {
|
||||
|
|
@ -40,6 +41,8 @@ CInputManager::CInputManager() {
|
|||
m_sListeners.newIdleInhibitor = PROTO::idleInhibit->events.newIdleInhibitor.registerListener([this](std::any data) { this->newIdleInhibitor(data); });
|
||||
m_sListeners.newVirtualKeyboard =
|
||||
PROTO::virtualKeyboard->events.newKeyboard.registerListener([this](std::any data) { this->newVirtualKeyboard(std::any_cast<SP<CVirtualKeyboard>>(data)); });
|
||||
m_sListeners.newVirtualMouse =
|
||||
PROTO::virtualPointer->events.newPointer.registerListener([this](std::any data) { this->newVirtualMouse(std::any_cast<SP<CVirtualPointer>>(data)); });
|
||||
}
|
||||
|
||||
CInputManager::~CInputManager() {
|
||||
|
|
@ -968,12 +971,41 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
|||
pKeyboard->keyboard->name);
|
||||
}
|
||||
|
||||
void CInputManager::newMouse(wlr_input_device* mouse, bool virt) {
|
||||
void CInputManager::newVirtualMouse(SP<CVirtualPointer> mouse) {
|
||||
const auto PMOUSE = &m_lMice.emplace_back();
|
||||
|
||||
PMOUSE->mouse = &mouse->wlr()->base;
|
||||
PMOUSE->virtualPointer = mouse;
|
||||
PMOUSE->virt = true;
|
||||
try {
|
||||
PMOUSE->name = getNameForNewDevice(mouse->wlr()->base.name);
|
||||
} catch (std::exception& e) {
|
||||
Debug::log(ERR, "Mouse had no name???"); // logic error
|
||||
}
|
||||
|
||||
wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, &mouse->wlr()->base);
|
||||
|
||||
PMOUSE->connected = true;
|
||||
|
||||
setPointerConfigs();
|
||||
|
||||
PMOUSE->hyprListener_destroyMouse.initCallback(&mouse->wlr()->base.events.destroy, &Events::listener_destroyMouse, PMOUSE, "Mouse");
|
||||
|
||||
// TODO: this pointer pass sucks.
|
||||
PMOUSE->listeners.destroyMouse = mouse->events.destroy.registerListener([this, PMOUSE](std::any data) { destroyMouse(PMOUSE->mouse); });
|
||||
|
||||
g_pCompositor->m_sSeat.mouse = PMOUSE;
|
||||
|
||||
m_tmrLastCursorMovement.reset();
|
||||
|
||||
Debug::log(LOG, "New virtual mouse created, pointer WLR: {:x}", (uintptr_t)mouse->wlr());
|
||||
}
|
||||
|
||||
void CInputManager::newMouse(wlr_input_device* mouse) {
|
||||
m_lMice.emplace_back();
|
||||
const auto PMOUSE = &m_lMice.back();
|
||||
|
||||
PMOUSE->mouse = mouse;
|
||||
PMOUSE->virt = virt;
|
||||
try {
|
||||
PMOUSE->name = getNameForNewDevice(mouse->name);
|
||||
} catch (std::exception& e) {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ class CPointerConstraint;
|
|||
class CWindow;
|
||||
class CIdleInhibitor;
|
||||
class CVirtualKeyboard;
|
||||
class CVirtualPointer;
|
||||
|
||||
enum eClickBehaviorMode {
|
||||
CLICKMODE_DEFAULT = 0,
|
||||
|
|
@ -79,7 +80,8 @@ class CInputManager {
|
|||
|
||||
void newKeyboard(wlr_input_device*);
|
||||
void newVirtualKeyboard(SP<CVirtualKeyboard>);
|
||||
void newMouse(wlr_input_device*, bool virt = false);
|
||||
void newMouse(wlr_input_device*);
|
||||
void newVirtualMouse(SP<CVirtualPointer>);
|
||||
void newTouchDevice(wlr_input_device*);
|
||||
void newSwitch(wlr_input_device*);
|
||||
void destroyTouchDevice(STouchDevice*);
|
||||
|
|
@ -201,6 +203,7 @@ class CInputManager {
|
|||
CHyprSignalListener setCursorShape;
|
||||
CHyprSignalListener newIdleInhibitor;
|
||||
CHyprSignalListener newVirtualKeyboard;
|
||||
CHyprSignalListener newVirtualMouse;
|
||||
} m_sListeners;
|
||||
|
||||
bool m_bCursorImageOverridden = false;
|
||||
|
|
|
|||
165
src/protocols/VirtualPointer.cpp
Normal file
165
src/protocols/VirtualPointer.cpp
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
#include "VirtualPointer.hpp"
|
||||
|
||||
#define LOGM PROTO::virtualPointer->protoLog
|
||||
|
||||
static const wlr_pointer_impl pointerImpl = {
|
||||
.name = "virtual-pointer-v1",
|
||||
};
|
||||
|
||||
CVirtualPointer::CVirtualPointer(SP<CZwlrVirtualPointerV1> resource_) : resource(resource_) {
|
||||
if (!good())
|
||||
return;
|
||||
|
||||
resource->setDestroy([this](CZwlrVirtualPointerV1* r) {
|
||||
events.destroy.emit();
|
||||
PROTO::virtualPointer->destroyResource(this);
|
||||
});
|
||||
resource->setOnDestroy([this](CZwlrVirtualPointerV1* r) {
|
||||
events.destroy.emit();
|
||||
PROTO::virtualPointer->destroyResource(this);
|
||||
});
|
||||
|
||||
wlr_pointer_init(&pointer, &pointerImpl, "CVirtualPointer");
|
||||
|
||||
resource->setMotion([this](CZwlrVirtualPointerV1* r, uint32_t timeMs, wl_fixed_t dx, wl_fixed_t dy) {
|
||||
wlr_pointer_motion_event event = {
|
||||
.pointer = &pointer,
|
||||
.time_msec = timeMs,
|
||||
.delta_x = wl_fixed_to_double(dx),
|
||||
.delta_y = wl_fixed_to_double(dy),
|
||||
.unaccel_dx = wl_fixed_to_double(dx),
|
||||
.unaccel_dy = wl_fixed_to_double(dy),
|
||||
};
|
||||
wl_signal_emit_mutable(&pointer.events.motion, &event);
|
||||
});
|
||||
|
||||
resource->setMotionAbsolute([this](CZwlrVirtualPointerV1* r, uint32_t timeMs, uint32_t x, uint32_t y, uint32_t xExtent, uint32_t yExtent) {
|
||||
if (!xExtent || !yExtent)
|
||||
return;
|
||||
|
||||
wlr_pointer_motion_absolute_event event = {
|
||||
.pointer = &pointer,
|
||||
.time_msec = timeMs,
|
||||
.x = (double)x / xExtent,
|
||||
.y = (double)y / yExtent,
|
||||
};
|
||||
wl_signal_emit_mutable(&pointer.events.motion_absolute, &event);
|
||||
});
|
||||
|
||||
resource->setButton([this](CZwlrVirtualPointerV1* r, uint32_t timeMs, uint32_t button, uint32_t state) {
|
||||
struct wlr_pointer_button_event event = {
|
||||
.pointer = &pointer,
|
||||
.time_msec = timeMs,
|
||||
.button = button,
|
||||
.state = (wl_pointer_button_state)state,
|
||||
};
|
||||
wl_signal_emit_mutable(&pointer.events.button, &event);
|
||||
});
|
||||
|
||||
resource->setAxis([this](CZwlrVirtualPointerV1* r, uint32_t timeMs, uint32_t axis_, wl_fixed_t value) {
|
||||
if (axis > WL_POINTER_AXIS_HORIZONTAL_SCROLL) {
|
||||
r->error(ZWLR_VIRTUAL_POINTER_V1_ERROR_INVALID_AXIS, "Invalid axis");
|
||||
return;
|
||||
}
|
||||
|
||||
axis = axis_;
|
||||
axisEvents[axis] = wlr_pointer_axis_event{.pointer = &pointer, .time_msec = timeMs, .orientation = (wl_pointer_axis)axis, .delta = wl_fixed_to_double(value)};
|
||||
});
|
||||
|
||||
resource->setFrame([this](CZwlrVirtualPointerV1* r) {
|
||||
for (auto& e : axisEvents) {
|
||||
if (!e.pointer)
|
||||
continue;
|
||||
wl_signal_emit_mutable(&pointer.events.axis, &e);
|
||||
e.pointer = nullptr;
|
||||
}
|
||||
|
||||
wl_signal_emit_mutable(&pointer.events.frame, &pointer);
|
||||
});
|
||||
|
||||
resource->setAxisSource([this](CZwlrVirtualPointerV1* r, uint32_t source) { axisEvents[axis].source = (wl_pointer_axis_source)source; });
|
||||
|
||||
resource->setAxisStop([this](CZwlrVirtualPointerV1* r, uint32_t timeMs, uint32_t axis_) {
|
||||
if (axis > WL_POINTER_AXIS_HORIZONTAL_SCROLL) {
|
||||
r->error(ZWLR_VIRTUAL_POINTER_V1_ERROR_INVALID_AXIS, "Invalid axis");
|
||||
return;
|
||||
}
|
||||
|
||||
axis = axis_;
|
||||
axisEvents[axis].pointer = &pointer;
|
||||
axisEvents[axis].time_msec = timeMs;
|
||||
axisEvents[axis].orientation = (wl_pointer_axis)axis;
|
||||
axisEvents[axis].delta = 0;
|
||||
axisEvents[axis].delta_discrete = 0;
|
||||
});
|
||||
|
||||
resource->setAxisDiscrete([this](CZwlrVirtualPointerV1* r, uint32_t timeMs, uint32_t axis_, wl_fixed_t value, int32_t discrete) {
|
||||
if (axis > WL_POINTER_AXIS_HORIZONTAL_SCROLL) {
|
||||
r->error(ZWLR_VIRTUAL_POINTER_V1_ERROR_INVALID_AXIS, "Invalid axis");
|
||||
return;
|
||||
}
|
||||
|
||||
axis = axis_;
|
||||
axisEvents[axis].pointer = &pointer;
|
||||
axisEvents[axis].time_msec = timeMs;
|
||||
axisEvents[axis].orientation = (wl_pointer_axis)axis;
|
||||
axisEvents[axis].delta = wl_fixed_to_double(value);
|
||||
axisEvents[axis].delta_discrete = discrete * 120;
|
||||
});
|
||||
}
|
||||
|
||||
CVirtualPointer::~CVirtualPointer() {
|
||||
wlr_pointer_finish(&pointer);
|
||||
events.destroy.emit();
|
||||
}
|
||||
|
||||
bool CVirtualPointer::good() {
|
||||
return resource->resource();
|
||||
}
|
||||
|
||||
wlr_pointer* CVirtualPointer::wlr() {
|
||||
return &pointer;
|
||||
}
|
||||
|
||||
wl_client* CVirtualPointer::client() {
|
||||
return resource->client();
|
||||
}
|
||||
|
||||
CVirtualPointerProtocol::CVirtualPointerProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
|
||||
;
|
||||
}
|
||||
|
||||
void CVirtualPointerProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
|
||||
const auto RESOURCE = m_vManagers.emplace_back(std::make_unique<CZwlrVirtualPointerManagerV1>(client, ver, id)).get();
|
||||
RESOURCE->setOnDestroy([this](CZwlrVirtualPointerManagerV1* p) { this->onManagerResourceDestroy(p->resource()); });
|
||||
RESOURCE->setDestroy([this](CZwlrVirtualPointerManagerV1* p) { this->onManagerResourceDestroy(p->resource()); });
|
||||
|
||||
RESOURCE->setCreateVirtualPointer([this](CZwlrVirtualPointerManagerV1* pMgr, wl_resource* seat, uint32_t id) { this->onCreatePointer(pMgr, seat, id); });
|
||||
RESOURCE->setCreateVirtualPointerWithOutput([this](CZwlrVirtualPointerManagerV1* pMgr, wl_resource* seat, wl_resource* output, uint32_t id) {
|
||||
LOGM(WARN, "TODO: CreateWithOutput is not supported yet. Ignoring for now.");
|
||||
this->onCreatePointer(pMgr, seat, id);
|
||||
});
|
||||
}
|
||||
|
||||
void CVirtualPointerProtocol::onManagerResourceDestroy(wl_resource* res) {
|
||||
std::erase_if(m_vManagers, [&](const auto& other) { return other->resource() == res; });
|
||||
}
|
||||
|
||||
void CVirtualPointerProtocol::destroyResource(CVirtualPointer* pointer) {
|
||||
std::erase_if(m_vPointers, [&](const auto& other) { return other.get() == pointer; });
|
||||
}
|
||||
|
||||
void CVirtualPointerProtocol::onCreatePointer(CZwlrVirtualPointerManagerV1* pMgr, wl_resource* seat, uint32_t id) {
|
||||
|
||||
const auto RESOURCE = m_vPointers.emplace_back(std::make_shared<CVirtualPointer>(std::make_shared<CZwlrVirtualPointerV1>(pMgr->client(), pMgr->version(), id)));
|
||||
|
||||
if (!RESOURCE->good()) {
|
||||
pMgr->noMemory();
|
||||
m_vPointers.pop_back();
|
||||
return;
|
||||
}
|
||||
|
||||
LOGM(LOG, "New VPointer at id {}", id);
|
||||
|
||||
events.newPointer.emit(RESOURCE);
|
||||
}
|
||||
57
src/protocols/VirtualPointer.hpp
Normal file
57
src/protocols/VirtualPointer.hpp
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include <array>
|
||||
#include "WaylandProtocol.hpp"
|
||||
#include "wlr-virtual-pointer-unstable-v1.hpp"
|
||||
#include "../helpers/signal/Signal.hpp"
|
||||
|
||||
class CVirtualPointer {
|
||||
public:
|
||||
CVirtualPointer(SP<CZwlrVirtualPointerV1> resource_);
|
||||
~CVirtualPointer();
|
||||
|
||||
struct {
|
||||
CSignal destroy;
|
||||
} events;
|
||||
|
||||
bool good();
|
||||
wlr_pointer* wlr();
|
||||
wl_client* client();
|
||||
|
||||
private:
|
||||
SP<CZwlrVirtualPointerV1> resource;
|
||||
wlr_pointer pointer;
|
||||
|
||||
uint32_t axis = 0;
|
||||
|
||||
std::array<wlr_pointer_axis_event, 2> axisEvents;
|
||||
};
|
||||
|
||||
class CVirtualPointerProtocol : public IWaylandProtocol {
|
||||
public:
|
||||
CVirtualPointerProtocol(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);
|
||||
|
||||
struct {
|
||||
CSignal newPointer; // SP<CVirtualPointer>
|
||||
} events;
|
||||
|
||||
private:
|
||||
void onManagerResourceDestroy(wl_resource* res);
|
||||
void destroyResource(CVirtualPointer* pointer);
|
||||
void onCreatePointer(CZwlrVirtualPointerManagerV1* pMgr, wl_resource* seat, uint32_t id);
|
||||
|
||||
//
|
||||
std::vector<UP<CZwlrVirtualPointerManagerV1>> m_vManagers;
|
||||
std::vector<SP<CVirtualPointer>> m_vPointers;
|
||||
|
||||
friend class CVirtualPointer;
|
||||
};
|
||||
|
||||
namespace PROTO {
|
||||
inline UP<CVirtualPointerProtocol> virtualPointer;
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue