mirror of https://github.com/hyprwm/Hyprland
virtual-pointer: move to new impl
This commit is contained in:
parent
7d49819b5e
commit
2755297670
|
@ -262,6 +262,7 @@ protocolNew("protocols/wlr-gamma-control-unstable-v1.xml" "wlr-gamma-control-uns
|
||||||
protocolNew("protocols/wlr-foreign-toplevel-management-unstable-v1.xml" "wlr-foreign-toplevel-management-unstable-v1" true)
|
protocolNew("protocols/wlr-foreign-toplevel-management-unstable-v1.xml" "wlr-foreign-toplevel-management-unstable-v1" true)
|
||||||
protocolNew("protocols/wlr-output-power-management-unstable-v1.xml" "wlr-output-power-management-unstable-v1" true)
|
protocolNew("protocols/wlr-output-power-management-unstable-v1.xml" "wlr-output-power-management-unstable-v1" true)
|
||||||
protocolNew("protocols/virtual-keyboard-unstable-v1.xml" "virtual-keyboard-unstable-v1" true)
|
protocolNew("protocols/virtual-keyboard-unstable-v1.xml" "virtual-keyboard-unstable-v1" true)
|
||||||
|
protocolNew("protocols/wlr-virtual-pointer-unstable-v1.xml" "wlr-virtual-pointer-unstable-v1" true)
|
||||||
protocolNew("protocols/input-method-unstable-v2.xml" "input-method-unstable-v2" true)
|
protocolNew("protocols/input-method-unstable-v2.xml" "input-method-unstable-v2" true)
|
||||||
protocolNew("staging/tearing-control/tearing-control-v1.xml" "tearing-control-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("staging/fractional-scale/fractional-scale-v1.xml" "fractional-scale-v1" false)
|
||||||
|
|
|
@ -40,6 +40,7 @@ new_protocols = [
|
||||||
['wlr-output-power-management-unstable-v1.xml'],
|
['wlr-output-power-management-unstable-v1.xml'],
|
||||||
['input-method-unstable-v2.xml'],
|
['input-method-unstable-v2.xml'],
|
||||||
['virtual-keyboard-unstable-v1.xml'],
|
['virtual-keyboard-unstable-v1.xml'],
|
||||||
|
['wlr-virtual-pointer-unstable-v1.xml'],
|
||||||
[wl_protocol_dir, 'staging/tearing-control/tearing-control-v1.xml'],
|
[wl_protocol_dir, 'staging/tearing-control/tearing-control-v1.xml'],
|
||||||
[wl_protocol_dir, 'staging/fractional-scale/fractional-scale-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, 'unstable/xdg-output/xdg-output-unstable-v1.xml'],
|
||||||
|
|
|
@ -0,0 +1,152 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<protocol name="wlr_virtual_pointer_unstable_v1">
|
||||||
|
<copyright>
|
||||||
|
Copyright © 2019 Josef Gajdusek
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice (including the next
|
||||||
|
paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
</copyright>
|
||||||
|
|
||||||
|
<interface name="zwlr_virtual_pointer_v1" version="2">
|
||||||
|
<description summary="virtual pointer">
|
||||||
|
This protocol allows clients to emulate a physical pointer device. The
|
||||||
|
requests are mostly mirror opposites of those specified in wl_pointer.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<enum name="error">
|
||||||
|
<entry name="invalid_axis" value="0"
|
||||||
|
summary="client sent invalid axis enumeration value" />
|
||||||
|
<entry name="invalid_axis_source" value="1"
|
||||||
|
summary="client sent invalid axis source enumeration value" />
|
||||||
|
</enum>
|
||||||
|
|
||||||
|
<request name="motion">
|
||||||
|
<description summary="pointer relative motion event">
|
||||||
|
The pointer has moved by a relative amount to the previous request.
|
||||||
|
|
||||||
|
Values are in the global compositor space.
|
||||||
|
</description>
|
||||||
|
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
|
||||||
|
<arg name="dx" type="fixed" summary="displacement on the x-axis"/>
|
||||||
|
<arg name="dy" type="fixed" summary="displacement on the y-axis"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="motion_absolute">
|
||||||
|
<description summary="pointer absolute motion event">
|
||||||
|
The pointer has moved in an absolute coordinate frame.
|
||||||
|
|
||||||
|
Value of x can range from 0 to x_extent, value of y can range from 0
|
||||||
|
to y_extent.
|
||||||
|
</description>
|
||||||
|
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
|
||||||
|
<arg name="x" type="uint" summary="position on the x-axis"/>
|
||||||
|
<arg name="y" type="uint" summary="position on the y-axis"/>
|
||||||
|
<arg name="x_extent" type="uint" summary="extent of the x-axis"/>
|
||||||
|
<arg name="y_extent" type="uint" summary="extent of the y-axis"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="button">
|
||||||
|
<description summary="button event">
|
||||||
|
A button was pressed or released.
|
||||||
|
</description>
|
||||||
|
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
|
||||||
|
<arg name="button" type="uint" summary="button that produced the event"/>
|
||||||
|
<arg name="state" type="uint" enum="wl_pointer.button_state" summary="physical state of the button"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="axis">
|
||||||
|
<description summary="axis event">
|
||||||
|
Scroll and other axis requests.
|
||||||
|
</description>
|
||||||
|
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
|
||||||
|
<arg name="axis" type="uint" enum="wl_pointer.axis" summary="axis type"/>
|
||||||
|
<arg name="value" type="fixed" summary="length of vector in touchpad coordinates"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="frame">
|
||||||
|
<description summary="end of a pointer event sequence">
|
||||||
|
Indicates the set of events that logically belong together.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="axis_source">
|
||||||
|
<description summary="axis source event">
|
||||||
|
Source information for scroll and other axis.
|
||||||
|
</description>
|
||||||
|
<arg name="axis_source" type="uint" enum="wl_pointer.axis_source" summary="source of the axis event"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="axis_stop">
|
||||||
|
<description summary="axis stop event">
|
||||||
|
Stop notification for scroll and other axes.
|
||||||
|
</description>
|
||||||
|
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
|
||||||
|
<arg name="axis" type="uint" enum="wl_pointer.axis" summary="the axis stopped with this event"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="axis_discrete">
|
||||||
|
<description summary="axis click event">
|
||||||
|
Discrete step information for scroll and other axes.
|
||||||
|
|
||||||
|
This event allows the client to extend data normally sent using the axis
|
||||||
|
event with discrete value.
|
||||||
|
</description>
|
||||||
|
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
|
||||||
|
<arg name="axis" type="uint" enum="wl_pointer.axis" summary="axis type"/>
|
||||||
|
<arg name="value" type="fixed" summary="length of vector in touchpad coordinates"/>
|
||||||
|
<arg name="discrete" type="int" summary="number of steps"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="destroy" type="destructor" since="1">
|
||||||
|
<description summary="destroy the virtual pointer object"/>
|
||||||
|
</request>
|
||||||
|
</interface>
|
||||||
|
|
||||||
|
<interface name="zwlr_virtual_pointer_manager_v1" version="2">
|
||||||
|
<description summary="virtual pointer manager">
|
||||||
|
This object allows clients to create individual virtual pointer objects.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<request name="create_virtual_pointer">
|
||||||
|
<description summary="Create a new virtual pointer">
|
||||||
|
Creates a new virtual pointer. The optional seat is a suggestion to the
|
||||||
|
compositor.
|
||||||
|
</description>
|
||||||
|
<arg name="seat" type="object" interface="wl_seat" allow-null="true"/>
|
||||||
|
<arg name="id" type="new_id" interface="zwlr_virtual_pointer_v1"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="destroy" type="destructor" since="1">
|
||||||
|
<description summary="destroy the virtual pointer manager"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<!-- Version 2 additions -->
|
||||||
|
<request name="create_virtual_pointer_with_output" since="2">
|
||||||
|
<description summary="Create a new virtual pointer">
|
||||||
|
Creates a new virtual pointer. The seat and the output arguments are
|
||||||
|
optional. If the seat argument is set, the compositor should assign the
|
||||||
|
input device to the requested seat. If the output argument is set, the
|
||||||
|
compositor should map the input device to the requested output.
|
||||||
|
</description>
|
||||||
|
<arg name="seat" type="object" interface="wl_seat" allow-null="true"/>
|
||||||
|
<arg name="output" type="object" interface="wl_output" allow-null="true"/>
|
||||||
|
<arg name="id" type="new_id" interface="zwlr_virtual_pointer_v1"/>
|
||||||
|
</request>
|
||||||
|
</interface>
|
||||||
|
</protocol>
|
|
@ -245,8 +245,6 @@ void CCompositor::initServer() {
|
||||||
|
|
||||||
m_sWLROutputMgr = wlr_output_manager_v1_create(m_sWLDisplay);
|
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);
|
m_sWRLDRMLeaseMgr = wlr_drm_lease_v1_manager_create(m_sWLDisplay, m_sWLRBackend);
|
||||||
if (!m_sWRLDRMLeaseMgr) {
|
if (!m_sWRLDRMLeaseMgr) {
|
||||||
Debug::log(INFO, "Failed to create wlr_drm_lease_v1_manager");
|
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_sWLROutputLayout->events.change, &Events::listen_change, m_sWLROutputLayout, "OutputLayout");
|
||||||
addWLSignal(&m_sWLROutputMgr->events.apply, &Events::listen_outputMgrApply, m_sWLROutputMgr, "OutputMgr");
|
addWLSignal(&m_sWLROutputMgr->events.apply, &Events::listen_outputMgrApply, m_sWLROutputMgr, "OutputMgr");
|
||||||
addWLSignal(&m_sWLROutputMgr->events.test, &Events::listen_outputMgrTest, 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");
|
addWLSignal(&m_sWLRRenderer->events.destroy, &Events::listen_RendererDestroy, m_sWLRRenderer, "WLRRenderer");
|
||||||
|
|
||||||
if (m_sWRLDRMLeaseMgr)
|
if (m_sWRLDRMLeaseMgr)
|
||||||
|
@ -346,7 +343,6 @@ void CCompositor::removeAllSignals() {
|
||||||
removeWLSignal(&Events::listen_change);
|
removeWLSignal(&Events::listen_change);
|
||||||
removeWLSignal(&Events::listen_outputMgrApply);
|
removeWLSignal(&Events::listen_outputMgrApply);
|
||||||
removeWLSignal(&Events::listen_outputMgrTest);
|
removeWLSignal(&Events::listen_outputMgrTest);
|
||||||
removeWLSignal(&Events::listen_newVirtPtr);
|
|
||||||
removeWLSignal(&Events::listen_RendererDestroy);
|
removeWLSignal(&Events::listen_RendererDestroy);
|
||||||
|
|
||||||
if (m_sWRLDRMLeaseMgr)
|
if (m_sWRLDRMLeaseMgr)
|
||||||
|
|
|
@ -60,7 +60,6 @@ class CCompositor {
|
||||||
wlr_egl* m_sWLREGL;
|
wlr_egl* m_sWLREGL;
|
||||||
int m_iDRMFD;
|
int m_iDRMFD;
|
||||||
wlr_server_decoration_manager* m_sWLRServerDecoMgr;
|
wlr_server_decoration_manager* m_sWLRServerDecoMgr;
|
||||||
wlr_virtual_pointer_manager_v1* m_sWLRVirtPtrMgr;
|
|
||||||
wlr_tablet_manager_v2* m_sWLRTabletManager;
|
wlr_tablet_manager_v2* m_sWLRTabletManager;
|
||||||
wlr_xdg_foreign_registry* m_sWLRForeignRegistry;
|
wlr_xdg_foreign_registry* m_sWLRForeignRegistry;
|
||||||
wlr_linux_dmabuf_v1* m_sWLRLinuxDMABuf;
|
wlr_linux_dmabuf_v1* m_sWLRLinuxDMABuf;
|
||||||
|
|
|
@ -93,14 +93,6 @@ void Events::listener_newInput(wl_listener* listener, void* data) {
|
||||||
g_pInputManager->updateCapabilities();
|
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) {
|
void Events::listener_destroyMouse(void* owner, void* data) {
|
||||||
const auto PMOUSE = (SMouse*)owner;
|
const auto PMOUSE = (SMouse*)owner;
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
class CMonitor;
|
class CMonitor;
|
||||||
class CVirtualKeyboard;
|
class CVirtualKeyboard;
|
||||||
|
class CVirtualPointer;
|
||||||
|
|
||||||
struct SRenderData {
|
struct SRenderData {
|
||||||
CMonitor* pMonitor;
|
CMonitor* pMonitor;
|
||||||
|
@ -104,13 +105,19 @@ struct SKeyboard {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SMouse {
|
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);
|
DYNLISTENER(destroyMouse);
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,6 @@ extern "C" {
|
||||||
#include <wlr/types/wlr_subcompositor.h>
|
#include <wlr/types/wlr_subcompositor.h>
|
||||||
#include <wlr/types/wlr_damage_ring.h>
|
#include <wlr/types/wlr_damage_ring.h>
|
||||||
#include <wlr/types/wlr_keyboard_shortcuts_inhibit_v1.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/log.h>
|
||||||
#include <wlr/util/region.h>
|
#include <wlr/util/region.h>
|
||||||
#include <wlr/util/edges.h>
|
#include <wlr/util/edges.h>
|
||||||
|
@ -79,6 +78,7 @@ extern "C" {
|
||||||
#include <wlr/render/gles2.h>
|
#include <wlr/render/gles2.h>
|
||||||
#include <wlr/render/wlr_texture.h>
|
#include <wlr/render/wlr_texture.h>
|
||||||
#include <wlr/interfaces/wlr_keyboard.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_registry.h>
|
||||||
#include <wlr/types/wlr_xdg_foreign_v1.h>
|
#include <wlr/types/wlr_xdg_foreign_v1.h>
|
||||||
#include <wlr/types/wlr_xdg_foreign_v2.h>
|
#include <wlr/types/wlr_xdg_foreign_v2.h>
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "../protocols/SessionLock.hpp"
|
#include "../protocols/SessionLock.hpp"
|
||||||
#include "../protocols/InputMethodV2.hpp"
|
#include "../protocols/InputMethodV2.hpp"
|
||||||
#include "../protocols/VirtualKeyboard.hpp"
|
#include "../protocols/VirtualKeyboard.hpp"
|
||||||
|
#include "../protocols/VirtualPointer.hpp"
|
||||||
|
|
||||||
CProtocolManager::CProtocolManager() {
|
CProtocolManager::CProtocolManager() {
|
||||||
|
|
||||||
|
@ -45,6 +46,7 @@ CProtocolManager::CProtocolManager() {
|
||||||
PROTO::sessionLock = std::make_unique<CSessionLockProtocol>(&ext_session_lock_manager_v1_interface, 1, "SessionLock");
|
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::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::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.
|
// Old protocol implementations.
|
||||||
// TODO: rewrite them to use hyprwayland-scanner.
|
// TODO: rewrite them to use hyprwayland-scanner.
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "../../protocols/SessionLock.hpp"
|
#include "../../protocols/SessionLock.hpp"
|
||||||
#include "../../protocols/InputMethodV2.hpp"
|
#include "../../protocols/InputMethodV2.hpp"
|
||||||
#include "../../protocols/VirtualKeyboard.hpp"
|
#include "../../protocols/VirtualKeyboard.hpp"
|
||||||
|
#include "../../protocols/VirtualPointer.hpp"
|
||||||
|
|
||||||
CInputManager::CInputManager() {
|
CInputManager::CInputManager() {
|
||||||
m_sListeners.setCursorShape = PROTO::cursorShape->events.setShape.registerListener([this](std::any data) {
|
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.newIdleInhibitor = PROTO::idleInhibit->events.newIdleInhibitor.registerListener([this](std::any data) { this->newIdleInhibitor(data); });
|
||||||
m_sListeners.newVirtualKeyboard =
|
m_sListeners.newVirtualKeyboard =
|
||||||
PROTO::virtualKeyboard->events.newKeyboard.registerListener([this](std::any data) { this->newVirtualKeyboard(std::any_cast<SP<CVirtualKeyboard>>(data)); });
|
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() {
|
CInputManager::~CInputManager() {
|
||||||
|
@ -968,12 +971,41 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
||||||
pKeyboard->keyboard->name);
|
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();
|
m_lMice.emplace_back();
|
||||||
const auto PMOUSE = &m_lMice.back();
|
const auto PMOUSE = &m_lMice.back();
|
||||||
|
|
||||||
PMOUSE->mouse = mouse;
|
PMOUSE->mouse = mouse;
|
||||||
PMOUSE->virt = virt;
|
|
||||||
try {
|
try {
|
||||||
PMOUSE->name = getNameForNewDevice(mouse->name);
|
PMOUSE->name = getNameForNewDevice(mouse->name);
|
||||||
} catch (std::exception& e) {
|
} catch (std::exception& e) {
|
||||||
|
|
|
@ -12,6 +12,7 @@ class CPointerConstraint;
|
||||||
class CWindow;
|
class CWindow;
|
||||||
class CIdleInhibitor;
|
class CIdleInhibitor;
|
||||||
class CVirtualKeyboard;
|
class CVirtualKeyboard;
|
||||||
|
class CVirtualPointer;
|
||||||
|
|
||||||
enum eClickBehaviorMode {
|
enum eClickBehaviorMode {
|
||||||
CLICKMODE_DEFAULT = 0,
|
CLICKMODE_DEFAULT = 0,
|
||||||
|
@ -79,7 +80,8 @@ class CInputManager {
|
||||||
|
|
||||||
void newKeyboard(wlr_input_device*);
|
void newKeyboard(wlr_input_device*);
|
||||||
void newVirtualKeyboard(SP<CVirtualKeyboard>);
|
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 newTouchDevice(wlr_input_device*);
|
||||||
void newSwitch(wlr_input_device*);
|
void newSwitch(wlr_input_device*);
|
||||||
void destroyTouchDevice(STouchDevice*);
|
void destroyTouchDevice(STouchDevice*);
|
||||||
|
@ -201,6 +203,7 @@ class CInputManager {
|
||||||
CHyprSignalListener setCursorShape;
|
CHyprSignalListener setCursorShape;
|
||||||
CHyprSignalListener newIdleInhibitor;
|
CHyprSignalListener newIdleInhibitor;
|
||||||
CHyprSignalListener newVirtualKeyboard;
|
CHyprSignalListener newVirtualKeyboard;
|
||||||
|
CHyprSignalListener newVirtualMouse;
|
||||||
} m_sListeners;
|
} m_sListeners;
|
||||||
|
|
||||||
bool m_bCursorImageOverridden = false;
|
bool m_bCursorImageOverridden = false;
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
|
@ -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…
Reference in New Issue