mirror of
https://github.com/hyprwm/Hypr.git
synced 2024-11-22 05:25:58 +01:00
Basic CFG system
This commit is contained in:
parent
0a5c4b46f9
commit
5a5ecafd91
8 changed files with 226 additions and 58 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -16,6 +16,7 @@ public:
|
|||
|
||||
void draw();
|
||||
void setup(Vector2D, Vector2D);
|
||||
void destroy();
|
||||
|
||||
private:
|
||||
Vector2D m_vecSize;
|
||||
|
|
142
src/config/ConfigManager.cpp
Normal file
142
src/config/ConfigManager.cpp
Normal 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;
|
||||
}
|
23
src/config/ConfigManager.hpp
Normal file
23
src/config/ConfigManager.hpp
Normal 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);
|
||||
};
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue