From 4db773b1e7d51cd008ae24f4c457710e8360fef7 Mon Sep 17 00:00:00 2001 From: vaxerski <43317083+vaxerski@users.noreply.github.com> Date: Sat, 2 Apr 2022 13:02:16 +0200 Subject: [PATCH] Fix popups focus on native GDK --- src/Compositor.cpp | 46 +++++++++++++++++++++++++++---- src/Compositor.hpp | 5 +++- src/events/Popups.cpp | 2 +- src/managers/AnimationManager.cpp | 2 +- src/managers/InputManager.cpp | 11 ++++++-- 5 files changed, 55 insertions(+), 11 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index b2947025..b57dd4bf 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -319,6 +319,31 @@ CWindow* CCompositor::windowFloatingFromCursor() { return nullptr; } +wlr_surface* CCompositor::vectorWindowToSurface(const Vector2D& pos, CWindow* pWindow, Vector2D& sl) { + + if (!windowValidMapped(pWindow)) + return nullptr; + + RASSERT(!pWindow->m_bIsX11, "Cannot call vectorWindowToSurface on an X11 window!"); + + const auto PSURFACE = pWindow->m_uSurface.xdg; + + double subx, suby; + + const auto PFOUND = wlr_xdg_surface_surface_at(PSURFACE, pos.x - pWindow->m_vRealPosition.x, pos.y - pWindow->m_vRealPosition.y, &subx, &suby); + + if (PFOUND) { + sl.x = subx; + sl.y = suby; + return PFOUND; + } + + sl.x = pos.x - pWindow->m_vRealPosition.x; + sl.y = pos.y - pWindow->m_vRealPosition.y; + + return PSURFACE->surface; +} + SMonitor* CCompositor::getMonitorFromOutput(wlr_output* out) { for (auto& m : m_lMonitors) { if (m.output == out) { @@ -341,16 +366,15 @@ void CCompositor::focusWindow(CWindow* pWindow) { focusSurface(PWINDOWSURFACE); } -void CCompositor::focusSurface(wlr_surface* pSurface) { - if (m_sSeat.seat->keyboard_state.focused_surface == pSurface) +void CCompositor::focusSurface(wlr_surface* pSurface, CWindow* pWindowOwner) { + if (m_sSeat.seat->keyboard_state.focused_surface == pSurface || (pWindowOwner && m_sSeat.seat->keyboard_state.focused_surface == g_pXWaylandManager->getWindowSurface(pWindowOwner))) return; // Don't focus when already focused on this. if (!pSurface) return; // Unfocus last surface if should - const auto PWINDOWATCURSOR = vectorToWindowIdeal(g_pInputManager->getMouseCoordsInternal()); - if (m_pLastFocus && !(PWINDOWATCURSOR && g_pXWaylandManager->getWindowSurface(PWINDOWATCURSOR) == m_pLastFocus)) + if (m_pLastFocus && !wlr_surface_is_xwayland_surface(pSurface) && !m_pLastFocusWindow) g_pXWaylandManager->activateSurface(m_pLastFocus, false); const auto KEYBOARD = wlr_seat_get_keyboard(m_sSeat.seat); @@ -361,8 +385,14 @@ void CCompositor::focusSurface(wlr_surface* pSurface) { wlr_seat_keyboard_notify_enter(m_sSeat.seat, pSurface, KEYBOARD->keycodes, KEYBOARD->num_keycodes, &KEYBOARD->modifiers); m_pLastFocus = pSurface; + m_pLastFocusWindow = nullptr; - g_pXWaylandManager->activateSurface(pSurface, true); + if (pWindowOwner) { + g_pXWaylandManager->activateSurface(g_pXWaylandManager->getWindowSurface(pWindowOwner), true); + m_pLastFocusWindow = pSurface; + } + else + g_pXWaylandManager->activateSurface(pSurface, true); if (const auto PWINDOW = getWindowFromSurface(pSurface); PWINDOW) Debug::log(LOG, "Set keyboard focus to surface %x, with window name: %s", pSurface, PWINDOW->m_szTitle.c_str()); @@ -492,4 +522,10 @@ void CCompositor::fixXWaylandWindowsOnWorkspace(const int& id) { bool CCompositor::doesSeatAcceptInput(wlr_surface* surface) { return !m_sSeat.exclusiveClient || (surface && m_sSeat.exclusiveClient == wl_resource_get_client(surface->resource)); +} + +bool CCompositor::isWindowActive(CWindow* pWindow) { + const auto PSURFACE = g_pXWaylandManager->getWindowSurface(pWindow); + + return PSURFACE == m_pLastFocus || PSURFACE == m_pLastFocusWindow; } \ No newline at end of file diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 5d67356d..bca0e3c5 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -60,6 +60,7 @@ public: void startCompositor(); wlr_surface* m_pLastFocus = nullptr; + wlr_surface* m_pLastFocusWindow = nullptr; SMonitor* m_pLastMonitor = nullptr; SSeat m_sSeat; @@ -71,13 +72,14 @@ public: SMonitor* getMonitorFromVector(const Vector2D&); void removeWindowFromVectorSafe(CWindow*); void focusWindow(CWindow*); - void focusSurface(wlr_surface*); + void focusSurface(wlr_surface*, CWindow* pWindowOwner = nullptr); bool windowExists(CWindow*); bool windowValidMapped(CWindow*); CWindow* vectorToWindow(const Vector2D&); CWindow* vectorToWindowIdeal(const Vector2D&); CWindow* vectorToWindowTiled(const Vector2D&); wlr_surface* vectorToLayerSurface(const Vector2D&, std::list*, Vector2D*); + wlr_surface* vectorWindowToSurface(const Vector2D&, CWindow*, Vector2D& sl); CWindow* windowFromCursor(); CWindow* windowFloatingFromCursor(); SMonitor* getMonitorFromOutput(wlr_output*); @@ -91,6 +93,7 @@ public: void fixXWaylandWindowsOnWorkspace(const int&); CWindow* getFullscreenWindowOnWorkspace(const int&); bool doesSeatAcceptInput(wlr_surface*); + bool isWindowActive(CWindow*); private: void initAllSignals(); diff --git a/src/events/Popups.cpp b/src/events/Popups.cpp index 6cc6a34e..b265d6a7 100644 --- a/src/events/Popups.cpp +++ b/src/events/Popups.cpp @@ -121,7 +121,7 @@ void Events::listener_mapPopupXDG(void* owner, void* data) { ASSERT(PPOPUP); - Debug::log(LOG, "New XDG Popup mapped"); + Debug::log(LOG, "New XDG Popup mapped at %d %d", (int)*PPOPUP->lx, (int)*PPOPUP->ly); PPOPUP->pSurfaceTree = SubsurfaceTree::createTreeRoot(PPOPUP->popup->base->surface, addPopupGlobalCoords, PPOPUP); diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index de83f023..c165b843 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -23,7 +23,7 @@ void CAnimationManager::tick() { for (auto& w : g_pCompositor->m_lWindows) { // process the borders - const auto& COLOR = g_pXWaylandManager->getWindowSurface(&w) == g_pCompositor->m_pLastFocus ? BORDERACTIVECOL : BORDERINACTIVECOL; + const auto& COLOR = g_pCompositor->isWindowActive(&w) ? BORDERACTIVECOL : BORDERINACTIVECOL; if (BORDERSENABLED) { if (!deltazero(COLOR, w.m_cRealBorderColor)) { diff --git a/src/managers/InputManager.cpp b/src/managers/InputManager.cpp index e7723fbb..4c66c7bf 100644 --- a/src/managers/InputManager.cpp +++ b/src/managers/InputManager.cpp @@ -68,9 +68,12 @@ void CInputManager::mouseMoveUnified(uint32_t time) { // then windows const auto PWINDOWIDEAL = g_pCompositor->vectorToWindowIdeal(mouseCoords); if (!foundSurface && PWINDOWIDEAL) { - foundSurface = g_pXWaylandManager->getWindowSurface(PWINDOWIDEAL); - if (foundSurface) + if (!PWINDOWIDEAL->m_bIsX11) { + foundSurface = g_pCompositor->vectorWindowToSurface(mouseCoords, PWINDOWIDEAL, surfaceCoords); + } else { + foundSurface = g_pXWaylandManager->getWindowSurface(PWINDOWIDEAL); surfacePos = PWINDOWIDEAL->m_vRealPosition; + } } // then surfaces below @@ -97,7 +100,7 @@ void CInputManager::mouseMoveUnified(uint32_t time) { wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y); wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, time, surfaceLocal.x, surfaceLocal.y); - g_pCompositor->focusSurface(foundSurface); + g_pCompositor->focusSurface(foundSurface, PWINDOWIDEAL ? PWINDOWIDEAL : nullptr); g_pLayoutManager->getCurrentLayout()->onMouseMove(getMouseCoordsInternal()); } @@ -109,6 +112,8 @@ void CInputManager::onMouseButton(wlr_pointer_button_event* e) { switch (e->state) { case WLR_BUTTON_PRESSED: + refocus(); + if ((e->button == BTN_LEFT || e->button == BTN_RIGHT) && wlr_keyboard_get_modifiers(PKEYBOARD) == (uint32_t)g_pConfigManager->getInt("general:main_mod_internal")) { currentlyDraggedWindow = g_pCompositor->windowFloatingFromCursor(); dragButton = e->button;