aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorvaxerski <[email protected]>2023-04-02 13:30:45 +0100
committervaxerski <[email protected]>2023-04-02 13:30:45 +0100
commit0fc145c52cf1743a9bb71a8d7c759305d2323a23 (patch)
tree743ad00776d7c656b4c39c7cdf14819f6f18c80a
parentc2b25f4701c98704303ab4ca9d008a29deb527b3 (diff)
downloadHyprland-0fc145c52cf1743a9bb71a8d7c759305d2323a23.tar.gz
Hyprland-0fc145c52cf1743a9bb71a8d7c759305d2323a23.zip
input: hold focus on mouse buttons
-rw-r--r--src/Compositor.cpp17
-rw-r--r--src/managers/input/InputManager.cpp36
-rw-r--r--src/managers/input/InputManager.hpp4
3 files changed, 57 insertions, 0 deletions
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<wlr_surface*, bool> 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<wlr_surface*, bool>*)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<uint32_t> m_lCurrentlyHeldButtons;