wl_seat: move to hyprland impl
This commit is contained in:
parent
4cdddcfe46
commit
121d3a7213
31 changed files with 1441 additions and 395 deletions
|
|
@ -1,124 +1,125 @@
|
|||
#include "FocusGrab.hpp"
|
||||
#include "Compositor.hpp"
|
||||
#include <hyprland-focus-grab-v1.hpp>
|
||||
#include <managers/input/InputManager.hpp>
|
||||
#include "../managers/input/InputManager.hpp"
|
||||
#include "../managers/SeatManager.hpp"
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <wayland-server.h>
|
||||
|
||||
static void focus_grab_pointer_enter(wlr_seat_pointer_grab* grab, wlr_surface* surface, double sx, double sy) {
|
||||
if (static_cast<CFocusGrab*>(grab->data)->isSurfaceComitted(surface))
|
||||
wlr_seat_pointer_enter(grab->seat, surface, sx, sy);
|
||||
else
|
||||
wlr_seat_pointer_clear_focus(grab->seat);
|
||||
}
|
||||
// static void focus_grab_pointer_enter(wlr_seat_pointer_grab* grab, wlr_surface* surface, double sx, double sy) {
|
||||
// if (static_cast<CFocusGrab*>(grab->data)->isSurfaceComitted(surface))
|
||||
// wlr_seat_pointer_enter(grab->seat, surface, sx, sy);
|
||||
// else
|
||||
// wlr_seat_pointer_clear_focus(grab->seat);
|
||||
// }
|
||||
|
||||
static void focus_grab_pointer_clear_focus(wlr_seat_pointer_grab* grab) {
|
||||
wlr_seat_pointer_clear_focus(grab->seat);
|
||||
}
|
||||
// static void focus_grab_pointer_clear_focus(wlr_seat_pointer_grab* grab) {
|
||||
// wlr_seat_pointer_clear_focus(grab->seat);
|
||||
// }
|
||||
|
||||
static void focus_grab_pointer_motion(wlr_seat_pointer_grab* grab, uint32_t time, double sx, double sy) {
|
||||
wlr_seat_pointer_send_motion(grab->seat, time, sx, sy);
|
||||
}
|
||||
// static void focus_grab_pointer_motion(wlr_seat_pointer_grab* grab, uint32_t time, double sx, double sy) {
|
||||
// wlr_seat_pointer_send_motion(grab->seat, time, sx, sy);
|
||||
// }
|
||||
|
||||
static uint32_t focus_grab_pointer_button(wlr_seat_pointer_grab* grab, uint32_t time, uint32_t button, wl_pointer_button_state state) {
|
||||
uint32_t serial = wlr_seat_pointer_send_button(grab->seat, time, button, state);
|
||||
// static uint32_t focus_grab_pointer_button(wlr_seat_pointer_grab* grab, uint32_t time, uint32_t button, wl_pointer_button_state state) {
|
||||
// uint32_t serial = wlr_seat_pointer_send_button(grab->seat, time, button, state);
|
||||
|
||||
if (serial)
|
||||
return serial;
|
||||
else {
|
||||
static_cast<CFocusGrab*>(grab->data)->finish(true);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// if (serial)
|
||||
// return serial;
|
||||
// else {
|
||||
// static_cast<CFocusGrab*>(grab->data)->finish(true);
|
||||
// return 0;
|
||||
// }
|
||||
// }
|
||||
|
||||
static void focus_grab_pointer_axis(wlr_seat_pointer_grab* grab, uint32_t time, enum wl_pointer_axis orientation, double value, int32_t value_discrete,
|
||||
enum wl_pointer_axis_source source, enum wl_pointer_axis_relative_direction relative_direction) {
|
||||
wlr_seat_pointer_send_axis(grab->seat, time, orientation, value, value_discrete, source, relative_direction);
|
||||
}
|
||||
// static void focus_grab_pointer_axis(wlr_seat_pointer_grab* grab, uint32_t time, enum wl_pointer_axis orientation, double value, int32_t value_discrete,
|
||||
// enum wl_pointer_axis_source source, enum wl_pointer_axis_relative_direction relative_direction) {
|
||||
// wlr_seat_pointer_send_axis(grab->seat, time, orientation, value, value_discrete, source, relative_direction);
|
||||
// }
|
||||
|
||||
static void focus_grab_pointer_frame(wlr_seat_pointer_grab* grab) {
|
||||
wlr_seat_pointer_send_frame(grab->seat);
|
||||
}
|
||||
// static void focus_grab_pointer_frame(wlr_seat_pointer_grab* grab) {
|
||||
// wlr_seat_pointer_send_frame(grab->seat);
|
||||
// }
|
||||
|
||||
static void focus_grab_pointer_cancel(wlr_seat_pointer_grab* grab) {
|
||||
static_cast<CFocusGrab*>(grab->data)->finish(true);
|
||||
}
|
||||
// static void focus_grab_pointer_cancel(wlr_seat_pointer_grab* grab) {
|
||||
// static_cast<CFocusGrab*>(grab->data)->finish(true);
|
||||
// }
|
||||
|
||||
static const wlr_pointer_grab_interface focus_grab_pointer_impl = {
|
||||
.enter = focus_grab_pointer_enter,
|
||||
.clear_focus = focus_grab_pointer_clear_focus,
|
||||
.motion = focus_grab_pointer_motion,
|
||||
.button = focus_grab_pointer_button,
|
||||
.axis = focus_grab_pointer_axis,
|
||||
.frame = focus_grab_pointer_frame,
|
||||
.cancel = focus_grab_pointer_cancel,
|
||||
};
|
||||
// static const wlr_pointer_grab_interface focus_grab_pointer_impl = {
|
||||
// .enter = focus_grab_pointer_enter,
|
||||
// .clear_focus = focus_grab_pointer_clear_focus,
|
||||
// .motion = focus_grab_pointer_motion,
|
||||
// .button = focus_grab_pointer_button,
|
||||
// .axis = focus_grab_pointer_axis,
|
||||
// .frame = focus_grab_pointer_frame,
|
||||
// .cancel = focus_grab_pointer_cancel,
|
||||
// };
|
||||
|
||||
static void focus_grab_keyboard_enter(wlr_seat_keyboard_grab* grab, wlr_surface* surface, const uint32_t keycodes[], size_t num_keycodes, const wlr_keyboard_modifiers* modifiers) {
|
||||
if (static_cast<CFocusGrab*>(grab->data)->isSurfaceComitted(surface))
|
||||
wlr_seat_keyboard_enter(grab->seat, surface, keycodes, num_keycodes, modifiers);
|
||||
// static void focus_grab_keyboard_enter(wlr_seat_keyboard_grab* grab, wlr_surface* surface, const uint32_t keycodes[], size_t num_keycodes, const wlr_keyboard_modifiers* modifiers) {
|
||||
// if (static_cast<CFocusGrab*>(grab->data)->isSurfaceComitted(surface))
|
||||
// wlr_seat_keyboard_enter(grab->seat, surface, keycodes, num_keycodes, modifiers);
|
||||
|
||||
// otherwise the last grabbed window should retain keyboard focus.
|
||||
}
|
||||
// // otherwise the last grabbed window should retain keyboard focus.
|
||||
// }
|
||||
|
||||
static void focus_grab_keyboard_clear_focus(wlr_seat_keyboard_grab* grab) {
|
||||
static_cast<CFocusGrab*>(grab->data)->finish(true);
|
||||
}
|
||||
// static void focus_grab_keyboard_clear_focus(wlr_seat_keyboard_grab* grab) {
|
||||
// static_cast<CFocusGrab*>(grab->data)->finish(true);
|
||||
// }
|
||||
|
||||
static void focus_grab_keyboard_key(wlr_seat_keyboard_grab* grab, uint32_t time, uint32_t key, uint32_t state) {
|
||||
wlr_seat_keyboard_send_key(grab->seat, time, key, state);
|
||||
}
|
||||
// static void focus_grab_keyboard_key(wlr_seat_keyboard_grab* grab, uint32_t time, uint32_t key, uint32_t state) {
|
||||
// wlr_seat_keyboard_send_key(grab->seat, time, key, state);
|
||||
// }
|
||||
|
||||
static void focus_grab_keyboard_modifiers(wlr_seat_keyboard_grab* grab, const wlr_keyboard_modifiers* modifiers) {
|
||||
wlr_seat_keyboard_send_modifiers(grab->seat, modifiers);
|
||||
}
|
||||
// static void focus_grab_keyboard_modifiers(wlr_seat_keyboard_grab* grab, const wlr_keyboard_modifiers* modifiers) {
|
||||
// wlr_seat_keyboard_send_modifiers(grab->seat, modifiers);
|
||||
// }
|
||||
|
||||
static void focus_grab_keyboard_cancel(wlr_seat_keyboard_grab* grab) {
|
||||
static_cast<CFocusGrab*>(grab->data)->finish(true);
|
||||
}
|
||||
// static void focus_grab_keyboard_cancel(wlr_seat_keyboard_grab* grab) {
|
||||
// static_cast<CFocusGrab*>(grab->data)->finish(true);
|
||||
// }
|
||||
|
||||
static const wlr_keyboard_grab_interface focus_grab_keyboard_impl = {
|
||||
.enter = focus_grab_keyboard_enter,
|
||||
.clear_focus = focus_grab_keyboard_clear_focus,
|
||||
.key = focus_grab_keyboard_key,
|
||||
.modifiers = focus_grab_keyboard_modifiers,
|
||||
.cancel = focus_grab_keyboard_cancel,
|
||||
};
|
||||
// static const wlr_keyboard_grab_interface focus_grab_keyboard_impl = {
|
||||
// .enter = focus_grab_keyboard_enter,
|
||||
// .clear_focus = focus_grab_keyboard_clear_focus,
|
||||
// .key = focus_grab_keyboard_key,
|
||||
// .modifiers = focus_grab_keyboard_modifiers,
|
||||
// .cancel = focus_grab_keyboard_cancel,
|
||||
// };
|
||||
|
||||
static uint32_t focus_grab_touch_down(wlr_seat_touch_grab* grab, uint32_t time, wlr_touch_point* point) {
|
||||
if (!static_cast<CFocusGrab*>(grab->data)->isSurfaceComitted(point->surface))
|
||||
return 0;
|
||||
// static uint32_t focus_grab_touch_down(wlr_seat_touch_grab* grab, uint32_t time, wlr_touch_point* point) {
|
||||
// if (!static_cast<CFocusGrab*>(grab->data)->isSurfaceComitted(point->surface))
|
||||
// return 0;
|
||||
|
||||
return wlr_seat_touch_send_down(grab->seat, point->surface, time, point->touch_id, point->sx, point->sy);
|
||||
}
|
||||
// return wlr_seat_touch_send_down(grab->seat, point->surface, time, point->touch_id, point->sx, point->sy);
|
||||
// }
|
||||
|
||||
static void focus_grab_touch_up(wlr_seat_touch_grab* grab, uint32_t time, wlr_touch_point* point) {
|
||||
wlr_seat_touch_send_up(grab->seat, time, point->touch_id);
|
||||
}
|
||||
// static void focus_grab_touch_up(wlr_seat_touch_grab* grab, uint32_t time, wlr_touch_point* point) {
|
||||
// wlr_seat_touch_send_up(grab->seat, time, point->touch_id);
|
||||
// }
|
||||
|
||||
static void focus_grab_touch_motion(wlr_seat_touch_grab* grab, uint32_t time, wlr_touch_point* point) {
|
||||
wlr_seat_touch_send_motion(grab->seat, time, point->touch_id, point->sx, point->sy);
|
||||
}
|
||||
// static void focus_grab_touch_motion(wlr_seat_touch_grab* grab, uint32_t time, wlr_touch_point* point) {
|
||||
// wlr_seat_touch_send_motion(grab->seat, time, point->touch_id, point->sx, point->sy);
|
||||
// }
|
||||
|
||||
static void focus_grab_touch_enter(wlr_seat_touch_grab* grab, uint32_t time, wlr_touch_point* point) {}
|
||||
// static void focus_grab_touch_enter(wlr_seat_touch_grab* grab, uint32_t time, wlr_touch_point* point) {}
|
||||
|
||||
static void focus_grab_touch_frame(wlr_seat_touch_grab* grab) {
|
||||
wlr_seat_touch_send_frame(grab->seat);
|
||||
}
|
||||
// static void focus_grab_touch_frame(wlr_seat_touch_grab* grab) {
|
||||
// wlr_seat_touch_send_frame(grab->seat);
|
||||
// }
|
||||
|
||||
static void focus_grab_touch_cancel(wlr_seat_touch_grab* grab) {
|
||||
static_cast<CFocusGrab*>(grab->data)->finish(true);
|
||||
}
|
||||
// static void focus_grab_touch_cancel(wlr_seat_touch_grab* grab) {
|
||||
// static_cast<CFocusGrab*>(grab->data)->finish(true);
|
||||
// }
|
||||
|
||||
static const wlr_touch_grab_interface focus_grab_touch_impl = {
|
||||
.down = focus_grab_touch_down,
|
||||
.up = focus_grab_touch_up,
|
||||
.motion = focus_grab_touch_motion,
|
||||
.enter = focus_grab_touch_enter,
|
||||
.frame = focus_grab_touch_frame,
|
||||
.cancel = focus_grab_touch_cancel,
|
||||
};
|
||||
// static const wlr_touch_grab_interface focus_grab_touch_impl = {
|
||||
// .down = focus_grab_touch_down,
|
||||
// .up = focus_grab_touch_up,
|
||||
// .motion = focus_grab_touch_motion,
|
||||
// .enter = focus_grab_touch_enter,
|
||||
// .frame = focus_grab_touch_frame,
|
||||
// .cancel = focus_grab_touch_cancel,
|
||||
// };
|
||||
|
||||
CFocusGrabSurfaceState::CFocusGrabSurfaceState(CFocusGrab* grab, wlr_surface* surface) {
|
||||
hyprListener_surfaceDestroy.initCallback(
|
||||
|
|
@ -133,14 +134,14 @@ CFocusGrab::CFocusGrab(SP<CHyprlandFocusGrabV1> resource_) : resource(resource_)
|
|||
if (!resource->resource())
|
||||
return;
|
||||
|
||||
m_sPointerGrab.interface = &focus_grab_pointer_impl;
|
||||
m_sPointerGrab.data = this;
|
||||
// m_sPointerGrab.interface = &focus_grab_pointer_impl;
|
||||
// m_sPointerGrab.data = this;
|
||||
|
||||
m_sKeyboardGrab.interface = &focus_grab_keyboard_impl;
|
||||
m_sKeyboardGrab.data = this;
|
||||
// m_sKeyboardGrab.interface = &focus_grab_keyboard_impl;
|
||||
// m_sKeyboardGrab.data = this;
|
||||
|
||||
m_sTouchGrab.interface = &focus_grab_touch_impl;
|
||||
m_sTouchGrab.data = this;
|
||||
// m_sTouchGrab.interface = &focus_grab_touch_impl;
|
||||
// m_sTouchGrab.data = this;
|
||||
|
||||
resource->setDestroy([this](CHyprlandFocusGrabV1* pMgr) { PROTO::focusGrab->destroyGrab(this); });
|
||||
resource->setOnDestroy([this](CHyprlandFocusGrabV1* pMgr) { PROTO::focusGrab->destroyGrab(this); });
|
||||
|
|
@ -167,21 +168,21 @@ bool CFocusGrab::isSurfaceComitted(wlr_surface* surface) {
|
|||
|
||||
void CFocusGrab::start() {
|
||||
if (!m_bGrabActive) {
|
||||
wlr_seat_pointer_start_grab(g_pCompositor->m_sSeat.seat, &m_sPointerGrab);
|
||||
wlr_seat_keyboard_start_grab(g_pCompositor->m_sSeat.seat, &m_sKeyboardGrab);
|
||||
wlr_seat_touch_start_grab(g_pCompositor->m_sSeat.seat, &m_sTouchGrab);
|
||||
// wlr_seat_pointer_start_grab(g_pCompositor->m_sSeat.seat, &m_sPointerGrab);
|
||||
// wlr_seat_keyboard_start_grab(g_pCompositor->m_sSeat.seat, &m_sKeyboardGrab);
|
||||
// wlr_seat_touch_start_grab(g_pCompositor->m_sSeat.seat, &m_sTouchGrab);
|
||||
m_bGrabActive = true;
|
||||
|
||||
// Ensure the grab ends if another grab begins, including from xdg_popup::grab.
|
||||
|
||||
hyprListener_pointerGrabStarted.initCallback(
|
||||
&g_pCompositor->m_sSeat.seat->events.pointer_grab_begin, [this](void*, void*) { finish(true); }, this, "CFocusGrab");
|
||||
// hyprListener_pointerGrabStarted.initCallback(
|
||||
// &g_pCompositor->m_sSeat.seat->events.pointer_grab_begin, [this](void*, void*) { finish(true); }, this, "CFocusGrab");
|
||||
|
||||
hyprListener_keyboardGrabStarted.initCallback(
|
||||
&g_pCompositor->m_sSeat.seat->events.keyboard_grab_begin, [this](void*, void*) { finish(true); }, this, "CFocusGrab");
|
||||
// hyprListener_keyboardGrabStarted.initCallback(
|
||||
// &g_pCompositor->m_sSeat.seat->events.keyboard_grab_begin, [this](void*, void*) { finish(true); }, this, "CFocusGrab");
|
||||
|
||||
hyprListener_touchGrabStarted.initCallback(
|
||||
&g_pCompositor->m_sSeat.seat->events.touch_grab_begin, [this](void*, void*) { finish(true); }, this, "CFocusGrab");
|
||||
// hyprListener_touchGrabStarted.initCallback(
|
||||
// &g_pCompositor->m_sSeat.seat->events.touch_grab_begin, [this](void*, void*) { finish(true); }, this, "CFocusGrab");
|
||||
}
|
||||
|
||||
// Ensure new surfaces are focused if under the mouse when comitted.
|
||||
|
|
@ -192,28 +193,28 @@ void CFocusGrab::start() {
|
|||
void CFocusGrab::finish(bool sendCleared) {
|
||||
if (m_bGrabActive) {
|
||||
m_bGrabActive = false;
|
||||
hyprListener_pointerGrabStarted.removeCallback();
|
||||
hyprListener_keyboardGrabStarted.removeCallback();
|
||||
hyprListener_touchGrabStarted.removeCallback();
|
||||
// hyprListener_pointerGrabStarted.removeCallback();
|
||||
// hyprListener_keyboardGrabStarted.removeCallback();
|
||||
// hyprListener_touchGrabStarted.removeCallback();
|
||||
|
||||
// Only clear grabs that belong to this focus grab. When superseded by another grab
|
||||
// or xdg_popup grab we might not own the current grab.
|
||||
|
||||
bool hadGrab = false;
|
||||
if (g_pCompositor->m_sSeat.seat->pointer_state.grab == &m_sPointerGrab) {
|
||||
wlr_seat_pointer_end_grab(g_pCompositor->m_sSeat.seat);
|
||||
hadGrab = true;
|
||||
}
|
||||
// if (g_pCompositor->m_sSeat.seat->pointer_state.grab == &m_sPointerGrab) {
|
||||
// wlr_seat_pointer_end_grab(g_pCompositor->m_sSeat.seat);
|
||||
// hadGrab = true;
|
||||
// }
|
||||
|
||||
if (g_pCompositor->m_sSeat.seat->keyboard_state.grab == &m_sKeyboardGrab) {
|
||||
wlr_seat_keyboard_end_grab(g_pCompositor->m_sSeat.seat);
|
||||
hadGrab = true;
|
||||
}
|
||||
// if (g_pCompositor->m_sSeat.seat->keyboard_state.grab == &m_sKeyboardGrab) {
|
||||
// wlr_seat_keyboard_end_grab(g_pCompositor->m_sSeat.seat);
|
||||
// hadGrab = true;
|
||||
// }
|
||||
|
||||
if (g_pCompositor->m_sSeat.seat->touch_state.grab == &m_sTouchGrab) {
|
||||
wlr_seat_touch_end_grab(g_pCompositor->m_sSeat.seat);
|
||||
hadGrab = true;
|
||||
}
|
||||
// if (g_pCompositor->m_sSeat.seat->touch_state.grab == &m_sTouchGrab) {
|
||||
// wlr_seat_touch_end_grab(g_pCompositor->m_sSeat.seat);
|
||||
// hadGrab = true;
|
||||
// }
|
||||
|
||||
m_mSurfaces.clear();
|
||||
|
||||
|
|
@ -248,7 +249,7 @@ void CFocusGrab::eraseSurface(wlr_surface* surface) {
|
|||
}
|
||||
|
||||
void CFocusGrab::refocusKeyboard() {
|
||||
auto keyboardSurface = g_pCompositor->m_sSeat.seat->keyboard_state.focused_surface;
|
||||
auto keyboardSurface = g_pSeatManager->state.keyboardFocus;
|
||||
if (keyboardSurface != nullptr && isSurfaceComitted(keyboardSurface))
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -44,10 +44,10 @@ class CFocusGrab {
|
|||
|
||||
SP<CHyprlandFocusGrabV1> resource;
|
||||
std::unordered_map<wlr_surface*, UP<CFocusGrabSurfaceState>> m_mSurfaces;
|
||||
wlr_seat_pointer_grab m_sPointerGrab;
|
||||
wlr_seat_keyboard_grab m_sKeyboardGrab;
|
||||
wlr_seat_touch_grab m_sTouchGrab;
|
||||
bool m_bGrabActive = false;
|
||||
// wlr_seat_pointer_grab m_sPointerGrab;
|
||||
// wlr_seat_keyboard_grab m_sKeyboardGrab;
|
||||
// wlr_seat_touch_grab m_sTouchGrab;
|
||||
bool m_bGrabActive = false;
|
||||
|
||||
DYNLISTENER(pointerGrabStarted);
|
||||
DYNLISTENER(keyboardGrabStarted);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
#include "InputMethodV2.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
#include "../managers/SeatManager.hpp"
|
||||
#include "../devices/IKeyboard.hpp"
|
||||
#include <sys/mman.h>
|
||||
|
||||
#define LOGM PROTO::ime->protoLog
|
||||
|
|
@ -11,14 +13,12 @@ CInputMethodKeyboardGrabV2::CInputMethodKeyboardGrabV2(SP<CZwpInputMethodKeyboar
|
|||
resource->setRelease([this](CZwpInputMethodKeyboardGrabV2* r) { PROTO::ime->destroyResource(this); });
|
||||
resource->setOnDestroy([this](CZwpInputMethodKeyboardGrabV2* r) { PROTO::ime->destroyResource(this); });
|
||||
|
||||
const auto PKEYBOARD = wlr_seat_get_keyboard(g_pCompositor->m_sSeat.seat);
|
||||
|
||||
if (!PKEYBOARD) {
|
||||
if (!g_pSeatManager->keyboard) {
|
||||
LOGM(ERR, "IME called but no active keyboard???");
|
||||
return;
|
||||
}
|
||||
|
||||
sendKeyboardData(PKEYBOARD);
|
||||
sendKeyboardData(g_pSeatManager->keyboard->wlr());
|
||||
}
|
||||
|
||||
CInputMethodKeyboardGrabV2::~CInputMethodKeyboardGrabV2() {
|
||||
|
|
@ -60,13 +60,13 @@ void CInputMethodKeyboardGrabV2::sendKeyboardData(wlr_keyboard* keyboard) {
|
|||
}
|
||||
|
||||
void CInputMethodKeyboardGrabV2::sendKey(uint32_t time, uint32_t key, wl_keyboard_key_state state) {
|
||||
const auto SERIAL = wlr_seat_client_next_serial(wlr_seat_client_for_wl_client(g_pCompositor->m_sSeat.seat, resource->client()));
|
||||
const auto SERIAL = g_pSeatManager->nextSerial(g_pSeatManager->seatResourceForClient(resource->client()));
|
||||
|
||||
resource->sendKey(SERIAL, time, key, (uint32_t)state);
|
||||
}
|
||||
|
||||
void CInputMethodKeyboardGrabV2::sendMods(uint32_t depressed, uint32_t latched, uint32_t locked, uint32_t group) {
|
||||
const auto SERIAL = wlr_seat_client_next_serial(wlr_seat_client_for_wl_client(g_pCompositor->m_sSeat.seat, resource->client()));
|
||||
const auto SERIAL = g_pSeatManager->nextSerial(g_pSeatManager->seatResourceForClient(resource->client()));
|
||||
|
||||
resource->sendModifiers(SERIAL, depressed, latched, locked, group);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include "../desktop/WLSurface.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
#include "../config/ConfigValue.hpp"
|
||||
#include "../managers/SeatManager.hpp"
|
||||
|
||||
#define LOGM PROTO::constraints->protoLog
|
||||
|
||||
|
|
@ -125,10 +126,10 @@ void CPointerConstraint::activate() {
|
|||
return;
|
||||
|
||||
// TODO: hack, probably not a super duper great idea
|
||||
if (g_pCompositor->m_sSeat.seat->pointer_state.focused_surface != pHLSurface->wlr()) {
|
||||
if (g_pSeatManager->state.pointerFocus != pHLSurface->wlr()) {
|
||||
const auto SURFBOX = pHLSurface->getSurfaceBoxGlobal();
|
||||
const auto LOCAL = SURFBOX.has_value() ? logicPositionHint() - SURFBOX->pos() : Vector2D{};
|
||||
wlr_seat_pointer_enter(g_pCompositor->m_sSeat.seat, pHLSurface->wlr(), LOCAL.x, LOCAL.y);
|
||||
g_pSeatManager->setPointerFocus(pHLSurface->wlr(), LOCAL);
|
||||
}
|
||||
|
||||
if (locked)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
#include "PointerGestures.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
#include "../managers/SeatManager.hpp"
|
||||
#include "core/Seat.hpp"
|
||||
|
||||
#define LOGM PROTO::pointerGestures->protoLog
|
||||
|
||||
|
|
@ -103,26 +105,26 @@ void CPointerGesturesProtocol::onGetHoldGesture(CZwpPointerGesturesV1* pMgr, uin
|
|||
}
|
||||
|
||||
void CPointerGesturesProtocol::swipeBegin(uint32_t timeMs, uint32_t fingers) {
|
||||
if (!g_pCompositor->m_sSeat.seat->pointer_state.focused_client)
|
||||
if (!g_pSeatManager->state.pointerFocusResource)
|
||||
return;
|
||||
|
||||
const auto FOCUSEDCLIENT = g_pCompositor->m_sSeat.seat->pointer_state.focused_client->client;
|
||||
const auto FOCUSEDCLIENT = g_pSeatManager->state.pointerFocusResource->client();
|
||||
|
||||
const auto SERIAL = wlr_seat_client_next_serial(g_pCompositor->m_sSeat.seat->pointer_state.focused_client);
|
||||
const auto SERIAL = g_pSeatManager->nextSerial(g_pSeatManager->state.pointerFocusResource.lock());
|
||||
|
||||
for (auto& sw : m_vSwipes) {
|
||||
if (sw->resource->client() != FOCUSEDCLIENT)
|
||||
continue;
|
||||
|
||||
sw->resource->sendBegin(SERIAL, timeMs, g_pCompositor->m_sSeat.seat->pointer_state.focused_surface->resource, fingers);
|
||||
sw->resource->sendBegin(SERIAL, timeMs, g_pSeatManager->state.pointerFocus->resource, fingers);
|
||||
}
|
||||
}
|
||||
|
||||
void CPointerGesturesProtocol::swipeUpdate(uint32_t timeMs, const Vector2D& delta) {
|
||||
if (!g_pCompositor->m_sSeat.seat->pointer_state.focused_client)
|
||||
if (!g_pSeatManager->state.pointerFocusResource)
|
||||
return;
|
||||
|
||||
const auto FOCUSEDCLIENT = g_pCompositor->m_sSeat.seat->pointer_state.focused_client->client;
|
||||
const auto FOCUSEDCLIENT = g_pSeatManager->state.pointerFocusResource->client();
|
||||
|
||||
for (auto& sw : m_vSwipes) {
|
||||
if (sw->resource->client() != FOCUSEDCLIENT)
|
||||
|
|
@ -133,12 +135,12 @@ void CPointerGesturesProtocol::swipeUpdate(uint32_t timeMs, const Vector2D& delt
|
|||
}
|
||||
|
||||
void CPointerGesturesProtocol::swipeEnd(uint32_t timeMs, bool cancelled) {
|
||||
if (!g_pCompositor->m_sSeat.seat->pointer_state.focused_client)
|
||||
if (!g_pSeatManager->state.pointerFocusResource)
|
||||
return;
|
||||
|
||||
const auto FOCUSEDCLIENT = g_pCompositor->m_sSeat.seat->pointer_state.focused_client->client;
|
||||
const auto FOCUSEDCLIENT = g_pSeatManager->state.pointerFocusResource->client();
|
||||
|
||||
const auto SERIAL = wlr_seat_client_next_serial(g_pCompositor->m_sSeat.seat->pointer_state.focused_client);
|
||||
const auto SERIAL = g_pSeatManager->nextSerial(g_pSeatManager->state.pointerFocusResource.lock());
|
||||
|
||||
for (auto& sw : m_vSwipes) {
|
||||
if (sw->resource->client() != FOCUSEDCLIENT)
|
||||
|
|
@ -149,26 +151,26 @@ void CPointerGesturesProtocol::swipeEnd(uint32_t timeMs, bool cancelled) {
|
|||
}
|
||||
|
||||
void CPointerGesturesProtocol::pinchBegin(uint32_t timeMs, uint32_t fingers) {
|
||||
if (!g_pCompositor->m_sSeat.seat->pointer_state.focused_client)
|
||||
if (!g_pSeatManager->state.pointerFocusResource)
|
||||
return;
|
||||
|
||||
const auto FOCUSEDCLIENT = g_pCompositor->m_sSeat.seat->pointer_state.focused_client->client;
|
||||
const auto FOCUSEDCLIENT = g_pSeatManager->state.pointerFocusResource->client();
|
||||
|
||||
const auto SERIAL = wlr_seat_client_next_serial(g_pCompositor->m_sSeat.seat->pointer_state.focused_client);
|
||||
const auto SERIAL = g_pSeatManager->nextSerial(g_pSeatManager->state.pointerFocusResource.lock());
|
||||
|
||||
for (auto& sw : m_vPinches) {
|
||||
if (sw->resource->client() != FOCUSEDCLIENT)
|
||||
continue;
|
||||
|
||||
sw->resource->sendBegin(SERIAL, timeMs, g_pCompositor->m_sSeat.seat->pointer_state.focused_surface->resource, fingers);
|
||||
sw->resource->sendBegin(SERIAL, timeMs, g_pSeatManager->state.pointerFocus->resource, fingers);
|
||||
}
|
||||
}
|
||||
|
||||
void CPointerGesturesProtocol::pinchUpdate(uint32_t timeMs, const Vector2D& delta, double scale, double rotation) {
|
||||
if (!g_pCompositor->m_sSeat.seat->pointer_state.focused_client)
|
||||
if (!g_pSeatManager->state.pointerFocusResource)
|
||||
return;
|
||||
|
||||
const auto FOCUSEDCLIENT = g_pCompositor->m_sSeat.seat->pointer_state.focused_client->client;
|
||||
const auto FOCUSEDCLIENT = g_pSeatManager->state.pointerFocusResource->client();
|
||||
|
||||
for (auto& sw : m_vPinches) {
|
||||
if (sw->resource->client() != FOCUSEDCLIENT)
|
||||
|
|
@ -179,12 +181,12 @@ void CPointerGesturesProtocol::pinchUpdate(uint32_t timeMs, const Vector2D& delt
|
|||
}
|
||||
|
||||
void CPointerGesturesProtocol::pinchEnd(uint32_t timeMs, bool cancelled) {
|
||||
if (!g_pCompositor->m_sSeat.seat->pointer_state.focused_client)
|
||||
if (!g_pSeatManager->state.pointerFocusResource)
|
||||
return;
|
||||
|
||||
const auto FOCUSEDCLIENT = g_pCompositor->m_sSeat.seat->pointer_state.focused_client->client;
|
||||
const auto FOCUSEDCLIENT = g_pSeatManager->state.pointerFocusResource->client();
|
||||
|
||||
const auto SERIAL = wlr_seat_client_next_serial(g_pCompositor->m_sSeat.seat->pointer_state.focused_client);
|
||||
const auto SERIAL = g_pSeatManager->nextSerial(g_pSeatManager->state.pointerFocusResource.lock());
|
||||
|
||||
for (auto& sw : m_vPinches) {
|
||||
if (sw->resource->client() != FOCUSEDCLIENT)
|
||||
|
|
@ -195,28 +197,28 @@ void CPointerGesturesProtocol::pinchEnd(uint32_t timeMs, bool cancelled) {
|
|||
}
|
||||
|
||||
void CPointerGesturesProtocol::holdBegin(uint32_t timeMs, uint32_t fingers) {
|
||||
if (!g_pCompositor->m_sSeat.seat->pointer_state.focused_client)
|
||||
if (!g_pSeatManager->state.pointerFocusResource)
|
||||
return;
|
||||
|
||||
const auto FOCUSEDCLIENT = g_pCompositor->m_sSeat.seat->pointer_state.focused_client->client;
|
||||
const auto FOCUSEDCLIENT = g_pSeatManager->state.pointerFocusResource->client();
|
||||
|
||||
const auto SERIAL = wlr_seat_client_next_serial(g_pCompositor->m_sSeat.seat->pointer_state.focused_client);
|
||||
const auto SERIAL = g_pSeatManager->nextSerial(g_pSeatManager->state.pointerFocusResource.lock());
|
||||
|
||||
for (auto& sw : m_vHolds) {
|
||||
if (sw->resource->client() != FOCUSEDCLIENT)
|
||||
continue;
|
||||
|
||||
sw->resource->sendBegin(SERIAL, timeMs, g_pCompositor->m_sSeat.seat->pointer_state.focused_surface->resource, fingers);
|
||||
sw->resource->sendBegin(SERIAL, timeMs, g_pSeatManager->state.pointerFocus->resource, fingers);
|
||||
}
|
||||
}
|
||||
|
||||
void CPointerGesturesProtocol::holdEnd(uint32_t timeMs, bool cancelled) {
|
||||
if (!g_pCompositor->m_sSeat.seat->pointer_state.focused_client)
|
||||
if (!g_pSeatManager->state.pointerFocusResource)
|
||||
return;
|
||||
|
||||
const auto FOCUSEDCLIENT = g_pCompositor->m_sSeat.seat->pointer_state.focused_client->client;
|
||||
const auto FOCUSEDCLIENT = g_pSeatManager->state.pointerFocusResource->client();
|
||||
|
||||
const auto SERIAL = wlr_seat_client_next_serial(g_pCompositor->m_sSeat.seat->pointer_state.focused_client);
|
||||
const auto SERIAL = g_pSeatManager->nextSerial(g_pSeatManager->state.pointerFocusResource.lock());
|
||||
|
||||
for (auto& sw : m_vHolds) {
|
||||
if (sw->resource->client() != FOCUSEDCLIENT)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
#include "RelativePointer.hpp"
|
||||
#include "Compositor.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
#include "../managers/SeatManager.hpp"
|
||||
#include "core/Seat.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
CRelativePointer::CRelativePointer(SP<CZwpRelativePointerV1> resource_) : resource(resource_) {
|
||||
|
|
@ -58,10 +60,10 @@ void CRelativePointerProtocol::onGetRelativePointer(CZwpRelativePointerManagerV1
|
|||
|
||||
void CRelativePointerProtocol::sendRelativeMotion(uint64_t time, const Vector2D& delta, const Vector2D& deltaUnaccel) {
|
||||
|
||||
if (!g_pCompositor->m_sSeat.seat->pointer_state.focused_client)
|
||||
if (!g_pSeatManager->state.pointerFocusResource)
|
||||
return;
|
||||
|
||||
const auto FOCUSED = g_pCompositor->m_sSeat.seat->pointer_state.focused_client->client;
|
||||
const auto FOCUSED = g_pSeatManager->state.pointerFocusResource->client();
|
||||
|
||||
for (auto& rp : m_vRelativePointers) {
|
||||
if (FOCUSED != rp->client())
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "SessionLock.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
#include "../managers/SeatManager.hpp"
|
||||
#include "FractionalScale.hpp"
|
||||
|
||||
#define LOGM PROTO::sessionLock->protoLog
|
||||
|
|
@ -76,7 +77,7 @@ CSessionLockSurface::~CSessionLockSurface() {
|
|||
}
|
||||
|
||||
void CSessionLockSurface::sendConfigure() {
|
||||
const auto SERIAL = wlr_seat_client_next_serial(wlr_seat_client_for_wl_client(g_pCompositor->m_sSeat.seat, resource->client()));
|
||||
const auto SERIAL = g_pSeatManager->nextSerial(g_pSeatManager->seatResourceForClient(resource->client()));
|
||||
resource->sendConfigure(SERIAL, pMonitor->vecSize.x, pMonitor->vecSize.y);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#include "Tablet.hpp"
|
||||
#include "../devices/Tablet.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
#include "../managers/SeatManager.hpp"
|
||||
#include "core/Seat.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
#define LOGM PROTO::tablet->protoLog
|
||||
|
|
@ -159,12 +161,10 @@ CTabletToolV2Resource::CTabletToolV2Resource(SP<CZwpTabletToolV2> resource_, SP<
|
|||
resource->setOnDestroy([this](CZwpTabletToolV2* r) { PROTO::tablet->destroyResource(this); });
|
||||
|
||||
resource->setSetCursor([this](CZwpTabletToolV2* r, uint32_t serial, wl_resource* surf, int32_t hot_x, int32_t hot_y) {
|
||||
wlr_seat_pointer_request_set_cursor_event e;
|
||||
e.hotspot_x = hot_x;
|
||||
e.hotspot_y = hot_y;
|
||||
e.surface = surf ? wlr_surface_from_resource(surf) : nullptr;
|
||||
e.serial = serial;
|
||||
g_pInputManager->processMouseRequest(&e);
|
||||
if (!g_pSeatManager->state.pointerFocusResource || g_pSeatManager->state.pointerFocusResource->client() != r->client())
|
||||
return;
|
||||
|
||||
g_pInputManager->processMouseRequest(CSeatManager::SSetCursorEvent{wlr_surface_from_resource(surf), {hot_x, hot_y}});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -539,7 +539,7 @@ void CTabletV2Protocol::down(SP<CTabletTool> tool) {
|
|||
if (t->tool != tool || !t->current)
|
||||
continue;
|
||||
|
||||
auto serial = wlr_seat_client_next_serial(wlr_seat_client_for_wl_client(g_pCompositor->m_sSeat.seat, t->resource->client()));
|
||||
auto serial = g_pSeatManager->nextSerial(g_pSeatManager->seatResourceForClient(t->resource->client()));
|
||||
t->resource->sendDown(serial);
|
||||
t->queueFrame();
|
||||
}
|
||||
|
|
@ -586,7 +586,7 @@ void CTabletV2Protocol::proximityIn(SP<CTabletTool> tool, SP<CTablet> tablet, wl
|
|||
toolResource->current = true;
|
||||
toolResource->lastSurf = surf;
|
||||
|
||||
auto serial = wlr_seat_client_next_serial(wlr_seat_client_for_wl_client(g_pCompositor->m_sSeat.seat, toolResource->resource->client()));
|
||||
auto serial = g_pSeatManager->nextSerial(g_pSeatManager->seatResourceForClient(toolResource->resource->client()));
|
||||
toolResource->resource->sendProximityIn(serial, tabletResource->resource.get(), surf->resource);
|
||||
toolResource->queueFrame();
|
||||
|
||||
|
|
@ -610,7 +610,7 @@ void CTabletV2Protocol::buttonTool(SP<CTabletTool> tool, uint32_t button, uint32
|
|||
if (t->tool != tool || !t->current)
|
||||
continue;
|
||||
|
||||
auto serial = wlr_seat_client_next_serial(wlr_seat_client_for_wl_client(g_pCompositor->m_sSeat.seat, t->resource->client()));
|
||||
auto serial = g_pSeatManager->nextSerial(g_pSeatManager->seatResourceForClient(t->resource->client()));
|
||||
t->resource->sendButton(serial, button, (zwpTabletToolV2ButtonState)state);
|
||||
t->queueFrame();
|
||||
}
|
||||
|
|
@ -634,7 +634,7 @@ void CTabletV2Protocol::mode(SP<CTabletPad> pad, uint32_t group, uint32_t mode,
|
|||
LOGM(ERR, "BUG THIS: group >= t->groups.size()");
|
||||
return;
|
||||
}
|
||||
auto serial = wlr_seat_client_next_serial(wlr_seat_client_for_wl_client(g_pCompositor->m_sSeat.seat, t->resource->client()));
|
||||
auto serial = g_pSeatManager->nextSerial(g_pSeatManager->seatResourceForClient(t->resource->client()));
|
||||
t->groups.at(group)->resource->sendModeSwitch(timeMs, serial, mode);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
437
src/protocols/core/Seat.cpp
Normal file
437
src/protocols/core/Seat.cpp
Normal file
|
|
@ -0,0 +1,437 @@
|
|||
#include "Seat.hpp"
|
||||
#include "../../devices/IKeyboard.hpp"
|
||||
#include "../../managers/SeatManager.hpp"
|
||||
#include "../../config/ConfigValue.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
#define LOGM PROTO::seat->protoLog
|
||||
|
||||
CWLTouchResource::CWLTouchResource(SP<CWlTouch> resource_, SP<CWLSeatResource> owner_) : owner(owner_), resource(resource_) {
|
||||
if (!good())
|
||||
return;
|
||||
|
||||
resource->setRelease([this](CWlTouch* r) { PROTO::seat->destroyResource(this); });
|
||||
resource->setOnDestroy([this](CWlTouch* r) { PROTO::seat->destroyResource(this); });
|
||||
}
|
||||
|
||||
bool CWLTouchResource::good() {
|
||||
return resource->resource();
|
||||
}
|
||||
|
||||
void CWLTouchResource::sendDown(wlr_surface* surface, uint32_t timeMs, int32_t id, const Vector2D& local) {
|
||||
if (!owner)
|
||||
return;
|
||||
|
||||
if (currentSurface) {
|
||||
LOGM(WARN, "requested CWLTouchResource::sendDown without sendUp first.");
|
||||
sendUp(timeMs, id);
|
||||
}
|
||||
|
||||
ASSERT(wl_resource_get_client(surface->resource) == owner->client());
|
||||
|
||||
currentSurface = surface;
|
||||
hyprListener_surfaceDestroy.initCallback(
|
||||
&surface->events.destroy, [this, id, timeMs](void* owner, void* data) { sendUp(timeMs + 10 /* hack */, id); }, this, "CWLTouchResource");
|
||||
|
||||
// FIXME:
|
||||
// fix this once we get our own wlr_surface, this is horrible
|
||||
resource->sendDownRaw(g_pSeatManager->nextSerial(owner.lock()), timeMs, surface->resource, id, wl_fixed_from_double(local.x), wl_fixed_from_double(local.y));
|
||||
}
|
||||
|
||||
void CWLTouchResource::sendUp(uint32_t timeMs, int32_t id) {
|
||||
if (!owner || !currentSurface)
|
||||
return;
|
||||
|
||||
resource->sendUp(g_pSeatManager->nextSerial(owner.lock()), timeMs, id);
|
||||
currentSurface = nullptr;
|
||||
hyprListener_surfaceDestroy.removeCallback();
|
||||
}
|
||||
|
||||
void CWLTouchResource::sendMotion(uint32_t timeMs, int32_t id, const Vector2D& local) {
|
||||
if (!owner || !currentSurface)
|
||||
return;
|
||||
|
||||
resource->sendMotion(timeMs, id, wl_fixed_from_double(local.x), wl_fixed_from_double(local.y));
|
||||
}
|
||||
|
||||
void CWLTouchResource::sendFrame() {
|
||||
if (!owner || !currentSurface)
|
||||
return;
|
||||
|
||||
resource->sendFrame();
|
||||
}
|
||||
|
||||
void CWLTouchResource::sendCancel() {
|
||||
if (!owner || !currentSurface)
|
||||
return;
|
||||
|
||||
resource->sendCancel();
|
||||
}
|
||||
|
||||
void CWLTouchResource::sendShape(int32_t id, const Vector2D& shape) {
|
||||
if (!owner || !currentSurface || resource->version() < 6)
|
||||
return;
|
||||
|
||||
resource->sendShape(id, wl_fixed_from_double(shape.x), wl_fixed_from_double(shape.y));
|
||||
}
|
||||
|
||||
void CWLTouchResource::sendOrientation(int32_t id, double angle) {
|
||||
if (!owner || !currentSurface || resource->version() < 6)
|
||||
return;
|
||||
|
||||
resource->sendOrientation(id, wl_fixed_from_double(angle));
|
||||
}
|
||||
|
||||
CWLPointerResource::CWLPointerResource(SP<CWlPointer> resource_, SP<CWLSeatResource> owner_) : owner(owner_), resource(resource_) {
|
||||
if (!good())
|
||||
return;
|
||||
|
||||
resource->setRelease([this](CWlPointer* r) { PROTO::seat->destroyResource(this); });
|
||||
resource->setOnDestroy([this](CWlPointer* r) { PROTO::seat->destroyResource(this); });
|
||||
|
||||
resource->setSetCursor([this](CWlPointer* r, uint32_t serial, wl_resource* surf, int32_t hotX, int32_t hotY) {
|
||||
if (!owner) {
|
||||
LOGM(ERR, "Client bug: setCursor when seatClient is already dead");
|
||||
return;
|
||||
}
|
||||
|
||||
g_pSeatManager->onSetCursor(owner.lock(), serial, surf ? wlr_surface_from_resource(surf) : nullptr, {hotX, hotY});
|
||||
});
|
||||
}
|
||||
|
||||
bool CWLPointerResource::good() {
|
||||
return resource->resource();
|
||||
}
|
||||
|
||||
void CWLPointerResource::sendEnter(wlr_surface* surface, const Vector2D& local) {
|
||||
if (!owner || currentSurface == surface)
|
||||
return;
|
||||
|
||||
if (currentSurface) {
|
||||
LOGM(WARN, "requested CWLPointerResource::sendEnter without sendLeave first.");
|
||||
sendLeave();
|
||||
}
|
||||
|
||||
ASSERT(wl_resource_get_client(surface->resource) == owner->client());
|
||||
|
||||
currentSurface = surface;
|
||||
hyprListener_surfaceDestroy.initCallback(
|
||||
&surface->events.destroy, [this](void* owner, void* data) { sendLeave(); }, this, "CWLPointerResource");
|
||||
|
||||
resource->sendEnterRaw(g_pSeatManager->nextSerial(owner.lock()), surface->resource, wl_fixed_from_double(local.x), wl_fixed_from_double(local.y));
|
||||
}
|
||||
|
||||
void CWLPointerResource::sendLeave() {
|
||||
if (!owner || !currentSurface)
|
||||
return;
|
||||
|
||||
resource->sendLeaveRaw(g_pSeatManager->nextSerial(owner.lock()), currentSurface->resource);
|
||||
currentSurface = nullptr;
|
||||
hyprListener_surfaceDestroy.removeCallback();
|
||||
}
|
||||
|
||||
void CWLPointerResource::sendMotion(uint32_t timeMs, const Vector2D& local) {
|
||||
if (!owner || !currentSurface)
|
||||
return;
|
||||
|
||||
resource->sendMotion(timeMs, wl_fixed_from_double(local.x), wl_fixed_from_double(local.y));
|
||||
}
|
||||
|
||||
void CWLPointerResource::sendButton(uint32_t timeMs, uint32_t button, wl_pointer_button_state state) {
|
||||
if (!owner || !currentSurface)
|
||||
return;
|
||||
|
||||
resource->sendButton(g_pSeatManager->nextSerial(owner.lock()), timeMs, button, state);
|
||||
}
|
||||
|
||||
void CWLPointerResource::sendAxis(uint32_t timeMs, wl_pointer_axis axis, double value) {
|
||||
if (!owner || !currentSurface)
|
||||
return;
|
||||
|
||||
resource->sendAxis(timeMs, axis, wl_fixed_from_double(value));
|
||||
}
|
||||
|
||||
void CWLPointerResource::sendFrame() {
|
||||
if (!owner || resource->version() < 5)
|
||||
return;
|
||||
|
||||
resource->sendFrame();
|
||||
}
|
||||
|
||||
void CWLPointerResource::sendAxisSource(wl_pointer_axis_source source) {
|
||||
if (!owner || !currentSurface || resource->version() < 5)
|
||||
return;
|
||||
|
||||
resource->sendAxisSource(source);
|
||||
}
|
||||
|
||||
void CWLPointerResource::sendAxisStop(uint32_t timeMs, wl_pointer_axis axis) {
|
||||
if (!owner || !currentSurface || resource->version() < 5)
|
||||
return;
|
||||
|
||||
resource->sendAxisStop(timeMs, axis);
|
||||
}
|
||||
|
||||
void CWLPointerResource::sendAxisDiscrete(wl_pointer_axis axis, int32_t discrete) {
|
||||
if (!owner || !currentSurface || resource->version() < 5)
|
||||
return;
|
||||
|
||||
resource->sendAxisDiscrete(axis, discrete);
|
||||
}
|
||||
|
||||
void CWLPointerResource::sendAxisValue120(wl_pointer_axis axis, int32_t value120) {
|
||||
if (!owner || !currentSurface || resource->version() < 8)
|
||||
return;
|
||||
|
||||
resource->sendAxisValue120(axis, value120);
|
||||
}
|
||||
|
||||
void CWLPointerResource::sendAxisRelativeDirection(wl_pointer_axis axis, wl_pointer_axis_relative_direction direction) {
|
||||
if (!owner || !currentSurface || resource->version() < 9)
|
||||
return;
|
||||
|
||||
resource->sendAxisRelativeDirection(axis, direction);
|
||||
}
|
||||
|
||||
CWLKeyboardResource::CWLKeyboardResource(SP<CWlKeyboard> resource_, SP<CWLSeatResource> owner_) : owner(owner_), resource(resource_) {
|
||||
if (!good())
|
||||
return;
|
||||
|
||||
resource->setRelease([this](CWlKeyboard* r) { PROTO::seat->destroyResource(this); });
|
||||
resource->setOnDestroy([this](CWlKeyboard* r) { PROTO::seat->destroyResource(this); });
|
||||
|
||||
static auto REPEAT = CConfigValue<Hyprlang::INT>("input:repeat_rate");
|
||||
static auto DELAY = CConfigValue<Hyprlang::INT>("input:repeat_delay");
|
||||
sendKeymap(g_pSeatManager->keyboard.lock());
|
||||
repeatInfo(*REPEAT, *DELAY);
|
||||
}
|
||||
|
||||
bool CWLKeyboardResource::good() {
|
||||
return resource->resource();
|
||||
}
|
||||
|
||||
void CWLKeyboardResource::sendKeymap(SP<IKeyboard> keyboard) {
|
||||
wl_keyboard_keymap_format format = keyboard ? WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1 : WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP;
|
||||
int fd;
|
||||
uint32_t size;
|
||||
if (keyboard) {
|
||||
fd = keyboard->wlr()->keymap_fd;
|
||||
size = keyboard->wlr()->keymap_size;
|
||||
} else {
|
||||
fd = open("/dev/null", O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
LOGM(ERR, "Failed to open /dev/null");
|
||||
return;
|
||||
}
|
||||
size = 0;
|
||||
}
|
||||
|
||||
resource->sendKeymap(format, fd, size);
|
||||
|
||||
if (!keyboard)
|
||||
close(fd);
|
||||
}
|
||||
|
||||
void CWLKeyboardResource::sendEnter(wlr_surface* surface) {
|
||||
if (!owner || currentSurface == surface)
|
||||
return;
|
||||
|
||||
if (currentSurface) {
|
||||
LOGM(WARN, "requested CWLKeyboardResource::sendEnter without sendLeave first.");
|
||||
sendLeave();
|
||||
}
|
||||
|
||||
ASSERT(wl_resource_get_client(surface->resource) == owner->client());
|
||||
|
||||
currentSurface = surface;
|
||||
hyprListener_surfaceDestroy.initCallback(
|
||||
&surface->events.destroy, [this](void* owner, void* data) { sendLeave(); }, this, "CWLKeyboardResource");
|
||||
|
||||
wl_array arr;
|
||||
wl_array_init(&arr);
|
||||
|
||||
resource->sendEnterRaw(g_pSeatManager->nextSerial(owner.lock()), surface->resource, &arr);
|
||||
|
||||
wl_array_release(&arr);
|
||||
}
|
||||
|
||||
void CWLKeyboardResource::sendLeave() {
|
||||
if (!owner || !currentSurface)
|
||||
return;
|
||||
|
||||
resource->sendLeaveRaw(g_pSeatManager->nextSerial(owner.lock()), currentSurface->resource);
|
||||
currentSurface = nullptr;
|
||||
hyprListener_surfaceDestroy.removeCallback();
|
||||
}
|
||||
|
||||
void CWLKeyboardResource::sendKey(uint32_t timeMs, uint32_t key, wl_keyboard_key_state state) {
|
||||
if (!owner || !currentSurface)
|
||||
return;
|
||||
|
||||
resource->sendKey(g_pSeatManager->nextSerial(owner.lock()), timeMs, key, state);
|
||||
}
|
||||
|
||||
void CWLKeyboardResource::sendMods(uint32_t depressed, uint32_t latched, uint32_t locked, uint32_t group) {
|
||||
if (!owner || !currentSurface)
|
||||
return;
|
||||
|
||||
resource->sendModifiers(g_pSeatManager->nextSerial(owner.lock()), depressed, latched, locked, group);
|
||||
}
|
||||
|
||||
void CWLKeyboardResource::repeatInfo(uint32_t rate, uint32_t delayMs) {
|
||||
if (!owner || resource->version() < 4)
|
||||
return;
|
||||
|
||||
resource->sendRepeatInfo(rate, delayMs);
|
||||
}
|
||||
|
||||
CWLSeatResource::CWLSeatResource(SP<CWlSeat> resource_) : resource(resource_) {
|
||||
if (!good())
|
||||
return;
|
||||
|
||||
resource->setOnDestroy([this](CWlSeat* r) {
|
||||
events.destroy.emit();
|
||||
PROTO::seat->destroyResource(this);
|
||||
});
|
||||
resource->setRelease([this](CWlSeat* r) {
|
||||
events.destroy.emit();
|
||||
PROTO::seat->destroyResource(this);
|
||||
});
|
||||
|
||||
pClient = resource->client();
|
||||
|
||||
resource->setGetKeyboard([this](CWlSeat* r, uint32_t id) {
|
||||
const auto RESOURCE = PROTO::seat->m_vKeyboards.emplace_back(makeShared<CWLKeyboardResource>(makeShared<CWlKeyboard>(r->client(), r->version(), id), self.lock()));
|
||||
|
||||
if (!RESOURCE->good()) {
|
||||
r->noMemory();
|
||||
PROTO::seat->m_vKeyboards.pop_back();
|
||||
return;
|
||||
}
|
||||
|
||||
keyboards.push_back(RESOURCE);
|
||||
});
|
||||
|
||||
resource->setGetPointer([this](CWlSeat* r, uint32_t id) {
|
||||
const auto RESOURCE = PROTO::seat->m_vPointers.emplace_back(makeShared<CWLPointerResource>(makeShared<CWlPointer>(r->client(), r->version(), id), self.lock()));
|
||||
|
||||
if (!RESOURCE->good()) {
|
||||
r->noMemory();
|
||||
PROTO::seat->m_vPointers.pop_back();
|
||||
return;
|
||||
}
|
||||
|
||||
pointers.push_back(RESOURCE);
|
||||
});
|
||||
|
||||
resource->setGetTouch([this](CWlSeat* r, uint32_t id) {
|
||||
const auto RESOURCE = PROTO::seat->m_vTouches.emplace_back(makeShared<CWLTouchResource>(makeShared<CWlTouch>(r->client(), r->version(), id), self.lock()));
|
||||
|
||||
if (!RESOURCE->good()) {
|
||||
r->noMemory();
|
||||
PROTO::seat->m_vTouches.pop_back();
|
||||
return;
|
||||
}
|
||||
|
||||
touches.push_back(RESOURCE);
|
||||
});
|
||||
|
||||
if (resource->version() >= 2)
|
||||
resource->sendName(HL_SEAT_NAME);
|
||||
|
||||
sendCapabilities(PROTO::seat->currentCaps);
|
||||
}
|
||||
|
||||
CWLSeatResource::~CWLSeatResource() {
|
||||
events.destroy.emit();
|
||||
}
|
||||
|
||||
void CWLSeatResource::sendCapabilities(uint32_t caps) {
|
||||
uint32_t wlCaps = 0;
|
||||
if (caps & eHIDCapabilityType::HID_INPUT_CAPABILITY_KEYBOARD)
|
||||
wlCaps |= WL_SEAT_CAPABILITY_KEYBOARD;
|
||||
if (caps & eHIDCapabilityType::HID_INPUT_CAPABILITY_POINTER)
|
||||
wlCaps |= WL_SEAT_CAPABILITY_POINTER;
|
||||
if (caps & eHIDCapabilityType::HID_INPUT_CAPABILITY_TOUCH)
|
||||
wlCaps |= WL_SEAT_CAPABILITY_TOUCH;
|
||||
|
||||
resource->sendCapabilities((wl_seat_capability)wlCaps);
|
||||
}
|
||||
|
||||
bool CWLSeatResource::good() {
|
||||
return resource->resource();
|
||||
}
|
||||
|
||||
wl_client* CWLSeatResource::client() {
|
||||
return pClient;
|
||||
}
|
||||
|
||||
CWLSeatProtocol::CWLSeatProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
|
||||
;
|
||||
}
|
||||
|
||||
void CWLSeatProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
|
||||
const auto RESOURCE = m_vSeatResources.emplace_back(makeShared<CWLSeatResource>(makeShared<CWlSeat>(client, ver, id)));
|
||||
|
||||
if (!RESOURCE->good()) {
|
||||
wl_client_post_no_memory(client);
|
||||
m_vSeatResources.pop_back();
|
||||
return;
|
||||
}
|
||||
|
||||
RESOURCE->self = RESOURCE;
|
||||
|
||||
LOGM(LOG, "New seat resource bound at {:x}", (uintptr_t)RESOURCE.get());
|
||||
|
||||
events.newSeatResource.emit(RESOURCE);
|
||||
}
|
||||
|
||||
void CWLSeatProtocol::destroyResource(CWLSeatResource* seat) {
|
||||
std::erase_if(m_vSeatResources, [&](const auto& other) { return other.get() == seat; });
|
||||
}
|
||||
|
||||
void CWLSeatProtocol::destroyResource(CWLKeyboardResource* resource) {
|
||||
std::erase_if(m_vKeyboards, [&](const auto& other) { return other.get() == resource; });
|
||||
}
|
||||
|
||||
void CWLSeatProtocol::destroyResource(CWLPointerResource* resource) {
|
||||
std::erase_if(m_vPointers, [&](const auto& other) { return other.get() == resource; });
|
||||
}
|
||||
|
||||
void CWLSeatProtocol::destroyResource(CWLTouchResource* resource) {
|
||||
std::erase_if(m_vTouches, [&](const auto& other) { return other.get() == resource; });
|
||||
}
|
||||
|
||||
void CWLSeatProtocol::updateCapabilities(uint32_t caps) {
|
||||
if (caps == currentCaps)
|
||||
return;
|
||||
|
||||
currentCaps = caps;
|
||||
|
||||
for (auto& s : m_vSeatResources) {
|
||||
s->sendCapabilities(caps);
|
||||
}
|
||||
}
|
||||
|
||||
void CWLSeatProtocol::updateKeymap() {
|
||||
for (auto& k : m_vKeyboards) {
|
||||
k->sendKeymap(g_pSeatManager->keyboard.lock());
|
||||
}
|
||||
}
|
||||
|
||||
void CWLSeatProtocol::updateRepeatInfo(uint32_t rate, uint32_t delayMs) {
|
||||
for (auto& k : m_vKeyboards) {
|
||||
k->repeatInfo(rate, delayMs);
|
||||
}
|
||||
}
|
||||
|
||||
SP<CWLSeatResource> CWLSeatProtocol::seatResourceForClient(wl_client* client) {
|
||||
for (auto& r : m_vSeatResources) {
|
||||
if (r->client() == client)
|
||||
return r;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
163
src/protocols/core/Seat.hpp
Normal file
163
src/protocols/core/Seat.hpp
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
#pragma once
|
||||
|
||||
/*
|
||||
Implementations for:
|
||||
- wl_seat
|
||||
- wl_keyboard
|
||||
- wl_pointer
|
||||
- wl_touch
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include "../WaylandProtocol.hpp"
|
||||
#include <wayland-server-protocol.h>
|
||||
#include "wayland.hpp"
|
||||
#include "../../helpers/signal/Signal.hpp"
|
||||
#include "../../helpers/Vector2D.hpp"
|
||||
|
||||
constexpr const char* HL_SEAT_NAME = "Hyprland";
|
||||
|
||||
class IKeyboard;
|
||||
|
||||
class CWLPointerResource;
|
||||
class CWLKeyboardResource;
|
||||
class CWLTouchResource;
|
||||
class CWLSeatResource;
|
||||
|
||||
class CWLTouchResource {
|
||||
public:
|
||||
CWLTouchResource(SP<CWlTouch> resource_, SP<CWLSeatResource> owner_);
|
||||
|
||||
bool good();
|
||||
void sendDown(wlr_surface* surface, uint32_t timeMs, int32_t id, const Vector2D& local);
|
||||
void sendUp(uint32_t timeMs, int32_t id);
|
||||
void sendMotion(uint32_t timeMs, int32_t id, const Vector2D& local);
|
||||
void sendFrame();
|
||||
void sendCancel();
|
||||
void sendShape(int32_t id, const Vector2D& shape);
|
||||
void sendOrientation(int32_t id, double angle);
|
||||
|
||||
WP<CWLSeatResource> owner;
|
||||
|
||||
private:
|
||||
SP<CWlTouch> resource;
|
||||
wlr_surface* currentSurface = nullptr;
|
||||
|
||||
DYNLISTENER(surfaceDestroy);
|
||||
};
|
||||
|
||||
class CWLPointerResource {
|
||||
public:
|
||||
CWLPointerResource(SP<CWlPointer> resource_, SP<CWLSeatResource> owner_);
|
||||
|
||||
bool good();
|
||||
void sendEnter(wlr_surface* surface, const Vector2D& local);
|
||||
void sendLeave();
|
||||
void sendMotion(uint32_t timeMs, const Vector2D& local);
|
||||
void sendButton(uint32_t timeMs, uint32_t button, wl_pointer_button_state state);
|
||||
void sendAxis(uint32_t timeMs, wl_pointer_axis axis, double value);
|
||||
void sendFrame();
|
||||
void sendAxisSource(wl_pointer_axis_source source);
|
||||
void sendAxisStop(uint32_t timeMs, wl_pointer_axis axis);
|
||||
void sendAxisDiscrete(wl_pointer_axis axis, int32_t discrete);
|
||||
void sendAxisValue120(wl_pointer_axis axis, int32_t value120);
|
||||
void sendAxisRelativeDirection(wl_pointer_axis axis, wl_pointer_axis_relative_direction direction);
|
||||
|
||||
WP<CWLSeatResource> owner;
|
||||
|
||||
private:
|
||||
SP<CWlPointer> resource;
|
||||
wlr_surface* currentSurface = nullptr;
|
||||
|
||||
DYNLISTENER(surfaceDestroy);
|
||||
};
|
||||
|
||||
class CWLKeyboardResource {
|
||||
public:
|
||||
CWLKeyboardResource(SP<CWlKeyboard> resource_, SP<CWLSeatResource> owner_);
|
||||
|
||||
bool good();
|
||||
void sendKeymap(SP<IKeyboard> keeb);
|
||||
void sendEnter(wlr_surface* surface);
|
||||
void sendLeave();
|
||||
void sendKey(uint32_t timeMs, uint32_t key, wl_keyboard_key_state state);
|
||||
void sendMods(uint32_t depressed, uint32_t latched, uint32_t locked, uint32_t group);
|
||||
void repeatInfo(uint32_t rate, uint32_t delayMs);
|
||||
|
||||
WP<CWLSeatResource> owner;
|
||||
|
||||
private:
|
||||
SP<CWlKeyboard> resource;
|
||||
wlr_surface* currentSurface = nullptr;
|
||||
|
||||
DYNLISTENER(surfaceDestroy);
|
||||
};
|
||||
|
||||
class CWLSeatResource {
|
||||
public:
|
||||
CWLSeatResource(SP<CWlSeat> resource_);
|
||||
~CWLSeatResource();
|
||||
|
||||
void sendCapabilities(uint32_t caps); // uses IHID capabilities
|
||||
|
||||
bool good();
|
||||
wl_client* client();
|
||||
|
||||
std::vector<WP<CWLPointerResource>> pointers;
|
||||
std::vector<WP<CWLKeyboardResource>> keyboards;
|
||||
std::vector<WP<CWLTouchResource>> touches;
|
||||
|
||||
WP<CWLSeatResource> self;
|
||||
|
||||
struct {
|
||||
CSignal destroy;
|
||||
} events;
|
||||
|
||||
private:
|
||||
SP<CWlSeat> resource;
|
||||
wl_client* pClient = nullptr;
|
||||
};
|
||||
|
||||
class CWLSeatProtocol : public IWaylandProtocol {
|
||||
public:
|
||||
CWLSeatProtocol(const wl_interface* iface, const int& ver, const std::string& name);
|
||||
|
||||
virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);
|
||||
|
||||
struct {
|
||||
CSignal newSeatResource; // SP<CWLSeatResource>
|
||||
} events;
|
||||
|
||||
private:
|
||||
void updateCapabilities(uint32_t caps); // in IHID caps
|
||||
void updateRepeatInfo(uint32_t rate, uint32_t delayMs);
|
||||
void updateKeymap();
|
||||
|
||||
void destroyResource(CWLSeatResource* resource);
|
||||
void destroyResource(CWLKeyboardResource* resource);
|
||||
void destroyResource(CWLTouchResource* resource);
|
||||
void destroyResource(CWLPointerResource* resource);
|
||||
|
||||
//
|
||||
std::vector<SP<CWLSeatResource>> m_vSeatResources;
|
||||
std::vector<SP<CWLKeyboardResource>> m_vKeyboards;
|
||||
std::vector<SP<CWLTouchResource>> m_vTouches;
|
||||
std::vector<SP<CWLPointerResource>> m_vPointers;
|
||||
|
||||
SP<CWLSeatResource> seatResourceForClient(wl_client* client);
|
||||
|
||||
//
|
||||
uint32_t currentCaps = 0;
|
||||
|
||||
friend class CWLSeatResource;
|
||||
friend class CWLKeyboardResource;
|
||||
friend class CWLTouchResource;
|
||||
friend class CWLPointerResource;
|
||||
friend class CSeatManager;
|
||||
};
|
||||
|
||||
namespace PROTO {
|
||||
inline UP<CWLSeatProtocol> seat;
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue