diff --git a/src/Compositor.cpp b/src/Compositor.cpp index b145022c..0f67b9b1 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -2150,11 +2150,28 @@ void CCompositor::closeWindow(CWindow* pWindow) { } SLayerSurface* CCompositor::getLayerSurfaceFromSurface(wlr_surface* pSurface) { + std::pair result = {pSurface, false}; + for (auto& m : m_vMonitors) { for (auto& lsl : m->m_aLayerSurfaceLayers) { for (auto& ls : lsl) { if (ls->layerSurface && ls->layerSurface->surface == pSurface) return ls.get(); + + static auto iter = [](wlr_surface* surf, int x, int y, void* data) -> void { + if (surf == ((std::pair*)data)->first) { + *(bool*)data = true; + return; + } + }; + + if (!ls->layerSurface || !ls->mapped) + continue; + + wlr_surface_for_each_surface(ls->layerSurface->surface, iter, &result); + + if (result.second) + return ls.get(); } } } diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index bf9ffaef..db9ff108 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -145,6 +145,32 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { // update stuff updateDragIcon(); + if (!m_sDrag.drag && !m_lCurrentlyHeldButtons.empty() && g_pCompositor->m_pLastFocus) { + if (m_bLastFocusOnLS) { + foundSurface = g_pCompositor->m_pLastFocus; + pFoundLayerSurface = g_pCompositor->getLayerSurfaceFromSurface(foundSurface); + if (pFoundLayerSurface) { + surfacePos = g_pCompositor->getLayerSurfaceFromSurface(foundSurface)->position; + m_bFocusHeldByButtons = true; + m_bRefocusHeldByButtons = refocus; + } else { + // ? + foundSurface = nullptr; + pFoundLayerSurface = nullptr; + } + } else if (g_pCompositor->m_pLastWindow) { + foundSurface = g_pCompositor->m_pLastFocus; + + if (!g_pCompositor->m_pLastWindow->m_bIsX11) + g_pCompositor->vectorWindowToSurface(mouseCoords, g_pCompositor->m_pLastWindow, surfaceCoords); + else + surfacePos = g_pCompositor->m_pLastWindow->m_vRealPosition.vec(); + + m_bFocusHeldByButtons = true; + m_bRefocusHeldByButtons = refocus; + } + } + g_pLayoutManager->getCurrentLayout()->onMouseMove(getMouseCoordsInternal()); if (PMONITOR && PMONITOR != g_pCompositor->m_pLastMonitor && (*PMOUSEFOCUSMON || refocus)) { @@ -391,6 +417,16 @@ void CInputManager::onMouseButton(wlr_pointer_button_event* e) { case CLICKMODE_KILL: processMouseDownKill(e); break; default: break; } + + if (m_bFocusHeldByButtons && m_lCurrentlyHeldButtons.empty() && e->state == WLR_BUTTON_RELEASED) { + if (m_bRefocusHeldByButtons) + refocus(); + else + simulateMouseMovement(); + + m_bFocusHeldByButtons = false; + m_bRefocusHeldByButtons = false; + } } void CInputManager::processMouseRequest(wlr_seat_pointer_request_set_cursor_event* e) { diff --git a/src/managers/input/InputManager.hpp b/src/managers/input/InputManager.hpp index b64cae5b..a98ad497 100644 --- a/src/managers/input/InputManager.hpp +++ b/src/managers/input/InputManager.hpp @@ -202,6 +202,10 @@ class CInputManager { SLayerSurface* m_pFoundLSToFocus = nullptr; CWindow* m_pFoundWindowToFocus = nullptr; + // for holding focus on buttons held + bool m_bFocusHeldByButtons = false; + bool m_bRefocusHeldByButtons = false; + // for releasing mouse buttons std::list m_lCurrentlyHeldButtons;