summaryrefslogtreecommitdiff
path: root/src/desktop/view/Window.cpp
diff options
context:
space:
mode:
authorVaxry <vaxry@vaxry.net>2025-12-22 17:53:28 +0100
committerVaxry <vaxry@vaxry.net>2025-12-22 17:53:28 +0100
commitabffe75088e2d776e14e5dbd726a835fa157df9a (patch)
tree7ae3a93e0705774848c3d4a22474191323109ca1 /src/desktop/view/Window.cpp
parent60efbf3f63bec3100477ea9ba6cd634e35d5aeaa (diff)
desktop/window: improve fullscreen handling for grouped windows
fixes #12700
Diffstat (limited to 'src/desktop/view/Window.cpp')
-rw-r--r--src/desktop/view/Window.cpp54
1 files changed, 37 insertions, 17 deletions
diff --git a/src/desktop/view/Window.cpp b/src/desktop/view/Window.cpp
index c2246db8..32a0086e 100644
--- a/src/desktop/view/Window.cpp
+++ b/src/desktop/view/Window.cpp
@@ -1930,6 +1930,10 @@ void CWindow::mapWindow() {
static auto PNEWTAKESOVERFS = CConfigValue<Hyprlang::INT>("misc:on_focus_under_fullscreen");
static auto PINITIALWSTRACKING = CConfigValue<Hyprlang::INT>("misc:initial_workspace_tracking");
+ const auto LAST_FOCUS_WINDOW = Desktop::focusState()->window();
+ const bool IS_LAST_IN_FS = LAST_FOCUS_WINDOW ? LAST_FOCUS_WINDOW->m_fullscreenState.internal != FSMODE_NONE : false;
+ const auto LAST_FS_MODE = LAST_FOCUS_WINDOW ? LAST_FOCUS_WINDOW->m_fullscreenState.internal : FSMODE_NONE;
+
auto PMONITOR = Desktop::focusState()->monitor();
if (!Desktop::focusState()->monitor()) {
Desktop::focusState()->rawMonitorFocus(g_pCompositor->getMonitorFromVector({}));
@@ -2305,7 +2309,16 @@ void CWindow::mapWindow() {
if (!m_ruleApplicator->noFocus().valueOrDefault() && !m_noInitialFocus && (!isX11OverrideRedirect() || (m_isX11 && m_xwaylandSurface->wantsFocus())) && !workspaceSilent &&
(!PFORCEFOCUS || PFORCEFOCUS == m_self.lock()) && !g_pInputManager->isConstrained()) {
- Desktop::focusState()->fullWindowFocus(m_self.lock());
+
+ // this window should gain focus: if it's grouped, preserve fullscreen state.
+ const bool SAME_GROUP = hasInGroup(LAST_FOCUS_WINDOW);
+
+ if (IS_LAST_IN_FS && SAME_GROUP) {
+ Desktop::focusState()->rawWindowFocus(m_self.lock());
+ g_pCompositor->setWindowFullscreenInternal(m_self.lock(), LAST_FS_MODE);
+ } else
+ Desktop::focusState()->fullWindowFocus(m_self.lock());
+
m_activeInactiveAlpha->setValueAndWarp(*PACTIVEALPHA);
m_dimPercent->setValueAndWarp(m_ruleApplicator->noDim().valueOrDefault() ? 0.f : *PDIMSTRENGTH);
} else {
@@ -2451,12 +2464,12 @@ void CWindow::unmapWindow() {
m_swallowed.reset();
}
- bool wasLastWindow = false;
+ bool wasLastWindow = false;
+ PHLWINDOW nextInGroup = m_groupData.pNextWindow ? m_groupData.pNextWindow.lock() : nullptr;
if (m_self.lock() == Desktop::focusState()->window()) {
wasLastWindow = true;
- Desktop::focusState()->window().reset();
- Desktop::focusState()->surface().reset();
+ Desktop::focusState()->resetWindowFocus();
g_pInputManager->releaseAllMouseButtons();
}
@@ -2479,23 +2492,30 @@ void CWindow::unmapWindow() {
// refocus on a new window if needed
if (wasLastWindow) {
- static auto FOCUSONCLOSE = CConfigValue<Hyprlang::INT>("input:focus_on_close");
- PHLWINDOW PWINDOWCANDIDATE = nullptr;
- if (*FOCUSONCLOSE)
- PWINDOWCANDIDATE = (g_pCompositor->vectorToWindowUnified(g_pInputManager->getMouseCoordsInternal(),
- Desktop::View::RESERVED_EXTENTS | Desktop::View::INPUT_EXTENTS | Desktop::View::ALLOW_FLOATING));
- else
- PWINDOWCANDIDATE = g_pLayoutManager->getCurrentLayout()->getNextWindowCandidate(m_self.lock());
+ static auto FOCUSONCLOSE = CConfigValue<Hyprlang::INT>("input:focus_on_close");
+ PHLWINDOW candidate = nextInGroup;
- Log::logger->log(Log::DEBUG, "On closed window, new focused candidate is {}", PWINDOWCANDIDATE);
+ if (!candidate) {
+ if (*FOCUSONCLOSE)
+ candidate = (g_pCompositor->vectorToWindowUnified(g_pInputManager->getMouseCoordsInternal(),
+ Desktop::View::RESERVED_EXTENTS | Desktop::View::INPUT_EXTENTS | Desktop::View::ALLOW_FLOATING));
+ else
+ candidate = g_pLayoutManager->getCurrentLayout()->getNextWindowCandidate(m_self.lock());
+ }
+
+ Log::logger->log(Log::DEBUG, "On closed window, new focused candidate is {}", candidate);
+
+ if (candidate != Desktop::focusState()->window() && candidate) {
+ if (candidate == nextInGroup)
+ Desktop::focusState()->rawWindowFocus(candidate);
+ else
+ Desktop::focusState()->fullWindowFocus(candidate);
- if (PWINDOWCANDIDATE != Desktop::focusState()->window() && PWINDOWCANDIDATE) {
- Desktop::focusState()->fullWindowFocus(PWINDOWCANDIDATE);
- if (*PEXITRETAINSFS && CURRENTWINDOWFSSTATE)
- g_pCompositor->setWindowFullscreenInternal(PWINDOWCANDIDATE, CURRENTFSMODE);
+ if ((*PEXITRETAINSFS || candidate == nextInGroup) && CURRENTWINDOWFSSTATE)
+ g_pCompositor->setWindowFullscreenInternal(candidate, CURRENTFSMODE);
}
- if (!PWINDOWCANDIDATE && m_workspace && m_workspace->getWindows() == 0)
+ if (!candidate && m_workspace && m_workspace->getWindows() == 0)
g_pInputManager->refocus();
g_pInputManager->sendMotionEventsToFocused();