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()) { if (w->m_bIsX11 && w->isX11OverrideRedirect() && !w->m_pXWaylandSurface->wantsFocus()) {
// Override Redirect // Override Redirect
return g_pCompositor->m_pLastWindow.lock(); // we kinda trick everything here. 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; return w;

View File

@@ -25,53 +25,54 @@ class CCompositor {
CCompositor(bool onlyConfig = false); CCompositor(bool onlyConfig = false);
~CCompositor(); ~CCompositor();
wl_display* m_sWLDisplay = nullptr; wl_display* m_sWLDisplay = nullptr;
wl_event_loop* m_sWLEventLoop = nullptr; wl_event_loop* m_sWLEventLoop = nullptr;
int m_iDRMFD = -1; int m_iDRMFD = -1;
bool m_bInitialized = false; bool m_bInitialized = false;
SP<Aquamarine::CBackend> m_pAqBackend; SP<Aquamarine::CBackend> m_pAqBackend;
std::string m_szHyprTempDataRoot = ""; std::string m_szHyprTempDataRoot = "";
std::string m_szWLDisplaySocket = ""; std::string m_szWLDisplaySocket = "";
std::string m_szInstanceSignature = ""; std::string m_szInstanceSignature = "";
std::string m_szInstancePath = ""; std::string m_szInstancePath = "";
std::string m_szCurrentSplash = "error"; std::string m_szCurrentSplash = "error";
std::vector<PHLMONITOR> m_vMonitors; std::vector<PHLMONITOR> m_vMonitors;
std::vector<PHLMONITOR> m_vRealMonitors; // for all monitors, even those turned off std::vector<PHLMONITOR> m_vRealMonitors; // for all monitors, even those turned off
std::vector<PHLWINDOW> m_vWindows; std::vector<PHLWINDOW> m_vWindows;
std::vector<PHLLS> m_vLayers; std::vector<PHLLS> m_vLayers;
std::vector<PHLWORKSPACE> m_vWorkspaces; std::vector<PHLWORKSPACE> m_vWorkspaces;
std::vector<PHLWINDOWREF> m_vWindowsFadingOut; std::vector<PHLWINDOWREF> m_vWindowsFadingOut;
std::vector<PHLLSREF> m_vSurfacesFadingOut; 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 initServer(std::string socketName, int socketFd);
void startCompositor(); void startCompositor();
void stopCompositor(); void stopCompositor();
void cleanup(); void cleanup();
void bumpNofile(); void bumpNofile();
void restoreNofile(); void restoreNofile();
WP<CWLSurfaceResource> m_pLastFocus; WP<CWLSurfaceResource> m_pLastFocus;
PHLWINDOWREF m_pLastWindow; PHLWINDOWREF m_pLastWindow;
PHLMONITORREF m_pLastMonitor; 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_bReadyToProcess = false;
bool m_bSessionActive = true; bool m_bSessionActive = true;
bool m_bDPMSStateON = true; bool m_bDPMSStateON = true;
bool m_bUnsafeState = false; // unsafe state is when there is no monitors. bool m_bUnsafeState = false; // unsafe state is when there is no monitors.
bool m_bNextIsUnsafe = false; bool m_bNextIsUnsafe = false;
PHLMONITORREF m_pUnsafeOutput; // fallback output for the unsafe state PHLMONITORREF m_pUnsafeOutput; // fallback output for the unsafe state
bool m_bIsShuttingDown = false; bool m_bIsShuttingDown = false;
bool m_bFinalRequests = false; bool m_bFinalRequests = false;
bool m_bDesktopEnvSet = false; bool m_bDesktopEnvSet = false;
bool m_bWantsXwayland = true; bool m_bWantsXwayland = true;
bool m_bOnlyConfigVerification = false; 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) if (!found)
g_pCompositor->setActiveMonitor(self.lock()); g_pCompositor->setActiveMonitor(self.lock());
@@ -273,6 +286,12 @@ void CMonitor::onDisconnect(bool destroy) {
events.disconnect.emit(); 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. // Cleanup everything. Move windows back, snap cursor, shit.
PHLMONITOR BACKUPMON = nullptr; PHLMONITOR BACKUPMON = nullptr;
for (auto const& m : g_pCompositor->m_vMonitors) { for (auto const& m : g_pCompositor->m_vMonitors) {