Skip to content

Commit

Permalink
WIP : honor xdg_toplevel_set_fullscreen output
Browse files Browse the repository at this point in the history
  • Loading branch information
Dardo D Kleiner committed Jan 5, 2025
1 parent 391ff29 commit b642108
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 9 deletions.
21 changes: 17 additions & 4 deletions src/desktop/Window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1404,14 +1404,27 @@ void CWindow::activate(bool force) {
}

void CWindow::onUpdateState() {
std::optional<bool> requestsFS = m_pXDGSurface ? m_pXDGSurface->toplevel->state.requestsFullscreen : m_pXWaylandSurface->state.requestsFullscreen;
std::optional<bool> requestsMX = m_pXDGSurface ? m_pXDGSurface->toplevel->state.requestsMaximize : m_pXWaylandSurface->state.requestsMaximize;
std::optional<bool> requestsFS = m_pXDGSurface ? m_pXDGSurface->toplevel->state.requestsFullscreen : m_pXWaylandSurface->state.requestsFullscreen;
std::optional<MONITORID> requestsID = m_pXDGSurface ? m_pXDGSurface->toplevel->state.requestsFullscreenMonitor : MONITOR_INVALID;
std::optional<bool> requestsMX = m_pXDGSurface ? m_pXDGSurface->toplevel->state.requestsMaximize : m_pXWaylandSurface->state.requestsMaximize;

if (requestsFS.has_value() && !(m_eSuppressedEvents & SUPPRESS_FULLSCREEN)) {
if (requestsID.has_value() && (requestsID.value() != MONITOR_INVALID) && !(m_eSuppressedEvents & SUPPRESS_FULLSCREEN_OUTPUT)) {
if (m_bIsMapped) {
const auto monitor = g_pCompositor->getMonitorFromID(requestsID.value());
g_pCompositor->moveWindowToWorkspaceSafe(m_pSelf.lock(), monitor->activeWorkspace);
g_pCompositor->setActiveMonitor(monitor);
}

if (!m_bIsMapped)
m_iWantsInitialFullscreenMonitor = requestsID.value();

Debug::log(LOG, "[window] fullscreen requested on {}", m_iWantsInitialFullscreenMonitor);
}

bool fs = requestsFS.value();
if (m_bIsMapped) {
if (m_bIsMapped)
g_pCompositor->changeWindowFullscreenModeClient(m_pSelf.lock(), FSMODE_FULLSCREEN, requestsFS.value());
}

if (!m_bIsMapped)
m_bWantsInitialFullscreen = fs;
Expand Down
4 changes: 3 additions & 1 deletion src/desktop/Window.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ enum eSuppressEvents : uint8_t {
SUPPRESS_MAXIMIZE = 1 << 1,
SUPPRESS_ACTIVATE = 1 << 2,
SUPPRESS_ACTIVATE_FOCUSONLY = 1 << 3,
SUPPRESS_FULLSCREEN_OUTPUT = 1 << 4,
};

class IWindowTransformer;
Expand Down Expand Up @@ -288,7 +289,8 @@ class CWindow {
bool m_bNoInitialFocus = false;

// Fullscreen and Maximize
bool m_bWantsInitialFullscreen = false;
bool m_bWantsInitialFullscreen = false;
MONITORID m_iWantsInitialFullscreenMonitor = MONITOR_INVALID;

// bitfield eSuppressEvents
uint64_t m_eSuppressedEvents = SUPPRESS_NONE;
Expand Down
13 changes: 13 additions & 0 deletions src/events/Windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
std::optional<SFullscreenState> requestedFSState;
if (PWINDOW->m_bWantsInitialFullscreen || (PWINDOW->m_bIsX11 && PWINDOW->m_pXWaylandSurface->fullscreen))
requestedClientFSMode = FSMODE_FULLSCREEN;
MONITORID requestedFSMonitor = PWINDOW->m_iWantsInitialFullscreenMonitor;

for (auto const& r : PWINDOW->m_vMatchedRules) {
switch (r->ruleType) {
Expand Down Expand Up @@ -164,6 +165,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
PWORKSPACE = PWINDOW->m_pWorkspace;

Debug::log(LOG, "Rule monitor, applying to {:mw}", PWINDOW);
requestedFSMonitor = MONITOR_INVALID;
} catch (std::exception& e) { Debug::log(ERR, "Rule monitor failed, rule: {} -> {} | err: {}", r->szRule, r->szValue, e.what()); }
break;
}
Expand All @@ -182,6 +184,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
requestedWorkspace = "";

Debug::log(LOG, "Rule workspace matched by {}, {} applied.", PWINDOW, r->szValue);
requestedFSMonitor = MONITOR_INVALID;
break;
}
case CWindowRule::RULE_FLOAT: {
Expand Down Expand Up @@ -223,6 +226,8 @@ void Events::listener_mapWindow(void* owner, void* data) {
PWINDOW->m_eSuppressedEvents |= SUPPRESS_ACTIVATE;
else if (vars[i] == "activatefocus")
PWINDOW->m_eSuppressedEvents |= SUPPRESS_ACTIVATE_FOCUSONLY;
else if (vars[i] == "fullscreenoutput")
PWINDOW->m_eSuppressedEvents |= SUPPRESS_FULLSCREEN_OUTPUT;
else
Debug::log(ERR, "Error while parsing suppressevent windowrule: unknown event type {}", vars[i]);
}
Expand Down Expand Up @@ -347,6 +352,14 @@ void Events::listener_mapWindow(void* owner, void* data) {
PWINDOW->m_vPseudoSize = Vector2D(desiredGeometry.width, desiredGeometry.height);
}

if (PWINDOW->m_eSuppressedEvents & SUPPRESS_FULLSCREEN_OUTPUT)
requestedFSMonitor = MONITOR_INVALID;
if (requestedFSMonitor != MONITOR_INVALID) {
Debug::log(LOG, "[window] applying requestedFSMonitor {}", requestedFSMonitor);
if (const auto PM = g_pCompositor->getMonitorFromID(requestedFSMonitor); PM)
PWINDOW->m_pMonitor = PM;
}

PWINDOW->updateWindowData();

// Verify window swallowing. Get the swallower before calling onWindowCreated(PWINDOW) because getSwallower() wouldn't get it after if PWINDOW gets auto grouped.
Expand Down
6 changes: 5 additions & 1 deletion src/protocols/XDGShell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "../managers/SeatManager.hpp"
#include "core/Seat.hpp"
#include "core/Compositor.hpp"
#include "protocols/core/Output.hpp"
#include <cstring>
#include <ranges>

Expand Down Expand Up @@ -191,9 +192,12 @@ CXDGToplevelResource::CXDGToplevelResource(SP<CXdgToplevel> resource_, SP<CXDGSu
});

resource->setSetFullscreen([this](CXdgToplevel* r, wl_resource* output) {
if (output)
state.requestsFullscreenMonitor = CWLOutputResource::fromResource(output)->monitor->ID;
state.requestsFullscreen = true;
events.stateChanged.emit();
state.requestsFullscreen.reset();
state.requestsFullscreenMonitor.reset();
});

resource->setUnsetFullscreen([this](CXdgToplevel* r) {
Expand All @@ -205,7 +209,7 @@ CXDGToplevelResource::CXDGToplevelResource(SP<CXdgToplevel> resource_, SP<CXDGSu
resource->setSetMinimized([this](CXdgToplevel* r) {
state.requestsMinimize = true;
events.stateChanged.emit();
state.requestsFullscreen.reset();
state.requestsMinimize.reset();
});

resource->setSetParent([this](CXdgToplevel* r, wl_resource* parentR) {
Expand Down
7 changes: 4 additions & 3 deletions src/protocols/XDGShell.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,10 @@ class CXDGToplevelResource {
std::string appid;

// volatile state: is reset after the stateChanged signal fires
std::optional<bool> requestsMaximize;
std::optional<bool> requestsFullscreen;
std::optional<bool> requestsMinimize;
std::optional<bool> requestsMaximize;
std::optional<bool> requestsFullscreen;
std::optional<MONITORID> requestsFullscreenMonitor;
std::optional<bool> requestsMinimize;
} state;

struct {
Expand Down

0 comments on commit b642108

Please sign in to comment.