Reload on RandR update.

This commit is contained in:
vaxerski 2021-12-22 14:53:53 +01:00
parent 582afac75e
commit 05670e34f7
5 changed files with 132 additions and 35 deletions

View file

@ -149,9 +149,17 @@ CWindow* Events::remapFloatingWindow(int windowID, int forcemonitor) {
PWINDOWINARR->setIsFloating(true); PWINDOWINARR->setIsFloating(true);
PWINDOWINARR->setDirty(true); PWINDOWINARR->setDirty(true);
if (!g_pWindowManager->getMonitorFromCursor()) {
Debug::log(ERR, "Monitor was null! (remapWindow)"); auto PMONITOR = g_pWindowManager->getMonitorFromCursor();
// rip! we cannot continue. if (!PMONITOR) {
Debug::log(ERR, "Monitor was null! (remapWindow) Using 0.");
PMONITOR = &g_pWindowManager->monitors[0];
if (g_pWindowManager->monitors.size() == 0) {
Debug::log(ERR, "Not continuing. Monitors size 0.");
return nullptr;
}
} }
// Check the monitor rule // Check the monitor rule
@ -175,7 +183,7 @@ CWindow* Events::remapFloatingWindow(int windowID, int forcemonitor) {
} }
} }
const auto CURRENTSCREEN = forcemonitor != -1 ? forcemonitor : g_pWindowManager->getMonitorFromCursor()->ID; const auto CURRENTSCREEN = forcemonitor != -1 ? forcemonitor : PMONITOR->ID;
PWINDOWINARR->setWorkspaceID(g_pWindowManager->activeWorkspaces[CURRENTSCREEN]); PWINDOWINARR->setWorkspaceID(g_pWindowManager->activeWorkspaces[CURRENTSCREEN]);
PWINDOWINARR->setMonitor(CURRENTSCREEN); PWINDOWINARR->setMonitor(CURRENTSCREEN);
@ -384,9 +392,16 @@ CWindow* Events::remapWindow(int windowID, bool wasfloating, int forcemonitor) {
PWINDOWINARR->setIsFloating(false); PWINDOWINARR->setIsFloating(false);
PWINDOWINARR->setDirty(true); PWINDOWINARR->setDirty(true);
if (!g_pWindowManager->getMonitorFromCursor()) {
Debug::log(ERR, "Monitor was null! (remapWindow)"); auto PMONITOR = g_pWindowManager->getMonitorFromCursor();
// rip! we cannot continue. if (!PMONITOR) {
Debug::log(ERR, "Monitor was null! (remapWindow) Using 0.");
PMONITOR = &g_pWindowManager->monitors[0];
if (g_pWindowManager->monitors.size() == 0) {
Debug::log(ERR, "Not continuing. Monitors size 0.");
return nullptr;
}
} }
// Check the monitor rule // Check the monitor rule
@ -410,7 +425,7 @@ CWindow* Events::remapWindow(int windowID, bool wasfloating, int forcemonitor) {
} }
} }
const auto CURRENTSCREEN = forcemonitor != -1 ? forcemonitor : g_pWindowManager->getMonitorFromCursor()->ID; const auto CURRENTSCREEN = forcemonitor != -1 ? forcemonitor : PMONITOR->ID;
PWINDOWINARR->setWorkspaceID(g_pWindowManager->activeWorkspaces[CURRENTSCREEN]); PWINDOWINARR->setWorkspaceID(g_pWindowManager->activeWorkspaces[CURRENTSCREEN]);
PWINDOWINARR->setMonitor(CURRENTSCREEN); PWINDOWINARR->setMonitor(CURRENTSCREEN);
@ -439,12 +454,12 @@ CWindow* Events::remapWindow(int windowID, bool wasfloating, int forcemonitor) {
// Set the parent // Set the parent
// check if lastwindow is on our workspace // check if lastwindow is on our workspace
if (auto PLASTWINDOW = g_pWindowManager->getWindowFromDrawable(g_pWindowManager->LastWindow); (PLASTWINDOW && PLASTWINDOW->getWorkspaceID() == g_pWindowManager->activeWorkspaces[CURRENTSCREEN]) || wasfloating || (forcemonitor != -1 && forcemonitor != g_pWindowManager->getMonitorFromCursor()->ID)) { if (auto PLASTWINDOW = g_pWindowManager->getWindowFromDrawable(g_pWindowManager->LastWindow); (PLASTWINDOW && PLASTWINDOW->getWorkspaceID() == g_pWindowManager->activeWorkspaces[CURRENTSCREEN]) || wasfloating || (forcemonitor != -1 && forcemonitor != PMONITOR->ID)) {
// LastWindow is on our workspace, let's make a new split node // LastWindow is on our workspace, let's make a new split node
if (wasfloating || (forcemonitor != -1 && forcemonitor != g_pWindowManager->getMonitorFromCursor()->ID) || PLASTWINDOW->getIsFloating()) { if (wasfloating || (forcemonitor != -1 && forcemonitor != PMONITOR->ID) || PLASTWINDOW->getIsFloating()) {
// if it's force monitor, find the first on a workspace. // if it's force monitor, find the first on a workspace.
if (forcemonitor != -1 && forcemonitor != g_pWindowManager->getMonitorFromCursor()->ID) { if (forcemonitor != -1 && forcemonitor != PMONITOR->ID) {
PLASTWINDOW = g_pWindowManager->findFirstWindowOnWorkspace(g_pWindowManager->activeWorkspaces[CURRENTSCREEN]); PLASTWINDOW = g_pWindowManager->findFirstWindowOnWorkspace(g_pWindowManager->activeWorkspaces[CURRENTSCREEN]);
} else { } else {
// find a window manually by the cursor // find a window manually by the cursor
@ -675,7 +690,7 @@ void Events::eventMotionNotify(xcb_generic_event_t* event) {
const auto WORKSPACE = g_pWindowManager->activeWorkspaces[g_pWindowManager->getMonitorFromCursor()->ID]; const auto WORKSPACE = g_pWindowManager->activeWorkspaces[g_pWindowManager->getMonitorFromCursor()->ID];
PACTINGWINDOW->setWorkspaceID(WORKSPACE); PACTINGWINDOW->setWorkspaceID(WORKSPACE);
} else { } else {
PACTINGWINDOW->setWorkspaceID(-1); Debug::log(WARN, "Monitor was nullptr! Ignoring workspace change in MouseMoveEvent.");
} }
PACTINGWINDOW->setDirty(true); PACTINGWINDOW->setDirty(true);
@ -787,3 +802,44 @@ void Events::eventClientMessage(xcb_generic_event_t* event) {
} }
} }
} }
void Events::eventRandRScreenChange(xcb_generic_event_t* event) {
// redetect screens
g_pWindowManager->monitors.clear();
g_pWindowManager->setupRandrMonitors();
// Detect monitors that are incorrect
// Orphaned workspaces
for (auto& w : g_pWindowManager->workspaces) {
if (w.getMonitor() >= g_pWindowManager->monitors.size())
w.setMonitor(0);
}
// Empty monitors
bool fineMonitors[g_pWindowManager->monitors.size()];
for (int i = 0; i < g_pWindowManager->monitors.size(); ++i)
fineMonitors[i] = false;
for (auto& w : g_pWindowManager->workspaces) {
fineMonitors[w.getMonitor()] = true;
}
for (int i = 0; i < g_pWindowManager->monitors.size(); ++i) {
if (!fineMonitors[i]) {
// add a workspace
CWorkspace newWorkspace;
newWorkspace.setMonitor(i);
newWorkspace.setID(g_pWindowManager->getHighestWorkspaceID() + 1);
newWorkspace.setHasFullscreenWindow(false);
newWorkspace.setLastWindow(0);
g_pWindowManager->workspaces.push_back(newWorkspace);
}
}
// reload the config to update the bar too
ConfigManager::loadConfigLoadVars();
// Make all windows dirty and recalc all workspaces
g_pWindowManager->recalcAllWorkspaces();
}

View file

@ -17,6 +17,8 @@ namespace Events {
EVENT(MotionNotify); EVENT(MotionNotify);
EVENT(ClientMessage); EVENT(ClientMessage);
EVENT(RandRScreenChange);
// Bypass some events for floating windows // Bypass some events for floating windows
CWindow* remapWindow(int, bool floating = false, int forcemonitor = -1); CWindow* remapWindow(int, bool floating = false, int forcemonitor = -1);
CWindow* remapFloatingWindow(int, int forcemonitor = -1); CWindow* remapFloatingWindow(int, int forcemonitor = -1);

View file

@ -76,12 +76,18 @@ void EWMH::setFrameExtents(xcb_window_t w) {
void EWMH::updateDesktops() { void EWMH::updateDesktops() {
int ACTIVEWORKSPACE = -1;
if (!g_pWindowManager->getMonitorFromCursor()) { if (!g_pWindowManager->getMonitorFromCursor()) {
Debug::log(ERR, "Monitor was null! (updateDesktops EWMH)"); Debug::log(ERR, "Monitor was null! (updateDesktops EWMH) Using LastWindow");
return; if (const auto PWINDOW = g_pWindowManager->getWindowFromDrawable(g_pWindowManager->LastWindow); PWINDOW)
ACTIVEWORKSPACE = g_pWindowManager->activeWorkspaces[PWINDOW->getWorkspaceID()];
else
ACTIVEWORKSPACE = 0;
} else {
ACTIVEWORKSPACE = g_pWindowManager->activeWorkspaces[g_pWindowManager->getMonitorFromCursor()->ID];
} }
const auto ACTIVEWORKSPACE = g_pWindowManager->activeWorkspaces[g_pWindowManager->getMonitorFromCursor()->ID];
if (DesktopInfo::lastid != ACTIVEWORKSPACE) { if (DesktopInfo::lastid != ACTIVEWORKSPACE) {
// Update the current workspace // Update the current workspace
DesktopInfo::lastid = ACTIVEWORKSPACE; DesktopInfo::lastid = ACTIVEWORKSPACE;

View file

@ -129,16 +129,25 @@ void CWindowManager::setupRandrMonitors() {
else { else {
//listen for screen change events //listen for screen change events
xcb_randr_select_input(DisplayConnection, Screen->root, XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE); xcb_randr_select_input(DisplayConnection, Screen->root, XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE);
RandREventBase = EXTENSIONREPLY->first_event;
} }
xcb_flush(DisplayConnection); xcb_flush(DisplayConnection);
}
void CWindowManager::setupManager() {
setupColormapAndStuff();
EWMH::setupInitEWMH();
// ---- RANDR ----- //
setupRandrMonitors();
if (monitors.size() == 0) { if (monitors.size() == 0) {
// RandR failed! // RandR failed!
Debug::log(WARN, "RandR failed!"); Debug::log(WARN, "RandR failed!");
monitors.clear(); monitors.clear();
#define TESTING_MON_AMOUNT 3 #define TESTING_MON_AMOUNT 3
for (int i = 0; i < TESTING_MON_AMOUNT /* Testing on 3 monitors, RandR shouldnt fail on a real desktop */; ++i) { for (int i = 0; i < TESTING_MON_AMOUNT /* Testing on 3 monitors, RandR shouldnt fail on a real desktop */; ++i) {
monitors.push_back(SMonitor()); monitors.push_back(SMonitor());
monitors[i].vecPosition = Vector2D(i * Screen->width_in_pixels / TESTING_MON_AMOUNT, 0); monitors[i].vecPosition = Vector2D(i * Screen->width_in_pixels / TESTING_MON_AMOUNT, 0);
@ -147,15 +156,12 @@ void CWindowManager::setupRandrMonitors() {
monitors[i].szName = "Screen" + std::to_string(i); monitors[i].szName = "Screen" + std::to_string(i);
} }
} }
}
void CWindowManager::setupManager() {
setupColormapAndStuff();
EWMH::setupInitEWMH();
setupRandrMonitors();
Debug::log(LOG, "RandR done."); Debug::log(LOG, "RandR done.");
//
//
Values[0] = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE; Values[0] = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE;
xcb_change_window_attributes_checked(DisplayConnection, Screen->root, xcb_change_window_attributes_checked(DisplayConnection, Screen->root,
XCB_CW_EVENT_MASK, Values); XCB_CW_EVENT_MASK, Values);
@ -244,6 +250,7 @@ void CWindowManager::recieveEvent() {
if (!g_pWindowManager->statusBar) if (!g_pWindowManager->statusBar)
IPCRecieveMessageM(m_sIPCBarPipeOut.szPipeName); IPCRecieveMessageM(m_sIPCBarPipeOut.szPipeName);
const uint8_t TYPE = XCB_EVENT_RESPONSE_TYPE(ev);
const auto EVENTCODE = ev->response_type & ~0x80; const auto EVENTCODE = ev->response_type & ~0x80;
switch (EVENTCODE) { switch (EVENTCODE) {
@ -299,6 +306,11 @@ void CWindowManager::recieveEvent() {
break; break;
} }
if (TYPE - RandREventBase == XCB_RANDR_SCREEN_CHANGE_NOTIFY) {
Events::eventRandRScreenChange(ev);
Debug::log(LOG, "Event dispatched RANDR_SCREEN_CHANGE");
}
free(ev); free(ev);
} }
} }
@ -777,11 +789,16 @@ void CWindowManager::calculateNewTileSetOldTile(CWindow* pWindow) {
// Get the parent and both children, one of which will be pWindow // Get the parent and both children, one of which will be pWindow
const auto PPARENT = getWindowFromDrawable(pWindow->getParentNodeID()); const auto PPARENT = getWindowFromDrawable(pWindow->getParentNodeID());
const auto PMONITOR = getMonitorFromWindow(pWindow); auto PMONITOR = getMonitorFromWindow(pWindow);
if (!PMONITOR) { if (!PMONITOR) {
Debug::log(ERR, "Monitor was nullptr! (calculateNewTileSetOldTile)"); Debug::log(ERR, "Monitor was nullptr! (calculateNewTileSetOldTile) using 0.");
PMONITOR = &monitors[0];
if (monitors.size() == 0) {
Debug::log(ERR, "Not continuing. Monitors size 0.");
return; return;
} }
}
if (!PPARENT) { if (!PPARENT) {
// New window on this workspace. // New window on this workspace.
@ -929,9 +946,18 @@ void CWindowManager::recalcEntireWorkspace(const int& workspace) {
} }
} }
if (!pMasterWindow) { if (!pMasterWindow)
return; return;
}
const auto PMONITOR = getMonitorFromWorkspace(workspace);
if (!PMONITOR)
return;
Debug::log(LOG, "Recalc for workspace " + std::to_string(workspace));
pMasterWindow->setSize(PMONITOR->vecSize);
pMasterWindow->setPosition(PMONITOR->vecPosition);
pMasterWindow->recalcSizePosRecursive(); pMasterWindow->recalcSizePosRecursive();
setAllWorkspaceWindowsDirtyByID(workspace); setAllWorkspaceWindowsDirtyByID(workspace);
@ -1355,11 +1381,11 @@ void CWindowManager::moveActiveFocusTo(char dir) {
void CWindowManager::changeWorkspaceByID(int ID) { void CWindowManager::changeWorkspaceByID(int ID) {
const auto MONITOR = getMonitorFromCursor(); auto MONITOR = getMonitorFromCursor();
if (!MONITOR) { if (!MONITOR) {
Debug::log(ERR, "Monitor was nullptr! (changeWorkspaceByID)"); Debug::log(ERR, "Monitor was nullptr! (changeWorkspaceByID) Using monitor 0.");
return; MONITOR = &monitors[0];
} }
// mark old workspace dirty // mark old workspace dirty
@ -1513,12 +1539,18 @@ void CWindowManager::updateBarInfo() {
SIPCMessageMainToBar message; SIPCMessageMainToBar message;
if (!getMonitorFromCursor()) { auto PMONITOR = getMonitorFromCursor();
Debug::log(ERR, "Monitor was null! (updateBarInfo)"); if (!PMONITOR) {
Debug::log(ERR, "Monitor was null! (updateBarInfo) Using 0.");
PMONITOR = &monitors[0];
if (monitors.size() == 0) {
Debug::log(ERR, "Not continuing. Monitors size 0.");
return; return;
} }
}
message.activeWorkspace = activeWorkspaces[getMonitorFromCursor()->ID]; message.activeWorkspace = activeWorkspaces[PMONITOR->ID];
auto winname = getWindowFromDrawable(LastWindow) ? getWindowFromDrawable(LastWindow)->getName() : ""; auto winname = getWindowFromDrawable(LastWindow) ? getWindowFromDrawable(LastWindow)->getName() : "";
auto winclassname = getWindowFromDrawable(LastWindow) ? getWindowFromDrawable(LastWindow)->getClassName() : ""; auto winclassname = getWindowFromDrawable(LastWindow) ? getWindowFromDrawable(LastWindow)->getClassName() : "";

View file

@ -26,6 +26,7 @@ public:
xcb_ewmh_connection_t* EWMHConnection = nullptr; // Bar uses this xcb_ewmh_connection_t* EWMHConnection = nullptr; // Bar uses this
xcb_screen_t* Screen = nullptr; xcb_screen_t* Screen = nullptr;
xcb_drawable_t Drawable; xcb_drawable_t Drawable;
int RandREventBase = -1;
uint32_t Values[3]; uint32_t Values[3];
std::vector<SMonitor> monitors; std::vector<SMonitor> monitors;