windowrules: rewrite completely (#12269)
Reworks the window rule syntax completely --------- Co-authored-by: Mihai Fufezan <mihai@fufexan.net>
This commit is contained in:
parent
95ee08b340
commit
c2670e9ab9
93 changed files with 3574 additions and 2255 deletions
|
|
@ -901,8 +901,8 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper
|
|||
if (ONLY_PRIORITY && !w->priorityFocus())
|
||||
continue;
|
||||
|
||||
if (w->m_isFloating && w->m_isMapped && !w->isHidden() && !w->m_X11ShouldntFocus && w->m_pinned && !w->m_windowData.noFocus.valueOrDefault() && w != pIgnoreWindow &&
|
||||
!isShadowedByModal(w)) {
|
||||
if (w->m_isFloating && w->m_isMapped && !w->isHidden() && !w->m_X11ShouldntFocus && w->m_pinned && !w->m_ruleApplicator->noFocus().valueOrDefault() &&
|
||||
w != pIgnoreWindow && !isShadowedByModal(w)) {
|
||||
const auto BB = w->getWindowBoxUnified(properties);
|
||||
CBox box = BB.copy().expand(!w->isX11OverrideRedirect() ? BORDER_GRAB_AREA : 0);
|
||||
if (box.containsPoint(g_pPointerManager->position()))
|
||||
|
|
@ -939,7 +939,7 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper
|
|||
continue;
|
||||
}
|
||||
|
||||
if (w->m_isFloating && w->m_isMapped && w->m_workspace->isVisible() && !w->isHidden() && !w->m_pinned && !w->m_windowData.noFocus.valueOrDefault() &&
|
||||
if (w->m_isFloating && w->m_isMapped && w->m_workspace->isVisible() && !w->isHidden() && !w->m_pinned && !w->m_ruleApplicator->noFocus().valueOrDefault() &&
|
||||
w != pIgnoreWindow && (!aboveFullscreen || w->m_createdOverFullscreen) && !isShadowedByModal(w)) {
|
||||
// OR windows should add focus to parent
|
||||
if (w->m_X11ShouldntFocus && !w->isX11OverrideRedirect())
|
||||
|
|
@ -1000,7 +1000,7 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper
|
|||
continue;
|
||||
|
||||
if (!w->m_isX11 && !w->m_isFloating && w->m_isMapped && w->workspaceID() == WSPID && !w->isHidden() && !w->m_X11ShouldntFocus &&
|
||||
!w->m_windowData.noFocus.valueOrDefault() && w != pIgnoreWindow && !isShadowedByModal(w)) {
|
||||
!w->m_ruleApplicator->noFocus().valueOrDefault() && w != pIgnoreWindow && !isShadowedByModal(w)) {
|
||||
if (w->hasPopupAt(pos))
|
||||
return w;
|
||||
}
|
||||
|
|
@ -1016,7 +1016,7 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper
|
|||
if (!w->m_workspace)
|
||||
continue;
|
||||
|
||||
if (!w->m_isFloating && w->m_isMapped && w->workspaceID() == WSPID && !w->isHidden() && !w->m_X11ShouldntFocus && !w->m_windowData.noFocus.valueOrDefault() &&
|
||||
if (!w->m_isFloating && w->m_isMapped && w->workspaceID() == WSPID && !w->isHidden() && !w->m_X11ShouldntFocus && !w->m_ruleApplicator->noFocus().valueOrDefault() &&
|
||||
w != pIgnoreWindow && !isShadowedByModal(w)) {
|
||||
CBox box = (properties & USE_PROP_TILED) ? w->getWindowBoxUnified(properties) : CBox{w->m_position, w->m_size};
|
||||
if (box.containsPoint(pos))
|
||||
|
|
@ -1152,7 +1152,7 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, SP<CWLSurfaceResource> pSurface
|
|||
m_lastWindow.reset();
|
||||
|
||||
if (PLASTWINDOW && PLASTWINDOW->m_isMapped) {
|
||||
updateWindowAnimatedDecorationValues(PLASTWINDOW);
|
||||
PLASTWINDOW->updateDecorationValues();
|
||||
|
||||
g_pXWaylandManager->activateWindow(PLASTWINDOW, false);
|
||||
}
|
||||
|
|
@ -1172,7 +1172,7 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, SP<CWLSurfaceResource> pSurface
|
|||
return;
|
||||
}
|
||||
|
||||
if (pWindow->m_windowData.noFocus.valueOrDefault()) {
|
||||
if (pWindow->m_ruleApplicator->noFocus().valueOrDefault()) {
|
||||
Debug::log(LOG, "Ignoring focus to nofocus window!");
|
||||
return;
|
||||
}
|
||||
|
|
@ -1209,9 +1209,9 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, SP<CWLSurfaceResource> pSurface
|
|||
|
||||
// we need to make the PLASTWINDOW not equal to m_pLastWindow so that RENDERDATA is correct for an unfocused window
|
||||
if (PLASTWINDOW && PLASTWINDOW->m_isMapped) {
|
||||
PLASTWINDOW->updateDynamicRules();
|
||||
PLASTWINDOW->m_ruleApplicator->propertiesChanged(Desktop::Rule::RULE_PROP_FOCUS);
|
||||
|
||||
updateWindowAnimatedDecorationValues(PLASTWINDOW);
|
||||
PLASTWINDOW->updateDecorationValues();
|
||||
|
||||
if (!pWindow->m_isX11 || !pWindow->isX11OverrideRedirect())
|
||||
g_pXWaylandManager->activateWindow(PLASTWINDOW, false);
|
||||
|
|
@ -1225,10 +1225,10 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, SP<CWLSurfaceResource> pSurface
|
|||
|
||||
g_pXWaylandManager->activateWindow(pWindow, true); // sets the m_pLastWindow
|
||||
|
||||
pWindow->updateDynamicRules();
|
||||
pWindow->m_ruleApplicator->propertiesChanged(Desktop::Rule::RULE_PROP_FOCUS);
|
||||
pWindow->onFocusAnimUpdate();
|
||||
|
||||
updateWindowAnimatedDecorationValues(pWindow);
|
||||
pWindow->updateDecorationValues();
|
||||
|
||||
if (pWindow->m_isUrgent)
|
||||
pWindow->m_isUrgent = false;
|
||||
|
|
@ -1334,7 +1334,7 @@ SP<CWLSurfaceResource> CCompositor::vectorToLayerSurface(const Vector2D& pos, st
|
|||
|
||||
for (auto const& ls : *layerSurfaces | std::views::reverse) {
|
||||
if (!ls->m_mapped || ls->m_fadingOut || !ls->m_layerSurface || (ls->m_layerSurface && !ls->m_layerSurface->m_surface->m_mapped) || ls->m_alpha->value() == 0.f ||
|
||||
(aboveLockscreen && (!ls->m_aboveLockscreen || !ls->m_aboveLockscreenInteractable)))
|
||||
(aboveLockscreen && ls->m_ruleApplicator->aboveLock().valueOrDefault() != 2))
|
||||
continue;
|
||||
|
||||
auto [surf, local] = ls->m_layerSurface->m_surface->at(pos - ls->m_geometry.pos(), true);
|
||||
|
|
@ -1715,7 +1715,7 @@ static bool isFloatingMatches(WINDOWPTR w, std::optional<bool> floating) {
|
|||
template <typename WINDOWPTR>
|
||||
static bool isWindowAvailableForCycle(WINDOWPTR pWindow, WINDOWPTR w, bool focusableOnly, std::optional<bool> floating, bool anyWorkspace = false) {
|
||||
return isFloatingMatches(w, floating) &&
|
||||
(w != pWindow && isWorkspaceMatches(pWindow, w, anyWorkspace) && w->m_isMapped && !w->isHidden() && (!focusableOnly || !w->m_windowData.noFocus.valueOrDefault()));
|
||||
(w != pWindow && isWorkspaceMatches(pWindow, w, anyWorkspace) && w->m_isMapped && !w->isHidden() && (!focusableOnly || !w->m_ruleApplicator->noFocus().valueOrDefault()));
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
|
|
@ -1906,103 +1906,10 @@ void CCompositor::updateAllWindowsAnimatedDecorationValues() {
|
|||
if (!w->m_isMapped)
|
||||
continue;
|
||||
|
||||
updateWindowAnimatedDecorationValues(w);
|
||||
w->updateDecorationValues();
|
||||
}
|
||||
}
|
||||
|
||||
void CCompositor::updateWindowAnimatedDecorationValues(PHLWINDOW pWindow) {
|
||||
// optimization
|
||||
static auto PACTIVECOL = CConfigValue<Hyprlang::CUSTOMTYPE>("general:col.active_border");
|
||||
static auto PINACTIVECOL = CConfigValue<Hyprlang::CUSTOMTYPE>("general:col.inactive_border");
|
||||
static auto PNOGROUPACTIVECOL = CConfigValue<Hyprlang::CUSTOMTYPE>("general:col.nogroup_border_active");
|
||||
static auto PNOGROUPINACTIVECOL = CConfigValue<Hyprlang::CUSTOMTYPE>("general:col.nogroup_border");
|
||||
static auto PGROUPACTIVECOL = CConfigValue<Hyprlang::CUSTOMTYPE>("group:col.border_active");
|
||||
static auto PGROUPINACTIVECOL = CConfigValue<Hyprlang::CUSTOMTYPE>("group:col.border_inactive");
|
||||
static auto PGROUPACTIVELOCKEDCOL = CConfigValue<Hyprlang::CUSTOMTYPE>("group:col.border_locked_active");
|
||||
static auto PGROUPINACTIVELOCKEDCOL = CConfigValue<Hyprlang::CUSTOMTYPE>("group:col.border_locked_inactive");
|
||||
static auto PINACTIVEALPHA = CConfigValue<Hyprlang::FLOAT>("decoration:inactive_opacity");
|
||||
static auto PACTIVEALPHA = CConfigValue<Hyprlang::FLOAT>("decoration:active_opacity");
|
||||
static auto PFULLSCREENALPHA = CConfigValue<Hyprlang::FLOAT>("decoration:fullscreen_opacity");
|
||||
static auto PSHADOWCOL = CConfigValue<Hyprlang::INT>("decoration:shadow:color");
|
||||
static auto PSHADOWCOLINACTIVE = CConfigValue<Hyprlang::INT>("decoration:shadow:color_inactive");
|
||||
static auto PDIMSTRENGTH = CConfigValue<Hyprlang::FLOAT>("decoration:dim_strength");
|
||||
static auto PDIMENABLED = CConfigValue<Hyprlang::INT>("decoration:dim_inactive");
|
||||
static auto PDIMMODAL = CConfigValue<Hyprlang::INT>("decoration:dim_modal");
|
||||
|
||||
auto* const ACTIVECOL = sc<CGradientValueData*>((PACTIVECOL.ptr())->getData());
|
||||
auto* const INACTIVECOL = sc<CGradientValueData*>((PINACTIVECOL.ptr())->getData());
|
||||
auto* const NOGROUPACTIVECOL = sc<CGradientValueData*>((PNOGROUPACTIVECOL.ptr())->getData());
|
||||
auto* const NOGROUPINACTIVECOL = sc<CGradientValueData*>((PNOGROUPINACTIVECOL.ptr())->getData());
|
||||
auto* const GROUPACTIVECOL = sc<CGradientValueData*>((PGROUPACTIVECOL.ptr())->getData());
|
||||
auto* const GROUPINACTIVECOL = sc<CGradientValueData*>((PGROUPINACTIVECOL.ptr())->getData());
|
||||
auto* const GROUPACTIVELOCKEDCOL = sc<CGradientValueData*>((PGROUPACTIVELOCKEDCOL.ptr())->getData());
|
||||
auto* const GROUPINACTIVELOCKEDCOL = sc<CGradientValueData*>((PGROUPINACTIVELOCKEDCOL.ptr())->getData());
|
||||
|
||||
auto setBorderColor = [&](CGradientValueData grad) -> void {
|
||||
if (grad == pWindow->m_realBorderColor)
|
||||
return;
|
||||
|
||||
pWindow->m_realBorderColorPrevious = pWindow->m_realBorderColor;
|
||||
pWindow->m_realBorderColor = grad;
|
||||
pWindow->m_borderFadeAnimationProgress->setValueAndWarp(0.f);
|
||||
*pWindow->m_borderFadeAnimationProgress = 1.f;
|
||||
};
|
||||
|
||||
const bool IS_SHADOWED_BY_MODAL = pWindow->m_xdgSurface && pWindow->m_xdgSurface->m_toplevel && pWindow->m_xdgSurface->m_toplevel->anyChildModal();
|
||||
|
||||
// border
|
||||
const auto RENDERDATA = g_pLayoutManager->getCurrentLayout()->requestRenderHints(pWindow);
|
||||
if (RENDERDATA.isBorderGradient)
|
||||
setBorderColor(*RENDERDATA.borderGradient);
|
||||
else {
|
||||
const bool GROUPLOCKED = pWindow->m_groupData.pNextWindow.lock() ? pWindow->getGroupHead()->m_groupData.locked : false;
|
||||
if (pWindow == m_lastWindow) {
|
||||
const auto* const ACTIVECOLOR =
|
||||
!pWindow->m_groupData.pNextWindow.lock() ? (!pWindow->m_groupData.deny ? ACTIVECOL : NOGROUPACTIVECOL) : (GROUPLOCKED ? GROUPACTIVELOCKEDCOL : GROUPACTIVECOL);
|
||||
setBorderColor(pWindow->m_windowData.activeBorderColor.valueOr(*ACTIVECOLOR));
|
||||
} else {
|
||||
const auto* const INACTIVECOLOR = !pWindow->m_groupData.pNextWindow.lock() ? (!pWindow->m_groupData.deny ? INACTIVECOL : NOGROUPINACTIVECOL) :
|
||||
(GROUPLOCKED ? GROUPINACTIVELOCKEDCOL : GROUPINACTIVECOL);
|
||||
setBorderColor(pWindow->m_windowData.inactiveBorderColor.valueOr(*INACTIVECOLOR));
|
||||
}
|
||||
}
|
||||
|
||||
// opacity
|
||||
const auto PWORKSPACE = pWindow->m_workspace;
|
||||
if (pWindow->isEffectiveInternalFSMode(FSMODE_FULLSCREEN)) {
|
||||
*pWindow->m_activeInactiveAlpha = pWindow->m_windowData.alphaFullscreen.valueOrDefault().applyAlpha(*PFULLSCREENALPHA);
|
||||
} else {
|
||||
if (pWindow == m_lastWindow)
|
||||
*pWindow->m_activeInactiveAlpha = pWindow->m_windowData.alpha.valueOrDefault().applyAlpha(*PACTIVEALPHA);
|
||||
else
|
||||
*pWindow->m_activeInactiveAlpha = pWindow->m_windowData.alphaInactive.valueOrDefault().applyAlpha(*PINACTIVEALPHA);
|
||||
}
|
||||
|
||||
// dim
|
||||
float goalDim = 1.F;
|
||||
if (pWindow == m_lastWindow.lock() || pWindow->m_windowData.noDim.valueOrDefault() || !*PDIMENABLED)
|
||||
goalDim = 0;
|
||||
else
|
||||
goalDim = *PDIMSTRENGTH;
|
||||
|
||||
if (IS_SHADOWED_BY_MODAL && *PDIMMODAL)
|
||||
goalDim += (1.F - goalDim) / 2.F;
|
||||
|
||||
*pWindow->m_dimPercent = goalDim;
|
||||
|
||||
// shadow
|
||||
if (!pWindow->isX11OverrideRedirect() && !pWindow->m_X11DoesntWantBorders) {
|
||||
if (pWindow == m_lastWindow)
|
||||
*pWindow->m_realShadowColor = CHyprColor(*PSHADOWCOL);
|
||||
else
|
||||
*pWindow->m_realShadowColor = CHyprColor(*PSHADOWCOLINACTIVE != -1 ? *PSHADOWCOLINACTIVE : *PSHADOWCOL);
|
||||
} else {
|
||||
pWindow->m_realShadowColor->setValueAndWarp(CHyprColor(0, 0, 0, 0)); // no shadow
|
||||
}
|
||||
|
||||
pWindow->updateWindowDecos();
|
||||
}
|
||||
|
||||
MONITORID CCompositor::getNextAvailableMonitorID(std::string const& name) {
|
||||
// reuse ID if it's already in the map, and the monitor with that ID is not being used by another monitor
|
||||
if (m_monitorIDMap.contains(name) && !std::ranges::any_of(m_realMonitors, [&](auto m) { return m->m_id == m_monitorIDMap[name]; }))
|
||||
|
|
@ -2341,14 +2248,14 @@ void CCompositor::changeWindowFullscreenModeClient(const PHLWINDOW PWINDOW, cons
|
|||
}
|
||||
|
||||
void CCompositor::setWindowFullscreenInternal(const PHLWINDOW PWINDOW, const eFullscreenMode MODE) {
|
||||
if (PWINDOW->m_windowData.syncFullscreen.valueOrDefault())
|
||||
if (PWINDOW->m_ruleApplicator->syncFullscreen().valueOrDefault())
|
||||
setWindowFullscreenState(PWINDOW, SFullscreenState{.internal = MODE, .client = MODE});
|
||||
else
|
||||
setWindowFullscreenState(PWINDOW, SFullscreenState{.internal = MODE, .client = PWINDOW->m_fullscreenState.client});
|
||||
}
|
||||
|
||||
void CCompositor::setWindowFullscreenClient(const PHLWINDOW PWINDOW, const eFullscreenMode MODE) {
|
||||
if (PWINDOW->m_windowData.syncFullscreen.valueOrDefault())
|
||||
if (PWINDOW->m_ruleApplicator->syncFullscreen().valueOrDefault())
|
||||
setWindowFullscreenState(PWINDOW, SFullscreenState{.internal = MODE, .client = MODE});
|
||||
else
|
||||
setWindowFullscreenState(PWINDOW, SFullscreenState{.internal = PWINDOW->m_fullscreenState.internal, .client = MODE});
|
||||
|
|
@ -2389,15 +2296,16 @@ void CCompositor::setWindowFullscreenState(const PHLWINDOW PWINDOW, SFullscreenS
|
|||
}
|
||||
|
||||
// TODO: update the state on syncFullscreen changes
|
||||
if (!CHANGEINTERNAL && PWINDOW->m_windowData.syncFullscreen.valueOrDefault())
|
||||
if (!CHANGEINTERNAL && PWINDOW->m_ruleApplicator->syncFullscreen().valueOrDefault())
|
||||
return;
|
||||
|
||||
PWINDOW->m_fullscreenState.client = state.client;
|
||||
g_pXWaylandManager->setWindowFullscreen(PWINDOW, state.client & FSMODE_FULLSCREEN);
|
||||
|
||||
if (!CHANGEINTERNAL) {
|
||||
PWINDOW->updateDynamicRules();
|
||||
updateWindowAnimatedDecorationValues(PWINDOW);
|
||||
PWINDOW->m_ruleApplicator->propertiesChanged(Desktop::Rule::RULE_PROP_FULLSCREEN | Desktop::Rule::RULE_PROP_FULLSCREENSTATE_CLIENT |
|
||||
Desktop::Rule::RULE_PROP_FULLSCREENSTATE_INTERNAL | Desktop::Rule::RULE_PROP_ON_WORKSPACE);
|
||||
PWINDOW->updateDecorationValues();
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PWINDOW->monitorID());
|
||||
return;
|
||||
}
|
||||
|
|
@ -2411,8 +2319,10 @@ void CCompositor::setWindowFullscreenState(const PHLWINDOW PWINDOW, SFullscreenS
|
|||
g_pEventManager->postEvent(SHyprIPCEvent{.event = "fullscreen", .data = std::to_string(sc<int>(EFFECTIVE_MODE) != FSMODE_NONE)});
|
||||
EMIT_HOOK_EVENT("fullscreen", PWINDOW);
|
||||
|
||||
PWINDOW->updateDynamicRules();
|
||||
updateWindowAnimatedDecorationValues(PWINDOW);
|
||||
PWINDOW->m_ruleApplicator->propertiesChanged(Desktop::Rule::RULE_PROP_FULLSCREEN | Desktop::Rule::RULE_PROP_FULLSCREENSTATE_CLIENT |
|
||||
Desktop::Rule::RULE_PROP_FULLSCREENSTATE_INTERNAL | Desktop::Rule::RULE_PROP_ON_WORKSPACE);
|
||||
|
||||
PWINDOW->updateDecorationValues();
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PWINDOW->monitorID());
|
||||
|
||||
// make all windows on the same workspace under the fullscreen window
|
||||
|
|
@ -2552,7 +2462,7 @@ PHLWINDOW CCompositor::getWindowByRegex(const std::string& regexp_) {
|
|||
}
|
||||
case MODE_TAG_REGEX: {
|
||||
bool tagMatched = false;
|
||||
for (auto const& t : w->m_tags.getTags()) {
|
||||
for (auto const& t : w->m_ruleApplicator->m_tagKeeper.getTags()) {
|
||||
if (RE2::FullMatch(t, regexCheck)) {
|
||||
tagMatched = true;
|
||||
break;
|
||||
|
|
@ -2843,7 +2753,7 @@ void CCompositor::moveWindowToWorkspaceSafe(PHLWINDOW pWindow, PHLWORKSPACE pWor
|
|||
}
|
||||
|
||||
pWindow->updateToplevel();
|
||||
pWindow->updateDynamicRules();
|
||||
pWindow->m_ruleApplicator->propertiesChanged(Desktop::Rule::RULE_PROP_ON_WORKSPACE);
|
||||
pWindow->uncacheWindowDecos();
|
||||
pWindow->updateGroupOutputs();
|
||||
|
||||
|
|
@ -2874,7 +2784,7 @@ PHLWINDOW CCompositor::getForceFocus() {
|
|||
if (!w->m_isMapped || w->isHidden() || !w->m_workspace || !w->m_workspace->isVisible())
|
||||
continue;
|
||||
|
||||
if (!w->m_stayFocused)
|
||||
if (!w->m_ruleApplicator->stayFocused().valueOrDefault())
|
||||
continue;
|
||||
|
||||
return w;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue