monitors: fix disconnected monitors are reconnected to an empty workspace (#9874)

---------

Co-authored-by: nyx <nnyyxxxx@protonmail.com>
This commit is contained in:
Nathan Ollerenshaw
2025-04-14 02:07:53 -07:00
committed by GitHub
parent 99ab3e19d9
commit 533bc5115e
3 changed files with 60 additions and 40 deletions

View File

@@ -923,7 +923,7 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper
if (w->m_bIsX11 && w->isX11OverrideRedirect() && !w->m_pXWaylandSurface->wantsFocus()) {
// Override Redirect
return g_pCompositor->m_pLastWindow.lock(); // we kinda trick everything here.
// TODO: this is wrong, we should focus the parent, but idk how to get it considering it's nullptr in most cases.
// TODO: this is wrong, we should focus the parent, but idk how to get it considering it's nullptr in most cases.
}
return w;

View File

@@ -25,53 +25,54 @@ class CCompositor {
CCompositor(bool onlyConfig = false);
~CCompositor();
wl_display* m_sWLDisplay = nullptr;
wl_event_loop* m_sWLEventLoop = nullptr;
int m_iDRMFD = -1;
bool m_bInitialized = false;
SP<Aquamarine::CBackend> m_pAqBackend;
wl_display* m_sWLDisplay = nullptr;
wl_event_loop* m_sWLEventLoop = nullptr;
int m_iDRMFD = -1;
bool m_bInitialized = false;
SP<Aquamarine::CBackend> m_pAqBackend;
std::string m_szHyprTempDataRoot = "";
std::string m_szHyprTempDataRoot = "";
std::string m_szWLDisplaySocket = "";
std::string m_szInstanceSignature = "";
std::string m_szInstancePath = "";
std::string m_szCurrentSplash = "error";
std::string m_szWLDisplaySocket = "";
std::string m_szInstanceSignature = "";
std::string m_szInstancePath = "";
std::string m_szCurrentSplash = "error";
std::vector<PHLMONITOR> m_vMonitors;
std::vector<PHLMONITOR> m_vRealMonitors; // for all monitors, even those turned off
std::vector<PHLWINDOW> m_vWindows;
std::vector<PHLLS> m_vLayers;
std::vector<PHLWORKSPACE> m_vWorkspaces;
std::vector<PHLWINDOWREF> m_vWindowsFadingOut;
std::vector<PHLLSREF> m_vSurfacesFadingOut;
std::vector<PHLMONITOR> m_vMonitors;
std::vector<PHLMONITOR> m_vRealMonitors; // for all monitors, even those turned off
std::vector<PHLWINDOW> m_vWindows;
std::vector<PHLLS> m_vLayers;
std::vector<PHLWORKSPACE> m_vWorkspaces;
std::vector<PHLWINDOWREF> m_vWindowsFadingOut;
std::vector<PHLLSREF> m_vSurfacesFadingOut;
std::unordered_map<std::string, MONITORID> m_mMonitorIDMap;
std::unordered_map<std::string, MONITORID> m_mMonitorIDMap;
std::unordered_map<std::string, WORKSPACEID> m_mSeenMonitorWorkspaceMap; // map of seen monitor names to workspace IDs
void initServer(std::string socketName, int socketFd);
void startCompositor();
void stopCompositor();
void cleanup();
void bumpNofile();
void restoreNofile();
void initServer(std::string socketName, int socketFd);
void startCompositor();
void stopCompositor();
void cleanup();
void bumpNofile();
void restoreNofile();
WP<CWLSurfaceResource> m_pLastFocus;
PHLWINDOWREF m_pLastWindow;
PHLMONITORREF m_pLastMonitor;
WP<CWLSurfaceResource> m_pLastFocus;
PHLWINDOWREF m_pLastWindow;
PHLMONITORREF m_pLastMonitor;
std::vector<PHLWINDOWREF> m_vWindowFocusHistory; // first element is the most recently focused.
std::vector<PHLWINDOWREF> m_vWindowFocusHistory; // first element is the most recently focused.
bool m_bReadyToProcess = false;
bool m_bSessionActive = true;
bool m_bDPMSStateON = true;
bool m_bUnsafeState = false; // unsafe state is when there is no monitors.
bool m_bNextIsUnsafe = false;
PHLMONITORREF m_pUnsafeOutput; // fallback output for the unsafe state
bool m_bIsShuttingDown = false;
bool m_bFinalRequests = false;
bool m_bDesktopEnvSet = false;
bool m_bWantsXwayland = true;
bool m_bOnlyConfigVerification = false;
bool m_bReadyToProcess = false;
bool m_bSessionActive = true;
bool m_bDPMSStateON = true;
bool m_bUnsafeState = false; // unsafe state is when there is no monitors.
bool m_bNextIsUnsafe = false;
PHLMONITORREF m_pUnsafeOutput; // fallback output for the unsafe state
bool m_bIsShuttingDown = false;
bool m_bFinalRequests = false;
bool m_bDesktopEnvSet = false;
bool m_bWantsXwayland = true;
bool m_bOnlyConfigVerification = false;
// ------------------------------------------------- //

View File

@@ -235,6 +235,19 @@ void CMonitor::onConnect(bool noRule) {
}
}
Debug::log(LOG, "checking if we have seen this monitor before: {}", szName);
// if we saw this monitor before, set it to the workspace it was on
if (g_pCompositor->m_mSeenMonitorWorkspaceMap.contains(szName)) {
auto workspaceID = g_pCompositor->m_mSeenMonitorWorkspaceMap[szName];
Debug::log(LOG, "Monitor {} was on workspace {}, setting it to that", szName, workspaceID);
auto ws = g_pCompositor->getWorkspaceByID(workspaceID);
if (ws) {
g_pCompositor->moveWorkspaceToMonitor(ws, self.lock());
changeWorkspace(ws, true, false, false);
}
} else
Debug::log(LOG, "Monitor {} was not on any workspace", szName);
if (!found)
g_pCompositor->setActiveMonitor(self.lock());
@@ -273,6 +286,12 @@ void CMonitor::onDisconnect(bool destroy) {
events.disconnect.emit();
// record what workspace this monitor was on
if (activeWorkspace) {
Debug::log(LOG, "Disconnecting Monitor {} was on workspace {}", szName, activeWorkspace->m_iID);
g_pCompositor->m_mSeenMonitorWorkspaceMap[szName] = activeWorkspace->m_iID;
}
// Cleanup everything. Move windows back, snap cursor, shit.
PHLMONITOR BACKUPMON = nullptr;
for (auto const& m : g_pCompositor->m_vMonitors) {