fix(gtk): use idle to avoid mutex

This commit is contained in:
Alexis 2018-08-10 23:21:21 +02:00
parent 95f1ab471a
commit 2512d51564
15 changed files with 42 additions and 71 deletions

View File

@ -3,7 +3,6 @@
#include <json/json.h> #include <json/json.h>
#include <gtkmm.h> #include <gtkmm.h>
#include <fmt/format.h> #include <fmt/format.h>
#include <thread>
#include "util/chrono.hpp" #include "util/chrono.hpp"
#include "IModule.hpp" #include "IModule.hpp"

View File

@ -4,7 +4,6 @@
#include <gtkmm.h> #include <gtkmm.h>
#include <fmt/format.h> #include <fmt/format.h>
#include <sys/sysinfo.h> #include <sys/sysinfo.h>
#include <thread>
#include "util/chrono.hpp" #include "util/chrono.hpp"
#include "IModule.hpp" #include "IModule.hpp"

View File

@ -3,7 +3,6 @@
#include <json/json.h> #include <json/json.h>
#include <gtkmm.h> #include <gtkmm.h>
#include <fmt/format.h> #include <fmt/format.h>
#include <thread>
#include "util/chrono.hpp" #include "util/chrono.hpp"
#include "IModule.hpp" #include "IModule.hpp"

View File

@ -4,7 +4,6 @@
#include <gtkmm.h> #include <gtkmm.h>
#include <fmt/format.h> #include <fmt/format.h>
#include <sys/sysinfo.h> #include <sys/sysinfo.h>
#include <thread>
#include "util/chrono.hpp" #include "util/chrono.hpp"
#include "IModule.hpp" #include "IModule.hpp"

View File

@ -9,7 +9,6 @@
#include <json/json.h> #include <json/json.h>
#include <gtkmm.h> #include <gtkmm.h>
#include <fmt/format.h> #include <fmt/format.h>
#include <thread>
#include "util/chrono.hpp" #include "util/chrono.hpp"
#include "IModule.hpp" #include "IModule.hpp"

View File

@ -14,20 +14,14 @@ namespace waybar::modules {
auto update() -> void; auto update() -> void;
operator Gtk::Widget &(); operator Gtk::Widget &();
private: private:
void _updateThread();
static void _handle_idle(void *data,
struct org_kde_kwin_idle_timeout *timer);
static void _handle_resume(void *data,
struct org_kde_kwin_idle_timeout *timer);
void _addWorkspace(Json::Value node); void _addWorkspace(Json::Value node);
Json::Value _getWorkspaces(); Json::Value _getWorkspaces();
Bar &_bar; Bar &_bar;
util::SleeperThread *_thread; waybar::util::SleeperThread _thread;
Gtk::Box *_box; Gtk::Box _box;
std::unordered_map<int, Gtk::Button> _buttons; std::unordered_map<int, Gtk::Button> _buttons;
int _ipcSocketfd; int _ipcSocketfd;
int _ipcEventSocketfd; int _ipcEventSocketfd;
struct org_kde_kwin_idle_timeout *_idle_timer;
}; };
} }

View File

@ -6,7 +6,7 @@ project(
) )
cpp_args = [] cpp_args = []
cpp_link_args = [] cpp_link_args = ['-g']
if false # libc++ if false # libc++
cpp_args += ['-stdlib=libc++'] cpp_args += ['-stdlib=libc++']

View File

@ -5,7 +5,6 @@
#include "bar.hpp" #include "bar.hpp"
#include "client.hpp" #include "client.hpp"
#include "factory.hpp" #include "factory.hpp"
#include "util/chrono.hpp"
waybar::Bar::Bar(Client &client, std::unique_ptr<struct wl_output *> &&p_output) waybar::Bar::Bar(Client &client, std::unique_ptr<struct wl_output *> &&p_output)
: client(client), window{Gtk::WindowType::WINDOW_TOPLEVEL}, : client(client), window{Gtk::WindowType::WINDOW_TOPLEVEL},

View File

@ -20,10 +20,10 @@ waybar::modules::Battery::Battery(Json::Value config)
} }
_label.get_style_context()->add_class("battery"); _label.get_style_context()->add_class("battery");
int interval = _config["interval"] ? _config["inveral"].asInt() : 1;
_thread = [this] { _thread = [this, interval] {
update(); update();
_thread.sleep_for(chrono::minutes(1)); _thread.sleep_for(chrono::seconds(interval));
}; };
} }

