Added pseudotiling

This commit is contained in:
vaxerski 2022-03-22 16:17:18 +01:00
parent 0a40030e35
commit 31694d4a49
10 changed files with 113 additions and 31 deletions

View File

@ -1,4 +1,7 @@
cmake_minimum_required(VERSION 3.4)
set(CMAKE_CXX_COMPILER "/bin/g++")
project(Hypr
VERSION 0.1
DESCRIPTION "A Modern OOP C++ Window Manager"

View File

@ -68,6 +68,7 @@ windowrule=float,role:task_dialog
windowrule=monitor 0,class:krunner
windowrule=size 500 50,class:krunner
windowrule=move 700 500,class:krunner
windowrule=pseudo,class:discord
# keybinds
bind=SUPER,R,exec,dmenu_run

View File

@ -189,12 +189,17 @@ void KeybindManager::toggleActiveWindowFloating(std::string unusedArg) {
const auto RESTOREACPOS = PWINDOW->getDefaultPosition();
const auto RESTOREWINID = PWINDOW->getDrawable();
const auto RESTORECANKILL = PWINDOW->getCanKill();
const auto RESTOREPSEUDO = PWINDOW->getPseudoSize();
const auto RESTOREISPSEUDO = PWINDOW->getIsPseudotiled();
const auto RESTOREREALS = PWINDOW->getRealSize();
const auto RESTOREREALP = PWINDOW->getRealPosition();
g_pWindowManager->removeWindowFromVectorSafe(PWINDOW->getDrawable());
CWindow newWindow;
newWindow.setDrawable(RESTOREWINID);
newWindow.setFirstOpen(false);
newWindow.setConstructed(false);
g_pWindowManager->addWindowToVectorSafe(newWindow);
const auto PNEWWINDOW = Events::remapWindow(RESTOREWINID, true);
@ -202,6 +207,10 @@ void KeybindManager::toggleActiveWindowFloating(std::string unusedArg) {
PNEWWINDOW->setDefaultPosition(RESTOREACPOS);
PNEWWINDOW->setDefaultSize(RESTOREACSIZE);
PNEWWINDOW->setCanKill(RESTORECANKILL);
PNEWWINDOW->setPseudoSize(RESTOREPSEUDO);
PNEWWINDOW->setIsPseudotiled(RESTOREISPSEUDO);
PNEWWINDOW->setRealPosition(RESTOREREALP);
PNEWWINDOW->setRealSize(RESTOREREALS);
}
// EWMH to let everyone know
@ -215,4 +224,15 @@ void KeybindManager::toggleActiveWindowFloating(std::string unusedArg) {
void KeybindManager::changeSplitRatio(std::string args) {
g_pWindowManager->changeSplitRatioCurrent(args[0]);
}
void KeybindManager::togglePseudoActive(std::string args) {
const auto PWINDOW = g_pWindowManager->getWindowFromDrawable(g_pWindowManager->LastWindow);
if (!PWINDOW)
return;
PWINDOW->setIsPseudotiled(!PWINDOW->getIsPseudotiled());
PWINDOW->setDirty(true);
}

View File

@ -28,4 +28,5 @@ namespace KeybindManager {
void toggleActiveWindowFloating(std::string args);
void movetoworkspace(std::string args);
void changeSplitRatio(std::string args);
void togglePseudoActive(std::string args);
};

View File

@ -125,6 +125,7 @@ void handleBind(const std::string& command, const std::string& value) {
if (HANDLER == "lastworkspace") dispatcher = KeybindManager::changetolastworkspace;
if (HANDLER == "togglefloating") dispatcher = KeybindManager::toggleActiveWindowFloating;
if (HANDLER == "splitratio") dispatcher = KeybindManager::changeSplitRatio;
if (HANDLER == "pseudo") dispatcher = KeybindManager::togglePseudoActive;
if (dispatcher && KEY != 0)
KeybindManager::keybinds.push_back(Keybind(KeybindManager::modToMask(MOD), KEY, COMMAND, dispatcher));
@ -240,6 +241,7 @@ void handleWindowRule(const std::string& command, const std::string& value) {
&& RULE.find("move") != 0
&& RULE.find("size") != 0
&& RULE.find("nointerventions") != 0
&& RULE.find("pseudo") != 0
&& RULE.find("monitor") != 0) {
Debug::log(ERR, "Invalid rule found: " + RULE);
ConfigManager::parseError = "Invalid rule found: " + RULE;
@ -486,15 +488,23 @@ std::vector<SWindowRule> ConfigManager::getMatchingRules(xcb_window_t w) {
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:")));
try {
std::regex classCheck(rule.szValue.substr(strlen("class:")));
if (!std::regex_search(PWINDOW->getClassName(), classCheck))
continue;
if (!std::regex_search(PWINDOW->getClassName(), classCheck))
continue;
} catch (...) {
Debug::log(ERR, "Regex error at " + rule.szValue);
}
} else if (rule.szValue.find("role:") == 0) {
std::regex roleCheck(rule.szValue.substr(strlen("role:")));
try {
std::regex roleCheck(rule.szValue.substr(strlen("role:")));
if (!std::regex_search(PWINDOW->getRoleName(), roleCheck))
continue;
if (!std::regex_search(PWINDOW->getRoleName(), roleCheck))
continue;
} catch (...) {
Debug::log(ERR, "Regex error at " + rule.szValue);
}
} else {
continue;
}

View File

@ -213,6 +213,10 @@ CWindow* Events::remapFloatingWindow(int windowID, int forcemonitor) {
Debug::log(LOG, "Rule monitor failed, rule: " + rule.szRule + "=" + rule.szValue);
}
}
if (rule.szRule.find("pseudo") == 0) {
PWINDOWINARR->setIsPseudotiled(true);
}
}
const auto CURRENTSCREEN = forcemonitor != -1 ? forcemonitor : PMONITOR->ID;
@ -325,27 +329,14 @@ CWindow* Events::remapFloatingWindow(int windowID, int forcemonitor) {
//
//
// ICCCM
g_pWindowManager->getICCCMSizeHints(PWINDOWINARR);
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, 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)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 - PWINDOWINARR->getDefaultSize();
if (nextWindowCentered /* Basically means dialog */) {
auto DELTA = PWINDOWINARR->getPseudoSize() - PWINDOWINARR->getDefaultSize();
// update
PWINDOWINARR->setDefaultSize(NEWSIZE);
PWINDOWINARR->setDefaultSize(PWINDOWINARR->getPseudoSize());
PWINDOWINARR->setDefaultPosition(PWINDOWINARR->getDefaultPosition() - DELTA / 2.f);
} else if (!succ) {
Debug::log(ERR, "ICCCM Size Hints failed.");
}
// Check the size and pos rules
@ -453,6 +444,10 @@ CWindow* Events::remapWindow(int windowID, bool wasfloating, int forcemonitor) {
Debug::log(LOG, "Rule monitor failed, rule: " + rule.szRule + "=" + rule.szValue);
}
}
if (rule.szRule.find("pseudo") == 0) {
PWINDOWINARR->setIsPseudotiled(true);
}
}
if (g_pWindowManager->getWindowFromDrawable(g_pWindowManager->LastWindow) && forcemonitor == -1 && PMONITOR->ID != g_pWindowManager->getWindowFromDrawable(g_pWindowManager->LastWindow)->getMonitor()) {
@ -500,6 +495,8 @@ CWindow* Events::remapWindow(int windowID, bool wasfloating, int forcemonitor) {
}
}
g_pWindowManager->getICCCMSizeHints(PWINDOWINARR);
// 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 || (forcemonitor != -1 && forcemonitor != PMONITOR->ID)) {
@ -763,6 +760,7 @@ void Events::eventMotionNotify(xcb_generic_event_t* event) {
PACTINGWINDOW->setDefaultSize(PACTINGWINDOW->getSize());
PACTINGWINDOW->setEffectiveSize(PACTINGWINDOW->getSize());
PACTINGWINDOW->setRealSize(PACTINGWINDOW->getSize());
PACTINGWINDOW->setPseudoSize(PACTINGWINDOW->getSize());
PACTINGWINDOW->setDirty(true);
}

View File

@ -1,7 +1,7 @@
#include "window.hpp"
#include "windowManager.hpp"
CWindow::CWindow() { this->setSplitRatio(1); this->setDockHidden(false); 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() { this->setIsPseudotiled(false); this->setSplitRatio(1); this->setDockHidden(false); 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() {

View File

@ -108,6 +108,10 @@ public:
EXPOSED_MEMBER(Children, std::vector<int64_t>, vec);
EXPOSED_MEMBER(Transient, bool, b);
// Pseudotiling
EXPOSED_MEMBER(IsPseudotiled, bool, b);
EXPOSED_MEMBER(PseudoSize, Vector2D, vec);
private:
};

View File

@ -899,21 +899,51 @@ void CWindowManager::setEffectiveSizePosUsingConfig(CWindow* pWindow) {
const auto GAPSOUT = ConfigManager::getInt("gaps_out");
const auto GAPSIN = ConfigManager::getInt("gaps_in");
pWindow->setEffectivePosition(pWindow->getPosition() + Vector2D(BORDERSIZE, BORDERSIZE));
pWindow->setEffectiveSize(pWindow->getSize() - (Vector2D(BORDERSIZE, BORDERSIZE) * 2));
auto TEMPEFFECTIVESIZE = pWindow->getSize();
auto TEMPEFFECTIVEPOS = pWindow->getPosition();
const auto OFFSETTOPLEFT = Vector2D(DISPLAYLEFT ? GAPSOUT + MONITOR->vecReservedTopLeft.x : GAPSIN,
DISPLAYTOP ? GAPSOUT + MONITOR->vecReservedTopLeft.y : GAPSIN);
DISPLAYTOP ? GAPSOUT + MONITOR->vecReservedTopLeft.y : GAPSIN);
const auto OFFSETBOTTOMRIGHT = Vector2D( DISPLAYRIGHT ? GAPSOUT + MONITOR->vecReservedBottomRight.x : GAPSIN,
const auto OFFSETBOTTOMRIGHT = Vector2D(DISPLAYRIGHT ? GAPSOUT + MONITOR->vecReservedBottomRight.x : GAPSIN,
DISPLAYBOTTOM ? GAPSOUT + MONITOR->vecReservedBottomRight.y : GAPSIN);
TEMPEFFECTIVEPOS = TEMPEFFECTIVEPOS + Vector2D(BORDERSIZE, BORDERSIZE);
TEMPEFFECTIVESIZE = TEMPEFFECTIVESIZE - (Vector2D(BORDERSIZE, BORDERSIZE) * 2);
// do gaps, set top left
pWindow->setEffectivePosition(pWindow->getEffectivePosition() + OFFSETTOPLEFT);
TEMPEFFECTIVEPOS = TEMPEFFECTIVEPOS + OFFSETTOPLEFT;
// fix to old size bottom right
pWindow->setEffectiveSize(pWindow->getEffectiveSize() - OFFSETTOPLEFT);
TEMPEFFECTIVESIZE = TEMPEFFECTIVESIZE - OFFSETTOPLEFT;
// set bottom right
pWindow->setEffectiveSize(pWindow->getEffectiveSize() - OFFSETBOTTOMRIGHT);
TEMPEFFECTIVESIZE = TEMPEFFECTIVESIZE - OFFSETBOTTOMRIGHT;
if (pWindow->getIsPseudotiled()) {
float scale = 1;
// adjust if doesnt fit
if (pWindow->getPseudoSize().x > TEMPEFFECTIVESIZE.x || pWindow->getPseudoSize().y > TEMPEFFECTIVESIZE.y) {
if (pWindow->getPseudoSize().x > TEMPEFFECTIVESIZE.x) {
scale = TEMPEFFECTIVESIZE.x / pWindow->getPseudoSize().x;
}
if (pWindow->getPseudoSize().y * scale > TEMPEFFECTIVESIZE.y) {
scale = TEMPEFFECTIVESIZE.y / pWindow->getPseudoSize().y;
}
auto DELTA = TEMPEFFECTIVESIZE - pWindow->getPseudoSize() * scale;
TEMPEFFECTIVESIZE = pWindow->getPseudoSize() * scale;
TEMPEFFECTIVEPOS = TEMPEFFECTIVEPOS + DELTA / 2.f; // center
} else {
auto DELTA = TEMPEFFECTIVESIZE - pWindow->getPseudoSize();
TEMPEFFECTIVEPOS = TEMPEFFECTIVEPOS + DELTA / 2.f; // center
TEMPEFFECTIVESIZE = pWindow->getPseudoSize();
}
}
pWindow->setEffectivePosition(TEMPEFFECTIVEPOS);
pWindow->setEffectiveSize(TEMPEFFECTIVESIZE);
}
CWindow* CWindowManager::findWindowAtCursor() {
@ -2465,4 +2495,18 @@ void CWindowManager::changeSplitRatioCurrent(const char& dir) {
Debug::log(LOG, "Changed SplitRatio of " + std::to_string(PARENT->getDrawable()) + " to " + std::to_string(PARENT->getSplitRatio()) + " (" + dir + ")" );
recalcEntireWorkspace(CURRENT->getWorkspaceID());
}
void CWindowManager::getICCCMSizeHints(CWindow* pWindow) {
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, pWindow->getDrawable()), &sizeHints, NULL);
if (succ) {
auto NEWSIZE = Vector2D(std::max(std::max(sizeHints.width, (int32_t)pWindow->getDefaultSize().x), std::max(sizeHints.max_width > g_pWindowManager->monitors[pWindow->getMonitor()].vecSize.x ? 0 : sizeHints.max_width, sizeHints.base_width)),
std::max(std::max(sizeHints.height, (int32_t)pWindow->getDefaultSize().y), std::max(sizeHints.max_height > g_pWindowManager->monitors[pWindow->getMonitor()].vecSize.y ? 0 : sizeHints.max_height, sizeHints.base_height)));
pWindow->setPseudoSize(NEWSIZE);
} else {
Debug::log(ERR, "ICCCM Size Hints failed.");
}
}

View File

@ -84,6 +84,7 @@ public:
void refocusWindowOnClosed();
void calculateNewWindowParams(CWindow*);
void getICCCMSizeHints(CWindow*);
void fixWindowOnClose(CWindow*);
void closeWindowAllChecks(int64_t);