mirror of
https://github.com/hyprwm/Hypr.git
synced 2024-11-24 06:15:57 +01:00
Added pseudotiling
This commit is contained in:
parent
0a40030e35
commit
31694d4a49
10 changed files with 113 additions and 31 deletions
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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:
|
||||
|
||||
};
|
|
@ -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.");
|
||||
}
|
||||
}
|
|
@ -84,6 +84,7 @@ public:
|
|||
void refocusWindowOnClosed();
|
||||
|
||||
void calculateNewWindowParams(CWindow*);
|
||||
void getICCCMSizeHints(CWindow*);
|
||||
void fixWindowOnClose(CWindow*);
|
||||
void closeWindowAllChecks(int64_t);
|
||||
|
||||
|
|
Loading…
Reference in a new issue