mirror of
https://github.com/polybar/polybar.git
synced 2024-11-25 13:55:47 -05:00
refactor(xworkspaces): Cleanup
This commit is contained in:
parent
6364bb4385
commit
1a25be374f
4 changed files with 235 additions and 147 deletions
|
@ -31,8 +31,10 @@ namespace modules {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct desktop {
|
struct desktop {
|
||||||
explicit desktop(size_t index, desktop_state state, label_t&& label) : index(index), state(state), label(label) {}
|
explicit desktop(unsigned int index, unsigned int offset, desktop_state state, label_t&& label)
|
||||||
size_t index;
|
: index(index), offset(offset), state(state), label(label) {}
|
||||||
|
unsigned int index;
|
||||||
|
unsigned int offset;
|
||||||
desktop_state state;
|
desktop_state state;
|
||||||
label_t label;
|
label_t label;
|
||||||
};
|
};
|
||||||
|
@ -60,8 +62,11 @@ namespace modules {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void handle(const evt::property_notify& evt);
|
void handle(const evt::property_notify& evt);
|
||||||
|
|
||||||
|
void rebuild_clientlist();
|
||||||
void rebuild_desktops();
|
void rebuild_desktops();
|
||||||
void set_current_desktop();
|
void rebuild_desktop_states();
|
||||||
|
|
||||||
bool input(string&& cmd);
|
bool input(string&& cmd);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -79,9 +84,14 @@ namespace modules {
|
||||||
|
|
||||||
connection& m_connection;
|
connection& m_connection;
|
||||||
ewmh_connection_t m_ewmh;
|
ewmh_connection_t m_ewmh;
|
||||||
|
|
||||||
vector<monitor_t> m_monitors;
|
vector<monitor_t> m_monitors;
|
||||||
bool m_monitorsupport{true};
|
bool m_monitorsupport{true};
|
||||||
|
|
||||||
|
vector<string> m_desktop_names;
|
||||||
|
unsigned int m_current_desktop;
|
||||||
|
|
||||||
|
vector<xcb_window_t> m_clientlist;
|
||||||
vector<unique_ptr<viewport>> m_viewports;
|
vector<unique_ptr<viewport>> m_viewports;
|
||||||
map<desktop_state, label_t> m_labels;
|
map<desktop_state, label_t> m_labels;
|
||||||
label_t m_monitorlabel;
|
label_t m_monitorlabel;
|
||||||
|
@ -90,6 +100,8 @@ namespace modules {
|
||||||
bool m_click{true};
|
bool m_click{true};
|
||||||
bool m_scroll{true};
|
bool m_scroll{true};
|
||||||
size_t m_index{0};
|
size_t m_index{0};
|
||||||
|
|
||||||
|
event_timer m_timer{0L, 25L};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,11 +29,17 @@ namespace ewmh_util {
|
||||||
void change_current_desktop(unsigned int desktop);
|
void change_current_desktop(unsigned int desktop);
|
||||||
|
|
||||||
void set_wm_window_type(xcb_window_t win, vector<xcb_atom_t> types);
|
void set_wm_window_type(xcb_window_t win, vector<xcb_atom_t> types);
|
||||||
|
|
||||||
void set_wm_state(xcb_window_t win, vector<xcb_atom_t> states);
|
void set_wm_state(xcb_window_t win, vector<xcb_atom_t> states);
|
||||||
|
vector<xcb_atom_t> get_wm_state(xcb_window_t win);
|
||||||
|
|
||||||
void set_wm_pid(xcb_window_t win);
|
void set_wm_pid(xcb_window_t win);
|
||||||
void set_wm_pid(xcb_window_t win, unsigned int pid);
|
void set_wm_pid(xcb_window_t win, unsigned int pid);
|
||||||
|
|
||||||
void set_wm_desktop(xcb_window_t win, unsigned int desktop = -1u);
|
void set_wm_desktop(xcb_window_t win, unsigned int desktop = -1u);
|
||||||
void set_wm_window_opacity(xcb_window_t win, unsigned long int values);
|
void set_wm_window_opacity(xcb_window_t win, unsigned long int values);
|
||||||
|
|
||||||
|
vector<xcb_window_t> get_client_list(int screen = 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
POLYBAR_NS_END
|
POLYBAR_NS_END
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include <algorithm>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "drawtypes/iconset.hpp"
|
#include "drawtypes/iconset.hpp"
|
||||||
|
@ -12,6 +13,15 @@
|
||||||
|
|
||||||
POLYBAR_NS
|
POLYBAR_NS
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
inline bool operator==(const position& a, const position& b) {
|
||||||
|
return a.x + a.y == b.x + b.y;
|
||||||
|
}
|
||||||
|
inline bool operator!=(const position& a, const position& b) {
|
||||||
|
return !(a == b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace modules {
|
namespace modules {
|
||||||
template class module<xworkspaces_module>;
|
template class module<xworkspaces_module>;
|
||||||
|
|
||||||
|
@ -36,15 +46,10 @@ namespace modules {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the WM supports _NET_DESKTOP_VIEWPORT
|
// Check if the WM supports _NET_DESKTOP_VIEWPORT
|
||||||
if (!ewmh_util::supports(m_ewmh->_NET_DESKTOP_VIEWPORT) && m_pinworkspaces) {
|
if (!(m_monitorsupport = ewmh_util::supports(m_ewmh->_NET_DESKTOP_VIEWPORT)) && m_pinworkspaces) {
|
||||||
throw module_error("The WM does not support _NET_DESKTOP_VIEWPORT (required when `pin-workspaces = true`)");
|
throw module_error("The WM does not support _NET_DESKTOP_VIEWPORT (required when `pin-workspaces = true`)");
|
||||||
} else if (!m_pinworkspaces) {
|
|
||||||
m_monitorsupport = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get list of monitors
|
|
||||||
m_monitors = randr_util::get_monitors(m_connection, m_connection.root(), false);
|
|
||||||
|
|
||||||
// Add formats and elements
|
// Add formats and elements
|
||||||
m_formatter->add(DEFAULT_FORMAT, TAG_LABEL_STATE, {TAG_LABEL_STATE, TAG_LABEL_MONITOR});
|
m_formatter->add(DEFAULT_FORMAT, TAG_LABEL_STATE, {TAG_LABEL_STATE, TAG_LABEL_MONITOR});
|
||||||
|
|
||||||
|
@ -74,137 +79,210 @@ namespace modules {
|
||||||
m_icons->add(vec[0], factory_util::shared<label>(vec[1]));
|
m_icons->add(vec[0], factory_util::shared<label>(vec[1]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get list of monitors
|
||||||
|
m_monitors = randr_util::get_monitors(m_connection, m_connection.root(), false);
|
||||||
|
|
||||||
|
// Get desktop details
|
||||||
|
m_desktop_names = ewmh_util::get_desktop_names();
|
||||||
|
m_current_desktop = ewmh_util::get_current_desktop();
|
||||||
|
|
||||||
|
rebuild_desktops();
|
||||||
|
rebuild_desktop_states();
|
||||||
|
|
||||||
|
// Get _NET_CLIENT_LIST
|
||||||
|
rebuild_clientlist();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler for XCB_PROPERTY_NOTIFY events
|
* Handler for XCB_PROPERTY_NOTIFY events
|
||||||
*/
|
*/
|
||||||
void xworkspaces_module::handle(const evt::property_notify& evt) {
|
void xworkspaces_module::handle(const evt::property_notify& evt) {
|
||||||
if (evt->atom == m_ewmh->_NET_DESKTOP_NAMES) {
|
if (evt->atom == m_ewmh->_NET_CLIENT_LIST) {
|
||||||
update();
|
rebuild_clientlist();
|
||||||
|
} else if (evt->atom == m_ewmh->_NET_DESKTOP_NAMES) {
|
||||||
|
m_desktop_names = ewmh_util::get_desktop_names();
|
||||||
|
rebuild_desktops();
|
||||||
|
rebuild_desktop_states();
|
||||||
} else if (evt->atom == m_ewmh->_NET_CURRENT_DESKTOP) {
|
} else if (evt->atom == m_ewmh->_NET_CURRENT_DESKTOP) {
|
||||||
update();
|
m_current_desktop = ewmh_util::get_current_desktop();
|
||||||
|
rebuild_desktop_states();
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit notification to trigger redraw
|
if (m_timer.allow(evt->time)) {
|
||||||
broadcast();
|
broadcast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rebuild the list of managed clients
|
||||||
|
*/
|
||||||
|
void xworkspaces_module::rebuild_clientlist() {
|
||||||
|
vector<xcb_window_t> clients = ewmh_util::get_client_list();
|
||||||
|
vector<xcb_window_t> diff;
|
||||||
|
std::sort(clients.begin(), clients.end());
|
||||||
|
std::sort(m_clientlist.begin(), m_clientlist.end());
|
||||||
|
|
||||||
|
if (m_clientlist.size() > clients.size()) {
|
||||||
|
std::set_difference(
|
||||||
|
m_clientlist.begin(), m_clientlist.end(), clients.begin(), clients.end(), back_inserter(diff));
|
||||||
|
for (auto&& win : diff) {
|
||||||
|
// untrack window
|
||||||
|
m_clientlist.erase(std::remove(m_clientlist.begin(), m_clientlist.end(), win), m_clientlist.end());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::set_difference(
|
||||||
|
clients.begin(), clients.end(), m_clientlist.begin(), m_clientlist.end(), back_inserter(diff));
|
||||||
|
for (auto&& win : diff) {
|
||||||
|
// track window
|
||||||
|
m_clientlist.emplace_back(win);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rebuild the desktop tree
|
||||||
|
*/
|
||||||
|
void xworkspaces_module::rebuild_desktops() {
|
||||||
|
m_viewports.clear();
|
||||||
|
|
||||||
|
auto bounds = [&] {
|
||||||
|
if (m_monitorsupport) {
|
||||||
|
return ewmh_util::get_desktop_viewports();
|
||||||
|
} else {
|
||||||
|
vector<position> b;
|
||||||
|
std::fill_n(std::back_inserter(b), m_desktop_names.size(), position{m_bar.monitor->x, m_bar.monitor->y});
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
|
||||||
|
bounds.erase(std::unique(bounds.begin(), bounds.end(), [](auto& a, auto& b) { return a == b; }), bounds.end());
|
||||||
|
|
||||||
|
unsigned int step = m_desktop_names.size() / bounds.size();
|
||||||
|
unsigned int offset = 0;
|
||||||
|
for (unsigned int i = 0; i < bounds.size(); i++) {
|
||||||
|
if (!m_pinworkspaces || m_bar.monitor->match(bounds[i])) {
|
||||||
|
auto viewport = make_unique<struct viewport>();
|
||||||
|
viewport->state = viewport_state::UNFOCUSED;
|
||||||
|
viewport->pos = bounds[i];
|
||||||
|
|
||||||
|
for (auto&& m : m_monitors) {
|
||||||
|
if (m->match(viewport->pos)) {
|
||||||
|
viewport->name = m->name;
|
||||||
|
viewport->state = viewport_state::FOCUSED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
viewport->label = [&] {
|
||||||
|
label_t label;
|
||||||
|
if (m_monitorlabel) {
|
||||||
|
label = m_monitorlabel->clone();
|
||||||
|
label->reset_tokens();
|
||||||
|
label->replace_token("%name%", viewport->name);
|
||||||
|
}
|
||||||
|
return label;
|
||||||
|
}();
|
||||||
|
|
||||||
|
for (unsigned int index = offset; index < offset + step; index++) {
|
||||||
|
viewport->desktops.emplace_back(make_unique<struct desktop>(index, offset, desktop_state::EMPTY, label_t{}));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_viewports.emplace_back(move(viewport));
|
||||||
|
}
|
||||||
|
offset += step;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update active state of current desktops
|
||||||
|
*/
|
||||||
|
void xworkspaces_module::rebuild_desktop_states() {
|
||||||
|
for (auto&& v : m_viewports) {
|
||||||
|
for (auto&& d : v->desktops) {
|
||||||
|
if (d->index == m_current_desktop && d->state != desktop_state::ACTIVE) {
|
||||||
|
d->state = desktop_state::ACTIVE;
|
||||||
|
} else if (d->state == desktop_state::ACTIVE) {
|
||||||
|
d->state = desktop_state::EMPTY;
|
||||||
|
} else if (d->label) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
d->label = m_labels.at(d->state)->clone();
|
||||||
|
d->label->reset_tokens();
|
||||||
|
d->label->replace_token("%index%", to_string(d->index - d->offset + 1));
|
||||||
|
d->label->replace_token("%name%", m_desktop_names[d->index]);
|
||||||
|
d->label->replace_token("%icon%", m_icons->get(m_desktop_names[d->index], DEFAULT_ICON)->get());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch and parse data
|
* Fetch and parse data
|
||||||
*/
|
*/
|
||||||
void xworkspaces_module::update() {
|
void xworkspaces_module::update() {}
|
||||||
auto current = ewmh_util::get_current_desktop();
|
|
||||||
auto names = ewmh_util::get_desktop_names();
|
|
||||||
vector<position> viewports;
|
|
||||||
size_t num{0};
|
|
||||||
position pos{};
|
|
||||||
|
|
||||||
if (m_monitorsupport) {
|
|
||||||
viewports = ewmh_util::get_desktop_viewports();
|
|
||||||
num = math_util::min(names.size(), viewports.size());
|
|
||||||
} else {
|
|
||||||
num = names.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_viewports.clear();
|
|
||||||
|
|
||||||
for (size_t n = 0; n < num; n++) {
|
|
||||||
if (m_pinworkspaces && !m_bar.monitor->match(viewports[n])) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_monitorsupport && (n == 0 || pos.x != viewports[n].x || pos.y != viewports[n].y)) {
|
|
||||||
m_viewports.emplace_back(factory_util::unique<viewport>());
|
|
||||||
|
|
||||||
for (auto&& monitor : m_monitors) {
|
|
||||||
if (monitor->match(viewports[n])) {
|
|
||||||
m_viewports.back()->name = monitor->name;
|
|
||||||
m_viewports.back()->pos.x = static_cast<short int>(monitor->x);
|
|
||||||
m_viewports.back()->pos.y = static_cast<short int>(monitor->y);
|
|
||||||
m_viewports.back()->state = viewport_state::FOCUSED;
|
|
||||||
m_viewports.back()->label = m_monitorlabel->clone();
|
|
||||||
m_viewports.back()->label->replace_token("%name%", monitor->name);
|
|
||||||
pos = m_viewports.back()->pos;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (!m_monitorsupport && n == 0) {
|
|
||||||
m_viewports.emplace_back(factory_util::unique<viewport>());
|
|
||||||
m_viewports.back()->state = viewport_state::NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
desktop_state state{current == n ? desktop_state::ACTIVE : desktop_state::EMPTY};
|
|
||||||
m_viewports.back()->desktops.emplace_back(factory_util::unique<desktop>(n, state, m_labels[state]->clone()));
|
|
||||||
|
|
||||||
auto& desktop = m_viewports.back()->desktops.back();
|
|
||||||
desktop->label->reset_tokens();
|
|
||||||
desktop->label->replace_token("%name%", names[n]);
|
|
||||||
desktop->label->replace_token("%icon%", m_icons->get(names[n], DEFAULT_ICON)->get());
|
|
||||||
desktop->label->replace_token("%index%", to_string(n));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate module output
|
* Generate module output
|
||||||
*/
|
*/
|
||||||
string xworkspaces_module::get_output() {
|
string xworkspaces_module::get_output() {
|
||||||
|
// Get the module output early so that
|
||||||
|
// the format prefix/suffix also gets wrapped
|
||||||
|
// with the cmd handlers
|
||||||
string output;
|
string output;
|
||||||
for (m_index = 0; m_index < m_viewports.size(); m_index++) {
|
for (m_index = 0; m_index < m_viewports.size(); m_index++) {
|
||||||
if (m_index > 0) {
|
if (m_index > 0) {
|
||||||
m_builder->space(m_formatter->get(DEFAULT_FORMAT)->spacing);
|
m_builder->space(m_formatter->get(DEFAULT_FORMAT)->spacing);
|
||||||
}
|
}
|
||||||
output += static_module::get_output();
|
output += module::get_output();
|
||||||
}
|
}
|
||||||
return output;
|
|
||||||
|
m_builder->cmd(mousebtn::SCROLL_DOWN, string{EVENT_PREFIX} + string{EVENT_SCROLL_DOWN});
|
||||||
|
m_builder->cmd(mousebtn::SCROLL_UP, string{EVENT_PREFIX} + string{EVENT_SCROLL_UP});
|
||||||
|
|
||||||
|
m_builder->append(output);
|
||||||
|
|
||||||
|
m_builder->cmd_close();
|
||||||
|
m_builder->cmd_close();
|
||||||
|
|
||||||
|
return m_builder->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Output content as defined in the config
|
* Output content as defined in the config
|
||||||
*/
|
*/
|
||||||
bool xworkspaces_module::build(builder* builder, const string& tag) const {
|
bool xworkspaces_module::build(builder* builder, const string& tag) const {
|
||||||
if (m_index >= m_viewports.size()) {
|
if (tag == TAG_LABEL_MONITOR) {
|
||||||
m_log.warn("%s: Invalid index (index=%lu, viewports=%lu)", name(), m_index, m_viewports.size());
|
if (m_viewports[m_index]->state != viewport_state::NONE) {
|
||||||
} else if (tag == TAG_LABEL_MONITOR && m_viewports[m_index]->state != viewport_state::NONE) {
|
builder->node(m_viewports[m_index]->label);
|
||||||
builder->node(m_viewports[m_index]->label);
|
return true;
|
||||||
return true;
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
} else if (tag == TAG_LABEL_STATE) {
|
} else if (tag == TAG_LABEL_STATE) {
|
||||||
size_t num{0};
|
unsigned int added_states = 0;
|
||||||
|
|
||||||
if (m_scroll) {
|
|
||||||
builder->cmd(mousebtn::SCROLL_DOWN, string{EVENT_PREFIX} + string{EVENT_SCROLL_DOWN});
|
|
||||||
builder->cmd(mousebtn::SCROLL_UP, string{EVENT_PREFIX} + string{EVENT_SCROLL_UP});
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto&& desktop : m_viewports[m_index]->desktops) {
|
for (auto&& desktop : m_viewports[m_index]->desktops) {
|
||||||
if (!desktop->label.get()) {
|
if (desktop->label.get()) {
|
||||||
continue;
|
if (m_click && desktop->state != desktop_state::ACTIVE) {
|
||||||
|
builder->cmd(mousebtn::LEFT, string{EVENT_PREFIX} + string{EVENT_CLICK} + to_string(desktop->index));
|
||||||
|
builder->node(desktop->label);
|
||||||
|
builder->cmd_close();
|
||||||
|
} else {
|
||||||
|
builder->node(desktop->label);
|
||||||
|
}
|
||||||
|
added_states++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_click && desktop->state != desktop_state::ACTIVE) {
|
|
||||||
builder->cmd(mousebtn::LEFT, string{EVENT_PREFIX} + string{EVENT_CLICK} + to_string(desktop->index));
|
|
||||||
builder->node(desktop->label);
|
|
||||||
builder->cmd_close();
|
|
||||||
} else {
|
|
||||||
builder->node(desktop->label);
|
|
||||||
}
|
|
||||||
|
|
||||||
num++;
|
|
||||||
}
|
}
|
||||||
|
return added_states > 0;
|
||||||
if (m_scroll) {
|
} else {
|
||||||
builder->cmd_close();
|
return false;
|
||||||
builder->cmd_close();
|
|
||||||
}
|
|
||||||
|
|
||||||
return num > 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle user input event
|
||||||
|
*/
|
||||||
bool xworkspaces_module::input(string&& cmd) {
|
bool xworkspaces_module::input(string&& cmd) {
|
||||||
size_t len{strlen(EVENT_PREFIX)};
|
size_t len{strlen(EVENT_PREFIX)};
|
||||||
if (cmd.compare(0, len, EVENT_PREFIX) != 0) {
|
if (cmd.compare(0, len, EVENT_PREFIX) != 0) {
|
||||||
|
@ -212,41 +290,31 @@ namespace modules {
|
||||||
}
|
}
|
||||||
cmd.erase(0, len);
|
cmd.erase(0, len);
|
||||||
|
|
||||||
unsigned int new_desktop{0};
|
vector<unsigned int> indexes;
|
||||||
unsigned int min_desktop{0};
|
|
||||||
unsigned int max_desktop{0};
|
|
||||||
unsigned int current_desktop{ewmh_util::get_current_desktop()};
|
|
||||||
|
|
||||||
for (auto&& viewport : m_viewports) {
|
for (auto&& viewport : m_viewports) {
|
||||||
for (auto&& desktop : viewport->desktops) {
|
for (auto&& desktop : viewport->desktops) {
|
||||||
if (min_desktop == 0) {
|
indexes.emplace_back(desktop->index);
|
||||||
min_desktop = desktop->index;
|
|
||||||
max_desktop = math_util::max<unsigned short int>(max_desktop, desktop->index);
|
|
||||||
} else {
|
|
||||||
min_desktop = math_util::min<unsigned short int>(min_desktop, desktop->index);
|
|
||||||
max_desktop = math_util::max<unsigned short int>(max_desktop, desktop->index);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::sort(indexes.begin(), indexes.end());
|
||||||
|
|
||||||
|
unsigned int new_desktop{0};
|
||||||
|
unsigned int current_desktop{ewmh_util::get_current_desktop()};
|
||||||
|
|
||||||
if ((len = strlen(EVENT_CLICK)) && cmd.compare(0, len, EVENT_CLICK) == 0) {
|
if ((len = strlen(EVENT_CLICK)) && cmd.compare(0, len, EVENT_CLICK) == 0) {
|
||||||
new_desktop = std::strtoul(cmd.substr(len).c_str(), nullptr, 10);
|
new_desktop = std::strtoul(cmd.substr(len).c_str(), nullptr, 10);
|
||||||
} else if ((len = strlen(EVENT_SCROLL_UP)) && cmd.compare(0, len, EVENT_SCROLL_UP) == 0) {
|
} else if ((len = strlen(EVENT_SCROLL_UP)) && cmd.compare(0, len, EVENT_SCROLL_UP) == 0) {
|
||||||
new_desktop = math_util::min<unsigned int>(max_desktop, current_desktop + 1);
|
new_desktop = math_util::min<unsigned int>(indexes.back(), current_desktop + 1);
|
||||||
if (new_desktop == current_desktop) {
|
new_desktop = new_desktop == current_desktop ? indexes.front() : new_desktop;
|
||||||
new_desktop = min_desktop;
|
|
||||||
}
|
|
||||||
} else if ((len = strlen(EVENT_SCROLL_DOWN)) && cmd.compare(0, len, EVENT_SCROLL_DOWN) == 0) {
|
} else if ((len = strlen(EVENT_SCROLL_DOWN)) && cmd.compare(0, len, EVENT_SCROLL_DOWN) == 0) {
|
||||||
new_desktop = math_util::max<unsigned int>(min_desktop, std::max(0U, current_desktop - 1));
|
new_desktop = math_util::max<unsigned int>(indexes.front(), current_desktop - 1);
|
||||||
if (new_desktop == current_desktop) {
|
new_desktop = new_desktop == current_desktop ? indexes.back() : new_desktop;
|
||||||
new_desktop = max_desktop;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_desktop != current_desktop) {
|
if (new_desktop != current_desktop) {
|
||||||
m_log.info("%s: Requesting change to desktop #%u", name(), new_desktop);
|
m_log.info("%s: Requesting change to desktop #%u", name(), new_desktop);
|
||||||
ewmh_util::change_current_desktop(new_desktop);
|
ewmh_util::change_current_desktop(new_desktop);
|
||||||
m_connection.flush();
|
|
||||||
} else {
|
} else {
|
||||||
m_log.info("%s: Ignoring change to current desktop", name());
|
m_log.info("%s: Ignoring change to current desktop", name());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "components/types.hpp"
|
#include "components/types.hpp"
|
||||||
|
#include "utils/string.hpp"
|
||||||
#include "x11/atoms.hpp"
|
#include "x11/atoms.hpp"
|
||||||
#include "x11/connection.hpp"
|
#include "x11/connection.hpp"
|
||||||
#include "x11/ewmh.hpp"
|
#include "x11/ewmh.hpp"
|
||||||
|
@ -20,22 +21,17 @@ namespace ewmh_util {
|
||||||
|
|
||||||
bool supports(xcb_atom_t atom, int screen) {
|
bool supports(xcb_atom_t atom, int screen) {
|
||||||
auto conn = initialize().get();
|
auto conn = initialize().get();
|
||||||
bool supports{false};
|
|
||||||
xcb_ewmh_get_atoms_reply_t reply{};
|
xcb_ewmh_get_atoms_reply_t reply{};
|
||||||
reply.atoms = nullptr;
|
|
||||||
if (xcb_ewmh_get_supported_reply(conn, xcb_ewmh_get_supported(conn, screen), &reply, nullptr)) {
|
if (xcb_ewmh_get_supported_reply(conn, xcb_ewmh_get_supported(conn, screen), &reply, nullptr)) {
|
||||||
for (size_t n = 0; n < reply.atoms_len; ++n) {
|
for (size_t n = 0; n < reply.atoms_len; n++) {
|
||||||
if (reply.atoms[n] == atom) {
|
if (reply.atoms[n] == atom) {
|
||||||
supports = true;
|
xcb_ewmh_get_atoms_reply_wipe(&reply);
|
||||||
break;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (reply.atoms != nullptr) {
|
xcb_ewmh_get_atoms_reply_wipe(&reply);
|
||||||
xcb_ewmh_get_atoms_reply_wipe(&reply);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
return supports;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string get_wm_name(xcb_window_t win) {
|
string get_wm_name(xcb_window_t win) {
|
||||||
|
@ -96,24 +92,11 @@ namespace ewmh_util {
|
||||||
|
|
||||||
vector<string> get_desktop_names(int screen) {
|
vector<string> get_desktop_names(int screen) {
|
||||||
auto conn = initialize().get();
|
auto conn = initialize().get();
|
||||||
vector<string> names;
|
|
||||||
xcb_ewmh_get_utf8_strings_reply_t reply{};
|
xcb_ewmh_get_utf8_strings_reply_t reply{};
|
||||||
if (xcb_ewmh_get_desktop_names_reply(conn, xcb_ewmh_get_desktop_names(conn, screen), &reply, nullptr)) {
|
if (xcb_ewmh_get_desktop_names_reply(conn, xcb_ewmh_get_desktop_names(conn, screen), &reply, nullptr)) {
|
||||||
char buffer[BUFSIZ];
|
return string_util::split(string(reply.strings, reply.strings_len), '\0');
|
||||||
size_t len{0};
|
|
||||||
for (size_t n = 0; n < reply.strings_len; n++) {
|
|
||||||
if (reply.strings[n] == '\0') {
|
|
||||||
names.emplace_back(buffer, len);
|
|
||||||
len = 0;
|
|
||||||
} else {
|
|
||||||
buffer[len++] = reply.strings[n];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (len) {
|
|
||||||
names.emplace_back(buffer, len);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return names;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
xcb_window_t get_active_window(int screen) {
|
xcb_window_t get_active_window(int screen) {
|
||||||
|
@ -141,6 +124,15 @@ namespace ewmh_util {
|
||||||
xcb_flush(conn->connection);
|
xcb_flush(conn->connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vector<xcb_atom_t> get_wm_state(xcb_window_t win) {
|
||||||
|
auto conn = initialize().get();
|
||||||
|
xcb_ewmh_get_atoms_reply_t reply;
|
||||||
|
if (xcb_ewmh_get_wm_state_reply(conn, xcb_ewmh_get_wm_state(conn, win), &reply, nullptr)) {
|
||||||
|
return {reply.atoms, reply.atoms + reply.atoms_len};
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
void set_wm_pid(xcb_window_t win) {
|
void set_wm_pid(xcb_window_t win) {
|
||||||
auto conn = initialize().get();
|
auto conn = initialize().get();
|
||||||
xcb_ewmh_set_wm_pid(conn, win, getpid());
|
xcb_ewmh_set_wm_pid(conn, win, getpid());
|
||||||
|
@ -161,9 +153,19 @@ namespace ewmh_util {
|
||||||
|
|
||||||
void set_wm_window_opacity(xcb_window_t win, unsigned long int values) {
|
void set_wm_window_opacity(xcb_window_t win, unsigned long int values) {
|
||||||
auto conn = initialize().get();
|
auto conn = initialize().get();
|
||||||
xcb_change_property(conn->connection, XCB_PROP_MODE_REPLACE, win, _NET_WM_WINDOW_OPACITY, XCB_ATOM_CARDINAL, 32, 1, &values);
|
xcb_change_property(
|
||||||
|
conn->connection, XCB_PROP_MODE_REPLACE, win, _NET_WM_WINDOW_OPACITY, XCB_ATOM_CARDINAL, 32, 1, &values);
|
||||||
xcb_flush(conn->connection);
|
xcb_flush(conn->connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vector<xcb_window_t> get_client_list(int screen) {
|
||||||
|
auto conn = initialize().get();
|
||||||
|
xcb_ewmh_get_windows_reply_t reply;
|
||||||
|
if (xcb_ewmh_get_client_list_reply(conn, xcb_ewmh_get_client_list(conn, screen), &reply, nullptr)) {
|
||||||
|
return {reply.windows, reply.windows + reply.windows_len};
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
POLYBAR_NS_END
|
POLYBAR_NS_END
|
||||||
|
|
Loading…
Reference in a new issue