Made the bar modules async

This commit is contained in:
vaxerski 2022-03-01 20:40:44 +01:00
parent 13744ae7c8
commit d12c35ce1b
4 changed files with 68 additions and 41 deletions

View file

@ -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.
mod->updateLast = std::chrono::system_clock::now();
mod->valueCalculated = BarCommands::parseCommand(mod->value);
// 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();
}).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;
}

View file

@ -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;

View file

@ -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();
}

View file

@ -40,6 +40,11 @@
#define ISDEBUG false
#endif
// hints
#define NONMOVABLE
#define NONCOPYABLE
//
#define EXPOSED_MEMBER(var, type, prefix) \
private: \
type m_##prefix##var; \