compositor: Configurable behavior when window to be focused conflicts with fullscreen (#12033)

Renames `misc:new_window_takes_over_fullscreen` into
`misc:on_focus_under_fullscreen` and implements the following behavior:

- By default, when a tiling window is being focused on a workspace where
  a fullscreen/maximized window exists, respect
  the `misc:on_focus_under_fullscreen` config variable.
This commit is contained in:
Nikolai Nechaev 2025-11-26 07:44:26 +09:00 committed by GitHub
parent 1c1746de61
commit 40d8fa8491
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
51 changed files with 1003 additions and 694 deletions

View file

@ -14,6 +14,7 @@
#include "../config/ConfigManager.hpp"
#include "../managers/PointerManager.hpp"
#include "../desktop/LayerSurface.hpp"
#include "../desktop/state/FocusState.hpp"
#include "../protocols/LayerShell.hpp"
#include "../protocols/core/Compositor.hpp"
#include "../protocols/ColorManagement.hpp"
@ -424,7 +425,7 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() : m_drmFD(g_pCompositor->m_drmRenderNode.fd >
auto PMONITOR = g_pCompositor->getMonitorFromName(!E.device->m_boundOutput.empty() ? E.device->m_boundOutput : "");
PMONITOR = PMONITOR ? PMONITOR : g_pCompositor->m_lastMonitor.lock();
PMONITOR = PMONITOR ? PMONITOR : Desktop::focusState()->monitor();
const auto TOUCH_COORDS = PMONITOR->m_position + (E.pos * PMONITOR->m_size);

View file

@ -14,6 +14,7 @@
#include "../managers/LayoutManager.hpp"
#include "../desktop/Window.hpp"
#include "../desktop/LayerSurface.hpp"
#include "../desktop/state/FocusState.hpp"
#include "../protocols/SessionLock.hpp"
#include "../protocols/LayerShell.hpp"
#include "../protocols/XDGShell.hpp"
@ -168,7 +169,7 @@ CHyprRenderer::CHyprRenderer() {
w->m_wlSurface->resource()->frame(Time::steadyNow());
auto FEEDBACK = makeUnique<CQueuedPresentationData>(w->m_wlSurface->resource());
FEEDBACK->attachMonitor(g_pCompositor->m_lastMonitor.lock());
FEEDBACK->attachMonitor(Desktop::focusState()->monitor());
FEEDBACK->discarded();
PROTO::presentation->queueData(std::move(FEEDBACK));
}
@ -403,7 +404,7 @@ void CHyprRenderer::renderWorkspaceWindows(PHLMONITOR pMonitor, PHLWORKSPACE pWo
continue;
// render active window after all others of this pass
if (w == g_pCompositor->m_lastWindow) {
if (w == Desktop::focusState()->window()) {
lastWindow = w.lock();
continue;
}
@ -1407,7 +1408,7 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor, bool commit) {
renderLockscreen(pMonitor, NOW, renderBox);
if (pMonitor == g_pCompositor->m_lastMonitor) {
if (pMonitor == Desktop::focusState()->monitor()) {
g_pHyprNotificationOverlay->draw(pMonitor);
g_pHyprError->draw();
}
@ -1895,7 +1896,7 @@ void CHyprRenderer::arrangeLayersForMonitor(const MONITORID& monitor) {
CBox usableArea = {PMONITOR->m_position.x, PMONITOR->m_position.y, PMONITOR->m_size.x, PMONITOR->m_size.y};
if (g_pHyprError->active() && g_pCompositor->m_lastMonitor == PMONITOR->m_self) {
if (g_pHyprError->active() && Desktop::focusState()->monitor() == PMONITOR->m_self) {
const auto HEIGHT = g_pHyprError->height();
if (*BAR_POSITION == 0) {
PMONITOR->m_reservedTopLeft.y = HEIGHT;

View file

@ -1,6 +1,7 @@
#include "CHyprGroupBarDecoration.hpp"
#include "../../Compositor.hpp"
#include "../../config/ConfigValue.hpp"
#include "../../desktop/state/FocusState.hpp"
#include "managers/LayoutManager.hpp"
#include <ranges>
#include <pango/pangocairo.h>
@ -160,7 +161,7 @@ void CHyprGroupBarDecoration::draw(PHLMONITOR pMonitor, float const& a) {
const auto* const PCOLACTIVE = GROUPLOCKED ? GROUPCOLACTIVELOCKED : GROUPCOLACTIVE;
const auto* const PCOLINACTIVE = GROUPLOCKED ? GROUPCOLINACTIVELOCKED : GROUPCOLINACTIVE;
CHyprColor color = m_dwGroupMembers[WINDOWINDEX].lock() == g_pCompositor->m_lastWindow.lock() ? PCOLACTIVE->m_colors[0] : PCOLINACTIVE->m_colors[0];
CHyprColor color = m_dwGroupMembers[WINDOWINDEX].lock() == Desktop::focusState()->window() ? PCOLACTIVE->m_colors[0] : PCOLINACTIVE->m_colors[0];
color.a *= a;
if (!rect.empty()) {
@ -195,8 +196,8 @@ void CHyprGroupBarDecoration::draw(PHLMONITOR pMonitor, float const& a) {
if (!rect.empty()) {
if (*PGRADIENTS) {
const auto GRADIENTTEX = (m_dwGroupMembers[WINDOWINDEX] == g_pCompositor->m_lastWindow ? (GROUPLOCKED ? m_tGradientLockedActive : m_tGradientActive) :
(GROUPLOCKED ? m_tGradientLockedInactive : m_tGradientInactive));
const auto GRADIENTTEX = (m_dwGroupMembers[WINDOWINDEX] == Desktop::focusState()->window() ? (GROUPLOCKED ? m_tGradientLockedActive : m_tGradientActive) :
(GROUPLOCKED ? m_tGradientLockedInactive : m_tGradientInactive));
if (GRADIENTTEX->m_texID) {
CTexPassElement::SRenderData data;
data.tex = GRADIENTTEX;
@ -234,7 +235,7 @@ void CHyprGroupBarDecoration::draw(PHLMONITOR pMonitor, float const& a) {
.get();
SP<CTexture> titleTex;
if (m_dwGroupMembers[WINDOWINDEX] == g_pCompositor->m_lastWindow)
if (m_dwGroupMembers[WINDOWINDEX] == Desktop::focusState()->window())
titleTex = GROUPLOCKED ? pTitleTex->m_texLockedActive : pTitleTex->m_texActive;
else
titleTex = GROUPLOCKED ? pTitleTex->m_texLockedInactive : pTitleTex->m_texInactive;
@ -308,10 +309,10 @@ CTitleTex::CTitleTex(PHLWINDOW pWindow, const Vector2D& bufferSize, const float
static void renderGradientTo(SP<CTexture> tex, CGradientValueData* grad) {
if (!g_pCompositor->m_lastMonitor)
if (!Desktop::focusState()->monitor())
return;
const Vector2D& bufferSize = g_pCompositor->m_lastMonitor->m_pixelSize;
const Vector2D& bufferSize = Desktop::focusState()->monitor()->m_pixelSize;
const auto CAIROSURFACE = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, bufferSize.x, bufferSize.y);
const auto CAIRO = cairo_create(CAIROSURFACE);
@ -415,7 +416,7 @@ bool CHyprGroupBarDecoration::onBeginWindowDragOnDeco(const Vector2D& pos) {
g_pInputManager->m_currentlyDraggedWindow = pWindow;
if (!g_pCompositor->isWindowActive(pWindow))
g_pCompositor->focusWindow(pWindow);
Desktop::focusState()->rawWindowFocus(pWindow);
return true;
}
@ -529,7 +530,7 @@ bool CHyprGroupBarDecoration::onMouseButtonOnDeco(const Vector2D& pos, const IPo
const auto STACKPAD = *PSTACKED && (BARRELATIVEY - (m_barHeight + *POUTERGAP) * WINDOWINDEX < *POUTERGAP);
if (TABPAD || STACKPAD) {
if (!g_pCompositor->isWindowActive(m_window.lock()))
g_pCompositor->focusWindow(m_window.lock());
Desktop::focusState()->rawWindowFocus(m_window.lock());
return true;
}
@ -539,7 +540,7 @@ bool CHyprGroupBarDecoration::onMouseButtonOnDeco(const Vector2D& pos, const IPo
pWindow->setGroupCurrent(pWindow);
if (!g_pCompositor->isWindowActive(pWindow) && *PFOLLOWMOUSE != 3)
g_pCompositor->focusWindow(pWindow);
Desktop::focusState()->rawWindowFocus(pWindow);
if (pWindow->m_isFloating)
g_pCompositor->changeWindowZOrder(pWindow, true);

View file

@ -2,12 +2,13 @@
#include "../OpenGL.hpp"
#include <algorithm>
#include <ranges>
#include "../../Compositor.hpp"
#include "../../config/ConfigValue.hpp"
#include "../../desktop/WLSurface.hpp"
#include "../../managers/SeatManager.hpp"
#include "../../managers/eventLoop/EventLoopManager.hpp"
#include "../../render/Renderer.hpp"
#include "../../Compositor.hpp"
#include "../../desktop/state/FocusState.hpp"
#include "../../protocols/core/Compositor.hpp"
bool CRenderPass::empty() const {
@ -242,8 +243,8 @@ void CRenderPass::renderDebugData() {
renderHLSurface(m_debugData.keyboardFocusText, g_pSeatManager->m_state.keyboardFocus.lock(), Colors::PURPLE.modifyA(0.1F));
renderHLSurface(m_debugData.pointerFocusText, g_pSeatManager->m_state.pointerFocus.lock(), Colors::ORANGE.modifyA(0.1F));
if (g_pCompositor->m_lastWindow)
renderHLSurface(m_debugData.lastWindowText, g_pCompositor->m_lastWindow->m_wlSurface->resource(), Colors::LIGHT_BLUE.modifyA(0.1F));
if (Desktop::focusState()->window())
renderHLSurface(m_debugData.lastWindowText, Desktop::focusState()->window()->m_wlSurface->resource(), Colors::LIGHT_BLUE.modifyA(0.1F));
if (g_pSeatManager->m_state.pointerFocus) {
if (g_pSeatManager->m_state.pointerFocus->m_current.input.intersect(CBox{{}, g_pSeatManager->m_state.pointerFocus->m_current.size}).getExtents().size() !=