fix: improved focus behaviour on workspace switching for follow_mouse!=1 (#3041)

* fix: improved focus behaviour on workspace switching for follow_mouse!=1

When the 'input:follow_mouse' is not set to 1 and the target workspace
for switching does not currently have the previously focused window,
Hyprland will prioritize focusing on the top-left-most window.

* fix: #2451 call simulateMouseMovement.

* unify logic

* multimon fix

---------

Co-authored-by: vaxerski <43317083+vaxerski@users.noreply.github.com>
This commit is contained in:
memchr 2023-08-21 18:54:02 +00:00 committed by GitHub
parent 9977a8bfd4
commit cb59763d32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 2 deletions

View File

@ -1198,6 +1198,26 @@ CWindow* CCompositor::getFirstWindowOnWorkspace(const int& id) {
return nullptr;
}
CWindow* CCompositor::getTopLeftWindowOnWorkspace(const int& id) {
const auto PWORKSPACE = getWorkspaceByID(id);
if (!PWORKSPACE)
return nullptr;
const auto PMONITOR = getMonitorFromID(PWORKSPACE->m_iMonitorID);
for (auto& w : m_vWindows) {
if (w->m_iWorkspaceID != id || !w->m_bIsMapped || w->isHidden())
continue;
const auto WINDOWIDEALBB = w->getWindowIdealBoundingBoxIgnoreReserved();
if (WINDOWIDEALBB.x <= PMONITOR->vecPosition.x + 1 && WINDOWIDEALBB.y <= PMONITOR->vecPosition.y + 1)
return w.get();
}
return nullptr;
}
bool CCompositor::doesSeatAcceptInput(wlr_surface* surface) {
if (g_pSessionLockManager->isSessionLocked()) {
if (g_pSessionLockManager->isSurfaceSessionLock(surface))

View File

@ -158,6 +158,7 @@ class CCompositor {
CWindow* getUrgentWindow();
bool hasUrgentWindowOnWorkspace(const int&);
CWindow* getFirstWindowOnWorkspace(const int&);
CWindow* getTopLeftWindowOnWorkspace(const int&);
CWindow* getFullscreenWindowOnWorkspace(const int&);
bool doesSeatAcceptInput(wlr_surface*);
bool isWindowActive(CWindow*);

View File

@ -551,13 +551,27 @@ void CMonitor::changeWorkspace(CWorkspace* const pWorkspace, bool internal) {
}
}
static auto* const PFOLLOWMOUSE = &g_pConfigManager->getConfigValuePtr("input:follow_mouse")->intValue;
if (const auto PLASTWINDOW = pWorkspace->getLastFocusedWindow(); PLASTWINDOW)
g_pCompositor->focusWindow(PLASTWINDOW);
else {
g_pCompositor->focusWindow(nullptr);
g_pInputManager->simulateMouseMovement();
CWindow* pWindow = nullptr;
if (*PFOLLOWMOUSE == 1)
pWindow = g_pCompositor->vectorToWindowIdeal(g_pInputManager->getMouseCoordsInternal());
if (!pWindow)
pWindow = g_pCompositor->getTopLeftWindowOnWorkspace(pWorkspace->m_iID);
if (!pWindow)
pWindow = g_pCompositor->getFirstWindowOnWorkspace(pWorkspace->m_iID);
g_pCompositor->focusWindow(pWindow);
}
g_pInputManager->simulateMouseMovement();
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(ID);
// set some flags and fire event