Hyprland/src/managers/SeatManager.hpp

164 lines
5.4 KiB
C++
Raw Normal View History

2024-05-10 19:27:57 +02:00
#pragma once
#include <cstdint>
2024-05-10 19:27:57 +02:00
#include <wayland-server-protocol.h>
#include "../helpers/WLListener.hpp"
#include "../macros.hpp"
#include "../helpers/signal/Signal.hpp"
#include "../helpers/Vector2D.hpp"
2024-05-11 18:13:20 +02:00
#include "../protocols/types/DataDevice.hpp"
2024-05-10 19:27:57 +02:00
#include <vector>
constexpr size_t MAX_SERIAL_STORE_LEN = 100;
class CWLSurfaceResource;
2024-05-10 19:27:57 +02:00
class CWLSeatResource;
class IPointer;
class IKeyboard;
2024-05-11 02:02:57 +02:00
/*
A seat grab defines a restricted set of surfaces that can be focused.
Only one grab can be active at a time
when a grab is removed, refocus() will happen
Different from a constraint.
When first set with setGrab, SeatManager will try to find a surface that is at the mouse pointer to focus,
from first added to last added. If none are, first is focused.
*/
class CSeatGrab {
public:
bool accepts(SP<CWLSurfaceResource> surf);
void add(SP<CWLSurfaceResource> surf);
void remove(SP<CWLSurfaceResource> surf);
2024-05-11 02:02:57 +02:00
void setCallback(std::function<void()> onEnd_);
void clear();
bool keyboard = false;
bool pointer = false;
bool touch = false;
bool removeOnInput = true; // on hard input e.g. click outside, remove
private:
std::vector<WP<CWLSurfaceResource>> surfs;
std::function<void()> onEnd;
2024-05-11 02:02:57 +02:00
friend class CSeatManager;
};
2024-05-10 19:27:57 +02:00
class CSeatManager {
public:
CSeatManager();
void updateCapabilities(uint32_t capabilities); // in IHID caps
void setMouse(SP<IPointer> mouse);
void setKeyboard(SP<IKeyboard> keeb);
void updateActiveKeyboardData(); // updates the clients with the keymap and repeat info
2024-05-10 19:27:57 +02:00
void setKeyboardFocus(SP<CWLSurfaceResource> surf);
2024-05-10 19:27:57 +02:00
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(SP<CWLSurfaceResource> surf, const Vector2D& local);
2024-05-10 19:27:57 +02:00
void sendPointerMotion(uint32_t timeMs, const Vector2D& local);
void sendPointerButton(uint32_t timeMs, uint32_t key, wl_pointer_button_state state);
void sendPointerFrame();
void sendPointerFrame(WP<CWLSeatResource> pResource);
void sendPointerAxis(uint32_t timeMs, wl_pointer_axis axis, double value, int32_t discrete, int32_t value120, wl_pointer_axis_source source,
wl_pointer_axis_relative_direction relative);
2024-05-10 19:27:57 +02:00
void sendTouchDown(SP<CWLSurfaceResource> surf, uint32_t timeMs, int32_t id, const Vector2D& local);
2024-05-10 19:27:57 +02:00
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);
2024-05-11 18:13:20 +02:00
void resendEnterEvents();
2024-05-10 19:27:57 +02:00
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, SP<CWLSurfaceResource> surf, const Vector2D& hotspot);
2024-05-10 19:27:57 +02:00
SP<CWLSeatResource> seatResourceForClient(wl_client* client);
struct {
WP<CWLSurfaceResource> keyboardFocus;
WP<CWLSeatResource> keyboardFocusResource;
2024-05-10 19:27:57 +02:00
WP<CWLSurfaceResource> pointerFocus;
WP<CWLSeatResource> pointerFocusResource;
2024-05-10 19:27:57 +02:00
WP<CWLSurfaceResource> touchFocus;
WP<CWLSeatResource> touchFocusResource;
2024-05-10 19:27:57 +02:00
} state;
struct SSetCursorEvent {
SP<CWLSurfaceResource> surf = nullptr;
Vector2D hotspot;
2024-05-10 19:27:57 +02:00
};
struct {
CSignal keyboardFocusChange;
CSignal pointerFocusChange;
CSignal touchFocusChange;
CSignal setCursor; // SSetCursorEvent
CSignal setSelection;
CSignal setPrimarySelection;
2024-05-10 19:27:57 +02:00
} events;
2024-05-11 18:13:20 +02:00
struct {
WP<IDataSource> currentSelection;
CHyprSignalListener destroySelection;
WP<IDataSource> currentPrimarySelection;
CHyprSignalListener destroyPrimarySelection;
2024-05-11 18:13:20 +02:00
} selection;
void setCurrentSelection(SP<IDataSource> source);
void setCurrentPrimarySelection(SP<IDataSource> source);
2024-05-11 18:13:20 +02:00
2024-05-10 19:27:57 +02:00
// do not write to directly, use set...
WP<IPointer> mouse;
WP<IKeyboard> keyboard;
2024-05-11 02:02:57 +02:00
void setGrab(SP<CSeatGrab> grab); // nullptr removes
SP<CSeatGrab> seatGrab;
2024-05-10 19:27:57 +02:00
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);
2024-05-11 02:02:57 +02:00
void refocusGrab();
2024-05-10 19:27:57 +02:00
struct {
CHyprSignalListener newSeatResource;
CHyprSignalListener keyboardSurfaceDestroy;
CHyprSignalListener pointerSurfaceDestroy;
CHyprSignalListener touchSurfaceDestroy;
2024-05-10 19:27:57 +02:00
} listeners;
2024-05-11 18:13:20 +02:00
Vector2D lastLocalCoords;
2024-05-10 19:27:57 +02:00
friend struct SSeatResourceContainer;
2024-05-11 02:02:57 +02:00
friend class CSeatGrab;
2024-05-10 19:27:57 +02:00
};
inline UP<CSeatManager> g_pSeatManager;