aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/managers/input/Swipe.cpp
diff options
context:
space:
mode:
authorAndrew Pritchard <[email protected]>2023-04-07 04:18:53 -0700
committerGitHub <[email protected]>2023-04-07 12:18:53 +0100
commitdfb78e059394a637e0f36242fe36d118bd1ce3e6 (patch)
tree341fdf9a4fdd8b0d64e6e524a159bdf4e927afe4 /src/managers/input/Swipe.cpp
parent24ace0378083fef23735ba426f8af3180e67994f (diff)
downloadHyprland-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/managers/input/Swipe.cpp')
-rw-r--r--src/managers/input/Swipe.cpp20
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
+}