major changes and added more window rule keys

added move monitor and size to window rules
changed how shit works with rules
This commit is contained in:
vaxerski 2021-12-21 18:30:35 +01:00
parent 30a6f6d2d2
commit ef2549f530
11 changed files with 274 additions and 125 deletions

View file

@ -172,6 +172,12 @@ void KeybindManager::toggleActiveWindowFloating(std::string unusedArg) {
const auto RESTORECANKILL = PWINDOW->getCanKill(); const auto RESTORECANKILL = PWINDOW->getCanKill();
g_pWindowManager->removeWindowFromVectorSafe(PWINDOW->getDrawable()); g_pWindowManager->removeWindowFromVectorSafe(PWINDOW->getDrawable());
CWindow newWindow;
newWindow.setDrawable(RESTOREWINID);
newWindow.setFirstOpen(false);
g_pWindowManager->addWindowToVectorSafe(newWindow);
const auto PNEWWINDOW = Events::remapWindow(RESTOREWINID, true); const auto PNEWWINDOW = Events::remapWindow(RESTOREWINID, true);
PNEWWINDOW->setDefaultPosition(RESTOREACPOS); PNEWWINDOW->setDefaultPosition(RESTOREACPOS);

View file

@ -261,7 +261,10 @@ void handleWindowRule(const std::string& command, const std::string& value) {
// verify we support a rule // verify we support a rule
if (RULE != "float" if (RULE != "float"
&& RULE != "tile") { && RULE != "tile"
&& RULE.find("move") != 0
&& RULE.find("size") != 0
&& RULE.find("monitor") != 0) {
Debug::log(ERR, "Invalid rule found: " + RULE); Debug::log(ERR, "Invalid rule found: " + RULE);
ConfigManager::parseError = "Invalid rule found: " + RULE; ConfigManager::parseError = "Invalid rule found: " + RULE;
return; return;
@ -500,3 +503,36 @@ float ConfigManager::getFloat(std::string v) {
std::string ConfigManager::getString(std::string v) { std::string ConfigManager::getString(std::string v) {
return configValues[v].strValue; return configValues[v].strValue;
} }
std::vector<SWindowRule> ConfigManager::getMatchingRules(xcb_window_t w) {
const auto PWINDOW = g_pWindowManager->getWindowFromDrawable(w);
if (!PWINDOW)
return std::vector<SWindowRule>();
std::vector<SWindowRule> returns;
for (auto& rule : ConfigManager::windowRules) {
// check if we have a matching rule
if (rule.szValue.find("class:") == 0) {
std::regex classCheck(rule.szValue.substr(strlen("class:")));
if (!std::regex_search(PWINDOW->getClassName(), classCheck))
continue;
} else if (rule.szValue.find("role:") == 0) {
std::regex roleCheck(rule.szValue.substr(strlen("role:")));
if (!std::regex_search(PWINDOW->getRoleName(), roleCheck))
continue;
} else {
continue;
}
// applies. Read the rule and behave accordingly
Debug::log(LOG, "Window rule " + rule.szRule + "," + rule.szValue + " matched.");
returns.push_back(rule);
}
return returns;
}

View file

@ -3,6 +3,7 @@
#include <map> #include <map>
#include "../utilities/Debug.hpp" #include "../utilities/Debug.hpp"
#include <unordered_map> #include <unordered_map>
#include "../defines.hpp"
#include <vector> #include <vector>
enum ELayouts { enum ELayouts {
@ -41,6 +42,8 @@ namespace ConfigManager {
void applyKeybindsToX(); void applyKeybindsToX();
std::vector<SWindowRule> getMatchingRules(xcb_window_t);
int getInt(std::string); int getInt(std::string);
float getFloat(std::string); float getFloat(std::string);
std::string getString(std::string); std::string getString(std::string);

View file

@ -139,49 +139,77 @@ void Events::eventUnmapWindow(xcb_generic_event_t* event) {
} }
CWindow* Events::remapFloatingWindow(int windowID, int forcemonitor) { CWindow* Events::remapFloatingWindow(int windowID, int forcemonitor) {
CWindow window; // The array is not realloc'd in this method we can make this const
window.setDrawable(windowID); const auto PWINDOWINARR = g_pWindowManager->getWindowFromDrawable(windowID);
window.setIsFloating(true);
window.setDirty(true); if (!PWINDOWINARR) {
Debug::log(ERR, "remapWindow called with an invalid window!");
return nullptr;
}
PWINDOWINARR->setIsFloating(true);
PWINDOWINARR->setDirty(true);
if (!g_pWindowManager->getMonitorFromCursor()) { if (!g_pWindowManager->getMonitorFromCursor()) {
Debug::log(ERR, "Monitor was null! (remapWindow)"); Debug::log(ERR, "Monitor was null! (remapWindow)");
// rip! we cannot continue. // rip! we cannot continue.
} }
// Check the monitor rule
for (auto& rule : ConfigManager::getMatchingRules(windowID)) {
if (!PWINDOWINARR->getFirstOpen())
break;
if (rule.szRule.find("monitor") == 0) {
try {
const auto MONITOR = stoi(rule.szRule.substr(rule.szRule.find(" ") + 1));
Debug::log(LOG, "Rule monitor, applying to window " + std::to_string(windowID));
if (MONITOR > g_pWindowManager->monitors.size() || MONITOR < 0)
forcemonitor = -1;
else
forcemonitor = MONITOR;
} catch(...) {
Debug::log(LOG, "Rule monitor failed, rule: " + rule.szRule + "=" + rule.szValue);
}
}
}
const auto CURRENTSCREEN = forcemonitor != -1 ? forcemonitor : g_pWindowManager->getMonitorFromCursor()->ID; const auto CURRENTSCREEN = forcemonitor != -1 ? forcemonitor : g_pWindowManager->getMonitorFromCursor()->ID;
window.setWorkspaceID(g_pWindowManager->activeWorkspaces[CURRENTSCREEN]); PWINDOWINARR->setWorkspaceID(g_pWindowManager->activeWorkspaces[CURRENTSCREEN]);
window.setMonitor(CURRENTSCREEN); PWINDOWINARR->setMonitor(CURRENTSCREEN);
// Window name // Window name
const auto WINNAME = getWindowName(windowID); const auto WINNAME = getWindowName(windowID);
Debug::log(LOG, "New window got name: " + WINNAME); Debug::log(LOG, "New window got name: " + WINNAME);
window.setName(WINNAME); PWINDOWINARR->setName(WINNAME);
const auto WINCLASSNAME = getClassName(windowID); const auto WINCLASSNAME = getClassName(windowID);
Debug::log(LOG, "New window got class: " + WINCLASSNAME.second); Debug::log(LOG, "New window got class: " + WINCLASSNAME.second);
window.setClassName(WINCLASSNAME.second); PWINDOWINARR->setClassName(WINCLASSNAME.second);
// For all floating windows, get their default size // For all floating windows, get their default size
const auto GEOMETRYCOOKIE = xcb_get_geometry(g_pWindowManager->DisplayConnection, windowID); const auto GEOMETRYCOOKIE = xcb_get_geometry(g_pWindowManager->DisplayConnection, windowID);
const auto GEOMETRY = xcb_get_geometry_reply(g_pWindowManager->DisplayConnection, GEOMETRYCOOKIE, 0); const auto GEOMETRY = xcb_get_geometry_reply(g_pWindowManager->DisplayConnection, GEOMETRYCOOKIE, 0);
if (GEOMETRY) { if (GEOMETRY) {
window.setDefaultPosition(g_pWindowManager->monitors[CURRENTSCREEN].vecPosition); PWINDOWINARR->setDefaultPosition(g_pWindowManager->monitors[CURRENTSCREEN].vecPosition);
window.setDefaultSize(Vector2D(GEOMETRY->width, GEOMETRY->height)); PWINDOWINARR->setDefaultSize(Vector2D(GEOMETRY->width, GEOMETRY->height));
} else { } else {
Debug::log(ERR, "Geometry failed in remap."); Debug::log(ERR, "Geometry failed in remap.");
window.setDefaultPosition(g_pWindowManager->monitors[CURRENTSCREEN].vecPosition); PWINDOWINARR->setDefaultPosition(g_pWindowManager->monitors[CURRENTSCREEN].vecPosition);
window.setDefaultSize(Vector2D(g_pWindowManager->Screen->width_in_pixels / 2.f, g_pWindowManager->Screen->height_in_pixels / 2.f)); PWINDOWINARR->setDefaultSize(Vector2D(g_pWindowManager->Screen->width_in_pixels / 2.f, g_pWindowManager->Screen->height_in_pixels / 2.f));
} }
if (window.getDefaultSize().x < 40 || window.getDefaultSize().y < 40) { if (PWINDOWINARR->getDefaultSize().x < 40 || PWINDOWINARR->getDefaultSize().y < 40) {
// min size // min size
window.setDefaultSize(Vector2D(std::clamp(window.getDefaultSize().x, (double)40, (double)99999), PWINDOWINARR->setDefaultSize(Vector2D(std::clamp(PWINDOWINARR->getDefaultSize().x, (double)40, (double)99999),
std::clamp(window.getDefaultSize().y, (double)40, (double)99999))); std::clamp(PWINDOWINARR->getDefaultSize().y, (double)40, (double)99999)));
} }
if (nextWindowCentered) { if (nextWindowCentered) {
window.setDefaultPosition(g_pWindowManager->monitors[CURRENTSCREEN].vecPosition + g_pWindowManager->monitors[CURRENTSCREEN].vecSize / 2.f - window.getDefaultSize() / 2.f); PWINDOWINARR->setDefaultPosition(g_pWindowManager->monitors[CURRENTSCREEN].vecPosition + g_pWindowManager->monitors[CURRENTSCREEN].vecSize / 2.f - PWINDOWINARR->getDefaultSize() / 2.f);
} }
// //
@ -199,13 +227,13 @@ CWindow* Events::remapFloatingWindow(int windowID, int forcemonitor) {
} else { } else {
if (xcbContainsAtom(wm_type_cookiereply, HYPRATOMS["_NET_WM_WINDOW_TYPE_DOCK"])) { if (xcbContainsAtom(wm_type_cookiereply, HYPRATOMS["_NET_WM_WINDOW_TYPE_DOCK"])) {
// set to floating and set the immovable and nointerventions flag // set to floating and set the immovable and nointerventions flag
window.setImmovable(true); PWINDOWINARR->setImmovable(true);
window.setNoInterventions(true); PWINDOWINARR->setNoInterventions(true);
window.setDefaultPosition(Vector2D(GEOMETRY->x, GEOMETRY->y)); PWINDOWINARR->setDefaultPosition(Vector2D(GEOMETRY->x, GEOMETRY->y));
window.setDefaultSize(Vector2D(GEOMETRY->width, GEOMETRY->height)); PWINDOWINARR->setDefaultSize(Vector2D(GEOMETRY->width, GEOMETRY->height));
window.setDockAlign(DOCK_TOP); PWINDOWINARR->setDockAlign(DOCK_TOP);
// Check reserved // Check reserved
const auto STRUTREPLY = xcb_get_property_reply(g_pWindowManager->DisplayConnection, xcb_get_property(g_pWindowManager->DisplayConnection, false, windowID, HYPRATOMS["_NET_WM_STRUT_PARTIAL"], XCB_GET_PROPERTY_TYPE_ANY, 0, (4294967295U)), NULL); const auto STRUTREPLY = xcb_get_property_reply(g_pWindowManager->DisplayConnection, xcb_get_property(g_pWindowManager->DisplayConnection, false, windowID, HYPRATOMS["_NET_WM_STRUT_PARTIAL"], XCB_GET_PROPERTY_TYPE_ANY, 0, (4294967295U)), NULL);
@ -223,10 +251,10 @@ CWindow* Events::remapFloatingWindow(int windowID, int forcemonitor) {
// 0 1 2 3 // 0 1 2 3
if (STRUT[2] > 0 && STRUT[3] == 0) { if (STRUT[2] > 0 && STRUT[3] == 0) {
// top // top
window.setDockAlign(DOCK_TOP); PWINDOWINARR->setDockAlign(DOCK_TOP);
} else if (STRUT[2] == 0 && STRUT[3] > 0) { } else if (STRUT[2] == 0 && STRUT[3] > 0) {
// bottom // bottom
window.setDockAlign(DOCK_BOTTOM); PWINDOWINARR->setDockAlign(DOCK_BOTTOM);
} }
// little todo: support left/right docks // little todo: support left/right docks
@ -235,21 +263,21 @@ CWindow* Events::remapFloatingWindow(int windowID, int forcemonitor) {
free(STRUTREPLY); free(STRUTREPLY);
switch (window.getDockAlign()) { switch (PWINDOWINARR->getDockAlign()) {
case DOCK_TOP: case DOCK_TOP:
window.setDefaultPosition(Vector2D(g_pWindowManager->monitors[CURRENTSCREEN].vecPosition.x, g_pWindowManager->monitors[CURRENTSCREEN].vecPosition.y)); PWINDOWINARR->setDefaultPosition(Vector2D(g_pWindowManager->monitors[CURRENTSCREEN].vecPosition.x, g_pWindowManager->monitors[CURRENTSCREEN].vecPosition.y));
break; break;
case DOCK_BOTTOM: case DOCK_BOTTOM:
window.setDefaultPosition(Vector2D(g_pWindowManager->monitors[CURRENTSCREEN].vecPosition.x, g_pWindowManager->monitors[CURRENTSCREEN].vecPosition.y + g_pWindowManager->monitors[CURRENTSCREEN].vecSize.y - window.getDefaultSize().y)); PWINDOWINARR->setDefaultPosition(Vector2D(g_pWindowManager->monitors[CURRENTSCREEN].vecPosition.x, g_pWindowManager->monitors[CURRENTSCREEN].vecPosition.y + g_pWindowManager->monitors[CURRENTSCREEN].vecSize.y - PWINDOWINARR->getDefaultSize().y));
break; break;
default: default:
break; break;
} }
Debug::log(LOG, "New dock created, setting default XYWH to: " + std::to_string(window.getDefaultPosition().x) + ", " + std::to_string(window.getDefaultPosition().y) Debug::log(LOG, "New dock created, setting default XYWH to: " + std::to_string(PWINDOWINARR->getDefaultPosition().x) + ", " + std::to_string(PWINDOWINARR->getDefaultPosition().y)
+ ", " + std::to_string(window.getDefaultSize().x) + ", " + std::to_string(window.getDefaultSize().y)); + ", " + std::to_string(PWINDOWINARR->getDefaultSize().x) + ", " + std::to_string(PWINDOWINARR->getDefaultSize().y));
window.setDock(true); PWINDOWINARR->setDock(true);
} }
} }
} }
@ -261,102 +289,167 @@ CWindow* Events::remapFloatingWindow(int windowID, int forcemonitor) {
// ICCCM // ICCCM
xcb_size_hints_t sizeHints; xcb_size_hints_t sizeHints;
const auto succ = xcb_icccm_get_wm_normal_hints_reply(g_pWindowManager->DisplayConnection, xcb_icccm_get_wm_normal_hints_unchecked(g_pWindowManager->DisplayConnection, window.getDrawable()), &sizeHints, NULL); const auto succ = xcb_icccm_get_wm_normal_hints_reply(g_pWindowManager->DisplayConnection, xcb_icccm_get_wm_normal_hints_unchecked(g_pWindowManager->DisplayConnection, PWINDOWINARR->getDrawable()), &sizeHints, NULL);
if (succ && nextWindowCentered /* Basically means dialog */) { if (succ && nextWindowCentered /* Basically means dialog */) {
// vvv gets the max value out of the geometry, size hint, (size hint max if < screen) and size hint base. // vvv gets the max value out of the geometry, size hint, (size hint max if < screen) and size hint base.
auto NEWSIZE = Vector2D(std::max(std::max(sizeHints.width, (int32_t)window.getDefaultSize().x), std::max(sizeHints.max_width > g_pWindowManager->monitors[CURRENTSCREEN].vecSize.x ? 0 : sizeHints.max_width, sizeHints.base_width)), auto NEWSIZE = Vector2D(std::max(std::max(sizeHints.width, (int32_t)PWINDOWINARR->getDefaultSize().x), std::max(sizeHints.max_width > g_pWindowManager->monitors[CURRENTSCREEN].vecSize.x ? 0 : sizeHints.max_width, sizeHints.base_width)),
std::max(std::max(sizeHints.height, (int32_t)window.getDefaultSize().y), std::max(sizeHints.max_height > g_pWindowManager->monitors[CURRENTSCREEN].vecSize.y ? 0 : sizeHints.max_height, sizeHints.base_height))); std::max(std::max(sizeHints.height, (int32_t)PWINDOWINARR->getDefaultSize().y), std::max(sizeHints.max_height > g_pWindowManager->monitors[CURRENTSCREEN].vecSize.y ? 0 : sizeHints.max_height, sizeHints.base_height)));
// clip the new size to max monitor size // clip the new size to max monitor size
NEWSIZE = Vector2D(std::clamp(NEWSIZE.x, (double)40.f, g_pWindowManager->monitors[CURRENTSCREEN].vecSize.x), NEWSIZE = Vector2D(std::clamp(NEWSIZE.x, (double)40.f, g_pWindowManager->monitors[CURRENTSCREEN].vecSize.x),
std::clamp(NEWSIZE.y, (double)40.f, g_pWindowManager->monitors[CURRENTSCREEN].vecSize.y)); std::clamp(NEWSIZE.y, (double)40.f, g_pWindowManager->monitors[CURRENTSCREEN].vecSize.y));
auto DELTA = NEWSIZE - window.getDefaultSize(); auto DELTA = NEWSIZE - PWINDOWINARR->getDefaultSize();
// update // update
window.setDefaultSize(NEWSIZE); PWINDOWINARR->setDefaultSize(NEWSIZE);
window.setDefaultPosition(window.getDefaultPosition() - DELTA / 2.f); PWINDOWINARR->setDefaultPosition(PWINDOWINARR->getDefaultPosition() - DELTA / 2.f);
} else if (!succ) { } else if (!succ) {
Debug::log(ERR, "ICCCM Size Hints failed."); Debug::log(ERR, "ICCCM Size Hints failed.");
} }
// Check the size and pos rules
for (auto& rule : ConfigManager::getMatchingRules(windowID)) {
if (!PWINDOWINARR->getFirstOpen())
break;
if (rule.szRule.find("size") == 0) {
try {
const auto VALUE = rule.szRule.substr(rule.szRule.find(" ") + 1);
const auto SIZEX = stoi(VALUE.substr(0, VALUE.find(" ")));
const auto SIZEY = stoi(VALUE.substr(VALUE.find(" ") + 1));
Debug::log(LOG, "Rule size, applying to window " + std::to_string(windowID));
PWINDOWINARR->setDefaultSize(Vector2D(SIZEX, SIZEY));
} catch (...) {
Debug::log(LOG, "Rule size failed, rule: " + rule.szRule + "=" + rule.szValue);
}
} else if (rule.szRule.find("move") == 0) {
try {
const auto VALUE = rule.szRule.substr(rule.szRule.find(" ") + 1);
const auto POSX = stoi(VALUE.substr(0, VALUE.find(" ")));
const auto POSY = stoi(VALUE.substr(VALUE.find(" ") + 1));
Debug::log(LOG, "Rule move, applying to window " + std::to_string(windowID));
PWINDOWINARR->setDefaultPosition(Vector2D(POSX, POSY) + g_pWindowManager->monitors[CURRENTSCREEN].vecPosition);
} catch (...) {
Debug::log(LOG, "Rule move failed, rule: " + rule.szRule + "=" + rule.szValue);
}
}
}
// //
window.setSize(window.getDefaultSize()); PWINDOWINARR->setSize(PWINDOWINARR->getDefaultSize());
window.setPosition(window.getDefaultPosition()); PWINDOWINARR->setPosition(PWINDOWINARR->getDefaultPosition());
// The anim util will take care of this. // The anim util will take care of this.
window.setEffectiveSize(window.getDefaultSize()); PWINDOWINARR->setEffectiveSize(PWINDOWINARR->getDefaultSize());
window.setEffectivePosition(window.getDefaultPosition()); PWINDOWINARR->setEffectivePosition(PWINDOWINARR->getDefaultPosition());
// Also sets the old one // Also sets the old one
g_pWindowManager->calculateNewWindowParams(&window); g_pWindowManager->calculateNewWindowParams(PWINDOWINARR);
// Add to arr Debug::log(LOG, "Created a new floating window! X: " + std::to_string(PWINDOWINARR->getPosition().x) + ", Y: " + std::to_string(PWINDOWINARR->getPosition().y) + ", W: " + std::to_string(PWINDOWINARR->getSize().x) + ", H:" + std::to_string(PWINDOWINARR->getSize().y) + " ID: " + std::to_string(windowID));
g_pWindowManager->addWindowToVectorSafe(window);
Debug::log(LOG, "Created a new floating window! X: " + std::to_string(window.getPosition().x) + ", Y: " + std::to_string(window.getPosition().y) + ", W: " + std::to_string(window.getSize().x) + ", H:" + std::to_string(window.getSize().y) + " ID: " + std::to_string(windowID));
// Set map values // Set map values
g_pWindowManager->Values[0] = XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_FOCUS_CHANGE; g_pWindowManager->Values[0] = XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_FOCUS_CHANGE;
xcb_change_window_attributes_checked(g_pWindowManager->DisplayConnection, windowID, XCB_CW_EVENT_MASK, g_pWindowManager->Values); xcb_change_window_attributes_checked(g_pWindowManager->DisplayConnection, windowID, XCB_CW_EVENT_MASK, g_pWindowManager->Values);
// Fix docks // Fix docks
if (window.getDock()) if (PWINDOWINARR->getDock())
g_pWindowManager->recalcAllDocks(); g_pWindowManager->recalcAllDocks();
nextWindowCentered = false; nextWindowCentered = false;
return g_pWindowManager->getWindowFromDrawable(windowID); // Reset flags
PWINDOWINARR->setConstructed(true);
PWINDOWINARR->setFirstOpen(false);
return PWINDOWINARR;
} }
CWindow* Events::remapWindow(int windowID, bool wasfloating, int forcemonitor) { CWindow* Events::remapWindow(int windowID, bool wasfloating, int forcemonitor) {
// Do the setup of the window's params and stuf
CWindow window; // Not const because we realloc the array later
window.setDrawable(windowID); auto PWINDOWINARR = g_pWindowManager->getWindowFromDrawable(windowID);
window.setIsFloating(false);
window.setDirty(true); if (!PWINDOWINARR) {
Debug::log(ERR, "remapWindow called with an invalid window!");
return nullptr;
}
PWINDOWINARR->setIsFloating(false);
PWINDOWINARR->setDirty(true);
if (!g_pWindowManager->getMonitorFromCursor()) { if (!g_pWindowManager->getMonitorFromCursor()) {
Debug::log(ERR, "Monitor was null! (remapWindow)"); Debug::log(ERR, "Monitor was null! (remapWindow)");
// rip! we cannot continue. // rip! we cannot continue.
} }
// Check the monitor rule
for (auto& rule : ConfigManager::getMatchingRules(windowID)) {
if (!PWINDOWINARR->getFirstOpen())
break;
if (rule.szRule.find("monitor") == 0) {
try {
const auto MONITOR = stoi(rule.szRule.substr(rule.szRule.find(" ") + 1));
Debug::log(LOG, "Rule monitor, applying to window " + std::to_string(windowID));
if (MONITOR > g_pWindowManager->monitors.size() || MONITOR < 0)
forcemonitor = -1;
else
forcemonitor = MONITOR;
} catch (...) {
Debug::log(LOG, "Rule monitor failed, rule: " + rule.szRule + "=" + rule.szValue);
}
}
}
const auto CURRENTSCREEN = forcemonitor != -1 ? forcemonitor : g_pWindowManager->getMonitorFromCursor()->ID; const auto CURRENTSCREEN = forcemonitor != -1 ? forcemonitor : g_pWindowManager->getMonitorFromCursor()->ID;
window.setWorkspaceID(g_pWindowManager->activeWorkspaces[CURRENTSCREEN]); PWINDOWINARR->setWorkspaceID(g_pWindowManager->activeWorkspaces[CURRENTSCREEN]);
window.setMonitor(CURRENTSCREEN); PWINDOWINARR->setMonitor(CURRENTSCREEN);
// Window name // Window name
const auto WINNAME = getWindowName(windowID); const auto WINNAME = getWindowName(windowID);
Debug::log(LOG, "New window got name: " + WINNAME); Debug::log(LOG, "New window got name: " + WINNAME);
window.setName(WINNAME); PWINDOWINARR->setName(WINNAME);
const auto WINCLASSNAME = getClassName(windowID); const auto WINCLASSNAME = getClassName(windowID);
Debug::log(LOG, "New window got class: " + WINCLASSNAME.second); Debug::log(LOG, "New window got class: " + WINCLASSNAME.second);
window.setClassName(WINCLASSNAME.second); PWINDOWINARR->setClassName(WINCLASSNAME.second);
// For all floating windows, get their default size // For all floating windows, get their default size
const auto GEOMETRYCOOKIE = xcb_get_geometry(g_pWindowManager->DisplayConnection, windowID); const auto GEOMETRYCOOKIE = xcb_get_geometry(g_pWindowManager->DisplayConnection, windowID);
const auto GEOMETRY = xcb_get_geometry_reply(g_pWindowManager->DisplayConnection, GEOMETRYCOOKIE, 0); const auto GEOMETRY = xcb_get_geometry_reply(g_pWindowManager->DisplayConnection, GEOMETRYCOOKIE, 0);
if (GEOMETRY) { if (GEOMETRY) {
window.setDefaultPosition(Vector2D(GEOMETRY->x, GEOMETRY->y)); PWINDOWINARR->setDefaultPosition(Vector2D(GEOMETRY->x, GEOMETRY->y));
window.setDefaultSize(Vector2D(GEOMETRY->width, GEOMETRY->height)); PWINDOWINARR->setDefaultSize(Vector2D(GEOMETRY->width, GEOMETRY->height));
} else { } else {
Debug::log(ERR, "Geometry failed in remap."); Debug::log(ERR, "Geometry failed in remap.");
window.setDefaultPosition(Vector2D(0, 0)); PWINDOWINARR->setDefaultPosition(Vector2D(0, 0));
window.setDefaultSize(Vector2D(g_pWindowManager->Screen->width_in_pixels / 2.f, g_pWindowManager->Screen->height_in_pixels / 2.f)); PWINDOWINARR->setDefaultSize(Vector2D(g_pWindowManager->Screen->width_in_pixels / 2.f, g_pWindowManager->Screen->height_in_pixels / 2.f));
} }
// 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) { if (auto PLASTWINDOW = g_pWindowManager->getWindowFromDrawable(g_pWindowManager->LastWindow); (PLASTWINDOW && PLASTWINDOW->getWorkspaceID() == g_pWindowManager->activeWorkspaces[CURRENTSCREEN]) || wasfloating || (forcemonitor != -1 && forcemonitor != g_pWindowManager->getMonitorFromCursor()->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 || PLASTWINDOW->getIsFloating()) { if (wasfloating || (forcemonitor != -1 && forcemonitor != g_pWindowManager->getMonitorFromCursor()->ID) || PLASTWINDOW->getIsFloating()) {
// find a window manually // if it's force monitor, find the first on a workspace.
PLASTWINDOW = g_pWindowManager->findWindowAtCursor(); if (forcemonitor != -1 && forcemonitor != g_pWindowManager->getMonitorFromCursor()->ID) {
PLASTWINDOW = g_pWindowManager->findFirstWindowOnWorkspace(g_pWindowManager->activeWorkspaces[CURRENTSCREEN]);
} else {
// find a window manually by the cursor
PLASTWINDOW = g_pWindowManager->findWindowAtCursor();
}
} }
if (PLASTWINDOW) { if (PLASTWINDOW) {
@ -369,8 +462,8 @@ CWindow* Events::remapWindow(int windowID, bool wasfloating, int forcemonitor) {
newWindowSplitNode.setParentNodeID(PLASTWINDOW->getParentNodeID()); newWindowSplitNode.setParentNodeID(PLASTWINDOW->getParentNodeID());
newWindowSplitNode.setWorkspaceID(window.getWorkspaceID()); newWindowSplitNode.setWorkspaceID(PWINDOWINARR->getWorkspaceID());
newWindowSplitNode.setMonitor(window.getMonitor()); newWindowSplitNode.setMonitor(PWINDOWINARR->getMonitor());
// generates a negative node ID // generates a negative node ID
newWindowSplitNode.generateNodeID(); newWindowSplitNode.generateNodeID();
@ -384,31 +477,27 @@ CWindow* Events::remapWindow(int windowID, bool wasfloating, int forcemonitor) {
} }
} }
window.setParentNodeID(newWindowSplitNode.getDrawable()); PWINDOWINARR->setParentNodeID(newWindowSplitNode.getDrawable());
PLASTWINDOW->setParentNodeID(newWindowSplitNode.getDrawable()); PLASTWINDOW->setParentNodeID(newWindowSplitNode.getDrawable());
g_pWindowManager->addWindowToVectorSafe(newWindowSplitNode); g_pWindowManager->addWindowToVectorSafe(newWindowSplitNode);
// The array got reallocated, let's update the pointer
PWINDOWINARR = g_pWindowManager->getWindowFromDrawable(windowID);
} else { } else {
window.setParentNodeID(0); PWINDOWINARR->setParentNodeID(0);
} }
} else { } else {
// LastWindow is not on our workspace, so set the parent to 0. // LastWindow is not on our workspace, so set the parent to 0.
window.setParentNodeID(0); PWINDOWINARR->setParentNodeID(0);
} }
// For master layout, add the index // For master layout, add the index
window.setMasterChildIndex(g_pWindowManager->getWindowsOnWorkspace(g_pWindowManager->activeWorkspaces[CURRENTSCREEN]) - 1); PWINDOWINARR->setMasterChildIndex(g_pWindowManager->getWindowsOnWorkspace(g_pWindowManager->activeWorkspaces[CURRENTSCREEN]) - 1);
// and set master if needed // and set master if needed
if (g_pWindowManager->getWindowsOnWorkspace(g_pWindowManager->activeWorkspaces[CURRENTSCREEN]) == 0) if (g_pWindowManager->getWindowsOnWorkspace(g_pWindowManager->activeWorkspaces[CURRENTSCREEN]) == 0)
window.setMaster(true); PWINDOWINARR->setMaster(true);
// Add to arr
g_pWindowManager->addWindowToVectorSafe(window);
// Now we need to modify the copy in the array.
const auto PWINDOWINARR = g_pWindowManager->getWindowFromDrawable(windowID);
// Also sets the old one // Also sets the old one
g_pWindowManager->calculateNewWindowParams(PWINDOWINARR); g_pWindowManager->calculateNewWindowParams(PWINDOWINARR);
@ -429,6 +518,10 @@ CWindow* Events::remapWindow(int windowID, bool wasfloating, int forcemonitor) {
// Focus // Focus
g_pWindowManager->setFocusedWindow(windowID); g_pWindowManager->setFocusedWindow(windowID);
// Reset flags
PWINDOWINARR->setConstructed(true);
PWINDOWINARR->setFirstOpen(false);
return PWINDOWINARR; return PWINDOWINARR;
} }
@ -457,6 +550,10 @@ void Events::eventMapWindow(xcb_generic_event_t* event) {
// We check if the window is not on our tile-blacklist and if it is, we have a special treatment procedure for it. // We check if the window is not on our tile-blacklist and if it is, we have a special treatment procedure for it.
// this func also sets some stuff // this func also sets some stuff
CWindow window;
window.setDrawable(E->window);
g_pWindowManager->addWindowToVectorSafe(window);
CWindow* pNewWindow = nullptr; CWindow* pNewWindow = nullptr;
if (g_pWindowManager->shouldBeFloatedOnInit(E->window)) { if (g_pWindowManager->shouldBeFloatedOnInit(E->window)) {
Debug::log(LOG, "Window SHOULD be floating on start."); Debug::log(LOG, "Window SHOULD be floating on start.");

View file

@ -14,6 +14,11 @@ class Vector2D {
// returns the scale // returns the scale
double normalize(); double normalize();
Vector2D& operator=(Vector2D a) {
this->x = a.x; this->y = a.y;
return *this;
}
Vector2D operator+(Vector2D a) { Vector2D operator+(Vector2D a) {
return Vector2D(this->x + a.x, this->y + a.y); return Vector2D(this->x + a.x, this->y + a.y);
} }

View file

@ -16,6 +16,9 @@ void AnimationUtil::move() {
// check if window needs an animation. // check if window needs an animation.
window.setIsAnimated(false); window.setIsAnimated(false);
if (!window.getConstructed())
continue;
// Border animations // Border animations
if (window.getDrawable() > 0) { if (window.getDrawable() > 0) {
if (window.getEffectiveBorderColor().getAsUint32() != window.getRealBorderColor().getAsUint32() /* As uint32 to round and not spam */) { if (window.getEffectiveBorderColor().getAsUint32() != window.getRealBorderColor().getAsUint32() /* As uint32 to round and not spam */) {

View file

@ -27,6 +27,14 @@ public:
; ;
} }
CFloatingColor& operator=(uint32_t c) {
r = RED(c) * 255.f;
g = GREEN(c) * 255.f;
b = BLUE(c) * 255.f;
a = ALPHA(c) * 255.f;
return *this;
}
bool operator==(CFloatingColor B) { bool operator==(CFloatingColor B) {
return r == B.r && g == B.g && b == B.b && a == B.a; return r == B.r && g == B.g && b == B.b && a == B.a;
} }

View file

@ -1,7 +1,7 @@
#include "window.hpp" #include "window.hpp"
#include "windowManager.hpp" #include "windowManager.hpp"
CWindow::CWindow() { this->setTransient(false); this->setLastUpdatePosition(Vector2D(0,0)); this->setLastUpdateSize(Vector2D(0,0)); this->setDock(false); this->setUnderFullscreen(false); this->setIsSleeping(true); this->setFirstAnimFrame(true); this->setIsAnimated(false); this->setDead(false); this->setMasterChildIndex(0); this->setMaster(false); this->setCanKill(false); this->setImmovable(false); this->setNoInterventions(false); this->setDirty(true); this->setFullscreen(false); this->setIsFloating(false); this->setParentNodeID(0); this->setChildNodeAID(0); this->setChildNodeBID(0); this->setName(""); } CWindow::CWindow() { this->setRealBorderColor(0); this->setEffectiveBorderColor(0); this->setFirstOpen(true); this->setConstructed(false); this->setTransient(false); this->setLastUpdatePosition(Vector2D(0,0)); this->setLastUpdateSize(Vector2D(0,0)); this->setDock(false); this->setUnderFullscreen(false); this->setIsSleeping(true); this->setFirstAnimFrame(true); this->setIsAnimated(false); this->setDead(false); this->setMasterChildIndex(0); this->setMaster(false); this->setCanKill(false); this->setImmovable(false); this->setNoInterventions(false); this->setDirty(true); this->setFullscreen(false); this->setIsFloating(false); this->setParentNodeID(0); this->setChildNodeAID(0); this->setChildNodeBID(0); this->setName(""); }
CWindow::~CWindow() { } CWindow::~CWindow() { }
void CWindow::generateNodeID() { void CWindow::generateNodeID() {

View file

@ -35,6 +35,9 @@ public:
EXPOSED_MEMBER(Name, std::string, sz); EXPOSED_MEMBER(Name, std::string, sz);
EXPOSED_MEMBER(ClassName, std::string, sz); EXPOSED_MEMBER(ClassName, std::string, sz);
EXPOSED_MEMBER(RoleName, std::string, sz);
EXPOSED_MEMBER(Constructed, bool, b);
EXPOSED_MEMBER(FirstOpen, bool, b);
// Tells the window manager to reload the window's params // Tells the window manager to reload the window's params
EXPOSED_MEMBER(Dirty, bool, b); EXPOSED_MEMBER(Dirty, bool, b);

View file

@ -762,6 +762,16 @@ CWindow* CWindowManager::findWindowAtCursor() {
return nullptr; return nullptr;
} }
CWindow* CWindowManager::findFirstWindowOnWorkspace(const int& work) {
for (auto& w : windows) {
if (w.getWorkspaceID() == work && !w.getIsFloating() && !w.getNoInterventions() && w.getDrawable() > 0) {
return &w;
}
}
return nullptr;
}
void CWindowManager::calculateNewTileSetOldTile(CWindow* pWindow) { 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
@ -1268,6 +1278,10 @@ void CWindowManager::moveActiveWindowToWorkspace(int workspace) {
setFocusedWindow(newLastWindow); setFocusedWindow(newLastWindow);
} }
CWindow newWindow;
newWindow.setDrawable(SAVEDDRAWABLE);
newWindow.setFirstOpen(false);
addWindowToVectorSafe(newWindow);
CWindow* PNEWWINDOW = nullptr; CWindow* PNEWWINDOW = nullptr;
if (SAVEDFLOATSTATUS) if (SAVEDFLOATSTATUS)
@ -1576,11 +1590,13 @@ void CWindowManager::setAWindowTop(xcb_window_t window) {
bool CWindowManager::shouldBeFloatedOnInit(int64_t window) { bool CWindowManager::shouldBeFloatedOnInit(int64_t window) {
// Should be floated also sets some properties // Should be floated also sets some properties
// get stuffza
// floating for krunner const auto PWINDOW = getWindowFromDrawable(window);
// TODO: config this
if (!PWINDOW) {
Debug::log(ERR, "shouldBeFloatedOnInit with an invalid window!");
return true;
}
const auto WINCLASS = getClassName(window); const auto WINCLASS = getClassName(window);
const auto CLASSNAME = WINCLASS.second; const auto CLASSNAME = WINCLASS.second;
@ -1590,52 +1606,14 @@ bool CWindowManager::shouldBeFloatedOnInit(int64_t window) {
xcb_change_property(DisplayConnection, XCB_PROP_MODE_REPLACE, window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, strlen("hypr"), "hypr"); xcb_change_property(DisplayConnection, XCB_PROP_MODE_REPLACE, window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, strlen("hypr"), "hypr");
// Verify the class (rules)
for (auto& rule : ConfigManager::windowRules) {
// check if we have a class rule
if (rule.szValue.find("class:") != 0)
continue;
// regex check the arg
std::regex classCheck(rule.szValue.substr(strlen("class:")));
if (!std::regex_search(CLASSNAME, classCheck))
continue;
// applies. Read the rule and behave accordingly
Debug::log(LOG, "Window rule " + rule.szRule + "," + rule.szValue + " matched.");
if (rule.szRule == "tile")
return false;
else if (rule.szRule == "float")
return true;
}
// Role stuff // Role stuff
const auto WINROLE = getRoleName(window); const auto WINROLE = getRoleName(window);
Debug::log(LOG, "Window opened with a role of " + WINROLE); Debug::log(LOG, "Window opened with a role of " + WINROLE);
for (auto& rule : ConfigManager::windowRules) { // Set it in the pwindow
// check if we have a role rule PWINDOW->setClassName(CLASSNAME);
if (rule.szValue.find("role:") != 0) PWINDOW->setRoleName(WINROLE);
continue;
// regex check the arg
std::regex roleCheck(rule.szValue.substr(strlen("role:")));
if (!std::regex_search(WINROLE, roleCheck))
continue;
// applies. Read the rule and behave accordingly
Debug::log(LOG, "Window rule " + rule.szRule + "," + rule.szValue + " matched.");
if (rule.szRule == "tile")
return false;
else if (rule.szRule == "float")
return true;
}
// //
// Type stuff // Type stuff
@ -1670,6 +1648,14 @@ bool CWindowManager::shouldBeFloatedOnInit(int64_t window) {
// //
// //
// Verify the rules.
for (auto& rule : ConfigManager::getMatchingRules(window)) {
if (rule.szRule == "tile")
return false;
else if (rule.szRule == "float")
return true;
}
return false; return false;
} }

View file

@ -103,6 +103,8 @@ public:
// finds a window that's tiled at cursor. // finds a window that's tiled at cursor.
CWindow* findWindowAtCursor(); CWindow* findWindowAtCursor();
CWindow* findFirstWindowOnWorkspace(const int&);
bool shouldBeFloatedOnInit(int64_t); bool shouldBeFloatedOnInit(int64_t);
void doPostCreationChecks(CWindow*); void doPostCreationChecks(CWindow*);
void getICCCMWMProtocols(CWindow*); void getICCCMWMProtocols(CWindow*);