View File

@ -5,7 +5,9 @@ waybar::modules::Clock::Clock(Json::Value config)
{ {
_label.get_style_context()->add_class("clock"); _label.get_style_context()->add_class("clock");
_thread = [this] { _thread = [this] {
Glib::signal_idle().connect_once([this] {
update(); update();
});
auto now = waybar::chrono::clock::now(); auto now = waybar::chrono::clock::now();
auto timeout = auto timeout =
std::chrono::floor<std::chrono::minutes>(now + std::chrono::minutes(1)); std::chrono::floor<std::chrono::minutes>(now + std::chrono::minutes(1));

View File

@ -4,9 +4,11 @@ waybar::modules::Cpu::Cpu(Json::Value config)
: _config(config) : _config(config)
{ {
_label.get_style_context()->add_class("cpu"); _label.get_style_context()->add_class("cpu");
_thread = [this] {
update();
int interval = _config["interval"] ? _config["inveral"].asInt() : 10; int interval = _config["interval"] ? _config["inveral"].asInt() : 10;
_thread = [this, interval] {
Glib::signal_idle().connect_once([this] {
update();
});
_thread.sleep_for(chrono::seconds(interval)); _thread.sleep_for(chrono::seconds(interval));
}; };
}; };

View File

@ -8,9 +8,11 @@ waybar::modules::Custom::Custom(std::string name, Json::Value config)
std::cerr << name + " has no exec path." << std::endl; std::cerr << name + " has no exec path." << std::endl;
return; return;
} }
_thread = [this] {
update();
int interval = _config["interval"] ? _config["inveral"].asInt() : 30; int interval = _config["interval"] ? _config["inveral"].asInt() : 30;
_thread = [this, interval] {
Glib::signal_idle().connect_once([this] {
update();
});
_thread.sleep_for(chrono::seconds(interval)); _thread.sleep_for(chrono::seconds(interval));
}; };
}; };

View File

@ -4,9 +4,11 @@ waybar::modules::Memory::Memory(Json::Value config)
: _config(config) : _config(config)
{ {
_label.get_style_context()->add_class("memory"); _label.get_style_context()->add_class("memory");
_thread = [this] {
update();
int interval = _config["interval"] ? _config["inveral"].asInt() : 30; int interval = _config["interval"] ? _config["inveral"].asInt() : 30;
_thread = [this, interval] {
Glib::signal_idle().connect_once([this] {
update();
});
_thread.sleep_for(chrono::seconds(interval)); _thread.sleep_for(chrono::seconds(interval));
}; };
}; };

View File

@ -4,8 +4,11 @@ waybar::modules::Network::Network(Json::Value config)
: _config(config), _ifid(if_nametoindex(config["interface"].asString().c_str())) : _config(config), _ifid(if_nametoindex(config["interface"].asString().c_str()))
{ {
_label.get_style_context()->add_class("network"); _label.get_style_context()->add_class("network");
_thread = [this] { int interval = _config["interval"] ? _config["inveral"].asInt() : 30;
_thread = [this, interval] {
Glib::signal_idle().connect_once([this] {
update(); update();
});
_thread.sleep_for(chrono::minutes(1)); _thread.sleep_for(chrono::minutes(1));
}; };
}; };

View File

