summaryrefslogtreecommitdiff
path: root/src/desktop
diff options
context:
space:
mode:
authorerstarr <253168930+erstarr@users.noreply.github.com>2026-05-08 17:45:43 +0200
committerGitHub <noreply@github.com>2026-05-08 16:45:43 +0100
commitbd7f695363898826d5bd04fe830f19581ac4c5b2 (patch)
treea4dd157b8d851330035b4b6184995fb4ebd9d277 /src/desktop
parentac75bcab713490eb000e4fa48f7e7316c3535854 (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.cpp3
-rw-r--r--src/desktop/state/FocusState.hpp10
-rw-r--r--src/desktop/view/Group.cpp8
-rw-r--r--src/desktop/view/Group.hpp7
-rw-r--r--src/desktop/view/Window.cpp4
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);