feat(sway): add focused window name

This commit is contained in:
Alexis 2018-08-15 20:17:17 +02:00
parent 9b75302d22
commit f94598c138
10 changed files with 119 additions and 31 deletions

View File

@ -2,7 +2,8 @@
#include <json/json.h> #include <json/json.h>
#include "modules/clock.hpp" #include "modules/clock.hpp"
#include "modules/workspaces.hpp" #include "modules/sway/workspaces.hpp"
#include "modules/sway/window.hpp"
#include "modules/battery.hpp" #include "modules/battery.hpp"
#include "modules/memory.hpp" #include "modules/memory.hpp"
#include "modules/cpu.hpp" #include "modules/cpu.hpp"

View File

@ -0,0 +1,30 @@
#pragma once
#include <fmt/format.h>
#include "bar.hpp"
#include "client.hpp"
#include "util/chrono.hpp"
#include "util/json.hpp"
#include "IModule.hpp"
namespace waybar::modules::sway {
class Window : public IModule {
public:
Window(waybar::Bar &bar, Json::Value config);
auto update() -> void;
operator Gtk::Widget &();
private:
std::string _getFocusedNode(Json::Value nodes);
void _getFocusedWindow();
Bar &_bar;
Json::Value _config;
waybar::util::SleeperThread _thread;
Gtk::Label _label;
util::JsonParser _parser;
int _ipcfd;
int _ipcEventfd;
std::string _window;
};
}

View File

