2017-01-24 07:49:27 +00:00
|
|
|
#include <unistd.h>
|
|
|
|
|
2016-12-03 14:44:54 +00:00
|
|
|
#include "components/types.hpp"
|
2017-01-25 02:29:11 +00:00
|
|
|
#include "utils/string.hpp"
|
2017-01-24 07:49:27 +00:00
|
|
|
#include "x11/atoms.hpp"
|
2016-12-31 06:39:50 +00:00
|
|
|
#include "x11/connection.hpp"
|
2017-01-24 07:49:27 +00:00
|
|
|
#include "x11/ewmh.hpp"
|
2016-11-19 03:03:18 +00:00
|
|
|
|
2016-11-19 05:22:44 +00:00
|
|
|
POLYBAR_NS
|
2016-11-19 03:03:18 +00:00
|
|
|
|
|
|
|
namespace ewmh_util {
|
2016-12-21 22:22:02 +00:00
|
|
|
ewmh_connection_t g_connection{nullptr};
|
2016-11-26 05:14:58 +00:00
|
|
|
ewmh_connection_t initialize() {
|
2016-12-21 22:22:02 +00:00
|
|
|
if (!g_connection) {
|
|
|
|
g_connection = memory_util::make_malloc_ptr<xcb_ewmh_connection_t>(
|
|
|
|
[=](xcb_ewmh_connection_t* c) { xcb_ewmh_connection_wipe(c); });
|
2016-12-31 06:39:50 +00:00
|
|
|
xcb_ewmh_init_atoms_replies(&*g_connection, xcb_ewmh_init_atoms(connection::make(), &*g_connection), nullptr);
|
2016-11-26 05:14:58 +00:00
|
|
|
}
|
2016-12-21 22:22:02 +00:00
|
|
|
return g_connection;
|
2016-11-19 03:03:18 +00:00
|
|
|
}
|
|
|
|
|
2017-01-24 07:49:27 +00:00
|
|
|
bool supports(xcb_atom_t atom, int screen) {
|
|
|
|
auto conn = initialize().get();
|
2016-12-15 08:29:14 +00:00
|
|
|
xcb_ewmh_get_atoms_reply_t reply{};
|
2017-01-24 07:49:27 +00:00
|
|
|
if (xcb_ewmh_get_supported_reply(conn, xcb_ewmh_get_supported(conn, screen), &reply, nullptr)) {
|
2017-01-25 02:29:11 +00:00
|
|
|
for (size_t n = 0; n < reply.atoms_len; n++) {
|
2017-01-24 07:49:27 +00:00
|
|
|
if (reply.atoms[n] == atom) {
|
2017-01-25 02:29:11 +00:00
|
|
|
xcb_ewmh_get_atoms_reply_wipe(&reply);
|
|
|
|
return true;
|
2017-01-24 07:49:27 +00:00
|
|
|
}
|
|
|
|
}
|
2017-01-25 02:29:11 +00:00
|
|
|
xcb_ewmh_get_atoms_reply_wipe(&reply);
|
2016-11-19 03:03:18 +00:00
|
|
|
}
|
2017-01-25 02:29:11 +00:00
|
|
|
return false;
|
2016-11-19 03:03:18 +00:00
|
|
|
}
|
|
|
|
|
2017-01-24 07:49:27 +00:00
|
|
|
string get_wm_name(xcb_window_t win) {
|
|
|
|
auto conn = initialize().get();
|
2016-12-15 08:29:14 +00:00
|
|
|
xcb_ewmh_get_utf8_strings_reply_t utf8_reply{};
|
2016-11-30 12:38:40 +00:00
|
|
|
if (xcb_ewmh_get_wm_name_reply(conn, xcb_ewmh_get_wm_name(conn, win), &utf8_reply, nullptr)) {
|
|
|
|
return get_reply_string(&utf8_reply);
|
|
|
|
}
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
2017-01-24 07:49:27 +00:00
|
|
|
string get_visible_name(xcb_window_t win) {
|
|
|
|
auto conn = initialize().get();
|
2016-12-15 08:29:14 +00:00
|
|
|
xcb_ewmh_get_utf8_strings_reply_t utf8_reply{};
|
2016-11-30 12:38:40 +00:00
|
|
|
if (xcb_ewmh_get_wm_visible_name_reply(conn, xcb_ewmh_get_wm_visible_name(conn, win), &utf8_reply, nullptr)) {
|
|
|
|
return get_reply_string(&utf8_reply);
|
2016-11-25 12:55:15 +00:00
|
|
|
}
|
2016-11-30 12:38:40 +00:00
|
|
|
return "";
|
2016-11-19 03:03:18 +00:00
|
|
|
}
|
|
|
|
|
2017-01-24 07:49:27 +00:00
|
|
|
string get_icon_name(xcb_window_t win) {
|
|
|
|
auto conn = initialize().get();
|
2016-12-15 08:29:14 +00:00
|
|
|
xcb_ewmh_get_utf8_strings_reply_t utf8_reply{};
|
2016-11-30 12:38:40 +00:00
|
|
|
if (xcb_ewmh_get_wm_icon_name_reply(conn, xcb_ewmh_get_wm_icon_name(conn, win), &utf8_reply, nullptr)) {
|
|
|
|
return get_reply_string(&utf8_reply);
|
2016-11-25 12:55:15 +00:00
|
|
|
}
|
2016-11-30 12:38:40 +00:00
|
|
|
return "";
|
2016-11-19 03:03:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
string get_reply_string(xcb_ewmh_get_utf8_strings_reply_t* reply) {
|
2017-01-24 07:49:27 +00:00
|
|
|
string str;
|
|
|
|
if (reply) {
|
|
|
|
str = string(reply->strings, reply->strings_len);
|
|
|
|
xcb_ewmh_get_utf8_strings_reply_wipe(reply);
|
2016-11-25 12:55:15 +00:00
|
|
|
}
|
2016-11-30 12:38:40 +00:00
|
|
|
return str;
|
2016-11-19 03:03:18 +00:00
|
|
|
}
|
2016-11-26 05:14:58 +00:00
|
|
|
|
2017-01-24 07:49:27 +00:00
|
|
|
unsigned int get_current_desktop(int screen) {
|
|
|
|
auto conn = initialize().get();
|
|
|
|
unsigned int desktop = XCB_NONE;
|
|
|
|
xcb_ewmh_get_current_desktop_reply(conn, xcb_ewmh_get_current_desktop(conn, screen), &desktop, nullptr);
|
|
|
|
return desktop;
|
2016-11-26 05:14:58 +00:00
|
|
|
}
|
|
|
|
|
2019-02-08 12:32:31 +00:00
|
|
|
unsigned int get_number_of_desktops(int screen) {
|
|
|
|
auto conn = initialize().get();
|
|
|
|
unsigned int desktops = XCB_NONE;
|
|
|
|
xcb_ewmh_get_number_of_desktops_reply(conn, xcb_ewmh_get_number_of_desktops(conn, screen), &desktops, nullptr);
|
|
|
|
return desktops;
|
|
|
|
}
|
|
|
|
|
2017-01-24 07:49:27 +00:00
|
|
|
vector<position> get_desktop_viewports(int screen) {
|
|
|
|
auto conn = initialize().get();
|
2016-11-26 08:51:06 +00:00
|
|
|
vector<position> viewports;
|
2016-12-15 08:29:14 +00:00
|
|
|
xcb_ewmh_get_desktop_viewport_reply_t reply{};
|
2017-01-24 07:49:27 +00:00
|
|
|
if (xcb_ewmh_get_desktop_viewport_reply(conn, xcb_ewmh_get_desktop_viewport(conn, screen), &reply, nullptr)) {
|
|
|
|
for (size_t n = 0; n < reply.desktop_viewport_len; n++) {
|
|
|
|
viewports.emplace_back(position{
|
|
|
|
static_cast<short int>(reply.desktop_viewport[n].x), static_cast<short int>(reply.desktop_viewport[n].y)});
|
|
|
|
}
|
2016-11-26 08:38:55 +00:00
|
|
|
}
|
|
|
|
return viewports;
|
|
|
|
}
|
|
|
|
|
2017-01-24 07:49:27 +00:00
|
|
|
vector<string> get_desktop_names(int screen) {
|
|
|
|
auto conn = initialize().get();
|
2016-12-15 08:29:14 +00:00
|
|
|
xcb_ewmh_get_utf8_strings_reply_t reply{};
|
2017-01-24 07:49:27 +00:00
|
|
|
if (xcb_ewmh_get_desktop_names_reply(conn, xcb_ewmh_get_desktop_names(conn, screen), &reply, nullptr)) {
|
2017-01-25 02:29:11 +00:00
|
|
|
return string_util::split(string(reply.strings, reply.strings_len), '\0');
|
2016-11-26 05:14:58 +00:00
|
|
|
}
|
2017-01-25 02:29:11 +00:00
|
|
|
return {};
|
2016-11-26 05:14:58 +00:00
|
|
|
}
|
|
|
|
|
2017-01-24 07:49:27 +00:00
|
|
|
xcb_window_t get_active_window(int screen) {
|
|
|
|
auto conn = initialize().get();
|
|
|
|
unsigned int win = XCB_NONE;
|
|
|
|
xcb_ewmh_get_active_window_reply(conn, xcb_ewmh_get_active_window(conn, screen), &win, nullptr);
|
2016-11-26 05:14:58 +00:00
|
|
|
return win;
|
|
|
|
}
|
2016-11-26 09:33:32 +00:00
|
|
|
|
2017-01-24 07:49:27 +00:00
|
|
|
void change_current_desktop(unsigned int desktop) {
|
|
|
|
auto conn = initialize().get();
|
2016-11-26 09:33:32 +00:00
|
|
|
xcb_ewmh_request_change_current_desktop(conn, 0, desktop, XCB_CURRENT_TIME);
|
2017-01-24 07:49:27 +00:00
|
|
|
xcb_flush(conn->connection);
|
|
|
|
}
|
|
|
|
|
2017-02-20 07:25:19 +00:00
|
|
|
unsigned int get_desktop_from_window(xcb_window_t window) {
|
|
|
|
auto conn = initialize().get();
|
|
|
|
unsigned int desktop = XCB_NONE;
|
|
|
|
xcb_ewmh_get_wm_desktop_reply(conn, xcb_ewmh_get_wm_desktop(conn, window), &desktop, nullptr);
|
|
|
|
return desktop;
|
|
|
|
}
|
|
|
|
|
2017-01-24 07:49:27 +00:00
|
|
|
void set_wm_window_type(xcb_window_t win, vector<xcb_atom_t> types) {
|
|
|
|
auto conn = initialize().get();
|
|
|
|
xcb_ewmh_set_wm_window_type(conn, win, types.size(), types.data());
|
|
|
|
xcb_flush(conn->connection);
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_wm_state(xcb_window_t win, vector<xcb_atom_t> states) {
|
|
|
|
auto conn = initialize().get();
|
|
|
|
xcb_ewmh_set_wm_state(conn, win, states.size(), states.data());
|
|
|
|
xcb_flush(conn->connection);
|
|
|
|
}
|
|
|
|
|
2017-01-25 02:29:11 +00:00
|
|
|
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 {};
|
|
|
|
}
|
|
|
|
|
2017-01-24 07:49:27 +00:00
|
|
|
void set_wm_pid(xcb_window_t win) {
|
|
|
|
auto conn = initialize().get();
|
|
|
|
xcb_ewmh_set_wm_pid(conn, win, getpid());
|
|
|
|
xcb_flush(conn->connection);
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_wm_pid(xcb_window_t win, unsigned int pid) {
|
|
|
|
auto conn = initialize().get();
|
|
|
|
xcb_ewmh_set_wm_pid(conn, win, pid);
|
|
|
|
xcb_flush(conn->connection);
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_wm_desktop(xcb_window_t win, unsigned int desktop) {
|
|
|
|
auto conn = initialize().get();
|
|
|
|
xcb_ewmh_set_wm_desktop(conn, win, desktop);
|
|
|
|
xcb_flush(conn->connection);
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_wm_window_opacity(xcb_window_t win, unsigned long int values) {
|
|
|
|
auto conn = initialize().get();
|
2017-01-25 02:29:11 +00:00
|
|
|
xcb_change_property(
|
|
|
|
conn->connection, XCB_PROP_MODE_REPLACE, win, _NET_WM_WINDOW_OPACITY, XCB_ATOM_CARDINAL, 32, 1, &values);
|
2017-01-24 07:49:27 +00:00
|
|
|
xcb_flush(conn->connection);
|
2016-11-26 09:33:32 +00:00
|
|
|
}
|
2017-01-25 02:29:11 +00:00
|
|
|
|
|
|
|
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 {};
|
|
|
|
}
|
2016-11-19 03:03:18 +00:00
|
|
|
}
|
|
|
|
|
2016-11-19 05:22:44 +00:00
|
|
|
POLYBAR_NS_END
|