compositor: When processing fullscreen states, only use effective mode where necessary (#13607)

Simplify the compositor fullscreen state processing: use the complete
fullscreen mode value except when the effective fullscreen mode value
is needed.

Fixes #13041.
This commit is contained in:
Nikolai Nechaev 2026-03-10 19:09:47 +09:00 committed by Vaxry
parent 59f9f2688a
commit e8b06b832c
Signed by: vaxry
GPG key ID: 665806380871D640
2 changed files with 50 additions and 12 deletions

View file

@ -177,6 +177,7 @@ static bool test() {
{
auto str = getFromSocket("/activewindow");
EXPECT_CONTAINS(str, "fullscreen: 2");
EXPECT_CONTAINS(str, "fullscreenClient: 2");
EXPECT_CONTAINS(str, "kitty_A");
}
@ -185,6 +186,7 @@ static bool test() {
{
auto str = getFromSocket("/activewindow");
EXPECT_CONTAINS(str, "fullscreen: 2");
EXPECT_CONTAINS(str, "fullscreenClient: 2");
EXPECT_CONTAINS(str, "kitty_A");
}
@ -194,6 +196,7 @@ static bool test() {
// should be ignored as per focus_under_fullscreen 0
auto str = getFromSocket("/activewindow");
EXPECT_CONTAINS(str, "fullscreen: 2");
EXPECT_CONTAINS(str, "fullscreenClient: 2");
EXPECT_CONTAINS(str, "kitty_A");
}
@ -204,6 +207,7 @@ static bool test() {
{
auto str = getFromSocket("/activewindow");
EXPECT_CONTAINS(str, "fullscreen: 2");
EXPECT_CONTAINS(str, "fullscreenClient: 2");
EXPECT_CONTAINS(str, "kitty_C");
}
@ -214,6 +218,7 @@ static bool test() {
{
auto str = getFromSocket("/activewindow");
EXPECT_CONTAINS(str, "fullscreen: 0");
EXPECT_CONTAINS(str, "fullscreenClient: 0");
EXPECT_CONTAINS(str, "kitty_D");
}
@ -233,6 +238,7 @@ static bool test() {
{
auto str = getFromSocket("/activewindow");
EXPECT_CONTAINS(str, "fullscreen: 2");
EXPECT_CONTAINS(str, "fullscreenClient: 2");
}
OK(getFromSocket("/dispatch killwindow activewindow"));
@ -241,6 +247,7 @@ static bool test() {
{
auto str = getFromSocket("/activewindow");
EXPECT_CONTAINS(str, "fullscreen: 0");
EXPECT_CONTAINS(str, "fullscreenClient: 0");
}
Tests::spawnKitty("kitty_B");
@ -253,6 +260,7 @@ static bool test() {
{
auto str = getFromSocket("/activewindow");
EXPECT_CONTAINS(str, "fullscreen: 2");
EXPECT_CONTAINS(str, "fullscreenClient: 2");
}
Tests::killAllWindows();
@ -268,6 +276,7 @@ static bool test() {
{
auto str = getFromSocket("/activewindow");
EXPECT_CONTAINS(str, "fullscreen: 2");
EXPECT_CONTAINS(str, "fullscreenClient: 2");
}
OK(getFromSocket("/dispatch fullscreen 0 unset"));
@ -275,6 +284,7 @@ static bool test() {
{
auto str = getFromSocket("/activewindow");
EXPECT_CONTAINS(str, "fullscreen: 0");
EXPECT_CONTAINS(str, "fullscreenClient: 0");
}
OK(getFromSocket("/dispatch fullscreen 1 toggle"));
@ -282,6 +292,7 @@ static bool test() {
{
auto str = getFromSocket("/activewindow");
EXPECT_CONTAINS(str, "fullscreen: 1");
EXPECT_CONTAINS(str, "fullscreenClient: 1");
}
OK(getFromSocket("/dispatch fullscreen 1 toggle"));
@ -289,6 +300,23 @@ static bool test() {
{
auto str = getFromSocket("/activewindow");
EXPECT_CONTAINS(str, "fullscreen: 0");
EXPECT_CONTAINS(str, "fullscreenClient: 0");
}
OK(getFromSocket("/dispatch fullscreenstate 3 3 set"));
{
auto str = getFromSocket("/activewindow");
EXPECT_CONTAINS(str, "fullscreen: 3");
EXPECT_CONTAINS(str, "fullscreenClient: 3");
}
OK(getFromSocket("/dispatch fullscreenstate 3 3 set"));
{
auto str = getFromSocket("/activewindow");
EXPECT_CONTAINS(str, "fullscreen: 3");
EXPECT_CONTAINS(str, "fullscreenClient: 3");
}
OK(getFromSocket("/dispatch fullscreenstate 2 2 set"));
@ -296,6 +324,7 @@ static bool test() {
{
auto str = getFromSocket("/activewindow");
EXPECT_CONTAINS(str, "fullscreen: 2");
EXPECT_CONTAINS(str, "fullscreenClient: 2");
}
OK(getFromSocket("/dispatch fullscreenstate 2 2 set"));
@ -303,6 +332,7 @@ static bool test() {
{
auto str = getFromSocket("/activewindow");
EXPECT_CONTAINS(str, "fullscreen: 2");
EXPECT_CONTAINS(str, "fullscreenClient: 2");
}
OK(getFromSocket("/dispatch fullscreenstate 2 2 toggle"));
@ -310,6 +340,7 @@ static bool test() {
{
auto str = getFromSocket("/activewindow");
EXPECT_CONTAINS(str, "fullscreen: 0");
EXPECT_CONTAINS(str, "fullscreenClient: 0");
}
OK(getFromSocket("/dispatch fullscreenstate 2 2 toggle"));
@ -317,6 +348,7 @@ static bool test() {
{
auto str = getFromSocket("/activewindow");
EXPECT_CONTAINS(str, "fullscreen: 2");
EXPECT_CONTAINS(str, "fullscreenClient: 2");
}
// Ensure that the process autostarted in the config does not

View file

@ -2115,13 +2115,10 @@ void CCompositor::setWindowFullscreenState(const PHLWINDOW PWINDOW, Desktop::Vie
state.internal = std::clamp(state.internal, sc<eFullscreenMode>(0), FSMODE_MAX);
state.client = std::clamp(state.client, sc<eFullscreenMode>(0), FSMODE_MAX);
const auto PMONITOR = PWINDOW->m_monitor.lock();
const auto PWORKSPACE = PWINDOW->m_workspace;
const auto PMONITOR = PWINDOW->m_monitor.lock();
const auto PWORKSPACE = PWINDOW->m_workspace;
const eFullscreenMode CURRENT_EFFECTIVE_MODE = sc<eFullscreenMode>(std::bit_floor(sc<uint8_t>(PWINDOW->m_fullscreenState.internal)));
const eFullscreenMode EFFECTIVE_MODE = sc<eFullscreenMode>(std::bit_floor(sc<uint8_t>(state.internal)));
if (PWINDOW->m_isFloating && CURRENT_EFFECTIVE_MODE == FSMODE_NONE && EFFECTIVE_MODE != FSMODE_NONE)
if (PWINDOW->m_isFloating && PWINDOW->m_fullscreenState.internal == FSMODE_NONE && state.internal != FSMODE_NONE)
g_pHyprRenderer->damageWindow(PWINDOW);
if (*PALLOWPINFULLSCREEN && !PWINDOW->m_pinFullscreened && !PWINDOW->isFullscreen() && PWINDOW->m_pinned) {
@ -2132,7 +2129,7 @@ void CCompositor::setWindowFullscreenState(const PHLWINDOW PWINDOW, Desktop::Vie
if (PWORKSPACE->m_hasFullscreenWindow && !PWINDOW->isFullscreen())
setWindowFullscreenInternal(PWORKSPACE->getFullscreenWindow(), FSMODE_NONE);
const bool CHANGEINTERNAL = !PWINDOW->m_pinned && CURRENT_EFFECTIVE_MODE != EFFECTIVE_MODE;
const bool CHANGEINTERNAL = !PWINDOW->m_pinned && PWINDOW->m_fullscreenState.internal != state.internal;
if (*PALLOWPINFULLSCREEN && PWINDOW->m_pinFullscreened && PWINDOW->isFullscreen() && !PWINDOW->m_pinned && state.internal == FSMODE_NONE) {
PWINDOW->m_pinned = true;
@ -2154,14 +2151,23 @@ void CCompositor::setWindowFullscreenState(const PHLWINDOW PWINDOW, Desktop::Vie
return;
}
PWORKSPACE->m_fullscreenMode = EFFECTIVE_MODE;
PWORKSPACE->m_hasFullscreenWindow = EFFECTIVE_MODE != FSMODE_NONE;
// "Effective mode" is the fullscreen mode according to which a window is rendered.
// For fullscreen modes `FSMODE_NONE` (0), `FSMODE_MAXIMIZED` (1), and `FSMODE_FULLSCREEN` (2),
// the effective mode is the same as the fullscreen mode;
// for fullscreen mode `FSMODE_MAXIMIZED|FSMODE_FULLSCREEN` (a window is maximized then fullscreened),
// the effective mode is `FSMODE_FULLSCREEN` (2), since the window is rendered as a fullscreen window.
// But when the latter window exists fullscreen, it will return to `FSMODE_MAXIMIZED`, rather than `FSMODE_NONE`.
const eFullscreenMode OLD_EFFECTIVE_MODE = sc<eFullscreenMode>(std::bit_floor(sc<uint8_t>(PWINDOW->m_fullscreenState.internal)));
const eFullscreenMode NEW_EFFECTIVE_MODE = sc<eFullscreenMode>(std::bit_floor(sc<uint8_t>(state.internal)));
g_layoutManager->fullscreenRequestForTarget(PWINDOW->layoutTarget(), CURRENT_EFFECTIVE_MODE, EFFECTIVE_MODE);
PWORKSPACE->m_fullscreenMode = NEW_EFFECTIVE_MODE;
PWORKSPACE->m_hasFullscreenWindow = NEW_EFFECTIVE_MODE != FSMODE_NONE;
g_layoutManager->fullscreenRequestForTarget(PWINDOW->layoutTarget(), OLD_EFFECTIVE_MODE, NEW_EFFECTIVE_MODE);
PWINDOW->m_fullscreenState.internal = state.internal;
g_pEventManager->postEvent(SHyprIPCEvent{.event = "fullscreen", .data = std::to_string(sc<int>(EFFECTIVE_MODE) != FSMODE_NONE)});
g_pEventManager->postEvent(SHyprIPCEvent{.event = "fullscreen", .data = std::to_string(sc<int>(NEW_EFFECTIVE_MODE) != FSMODE_NONE)});
Event::bus()->m_events.window.fullscreen.emit(PWINDOW);
PWINDOW->m_ruleApplicator->propertiesChanged(Desktop::Rule::RULE_PROP_FULLSCREEN | Desktop::Rule::RULE_PROP_FULLSCREENSTATE_CLIENT |
@ -2198,7 +2204,7 @@ void CCompositor::setWindowFullscreenState(const PHLWINDOW PWINDOW, Desktop::Vie
if (*PDIRECTSCANOUT == 1 || (*PDIRECTSCANOUT == 2 && PWINDOW->getContentType() == CONTENT_TYPE_GAME)) {
auto surf = PWINDOW->getSolitaryResource();
if (surf)
g_pHyprRenderer->setSurfaceScanoutMode(surf, EFFECTIVE_MODE != FSMODE_NONE ? PMONITOR->m_self.lock() : nullptr);
g_pHyprRenderer->setSurfaceScanoutMode(surf, NEW_EFFECTIVE_MODE != FSMODE_NONE ? PMONITOR->m_self.lock() : nullptr);
}
g_pConfigManager->ensureVRR(PMONITOR);