mirror of
https://github.com/hyprwm/Hypr.git
synced 2024-11-25 22:35:58 +01:00
Made the bar modules async
This commit is contained in:
parent
13744ae7c8
commit
d12c35ce1b
4 changed files with 68 additions and 41 deletions
|
@ -142,6 +142,9 @@ void CStatusBar::setupModule(SBarModule* module) {
|
|||
void CStatusBar::destroyModule(SBarModule* module) {
|
||||
if (module->bgcontext)
|
||||
xcb_free_gc(g_pWindowManager->DisplayConnection, module->bgcontext);
|
||||
|
||||
// delete it from the heap
|
||||
delete module;
|
||||
}
|
||||
|
||||
void CStatusBar::setupTray() {
|
||||
|
@ -181,8 +184,8 @@ void CStatusBar::setupTray() {
|
|||
// Check if the tray module is active
|
||||
SBarModule* pBarModule = nullptr;
|
||||
for (auto& mod : modules) {
|
||||
if (mod.value == "tray") {
|
||||
pBarModule = &mod;
|
||||
if (mod->value == "tray") {
|
||||
pBarModule = mod;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -299,7 +302,7 @@ void CStatusBar::setup(int MonitorID) {
|
|||
|
||||
m_bHasTray = false;
|
||||
for (auto& mod : g_pWindowManager->statusBar->modules) {
|
||||
if (mod.value == "tray") {
|
||||
if (mod->value == "tray") {
|
||||
m_bHasTray = true;
|
||||
break;
|
||||
}
|
||||
|
@ -474,18 +477,18 @@ void CStatusBar::draw() {
|
|||
|
||||
for (auto& module : modules) {
|
||||
|
||||
if (!module.bgcontext && !module.isPad)
|
||||
setupModule(&module);
|
||||
if (!module->bgcontext && !module->isPad)
|
||||
setupModule(module);
|
||||
|
||||
if (module.value == "workspaces") {
|
||||
offLeft += drawWorkspacesModule(&module, offLeft);
|
||||
if (module->value == "workspaces") {
|
||||
offLeft += drawWorkspacesModule(module, offLeft);
|
||||
} else {
|
||||
if (module.alignment == LEFT) {
|
||||
offLeft += drawModule(&module, offLeft);
|
||||
} else if (module.alignment == RIGHT) {
|
||||
offRight += drawModule(&module, offRight);
|
||||
if (module->alignment == LEFT) {
|
||||
offLeft += drawModule(module, offLeft);
|
||||
} else if (module->alignment == RIGHT) {
|
||||
offRight += drawModule(module, offRight);
|
||||
} else {
|
||||
drawModule(&module, 0);
|
||||
drawModule(module, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -609,10 +612,13 @@ int CStatusBar::drawModule(SBarModule* mod, int off) {
|
|||
|
||||
// check if we need to update
|
||||
if (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - mod->updateLast).count() > mod->updateEveryMs) {
|
||||
// Yes. Set the new last and do it.
|
||||
// This is done asynchronously to prevent lag on especially slower PCs
|
||||
// but ngl it also did hang on more powerful ones
|
||||
std::thread([=](){
|
||||
const auto RETVAL = BarCommands::parseCommand(mod->value);
|
||||
mod->accessValueCalculated(true, RETVAL);
|
||||
mod->updateLast = std::chrono::system_clock::now();
|
||||
|
||||
mod->valueCalculated = BarCommands::parseCommand(mod->value);
|
||||
}).detach();
|
||||
}
|
||||
|
||||
// We have the value, draw the module!
|
||||
|
@ -620,7 +626,7 @@ int CStatusBar::drawModule(SBarModule* mod, int off) {
|
|||
const auto MODULEWIDTH = getTextWidth(mod->valueCalculated, ConfigManager::getString("bar:font.main")) + PAD;
|
||||
const auto ICONWIDTH = getTextWidth(mod->icon, ConfigManager::getString("bar:font.secondary"));
|
||||
|
||||
if (!MODULEWIDTH || mod->valueCalculated == "")
|
||||
if (!MODULEWIDTH || mod->accessValueCalculated(false) == "")
|
||||
return 0; // empty module
|
||||
|
||||
Vector2D position;
|
||||
|
@ -639,7 +645,7 @@ int CStatusBar::drawModule(SBarModule* mod, int off) {
|
|||
drawCairoRectangle(position, Vector2D(MODULEWIDTH + ICONWIDTH, m_vecSize.y), mod->bgcolor);
|
||||
|
||||
drawText(position + Vector2D(PAD / 2, getTextHalfY()), mod->icon, mod->color, ConfigManager::getString("bar:font.secondary"));
|
||||
drawText(position + Vector2D(PAD / 2 + ICONWIDTH, getTextHalfY()), mod->valueCalculated, mod->color, ConfigManager::getString("bar:font.main"));
|
||||
drawText(position + Vector2D(PAD / 2 + ICONWIDTH, getTextHalfY()), mod->accessValueCalculated(false), mod->color, ConfigManager::getString("bar:font.main"));
|
||||
|
||||
return MODULEWIDTH + ICONWIDTH;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include "../ipc/ipc.hpp"
|
||||
#include "BarCommands.hpp"
|
||||
#include <chrono>
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
|
||||
inline int barScreen = 0;
|
||||
|
||||
|
@ -20,7 +22,7 @@ enum ModuleAlignment {
|
|||
RIGHT
|
||||
};
|
||||
|
||||
struct SBarModule {
|
||||
NONMOVABLE NONCOPYABLE struct SBarModule {
|
||||
ModuleAlignment alignment;
|
||||
std::string value;
|
||||
std::string icon;
|
||||
|
@ -36,6 +38,19 @@ struct SBarModule {
|
|||
// PADS
|
||||
bool isPad = false;
|
||||
int pad = 0;
|
||||
|
||||
|
||||
// Simple but working thread safe value accessor
|
||||
std::mutex mtx;
|
||||
std::string accessValueCalculated(bool write, std::string val = "") {
|
||||
std::lock_guard<std::mutex> lg(mtx);
|
||||
|
||||
if (write)
|
||||
valueCalculated = val;
|
||||
else
|
||||
return valueCalculated;
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
class CStatusBar {
|
||||
|
@ -61,7 +76,7 @@ public:
|
|||
std::vector<int> openWorkspaces;
|
||||
EXPOSED_MEMBER(CurrentWorkspace, int, i);
|
||||
|
||||
std::vector<SBarModule> modules;
|
||||
std::vector<SBarModule*> modules;
|
||||
|
||||
xcb_window_t trayWindowID = 0;
|
||||
|
||||
|
|
|
@ -143,7 +143,8 @@ void handleStatusCommand(const std::string& command, const std::string& args) {
|
|||
}
|
||||
|
||||
void parseModule(const std::string& COMMANDC, const std::string& VALUE) {
|
||||
SBarModule module;
|
||||
SBarModule* module = new SBarModule();
|
||||
g_pWindowManager->statusBar->modules.push_back(module);
|
||||
|
||||
auto valueCopy = VALUE;
|
||||
|
||||
|
@ -156,24 +157,22 @@ void parseModule(const std::string& COMMANDC, const std::string& VALUE) {
|
|||
|
||||
const auto PADW = valueCopy;
|
||||
|
||||
if (ALIGNR == "left") module.alignment = LEFT;
|
||||
else if (ALIGNR == "right") module.alignment = RIGHT;
|
||||
else if (ALIGNR == "center") module.alignment = CENTER;
|
||||
if (ALIGNR == "left") module->alignment = LEFT;
|
||||
else if (ALIGNR == "right") module->alignment = RIGHT;
|
||||
else if (ALIGNR == "center") module->alignment = CENTER;
|
||||
|
||||
try {
|
||||
module.pad = stol(PADW);
|
||||
module->pad = stol(PADW);
|
||||
} catch (...) {
|
||||
Debug::log(ERR, "Module creation pad error: invalid pad");
|
||||
ConfigManager::parseError = "Module creation error in pad: invalid pad.";
|
||||
return;
|
||||
}
|
||||
|
||||
module.isPad = true;
|
||||
module->isPad = true;
|
||||
|
||||
module.color = 0;
|
||||
module.bgcolor = 0;
|
||||
|
||||
g_pWindowManager->statusBar->modules.push_back(module);
|
||||
module->color = 0;
|
||||
module->bgcolor = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -192,32 +191,34 @@ void parseModule(const std::string& COMMANDC, const std::string& VALUE) {
|
|||
|
||||
const auto COMMAND = valueCopy;
|
||||
|
||||
if (ALIGN == "left") module.alignment = LEFT;
|
||||
else if (ALIGN == "right") module.alignment = RIGHT;
|
||||
else if (ALIGN == "center") module.alignment = CENTER;
|
||||
if (ALIGN == "left") module->alignment = LEFT;
|
||||
else if (ALIGN == "right") module->alignment = RIGHT;
|
||||
else if (ALIGN == "center") module->alignment = CENTER;
|
||||
|
||||
try {
|
||||
module.color = stol(COL1.substr(2), nullptr, 16);
|
||||
module.bgcolor = stol(COL2.substr(2), nullptr, 16);
|
||||
module->color = stol(COL1.substr(2), nullptr, 16);
|
||||
module->bgcolor = stol(COL2.substr(2), nullptr, 16);
|
||||
} catch (...) {
|
||||
Debug::log(ERR, "Module creation color error: invalid color");
|
||||
ConfigManager::parseError = "Module creation error in color: invalid color.";
|
||||
g_pWindowManager->statusBar->modules.pop_back();
|
||||
delete module;
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
module.updateEveryMs = stol(UPDATE);
|
||||
module->updateEveryMs = stol(UPDATE);
|
||||
} catch (...) {
|
||||
Debug::log(ERR, "Module creation error: invalid update interval");
|
||||
ConfigManager::parseError = "Module creation error in interval: invalid interval.";
|
||||
g_pWindowManager->statusBar->modules.pop_back();
|
||||
delete module;
|
||||
return;
|
||||
}
|
||||
|
||||
module.icon = ICON;
|
||||
module->icon = ICON;
|
||||
|
||||
module.value = COMMAND;
|
||||
|
||||
g_pWindowManager->statusBar->modules.push_back(module);
|
||||
module->value = COMMAND;
|
||||
}
|
||||
|
||||
void parseBarLine(const std::string& line) {
|
||||
|
@ -363,7 +364,7 @@ void ConfigManager::loadConfigLoadVars() {
|
|||
if (loadBar && g_pWindowManager->statusBar) {
|
||||
// clear modules as we overwrite them
|
||||
for (auto& m : g_pWindowManager->statusBar->modules) {
|
||||
g_pWindowManager->statusBar->destroyModule(&m);
|
||||
g_pWindowManager->statusBar->destroyModule(m);
|
||||
}
|
||||
g_pWindowManager->statusBar->modules.clear();
|
||||
}
|
||||
|
|
|
@ -40,6 +40,11 @@
|
|||
#define ISDEBUG false
|
||||
#endif
|
||||
|
||||
// hints
|
||||
#define NONMOVABLE
|
||||
#define NONCOPYABLE
|
||||
//
|
||||
|
||||
#define EXPOSED_MEMBER(var, type, prefix) \
|
||||
private: \
|
||||
type m_##prefix##var; \
|
||||
|
|
Loading…
Reference in a new issue