master: Fix master layout window focus and scroll (#5074)

* fix master switch window scrolling

* fix some more dispatchers and remove some duplicate code

* refactor and remove duplicate code

* fix focusmonitor: https://github.com/hyprwm/Hyprland/issues/5006#issuecomment-1986977255

* change check
This commit is contained in:
thejch 2024-03-12 19:09:20 -07:00 committed by GitHub
parent 6c53d4d82f
commit 7ea555da7f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 39 additions and 63 deletions

View file

@ -2297,6 +2297,11 @@ void CCompositor::setWindowFullscreen(CWindow* pWindow, bool on, eFullscreenMode
return; return;
} }
if (pWindow->m_bIsFullscreen == on) {
Debug::log(LOG, "Window is already in the required fullscreen state");
return;
}
const auto PMONITOR = getMonitorFromID(pWindow->m_iMonitorID); const auto PMONITOR = getMonitorFromID(pWindow->m_iMonitorID);
const auto PWORKSPACE = getWorkspaceByID(pWindow->m_iWorkspaceID); const auto PWORKSPACE = getWorkspaceByID(pWindow->m_iWorkspaceID);

View file

@ -245,8 +245,7 @@ void CHyprMasterLayout::onWindowRemovedTiling(CWindow* pWindow) {
pWindow->updateSpecialRenderData(); pWindow->updateSpecialRenderData();
if (pWindow->m_bIsFullscreen) g_pCompositor->setWindowFullscreen(pWindow, false, FULLSCREEN_FULL);
g_pCompositor->setWindowFullscreen(pWindow, false, FULLSCREEN_FULL);
if (PNODE->isMaster && (MASTERSLEFT <= 1 || *SMALLSPLIT == 1)) { if (PNODE->isMaster && (MASTERSLEFT <= 1 || *SMALLSPLIT == 1)) {
// find a new master from top of the list // find a new master from top of the list
@ -1017,8 +1016,6 @@ void CHyprMasterLayout::switchWindows(CWindow* pWindow, CWindow* pWindow2) {
if (!PNODE2 || !PNODE) if (!PNODE2 || !PNODE)
return; return;
const auto inheritFullscreen = prepareLoseFocus(pWindow);
if (PNODE->workspaceID != PNODE2->workspaceID) { if (PNODE->workspaceID != PNODE2->workspaceID) {
std::swap(pWindow2->m_iMonitorID, pWindow->m_iMonitorID); std::swap(pWindow2->m_iMonitorID, pWindow->m_iMonitorID);
std::swap(pWindow2->m_iWorkspaceID, pWindow->m_iWorkspaceID); std::swap(pWindow2->m_iWorkspaceID, pWindow->m_iWorkspaceID);
@ -1034,8 +1031,6 @@ void CHyprMasterLayout::switchWindows(CWindow* pWindow, CWindow* pWindow2) {
g_pHyprRenderer->damageWindow(pWindow); g_pHyprRenderer->damageWindow(pWindow);
g_pHyprRenderer->damageWindow(pWindow2); g_pHyprRenderer->damageWindow(pWindow2);
prepareNewFocus(pWindow2, inheritFullscreen);
} }
void CHyprMasterLayout::alterSplitRatio(CWindow* pWindow, float ratio, bool exact) { void CHyprMasterLayout::alterSplitRatio(CWindow* pWindow, float ratio, bool exact) {
@ -1076,35 +1071,27 @@ CWindow* CHyprMasterLayout::getNextWindow(CWindow* pWindow, bool next) {
return CANDIDATE == nodes.end() ? nullptr : CANDIDATE->pWindow; return CANDIDATE == nodes.end() ? nullptr : CANDIDATE->pWindow;
} }
bool CHyprMasterLayout::prepareLoseFocus(CWindow* pWindow) {
if (!pWindow)
return false;
//if the current window is fullscreen, make it normal again if we are about to lose focus
if (pWindow->m_bIsFullscreen) {
g_pCompositor->setWindowFullscreen(pWindow, false, FULLSCREEN_FULL);
static auto INHERIT = CConfigValue<Hyprlang::INT>("master:inherit_fullscreen");
return *INHERIT == 1;
}
return false;
}
void CHyprMasterLayout::prepareNewFocus(CWindow* pWindow, bool inheritFullscreen) {
if (!pWindow)
return;
if (inheritFullscreen)
g_pCompositor->setWindowFullscreen(pWindow, true, g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID)->m_efFullscreenMode);
}
std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::string message) { std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::string message) {
auto switchToWindow = [&](CWindow* PWINDOWTOCHANGETO) { auto switchToWindow = [&](CWindow* PWINDOWTOCHANGETO) {
if (!g_pCompositor->windowValidMapped(PWINDOWTOCHANGETO)) if (!g_pCompositor->windowValidMapped(PWINDOWTOCHANGETO))
return; return;
g_pCompositor->focusWindow(PWINDOWTOCHANGETO); if (header.pWindow->m_bIsFullscreen) {
g_pCompositor->warpCursorTo(PWINDOWTOCHANGETO->middle()); const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(header.pWindow->m_iWorkspaceID);
const auto FSMODE = PWORKSPACE->m_efFullscreenMode;
static auto INHERITFULLSCREEN = CConfigValue<Hyprlang::INT>("master:inherit_fullscreen");
g_pCompositor->setWindowFullscreen(header.pWindow, false, FULLSCREEN_FULL);
g_pCompositor->focusWindow(PWINDOWTOCHANGETO);
if (*INHERITFULLSCREEN)
g_pCompositor->setWindowFullscreen(PWINDOWTOCHANGETO, true, FSMODE);
} else {
g_pCompositor->focusWindow(PWINDOWTOCHANGETO);
g_pCompositor->warpCursorTo(PWINDOWTOCHANGETO->middle());
}
g_pInputManager->m_pForcedFocus = PWINDOWTOCHANGETO;
g_pInputManager->simulateMouseMovement();
g_pInputManager->m_pForcedFocus = nullptr;
}; };
CVarList vars(message, 0, ' '); CVarList vars(message, 0, ' ');
@ -1138,23 +1125,19 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
const auto NEWCHILD = PMASTER->pWindow; const auto NEWCHILD = PMASTER->pWindow;
if (PMASTER->pWindow != PWINDOW) { if (PMASTER->pWindow != PWINDOW) {
const auto NEWMASTER = PWINDOW; const auto NEWMASTER = PWINDOW;
const bool newFocusToChild = vars.size() >= 2 && vars[1] == "child"; const bool newFocusToChild = vars.size() >= 2 && vars[1] == "child";
const bool inheritFullscreen = prepareLoseFocus(NEWMASTER);
switchWindows(NEWMASTER, NEWCHILD); switchWindows(NEWMASTER, NEWCHILD);
const auto NEWFOCUS = newFocusToChild ? NEWCHILD : NEWMASTER; const auto NEWFOCUS = newFocusToChild ? NEWCHILD : NEWMASTER;
switchToWindow(NEWFOCUS); switchToWindow(NEWFOCUS);
prepareNewFocus(NEWFOCUS, inheritFullscreen);
} else { } else {
for (auto& n : m_lMasterNodesData) { for (auto& n : m_lMasterNodesData) {
if (n.workspaceID == PMASTER->workspaceID && !n.isMaster) { if (n.workspaceID == PMASTER->workspaceID && !n.isMaster) {
const auto NEWMASTER = n.pWindow; const auto NEWMASTER = n.pWindow;
const bool inheritFullscreen = prepareLoseFocus(NEWCHILD);
switchWindows(NEWMASTER, NEWCHILD); switchWindows(NEWMASTER, NEWCHILD);
const bool newFocusToMaster = vars.size() >= 2 && vars[1] == "master"; const bool newFocusToMaster = vars.size() >= 2 && vars[1] == "master";
const auto NEWFOCUS = newFocusToMaster ? NEWMASTER : NEWCHILD; const auto NEWFOCUS = newFocusToMaster ? NEWMASTER : NEWCHILD;
switchToWindow(NEWFOCUS); switchToWindow(NEWFOCUS);
prepareNewFocus(NEWFOCUS, inheritFullscreen);
break; break;
} }
} }
@ -1172,8 +1155,6 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
if (!PWINDOW) if (!PWINDOW)
return 0; return 0;
const bool inheritFullscreen = prepareLoseFocus(PWINDOW);
const auto PMASTER = getMasterNodeOnWorkspace(PWINDOW->m_iWorkspaceID); const auto PMASTER = getMasterNodeOnWorkspace(PWINDOW->m_iWorkspaceID);
if (!PMASTER) if (!PMASTER)
@ -1181,7 +1162,6 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
if (PMASTER->pWindow != PWINDOW) { if (PMASTER->pWindow != PWINDOW) {
switchToWindow(PMASTER->pWindow); switchToWindow(PMASTER->pWindow);
prepareNewFocus(PMASTER->pWindow, inheritFullscreen);
} else if (vars.size() >= 2 && vars[1] == "master") { } else if (vars.size() >= 2 && vars[1] == "master") {
return 0; return 0;
} else { } else {
@ -1189,7 +1169,6 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
for (auto& n : m_lMasterNodesData) { for (auto& n : m_lMasterNodesData) {
if (n.workspaceID == PMASTER->workspaceID && !n.isMaster) { if (n.workspaceID == PMASTER->workspaceID && !n.isMaster) {
switchToWindow(n.pWindow); switchToWindow(n.pWindow);
prepareNewFocus(n.pWindow, inheritFullscreen);
break; break;
} }
} }
@ -1202,22 +1181,16 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
if (!PWINDOW) if (!PWINDOW)
return 0; return 0;
const bool inheritFullscreen = prepareLoseFocus(PWINDOW);
const auto PNEXTWINDOW = getNextWindow(PWINDOW, true); const auto PNEXTWINDOW = getNextWindow(PWINDOW, true);
switchToWindow(PNEXTWINDOW); switchToWindow(PNEXTWINDOW);
prepareNewFocus(PNEXTWINDOW, inheritFullscreen);
} else if (command == "cycleprev") { } else if (command == "cycleprev") {
const auto PWINDOW = header.pWindow; const auto PWINDOW = header.pWindow;
if (!PWINDOW) if (!PWINDOW)
return 0; return 0;
const bool inheritFullscreen = prepareLoseFocus(PWINDOW);
const auto PPREVWINDOW = getNextWindow(PWINDOW, false); const auto PPREVWINDOW = getNextWindow(PWINDOW, false);
switchToWindow(PPREVWINDOW); switchToWindow(PPREVWINDOW);
prepareNewFocus(PPREVWINDOW, inheritFullscreen);
} else if (command == "swapnext") { } else if (command == "swapnext") {
if (!g_pCompositor->windowValidMapped(header.pWindow)) if (!g_pCompositor->windowValidMapped(header.pWindow))
return 0; return 0;
@ -1230,9 +1203,9 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
const auto PWINDOWTOSWAPWITH = getNextWindow(header.pWindow, true); const auto PWINDOWTOSWAPWITH = getNextWindow(header.pWindow, true);
if (PWINDOWTOSWAPWITH) { if (PWINDOWTOSWAPWITH) {
prepareLoseFocus(header.pWindow); g_pCompositor->setWindowFullscreen(header.pWindow, false, FULLSCREEN_FULL);
switchWindows(header.pWindow, PWINDOWTOSWAPWITH); switchWindows(header.pWindow, PWINDOWTOSWAPWITH);
g_pCompositor->focusWindow(header.pWindow); switchToWindow(header.pWindow);
} }
} else if (command == "swapprev") { } else if (command == "swapprev") {
if (!g_pCompositor->windowValidMapped(header.pWindow)) if (!g_pCompositor->windowValidMapped(header.pWindow))
@ -1246,9 +1219,9 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
const auto PWINDOWTOSWAPWITH = getNextWindow(header.pWindow, false); const auto PWINDOWTOSWAPWITH = getNextWindow(header.pWindow, false);
if (PWINDOWTOSWAPWITH) { if (PWINDOWTOSWAPWITH) {
prepareLoseFocus(header.pWindow); g_pCompositor->setWindowFullscreen(header.pWindow, false, FULLSCREEN_FULL);
switchWindows(header.pWindow, PWINDOWTOSWAPWITH); switchWindows(header.pWindow, PWINDOWTOSWAPWITH);
g_pCompositor->focusWindow(header.pWindow); switchToWindow(header.pWindow);
} }
} else if (command == "addmaster") { } else if (command == "addmaster") {
if (!g_pCompositor->windowValidMapped(header.pWindow)) if (!g_pCompositor->windowValidMapped(header.pWindow))
@ -1265,7 +1238,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
if (MASTERS + 2 > WINDOWS && *SMALLSPLIT == 0) if (MASTERS + 2 > WINDOWS && *SMALLSPLIT == 0)
return 0; return 0;
prepareLoseFocus(header.pWindow); g_pCompositor->setWindowFullscreen(header.pWindow, false, FULLSCREEN_FULL);
if (!PNODE || PNODE->isMaster) { if (!PNODE || PNODE->isMaster) {
// first non-master node // first non-master node
@ -1297,7 +1270,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
if (WINDOWS < 2 || MASTERS < 2) if (WINDOWS < 2 || MASTERS < 2)
return 0; return 0;
prepareLoseFocus(header.pWindow); g_pCompositor->setWindowFullscreen(header.pWindow, false, FULLSCREEN_FULL);
if (!PNODE || !PNODE->isMaster) { if (!PNODE || !PNODE->isMaster) {
// first non-master node // first non-master node
@ -1318,7 +1291,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
if (!PWINDOW) if (!PWINDOW)
return 0; return 0;
prepareLoseFocus(PWINDOW); g_pCompositor->setWindowFullscreen(PWINDOW, false, FULLSCREEN_FULL);
const auto PWORKSPACEDATA = getMasterWorkspaceData(PWINDOW->m_iWorkspaceID); const auto PWORKSPACEDATA = getMasterWorkspaceData(PWINDOW->m_iWorkspaceID);
@ -1373,9 +1346,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
nd.isMaster = true; nd.isMaster = true;
const auto NEWMASTERIT = std::find(m_lMasterNodesData.begin(), m_lMasterNodesData.end(), nd); const auto NEWMASTERIT = std::find(m_lMasterNodesData.begin(), m_lMasterNodesData.end(), nd);
m_lMasterNodesData.splice(OLDMASTERIT, m_lMasterNodesData, NEWMASTERIT); m_lMasterNodesData.splice(OLDMASTERIT, m_lMasterNodesData, NEWMASTERIT);
const bool inheritFullscreen = prepareLoseFocus(PWINDOW);
switchToWindow(nd.pWindow); switchToWindow(nd.pWindow);
prepareNewFocus(nd.pWindow, inheritFullscreen);
OLDMASTER->isMaster = false; OLDMASTER->isMaster = false;
m_lMasterNodesData.splice(m_lMasterNodesData.end(), m_lMasterNodesData, OLDMASTERIT); m_lMasterNodesData.splice(m_lMasterNodesData.end(), m_lMasterNodesData, OLDMASTERIT);
break; break;
@ -1401,9 +1372,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
nd.isMaster = true; nd.isMaster = true;
const auto NEWMASTERIT = std::find(m_lMasterNodesData.begin(), m_lMasterNodesData.end(), nd); const auto NEWMASTERIT = std::find(m_lMasterNodesData.begin(), m_lMasterNodesData.end(), nd);
m_lMasterNodesData.splice(OLDMASTERIT, m_lMasterNodesData, NEWMASTERIT); m_lMasterNodesData.splice(OLDMASTERIT, m_lMasterNodesData, NEWMASTERIT);
const bool inheritFullscreen = prepareLoseFocus(PWINDOW);
switchToWindow(nd.pWindow); switchToWindow(nd.pWindow);
prepareNewFocus(nd.pWindow, inheritFullscreen);
OLDMASTER->isMaster = false; OLDMASTER->isMaster = false;
m_lMasterNodesData.splice(m_lMasterNodesData.begin(), m_lMasterNodesData, OLDMASTERIT); m_lMasterNodesData.splice(m_lMasterNodesData.begin(), m_lMasterNodesData, OLDMASTERIT);
break; break;
@ -1430,7 +1399,7 @@ void CHyprMasterLayout::runOrientationCycle(SLayoutMessageHeader& header, CVarLi
if (!PWINDOW) if (!PWINDOW)
return; return;
prepareLoseFocus(PWINDOW); g_pCompositor->setWindowFullscreen(PWINDOW, false, FULLSCREEN_FULL);
const auto PWORKSPACEDATA = getMasterWorkspaceData(PWINDOW->m_iWorkspaceID); const auto PWORKSPACEDATA = getMasterWorkspaceData(PWINDOW->m_iWorkspaceID);

View file

@ -87,8 +87,6 @@ class CHyprMasterLayout : public IHyprLayout {
void calculateWorkspace(const int&); void calculateWorkspace(const int&);
CWindow* getNextWindow(CWindow*, bool); CWindow* getNextWindow(CWindow*, bool);
int getMastersOnWorkspace(const int&); int getMastersOnWorkspace(const int&);
bool prepareLoseFocus(CWindow*);
void prepareNewFocus(CWindow*, bool inherit_fullscreen);
friend struct SMasterNodeData; friend struct SMasterNodeData;
friend struct SMasterWorkspaceData; friend struct SMasterWorkspaceData;

View file

@ -227,7 +227,6 @@ bool CKeybindManager::tryMoveFocusToMonitor(CMonitor* monitor) {
const auto PNEWMAINWORKSPACE = g_pCompositor->getWorkspaceByID(monitor->activeWorkspace); const auto PNEWMAINWORKSPACE = g_pCompositor->getWorkspaceByID(monitor->activeWorkspace);
g_pInputManager->unconstrainMouse(); g_pInputManager->unconstrainMouse();
g_pCompositor->setActiveMonitor(monitor);
PNEWMAINWORKSPACE->rememberPrevWorkspace(PWORKSPACE); PNEWMAINWORKSPACE->rememberPrevWorkspace(PWORKSPACE);
const auto PNEWWORKSPACE = monitor->specialWorkspaceID != 0 ? g_pCompositor->getWorkspaceByID(monitor->specialWorkspaceID) : PNEWMAINWORKSPACE; const auto PNEWWORKSPACE = monitor->specialWorkspaceID != 0 ? g_pCompositor->getWorkspaceByID(monitor->specialWorkspaceID) : PNEWMAINWORKSPACE;
@ -236,10 +235,15 @@ bool CKeybindManager::tryMoveFocusToMonitor(CMonitor* monitor) {
if (PNEWWINDOW) { if (PNEWWINDOW) {
g_pCompositor->focusWindow(PNEWWINDOW); g_pCompositor->focusWindow(PNEWWINDOW);
g_pCompositor->warpCursorTo(PNEWWINDOW->middle()); g_pCompositor->warpCursorTo(PNEWWINDOW->middle());
g_pInputManager->m_pForcedFocus = PNEWWINDOW;
g_pInputManager->simulateMouseMovement();
g_pInputManager->m_pForcedFocus = nullptr;
} else { } else {
g_pCompositor->focusWindow(nullptr); g_pCompositor->focusWindow(nullptr);
g_pCompositor->warpCursorTo(monitor->middle()); g_pCompositor->warpCursorTo(monitor->middle());
} }
g_pCompositor->setActiveMonitor(monitor);
return true; return true;
} }