mirror of
https://github.com/hyprwm/Hypr.git
synced 2024-11-22 13:35:57 +01:00
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:
parent
30a6f6d2d2
commit
ef2549f530
11 changed files with 274 additions and 125 deletions
|
@ -172,6 +172,12 @@ void KeybindManager::toggleActiveWindowFloating(std::string unusedArg) {
|
|||
const auto RESTORECANKILL = PWINDOW->getCanKill();
|
||||
|
||||
g_pWindowManager->removeWindowFromVectorSafe(PWINDOW->getDrawable());
|
||||
|
||||
CWindow newWindow;
|
||||
newWindow.setDrawable(RESTOREWINID);
|
||||
newWindow.setFirstOpen(false);
|
||||
g_pWindowManager->addWindowToVectorSafe(newWindow);
|
||||
|
||||
const auto PNEWWINDOW = Events::remapWindow(RESTOREWINID, true);
|
||||
|
||||
PNEWWINDOW->setDefaultPosition(RESTOREACPOS);
|
||||
|
|
|
@ -261,7 +261,10 @@ void handleWindowRule(const std::string& command, const std::string& value) {
|
|||
|
||||
// verify we support a rule
|
||||
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);
|
||||
ConfigManager::parseError = "Invalid rule found: " + RULE;
|
||||
return;
|
||||
|
@ -500,3 +503,36 @@ float ConfigManager::getFloat(std::string v) {
|
|||
std::string ConfigManager::getString(std::string v) {
|
||||
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;
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
#include <map>
|
||||
#include "../utilities/Debug.hpp"
|
||||
#include <unordered_map>
|
||||
#include "../defines.hpp"
|
||||
#include <vector>
|
||||
|
||||
enum ELayouts {
|
||||
|
@ -41,6 +42,8 @@ namespace ConfigManager {
|
|||
|
||||
void applyKeybindsToX();
|
||||
|
||||
std::vector<SWindowRule> getMatchingRules(xcb_window_t);
|
||||
|
||||
int getInt(std::string);
|
||||
float getFloat(std::string);
|
||||
std::string getString(std::string);
|
||||
|
|
|
@ -139,49 +139,77 @@ void Events::eventUnmapWindow(xcb_generic_event_t* event) {
|
|||
}
|
||||
|
||||
CWindow* Events::remapFloatingWindow(int windowID, int forcemonitor) {
|
||||
CWindow window;
|
||||
window.setDrawable(windowID);
|
||||
window.setIsFloating(true);
|
||||
window.setDirty(true);
|
||||
// The array is not realloc'd in this method we can make this const
|
||||
const auto PWINDOWINARR = g_pWindowManager->getWindowFromDrawable(windowID);
|
||||
|
||||
if (!PWINDOWINARR) {
|
||||
Debug::log(ERR, "remapWindow called with an invalid window!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PWINDOWINARR->setIsFloating(true);
|
||||
PWINDOWINARR->setDirty(true);
|
||||
if (!g_pWindowManager->getMonitorFromCursor()) {
|
||||
Debug::log(ERR, "Monitor was null! (remapWindow)");
|
||||
// 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;
|
||||
window.setWorkspaceID(g_pWindowManager->activeWorkspaces[CURRENTSCREEN]);
|
||||
window.setMonitor(CURRENTSCREEN);
|
||||
PWINDOWINARR->setWorkspaceID(g_pWindowManager->activeWorkspaces[CURRENTSCREEN]);
|
||||
PWINDOWINARR->setMonitor(CURRENTSCREEN);
|
||||
|
||||
// Window name
|
||||
const auto WINNAME = getWindowName(windowID);
|
||||
Debug::log(LOG, "New window got name: " + WINNAME);
|
||||
window.setName(WINNAME);
|
||||
PWINDOWINARR->setName(WINNAME);
|
||||
|
||||
const auto WINCLASSNAME = getClassName(windowID);
|
||||
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
|
||||
const auto GEOMETRYCOOKIE = xcb_get_geometry(g_pWindowManager->DisplayConnection, windowID);
|
||||
const auto GEOMETRY = xcb_get_geometry_reply(g_pWindowManager->DisplayConnection, GEOMETRYCOOKIE, 0);
|
||||
|
||||
if (GEOMETRY) {
|
||||
window.setDefaultPosition(g_pWindowManager->monitors[CURRENTSCREEN].vecPosition);
|
||||
window.setDefaultSize(Vector2D(GEOMETRY->width, GEOMETRY->height));
|
||||
PWINDOWINARR->setDefaultPosition(g_pWindowManager->monitors[CURRENTSCREEN].vecPosition);
|
||||
PWINDOWINARR->setDefaultSize(Vector2D(GEOMETRY->width, GEOMETRY->height));
|
||||
} else {
|
||||
Debug::log(ERR, "Geometry failed in remap.");
|
||||
|
||||
window.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->setDefaultPosition(g_pWindowManager->monitors[CURRENTSCREEN].vecPosition);
|
||||
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
|
||||
window.setDefaultSize(Vector2D(std::clamp(window.getDefaultSize().x, (double)40, (double)99999),
|
||||
std::clamp(window.getDefaultSize().y, (double)40, (double)99999)));
|
||||
PWINDOWINARR->setDefaultSize(Vector2D(std::clamp(PWINDOWINARR->getDefaultSize().x, (double)40, (double)99999),
|
||||
std::clamp(PWINDOWINARR->getDefaultSize().y, (double)40, (double)99999)));
|
||||
}
|
||||
|
||||
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 {
|
||||
if (xcbContainsAtom(wm_type_cookiereply, HYPRATOMS["_NET_WM_WINDOW_TYPE_DOCK"])) {
|
||||
// set to floating and set the immovable and nointerventions flag
|
||||
window.setImmovable(true);
|
||||
window.setNoInterventions(true);
|
||||
PWINDOWINARR->setImmovable(true);
|
||||
PWINDOWINARR->setNoInterventions(true);
|
||||
|
||||
window.setDefaultPosition(Vector2D(GEOMETRY->x, GEOMETRY->y));
|
||||
window.setDefaultSize(Vector2D(GEOMETRY->width, GEOMETRY->height));
|
||||
PWINDOWINARR->setDefaultPosition(Vector2D(GEOMETRY->x, GEOMETRY->y));
|
||||
PWINDOWINARR->setDefaultSize(Vector2D(GEOMETRY->width, GEOMETRY->height));
|
||||
|
||||
window.setDockAlign(DOCK_TOP);
|
||||
PWINDOWINARR->setDockAlign(DOCK_TOP);
|
||||
|
||||
// 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);
|
||||
|
@ -223,10 +251,10 @@ CWindow* Events::remapFloatingWindow(int windowID, int forcemonitor) {
|
|||
// 0 1 2 3
|
||||
if (STRUT[2] > 0 && STRUT[3] == 0) {
|
||||
// top
|
||||
window.setDockAlign(DOCK_TOP);
|
||||
PWINDOWINARR->setDockAlign(DOCK_TOP);
|
||||
} else if (STRUT[2] == 0 && STRUT[3] > 0) {
|
||||
// bottom
|
||||
window.setDockAlign(DOCK_BOTTOM);
|
||||
PWINDOWINARR->setDockAlign(DOCK_BOTTOM);
|
||||
}
|
||||
|
||||
// little todo: support left/right docks
|
||||
|
@ -235,21 +263,21 @@ CWindow* Events::remapFloatingWindow(int windowID, int forcemonitor) {
|
|||
|
||||
free(STRUTREPLY);
|
||||
|
||||
switch (window.getDockAlign()) {
|
||||
switch (PWINDOWINARR->getDockAlign()) {
|
||||
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;
|
||||
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;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Debug::log(LOG, "New dock created, setting default XYWH to: " + std::to_string(window.getDefaultPosition().x) + ", " + std::to_string(window.getDefaultPosition().y)
|
||||
+ ", " + std::to_string(window.getDefaultSize().x) + ", " + std::to_string(window.getDefaultSize().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(PWINDOWINARR->getDefaultSize().x) + ", " + std::to_string(PWINDOWINARR->getDefaultSize().y));
|
||||
|
||||
window.setDock(true);
|
||||
PWINDOWINARR->setDock(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -261,103 +289,168 @@ CWindow* Events::remapFloatingWindow(int windowID, int forcemonitor) {
|
|||
// ICCCM
|
||||
|
||||
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 */) {
|
||||
|
||||
// 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)),
|
||||
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)));
|
||||
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)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
|
||||
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));
|
||||
|
||||
auto DELTA = NEWSIZE - window.getDefaultSize();
|
||||
auto DELTA = NEWSIZE - PWINDOWINARR->getDefaultSize();
|
||||
|
||||
// update
|
||||
window.setDefaultSize(NEWSIZE);
|
||||
window.setDefaultPosition(window.getDefaultPosition() - DELTA / 2.f);
|
||||
PWINDOWINARR->setDefaultSize(NEWSIZE);
|
||||
PWINDOWINARR->setDefaultPosition(PWINDOWINARR->getDefaultPosition() - DELTA / 2.f);
|
||||
} else if (!succ) {
|
||||
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());
|
||||
window.setPosition(window.getDefaultPosition());
|
||||
PWINDOWINARR->setSize(PWINDOWINARR->getDefaultSize());
|
||||
PWINDOWINARR->setPosition(PWINDOWINARR->getDefaultPosition());
|
||||
|
||||
// The anim util will take care of this.
|
||||
window.setEffectiveSize(window.getDefaultSize());
|
||||
window.setEffectivePosition(window.getDefaultPosition());
|
||||
PWINDOWINARR->setEffectiveSize(PWINDOWINARR->getDefaultSize());
|
||||
PWINDOWINARR->setEffectivePosition(PWINDOWINARR->getDefaultPosition());
|
||||
|
||||
// Also sets the old one
|
||||
g_pWindowManager->calculateNewWindowParams(&window);
|
||||
g_pWindowManager->calculateNewWindowParams(PWINDOWINARR);
|
||||
|
||||
// Add to arr
|
||||
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));
|
||||
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));
|
||||
|
||||
// Set map values
|
||||
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);
|
||||
|
||||
// Fix docks
|
||||
if (window.getDock())
|
||||
if (PWINDOWINARR->getDock())
|
||||
g_pWindowManager->recalcAllDocks();
|
||||
|
||||
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) {
|
||||
// Do the setup of the window's params and stuf
|
||||
CWindow window;
|
||||
window.setDrawable(windowID);
|
||||
window.setIsFloating(false);
|
||||
window.setDirty(true);
|
||||
|
||||
// Not const because we realloc the array later
|
||||
auto PWINDOWINARR = g_pWindowManager->getWindowFromDrawable(windowID);
|
||||
|
||||
if (!PWINDOWINARR) {
|
||||
Debug::log(ERR, "remapWindow called with an invalid window!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PWINDOWINARR->setIsFloating(false);
|
||||
PWINDOWINARR->setDirty(true);
|
||||
if (!g_pWindowManager->getMonitorFromCursor()) {
|
||||
Debug::log(ERR, "Monitor was null! (remapWindow)");
|
||||
// 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;
|
||||
window.setWorkspaceID(g_pWindowManager->activeWorkspaces[CURRENTSCREEN]);
|
||||
window.setMonitor(CURRENTSCREEN);
|
||||
PWINDOWINARR->setWorkspaceID(g_pWindowManager->activeWorkspaces[CURRENTSCREEN]);
|
||||
PWINDOWINARR->setMonitor(CURRENTSCREEN);
|
||||
|
||||
// Window name
|
||||
const auto WINNAME = getWindowName(windowID);
|
||||
Debug::log(LOG, "New window got name: " + WINNAME);
|
||||
window.setName(WINNAME);
|
||||
PWINDOWINARR->setName(WINNAME);
|
||||
|
||||
const auto WINCLASSNAME = getClassName(windowID);
|
||||
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
|
||||
const auto GEOMETRYCOOKIE = xcb_get_geometry(g_pWindowManager->DisplayConnection, windowID);
|
||||
const auto GEOMETRY = xcb_get_geometry_reply(g_pWindowManager->DisplayConnection, GEOMETRYCOOKIE, 0);
|
||||
|
||||
if (GEOMETRY) {
|
||||
window.setDefaultPosition(Vector2D(GEOMETRY->x, GEOMETRY->y));
|
||||
window.setDefaultSize(Vector2D(GEOMETRY->width, GEOMETRY->height));
|
||||
PWINDOWINARR->setDefaultPosition(Vector2D(GEOMETRY->x, GEOMETRY->y));
|
||||
PWINDOWINARR->setDefaultSize(Vector2D(GEOMETRY->width, GEOMETRY->height));
|
||||
} else {
|
||||
Debug::log(ERR, "Geometry failed in remap.");
|
||||
|
||||
window.setDefaultPosition(Vector2D(0, 0));
|
||||
window.setDefaultSize(Vector2D(g_pWindowManager->Screen->width_in_pixels / 2.f, g_pWindowManager->Screen->height_in_pixels / 2.f));
|
||||
PWINDOWINARR->setDefaultPosition(Vector2D(0, 0));
|
||||
PWINDOWINARR->setDefaultSize(Vector2D(g_pWindowManager->Screen->width_in_pixels / 2.f, g_pWindowManager->Screen->height_in_pixels / 2.f));
|
||||
}
|
||||
|
||||
// Set the parent
|
||||
// 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
|
||||
|
||||
if (wasfloating || PLASTWINDOW->getIsFloating()) {
|
||||
// find a window manually
|
||||
if (wasfloating || (forcemonitor != -1 && forcemonitor != g_pWindowManager->getMonitorFromCursor()->ID) || PLASTWINDOW->getIsFloating()) {
|
||||
// if it's force monitor, find the first on a workspace.
|
||||
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) {
|
||||
CWindow newWindowSplitNode;
|
||||
|
@ -369,8 +462,8 @@ CWindow* Events::remapWindow(int windowID, bool wasfloating, int forcemonitor) {
|
|||
|
||||
newWindowSplitNode.setParentNodeID(PLASTWINDOW->getParentNodeID());
|
||||
|
||||
newWindowSplitNode.setWorkspaceID(window.getWorkspaceID());
|
||||
newWindowSplitNode.setMonitor(window.getMonitor());
|
||||
newWindowSplitNode.setWorkspaceID(PWINDOWINARR->getWorkspaceID());
|
||||
newWindowSplitNode.setMonitor(PWINDOWINARR->getMonitor());
|
||||
|
||||
// generates a negative node ID
|
||||
newWindowSplitNode.generateNodeID();
|
||||
|
@ -384,30 +477,26 @@ CWindow* Events::remapWindow(int windowID, bool wasfloating, int forcemonitor) {
|
|||
}
|
||||
}
|
||||
|
||||
window.setParentNodeID(newWindowSplitNode.getDrawable());
|
||||
PWINDOWINARR->setParentNodeID(newWindowSplitNode.getDrawable());
|
||||
PLASTWINDOW->setParentNodeID(newWindowSplitNode.getDrawable());
|
||||
|
||||
g_pWindowManager->addWindowToVectorSafe(newWindowSplitNode);
|
||||
|
||||
// The array got reallocated, let's update the pointer
|
||||
PWINDOWINARR = g_pWindowManager->getWindowFromDrawable(windowID);
|
||||
} else {
|
||||
window.setParentNodeID(0);
|
||||
PWINDOWINARR->setParentNodeID(0);
|
||||
}
|
||||
} else {
|
||||
// LastWindow is not on our workspace, so set the parent to 0.
|
||||
window.setParentNodeID(0);
|
||||
PWINDOWINARR->setParentNodeID(0);
|
||||
}
|
||||
|
||||
// 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
|
||||
if (g_pWindowManager->getWindowsOnWorkspace(g_pWindowManager->activeWorkspaces[CURRENTSCREEN]) == 0)
|
||||
window.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);
|
||||
PWINDOWINARR->setMaster(true);
|
||||
|
||||
|
||||
// Also sets the old one
|
||||
|
@ -429,6 +518,10 @@ CWindow* Events::remapWindow(int windowID, bool wasfloating, int forcemonitor) {
|
|||
// Focus
|
||||
g_pWindowManager->setFocusedWindow(windowID);
|
||||
|
||||
// Reset flags
|
||||
PWINDOWINARR->setConstructed(true);
|
||||
PWINDOWINARR->setFirstOpen(false);
|
||||
|
||||
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.
|
||||
// this func also sets some stuff
|
||||
|
||||
CWindow window;
|
||||
window.setDrawable(E->window);
|
||||
g_pWindowManager->addWindowToVectorSafe(window);
|
||||
|
||||
CWindow* pNewWindow = nullptr;
|
||||
if (g_pWindowManager->shouldBeFloatedOnInit(E->window)) {
|
||||
Debug::log(LOG, "Window SHOULD be floating on start.");
|
||||
|
|
|
@ -14,6 +14,11 @@ class Vector2D {
|
|||
// returns the scale
|
||||
double normalize();
|
||||
|
||||
Vector2D& operator=(Vector2D a) {
|
||||
this->x = a.x; this->y = a.y;
|
||||
|
||||
return *this;
|
||||
}
|
||||
Vector2D operator+(Vector2D a) {
|
||||
return Vector2D(this->x + a.x, this->y + a.y);
|
||||
}
|
||||
|
|
|
@ -16,6 +16,9 @@ void AnimationUtil::move() {
|
|||
// check if window needs an animation.
|
||||
window.setIsAnimated(false);
|
||||
|
||||
if (!window.getConstructed())
|
||||
continue;
|
||||
|
||||
// Border animations
|
||||
if (window.getDrawable() > 0) {
|
||||
if (window.getEffectiveBorderColor().getAsUint32() != window.getRealBorderColor().getAsUint32() /* As uint32 to round and not spam */) {
|
||||
|
|
|
@ -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) {
|
||||
return r == B.r && g == B.g && b == B.b && a == B.a;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "window.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() { }
|
||||
|
||||
void CWindow::generateNodeID() {
|
||||
|
|
|
@ -35,6 +35,9 @@ public:
|
|||
|
||||
EXPOSED_MEMBER(Name, 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
|
||||
EXPOSED_MEMBER(Dirty, bool, b);
|
||||
|
|
|
@ -762,6 +762,16 @@ CWindow* CWindowManager::findWindowAtCursor() {
|
|||
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) {
|
||||
|
||||
// Get the parent and both children, one of which will be pWindow
|
||||
|
@ -1268,6 +1278,10 @@ void CWindowManager::moveActiveWindowToWorkspace(int workspace) {
|
|||
setFocusedWindow(newLastWindow);
|
||||
}
|
||||
|
||||
CWindow newWindow;
|
||||
newWindow.setDrawable(SAVEDDRAWABLE);
|
||||
newWindow.setFirstOpen(false);
|
||||
addWindowToVectorSafe(newWindow);
|
||||
|
||||
CWindow* PNEWWINDOW = nullptr;
|
||||
if (SAVEDFLOATSTATUS)
|
||||
|
@ -1577,10 +1591,12 @@ void CWindowManager::setAWindowTop(xcb_window_t window) {
|
|||
bool CWindowManager::shouldBeFloatedOnInit(int64_t window) {
|
||||
// Should be floated also sets some properties
|
||||
|
||||
// get stuffza
|
||||
const auto PWINDOW = getWindowFromDrawable(window);
|
||||
|
||||
// floating for krunner
|
||||
// TODO: config this
|
||||
if (!PWINDOW) {
|
||||
Debug::log(ERR, "shouldBeFloatedOnInit with an invalid window!");
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto WINCLASS = getClassName(window);
|
||||
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");
|
||||
|
||||
// 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
|
||||
const auto WINROLE = getRoleName(window);
|
||||
|
||||
Debug::log(LOG, "Window opened with a role of " + WINROLE);
|
||||
|
||||
for (auto& rule : ConfigManager::windowRules) {
|
||||
// check if we have a role rule
|
||||
if (rule.szValue.find("role:") != 0)
|
||||
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;
|
||||
}
|
||||
// Set it in the pwindow
|
||||
PWINDOW->setClassName(CLASSNAME);
|
||||
PWINDOW->setRoleName(WINROLE);
|
||||
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -103,6 +103,8 @@ public:
|
|||
// finds a window that's tiled at cursor.
|
||||
CWindow* findWindowAtCursor();
|
||||
|
||||
CWindow* findFirstWindowOnWorkspace(const int&);
|
||||
|
||||
bool shouldBeFloatedOnInit(int64_t);
|
||||
void doPostCreationChecks(CWindow*);
|
||||
void getICCCMWMProtocols(CWindow*);
|
||||
|
|
Loading…
Reference in a new issue