mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-22 14:25:59 +01:00
virtual-keyboard: move to new impl
This commit is contained in:
parent
a3ca016d42
commit
6aa2d123ae
14 changed files with 370 additions and 67 deletions
|
@ -261,6 +261,7 @@ protocol("unstable/text-input/text-input-unstable-v1.xml" "text-input-unstable-v
|
|||
protocolNew("protocols/wlr-gamma-control-unstable-v1.xml" "wlr-gamma-control-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/virtual-keyboard-unstable-v1.xml" "virtual-keyboard-unstable-v1" 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/fractional-scale/fractional-scale-v1.xml" "fractional-scale-v1" false)
|
||||
|
|
|
@ -39,6 +39,7 @@ new_protocols = [
|
|||
['wlr-foreign-toplevel-management-unstable-v1.xml'],
|
||||
['wlr-output-power-management-unstable-v1.xml'],
|
||||
['input-method-unstable-v2.xml'],
|
||||
['virtual-keyboard-unstable-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, 'unstable/xdg-output/xdg-output-unstable-v1.xml'],
|
||||
|
|
113
protocols/virtual-keyboard-unstable-v1.xml
Normal file
113
protocols/virtual-keyboard-unstable-v1.xml
Normal file
|
@ -0,0 +1,113 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="virtual_keyboard_unstable_v1">
|
||||
<copyright>
|
||||
Copyright © 2008-2011 Kristian Høgsberg
|
||||
Copyright © 2010-2013 Intel Corporation
|
||||
Copyright © 2012-2013 Collabora, Ltd.
|
||||
Copyright © 2018 Purism SPC
|
||||
|
||||
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="zwp_virtual_keyboard_v1" version="1">
|
||||
<description summary="virtual keyboard">
|
||||
The virtual keyboard provides an application with requests which emulate
|
||||
the behaviour of a physical keyboard.
|
||||
|
||||
This interface can be used by clients on its own to provide raw input
|
||||
events, or it can accompany the input method protocol.
|
||||
</description>
|
||||
|
||||
<request name="keymap">
|
||||
<description summary="keyboard mapping">
|
||||
Provide a file descriptor to the compositor which can be
|
||||
memory-mapped to provide a keyboard mapping description.
|
||||
|
||||
Format carries a value from the keymap_format enumeration.
|
||||
</description>
|
||||
<arg name="format" type="uint" summary="keymap format"/>
|
||||
<arg name="fd" type="fd" summary="keymap file descriptor"/>
|
||||
<arg name="size" type="uint" summary="keymap size, in bytes"/>
|
||||
</request>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="no_keymap" value="0" summary="No keymap was set"/>
|
||||
</enum>
|
||||
|
||||
<request name="key">
|
||||
<description summary="key event">
|
||||
A key was pressed or released.
|
||||
The time argument is a timestamp with millisecond granularity, with an
|
||||
undefined base. All requests regarding a single object must share the
|
||||
same clock.
|
||||
|
||||
Keymap must be set before issuing this request.
|
||||
|
||||
State carries a value from the key_state enumeration.
|
||||
</description>
|
||||
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
|
||||
<arg name="key" type="uint" summary="key that produced the event"/>
|
||||
<arg name="state" type="uint" summary="physical state of the key"/>
|
||||
</request>
|
||||
|
||||
<request name="modifiers">
|
||||
<description summary="modifier and group state">
|
||||
Notifies the compositor that the modifier and/or group state has
|
||||
changed, and it should update state.
|
||||
|
||||
The client should use wl_keyboard.modifiers event to synchronize its
|
||||
internal state with seat state.
|
||||
|
||||
Keymap must be set before issuing this request.
|
||||
</description>
|
||||
<arg name="mods_depressed" type="uint" summary="depressed modifiers"/>
|
||||
<arg name="mods_latched" type="uint" summary="latched modifiers"/>
|
||||
<arg name="mods_locked" type="uint" summary="locked modifiers"/>
|
||||
<arg name="group" type="uint" summary="keyboard layout"/>
|
||||
</request>
|
||||
|
||||
<request name="destroy" type="destructor" since="1">
|
||||
<description summary="destroy the virtual keyboard keyboard object"/>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="zwp_virtual_keyboard_manager_v1" version="1">
|
||||
<description summary="virtual keyboard manager">
|
||||
A virtual keyboard manager allows an application to provide keyboard
|
||||
input events as if they came from a physical keyboard.
|
||||
</description>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="unauthorized" value="0" summary="client not authorized to use the interface"/>
|
||||
</enum>
|
||||
|
||||
<request name="create_virtual_keyboard">
|
||||
<description summary="Create a new virtual keyboard">
|
||||
Creates a new virtual keyboard associated to a seat.
|
||||
|
||||
If the compositor enables a keyboard to perform arbitrary actions, it
|
||||
should present an error when an untrusted client requests a new
|
||||
keyboard.
|
||||
</description>
|
||||
<arg name="seat" type="object" interface="wl_seat"/>
|
||||
<arg name="id" type="new_id" interface="zwp_virtual_keyboard_v1"/>
|
||||
</request>
|
||||
</interface>
|
||||
</protocol>
|
|
@ -245,8 +245,6 @@ void CCompositor::initServer() {
|
|||
|
||||
m_sWLROutputMgr = wlr_output_manager_v1_create(m_sWLDisplay);
|
||||
|
||||
m_sWLRVKeyboardMgr = wlr_virtual_keyboard_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);
|
||||
|
@ -308,7 +306,6 @@ void CCompositor::initAllSignals() {
|
|||
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_sWLRVKeyboardMgr->events.new_virtual_keyboard, &Events::listen_newVirtualKeyboard, m_sWLRVKeyboardMgr, "VKeyboardMgr");
|
||||
addWLSignal(&m_sWLRRenderer->events.destroy, &Events::listen_RendererDestroy, m_sWLRRenderer, "WLRRenderer");
|
||||
|
||||
if (m_sWRLDRMLeaseMgr)
|
||||
|
@ -350,7 +347,6 @@ void CCompositor::removeAllSignals() {
|
|||
removeWLSignal(&Events::listen_outputMgrApply);
|
||||
removeWLSignal(&Events::listen_outputMgrTest);
|
||||
removeWLSignal(&Events::listen_newVirtPtr);
|
||||
removeWLSignal(&Events::listen_newVirtualKeyboard);
|
||||
removeWLSignal(&Events::listen_RendererDestroy);
|
||||
|
||||
if (m_sWRLDRMLeaseMgr)
|
||||
|
|
|
@ -55,7 +55,6 @@ class CCompositor {
|
|||
wlr_layer_shell_v1* m_sWLRLayerShell;
|
||||
wlr_xdg_shell* m_sWLRXDGShell;
|
||||
wlr_cursor* m_sWLRCursor;
|
||||
wlr_virtual_keyboard_manager_v1* m_sWLRVKeyboardMgr;
|
||||
wlr_output_manager_v1* m_sWLROutputMgr;
|
||||
wlr_presentation* m_sWLRPresentation;
|
||||
wlr_egl* m_sWLREGL;
|
||||
|
|
|
@ -140,12 +140,6 @@ void Events::listener_pinchEnd(wl_listener* listener, void* data) {
|
|||
PROTO::pointerGestures->pinchEnd(EV->time_msec, EV->cancelled);
|
||||
}
|
||||
|
||||
void Events::listener_newVirtualKeyboard(wl_listener* listener, void* data) {
|
||||
const auto WLRKB = (wlr_virtual_keyboard_v1*)data;
|
||||
|
||||
g_pInputManager->newVirtualKeyboard(&WLRKB->keyboard.base);
|
||||
}
|
||||
|
||||
void Events::listener_touchBegin(wl_listener* listener, void* data) {
|
||||
g_pInputManager->onTouchDown((wlr_touch_down_event*)data);
|
||||
}
|
||||
|
|
|
@ -106,9 +106,6 @@ namespace Events {
|
|||
LISTENER(pinchUpdate);
|
||||
LISTENER(pinchEnd);
|
||||
|
||||
// IME
|
||||
LISTENER(newVirtualKeyboard);
|
||||
|
||||
// Touch
|
||||
LISTENER(touchBegin);
|
||||
LISTENER(touchEnd);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "Region.hpp"
|
||||
|
||||
class CMonitor;
|
||||
class CVirtualKeyboard;
|
||||
|
||||
struct SRenderData {
|
||||
CMonitor* pMonitor;
|
||||
|
@ -75,6 +76,8 @@ struct SKeyboard {
|
|||
bool active = false;
|
||||
bool enabled = true;
|
||||
|
||||
WP<CVirtualKeyboard> virtKeyboard;
|
||||
|
||||
xkb_layout_index_t activeLayout = 0;
|
||||
xkb_state* xkbTranslationState = nullptr;
|
||||
|
||||
|
|
|
@ -62,7 +62,6 @@ extern "C" {
|
|||
#include <wlr/types/wlr_seat.h>
|
||||
#include <wlr/types/wlr_server_decoration.h>
|
||||
#include <wlr/types/wlr_viewporter.h>
|
||||
#include <wlr/types/wlr_virtual_keyboard_v1.h>
|
||||
#include <wlr/types/wlr_xdg_output_v1.h>
|
||||
#include <wlr/types/wlr_xdg_shell.h>
|
||||
#include <wlr/types/wlr_subcompositor.h>
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "../protocols/IdleNotify.hpp"
|
||||
#include "../protocols/SessionLock.hpp"
|
||||
#include "../protocols/InputMethodV2.hpp"
|
||||
#include "../protocols/VirtualKeyboard.hpp"
|
||||
|
||||
CProtocolManager::CProtocolManager() {
|
||||
|
||||
|
@ -43,6 +44,7 @@ CProtocolManager::CProtocolManager() {
|
|||
PROTO::idle = std::make_unique<CIdleNotifyProtocol>(&ext_idle_notifier_v1_interface, 1, "IdleNotify");
|
||||
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");
|
||||
|
||||
// Old protocol implementations.
|
||||
// TODO: rewrite them to use hyprwayland-scanner.
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "../../protocols/IdleNotify.hpp"
|
||||
#include "../../protocols/SessionLock.hpp"
|
||||
#include "../../protocols/InputMethodV2.hpp"
|
||||
#include "../../protocols/VirtualKeyboard.hpp"
|
||||
|
||||
CInputManager::CInputManager() {
|
||||
m_sListeners.setCursorShape = PROTO::cursorShape->events.setShape.registerListener([this](std::any data) {
|
||||
|
@ -37,6 +38,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)); });
|
||||
}
|
||||
|
||||
CInputManager::~CInputManager() {
|
||||
|
@ -786,23 +789,24 @@ void CInputManager::newKeyboard(wlr_input_device* keyboard) {
|
|||
Debug::log(LOG, "New keyboard created, pointers Hypr: {:x} and WLR: {:x}", (uintptr_t)PNEWKEYBOARD, (uintptr_t)keyboard);
|
||||
}
|
||||
|
||||
void CInputManager::newVirtualKeyboard(wlr_input_device* keyboard) {
|
||||
void CInputManager::newVirtualKeyboard(SP<CVirtualKeyboard> keyboard) {
|
||||
const auto PNEWKEYBOARD = &m_lKeyboards.emplace_back();
|
||||
|
||||
PNEWKEYBOARD->keyboard = keyboard;
|
||||
PNEWKEYBOARD->keyboard = &keyboard->wlr()->base;
|
||||
PNEWKEYBOARD->isVirtual = true;
|
||||
PNEWKEYBOARD->virtKeyboard = keyboard;
|
||||
|
||||
try {
|
||||
PNEWKEYBOARD->name = getNameForNewDevice(keyboard->name);
|
||||
PNEWKEYBOARD->name = getNameForNewDevice(keyboard->wlr()->base.name);
|
||||
} catch (std::exception& e) {
|
||||
Debug::log(ERR, "Keyboard had no name???"); // logic error
|
||||
}
|
||||
|
||||
PNEWKEYBOARD->hyprListener_keyboardMod.initCallback(&wlr_keyboard_from_input_device(keyboard)->events.modifiers, &Events::listener_keyboardMod, PNEWKEYBOARD, "Keyboard");
|
||||
PNEWKEYBOARD->hyprListener_keyboardKey.initCallback(&wlr_keyboard_from_input_device(keyboard)->events.key, &Events::listener_keyboardKey, PNEWKEYBOARD, "Keyboard");
|
||||
PNEWKEYBOARD->hyprListener_keyboardDestroy.initCallback(&keyboard->events.destroy, &Events::listener_keyboardDestroy, PNEWKEYBOARD, "Keyboard");
|
||||
PNEWKEYBOARD->hyprListener_keyboardMod.initCallback(&keyboard->wlr()->events.modifiers, &Events::listener_keyboardMod, PNEWKEYBOARD, "VKeyboard");
|
||||
PNEWKEYBOARD->hyprListener_keyboardKey.initCallback(&keyboard->wlr()->events.key, &Events::listener_keyboardKey, PNEWKEYBOARD, "VKeyboard");
|
||||
PNEWKEYBOARD->hyprListener_keyboardDestroy.initCallback(&keyboard->wlr()->base.events.destroy, &Events::listener_keyboardDestroy, PNEWKEYBOARD, "VKeyboard");
|
||||
PNEWKEYBOARD->hyprListener_keyboardKeymap.initCallback(
|
||||
&wlr_keyboard_from_input_device(keyboard)->events.keymap,
|
||||
&keyboard->wlr()->events.keymap,
|
||||
[&](void* owner, void* data) {
|
||||
const auto PKEYBOARD = (SKeyboard*)owner;
|
||||
const auto LAYOUT = getActiveLayoutForKeyboard(PKEYBOARD);
|
||||
|
@ -810,7 +814,7 @@ void CInputManager::newVirtualKeyboard(wlr_input_device* keyboard) {
|
|||
g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", PKEYBOARD->name + "," + LAYOUT});
|
||||
EMIT_HOOK_EVENT("activeLayout", (std::vector<void*>{PKEYBOARD, (void*)&LAYOUT}));
|
||||
},
|
||||
PNEWKEYBOARD, "Keyboard");
|
||||
PNEWKEYBOARD, "VKeyboard");
|
||||
|
||||
disableAllKeyboards(true);
|
||||
|
||||
|
@ -820,9 +824,9 @@ void CInputManager::newVirtualKeyboard(wlr_input_device* keyboard) {
|
|||
|
||||
applyConfigToKeyboard(PNEWKEYBOARD);
|
||||
|
||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, wlr_keyboard_from_input_device(keyboard));
|
||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, keyboard->wlr());
|
||||
|
||||
Debug::log(LOG, "New virtual keyboard created, pointers Hypr: {:x} and WLR: {:x}", (uintptr_t)PNEWKEYBOARD, (uintptr_t)keyboard);
|
||||
Debug::log(LOG, "New virtual keyboard created, pointers Hypr: {:x} and WLR: {:x}", (uintptr_t)PNEWKEYBOARD, (uintptr_t)keyboard->wlr());
|
||||
}
|
||||
|
||||
void CInputManager::setKeyboardLayout() {
|
||||
|
@ -1276,8 +1280,10 @@ void CInputManager::onKeyboardMod(void* data, SKeyboard* pKeyboard) {
|
|||
}
|
||||
|
||||
bool CInputManager::shouldIgnoreVirtualKeyboard(SKeyboard* pKeyboard) {
|
||||
return !pKeyboard ||
|
||||
(!m_sIMERelay.m_pIME.expired() && m_sIMERelay.m_pIME.lock()->grabClient() == wl_resource_get_client(wlr_input_device_get_virtual_keyboard(pKeyboard->keyboard)->resource));
|
||||
if (!pKeyboard->isVirtual)
|
||||
return false;
|
||||
|
||||
return !pKeyboard || (!m_sIMERelay.m_pIME.expired() && m_sIMERelay.m_pIME.lock()->grabClient() == pKeyboard->virtKeyboard.lock()->client());
|
||||
}
|
||||
|
||||
void CInputManager::refocus() {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
class CPointerConstraint;
|
||||
class CWindow;
|
||||
class CIdleInhibitor;
|
||||
class CVirtualKeyboard;
|
||||
|
||||
enum eClickBehaviorMode {
|
||||
CLICKMODE_DEFAULT = 0,
|
||||
|
@ -77,7 +78,7 @@ class CInputManager {
|
|||
void onKeyboardMod(void*, SKeyboard*);
|
||||
|
||||
void newKeyboard(wlr_input_device*);
|
||||
void newVirtualKeyboard(wlr_input_device*);
|
||||
void newVirtualKeyboard(SP<CVirtualKeyboard>);
|
||||
void newMouse(wlr_input_device*, bool virt = false);
|
||||
void newTouchDevice(wlr_input_device*);
|
||||
void newSwitch(wlr_input_device*);
|
||||
|
@ -199,6 +200,7 @@ class CInputManager {
|
|||
struct {
|
||||
CHyprSignalListener setCursorShape;
|
||||
CHyprSignalListener newIdleInhibitor;
|
||||
CHyprSignalListener newVirtualKeyboard;
|
||||
} m_sListeners;
|
||||
|
||||
bool m_bCursorImageOverridden = false;
|
||||
|
|
136
src/protocols/VirtualKeyboard.cpp
Normal file
136
src/protocols/VirtualKeyboard.cpp
Normal file
|
@ -0,0 +1,136 @@
|
|||
#include "VirtualKeyboard.hpp"
|
||||
#include <sys/mman.h>
|
||||
|
||||
#define LOGM PROTO::virtualKeyboard->protoLog
|
||||
|
||||
static const struct wlr_keyboard_impl virtualKeyboardImpl = {
|
||||
.name = "virtual-keyboard",
|
||||
};
|
||||
|
||||
CVirtualKeyboard::CVirtualKeyboard(SP<CZwpVirtualKeyboardV1> resource_) : resource(resource_) {
|
||||
if (!good())
|
||||
return;
|
||||
|
||||
resource->setDestroy([this](CZwpVirtualKeyboardV1* r) {
|
||||
events.destroy.emit();
|
||||
PROTO::virtualKeyboard->destroyResource(this);
|
||||
});
|
||||
resource->setOnDestroy([this](CZwpVirtualKeyboardV1* r) {
|
||||
events.destroy.emit();
|
||||
PROTO::virtualKeyboard->destroyResource(this);
|
||||
});
|
||||
|
||||
resource->setKey([this](CZwpVirtualKeyboardV1* r, uint32_t timeMs, uint32_t key, uint32_t state) {
|
||||
if (!hasKeymap) {
|
||||
r->error(ZWP_VIRTUAL_KEYBOARD_V1_ERROR_NO_KEYMAP, "Key event received before a keymap was set");
|
||||
return;
|
||||
}
|
||||
|
||||
wlr_keyboard_key_event event = {
|
||||
.time_msec = timeMs,
|
||||
.keycode = key,
|
||||
.update_state = false,
|
||||
.state = (wl_keyboard_key_state)state,
|
||||
};
|
||||
wlr_keyboard_notify_key(&keyboard, &event);
|
||||
});
|
||||
|
||||
resource->setModifiers([this](CZwpVirtualKeyboardV1* r, uint32_t depressed, uint32_t latched, uint32_t locked, uint32_t group) {
|
||||
if (!hasKeymap) {
|
||||
r->error(ZWP_VIRTUAL_KEYBOARD_V1_ERROR_NO_KEYMAP, "Mods event received before a keymap was set");
|
||||
return;
|
||||
}
|
||||
|
||||
wlr_keyboard_notify_modifiers(&keyboard, depressed, latched, locked, group);
|
||||
});
|
||||
|
||||
resource->setKeymap([this](CZwpVirtualKeyboardV1* r, uint32_t fmt, int32_t fd, uint32_t len) {
|
||||
auto xkbContext = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
if (!xkbContext) {
|
||||
LOGM(ERR, "xkbContext creation failed");
|
||||
r->noMemory();
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
auto keymapData = mmap(nullptr, len, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (keymapData == MAP_FAILED) {
|
||||
LOGM(ERR, "keymapData alloc failed");
|
||||
xkb_context_unref(xkbContext);
|
||||
r->noMemory();
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
auto xkbKeymap = xkb_keymap_new_from_string(xkbContext, (const char*)keymapData, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
munmap(keymapData, len);
|
||||
|
||||
if (!xkbKeymap) {
|
||||
LOGM(ERR, "xkbKeymap creation failed");
|
||||
xkb_context_unref(xkbContext);
|
||||
r->noMemory();
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
wlr_keyboard_set_keymap(&keyboard, xkbKeymap);
|
||||
hasKeymap = true;
|
||||
|
||||
xkb_keymap_unref(xkbKeymap);
|
||||
xkb_context_unref(xkbContext);
|
||||
close(fd);
|
||||
});
|
||||
|
||||
wlr_keyboard_init(&keyboard, &virtualKeyboardImpl, "CVirtualKeyboard");
|
||||
}
|
||||
|
||||
CVirtualKeyboard::~CVirtualKeyboard() {
|
||||
wlr_keyboard_finish(&keyboard);
|
||||
events.destroy.emit();
|
||||
}
|
||||
|
||||
bool CVirtualKeyboard::good() {
|
||||
return resource->resource();
|
||||
}
|
||||
|
||||
wlr_keyboard* CVirtualKeyboard::wlr() {
|
||||
return &keyboard;
|
||||
}
|
||||
|
||||
wl_client* CVirtualKeyboard::client() {
|
||||
return resource->client();
|
||||
}
|
||||
|
||||
CVirtualKeyboardProtocol::CVirtualKeyboardProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
|
||||
;
|
||||
}
|
||||
|
||||
void CVirtualKeyboardProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
|
||||
const auto RESOURCE = m_vManagers.emplace_back(std::make_unique<CZwpVirtualKeyboardManagerV1>(client, ver, id)).get();
|
||||
RESOURCE->setOnDestroy([this](CZwpVirtualKeyboardManagerV1* p) { this->onManagerResourceDestroy(p->resource()); });
|
||||
|
||||
RESOURCE->setCreateVirtualKeyboard([this](CZwpVirtualKeyboardManagerV1* pMgr, wl_resource* seat, uint32_t id) { this->onCreateKeeb(pMgr, seat, id); });
|
||||
}
|
||||
|
||||
void CVirtualKeyboardProtocol::onManagerResourceDestroy(wl_resource* res) {
|
||||
std::erase_if(m_vManagers, [&](const auto& other) { return other->resource() == res; });
|
||||
}
|
||||
|
||||
void CVirtualKeyboardProtocol::destroyResource(CVirtualKeyboard* keeb) {
|
||||
std::erase_if(m_vKeyboards, [&](const auto& other) { return other.get() == keeb; });
|
||||
}
|
||||
|
||||
void CVirtualKeyboardProtocol::onCreateKeeb(CZwpVirtualKeyboardManagerV1* pMgr, wl_resource* seat, uint32_t id) {
|
||||
|
||||
const auto RESOURCE = m_vKeyboards.emplace_back(std::make_shared<CVirtualKeyboard>(std::make_shared<CZwpVirtualKeyboardV1>(pMgr->client(), pMgr->version(), id)));
|
||||
|
||||
if (!RESOURCE->good()) {
|
||||
pMgr->noMemory();
|
||||
m_vKeyboards.pop_back();
|
||||
return;
|
||||
}
|
||||
|
||||
LOGM(LOG, "New VKeyboard at id {}", id);
|
||||
|
||||
events.newKeyboard.emit(RESOURCE);
|
||||
}
|
54
src/protocols/VirtualKeyboard.hpp
Normal file
54
src/protocols/VirtualKeyboard.hpp
Normal file
|
@ -0,0 +1,54 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include "WaylandProtocol.hpp"
|
||||
#include "virtual-keyboard-unstable-v1.hpp"
|
||||
#include "../helpers/signal/Signal.hpp"
|
||||
|
||||
class CVirtualKeyboard {
|
||||
public:
|
||||
CVirtualKeyboard(SP<CZwpVirtualKeyboardV1> resource_);
|
||||
~CVirtualKeyboard();
|
||||
|
||||
struct {
|
||||
CSignal destroy;
|
||||
} events;
|
||||
|
||||
bool good();
|
||||
wlr_keyboard* wlr();
|
||||
wl_client* client();
|
||||
|
||||
private:
|
||||
SP<CZwpVirtualKeyboardV1> resource;
|
||||
wlr_keyboard keyboard;
|
||||
|
||||
bool hasKeymap = false;
|
||||
};
|
||||
|
||||
class CVirtualKeyboardProtocol : public IWaylandProtocol {
|
||||
public:
|
||||
CVirtualKeyboardProtocol(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 newKeyboard; // SP<CVirtualKeyboard>
|
||||
} events;
|
||||
|
||||
private:
|
||||
void onManagerResourceDestroy(wl_resource* res);
|
||||
void destroyResource(CVirtualKeyboard* keeb);
|
||||
void onCreateKeeb(CZwpVirtualKeyboardManagerV1* pMgr, wl_resource* seat, uint32_t id);
|
||||
|
||||
//
|
||||
std::vector<UP<CZwpVirtualKeyboardManagerV1>> m_vManagers;
|
||||
std::vector<SP<CVirtualKeyboard>> m_vKeyboards;
|
||||
|
||||
friend class CVirtualKeyboard;
|
||||
};
|
||||
|
||||
namespace PROTO {
|
||||
inline UP<CVirtualKeyboardProtocol> virtualKeyboard;
|
||||
};
|
Loading…
Reference in a new issue