From fc72df8e58bc127442a245f2f29a3246acf77cce Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sat, 11 May 2024 01:02:57 +0100 Subject: seatmgr: Add a grab class --- src/protocols/FocusGrab.cpp | 193 ++++++-------------------------------------- 1 file changed, 24 insertions(+), 169 deletions(-) (limited to 'src/protocols/FocusGrab.cpp') diff --git a/src/protocols/FocusGrab.cpp b/src/protocols/FocusGrab.cpp index 4189ed6e..5f0771e0 100644 --- a/src/protocols/FocusGrab.cpp +++ b/src/protocols/FocusGrab.cpp @@ -7,119 +7,7 @@ #include #include -// static void focus_grab_pointer_enter(wlr_seat_pointer_grab* grab, wlr_surface* surface, double sx, double sy) { -// if (static_cast(grab->data)->isSurfaceComitted(surface)) -// wlr_seat_pointer_enter(grab->seat, surface, sx, sy); -// else -// wlr_seat_pointer_clear_focus(grab->seat); -// } - -// static void focus_grab_pointer_clear_focus(wlr_seat_pointer_grab* grab) { -// wlr_seat_pointer_clear_focus(grab->seat); -// } - -// static void focus_grab_pointer_motion(wlr_seat_pointer_grab* grab, uint32_t time, double sx, double sy) { -// wlr_seat_pointer_send_motion(grab->seat, time, sx, sy); -// } - -// static uint32_t focus_grab_pointer_button(wlr_seat_pointer_grab* grab, uint32_t time, uint32_t button, wl_pointer_button_state state) { -// uint32_t serial = wlr_seat_pointer_send_button(grab->seat, time, button, state); - -// if (serial) -// return serial; -// else { -// static_cast(grab->data)->finish(true); -// return 0; -// } -// } - -// static void focus_grab_pointer_axis(wlr_seat_pointer_grab* grab, uint32_t time, enum wl_pointer_axis orientation, double value, int32_t value_discrete, -// enum wl_pointer_axis_source source, enum wl_pointer_axis_relative_direction relative_direction) { -// wlr_seat_pointer_send_axis(grab->seat, time, orientation, value, value_discrete, source, relative_direction); -// } - -// static void focus_grab_pointer_frame(wlr_seat_pointer_grab* grab) { -// wlr_seat_pointer_send_frame(grab->seat); -// } - -// static void focus_grab_pointer_cancel(wlr_seat_pointer_grab* grab) { -// static_cast(grab->data)->finish(true); -// } - -// static const wlr_pointer_grab_interface focus_grab_pointer_impl = { -// .enter = focus_grab_pointer_enter, -// .clear_focus = focus_grab_pointer_clear_focus, -// .motion = focus_grab_pointer_motion, -// .button = focus_grab_pointer_button, -// .axis = focus_grab_pointer_axis, -// .frame = focus_grab_pointer_frame, -// .cancel = focus_grab_pointer_cancel, -// }; - -// static 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(grab->data)->isSurfaceComitted(surface)) -// wlr_seat_keyboard_enter(grab->seat, surface, keycodes, num_keycodes, modifiers); - -// // otherwise the last grabbed window should retain keyboard focus. -// } - -// static void focus_grab_keyboard_clear_focus(wlr_seat_keyboard_grab* grab) { -// static_cast(grab->data)->finish(true); -// } - -// static void focus_grab_keyboard_key(wlr_seat_keyboard_grab* grab, uint32_t time, uint32_t key, uint32_t state) { -// wlr_seat_keyboard_send_key(grab->seat, time, key, state); -// } - -// static void focus_grab_keyboard_modifiers(wlr_seat_keyboard_grab* grab, const wlr_keyboard_modifiers* modifiers) { -// wlr_seat_keyboard_send_modifiers(grab->seat, modifiers); -// } - -// static void focus_grab_keyboard_cancel(wlr_seat_keyboard_grab* grab) { -// static_cast(grab->data)->finish(true); -// } - -// static const wlr_keyboard_grab_interface focus_grab_keyboard_impl = { -// .enter = focus_grab_keyboard_enter, -// .clear_focus = focus_grab_keyboard_clear_focus, -// .key = focus_grab_keyboard_key, -// .modifiers = focus_grab_keyboard_modifiers, -// .cancel = focus_grab_keyboard_cancel, -// }; - -// static uint32_t focus_grab_touch_down(wlr_seat_touch_grab* grab, uint32_t time, wlr_touch_point* point) { -// if (!static_cast(grab->data)->isSurfaceComitted(point->surface)) -// return 0; - -// return wlr_seat_touch_send_down(grab->seat, point->surface, time, point->touch_id, point->sx, point->sy); -// } - -// static void focus_grab_touch_up(wlr_seat_touch_grab* grab, uint32_t time, wlr_touch_point* point) { -// wlr_seat_touch_send_up(grab->seat, time, point->touch_id); -// } - -// static void focus_grab_touch_motion(wlr_seat_touch_grab* grab, uint32_t time, wlr_touch_point* point) { -// wlr_seat_touch_send_motion(grab->seat, time, point->touch_id, point->sx, point->sy); -// } - -// static void focus_grab_touch_enter(wlr_seat_touch_grab* grab, uint32_t time, wlr_touch_point* point) {} - -// static void focus_grab_touch_frame(wlr_seat_touch_grab* grab) { -// wlr_seat_touch_send_frame(grab->seat); -// } - -// static void focus_grab_touch_cancel(wlr_seat_touch_grab* grab) { -// static_cast(grab->data)->finish(true); -// } - -// static const wlr_touch_grab_interface focus_grab_touch_impl = { -// .down = focus_grab_touch_down, -// .up = focus_grab_touch_up, -// .motion = focus_grab_touch_motion, -// .enter = focus_grab_touch_enter, -// .frame = focus_grab_touch_frame, -// .cancel = focus_grab_touch_cancel, -// }; +#define LOGM PROTO::focusGrab->protoLog CFocusGrabSurfaceState::CFocusGrabSurfaceState(CFocusGrab* grab, wlr_surface* surface) { hyprListener_surfaceDestroy.initCallback( @@ -134,14 +22,10 @@ CFocusGrab::CFocusGrab(SP resource_) : resource(resource_) if (!resource->resource()) return; - // m_sPointerGrab.interface = &focus_grab_pointer_impl; - // m_sPointerGrab.data = this; - - // m_sKeyboardGrab.interface = &focus_grab_keyboard_impl; - // m_sKeyboardGrab.data = this; - - // m_sTouchGrab.interface = &focus_grab_touch_impl; - // m_sTouchGrab.data = this; + grab = makeShared(); + grab->keyboard = true; + grab->pointer = true; + grab->setCallback([this]() { finish(true); }); resource->setDestroy([this](CHyprlandFocusGrabV1* pMgr) { PROTO::focusGrab->destroyGrab(this); }); resource->setOnDestroy([this](CHyprlandFocusGrabV1* pMgr) { PROTO::focusGrab->destroyGrab(this); }); @@ -168,21 +52,8 @@ bool CFocusGrab::isSurfaceComitted(wlr_surface* surface) { void CFocusGrab::start() { if (!m_bGrabActive) { - // wlr_seat_pointer_start_grab(g_pCompositor->m_sSeat.seat, &m_sPointerGrab); - // wlr_seat_keyboard_start_grab(g_pCompositor->m_sSeat.seat, &m_sKeyboardGrab); - // wlr_seat_touch_start_grab(g_pCompositor->m_sSeat.seat, &m_sTouchGrab); m_bGrabActive = true; - - // Ensure the grab ends if another grab begins, including from xdg_popup::grab. - - // hyprListener_pointerGrabStarted.initCallback( - // &g_pCompositor->m_sSeat.seat->events.pointer_grab_begin, [this](void*, void*) { finish(true); }, this, "CFocusGrab"); - - // hyprListener_keyboardGrabStarted.initCallback( - // &g_pCompositor->m_sSeat.seat->events.keyboard_grab_begin, [this](void*, void*) { finish(true); }, this, "CFocusGrab"); - - // hyprListener_touchGrabStarted.initCallback( - // &g_pCompositor->m_sSeat.seat->events.touch_grab_begin, [this](void*, void*) { finish(true); }, this, "CFocusGrab"); + g_pSeatManager->setGrab(grab); } // Ensure new surfaces are focused if under the mouse when comitted. @@ -193,59 +64,39 @@ void CFocusGrab::start() { void CFocusGrab::finish(bool sendCleared) { if (m_bGrabActive) { m_bGrabActive = false; - // hyprListener_pointerGrabStarted.removeCallback(); - // hyprListener_keyboardGrabStarted.removeCallback(); - // hyprListener_touchGrabStarted.removeCallback(); - - // Only clear grabs that belong to this focus grab. When superseded by another grab - // or xdg_popup grab we might not own the current grab. - bool hadGrab = false; - // if (g_pCompositor->m_sSeat.seat->pointer_state.grab == &m_sPointerGrab) { - // wlr_seat_pointer_end_grab(g_pCompositor->m_sSeat.seat); - // hadGrab = true; - // } - - // if (g_pCompositor->m_sSeat.seat->keyboard_state.grab == &m_sKeyboardGrab) { - // wlr_seat_keyboard_end_grab(g_pCompositor->m_sSeat.seat); - // hadGrab = true; - // } - - // if (g_pCompositor->m_sSeat.seat->touch_state.grab == &m_sTouchGrab) { - // wlr_seat_touch_end_grab(g_pCompositor->m_sSeat.seat); - // hadGrab = true; - // } + if (g_pSeatManager->seatGrab == grab) { + g_pSeatManager->setGrab(nullptr); + } + grab->clear(); m_mSurfaces.clear(); if (sendCleared) resource->sendCleared(); - - // Ensure surfaces under the mouse when the grab ends get focus. - if (hadGrab) - g_pInputManager->refocus(); } } void CFocusGrab::addSurface(wlr_surface* surface) { auto iter = m_mSurfaces.find(surface); - if (iter == m_mSurfaces.end()) + if (iter == m_mSurfaces.end()) { m_mSurfaces.emplace(surface, std::make_unique(this, surface)); + } } void CFocusGrab::removeSurface(wlr_surface* surface) { auto iter = m_mSurfaces.find(surface); if (iter != m_mSurfaces.end()) { - if (iter->second->state == CFocusGrabSurfaceState::PendingAddition) + if (iter->second->state == CFocusGrabSurfaceState::PendingAddition) { m_mSurfaces.erase(iter); - else + } else iter->second->state = CFocusGrabSurfaceState::PendingRemoval; } } void CFocusGrab::eraseSurface(wlr_surface* surface) { removeSurface(surface); - commit(); + commit(true); } void CFocusGrab::refocusKeyboard() { @@ -264,22 +115,26 @@ void CFocusGrab::refocusKeyboard() { if (surface) g_pCompositor->focusSurface(surface); else - Debug::log(ERR, "CFocusGrab::refocusKeyboard called with no committed surfaces. This should never happen."); + LOGM(ERR, "CFocusGrab::refocusKeyboard called with no committed surfaces. This should never happen."); } -void CFocusGrab::commit() { +void CFocusGrab::commit(bool removeOnly) { auto surfacesChanged = false; auto anyComitted = false; for (auto iter = m_mSurfaces.begin(); iter != m_mSurfaces.end();) { switch (iter->second->state) { case CFocusGrabSurfaceState::PendingRemoval: + grab->remove(iter->first); iter = m_mSurfaces.erase(iter); surfacesChanged = true; continue; case CFocusGrabSurfaceState::PendingAddition: - iter->second->state = CFocusGrabSurfaceState::Comitted; - surfacesChanged = true; - anyComitted = true; + if (!removeOnly) { + iter->second->state = CFocusGrabSurfaceState::Comitted; + grab->add(iter->first); + surfacesChanged = true; + anyComitted = true; + } break; case CFocusGrabSurfaceState::Comitted: anyComitted = true; break; } -- cgit v1.2.3