diff options
author | vaxerski <[email protected]> | 2023-09-23 01:21:59 +0100 |
---|---|---|
committer | vaxerski <[email protected]> | 2023-09-23 01:28:45 +0100 |
commit | fb80cbe415835a7e0c64e2038d0fc56e8aba0ab4 (patch) | |
tree | 15058bb43121adf14735c4e551064716de92a8a8 | |
parent | 1b48642fd15c433c53876f1b933dcd46265caf8f (diff) | |
download | Hyprland-fb80cbe415835a7e0c64e2038d0fc56e8aba0ab4.tar.gz Hyprland-fb80cbe415835a7e0c64e2038d0fc56e8aba0ab4.zip |
input: properly track mouse focus on drag operations
-rw-r--r-- | src/Compositor.cpp | 28 | ||||
-rw-r--r-- | src/Compositor.hpp | 4 | ||||
-rw-r--r-- | src/helpers/WLSurface.cpp | 2 | ||||
-rw-r--r-- | src/managers/input/InputManager.cpp | 11 | ||||
-rw-r--r-- | src/managers/input/InputManager.hpp | 12 |
5 files changed, 49 insertions, 8 deletions
diff --git a/src/Compositor.cpp b/src/Compositor.cpp index d3f8bab2..92545faf 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -830,6 +830,34 @@ wlr_surface* CCompositor::vectorWindowToSurface(const Vector2D& pos, CWindow* pW return PSURFACE->surface; } +Vector2D CCompositor::vectorToSurfaceLocal(const Vector2D& vec, CWindow* pWindow, wlr_surface* pSurface) { + if (!windowValidMapped(pWindow)) + return {}; + + if (pWindow->m_bIsX11) + return vec - pWindow->m_vRealPosition.goalv(); + + const auto PSURFACE = pWindow->m_uSurface.xdg; + + std::tuple<wlr_surface*, int, int> iterData = {pSurface, -1337, -1337}; + + wlr_xdg_surface_for_each_surface( + PSURFACE, + [](wlr_surface* surf, int x, int y, void* data) { + const auto PDATA = (std::tuple<wlr_surface*, int, int>*)data; + if (surf == std::get<0>(*PDATA)) { + std::get<1>(*PDATA) = x; + std::get<2>(*PDATA) = y; + } + }, + &iterData); + + if (std::get<1>(iterData) == -1337 && std::get<2>(iterData) == -1337) + return vec - pWindow->m_vRealPosition.goalv(); + + return vec - pWindow->m_vRealPosition.goalv() - Vector2D{std::get<1>(iterData), std::get<2>(iterData)}; +} + CMonitor* CCompositor::getMonitorFromOutput(wlr_output* out) { for (auto& m : m_vMonitors) { if (m->output == out) { diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 9102bac4..27a27e3b 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -28,7 +28,8 @@ #include "hyprerror/HyprError.hpp" #include "plugins/PluginSystem.hpp" -enum eManagersInitStage { +enum eManagersInitStage +{ STAGE_PRIORITY = 0, STAGE_LATE }; @@ -138,6 +139,7 @@ class CCompositor { CWindow* vectorToWindowTiled(const Vector2D&); wlr_surface* vectorToLayerSurface(const Vector2D&, std::vector<std::unique_ptr<SLayerSurface>>*, Vector2D*, SLayerSurface**); wlr_surface* vectorWindowToSurface(const Vector2D&, CWindow*, Vector2D& sl); + Vector2D vectorToSurfaceLocal(const Vector2D&, CWindow*, wlr_surface*); CWindow* windowFromCursor(); CWindow* windowFloatingFromCursor(); CMonitor* getMonitorFromOutput(wlr_output*); diff --git a/src/helpers/WLSurface.cpp b/src/helpers/WLSurface.cpp index 8057925b..8524c9a5 100644 --- a/src/helpers/WLSurface.cpp +++ b/src/helpers/WLSurface.cpp @@ -36,6 +36,8 @@ void CWLSurface::destroy() { if (g_pCompositor->m_pLastFocus == m_pWLRSurface) g_pCompositor->m_pLastFocus = nullptr; + if (g_pInputManager->m_pLastMouseSurface == m_pWLRSurface) + g_pInputManager->m_pLastMouseSurface = nullptr; m_pWLRSurface = nullptr; diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 366dc8bd..c8221e56 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -201,10 +201,10 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { pFoundLayerSurface = nullptr; } } else if (g_pCompositor->m_pLastWindow) { - foundSurface = g_pCompositor->m_pLastFocus; + foundSurface = m_pLastMouseSurface; pFoundWindow = g_pCompositor->m_pLastWindow; - surfacePos = g_pCompositor->m_pLastWindow->m_vRealPosition.vec(); + surfaceCoords = g_pCompositor->vectorToSurfaceLocal(mouseCoords, pFoundWindow, foundSurface); m_bFocusHeldByButtons = true; m_bRefocusHeldByButtons = refocus; @@ -389,14 +389,17 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { // enter if change floating style if (FOLLOWMOUSE != 3 && allowKeyboardRefocus) g_pCompositor->focusWindow(pFoundWindow, foundSurface); + m_pLastMouseSurface = foundSurface; wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y); } else if (FOLLOWMOUSE == 2 || FOLLOWMOUSE == 3) { + m_pLastMouseSurface = foundSurface; wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y); } if (pFoundWindow == g_pCompositor->m_pLastWindow) { if (foundSurface != g_pCompositor->m_pLastFocus || m_bLastFocusOnLS) { // ^^^ changed the subsurface ^^^ came back from a LS + m_pLastMouseSurface = foundSurface; wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y); } } @@ -430,6 +433,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { m_bLastFocusOnLS = true; } + m_pLastMouseSurface = foundSurface; 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); } @@ -581,7 +585,8 @@ void CInputManager::processMouseDownNormal(wlr_pointer_button_event* e) { if (*PFOLLOWMOUSE == 3) // don't refocus on full loose break; - if (!g_pCompositor->m_sSeat.mouse || !g_pCompositor->m_sSeat.mouse->currentConstraint) { + if ((!g_pCompositor->m_sSeat.mouse || !g_pCompositor->m_sSeat.mouse->currentConstraint) /* No constraints */ + && (!g_pCompositor->m_pLastWindow && g_pCompositor->m_pLastWindow != w) /* window should change */) { // a bit hacky // if we only pressed one button, allow us to refocus. m_lCurrentlyHeldButtons.size() > 0 will stick the focus if (m_lCurrentlyHeldButtons.size() == 1) { diff --git a/src/managers/input/InputManager.hpp b/src/managers/input/InputManager.hpp index 323be307..670bc4da 100644 --- a/src/managers/input/InputManager.hpp +++ b/src/managers/input/InputManager.hpp @@ -7,12 +7,14 @@ #include "../../helpers/Timer.hpp" #include "InputMethodRelay.hpp" -enum eClickBehaviorMode { +enum eClickBehaviorMode +{ CLICKMODE_DEFAULT = 0, CLICKMODE_KILL }; -enum eMouseBindMode { +enum eMouseBindMode +{ MBIND_INVALID = -1, MBIND_MOVE = 0, MBIND_RESIZE = 1, @@ -20,7 +22,8 @@ enum eMouseBindMode { MBIND_RESIZE_FORCE_RATIO = 3 }; -enum eBorderIconDirection { +enum eBorderIconDirection +{ BORDERICON_NONE, BORDERICON_UP, BORDERICON_DOWN, @@ -181,7 +184,8 @@ class CInputManager { bool m_bLastInputTouch = false; // for tracking mouse refocus - CWindow* m_pLastMouseFocus = nullptr; + CWindow* m_pLastMouseFocus = nullptr; + wlr_surface* m_pLastMouseSurface = nullptr; private: bool m_bCursorImageOverridden = false; |