wl_seat: move to hyprland impl

This commit is contained in:
Vaxry 2024-05-10 18:27:57 +01:00 committed by Vaxry
parent 4cdddcfe46
commit 121d3a7213
31 changed files with 1441 additions and 395 deletions

View file

@ -71,6 +71,7 @@ pkg_get_variable(WaylandScanner wayland-scanner wayland_scanner)
message(STATUS "Found WaylandScanner at ${WaylandScanner}") message(STATUS "Found WaylandScanner at ${WaylandScanner}")
pkg_get_variable(WAYLAND_PROTOCOLS_DIR wayland-protocols pkgdatadir) pkg_get_variable(WAYLAND_PROTOCOLS_DIR wayland-protocols pkgdatadir)
message(STATUS "Found wayland-protocols at ${WAYLAND_PROTOCOLS_DIR}") message(STATUS "Found wayland-protocols at ${WAYLAND_PROTOCOLS_DIR}")
pkg_get_variable(WAYLAND_SERVER_DIR wayland-server pkgdatadir)
if(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG) if(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
message(STATUS "Configuring Hyprland in Debug with CMake") message(STATUS "Configuring Hyprland in Debug with CMake")
@ -239,6 +240,13 @@ function(protocolNew protoPath protoName external)
target_sources(Hyprland PRIVATE protocols/${protoName}.cpp) target_sources(Hyprland PRIVATE protocols/${protoName}.cpp)
endif() endif()
endfunction() endfunction()
function(protocolWayland)
execute_process(
COMMAND hyprwayland-scanner --wayland-enums ${WAYLAND_SERVER_DIR}/wayland.xml ${CMAKE_SOURCE_DIR}/protocols/
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
target_sources(Hyprland PRIVATE protocols/wayland.cpp)
endfunction()
target_link_libraries(Hyprland target_link_libraries(Hyprland
${CMAKE_SOURCE_DIR}/subprojects/wlroots-hyprland/build/libwlroots.a ${CMAKE_SOURCE_DIR}/subprojects/wlroots-hyprland/build/libwlroots.a
@ -285,6 +293,8 @@ protocolNew("staging/ext-session-lock/ext-session-lock-v1.xml" "ext-session-lock
protocolNew("stable/tablet/tablet-v2.xml" "tablet-v2" false) protocolNew("stable/tablet/tablet-v2.xml" "tablet-v2" false)
protocolNew("stable/presentation-time/presentation-time.xml" "presentation-time" false) protocolNew("stable/presentation-time/presentation-time.xml" "presentation-time" false)
protocolWayland()
# tools # tools
add_subdirectory(hyprctl) add_subdirectory(hyprctl)
add_subdirectory(hyprpm) add_subdirectory(hyprpm)

View file

@ -4,6 +4,7 @@
#include "managers/CursorManager.hpp" #include "managers/CursorManager.hpp"
#include "managers/TokenManager.hpp" #include "managers/TokenManager.hpp"
#include "managers/PointerManager.hpp" #include "managers/PointerManager.hpp"
#include "managers/SeatManager.hpp"
#include "managers/eventLoop/EventLoopManager.hpp" #include "managers/eventLoop/EventLoopManager.hpp"
#include <random> #include <random>
#include <unordered_set> #include <unordered_set>
@ -222,16 +223,14 @@ void CCompositor::initServer() {
m_sWLRCompositor = wlr_compositor_create(m_sWLDisplay, 6, m_sWLRRenderer); m_sWLRCompositor = wlr_compositor_create(m_sWLDisplay, 6, m_sWLRRenderer);
m_sWLRSubCompositor = wlr_subcompositor_create(m_sWLDisplay); m_sWLRSubCompositor = wlr_subcompositor_create(m_sWLDisplay);
m_sWLRDataDevMgr = wlr_data_device_manager_create(m_sWLDisplay); // m_sWLRDataDevMgr = wlr_data_device_manager_create(m_sWLDisplay);
wlr_data_control_manager_v1_create(m_sWLDisplay); // wlr_data_control_manager_v1_create(m_sWLDisplay);
wlr_primary_selection_v1_device_manager_create(m_sWLDisplay); // wlr_primary_selection_v1_device_manager_create(m_sWLDisplay);
wlr_viewporter_create(m_sWLDisplay); wlr_viewporter_create(m_sWLDisplay);
m_sWLRXDGShell = wlr_xdg_shell_create(m_sWLDisplay, 6); m_sWLRXDGShell = wlr_xdg_shell_create(m_sWLDisplay, 6);
m_sSeat.seat = wlr_seat_create(m_sWLDisplay, "seat0");
m_sWRLDRMLeaseMgr = wlr_drm_lease_v1_manager_create(m_sWLDisplay, m_sWLRBackend); m_sWRLDRMLeaseMgr = wlr_drm_lease_v1_manager_create(m_sWLDisplay, m_sWLRBackend);
if (!m_sWRLDRMLeaseMgr) { if (!m_sWRLDRMLeaseMgr) {
Debug::log(INFO, "Failed to create wlr_drm_lease_v1_manager"); Debug::log(INFO, "Failed to create wlr_drm_lease_v1_manager");
@ -256,12 +255,11 @@ void CCompositor::initAllSignals() {
addWLSignal(&m_sWLRBackend->events.new_output, &Events::listen_newOutput, m_sWLRBackend, "Backend"); addWLSignal(&m_sWLRBackend->events.new_output, &Events::listen_newOutput, m_sWLRBackend, "Backend");
addWLSignal(&m_sWLRXDGShell->events.new_toplevel, &Events::listen_newXDGToplevel, m_sWLRXDGShell, "XDG Shell"); addWLSignal(&m_sWLRXDGShell->events.new_toplevel, &Events::listen_newXDGToplevel, m_sWLRXDGShell, "XDG Shell");
addWLSignal(&m_sWLRBackend->events.new_input, &Events::listen_newInput, m_sWLRBackend, "Backend"); addWLSignal(&m_sWLRBackend->events.new_input, &Events::listen_newInput, m_sWLRBackend, "Backend");
addWLSignal(&m_sSeat.seat->events.request_set_cursor, &Events::listen_requestMouse, &m_sSeat, "Seat"); // addWLSignal(&m_sSeat.seat->events.request_set_selection, &Events::listen_requestSetSel, &m_sSeat, "Seat");
addWLSignal(&m_sSeat.seat->events.request_set_selection, &Events::listen_requestSetSel, &m_sSeat, "Seat"); // addWLSignal(&m_sSeat.seat->events.request_start_drag, &Events::listen_requestDrag, &m_sSeat, "Seat");
addWLSignal(&m_sSeat.seat->events.request_start_drag, &Events::listen_requestDrag, &m_sSeat, "Seat"); // addWLSignal(&m_sSeat.seat->events.start_drag, &Events::listen_startDrag, &m_sSeat, "Seat");
addWLSignal(&m_sSeat.seat->events.start_drag, &Events::listen_startDrag, &m_sSeat, "Seat"); // addWLSignal(&m_sSeat.seat->events.request_set_selection, &Events::listen_requestSetSel, &m_sSeat, "Seat");
addWLSignal(&m_sSeat.seat->events.request_set_selection, &Events::listen_requestSetSel, &m_sSeat, "Seat"); // addWLSignal(&m_sSeat.seat->events.request_set_primary_selection, &Events::listen_requestSetPrimarySel, &m_sSeat, "Seat");
addWLSignal(&m_sSeat.seat->events.request_set_primary_selection, &Events::listen_requestSetPrimarySel, &m_sSeat, "Seat");
addWLSignal(&m_sWLRRenderer->events.destroy, &Events::listen_RendererDestroy, m_sWLRRenderer, "WLRRenderer"); addWLSignal(&m_sWLRRenderer->events.destroy, &Events::listen_RendererDestroy, m_sWLRRenderer, "WLRRenderer");
if (m_sWRLDRMLeaseMgr) if (m_sWRLDRMLeaseMgr)
@ -275,7 +273,6 @@ void CCompositor::removeAllSignals() {
removeWLSignal(&Events::listen_newOutput); removeWLSignal(&Events::listen_newOutput);
removeWLSignal(&Events::listen_newXDGToplevel); removeWLSignal(&Events::listen_newXDGToplevel);
removeWLSignal(&Events::listen_newInput); removeWLSignal(&Events::listen_newInput);
removeWLSignal(&Events::listen_requestMouse);
removeWLSignal(&Events::listen_requestSetSel); removeWLSignal(&Events::listen_requestSetSel);
removeWLSignal(&Events::listen_requestDrag); removeWLSignal(&Events::listen_requestDrag);
removeWLSignal(&Events::listen_startDrag); removeWLSignal(&Events::listen_startDrag);
@ -379,9 +376,8 @@ void CCompositor::cleanup() {
g_pHookSystem.reset(); g_pHookSystem.reset();
g_pWatchdog.reset(); g_pWatchdog.reset();
g_pXWaylandManager.reset(); g_pXWaylandManager.reset();
g_pPointerManager.reset();
if (m_sSeat.seat) g_pSeatManager.reset();
wlr_seat_destroy(m_sSeat.seat);
if (m_sWLRRenderer) if (m_sWLRRenderer)
wlr_renderer_destroy(m_sWLRRenderer); wlr_renderer_destroy(m_sWLRRenderer);
@ -412,6 +408,9 @@ void CCompositor::initManagers(eManagersInitStage stage) {
Debug::log(LOG, "Creating the ProtocolManager!"); Debug::log(LOG, "Creating the ProtocolManager!");
g_pProtocolManager = std::make_unique<CProtocolManager>(); g_pProtocolManager = std::make_unique<CProtocolManager>();
Debug::log(LOG, "Creating the SeatManager!");
g_pSeatManager = std::make_unique<CSeatManager>();
Debug::log(LOG, "Creating the KeybindManager!"); Debug::log(LOG, "Creating the KeybindManager!");
g_pKeybindManager = std::make_unique<CKeybindManager>(); g_pKeybindManager = std::make_unique<CKeybindManager>();
@ -890,8 +889,8 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, wlr_surface* pSurface) {
static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse"); static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
static auto PSPECIALFALLTHROUGH = CConfigValue<Hyprlang::INT>("input:special_fallthrough"); static auto PSPECIALFALLTHROUGH = CConfigValue<Hyprlang::INT>("input:special_fallthrough");
if (g_pCompositor->m_sSeat.exclusiveClient) { if (g_pSessionLockManager->isSessionLocked()) {
Debug::log(LOG, "Disallowing setting focus to a window due to there being an active input inhibitor layer."); Debug::log(LOG, "Refusing a keyboard focus to a window because of a sessionlock");
return; return;
} }
@ -919,7 +918,7 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, wlr_surface* pSurface) {
g_pXWaylandManager->activateWindow(PLASTWINDOW, false); g_pXWaylandManager->activateWindow(PLASTWINDOW, false);
} }
wlr_seat_keyboard_notify_clear_focus(m_sSeat.seat); g_pSeatManager->setKeyboardFocus(nullptr);
g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", ","}); g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", ","});
g_pEventManager->postEvent(SHyprIPCEvent{"activewindowv2", ""}); g_pEventManager->postEvent(SHyprIPCEvent{"activewindowv2", ""});
@ -939,7 +938,7 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, wlr_surface* pSurface) {
return; return;
} }
if (m_pLastWindow.lock() == pWindow && m_sSeat.seat->keyboard_state.focused_surface == pSurface) if (m_pLastWindow.lock() == pWindow && g_pSeatManager->state.keyboardFocus == pSurface)
return; return;
if (pWindow->m_bPinned) if (pWindow->m_bPinned)
@ -1017,7 +1016,7 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, wlr_surface* pSurface) {
void CCompositor::focusSurface(wlr_surface* pSurface, PHLWINDOW pWindowOwner) { void CCompositor::focusSurface(wlr_surface* pSurface, PHLWINDOW pWindowOwner) {
if (m_sSeat.seat->keyboard_state.focused_surface == pSurface || (pWindowOwner && m_sSeat.seat->keyboard_state.focused_surface == pWindowOwner->m_pWLSurface.wlr())) if (g_pSeatManager->state.keyboardFocus == pSurface || (pWindowOwner && g_pSeatManager->state.keyboardFocus == pWindowOwner->m_pWLSurface.wlr()))
return; // Don't focus when already focused on this. return; // Don't focus when already focused on this.
if (g_pSessionLockManager->isSessionLocked() && !g_pSessionLockManager->isSurfaceSessionLock(pSurface)) if (g_pSessionLockManager->isSessionLocked() && !g_pSessionLockManager->isSurfaceSessionLock(pSurface))
@ -1030,7 +1029,7 @@ void CCompositor::focusSurface(wlr_surface* pSurface, PHLWINDOW pWindowOwner) {
g_pXWaylandManager->activateSurface(m_pLastFocus, false); g_pXWaylandManager->activateSurface(m_pLastFocus, false);
if (!pSurface) { if (!pSurface) {
wlr_seat_keyboard_clear_focus(m_sSeat.seat); g_pSeatManager->setKeyboardFocus(nullptr);
g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", ","}); // unfocused g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", ","}); // unfocused
g_pEventManager->postEvent(SHyprIPCEvent{"activewindowv2", ""}); g_pEventManager->postEvent(SHyprIPCEvent{"activewindowv2", ""});
EMIT_HOOK_EVENT("keyboardFocus", (wlr_surface*)nullptr); EMIT_HOOK_EVENT("keyboardFocus", (wlr_surface*)nullptr);
@ -1038,17 +1037,8 @@ void CCompositor::focusSurface(wlr_surface* pSurface, PHLWINDOW pWindowOwner) {
return; return;
} }
if (const auto KEYBOARD = wlr_seat_get_keyboard(m_sSeat.seat); KEYBOARD) { if (g_pSeatManager->keyboard)
uint32_t keycodes[WLR_KEYBOARD_KEYS_CAP] = {0}; // TODO: maybe send valid, non-keybind codes? g_pSeatManager->setKeyboardFocus(pSurface);
wlr_seat_keyboard_notify_enter(m_sSeat.seat, pSurface, keycodes, 0, &KEYBOARD->modifiers);
wlr_seat_keyboard_focus_change_event event = {
.seat = m_sSeat.seat,
.old_surface = m_pLastFocus,
.new_surface = pSurface,
};
wl_signal_emit_mutable(&m_sSeat.seat->keyboard_state.events.focus_change, &event);
}
if (pWindowOwner) if (pWindowOwner)
Debug::log(LOG, "Set keyboard focus to surface {:x}, with {}", (uintptr_t)pSurface, pWindowOwner); Debug::log(LOG, "Set keyboard focus to surface {:x}, with {}", (uintptr_t)pSurface, pWindowOwner);
@ -1245,27 +1235,6 @@ PHLWINDOW CCompositor::getTopLeftWindowOnWorkspace(const int& id) {
return nullptr; return nullptr;
} }
bool CCompositor::doesSeatAcceptInput(wlr_surface* surface) {
if (g_pSessionLockManager->isSessionLocked()) {
if (g_pSessionLockManager->isSurfaceSessionLock(surface))
return true;
if (surface && m_sSeat.exclusiveClient == wl_resource_get_client(surface->resource))
return true;
return false;
}
if (m_sSeat.exclusiveClient) {
if (surface && m_sSeat.exclusiveClient == wl_resource_get_client(surface->resource))
return true;
return false;
}
return true;
}
bool CCompositor::isWindowActive(PHLWINDOW pWindow) { bool CCompositor::isWindowActive(PHLWINDOW pWindow) {
if (m_pLastWindow.expired() && !m_pLastFocus) if (m_pLastWindow.expired() && !m_pLastFocus)
return false; return false;

View file

@ -48,7 +48,6 @@ class CCompositor {
wlr_allocator* m_sWLRAllocator; wlr_allocator* m_sWLRAllocator;
wlr_compositor* m_sWLRCompositor; wlr_compositor* m_sWLRCompositor;
wlr_subcompositor* m_sWLRSubCompositor; wlr_subcompositor* m_sWLRSubCompositor;
wlr_data_device_manager* m_sWLRDataDevMgr;
wlr_drm* m_sWRLDRM; wlr_drm* m_sWRLDRM;
wlr_drm_lease_v1_manager* m_sWRLDRMLeaseMgr; wlr_drm_lease_v1_manager* m_sWRLDRMLeaseMgr;
wlr_xdg_shell* m_sWLRXDGShell; wlr_xdg_shell* m_sWLRXDGShell;
@ -87,8 +86,6 @@ class CCompositor {
std::vector<PHLWINDOWREF> m_vWindowFocusHistory; // first element is the most recently focused. std::vector<PHLWINDOWREF> m_vWindowFocusHistory; // first element is the most recently focused.
SSeat m_sSeat;
bool m_bReadyToProcess = false; bool m_bReadyToProcess = false;
bool m_bSessionActive = true; bool m_bSessionActive = true;
bool m_bDPMSStateON = true; bool m_bDPMSStateON = true;
@ -132,7 +129,6 @@ class CCompositor {
PHLWINDOW getFirstWindowOnWorkspace(const int&); PHLWINDOW getFirstWindowOnWorkspace(const int&);
PHLWINDOW getTopLeftWindowOnWorkspace(const int&); PHLWINDOW getTopLeftWindowOnWorkspace(const int&);
PHLWINDOW getFullscreenWindowOnWorkspace(const int&); PHLWINDOW getFullscreenWindowOnWorkspace(const int&);
bool doesSeatAcceptInput(wlr_surface*);
bool isWindowActive(PHLWINDOW); bool isWindowActive(PHLWINDOW);
void changeWindowZOrder(PHLWINDOW, bool); void changeWindowZOrder(PHLWINDOW, bool);
void cleanupFadingOut(const int& monid); void cleanupFadingOut(const int& monid);

View file

@ -2,6 +2,7 @@
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../events/Events.hpp" #include "../events/Events.hpp"
#include "../protocols/LayerShell.hpp" #include "../protocols/LayerShell.hpp"
#include "../managers/SeatManager.hpp"
PHLLS CLayerSurface::create(SP<CLayerShellResource> resource) { PHLLS CLayerSurface::create(SP<CLayerShellResource> resource) {
PHLLS pLS = SP<CLayerSurface>(new CLayerSurface(resource)); PHLLS pLS = SP<CLayerSurface>(new CLayerSurface(resource));
@ -132,15 +133,14 @@ void CLayerSurface::onMap() {
const bool GRABSFOCUS = layerSurface->current.interactivity != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE && const bool GRABSFOCUS = layerSurface->current.interactivity != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE &&
// don't focus if constrained // don't focus if constrained
(g_pCompositor->m_sSeat.mouse.expired() || !g_pInputManager->isConstrained()); (g_pSeatManager->mouse.expired() || !g_pInputManager->isConstrained());
if (GRABSFOCUS) { if (GRABSFOCUS) {
g_pInputManager->releaseAllMouseButtons(); g_pInputManager->releaseAllMouseButtons();
g_pCompositor->focusSurface(surface.wlr()); g_pCompositor->focusSurface(surface.wlr());
const auto LOCAL = g_pInputManager->getMouseCoordsInternal() - Vector2D(geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y); const auto LOCAL = g_pInputManager->getMouseCoordsInternal() - Vector2D(geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y);
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, surface.wlr(), LOCAL.x, LOCAL.y); g_pSeatManager->setPointerFocus(surface.wlr(), LOCAL);
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;
} }
@ -304,15 +304,14 @@ void CLayerSurface::onCommit() {
realSize.setValueAndWarp(geometry.size()); realSize.setValueAndWarp(geometry.size());
} }
if (layerSurface->current.interactivity && (g_pCompositor->m_sSeat.mouse.expired() || !g_pInputManager->isConstrained()) // don't focus if constrained if (layerSurface->current.interactivity && (g_pSeatManager->mouse.expired() || !g_pInputManager->isConstrained()) // don't focus if constrained
&& !keyboardExclusive && mapped) { && !keyboardExclusive && mapped) {
g_pCompositor->focusSurface(layerSurface->surface); g_pCompositor->focusSurface(layerSurface->surface);
const auto LOCAL = g_pInputManager->getMouseCoordsInternal() - Vector2D(geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y); const auto LOCAL = g_pInputManager->getMouseCoordsInternal() - Vector2D(geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y);
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, layerSurface->surface, LOCAL.x, LOCAL.y); g_pSeatManager->setPointerFocus(layerSurface->surface, LOCAL);
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.interactivity && (g_pCompositor->m_sSeat.mouse.expired() || !g_pInputManager->isConstrained()) && keyboardExclusive) { } else if (!layerSurface->current.interactivity && (g_pSeatManager->mouse.expired() || !g_pInputManager->isConstrained()) && keyboardExclusive) {
g_pInputManager->refocus(); g_pInputManager->refocus();
} }

View file

@ -120,8 +120,6 @@ void CWLSurface::destroy() {
if (g_pCompositor && g_pCompositor->m_pLastFocus == m_pWLRSurface) if (g_pCompositor && g_pCompositor->m_pLastFocus == m_pWLRSurface)
g_pCompositor->m_pLastFocus = nullptr; g_pCompositor->m_pLastFocus = nullptr;
if (g_pInputManager && g_pInputManager->m_pLastMouseSurface == m_pWLRSurface)
g_pInputManager->m_pLastMouseSurface = nullptr;
if (g_pHyprRenderer && g_pHyprRenderer->m_sLastCursorData.surf == this) if (g_pHyprRenderer && g_pHyprRenderer->m_sLastCursorData.surf == this)
g_pHyprRenderer->m_sLastCursorData.surf.reset(); g_pHyprRenderer->m_sLastCursorData.surf.reset();

View file

@ -15,12 +15,6 @@
// // // //
// ---------------------------------------------------- // // ---------------------------------------------------- //
void Events::listener_requestMouse(wl_listener* listener, void* data) {
const auto EVENT = (wlr_seat_pointer_request_set_cursor_event*)data;
g_pInputManager->processMouseRequest(EVENT);
}
void Events::listener_newInput(wl_listener* listener, void* data) { void Events::listener_newInput(wl_listener* listener, void* data) {
const auto DEVICE = (wlr_input_device*)data; const auto DEVICE = (wlr_input_device*)data;

View file

@ -46,7 +46,6 @@ namespace Events {
LISTENER(newVirtPtr); LISTENER(newVirtPtr);
// Various // Various
LISTENER(requestMouse);
LISTENER(requestSetSel); LISTENER(requestSetSel);
LISTENER(requestSetPrimarySel); LISTENER(requestSetPrimarySel);

View file

@ -26,13 +26,13 @@ void Events::listener_leaseRequest(wl_listener* listener, void* data) {
} }
void Events::listener_requestSetPrimarySel(wl_listener* listener, void* data) { void Events::listener_requestSetPrimarySel(wl_listener* listener, void* data) {
const auto EVENT = (wlr_seat_request_set_primary_selection_event*)data; // const auto EVENT = (wlr_seat_request_set_primary_selection_event*)data;
wlr_seat_set_primary_selection(g_pCompositor->m_sSeat.seat, EVENT->source, EVENT->serial); // wlr_seat_set_primary_selection(g_pCompositor->m_sSeat.seat, EVENT->source, EVENT->serial);
} }
void Events::listener_requestSetSel(wl_listener* listener, void* data) { void Events::listener_requestSetSel(wl_listener* listener, void* data) {
const auto EVENT = (wlr_seat_request_set_selection_event*)data; // const auto EVENT = (wlr_seat_request_set_selection_event*)data;
wlr_seat_set_selection(g_pCompositor->m_sSeat.seat, EVENT->source, EVENT->serial); // wlr_seat_set_selection(g_pCompositor->m_sSeat.seat, EVENT->source, EVENT->serial);
} }
void Events::listener_readyXWayland(wl_listener* listener, void* data) { void Events::listener_readyXWayland(wl_listener* listener, void* data) {
@ -58,7 +58,7 @@ void Events::listener_readyXWayland(wl_listener* listener, void* data) {
free(reply); free(reply);
} }
wlr_xwayland_set_seat(g_pXWaylandManager->m_sWLRXWayland, g_pCompositor->m_sSeat.seat); //wlr_xwayland_set_seat(g_pXWaylandManager->m_sWLRXWayland, g_pCompositor->m_sSeat.seat);
g_pCursorManager->setXWaylandCursor(g_pXWaylandManager->m_sWLRXWayland); g_pCursorManager->setXWaylandCursor(g_pXWaylandManager->m_sWLRXWayland);
@ -80,15 +80,15 @@ void Events::listener_readyXWayland(wl_listener* listener, void* data) {
} }
void Events::listener_requestDrag(wl_listener* listener, void* data) { void Events::listener_requestDrag(wl_listener* listener, void* data) {
const auto E = (wlr_seat_request_start_drag_event*)data; // const auto E = (wlr_seat_request_start_drag_event*)data;
if (!wlr_seat_validate_pointer_grab_serial(g_pCompositor->m_sSeat.seat, E->origin, E->serial)) { // if (!wlr_seat_validate_pointer_grab_serial(g_pCompositor->m_sSeat.seat, E->origin, E->serial)) {
Debug::log(LOG, "Ignoring drag and drop request: serial mismatch."); // Debug::log(LOG, "Ignoring drag and drop request: serial mismatch.");
wlr_data_source_destroy(E->drag->source); // wlr_data_source_destroy(E->drag->source);
return; // return;
} // }
wlr_seat_start_pointer_drag(g_pCompositor->m_sSeat.seat, E->drag, E->serial); // wlr_seat_start_pointer_drag(g_pCompositor->m_sSeat.seat, E->drag, E->serial);
} }
void Events::listener_startDrag(wl_listener* listener, void* data) { void Events::listener_startDrag(wl_listener* listener, void* data) {

View file

@ -4,6 +4,7 @@
#include "../helpers/WLClasses.hpp" #include "../helpers/WLClasses.hpp"
#include "../managers/input/InputManager.hpp" #include "../managers/input/InputManager.hpp"
#include "../managers/TokenManager.hpp" #include "../managers/TokenManager.hpp"
#include "../managers/SeatManager.hpp"
#include "../render/Renderer.hpp" #include "../render/Renderer.hpp"
#include "../config/ConfigValue.hpp" #include "../config/ConfigValue.hpp"
#include "../protocols/LayerShell.hpp" #include "../protocols/LayerShell.hpp"
@ -668,7 +669,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.expired() || !g_pInputManager->isConstrained()) if (g_pSeatManager->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

@ -58,14 +58,6 @@ struct SExtensionFindingData {
wlr_surface** found; wlr_surface** found;
}; };
struct SSeat {
wlr_seat* seat = nullptr;
wl_client* exclusiveClient = nullptr;
WP<IPointer> mouse;
WP<IKeyboard> keyboard;
};
struct SDrag { struct SDrag {
wlr_drag* drag = nullptr; wlr_drag* drag = nullptr;

View file

@ -51,7 +51,6 @@ extern "C" {
#include <wlr/types/wlr_pointer.h> #include <wlr/types/wlr_pointer.h>
#include <wlr/types/wlr_primary_selection.h> #include <wlr/types/wlr_primary_selection.h>
#include <wlr/types/wlr_primary_selection_v1.h> #include <wlr/types/wlr_primary_selection_v1.h>
#include <wlr/types/wlr_seat.h>
#include <wlr/types/wlr_viewporter.h> #include <wlr/types/wlr_viewporter.h>
#include <wlr/types/wlr_xdg_output_v1.h> #include <wlr/types/wlr_xdg_output_v1.h>
#include <wlr/types/wlr_xdg_shell.h> #include <wlr/types/wlr_xdg_shell.h>

View file

@ -6,6 +6,7 @@
#include "TokenManager.hpp" #include "TokenManager.hpp"
#include "../protocols/ShortcutsInhibit.hpp" #include "../protocols/ShortcutsInhibit.hpp"
#include "../devices/IKeyboard.hpp" #include "../devices/IKeyboard.hpp"
#include "../managers/SeatManager.hpp"
#include <regex> #include <regex>
#include <tuple> #include <tuple>
@ -522,7 +523,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 || g_pCompositor->m_sSeat.keyboard.expired()) if (!*ppActiveKeybind || g_pSeatManager->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);
@ -530,7 +531,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_pCompositor->m_sSeat.keyboard->repeatRate); wl_event_source_timer_update(g_pKeybindManager->m_pActiveKeybindEventSource, 1000 / g_pSeatManager->keyboard->wlr()->repeat_info.rate);
return 0; return 0;
} }
@ -538,9 +539,6 @@ int repeatKeyHandler(void* data) {
bool CKeybindManager::handleKeybinds(const uint32_t modmask, const SPressedKeyWithMods& key, bool pressed) { bool CKeybindManager::handleKeybinds(const uint32_t modmask, const SPressedKeyWithMods& key, bool pressed) {
bool found = false; bool found = false;
if (g_pCompositor->m_sSeat.exclusiveClient)
Debug::log(LOG, "Keybind handling only locked (inhibitor)");
static auto PDISABLEINHIBIT = CConfigValue<Hyprlang::INT>("binds:disable_keybind_grabbing"); static auto PDISABLEINHIBIT = CConfigValue<Hyprlang::INT>("binds:disable_keybind_grabbing");
if (!*PDISABLEINHIBIT && PROTO::shortcutsInhibit->isInhibited()) { if (!*PDISABLEINHIBIT && PROTO::shortcutsInhibit->isInhibited()) {
@ -558,8 +556,7 @@ bool CKeybindManager::handleKeybinds(const uint32_t modmask, const SPressedKeyWi
if (!k.locked && g_pSessionLockManager->isSessionLocked()) if (!k.locked && g_pSessionLockManager->isSessionLocked())
continue; continue;
if (!IGNORECONDITIONS && if (!IGNORECONDITIONS && ((modmask != k.modmask && !k.ignoreMods) || k.submap != m_szCurrentSelectedSubmap || k.shadowed))
((modmask != k.modmask && !k.ignoreMods) || (g_pCompositor->m_sSeat.exclusiveClient && !k.locked) || k.submap != m_szCurrentSelectedSubmap || k.shadowed))
continue; continue;
if (!key.keyName.empty()) { if (!key.keyName.empty()) {
@ -653,7 +650,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_pCompositor->m_sSeat.keyboard.lock(); const auto PACTIVEKEEB = g_pSeatManager->keyboard.lock();
wl_event_source_timer_update(m_pActiveKeybindEventSource, PACTIVEKEEB->repeatDelay); wl_event_source_timer_update(m_pActiveKeybindEventSource, PACTIVEKEEB->repeatDelay);
} }
@ -1901,47 +1898,42 @@ void CKeybindManager::pass(std::string regexp) {
return; return;
} }
const auto KEYBOARD = wlr_seat_get_keyboard(g_pCompositor->m_sSeat.seat); if (!g_pSeatManager->keyboard) {
if (!KEYBOARD) {
Debug::log(ERR, "No kb in pass?"); Debug::log(ERR, "No kb in pass?");
return; return;
} }
const auto XWTOXW = PWINDOW->m_bIsX11 && g_pCompositor->m_pLastWindow.lock() && g_pCompositor->m_pLastWindow->m_bIsX11; const auto XWTOXW = PWINDOW->m_bIsX11 && g_pCompositor->m_pLastWindow.lock() && g_pCompositor->m_pLastWindow->m_bIsX11;
const auto SL = Vector2D(g_pCompositor->m_sSeat.seat->pointer_state.sx, g_pCompositor->m_sSeat.seat->pointer_state.sy);
uint32_t keycodes[32] = {0};
const auto LASTSRF = g_pCompositor->m_pLastFocus; const auto LASTSRF = g_pCompositor->m_pLastFocus;
// pass all mf shit // pass all mf shit
if (!XWTOXW) { if (!XWTOXW) {
if (g_pKeybindManager->m_uLastCode != 0) if (g_pKeybindManager->m_uLastCode != 0)
wlr_seat_keyboard_enter(g_pCompositor->m_sSeat.seat, PWINDOW->m_pWLSurface.wlr(), keycodes, 0, &KEYBOARD->modifiers); g_pSeatManager->setKeyboardFocus(PWINDOW->m_pWLSurface.wlr());
else else
wlr_seat_pointer_enter(g_pCompositor->m_sSeat.seat, PWINDOW->m_pWLSurface.wlr(), 1, 1); g_pSeatManager->setPointerFocus(PWINDOW->m_pWLSurface.wlr(), {1, 1});
} }
wlr_keyboard_modifiers kbmods = {g_pInputManager->accumulateModsFromAllKBs(), 0, 0, 0}; g_pSeatManager->sendKeyboardMods(g_pInputManager->accumulateModsFromAllKBs(), 0, 0, 0);
wlr_seat_keyboard_notify_modifiers(g_pCompositor->m_sSeat.seat, &kbmods);
if (g_pKeybindManager->m_iPassPressed == 1) { if (g_pKeybindManager->m_iPassPressed == 1) {
if (g_pKeybindManager->m_uLastCode != 0) if (g_pKeybindManager->m_uLastCode != 0)
wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastCode - 8, WLR_BUTTON_PRESSED); g_pSeatManager->sendKeyboardKey(g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastCode - 8, WL_KEYBOARD_KEY_STATE_PRESSED);
else else
wlr_seat_pointer_notify_button(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastMouseCode, WL_POINTER_BUTTON_STATE_PRESSED); g_pSeatManager->sendPointerButton(g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastMouseCode, WL_POINTER_BUTTON_STATE_PRESSED);
} else if (g_pKeybindManager->m_iPassPressed == 0) } else if (g_pKeybindManager->m_iPassPressed == 0)
if (g_pKeybindManager->m_uLastCode != 0) if (g_pKeybindManager->m_uLastCode != 0)
wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastCode - 8, WLR_BUTTON_RELEASED); g_pSeatManager->sendKeyboardKey(g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastCode - 8, WL_KEYBOARD_KEY_STATE_RELEASED);
else else
wlr_seat_pointer_notify_button(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastMouseCode, WL_POINTER_BUTTON_STATE_RELEASED); g_pSeatManager->sendPointerButton(g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastMouseCode, WL_POINTER_BUTTON_STATE_RELEASED);
else { else {
// dynamic call of the dispatcher // dynamic call of the dispatcher
if (g_pKeybindManager->m_uLastCode != 0) { if (g_pKeybindManager->m_uLastCode != 0) {
wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastCode - 8, WLR_BUTTON_PRESSED); g_pSeatManager->sendKeyboardKey(g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastCode - 8, WL_KEYBOARD_KEY_STATE_PRESSED);
wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastCode - 8, WLR_BUTTON_RELEASED); g_pSeatManager->sendKeyboardKey(g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastCode - 8, WL_KEYBOARD_KEY_STATE_RELEASED);
} else { } else {
wlr_seat_pointer_notify_button(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastMouseCode, WL_POINTER_BUTTON_STATE_PRESSED); g_pSeatManager->sendPointerButton(g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastMouseCode, WL_POINTER_BUTTON_STATE_PRESSED);
wlr_seat_pointer_notify_button(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastMouseCode, WL_POINTER_BUTTON_STATE_RELEASED); g_pSeatManager->sendPointerButton(g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastMouseCode, WL_POINTER_BUTTON_STATE_RELEASED);
} }
} }
@ -1949,22 +1941,24 @@ void CKeybindManager::pass(std::string regexp) {
return; return;
// Massive hack: // Massive hack:
// this will make wlroots NOT send the leave event to XWayland apps, provided we are not on an XWayland window already. // this will make g_pSeatManager NOT send the leave event to XWayland apps, provided we are not on an XWayland window already.
// please kill me // please kill me
if (PWINDOW->m_bIsX11) { if (PWINDOW->m_bIsX11) {
if (g_pKeybindManager->m_uLastCode != 0) { if (g_pKeybindManager->m_uLastCode != 0) {
g_pCompositor->m_sSeat.seat->keyboard_state.focused_client = nullptr; g_pSeatManager->state.keyboardFocus = nullptr;
g_pCompositor->m_sSeat.seat->keyboard_state.focused_surface = nullptr; g_pSeatManager->state.keyboardFocusResource.reset();
} else { } else {
g_pCompositor->m_sSeat.seat->pointer_state.focused_client = nullptr; g_pSeatManager->state.pointerFocus = nullptr;
g_pCompositor->m_sSeat.seat->pointer_state.focused_surface = nullptr; g_pSeatManager->state.pointerFocusResource.reset();
} }
} }
const auto SL = PWINDOW->m_vRealPosition.goal() - g_pInputManager->getMouseCoordsInternal();
if (g_pKeybindManager->m_uLastCode != 0) if (g_pKeybindManager->m_uLastCode != 0)
wlr_seat_keyboard_enter(g_pCompositor->m_sSeat.seat, LASTSRF, KEYBOARD->keycodes, KEYBOARD->num_keycodes, &KEYBOARD->modifiers); g_pSeatManager->setKeyboardFocus(LASTSRF);
else else
wlr_seat_pointer_enter(g_pCompositor->m_sSeat.seat, PWINDOW->m_pWLSurface.wlr(), SL.x, SL.y); g_pSeatManager->setPointerFocus(PWINDOW->m_pWLSurface.wlr(), SL);
} }
void CKeybindManager::layoutmsg(std::string msg) { void CKeybindManager::layoutmsg(std::string msg) {

View file

@ -3,6 +3,7 @@
#include "../config/ConfigValue.hpp" #include "../config/ConfigValue.hpp"
#include "../protocols/PointerGestures.hpp" #include "../protocols/PointerGestures.hpp"
#include "../protocols/FractionalScale.hpp" #include "../protocols/FractionalScale.hpp"
#include "SeatManager.hpp"
#include <wlr/interfaces/wlr_output.h> #include <wlr/interfaces/wlr_output.h>
#include <wlr/render/interface.h> #include <wlr/render/interface.h>
#include <wlr/render/wlr_renderer.h> #include <wlr/render/wlr_renderer.h>
@ -774,7 +775,7 @@ void CPointerManager::attachPointer(SP<IPointer> pointer) {
}); });
listener->frame = pointer->pointerEvents.frame.registerListener([this] (std::any e) { listener->frame = pointer->pointerEvents.frame.registerListener([this] (std::any e) {
wlr_seat_pointer_notify_frame(g_pCompositor->m_sSeat.seat); g_pSeatManager->sendPointerFrame();
}); });
listener->swipeBegin = pointer->pointerEvents.swipeBegin.registerListener([this] (std::any e) { listener->swipeBegin = pointer->pointerEvents.swipeBegin.registerListener([this] (std::any e) {
@ -865,7 +866,7 @@ void CPointerManager::attachTouch(SP<ITouch> touch) {
}); });
listener->frame = touch->touchEvents.frame.registerListener([this] (std::any e) { listener->frame = touch->touchEvents.frame.registerListener([this] (std::any e) {
wlr_seat_touch_notify_frame(g_pCompositor->m_sSeat.seat); g_pSeatManager->sendTouchFrame();
}); });
// clang-format on // clang-format on

View file

@ -28,9 +28,14 @@
#include "../protocols/Tablet.hpp" #include "../protocols/Tablet.hpp"
#include "../protocols/LayerShell.hpp" #include "../protocols/LayerShell.hpp"
#include "../protocols/PresentationTime.hpp" #include "../protocols/PresentationTime.hpp"
#include "../protocols/core/Seat.hpp"
CProtocolManager::CProtocolManager() { CProtocolManager::CProtocolManager() {
// Core
PROTO::seat = std::make_unique<CWLSeatProtocol>(&wl_seat_interface, 9, "WLSeat");
// Extensions
PROTO::tearing = std::make_unique<CTearingControlProtocol>(&wp_tearing_control_manager_v1_interface, 1, "TearingControl"); PROTO::tearing = std::make_unique<CTearingControlProtocol>(&wp_tearing_control_manager_v1_interface, 1, "TearingControl");
PROTO::fractional = std::make_unique<CFractionalScaleProtocol>(&wp_fractional_scale_manager_v1_interface, 1, "FractionalScale"); PROTO::fractional = std::make_unique<CFractionalScaleProtocol>(&wp_fractional_scale_manager_v1_interface, 1, "FractionalScale");
PROTO::xdgOutput = std::make_unique<CXDGOutputProtocol>(&zxdg_output_manager_v1_interface, 3, "XDGOutput"); PROTO::xdgOutput = std::make_unique<CXDGOutputProtocol>(&zxdg_output_manager_v1_interface, 3, "XDGOutput");

View file

@ -0,0 +1,391 @@
#include "SeatManager.hpp"
#include "../protocols/core/Seat.hpp"
#include "../Compositor.hpp"
#include "../devices/IKeyboard.hpp"
#include <algorithm>
CSeatManager::CSeatManager() {
listeners.newSeatResource = PROTO::seat->events.newSeatResource.registerListener([this](std::any res) { onNewSeatResource(std::any_cast<SP<CWLSeatResource>>(res)); });
}
CSeatManager::SSeatResourceContainer::SSeatResourceContainer(SP<CWLSeatResource> res) {
resource = res;
listeners.destroy = res->events.destroy.registerListener(
[this](std::any data) { std::erase_if(g_pSeatManager->seatResources, [this](const auto& e) { return e->resource.expired() || e->resource == resource; }); });
}
void CSeatManager::onNewSeatResource(SP<CWLSeatResource> resource) {
seatResources.emplace_back(makeShared<SSeatResourceContainer>(resource));
}
SP<CSeatManager::SSeatResourceContainer> CSeatManager::containerForResource(SP<CWLSeatResource> seatResource) {
for (auto& c : seatResources) {
if (c->resource == seatResource)
return c;
}
return nullptr;
}
uint32_t CSeatManager::nextSerial(SP<CWLSeatResource> seatResource) {
if (!seatResource)
return 0;
auto container = containerForResource(seatResource);
ASSERT(container);
auto serial = wl_display_next_serial(g_pCompositor->m_sWLDisplay);
container->serials.emplace_back(serial);
if (container->serials.size() > MAX_SERIAL_STORE_LEN)
container->serials.erase(container->serials.begin());
return serial;
}
bool CSeatManager::serialValid(SP<CWLSeatResource> seatResource, uint32_t serial) {
if (!seatResource)
return false;
auto container = containerForResource(seatResource);
ASSERT(container);
for (auto it = container->serials.begin(); it != container->serials.end(); ++it) {
if (*it == serial) {
container->serials.erase(it);
return true;
}
}
return false;
}
void CSeatManager::updateCapabilities(uint32_t capabilities) {
PROTO::seat->updateCapabilities(capabilities);
}
void CSeatManager::setMouse(SP<IPointer> MAUZ) {
if (mouse == MAUZ)
return;
mouse = MAUZ;
}
void CSeatManager::setKeyboard(SP<IKeyboard> KEEB) {
if (keyboard == KEEB)
return;
if (keyboard)
keyboard->active = false;
keyboard = KEEB;
if (KEEB) {
KEEB->active = true;
PROTO::seat->updateRepeatInfo(KEEB->wlr()->repeat_info.rate, KEEB->wlr()->repeat_info.delay);
}
PROTO::seat->updateKeymap();
}
void CSeatManager::setKeyboardFocus(wlr_surface* surf) {
if (state.keyboardFocus == surf)
return;
if (!keyboard || !keyboard->wlr()) {
Debug::log(ERR, "BUG THIS: setKeyboardFocus without a valid keyboard set");
return;
}
hyprListener_keyboardSurfaceDestroy.removeCallback();
if (state.keyboardFocusResource) {
for (auto& k : state.keyboardFocusResource->keyboards) {
if (!k)
continue;
k->sendLeave();
}
}
state.keyboardFocusResource.reset();
state.keyboardFocus = surf;
if (!surf) {
events.keyboardFocusChange.emit();
return;
}
auto client = wl_resource_get_client(surf->resource);
for (auto& r : seatResources) {
if (r->resource->client() == client) {
state.keyboardFocusResource = r->resource;
for (auto& k : state.keyboardFocusResource->keyboards) {
if (!k)
continue;
k->sendEnter(surf);
k->sendMods(keyboard->wlr()->modifiers.depressed, keyboard->wlr()->modifiers.latched, keyboard->wlr()->modifiers.locked, keyboard->wlr()->modifiers.group);
}
break;
}
}
hyprListener_keyboardSurfaceDestroy.initCallback(
&surf->events.destroy, [this](void* owner, void* data) { setKeyboardFocus(nullptr); }, nullptr, "CSeatManager");
events.keyboardFocusChange.emit();
}
void CSeatManager::sendKeyboardKey(uint32_t timeMs, uint32_t key, wl_keyboard_key_state state_) {
if (!state.keyboardFocusResource)
return;
for (auto& k : state.keyboardFocusResource->keyboards) {
if (!k)
continue;
k->sendKey(timeMs, key, state_);
}
}
void CSeatManager::sendKeyboardMods(uint32_t depressed, uint32_t latched, uint32_t locked, uint32_t group) {
if (!state.keyboardFocusResource)
return;
for (auto& k : state.keyboardFocusResource->keyboards) {
if (!k)
continue;
k->sendMods(depressed, latched, locked, group);
}
}
void CSeatManager::setPointerFocus(wlr_surface* surf, const Vector2D& local) {
if (state.pointerFocus == surf)
return;
if (!mouse || !mouse->wlr()) {
Debug::log(ERR, "BUG THIS: setPointerFocus without a valid mouse set");
return;
}
hyprListener_pointerSurfaceDestroy.removeCallback();
if (state.pointerFocusResource) {
for (auto& p : state.pointerFocusResource->pointers) {
if (!p)
continue;
p->sendLeave();
}
}
state.pointerFocusResource.reset();
state.pointerFocus = surf;
if (!surf) {
events.pointerFocusChange.emit();
return;
}
auto client = wl_resource_get_client(surf->resource);
for (auto& r : seatResources) {
if (r->resource->client() == client) {
state.pointerFocusResource = r->resource;
for (auto& p : state.pointerFocusResource->pointers) {
if (!p)
continue;
p->sendEnter(surf, local);
}
break;
}
}
hyprListener_pointerSurfaceDestroy.initCallback(
&surf->events.destroy, [this](void* owner, void* data) { setPointerFocus(nullptr, {}); }, nullptr, "CSeatManager");
events.pointerFocusChange.emit();
}
void CSeatManager::sendPointerMotion(uint32_t timeMs, const Vector2D& local) {
if (!state.pointerFocusResource)
return;
for (auto& p : state.pointerFocusResource->pointers) {
if (!p)
continue;
p->sendMotion(timeMs, local);
}
}
void CSeatManager::sendPointerButton(uint32_t timeMs, uint32_t key, wl_pointer_button_state state_) {
if (!state.pointerFocusResource)
return;
for (auto& p : state.pointerFocusResource->pointers) {
if (!p)
continue;
p->sendButton(timeMs, key, state_);
}
}
void CSeatManager::sendPointerFrame() {
if (!state.pointerFocusResource)
return;
for (auto& p : state.pointerFocusResource->pointers) {
if (!p)
continue;
p->sendFrame();
}
}
void CSeatManager::sendPointerAxis(uint32_t timeMs, wl_pointer_axis axis, double value, int32_t discrete, wl_pointer_axis_source source,
wl_pointer_axis_relative_direction relative) {
if (!state.pointerFocusResource)
return;
for (auto& p : state.pointerFocusResource->pointers) {
if (!p)
continue;
p->sendAxis(timeMs, axis, value);
p->sendAxisSource(source);
p->sendAxisRelativeDirection(axis, relative);
}
}
void CSeatManager::sendTouchDown(wlr_surface* surf, uint32_t timeMs, int32_t id, const Vector2D& local) {
if (state.touchFocus == surf)
return;
hyprListener_touchSurfaceDestroy.removeCallback();
if (state.touchFocusResource) {
for (auto& t : state.touchFocusResource->touches) {
if (!t)
continue;
t->sendUp(timeMs, id);
}
}
state.touchFocusResource.reset();
state.touchFocus = surf;
if (!surf) {
events.touchFocusChange.emit();
return;
}
auto client = wl_resource_get_client(surf->resource);
for (auto& r : seatResources) {
if (r->resource->client() == client) {
state.touchFocusResource = r->resource;
for (auto& t : state.touchFocusResource->touches) {
if (!t)
continue;
t->sendDown(surf, timeMs, id, local);
}
break;
}
}
hyprListener_touchSurfaceDestroy.initCallback(
&surf->events.destroy, [this, timeMs, id](void* owner, void* data) { sendTouchUp(timeMs + 10, id); }, nullptr, "CSeatManager");
events.touchFocusChange.emit();
}
void CSeatManager::sendTouchUp(uint32_t timeMs, int32_t id) {
sendTouchDown(nullptr, timeMs, id, {});
}
void CSeatManager::sendTouchMotion(uint32_t timeMs, int32_t id, const Vector2D& local) {
if (!state.touchFocusResource)
return;
for (auto& t : state.touchFocusResource->touches) {
if (!t)
continue;
t->sendMotion(timeMs, id, local);
}
}
void CSeatManager::sendTouchFrame() {
if (!state.touchFocusResource)
return;
for (auto& t : state.touchFocusResource->touches) {
if (!t)
continue;
t->sendFrame();
}
}
void CSeatManager::sendTouchCancel() {
if (!state.touchFocusResource)
return;
for (auto& t : state.touchFocusResource->touches) {
if (!t)
continue;
t->sendCancel();
}
}
void CSeatManager::sendTouchShape(int32_t id, const Vector2D& shape) {
if (!state.touchFocusResource)
return;
for (auto& t : state.touchFocusResource->touches) {
if (!t)
continue;
t->sendShape(id, shape);
}
}
void CSeatManager::sendTouchOrientation(int32_t id, double angle) {
if (!state.touchFocusResource)
return;
for (auto& t : state.touchFocusResource->touches) {
if (!t)
continue;
t->sendOrientation(id, angle);
}
}
void CSeatManager::onSetCursor(SP<CWLSeatResource> seatResource, uint32_t serial, wlr_surface* surf, const Vector2D& hotspot) {
if (!state.pointerFocusResource || !seatResource || seatResource->client() != state.pointerFocusResource->client()) {
Debug::log(LOG, "[seatmgr] Rejecting a setCursor because the client ain't in focus");
return;
}
// TODO: fix this. Probably should be done in the CWlPointer as the serial could be lost by us.
// if (!serialValid(seatResource, serial)) {
// Debug::log(LOG, "[seatmgr] Rejecting a setCursor because the serial is invalid");
// return;
// }
events.setCursor.emit(SSetCursorEvent{surf, hotspot});
}
SP<CWLSeatResource> CSeatManager::seatResourceForClient(wl_client* client) {
return PROTO::seat->seatResourceForClient(client);
}

View file

@ -0,0 +1,106 @@
#pragma once
#include <wayland-server-protocol.h>
#include "../helpers/WLListener.hpp"
#include "../macros.hpp"
#include "../helpers/signal/Signal.hpp"
#include "../helpers/Vector2D.hpp"
#include <vector>
constexpr size_t MAX_SERIAL_STORE_LEN = 100;
struct wlr_surface;
class CWLSeatResource;
class IPointer;
class IKeyboard;
class CSeatManager {
public:
CSeatManager();
void updateCapabilities(uint32_t capabilities); // in IHID caps
void setMouse(SP<IPointer> mouse);
void setKeyboard(SP<IKeyboard> keeb);
void setKeyboardFocus(wlr_surface* surf);
void sendKeyboardKey(uint32_t timeMs, uint32_t key, wl_keyboard_key_state state);
void sendKeyboardMods(uint32_t depressed, uint32_t latched, uint32_t locked, uint32_t group);
void setPointerFocus(wlr_surface* surf, const Vector2D& local);
void sendPointerMotion(uint32_t timeMs, const Vector2D& local);
void sendPointerButton(uint32_t timeMs, uint32_t key, wl_pointer_button_state state);
void sendPointerFrame();
void sendPointerAxis(uint32_t timeMs, wl_pointer_axis axis, double value, int32_t discrete, wl_pointer_axis_source source, wl_pointer_axis_relative_direction relative);
void sendTouchDown(wlr_surface* surf, uint32_t timeMs, int32_t id, const Vector2D& local);
void sendTouchUp(uint32_t timeMs, int32_t id);
void sendTouchMotion(uint32_t timeMs, int32_t id, const Vector2D& local);
void sendTouchFrame();
void sendTouchCancel();
void sendTouchShape(int32_t id, const Vector2D& shape);
void sendTouchOrientation(int32_t id, double angle);
uint32_t nextSerial(SP<CWLSeatResource> seatResource);
// pops the serial if it was valid, meaning it is consumed.
bool serialValid(SP<CWLSeatResource> seatResource, uint32_t serial);
void onSetCursor(SP<CWLSeatResource> seatResource, uint32_t serial, wlr_surface* surf, const Vector2D& hotspot);
SP<CWLSeatResource> seatResourceForClient(wl_client* client);
struct {
wlr_surface* keyboardFocus = nullptr;
WP<CWLSeatResource> keyboardFocusResource;
wlr_surface* pointerFocus = nullptr;
WP<CWLSeatResource> pointerFocusResource;
wlr_surface* touchFocus = nullptr;
WP<CWLSeatResource> touchFocusResource;
} state;
struct SSetCursorEvent {
wlr_surface* surf = nullptr;
Vector2D hotspot;
};
struct {
CSignal keyboardFocusChange;
CSignal pointerFocusChange;
CSignal touchFocusChange;
CSignal setCursor; // SSetCursorEvent
} events;
// do not write to directly, use set...
WP<IPointer> mouse;
WP<IKeyboard> keyboard;
private:
struct SSeatResourceContainer {
SSeatResourceContainer(SP<CWLSeatResource>);
WP<CWLSeatResource> resource;
std::vector<uint32_t> serials; // old -> new
struct {
CHyprSignalListener destroy;
} listeners;
};
std::vector<SP<SSeatResourceContainer>> seatResources;
void onNewSeatResource(SP<CWLSeatResource> resource);
SP<SSeatResourceContainer> containerForResource(SP<CWLSeatResource> seatResource);
struct {
CHyprSignalListener newSeatResource;
} listeners;
DYNLISTENER(keyboardSurfaceDestroy);
DYNLISTENER(pointerSurfaceDestroy);
DYNLISTENER(touchSurfaceDestroy);
friend struct SSeatResourceContainer;
};
inline UP<CSeatManager> g_pSeatManager;

View file

@ -14,6 +14,7 @@
#include "../../protocols/VirtualKeyboard.hpp" #include "../../protocols/VirtualKeyboard.hpp"
#include "../../protocols/VirtualPointer.hpp" #include "../../protocols/VirtualPointer.hpp"
#include "../../protocols/LayerShell.hpp" #include "../../protocols/LayerShell.hpp"
#include "../../protocols/core/Seat.hpp"
#include "../../devices/Mouse.hpp" #include "../../devices/Mouse.hpp"
#include "../../devices/VirtualPointer.hpp" #include "../../devices/VirtualPointer.hpp"
@ -22,6 +23,7 @@
#include "../../devices/TouchDevice.hpp" #include "../../devices/TouchDevice.hpp"
#include "../../managers/PointerManager.hpp" #include "../../managers/PointerManager.hpp"
#include "../../managers/SeatManager.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) {
@ -30,10 +32,10 @@ CInputManager::CInputManager() {
auto event = std::any_cast<CCursorShapeProtocol::SSetShapeEvent>(data); auto event = std::any_cast<CCursorShapeProtocol::SSetShapeEvent>(data);
if (!g_pCompositor->m_sSeat.seat->pointer_state.focused_client) if (!g_pSeatManager->state.pointerFocusResource)
return; return;
if (wl_resource_get_client(event.pMgr->resource()) != g_pCompositor->m_sSeat.seat->pointer_state.focused_client->client) if (wl_resource_get_client(event.pMgr->resource()) != g_pSeatManager->state.pointerFocusResource->client())
return; return;
Debug::log(LOG, "cursorImage request: shape {} -> {}", (uint32_t)event.shape, event.shapeName); Debug::log(LOG, "cursorImage request: shape {} -> {}", (uint32_t)event.shape, event.shapeName);
@ -52,6 +54,7 @@ CInputManager::CInputManager() {
PROTO::virtualKeyboard->events.newKeyboard.registerListener([this](std::any data) { this->newVirtualKeyboard(std::any_cast<SP<CVirtualKeyboardV1Resource>>(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<CVirtualPointerV1Resource>>(data)); }); PROTO::virtualPointer->events.newPointer.registerListener([this](std::any data) { this->newVirtualMouse(std::any_cast<SP<CVirtualPointerV1Resource>>(data)); });
m_sListeners.setCursor = g_pSeatManager->events.setCursor.registerListener([this](std::any d) { this->processMouseRequest(d); });
} }
CInputManager::~CInputManager() { CInputManager::~CInputManager() {
@ -119,8 +122,7 @@ void CInputManager::sendMotionEventsToFocused() {
m_bEmptyFocusCursorSet = false; m_bEmptyFocusCursorSet = false;
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, g_pCompositor->m_pLastFocus, LOCAL.x, LOCAL.y); g_pSeatManager->setPointerFocus(g_pCompositor->m_pLastFocus, LOCAL);
wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, now.tv_sec * 1000 + now.tv_nsec / 10000000, LOCAL.x, LOCAL.y);
} }
void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
@ -190,7 +192,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
} }
// constraints // constraints
if (!g_pCompositor->m_sSeat.mouse.expired() && isConstrained()) { if (!g_pSeatManager->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();
@ -205,7 +207,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
const auto CLOSESTLOCAL = (CLOSEST - (BOX.has_value() ? BOX->pos() : Vector2D{})) * (SURF->getWindow() ? SURF->getWindow()->m_fX11SurfaceScaledBy : 1.0); const auto CLOSESTLOCAL = (CLOSEST - (BOX.has_value() ? BOX->pos() : Vector2D{})) * (SURF->getWindow() ? SURF->getWindow()->m_fX11SurfaceScaledBy : 1.0);
g_pCompositor->warpCursorTo(CLOSEST, true); g_pCompositor->warpCursorTo(CLOSEST, true);
wlr_seat_pointer_send_motion(g_pCompositor->m_sSeat.seat, time, CLOSESTLOCAL.x, CLOSESTLOCAL.y); g_pSeatManager->sendPointerMotion(time, CLOSESTLOCAL);
PROTO::relativePointer->sendRelativeMotion((uint64_t)time * 1000, {}, {}); PROTO::relativePointer->sendRelativeMotion((uint64_t)time * 1000, {}, {});
} }
@ -218,8 +220,8 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
// update stuff // update stuff
updateDragIcon(); updateDragIcon();
if (!m_sDrag.drag && !m_lCurrentlyHeldButtons.empty() && g_pCompositor->m_pLastFocus && m_pLastMouseSurface) { if (!m_sDrag.drag && !m_lCurrentlyHeldButtons.empty() && g_pCompositor->m_pLastFocus && g_pSeatManager->state.pointerFocus) {
foundSurface = m_pLastMouseSurface; foundSurface = g_pSeatManager->state.pointerFocus;
pFoundLayerSurface = g_pCompositor->getLayerSurfaceFromSurface(foundSurface); pFoundLayerSurface = g_pCompositor->getLayerSurfaceFromSurface(foundSurface);
if (pFoundLayerSurface) { if (pFoundLayerSurface) {
surfacePos = pFoundLayerSurface->position; surfacePos = pFoundLayerSurface->position;
@ -232,7 +234,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
m_bFocusHeldByButtons = true; m_bFocusHeldByButtons = true;
m_bRefocusHeldByButtons = refocus; m_bRefocusHeldByButtons = refocus;
} else if (!g_pCompositor->m_pLastWindow.expired()) { } else if (!g_pCompositor->m_pLastWindow.expired()) {
foundSurface = m_pLastMouseSurface; foundSurface = g_pSeatManager->state.pointerFocus;
pFoundWindow = g_pCompositor->m_pLastWindow.lock(); pFoundWindow = g_pCompositor->m_pLastWindow.lock();
surfaceCoords = g_pCompositor->vectorToSurfaceLocal(mouseCoords, pFoundWindow, foundSurface); surfaceCoords = g_pCompositor->vectorToSurfaceLocal(mouseCoords, pFoundWindow, foundSurface);
@ -371,8 +373,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
m_bEmptyFocusCursorSet = true; m_bEmptyFocusCursorSet = true;
} }
wlr_seat_pointer_clear_focus(g_pCompositor->m_sSeat.seat); g_pSeatManager->setPointerFocus(nullptr, {});
m_pLastMouseSurface = nullptr;
if (refocus || g_pCompositor->m_pLastWindow.expired()) // if we are forcing a refocus, and we don't find a surface, clear the kb focus too! if (refocus || g_pCompositor->m_pLastWindow.expired()) // if we are forcing a refocus, and we don't find a surface, clear the kb focus too!
g_pCompositor->focusWindow(nullptr); g_pCompositor->focusWindow(nullptr);
@ -412,8 +413,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
} }
if (currentlyDraggedWindow.lock() && pFoundWindow != currentlyDraggedWindow) { if (currentlyDraggedWindow.lock() && pFoundWindow != currentlyDraggedWindow) {
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y); g_pSeatManager->setPointerFocus(foundSurface, surfaceLocal);
wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, time, surfaceLocal.x, surfaceLocal.y);
return; return;
} }
@ -441,20 +441,15 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
// enter if change floating style // enter if change floating style
if (FOLLOWMOUSE != 3 && allowKeyboardRefocus) if (FOLLOWMOUSE != 3 && allowKeyboardRefocus)
g_pCompositor->focusWindow(pFoundWindow, foundSurface); g_pCompositor->focusWindow(pFoundWindow, foundSurface);
m_pLastMouseSurface = foundSurface; g_pSeatManager->setPointerFocus(foundSurface, surfaceLocal);
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y); } else if (FOLLOWMOUSE == 2 || FOLLOWMOUSE == 3)
} else if (FOLLOWMOUSE == 2 || FOLLOWMOUSE == 3) { g_pSeatManager->setPointerFocus(foundSurface, surfaceLocal);
m_pLastMouseSurface = foundSurface;
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y);
}
if (pFoundWindow == g_pCompositor->m_pLastWindow) { if (pFoundWindow == g_pCompositor->m_pLastWindow)
m_pLastMouseSurface = foundSurface; g_pSeatManager->setPointerFocus(foundSurface, surfaceLocal);
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y);
}
if (FOLLOWMOUSE != 0 || pFoundWindow == g_pCompositor->m_pLastWindow) if (FOLLOWMOUSE != 0 || pFoundWindow == g_pCompositor->m_pLastWindow)
wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, time, surfaceLocal.x, surfaceLocal.y); g_pSeatManager->setPointerFocus(foundSurface, surfaceLocal);
m_bLastFocusOnLS = false; m_bLastFocusOnLS = false;
return; // don't enter any new surfaces return; // don't enter any new surfaces
@ -489,9 +484,8 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
m_bLastFocusOnLS = true; m_bLastFocusOnLS = true;
} }
m_pLastMouseSurface = foundSurface; g_pSeatManager->setPointerFocus(foundSurface, surfaceLocal);
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y); g_pSeatManager->sendPointerMotion(time, surfaceLocal);
wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, time, surfaceLocal.x, surfaceLocal.y);
} }
void CInputManager::onMouseButton(IPointer::SButtonEvent e) { void CInputManager::onMouseButton(IPointer::SButtonEvent e) {
@ -526,23 +520,23 @@ void CInputManager::onMouseButton(IPointer::SButtonEvent e) {
} }
} }
void CInputManager::processMouseRequest(wlr_seat_pointer_request_set_cursor_event* e) { void CInputManager::processMouseRequest(std::any E) {
if (!cursorImageUnlocked()) if (!cursorImageUnlocked())
return; return;
Debug::log(LOG, "cursorImage request: surface {:x}", (uintptr_t)e->surface); auto e = std::any_cast<CSeatManager::SSetCursorEvent>(E);
if (e->seat_client == g_pCompositor->m_sSeat.seat->pointer_state.focused_client) { Debug::log(LOG, "cursorImage request: surface {:x}", (uintptr_t)e.surf);
if (e->surface != m_sCursorSurfaceInfo.wlSurface.wlr()) { if (e.surf != m_sCursorSurfaceInfo.wlSurface.wlr()) {
m_sCursorSurfaceInfo.wlSurface.unassign(); m_sCursorSurfaceInfo.wlSurface.unassign();
if (e->surface) if (e.surf)
m_sCursorSurfaceInfo.wlSurface.assign(e->surface); m_sCursorSurfaceInfo.wlSurface.assign(e.surf);
} }
if (e->surface) { if (e.surf) {
m_sCursorSurfaceInfo.vHotspot = {e->hotspot_x, e->hotspot_y}; m_sCursorSurfaceInfo.vHotspot = e.hotspot;
m_sCursorSurfaceInfo.hidden = false; m_sCursorSurfaceInfo.hidden = false;
} else { } else {
m_sCursorSurfaceInfo.vHotspot = {}; m_sCursorSurfaceInfo.vHotspot = {};
@ -552,8 +546,7 @@ void CInputManager::processMouseRequest(wlr_seat_pointer_request_set_cursor_even
m_sCursorSurfaceInfo.name = ""; m_sCursorSurfaceInfo.name = "";
m_sCursorSurfaceInfo.inUse = true; m_sCursorSurfaceInfo.inUse = true;
g_pHyprRenderer->setCursorSurface(&m_sCursorSurfaceInfo.wlSurface, e->hotspot_x, e->hotspot_y); g_pHyprRenderer->setCursorSurface(&m_sCursorSurfaceInfo.wlSurface, e.hotspot.x, e.hotspot.y);
}
} }
void CInputManager::restoreCursorIconToApp() { void CInputManager::restoreCursorIconToApp() {
@ -659,7 +652,7 @@ void CInputManager::processMouseDownNormal(const IPointer::SButtonEvent& 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.expired() || !isConstrained()) /* No constraints */ if ((g_pSeatManager->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
@ -681,8 +674,7 @@ void CInputManager::processMouseDownNormal(const IPointer::SButtonEvent& e) {
} }
// notify app if we didnt handle it // notify app if we didnt handle it
if (g_pCompositor->doesSeatAcceptInput(g_pCompositor->m_pLastFocus)) g_pSeatManager->sendPointerButton(e.timeMs, e.button, e.state);
wlr_seat_pointer_notify_button(g_pCompositor->m_sSeat.seat, e.timeMs, e.button, e.state);
if (const auto PMON = g_pCompositor->getMonitorFromVector(mouseCoords); PMON != g_pCompositor->m_pLastMonitor.get() && PMON) if (const auto PMON = g_pCompositor->getMonitorFromVector(mouseCoords); PMON != g_pCompositor->m_pLastMonitor.get() && PMON)
g_pCompositor->setActiveMonitor(PMON); g_pCompositor->setActiveMonitor(PMON);
@ -747,14 +739,13 @@ void CInputManager::onMouseWheel(IPointer::SAxisEvent e) {
if (*POFFWINDOWAXIS == 3) if (*POFFWINDOWAXIS == 3)
g_pCompositor->warpCursorTo({TEMPCURX, TEMPCURY}, true); g_pCompositor->warpCursorTo({TEMPCURX, TEMPCURY}, true);
wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, e.timeMs, TEMPCURX - BOX.x, TEMPCURY - BOX.y); g_pSeatManager->sendPointerMotion(e.timeMs, Vector2D{TEMPCURX, TEMPCURY} - BOX.pos());
wlr_seat_pointer_notify_frame(g_pCompositor->m_sSeat.seat); g_pSeatManager->sendPointerFrame();
} }
} }
} }
wlr_seat_pointer_notify_axis(g_pCompositor->m_sSeat.seat, e.timeMs, e.axis, factor * e.delta, std::round(factor * e.deltaDiscrete), e.source, g_pSeatManager->sendPointerAxis(e.timeMs, e.axis, factor * e.delta, std::round(factor * e.deltaDiscrete), e.source, WL_POINTER_AXIS_RELATIVE_DIRECTION_IDENTICAL);
WL_POINTER_AXIS_RELATIVE_DIRECTION_IDENTICAL);
} }
Vector2D CInputManager::getMouseCoordsInternal() { Vector2D CInputManager::getMouseCoordsInternal() {
@ -826,13 +817,9 @@ void CInputManager::setupKeyboard(SP<IKeyboard> keeb) {
disableAllKeyboards(false); disableAllKeyboards(false);
g_pCompositor->m_sSeat.keyboard = keeb;
keeb->active = true;
applyConfigToKeyboard(keeb); applyConfigToKeyboard(keeb);
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, keeb->wlr()); g_pSeatManager->setKeyboard(keeb);
} }
void CInputManager::setKeyboardLayout() { void CInputManager::setKeyboardLayout() {
@ -1015,7 +1002,7 @@ void CInputManager::setupMouse(SP<IPointer> mauz) {
}, },
mauz.get()); mauz.get());
g_pCompositor->m_sSeat.mouse = mauz; g_pSeatManager->setMouse(mauz);
m_tmrLastCursorMovement.reset(); m_tmrLastCursorMovement.reset();
} }
@ -1185,12 +1172,11 @@ void CInputManager::destroyKeyboard(SP<IKeyboard> pKeyboard) {
std::erase_if(m_vKeyboards, [pKeyboard](const auto& other) { return other == pKeyboard; }); std::erase_if(m_vKeyboards, [pKeyboard](const auto& other) { return other == pKeyboard; });
if (m_vKeyboards.size() > 0) { if (m_vKeyboards.size() > 0) {
g_pCompositor->m_sSeat.keyboard = m_vKeyboards.back(); const auto PNEWKEYBOARD = m_vKeyboards.back();
g_pCompositor->m_sSeat.keyboard->active = true; g_pSeatManager->setKeyboard(PNEWKEYBOARD);
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, g_pCompositor->m_sSeat.keyboard->wlr()); PNEWKEYBOARD->active = true;
} else { } else {
g_pCompositor->m_sSeat.keyboard.reset(); g_pSeatManager->setKeyboard(nullptr);
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, nullptr);
} }
removeFromHIDs(pKeyboard); removeFromHIDs(pKeyboard);
@ -1199,9 +1185,9 @@ void CInputManager::destroyKeyboard(SP<IKeyboard> pKeyboard) {
void CInputManager::destroyPointer(SP<IPointer> mouse) { void CInputManager::destroyPointer(SP<IPointer> mouse) {
std::erase_if(m_vPointers, [mouse](const auto& other) { return other == mouse; }); std::erase_if(m_vPointers, [mouse](const auto& other) { return other == mouse; });
g_pCompositor->m_sSeat.mouse = m_vPointers.size() > 0 ? m_vPointers.front() : nullptr; g_pSeatManager->setMouse(m_vPointers.size() > 0 ? m_vPointers.front() : nullptr);
if (!g_pCompositor->m_sSeat.mouse.expired()) if (!g_pSeatManager->mouse.expired())
unconstrainMouse(); unconstrainMouse();
removeFromHIDs(mouse); removeFromHIDs(mouse);
@ -1287,8 +1273,8 @@ void CInputManager::onKeyboardKey(std::any event, SP<IKeyboard> pKeyboard) {
IME->setKeyboard(pKeyboard->wlr()); IME->setKeyboard(pKeyboard->wlr());
IME->sendKey(e.timeMs, e.keycode, e.state); IME->sendKey(e.timeMs, e.keycode, e.state);
} else { } else {
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, pKeyboard->wlr()); g_pSeatManager->setKeyboard(pKeyboard);
wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, e.timeMs, e.keycode, e.state); g_pSeatManager->sendKeyboardKey(e.timeMs, e.keycode, e.state);
} }
updateKeyboardsLeds(pKeyboard); updateKeyboardsLeds(pKeyboard);
@ -1313,8 +1299,8 @@ void CInputManager::onKeyboardMod(SP<IKeyboard> pKeyboard) {
IME->setKeyboard(PWLRKB); 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, PWLRKB); g_pSeatManager->setKeyboard(pKeyboard);
wlr_seat_keyboard_notify_modifiers(g_pCompositor->m_sSeat.seat, &MODS); g_pSeatManager->sendKeyboardMods(MODS.depressed, MODS.latched, MODS.locked, MODS.group);
} }
updateKeyboardsLeds(pKeyboard); updateKeyboardsLeds(pKeyboard);
@ -1361,7 +1347,7 @@ void CInputManager::updateDragIcon() {
} }
void CInputManager::unconstrainMouse() { void CInputManager::unconstrainMouse() {
if (g_pCompositor->m_sSeat.mouse.expired()) if (g_pSeatManager->mouse.expired())
return; return;
for (auto& c : m_vConstraints) { for (auto& c : m_vConstraints) {
@ -1410,7 +1396,7 @@ void CInputManager::updateCapabilities() {
caps |= WL_SEAT_CAPABILITY_TOUCH; caps |= WL_SEAT_CAPABILITY_TOUCH;
} }
wlr_seat_set_capabilities(g_pCompositor->m_sSeat.seat, caps); g_pSeatManager->updateCapabilities(caps);
m_uiCapabilities = caps; m_uiCapabilities = caps;
} }
@ -1422,7 +1408,7 @@ uint32_t CInputManager::accumulateModsFromAllKBs() {
if (kb->isVirtual() && shouldIgnoreVirtualKeyboard(kb)) if (kb->isVirtual() && shouldIgnoreVirtualKeyboard(kb))
continue; continue;
if (!kb->enabled) if (!kb->enabled || !kb->wlr())
continue; continue;
finalMask |= wlr_keyboard_get_modifiers(kb->wlr()); finalMask |= wlr_keyboard_get_modifiers(kb->wlr());
@ -1657,7 +1643,7 @@ void CInputManager::releaseAllMouseButtons() {
return; return;
for (auto& mb : buttonsCopy) { for (auto& mb : buttonsCopy) {
wlr_seat_pointer_notify_button(g_pCompositor->m_sSeat.seat, 0, mb, WL_POINTER_BUTTON_STATE_RELEASED); g_pSeatManager->sendPointerButton(0, mb, WL_POINTER_BUTTON_STATE_RELEASED);
} }
m_lCurrentlyHeldButtons.clear(); m_lCurrentlyHeldButtons.clear();

View file

@ -118,7 +118,7 @@ class CInputManager {
void setClickMode(eClickBehaviorMode); void setClickMode(eClickBehaviorMode);
eClickBehaviorMode getClickMode(); eClickBehaviorMode getClickMode();
void processMouseRequest(wlr_seat_pointer_request_set_cursor_event* e); void processMouseRequest(std::any e);
void onTouchDown(ITouch::SDownEvent); void onTouchDown(ITouch::SDownEvent);
void onTouchUp(ITouch::SUpEvent); void onTouchUp(ITouch::SUpEvent);
@ -197,7 +197,6 @@ class CInputManager {
// for tracking mouse refocus // for tracking mouse refocus
PHLWINDOWREF m_pLastMouseFocus; PHLWINDOWREF m_pLastMouseFocus;
wlr_surface* m_pLastMouseSurface = nullptr;
// //
bool m_bEmptyFocusCursorSet = false; bool m_bEmptyFocusCursorSet = false;
@ -209,6 +208,7 @@ class CInputManager {
CHyprSignalListener newIdleInhibitor; CHyprSignalListener newIdleInhibitor;
CHyprSignalListener newVirtualKeyboard; CHyprSignalListener newVirtualKeyboard;
CHyprSignalListener newVirtualMouse; CHyprSignalListener newVirtualMouse;
CHyprSignalListener setCursor;
} m_sListeners; } m_sListeners;
bool m_bCursorImageOverridden = false; bool m_bCursorImageOverridden = false;

View file

@ -4,6 +4,7 @@
#include "../../protocols/Tablet.hpp" #include "../../protocols/Tablet.hpp"
#include "../../devices/Tablet.hpp" #include "../../devices/Tablet.hpp"
#include "../../managers/PointerManager.hpp" #include "../../managers/PointerManager.hpp"
#include "../../managers/SeatManager.hpp"
#include "../../protocols/PointerConstraints.hpp" #include "../../protocols/PointerConstraints.hpp"
static void unfocusTool(SP<CTabletTool> tool) { static void unfocusTool(SP<CTabletTool> tool) {
@ -36,7 +37,7 @@ static void focusTool(SP<CTabletTool> tool, SP<CTablet> tablet, wlr_surface* sur
} }
static void refocusTablet(SP<CTablet> tab, SP<CTabletTool> tool, bool motion = false) { static void refocusTablet(SP<CTablet> tab, SP<CTabletTool> tool, bool motion = false) {
const auto LASTHLSURFACE = CWLSurface::surfaceFromWlr(g_pInputManager->m_pLastMouseSurface); const auto LASTHLSURFACE = CWLSurface::surfaceFromWlr(g_pSeatManager->state.pointerFocus);
if (!LASTHLSURFACE || !tool->active) { if (!LASTHLSURFACE || !tool->active) {
if (tool->getSurface()) if (tool->getSurface())
@ -56,7 +57,7 @@ static void refocusTablet(SP<CTablet> tab, SP<CTabletTool> tool, bool motion = f
const auto CURSORPOS = g_pInputManager->getMouseCoordsInternal(); const auto CURSORPOS = g_pInputManager->getMouseCoordsInternal();
focusTool(tool, tab, g_pInputManager->m_pLastMouseSurface); focusTool(tool, tab, g_pSeatManager->state.pointerFocus);
if (!motion) if (!motion)
return; return;

View file

@ -3,6 +3,7 @@
#include "../../config/ConfigValue.hpp" #include "../../config/ConfigValue.hpp"
#include "../../protocols/IdleNotify.hpp" #include "../../protocols/IdleNotify.hpp"
#include "../../devices/ITouch.hpp" #include "../../devices/ITouch.hpp"
#include "../SeatManager.hpp"
void CInputManager::onTouchDown(ITouch::SDownEvent e) { void CInputManager::onTouchDown(ITouch::SDownEvent e) {
static auto PSWIPETOUCH = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_touch"); static auto PSWIPETOUCH = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_touch");
@ -76,7 +77,7 @@ void CInputManager::onTouchDown(ITouch::SDownEvent e) {
} else } else
return; // oops, nothing found. return; // oops, nothing found.
wlr_seat_touch_notify_down(g_pCompositor->m_sSeat.seat, m_sTouchData.touchFocusSurface, e.timeMs, e.touchID, local.x, local.y); g_pSeatManager->sendTouchDown(m_sTouchData.touchFocusSurface, e.timeMs, e.touchID, local);
PROTO::idle->onActivity(); PROTO::idle->onActivity();
} }
@ -90,9 +91,8 @@ void CInputManager::onTouchUp(ITouch::SUpEvent e) {
return; return;
} }
if (m_sTouchData.touchFocusSurface) { if (m_sTouchData.touchFocusSurface)
wlr_seat_touch_notify_up(g_pCompositor->m_sSeat.seat, e.timeMs, e.touchID); g_pSeatManager->sendTouchUp(e.timeMs, e.touchID);
}
} }
void CInputManager::onTouchMove(ITouch::SMotionEvent e) { void CInputManager::onTouchMove(ITouch::SMotionEvent e) {
@ -131,8 +131,7 @@ void CInputManager::onTouchMove(ITouch::SMotionEvent e) {
if (m_sTouchData.touchFocusWindow->m_bIsX11) if (m_sTouchData.touchFocusWindow->m_bIsX11)
local = local * m_sTouchData.touchFocusWindow->m_fX11SurfaceScaledBy; local = local * m_sTouchData.touchFocusWindow->m_fX11SurfaceScaledBy;
wlr_seat_touch_notify_motion(g_pCompositor->m_sSeat.seat, e.timeMs, e.touchID, local.x, local.y); g_pSeatManager->sendTouchMotion(e.timeMs, e.touchID, local);
// wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, e->time_msec, local.x, local.y);
} else if (!m_sTouchData.touchFocusLS.expired()) { } else if (!m_sTouchData.touchFocusLS.expired()) {
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_sTouchData.touchFocusLS->monitorID); const auto PMONITOR = g_pCompositor->getMonitorFromID(m_sTouchData.touchFocusLS->monitorID);
@ -140,7 +139,6 @@ void CInputManager::onTouchMove(ITouch::SMotionEvent e) {
const auto local = g_pInputManager->getMouseCoordsInternal() - m_sTouchData.touchSurfaceOrigin; const auto local = g_pInputManager->getMouseCoordsInternal() - m_sTouchData.touchSurfaceOrigin;
wlr_seat_touch_notify_motion(g_pCompositor->m_sSeat.seat, e.timeMs, e.touchID, local.x, local.y); g_pSeatManager->sendTouchMotion(e.timeMs, e.touchID, local);
// wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, e->time_msec, local.x, local.y);
} }
} }

View file

@ -1,124 +1,125 @@
#include "FocusGrab.hpp" #include "FocusGrab.hpp"
#include "Compositor.hpp" #include "Compositor.hpp"
#include <hyprland-focus-grab-v1.hpp> #include <hyprland-focus-grab-v1.hpp>
#include <managers/input/InputManager.hpp> #include "../managers/input/InputManager.hpp"
#include "../managers/SeatManager.hpp"
#include <cstdint> #include <cstdint>
#include <memory> #include <memory>
#include <wayland-server.h> #include <wayland-server.h>
static void focus_grab_pointer_enter(wlr_seat_pointer_grab* grab, wlr_surface* surface, double sx, double sy) { // 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)) // if (static_cast<CFocusGrab*>(grab->data)->isSurfaceComitted(surface))
wlr_seat_pointer_enter(grab->seat, surface, sx, sy); // wlr_seat_pointer_enter(grab->seat, surface, sx, sy);
else // else
wlr_seat_pointer_clear_focus(grab->seat); // wlr_seat_pointer_clear_focus(grab->seat);
} // }
static void focus_grab_pointer_clear_focus(wlr_seat_pointer_grab* grab) { // static void focus_grab_pointer_clear_focus(wlr_seat_pointer_grab* grab) {
wlr_seat_pointer_clear_focus(grab->seat); // 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) { // 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); // 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) { // 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); // uint32_t serial = wlr_seat_pointer_send_button(grab->seat, time, button, state);
if (serial) // if (serial)
return serial; // return serial;
else { // else {
static_cast<CFocusGrab*>(grab->data)->finish(true); // static_cast<CFocusGrab*>(grab->data)->finish(true);
return 0; // 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, // 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) { // 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); // 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) { // static void focus_grab_pointer_frame(wlr_seat_pointer_grab* grab) {
wlr_seat_pointer_send_frame(grab->seat); // wlr_seat_pointer_send_frame(grab->seat);
} // }
static void focus_grab_pointer_cancel(wlr_seat_pointer_grab* grab) { // static void focus_grab_pointer_cancel(wlr_seat_pointer_grab* grab) {
static_cast<CFocusGrab*>(grab->data)->finish(true); // static_cast<CFocusGrab*>(grab->data)->finish(true);
} // }
static const wlr_pointer_grab_interface focus_grab_pointer_impl = { // static const wlr_pointer_grab_interface focus_grab_pointer_impl = {
.enter = focus_grab_pointer_enter, // .enter = focus_grab_pointer_enter,
.clear_focus = focus_grab_pointer_clear_focus, // .clear_focus = focus_grab_pointer_clear_focus,
.motion = focus_grab_pointer_motion, // .motion = focus_grab_pointer_motion,
.button = focus_grab_pointer_button, // .button = focus_grab_pointer_button,
.axis = focus_grab_pointer_axis, // .axis = focus_grab_pointer_axis,
.frame = focus_grab_pointer_frame, // .frame = focus_grab_pointer_frame,
.cancel = focus_grab_pointer_cancel, // .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) { // 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)) // if (static_cast<CFocusGrab*>(grab->data)->isSurfaceComitted(surface))
wlr_seat_keyboard_enter(grab->seat, surface, keycodes, num_keycodes, modifiers); // 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 void focus_grab_keyboard_clear_focus(wlr_seat_keyboard_grab* grab) {
static_cast<CFocusGrab*>(grab->data)->finish(true); // 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) { // 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); // 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) { // static void focus_grab_keyboard_modifiers(wlr_seat_keyboard_grab* grab, const wlr_keyboard_modifiers* modifiers) {
wlr_seat_keyboard_send_modifiers(grab->seat, modifiers); // wlr_seat_keyboard_send_modifiers(grab->seat, modifiers);
} // }
static void focus_grab_keyboard_cancel(wlr_seat_keyboard_grab* grab) { // static void focus_grab_keyboard_cancel(wlr_seat_keyboard_grab* grab) {
static_cast<CFocusGrab*>(grab->data)->finish(true); // static_cast<CFocusGrab*>(grab->data)->finish(true);
} // }
static const wlr_keyboard_grab_interface focus_grab_keyboard_impl = { // static const wlr_keyboard_grab_interface focus_grab_keyboard_impl = {
.enter = focus_grab_keyboard_enter, // .enter = focus_grab_keyboard_enter,
.clear_focus = focus_grab_keyboard_clear_focus, // .clear_focus = focus_grab_keyboard_clear_focus,
.key = focus_grab_keyboard_key, // .key = focus_grab_keyboard_key,
.modifiers = focus_grab_keyboard_modifiers, // .modifiers = focus_grab_keyboard_modifiers,
.cancel = focus_grab_keyboard_cancel, // .cancel = focus_grab_keyboard_cancel,
}; // };
static uint32_t focus_grab_touch_down(wlr_seat_touch_grab* grab, uint32_t time, wlr_touch_point* point) { // 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)) // if (!static_cast<CFocusGrab*>(grab->data)->isSurfaceComitted(point->surface))
return 0; // 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) { // 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); // 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) { // 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); // 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) { // static void focus_grab_touch_frame(wlr_seat_touch_grab* grab) {
wlr_seat_touch_send_frame(grab->seat); // wlr_seat_touch_send_frame(grab->seat);
} // }
static void focus_grab_touch_cancel(wlr_seat_touch_grab* grab) { // static void focus_grab_touch_cancel(wlr_seat_touch_grab* grab) {
static_cast<CFocusGrab*>(grab->data)->finish(true); // static_cast<CFocusGrab*>(grab->data)->finish(true);
} // }
static const wlr_touch_grab_interface focus_grab_touch_impl = { // static const wlr_touch_grab_interface focus_grab_touch_impl = {
.down = focus_grab_touch_down, // .down = focus_grab_touch_down,
.up = focus_grab_touch_up, // .up = focus_grab_touch_up,
.motion = focus_grab_touch_motion, // .motion = focus_grab_touch_motion,
.enter = focus_grab_touch_enter, // .enter = focus_grab_touch_enter,
.frame = focus_grab_touch_frame, // .frame = focus_grab_touch_frame,
.cancel = focus_grab_touch_cancel, // .cancel = focus_grab_touch_cancel,
}; // };
CFocusGrabSurfaceState::CFocusGrabSurfaceState(CFocusGrab* grab, wlr_surface* surface) { CFocusGrabSurfaceState::CFocusGrabSurfaceState(CFocusGrab* grab, wlr_surface* surface) {
hyprListener_surfaceDestroy.initCallback( hyprListener_surfaceDestroy.initCallback(
@ -133,14 +134,14 @@ CFocusGrab::CFocusGrab(SP<CHyprlandFocusGrabV1> resource_) : resource(resource_)
if (!resource->resource()) if (!resource->resource())
return; return;
m_sPointerGrab.interface = &focus_grab_pointer_impl; // m_sPointerGrab.interface = &focus_grab_pointer_impl;
m_sPointerGrab.data = this; // m_sPointerGrab.data = this;
m_sKeyboardGrab.interface = &focus_grab_keyboard_impl; // m_sKeyboardGrab.interface = &focus_grab_keyboard_impl;
m_sKeyboardGrab.data = this; // m_sKeyboardGrab.data = this;
m_sTouchGrab.interface = &focus_grab_touch_impl; // m_sTouchGrab.interface = &focus_grab_touch_impl;
m_sTouchGrab.data = this; // m_sTouchGrab.data = this;
resource->setDestroy([this](CHyprlandFocusGrabV1* pMgr) { PROTO::focusGrab->destroyGrab(this); }); resource->setDestroy([this](CHyprlandFocusGrabV1* pMgr) { PROTO::focusGrab->destroyGrab(this); });
resource->setOnDestroy([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() { void CFocusGrab::start() {
if (!m_bGrabActive) { if (!m_bGrabActive) {
wlr_seat_pointer_start_grab(g_pCompositor->m_sSeat.seat, &m_sPointerGrab); // 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_keyboard_start_grab(g_pCompositor->m_sSeat.seat, &m_sKeyboardGrab);
wlr_seat_touch_start_grab(g_pCompositor->m_sSeat.seat, &m_sTouchGrab); // wlr_seat_touch_start_grab(g_pCompositor->m_sSeat.seat, &m_sTouchGrab);
m_bGrabActive = true; m_bGrabActive = true;
// Ensure the grab ends if another grab begins, including from xdg_popup::grab. // Ensure the grab ends if another grab begins, including from xdg_popup::grab.
hyprListener_pointerGrabStarted.initCallback( // hyprListener_pointerGrabStarted.initCallback(
&g_pCompositor->m_sSeat.seat->events.pointer_grab_begin, [this](void*, void*) { finish(true); }, this, "CFocusGrab"); // &g_pCompositor->m_sSeat.seat->events.pointer_grab_begin, [this](void*, void*) { finish(true); }, this, "CFocusGrab");
hyprListener_keyboardGrabStarted.initCallback( // hyprListener_keyboardGrabStarted.initCallback(
&g_pCompositor->m_sSeat.seat->events.keyboard_grab_begin, [this](void*, void*) { finish(true); }, this, "CFocusGrab"); // &g_pCompositor->m_sSeat.seat->events.keyboard_grab_begin, [this](void*, void*) { finish(true); }, this, "CFocusGrab");
hyprListener_touchGrabStarted.initCallback( // hyprListener_touchGrabStarted.initCallback(
&g_pCompositor->m_sSeat.seat->events.touch_grab_begin, [this](void*, void*) { finish(true); }, this, "CFocusGrab"); // &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. // Ensure new surfaces are focused if under the mouse when comitted.
@ -192,28 +193,28 @@ void CFocusGrab::start() {
void CFocusGrab::finish(bool sendCleared) { void CFocusGrab::finish(bool sendCleared) {
if (m_bGrabActive) { if (m_bGrabActive) {
m_bGrabActive = false; m_bGrabActive = false;
hyprListener_pointerGrabStarted.removeCallback(); // hyprListener_pointerGrabStarted.removeCallback();
hyprListener_keyboardGrabStarted.removeCallback(); // hyprListener_keyboardGrabStarted.removeCallback();
hyprListener_touchGrabStarted.removeCallback(); // hyprListener_touchGrabStarted.removeCallback();
// Only clear grabs that belong to this focus grab. When superseded by another grab // 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. // or xdg_popup grab we might not own the current grab.
bool hadGrab = false; bool hadGrab = false;
if (g_pCompositor->m_sSeat.seat->pointer_state.grab == &m_sPointerGrab) { // if (g_pCompositor->m_sSeat.seat->pointer_state.grab == &m_sPointerGrab) {
wlr_seat_pointer_end_grab(g_pCompositor->m_sSeat.seat); // wlr_seat_pointer_end_grab(g_pCompositor->m_sSeat.seat);
hadGrab = true; // hadGrab = true;
} // }
if (g_pCompositor->m_sSeat.seat->keyboard_state.grab == &m_sKeyboardGrab) { // if (g_pCompositor->m_sSeat.seat->keyboard_state.grab == &m_sKeyboardGrab) {
wlr_seat_keyboard_end_grab(g_pCompositor->m_sSeat.seat); // wlr_seat_keyboard_end_grab(g_pCompositor->m_sSeat.seat);
hadGrab = true; // hadGrab = true;
} // }
if (g_pCompositor->m_sSeat.seat->touch_state.grab == &m_sTouchGrab) { // if (g_pCompositor->m_sSeat.seat->touch_state.grab == &m_sTouchGrab) {
wlr_seat_touch_end_grab(g_pCompositor->m_sSeat.seat); // wlr_seat_touch_end_grab(g_pCompositor->m_sSeat.seat);
hadGrab = true; // hadGrab = true;
} // }
m_mSurfaces.clear(); m_mSurfaces.clear();
@ -248,7 +249,7 @@ void CFocusGrab::eraseSurface(wlr_surface* surface) {
} }
void CFocusGrab::refocusKeyboard() { 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)) if (keyboardSurface != nullptr && isSurfaceComitted(keyboardSurface))
return; return;

View file

@ -44,9 +44,9 @@ class CFocusGrab {
SP<CHyprlandFocusGrabV1> resource; SP<CHyprlandFocusGrabV1> resource;
std::unordered_map<wlr_surface*, UP<CFocusGrabSurfaceState>> m_mSurfaces; std::unordered_map<wlr_surface*, UP<CFocusGrabSurfaceState>> m_mSurfaces;
wlr_seat_pointer_grab m_sPointerGrab; // wlr_seat_pointer_grab m_sPointerGrab;
wlr_seat_keyboard_grab m_sKeyboardGrab; // wlr_seat_keyboard_grab m_sKeyboardGrab;
wlr_seat_touch_grab m_sTouchGrab; // wlr_seat_touch_grab m_sTouchGrab;
bool m_bGrabActive = false; bool m_bGrabActive = false;
DYNLISTENER(pointerGrabStarted); DYNLISTENER(pointerGrabStarted);

View file

@ -1,5 +1,7 @@
#include "InputMethodV2.hpp" #include "InputMethodV2.hpp"
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../managers/SeatManager.hpp"
#include "../devices/IKeyboard.hpp"
#include <sys/mman.h> #include <sys/mman.h>
#define LOGM PROTO::ime->protoLog #define LOGM PROTO::ime->protoLog
@ -11,14 +13,12 @@ CInputMethodKeyboardGrabV2::CInputMethodKeyboardGrabV2(SP<CZwpInputMethodKeyboar
resource->setRelease([this](CZwpInputMethodKeyboardGrabV2* r) { PROTO::ime->destroyResource(this); }); resource->setRelease([this](CZwpInputMethodKeyboardGrabV2* r) { PROTO::ime->destroyResource(this); });
resource->setOnDestroy([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 (!g_pSeatManager->keyboard) {
if (!PKEYBOARD) {
LOGM(ERR, "IME called but no active keyboard???"); LOGM(ERR, "IME called but no active keyboard???");
return; return;
} }
sendKeyboardData(PKEYBOARD); sendKeyboardData(g_pSeatManager->keyboard->wlr());
} }
CInputMethodKeyboardGrabV2::~CInputMethodKeyboardGrabV2() { 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) { 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); resource->sendKey(SERIAL, time, key, (uint32_t)state);
} }
void CInputMethodKeyboardGrabV2::sendMods(uint32_t depressed, uint32_t latched, uint32_t locked, uint32_t group) { 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); resource->sendModifiers(SERIAL, depressed, latched, locked, group);
} }

View file

@ -2,6 +2,7 @@
#include "../desktop/WLSurface.hpp" #include "../desktop/WLSurface.hpp"
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../config/ConfigValue.hpp" #include "../config/ConfigValue.hpp"
#include "../managers/SeatManager.hpp"
#define LOGM PROTO::constraints->protoLog #define LOGM PROTO::constraints->protoLog
@ -125,10 +126,10 @@ void CPointerConstraint::activate() {
return; return;
// TODO: hack, probably not a super duper great idea // 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 SURFBOX = pHLSurface->getSurfaceBoxGlobal();
const auto LOCAL = SURFBOX.has_value() ? logicPositionHint() - SURFBOX->pos() : Vector2D{}; 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) if (locked)

View file

@ -1,5 +1,7 @@
#include "PointerGestures.hpp" #include "PointerGestures.hpp"
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../managers/SeatManager.hpp"
#include "core/Seat.hpp"
#define LOGM PROTO::pointerGestures->protoLog #define LOGM PROTO::pointerGestures->protoLog
@ -103,26 +105,26 @@ void CPointerGesturesProtocol::onGetHoldGesture(CZwpPointerGesturesV1* pMgr, uin
} }
void CPointerGesturesProtocol::swipeBegin(uint32_t timeMs, uint32_t fingers) { 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; 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) { for (auto& sw : m_vSwipes) {
if (sw->resource->client() != FOCUSEDCLIENT) if (sw->resource->client() != FOCUSEDCLIENT)
continue; 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) { 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; 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) { for (auto& sw : m_vSwipes) {
if (sw->resource->client() != FOCUSEDCLIENT) 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) { void CPointerGesturesProtocol::swipeEnd(uint32_t timeMs, bool cancelled) {
if (!g_pCompositor->m_sSeat.seat->pointer_state.focused_client) if (!g_pSeatManager->state.pointerFocusResource)
return; 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) { for (auto& sw : m_vSwipes) {
if (sw->resource->client() != FOCUSEDCLIENT) 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) { 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; 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) { for (auto& sw : m_vPinches) {
if (sw->resource->client() != FOCUSEDCLIENT) if (sw->resource->client() != FOCUSEDCLIENT)
continue; 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) { 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; 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) { for (auto& sw : m_vPinches) {
if (sw->resource->client() != FOCUSEDCLIENT) 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) { void CPointerGesturesProtocol::pinchEnd(uint32_t timeMs, bool cancelled) {
if (!g_pCompositor->m_sSeat.seat->pointer_state.focused_client) if (!g_pSeatManager->state.pointerFocusResource)
return; 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) { for (auto& sw : m_vPinches) {
if (sw->resource->client() != FOCUSEDCLIENT) 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) { 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; 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) { for (auto& sw : m_vHolds) {
if (sw->resource->client() != FOCUSEDCLIENT) if (sw->resource->client() != FOCUSEDCLIENT)
continue; 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) { void CPointerGesturesProtocol::holdEnd(uint32_t timeMs, bool cancelled) {
if (!g_pCompositor->m_sSeat.seat->pointer_state.focused_client) if (!g_pSeatManager->state.pointerFocusResource)
return; 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) { for (auto& sw : m_vHolds) {
if (sw->resource->client() != FOCUSEDCLIENT) if (sw->resource->client() != FOCUSEDCLIENT)

View file

@ -1,5 +1,7 @@
#include "RelativePointer.hpp" #include "RelativePointer.hpp"
#include "Compositor.hpp" #include "../Compositor.hpp"
#include "../managers/SeatManager.hpp"
#include "core/Seat.hpp"
#include <algorithm> #include <algorithm>
CRelativePointer::CRelativePointer(SP<CZwpRelativePointerV1> resource_) : resource(resource_) { 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) { 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; 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) { for (auto& rp : m_vRelativePointers) {
if (FOCUSED != rp->client()) if (FOCUSED != rp->client())

View file

@ -1,5 +1,6 @@
#include "SessionLock.hpp" #include "SessionLock.hpp"
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../managers/SeatManager.hpp"
#include "FractionalScale.hpp" #include "FractionalScale.hpp"
#define LOGM PROTO::sessionLock->protoLog #define LOGM PROTO::sessionLock->protoLog
@ -76,7 +77,7 @@ CSessionLockSurface::~CSessionLockSurface() {
} }
void CSessionLockSurface::sendConfigure() { 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); resource->sendConfigure(SERIAL, pMonitor->vecSize.x, pMonitor->vecSize.y);
} }

View file

@ -1,6 +1,8 @@
#include "Tablet.hpp" #include "Tablet.hpp"
#include "../devices/Tablet.hpp" #include "../devices/Tablet.hpp"
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../managers/SeatManager.hpp"
#include "core/Seat.hpp"
#include <algorithm> #include <algorithm>
#define LOGM PROTO::tablet->protoLog #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->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) { 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; if (!g_pSeatManager->state.pointerFocusResource || g_pSeatManager->state.pointerFocusResource->client() != r->client())
e.hotspot_x = hot_x; return;
e.hotspot_y = hot_y;
e.surface = surf ? wlr_surface_from_resource(surf) : nullptr; g_pInputManager->processMouseRequest(CSeatManager::SSetCursorEvent{wlr_surface_from_resource(surf), {hot_x, hot_y}});
e.serial = serial;
g_pInputManager->processMouseRequest(&e);
}); });
} }
@ -539,7 +539,7 @@ void CTabletV2Protocol::down(SP<CTabletTool> tool) {
if (t->tool != tool || !t->current) if (t->tool != tool || !t->current)
continue; 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->resource->sendDown(serial);
t->queueFrame(); t->queueFrame();
} }
@ -586,7 +586,7 @@ void CTabletV2Protocol::proximityIn(SP<CTabletTool> tool, SP<CTablet> tablet, wl
toolResource->current = true; toolResource->current = true;
toolResource->lastSurf = surf; 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->resource->sendProximityIn(serial, tabletResource->resource.get(), surf->resource);
toolResource->queueFrame(); toolResource->queueFrame();
@ -610,7 +610,7 @@ void CTabletV2Protocol::buttonTool(SP<CTabletTool> tool, uint32_t button, uint32
if (t->tool != tool || !t->current) if (t->tool != tool || !t->current)
continue; 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->resource->sendButton(serial, button, (zwpTabletToolV2ButtonState)state);
t->queueFrame(); 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()"); LOGM(ERR, "BUG THIS: group >= t->groups.size()");
return; 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); t->groups.at(group)->resource->sendModeSwitch(timeMs, serial, mode);
} }
} }

437
src/protocols/core/Seat.cpp Normal file
View 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
View 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;
};

View file

@ -2490,8 +2490,8 @@ void CHyprRenderer::recheckSolitaryForMonitor(CMonitor* pMonitor) {
const auto PWORKSPACE = pMonitor->activeWorkspace; const auto PWORKSPACE = pMonitor->activeWorkspace;
if (!PWORKSPACE || !PWORKSPACE->m_bHasFullscreenWindow || g_pInputManager->m_sDrag.drag || g_pCompositor->m_sSeat.exclusiveClient || pMonitor->activeSpecialWorkspace || if (!PWORKSPACE || !PWORKSPACE->m_bHasFullscreenWindow || g_pInputManager->m_sDrag.drag || pMonitor->activeSpecialWorkspace || PWORKSPACE->m_fAlpha.value() != 1.f ||
PWORKSPACE->m_fAlpha.value() != 1.f || PWORKSPACE->m_vRenderOffset.value() != Vector2D{}) PWORKSPACE->m_vRenderOffset.value() != Vector2D{})
return; return;
const auto PCANDIDATE = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID); const auto PCANDIDATE = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);