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:
Vaxry 2024-05-03 22:34:10 +01:00
parent 1d2acbe193
commit 1237732b97
39 changed files with 1450 additions and 573 deletions

View file

@ -2418,10 +2418,7 @@ void CCompositor::warpCursorTo(const Vector2D& pos, bool force) {
if (*PNOWARPS && !force) if (*PNOWARPS && !force)
return; return;
if (!m_sSeat.mouse) wlr_cursor_warp(m_sWLRCursor, nullptr, pos.x, pos.y);
return;
wlr_cursor_warp(m_sWLRCursor, m_sSeat.mouse->mouse, pos.x, pos.y);
const auto PMONITORNEW = getMonitorFromVector(pos); const auto PMONITORNEW = getMonitorFromVector(pos);
if (PMONITORNEW != m_pLastMonitor) if (PMONITORNEW != m_pLastMonitor)

View file

@ -19,6 +19,9 @@
#include "../config/ConfigValue.hpp" #include "../config/ConfigValue.hpp"
#include "../managers/CursorManager.hpp" #include "../managers/CursorManager.hpp"
#include "../hyprerror/HyprError.hpp" #include "../hyprerror/HyprError.hpp"
#include "../devices/IPointer.hpp"
#include "../devices/IKeyboard.hpp"
#include "../devices/ITouch.hpp"
static void trimTrailingComma(std::string& str) { static void trimTrailingComma(std::string& str) {
if (!str.empty() && str.back() == ',') if (!str.empty() && str.back() == ',')
@ -514,23 +517,24 @@ std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) {
result += "{\n"; result += "{\n";
result += "\"mice\": [\n"; result += "\"mice\": [\n";
for (auto& m : g_pInputManager->m_lMice) { for (auto& m : g_pInputManager->m_vPointers) {
result += std::format( result += std::format(
R"#( {{ R"#( {{
"address": "0x{:x}", "address": "0x{:x}",
"name": "{}", "name": "{}",
"defaultSpeed": {:.5f} "defaultSpeed": {:.5f}
}},)#", }},)#",
(uintptr_t)&m, escapeJSONStrings(m.name), (uintptr_t)m.get(), escapeJSONStrings(m->hlName),
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); 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); trimTrailingComma(result);
result += "\n],\n"; result += "\n],\n";
result += "\"keyboards\": [\n"; result += "\"keyboards\": [\n";
for (auto& k : g_pInputManager->m_lKeyboards) { for (auto& k : g_pInputManager->m_vKeyboards) {
const auto KM = g_pInputManager->getActiveLayoutForKeyboard(&k); const auto KM = k->getActiveLayout();
result += std::format( result += std::format(
R"#( {{ R"#( {{
"address": "0x{:x}", "address": "0x{:x}",
@ -543,9 +547,9 @@ std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) {
"active_keymap": "{}", "active_keymap": "{}",
"main": {} "main": {}
}},)#", }},)#",
(uintptr_t)&k, escapeJSONStrings(k.name), escapeJSONStrings(k.currentRules.rules), escapeJSONStrings(k.currentRules.model), (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), escapeJSONStrings(k->currentRules.layout), escapeJSONStrings(k->currentRules.variant), escapeJSONStrings(k->currentRules.options), escapeJSONStrings(KM),
(k.active ? "true" : "false")); (k->active ? "true" : "false"));
} }
trimTrailingComma(result); trimTrailingComma(result);
@ -590,13 +594,13 @@ std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) {
result += "\"touch\": [\n"; result += "\"touch\": [\n";
for (auto& d : g_pInputManager->m_lTouchDevices) { for (auto& d : g_pInputManager->m_vTouches) {
result += std::format( result += std::format(
R"#( {{ R"#( {{
"address": "0x{:x}", "address": "0x{:x}",
"name": "{}" "name": "{}"
}},)#", }},)#",
(uintptr_t)&d, escapeJSONStrings(d.name)); (uintptr_t)d.get(), escapeJSONStrings(d->hlName));
} }
trimTrailingComma(result); trimTrailingComma(result);
@ -621,19 +625,20 @@ std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) {
} else { } else {
result += "mice:\n"; result += "mice:\n";
for (auto& m : g_pInputManager->m_lMice) { for (auto& m : g_pInputManager->m_vPointers) {
result += std::format( result += std::format("\tMouse at {:x}:\n\t\t{}\n\t\t\tdefault speed: {:.5f}\n", (uintptr_t)m.get(), m->hlName,
"\tMouse at {:x}:\n\t\t{}\n\t\t\tdefault speed: {:.5f}\n", (uintptr_t)&m, m.name, (wlr_input_device_is_libinput(&m->wlr()->base) ?
(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)); libinput_device_config_accel_get_default_speed((libinput_device*)wlr_libinput_get_device_handle(&m->wlr()->base)) :
0.f));
} }
result += "\n\nKeyboards:\n"; result += "\n\nKeyboards:\n";
for (auto& k : g_pInputManager->m_lKeyboards) { for (auto& k : g_pInputManager->m_vKeyboards) {
const auto KM = g_pInputManager->getActiveLayoutForKeyboard(&k); 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", 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, (uintptr_t)k.get(), k->hlName, k->currentRules.rules, k->currentRules.model, k->currentRules.layout, k->currentRules.variant,
(k.active ? "yes" : "no")); k->currentRules.options, KM, (k->active ? "yes" : "no"));
} }
result += "\n\nTablets:\n"; result += "\n\nTablets:\n";
@ -652,8 +657,8 @@ std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) {
result += "\n\nTouch:\n"; result += "\n\nTouch:\n";
for (auto& d : g_pInputManager->m_lTouchDevices) { for (auto& d : g_pInputManager->m_vTouches) {
result += std::format("\tTouch Device at {:x}:\n\t\t{}\n", (uintptr_t)&d, d.name); result += std::format("\tTouch Device at {:x}:\n\t\t{}\n", (uintptr_t)d.get(), d->hlName);
} }
result += "\n\nSwitches:\n"; result += "\n\nSwitches:\n";
@ -1069,13 +1074,13 @@ std::string switchXKBLayoutRequest(eHyprCtlOutputFormat format, std::string requ
const auto CMD = vars[2]; const auto CMD = vars[2];
// get kb // get kb
const auto PKEYBOARD = std::find_if(g_pInputManager->m_lKeyboards.begin(), g_pInputManager->m_lKeyboards.end(), const auto PKEYBOARD = std::find_if(g_pInputManager->m_vKeyboards.begin(), g_pInputManager->m_vKeyboards.end(),
[&](const SKeyboard& other) { return other.name == g_pInputManager->deviceNameToInternalString(KB); }); [&](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"; 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); const auto LAYOUTS = xkb_keymap_num_layouts(PWLRKEYBOARD->keymap);
xkb_layout_index_t activeLayout = 0; xkb_layout_index_t activeLayout = 0;
while (activeLayout < LAYOUTS) { while (activeLayout < LAYOUTS) {

View file

@ -196,7 +196,7 @@ void CLayerSurface::onMap() {
const bool GRABSFOCUS = layerSurface->current.keyboard_interactive != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE && const bool GRABSFOCUS = layerSurface->current.keyboard_interactive != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE &&
// don't focus if constrained // don't focus if constrained
(!g_pCompositor->m_sSeat.mouse || !g_pInputManager->isConstrained()); (g_pCompositor->m_sSeat.mouse.expired() || !g_pInputManager->isConstrained());
if (GRABSFOCUS) { if (GRABSFOCUS) {
g_pInputManager->releaseAllMouseButtons(); g_pInputManager->releaseAllMouseButtons();
@ -383,7 +383,7 @@ void CLayerSurface::onCommit() {
realSize.setValueAndWarp(geometry.size()); 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) { && !keyboardExclusive && mapped) {
g_pCompositor->focusSurface(layerSurface->surface); 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_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); wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, 0, LOCAL.x, LOCAL.y);
g_pInputManager->m_bEmptyFocusCursorSet = false; 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(); g_pInputManager->refocus();
} }

26
src/devices/IHID.hpp Normal file
View 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
View 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
View 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
View file

@ -0,0 +1,5 @@
#include "IPointer.hpp"
uint32_t IPointer::getCapabilities() {
return HID_INPUT_CAPABILITY_POINTER;
}

110
src/devices/IPointer.hpp Normal file
View 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
View file

@ -0,0 +1,5 @@
#include "ITouch.hpp"
uint32_t ITouch::getCapabilities() {
return HID_INPUT_CAPABILITY_TOUCH;
}

50
src/devices/ITouch.hpp Normal file
View 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
View 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
View 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
View 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
View 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);
};

View 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();
}

View 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);
};

View 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();
}

