mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-26 09:05:59 +01:00
input: Introduce basic hyprland HID classes
Implements an intermediary HID class for mice, keyboards and touch devices, removing the old structs from WLClasses.hpp Yes, virtual ones are duplicated a bit, but will likely be de-duped once wlr_input_device is not used anymore.
This commit is contained in:
parent
1d2acbe193
commit
1237732b97
39 changed files with 1450 additions and 573 deletions
|
@ -2418,10 +2418,7 @@ void CCompositor::warpCursorTo(const Vector2D& pos, bool force) {
|
|||
if (*PNOWARPS && !force)
|
||||
return;
|
||||
|
||||
if (!m_sSeat.mouse)
|
||||
return;
|
||||
|
||||
wlr_cursor_warp(m_sWLRCursor, m_sSeat.mouse->mouse, pos.x, pos.y);
|
||||
wlr_cursor_warp(m_sWLRCursor, nullptr, pos.x, pos.y);
|
||||
|
||||
const auto PMONITORNEW = getMonitorFromVector(pos);
|
||||
if (PMONITORNEW != m_pLastMonitor)
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
#include "../config/ConfigValue.hpp"
|
||||
#include "../managers/CursorManager.hpp"
|
||||
#include "../hyprerror/HyprError.hpp"
|
||||
#include "../devices/IPointer.hpp"
|
||||
#include "../devices/IKeyboard.hpp"
|
||||
#include "../devices/ITouch.hpp"
|
||||
|
||||
static void trimTrailingComma(std::string& str) {
|
||||
if (!str.empty() && str.back() == ',')
|
||||
|
@ -514,23 +517,24 @@ std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) {
|
|||
result += "{\n";
|
||||
result += "\"mice\": [\n";
|
||||
|
||||
for (auto& m : g_pInputManager->m_lMice) {
|
||||
for (auto& m : g_pInputManager->m_vPointers) {
|
||||
result += std::format(
|
||||
R"#( {{
|
||||
"address": "0x{:x}",
|
||||
"name": "{}",
|
||||
"defaultSpeed": {:.5f}
|
||||
}},)#",
|
||||
(uintptr_t)&m, escapeJSONStrings(m.name),
|
||||
wlr_input_device_is_libinput(m.mouse) ? libinput_device_config_accel_get_default_speed((libinput_device*)wlr_libinput_get_device_handle(m.mouse)) : 0.f);
|
||||
(uintptr_t)m.get(), escapeJSONStrings(m->hlName),
|
||||
wlr_input_device_is_libinput(&m->wlr()->base) ? libinput_device_config_accel_get_default_speed((libinput_device*)wlr_libinput_get_device_handle(&m->wlr()->base)) :
|
||||
0.f);
|
||||
}
|
||||
|
||||
trimTrailingComma(result);
|
||||
result += "\n],\n";
|
||||
|
||||
result += "\"keyboards\": [\n";
|
||||
for (auto& k : g_pInputManager->m_lKeyboards) {
|
||||
const auto KM = g_pInputManager->getActiveLayoutForKeyboard(&k);
|
||||
for (auto& k : g_pInputManager->m_vKeyboards) {
|
||||
const auto KM = k->getActiveLayout();
|
||||
result += std::format(
|
||||
R"#( {{
|
||||
"address": "0x{:x}",
|
||||
|
@ -543,9 +547,9 @@ std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) {
|
|||
"active_keymap": "{}",
|
||||
"main": {}
|
||||
}},)#",
|
||||
(uintptr_t)&k, escapeJSONStrings(k.name), escapeJSONStrings(k.currentRules.rules), escapeJSONStrings(k.currentRules.model),
|
||||
escapeJSONStrings(k.currentRules.layout), escapeJSONStrings(k.currentRules.variant), escapeJSONStrings(k.currentRules.options), escapeJSONStrings(KM),
|
||||
(k.active ? "true" : "false"));
|
||||
(uintptr_t)k.get(), escapeJSONStrings(k->hlName), escapeJSONStrings(k->currentRules.rules), escapeJSONStrings(k->currentRules.model),
|
||||
escapeJSONStrings(k->currentRules.layout), escapeJSONStrings(k->currentRules.variant), escapeJSONStrings(k->currentRules.options), escapeJSONStrings(KM),
|
||||
(k->active ? "true" : "false"));
|
||||
}
|
||||
|
||||
trimTrailingComma(result);
|
||||
|
@ -590,13 +594,13 @@ std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) {
|
|||
|
||||
result += "\"touch\": [\n";
|
||||
|
||||
for (auto& d : g_pInputManager->m_lTouchDevices) {
|
||||
for (auto& d : g_pInputManager->m_vTouches) {
|
||||
result += std::format(
|
||||
R"#( {{
|
||||
"address": "0x{:x}",
|
||||
"name": "{}"
|
||||
}},)#",
|
||||
(uintptr_t)&d, escapeJSONStrings(d.name));
|
||||
(uintptr_t)d.get(), escapeJSONStrings(d->hlName));
|
||||
}
|
||||
|
||||
trimTrailingComma(result);
|
||||
|
@ -621,19 +625,20 @@ std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) {
|
|||
} else {
|
||||
result += "mice:\n";
|
||||
|
||||
for (auto& m : g_pInputManager->m_lMice) {
|
||||
result += std::format(
|
||||
"\tMouse at {:x}:\n\t\t{}\n\t\t\tdefault speed: {:.5f}\n", (uintptr_t)&m, m.name,
|
||||
(wlr_input_device_is_libinput(m.mouse) ? libinput_device_config_accel_get_default_speed((libinput_device*)wlr_libinput_get_device_handle(m.mouse)) : 0.f));
|
||||
for (auto& m : g_pInputManager->m_vPointers) {
|
||||
result += std::format("\tMouse at {:x}:\n\t\t{}\n\t\t\tdefault speed: {:.5f}\n", (uintptr_t)m.get(), m->hlName,
|
||||
(wlr_input_device_is_libinput(&m->wlr()->base) ?
|
||||
libinput_device_config_accel_get_default_speed((libinput_device*)wlr_libinput_get_device_handle(&m->wlr()->base)) :
|
||||
0.f));
|
||||
}
|
||||
|
||||
result += "\n\nKeyboards:\n";
|
||||
|
||||
for (auto& k : g_pInputManager->m_lKeyboards) {
|
||||
const auto KM = g_pInputManager->getActiveLayoutForKeyboard(&k);
|
||||
for (auto& k : g_pInputManager->m_vKeyboards) {
|
||||
const auto KM = k->getActiveLayout();
|
||||
result += std::format("\tKeyboard at {:x}:\n\t\t{}\n\t\t\trules: r \"{}\", m \"{}\", l \"{}\", v \"{}\", o \"{}\"\n\t\t\tactive keymap: {}\n\t\t\tmain: {}\n",
|
||||
(uintptr_t)&k, k.name, k.currentRules.rules, k.currentRules.model, k.currentRules.layout, k.currentRules.variant, k.currentRules.options, KM,
|
||||
(k.active ? "yes" : "no"));
|
||||
(uintptr_t)k.get(), k->hlName, k->currentRules.rules, k->currentRules.model, k->currentRules.layout, k->currentRules.variant,
|
||||
k->currentRules.options, KM, (k->active ? "yes" : "no"));
|
||||
}
|
||||
|
||||
result += "\n\nTablets:\n";
|
||||
|
@ -652,8 +657,8 @@ std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) {
|
|||
|
||||
result += "\n\nTouch:\n";
|
||||
|
||||
for (auto& d : g_pInputManager->m_lTouchDevices) {
|
||||
result += std::format("\tTouch Device at {:x}:\n\t\t{}\n", (uintptr_t)&d, d.name);
|
||||
for (auto& d : g_pInputManager->m_vTouches) {
|
||||
result += std::format("\tTouch Device at {:x}:\n\t\t{}\n", (uintptr_t)d.get(), d->hlName);
|
||||
}
|
||||
|
||||
result += "\n\nSwitches:\n";
|
||||
|
@ -1069,13 +1074,13 @@ std::string switchXKBLayoutRequest(eHyprCtlOutputFormat format, std::string requ
|
|||
const auto CMD = vars[2];
|
||||
|
||||
// get kb
|
||||
const auto PKEYBOARD = std::find_if(g_pInputManager->m_lKeyboards.begin(), g_pInputManager->m_lKeyboards.end(),
|
||||
[&](const SKeyboard& other) { return other.name == g_pInputManager->deviceNameToInternalString(KB); });
|
||||
const auto PKEYBOARD = std::find_if(g_pInputManager->m_vKeyboards.begin(), g_pInputManager->m_vKeyboards.end(),
|
||||
[&](const auto& other) { return other->hlName == g_pInputManager->deviceNameToInternalString(KB); });
|
||||
|
||||
if (PKEYBOARD == g_pInputManager->m_lKeyboards.end())
|
||||
if (PKEYBOARD == g_pInputManager->m_vKeyboards.end())
|
||||
return "device not found";
|
||||
|
||||
const auto PWLRKEYBOARD = wlr_keyboard_from_input_device(PKEYBOARD->keyboard);
|
||||
const auto PWLRKEYBOARD = (*PKEYBOARD)->wlr();
|
||||
const auto LAYOUTS = xkb_keymap_num_layouts(PWLRKEYBOARD->keymap);
|
||||
xkb_layout_index_t activeLayout = 0;
|
||||
while (activeLayout < LAYOUTS) {
|
||||
|
|
|
@ -196,7 +196,7 @@ void CLayerSurface::onMap() {
|
|||
|
||||
const bool GRABSFOCUS = layerSurface->current.keyboard_interactive != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE &&
|
||||
// don't focus if constrained
|
||||
(!g_pCompositor->m_sSeat.mouse || !g_pInputManager->isConstrained());
|
||||
(g_pCompositor->m_sSeat.mouse.expired() || !g_pInputManager->isConstrained());
|
||||
|
||||
if (GRABSFOCUS) {
|
||||
g_pInputManager->releaseAllMouseButtons();
|
||||
|
@ -383,7 +383,7 @@ void CLayerSurface::onCommit() {
|
|||
realSize.setValueAndWarp(geometry.size());
|
||||
}
|
||||
|
||||
if (layerSurface->current.keyboard_interactive && (!g_pCompositor->m_sSeat.mouse || !g_pInputManager->isConstrained()) // don't focus if constrained
|
||||
if (layerSurface->current.keyboard_interactive && (g_pCompositor->m_sSeat.mouse.expired() || !g_pInputManager->isConstrained()) // don't focus if constrained
|
||||
&& !keyboardExclusive && mapped) {
|
||||
g_pCompositor->focusSurface(layerSurface->surface);
|
||||
|
||||
|
@ -391,7 +391,7 @@ void CLayerSurface::onCommit() {
|
|||
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, layerSurface->surface, LOCAL.x, LOCAL.y);
|
||||
wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, 0, LOCAL.x, LOCAL.y);
|
||||
g_pInputManager->m_bEmptyFocusCursorSet = false;
|
||||
} else if (!layerSurface->current.keyboard_interactive && (!g_pCompositor->m_sSeat.mouse || !g_pInputManager->isConstrained()) && keyboardExclusive) {
|
||||
} else if (!layerSurface->current.keyboard_interactive && (g_pCompositor->m_sSeat.mouse.expired() || !g_pInputManager->isConstrained()) && keyboardExclusive) {
|
||||
g_pInputManager->refocus();
|
||||
}
|
||||
|
||||
|
|
26
src/devices/IHID.hpp
Normal file
26
src/devices/IHID.hpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include "../helpers/signal/Signal.hpp"
|
||||
|
||||
enum eHIDCapabilityType : uint32_t {
|
||||
HID_INPUT_CAPABILITY_KEYBOARD = (1 << 0),
|
||||
HID_INPUT_CAPABILITY_POINTER = (1 << 1),
|
||||
HID_INPUT_CAPABILITY_TOUCH = (1 << 2),
|
||||
};
|
||||
|
||||
/*
|
||||
Base class for a HID device.
|
||||
This could be a keyboard, a mouse, or a touchscreen.
|
||||
*/
|
||||
class IHID {
|
||||
public:
|
||||
virtual uint32_t getCapabilities() = 0;
|
||||
|
||||
struct {
|
||||
CSignal destroy;
|
||||
} events;
|
||||
|
||||
std::string deviceName;
|
||||
};
|
134
src/devices/IKeyboard.cpp
Normal file
134
src/devices/IKeyboard.cpp
Normal file
|
@ -0,0 +1,134 @@
|
|||
#include "IKeyboard.hpp"
|
||||
#include "../defines.hpp"
|
||||
#include "../helpers/VarList.hpp"
|
||||
#include "../managers/input/InputManager.hpp"
|
||||
|
||||
uint32_t IKeyboard::getCapabilities() {
|
||||
return HID_INPUT_CAPABILITY_KEYBOARD;
|
||||
}
|
||||
|
||||
IKeyboard::~IKeyboard() {
|
||||
events.destroy.emit();
|
||||
|
||||
if (!xkbTranslationState)
|
||||
return;
|
||||
|
||||
xkb_state_unref(xkbTranslationState);
|
||||
xkbTranslationState = nullptr;
|
||||
}
|
||||
|
||||
void IKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) {
|
||||
|
||||
if (xkbTranslationState)
|
||||
xkb_state_unref(xkbTranslationState);
|
||||
|
||||
if (keymap) {
|
||||
Debug::log(LOG, "Updating keyboard {:x}'s translation state from a provided keymap", (uintptr_t)this);
|
||||
xkbTranslationState = xkb_state_new(keymap);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto WLRKB = wlr();
|
||||
const auto KEYMAP = WLRKB->keymap;
|
||||
const auto STATE = WLRKB->xkb_state;
|
||||
const auto LAYOUTSNUM = xkb_keymap_num_layouts(KEYMAP);
|
||||
|
||||
const auto PCONTEXT = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
|
||||
for (uint32_t i = 0; i < LAYOUTSNUM; ++i) {
|
||||
if (xkb_state_layout_index_is_active(STATE, i, XKB_STATE_LAYOUT_EFFECTIVE)) {
|
||||
Debug::log(LOG, "Updating keyboard {:x}'s translation state from an active index {}", (uintptr_t)this, i);
|
||||
|
||||
CVarList keyboardLayouts(currentRules.layout, 0, ',');
|
||||
CVarList keyboardModels(currentRules.model, 0, ',');
|
||||
CVarList keyboardVariants(currentRules.variant, 0, ',');
|
||||
|
||||
xkb_rule_names rules = {.rules = "", .model = "", .layout = "", .variant = "", .options = ""};
|
||||
|
||||
std::string layout, model, variant;
|
||||
layout = keyboardLayouts[i % keyboardLayouts.size()];
|
||||
model = keyboardModels[i % keyboardModels.size()];
|
||||
variant = keyboardVariants[i % keyboardVariants.size()];
|
||||
|
||||
rules.layout = layout.c_str();
|
||||
rules.model = model.c_str();
|
||||
rules.variant = variant.c_str();
|
||||
|
||||
auto KEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
|
||||
if (!KEYMAP) {
|
||||
Debug::log(ERR, "updateXKBTranslationState: keymap failed 1, fallback without model/variant");
|
||||
rules.model = "";
|
||||
rules.variant = "";
|
||||
KEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
}
|
||||
|
||||
if (!KEYMAP) {
|
||||
Debug::log(ERR, "updateXKBTranslationState: keymap failed 2, fallback to us");
|
||||
rules.layout = "us";
|
||||
KEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
}
|
||||
|
||||
xkbTranslationState = xkb_state_new(KEYMAP);
|
||||
|
||||
xkb_keymap_unref(KEYMAP);
|
||||
xkb_context_unref(PCONTEXT);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Debug::log(LOG, "Updating keyboard {:x}'s translation state from an unknown index", (uintptr_t)this);
|
||||
|
||||
xkb_rule_names rules = {
|
||||
.rules = currentRules.rules.c_str(),
|
||||
.model = currentRules.model.c_str(),
|
||||
.layout = currentRules.layout.c_str(),
|
||||
.variant = currentRules.variant.c_str(),
|
||||
.options = currentRules.options.c_str(),
|
||||
};
|
||||
|
||||
const auto NEWKEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
|
||||
xkbTranslationState = xkb_state_new(NEWKEYMAP);
|
||||
|
||||
xkb_keymap_unref(NEWKEYMAP);
|
||||
xkb_context_unref(PCONTEXT);
|
||||
}
|
||||
|
||||
std::string IKeyboard::getActiveLayout() {
|
||||
const auto WLRKB = wlr();
|
||||
const auto KEYMAP = WLRKB->keymap;
|
||||
const auto STATE = WLRKB->xkb_state;
|
||||
const auto LAYOUTSNUM = xkb_keymap_num_layouts(KEYMAP);
|
||||
|
||||
for (uint32_t i = 0; i < LAYOUTSNUM; ++i) {
|
||||
if (xkb_state_layout_index_is_active(STATE, i, XKB_STATE_LAYOUT_EFFECTIVE)) {
|
||||
const auto LAYOUTNAME = xkb_keymap_layout_get_name(KEYMAP, i);
|
||||
|
||||
if (LAYOUTNAME)
|
||||
return std::string(LAYOUTNAME);
|
||||
return "error";
|
||||
}
|
||||
}
|
||||
|
||||
return "none";
|
||||
}
|
||||
|
||||
void IKeyboard::updateLEDs() {
|
||||
auto keyboard = wlr();
|
||||
|
||||
if (keyboard->xkb_state == nullptr)
|
||||
return;
|
||||
|
||||
uint32_t leds = 0;
|
||||
for (uint32_t i = 0; i < WLR_LED_COUNT; ++i) {
|
||||
if (xkb_state_led_index_is_active(keyboard->xkb_state, keyboard->led_indexes[i]))
|
||||
leds |= (1 << i);
|
||||
}
|
||||
|
||||
if (isVirtual() && g_pInputManager->shouldIgnoreVirtualKeyboard(self.lock()))
|
||||
return;
|
||||
|
||||
wlr_keyboard_led_update(wlr(), leds);
|
||||
}
|
61
src/devices/IKeyboard.hpp
Normal file
61
src/devices/IKeyboard.hpp
Normal file
|
@ -0,0 +1,61 @@
|
|||
#pragma once
|
||||
|
||||
#include "IHID.hpp"
|
||||
#include "../helpers/WLListener.hpp"
|
||||
#include "../macros.hpp"
|
||||
#include "../helpers/Vector2D.hpp"
|
||||
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
struct wlr_keyboard;
|
||||
|
||||
class IKeyboard : public IHID {
|
||||
public:
|
||||
virtual ~IKeyboard();
|
||||
virtual uint32_t getCapabilities();
|
||||
virtual bool isVirtual() = 0;
|
||||
virtual wlr_keyboard* wlr() = 0;
|
||||
|
||||
struct SKeyEvent {
|
||||
uint32_t timeMs = 0;
|
||||
uint32_t keycode = 0;
|
||||
bool updateMods = false;
|
||||
wl_keyboard_key_state state = WL_KEYBOARD_KEY_STATE_PRESSED;
|
||||
};
|
||||
|
||||
struct {
|
||||
CSignal key;
|
||||
CSignal modifiers;
|
||||
CSignal keymap;
|
||||
CSignal repeatInfo;
|
||||
} keyboardEvents;
|
||||
|
||||
struct SStringRuleNames {
|
||||
std::string layout = "";
|
||||
std::string model = "";
|
||||
std::string variant = "";
|
||||
std::string options = "";
|
||||
std::string rules = "";
|
||||
};
|
||||
|
||||
void updateXKBTranslationState(xkb_keymap* const keymap = nullptr);
|
||||
std::string getActiveLayout();
|
||||
void updateLEDs();
|
||||
|
||||
bool active = false;
|
||||
bool enabled = true;
|
||||
|
||||
xkb_layout_index_t activeLayout = 0;
|
||||
xkb_state* xkbTranslationState = nullptr;
|
||||
|
||||
std::string hlName = "";
|
||||
std::string xkbFilePath = "";
|
||||
|
||||
SStringRuleNames currentRules;
|
||||
int repeatRate = 0;
|
||||
int repeatDelay = 0;
|
||||
int numlockOn = -1;
|
||||
bool resolveBindsBySym = false;
|
||||
|
||||
WP<IKeyboard> self;
|
||||
};
|
5
src/devices/IPointer.cpp
Normal file
5
src/devices/IPointer.cpp
Normal file
|
@ -0,0 +1,5 @@
|
|||
#include "IPointer.hpp"
|
||||
|
||||
uint32_t IPointer::getCapabilities() {
|
||||
return HID_INPUT_CAPABILITY_POINTER;
|
||||
}
|
110
src/devices/IPointer.hpp
Normal file
110
src/devices/IPointer.hpp
Normal file
|
@ -0,0 +1,110 @@
|
|||
#pragma once
|
||||
|
||||
#include "IHID.hpp"
|
||||
#include "../helpers/WLListener.hpp"
|
||||
#include "../macros.hpp"
|
||||
#include "../helpers/Vector2D.hpp"
|
||||
|
||||
struct wlr_pointer;
|
||||
|
||||
/*
|
||||
Base class for a pointer.
|
||||
*/
|
||||
class IPointer : public IHID {
|
||||
public:
|
||||
virtual uint32_t getCapabilities();
|
||||
virtual bool isVirtual() = 0;
|
||||
virtual wlr_pointer* wlr() = 0;
|
||||
|
||||
struct SMotionEvent {
|
||||
uint32_t timeMs = 0;
|
||||
Vector2D delta, unaccel;
|
||||
};
|
||||
|
||||
struct SMotionAbsoluteEvent {
|
||||
uint32_t timeMs = 0;
|
||||
Vector2D absolute; // 0.0 - 1.0
|
||||
};
|
||||
|
||||
struct SButtonEvent {
|
||||
uint32_t timeMs = 0;
|
||||
uint32_t button = 0;
|
||||
wl_pointer_button_state state = WL_POINTER_BUTTON_STATE_PRESSED;
|
||||
};
|
||||
|
||||
struct SAxisEvent {
|
||||
uint32_t timeMs = 0;
|
||||
wl_pointer_axis_source source = WL_POINTER_AXIS_SOURCE_WHEEL;
|
||||
wl_pointer_axis axis = WL_POINTER_AXIS_VERTICAL_SCROLL;
|
||||
wl_pointer_axis_relative_direction relativeDirection = WL_POINTER_AXIS_RELATIVE_DIRECTION_IDENTICAL;
|
||||
double delta = 0.0;
|
||||
int32_t deltaDiscrete = 0;
|
||||
};
|
||||
|
||||
struct SSwipeBeginEvent {
|
||||
uint32_t timeMs = 0;
|
||||
uint32_t fingers = 0;
|
||||
};
|
||||
|
||||
struct SSwipeUpdateEvent {
|
||||
uint32_t timeMs = 0;
|
||||
uint32_t fingers = 0;
|
||||
Vector2D delta;
|
||||
};
|
||||
|
||||
struct SSwipeEndEvent {
|
||||
uint32_t timeMs = 0;
|
||||
bool cancelled = false;
|
||||
};
|
||||
|
||||
struct SPinchBeginEvent {
|
||||
uint32_t timeMs = 0;
|
||||
uint32_t fingers = 0;
|
||||
};
|
||||
|
||||
struct SPinchUpdateEvent {
|
||||
uint32_t timeMs = 0;
|
||||
uint32_t fingers = 0;
|
||||
Vector2D delta;
|
||||
double scale = 1.0, rotation = 0.0;
|
||||
};
|
||||
|
||||
struct SPinchEndEvent {
|
||||
uint32_t timeMs = 0;
|
||||
bool cancelled = false;
|
||||
};
|
||||
|
||||
struct SHoldBeginEvent {
|
||||
uint32_t timeMs = 0;
|
||||
uint32_t fingers = 0;
|
||||
};
|
||||
|
||||
struct SHoldEndEvent {
|
||||
uint32_t timeMs = 0;
|
||||
bool cancelled = false;
|
||||
};
|
||||
|
||||
struct {
|
||||
CSignal motion;
|
||||
CSignal motionAbsolute;
|
||||
CSignal button;
|
||||
CSignal axis;
|
||||
CSignal frame;
|
||||
|
||||
CSignal swipeBegin;
|
||||
CSignal swipeEnd;
|
||||
CSignal swipeUpdate;
|
||||
|
||||
CSignal pinchBegin;
|
||||
CSignal pinchEnd;
|
||||
CSignal pinchUpdate;
|
||||
|
||||
CSignal holdBegin;
|
||||
CSignal holdEnd;
|
||||
} pointerEvents;
|
||||
|
||||
std::string hlName;
|
||||
bool connected = false; // means connected to the cursor
|
||||
|
||||
WP<IPointer> self;
|
||||
};
|
5
src/devices/ITouch.cpp
Normal file
5
src/devices/ITouch.cpp
Normal file
|
@ -0,0 +1,5 @@
|
|||
#include "ITouch.hpp"
|
||||
|
||||
uint32_t ITouch::getCapabilities() {
|
||||
return HID_INPUT_CAPABILITY_TOUCH;
|
||||
}
|
50
src/devices/ITouch.hpp
Normal file
50
src/devices/ITouch.hpp
Normal file
|
@ -0,0 +1,50 @@
|
|||
#pragma once
|
||||
|
||||
#include "IHID.hpp"
|
||||
#include "../helpers/WLListener.hpp"
|
||||
#include "../macros.hpp"
|
||||
#include "../helpers/Vector2D.hpp"
|
||||
|
||||
struct wlr_touch;
|
||||
|
||||
class ITouch : public IHID {
|
||||
public:
|
||||
virtual uint32_t getCapabilities();
|
||||
virtual bool isVirtual() = 0;
|
||||
virtual wlr_touch* wlr() = 0;
|
||||
|
||||
struct SDownEvent {
|
||||
uint32_t timeMs = 0;
|
||||
int32_t touchID = 0;
|
||||
Vector2D pos;
|
||||
};
|
||||
|
||||
struct SUpEvent {
|
||||
uint32_t timeMs = 0;
|
||||
int32_t touchID = 0;
|
||||
};
|
||||
|
||||
struct SMotionEvent {
|
||||
uint32_t timeMs = 0;
|
||||
int32_t touchID = 0;
|
||||
Vector2D pos;
|
||||
};
|
||||
|
||||
struct SCancelEvent {
|
||||
uint32_t timeMs = 0;
|
||||
int32_t touchID = 0;
|
||||
};
|
||||
|
||||
struct {
|
||||
CSignal down;
|
||||
CSignal up;
|
||||
CSignal motion;
|
||||
CSignal cancel;
|
||||
CSignal frame;
|
||||
} touchEvents;
|
||||
|
||||
std::string hlName = "";
|
||||
std::string boundOutput = "";
|
||||
|
||||
WP<ITouch> self;
|
||||
};
|
64
src/devices/Keyboard.cpp
Normal file
64
src/devices/Keyboard.cpp
Normal file
|
@ -0,0 +1,64 @@
|
|||
#include "Keyboard.hpp"
|
||||
#include "../defines.hpp"
|
||||
|
||||
SP<CKeyboard> CKeyboard::create(wlr_keyboard* keeb) {
|
||||
SP<CKeyboard> pKeeb = SP<CKeyboard>(new CKeyboard(keeb));
|
||||
|
||||
pKeeb->self = pKeeb;
|
||||
|
||||
return pKeeb;
|
||||
}
|
||||
|
||||
bool CKeyboard::isVirtual() {
|
||||
return false;
|
||||
}
|
||||
|
||||
wlr_keyboard* CKeyboard::wlr() {
|
||||
return keyboard;
|
||||
}
|
||||
|
||||
CKeyboard::CKeyboard(wlr_keyboard* keeb) : keyboard(keeb) {
|
||||
if (!keeb)
|
||||
return;
|
||||
|
||||
// clang-format off
|
||||
hyprListener_destroy.initCallback(&keeb->base.events.destroy, [this] (void* owner, void* data) {
|
||||
events.destroy.emit();
|
||||
disconnectCallbacks();
|
||||
keyboard = nullptr;
|
||||
}, this, "CKeyboard");
|
||||
|
||||
hyprListener_key.initCallback(&keeb->events.key, [this] (void* owner, void* data) {
|
||||
auto E = (wlr_keyboard_key_event*)data;
|
||||
|
||||
keyboardEvents.key.emit(SKeyEvent{
|
||||
.timeMs = E->time_msec,
|
||||
.keycode = E->keycode,
|
||||
.updateMods = E->update_state,
|
||||
.state = E->state,
|
||||
});
|
||||
}, this, "CKeyboard");
|
||||
|
||||
hyprListener_keymap.initCallback(&keeb->events.keymap, [this] (void* owner, void* data) {
|
||||
keyboardEvents.keymap.emit();
|
||||
}, this, "CKeyboard");
|
||||
|
||||
hyprListener_modifiers.initCallback(&keeb->events.modifiers, [this] (void* owner, void* data) {
|
||||
keyboardEvents.modifiers.emit();
|
||||
}, this, "CKeyboard");
|
||||
|
||||
hyprListener_repeatInfo.initCallback(&keeb->events.repeat_info, [this] (void* owner, void* data) {
|
||||
keyboardEvents.repeatInfo.emit();
|
||||
}, this, "CKeyboard");
|
||||
// clang-format on
|
||||
|
||||
deviceName = keeb->base.name ? keeb->base.name : "UNKNOWN";
|
||||
}
|
||||
|
||||
void CKeyboard::disconnectCallbacks() {
|
||||
hyprListener_destroy.removeCallback();
|
||||
hyprListener_key.removeCallback();
|
||||
hyprListener_keymap.removeCallback();
|
||||
hyprListener_repeatInfo.removeCallback();
|
||||
hyprListener_modifiers.removeCallback();
|
||||
}
|
24
src/devices/Keyboard.hpp
Normal file
24
src/devices/Keyboard.hpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
#pragma once
|
||||
|
||||
#include "IKeyboard.hpp"
|
||||
|
||||
class CKeyboard : public IKeyboard {
|
||||
public:
|
||||
static SP<CKeyboard> create(wlr_keyboard* keeb);
|
||||
|
||||
virtual bool isVirtual();
|
||||
virtual wlr_keyboard* wlr();
|
||||
|
||||
private:
|
||||
CKeyboard(wlr_keyboard* keeb);
|
||||
|
||||
wlr_keyboard* keyboard = nullptr;
|
||||
|
||||
void disconnectCallbacks();
|
||||
|
||||
DYNLISTENER(destroy);
|
||||
DYNLISTENER(key);
|
||||
DYNLISTENER(modifiers);
|
||||
DYNLISTENER(keymap);
|
||||
DYNLISTENER(repeatInfo);
|
||||
};
|
169
src/devices/Mouse.cpp
Normal file
169
src/devices/Mouse.cpp
Normal file
|
@ -0,0 +1,169 @@
|
|||
#include "Mouse.hpp"
|
||||
#include "../defines.hpp"
|
||||
|
||||
SP<CMouse> CMouse::create(wlr_pointer* mouse) {
|
||||
SP<CMouse> pMouse = SP<CMouse>(new CMouse(mouse));
|
||||
|
||||
pMouse->self = pMouse;
|
||||
|
||||
return pMouse;
|
||||
}
|
||||
|
||||
CMouse::CMouse(wlr_pointer* mouse_) : mouse(mouse_) {
|
||||
if (!mouse)
|
||||
return;
|
||||
|
||||
// clang-format off
|
||||
hyprListener_destroy.initCallback(&mouse->base.events.destroy, [this] (void* owner, void* data) {
|
||||
disconnectCallbacks();
|
||||
mouse = nullptr;
|
||||
events.destroy.emit();
|
||||
}, this, "CMouse");
|
||||
|
||||
hyprListener_motion.initCallback(&mouse->events.motion, [this] (void* owner, void* data) {
|
||||
auto E = (wlr_pointer_motion_event*)data;
|
||||
|
||||
pointerEvents.motion.emit(SMotionEvent{
|
||||
.timeMs = E->time_msec,
|
||||
.delta = {E->delta_x, E->delta_y},
|
||||
.unaccel = {E->unaccel_dx, E->unaccel_dy},
|
||||
});
|
||||
}, this, "CMouse");
|
||||
|
||||
hyprListener_motionAbsolute.initCallback(&mouse->events.motion_absolute, [this] (void* owner, void* data) {
|
||||
auto E = (wlr_pointer_motion_absolute_event*)data;
|
||||
|
||||
pointerEvents.motionAbsolute.emit(SMotionAbsoluteEvent{
|
||||
.timeMs = E->time_msec,
|
||||
.absolute = {E->x, E->y},
|
||||
});
|
||||
}, this, "CMouse");
|
||||
|
||||
hyprListener_button.initCallback(&mouse->events.button, [this] (void* owner, void* data) {
|
||||
auto E = (wlr_pointer_button_event*)data;
|
||||
|
||||
pointerEvents.button.emit(SButtonEvent{
|
||||
.timeMs = E->time_msec,
|
||||
.button = E->button,
|
||||
.state = (wl_pointer_button_state)E->state,
|
||||
});
|
||||
}, this, "CMouse");
|
||||
|
||||
hyprListener_axis.initCallback(&mouse->events.axis, [this] (void* owner, void* data) {
|
||||
auto E = (wlr_pointer_axis_event*)data;
|
||||
|
||||
pointerEvents.axis.emit(SAxisEvent{
|
||||
.timeMs = E->time_msec,
|
||||
.source = E->source,
|
||||
.axis = E->orientation,
|
||||
.relativeDirection = E->relative_direction,
|
||||
.delta = E->delta,
|
||||
.deltaDiscrete = E->delta_discrete,
|
||||
});
|
||||
}, this, "CMouse");
|
||||
|
||||
hyprListener_swipeBegin.initCallback(&mouse->events.swipe_begin, [this] (void* owner, void* data) {
|
||||
auto E = (wlr_pointer_swipe_begin_event*)data;
|
||||
|
||||
pointerEvents.swipeBegin.emit(SSwipeBeginEvent{
|
||||
.timeMs = E->time_msec,
|
||||
.fingers = E->fingers,
|
||||
});
|
||||
}, this, "CMouse");
|
||||
|
||||
hyprListener_swipeEnd.initCallback(&mouse->events.swipe_end, [this] (void* owner, void* data) {
|
||||
auto E = (wlr_pointer_swipe_end_event*)data;
|
||||
|
||||
pointerEvents.swipeEnd.emit(SSwipeEndEvent{
|
||||
.timeMs = E->time_msec,
|
||||
.cancelled = E->cancelled,
|
||||
});
|
||||
}, this, "CMouse");
|
||||
|
||||
hyprListener_swipeUpdate.initCallback(&mouse->events.swipe_update, [this] (void* owner, void* data) {
|
||||
auto E = (wlr_pointer_swipe_update_event*)data;
|
||||
|
||||
pointerEvents.swipeUpdate.emit(SSwipeUpdateEvent{
|
||||
.timeMs = E->time_msec,
|
||||
.fingers = E->fingers,
|
||||
.delta = {E->dx, E->dy},
|
||||
});
|
||||
}, this, "CMouse");
|
||||
|
||||
hyprListener_pinchBegin.initCallback(&mouse->events.pinch_begin, [this] (void* owner, void* data) {
|
||||
auto E = (wlr_pointer_pinch_begin_event*)data;
|
||||
|
||||
pointerEvents.pinchBegin.emit(SPinchBeginEvent{
|
||||
.timeMs = E->time_msec,
|
||||
.fingers = E->fingers,
|
||||
});
|
||||
}, this, "CMouse");
|
||||
|
||||
hyprListener_pinchEnd.initCallback(&mouse->events.pinch_end, [this] (void* owner, void* data) {
|
||||
auto E = (wlr_pointer_pinch_end_event*)data;
|
||||
|
||||
pointerEvents.pinchEnd.emit(SPinchEndEvent{
|
||||
.timeMs = E->time_msec,
|
||||
.cancelled = E->cancelled,
|
||||
});
|
||||
}, this, "CMouse");
|
||||
|
||||
hyprListener_pinchUpdate.initCallback(&mouse->events.pinch_update, [this] (void* owner, void* data) {
|
||||
auto E = (wlr_pointer_pinch_update_event*)data;
|
||||
|
||||
pointerEvents.pinchUpdate.emit(SPinchUpdateEvent{
|
||||
.timeMs = E->time_msec,
|
||||
.fingers = E->fingers,
|
||||
.delta = {E->dx, E->dy},
|
||||
.scale = E->scale,
|
||||
.rotation = E->rotation,
|
||||
});
|
||||
}, this, "CMouse");
|
||||
|
||||
hyprListener_holdBegin.initCallback(&mouse->events.hold_begin, [this] (void* owner, void* data) {
|
||||
auto E = (wlr_pointer_hold_begin_event*)data;
|
||||
|
||||
pointerEvents.holdBegin.emit(SHoldBeginEvent{
|
||||
.timeMs = E->time_msec,
|
||||
.fingers = E->fingers,
|
||||
});
|
||||
}, this, "CMouse");
|
||||
|
||||
hyprListener_holdEnd.initCallback(&mouse->events.hold_end, [this] (void* owner, void* data) {
|
||||
auto E = (wlr_pointer_hold_end_event*)data;
|
||||
|
||||
pointerEvents.holdEnd.emit(SHoldEndEvent{
|
||||
.timeMs = E->time_msec,
|
||||
.cancelled = E->cancelled,
|
||||
});
|
||||
}, this, "CMouse");
|
||||
|
||||
// clang-format on
|
||||
|
||||
deviceName = mouse->base.name ? mouse->base.name : "UNKNOWN";
|
||||
}
|
||||
|
||||
void CMouse::disconnectCallbacks() {
|
||||
hyprListener_destroy.removeCallback();
|
||||
hyprListener_motion.removeCallback();
|
||||
hyprListener_motionAbsolute.removeCallback();
|
||||
hyprListener_button.removeCallback();
|
||||
hyprListener_axis.removeCallback();
|
||||
hyprListener_frame.removeCallback();
|
||||
hyprListener_swipeBegin.removeCallback();
|
||||
hyprListener_swipeEnd.removeCallback();
|
||||
hyprListener_swipeUpdate.removeCallback();
|
||||
hyprListener_pinchBegin.removeCallback();
|
||||
hyprListener_pinchEnd.removeCallback();
|
||||
hyprListener_pinchUpdate.removeCallback();
|
||||
hyprListener_holdBegin.removeCallback();
|
||||
hyprListener_holdEnd.removeCallback();
|
||||
}
|
||||
|
||||
bool CMouse::isVirtual() {
|
||||
return false;
|
||||
}
|
||||
|
||||
wlr_pointer* CMouse::wlr() {
|
||||
return mouse;
|
||||
}
|
36
src/devices/Mouse.hpp
Normal file
36
src/devices/Mouse.hpp
Normal file
|
@ -0,0 +1,36 @@
|
|||
#pragma once
|
||||
|
||||
#include "IPointer.hpp"
|
||||
|
||||
class CMouse : public IPointer {
|
||||
public:
|
||||
static SP<CMouse> create(wlr_pointer* mouse);
|
||||
|
||||
virtual bool isVirtual();
|
||||
virtual wlr_pointer* wlr();
|
||||
|
||||
private:
|
||||
CMouse(wlr_pointer* mouse);
|
||||
|
||||
wlr_pointer* mouse = nullptr;
|
||||
|
||||
void disconnectCallbacks();
|
||||
|
||||
DYNLISTENER(destroy);
|
||||
DYNLISTENER(motion);
|
||||
DYNLISTENER(motionAbsolute);
|
||||
DYNLISTENER(button);
|
||||
DYNLISTENER(axis);
|
||||
DYNLISTENER(frame);
|
||||
|
||||
DYNLISTENER(swipeBegin);
|
||||
DYNLISTENER(swipeEnd);
|
||||
DYNLISTENER(swipeUpdate);
|
||||
|
||||
DYNLISTENER(pinchBegin);
|
||||
DYNLISTENER(pinchEnd);
|
||||
DYNLISTENER(pinchUpdate);
|
||||
|
||||
DYNLISTENER(holdBegin);
|
||||
DYNLISTENER(holdEnd);
|
||||
};
|
85
src/devices/TouchDevice.cpp
Normal file
85
src/devices/TouchDevice.cpp
Normal file
|
@ -0,0 +1,85 @@
|
|||
#include "TouchDevice.hpp"
|
||||
#include "../defines.hpp"
|
||||
|
||||
SP<CTouchDevice> CTouchDevice::create(wlr_touch* touch) {
|
||||
SP<CTouchDevice> pTouch = SP<CTouchDevice>(new CTouchDevice(touch));
|
||||
|
||||
pTouch->self = pTouch;
|
||||
|
||||
return pTouch;
|
||||
}
|
||||
|
||||
CTouchDevice::CTouchDevice(wlr_touch* touch_) : touch(touch_) {
|
||||
if (!touch)
|
||||
return;
|
||||
|
||||
// clang-format off
|
||||
hyprListener_destroy.initCallback(&touch->base.events.destroy, [this] (void* owner, void* data) {
|
||||
events.destroy.emit();
|
||||
disconnectCallbacks();
|
||||
touch = nullptr;
|
||||
}, this, "CTouchDevice");
|
||||
|
||||
hyprListener_down.initCallback(&touch->events.down, [this] (void* owner, void* data) {
|
||||
auto E = (wlr_touch_down_event*)data;
|
||||
|
||||
touchEvents.down.emit(SDownEvent{
|
||||
.timeMs = E->time_msec,
|
||||
.touchID = E->touch_id,
|
||||
.pos = {E->x, E->y},
|
||||
});
|
||||
}, this, "CTouchDevice");
|
||||
|
||||
hyprListener_up.initCallback(&touch->events.up, [this] (void* owner, void* data) {
|
||||
auto E = (wlr_touch_up_event*)data;
|
||||
|
||||
touchEvents.up.emit(SUpEvent{
|
||||
.timeMs = E->time_msec,
|
||||
.touchID = E->touch_id
|
||||
});
|
||||
}, this, "CTouchDevice");
|
||||
|
||||
hyprListener_motion.initCallback(&touch->events.motion, [this] (void* owner, void* data) {
|
||||
auto E = (wlr_touch_motion_event*)data;
|
||||
|
||||
touchEvents.motion.emit(SMotionEvent{
|
||||
.timeMs = E->time_msec,
|
||||
.touchID = E->touch_id,
|
||||
.pos = {E->x, E->y},
|
||||
});
|
||||
}, this, "CTouchDevice");
|
||||
|
||||
hyprListener_cancel.initCallback(&touch->events.cancel, [this] (void* owner, void* data) {
|
||||
auto E = (wlr_touch_cancel_event*)data;
|
||||
|
||||
touchEvents.cancel.emit(SCancelEvent{
|
||||
.timeMs = E->time_msec,
|
||||
.touchID = E->touch_id
|
||||
});
|
||||
}, this, "CTouchDevice");
|
||||
|
||||
hyprListener_frame.initCallback(&touch->events.frame, [this] (void* owner, void* data) {
|
||||
touchEvents.frame.emit();
|
||||
}, this, "CTouchDevice");
|
||||
|
||||
// clang-format on
|
||||
|
||||
deviceName = touch->base.name ? touch->base.name : "UNKNOWN";
|
||||
}
|
||||
|
||||
bool CTouchDevice::isVirtual() {
|
||||
return false;
|
||||
}
|
||||
|
||||
wlr_touch* CTouchDevice::wlr() {
|
||||
return touch;
|
||||
}
|
||||
|
||||
void CTouchDevice::disconnectCallbacks() {
|
||||
hyprListener_destroy.removeCallback();
|
||||
hyprListener_down.removeCallback();
|
||||
hyprListener_up.removeCallback();
|
||||
hyprListener_motion.removeCallback();
|
||||
hyprListener_cancel.removeCallback();
|
||||
hyprListener_frame.removeCallback();
|
||||
}
|
25
src/devices/TouchDevice.hpp
Normal file
25
src/devices/TouchDevice.hpp
Normal file
|
@ -0,0 +1,25 @@
|
|||
#pragma once
|
||||
|
||||
#include "ITouch.hpp"
|
||||
|
||||
class CTouchDevice : public ITouch {
|
||||
public:
|
||||
static SP<CTouchDevice> create(wlr_touch* touch);
|
||||
|
||||
virtual bool isVirtual();
|
||||
virtual wlr_touch* wlr();
|
||||
|
||||
private:
|
||||
CTouchDevice(wlr_touch* touch);
|
||||
|
||||
wlr_touch* touch = nullptr;
|
||||
|
||||
void disconnectCallbacks();
|
||||
|
||||
DYNLISTENER(destroy);
|
||||
DYNLISTENER(down);
|
||||
DYNLISTENER(up);
|
||||
DYNLISTENER(motion);
|
||||
DYNLISTENER(cancel);
|
||||
DYNLISTENER(frame);
|
||||
};
|
71
src/devices/VirtualKeyboard.cpp
Normal file
71
src/devices/VirtualKeyboard.cpp
Normal file
|
@ -0,0 +1,71 @@
|
|||
#include "VirtualKeyboard.hpp"
|
||||
#include "../defines.hpp"
|
||||
#include "../protocols/VirtualKeyboard.hpp"
|
||||
|
||||
SP<CVirtualKeyboard> CVirtualKeyboard::create(SP<CVirtualKeyboardV1Resource> keeb) {
|
||||
SP<CVirtualKeyboard> pKeeb = SP<CVirtualKeyboard>(new CVirtualKeyboard(keeb));
|
||||
|
||||
pKeeb->self = pKeeb;
|
||||
|
||||
return pKeeb;
|
||||
}
|
||||
|
||||
CVirtualKeyboard::CVirtualKeyboard(SP<CVirtualKeyboardV1Resource> keeb_) : keyboard(keeb_) {
|
||||
if (!keeb_)
|
||||
return;
|
||||
|
||||
auto keeb = keeb_->wlr();
|
||||
|
||||
// clang-format off
|
||||
hyprListener_destroy.initCallback(&keeb->base.events.destroy, [this] (void* owner, void* data) {
|
||||
events.destroy.emit();
|
||||
disconnectCallbacks();
|
||||
keyboard.reset();
|
||||
}, this, "CVirtualKeyboard");
|
||||
|
||||
hyprListener_key.initCallback(&keeb->events.key, [this] (void* owner, void* data) {
|
||||
auto E = (wlr_keyboard_key_event*)data;
|
||||
|
||||
keyboardEvents.key.emit(SKeyEvent{
|
||||
.timeMs = E->time_msec,
|
||||
.keycode = E->keycode,
|
||||
.updateMods = E->update_state,
|
||||
.state = E->state,
|
||||
});
|
||||
}, this, "CVirtualKeyboard");
|
||||
|
||||
hyprListener_keymap.initCallback(&keeb->events.keymap, [this] (void* owner, void* data) {
|
||||
keyboardEvents.keymap.emit();
|
||||
}, this, "CVirtualKeyboard");
|
||||
|
||||
hyprListener_modifiers.initCallback(&keeb->events.modifiers, [this] (void* owner, void* data) {
|
||||
keyboardEvents.modifiers.emit();
|
||||
}, this, "CVirtualKeyboard");
|
||||
|
||||
hyprListener_repeatInfo.initCallback(&keeb->events.repeat_info, [this] (void* owner, void* data) {
|
||||
keyboardEvents.repeatInfo.emit();
|
||||
}, this, "CVirtualKeyboard");
|
||||
// clang-format on
|
||||
|
||||
deviceName = keeb->base.name ? keeb->base.name : "UNKNOWN";
|
||||
}
|
||||
|
||||
bool CVirtualKeyboard::isVirtual() {
|
||||
return true;
|
||||
}
|
||||
|
||||
wlr_keyboard* CVirtualKeyboard::wlr() {
|
||||
return keyboard.lock()->wlr();
|
||||
}
|
||||
|
||||
void CVirtualKeyboard::disconnectCallbacks() {
|
||||
hyprListener_destroy.removeCallback();
|
||||
hyprListener_key.removeCallback();
|
||||
hyprListener_keymap.removeCallback();
|
||||
hyprListener_repeatInfo.removeCallback();
|
||||
hyprListener_modifiers.removeCallback();
|
||||
}
|
||||
|
||||
wl_client* CVirtualKeyboard::getClient() {
|
||||
return keyboard.lock()->client();
|
||||
}
|
28
src/devices/VirtualKeyboard.hpp
Normal file
28
src/devices/VirtualKeyboard.hpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
#pragma once
|
||||
|
||||
#include "IKeyboard.hpp"
|
||||
|
||||
class CVirtualKeyboardV1Resource;
|
||||
|
||||
class CVirtualKeyboard : public IKeyboard {
|
||||
public:
|
||||
static SP<CVirtualKeyboard> create(SP<CVirtualKeyboardV1Resource> keeb);
|
||||
|
||||
virtual bool isVirtual();
|
||||
virtual wlr_keyboard* wlr();
|
||||
|
||||
wl_client* getClient();
|
||||
|
||||
private:
|
||||
CVirtualKeyboard(SP<CVirtualKeyboardV1Resource> keeb);
|
||||
|
||||
WP<CVirtualKeyboardV1Resource> keyboard;
|
||||
|
||||
void disconnectCallbacks();
|
||||
|
||||
DYNLISTENER(destroy);
|
||||
DYNLISTENER(key);
|
||||
DYNLISTENER(modifiers);
|
||||
DYNLISTENER(keymap);
|
||||
DYNLISTENER(repeatInfo);
|
||||
};
|
170
src/devices/VirtualPointer.cpp
Normal file
170
src/devices/VirtualPointer.cpp
Normal file
|
@ -0,0 +1,170 @@
|
|||
#include "VirtualPointer.hpp"
|
||||
#include "../protocols/VirtualPointer.hpp"
|
||||
|
||||
SP<CVirtualPointer> CVirtualPointer::create(SP<CVirtualPointerV1Resource> resource) {
|
||||
SP<CVirtualPointer> pPointer = SP<CVirtualPointer>(new CVirtualPointer(resource));
|
||||
|
||||
pPointer->self = pPointer;
|
||||
|
||||
return pPointer;
|
||||
}
|
||||
|
||||
CVirtualPointer::CVirtualPointer(SP<CVirtualPointerV1Resource> resource) : pointer(resource) {
|
||||
if (!resource->good())
|
||||
return;
|
||||
|
||||
auto mouse = resource->wlr();
|
||||
|
||||
// clang-format off
|
||||
hyprListener_destroy.initCallback(&mouse->base.events.destroy, [this] (void* owner, void* data) {
|
||||
disconnectCallbacks();
|
||||
events.destroy.emit();
|
||||
}, this, "CVirtualPointer");
|
||||
|
||||
hyprListener_motion.initCallback(&mouse->events.motion, [this] (void* owner, void* data) {
|
||||
auto E = (wlr_pointer_motion_event*)data;
|
||||
|
||||
pointerEvents.motion.emit(SMotionEvent{
|
||||
.timeMs = E->time_msec,
|
||||
.delta = {E->delta_x, E->delta_y},
|
||||
.unaccel = {E->unaccel_dx, E->unaccel_dy},
|
||||
});
|
||||
}, this, "CVirtualPointer");
|
||||
|
||||
hyprListener_motionAbsolute.initCallback(&mouse->events.motion_absolute, [this] (void* owner, void* data) {
|
||||
auto E = (wlr_pointer_motion_absolute_event*)data;
|
||||
|
||||
pointerEvents.motionAbsolute.emit(SMotionAbsoluteEvent{
|
||||
.timeMs = E->time_msec,
|
||||
.absolute = {E->x, E->y},
|
||||
});
|
||||
}, this, "CVirtualPointer");
|
||||
|
||||
hyprListener_button.initCallback(&mouse->events.button, [this] (void* owner, void* data) {
|
||||
auto E = (wlr_pointer_button_event*)data;
|
||||
|
||||
pointerEvents.button.emit(SButtonEvent{
|
||||
.timeMs = E->time_msec,
|
||||
.button = E->button,
|
||||
.state = (wl_pointer_button_state)E->state,
|
||||
});
|
||||
}, this, "CVirtualPointer");
|
||||
|
||||
hyprListener_axis.initCallback(&mouse->events.axis, [this] (void* owner, void* data) {
|
||||
auto E = (wlr_pointer_axis_event*)data;
|
||||
|
||||
pointerEvents.axis.emit(SAxisEvent{
|
||||
.timeMs = E->time_msec,
|
||||
.source = E->source,
|
||||
.axis = E->orientation,
|
||||
.relativeDirection = E->relative_direction,
|
||||
.delta = E->delta,
|
||||
.deltaDiscrete = E->delta_discrete,
|
||||
});
|
||||
}, this, "CVirtualPointer");
|
||||
|
||||
hyprListener_swipeBegin.initCallback(&mouse->events.swipe_begin, [this] (void* owner, void* data) {
|
||||
auto E = (wlr_pointer_swipe_begin_event*)data;
|
||||
|
||||
pointerEvents.swipeBegin.emit(SSwipeBeginEvent{
|
||||
.timeMs = E->time_msec,
|
||||
.fingers = E->fingers,
|
||||
});
|
||||
}, this, "CVirtualPointer");
|
||||
|
||||
hyprListener_swipeEnd.initCallback(&mouse->events.swipe_end, [this] (void* owner, void* data) {
|
||||
auto E = (wlr_pointer_swipe_end_event*)data;
|
||||
|
||||
pointerEvents.swipeEnd.emit(SSwipeEndEvent{
|
||||
.timeMs = E->time_msec,
|
||||
.cancelled = E->cancelled,
|
||||
});
|
||||
}, this, "CVirtualPointer");
|
||||
|
||||
hyprListener_swipeUpdate.initCallback(&mouse->events.swipe_update, [this] (void* owner, void* data) {
|
||||
auto E = (wlr_pointer_swipe_update_event*)data;
|
||||
|
||||
pointerEvents.swipeUpdate.emit(SSwipeUpdateEvent{
|
||||
.timeMs = E->time_msec,
|
||||
.fingers = E->fingers,
|
||||
.delta = {E->dx, E->dy},
|
||||
});
|
||||
}, this, "CVirtualPointer");
|
||||
|
||||
hyprListener_pinchBegin.initCallback(&mouse->events.pinch_begin, [this] (void* owner, void* data) {
|
||||
auto E = (wlr_pointer_pinch_begin_event*)data;
|
||||
|
||||
pointerEvents.pinchBegin.emit(SPinchBeginEvent{
|
||||
.timeMs = E->time_msec,
|
||||
.fingers = E->fingers,
|
||||
});
|
||||
}, this, "CVirtualPointer");
|
||||
|
||||
hyprListener_pinchEnd.initCallback(&mouse->events.pinch_end, [this] (void* owner, void* data) {
|
||||
auto E = (wlr_pointer_pinch_end_event*)data;
|
||||
|
||||
pointerEvents.pinchEnd.emit(SPinchEndEvent{
|
||||
.timeMs = E->time_msec,
|
||||
.cancelled = E->cancelled,
|
||||
});
|
||||
}, this, "CVirtualPointer");
|
||||
|
||||
hyprListener_pinchUpdate.initCallback(&mouse->events.pinch_update, [this] (void* owner, void* data) {
|
||||
auto E = (wlr_pointer_pinch_update_event*)data;
|
||||
|
||||
pointerEvents.pinchUpdate.emit(SPinchUpdateEvent{
|
||||
.timeMs = E->time_msec,
|
||||
.fingers = E->fingers,
|
||||
.delta = {E->dx, E->dy},
|
||||
.scale = E->scale,
|
||||
.rotation = E->rotation,
|
||||
});
|
||||
}, this, "CVirtualPointer");
|
||||
|
||||
hyprListener_holdBegin.initCallback(&mouse->events.hold_begin, [this] (void* owner, void* data) {
|
||||
auto E = (wlr_pointer_hold_begin_event*)data;
|
||||
|
||||
pointerEvents.holdBegin.emit(SHoldBeginEvent{
|
||||
.timeMs = E->time_msec,
|
||||
.fingers = E->fingers,
|
||||
});
|
||||
}, this, "CVirtualPointer");
|
||||
|
||||
hyprListener_holdEnd.initCallback(&mouse->events.hold_end, [this] (void* owner, void* data) {
|
||||
auto E = (wlr_pointer_hold_end_event*)data;
|
||||
|
||||
pointerEvents.holdEnd.emit(SHoldEndEvent{
|
||||
.timeMs = E->time_msec,
|
||||
.cancelled = E->cancelled,
|
||||
});
|
||||
}, this, "CVirtualPointer");
|
||||
|
||||
// clang-format on
|
||||
|
||||
deviceName = mouse->base.name ? mouse->base.name : "UNKNOWN";
|
||||
}
|
||||
|
||||
bool CVirtualPointer::isVirtual() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void CVirtualPointer::disconnectCallbacks() {
|
||||
hyprListener_destroy.removeCallback();
|
||||
hyprListener_motion.removeCallback();
|
||||
hyprListener_motionAbsolute.removeCallback();
|
||||
hyprListener_button.removeCallback();
|
||||
hyprListener_axis.removeCallback();
|
||||
hyprListener_frame.removeCallback();
|
||||
hyprListener_swipeBegin.removeCallback();
|
||||
hyprListener_swipeEnd.removeCallback();
|
||||
hyprListener_swipeUpdate.removeCallback();
|
||||
hyprListener_pinchBegin.removeCallback();
|
||||
hyprListener_pinchEnd.removeCallback();
|
||||
hyprListener_pinchUpdate.removeCallback();
|
||||
hyprListener_holdBegin.removeCallback();
|
||||
hyprListener_holdEnd.removeCallback();
|
||||
}
|
||||
|
||||
wlr_pointer* CVirtualPointer::wlr() {
|
||||
return pointer.lock()->wlr();
|
||||
}
|
38
src/devices/VirtualPointer.hpp
Normal file
38
src/devices/VirtualPointer.hpp
Normal file
|
@ -0,0 +1,38 @@
|
|||
#pragma once
|
||||
|
||||
#include "IPointer.hpp"
|
||||
|
||||
class CVirtualPointerV1Resource;
|
||||
|
||||
class CVirtualPointer : public IPointer {
|
||||
public:
|
||||
static SP<CVirtualPointer> create(SP<CVirtualPointerV1Resource> resource);
|
||||
|
||||
virtual bool isVirtual();
|
||||
virtual wlr_pointer* wlr();
|
||||
|
||||
private:
|
||||
CVirtualPointer(SP<CVirtualPointerV1Resource>);
|
||||
|
||||
WP<CVirtualPointerV1Resource> pointer;
|
||||
|
||||
void disconnectCallbacks();
|
||||
|
||||
DYNLISTENER(destroy);
|
||||
DYNLISTENER(motion);
|
||||
DYNLISTENER(motionAbsolute);
|
||||
DYNLISTENER(button);
|
||||
DYNLISTENER(axis);
|
||||
DYNLISTENER(frame);
|
||||
|
||||
DYNLISTENER(swipeBegin);
|
||||
DYNLISTENER(swipeEnd);
|
||||
DYNLISTENER(swipeUpdate);
|
||||
|
||||
DYNLISTENER(pinchBegin);
|
||||
DYNLISTENER(pinchEnd);
|
||||
DYNLISTENER(pinchUpdate);
|
||||
|
||||
DYNLISTENER(holdBegin);
|
||||
DYNLISTENER(holdEnd);
|
||||
};
|
|
@ -16,23 +16,6 @@
|
|||
// //
|
||||
// ---------------------------------------------------- //
|
||||
|
||||
void Events::listener_keyboardDestroy(void* owner, void* data) {
|
||||
SKeyboard* PKEYBOARD = (SKeyboard*)owner;
|
||||
g_pInputManager->destroyKeyboard(PKEYBOARD);
|
||||
|
||||
Debug::log(LOG, "Destroyed keyboard {:x}", (uintptr_t)PKEYBOARD);
|
||||
}
|
||||
|
||||
void Events::listener_keyboardKey(void* owner, void* data) {
|
||||
SKeyboard* PKEYBOARD = (SKeyboard*)owner;
|
||||
g_pInputManager->onKeyboardKey((wlr_keyboard_key_event*)data, PKEYBOARD);
|
||||
}
|
||||
|
||||
void Events::listener_keyboardMod(void* owner, void* data) {
|
||||
SKeyboard* PKEYBOARD = (SKeyboard*)owner;
|
||||
g_pInputManager->onKeyboardMod(data, PKEYBOARD);
|
||||
}
|
||||
|
||||
void Events::listener_mouseFrame(wl_listener* listener, void* data) {
|
||||
wlr_seat_pointer_notify_frame(g_pCompositor->m_sSeat.seat);
|
||||
}
|
||||
|
@ -93,12 +76,6 @@ void Events::listener_newInput(wl_listener* listener, void* data) {
|
|||
g_pInputManager->updateCapabilities();
|
||||
}
|
||||
|
||||
void Events::listener_destroyMouse(void* owner, void* data) {
|
||||
const auto PMOUSE = (SMouse*)owner;
|
||||
|
||||
g_pInputManager->destroyMouse(PMOUSE->mouse);
|
||||
}
|
||||
|
||||
void Events::listener_swipeBegin(wl_listener* listener, void* data) {
|
||||
const auto EVENT = (wlr_pointer_swipe_begin_event*)data;
|
||||
|
||||
|
|
|
@ -54,11 +54,6 @@ namespace Events {
|
|||
|
||||
// Virt Ptr
|
||||
LISTENER(newVirtPtr);
|
||||
DYNLISTENFUNC(destroyMouse);
|
||||
|
||||
DYNLISTENFUNC(keyboardKey);
|
||||
DYNLISTENFUNC(keyboardMod);
|
||||
DYNLISTENFUNC(keyboardDestroy);
|
||||
|
||||
// Various
|
||||
LISTENER(requestMouse);
|
||||
|
|
|
@ -667,7 +667,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
|||
g_pCompositor->setPreferredScaleForSurface(PWINDOW->m_pWLSurface.wlr(), PMONITOR->scale);
|
||||
g_pCompositor->setPreferredTransformForSurface(PWINDOW->m_pWLSurface.wlr(), PMONITOR->transform);
|
||||
|
||||
if (!g_pCompositor->m_sSeat.mouse || !g_pInputManager->isConstrained())
|
||||
if (g_pCompositor->m_sSeat.mouse.expired() || !g_pInputManager->isConstrained())
|
||||
g_pInputManager->sendMotionEventsToFocused();
|
||||
|
||||
// fix some xwayland apps that don't behave nicely
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "../Compositor.hpp"
|
||||
#include "../config/ConfigValue.hpp"
|
||||
#include "../protocols/GammaControl.hpp"
|
||||
#include "../devices/ITouch.hpp"
|
||||
|
||||
int ratHandler(void* data) {
|
||||
g_pHyprRenderer->renderMonitor((CMonitor*)data);
|
||||
|
@ -145,10 +146,10 @@ void CMonitor::onConnect(bool noRule) {
|
|||
if (!noRule)
|
||||
g_pHyprRenderer->applyMonitorRule(this, &monitorRule, true);
|
||||
|
||||
for (const auto& PTOUCHDEV : g_pInputManager->m_lTouchDevices) {
|
||||
if (matchesStaticSelector(PTOUCHDEV.boundOutput)) {
|
||||
Debug::log(LOG, "Binding touch device {} to output {}", PTOUCHDEV.name, szName);
|
||||
wlr_cursor_map_input_to_output(g_pCompositor->m_sWLRCursor, PTOUCHDEV.pWlrDevice, output);
|
||||
for (const auto& PTOUCHDEV : g_pInputManager->m_vTouches) {
|
||||
if (matchesStaticSelector(PTOUCHDEV->boundOutput)) {
|
||||
Debug::log(LOG, "Binding touch device {} to output {}", PTOUCHDEV->hlName, szName);
|
||||
wlr_cursor_map_input_to_output(g_pCompositor->m_sWLRCursor, &PTOUCHDEV->wlr()->base, output);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,78 +1 @@
|
|||
#include "WLClasses.hpp"
|
||||
|
||||
void SKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) {
|
||||
xkb_state_unref(xkbTranslationState);
|
||||
|
||||
if (keymap) {
|
||||
Debug::log(LOG, "Updating keyboard {:x}'s translation state from a provided keymap", (uintptr_t)this);
|
||||
xkbTranslationState = xkb_state_new(keymap);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto WLRKB = wlr_keyboard_from_input_device(keyboard);
|
||||
const auto KEYMAP = WLRKB->keymap;
|
||||
const auto STATE = WLRKB->xkb_state;
|
||||
const auto LAYOUTSNUM = xkb_keymap_num_layouts(KEYMAP);
|
||||
|
||||
const auto PCONTEXT = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
|
||||
for (uint32_t i = 0; i < LAYOUTSNUM; ++i) {
|
||||
if (xkb_state_layout_index_is_active(STATE, i, XKB_STATE_LAYOUT_EFFECTIVE)) {
|
||||
Debug::log(LOG, "Updating keyboard {:x}'s translation state from an active index {}", (uintptr_t)this, i);
|
||||
|
||||
CVarList keyboardLayouts(currentRules.layout, 0, ',');
|
||||
CVarList keyboardModels(currentRules.model, 0, ',');
|
||||
CVarList keyboardVariants(currentRules.variant, 0, ',');
|
||||
|
||||
xkb_rule_names rules = {.rules = "", .model = "", .layout = "", .variant = "", .options = ""};
|
||||
|
||||
std::string layout, model, variant;
|
||||
layout = keyboardLayouts[i % keyboardLayouts.size()];
|
||||
model = keyboardModels[i % keyboardModels.size()];
|
||||
variant = keyboardVariants[i % keyboardVariants.size()];
|
||||
|
||||
rules.layout = layout.c_str();
|
||||
rules.model = model.c_str();
|
||||
rules.variant = variant.c_str();
|
||||
|
||||
auto KEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
|
||||
if (!KEYMAP) {
|
||||
Debug::log(ERR, "updateXKBTranslationState: keymap failed 1, fallback without model/variant");
|
||||
rules.model = "";
|
||||
rules.variant = "";
|
||||
KEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
}
|
||||
|
||||
if (!KEYMAP) {
|
||||
Debug::log(ERR, "updateXKBTranslationState: keymap failed 2, fallback to us");
|
||||
rules.layout = "us";
|
||||
KEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
}
|
||||
|
||||
xkbTranslationState = xkb_state_new(KEYMAP);
|
||||
|
||||
xkb_keymap_unref(KEYMAP);
|
||||
xkb_context_unref(PCONTEXT);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Debug::log(LOG, "Updating keyboard {:x}'s translation state from an unknown index", (uintptr_t)this);
|
||||
|
||||
xkb_rule_names rules = {
|
||||
.rules = currentRules.rules.c_str(),
|
||||
.model = currentRules.model.c_str(),
|
||||
.layout = currentRules.layout.c_str(),
|
||||
.variant = currentRules.variant.c_str(),
|
||||
.options = currentRules.options.c_str(),
|
||||
};
|
||||
|
||||
const auto NEWKEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
|
||||
xkbTranslationState = xkb_state_new(NEWKEYMAP);
|
||||
|
||||
xkb_keymap_unref(NEWKEYMAP);
|
||||
xkb_context_unref(PCONTEXT);
|
||||
}
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
#include "Region.hpp"
|
||||
|
||||
class CMonitor;
|
||||
class CVirtualKeyboard;
|
||||
class CVirtualPointer;
|
||||
class IPointer;
|
||||
class IKeyboard;
|
||||
|
||||
struct SRenderData {
|
||||
CMonitor* pMonitor;
|
||||
|
@ -58,86 +58,12 @@ struct SExtensionFindingData {
|
|||
wlr_surface** found;
|
||||
};
|
||||
|
||||
struct SStringRuleNames {
|
||||
std::string layout = "";
|
||||
std::string model = "";
|
||||
std::string variant = "";
|
||||
std::string options = "";
|
||||
std::string rules = "";
|
||||
};
|
||||
|
||||
struct SKeyboard {
|
||||
wlr_input_device* keyboard;
|
||||
|
||||
DYNLISTENER(keyboardMod);
|
||||
DYNLISTENER(keyboardKey);
|
||||
DYNLISTENER(keyboardKeymap);
|
||||
DYNLISTENER(keyboardDestroy);
|
||||
|
||||
bool isVirtual = false;
|
||||
bool active = false;
|
||||
bool enabled = true;
|
||||
|
||||
WP<CVirtualKeyboard> virtKeyboard;
|
||||
|
||||
xkb_layout_index_t activeLayout = 0;
|
||||
xkb_state* xkbTranslationState = nullptr;
|
||||
|
||||
std::string name = "";
|
||||
std::string xkbFilePath = "";
|
||||
|
||||
SStringRuleNames currentRules;
|
||||
int repeatRate = 0;
|
||||
int repeatDelay = 0;
|
||||
int numlockOn = -1;
|
||||
bool resolveBindsBySym = false;
|
||||
|
||||
void updateXKBTranslationState(xkb_keymap* const keymap = nullptr);
|
||||
|
||||
struct {
|
||||
CHyprSignalListener destroyVKeyboard;
|
||||
} listeners;
|
||||
|
||||
// For the list lookup
|
||||
bool operator==(const SKeyboard& rhs) const {
|
||||
return keyboard == rhs.keyboard;
|
||||
}
|
||||
|
||||
~SKeyboard() {
|
||||
if (xkbTranslationState)
|
||||
xkb_state_unref(xkbTranslationState);
|
||||
}
|
||||
};
|
||||
|
||||
struct SMouse {
|
||||
wlr_input_device* mouse = nullptr;
|
||||
|
||||
std::string name = "";
|
||||
|
||||
bool virt = false;
|
||||
|
||||
bool connected = false; // means connected to the cursor
|
||||
|
||||
WP<CVirtualPointer> virtualPointer;
|
||||
|
||||
struct {
|
||||
CHyprSignalListener destroyMouse;
|
||||
} listeners;
|
||||
|
||||
DYNLISTENER(destroyMouse);
|
||||
|
||||
bool operator==(const SMouse& b) const {
|
||||
return mouse == b.mouse;
|
||||
}
|
||||
};
|
||||
|
||||
class CMonitor;
|
||||
|
||||
struct SSeat {
|
||||
wlr_seat* seat = nullptr;
|
||||
wl_client* exclusiveClient = nullptr;
|
||||
wlr_seat* seat = nullptr;
|
||||
wl_client* exclusiveClient = nullptr;
|
||||
|
||||
SMouse* mouse = nullptr;
|
||||
WP<IPointer> mouse;
|
||||
WP<IKeyboard> keyboard;
|
||||
};
|
||||
|
||||
struct SDrag {
|
||||
|
@ -238,20 +164,6 @@ struct SSwipeGesture {
|
|||
CMonitor* pMonitor = nullptr;
|
||||
};
|
||||
|
||||
struct STouchDevice {
|
||||
wlr_input_device* pWlrDevice = nullptr;
|
||||
|
||||
std::string name = "";
|
||||
|
||||
std::string boundOutput = "";
|
||||
|
||||
DYNLISTENER(destroy);
|
||||
|
||||
bool operator==(const STouchDevice& other) const {
|
||||
return pWlrDevice == other.pWlrDevice;
|
||||
}
|
||||
};
|
||||
|
||||
struct SSwitchDevice {
|
||||
wlr_input_device* pWlrDevice = nullptr;
|
||||
|
||||
|
|
|
@ -11,3 +11,11 @@ void CSignalListener::emit(std::any data) {
|
|||
|
||||
m_fHandler(data);
|
||||
}
|
||||
|
||||
CStaticSignalListener::CStaticSignalListener(std::function<void(void*, std::any)> handler, void* owner) : m_pOwner(owner), m_fHandler(handler) {
|
||||
;
|
||||
}
|
||||
|
||||
void CStaticSignalListener::emit(std::any data) {
|
||||
m_fHandler(m_pOwner, data);
|
||||
}
|
||||
|
|
|
@ -22,3 +22,19 @@ class CSignalListener {
|
|||
};
|
||||
|
||||
typedef std::shared_ptr<CSignalListener> CHyprSignalListener;
|
||||
|
||||
class CStaticSignalListener {
|
||||
public:
|
||||
CStaticSignalListener(std::function<void(void*, std::any)> handler, void* owner);
|
||||
|
||||
CStaticSignalListener(CStaticSignalListener&&) = delete;
|
||||
CStaticSignalListener(CStaticSignalListener&) = delete;
|
||||
CStaticSignalListener(const CStaticSignalListener&) = delete;
|
||||
CStaticSignalListener(const CStaticSignalListener&&) = delete;
|
||||
|
||||
void emit(std::any data);
|
||||
|
||||
private:
|
||||
void* m_pOwner = nullptr;
|
||||
std::function<void(void*, std::any)> m_fHandler;
|
||||
};
|
|
@ -11,6 +11,10 @@ void CSignal::emit(std::any data) {
|
|||
dirty = true;
|
||||
}
|
||||
|
||||
for (auto& l : m_vStaticListeners) {
|
||||
l->emit(data);
|
||||
}
|
||||
|
||||
if (dirty)
|
||||
std::erase_if(m_vListeners, [](const auto& other) { return other.expired(); });
|
||||
}
|
||||
|
@ -20,3 +24,7 @@ CHyprSignalListener CSignal::registerListener(std::function<void(std::any)> hand
|
|||
m_vListeners.emplace_back(std::weak_ptr<CSignalListener>(listener));
|
||||
return listener;
|
||||
}
|
||||
|
||||
void CSignal::registerStaticListener(std::function<void(void*, std::any)> handler, void* owner) {
|
||||
m_vStaticListeners.emplace_back(std::make_unique<CStaticSignalListener>(handler, owner));
|
||||
}
|
|
@ -14,6 +14,11 @@ class CSignal {
|
|||
//
|
||||
[[nodiscard("Listener is unregistered when the ptr is lost")]] CHyprSignalListener registerListener(std::function<void(std::any)> handler);
|
||||
|
||||
// this is for static listeners. They die with this signal.
|
||||
// TODO: can we somehow rid of the void* data and make it a custom this?
|
||||
void registerStaticListener(std::function<void(void*, std::any)> handler, void* owner);
|
||||
|
||||
private:
|
||||
std::vector<std::weak_ptr<CSignalListener>> m_vListeners;
|
||||
std::vector<std::weak_ptr<CSignalListener>> m_vListeners;
|
||||
std::vector<std::unique_ptr<CStaticSignalListener>> m_vStaticListeners;
|
||||
};
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "../config/ConfigValue.hpp"
|
||||
#include "TokenManager.hpp"
|
||||
#include "../protocols/ShortcutsInhibit.hpp"
|
||||
#include "../devices/IKeyboard.hpp"
|
||||
|
||||
#include <regex>
|
||||
#include <tuple>
|
||||
|
@ -323,7 +324,7 @@ void CKeybindManager::switchToWindow(PHLWINDOW PWINDOWTOCHANGETO) {
|
|||
}
|
||||
};
|
||||
|
||||
bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard) {
|
||||
bool CKeybindManager::onKeyEvent(std::any event, SP<IKeyboard> pKeyboard) {
|
||||
if (!g_pCompositor->m_bSessionActive || g_pCompositor->m_bUnsafeState) {
|
||||
m_dPressedKeys.clear();
|
||||
return true;
|
||||
|
@ -337,17 +338,19 @@ bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard
|
|||
return true;
|
||||
}
|
||||
|
||||
const auto KEYCODE = e->keycode + 8; // Because to xkbcommon it's +8 from libinput
|
||||
auto e = std::any_cast<IKeyboard::SKeyEvent>(event);
|
||||
|
||||
const auto KEYCODE = e.keycode + 8; // Because to xkbcommon it's +8 from libinput
|
||||
|
||||
const xkb_keysym_t keysym = xkb_state_key_get_one_sym(pKeyboard->resolveBindsBySym ? pKeyboard->xkbTranslationState : m_pXKBTranslationState, KEYCODE);
|
||||
const xkb_keysym_t internalKeysym = xkb_state_key_get_one_sym(wlr_keyboard_from_input_device(pKeyboard->keyboard)->xkb_state, KEYCODE);
|
||||
const xkb_keysym_t internalKeysym = xkb_state_key_get_one_sym(pKeyboard->wlr()->xkb_state, KEYCODE);
|
||||
|
||||
if (handleInternalKeybinds(internalKeysym))
|
||||
return true;
|
||||
|
||||
const auto MODS = g_pInputManager->accumulateModsFromAllKBs();
|
||||
|
||||
m_uTimeLastMs = e->time_msec;
|
||||
m_uTimeLastMs = e.timeMs;
|
||||
m_uLastCode = KEYCODE;
|
||||
m_uLastMouseCode = 0;
|
||||
|
||||
|
@ -368,7 +371,7 @@ bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard
|
|||
}
|
||||
|
||||
bool suppressEvent = false;
|
||||
if (e->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||
if (e.state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||
|
||||
m_dPressedKeys.push_back(KEY);
|
||||
|
||||
|
@ -521,7 +524,7 @@ void CKeybindManager::onSwitchOffEvent(const std::string& switchName) {
|
|||
int repeatKeyHandler(void* data) {
|
||||
SKeybind** ppActiveKeybind = (SKeybind**)data;
|
||||
|
||||
if (!*ppActiveKeybind)
|
||||
if (!*ppActiveKeybind || g_pCompositor->m_sSeat.keyboard.expired())
|
||||
return 0;
|
||||
|
||||
const auto DISPATCHER = g_pKeybindManager->m_mDispatchers.find((*ppActiveKeybind)->handler);
|
||||
|
@ -529,7 +532,7 @@ int repeatKeyHandler(void* data) {
|
|||
Debug::log(LOG, "Keybind repeat triggered, calling dispatcher.");
|
||||
DISPATCHER->second((*ppActiveKeybind)->arg);
|
||||
|
||||
wl_event_source_timer_update(g_pKeybindManager->m_pActiveKeybindEventSource, 1000 / g_pInputManager->m_pActiveKeyboard->repeatRate);
|
||||
wl_event_source_timer_update(g_pKeybindManager->m_pActiveKeybindEventSource, 1000 / g_pCompositor->m_sSeat.keyboard.lock()->repeatRate);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -650,7 +653,7 @@ bool CKeybindManager::handleKeybinds(const uint32_t modmask, const SPressedKeyWi
|
|||
m_pActiveKeybind = &k;
|
||||
m_pActiveKeybindEventSource = wl_event_loop_add_timer(g_pCompositor->m_sWLEventLoop, repeatKeyHandler, &m_pActiveKeybind);
|
||||
|
||||
const auto PACTIVEKEEB = g_pInputManager->m_pActiveKeyboard;
|
||||
const auto PACTIVEKEEB = g_pCompositor->m_sSeat.keyboard.lock();
|
||||
|
||||
wl_event_source_timer_update(m_pActiveKeybindEventSource, PACTIVEKEEB->repeatDelay);
|
||||
}
|
||||
|
@ -1440,22 +1443,20 @@ void CKeybindManager::moveCursorToCorner(std::string arg) {
|
|||
switch (CORNER) {
|
||||
case 0:
|
||||
// bottom left
|
||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, PWINDOW->m_vRealPosition.value().x,
|
||||
PWINDOW->m_vRealPosition.value().y + PWINDOW->m_vRealSize.value().y);
|
||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, PWINDOW->m_vRealPosition.value().x, PWINDOW->m_vRealPosition.value().y + PWINDOW->m_vRealSize.value().y);
|
||||
break;
|
||||
case 1:
|
||||
// bottom right
|
||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, PWINDOW->m_vRealPosition.value().x + PWINDOW->m_vRealSize.value().x,
|
||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, PWINDOW->m_vRealPosition.value().x + PWINDOW->m_vRealSize.value().x,
|
||||
PWINDOW->m_vRealPosition.value().y + PWINDOW->m_vRealSize.value().y);
|
||||
break;
|
||||
case 2:
|
||||
// top right
|
||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, PWINDOW->m_vRealPosition.value().x + PWINDOW->m_vRealSize.value().x,
|
||||
PWINDOW->m_vRealPosition.value().y);
|
||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, PWINDOW->m_vRealPosition.value().x + PWINDOW->m_vRealSize.value().x, PWINDOW->m_vRealPosition.value().y);
|
||||
break;
|
||||
case 3:
|
||||
// top left
|
||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, PWINDOW->m_vRealPosition.value().x, PWINDOW->m_vRealPosition.value().y);
|
||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, PWINDOW->m_vRealPosition.value().x, PWINDOW->m_vRealPosition.value().y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1485,7 +1486,7 @@ void CKeybindManager::moveCursor(std::string args) {
|
|||
x = std::stoi(x_str);
|
||||
y = std::stoi(y_str);
|
||||
|
||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, x, y);
|
||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, x, y);
|
||||
}
|
||||
|
||||
void CKeybindManager::workspaceOpt(std::string args) {
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
class CInputManager;
|
||||
class CConfigManager;
|
||||
class CPluginSystem;
|
||||
class IKeyboard;
|
||||
|
||||
struct SKeybind {
|
||||
std::string key = "";
|
||||
|
@ -60,7 +61,7 @@ class CKeybindManager {
|
|||
CKeybindManager();
|
||||
~CKeybindManager();
|
||||
|
||||
bool onKeyEvent(wlr_keyboard_key_event*, SKeyboard*);
|
||||
bool onKeyEvent(std::any, SP<IKeyboard>);
|
||||
bool onAxisEvent(wlr_pointer_axis_event*);
|
||||
bool onMouseEvent(wlr_pointer_button_event*);
|
||||
void resizeWithBorder(wlr_pointer_button_event*);
|
||||
|
|
|
@ -14,6 +14,12 @@
|
|||
#include "../../protocols/VirtualKeyboard.hpp"
|
||||
#include "../../protocols/VirtualPointer.hpp"
|
||||
|
||||
#include "../../devices/Mouse.hpp"
|
||||
#include "../../devices/VirtualPointer.hpp"
|
||||
#include "../../devices/Keyboard.hpp"
|
||||
#include "../../devices/VirtualKeyboard.hpp"
|
||||
#include "../../devices/TouchDevice.hpp"
|
||||
|
||||
CInputManager::CInputManager() {
|
||||
m_sListeners.setCursorShape = PROTO::cursorShape->events.setShape.registerListener([this](std::any data) {
|
||||
if (!cursorImageUnlocked())
|
||||
|
@ -40,20 +46,20 @@ 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)); });
|
||||
PROTO::virtualKeyboard->events.newKeyboard.registerListener([this](std::any data) { this->newVirtualKeyboard(std::any_cast<SP<CVirtualKeyboardV1Resource>>(data)); });
|
||||
m_sListeners.newVirtualMouse =
|
||||
PROTO::virtualPointer->events.newPointer.registerListener([this](std::any data) { this->newVirtualMouse(std::any_cast<SP<CVirtualPointer>>(data)); });
|
||||
PROTO::virtualPointer->events.newPointer.registerListener([this](std::any data) { this->newVirtualMouse(std::any_cast<SP<CVirtualPointerV1Resource>>(data)); });
|
||||
}
|
||||
|
||||
CInputManager::~CInputManager() {
|
||||
m_vConstraints.clear();
|
||||
m_lKeyboards.clear();
|
||||
m_lMice.clear();
|
||||
m_vKeyboards.clear();
|
||||
m_vPointers.clear();
|
||||
m_vTouches.clear();
|
||||
m_lTablets.clear();
|
||||
m_lTabletTools.clear();
|
||||
m_lTabletPads.clear();
|
||||
m_vIdleInhibitors.clear();
|
||||
m_lTouchDevices.clear();
|
||||
m_lSwitches.clear();
|
||||
}
|
||||
|
||||
|
@ -181,7 +187,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
|||
}
|
||||
|
||||
// constraints
|
||||
if (g_pCompositor->m_sSeat.mouse && isConstrained()) {
|
||||
if (!g_pCompositor->m_sSeat.mouse.expired() && isConstrained()) {
|
||||
const auto SURF = CWLSurface::surfaceFromWlr(g_pCompositor->m_pLastFocus);
|
||||
const auto CONSTRAINT = SURF->constraint();
|
||||
|
||||
|
@ -651,7 +657,7 @@ void CInputManager::processMouseDownNormal(wlr_pointer_button_event* e) {
|
|||
if (*PFOLLOWMOUSE == 3) // don't refocus on full loose
|
||||
break;
|
||||
|
||||
if ((!g_pCompositor->m_sSeat.mouse || !isConstrained()) /* No constraints */
|
||||
if ((g_pCompositor->m_sSeat.mouse.expired() || !isConstrained()) /* No constraints */
|
||||
&& (w && g_pCompositor->m_pLastWindow.lock() != w) /* window should change */) {
|
||||
// a bit hacky
|
||||
// if we only pressed one button, allow us to refocus. m_lCurrentlyHeldButtons.size() > 0 will stick the focus
|
||||
|
@ -754,105 +760,84 @@ Vector2D CInputManager::getMouseCoordsInternal() {
|
|||
}
|
||||
|
||||
void CInputManager::newKeyboard(wlr_input_device* keyboard) {
|
||||
const auto PNEWKEYBOARD = &m_lKeyboards.emplace_back();
|
||||
const auto PNEWKEYBOARD = m_vKeyboards.emplace_back(CKeyboard::create(wlr_keyboard_from_input_device(keyboard)));
|
||||
|
||||
PNEWKEYBOARD->keyboard = keyboard;
|
||||
setupKeyboard(PNEWKEYBOARD);
|
||||
|
||||
Debug::log(LOG, "New keyboard created, pointers Hypr: {:x} and WLR: {:x}", (uintptr_t)PNEWKEYBOARD.get(), (uintptr_t)keyboard);
|
||||
}
|
||||
|
||||
void CInputManager::newVirtualKeyboard(SP<CVirtualKeyboardV1Resource> keyboard) {
|
||||
const auto PNEWKEYBOARD = m_vKeyboards.emplace_back(CVirtualKeyboard::create(keyboard));
|
||||
|
||||
setupKeyboard(PNEWKEYBOARD);
|
||||
|
||||
Debug::log(LOG, "New virtual keyboard created, pointers Hypr: {:x} and WLR: {:x}", (uintptr_t)PNEWKEYBOARD.get(), (uintptr_t)keyboard->wlr());
|
||||
}
|
||||
|
||||
void CInputManager::setupKeyboard(SP<IKeyboard> keeb) {
|
||||
try {
|
||||
PNEWKEYBOARD->name = getNameForNewDevice(keyboard->name);
|
||||
keeb->hlName = getNameForNewDevice(keeb->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_keyboardKeymap.initCallback(
|
||||
&wlr_keyboard_from_input_device(keyboard)->events.keymap,
|
||||
[&](void* owner, void* data) {
|
||||
const auto PKEYBOARD = (SKeyboard*)owner;
|
||||
const auto LAYOUT = getActiveLayoutForKeyboard(PKEYBOARD);
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", PKEYBOARD->name + "," + LAYOUT});
|
||||
EMIT_HOOK_EVENT("activeLayout", (std::vector<void*>{PKEYBOARD, (void*)&LAYOUT}));
|
||||
keeb->events.destroy.registerStaticListener(
|
||||
[this](void* owner, std::any data) {
|
||||
auto PKEEB = ((IKeyboard*)owner)->self.lock();
|
||||
destroyKeyboard(PKEEB);
|
||||
Debug::log(LOG, "Destroyed keyboard {:x}", (uintptr_t)owner);
|
||||
},
|
||||
PNEWKEYBOARD, "Keyboard");
|
||||
keeb.get());
|
||||
|
||||
keeb->keyboardEvents.key.registerStaticListener(
|
||||
[this](void* owner, std::any data) {
|
||||
auto PKEEB = ((IKeyboard*)owner)->self.lock();
|
||||
onKeyboardKey(data, PKEEB);
|
||||
},
|
||||
keeb.get());
|
||||
|
||||
keeb->keyboardEvents.modifiers.registerStaticListener(
|
||||
[this](void* owner, std::any data) {
|
||||
auto PKEEB = ((IKeyboard*)owner)->self.lock();
|
||||
onKeyboardMod(PKEEB);
|
||||
},
|
||||
keeb.get());
|
||||
|
||||
keeb->keyboardEvents.keymap.registerStaticListener(
|
||||
[this](void* owner, std::any data) {
|
||||
auto PKEEB = ((IKeyboard*)owner)->self.lock();
|
||||
const auto LAYOUT = PKEEB->getActiveLayout();
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", PKEEB->hlName + "," + LAYOUT});
|
||||
EMIT_HOOK_EVENT("activeLayout", (std::vector<std::any>{PKEEB, LAYOUT}));
|
||||
},
|
||||
keeb.get());
|
||||
|
||||
disableAllKeyboards(false);
|
||||
|
||||
m_pActiveKeyboard = PNEWKEYBOARD;
|
||||
g_pCompositor->m_sSeat.keyboard = keeb;
|
||||
|
||||
PNEWKEYBOARD->active = true;
|
||||
keeb->active = true;
|
||||
|
||||
applyConfigToKeyboard(PNEWKEYBOARD);
|
||||
applyConfigToKeyboard(keeb);
|
||||
|
||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, wlr_keyboard_from_input_device(keyboard));
|
||||
|
||||
Debug::log(LOG, "New keyboard created, pointers Hypr: {:x} and WLR: {:x}", (uintptr_t)PNEWKEYBOARD, (uintptr_t)keyboard);
|
||||
}
|
||||
|
||||
void CInputManager::newVirtualKeyboard(SP<CVirtualKeyboard> keyboard) {
|
||||
const auto PNEWKEYBOARD = &m_lKeyboards.emplace_back();
|
||||
|
||||
PNEWKEYBOARD->keyboard = &keyboard->wlr()->base;
|
||||
PNEWKEYBOARD->isVirtual = true;
|
||||
PNEWKEYBOARD->virtKeyboard = keyboard;
|
||||
|
||||
try {
|
||||
PNEWKEYBOARD->name = getNameForNewDevice(keyboard->wlr()->base.name);
|
||||
} catch (std::exception& e) {
|
||||
Debug::log(ERR, "Keyboard had no name???"); // logic error
|
||||
}
|
||||
|
||||
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(
|
||||
&keyboard->wlr()->events.keymap,
|
||||
[&](void* owner, void* data) {
|
||||
const auto PKEYBOARD = (SKeyboard*)owner;
|
||||
const auto LAYOUT = getActiveLayoutForKeyboard(PKEYBOARD);
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", PKEYBOARD->name + "," + LAYOUT});
|
||||
EMIT_HOOK_EVENT("activeLayout", (std::vector<void*>{PKEYBOARD, (void*)&LAYOUT}));
|
||||
},
|
||||
PNEWKEYBOARD, "VKeyboard");
|
||||
|
||||
// TODO: this pointer pass sucks.
|
||||
PNEWKEYBOARD->listeners.destroyVKeyboard = keyboard->events.destroy.registerListener([this, PNEWKEYBOARD](std::any data) { destroyKeyboard(PNEWKEYBOARD); });
|
||||
|
||||
disableAllKeyboards(true);
|
||||
|
||||
m_pActiveKeyboard = PNEWKEYBOARD;
|
||||
|
||||
PNEWKEYBOARD->active = true;
|
||||
|
||||
applyConfigToKeyboard(PNEWKEYBOARD);
|
||||
|
||||
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->wlr());
|
||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, keeb->wlr());
|
||||
}
|
||||
|
||||
void CInputManager::setKeyboardLayout() {
|
||||
for (auto& k : m_lKeyboards)
|
||||
applyConfigToKeyboard(&k);
|
||||
for (auto& k : m_vKeyboards)
|
||||
applyConfigToKeyboard(k);
|
||||
|
||||
g_pKeybindManager->updateXKBTranslationState();
|
||||
}
|
||||
|
||||
void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
||||
auto devname = pKeyboard->name;
|
||||
void CInputManager::applyConfigToKeyboard(SP<IKeyboard> pKeyboard) {
|
||||
auto devname = pKeyboard->hlName;
|
||||
|
||||
const auto HASCONFIG = g_pConfigManager->deviceConfigExists(devname);
|
||||
|
||||
Debug::log(LOG, "ApplyConfigToKeyboard for \"{}\", hasconfig: {}", pKeyboard->name, (int)HASCONFIG);
|
||||
|
||||
ASSERT(pKeyboard);
|
||||
|
||||
if (!wlr_keyboard_from_input_device(pKeyboard->keyboard))
|
||||
return;
|
||||
Debug::log(LOG, "ApplyConfigToKeyboard for \"{}\", hasconfig: {}", devname, (int)HASCONFIG);
|
||||
|
||||
const auto REPEATRATE = g_pConfigManager->getDeviceInt(devname, "repeat_rate", "input:repeat_rate");
|
||||
const auto REPEATDELAY = g_pConfigManager->getDeviceInt(devname, "repeat_delay", "input:repeat_delay");
|
||||
|
@ -884,7 +869,7 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
|||
// we can ignore those and just apply
|
||||
}
|
||||
|
||||
wlr_keyboard_set_repeat_info(wlr_keyboard_from_input_device(pKeyboard->keyboard), std::max(0, REPEATRATE), std::max(0, REPEATDELAY));
|
||||
wlr_keyboard_set_repeat_info(pKeyboard->wlr(), std::max(0, REPEATRATE), std::max(0, REPEATDELAY));
|
||||
|
||||
pKeyboard->repeatDelay = REPEATDELAY;
|
||||
pKeyboard->repeatRate = REPEATRATE;
|
||||
|
@ -942,7 +927,7 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
|||
KEYMAP = xkb_keymap_new_from_names(CONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
}
|
||||
|
||||
wlr_keyboard_set_keymap(wlr_keyboard_from_input_device(pKeyboard->keyboard), KEYMAP);
|
||||
wlr_keyboard_set_keymap(pKeyboard->wlr(), KEYMAP);
|
||||
|
||||
pKeyboard->updateXKBTranslationState();
|
||||
|
||||
|
@ -957,105 +942,87 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
|||
}
|
||||
|
||||
if (wlrMods.locked != 0)
|
||||
wlr_keyboard_notify_modifiers(wlr_keyboard_from_input_device(pKeyboard->keyboard), 0, 0, wlrMods.locked, 0);
|
||||
wlr_keyboard_notify_modifiers(pKeyboard->wlr(), 0, 0, wlrMods.locked, 0);
|
||||
|
||||
xkb_keymap_unref(KEYMAP);
|
||||
xkb_context_unref(CONTEXT);
|
||||
|
||||
const auto LAYOUTSTR = getActiveLayoutForKeyboard(pKeyboard);
|
||||
const auto LAYOUTSTR = pKeyboard->getActiveLayout();
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", pKeyboard->name + "," + LAYOUTSTR});
|
||||
EMIT_HOOK_EVENT("activeLayout", (std::vector<void*>{pKeyboard, (void*)&LAYOUTSTR}));
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", pKeyboard->hlName + "," + LAYOUTSTR});
|
||||
EMIT_HOOK_EVENT("activeLayout", (std::vector<std::any>{pKeyboard, LAYOUTSTR}));
|
||||
|
||||
Debug::log(LOG, "Set the keyboard layout to {} and variant to {} for keyboard \"{}\"", pKeyboard->currentRules.layout, pKeyboard->currentRules.variant,
|
||||
pKeyboard->keyboard->name);
|
||||
Debug::log(LOG, "Set the keyboard layout to {} and variant to {} for keyboard \"{}\"", pKeyboard->currentRules.layout, pKeyboard->currentRules.variant, pKeyboard->hlName);
|
||||
}
|
||||
|
||||
void CInputManager::newVirtualMouse(SP<CVirtualPointer> mouse) {
|
||||
const auto PMOUSE = &m_lMice.emplace_back();
|
||||
void CInputManager::newVirtualMouse(SP<CVirtualPointerV1Resource> mouse) {
|
||||
const auto PMOUSE = m_vPointers.emplace_back(CVirtualPointer::create(mouse));
|
||||
|
||||
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();
|
||||
setupMouse(PMOUSE);
|
||||
|
||||
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();
|
||||
const auto PMOUSE = m_vPointers.emplace_back(CMouse::create(wlr_pointer_from_input_device(mouse)));
|
||||
|
||||
PMOUSE->mouse = mouse;
|
||||
setupMouse(PMOUSE);
|
||||
|
||||
Debug::log(LOG, "New mouse created, pointer WLR: {:x}", (uintptr_t)mouse);
|
||||
}
|
||||
|
||||
void CInputManager::setupMouse(SP<IPointer> mauz) {
|
||||
try {
|
||||
PMOUSE->name = getNameForNewDevice(mouse->name);
|
||||
mauz->hlName = getNameForNewDevice(mauz->wlr()->base.name);
|
||||
} catch (std::exception& e) {
|
||||
Debug::log(ERR, "Mouse had no name???"); // logic error
|
||||
}
|
||||
|
||||
if (wlr_input_device_is_libinput(mouse)) {
|
||||
const auto LIBINPUTDEV = (libinput_device*)wlr_libinput_get_device_handle(mouse);
|
||||
if (wlr_input_device_is_libinput(&mauz->wlr()->base)) {
|
||||
const auto LIBINPUTDEV = (libinput_device*)wlr_libinput_get_device_handle(&mauz->wlr()->base);
|
||||
|
||||
Debug::log(LOG, "New mouse has libinput sens {:.2f} ({:.2f}) with accel profile {} ({})", libinput_device_config_accel_get_speed(LIBINPUTDEV),
|
||||
libinput_device_config_accel_get_default_speed(LIBINPUTDEV), (int)libinput_device_config_accel_get_profile(LIBINPUTDEV),
|
||||
(int)libinput_device_config_accel_get_default_profile(LIBINPUTDEV));
|
||||
}
|
||||
|
||||
wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, mouse);
|
||||
wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, &mauz->wlr()->base);
|
||||
|
||||
PMOUSE->connected = true;
|
||||
mauz->connected = true;
|
||||
|
||||
setPointerConfigs();
|
||||
|
||||
PMOUSE->hyprListener_destroyMouse.initCallback(&mouse->events.destroy, &Events::listener_destroyMouse, PMOUSE, "Mouse");
|
||||
mauz->events.destroy.registerStaticListener(
|
||||
[this](void* mouse, std::any data) {
|
||||
const auto PMOUSE = (IPointer*)mouse;
|
||||
destroyPointer(PMOUSE->self.lock());
|
||||
},
|
||||
mauz.get());
|
||||
|
||||
g_pCompositor->m_sSeat.mouse = PMOUSE;
|
||||
g_pCompositor->m_sSeat.mouse = mauz;
|
||||
|
||||
m_tmrLastCursorMovement.reset();
|
||||
|
||||
Debug::log(LOG, "New mouse created, pointer WLR: {:x}", (uintptr_t)mouse);
|
||||
}
|
||||
|
||||
void CInputManager::setPointerConfigs() {
|
||||
for (auto& m : m_lMice) {
|
||||
const auto PPOINTER = &m;
|
||||
|
||||
auto devname = PPOINTER->name;
|
||||
for (auto& m : m_vPointers) {
|
||||
auto devname = m->hlName;
|
||||
|
||||
const auto HASCONFIG = g_pConfigManager->deviceConfigExists(devname);
|
||||
|
||||
if (HASCONFIG) {
|
||||
const auto ENABLED = g_pConfigManager->getDeviceInt(devname, "enabled");
|
||||
if (ENABLED && !m.connected) {
|
||||
wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, m.mouse);
|
||||
m.connected = true;
|
||||
} else if (!ENABLED && m.connected) {
|
||||
wlr_cursor_detach_input_device(g_pCompositor->m_sWLRCursor, m.mouse);
|
||||
m.connected = false;
|
||||
if (ENABLED && !m->connected) {
|
||||
wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, &m->wlr()->base);
|
||||
m->connected = true;
|
||||
} else if (!ENABLED && m->connected) {
|
||||
wlr_cursor_detach_input_device(g_pCompositor->m_sWLRCursor, &m->wlr()->base);
|
||||
m->connected = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (wlr_input_device_is_libinput(m.mouse)) {
|
||||
const auto LIBINPUTDEV = (libinput_device*)wlr_libinput_get_device_handle(m.mouse);
|
||||
if (wlr_input_device_is_libinput(&m->wlr()->base)) {
|
||||
const auto LIBINPUTDEV = (libinput_device*)wlr_libinput_get_device_handle(&m->wlr()->base);
|
||||
|
||||
double touchw = 0, touchh = 0;
|
||||
const auto ISTOUCHPAD = libinput_device_has_capability(LIBINPUTDEV, LIBINPUT_DEVICE_CAP_POINTER) &&
|
||||
|
@ -1184,73 +1151,50 @@ void CInputManager::setPointerConfigs() {
|
|||
libinput_device_config_scroll_set_button_lock(LIBINPUTDEV,
|
||||
SCROLLBUTTONLOCK == 0 ? LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_DISABLED : LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_ENABLED);
|
||||
|
||||
Debug::log(LOG, "Applied config to mouse {}, sens {:.2f}", m.name, LIBINPUTSENS);
|
||||
Debug::log(LOG, "Applied config to mouse {}, sens {:.2f}", m->hlName, LIBINPUTSENS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CInputManager::destroyKeyboard(SKeyboard* pKeyboard) {
|
||||
pKeyboard->hyprListener_keyboardDestroy.removeCallback();
|
||||
pKeyboard->hyprListener_keyboardMod.removeCallback();
|
||||
pKeyboard->hyprListener_keyboardKey.removeCallback();
|
||||
|
||||
xkb_state_unref(pKeyboard->xkbTranslationState);
|
||||
void CInputManager::destroyKeyboard(SP<IKeyboard> pKeyboard) {
|
||||
if (pKeyboard->xkbTranslationState)
|
||||
xkb_state_unref(pKeyboard->xkbTranslationState);
|
||||
pKeyboard->xkbTranslationState = nullptr;
|
||||
|
||||
m_lKeyboards.remove(*pKeyboard);
|
||||
std::erase_if(m_vKeyboards, [pKeyboard](const auto& other) { return other == pKeyboard; });
|
||||
|
||||
if (m_lKeyboards.size() > 0) {
|
||||
m_pActiveKeyboard = &m_lKeyboards.back();
|
||||
m_pActiveKeyboard->active = true;
|
||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, wlr_keyboard_from_input_device(m_pActiveKeyboard->keyboard));
|
||||
if (m_vKeyboards.size() > 0) {
|
||||
g_pCompositor->m_sSeat.keyboard = m_vKeyboards.back();
|
||||
g_pCompositor->m_sSeat.keyboard.lock()->active = true;
|
||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, g_pCompositor->m_sSeat.keyboard.lock()->wlr());
|
||||
} else {
|
||||
m_pActiveKeyboard = nullptr;
|
||||
g_pCompositor->m_sSeat.keyboard.reset();
|
||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void CInputManager::destroyMouse(wlr_input_device* mouse) {
|
||||
for (auto& m : m_lMice) {
|
||||
if (m.mouse == mouse) {
|
||||
m_lMice.remove(m);
|
||||
break;
|
||||
}
|
||||
}
|
||||
void CInputManager::destroyPointer(SP<IPointer> mouse) {
|
||||
std::erase_if(m_vPointers, [mouse](const auto& other) { return other == mouse; });
|
||||
|
||||
g_pCompositor->m_sSeat.mouse = m_lMice.size() > 0 ? &m_lMice.front() : nullptr;
|
||||
g_pCompositor->m_sSeat.mouse = m_vPointers.size() > 0 ? m_vPointers.front() : nullptr;
|
||||
|
||||
if (g_pCompositor->m_sSeat.mouse)
|
||||
if (!g_pCompositor->m_sSeat.mouse.expired())
|
||||
unconstrainMouse();
|
||||
}
|
||||
|
||||
void CInputManager::updateKeyboardsLeds(wlr_input_device* pKeyboard) {
|
||||
auto keyboard = wlr_keyboard_from_input_device(pKeyboard);
|
||||
void CInputManager::destroyTouchDevice(SP<ITouch> touch) {
|
||||
Debug::log(LOG, "Touch device at {:x} removed", (uintptr_t)touch.get());
|
||||
|
||||
if (keyboard->xkb_state == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t leds = 0;
|
||||
for (uint32_t i = 0; i < WLR_LED_COUNT; ++i) {
|
||||
if (xkb_state_led_index_is_active(keyboard->xkb_state, keyboard->led_indexes[i]))
|
||||
leds |= (1 << i);
|
||||
}
|
||||
|
||||
for (auto& kb : m_lKeyboards) {
|
||||
if ((kb.isVirtual && shouldIgnoreVirtualKeyboard(&kb)) || kb.keyboard == pKeyboard)
|
||||
continue;
|
||||
|
||||
wlr_keyboard_led_update(wlr_keyboard_from_input_device(kb.keyboard), leds);
|
||||
}
|
||||
std::erase_if(m_vTouches, [touch](const auto& other) { return other == touch; });
|
||||
}
|
||||
|
||||
void CInputManager::onKeyboardKey(wlr_keyboard_key_event* e, SKeyboard* pKeyboard) {
|
||||
void CInputManager::onKeyboardKey(std::any event, SP<IKeyboard> pKeyboard) {
|
||||
if (!pKeyboard->enabled)
|
||||
return;
|
||||
|
||||
const bool DISALLOWACTION = pKeyboard->isVirtual && shouldIgnoreVirtualKeyboard(pKeyboard);
|
||||
const bool DISALLOWACTION = pKeyboard->isVirtual() && shouldIgnoreVirtualKeyboard(pKeyboard);
|
||||
|
||||
const auto EMAP = std::unordered_map<std::string, std::any>{{"keyboard", pKeyboard}, {"event", e}};
|
||||
const auto EMAP = std::unordered_map<std::string, std::any>{{"keyboard", pKeyboard}, {"event", event}};
|
||||
EMIT_HOOK_EVENT_CANCELLABLE("keyPress", EMAP);
|
||||
|
||||
static auto PDPMS = CConfigValue<Hyprlang::INT>("misc:key_press_enables_dpms");
|
||||
|
@ -1259,7 +1203,9 @@ void CInputManager::onKeyboardKey(wlr_keyboard_key_event* e, SKeyboard* pKeyboar
|
|||
g_pKeybindManager->dpms("on");
|
||||
}
|
||||
|
||||
bool passEvent = DISALLOWACTION || g_pKeybindManager->onKeyEvent(e, pKeyboard);
|
||||
bool passEvent = DISALLOWACTION || g_pKeybindManager->onKeyEvent(event, pKeyboard);
|
||||
|
||||
auto e = std::any_cast<IKeyboard::SKeyEvent>(event);
|
||||
|
||||
PROTO::idle->onActivity();
|
||||
|
||||
|
@ -1267,59 +1213,64 @@ void CInputManager::onKeyboardKey(wlr_keyboard_key_event* e, SKeyboard* pKeyboar
|
|||
const auto IME = m_sIMERelay.m_pIME.lock();
|
||||
|
||||
if (IME && IME->hasGrab() && !DISALLOWACTION) {
|
||||
IME->setKeyboard(wlr_keyboard_from_input_device(pKeyboard->keyboard));
|
||||
IME->sendKey(e->time_msec, e->keycode, e->state);
|
||||
IME->setKeyboard(pKeyboard->wlr());
|
||||
IME->sendKey(e.timeMs, e.keycode, e.state);
|
||||
} else {
|
||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, wlr_keyboard_from_input_device(pKeyboard->keyboard));
|
||||
wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, e->time_msec, e->keycode, e->state);
|
||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, pKeyboard->wlr());
|
||||
wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, e.timeMs, e.keycode, e.state);
|
||||
}
|
||||
|
||||
updateKeyboardsLeds(pKeyboard->keyboard);
|
||||
for (auto& k : m_vKeyboards) {
|
||||
k->updateLEDs();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CInputManager::onKeyboardMod(void* data, SKeyboard* pKeyboard) {
|
||||
void CInputManager::onKeyboardMod(SP<IKeyboard> pKeyboard) {
|
||||
if (!pKeyboard->enabled)
|
||||
return;
|
||||
|
||||
const bool DISALLOWACTION = pKeyboard->isVirtual && shouldIgnoreVirtualKeyboard(pKeyboard);
|
||||
const bool DISALLOWACTION = pKeyboard->isVirtual() && shouldIgnoreVirtualKeyboard(pKeyboard);
|
||||
|
||||
const auto ALLMODS = accumulateModsFromAllKBs();
|
||||
const auto PWLRKB = pKeyboard->wlr();
|
||||
|
||||
auto MODS = wlr_keyboard_from_input_device(pKeyboard->keyboard)->modifiers;
|
||||
auto MODS = PWLRKB->modifiers;
|
||||
MODS.depressed = ALLMODS;
|
||||
|
||||
const auto IME = m_sIMERelay.m_pIME.lock();
|
||||
|
||||
if (IME && IME->hasGrab() && !DISALLOWACTION) {
|
||||
IME->setKeyboard(wlr_keyboard_from_input_device(pKeyboard->keyboard));
|
||||
IME->setKeyboard(PWLRKB);
|
||||
IME->sendMods(MODS.depressed, MODS.latched, MODS.locked, MODS.group);
|
||||
} else {
|
||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, wlr_keyboard_from_input_device(pKeyboard->keyboard));
|
||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, PWLRKB);
|
||||
wlr_seat_keyboard_notify_modifiers(g_pCompositor->m_sSeat.seat, &MODS);
|
||||
}
|
||||
|
||||
updateKeyboardsLeds(pKeyboard->keyboard);
|
||||
|
||||
const auto PWLRKB = wlr_keyboard_from_input_device(pKeyboard->keyboard);
|
||||
for (auto& k : m_vKeyboards) {
|
||||
k->updateLEDs();
|
||||
}
|
||||
|
||||
if (PWLRKB->modifiers.group != pKeyboard->activeLayout) {
|
||||
pKeyboard->activeLayout = PWLRKB->modifiers.group;
|
||||
|
||||
const auto LAYOUT = getActiveLayoutForKeyboard(pKeyboard);
|
||||
const auto LAYOUT = pKeyboard->getActiveLayout();
|
||||
|
||||
pKeyboard->updateXKBTranslationState();
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", pKeyboard->name + "," + LAYOUT});
|
||||
EMIT_HOOK_EVENT("activeLayout", (std::vector<void*>{pKeyboard, (void*)&LAYOUT}));
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", pKeyboard->hlName + "," + LAYOUT});
|
||||
EMIT_HOOK_EVENT("activeLayout", (std::vector<std::any>{pKeyboard, LAYOUT}));
|
||||
}
|
||||
}
|
||||
|
||||
bool CInputManager::shouldIgnoreVirtualKeyboard(SKeyboard* pKeyboard) {
|
||||
if (!pKeyboard->isVirtual)
|
||||
bool CInputManager::shouldIgnoreVirtualKeyboard(SP<IKeyboard> pKeyboard) {
|
||||
if (!pKeyboard->isVirtual())
|
||||
return false;
|
||||
|
||||
return !pKeyboard || (!m_sIMERelay.m_pIME.expired() && m_sIMERelay.m_pIME.lock()->grabClient() == pKeyboard->virtKeyboard.lock()->client());
|
||||
CVirtualKeyboard* vk = (CVirtualKeyboard*)pKeyboard.get();
|
||||
|
||||
return !pKeyboard || (!m_sIMERelay.m_pIME.expired() && m_sIMERelay.m_pIME.lock()->grabClient() == vk->getClient());
|
||||
}
|
||||
|
||||
void CInputManager::refocus() {
|
||||
|
@ -1343,7 +1294,7 @@ void CInputManager::updateDragIcon() {
|
|||
}
|
||||
|
||||
void CInputManager::unconstrainMouse() {
|
||||
if (!g_pCompositor->m_sSeat.mouse)
|
||||
if (g_pCompositor->m_sSeat.mouse.expired())
|
||||
return;
|
||||
|
||||
for (auto& c : m_vConstraints) {
|
||||
|
@ -1378,11 +1329,11 @@ bool CInputManager::isConstrained() {
|
|||
void CInputManager::updateCapabilities() {
|
||||
uint32_t caps = 0;
|
||||
|
||||
if (!m_lKeyboards.empty())
|
||||
if (!m_vKeyboards.empty())
|
||||
caps |= WL_SEAT_CAPABILITY_KEYBOARD;
|
||||
if (!m_lMice.empty())
|
||||
if (!m_vPointers.empty())
|
||||
caps |= WL_SEAT_CAPABILITY_POINTER;
|
||||
if (!m_lTouchDevices.empty())
|
||||
if (!m_vTouches.empty())
|
||||
caps |= WL_SEAT_CAPABILITY_TOUCH;
|
||||
if (!m_lTabletTools.empty())
|
||||
caps |= WL_SEAT_CAPABILITY_POINTER;
|
||||
|
@ -1395,54 +1346,34 @@ uint32_t CInputManager::accumulateModsFromAllKBs() {
|
|||
|
||||
uint32_t finalMask = 0;
|
||||
|
||||
for (auto& kb : m_lKeyboards) {
|
||||
if (kb.isVirtual && shouldIgnoreVirtualKeyboard(&kb))
|
||||
for (auto& kb : m_vKeyboards) {
|
||||
if (kb->isVirtual() && shouldIgnoreVirtualKeyboard(kb))
|
||||
continue;
|
||||
|
||||
if (!kb.enabled)
|
||||
if (!kb->enabled)
|
||||
continue;
|
||||
|
||||
finalMask |= wlr_keyboard_get_modifiers(wlr_keyboard_from_input_device(kb.keyboard));
|
||||
finalMask |= wlr_keyboard_get_modifiers(kb->wlr());
|
||||
}
|
||||
|
||||
return finalMask;
|
||||
}
|
||||
|
||||
std::string CInputManager::getActiveLayoutForKeyboard(SKeyboard* pKeyboard) {
|
||||
const auto WLRKB = wlr_keyboard_from_input_device(pKeyboard->keyboard);
|
||||
const auto KEYMAP = WLRKB->keymap;
|
||||
const auto STATE = WLRKB->xkb_state;
|
||||
const auto LAYOUTSNUM = xkb_keymap_num_layouts(KEYMAP);
|
||||
|
||||
for (uint32_t i = 0; i < LAYOUTSNUM; ++i) {
|
||||
if (xkb_state_layout_index_is_active(STATE, i, XKB_STATE_LAYOUT_EFFECTIVE)) {
|
||||
const auto LAYOUTNAME = xkb_keymap_layout_get_name(KEYMAP, i);
|
||||
|
||||
if (LAYOUTNAME)
|
||||
return std::string(LAYOUTNAME);
|
||||
return "error";
|
||||
}
|
||||
}
|
||||
|
||||
return "none";
|
||||
}
|
||||
|
||||
void CInputManager::disableAllKeyboards(bool virt) {
|
||||
|
||||
for (auto& k : m_lKeyboards) {
|
||||
if (k.isVirtual != virt)
|
||||
for (auto& k : m_vKeyboards) {
|
||||
if (k->isVirtual() != virt)
|
||||
continue;
|
||||
|
||||
k.active = false;
|
||||
k->active = false;
|
||||
}
|
||||
}
|
||||
|
||||
void CInputManager::newTouchDevice(wlr_input_device* pDevice) {
|
||||
const auto PNEWDEV = &m_lTouchDevices.emplace_back();
|
||||
PNEWDEV->pWlrDevice = pDevice;
|
||||
const auto PNEWDEV = m_vTouches.emplace_back(CTouchDevice::create(wlr_touch_from_input_device(pDevice)));
|
||||
|
||||
try {
|
||||
PNEWDEV->name = getNameForNewDevice(pDevice->name);
|
||||
PNEWDEV->hlName = getNameForNewDevice(pDevice->name);
|
||||
} catch (std::exception& e) {
|
||||
Debug::log(ERR, "Touch Device had no name???"); // logic error
|
||||
}
|
||||
|
@ -1450,32 +1381,36 @@ void CInputManager::newTouchDevice(wlr_input_device* pDevice) {
|
|||
setTouchDeviceConfigs(PNEWDEV);
|
||||
wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, pDevice);
|
||||
|
||||
Debug::log(LOG, "New touch device added at {:x}", (uintptr_t)PNEWDEV);
|
||||
PNEWDEV->events.destroy.registerStaticListener(
|
||||
[this](void* owner, std::any data) {
|
||||
auto PDEV = ((ITouch*)owner)->self.lock();
|
||||
destroyTouchDevice(PDEV);
|
||||
},
|
||||
PNEWDEV.get());
|
||||
|
||||
PNEWDEV->hyprListener_destroy.initCallback(
|
||||
&pDevice->events.destroy, [&](void* owner, void* data) { destroyTouchDevice((STouchDevice*)data); }, PNEWDEV, "TouchDevice");
|
||||
Debug::log(LOG, "New touch device added at {:x}", (uintptr_t)PNEWDEV.get());
|
||||
}
|
||||
|
||||
void CInputManager::setTouchDeviceConfigs(STouchDevice* dev) {
|
||||
auto setConfig = [&](STouchDevice* const PTOUCHDEV) -> void {
|
||||
if (wlr_input_device_is_libinput(PTOUCHDEV->pWlrDevice)) {
|
||||
const auto LIBINPUTDEV = (libinput_device*)wlr_libinput_get_device_handle(PTOUCHDEV->pWlrDevice);
|
||||
void CInputManager::setTouchDeviceConfigs(SP<ITouch> dev) {
|
||||
auto setConfig = [&](SP<ITouch> PTOUCHDEV) -> void {
|
||||
if (wlr_input_device_is_libinput(&PTOUCHDEV->wlr()->base)) {
|
||||
const auto LIBINPUTDEV = (libinput_device*)wlr_libinput_get_device_handle(&PTOUCHDEV->wlr()->base);
|
||||
|
||||
const auto ENABLED = g_pConfigManager->getDeviceInt(PTOUCHDEV->name, "enabled", "input:touchdevice:enabled");
|
||||
const auto ENABLED = g_pConfigManager->getDeviceInt(PTOUCHDEV->hlName, "enabled", "input:touchdevice:enabled");
|
||||
const auto mode = ENABLED ? LIBINPUT_CONFIG_SEND_EVENTS_ENABLED : LIBINPUT_CONFIG_SEND_EVENTS_DISABLED;
|
||||
if (libinput_device_config_send_events_get_mode(LIBINPUTDEV) != mode)
|
||||
libinput_device_config_send_events_set_mode(LIBINPUTDEV, mode);
|
||||
|
||||
const int ROTATION = std::clamp(g_pConfigManager->getDeviceInt(PTOUCHDEV->name, "transform", "input:touchdevice:transform"), 0, 7);
|
||||
Debug::log(LOG, "Setting calibration matrix for device {}", PTOUCHDEV->name);
|
||||
const int ROTATION = std::clamp(g_pConfigManager->getDeviceInt(PTOUCHDEV->hlName, "transform", "input:touchdevice:transform"), 0, 7);
|
||||
Debug::log(LOG, "Setting calibration matrix for device {}", PTOUCHDEV->hlName);
|
||||
if (libinput_device_config_calibration_has_matrix(LIBINPUTDEV))
|
||||
libinput_device_config_calibration_set_matrix(LIBINPUTDEV, MATRICES[ROTATION]);
|
||||
|
||||
auto output = g_pConfigManager->getDeviceString(PTOUCHDEV->name, "output", "input:touchdevice:output");
|
||||
auto output = g_pConfigManager->getDeviceString(PTOUCHDEV->hlName, "output", "input:touchdevice:output");
|
||||
bool bound = !output.empty() && output != STRVAL_EMPTY;
|
||||
const bool AUTODETECT = output == "[[Auto]]";
|
||||
if (!bound && AUTODETECT) {
|
||||
const auto DEFAULTOUTPUT = wlr_touch_from_input_device(PTOUCHDEV->pWlrDevice)->output_name;
|
||||
const auto DEFAULTOUTPUT = PTOUCHDEV->wlr()->output_name;
|
||||
if (DEFAULTOUTPUT) {
|
||||
output = DEFAULTOUTPUT;
|
||||
bound = true;
|
||||
|
@ -1484,10 +1419,10 @@ void CInputManager::setTouchDeviceConfigs(STouchDevice* dev) {
|
|||
PTOUCHDEV->boundOutput = bound ? output : "";
|
||||
const auto PMONITOR = bound ? g_pCompositor->getMonitorFromName(output) : nullptr;
|
||||
if (PMONITOR) {
|
||||
Debug::log(LOG, "Binding touch device {} to output {}", PTOUCHDEV->name, PMONITOR->szName);
|
||||
wlr_cursor_map_input_to_output(g_pCompositor->m_sWLRCursor, PTOUCHDEV->pWlrDevice, PMONITOR->output);
|
||||
Debug::log(LOG, "Binding touch device {} to output {}", PTOUCHDEV->hlName, PMONITOR->szName);
|
||||
wlr_cursor_map_input_to_output(g_pCompositor->m_sWLRCursor, &PTOUCHDEV->wlr()->base, PMONITOR->output);
|
||||
} else if (bound)
|
||||
Debug::log(ERR, "Failed to bind touch device {} to output '{}': monitor not found", PTOUCHDEV->name, output);
|
||||
Debug::log(ERR, "Failed to bind touch device {} to output '{}': monitor not found", PTOUCHDEV->hlName, output);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1496,10 +1431,8 @@ void CInputManager::setTouchDeviceConfigs(STouchDevice* dev) {
|
|||
return;
|
||||
}
|
||||
|
||||
for (auto& m : m_lTouchDevices) {
|
||||
const auto PTOUCHDEV = &m;
|
||||
|
||||
setConfig(PTOUCHDEV);
|
||||
for (auto& m : m_vTouches) {
|
||||
setConfig(m);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1546,12 +1479,6 @@ void CInputManager::setTabletConfigs() {
|
|||
}
|
||||
}
|
||||
|
||||
void CInputManager::destroyTouchDevice(STouchDevice* pDevice) {
|
||||
Debug::log(LOG, "Touch device at {:x} removed", (uintptr_t)pDevice);
|
||||
|
||||
m_lTouchDevices.remove(*pDevice);
|
||||
}
|
||||
|
||||
void CInputManager::newSwitch(wlr_input_device* pDevice) {
|
||||
const auto PNEWDEV = &m_lSwitches.emplace_back();
|
||||
PNEWDEV->pWlrDevice = pDevice;
|
||||
|
@ -1623,16 +1550,16 @@ std::string CInputManager::getNameForNewDevice(std::string internalName) {
|
|||
auto proposedNewName = deviceNameToInternalString(internalName);
|
||||
int dupeno = 0;
|
||||
|
||||
while (std::find_if(m_lKeyboards.begin(), m_lKeyboards.end(),
|
||||
[&](const SKeyboard& other) { return other.name == proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); }) != m_lKeyboards.end())
|
||||
while (std::find_if(m_vKeyboards.begin(), m_vKeyboards.end(),
|
||||
[&](const auto& other) { return other->hlName == proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); }) != m_vKeyboards.end())
|
||||
dupeno++;
|
||||
|
||||
while (std::find_if(m_lMice.begin(), m_lMice.end(), [&](const SMouse& other) { return other.name == proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); }) !=
|
||||
m_lMice.end())
|
||||
while (std::find_if(m_vPointers.begin(), m_vPointers.end(),
|
||||
[&](const auto& other) { return other->hlName == proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); }) != m_vPointers.end())
|
||||
dupeno++;
|
||||
|
||||
while (std::find_if(m_lTouchDevices.begin(), m_lTouchDevices.end(),
|
||||
[&](const STouchDevice& other) { return other.name == proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); }) != m_lTouchDevices.end())
|
||||
while (std::find_if(m_vTouches.begin(), m_vTouches.end(),
|
||||
[&](const auto& other) { return other->hlName == proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); }) != m_vTouches.end())
|
||||
dupeno++;
|
||||
|
||||
while (std::find_if(m_lTabletPads.begin(), m_lTabletPads.end(),
|
||||
|
|
|
@ -11,8 +11,11 @@
|
|||
class CPointerConstraint;
|
||||
class CWindow;
|
||||
class CIdleInhibitor;
|
||||
class CVirtualKeyboard;
|
||||
class CVirtualPointer;
|
||||
class CVirtualKeyboardV1Resource;
|
||||
class CVirtualPointerV1Resource;
|
||||
class IPointer;
|
||||
class IKeyboard;
|
||||
class ITouch;
|
||||
|
||||
enum eClickBehaviorMode {
|
||||
CLICKMODE_DEFAULT = 0,
|
||||
|
@ -75,23 +78,22 @@ class CInputManager {
|
|||
void onMouseWarp(wlr_pointer_motion_absolute_event*);
|
||||
void onMouseButton(wlr_pointer_button_event*);
|
||||
void onMouseWheel(wlr_pointer_axis_event*);
|
||||
void onKeyboardKey(wlr_keyboard_key_event*, SKeyboard*);
|
||||
void onKeyboardMod(void*, SKeyboard*);
|
||||
void onKeyboardKey(std::any, SP<IKeyboard>);
|
||||
void onKeyboardMod(SP<IKeyboard>);
|
||||
|
||||
void newKeyboard(wlr_input_device*);
|
||||
void newVirtualKeyboard(SP<CVirtualKeyboard>);
|
||||
void newVirtualKeyboard(SP<CVirtualKeyboardV1Resource>);
|
||||
void newMouse(wlr_input_device*);
|
||||
void newVirtualMouse(SP<CVirtualPointer>);
|
||||
void newVirtualMouse(SP<CVirtualPointerV1Resource>);
|
||||
void newTouchDevice(wlr_input_device*);
|
||||
void newSwitch(wlr_input_device*);
|
||||
void destroyTouchDevice(STouchDevice*);
|
||||
void destroyKeyboard(SKeyboard*);
|
||||
void destroyMouse(wlr_input_device*);
|
||||
void destroyTouchDevice(SP<ITouch>);
|
||||
void destroyKeyboard(SP<IKeyboard>);
|
||||
void destroyPointer(SP<IPointer>);
|
||||
void destroySwitch(SSwitchDevice*);
|
||||
|
||||
void unconstrainMouse();
|
||||
bool isConstrained();
|
||||
std::string getActiveLayoutForKeyboard(SKeyboard*);
|
||||
|
||||
Vector2D getMouseCoordsInternal();
|
||||
void refocus();
|
||||
|
@ -100,7 +102,7 @@ class CInputManager {
|
|||
|
||||
void setKeyboardLayout();
|
||||
void setPointerConfigs();
|
||||
void setTouchDeviceConfigs(STouchDevice* dev = nullptr);
|
||||
void setTouchDeviceConfigs(SP<ITouch> dev = nullptr);
|
||||
void setTabletConfigs();
|
||||
|
||||
void updateDragIcon();
|
||||
|
@ -122,21 +124,19 @@ class CInputManager {
|
|||
bool m_bWasDraggingWindow = false;
|
||||
|
||||
// for refocus to be forced
|
||||
PHLWINDOWREF m_pForcedFocus;
|
||||
PHLWINDOWREF m_pForcedFocus;
|
||||
|
||||
SDrag m_sDrag;
|
||||
SDrag m_sDrag;
|
||||
|
||||
std::list<SKeyboard> m_lKeyboards;
|
||||
std::list<SMouse> m_lMice;
|
||||
std::vector<SP<IKeyboard>> m_vKeyboards;
|
||||
std::vector<SP<IPointer>> m_vPointers;
|
||||
std::vector<SP<ITouch>> m_vTouches;
|
||||
|
||||
// tablets
|
||||
std::list<STablet> m_lTablets;
|
||||
std::list<STabletTool> m_lTabletTools;
|
||||
std::list<STabletPad> m_lTabletPads;
|
||||
|
||||
// Touch devices
|
||||
std::list<STouchDevice> m_lTouchDevices;
|
||||
|
||||
// Switches
|
||||
std::list<SSwitchDevice> m_lSwitches;
|
||||
|
||||
|
@ -159,19 +159,15 @@ class CInputManager {
|
|||
|
||||
SSwipeGesture m_sActiveSwipe;
|
||||
|
||||
SKeyboard* m_pActiveKeyboard = nullptr;
|
||||
|
||||
CTimer m_tmrLastCursorMovement;
|
||||
|
||||
CInputMethodRelay m_sIMERelay;
|
||||
|
||||
void updateKeyboardsLeds(wlr_input_device* pKeyboard);
|
||||
|
||||
// for shared mods
|
||||
uint32_t accumulateModsFromAllKBs();
|
||||
|
||||
// for virtual keyboards: whether we should respect them as normal ones
|
||||
bool shouldIgnoreVirtualKeyboard(SKeyboard*);
|
||||
bool shouldIgnoreVirtualKeyboard(SP<IKeyboard>);
|
||||
|
||||
// for special cursors that we choose
|
||||
void setCursorImageUntilUnset(std::string);
|
||||
|
@ -213,6 +209,9 @@ class CInputManager {
|
|||
eClickBehaviorMode m_ecbClickBehavior = CLICKMODE_DEFAULT;
|
||||
Vector2D m_vLastCursorPosFloored = Vector2D();
|
||||
|
||||
void setupKeyboard(SP<IKeyboard> keeb);
|
||||
void setupMouse(SP<IPointer> mauz);
|
||||
|
||||
void processMouseDownNormal(wlr_pointer_button_event* e);
|
||||
void processMouseDownKill(wlr_pointer_button_event* e);
|
||||
|
||||
|
@ -226,7 +225,7 @@ class CInputManager {
|
|||
|
||||
STabletTool* ensureTabletToolPresent(wlr_tablet_tool*);
|
||||
|
||||
void applyConfigToKeyboard(SKeyboard*);
|
||||
void applyConfigToKeyboard(SP<IKeyboard>);
|
||||
|
||||
// this will be set after a refocus()
|
||||
wlr_surface* m_pFoundSurfaceToFocus = nullptr;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "../../Compositor.hpp"
|
||||
#include "../../config/ConfigValue.hpp"
|
||||
#include "../../protocols/IdleNotify.hpp"
|
||||
#include "../../devices/ITouch.hpp"
|
||||
|
||||
void CInputManager::onTouchDown(wlr_touch_down_event* e) {
|
||||
static auto PSWIPETOUCH = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_touch");
|
||||
|
@ -15,10 +16,10 @@ void CInputManager::onTouchDown(wlr_touch_down_event* e) {
|
|||
|
||||
auto PMONITOR = g_pCompositor->getMonitorFromName(e->touch->output_name ? e->touch->output_name : "");
|
||||
|
||||
const auto PDEVIT = std::find_if(m_lTouchDevices.begin(), m_lTouchDevices.end(), [&](const STouchDevice& other) { return other.pWlrDevice == &e->touch->base; });
|
||||
const auto PDEVIT = std::find_if(m_vTouches.begin(), m_vTouches.end(), [&](const auto& other) { return other->wlr() == e->touch; });
|
||||
|
||||
if (PDEVIT != m_lTouchDevices.end() && !PDEVIT->boundOutput.empty())
|
||||
PMONITOR = g_pCompositor->getMonitorFromName(PDEVIT->boundOutput);
|
||||
if (PDEVIT != m_vTouches.end() && !(*PDEVIT)->boundOutput.empty())
|
||||
PMONITOR = g_pCompositor->getMonitorFromName((*PDEVIT)->boundOutput);
|
||||
|
||||
PMONITOR = PMONITOR ? PMONITOR : g_pCompositor->m_pLastMonitor;
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ static const struct wlr_keyboard_impl virtualKeyboardImpl = {
|
|||
.name = "virtual-keyboard",
|
||||
};
|
||||
|
||||
CVirtualKeyboard::CVirtualKeyboard(SP<CZwpVirtualKeyboardV1> resource_) : resource(resource_) {
|
||||
CVirtualKeyboardV1Resource::CVirtualKeyboardV1Resource(SP<CZwpVirtualKeyboardV1> resource_) : resource(resource_) {
|
||||
if (!good())
|
||||
return;
|
||||
|
||||
|
@ -84,20 +84,20 @@ CVirtualKeyboard::CVirtualKeyboard(SP<CZwpVirtualKeyboardV1> resource_) : resour
|
|||
wlr_keyboard_init(&keyboard, &virtualKeyboardImpl, "CVirtualKeyboard");
|
||||
}
|
||||
|
||||
CVirtualKeyboard::~CVirtualKeyboard() {
|
||||
CVirtualKeyboardV1Resource::~CVirtualKeyboardV1Resource() {
|
||||
wlr_keyboard_finish(&keyboard);
|
||||
events.destroy.emit();
|
||||
}
|
||||
|
||||
bool CVirtualKeyboard::good() {
|
||||
bool CVirtualKeyboardV1Resource::good() {
|
||||
return resource->resource();
|
||||
}
|
||||
|
||||
wlr_keyboard* CVirtualKeyboard::wlr() {
|
||||
wlr_keyboard* CVirtualKeyboardV1Resource::wlr() {
|
||||
return &keyboard;
|
||||
}
|
||||
|
||||
wl_client* CVirtualKeyboard::client() {
|
||||
wl_client* CVirtualKeyboardV1Resource::client() {
|
||||
return resource->client();
|
||||
}
|
||||
|
||||
|
@ -116,13 +116,13 @@ void CVirtualKeyboardProtocol::onManagerResourceDestroy(wl_resource* res) {
|
|||
std::erase_if(m_vManagers, [&](const auto& other) { return other->resource() == res; });
|
||||
}
|
||||
|
||||
void CVirtualKeyboardProtocol::destroyResource(CVirtualKeyboard* keeb) {
|
||||
void CVirtualKeyboardProtocol::destroyResource(CVirtualKeyboardV1Resource* 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)));
|
||||
const auto RESOURCE = m_vKeyboards.emplace_back(std::make_shared<CVirtualKeyboardV1Resource>(std::make_shared<CZwpVirtualKeyboardV1>(pMgr->client(), pMgr->version(), id)));
|
||||
|
||||
if (!RESOURCE->good()) {
|
||||
pMgr->noMemory();
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
#include "virtual-keyboard-unstable-v1.hpp"
|
||||
#include "../helpers/signal/Signal.hpp"
|
||||
|
||||
class CVirtualKeyboard {
|
||||
class CVirtualKeyboardV1Resource {
|
||||
public:
|
||||
CVirtualKeyboard(SP<CZwpVirtualKeyboardV1> resource_);
|
||||
~CVirtualKeyboard();
|
||||
CVirtualKeyboardV1Resource(SP<CZwpVirtualKeyboardV1> resource_);
|
||||
~CVirtualKeyboardV1Resource();
|
||||
|
||||
struct {
|
||||
CSignal destroy;
|
||||
|
@ -39,14 +39,14 @@ class CVirtualKeyboardProtocol : public IWaylandProtocol {
|
|||
|
||||
private:
|
||||
void onManagerResourceDestroy(wl_resource* res);
|
||||
void destroyResource(CVirtualKeyboard* keeb);
|
||||
void destroyResource(CVirtualKeyboardV1Resource* keeb);
|
||||
void onCreateKeeb(CZwpVirtualKeyboardManagerV1* pMgr, wl_resource* seat, uint32_t id);
|
||||
|
||||
//
|
||||
std::vector<UP<CZwpVirtualKeyboardManagerV1>> m_vManagers;
|
||||
std::vector<SP<CVirtualKeyboard>> m_vKeyboards;
|
||||
std::vector<SP<CVirtualKeyboardV1Resource>> m_vKeyboards;
|
||||
|
||||
friend class CVirtualKeyboard;
|
||||
friend class CVirtualKeyboardV1Resource;
|
||||
};
|
||||
|
||||
namespace PROTO {
|
||||
|
|
|
@ -6,7 +6,7 @@ static const wlr_pointer_impl pointerImpl = {
|
|||
.name = "virtual-pointer-v1",
|
||||
};
|
||||
|
||||
CVirtualPointer::CVirtualPointer(SP<CZwlrVirtualPointerV1> resource_) : resource(resource_) {
|
||||
CVirtualPointerV1Resource::CVirtualPointerV1Resource(SP<CZwlrVirtualPointerV1> resource_) : resource(resource_) {
|
||||
if (!good())
|
||||
return;
|
||||
|
||||
|
@ -19,7 +19,7 @@ CVirtualPointer::CVirtualPointer(SP<CZwlrVirtualPointerV1> resource_) : resource
|
|||
PROTO::virtualPointer->destroyResource(this);
|
||||
});
|
||||
|
||||
wlr_pointer_init(&pointer, &pointerImpl, "CVirtualPointer");
|
||||
wlr_pointer_init(&pointer, &pointerImpl, "CVirtualPointerV1Resource");
|
||||
|
||||
resource->setMotion([this](CZwlrVirtualPointerV1* r, uint32_t timeMs, wl_fixed_t dx, wl_fixed_t dy) {
|
||||
wlr_pointer_motion_event event = {
|
||||
|
@ -108,20 +108,20 @@ CVirtualPointer::CVirtualPointer(SP<CZwlrVirtualPointerV1> resource_) : resource
|
|||
});
|
||||
}
|
||||
|
||||
CVirtualPointer::~CVirtualPointer() {
|
||||
CVirtualPointerV1Resource::~CVirtualPointerV1Resource() {
|
||||
wlr_pointer_finish(&pointer);
|
||||
events.destroy.emit();
|
||||
}
|
||||
|
||||
bool CVirtualPointer::good() {
|
||||
bool CVirtualPointerV1Resource::good() {
|
||||
return resource->resource();
|
||||
}
|
||||
|
||||
wlr_pointer* CVirtualPointer::wlr() {
|
||||
wlr_pointer* CVirtualPointerV1Resource::wlr() {
|
||||
return &pointer;
|
||||
}
|
||||
|
||||
wl_client* CVirtualPointer::client() {
|
||||
wl_client* CVirtualPointerV1Resource::client() {
|
||||
return resource->client();
|
||||
}
|
||||
|
||||
|
@ -145,13 +145,13 @@ void CVirtualPointerProtocol::onManagerResourceDestroy(wl_resource* res) {
|
|||
std::erase_if(m_vManagers, [&](const auto& other) { return other->resource() == res; });
|
||||
}
|
||||
|
||||
void CVirtualPointerProtocol::destroyResource(CVirtualPointer* pointer) {
|
||||
void CVirtualPointerProtocol::destroyResource(CVirtualPointerV1Resource* 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)));
|
||||
const auto RESOURCE = m_vPointers.emplace_back(std::make_shared<CVirtualPointerV1Resource>(std::make_shared<CZwlrVirtualPointerV1>(pMgr->client(), pMgr->version(), id)));
|
||||
|
||||
if (!RESOURCE->good()) {
|
||||
pMgr->noMemory();
|
||||
|
|
|
@ -8,10 +8,10 @@
|
|||
#include "wlr-virtual-pointer-unstable-v1.hpp"
|
||||
#include "../helpers/signal/Signal.hpp"
|
||||
|
||||
class CVirtualPointer {
|
||||
class CVirtualPointerV1Resource {
|
||||
public:
|
||||
CVirtualPointer(SP<CZwlrVirtualPointerV1> resource_);
|
||||
~CVirtualPointer();
|
||||
CVirtualPointerV1Resource(SP<CZwlrVirtualPointerV1> resource_);
|
||||
~CVirtualPointerV1Resource();
|
||||
|
||||
struct {
|
||||
CSignal destroy;
|
||||
|
@ -37,19 +37,19 @@ class CVirtualPointerProtocol : public IWaylandProtocol {
|
|||
virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);
|
||||
|
||||
struct {
|
||||
CSignal newPointer; // SP<CVirtualPointer>
|
||||
CSignal newPointer; // SP<CVirtualPointerV1Resource>
|
||||
} events;
|
||||
|
||||
private:
|
||||
void onManagerResourceDestroy(wl_resource* res);
|
||||
void destroyResource(CVirtualPointer* pointer);
|
||||
void destroyResource(CVirtualPointerV1Resource* pointer);
|
||||
void onCreatePointer(CZwlrVirtualPointerManagerV1* pMgr, wl_resource* seat, uint32_t id);
|
||||
|
||||
//
|
||||
std::vector<UP<CZwlrVirtualPointerManagerV1>> m_vManagers;
|
||||
std::vector<SP<CVirtualPointer>> m_vPointers;
|
||||
std::vector<SP<CVirtualPointerV1Resource>> m_vPointers;
|
||||
|
||||
friend class CVirtualPointer;
|
||||
friend class CVirtualPointerV1Resource;
|
||||
};
|
||||
|
||||
namespace PROTO {
|
||||
|
|
Loading…
Reference in a new issue