@ -7,7 +7,7 @@
#include "util/json.hpp" #include "util/json.hpp"
#include "IModule.hpp" #include "IModule.hpp"
namespace waybar::modules { namespace waybar::modules::sway {
class Workspaces : public IModule { class Workspaces : public IModule {
public: public:
@ -17,7 +17,6 @@ namespace waybar::modules {
private: private:
void _addWorkspace(Json::Value node); void _addWorkspace(Json::Value node);
std::string _getIcon(std::string name); std::string _getIcon(std::string name);
Json::Value _getWorkspaces(const std::string data);
bool _handleScroll(GdkEventScroll *e); bool _handleScroll(GdkEventScroll *e);
int _getPrevWorkspace(); int _getPrevWorkspace();
int _getNextWorkspace(); int _getNextWorkspace();

View File

@ -4,7 +4,8 @@
// "height": 30, // Waybar height // "height": 30, // Waybar height
// "width": 1280, // Waybar width // "width": 1280, // Waybar width
// Choose the order of the modules // Choose the order of the modules
"modules-left": ["workspaces", "custom/spotify"], "modules-left": ["sway/workspaces", "custom/spotify"],
"modules-center": ["sway/window"],
"modules-right": ["pulseaudio", "network", "cpu", "memory", "battery", "clock"], "modules-right": ["pulseaudio", "network", "cpu", "memory", "battery", "clock"],
// Modules configuration // Modules configuration
"workspaces": { "workspaces": {

View File

@ -9,8 +9,10 @@ waybar::IModule *waybar::Factory::makeModule(std::string name)
try { try {
if (name == "battery") if (name == "battery")
return new waybar::modules::Battery(_config[name]); return new waybar::modules::Battery(_config[name]);
if (name == "workspaces") if (name == "sway/workspaces")
return new waybar::modules::Workspaces(_bar, _config[name]); return new waybar::modules::sway::Workspaces(_bar, _config[name]);
if (name == "sway/window")
return new waybar::modules::sway::Window(_bar, _config[name]);
if (name == "memory") if (name == "memory")
return new waybar::modules::Memory(_config[name]); return new waybar::modules::Memory(_config[name]);
if (name == "cpu") if (name == "cpu")

View File

@ -3,7 +3,7 @@
#include <stdio.h> #include <stdio.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/un.h> #include <sys/un.h>
#include "ipc/client.hpp" #include "modules/sway/ipc/client.hpp"
static const char ipc_magic[] = {'i', '3', '-', 'i', 'p', 'c'}; static const char ipc_magic[] = {'i', '3', '-', 'i', 'p', 'c'};
static const size_t ipc_header_size = sizeof(ipc_magic)+8; static const size_t ipc_header_size = sizeof(ipc_magic)+8;

View File

@ -0,0 +1,66 @@
#include "modules/sway/window.hpp"
#include "modules/sway/ipc/client.hpp"
waybar::modules::sway::Window::Window(Bar &bar, Json::Value config)
: _bar(bar), _config(config)
{
_label.set_name("window");
std::string socketPath = get_socketpath();
_ipcfd = ipc_open_socket(socketPath);
_ipcEventfd = ipc_open_socket(socketPath);
const char *subscribe = "[ \"window\" ]";
uint32_t len = strlen(subscribe);
ipc_single_command(_ipcEventfd, IPC_SUBSCRIBE, subscribe, &len);
_getFocusedWindow();
_thread = [this] {
try {
if (_bar.outputName.empty()) {
// Wait for the name of the output
while (_bar.outputName.empty())
_thread.sleep_for(chrono::milliseconds(150));
}
auto res = ipc_recv_response(_ipcEventfd);
auto parsed = _parser.parse(res.payload);
if (parsed["change"] != "focus")
return;
_window = parsed["container"]["name"].asString();
Glib::signal_idle().connect_once(sigc::mem_fun(*this, &Window::update));
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
}
};
}
auto waybar::modules::sway::Window::update() -> void
{
_label.set_text(_window);
}
std::string waybar::modules::sway::Window::_getFocusedNode(Json::Value nodes)
{
for (auto &node : nodes) {
if (node["focused"].asBool())
return node["name"].asString();
auto res = _getFocusedNode(node["nodes"]);
if (!res.empty())
return res;
}
return std::string();
}
void waybar::modules::sway::Window::_getFocusedWindow()
{
try {
uint32_t len = 0;
auto res = ipc_single_command(_ipcfd, IPC_GET_TREE, nullptr, &len);
auto parsed = _parser.parse(res);
_window = _getFocusedNode(parsed["nodes"]);
Glib::signal_idle().connect_once(sigc::mem_fun(*this, &Window::update));
} catch (const std::exception &e) {
std::cerr << e.what() << std::endl;
}
}
waybar::modules::sway::Window::operator Gtk::Widget &() {
return _label;
}

View File

@ -1,7 +1,7 @@
#include "modules/workspaces.hpp" #include "modules/sway/workspaces.hpp"
#include "ipc/client.hpp" #include "modules/sway/ipc/client.hpp"
waybar::modules::Workspaces::Workspaces(Bar &bar, Json::Value config) waybar::modules::sway::Workspaces::Workspaces(Bar &bar, Json::Value config)
: _bar(bar), _config(config), _scrolling(false) : _bar(bar), _config(config), _scrolling(false)
{ {
_box.set_name("workspaces"); _box.set_name("workspaces");
@ -22,15 +22,16 @@ waybar::modules::Workspaces::Workspaces(Bar &bar, Json::Value config)
uint32_t len = 0; uint32_t len = 0;
std::lock_guard<std::mutex> lock(_mutex); std::lock_guard<std::mutex> lock(_mutex);
auto str = ipc_single_command(_ipcfd, IPC_GET_WORKSPACES, nullptr, &len); auto str = ipc_single_command(_ipcfd, IPC_GET_WORKSPACES, nullptr, &len);
_workspaces = _getWorkspaces(str); _workspaces = _parser.parse(str);
Glib::signal_idle().connect_once(sigc::mem_fun(*this, &Workspaces::update)); Glib::signal_idle()
.connect_once(sigc::mem_fun(*this, &Workspaces::update));
} catch (const std::exception& e) { } catch (const std::exception& e) {
std::cerr << e.what() << std::endl; std::cerr << e.what() << std::endl;
} }
}; };
} }
auto waybar::modules::Workspaces::update() -> void auto waybar::modules::sway::Workspaces::update() -> void
{ {
std::lock_guard<std::mutex> lock(_mutex); std::lock_guard<std::mutex> lock(_mutex);
bool needReorder = false; bool needReorder = false;
@ -73,7 +74,7 @@ auto waybar::modules::Workspaces::update() -> void
_scrolling = false; _scrolling = false;
} }
void waybar::modules::Workspaces::_addWorkspace(Json::Value node) void waybar::modules::sway::Workspaces::_addWorkspace(Json::Value node)
{ {
auto icon = _getIcon(node["name"].asString()); auto icon = _getIcon(node["name"].asString());
auto pair = _buttons.emplace(node["num"].asInt(), icon); auto pair = _buttons.emplace(node["num"].asInt(), icon);
@ -105,7 +106,7 @@ void waybar::modules::Workspaces::_addWorkspace(Json::Value node)
button.show(); button.show();
} }
std::string waybar::modules::Workspaces::_getIcon(std::string name) std::string waybar::modules::sway::Workspaces::_getIcon(std::string name)
{ {
if (_config["format-icons"][name]) if (_config["format-icons"][name])
return _config["format-icons"][name].asString(); return _config["format-icons"][name].asString();
@ -114,7 +115,7 @@ std::string waybar::modules::Workspaces::_getIcon(std::string name)
return name; return name;
} }
bool waybar::modules::Workspaces::_handleScroll(GdkEventScroll *e) bool waybar::modules::sway::Workspaces::_handleScroll(GdkEventScroll *e)
{ {
std::lock_guard<std::mutex> lock(_mutex); std::lock_guard<std::mutex> lock(_mutex);
// Avoid concurrent scroll event // Avoid concurrent scroll event
@ -155,7 +156,7 @@ bool waybar::modules::Workspaces::_handleScroll(GdkEventScroll *e)
return true; return true;
} }
int waybar::modules::Workspaces::_getPrevWorkspace() int waybar::modules::sway::Workspaces::_getPrevWorkspace()
{ {
int current = -1; int current = -1;
for (uint16_t i = 0; i != _workspaces.size(); i += 1) for (uint16_t i = 0; i != _workspaces.size(); i += 1)
@ -168,7 +169,7 @@ int waybar::modules::Workspaces::_getPrevWorkspace()
return current; return current;
} }
int waybar::modules::Workspaces::_getNextWorkspace() int waybar::modules::sway::Workspaces::_getNextWorkspace()
{ {
int current = -1; int current = -1;
for (uint16_t i = 0; i != _workspaces.size(); i += 1) for (uint16_t i = 0; i != _workspaces.size(); i += 1)
@ -181,18 +182,6 @@ int waybar::modules::Workspaces::_getNextWorkspace()
return current; return current;
} }
Json::Value waybar::modules::Workspaces::_getWorkspaces(const std::string data) waybar::modules::sway::Workspaces::operator Gtk::Widget &() {
{
Json::Value res;
try {
std::string err;
res = _parser.parse(data);
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
}
return res;
}
waybar::modules::Workspaces::operator Gtk::Widget &() {
return _box; return _box;
} }