diff options
| author | erstarr <253168930+erstarr@users.noreply.github.com> | 2026-05-08 17:45:43 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-05-08 16:45:43 +0100 |
| commit | bd7f695363898826d5bd04fe830f19581ac4c5b2 (patch) | |
| tree | a4dd157b8d851330035b4b6184995fb4ebd9d277 /src/desktop | |
| parent | ac75bcab713490eb000e4fa48f7e7316c3535854 (diff) | |
algo/scrolling: various scrolling view related bugfixes (#13974)
* fix scrolling view move when a grouped window is closed - prevent redundant space assignment for a grouped window that's about to be unmapped, add a `FOCUS_REASON` for unmapping grouped windows
* fix focus_fallback after unmapping a window floating moving view
* fix view change when changing workspaces (special and normal).
add an optional `RECALCULATE_REASON` parameter to `recalculate()` calls of all algorithms.
add an optional `RECALCULATE_MONITOR_REASON` parameter to `recalculateMonitor()` calls.
add 2 new `FOCUS_REASON`s, for workspace change and special workspace toggle
* Fix hyprctl keyword causing scrolling view move.
rename INPUT_MODE_KB to INPUT_MODE_HARD since it seems to have little to do with keybinds
* fix fullscreen/maximise moving the scrolling view
* fix opening of layer 3 programs moving scrolling view
* refactor, clean up and clang-format
* fix bad decisions
* fix includes, clang-format.
* remove TODO
* `focuswindow` no longer moves scrolling view when `follow_focus = 0`
* fix: changes in a group's current window no longer casues scrolling view shift when `follow_focus = 0`
* fix: `moveintogroup`, `movewindoworgroup` no longer causes scrolling view change if `follow_focus = 0`
* clang-format
* add `RECALCULATE_REASON_UNKNOWN`, `RECALCULATE_MONITOR_REASON_UNKNOWN`, `REMOVE_FROM_GROUP_REASON_UNKNOWN`
remove optional wrapper from their enums, refactor code to work with the change
* dispatches that call `switchtoWindow()` in CKeybindManager no longer cause scrolling view to move if `follow_focus = 0`.
They still cause the move if `follow_focus = 1`
Dispatches effected by this: `movefocus`, `cyclenext`, `focuscurrentorlast`, `focuscurrentorurgent`
* Fix for Lua: switchToWondow
* Fix for Lua: focus({window})
* Fix for Lua: Move Window Into Group
* clang-format
* Drop `hyprctl keyword` change
* test: `focus({window})` with `follow_focus = false`
* test: `focus({window})` with `follow_focus = true`
* test: test Focus Fallback
* test: Focus Fallback with groups
* test: workspace change
* test: special workspace toggle
* test: workspace change - special to special
also minor refactoring
* test: close window in a group
* test: move window into group `follow_focus = false`
minor fix in test: expect -> assert
* test: move window into group `follow_focus = true`
* test: new layer
* test: maximise
fix in test: expect to assert.
* test: fullscreen
* test: `dispatch window.focus({ direction })` when `follow_focus = false`
* test: `dispatch window.focus({ direction })` when `follow_focus = true`
test-fix: expect -> assert
* test: move focus within group when `follow_focus = false`
* test: move focus within group when `follow_focus = true`
* test-fix: kill all layers before killing all windows in layers test. prevents internal post test cleanup function failing to kill all layers
test-fix: maximized and fullscreen swapped between their tests
test-fix: testScrollingViewBehaviourMoveFocusInGroupFollowFocusTrue missing layout initialization
test-fix: testScrollingViewBehaviourWorkspaceChange, testScrollingViewBehaviourCloseWindowInGroup have stale window class in a comment
clang-format
* catch up with main: move to new test function
* clean-up the clean-up part of the tests: redundant
* clang-format
* pain
* suffering: fix rebase fail
* test: manually kill all layers since the cleanup function fails
* remove test: fullscreen and maximise. scrolling has its own behaviour now
Diffstat (limited to 'src/desktop')
| -rw-r--r-- | src/desktop/state/FocusState.cpp | 3 | ||||
| -rw-r--r-- | src/desktop/state/FocusState.hpp | 10 | ||||
| -rw-r--r-- | src/desktop/view/Group.cpp | 8 | ||||
| -rw-r--r-- | src/desktop/view/Group.hpp | 7 | ||||
| -rw-r--r-- | src/desktop/view/Window.cpp | 4 |
5 files changed, 26 insertions, 6 deletions
diff --git a/src/desktop/state/FocusState.cpp b/src/desktop/state/FocusState.cpp index 48fb6456..702b02c4 100644 --- a/src/desktop/state/FocusState.cpp +++ b/src/desktop/state/FocusState.cpp @@ -308,5 +308,6 @@ void CFocusState::resetWindowFocus() { } bool Desktop::isHardInputFocusReason(eFocusReason r) { - return r == FOCUS_REASON_NEW_WINDOW || r == FOCUS_REASON_KEYBIND || r == FOCUS_REASON_GHOSTS || r == FOCUS_REASON_CLICK || r == FOCUS_REASON_DESKTOP_STATE_CHANGE; + return r == FOCUS_REASON_NEW_WINDOW || r == FOCUS_REASON_KEYBIND || r == FOCUS_REASON_GHOSTS || r == FOCUS_REASON_CLICK || r == FOCUS_REASON_DESKTOP_STATE_CHANGE || + r == FOCUS_REASON_UNMAP_WINDOW_TILING || r == FOCUS_REASON_SWITCH_TO_WINDOW_HARD; } diff --git a/src/desktop/state/FocusState.hpp b/src/desktop/state/FocusState.hpp index 71330a3e..334c426d 100644 --- a/src/desktop/state/FocusState.hpp +++ b/src/desktop/state/FocusState.hpp @@ -10,9 +10,19 @@ namespace Desktop { FOCUS_REASON_UNKNOWN = 0, FOCUS_REASON_FFM, FOCUS_REASON_KEYBIND, + FOCUS_REASON_DISPATCH_FOCUSWINDOW, + FOCUS_REASON_DISPATCH_MOVEWINDOWINTOGROUP, FOCUS_REASON_CLICK, FOCUS_REASON_OTHER, FOCUS_REASON_DESKTOP_STATE_CHANGE, + FOCUS_REASON_SWITCH_TO_WINDOW_SOFT, + FOCUS_REASON_SWITCH_TO_WINDOW_HARD, + FOCUS_REASON_GROUP_CURRENT_WINDOW_CHANGE, + FOCUS_REASON_WORKSPACE_CHANGE, + FOCUS_REASON_TOGGLE_SPECIAL_WORKSPACE, + FOCUS_REASON_UNMAP_WINDOW_TILING, + FOCUS_REASON_UNMAP_WINDOW_FLOATING, + FOCUS_REASON_UNMAP_GROUPED_WINDOW, FOCUS_REASON_NEW_WINDOW, FOCUS_REASON_GHOSTS, }; diff --git a/src/desktop/view/Group.cpp b/src/desktop/view/Group.cpp index f2b2a564..7073672a 100644 --- a/src/desktop/view/Group.cpp +++ b/src/desktop/view/Group.cpp @@ -122,7 +122,7 @@ void CGroup::add(PHLWINDOW w) { m_target->recalc(); } -void CGroup::remove(PHLWINDOW w, Math::eDirection dir) { +void CGroup::remove(PHLWINDOW w, Math::eDirection dir, eRemoveFromGroupReason reason) { std::optional<size_t> idx; for (size_t i = 0; i < m_windows.size(); ++i) { if (m_windows.at(i) == w) { @@ -171,6 +171,10 @@ void CGroup::remove(PHLWINDOW w, Math::eDirection dir) { default: break; } } + + // We don't need to assign a window to a new space if we intend to unmap it + if (reason == REMOVE_FROM_GROUP_REASON_UNMAP_WINDOW) + return; w->m_target->assignToSpace(m_target->space(), focalPoint); } } @@ -215,7 +219,7 @@ void CGroup::setCurrent(size_t idx) { } if (WASFOCUS) - Desktop::focusState()->rawWindowFocus(current(), FOCUS_REASON_DESKTOP_STATE_CHANGE); + Desktop::focusState()->rawWindowFocus(current(), FOCUS_REASON_GROUP_CURRENT_WINDOW_CHANGE); } void CGroup::setCurrent(PHLWINDOW w) { diff --git a/src/desktop/view/Group.hpp b/src/desktop/view/Group.hpp index 048c5023..3ada4d6e 100644 --- a/src/desktop/view/Group.hpp +++ b/src/desktop/view/Group.hpp @@ -15,10 +15,15 @@ namespace Desktop::View { static SP<CGroup> create(std::vector<PHLWINDOWREF>&& windows); ~CGroup(); + enum eRemoveFromGroupReason : uint8_t { + REMOVE_FROM_GROUP_REASON_UNKNOWN, // when the remove from group reason is unknown or not important to preserve + REMOVE_FROM_GROUP_REASON_UNMAP_WINDOW, + }; + bool has(PHLWINDOW w) const; void add(PHLWINDOW w); - void remove(PHLWINDOW w, Math::eDirection dir = Math::DIRECTION_DEFAULT); + void remove(PHLWINDOW w, Math::eDirection dir = Math::DIRECTION_DEFAULT, eRemoveFromGroupReason reason = REMOVE_FROM_GROUP_REASON_UNKNOWN); void moveCurrent(bool next); void setCurrent(size_t idx); void setCurrent(PHLWINDOW w); diff --git a/src/desktop/view/Window.cpp b/src/desktop/view/Window.cpp index 19f8f88d..22967a62 100644 --- a/src/desktop/view/Window.cpp +++ b/src/desktop/view/Window.cpp @@ -2397,9 +2397,9 @@ void CWindow::unmapWindow() { if (candidate != Desktop::focusState()->window() && candidate) { if (candidate == nextInGroup) - Desktop::focusState()->rawWindowFocus(candidate, FOCUS_REASON_DESKTOP_STATE_CHANGE); + Desktop::focusState()->rawWindowFocus(candidate, FOCUS_REASON_UNMAP_GROUPED_WINDOW); else - Desktop::focusState()->fullWindowFocus(candidate, FOCUS_REASON_DESKTOP_STATE_CHANGE); + Desktop::focusState()->fullWindowFocus(candidate, m_self->m_isFloating ? FOCUS_REASON_UNMAP_WINDOW_FLOATING : FOCUS_REASON_UNMAP_WINDOW_TILING); if ((*PEXITRETAINSFS || candidate == nextInGroup) && CURRENTWINDOWFSSTATE) g_pCompositor->setWindowFullscreenInternal(candidate, CURRENTFSMODE); |
