mirror of
https://github.com/hyprwm/Hypr.git
synced 2024-11-22 13:35:57 +01:00
Added workspaces, one thing off the roadmap! 🎉
This commit is contained in:
parent
6d2c030439
commit
292a13ba04
8 changed files with 141 additions and 6 deletions
|
@ -14,7 +14,7 @@ Hypr is a Linux tiling window manager for Xorg. It's written in XCB with modern
|
||||||
- [ ] Status bar
|
- [ ] Status bar
|
||||||
- [ ] Floating windows support
|
- [ ] Floating windows support
|
||||||
- [ ] Config system
|
- [ ] Config system
|
||||||
- [ ] Workspaces
|
- [x] Workspaces
|
||||||
- [ ] Moving windows / user input (e.g. fullscreening)
|
- [ ] Moving windows / user input (e.g. fullscreening)
|
||||||
- [ ] True lerp animations
|
- [ ] True lerp animations
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,12 @@ void KeybindManager::reloadAllKeybinds() {
|
||||||
KeybindManager::keybinds.push_back(Keybind(MOD_SUPER, 0xff53 /* > */, "r", &KeybindManager::movewindow));
|
KeybindManager::keybinds.push_back(Keybind(MOD_SUPER, 0xff53 /* > */, "r", &KeybindManager::movewindow));
|
||||||
KeybindManager::keybinds.push_back(Keybind(MOD_SUPER, 0xff52 /* ^ */, "t", &KeybindManager::movewindow));
|
KeybindManager::keybinds.push_back(Keybind(MOD_SUPER, 0xff52 /* ^ */, "t", &KeybindManager::movewindow));
|
||||||
KeybindManager::keybinds.push_back(Keybind(MOD_SUPER, 0xff54 /* v */, "b", &KeybindManager::movewindow));
|
KeybindManager::keybinds.push_back(Keybind(MOD_SUPER, 0xff54 /* v */, "b", &KeybindManager::movewindow));
|
||||||
|
|
||||||
|
// workspace binds
|
||||||
|
for (int i = 0; i < 10; ++i) {
|
||||||
|
// MOD + 1-9
|
||||||
|
KeybindManager::keybinds.push_back(Keybind(MOD_SUPER, 0x31 + i, std::to_string(i + 1), &KeybindManager::changeworkspace));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int KeybindManager::modToMask(MODS mod) {
|
unsigned int KeybindManager::modToMask(MODS mod) {
|
||||||
|
@ -105,4 +111,20 @@ void KeybindManager::call(std::string args) {
|
||||||
|
|
||||||
void KeybindManager::movewindow(std::string arg) {
|
void KeybindManager::movewindow(std::string arg) {
|
||||||
g_pWindowManager->moveActiveWindowTo(arg[0]);
|
g_pWindowManager->moveActiveWindowTo(arg[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeybindManager::changeworkspace(std::string arg) {
|
||||||
|
int ID = -1;
|
||||||
|
try {
|
||||||
|
ID = std::stoi(arg.c_str());
|
||||||
|
} catch (...) { ; }
|
||||||
|
|
||||||
|
if (ID != -1) {
|
||||||
|
Debug::log(LOG, "Changing the current workspace to " + std::to_string(ID));
|
||||||
|
|
||||||
|
// vvvv shouldn't be nullptr wallah
|
||||||
|
g_pWindowManager->setAllWorkspaceWindowsDirtyByID(g_pWindowManager->activeWorkspace->getID());
|
||||||
|
g_pWindowManager->changeWorkspaceByID(ID);
|
||||||
|
g_pWindowManager->setAllWorkspaceWindowsDirtyByID(ID);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -18,4 +18,5 @@ namespace KeybindManager {
|
||||||
void call(std::string args);
|
void call(std::string args);
|
||||||
void killactive(std::string args);
|
void killactive(std::string args);
|
||||||
void movewindow(std::string args);
|
void movewindow(std::string args);
|
||||||
|
void changeworkspace(std::string args);
|
||||||
};
|
};
|
|
@ -41,6 +41,7 @@ void Events::eventMapWindow(xcb_generic_event_t* event) {
|
||||||
window.setDrawable(E->window);
|
window.setDrawable(E->window);
|
||||||
window.setIsFloating(false);
|
window.setIsFloating(false);
|
||||||
window.setDirty(true);
|
window.setDirty(true);
|
||||||
|
window.setWorkspaceID(g_pWindowManager->activeWorkspace->getID());
|
||||||
|
|
||||||
// Also sets the old one
|
// Also sets the old one
|
||||||
g_pWindowManager->calculateNewWindowParams(&window);
|
g_pWindowManager->calculateNewWindowParams(&window);
|
||||||
|
|
9
src/utilities/Workspace.hpp
Normal file
9
src/utilities/Workspace.hpp
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../defines.hpp"
|
||||||
|
|
||||||
|
class CWorkspace {
|
||||||
|
public:
|
||||||
|
EXPOSED_MEMBER(ID, int, i);
|
||||||
|
EXPOSED_MEMBER(LastWindow, xcb_drawable_t, i);
|
||||||
|
};
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "defines.hpp"
|
#include "defines.hpp"
|
||||||
|
#include "utilities/Workspace.hpp"
|
||||||
|
|
||||||
class CWindow {
|
class CWindow {
|
||||||
public:
|
public:
|
||||||
|
@ -24,6 +25,9 @@ public:
|
||||||
EXPOSED_MEMBER(Position, Vector2D, vec);
|
EXPOSED_MEMBER(Position, Vector2D, vec);
|
||||||
EXPOSED_MEMBER(IsFloating, bool, b);
|
EXPOSED_MEMBER(IsFloating, bool, b);
|
||||||
EXPOSED_MEMBER(Drawable, xcb_drawable_t, i);
|
EXPOSED_MEMBER(Drawable, xcb_drawable_t, i);
|
||||||
|
|
||||||
|
// Workspace pointer
|
||||||
|
EXPOSED_MEMBER(WorkspaceID, int, i);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -28,6 +28,13 @@ void CWindowManager::setupManager() {
|
||||||
3, KeybindManager::modToMask(MOD_SUPER));
|
3, KeybindManager::modToMask(MOD_SUPER));
|
||||||
|
|
||||||
xcb_flush(DisplayConnection);
|
xcb_flush(DisplayConnection);
|
||||||
|
|
||||||
|
// Add a workspace to the monitor
|
||||||
|
CWorkspace protoWorkspace;
|
||||||
|
protoWorkspace.setID(1);
|
||||||
|
workspaces.push_back(protoWorkspace);
|
||||||
|
activeWorkspace = &workspaces[0];
|
||||||
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWindowManager::handleEvent() {
|
bool CWindowManager::handleEvent() {
|
||||||
|
@ -70,15 +77,59 @@ bool CWindowManager::handleEvent() {
|
||||||
// refresh and apply the parameters of all dirty windows.
|
// refresh and apply the parameters of all dirty windows.
|
||||||
refreshDirtyWindows();
|
refreshDirtyWindows();
|
||||||
|
|
||||||
|
// remove unused workspaces
|
||||||
|
cleanupUnusedWorkspaces();
|
||||||
|
|
||||||
xcb_flush(DisplayConnection);
|
xcb_flush(DisplayConnection);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CWindowManager::cleanupUnusedWorkspaces() {
|
||||||
|
std::vector<CWorkspace> temp = workspaces;
|
||||||
|
|
||||||
|
workspaces.clear();
|
||||||
|
|
||||||
|
for (auto& work : temp) {
|
||||||
|
if (work.getID() != activeWorkspace->getID()) {
|
||||||
|
// check if it has any children
|
||||||
|
bool hasChildren = false;
|
||||||
|
for (auto& window : windows) {
|
||||||
|
if (window.getWorkspaceID() == work.getID()) {
|
||||||
|
hasChildren = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasChildren) {
|
||||||
|
// Has windows opened on it.
|
||||||
|
workspaces.push_back(work);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Foreground workspace
|
||||||
|
workspaces.push_back(work);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CWindowManager::refreshDirtyWindows() {
|
void CWindowManager::refreshDirtyWindows() {
|
||||||
for(auto& window : windows) {
|
for(auto& window : windows) {
|
||||||
if (window.getDirty()) {
|
if (window.getDirty()) {
|
||||||
|
|
||||||
|
// first and foremost, let's check if the window isn't on a different workspace
|
||||||
|
if (window.getWorkspaceID() != activeWorkspace->getID()) {
|
||||||
|
// Move it to hades
|
||||||
|
Values[0] = (int)1500000; // hmu when monitors actually have that many pixels
|
||||||
|
Values[1] = (int)1500000; // and we are still using xorg =)
|
||||||
|
xcb_configure_window(DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, Values);
|
||||||
|
|
||||||
|
// Set the size JIC.
|
||||||
|
Values[0] = (int)window.getEffectiveSize().x;
|
||||||
|
Values[1] = (int)window.getEffectiveSize().y;
|
||||||
|
xcb_configure_window(DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, Values);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
Values[0] = (int)window.getEffectiveSize().x;
|
Values[0] = (int)window.getEffectiveSize().x;
|
||||||
Values[1] = (int)window.getEffectiveSize().y;
|
Values[1] = (int)window.getEffectiveSize().y;
|
||||||
|
@ -224,6 +275,10 @@ void CWindowManager::calculateNewWindowParams(CWindow* pWindow) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWindowManager::isNeighbor(CWindow* a, CWindow* b) {
|
bool CWindowManager::isNeighbor(CWindow* a, CWindow* b) {
|
||||||
|
|
||||||
|
if (a->getWorkspaceID() != b->getWorkspaceID())
|
||||||
|
return false; // Different workspaces
|
||||||
|
|
||||||
const auto POSA = a->getPosition();
|
const auto POSA = a->getPosition();
|
||||||
const auto POSB = b->getPosition();
|
const auto POSB = b->getPosition();
|
||||||
const auto SIZEA = a->getSize();
|
const auto SIZEA = a->getSize();
|
||||||
|
@ -274,7 +329,7 @@ bool CWindowManager::canEatWindow(CWindow* a, CWindow* toEat) {
|
||||||
};
|
};
|
||||||
|
|
||||||
for (auto& w : windows) {
|
for (auto& w : windows) {
|
||||||
if (w.getDrawable() == a->getDrawable() || w.getDrawable() == toEat->getDrawable())
|
if (w.getDrawable() == a->getDrawable() || w.getDrawable() == toEat->getDrawable() || w.getWorkspaceID() != toEat->getWorkspaceID())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (doOverlap(&w))
|
if (doOverlap(&w))
|
||||||
|
@ -335,7 +390,7 @@ CWindow* CWindowManager::getNeighborInDir(char dir) {
|
||||||
const auto SIZEA = CURRENTWINDOW->getSize();
|
const auto SIZEA = CURRENTWINDOW->getSize();
|
||||||
|
|
||||||
for (auto& w : windows) {
|
for (auto& w : windows) {
|
||||||
if (w.getDrawable() == CURRENTWINDOW->getDrawable())
|
if (w.getDrawable() == CURRENTWINDOW->getDrawable() || w.getWorkspaceID() != CURRENTWINDOW->getWorkspaceID())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const auto POSB = w.getPosition();
|
const auto POSB = w.getPosition();
|
||||||
|
@ -409,4 +464,39 @@ void CWindowManager::moveActiveWindowTo(char dir) {
|
||||||
|
|
||||||
// finish by moving the cursor to the current window
|
// finish by moving the cursor to the current window
|
||||||
warpCursorTo(CURRENTWINDOW->getPosition() + CURRENTWINDOW->getSize() / 2.f);
|
warpCursorTo(CURRENTWINDOW->getPosition() + CURRENTWINDOW->getSize() / 2.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWindowManager::changeWorkspaceByID(int ID) {
|
||||||
|
for (auto& workspace : workspaces) {
|
||||||
|
if (workspace.getID() == ID) {
|
||||||
|
activeWorkspace = &workspace;
|
||||||
|
LastWindow = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we are here it means the workspace is new. Let's create it.
|
||||||
|
CWorkspace newWorkspace;
|
||||||
|
newWorkspace.setID(ID);
|
||||||
|
workspaces.push_back(newWorkspace);
|
||||||
|
activeWorkspace = &workspaces[workspaces.size() - 1];
|
||||||
|
LastWindow = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWindowManager::setAllWorkspaceWindowsDirtyByID(int ID) {
|
||||||
|
int workspaceID = -1;
|
||||||
|
for (auto& workspace : workspaces) {
|
||||||
|
if (workspace.getID() == ID) {
|
||||||
|
workspaceID = workspace.getID();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (workspaceID == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (auto& window : windows) {
|
||||||
|
if (window.getWorkspaceID() == workspaceID)
|
||||||
|
window.setDirty(true);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -6,6 +6,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "KeybindManager.hpp"
|
#include "KeybindManager.hpp"
|
||||||
|
#include "./utilities/Workspace.hpp"
|
||||||
|
|
||||||
|
|
||||||
// temp config values
|
// temp config values
|
||||||
|
@ -23,6 +24,9 @@ public:
|
||||||
std::vector<CWindow> windows; // windows never left. It has always been hiding amongst us.
|
std::vector<CWindow> windows; // windows never left. It has always been hiding amongst us.
|
||||||
xcb_drawable_t LastWindow = -1;
|
xcb_drawable_t LastWindow = -1;
|
||||||
|
|
||||||
|
std::vector<CWorkspace> workspaces;
|
||||||
|
CWorkspace* activeWorkspace = nullptr;
|
||||||
|
|
||||||
CWindow* getWindowFromDrawable(xcb_drawable_t);
|
CWindow* getWindowFromDrawable(xcb_drawable_t);
|
||||||
void addWindowToVectorSafe(CWindow);
|
void addWindowToVectorSafe(CWindow);
|
||||||
void removeWindowFromVectorSafe(xcb_drawable_t);
|
void removeWindowFromVectorSafe(xcb_drawable_t);
|
||||||
|
@ -39,17 +43,21 @@ public:
|
||||||
void moveActiveWindowTo(char);
|
void moveActiveWindowTo(char);
|
||||||
void warpCursorTo(Vector2D);
|
void warpCursorTo(Vector2D);
|
||||||
|
|
||||||
|
void changeWorkspaceByID(int);
|
||||||
|
void setAllWorkspaceWindowsDirtyByID(int);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// Internal WM functions that don't have to be exposed
|
// Internal WM functions that don't have to be exposed
|
||||||
|
|
||||||
CWindow* getNeighborInDir(char dir);
|
CWindow* getNeighborInDir(char dir);
|
||||||
void eatWindow(CWindow* a, CWindow* toEat);
|
void eatWindow(CWindow* a, CWindow* toEat);
|
||||||
bool canEatWindow(CWindow* a, CWindow* toEat);
|
bool canEatWindow(CWindow* a, CWindow* toEat);
|
||||||
bool isNeighbor(CWindow* a, CWindow* b);
|
bool isNeighbor(CWindow* a, CWindow* b);
|
||||||
void calculateNewTileSetOldTile(CWindow* pWindow);
|
void calculateNewTileSetOldTile(CWindow* pWindow);
|
||||||
void setEffectiveSizePosUsingConfig(CWindow* pWindow);
|
void setEffectiveSizePosUsingConfig(CWindow* pWindow);
|
||||||
|
void cleanupUnusedWorkspaces();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::unique_ptr<CWindowManager> g_pWindowManager = std::make_unique<CWindowManager>();
|
inline std::unique_ptr<CWindowManager> g_pWindowManager = std::make_unique<CWindowManager>();
|
||||||
|
|
Loading…
Reference in a new issue