diff options
| author | 0rtz <46892933+0rtz@users.noreply.github.com> | 2025-10-20 14:13:27 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-10-20 12:13:27 +0100 |
| commit | a4200acfa6247d770c8ee10b42f1503a9a17718b (patch) | |
| tree | 42732bb33134a50fe147ec025cf856957fdd0063 /src/managers/SeatManager.cpp | |
| parent | 59ff7b2f891d06f4097128faf7027a3863542167 (diff) | |
input: fix refocus on grab dismiss (#12014)
Diffstat (limited to 'src/managers/SeatManager.cpp')
| -rw-r--r-- | src/managers/SeatManager.cpp | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/src/managers/SeatManager.cpp b/src/managers/SeatManager.cpp index f354fef6..3b3d8b04 100644 --- a/src/managers/SeatManager.cpp +++ b/src/managers/SeatManager.cpp @@ -616,8 +616,55 @@ void CSeatManager::setCurrentPrimarySelection(SP<IDataSource> source) { void CSeatManager::setGrab(SP<CSeatGrab> grab) { if (m_seatGrab) { auto oldGrab = m_seatGrab; + + // Try to find the parent window from the grab + PHLWINDOW parentWindow; + if (oldGrab && oldGrab->m_surfs.size()) { + // Try to find the surface that had focus when the grab ended + SP<CWLSurfaceResource> focusedSurf; + auto keyboardFocus = m_state.keyboardFocus.lock(); + auto pointerFocus = m_state.pointerFocus.lock(); + + // Check if keyboard or pointer focus is in the grab + for (auto const& s : oldGrab->m_surfs) { + auto surf = s.lock(); + if (surf && (surf == keyboardFocus || surf == pointerFocus)) { + focusedSurf = surf; + break; + } + } + + // Fall back to first surface if no focused surface found + if (!focusedSurf) + focusedSurf = oldGrab->m_surfs.front().lock(); + + if (focusedSurf) { + auto hlSurface = CWLSurface::fromResource(focusedSurf); + if (hlSurface) { + auto popup = hlSurface->getPopup(); + if (popup) { + auto t1Owner = popup->getT1Owner(); + if (t1Owner) + parentWindow = t1Owner->getWindow(); + } + } + } + } + m_seatGrab.reset(); - g_pInputManager->refocus(); + + static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse"); + if (*PFOLLOWMOUSE == 0 || *PFOLLOWMOUSE == 2 || *PFOLLOWMOUSE == 3) { + const auto PMONITOR = g_pCompositor->getMonitorFromCursor(); + + // If this was a popup grab, focus its parent window to maintain context + if (validMapped(parentWindow)) { + g_pCompositor->focusWindow(parentWindow); + Debug::log(LOG, "[seatmgr] Refocused popup parent window {} (follow_mouse={})", parentWindow->m_title, *PFOLLOWMOUSE); + } else + g_pInputManager->refocusLastWindow(PMONITOR); + } else + g_pInputManager->refocus(); auto currentFocus = m_state.keyboardFocus.lock(); auto refocus = !currentFocus; |