@ -2,27 +2,24 @@
#include "ipc/client.hpp" #include "ipc/client.hpp"
waybar::modules::Workspaces::Workspaces(Bar &bar) waybar::modules::Workspaces::Workspaces(Bar &bar)
: _bar(bar), _thread(nullptr), _box(Gtk::manage(new Gtk::Box)) : _bar(bar)
{ {
_box->get_style_context()->add_class("workspaces"); _box.get_style_context()->add_class("workspaces");
std::string socketPath = get_socketpath(); std::string socketPath = get_socketpath();
_ipcSocketfd = ipc_open_socket(socketPath); _ipcSocketfd = ipc_open_socket(socketPath);
_ipcEventSocketfd = ipc_open_socket(socketPath); _ipcEventSocketfd = ipc_open_socket(socketPath);
const char *subscribe = "[ \"workspace\", \"mode\" ]"; const char *subscribe = "[ \"workspace\", \"mode\" ]";
uint32_t len = strlen(subscribe); uint32_t len = strlen(subscribe);
ipc_single_command(_ipcEventSocketfd, IPC_SUBSCRIBE, subscribe, &len); ipc_single_command(_ipcEventSocketfd, IPC_SUBSCRIBE, subscribe, &len);
_idle_timer = _thread = [this] {
org_kde_kwin_idle_get_idle_timeout(_bar.client.idle_manager, Glib::signal_idle().connect_once([this] {
_bar.client.seat, 10000); // 10 seconds update();
static const struct org_kde_kwin_idle_timeout_listener idle_timer_listener = { });
.idle = _handle_idle, _thread.sleep_for(chrono::milliseconds(250));
.resumed = _handle_resume,
}; };
org_kde_kwin_idle_timeout_add_listener(_idle_timer,
&idle_timer_listener, this);
_updateThread();
} }
auto waybar::modules::Workspaces::update() -> void auto waybar::modules::Workspaces::update() -> void
{ {
Json::Value workspaces = _getWorkspaces(); Json::Value workspaces = _getWorkspaces();
@ -31,7 +28,7 @@ auto waybar::modules::Workspaces::update() -> void
auto ws = std::find_if(workspaces.begin(), workspaces.end(), auto ws = std::find_if(workspaces.begin(), workspaces.end(),
[it](auto node) -> bool { return node["num"].asInt() == it->first; }); [it](auto node) -> bool { return node["num"].asInt() == it->first; });
if (ws == workspaces.end()) { if (ws == workspaces.end()) {
it->second.hide(); it = _buttons.erase(it);
needReorder = true; needReorder = true;
} }
} }
@ -49,49 +46,24 @@ auto waybar::modules::Workspaces::update() -> void
styleContext->add_class("current"); styleContext->add_class("current");
} }
if (needReorder) if (needReorder)
_box->reorder_child(it->second, node["num"].asInt() - 1); _box.reorder_child(it->second, node["num"].asInt() - 1);
it->second.show(); it->second.show();
} }
} }
} }
void waybar::modules::Workspaces::_updateThread()
{
_thread = new waybar::util::SleeperThread([this] {
update();
_thread->sleep_for(waybar::chrono::milliseconds(150));
});
}
void waybar::modules::Workspaces::_handle_idle(void *data,
struct org_kde_kwin_idle_timeout *timer) {
auto o = reinterpret_cast<waybar::modules::Workspaces *>(data);
if (o->_thread) {
delete o->_thread;
o->_thread = nullptr;
}
}
void waybar::modules::Workspaces::_handle_resume(void *data,
struct org_kde_kwin_idle_timeout *timer) {
auto o = reinterpret_cast<waybar::modules::Workspaces *>(data);
if (!o->_thread) {
o->_updateThread();
}
}
void waybar::modules::Workspaces::_addWorkspace(Json::Value node) void waybar::modules::Workspaces::_addWorkspace(Json::Value node)
{ {
auto pair = _buttons.emplace(node["num"].asInt(), node["name"].asString()); auto pair = _buttons.emplace(node["num"].asInt(), node["name"].asString());
auto &button = pair.first->second; auto &button = pair.first->second;
_box.pack_start(button, false, false, 0);
button.set_relief(Gtk::RELIEF_NONE); button.set_relief(Gtk::RELIEF_NONE);
button.signal_clicked().connect([this, pair] { button.signal_clicked().connect([this, pair] {
auto value = fmt::format("workspace \"{}\"", pair.first->first); auto value = fmt::format("workspace \"{}\"", pair.first->first);
uint32_t size = value.size(); uint32_t size = value.size();
ipc_single_command(_ipcSocketfd, IPC_COMMAND, value.c_str(), &size); ipc_single_command(_ipcSocketfd, IPC_COMMAND, value.c_str(), &size);
}); });
_box->pack_start(button, false, false, 0); _box.reorder_child(button, node["num"].asInt() - 1);
_box->reorder_child(button, node["num"].asInt() - 1);
if (node["focused"].asBool()) { if (node["focused"].asBool()) {
button.get_style_context()->add_class("current"); button.get_style_context()->add_class("current");
} }
@ -117,5 +89,5 @@ Json::Value waybar::modules::Workspaces::_getWorkspaces()
} }
waybar::modules::Workspaces::operator Gtk::Widget &() { waybar::modules::Workspaces::operator Gtk::Widget &() {
return *_box; return _box;
} }