summaryrefslogtreecommitdiff
path: root/src/protocols/FocusGrab.hpp
diff options
context:
space:
mode:
authoroutfoxxed <outfoxxed@outfoxxed.me>2024-05-04 19:14:35 -0700
committerGitHub <noreply@github.com>2024-05-05 03:14:35 +0100
commitaaf35b9f1f0ce49080f2a0b1e7943336b1ba6057 (patch)
tree5e0b23e9b44ee1eabe68d6739c5d1d58ae558037 /src/protocols/FocusGrab.hpp
parent62eadad20fe10ffaf13d9c65ee68608996d93df0 (diff)
protocols: add hyprland_focus_grab_v1 implementation (#5850)
* protocols: add hyprland_focus_grab_v1 implementation * protocols/focus_grab: fix keyboard focus staying on unlisted windows When creating a focus grab with layershell surfaces, the last active toplevel kept keyboard focus. * protocols/focus_grab: fix formatting * protocols/focus_grab: try to pick surface for keyboard focus * focus_grab: update keyboard focus to match spec * Revert "protocols/focus_grab: try to pick surface for keyboard focus" This reverts commit 090358d0d19cc65208641eaefa0a905e99145730. * protocols/focus_grab: fix issues and match new spec * kde-server-decoration: move to new impl * protocols/focus_grab: review fixup * Update hyprland-protocols --------- Co-authored-by: Vaxry <vaxry@vaxry.net>
Diffstat (limited to 'src/protocols/FocusGrab.hpp')
-rw-r--r--src/protocols/FocusGrab.hpp77
1 files changed, 77 insertions, 0 deletions
diff --git a/src/protocols/FocusGrab.hpp b/src/protocols/FocusGrab.hpp
new file mode 100644
index 00000000..11c26774
--- /dev/null
+++ b/src/protocols/FocusGrab.hpp
@@ -0,0 +1,77 @@
+#pragma once
+
+#include "WaylandProtocol.hpp"
+#include "hyprland-focus-grab-v1.hpp"
+#include "macros.hpp"
+#include <cstdint>
+#include <unordered_map>
+#include <vector>
+
+class CFocusGrab;
+
+class CFocusGrabSurfaceState {
+ public:
+ CFocusGrabSurfaceState(CFocusGrab* grab, wlr_surface* surface);
+ ~CFocusGrabSurfaceState();
+
+ enum State {
+ PendingAddition,
+ PendingRemoval,
+ Comitted,
+ } state = PendingAddition;
+
+ private:
+ DYNLISTENER(surfaceDestroy);
+};
+
+class CFocusGrab {
+ public:
+ CFocusGrab(SP<CHyprlandFocusGrabV1> resource_);
+ ~CFocusGrab();
+
+ bool good();
+ bool isSurfaceComitted(wlr_surface* surface);
+
+ void start();
+ void finish(bool sendCleared);
+
+ private:
+ void addSurface(wlr_surface* surface);
+ void removeSurface(wlr_surface* surface);
+ void eraseSurface(wlr_surface* surface);
+ void refocusKeyboard();
+ void commit();
+
+ SP<CHyprlandFocusGrabV1> resource;
+ std::unordered_map<wlr_surface*, UP<CFocusGrabSurfaceState>> m_mSurfaces;
+ wlr_seat_pointer_grab m_sPointerGrab;
+ wlr_seat_keyboard_grab m_sKeyboardGrab;
+ wlr_seat_touch_grab m_sTouchGrab;
+ bool m_bGrabActive = false;
+
+ DYNLISTENER(pointerGrabStarted);
+ DYNLISTENER(keyboardGrabStarted);
+ DYNLISTENER(touchGrabStarted);
+ friend class CFocusGrabSurfaceState;
+};
+
+class CFocusGrabProtocol : public IWaylandProtocol {
+ public:
+ CFocusGrabProtocol(const wl_interface* iface, const int& var, const std::string& name);
+
+ virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);
+
+ private:
+ void onManagerResourceDestroy(wl_resource* res);
+ void destroyGrab(CFocusGrab* grab);
+ void onCreateGrab(CHyprlandFocusGrabManagerV1* pMgr, uint32_t id);
+
+ std::vector<UP<CHyprlandFocusGrabManagerV1>> m_vManagers;
+ std::vector<UP<CFocusGrab>> m_vGrabs;
+
+ friend class CFocusGrab;
+};
+
+namespace PROTO {
+ inline UP<CFocusGrabProtocol> focusGrab;
+}