diff options
author | Andrew Pritchard <[email protected]> | 2023-04-07 04:18:53 -0700 |
---|---|---|
committer | GitHub <[email protected]> | 2023-04-07 12:18:53 +0100 |
commit | dfb78e059394a637e0f36242fe36d118bd1ce3e6 (patch) | |
tree | 341fdf9a4fdd8b0d64e6e524a159bdf4e927afe4 /src | |
parent | 24ace0378083fef23735ba426f8af3180e67994f (diff) | |
download | Hyprland-dfb78e059394a637e0f36242fe36d118bd1ce3e6.tar.gz Hyprland-dfb78e059394a637e0f36242fe36d118bd1ce3e6.zip |
Fix swiping onto a new workspace with multiple monitors. (#1971)
The previous code could run into issues into the following circumstances:
* The focused monitor is on its rightmost workspace with ID `i`.
* Another monitor has a workspace with ID `i+1`.
* `workspace_swipe_create_new` is enabled.
Then, swiping rightwards attempts to target a new workspace with ID
`i+1`: completing the swipe gesture unintentionally focuses that
workspace on whichever monitor it's already on while leaving the active
monitor in a broken state where it shows no windows but creates new
windows on the workspace it was previously on; and cancelling the swipe
gesture shifts the entire workspace `i+1` to the right by the width of
the active monitor.
By choosing an ID that doesn't exist, this problematic behavior is
avoided. More specifically, it's the smallest ID greater than any
existing workspace's ID, because otherwise the new workspace that was
seemingly just created to the right of the rightmost workspace could end
up somewhere in the middle of the workspace order.
Diffstat (limited to 'src')
-rw-r--r-- | src/managers/input/Swipe.cpp | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/src/managers/input/Swipe.cpp b/src/managers/input/Swipe.cpp index 847db2f6..a3c429f9 100644 --- a/src/managers/input/Swipe.cpp +++ b/src/managers/input/Swipe.cpp @@ -56,9 +56,21 @@ void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) { auto workspaceIDLeft = getWorkspaceIDFromString(*PSWIPENUMBER ? "-1" : "m-1", wsname); auto workspaceIDRight = getWorkspaceIDFromString(*PSWIPENUMBER ? "+1" : "m+1", wsname); - if ((workspaceIDRight <= m_sActiveSwipe.pWorkspaceBegin->m_iID || (workspaceIDRight == workspaceIDLeft && workspaceIDLeft == m_sActiveSwipe.pWorkspaceBegin->m_iID)) && - *PSWIPENEW) { - workspaceIDRight = m_sActiveSwipe.pWorkspaceBegin->m_iID > 0 ? m_sActiveSwipe.pWorkspaceBegin->m_iID + 1 : 1; + // If we've been swiping off the right end with PSWIPENEW enabled, there is + // no workspace there yet, and we need to choose an ID for a new one now. + // With multiple monitors, it might not be appropriate to choose one more + // than the ID of the workspace we're swiping from, because that ID might + // just be on another monitor. It's also not just the smallest unused ID, + // because that could be a gap in the existing workspace numbers, and it'd + // be counterintuitive to swipe rightwards onto a new workspace and end up + // left of where we started. Instead, it's one more than the greatest + // workspace ID that currently exists. + if (workspaceIDRight <= m_sActiveSwipe.pWorkspaceBegin->m_iID && *PSWIPENEW) { + int maxWorkspace = 0; + for (const auto& ws : g_pCompositor->m_vWorkspaces) { + maxWorkspace = std::max(maxWorkspace, ws->m_iID); + } + workspaceIDRight = maxWorkspace + 1; } auto PWORKSPACER = g_pCompositor->getWorkspaceByID(workspaceIDRight); // not guaranteed if PSWIPENEW || PSWIPENUMBER @@ -305,4 +317,4 @@ void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) { beginWorkspaceSwipe(); } } -}
\ No newline at end of file +} |