mirror of
https://github.com/hyprwm/Hyprland
synced 2025-01-10 09:49:48 +01:00
windows: honor xdg_toplevel_set_fullscreen output hint (#8965)
Co-authored-by: Dardo D Kleiner <dardo.kleiner@nrl.navy.mil>
This commit is contained in:
parent
9dc9366fc6
commit
f9c37ca43b
5 changed files with 55 additions and 10 deletions
|
@ -1382,15 +1382,26 @@ 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)) {
|
||||
bool fs = requestsFS.value();
|
||||
if (m_bIsMapped) {
|
||||
g_pCompositor->changeWindowFullscreenModeClient(m_pSelf.lock(), FSMODE_FULLSCREEN, requestsFS.value());
|
||||
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();
|
||||
}
|
||||
|
||||
bool fs = requestsFS.value();
|
||||
if (m_bIsMapped)
|
||||
g_pCompositor->changeWindowFullscreenModeClient(m_pSelf.lock(), FSMODE_FULLSCREEN, requestsFS.value());
|
||||
|
||||
if (!m_bIsMapped)
|
||||
m_bWantsInitialFullscreen = fs;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -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;
|
||||
|
|
|
@ -131,6 +131,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) {
|
||||
|
@ -168,6 +169,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;
|
||||
}
|
||||
|
@ -186,6 +188,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: {
|
||||
|
@ -227,6 +230,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]);
|
||||
}
|
||||
|
@ -337,10 +342,30 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
|||
|
||||
PMONITOR = g_pCompositor->m_pLastMonitor.lock();
|
||||
}
|
||||
|
||||
requestedFSMonitor = MONITOR_INVALID;
|
||||
} else
|
||||
workspaceSilent = false;
|
||||
}
|
||||
|
||||
if (PWINDOW->m_eSuppressedEvents & SUPPRESS_FULLSCREEN_OUTPUT)
|
||||
requestedFSMonitor = MONITOR_INVALID;
|
||||
else if (requestedFSMonitor != MONITOR_INVALID) {
|
||||
if (const auto PM = g_pCompositor->getMonitorFromID(requestedFSMonitor); PM)
|
||||
PWINDOW->m_pMonitor = PM;
|
||||
|
||||
const auto PMONITORFROMID = PWINDOW->m_pMonitor.lock();
|
||||
|
||||
if (PWINDOW->m_pMonitor != PMONITOR) {
|
||||
g_pKeybindManager->m_mDispatchers["focusmonitor"](std::to_string(PWINDOW->monitorID()));
|
||||
PMONITOR = PMONITORFROMID;
|
||||
}
|
||||
PWINDOW->m_pWorkspace = PMONITOR->activeSpecialWorkspace ? PMONITOR->activeSpecialWorkspace : PMONITOR->activeWorkspace;
|
||||
PWORKSPACE = PWINDOW->m_pWorkspace;
|
||||
|
||||
Debug::log(LOG, "Requested monitor, applying to {:mw}", PWINDOW);
|
||||
}
|
||||
|
||||
if (PWORKSPACE->m_bDefaultFloating)
|
||||
PWINDOW->m_bIsFloating = true;
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
@ -191,9 +192,14 @@ CXDGToplevelResource::CXDGToplevelResource(SP<CXdgToplevel> resource_, SP<CXDGSu
|
|||
});
|
||||
|
||||
resource->setSetFullscreen([this](CXdgToplevel* r, wl_resource* output) {
|
||||
if (output)
|
||||
if (const auto PM = CWLOutputResource::fromResource(output)->monitor; PM)
|
||||
state.requestsFullscreenMonitor = PM->ID;
|
||||
|
||||
state.requestsFullscreen = true;
|
||||
events.stateChanged.emit();
|
||||
state.requestsFullscreen.reset();
|
||||
state.requestsFullscreenMonitor.reset();
|
||||
});
|
||||
|
||||
resource->setUnsetFullscreen([this](CXdgToplevel* r) {
|
||||
|
@ -205,7 +211,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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue