From cee031d2faeb66146928329dc284fbbfe40fc38f Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 14 Aug 2018 11:26:06 +0200 Subject: [PATCH] Workspaces scroll event (#19) --- include/modules/workspaces.hpp | 4 ++ src/modules/battery.cpp | 3 +- src/modules/workspaces.cpp | 81 +++++++++++++++++++++++++++++++--- 3 files changed, 82 insertions(+), 6 deletions(-) diff --git a/include/modules/workspaces.hpp b/include/modules/workspaces.hpp index ac3cc889..928ee6d1 100644 --- a/include/modules/workspaces.hpp +++ b/include/modules/workspaces.hpp @@ -17,11 +17,15 @@ namespace waybar::modules { private: void _addWorkspace(Json::Value node); Json::Value _getWorkspaces(const std::string data); + bool _handleScroll(GdkEventScroll *e); + int _getPrevWorkspace(); + int _getNextWorkspace(); Bar &_bar; waybar::util::SleeperThread _thread; Gtk::Box _box; util::JsonParser _parser; std::mutex _mutex; + bool _scrolling; std::unordered_map _buttons; Json::Value _workspaces; int _ipcfd; diff --git a/src/modules/battery.cpp b/src/modules/battery.cpp index fadebda4..697c64ec 100644 --- a/src/modules/battery.cpp +++ b/src/modules/battery.cpp @@ -57,7 +57,8 @@ auto waybar::modules::Battery::update() -> void _label.get_style_context()->add_class("charging"); else _label.get_style_context()->remove_class("charging"); - if (capacity < 16 && !charging) + auto critical = _config["critical"] ? _config["critical"].asUInt() : 15; + if (capacity <= critical && !charging) _label.get_style_context()->add_class("warning"); else _label.get_style_context()->remove_class("warning"); diff --git a/src/modules/workspaces.cpp b/src/modules/workspaces.cpp index 34ff7bd3..879a7ba2 100644 --- a/src/modules/workspaces.cpp +++ b/src/modules/workspaces.cpp @@ -2,7 +2,7 @@ #include "ipc/client.hpp" waybar::modules::Workspaces::Workspaces(Bar &bar) - : _bar(bar) + : _bar(bar), _scrolling(false) { _box.get_style_context()->add_class("workspaces"); std::string socketPath = get_socketpath(); @@ -58,10 +58,12 @@ auto waybar::modules::Workspaces::update() -> void button.get_style_context()->add_class("current"); } if (needReorder) - _box.reorder_child(button, node["num"].asInt() - 1); + _box.reorder_child(button, node["num"].asInt()); button.show(); } } + if (_scrolling) + _scrolling = false; } void waybar::modules::Workspaces::_addWorkspace(Json::Value node) @@ -80,13 +82,82 @@ void waybar::modules::Workspaces::_addWorkspace(Json::Value node) std::cerr << e.what() << std::endl; } }); - _box.reorder_child(button, node["num"].asInt() - 1); - if (node["focused"].asBool()) { + button.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK); + button.signal_scroll_event() + .connect(sigc::mem_fun(*this, &Workspaces::_handleScroll)); + _box.reorder_child(button, node["num"].asInt()); + if (node["focused"].asBool()) button.get_style_context()->add_class("current"); - } button.show(); } +bool waybar::modules::Workspaces::_handleScroll(GdkEventScroll *e) +{ + std::lock_guard lock(_mutex); + // Avoid concurrent scroll event + if (_scrolling) + return false; + _scrolling = true; + int id = -1; + uint16_t idx = 0; + for (; idx < _workspaces.size(); idx += 1) + if (_workspaces[idx]["focused"].asBool()) { + id = _workspaces[idx]["num"].asInt(); + break; + } + if (id == -1) { + _scrolling = false; + return false; + } + if (e->direction == GDK_SCROLL_UP) + id = _getNextWorkspace(); + if (e->direction == GDK_SCROLL_DOWN) + id = _getPrevWorkspace(); + if (e->direction == GDK_SCROLL_SMOOTH) { + gdouble delta_x, delta_y; + gdk_event_get_scroll_deltas ((const GdkEvent *) e, &delta_x, &delta_y); + if (delta_y < 0) + id = _getNextWorkspace(); + else if (delta_y > 0) + id = _getPrevWorkspace(); + } + if (id == _workspaces[idx]["num"].asInt()) { + _scrolling = false; + return false; + } + auto value = fmt::format("workspace \"{}\"", id); + uint32_t size = value.size(); + ipc_single_command(_ipcfd, IPC_COMMAND, value.c_str(), &size); + std::this_thread::sleep_for(std::chrono::milliseconds(150)); + return true; +} + +int waybar::modules::Workspaces::_getPrevWorkspace() +{ + int current = -1; + for (uint16_t i = 0; i != _workspaces.size(); i += 1) + if (_workspaces[i]["focused"].asBool()) { + current = _workspaces[i]["num"].asInt(); + if (i > 0) + return _workspaces[i - 1]["num"].asInt(); + return _workspaces[_workspaces.size() - 1]["num"].asInt(); + } + return current; +} + +int waybar::modules::Workspaces::_getNextWorkspace() +{ + int current = -1; + for (uint16_t i = 0; i != _workspaces.size(); i += 1) + if (_workspaces[i]["focused"].asBool()) { + current = _workspaces[i]["num"].asInt(); + if (i + 1U < _workspaces.size()) + return _workspaces[i + 1]["num"].asInt(); + return _workspaces[0]["num"].asInt(); + } + return current; +} + Json::Value waybar::modules::Workspaces::_getWorkspaces(const std::string data) { Json::Value res;