View 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);
};

View 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();
}

View 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);
};

View file

@ -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) { void Events::listener_mouseFrame(wl_listener* listener, void* data) {
wlr_seat_pointer_notify_frame(g_pCompositor->m_sSeat.seat); 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(); 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) { void Events::listener_swipeBegin(wl_listener* listener, void* data) {
const auto EVENT = (wlr_pointer_swipe_begin_event*)data; const auto EVENT = (wlr_pointer_swipe_begin_event*)data;

View file

@ -54,11 +54,6 @@ namespace Events {
// Virt Ptr // Virt Ptr
LISTENER(newVirtPtr); LISTENER(newVirtPtr);
DYNLISTENFUNC(destroyMouse);
DYNLISTENFUNC(keyboardKey);
DYNLISTENFUNC(keyboardMod);
DYNLISTENFUNC(keyboardDestroy);
// Various // Various
LISTENER(requestMouse); LISTENER(requestMouse);

View file

@ -667,7 +667,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
g_pCompositor->setPreferredScaleForSurface(PWINDOW->m_pWLSurface.wlr(), PMONITOR->scale); g_pCompositor->setPreferredScaleForSurface(PWINDOW->m_pWLSurface.wlr(), PMONITOR->scale);
g_pCompositor->setPreferredTransformForSurface(PWINDOW->m_pWLSurface.wlr(), PMONITOR->transform); 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(); g_pInputManager->sendMotionEventsToFocused();
// fix some xwayland apps that don't behave nicely // fix some xwayland apps that don't behave nicely

View file

@ -3,6 +3,7 @@
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../config/ConfigValue.hpp" #include "../config/ConfigValue.hpp"
#include "../protocols/GammaControl.hpp" #include "../protocols/GammaControl.hpp"
#include "../devices/ITouch.hpp"
int ratHandler(void* data) { int ratHandler(void* data) {
g_pHyprRenderer->renderMonitor((CMonitor*)data); g_pHyprRenderer->renderMonitor((CMonitor*)data);
@ -145,10 +146,10 @@ void CMonitor::onConnect(bool noRule) {
if (!noRule) if (!noRule)
g_pHyprRenderer->applyMonitorRule(this, &monitorRule, true); g_pHyprRenderer->applyMonitorRule(this, &monitorRule, true);
for (const auto& PTOUCHDEV : g_pInputManager->m_lTouchDevices) { for (const auto& PTOUCHDEV : g_pInputManager->m_vTouches) {
if (matchesStaticSelector(PTOUCHDEV.boundOutput)) { if (matchesStaticSelector(PTOUCHDEV->boundOutput)) {
Debug::log(LOG, "Binding touch device {} to output {}", PTOUCHDEV.name, szName); Debug::log(LOG, "Binding touch device {} to output {}", PTOUCHDEV->hlName, szName);
wlr_cursor_map_input_to_output(g_pCompositor->m_sWLRCursor, PTOUCHDEV.pWlrDevice, output); wlr_cursor_map_input_to_output(g_pCompositor->m_sWLRCursor, &PTOUCHDEV->wlr()->base, output);
} }
} }

View file

@ -1,78 +1 @@
#include "WLClasses.hpp" #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);
}

View file

@ -11,8 +11,8 @@
#include "Region.hpp" #include "Region.hpp"
class CMonitor; class CMonitor;
class CVirtualKeyboard; class IPointer;
class CVirtualPointer; class IKeyboard;
struct SRenderData { struct SRenderData {
CMonitor* pMonitor; CMonitor* pMonitor;
@ -58,86 +58,12 @@ struct SExtensionFindingData {
wlr_surface** found; 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 { struct SSeat {
wlr_seat* seat = nullptr; wlr_seat* seat = nullptr;
wl_client* exclusiveClient = nullptr; wl_client* exclusiveClient = nullptr;
SMouse* mouse = nullptr; WP<IPointer> mouse;
WP<IKeyboard> keyboard;
}; };
struct SDrag { struct SDrag {
@ -238,20 +164,6 @@ struct SSwipeGesture {
CMonitor* pMonitor = nullptr; 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 { struct SSwitchDevice {
wlr_input_device* pWlrDevice = nullptr; wlr_input_device* pWlrDevice = nullptr;

View file

@ -11,3 +11,11 @@ void CSignalListener::emit(std::any data) {
m_fHandler(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);
}

View file

@ -22,3 +22,19 @@ class CSignalListener {
}; };
typedef std::shared_ptr<CSignalListener> CHyprSignalListener; 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;
};

View file

@ -11,6 +11,10 @@ void CSignal::emit(std::any data) {
dirty = true; dirty = true;
} }
for (auto& l : m_vStaticListeners) {
l->emit(data);
}
if (dirty) if (dirty)
std::erase_if(m_vListeners, [](const auto& other) { return other.expired(); }); 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)); m_vListeners.emplace_back(std::weak_ptr<CSignalListener>(listener));
return 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));
}

View file

@ -14,6 +14,11 @@ class CSignal {
// //
[[nodiscard("Listener is unregistered when the ptr is lost")]] CHyprSignalListener registerListener(std::function<void(std::any)> handler); [[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: 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;
}; };

View file

@ -5,6 +5,7 @@
#include "../config/ConfigValue.hpp" #include "../config/ConfigValue.hpp"
#include "TokenManager.hpp" #include "TokenManager.hpp"
#include "../protocols/ShortcutsInhibit.hpp" #include "../protocols/ShortcutsInhibit.hpp"
#include "../devices/IKeyboard.hpp"
#include <regex> #include <regex>
#include <tuple> #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) { if (!g_pCompositor->m_bSessionActive || g_pCompositor->m_bUnsafeState) {
m_dPressedKeys.clear(); m_dPressedKeys.clear();
return true; return true;
@ -337,17 +338,19 @@ bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard
return true; 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 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)) if (handleInternalKeybinds(internalKeysym))
return true; return true;
const auto MODS = g_pInputManager->accumulateModsFromAllKBs(); const auto MODS = g_pInputManager->accumulateModsFromAllKBs();
m_uTimeLastMs = e->time_msec; m_uTimeLastMs = e.timeMs;
m_uLastCode = KEYCODE; m_uLastCode = KEYCODE;
m_uLastMouseCode = 0; m_uLastMouseCode = 0;
@ -368,7 +371,7 @@ bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard
} }
bool suppressEvent = false; bool suppressEvent = false;
if (e->state == WL_KEYBOARD_KEY_STATE_PRESSED) { if (e.state == WL_KEYBOARD_KEY_STATE_PRESSED) {
m_dPressedKeys.push_back(KEY); m_dPressedKeys.push_back(KEY);
@ -521,7 +524,7 @@ void CKeybindManager::onSwitchOffEvent(const std::string& switchName) {
int repeatKeyHandler(void* data) { int repeatKeyHandler(void* data) {
SKeybind** ppActiveKeybind = (SKeybind**)data; SKeybind** ppActiveKeybind = (SKeybind**)data;
if (!*ppActiveKeybind) if (!*ppActiveKeybind || g_pCompositor->m_sSeat.keyboard.expired())
return 0; return 0;
const auto DISPATCHER = g_pKeybindManager->m_mDispatchers.find((*ppActiveKeybind)->handler); 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."); Debug::log(LOG, "Keybind repeat triggered, calling dispatcher.");
DISPATCHER->second((*ppActiveKeybind)->arg); 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; return 0;
} }
@ -650,7 +653,7 @@ bool CKeybindManager::handleKeybinds(const uint32_t modmask, const SPressedKeyWi
m_pActiveKeybind = &k; m_pActiveKeybind = &k;
m_pActiveKeybindEventSource = wl_event_loop_add_timer(g_pCompositor->m_sWLEventLoop, repeatKeyHandler, &m_pActiveKeybind); 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); wl_event_source_timer_update(m_pActiveKeybindEventSource, PACTIVEKEEB->repeatDelay);
} }
@ -1440,22 +1443,20 @@ void CKeybindManager::moveCursorToCorner(std::string arg) {
switch (CORNER) { switch (CORNER) {
case 0: case 0:
// bottom left // bottom left
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, PWINDOW->m_vRealPosition.value().x, wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, PWINDOW->m_vRealPosition.value().x, PWINDOW->m_vRealPosition.value().y + PWINDOW->m_vRealSize.value().y);
PWINDOW->m_vRealPosition.value().y + PWINDOW->m_vRealSize.value().y);
break; break;
case 1: case 1:
// bottom right // 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); PWINDOW->m_vRealPosition.value().y + PWINDOW->m_vRealSize.value().y);
break; break;
case 2: case 2:
// top right // 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, 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_vRealPosition.value().y);
break; break;
case 3: case 3:
// top left // 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; break;
} }
} }
@ -1485,7 +1486,7 @@ void CKeybindManager::moveCursor(std::string args) {
x = std::stoi(x_str); x = std::stoi(x_str);
y = std::stoi(y_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) { void CKeybindManager::workspaceOpt(std::string args) {

View file

@ -9,6 +9,7 @@
class CInputManager; class CInputManager;
class CConfigManager; class CConfigManager;
class CPluginSystem; class CPluginSystem;
class IKeyboard;
struct SKeybind { struct SKeybind {
std::string key = ""; std::string key = "";
@ -60,7 +61,7 @@ class CKeybindManager {
CKeybindManager(); CKeybindManager();
~CKeybindManager(); ~CKeybindManager();
bool onKeyEvent(wlr_keyboard_key_event*, SKeyboard*); bool onKeyEvent(std::any, SP<IKeyboard>);
bool onAxisEvent(wlr_pointer_axis_event*); bool onAxisEvent(wlr_pointer_axis_event*);
bool onMouseEvent(wlr_pointer_button_event*); bool onMouseEvent(wlr_pointer_button_event*);
void resizeWithBorder(wlr_pointer_button_event*); void resizeWithBorder(wlr_pointer_button_event*);

View file

@ -14,6 +14,12 @@
#include "../../protocols/VirtualKeyboard.hpp" #include "../../protocols/VirtualKeyboard.hpp"
#include "../../protocols/VirtualPointer.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() { CInputManager::CInputManager() {
m_sListeners.setCursorShape = PROTO::cursorShape->events.setShape.registerListener([this](std::any data) { m_sListeners.setCursorShape = PROTO::cursorShape->events.setShape.registerListener([this](std::any data) {
if (!cursorImageUnlocked()) 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.newIdleInhibitor = PROTO::idleInhibit->events.newIdleInhibitor.registerListener([this](std::any data) { this->newIdleInhibitor(data); });
m_sListeners.newVirtualKeyboard = m_sListeners.newVirtualKeyboard =
PROTO::virtualKeyboard->events.newKeyboard.registerListener([this](std::any data) { this->newVirtualKeyboard(std::any_cast<SP<CVirtualKeyboard>>(data)); }); PROTO::virtualKeyboard->events.newKeyboard.registerListener([this](std::any data) { this->newVirtualKeyboard(std::any_cast<SP<CVirtualKeyboardV1Resource>>(data)); });
m_sListeners.newVirtualMouse = 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() { CInputManager::~CInputManager() {
m_vConstraints.clear(); m_vConstraints.clear();
m_lKeyboards.clear(); m_vKeyboards.clear();
m_lMice.clear(); m_vPointers.clear();
m_vTouches.clear();
m_lTablets.clear(); m_lTablets.clear();
m_lTabletTools.clear(); m_lTabletTools.clear();
m_lTabletPads.clear(); m_lTabletPads.clear();
m_vIdleInhibitors.clear(); m_vIdleInhibitors.clear();
m_lTouchDevices.clear();
m_lSwitches.clear(); m_lSwitches.clear();
} }
@ -181,7 +187,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
} }
// constraints // 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 SURF = CWLSurface::surfaceFromWlr(g_pCompositor->m_pLastFocus);
const auto CONSTRAINT = SURF->constraint(); 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 if (*PFOLLOWMOUSE == 3) // don't refocus on full loose
break; 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 */) { && (w && g_pCompositor->m_pLastWindow.lock() != w) /* window should change */) {
// a bit hacky // a bit hacky
// if we only pressed one button, allow us to refocus. m_lCurrentlyHeldButtons.size() > 0 will stick the focus // 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) { 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 { try {
PNEWKEYBOARD->name = getNameForNewDevice(keyboard->name); keeb->hlName = getNameForNewDevice(keeb->wlr()->base.name);
} catch (std::exception& e) { } catch (std::exception& e) {
Debug::log(ERR, "Keyboard had no name???"); // logic error 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"); keeb->events.destroy.registerStaticListener(
PNEWKEYBOARD->hyprListener_keyboardKey.initCallback(&wlr_keyboard_from_input_device(keyboard)->events.key, &Events::listener_keyboardKey, PNEWKEYBOARD, "Keyboard"); [this](void* owner, std::any data) {
PNEWKEYBOARD->hyprListener_keyboardDestroy.initCallback(&keyboard->events.destroy, &Events::listener_keyboardDestroy, PNEWKEYBOARD, "Keyboard"); auto PKEEB = ((IKeyboard*)owner)->self.lock();
destroyKeyboard(PKEEB);
PNEWKEYBOARD->hyprListener_keyboardKeymap.initCallback( Debug::log(LOG, "Destroyed keyboard {:x}", (uintptr_t)owner);
&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}));
}, },
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); 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)); wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, keeb->wlr());
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());
} }
void CInputManager::setKeyboardLayout() { void CInputManager::setKeyboardLayout() {
for (auto& k : m_lKeyboards) for (auto& k : m_vKeyboards)
applyConfigToKeyboard(&k); applyConfigToKeyboard(k);
g_pKeybindManager->updateXKBTranslationState(); g_pKeybindManager->updateXKBTranslationState();
} }
void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) { void CInputManager::applyConfigToKeyboard(SP<IKeyboard> pKeyboard) {
auto devname = pKeyboard->name; auto devname = pKeyboard->hlName;
const auto HASCONFIG = g_pConfigManager->deviceConfigExists(devname); const auto HASCONFIG = g_pConfigManager->deviceConfigExists(devname);
Debug::log(LOG, "ApplyConfigToKeyboard for \"{}\", hasconfig: {}", pKeyboard->name, (int)HASCONFIG); Debug::log(LOG, "ApplyConfigToKeyboard for \"{}\", hasconfig: {}", devname, (int)HASCONFIG);
ASSERT(pKeyboard);
if (!wlr_keyboard_from_input_device(pKeyboard->keyboard))
return;
const auto REPEATRATE = g_pConfigManager->getDeviceInt(devname, "repeat_rate", "input:repeat_rate"); const auto REPEATRATE = g_pConfigManager->getDeviceInt(devname, "repeat_rate", "input:repeat_rate");
const auto REPEATDELAY = g_pConfigManager->getDeviceInt(devname, "repeat_delay", "input:repeat_delay"); 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 // 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->repeatDelay = REPEATDELAY;
pKeyboard->repeatRate = REPEATRATE; 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); 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(); pKeyboard->updateXKBTranslationState();
@ -957,105 +942,87 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
} }
if (wlrMods.locked != 0) 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_keymap_unref(KEYMAP);
xkb_context_unref(CONTEXT); xkb_context_unref(CONTEXT);
const auto LAYOUTSTR = getActiveLayoutForKeyboard(pKeyboard); const auto LAYOUTSTR = pKeyboard->getActiveLayout();
g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", pKeyboard->name + "," + LAYOUTSTR}); g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", pKeyboard->hlName + "," + LAYOUTSTR});
EMIT_HOOK_EVENT("activeLayout", (std::vector<void*>{pKeyboard, (void*)&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, Debug::log(LOG, "Set the keyboard layout to {} and variant to {} for keyboard \"{}\"", pKeyboard->currentRules.layout, pKeyboard->currentRules.variant, pKeyboard->hlName);
pKeyboard->keyboard->name);
} }
void CInputManager::newVirtualMouse(SP<CVirtualPointer> mouse) { void CInputManager::newVirtualMouse(SP<CVirtualPointerV1Resource> mouse) {
const auto PMOUSE = &m_lMice.emplace_back(); const auto PMOUSE = m_vPointers.emplace_back(CVirtualPointer::create(mouse));
PMOUSE->mouse = &mouse->wlr()->base; setupMouse(PMOUSE);
PMOUSE->virtualPointer = mouse;
PMOUSE->virt = true;
try {
PMOUSE->name = getNameForNewDevice(mouse->wlr()->base.name);
} catch (std::exception& e) {
Debug::log(ERR, "Mouse had no name???"); // logic error
}
wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, &mouse->wlr()->base);
PMOUSE->connected = true;
setPointerConfigs();
PMOUSE->hyprListener_destroyMouse.initCallback(&mouse->wlr()->base.events.destroy, &Events::listener_destroyMouse, PMOUSE, "Mouse");
// TODO: this pointer pass sucks.
PMOUSE->listeners.destroyMouse = mouse->events.destroy.registerListener([this, PMOUSE](std::any data) { destroyMouse(PMOUSE->mouse); });
g_pCompositor->m_sSeat.mouse = PMOUSE;
m_tmrLastCursorMovement.reset();
Debug::log(LOG, "New virtual mouse created, pointer WLR: {:x}", (uintptr_t)mouse->wlr()); Debug::log(LOG, "New virtual mouse created, pointer WLR: {:x}", (uintptr_t)mouse->wlr());
} }
void CInputManager::newMouse(wlr_input_device* mouse) { void CInputManager::newMouse(wlr_input_device* mouse) {
m_lMice.emplace_back(); const auto PMOUSE = m_vPointers.emplace_back(CMouse::create(wlr_pointer_from_input_device(mouse)));
const auto PMOUSE = &m_lMice.back();
PMOUSE->mouse = mouse; setupMouse(PMOUSE);
Debug::log(LOG, "New mouse created, pointer WLR: {:x}", (uintptr_t)mouse);
}
void CInputManager::setupMouse(SP<IPointer> mauz) {
try { try {
PMOUSE->name = getNameForNewDevice(mouse->name); mauz->hlName = getNameForNewDevice(mauz->wlr()->base.name);
} catch (std::exception& e) { } catch (std::exception& e) {
Debug::log(ERR, "Mouse had no name???"); // logic error Debug::log(ERR, "Mouse had no name???"); // logic error
} }
if (wlr_input_device_is_libinput(mouse)) { if (wlr_input_device_is_libinput(&mauz->wlr()->base)) {
const auto LIBINPUTDEV = (libinput_device*)wlr_libinput_get_device_handle(mouse); 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), 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), 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)); (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(); 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(); m_tmrLastCursorMovement.reset();
Debug::log(LOG, "New mouse created, pointer WLR: {:x}", (uintptr_t)mouse);
} }
void CInputManager::setPointerConfigs() { void CInputManager::setPointerConfigs() {
for (auto& m : m_lMice) { for (auto& m : m_vPointers) {
const auto PPOINTER = &m; auto devname = m->hlName;
auto devname = PPOINTER->name;
const auto HASCONFIG = g_pConfigManager->deviceConfigExists(devname); const auto HASCONFIG = g_pConfigManager->deviceConfigExists(devname);
if (HASCONFIG) { if (HASCONFIG) {
const auto ENABLED = g_pConfigManager->getDeviceInt(devname, "enabled"); const auto ENABLED = g_pConfigManager->getDeviceInt(devname, "enabled");
if (ENABLED && !m.connected) { if (ENABLED && !m->connected) {
wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, m.mouse); wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, &m->wlr()->base);
m.connected = true; m->connected = true;
} else if (!ENABLED && m.connected) { } else if (!ENABLED && m->connected) {
wlr_cursor_detach_input_device(g_pCompositor->m_sWLRCursor, m.mouse); wlr_cursor_detach_input_device(g_pCompositor->m_sWLRCursor, &m->wlr()->base);
m.connected = false; m->connected = false;
} }
} }
if (wlr_input_device_is_libinput(m.mouse)) { if (wlr_input_device_is_libinput(&m->wlr()->base)) {
const auto LIBINPUTDEV = (libinput_device*)wlr_libinput_get_device_handle(m.mouse); const auto LIBINPUTDEV = (libinput_device*)wlr_libinput_get_device_handle(&m->wlr()->base);
double touchw = 0, touchh = 0; double touchw = 0, touchh = 0;
const auto ISTOUCHPAD = libinput_device_has_capability(LIBINPUTDEV, LIBINPUT_DEVICE_CAP_POINTER) && 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, libinput_device_config_scroll_set_button_lock(LIBINPUTDEV,
SCROLLBUTTONLOCK == 0 ? LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_DISABLED : LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_ENABLED); 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) { void CInputManager::destroyKeyboard(SP<IKeyboard> pKeyboard) {
pKeyboard->hyprListener_keyboardDestroy.removeCallback(); if (pKeyboard->xkbTranslationState)
pKeyboard->hyprListener_keyboardMod.removeCallback(); xkb_state_unref(pKeyboard->xkbTranslationState);
pKeyboard->hyprListener_keyboardKey.removeCallback();
xkb_state_unref(pKeyboard->xkbTranslationState);
pKeyboard->xkbTranslationState = nullptr; pKeyboard->xkbTranslationState = nullptr;
m_lKeyboards.remove(*pKeyboard); std::erase_if(m_vKeyboards, [pKeyboard](const auto& other) { return other == pKeyboard; });
if (m_lKeyboards.size() > 0) { if (m_vKeyboards.size() > 0) {
m_pActiveKeyboard = &m_lKeyboards.back(); g_pCompositor->m_sSeat.keyboard = m_vKeyboards.back();
m_pActiveKeyboard->active = true; g_pCompositor->m_sSeat.keyboard.lock()->active = true;
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, wlr_keyboard_from_input_device(m_pActiveKeyboard->keyboard)); wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, g_pCompositor->m_sSeat.keyboard.lock()->wlr());
} else { } else {
m_pActiveKeyboard = nullptr; g_pCompositor->m_sSeat.keyboard.reset();
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, nullptr); wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, nullptr);
} }
} }
void CInputManager::destroyMouse(wlr_input_device* mouse) { void CInputManager::destroyPointer(SP<IPointer> mouse) {
for (auto& m : m_lMice) { std::erase_if(m_vPointers, [mouse](const auto& other) { return other == mouse; });
if (m.mouse == mouse) {
m_lMice.remove(m);
break;
}
}
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(); unconstrainMouse();
} }
void CInputManager::updateKeyboardsLeds(wlr_input_device* pKeyboard) { void CInputManager::destroyTouchDevice(SP<ITouch> touch) {
auto keyboard = wlr_keyboard_from_input_device(pKeyboard); Debug::log(LOG, "Touch device at {:x} removed", (uintptr_t)touch.get());
if (keyboard->xkb_state == NULL) { std::erase_if(m_vTouches, [touch](const auto& other) { return other == touch; });
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);
}
} }
void CInputManager::onKeyboardKey(wlr_keyboard_key_event* e, SKeyboard* pKeyboard) { void CInputManager::onKeyboardKey(std::any event, SP<IKeyboard> pKeyboard) {
if (!pKeyboard->enabled) if (!pKeyboard->enabled)
return; 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); EMIT_HOOK_EVENT_CANCELLABLE("keyPress", EMAP);
static auto PDPMS = CConfigValue<Hyprlang::INT>("misc:key_press_enables_dpms"); 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"); 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(); 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(); const auto IME = m_sIMERelay.m_pIME.lock();
if (IME && IME->hasGrab() && !DISALLOWACTION) { if (IME && IME->hasGrab() && !DISALLOWACTION) {
IME->setKeyboard(wlr_keyboard_from_input_device(pKeyboard->keyboard)); IME->setKeyboard(pKeyboard->wlr());
IME->sendKey(e->time_msec, e->keycode, e->state); IME->sendKey(e.timeMs, e.keycode, e.state);
} else { } 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, pKeyboard->wlr());
wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, e->time_msec, e->keycode, e->state); 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) if (!pKeyboard->enabled)
return; return;
const bool DISALLOWACTION = pKeyboard->isVirtual && shouldIgnoreVirtualKeyboard(pKeyboard); const bool DISALLOWACTION = pKeyboard->isVirtual() && shouldIgnoreVirtualKeyboard(pKeyboard);
const auto ALLMODS = accumulateModsFromAllKBs(); 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; MODS.depressed = ALLMODS;
const auto IME = m_sIMERelay.m_pIME.lock(); const auto IME = m_sIMERelay.m_pIME.lock();
if (IME && IME->hasGrab() && !DISALLOWACTION) { 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); IME->sendMods(MODS.depressed, MODS.latched, MODS.locked, MODS.group);
} else { } 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); wlr_seat_keyboard_notify_modifiers(g_pCompositor->m_sSeat.seat, &MODS);
} }
updateKeyboardsLeds(pKeyboard->keyboard); for (auto& k : m_vKeyboards) {
k->updateLEDs();
const auto PWLRKB = wlr_keyboard_from_input_device(pKeyboard->keyboard); }
if (PWLRKB->modifiers.group != pKeyboard->activeLayout) { if (PWLRKB->modifiers.group != pKeyboard->activeLayout) {
pKeyboard->activeLayout = PWLRKB->modifiers.group; pKeyboard->activeLayout = PWLRKB->modifiers.group;
const auto LAYOUT = getActiveLayoutForKeyboard(pKeyboard); const auto LAYOUT = pKeyboard->getActiveLayout();
pKeyboard->updateXKBTranslationState(); pKeyboard->updateXKBTranslationState();
g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", pKeyboard->name + "," + LAYOUT}); g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", pKeyboard->hlName + "," + LAYOUT});
EMIT_HOOK_EVENT("activeLayout", (std::vector<void*>{pKeyboard, (void*)&LAYOUT})); EMIT_HOOK_EVENT("activeLayout", (std::vector<std::any>{pKeyboard, LAYOUT}));
} }
} }
bool CInputManager::shouldIgnoreVirtualKeyboard(SKeyboard* pKeyboard) { bool CInputManager::shouldIgnoreVirtualKeyboard(SP<IKeyboard> pKeyboard) {
if (!pKeyboard->isVirtual) if (!pKeyboard->isVirtual())
return false; 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() { void CInputManager::refocus() {
@ -1343,7 +1294,7 @@ void CInputManager::updateDragIcon() {
} }
void CInputManager::unconstrainMouse() { void CInputManager::unconstrainMouse() {
if (!g_pCompositor->m_sSeat.mouse) if (g_pCompositor->m_sSeat.mouse.expired())
return; return;
for (auto& c : m_vConstraints) { for (auto& c : m_vConstraints) {
@ -1378,11 +1329,11 @@ bool CInputManager::isConstrained() {
void CInputManager::updateCapabilities() { void CInputManager::updateCapabilities() {
uint32_t caps = 0; uint32_t caps = 0;
if (!m_lKeyboards.empty()) if (!m_vKeyboards.empty())
caps |= WL_SEAT_CAPABILITY_KEYBOARD; caps |= WL_SEAT_CAPABILITY_KEYBOARD;
if (!m_lMice.empty()) if (!m_vPointers.empty())
caps |= WL_SEAT_CAPABILITY_POINTER; caps |= WL_SEAT_CAPABILITY_POINTER;
if (!m_lTouchDevices.empty()) if (!m_vTouches.empty())
caps |= WL_SEAT_CAPABILITY_TOUCH; caps |= WL_SEAT_CAPABILITY_TOUCH;
if (!m_lTabletTools.empty()) if (!m_lTabletTools.empty())
caps |= WL_SEAT_CAPABILITY_POINTER; caps |= WL_SEAT_CAPABILITY_POINTER;
@ -1395,54 +1346,34 @@ uint32_t CInputManager::accumulateModsFromAllKBs() {
uint32_t finalMask = 0; uint32_t finalMask = 0;
for (auto& kb : m_lKeyboards) { for (auto& kb : m_vKeyboards) {
if (kb.isVirtual && shouldIgnoreVirtualKeyboard(&kb)) if (kb->isVirtual() && shouldIgnoreVirtualKeyboard(kb))
continue; continue;
if (!kb.enabled) if (!kb->enabled)
continue; continue;
finalMask |= wlr_keyboard_get_modifiers(wlr_keyboard_from_input_device(kb.keyboard)); finalMask |= wlr_keyboard_get_modifiers(kb->wlr());
} }
return finalMask; 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) { void CInputManager::disableAllKeyboards(bool virt) {
for (auto& k : m_lKeyboards) { for (auto& k : m_vKeyboards) {
if (k.isVirtual != virt) if (k->isVirtual() != virt)
continue; continue;
k.active = false; k->active = false;
} }
} }
void CInputManager::newTouchDevice(wlr_input_device* pDevice) { void CInputManager::newTouchDevice(wlr_input_device* pDevice) {
const auto PNEWDEV = &m_lTouchDevices.emplace_back(); const auto PNEWDEV = m_vTouches.emplace_back(CTouchDevice::create(wlr_touch_from_input_device(pDevice)));
PNEWDEV->pWlrDevice = pDevice;
try { try {
PNEWDEV->name = getNameForNewDevice(pDevice->name); PNEWDEV->hlName = getNameForNewDevice(pDevice->name);
} catch (std::exception& e) { } catch (std::exception& e) {
Debug::log(ERR, "Touch Device had no name???"); // logic error Debug::log(ERR, "Touch Device had no name???"); // logic error
} }
@ -1450,32 +1381,36 @@ void CInputManager::newTouchDevice(wlr_input_device* pDevice) {
setTouchDeviceConfigs(PNEWDEV); setTouchDeviceConfigs(PNEWDEV);
wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, pDevice); 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( Debug::log(LOG, "New touch device added at {:x}", (uintptr_t)PNEWDEV.get());
&pDevice->events.destroy, [&](void* owner, void* data) { destroyTouchDevice((STouchDevice*)data); }, PNEWDEV, "TouchDevice");
} }
void CInputManager::setTouchDeviceConfigs(STouchDevice* dev) { void CInputManager::setTouchDeviceConfigs(SP<ITouch> dev) {
auto setConfig = [&](STouchDevice* const PTOUCHDEV) -> void { auto setConfig = [&](SP<ITouch> PTOUCHDEV) -> void {
if (wlr_input_device_is_libinput(PTOUCHDEV->pWlrDevice)) { if (wlr_input_device_is_libinput(&PTOUCHDEV->wlr()->base)) {
const auto LIBINPUTDEV = (libinput_device*)wlr_libinput_get_device_handle(PTOUCHDEV->pWlrDevice); 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; const auto mode = ENABLED ? LIBINPUT_CONFIG_SEND_EVENTS_ENABLED : LIBINPUT_CONFIG_SEND_EVENTS_DISABLED;
if (libinput_device_config_send_events_get_mode(LIBINPUTDEV) != mode) if (libinput_device_config_send_events_get_mode(LIBINPUTDEV) != mode)
libinput_device_config_send_events_set_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); 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->name); Debug::log(LOG, "Setting calibration matrix for device {}", PTOUCHDEV->hlName);
if (libinput_device_config_calibration_has_matrix(LIBINPUTDEV)) if (libinput_device_config_calibration_has_matrix(LIBINPUTDEV))
libinput_device_config_calibration_set_matrix(LIBINPUTDEV, MATRICES[ROTATION]); 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; bool bound = !output.empty() && output != STRVAL_EMPTY;
const bool AUTODETECT = output == "[[Auto]]"; const bool AUTODETECT = output == "[[Auto]]";
if (!bound && AUTODETECT) { if (!bound && AUTODETECT) {
const auto DEFAULTOUTPUT = wlr_touch_from_input_device(PTOUCHDEV->pWlrDevice)->output_name; const auto DEFAULTOUTPUT = PTOUCHDEV->wlr()->output_name;
if (DEFAULTOUTPUT) { if (DEFAULTOUTPUT) {
output = DEFAULTOUTPUT; output = DEFAULTOUTPUT;
bound = true; bound = true;
@ -1484,10 +1419,10 @@ void CInputManager::setTouchDeviceConfigs(STouchDevice* dev) {
PTOUCHDEV->boundOutput = bound ? output : ""; PTOUCHDEV->boundOutput = bound ? output : "";
const auto PMONITOR = bound ? g_pCompositor->getMonitorFromName(output) : nullptr; const auto PMONITOR = bound ? g_pCompositor->getMonitorFromName(output) : nullptr;
if (PMONITOR) { if (PMONITOR) {
Debug::log(LOG, "Binding touch device {} to output {}", PTOUCHDEV->name, PMONITOR->szName); Debug::log(LOG, "Binding touch device {} to output {}", PTOUCHDEV->hlName, PMONITOR->szName);
wlr_cursor_map_input_to_output(g_pCompositor->m_sWLRCursor, PTOUCHDEV->pWlrDevice, PMONITOR->output); wlr_cursor_map_input_to_output(g_pCompositor->m_sWLRCursor, &PTOUCHDEV->wlr()->base, PMONITOR->output);
} else if (bound) } 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; return;
} }
for (auto& m : m_lTouchDevices) { for (auto& m : m_vTouches) {
const auto PTOUCHDEV = &m; setConfig(m);
setConfig(PTOUCHDEV);
} }
} }
@ -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) { void CInputManager::newSwitch(wlr_input_device* pDevice) {
const auto PNEWDEV = &m_lSwitches.emplace_back(); const auto PNEWDEV = &m_lSwitches.emplace_back();
PNEWDEV->pWlrDevice = pDevice; PNEWDEV->pWlrDevice = pDevice;
@ -1623,16 +1550,16 @@ std::string CInputManager::getNameForNewDevice(std::string internalName) {
auto proposedNewName = deviceNameToInternalString(internalName); auto proposedNewName = deviceNameToInternalString(internalName);
int dupeno = 0; int dupeno = 0;
while (std::find_if(m_lKeyboards.begin(), m_lKeyboards.end(), while (std::find_if(m_vKeyboards.begin(), m_vKeyboards.end(),
[&](const SKeyboard& other) { return other.name == proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); }) != m_lKeyboards.end()) [&](const auto& other) { return other->hlName == proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); }) != m_vKeyboards.end())
dupeno++; dupeno++;
while (std::find_if(m_lMice.begin(), m_lMice.end(), [&](const SMouse& other) { return other.name == proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); }) != while (std::find_if(m_vPointers.begin(), m_vPointers.end(),
m_lMice.end()) [&](const auto& other) { return other->hlName == proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); }) != m_vPointers.end())
dupeno++; dupeno++;
while (std::find_if(m_lTouchDevices.begin(), m_lTouchDevices.end(), while (std::find_if(m_vTouches.begin(), m_vTouches.end(),
[&](const STouchDevice& other) { return other.name == proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); }) != m_lTouchDevices.end()) [&](const auto& other) { return other->hlName == proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); }) != m_vTouches.end())
dupeno++; dupeno++;
while (std::find_if(m_lTabletPads.begin(), m_lTabletPads.end(), while (std::find_if(m_lTabletPads.begin(), m_lTabletPads.end(),

View file

@ -11,8 +11,11 @@
class CPointerConstraint; class CPointerConstraint;
class CWindow; class CWindow;
class CIdleInhibitor; class CIdleInhibitor;
class CVirtualKeyboard; class CVirtualKeyboardV1Resource;
class CVirtualPointer; class CVirtualPointerV1Resource;
class IPointer;
class IKeyboard;
class ITouch;
enum eClickBehaviorMode { enum eClickBehaviorMode {
CLICKMODE_DEFAULT = 0, CLICKMODE_DEFAULT = 0,
@ -75,23 +78,22 @@ class CInputManager {
void onMouseWarp(wlr_pointer_motion_absolute_event*); void onMouseWarp(wlr_pointer_motion_absolute_event*);
void onMouseButton(wlr_pointer_button_event*); void onMouseButton(wlr_pointer_button_event*);
void onMouseWheel(wlr_pointer_axis_event*); void onMouseWheel(wlr_pointer_axis_event*);
void onKeyboardKey(wlr_keyboard_key_event*, SKeyboard*); void onKeyboardKey(std::any, SP<IKeyboard>);
void onKeyboardMod(void*, SKeyboard*); void onKeyboardMod(SP<IKeyboard>);
void newKeyboard(wlr_input_device*); void newKeyboard(wlr_input_device*);
void newVirtualKeyboard(SP<CVirtualKeyboard>); void newVirtualKeyboard(SP<CVirtualKeyboardV1Resource>);
void newMouse(wlr_input_device*); void newMouse(wlr_input_device*);
void newVirtualMouse(SP<CVirtualPointer>); void newVirtualMouse(SP<CVirtualPointerV1Resource>);
void newTouchDevice(wlr_input_device*); void newTouchDevice(wlr_input_device*);
void newSwitch(wlr_input_device*); void newSwitch(wlr_input_device*);
void destroyTouchDevice(STouchDevice*); void destroyTouchDevice(SP<ITouch>);
void destroyKeyboard(SKeyboard*); void destroyKeyboard(SP<IKeyboard>);
void destroyMouse(wlr_input_device*); void destroyPointer(SP<IPointer>);
void destroySwitch(SSwitchDevice*); void destroySwitch(SSwitchDevice*);
void unconstrainMouse(); void unconstrainMouse();
bool isConstrained(); bool isConstrained();
std::string getActiveLayoutForKeyboard(SKeyboard*);
Vector2D getMouseCoordsInternal(); Vector2D getMouseCoordsInternal();
void refocus(); void refocus();
@ -100,7 +102,7 @@ class CInputManager {
void setKeyboardLayout(); void setKeyboardLayout();
void setPointerConfigs(); void setPointerConfigs();
void setTouchDeviceConfigs(STouchDevice* dev = nullptr); void setTouchDeviceConfigs(SP<ITouch> dev = nullptr);
void setTabletConfigs(); void setTabletConfigs();
void updateDragIcon(); void updateDragIcon();
@ -122,21 +124,19 @@ class CInputManager {
bool m_bWasDraggingWindow = false; bool m_bWasDraggingWindow = false;
// for refocus to be forced // for refocus to be forced
PHLWINDOWREF m_pForcedFocus; PHLWINDOWREF m_pForcedFocus;
SDrag m_sDrag; SDrag m_sDrag;
std::list<SKeyboard> m_lKeyboards; std::vector<SP<IKeyboard>> m_vKeyboards;
std::list<SMouse> m_lMice; std::vector<SP<IPointer>> m_vPointers;
std::vector<SP<ITouch>> m_vTouches;
// tablets // tablets
std::list<STablet> m_lTablets; std::list<STablet> m_lTablets;
std::list<STabletTool> m_lTabletTools; std::list<STabletTool> m_lTabletTools;
std::list<STabletPad> m_lTabletPads; std::list<STabletPad> m_lTabletPads;
// Touch devices
std::list<STouchDevice> m_lTouchDevices;
// Switches // Switches
std::list<SSwitchDevice> m_lSwitches; std::list<SSwitchDevice> m_lSwitches;
@ -159,19 +159,15 @@ class CInputManager {
SSwipeGesture m_sActiveSwipe; SSwipeGesture m_sActiveSwipe;
SKeyboard* m_pActiveKeyboard = nullptr;
CTimer m_tmrLastCursorMovement; CTimer m_tmrLastCursorMovement;
CInputMethodRelay m_sIMERelay; CInputMethodRelay m_sIMERelay;
void updateKeyboardsLeds(wlr_input_device* pKeyboard);
// for shared mods // for shared mods
uint32_t accumulateModsFromAllKBs(); uint32_t accumulateModsFromAllKBs();
// for virtual keyboards: whether we should respect them as normal ones // for virtual keyboards: whether we should respect them as normal ones
bool shouldIgnoreVirtualKeyboard(SKeyboard*); bool shouldIgnoreVirtualKeyboard(SP<IKeyboard>);
// for special cursors that we choose // for special cursors that we choose
void setCursorImageUntilUnset(std::string); void setCursorImageUntilUnset(std::string);
@ -213,6 +209,9 @@ class CInputManager {
eClickBehaviorMode m_ecbClickBehavior = CLICKMODE_DEFAULT; eClickBehaviorMode m_ecbClickBehavior = CLICKMODE_DEFAULT;
Vector2D m_vLastCursorPosFloored = Vector2D(); Vector2D m_vLastCursorPosFloored = Vector2D();
void setupKeyboard(SP<IKeyboard> keeb);
void setupMouse(SP<IPointer> mauz);
void processMouseDownNormal(wlr_pointer_button_event* e); void processMouseDownNormal(wlr_pointer_button_event* e);
void processMouseDownKill(wlr_pointer_button_event* e); void processMouseDownKill(wlr_pointer_button_event* e);
@ -226,7 +225,7 @@ class CInputManager {
STabletTool* ensureTabletToolPresent(wlr_tablet_tool*); STabletTool* ensureTabletToolPresent(wlr_tablet_tool*);
void applyConfigToKeyboard(SKeyboard*); void applyConfigToKeyboard(SP<IKeyboard>);
// this will be set after a refocus() // this will be set after a refocus()
wlr_surface* m_pFoundSurfaceToFocus = nullptr; wlr_surface* m_pFoundSurfaceToFocus = nullptr;

View file

@ -2,6 +2,7 @@
#include "../../Compositor.hpp" #include "../../Compositor.hpp"
#include "../../config/ConfigValue.hpp" #include "../../config/ConfigValue.hpp"
#include "../../protocols/IdleNotify.hpp" #include "../../protocols/IdleNotify.hpp"
#include "../../devices/ITouch.hpp"
void CInputManager::onTouchDown(wlr_touch_down_event* e) { void CInputManager::onTouchDown(wlr_touch_down_event* e) {
static auto PSWIPETOUCH = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_touch"); 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 : ""); 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()) if (PDEVIT != m_vTouches.end() && !(*PDEVIT)->boundOutput.empty())
PMONITOR = g_pCompositor->getMonitorFromName(PDEVIT->boundOutput); PMONITOR = g_pCompositor->getMonitorFromName((*PDEVIT)->boundOutput);
PMONITOR = PMONITOR ? PMONITOR : g_pCompositor->m_pLastMonitor; PMONITOR = PMONITOR ? PMONITOR : g_pCompositor->m_pLastMonitor;

View file

@ -7,7 +7,7 @@ static const struct wlr_keyboard_impl virtualKeyboardImpl = {
.name = "virtual-keyboard", .name = "virtual-keyboard",
}; };
CVirtualKeyboard::CVirtualKeyboard(SP<CZwpVirtualKeyboardV1> resource_) : resource(resource_) { CVirtualKeyboardV1Resource::CVirtualKeyboardV1Resource(SP<CZwpVirtualKeyboardV1> resource_) : resource(resource_) {
if (!good()) if (!good())
return; return;
@ -84,20 +84,20 @@ CVirtualKeyboard::CVirtualKeyboard(SP<CZwpVirtualKeyboardV1> resource_) : resour
wlr_keyboard_init(&keyboard, &virtualKeyboardImpl, "CVirtualKeyboard"); wlr_keyboard_init(&keyboard, &virtualKeyboardImpl, "CVirtualKeyboard");
} }
CVirtualKeyboard::~CVirtualKeyboard() { CVirtualKeyboardV1Resource::~CVirtualKeyboardV1Resource() {
wlr_keyboard_finish(&keyboard); wlr_keyboard_finish(&keyboard);
events.destroy.emit(); events.destroy.emit();
} }
bool CVirtualKeyboard::good() { bool CVirtualKeyboardV1Resource::good() {
return resource->resource(); return resource->resource();
} }
wlr_keyboard* CVirtualKeyboard::wlr() { wlr_keyboard* CVirtualKeyboardV1Resource::wlr() {
return &keyboard; return &keyboard;
} }
wl_client* CVirtualKeyboard::client() { wl_client* CVirtualKeyboardV1Resource::client() {
return resource->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; }); 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; }); std::erase_if(m_vKeyboards, [&](const auto& other) { return other.get() == keeb; });
} }
void CVirtualKeyboardProtocol::onCreateKeeb(CZwpVirtualKeyboardManagerV1* pMgr, wl_resource* seat, uint32_t id) { 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()) { if (!RESOURCE->good()) {
pMgr->noMemory(); pMgr->noMemory();

View file

@ -7,10 +7,10 @@
#include "virtual-keyboard-unstable-v1.hpp" #include "virtual-keyboard-unstable-v1.hpp"
#include "../helpers/signal/Signal.hpp" #include "../helpers/signal/Signal.hpp"
class CVirtualKeyboard { class CVirtualKeyboardV1Resource {
public: public:
CVirtualKeyboard(SP<CZwpVirtualKeyboardV1> resource_); CVirtualKeyboardV1Resource(SP<CZwpVirtualKeyboardV1> resource_);
~CVirtualKeyboard(); ~CVirtualKeyboardV1Resource();
struct { struct {
CSignal destroy; CSignal destroy;
@ -39,14 +39,14 @@ class CVirtualKeyboardProtocol : public IWaylandProtocol {
private: private:
void onManagerResourceDestroy(wl_resource* res); void onManagerResourceDestroy(wl_resource* res);
void destroyResource(CVirtualKeyboard* keeb); void destroyResource(CVirtualKeyboardV1Resource* keeb);
void onCreateKeeb(CZwpVirtualKeyboardManagerV1* pMgr, wl_resource* seat, uint32_t id); void onCreateKeeb(CZwpVirtualKeyboardManagerV1* pMgr, wl_resource* seat, uint32_t id);
// //
std::vector<UP<CZwpVirtualKeyboardManagerV1>> m_vManagers; 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 { namespace PROTO {

View file

@ -6,7 +6,7 @@ static const wlr_pointer_impl pointerImpl = {
.name = "virtual-pointer-v1", .name = "virtual-pointer-v1",
}; };
CVirtualPointer::CVirtualPointer(SP<CZwlrVirtualPointerV1> resource_) : resource(resource_) { CVirtualPointerV1Resource::CVirtualPointerV1Resource(SP<CZwlrVirtualPointerV1> resource_) : resource(resource_) {
if (!good()) if (!good())
return; return;
@ -19,7 +19,7 @@ CVirtualPointer::CVirtualPointer(SP<CZwlrVirtualPointerV1> resource_) : resource
PROTO::virtualPointer->destroyResource(this); 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) { resource->setMotion([this](CZwlrVirtualPointerV1* r, uint32_t timeMs, wl_fixed_t dx, wl_fixed_t dy) {
wlr_pointer_motion_event event = { wlr_pointer_motion_event event = {
@ -108,20 +108,20 @@ CVirtualPointer::CVirtualPointer(SP<CZwlrVirtualPointerV1> resource_) : resource
}); });
} }
CVirtualPointer::~CVirtualPointer() { CVirtualPointerV1Resource::~CVirtualPointerV1Resource() {
wlr_pointer_finish(&pointer); wlr_pointer_finish(&pointer);
events.destroy.emit(); events.destroy.emit();
} }
bool CVirtualPointer::good() { bool CVirtualPointerV1Resource::good() {
return resource->resource(); return resource->resource();
} }
wlr_pointer* CVirtualPointer::wlr() { wlr_pointer* CVirtualPointerV1Resource::wlr() {
return &pointer; return &pointer;
} }
wl_client* CVirtualPointer::client() { wl_client* CVirtualPointerV1Resource::client() {
return resource->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; }); 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; }); std::erase_if(m_vPointers, [&](const auto& other) { return other.get() == pointer; });
} }
void CVirtualPointerProtocol::onCreatePointer(CZwlrVirtualPointerManagerV1* pMgr, wl_resource* seat, uint32_t id) { 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()) { if (!RESOURCE->good()) {
pMgr->noMemory(); pMgr->noMemory();

View file

@ -8,10 +8,10 @@
#include "wlr-virtual-pointer-unstable-v1.hpp" #include "wlr-virtual-pointer-unstable-v1.hpp"
#include "../helpers/signal/Signal.hpp" #include "../helpers/signal/Signal.hpp"
class CVirtualPointer { class CVirtualPointerV1Resource {
public: public:
CVirtualPointer(SP<CZwlrVirtualPointerV1> resource_); CVirtualPointerV1Resource(SP<CZwlrVirtualPointerV1> resource_);
~CVirtualPointer(); ~CVirtualPointerV1Resource();
struct { struct {
CSignal destroy; CSignal destroy;
@ -37,19 +37,19 @@ class CVirtualPointerProtocol : public IWaylandProtocol {
virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id); virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);
struct { struct {
CSignal newPointer; // SP<CVirtualPointer> CSignal newPointer; // SP<CVirtualPointerV1Resource>
} events; } events;
private: private:
void onManagerResourceDestroy(wl_resource* res); void onManagerResourceDestroy(wl_resource* res);
void destroyResource(CVirtualPointer* pointer); void destroyResource(CVirtualPointerV1Resource* pointer);
void onCreatePointer(CZwlrVirtualPointerManagerV1* pMgr, wl_resource* seat, uint32_t id); void onCreatePointer(CZwlrVirtualPointerManagerV1* pMgr, wl_resource* seat, uint32_t id);
// //
std::vector<UP<CZwlrVirtualPointerManagerV1>> m_vManagers; 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 { namespace PROTO {