mirror of
https://github.com/polybar/polybar.git
synced 2024-11-18 13:55:11 -05:00
refactor(xcb): Namespacing
This commit is contained in:
parent
b8a1dd628e
commit
e1279d6582
3 changed files with 123 additions and 69 deletions
|
@ -39,8 +39,16 @@ namespace xcb
|
||||||
int index = 0;
|
int index = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<monitor_t> make_monitor();
|
namespace connection
|
||||||
std::shared_ptr<monitor_t> make_monitor(char *name, size_t name_len, int idx, xcb_rectangle_t *rect);
|
{
|
||||||
|
bool check(xcb_connection_t *connection);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::shared_ptr<monitor_t>> get_monitors(xcb_connection_t *connection, xcb_window_t root);
|
namespace monitor
|
||||||
|
{
|
||||||
|
std::shared_ptr<monitor_t> make_object();
|
||||||
|
std::shared_ptr<monitor_t> make_object(char *name, size_t name_len, int idx, xcb_rectangle_t *rect);
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<monitor_t>> get_list(xcb_connection_t *connection, xcb_window_t root);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ Bar::Bar() : config_path(config::get_bar_path()), opts(std::make_unique<Options>
|
||||||
} catch (config::MissingValueException &e) {}
|
} catch (config::MissingValueException &e) {}
|
||||||
|
|
||||||
auto monitor_name = config::get<std::string>(this->config_path, "monitor", "");
|
auto monitor_name = config::get<std::string>(this->config_path, "monitor", "");
|
||||||
auto monitors = xcb::get_monitors(x::connection(), x::connection().root());
|
auto monitors = xcb::monitor::get_list(x::connection(), x::connection().root());
|
||||||
|
|
||||||
// In case we're not connected to X, we'll just ignore the monitor
|
// In case we're not connected to X, we'll just ignore the monitor
|
||||||
if (!monitors.empty()) {
|
if (!monitors.empty()) {
|
||||||
|
@ -77,7 +77,7 @@ Bar::Bar() : config_path(config::get_bar_path()), opts(std::make_unique<Options>
|
||||||
|
|
||||||
// Create an empty monitor as fallback
|
// Create an empty monitor as fallback
|
||||||
if (!this->opts->monitor)
|
if (!this->opts->monitor)
|
||||||
this->opts->monitor = xcb::make_monitor();
|
this->opts->monitor = xcb::monitor::make_object();
|
||||||
|
|
||||||
this->opts->offset_x = config::get<int>(this->config_path, "offset_x", defaults.offset_x);
|
this->opts->offset_x = config::get<int>(this->config_path, "offset_x", defaults.offset_x);
|
||||||
this->opts->offset_y = config::get<int>(this->config_path, "offset_y", defaults.offset_y);
|
this->opts->offset_y = config::get<int>(this->config_path, "offset_y", defaults.offset_y);
|
||||||
|
|
|
@ -1,82 +1,128 @@
|
||||||
#include "utils/xcb.hpp"
|
#include "utils/xcb.hpp"
|
||||||
#include "utils/memory.hpp"
|
#include "utils/memory.hpp"
|
||||||
|
#include "services/logger.hpp"
|
||||||
|
|
||||||
namespace xcb
|
namespace xcb
|
||||||
{
|
{
|
||||||
std::shared_ptr<monitor_t> make_monitor() {
|
namespace connection
|
||||||
return memory::make_malloc_ptr<monitor_t>();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<monitor_t> make_monitor(char *name, size_t name_len, int idx, xcb_rectangle_t rect)
|
|
||||||
{
|
{
|
||||||
auto mon = make_monitor();
|
bool check(xcb_connection_t *connection)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
mon->bounds = rect;
|
if ((err = xcb_connection_has_error(connection)) == 0)
|
||||||
mon->index = idx;
|
return true;
|
||||||
|
|
||||||
size_t name_size = name_len + 1;
|
log_error("xcb: The server closed the connection");
|
||||||
if (sizeof(mon->name) < name_size)
|
|
||||||
name_size = sizeof(mon->name);
|
|
||||||
|
|
||||||
std::snprintf(mon->name, name_size, "%s", name);
|
switch (err) {
|
||||||
|
case XCB_CONN_ERROR:
|
||||||
return mon;
|
log_error("- socket, pipe or stream error");
|
||||||
}
|
break;
|
||||||
|
case XCB_CONN_CLOSED_EXT_NOTSUPPORTED:
|
||||||
std::vector<std::shared_ptr<monitor_t>> get_monitors(xcb_connection_t *connection, xcb_window_t root)
|
log_error("- unsupported extension");
|
||||||
{
|
break;
|
||||||
std::vector<std::shared_ptr<monitor_t>> monitors;
|
case XCB_CONN_CLOSED_MEM_INSUFFICIENT:
|
||||||
|
log_error("- not enough memory");
|
||||||
xcb_randr_get_screen_resources_reply_t *sres =
|
break;
|
||||||
xcb_randr_get_screen_resources_reply(connection,
|
case XCB_CONN_CLOSED_REQ_LEN_EXCEED:
|
||||||
xcb_randr_get_screen_resources(connection, root), nullptr);
|
log_error("- request length exceeded");
|
||||||
|
break;
|
||||||
if (sres == nullptr)
|
case XCB_CONN_CLOSED_PARSE_ERR:
|
||||||
return monitors;
|
log_error("- can't parse display string");
|
||||||
|
break;
|
||||||
int len = xcb_randr_get_screen_resources_outputs_length(sres);
|
case XCB_CONN_CLOSED_INVALID_SCREEN:
|
||||||
xcb_randr_output_t *outputs = xcb_randr_get_screen_resources_outputs(sres);
|
log_error("- invalid screen");
|
||||||
|
break;
|
||||||
for (int i = 0; i < len; i++) {
|
case XCB_CONN_CLOSED_FDPASSING_FAILED:
|
||||||
xcb_randr_get_output_info_cookie_t cookie =
|
log_error("- failed to pass FD");
|
||||||
xcb_randr_get_output_info(connection, outputs[i], XCB_CURRENT_TIME);
|
break;
|
||||||
xcb_randr_get_output_info_reply_t *info =
|
default:
|
||||||
xcb_randr_get_output_info_reply(connection, cookie, nullptr);
|
log_error("- unknown error");
|
||||||
xcb_randr_get_output_info(connection, outputs[i], XCB_CURRENT_TIME);
|
break;
|
||||||
|
|
||||||
if (info == nullptr)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (info->crtc == XCB_NONE) {
|
|
||||||
free(info);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xcb_randr_get_crtc_info_reply_t *cir =
|
return false;
|
||||||
xcb_randr_get_crtc_info_reply(connection,
|
}
|
||||||
xcb_randr_get_crtc_info(connection, info->crtc, XCB_CURRENT_TIME), nullptr);
|
}
|
||||||
|
|
||||||
if (cir == nullptr) {
|
namespace monitor
|
||||||
free(info);
|
{
|
||||||
continue;
|
std::shared_ptr<monitor_t> make_object() {
|
||||||
}
|
return memory::make_malloc_ptr<monitor_t>();
|
||||||
|
|
||||||
char *monitor_name = (char *) xcb_randr_get_output_info_name(info);
|
|
||||||
monitors.emplace_back(xcb::make_monitor(monitor_name, info->name_len, i,
|
|
||||||
{cir->x, cir->y, cir->width, cir->height}));
|
|
||||||
|
|
||||||
free(cir);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::sort(monitors.begin(), monitors.end(), [](std::shared_ptr<monitor_t> m1, std::shared_ptr<monitor_t> m2) -> bool
|
std::shared_ptr<monitor_t> make_object(char *name, size_t name_len, int idx, xcb_rectangle_t rect)
|
||||||
{
|
{
|
||||||
if (m1->bounds.x < m2->bounds.x || m1->bounds.y + m1->bounds.height <= m2->bounds.y)
|
auto mon = make_object();
|
||||||
return 1;
|
|
||||||
if (m1->bounds.x > m2->bounds.x || m1->bounds.y + m1->bounds.height > m2->bounds.y)
|
|
||||||
return -1;
|
|
||||||
return 0;
|
|
||||||
});
|
|
||||||
|
|
||||||
return monitors;
|
mon->bounds = rect;
|
||||||
|
mon->index = idx;
|
||||||
|
|
||||||
|
size_t name_size = name_len + 1;
|
||||||
|
if (sizeof(mon->name) < name_size)
|
||||||
|
name_size = sizeof(mon->name);
|
||||||
|
|
||||||
|
std::snprintf(mon->name, name_size, "%s", name);
|
||||||
|
|
||||||
|
return mon;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<monitor_t>> get_list(xcb_connection_t *connection, xcb_window_t root)
|
||||||
|
{
|
||||||
|
std::vector<std::shared_ptr<monitor_t>> monitors;
|
||||||
|
|
||||||
|
xcb_randr_get_screen_resources_reply_t *sres =
|
||||||
|
xcb_randr_get_screen_resources_reply(connection,
|
||||||
|
xcb_randr_get_screen_resources(connection, root), nullptr);
|
||||||
|
|
||||||
|
if (sres == nullptr)
|
||||||
|
return monitors;
|
||||||
|
|
||||||
|
int len = xcb_randr_get_screen_resources_outputs_length(sres);
|
||||||
|
xcb_randr_output_t *outputs = xcb_randr_get_screen_resources_outputs(sres);
|
||||||
|
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
xcb_randr_get_output_info_cookie_t cookie =
|
||||||
|
xcb_randr_get_output_info(connection, outputs[i], XCB_CURRENT_TIME);
|
||||||
|
xcb_randr_get_output_info_reply_t *info =
|
||||||
|
xcb_randr_get_output_info_reply(connection, cookie, nullptr);
|
||||||
|
xcb_randr_get_output_info(connection, outputs[i], XCB_CURRENT_TIME);
|
||||||
|
|
||||||
|
if (info == nullptr)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (info->crtc == XCB_NONE) {
|
||||||
|
free(info);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
xcb_randr_get_crtc_info_reply_t *cir =
|
||||||
|
xcb_randr_get_crtc_info_reply(connection,
|
||||||
|
xcb_randr_get_crtc_info(connection, info->crtc, XCB_CURRENT_TIME), nullptr);
|
||||||
|
|
||||||
|
if (cir == nullptr) {
|
||||||
|
free(info);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *monitor_name = (char *) xcb_randr_get_output_info_name(info);
|
||||||
|
monitors.emplace_back(make_object(monitor_name, info->name_len, i,
|
||||||
|
{cir->x, cir->y, cir->width, cir->height}));
|
||||||
|
|
||||||
|
free(cir);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(monitors.begin(), monitors.end(), [](std::shared_ptr<monitor_t> m1, std::shared_ptr<monitor_t> m2) -> bool
|
||||||
|
{
|
||||||
|
if (m1->bounds.x < m2->bounds.x || m1->bounds.y + m1->bounds.height <= m2->bounds.y)
|
||||||
|
return 1;
|
||||||
|
if (m1->bounds.x > m2->bounds.x || m1->bounds.y + m1->bounds.height > m2->bounds.y)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
return monitors;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue