Basic CFG system

This commit is contained in:
vaxerski 2021-11-21 12:40:03 +01:00
parent 0a5c4b46f9
commit 5a5ecafd91
8 changed files with 226 additions and 58 deletions

View File

@ -13,7 +13,7 @@ Hypr is a Linux tiling window manager for Xorg. It's written in XCB with modern
- [ ] Multi-monitor support
- [x] Status bar ~ UNFINISHED, someone help please
- [ ] Floating windows support
- [ ] Config system
- [x] Config system ~ Basic done
- [x] Workspaces
- [x] Moving windows / user input (e.g. fullscreening) ~ More to be done probably
- [ ] True lerp animations

View File

@ -6,15 +6,34 @@
#include "../windowManager.hpp"
void CStatusBar::setup(Vector2D origin, Vector2D size) {
m_vecPosition = origin;
m_vecSize = size;
if (origin.x != -1 && origin.y != -1) {
m_vecPosition = origin;
}
if (size.x != -1 && size.y != -1) {
m_vecSize = size;
}
uint32_t values[4];
// window
m_iWindowID = (xcb_generate_id(g_pWindowManager->DisplayConnection));
values[0] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE;
xcb_create_window(g_pWindowManager->DisplayConnection, g_pWindowManager->Depth, m_iWindowID,
g_pWindowManager->Screen->root, m_vecPosition.x, m_vecPosition.y, m_vecSize.x, m_vecSize.y,
0, XCB_WINDOW_CLASS_INPUT_OUTPUT, g_pWindowManager->Screen->root_visual,
XCB_CW_EVENT_MASK, values);
// map
xcb_map_window(g_pWindowManager->DisplayConnection, m_iWindowID);
// Create a pixmap for writing to.
m_iPixmap = xcb_generate_id(g_pWindowManager->DisplayConnection);
xcb_create_pixmap(g_pWindowManager->DisplayConnection, g_pWindowManager->Depth, m_iPixmap, m_iWindowID, m_vecSize.x, m_vecSize.y);
// setup contexts.. ugh.
uint32_t values[4];
// setup contexts.. ugh..
auto contextBG = &m_mContexts["BG"];
contextBG->GContext = xcb_generate_id(g_pWindowManager->DisplayConnection);
@ -63,6 +82,17 @@ void CStatusBar::setup(Vector2D origin, Vector2D size) {
//xcb_close_font(g_pWindowManager->DisplayConnection, contextBASETEXT->Font);
}
void CStatusBar::destroy() {
xcb_close_font(g_pWindowManager->DisplayConnection, m_mContexts["HITEXT"].Font);
xcb_destroy_window(g_pWindowManager->DisplayConnection, m_iWindowID);
xcb_destroy_window(g_pWindowManager->DisplayConnection, m_iPixmap);
xcb_free_gc(g_pWindowManager->DisplayConnection, m_mContexts["BG"].GContext);
xcb_free_gc(g_pWindowManager->DisplayConnection, m_mContexts["MEDBG"].GContext);
xcb_free_gc(g_pWindowManager->DisplayConnection, m_mContexts["TEXT"].GContext);
xcb_free_gc(g_pWindowManager->DisplayConnection, m_mContexts["HITEXT"].GContext);
}
int getTextWidth(std::string text, xcb_font_t font) {
// conv from utf8 to UCS-2 (what the fuck Xorg why)

View File

@ -16,6 +16,7 @@ public:
void draw();
void setup(Vector2D, Vector2D);
void destroy();
private:
Vector2D m_vecSize;

View File

@ -0,0 +1,142 @@
#include "ConfigManager.hpp"
#include "../windowManager.hpp"
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fstream>
#include <iostream>
void ConfigManager::init() {
configValues["border_size"].intValue = 1;
configValues["gaps_in"].intValue = 5;
configValues["gaps_out"].intValue = 20;
configValues["bar_height"].intValue = 15;
configValues["max_fps"].intValue = 60;
ConfigManager::loadConfigLoadVars();
}
void parseLine(std::string& line) {
// first check if its not a comment
const auto COMMENTSTART = line.find_first_of('#');
if (COMMENTSTART == 0)
return;
// now, cut the comment off
if (COMMENTSTART != std::string::npos)
line = line.substr(COMMENTSTART);
// And parse
// check if command
const auto EQUALSPLACE = line.find_first_of('=');
if (EQUALSPLACE == std::string::npos)
return;
const auto COMMAND = line.substr(0, EQUALSPLACE);
const auto VALUE = line.substr(EQUALSPLACE + 1);
if (ConfigManager::configValues.find(COMMAND) == ConfigManager::configValues.end())
return;
auto& CONFIGENTRY = ConfigManager::configValues.at(COMMAND);
if (CONFIGENTRY.intValue != -1) {
try {
CONFIGENTRY.intValue = stoi(VALUE);
} catch (...) {
Debug::log(WARN, "Error reading value of " + COMMAND);
}
} else if (CONFIGENTRY.floatValue != -1) {
try {
CONFIGENTRY.floatValue = stof(VALUE);
} catch (...) {
Debug::log(WARN, "Error reading value of " + COMMAND);
}
} else if (CONFIGENTRY.strValue != "") {
try {
CONFIGENTRY.strValue = VALUE;
} catch (...) {
Debug::log(WARN, "Error reading value of " + COMMAND);
}
}
}
void ConfigManager::loadConfigLoadVars() {
Debug::log(LOG, "Reloading the config!");
const char* const ENVHOME = getenv("HOME");
const std::string CONFIGPATH = ENVHOME + (std::string) "/.config/hypr/hypr.conf";
std::ifstream ifs;
ifs.open(CONFIGPATH.c_str());
if (!ifs.good()) {
Debug::log(WARN, "Config reading error. (No file?)");
return;
}
std::string line = "";
if (ifs.is_open()) {
while (std::getline(ifs, line)) {
// Read line by line.
parseLine(line);
}
}
ifs.close();
g_pWindowManager->setAllWindowsDirty();
// Reload the bar as well
g_pWindowManager->statusBar.destroy();
g_pWindowManager->statusBar.setup(Vector2D(-1,-1), Vector2D(g_pWindowManager->Screen->width_in_pixels, configValues["bar_height"].intValue));
}
void emptyEvent() {
xcb_expose_event_t exposeEvent;
exposeEvent.window = g_pWindowManager->statusBar.getWindowID();
exposeEvent.response_type = 0;
exposeEvent.x = 0;
exposeEvent.y = 0;
exposeEvent.width = g_pWindowManager->Screen->width_in_pixels;
exposeEvent.height = g_pWindowManager->Screen->height_in_pixels;
xcb_send_event(g_pWindowManager->DisplayConnection, false, g_pWindowManager->Screen->root, XCB_EVENT_MASK_EXPOSURE, (char*)&exposeEvent);
xcb_flush(g_pWindowManager->DisplayConnection);
}
void ConfigManager::tick() {
const char* const ENVHOME = getenv("HOME");
const std::string CONFIGPATH = ENVHOME + (std::string)"/.config/hypr/hypr.conf";
struct stat fileStat;
int err = stat(CONFIGPATH.c_str(), &fileStat);
if (err != 0) {
Debug::log(WARN, "Error at ticking config, error" + std::to_string(errno));
}
// check if we need to reload cfg
if(fileStat.st_mtime > lastModifyTime) {
lastModifyTime = fileStat.st_mtime;
ConfigManager::loadConfigLoadVars();
// so that the WM reloads the windows.
emptyEvent();
}
}
int ConfigManager::getInt(std::string_view v) {
return configValues[v].intValue;
}
float ConfigManager::getFloat(std::string_view v) {
return configValues[v].floatValue;
}
std::string ConfigManager::getString(std::string_view v) {
return configValues[v].strValue;
}

View File

@ -0,0 +1,23 @@
#pragma once
#include <map>
#include "../utilities/Debug.hpp"
struct SConfigValue {
int intValue = -1;
float floatValue = -1;
std::string strValue = "";
};
namespace ConfigManager {
inline std::map<std::string_view, SConfigValue> configValues;
inline time_t lastModifyTime = 0;
void init();
void loadConfigLoadVars();
void tick();
int getInt(std::string_view);
float getFloat(std::string_view);
std::string getString(std::string_view);
};

View File

@ -1,20 +1,10 @@
#include "events.hpp"
void Events::redraw() {
xcb_expose_event_t exposeEvent;
exposeEvent.window = g_pWindowManager->statusBar.getWindowID();
exposeEvent.response_type = XCB_EXPOSE;
exposeEvent.x = 0;
exposeEvent.y = 0;
exposeEvent.width = g_pWindowManager->Screen->width_in_pixels;
exposeEvent.height = g_pWindowManager->Screen->height_in_pixels;
xcb_send_event(g_pWindowManager->DisplayConnection, false, g_pWindowManager->statusBar.getWindowID(), XCB_EVENT_MASK_EXPOSURE, (char*)&exposeEvent);
xcb_flush(g_pWindowManager->DisplayConnection);
}
void handle(sigval val) {
//Events::redraw();
g_pWindowManager->statusBar.draw();
// check config
ConfigManager::tick();
}
void Events::setThread() {
@ -25,7 +15,7 @@ void Events::setThread() {
eventsig.sigev_value.sival_ptr = &timerid;
timer_create(CLOCK_REALTIME, &eventsig, &timerid);
itimerspec t = {{0, 1000 * (1000 / MAX_FPS)}, {1, 0}};
itimerspec t = {{0, 1000 * (1000 / ConfigManager::getInt("max_fps"))}, {1, 0}};
timer_settime(timerid, 0, &t, 0);
}

View File

@ -16,6 +16,7 @@ xcb_visualtype_t* CWindowManager::setupColors() {
void CWindowManager::setupManager() {
KeybindManager::reloadAllKeybinds();
ConfigManager::init();
Values[0] = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE;
xcb_change_window_attributes_checked(DisplayConnection, Screen->root,
@ -60,20 +61,7 @@ void CWindowManager::setupManager() {
// ---- INIT THE BAR ---- //
// window
statusBar.setWindowID(xcb_generate_id(DisplayConnection));
Values[0] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE;
xcb_create_window(DisplayConnection, Depth, statusBar.getWindowID(),
Screen->root, 0, 0, Screen->width_in_pixels, BAR_HEIGHT,
0, XCB_WINDOW_CLASS_INPUT_OUTPUT, Screen->root_visual,
XCB_CW_EVENT_MASK, Values);
// map
xcb_map_window(DisplayConnection, statusBar.getWindowID());
statusBar.setup(Vector2D(0, 0), Vector2D(Screen->width_in_pixels, BAR_HEIGHT));
statusBar.setup(Vector2D(0, 0), Vector2D(Screen->width_in_pixels, ConfigManager::getInt("bar_height")));
// start its' update thread
Events::setThread();
@ -163,6 +151,8 @@ void CWindowManager::refreshDirtyWindows() {
for(auto& window : windows) {
if (window.getDirty()) {
setEffectiveSizePosUsingConfig(&window);
// Fullscreen flag
bool bHasFullscreenWindow = activeWorkspace->getHasFullscreenWindow();
@ -211,13 +201,13 @@ void CWindowManager::refreshDirtyWindows() {
// Focused special border.
if (window.getDrawable() == LastWindow) {
Values[0] = (int)BORDERSIZE;
Values[0] = (int)ConfigManager::getInt("border_size");
xcb_configure_window(DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_BORDER_WIDTH, Values);
// Update the position because the border makes the window jump
// I have added the bordersize vec2d before in the setEffectiveSizePosUsingConfig function.
Values[0] = (int)window.getEffectivePosition().x - BORDERSIZE;
Values[1] = (int)window.getEffectivePosition().y - BORDERSIZE;
Values[0] = (int)window.getEffectivePosition().x - ConfigManager::getInt("border_size");
Values[1] = (int)window.getEffectivePosition().y - ConfigManager::getInt("border_size");
xcb_configure_window(DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, Values);
Values[0] = 0xFF3333; // RED :)
@ -294,15 +284,15 @@ void CWindowManager::setEffectiveSizePosUsingConfig(CWindow* pWindow) {
const bool DISPLAYTOP = pWindow->getPosition().y == 0;
const bool DISPLAYBOTTOM = pWindow->getPosition().y + pWindow->getSize().y == Screen->height_in_pixels;
pWindow->setEffectivePosition(pWindow->getPosition() + Vector2D(BORDERSIZE, BORDERSIZE));
pWindow->setEffectiveSize(pWindow->getSize() - (Vector2D(BORDERSIZE, BORDERSIZE) * 2));
pWindow->setEffectivePosition(pWindow->getPosition() + Vector2D(ConfigManager::getInt("border_size"), ConfigManager::getInt("border_size")));
pWindow->setEffectiveSize(pWindow->getSize() - (Vector2D(ConfigManager::getInt("border_size"), ConfigManager::getInt("border_size")) * 2));
// do gaps, set top left
pWindow->setEffectivePosition(pWindow->getEffectivePosition() + Vector2D(DISPLAYLEFT ? GAPS_OUT : GAPS_IN, DISPLAYTOP ? GAPS_OUT + BAR_HEIGHT : GAPS_IN));
pWindow->setEffectivePosition(pWindow->getEffectivePosition() + Vector2D(DISPLAYLEFT ? ConfigManager::getInt("gaps_out") : ConfigManager::getInt("gaps_in"), DISPLAYTOP ? ConfigManager::getInt("gaps_out") + ConfigManager::getInt("bar_height") : ConfigManager::getInt("gaps_in")));
// fix to old size bottom right
pWindow->setEffectiveSize(pWindow->getEffectiveSize() - Vector2D(DISPLAYLEFT ? GAPS_OUT : GAPS_IN, DISPLAYTOP ? GAPS_OUT + BAR_HEIGHT : GAPS_IN));
pWindow->setEffectiveSize(pWindow->getEffectiveSize() - Vector2D(DISPLAYLEFT ? ConfigManager::getInt("gaps_out") : ConfigManager::getInt("gaps_in"), DISPLAYTOP ? ConfigManager::getInt("gaps_out") + ConfigManager::getInt("bar_height") : ConfigManager::getInt("gaps_in")));
// set bottom right
pWindow->setEffectiveSize(pWindow->getEffectiveSize() - Vector2D(DISPLAYRIGHT ? GAPS_OUT : GAPS_IN, DISPLAYBOTTOM ? GAPS_OUT : GAPS_IN));
pWindow->setEffectiveSize(pWindow->getEffectiveSize() - Vector2D(DISPLAYRIGHT ? ConfigManager::getInt("gaps_out") : ConfigManager::getInt("gaps_in"), DISPLAYBOTTOM ? ConfigManager::getInt("gaps_out") : ConfigManager::getInt("gaps_in")));
}
void CWindowManager::calculateNewTileSetOldTile(CWindow* pWindow) {
@ -327,9 +317,6 @@ void CWindowManager::calculateNewTileSetOldTile(CWindow* pWindow) {
pWindow->setSize(Vector2D(Screen->width_in_pixels, Screen->height_in_pixels));
pWindow->setPosition(Vector2D(0, 0));
}
setEffectiveSizePosUsingConfig(pWindow);
setEffectiveSizePosUsingConfig(PLASTWINDOW);
}
void CWindowManager::calculateNewWindowParams(CWindow* pWindow) {
@ -449,8 +436,6 @@ void CWindowManager::fixWindowOnClose(CWindow* pClosedWindow) {
neighbor->setDirty(true);
setFocusedWindow(neighbor->getDrawable()); // Set focus. :)
setEffectiveSizePosUsingConfig(neighbor);
}
CWindow* CWindowManager::getNeighborInDir(char dir) {
@ -533,9 +518,6 @@ void CWindowManager::moveActiveWindowTo(char dir) {
CURRENTWINDOW->setDirty(true);
neighbor->setDirty(true);
setEffectiveSizePosUsingConfig(neighbor);
setEffectiveSizePosUsingConfig(CURRENTWINDOW);
// finish by moving the cursor to the current window
warpCursorTo(CURRENTWINDOW->getPosition() + CURRENTWINDOW->getSize() / 2.f);
}
@ -557,6 +539,12 @@ void CWindowManager::changeWorkspaceByID(int ID) {
LastWindow = -1;
}
void CWindowManager::setAllWindowsDirty() {
for (auto& window : windows) {
window.setDirty(true);
}
}
void CWindowManager::setAllWorkspaceWindowsDirtyByID(int ID) {
int workspaceID = -1;
for (auto& workspace : workspaces) {

View File

@ -10,15 +10,7 @@
#include "KeybindManager.hpp"
#include "utilities/Workspace.hpp"
#include "bar/Bar.hpp"
// temp config values
#define BORDERSIZE 1
#define GAPS_IN 5
#define GAPS_OUT 20
#define BAR_HEIGHT 15
#define MAX_FPS 60
#include "config/ConfigManager.hpp"
class CWindowManager {
public:
@ -59,6 +51,8 @@ public:
int getHighestWorkspaceID();
CWorkspace* getWorkspaceByID(int);
void setAllWindowsDirty();
private:
// Internal WM functions that don't have to be exposed