mirror of https://github.com/hyprwm/Hypr.git
Feat: made the status bar into a separate process.
This commit is contained in:
parent
11f3e23a94
commit
ec865f0f8e
|
@ -24,7 +24,7 @@ Hypr is a Linux tiling window manager for Xorg. It's written in XCB with modern
|
||||||
- Moving / Fullscreening windows
|
- Moving / Fullscreening windows
|
||||||
|
|
||||||
## Roadmap v2 (not in order)
|
## Roadmap v2 (not in order)
|
||||||
- [x] Upgrade the status bar rendering to Cairo ~ WARNING: only 99% stable (rarely crashes on wm startup)
|
- [x] Upgrade the status bar rendering to Cairo
|
||||||
- [ ] Better status bar configability
|
- [ ] Better status bar configability
|
||||||
- [ ] Rounded corners
|
- [ ] Rounded corners
|
||||||
- [x] Replace default X11 cursor with the pointer
|
- [x] Replace default X11 cursor with the pointer
|
||||||
|
|
|
@ -2,9 +2,90 @@
|
||||||
|
|
||||||
#include <codecvt>
|
#include <codecvt>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
|
#include "../config/ConfigManager.hpp"
|
||||||
#include "../windowManager.hpp"
|
#include "../windowManager.hpp"
|
||||||
|
|
||||||
|
bool isParentDead() {
|
||||||
|
const auto PPID = getppid();
|
||||||
|
|
||||||
|
return PPID == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t barMainThread() {
|
||||||
|
// Main already created all the pipes
|
||||||
|
|
||||||
|
Debug::log(LOG, "Child says Hello World!");
|
||||||
|
|
||||||
|
// Well now this is the init
|
||||||
|
// it's pretty tricky because we only need to init the stuff we need
|
||||||
|
g_pWindowManager->DisplayConnection = xcb_connect(NULL, NULL);
|
||||||
|
if (const auto RET = xcb_connection_has_error(g_pWindowManager->DisplayConnection); RET != 0) {
|
||||||
|
Debug::log(CRIT, "Connection Failed! Return: " + std::to_string(RET));
|
||||||
|
return RET;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Screen
|
||||||
|
g_pWindowManager->Screen = xcb_setup_roots_iterator(xcb_get_setup(g_pWindowManager->DisplayConnection)).data;
|
||||||
|
|
||||||
|
if (!g_pWindowManager->Screen) {
|
||||||
|
Debug::log(CRIT, "Screen was null!");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug::log(LOG, "Bar init Phase 1 done.");
|
||||||
|
|
||||||
|
// Init randr for monitors.
|
||||||
|
g_pWindowManager->setupRandrMonitors();
|
||||||
|
|
||||||
|
// Init depth
|
||||||
|
g_pWindowManager->setupDepth();
|
||||||
|
|
||||||
|
// Setup our bar
|
||||||
|
CStatusBar STATUSBAR;
|
||||||
|
|
||||||
|
// Tell everyone we are in the child process.
|
||||||
|
g_pWindowManager->statusBar = &STATUSBAR;
|
||||||
|
|
||||||
|
Debug::log(LOG, "Bar init Phase 2 done.");
|
||||||
|
|
||||||
|
// Init config manager
|
||||||
|
ConfigManager::init();
|
||||||
|
|
||||||
|
STATUSBAR.setup(0);
|
||||||
|
|
||||||
|
Debug::log(LOG, "Bar setup finished!");
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
ConfigManager::tick();
|
||||||
|
|
||||||
|
// Recieve the message and send our reply
|
||||||
|
IPCRecieveMessageB(g_pWindowManager->m_sIPCBarPipeIn.szPipeName);
|
||||||
|
SIPCMessageBarToMain message;
|
||||||
|
message.windowID = STATUSBAR.getWindowID();
|
||||||
|
IPCSendMessage(g_pWindowManager->m_sIPCBarPipeOut.szPipeName, message);
|
||||||
|
//
|
||||||
|
|
||||||
|
// draw the bar
|
||||||
|
STATUSBAR.draw();
|
||||||
|
|
||||||
|
if (isParentDead()) {
|
||||||
|
// Just for debugging
|
||||||
|
SIPCMessageBarToMain message;
|
||||||
|
message.windowID = 0;
|
||||||
|
IPCSendMessage(g_pWindowManager->m_sIPCBarPipeOut.szPipeName, message);
|
||||||
|
|
||||||
|
Debug::log(LOG, "Bar parent died!");
|
||||||
|
|
||||||
|
return 0; // If the parent died, kill the bar too.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(1000 / ConfigManager::getInt("max_fps")));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void CStatusBar::setup(int MonitorID) {
|
void CStatusBar::setup(int MonitorID) {
|
||||||
Debug::log(LOG, "Creating the bar!");
|
Debug::log(LOG, "Creating the bar!");
|
||||||
|
|
||||||
|
@ -24,6 +105,11 @@ void CStatusBar::setup(int MonitorID) {
|
||||||
// window
|
// window
|
||||||
m_iWindowID = (xcb_generate_id(g_pWindowManager->DisplayConnection));
|
m_iWindowID = (xcb_generate_id(g_pWindowManager->DisplayConnection));
|
||||||
|
|
||||||
|
// send the message IMMEDIATELY so that the main thread has time to update our WID.
|
||||||
|
SIPCMessageBarToMain message;
|
||||||
|
message.windowID = m_iWindowID;
|
||||||
|
IPCSendMessage(g_pWindowManager->m_sIPCBarPipeOut.szPipeName, message);
|
||||||
|
|
||||||
values[0] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE;
|
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,
|
xcb_create_window(g_pWindowManager->DisplayConnection, g_pWindowManager->Depth, m_iWindowID,
|
||||||
|
@ -139,10 +225,10 @@ void CStatusBar::drawText(Vector2D pos, std::string text, uint32_t color) {
|
||||||
|
|
||||||
void CStatusBar::draw() {
|
void CStatusBar::draw() {
|
||||||
|
|
||||||
const auto WORKSPACE = g_pWindowManager->getWorkspaceByID(g_pWindowManager->activeWorkspaces[m_iMonitorID]);
|
// const auto WORKSPACE = g_pWindowManager->getWorkspaceByID(g_pWindowManager->activeWorkspaces[m_iMonitorID]);
|
||||||
|
|
||||||
if (!WORKSPACE || WORKSPACE->getHasFullscreenWindow()) // TODO: fix this
|
// if (!WORKSPACE || WORKSPACE->getHasFullscreenWindow()) // TODO: fix this
|
||||||
return; // Do not draw a bar on a fullscreen window.
|
// return; // Do not draw a bar on a fullscreen window.
|
||||||
|
|
||||||
if (!m_pCairo) {
|
if (!m_pCairo) {
|
||||||
Debug::log(ERR, "Cairo is null but attempted to draw!");
|
Debug::log(ERR, "Cairo is null but attempted to draw!");
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "../defines.hpp"
|
#include "../defines.hpp"
|
||||||
#include "../utilities/AnimationUtil.hpp"
|
#include "../ipc/ipc.hpp"
|
||||||
|
|
||||||
struct SDrawingContext {
|
struct SDrawingContext {
|
||||||
xcb_gcontext_t GContext;
|
xcb_gcontext_t GContext;
|
||||||
|
@ -41,3 +41,6 @@ private:
|
||||||
|
|
||||||
std::unordered_map<std::string, SDrawingContext> m_mContexts;
|
std::unordered_map<std::string, SDrawingContext> m_mContexts;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Main thread for the bar. Is only initted once in main.cpp so we can do this.
|
||||||
|
int64_t barMainThread();
|
|
@ -81,7 +81,8 @@ void handleRawExec(const std::string& command, const std::string& args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleStatusCommand(const std::string& command, const std::string& args) {
|
void handleStatusCommand(const std::string& command, const std::string& args) {
|
||||||
g_pWindowManager->statusBar.setStatusCommand(args);
|
if (g_pWindowManager->statusBar)
|
||||||
|
g_pWindowManager->statusBar->setStatusCommand(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void parseLine(std::string& line) {
|
void parseLine(std::string& line) {
|
||||||
|
@ -174,22 +175,28 @@ void ConfigManager::loadConfigLoadVars() {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ifs.close();
|
ifs.close();
|
||||||
|
}
|
||||||
|
|
||||||
g_pWindowManager->setAllWindowsDirty();
|
g_pWindowManager->setAllWindowsDirty();
|
||||||
|
|
||||||
// Reload the bar as well, don't load it before the default is loaded.
|
// Reload the bar as well, don't load it before the default is loaded.
|
||||||
if (loadBar) {
|
if (loadBar && g_pWindowManager->statusBar) {
|
||||||
g_pWindowManager->statusBar.destroy();
|
g_pWindowManager->statusBar->destroy();
|
||||||
g_pWindowManager->statusBar.setup(configValues["bar_monitor"].intValue);
|
g_pWindowManager->statusBar->setup(configValues["bar_monitor"].intValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadBar = true;
|
loadBar = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigManager::applyKeybindsToX() {
|
void ConfigManager::applyKeybindsToX() {
|
||||||
|
if (g_pWindowManager->statusBar) {
|
||||||
|
Debug::log(LOG, "Not applying the keybinds because status bar not null");
|
||||||
|
return; // If we are in the status bar don't do this.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
xcb_ungrab_key(g_pWindowManager->DisplayConnection, XCB_GRAB_ANY, g_pWindowManager->Screen->root, XCB_MOD_MASK_ANY);
|
xcb_ungrab_key(g_pWindowManager->DisplayConnection, XCB_GRAB_ANY, g_pWindowManager->Screen->root, XCB_MOD_MASK_ANY);
|
||||||
|
|
||||||
for (auto& keybind : KeybindManager::keybinds) {
|
for (auto& keybind : KeybindManager::keybinds) {
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <xcb/randr.h>
|
#include <xcb/randr.h>
|
||||||
|
@ -27,6 +30,12 @@
|
||||||
#include "./helpers/Vector.hpp"
|
#include "./helpers/Vector.hpp"
|
||||||
#include "./utilities/Debug.hpp"
|
#include "./utilities/Debug.hpp"
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
#define ISDEBUG true
|
||||||
|
#else
|
||||||
|
#define ISDEBUG false
|
||||||
|
#endif
|
||||||
|
|
||||||
#define EXPOSED_MEMBER(var, type, prefix) \
|
#define EXPOSED_MEMBER(var, type, prefix) \
|
||||||
private: \
|
private: \
|
||||||
type m_##prefix##var; \
|
type m_##prefix##var; \
|
||||||
|
|
|
@ -10,9 +10,6 @@ gpointer handle(gpointer data) {
|
||||||
// set state to let the main thread know to wait.
|
// set state to let the main thread know to wait.
|
||||||
g_pWindowManager->animationUtilBusy = true;
|
g_pWindowManager->animationUtilBusy = true;
|
||||||
|
|
||||||
// draw bar
|
|
||||||
g_pWindowManager->statusBar.draw();
|
|
||||||
|
|
||||||
// check config
|
// check config
|
||||||
ConfigManager::tick();
|
ConfigManager::tick();
|
||||||
|
|
||||||
|
@ -223,13 +220,13 @@ CWindow* Events::remapWindow(int windowID, bool wasfloating, int forcemonitor) {
|
||||||
void Events::eventMapWindow(xcb_generic_event_t* event) {
|
void Events::eventMapWindow(xcb_generic_event_t* event) {
|
||||||
const auto E = reinterpret_cast<xcb_map_request_event_t*>(event);
|
const auto E = reinterpret_cast<xcb_map_request_event_t*>(event);
|
||||||
|
|
||||||
// make sure it's not the bar!
|
|
||||||
if (E->window == g_pWindowManager->statusBar.getWindowID())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Map the window
|
// Map the window
|
||||||
xcb_map_window(g_pWindowManager->DisplayConnection, E->window);
|
xcb_map_window(g_pWindowManager->DisplayConnection, E->window);
|
||||||
|
|
||||||
|
// make sure it's not the bar!
|
||||||
|
if (E->window == g_pWindowManager->barWindowID)
|
||||||
|
return;
|
||||||
|
|
||||||
// We check if the window is not on our tile-blacklist and if it is, we have a special treatment procedure for it.
|
// We check if the window is not on our tile-blacklist and if it is, we have a special treatment procedure for it.
|
||||||
// this func also sets some stuff
|
// this func also sets some stuff
|
||||||
if (g_pWindowManager->shouldBeFloatedOnInit(E->window)) {
|
if (g_pWindowManager->shouldBeFloatedOnInit(E->window)) {
|
||||||
|
@ -344,8 +341,5 @@ void Events::eventMotionNotify(xcb_generic_event_t* event) {
|
||||||
void Events::eventExpose(xcb_generic_event_t* event) {
|
void Events::eventExpose(xcb_generic_event_t* event) {
|
||||||
const auto E = reinterpret_cast<xcb_expose_event_t*>(event);
|
const auto E = reinterpret_cast<xcb_expose_event_t*>(event);
|
||||||
|
|
||||||
// Draw the bar, disable thread warn
|
// nothing
|
||||||
g_pWindowManager->mainThreadBusy = false;
|
|
||||||
g_pWindowManager->statusBar.draw();
|
|
||||||
g_pWindowManager->mainThreadBusy = true;
|
|
||||||
}
|
}
|
|
@ -0,0 +1,172 @@
|
||||||
|
#include "ipc.hpp"
|
||||||
|
#include "../windowManager.hpp"
|
||||||
|
#include <string.h>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
std::string readFromIPCChannel(std::string path) {
|
||||||
|
std::ifstream is;
|
||||||
|
is.open(path.c_str());
|
||||||
|
|
||||||
|
std::string resultString = std::string((std::istreambuf_iterator<char>(is)), std::istreambuf_iterator<char>());
|
||||||
|
|
||||||
|
is.close();
|
||||||
|
return resultString;
|
||||||
|
};
|
||||||
|
|
||||||
|
int writeToIPCChannel(const std::string path, std::string text) {
|
||||||
|
std::ofstream of;
|
||||||
|
of.open(path, std::ios::trunc);
|
||||||
|
|
||||||
|
of << text;
|
||||||
|
|
||||||
|
of.close();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IPCSendMessage(const std::string path, SIPCMessageBarToMain smessage) {
|
||||||
|
if (!g_pWindowManager->statusBar) {
|
||||||
|
Debug::log(ERR, "Tried to write as a bar from the main thread?!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
std::string message = "";
|
||||||
|
|
||||||
|
// write the WID
|
||||||
|
message += "wid" + IPC_MESSAGE_EQUALITY + std::to_string(g_pWindowManager->statusBar->getWindowID()) + IPC_MESSAGE_SEPARATOR;
|
||||||
|
|
||||||
|
// append the EOF
|
||||||
|
message += IPC_END_OF_FILE;
|
||||||
|
|
||||||
|
writeToIPCChannel(path, message);
|
||||||
|
} catch (...) {
|
||||||
|
Debug::log(WARN, "Error in sending Message B!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IPCSendMessage(const std::string path, SIPCMessageMainToBar smessage) {
|
||||||
|
if (g_pWindowManager->statusBar) {
|
||||||
|
Debug::log(ERR, "Tried to write as main from the bar thread?!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
std::string message = "";
|
||||||
|
|
||||||
|
// write active workspace data
|
||||||
|
message += "active" + IPC_MESSAGE_EQUALITY + std::to_string(smessage.activeWorkspace) + IPC_MESSAGE_SEPARATOR;
|
||||||
|
|
||||||
|
// write workspace data
|
||||||
|
message += "workspaces" + IPC_MESSAGE_EQUALITY;
|
||||||
|
for (const auto &w : smessage.openWorkspaces) {
|
||||||
|
message += std::to_string(w) + ",";
|
||||||
|
}
|
||||||
|
|
||||||
|
// append the EOF
|
||||||
|
message += IPC_MESSAGE_SEPARATOR + IPC_END_OF_FILE;
|
||||||
|
|
||||||
|
// Send
|
||||||
|
writeToIPCChannel(path, message);
|
||||||
|
} catch (...) {
|
||||||
|
Debug::log(WARN, "Error in sending Message M!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IPCRecieveMessageB(const std::string path) {
|
||||||
|
// recieve message as bar
|
||||||
|
|
||||||
|
if (!g_pWindowManager->statusBar) {
|
||||||
|
Debug::log(ERR, "Tried to read as a bar from the main thread?!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
std::string message = readFromIPCChannel(path);
|
||||||
|
|
||||||
|
const auto EOFPOS = message.find_first_of(IPC_END_OF_FILE);
|
||||||
|
|
||||||
|
if (EOFPOS == std::string::npos)
|
||||||
|
return;
|
||||||
|
|
||||||
|
message = message.substr(0, EOFPOS);
|
||||||
|
|
||||||
|
while (message.find_first_of(IPC_MESSAGE_SEPARATOR) != 0 && message.find_first_of(IPC_MESSAGE_SEPARATOR) != std::string::npos) {
|
||||||
|
// read until done.
|
||||||
|
const auto PROP = message.substr(0, message.find_first_of(IPC_MESSAGE_SEPARATOR));
|
||||||
|
message = message.substr(message.find_first_of(IPC_MESSAGE_SEPARATOR) + 1);
|
||||||
|
|
||||||
|
// Get the name and value
|
||||||
|
const auto PROPNAME = PROP.substr(0, PROP.find_first_of(IPC_MESSAGE_EQUALITY));
|
||||||
|
const auto PROPVALUE = PROP.substr(PROP.find_first_of(IPC_MESSAGE_EQUALITY) + 1);
|
||||||
|
|
||||||
|
if (PROPNAME == "active") {
|
||||||
|
try {
|
||||||
|
g_pWindowManager->statusBar->setCurrentWorkspace(stoi(PROPVALUE));
|
||||||
|
} catch (...) {
|
||||||
|
} // Try Catch because stoi can be weird
|
||||||
|
} else if (PROPNAME == "workspaces") {
|
||||||
|
// Read all
|
||||||
|
auto propvalue = PROPVALUE;
|
||||||
|
|
||||||
|
g_pWindowManager->statusBar->openWorkspaces.clear();
|
||||||
|
|
||||||
|
while (propvalue.find_first_of(',') != 0 && propvalue.find_first_of(',') != std::string::npos) {
|
||||||
|
const auto WORKSPACE = propvalue.substr(0, propvalue.find_first_of(','));
|
||||||
|
propvalue = propvalue.substr(propvalue.find_first_of(',') + 1);
|
||||||
|
|
||||||
|
try {
|
||||||
|
g_pWindowManager->statusBar->openWorkspaces.push_back(stoi(WORKSPACE));
|
||||||
|
} catch (...) {
|
||||||
|
} // Try Catch because stoi can be weird
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort
|
||||||
|
std::sort(g_pWindowManager->statusBar->openWorkspaces.begin(), g_pWindowManager->statusBar->openWorkspaces.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(...) {
|
||||||
|
Debug::log(WARN, "Error in reading Message B!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IPCRecieveMessageM(const std::string path) {
|
||||||
|
// recieve message as main
|
||||||
|
|
||||||
|
if (g_pWindowManager->statusBar) {
|
||||||
|
Debug::log(ERR, "Tried to read as main from the bar thread?!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
std::string message = readFromIPCChannel(path);
|
||||||
|
|
||||||
|
const auto EOFPOS = message.find_first_of(IPC_END_OF_FILE);
|
||||||
|
|
||||||
|
if (EOFPOS == std::string::npos)
|
||||||
|
return;
|
||||||
|
|
||||||
|
message = message.substr(0, EOFPOS);
|
||||||
|
|
||||||
|
while (message.find_first_of(IPC_MESSAGE_SEPARATOR) != 0 && message.find_first_of(IPC_MESSAGE_SEPARATOR) != std::string::npos) {
|
||||||
|
// read until done.
|
||||||
|
const auto PROP = message.substr(0, message.find_first_of(IPC_MESSAGE_SEPARATOR));
|
||||||
|
message = message.substr(message.find_first_of(IPC_MESSAGE_SEPARATOR) + 1);
|
||||||
|
|
||||||
|
// Get the name and value
|
||||||
|
const auto PROPNAME = PROP.substr(0, PROP.find_first_of(IPC_MESSAGE_EQUALITY));
|
||||||
|
const auto PROPVALUE = PROP.substr(PROP.find_first_of(IPC_MESSAGE_EQUALITY) + 1);
|
||||||
|
|
||||||
|
if (PROPNAME == "wid") {
|
||||||
|
try {
|
||||||
|
g_pWindowManager->barWindowID = stoi(PROPVALUE);
|
||||||
|
} catch (...) {
|
||||||
|
} // Try Catch because stoi can be weird
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (...) {
|
||||||
|
Debug::log(WARN, "Error in reading Message M!");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
#pragma once
|
||||||
|
#include "../defines.hpp"
|
||||||
|
|
||||||
|
std::string readFromIPCChannel(const std::string);
|
||||||
|
int writeToIPCChannel(const std::string, std::string);
|
||||||
|
|
||||||
|
#define IPC_END_OF_FILE (std::string)"HYPR_END_OF_FILE"
|
||||||
|
#define IPC_MESSAGE_SEPARATOR (std::string)"\t"
|
||||||
|
#define IPC_MESSAGE_EQUALITY (std::string)"="
|
||||||
|
|
||||||
|
struct SIPCMessageMainToBar {
|
||||||
|
std::vector<int> openWorkspaces;
|
||||||
|
uint64_t activeWorkspace;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SIPCMessageBarToMain {
|
||||||
|
uint64_t windowID;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SIPCPipe {
|
||||||
|
std::string szPipeName = "";
|
||||||
|
uint64_t iPipeFD = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// /tmp/ is RAM so the speeds will be decent, if anyone wants to implement
|
||||||
|
// actual pipes feel free.
|
||||||
|
|
||||||
|
void IPCSendMessage(const std::string, SIPCMessageMainToBar);
|
||||||
|
void IPCSendMessage(const std::string, SIPCMessageBarToMain);
|
||||||
|
void IPCRecieveMessageB(const std::string);
|
||||||
|
void IPCRecieveMessageM(const std::string);
|
21
src/main.cpp
21
src/main.cpp
|
@ -8,12 +8,33 @@ Started by Vaxry on 2021 / 11 / 17
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include "windowManager.hpp"
|
#include "windowManager.hpp"
|
||||||
#include "defines.hpp"
|
#include "defines.hpp"
|
||||||
|
#include "bar/Bar.hpp"
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
clearLogs();
|
clearLogs();
|
||||||
|
|
||||||
Debug::log(LOG, "Hypr debug log. Built on " + std::string(__DATE__) + " at " + std::string(__TIME__));
|
Debug::log(LOG, "Hypr debug log. Built on " + std::string(__DATE__) + " at " + std::string(__TIME__));
|
||||||
|
|
||||||
|
// Create all pipes
|
||||||
|
g_pWindowManager->createAndOpenAllPipes();
|
||||||
|
|
||||||
|
Debug::log(LOG, "Pipes done! Forking!");
|
||||||
|
|
||||||
|
if (fork() == 0) {
|
||||||
|
// Child. Bar.
|
||||||
|
|
||||||
|
// Sleep for 2 seconds. When launching on a real Xorg session there is some race condition there
|
||||||
|
// I don't know where it is but this will fix it for now.
|
||||||
|
// Feel free to search for it.
|
||||||
|
std::this_thread::sleep_for(std::chrono::seconds(2));
|
||||||
|
|
||||||
|
const int BARRET = barMainThread();
|
||||||
|
Debug::log(BARRET == 0 ? LOG : ERR, "Bar exited with code " + std::to_string(BARRET) + "!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug::log(LOG, "Parent continuing!");
|
||||||
|
|
||||||
g_pWindowManager->DisplayConnection = xcb_connect(NULL, NULL);
|
g_pWindowManager->DisplayConnection = xcb_connect(NULL, NULL);
|
||||||
if (const auto RET = xcb_connection_has_error(g_pWindowManager->DisplayConnection); RET != 0) {
|
if (const auto RET = xcb_connection_has_error(g_pWindowManager->DisplayConnection); RET != 0) {
|
||||||
Debug::log(CRIT, "Connection Failed! Return: " + std::to_string(RET));
|
Debug::log(CRIT, "Connection Failed! Return: " + std::to_string(RET));
|
||||||
|
|
|
@ -31,7 +31,7 @@ double parabolic(double from, double to, double incline) {
|
||||||
|
|
||||||
void emptyEvent() {
|
void emptyEvent() {
|
||||||
xcb_expose_event_t exposeEvent;
|
xcb_expose_event_t exposeEvent;
|
||||||
exposeEvent.window = g_pWindowManager->statusBar.getWindowID();
|
exposeEvent.window = 0;
|
||||||
exposeEvent.response_type = 0;
|
exposeEvent.response_type = 0;
|
||||||
exposeEvent.x = 0;
|
exposeEvent.x = 0;
|
||||||
exposeEvent.y = 0;
|
exposeEvent.y = 0;
|
||||||
|
|
|
@ -15,6 +15,25 @@ xcb_visualtype_t* CWindowManager::setupColors() {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CWindowManager::setupDepth() {
|
||||||
|
// init visual type, default 32 bit depth
|
||||||
|
// TODO: fix this, ugh
|
||||||
|
Depth = 24; //32
|
||||||
|
VisualType = setupColors();
|
||||||
|
if (VisualType == NULL) {
|
||||||
|
Depth = 24;
|
||||||
|
VisualType = setupColors();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWindowManager::createAndOpenAllPipes() {
|
||||||
|
system("mkdir -p /tmp/hypr");
|
||||||
|
system("cat \" \" > /tmp/hypr/hyprbarin");
|
||||||
|
system("cat \" \" > /tmp/hypr/hyprbarout");
|
||||||
|
system("cat \" \" > /tmp/hypr/hyprbarind");
|
||||||
|
system("cat \" \" > /tmp/hypr/hyprbaroutd");
|
||||||
|
}
|
||||||
|
|
||||||
void CWindowManager::updateRootCursor() {
|
void CWindowManager::updateRootCursor() {
|
||||||
if (xcb_cursor_context_new(DisplayConnection, Screen, &pointerContext) < 0) {
|
if (xcb_cursor_context_new(DisplayConnection, Screen, &pointerContext) < 0) {
|
||||||
Debug::log(ERR, "Creating a cursor context failed!");
|
Debug::log(ERR, "Creating a cursor context failed!");
|
||||||
|
@ -99,11 +118,6 @@ void CWindowManager::setupRandrMonitors() {
|
||||||
}
|
}
|
||||||
|
|
||||||
xcb_flush(DisplayConnection);
|
xcb_flush(DisplayConnection);
|
||||||
}
|
|
||||||
|
|
||||||
void CWindowManager::setupManager() {
|
|
||||||
EWMH::setupInitEWMH();
|
|
||||||
setupRandrMonitors();
|
|
||||||
|
|
||||||
if (monitors.size() == 0) {
|
if (monitors.size() == 0) {
|
||||||
// RandR failed!
|
// RandR failed!
|
||||||
|
@ -119,6 +133,11 @@ void CWindowManager::setupManager() {
|
||||||
monitors[i].szName = "Screen" + std::to_string(i);
|
monitors[i].szName = "Screen" + std::to_string(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWindowManager::setupManager() {
|
||||||
|
EWMH::setupInitEWMH();
|
||||||
|
setupRandrMonitors();
|
||||||
|
|
||||||
Debug::log(LOG, "RandR done.");
|
Debug::log(LOG, "RandR done.");
|
||||||
|
|
||||||
|
@ -143,32 +162,14 @@ void CWindowManager::setupManager() {
|
||||||
Debug::log(LOG, "Workspace protos done.");
|
Debug::log(LOG, "Workspace protos done.");
|
||||||
//
|
//
|
||||||
|
|
||||||
// init visual type, default 32 bit depth
|
setupDepth();
|
||||||
// TODO: fix this, ugh
|
|
||||||
Depth = 24; //32
|
|
||||||
VisualType = setupColors();
|
|
||||||
if (VisualType == NULL) {
|
|
||||||
Depth = 24;
|
|
||||||
VisualType = setupColors();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- INIT THE BAR ---- //
|
// ---- INIT THE THREAD FOR ANIM & CONFIG ---- //
|
||||||
|
|
||||||
if (ConfigManager::getInt("bar_enabled") == 1) {
|
|
||||||
for (auto& monitor : monitors) {
|
|
||||||
if (monitor.primary) {
|
|
||||||
statusBar.setup(ConfigManager::configValues["bar_monitor"].intValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update bar info
|
|
||||||
updateBarInfo();
|
|
||||||
|
|
||||||
// start its' update thread
|
// start its' update thread
|
||||||
Events::setThread();
|
Events::setThread();
|
||||||
}
|
|
||||||
|
|
||||||
Debug::log(LOG, "Bar done.");
|
Debug::log(LOG, "Thread (Parent) done.");
|
||||||
|
|
||||||
ConfigManager::loadConfigLoadVars();
|
ConfigManager::loadConfigLoadVars();
|
||||||
|
|
||||||
|
@ -193,6 +194,9 @@ bool CWindowManager::handleEvent() {
|
||||||
// Set thread state, halt animations until done.
|
// Set thread state, halt animations until done.
|
||||||
mainThreadBusy = true;
|
mainThreadBusy = true;
|
||||||
|
|
||||||
|
// Read from the bar
|
||||||
|
IPCRecieveMessageM(m_sIPCBarPipeOut.szPipeName);
|
||||||
|
|
||||||
switch (ev->response_type & ~0x80) {
|
switch (ev->response_type & ~0x80) {
|
||||||
case XCB_ENTER_NOTIFY:
|
case XCB_ENTER_NOTIFY:
|
||||||
Events::eventEnter(ev);
|
Events::eventEnter(ev);
|
||||||
|
@ -537,9 +541,9 @@ void CWindowManager::setEffectiveSizePosUsingConfig(CWindow* pWindow) {
|
||||||
pWindow->setEffectiveSize(pWindow->getSize() - (Vector2D(ConfigManager::getInt("border_size"), ConfigManager::getInt("border_size")) * 2));
|
pWindow->setEffectiveSize(pWindow->getSize() - (Vector2D(ConfigManager::getInt("border_size"), ConfigManager::getInt("border_size")) * 2));
|
||||||
|
|
||||||
// do gaps, set top left
|
// do gaps, set top left
|
||||||
pWindow->setEffectivePosition(pWindow->getEffectivePosition() + Vector2D(DISPLAYLEFT ? ConfigManager::getInt("gaps_out") : ConfigManager::getInt("gaps_in"), DISPLAYTOP ? ConfigManager::getInt("gaps_out") + (MONITOR->ID == statusBar.getMonitorID() ? ConfigManager::getInt("bar_height") : 0) : ConfigManager::getInt("gaps_in")));
|
pWindow->setEffectivePosition(pWindow->getEffectivePosition() + Vector2D(DISPLAYLEFT ? ConfigManager::getInt("gaps_out") : ConfigManager::getInt("gaps_in"), DISPLAYTOP ? ConfigManager::getInt("gaps_out") + (MONITOR->ID == ConfigManager::getInt("bar_monitor") ? ConfigManager::getInt("bar_height") : 0) : ConfigManager::getInt("gaps_in")));
|
||||||
// fix to old size bottom right
|
// fix to old size bottom right
|
||||||
pWindow->setEffectiveSize(pWindow->getEffectiveSize() - Vector2D(DISPLAYLEFT ? ConfigManager::getInt("gaps_out") : ConfigManager::getInt("gaps_in"), DISPLAYTOP ? ConfigManager::getInt("gaps_out") + (MONITOR->ID == statusBar.getMonitorID() ? ConfigManager::getInt("bar_height") : 0) : ConfigManager::getInt("gaps_in")));
|
pWindow->setEffectiveSize(pWindow->getEffectiveSize() - Vector2D(DISPLAYLEFT ? ConfigManager::getInt("gaps_out") : ConfigManager::getInt("gaps_in"), DISPLAYTOP ? ConfigManager::getInt("gaps_out") + (MONITOR->ID == ConfigManager::getInt("bar_monitor") ? ConfigManager::getInt("bar_height") : 0) : ConfigManager::getInt("gaps_in")));
|
||||||
// set bottom right
|
// set bottom right
|
||||||
pWindow->setEffectiveSize(pWindow->getEffectiveSize() - Vector2D(DISPLAYRIGHT ? ConfigManager::getInt("gaps_out") : ConfigManager::getInt("gaps_in"), DISPLAYBOTTOM ? ConfigManager::getInt("gaps_out") : ConfigManager::getInt("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")));
|
||||||
}
|
}
|
||||||
|
@ -1055,19 +1059,27 @@ bool CWindowManager::isWorkspaceVisible(int workspaceID) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWindowManager::updateBarInfo() {
|
void CWindowManager::updateBarInfo() {
|
||||||
statusBar.openWorkspaces.clear();
|
|
||||||
for (auto& workspace : workspaces) {
|
|
||||||
statusBar.openWorkspaces.push_back(workspace.getID());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::sort(statusBar.openWorkspaces.begin(), statusBar.openWorkspaces.end());
|
// IPC
|
||||||
|
|
||||||
|
// What we need to send:
|
||||||
|
// - Workspace data
|
||||||
|
// - Active Workspace
|
||||||
|
|
||||||
|
SIPCMessageMainToBar message;
|
||||||
|
|
||||||
if (!getMonitorFromCursor()) {
|
if (!getMonitorFromCursor()) {
|
||||||
Debug::log(ERR, "Monitor was null! (updateBarInfo)");
|
Debug::log(ERR, "Monitor was null! (updateBarInfo)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
statusBar.setCurrentWorkspace(activeWorkspaces[getMonitorFromCursor()->ID]);
|
message.activeWorkspace = activeWorkspaces[getMonitorFromCursor()->ID];
|
||||||
|
|
||||||
|
for (auto& workspace : workspaces) {
|
||||||
|
message.openWorkspaces.push_back(workspace.getID());
|
||||||
|
}
|
||||||
|
|
||||||
|
IPCSendMessage(m_sIPCBarPipeIn.szPipeName, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWindowManager::setAllFloatingWindowsTop() {
|
void CWindowManager::setAllFloatingWindowsTop() {
|
||||||
|
|
|
@ -9,13 +9,15 @@
|
||||||
|
|
||||||
#include "KeybindManager.hpp"
|
#include "KeybindManager.hpp"
|
||||||
#include "utilities/Workspace.hpp"
|
#include "utilities/Workspace.hpp"
|
||||||
#include "bar/Bar.hpp"
|
|
||||||
#include "config/ConfigManager.hpp"
|
#include "config/ConfigManager.hpp"
|
||||||
#include "utilities/Monitor.hpp"
|
#include "utilities/Monitor.hpp"
|
||||||
#include "utilities/Util.hpp"
|
#include "utilities/Util.hpp"
|
||||||
#include "utilities/AnimationUtil.hpp"
|
#include "utilities/AnimationUtil.hpp"
|
||||||
#include "utilities/XCBProps.hpp"
|
#include "utilities/XCBProps.hpp"
|
||||||
#include "ewmh/ewmh.hpp"
|
#include "ewmh/ewmh.hpp"
|
||||||
|
#include "bar/Bar.hpp"
|
||||||
|
|
||||||
|
#include "ipc/ipc.hpp"
|
||||||
|
|
||||||
class CWindowManager {
|
class CWindowManager {
|
||||||
public:
|
public:
|
||||||
|
@ -40,8 +42,12 @@ public:
|
||||||
std::vector<CWorkspace> workspaces;
|
std::vector<CWorkspace> workspaces;
|
||||||
std::vector<int> activeWorkspaces;
|
std::vector<int> activeWorkspaces;
|
||||||
|
|
||||||
CStatusBar statusBar;
|
// Pipes
|
||||||
GThread* barThread;
|
SIPCPipe m_sIPCBarPipeIn = {ISDEBUG ? "/tmp/hypr/hyprbarind" : "/tmp/hypr/hyprbarin", 0};
|
||||||
|
SIPCPipe m_sIPCBarPipeOut = {ISDEBUG ? "/tmp/hypr/hyprbaroutd" : "/tmp/hypr/hyprbarout", 0};
|
||||||
|
CStatusBar* statusBar = nullptr;
|
||||||
|
uint64_t barWindowID = 0;
|
||||||
|
GThread* barThread; /* Well right now anything but the bar but lol */
|
||||||
|
|
||||||
std::atomic<bool> mainThreadBusy = false;
|
std::atomic<bool> mainThreadBusy = false;
|
||||||
std::atomic<bool> animationUtilBusy = false;
|
std::atomic<bool> animationUtilBusy = false;
|
||||||
|
@ -86,12 +92,14 @@ public:
|
||||||
|
|
||||||
bool shouldBeFloatedOnInit(int64_t);
|
bool shouldBeFloatedOnInit(int64_t);
|
||||||
|
|
||||||
|
void setupRandrMonitors();
|
||||||
|
void createAndOpenAllPipes();
|
||||||
|
void setupDepth();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// Internal WM functions that don't have to be exposed
|
// Internal WM functions that don't have to be exposed
|
||||||
|
|
||||||
void setupRandrMonitors();
|
|
||||||
|
|
||||||
void sanityCheckOnWorkspace(int);
|
void sanityCheckOnWorkspace(int);
|
||||||
CWindow* getNeighborInDir(char dir);
|
CWindow* getNeighborInDir(char dir);
|
||||||
void eatWindow(CWindow* a, CWindow* toEat);
|
void eatWindow(CWindow* a, CWindow* toEat);
|
||||||
|
@ -104,7 +112,6 @@ public:
|
||||||
xcb_visualtype_t* setupColors();
|
xcb_visualtype_t* setupColors();
|
||||||
void updateBarInfo();
|
void updateBarInfo();
|
||||||
void updateRootCursor();
|
void updateRootCursor();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
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 New Issue