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:
parent
1c1746de61
commit
40d8fa8491
51 changed files with 1003 additions and 694 deletions
|
|
@ -3,6 +3,7 @@
|
|||
#include <algorithm>
|
||||
#include "../Compositor.hpp"
|
||||
#include "../managers/TokenManager.hpp"
|
||||
#include "../desktop/state/FocusState.hpp"
|
||||
#include "Monitor.hpp"
|
||||
#include "../config/ConfigManager.hpp"
|
||||
#include "fs/FsUtils.hpp"
|
||||
|
|
@ -146,7 +147,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
|
|||
} else if (in.starts_with("empty")) {
|
||||
const bool same_mon = in.substr(5).contains("m");
|
||||
const bool next = in.substr(5).contains("n");
|
||||
if ((same_mon || next) && !g_pCompositor->m_lastMonitor) {
|
||||
if ((same_mon || next) && !Desktop::focusState()->monitor()) {
|
||||
Debug::log(ERR, "Empty monitor workspace on monitor null!");
|
||||
return {WORKSPACE_INVALID};
|
||||
}
|
||||
|
|
@ -155,12 +156,12 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
|
|||
if (same_mon) {
|
||||
for (auto const& rule : g_pConfigManager->getAllWorkspaceRules()) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromString(rule.monitor);
|
||||
if (PMONITOR && (PMONITOR->m_id != g_pCompositor->m_lastMonitor->m_id))
|
||||
if (PMONITOR && (PMONITOR->m_id != Desktop::focusState()->monitor()->m_id))
|
||||
invalidWSes.insert(rule.workspaceId);
|
||||
}
|
||||
}
|
||||
|
||||
WORKSPACEID id = next ? g_pCompositor->m_lastMonitor->activeWorkspaceID() : 0;
|
||||
WORKSPACEID id = next ? Desktop::focusState()->monitor()->activeWorkspaceID() : 0;
|
||||
while (++id < LONG_MAX) {
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(id);
|
||||
if (!invalidWSes.contains(id) && (!PWORKSPACE || PWORKSPACE->getWindows() == 0)) {
|
||||
|
|
@ -169,10 +170,10 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
|
|||
}
|
||||
}
|
||||
} else if (in.starts_with("prev")) {
|
||||
if (!g_pCompositor->m_lastMonitor)
|
||||
if (!Desktop::focusState()->monitor())
|
||||
return {WORKSPACE_INVALID};
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->m_lastMonitor->m_activeWorkspace;
|
||||
const auto PWORKSPACE = Desktop::focusState()->monitor()->m_activeWorkspace;
|
||||
|
||||
if (!valid(PWORKSPACE))
|
||||
return {WORKSPACE_INVALID};
|
||||
|
|
@ -191,12 +192,12 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
|
|||
|
||||
return {PLASTWORKSPACE->m_id, PLASTWORKSPACE->m_name};
|
||||
} else if (in == "next") {
|
||||
if (!g_pCompositor->m_lastMonitor || !g_pCompositor->m_lastMonitor->m_activeWorkspace) {
|
||||
if (!Desktop::focusState()->monitor() || !Desktop::focusState()->monitor()->m_activeWorkspace) {
|
||||
Debug::log(ERR, "no active monitor or workspace for 'next'");
|
||||
return {WORKSPACE_INVALID};
|
||||
}
|
||||
|
||||
auto PCURRENTWORKSPACE = g_pCompositor->m_lastMonitor->m_activeWorkspace;
|
||||
auto PCURRENTWORKSPACE = Desktop::focusState()->monitor()->m_activeWorkspace;
|
||||
|
||||
WORKSPACEID nextId = PCURRENTWORKSPACE->m_id + 1;
|
||||
|
||||
|
|
@ -209,7 +210,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
|
|||
} else {
|
||||
if (in[0] == 'r' && (in[1] == '-' || in[1] == '+' || in[1] == '~') && isNumber(in.substr(2))) {
|
||||
bool absolute = in[1] == '~';
|
||||
if (!g_pCompositor->m_lastMonitor) {
|
||||
if (!Desktop::focusState()->monitor()) {
|
||||
Debug::log(ERR, "Relative monitor workspace on monitor null!");
|
||||
return {WORKSPACE_INVALID};
|
||||
}
|
||||
|
|
@ -227,14 +228,14 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
|
|||
|
||||
// Collect all the workspaces we can't jump to.
|
||||
for (auto const& ws : g_pCompositor->getWorkspaces()) {
|
||||
if (ws->m_isSpecialWorkspace || (ws->m_monitor != g_pCompositor->m_lastMonitor)) {
|
||||
if (ws->m_isSpecialWorkspace || (ws->m_monitor != Desktop::focusState()->monitor())) {
|
||||
// Can't jump to this workspace
|
||||
invalidWSes.insert(ws->m_id);
|
||||
}
|
||||
}
|
||||
for (auto const& rule : g_pConfigManager->getAllWorkspaceRules()) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromString(rule.monitor);
|
||||
if (!PMONITOR || PMONITOR->m_id == g_pCompositor->m_lastMonitor->m_id) {
|
||||
if (!PMONITOR || PMONITOR->m_id == Desktop::focusState()->monitor()->m_id) {
|
||||
// Can't be invalid
|
||||
continue;
|
||||
}
|
||||
|
|
@ -245,7 +246,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
|
|||
// Prepare all named workspaces in case when we need them
|
||||
std::vector<WORKSPACEID> namedWSes;
|
||||
for (auto const& ws : g_pCompositor->getWorkspaces()) {
|
||||
if (ws->m_isSpecialWorkspace || (ws->m_monitor != g_pCompositor->m_lastMonitor) || ws->m_id >= 0)
|
||||
if (ws->m_isSpecialWorkspace || (ws->m_monitor != Desktop::focusState()->monitor()) || ws->m_id >= 0)
|
||||
continue;
|
||||
|
||||
namedWSes.push_back(ws->m_id);
|
||||
|
|
@ -272,7 +273,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
|
|||
} else {
|
||||
|
||||
// Just take a blind guess at where we'll probably end up
|
||||
WORKSPACEID activeWSID = g_pCompositor->m_lastMonitor->m_activeWorkspace ? g_pCompositor->m_lastMonitor->m_activeWorkspace->m_id : 1;
|
||||
WORKSPACEID activeWSID = Desktop::focusState()->monitor()->m_activeWorkspace ? Desktop::focusState()->monitor()->m_activeWorkspace->m_id : 1;
|
||||
WORKSPACEID predictedWSID = activeWSID + remains;
|
||||
int remainingWSes = 0;
|
||||
char walkDir = in[1];
|
||||
|
|
@ -371,7 +372,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
|
|||
bool onAllMonitors = in[0] == 'e';
|
||||
bool absolute = in[1] == '~';
|
||||
|
||||
if (!g_pCompositor->m_lastMonitor) {
|
||||
if (!Desktop::focusState()->monitor()) {
|
||||
Debug::log(ERR, "Relative monitor workspace on monitor null!");
|
||||
return {WORKSPACE_INVALID};
|
||||
}
|
||||
|
|
@ -389,7 +390,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
|
|||
|
||||
std::vector<WORKSPACEID> validWSes;
|
||||
for (auto const& ws : g_pCompositor->getWorkspaces()) {
|
||||
if (ws->m_isSpecialWorkspace || (ws->m_monitor != g_pCompositor->m_lastMonitor && !onAllMonitors))
|
||||
if (ws->m_isSpecialWorkspace || (ws->m_monitor != Desktop::focusState()->monitor() && !onAllMonitors))
|
||||
continue;
|
||||
|
||||
validWSes.push_back(ws->m_id);
|
||||
|
|
@ -414,7 +415,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
|
|||
remains = remains < 0 ? -((-remains) % validWSes.size()) : remains % validWSes.size();
|
||||
|
||||
// get the current item
|
||||
WORKSPACEID activeWSID = g_pCompositor->m_lastMonitor->m_activeWorkspace ? g_pCompositor->m_lastMonitor->m_activeWorkspace->m_id : 1;
|
||||
WORKSPACEID activeWSID = Desktop::focusState()->monitor()->m_activeWorkspace ? Desktop::focusState()->monitor()->m_activeWorkspace->m_id : 1;
|
||||
for (ssize_t i = 0; i < sc<ssize_t>(validWSes.size()); i++) {
|
||||
if (validWSes[i] == activeWSID) {
|
||||
currentItem = i;
|
||||
|
|
@ -437,8 +438,8 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
|
|||
result.name = g_pCompositor->getWorkspaceByID(validWSes[currentItem])->m_name;
|
||||
} else {
|
||||
if (in[0] == '+' || in[0] == '-') {
|
||||
if (g_pCompositor->m_lastMonitor) {
|
||||
const auto PLUSMINUSRESULT = getPlusMinusKeywordResult(in, g_pCompositor->m_lastMonitor->activeWorkspaceID());
|
||||
if (Desktop::focusState()->monitor()) {
|
||||
const auto PLUSMINUSRESULT = getPlusMinusKeywordResult(in, Desktop::focusState()->monitor()->activeWorkspaceID());
|
||||
if (!PLUSMINUSRESULT.has_value())
|
||||
return {WORKSPACE_INVALID};
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "sync/SyncTimeline.hpp"
|
||||
#include "time/Time.hpp"
|
||||
#include "../desktop/LayerSurface.hpp"
|
||||
#include "../desktop/state/FocusState.hpp"
|
||||
#include <aquamarine/output/Output.hpp>
|
||||
#include "debug/Log.hpp"
|
||||
#include "debug/HyprNotificationOverlay.hpp"
|
||||
|
|
@ -298,8 +299,8 @@ void CMonitor::onConnect(bool noRule) {
|
|||
if (!m_activeMonitorRule.mirrorOf.empty())
|
||||
setMirror(m_activeMonitorRule.mirrorOf);
|
||||
|
||||
if (!g_pCompositor->m_lastMonitor) // set the last monitor if it isn't set yet
|
||||
g_pCompositor->setActiveMonitor(m_self.lock());
|
||||
if (!Desktop::focusState()->monitor()) // set the last monitor if it isn't set yet
|
||||
Desktop::focusState()->rawMonitorFocus(m_self.lock());
|
||||
|
||||
g_pHyprRenderer->arrangeLayersForMonitor(m_id);
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m_id);
|
||||
|
|
@ -310,7 +311,7 @@ void CMonitor::onConnect(bool noRule) {
|
|||
// verify last mon valid
|
||||
bool found = false;
|
||||
for (auto const& m : g_pCompositor->m_monitors) {
|
||||
if (m == g_pCompositor->m_lastMonitor) {
|
||||
if (m == Desktop::focusState()->monitor()) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
|
@ -330,7 +331,7 @@ void CMonitor::onConnect(bool noRule) {
|
|||
Debug::log(LOG, "Monitor {} was not on any workspace", m_name);
|
||||
|
||||
if (!found)
|
||||
g_pCompositor->setActiveMonitor(m_self.lock());
|
||||
Desktop::focusState()->rawMonitorFocus(m_self.lock());
|
||||
|
||||
g_pCompositor->scheduleFrameForMonitor(m_self.lock(), Aquamarine::IOutput::AQ_SCHEDULE_NEW_MONITOR);
|
||||
|
||||
|
|
@ -437,9 +438,9 @@ void CMonitor::onDisconnect(bool destroy) {
|
|||
g_pDesktopAnimationManager->startAnimation(w, CDesktopAnimationManager::ANIMATION_TYPE_IN, true, true);
|
||||
}
|
||||
} else {
|
||||
g_pCompositor->m_lastFocus.reset();
|
||||
g_pCompositor->m_lastWindow.reset();
|
||||
g_pCompositor->m_lastMonitor.reset();
|
||||
Desktop::focusState()->surface().reset();
|
||||
Desktop::focusState()->window().reset();
|
||||
Desktop::focusState()->monitor().reset();
|
||||
}
|
||||
|
||||
if (m_activeWorkspace)
|
||||
|
|
@ -453,8 +454,8 @@ void CMonitor::onDisconnect(bool destroy) {
|
|||
if (!m_state.commit())
|
||||
Debug::log(WARN, "state.commit() failed in CMonitor::onDisconnect");
|
||||
|
||||
if (g_pCompositor->m_lastMonitor == m_self)
|
||||
g_pCompositor->setActiveMonitor(BACKUPMON ? BACKUPMON : g_pCompositor->m_unsafeOutput.lock());
|
||||
if (Desktop::focusState()->monitor() == m_self)
|
||||
Desktop::focusState()->rawMonitorFocus(BACKUPMON ? BACKUPMON : g_pCompositor->m_unsafeOutput.lock());
|
||||
|
||||
if (g_pHyprRenderer->m_mostHzMonitor == m_self) {
|
||||
int mostHz = 0;
|
||||
|
|
@ -1203,7 +1204,7 @@ void CMonitor::setMirror(const std::string& mirrorOf) {
|
|||
|
||||
g_pCompositor->scheduleMonitorStateRecheck();
|
||||
|
||||
g_pCompositor->setActiveMonitor(g_pCompositor->m_monitors.front());
|
||||
Desktop::focusState()->rawMonitorFocus(g_pCompositor->m_monitors.front());
|
||||
|
||||
// Software lock mirrored monitor
|
||||
g_pPointerManager->lockSoftwareForMonitor(PMIRRORMON);
|
||||
|
|
@ -1286,8 +1287,8 @@ void CMonitor::changeWorkspace(const PHLWORKSPACE& pWorkspace, bool internal, bo
|
|||
w->moveToWorkspace(pWorkspace);
|
||||
}
|
||||
|
||||
if (!noFocus && !g_pCompositor->m_lastMonitor->m_activeSpecialWorkspace &&
|
||||
!(g_pCompositor->m_lastWindow.lock() && g_pCompositor->m_lastWindow->m_pinned && g_pCompositor->m_lastWindow->m_monitor == m_self)) {
|
||||
if (!noFocus && !Desktop::focusState()->monitor()->m_activeSpecialWorkspace &&
|
||||
!(Desktop::focusState()->window() && Desktop::focusState()->window()->m_pinned && Desktop::focusState()->window()->m_monitor == m_self)) {
|
||||
static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
|
||||
auto pWindow = pWorkspace->m_hasFullscreenWindow ? pWorkspace->getFullscreenWindow() : pWorkspace->getLastFocusedWindow();
|
||||
|
||||
|
|
@ -1302,7 +1303,7 @@ void CMonitor::changeWorkspace(const PHLWORKSPACE& pWorkspace, bool internal, bo
|
|||
pWindow = pWorkspace->getFirstWindow();
|
||||
}
|
||||
|
||||
g_pCompositor->focusWindow(pWindow);
|
||||
Desktop::focusState()->fullWindowFocus(pWindow);
|
||||
}
|
||||
|
||||
if (!noMouseMove)
|
||||
|
|
@ -1361,9 +1362,9 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) {
|
|||
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m_id);
|
||||
|
||||
if (!(g_pCompositor->m_lastWindow.lock() && g_pCompositor->m_lastWindow->m_pinned && g_pCompositor->m_lastWindow->m_monitor == m_self)) {
|
||||
if (!(Desktop::focusState()->window() && Desktop::focusState()->window()->m_pinned && Desktop::focusState()->window()->m_monitor == m_self)) {
|
||||
if (const auto PLAST = m_activeWorkspace->getLastFocusedWindow(); PLAST)
|
||||
g_pCompositor->focusWindow(PLAST);
|
||||
Desktop::focusState()->fullWindowFocus(PLAST);
|
||||
else
|
||||
g_pInputManager->refocus();
|
||||
}
|
||||
|
|
@ -1443,9 +1444,9 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) {
|
|||
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m_id);
|
||||
|
||||
if (!(g_pCompositor->m_lastWindow.lock() && g_pCompositor->m_lastWindow->m_pinned && g_pCompositor->m_lastWindow->m_monitor == m_self)) {
|
||||
if (!(Desktop::focusState()->window() && Desktop::focusState()->window()->m_pinned && Desktop::focusState()->window()->m_monitor == m_self)) {
|
||||
if (const auto PLAST = pWorkspace->getLastFocusedWindow(); PLAST)
|
||||
g_pCompositor->focusWindow(PLAST);
|
||||
Desktop::focusState()->fullWindowFocus(PLAST);
|
||||
else
|
||||
g_pInputManager->refocus();
|
||||
}
|
||||
|
|
@ -1553,7 +1554,7 @@ uint32_t CMonitor::isSolitaryBlocked(bool full) {
|
|||
return reasons;
|
||||
}
|
||||
|
||||
if (g_pHyprError->active() && g_pCompositor->m_lastMonitor == m_self) {
|
||||
if (g_pHyprError->active() && Desktop::focusState()->monitor() == m_self) {
|
||||
reasons |= SC_ERRORBAR;
|
||||
if (!full)
|
||||
return reasons;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue