refactor: Code cleanup
This commit is contained in:
parent
ae501d6ae1
commit
869c5fe718
@ -43,3 +43,7 @@ message(STATUS " Enable i3 support ${ENABLE_I3}")
|
|||||||
message(STATUS " Enable mpd support ${ENABLE_MPD}")
|
message(STATUS " Enable mpd support ${ENABLE_MPD}")
|
||||||
message(STATUS " Enable network support ${ENABLE_NETWORK}")
|
message(STATUS " Enable network support ${ENABLE_NETWORK}")
|
||||||
message(STATUS "---------------------------")
|
message(STATUS "---------------------------")
|
||||||
|
message(STATUS " Enable X RandR ${ENABLE_RANDR_EXT}")
|
||||||
|
message(STATUS " Enable X Render ${ENABLE_RENDER_EXT}")
|
||||||
|
message(STATUS " Enable X Damage ${ENABLE_DAMAGE_EXT}")
|
||||||
|
message(STATUS "---------------------------")
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "x11/connection.hpp"
|
#include "x11/connection.hpp"
|
||||||
#include "x11/draw.hpp"
|
#include "x11/draw.hpp"
|
||||||
#include "x11/fontmanager.hpp"
|
#include "x11/fontmanager.hpp"
|
||||||
|
#include "x11/graphics.hpp"
|
||||||
#include "x11/tray.hpp"
|
#include "x11/tray.hpp"
|
||||||
#include "x11/types.hpp"
|
#include "x11/types.hpp"
|
||||||
#include "x11/window.hpp"
|
#include "x11/window.hpp"
|
||||||
@ -20,21 +21,25 @@ LEMONBUDDY_NS
|
|||||||
class bar : public xpp::event::sink<evt::button_press, evt::expose, evt::property_notify> {
|
class bar : public xpp::event::sink<evt::button_press, evt::expose, evt::property_notify> {
|
||||||
public:
|
public:
|
||||||
explicit bar(connection& conn, const config& config, const logger& logger,
|
explicit bar(connection& conn, const config& config, const logger& logger,
|
||||||
unique_ptr<fontmanager> fontmanager)
|
unique_ptr<fontmanager> fontmanager, unique_ptr<traymanager> traymanager)
|
||||||
: m_connection(conn)
|
: m_connection(conn)
|
||||||
, m_conf(config)
|
, m_conf(config)
|
||||||
, m_log(logger)
|
, m_log(logger)
|
||||||
, m_fontmanager(forward<decltype(fontmanager)>(fontmanager)) {}
|
, m_fontmanager(forward<decltype(fontmanager)>(fontmanager))
|
||||||
|
, m_traymanager(forward<decltype(traymanager)>(traymanager)) {}
|
||||||
|
|
||||||
~bar();
|
~bar();
|
||||||
|
|
||||||
void bootstrap(bool nodraw = false);
|
void bootstrap(bool nodraw = false);
|
||||||
|
void bootstrap_tray();
|
||||||
|
void activate_tray();
|
||||||
|
|
||||||
const bar_settings settings() const;
|
const bar_settings settings() const;
|
||||||
const tray_settings tray() const;
|
const tray_settings tray() const;
|
||||||
|
|
||||||
void parse(string data, bool force = false);
|
void parse(string data, bool force = false);
|
||||||
void flush();
|
void flush();
|
||||||
|
void refresh_window();
|
||||||
|
|
||||||
void handle(const evt::button_press& evt);
|
void handle(const evt::button_press& evt);
|
||||||
void handle(const evt::expose& evt);
|
void handle(const evt::expose& evt);
|
||||||
@ -67,6 +72,7 @@ class bar : public xpp::event::sink<evt::button_press, evt::expose, evt::propert
|
|||||||
const config& m_conf;
|
const config& m_conf;
|
||||||
const logger& m_log;
|
const logger& m_log;
|
||||||
unique_ptr<fontmanager> m_fontmanager;
|
unique_ptr<fontmanager> m_fontmanager;
|
||||||
|
unique_ptr<traymanager> m_traymanager;
|
||||||
|
|
||||||
threading_util::spin_lock m_lock;
|
threading_util::spin_lock m_lock;
|
||||||
throttle_util::throttle_t m_throttler;
|
throttle_util::throttle_t m_throttler;
|
||||||
@ -78,6 +84,9 @@ class bar : public xpp::event::sink<evt::button_press, evt::expose, evt::propert
|
|||||||
colormap m_colormap{m_connection, m_connection.generate_id()};
|
colormap m_colormap{m_connection, m_connection.generate_id()};
|
||||||
pixmap m_pixmap{m_connection, m_connection.generate_id()};
|
pixmap m_pixmap{m_connection, m_connection.generate_id()};
|
||||||
|
|
||||||
|
// xcb_gcontext_t m_root_gc{0};
|
||||||
|
// graphics_util::root_pixmap m_rootpixmap;
|
||||||
|
|
||||||
bar_settings m_bar;
|
bar_settings m_bar;
|
||||||
tray_settings m_tray;
|
tray_settings m_tray;
|
||||||
map<border, border_settings> m_borders;
|
map<border, border_settings> m_borders;
|
||||||
@ -105,7 +114,8 @@ namespace {
|
|||||||
configure_connection(),
|
configure_connection(),
|
||||||
configure_config(),
|
configure_config(),
|
||||||
configure_logger(),
|
configure_logger(),
|
||||||
configure_fontmanager());
|
configure_fontmanager(),
|
||||||
|
configure_traymanager());
|
||||||
// clang-format on
|
// clang-format on
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
#include "utils/command.hpp"
|
#include "utils/command.hpp"
|
||||||
#include "utils/inotify.hpp"
|
#include "utils/inotify.hpp"
|
||||||
#include "x11/connection.hpp"
|
#include "x11/connection.hpp"
|
||||||
#include "x11/tray.hpp"
|
|
||||||
#include "x11/types.hpp"
|
#include "x11/types.hpp"
|
||||||
|
|
||||||
LEMONBUDDY_NS
|
LEMONBUDDY_NS
|
||||||
@ -18,14 +17,13 @@ LEMONBUDDY_NS
|
|||||||
class controller {
|
class controller {
|
||||||
public:
|
public:
|
||||||
explicit controller(connection& conn, const logger& logger, const config& config,
|
explicit controller(connection& conn, const logger& logger, const config& config,
|
||||||
unique_ptr<eventloop> eventloop, unique_ptr<bar> bar, unique_ptr<traymanager> tray,
|
unique_ptr<eventloop> eventloop, unique_ptr<bar> bar,
|
||||||
inotify_util::watch_t& confwatch)
|
inotify_util::watch_t& confwatch)
|
||||||
: m_connection(conn)
|
: m_connection(conn)
|
||||||
, m_log(logger)
|
, m_log(logger)
|
||||||
, m_conf(config)
|
, m_conf(config)
|
||||||
, m_eventloop(forward<decltype(eventloop)>(eventloop))
|
, m_eventloop(forward<decltype(eventloop)>(eventloop))
|
||||||
, m_bar(forward<decltype(bar)>(bar))
|
, m_bar(forward<decltype(bar)>(bar))
|
||||||
, m_traymanager(forward<decltype(tray)>(tray))
|
|
||||||
, m_confwatch(confwatch) {}
|
, m_confwatch(confwatch) {}
|
||||||
|
|
||||||
~controller();
|
~controller();
|
||||||
@ -43,7 +41,6 @@ class controller {
|
|||||||
void wait_for_signal();
|
void wait_for_signal();
|
||||||
void wait_for_xevent();
|
void wait_for_xevent();
|
||||||
|
|
||||||
void activate_tray();
|
|
||||||
void bootstrap_modules();
|
void bootstrap_modules();
|
||||||
|
|
||||||
void on_mouse_event(string input);
|
void on_mouse_event(string input);
|
||||||
@ -57,11 +54,11 @@ class controller {
|
|||||||
const config& m_conf;
|
const config& m_conf;
|
||||||
unique_ptr<eventloop> m_eventloop;
|
unique_ptr<eventloop> m_eventloop;
|
||||||
unique_ptr<bar> m_bar;
|
unique_ptr<bar> m_bar;
|
||||||
unique_ptr<traymanager> m_traymanager;
|
|
||||||
|
|
||||||
stateflag m_running{false};
|
stateflag m_running{false};
|
||||||
stateflag m_reload{false};
|
stateflag m_reload{false};
|
||||||
stateflag m_waiting{false};
|
stateflag m_waiting{false};
|
||||||
|
stateflag m_trayactivated{false};
|
||||||
|
|
||||||
sigset_t m_waitmask;
|
sigset_t m_waitmask;
|
||||||
sigset_t m_ignmask;
|
sigset_t m_ignmask;
|
||||||
@ -87,8 +84,7 @@ namespace {
|
|||||||
configure_logger(),
|
configure_logger(),
|
||||||
configure_config(),
|
configure_config(),
|
||||||
configure_eventloop(),
|
configure_eventloop(),
|
||||||
configure_bar(),
|
configure_bar());
|
||||||
configure_traymanager());
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,15 @@ namespace color_util {
|
|||||||
return b << 8 | b << 8 / 0xff;
|
return b << 8 | b << 8 / 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T = uint32_t>
|
||||||
|
uint32_t premultiply_alpha(const T value) {
|
||||||
|
auto a = color_util::alpha_channel(value);
|
||||||
|
auto r = color_util::red_channel(value) * a / 255;
|
||||||
|
auto g = color_util::green_channel(value) * a / 255;
|
||||||
|
auto b = color_util::blue_channel(value) * a / 255;
|
||||||
|
return (a << 24) | (r << 16) | (g << 8) | b;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T = uint8_t>
|
template <typename T = uint8_t>
|
||||||
string hex(uint32_t color) {
|
string hex(uint32_t color) {
|
||||||
char s[12];
|
char s[12];
|
||||||
|
@ -21,6 +21,7 @@ class color {
|
|||||||
static color parse(string input);
|
static color parse(string input);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
uint32_t m_value;
|
||||||
uint32_t m_color;
|
uint32_t m_color;
|
||||||
string m_source;
|
string m_source;
|
||||||
};
|
};
|
||||||
|
@ -17,6 +17,12 @@ class window : public xpp::window<connection_t&> {
|
|||||||
int16_t x, int16_t y, uint16_t w, uint16_t h, uint32_t mask, const xcb_params_cw_t* params);
|
int16_t x, int16_t y, uint16_t w, uint16_t h, uint32_t mask, const xcb_params_cw_t* params);
|
||||||
|
|
||||||
window create_checked(uint16_t w, uint16_t h, uint32_t mask, const xcb_params_cw_t* params);
|
window create_checked(uint16_t w, uint16_t h, uint32_t mask, const xcb_params_cw_t* params);
|
||||||
|
|
||||||
|
void refresh() {
|
||||||
|
xutils::visibility_notify(connection(), *this, XCB_VISIBILITY_FULLY_OBSCURED);
|
||||||
|
xutils::visibility_notify(connection(), *this, XCB_VISIBILITY_UNOBSCURED);
|
||||||
|
connection().flush();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// struct cw_size {
|
// struct cw_size {
|
||||||
|
20
include/x11/wm.hpp
Normal file
20
include/x11/wm.hpp
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common.hpp"
|
||||||
|
#include "x11/connection.hpp"
|
||||||
|
|
||||||
|
LEMONBUDDY_NS
|
||||||
|
|
||||||
|
namespace wm_util {
|
||||||
|
void set_wmname(connection& conn, xcb_window_t win, string wm_name, string wm_class);
|
||||||
|
void set_wmprotocols(connection& conn, xcb_window_t win, vector<xcb_atom_t> flags);
|
||||||
|
void set_windowtype(connection& conn, xcb_window_t win, vector<xcb_atom_t> types);
|
||||||
|
void set_wmstate(connection& conn, xcb_window_t win, vector<xcb_atom_t> states);
|
||||||
|
void set_wmpid(connection& conn, xcb_window_t win, pid_t pid);
|
||||||
|
void set_wmdesktop(connection& conn, xcb_window_t win, uint32_t desktop = -1u);
|
||||||
|
|
||||||
|
void set_trayorientation(connection& conn, xcb_window_t win, uint32_t orientation);
|
||||||
|
void set_trayvisual(connection& conn, xcb_window_t win, xcb_visualid_t visual);
|
||||||
|
}
|
||||||
|
|
||||||
|
LEMONBUDDY_NS_END
|
@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
LEMONBUDDY_NS
|
LEMONBUDDY_NS
|
||||||
|
|
||||||
|
class connection;
|
||||||
|
|
||||||
namespace xutils {
|
namespace xutils {
|
||||||
xcb_connection_t* get_connection();
|
xcb_connection_t* get_connection();
|
||||||
|
|
||||||
@ -14,6 +16,8 @@ namespace xutils {
|
|||||||
void pack_values(uint32_t mask, const xcb_params_cw_t* src, uint32_t* dest);
|
void pack_values(uint32_t mask, const xcb_params_cw_t* src, uint32_t* dest);
|
||||||
void pack_values(uint32_t mask, const xcb_params_gc_t* src, uint32_t* dest);
|
void pack_values(uint32_t mask, const xcb_params_gc_t* src, uint32_t* dest);
|
||||||
void pack_values(uint32_t mask, const xcb_params_configure_window_t* src, uint32_t* dest);
|
void pack_values(uint32_t mask, const xcb_params_configure_window_t* src, uint32_t* dest);
|
||||||
|
|
||||||
|
void visibility_notify(connection& conn, const xcb_window_t& win, xcb_visibility_t state);
|
||||||
}
|
}
|
||||||
|
|
||||||
LEMONBUDDY_NS_END
|
LEMONBUDDY_NS_END
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "utils/string.hpp"
|
#include "utils/string.hpp"
|
||||||
#include "x11/draw.hpp"
|
#include "x11/draw.hpp"
|
||||||
#include "x11/randr.hpp"
|
#include "x11/randr.hpp"
|
||||||
|
#include "x11/wm.hpp"
|
||||||
#include "x11/xlib.hpp"
|
#include "x11/xlib.hpp"
|
||||||
#include "x11/xutils.hpp"
|
#include "x11/xutils.hpp"
|
||||||
|
|
||||||
@ -37,8 +38,14 @@ bar::~bar() { // {{{
|
|||||||
g_signals::parser::string_write = nullptr;
|
g_signals::parser::string_write = nullptr;
|
||||||
g_signals::tray::report_slotcount = nullptr; // }}}
|
g_signals::tray::report_slotcount = nullptr; // }}}
|
||||||
|
|
||||||
if (m_sinkattached)
|
if (m_traymanager) {
|
||||||
|
m_traymanager.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_sinkattached) {
|
||||||
m_connection.detach_sink(this, 1);
|
m_connection.detach_sink(this, 1);
|
||||||
|
}
|
||||||
|
|
||||||
m_window.destroy();
|
m_window.destroy();
|
||||||
} // }}}
|
} // }}}
|
||||||
|
|
||||||
@ -208,6 +215,7 @@ void bar::bootstrap(bool nodraw) { // {{{
|
|||||||
// clang-format off
|
// clang-format off
|
||||||
XCB_AUX_ADD_PARAM(&mask, ¶ms, back_pixel, 0);
|
XCB_AUX_ADD_PARAM(&mask, ¶ms, back_pixel, 0);
|
||||||
XCB_AUX_ADD_PARAM(&mask, ¶ms, border_pixel, 0);
|
XCB_AUX_ADD_PARAM(&mask, ¶ms, border_pixel, 0);
|
||||||
|
XCB_AUX_ADD_PARAM(&mask, ¶ms, backing_store, XCB_BACKING_STORE_WHEN_MAPPED);
|
||||||
XCB_AUX_ADD_PARAM(&mask, ¶ms, colormap, m_colormap);
|
XCB_AUX_ADD_PARAM(&mask, ¶ms, colormap, m_colormap);
|
||||||
XCB_AUX_ADD_PARAM(&mask, ¶ms, override_redirect, m_bar.dock);
|
XCB_AUX_ADD_PARAM(&mask, ¶ms, override_redirect, m_bar.dock);
|
||||||
XCB_AUX_ADD_PARAM(&mask, ¶ms, event_mask, XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS);
|
XCB_AUX_ADD_PARAM(&mask, ¶ms, event_mask, XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS);
|
||||||
@ -216,25 +224,21 @@ void bar::bootstrap(bool nodraw) { // {{{
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_log.trace("bar: Set WM_NAME");
|
m_log.trace("bar: Set WM_NAME");
|
||||||
{
|
|
||||||
xcb_icccm_set_wm_name(
|
xcb_icccm_set_wm_name(
|
||||||
m_connection, m_window, XCB_ATOM_STRING, 8, m_bar.wmname.length(), m_bar.wmname.c_str());
|
m_connection, m_window, XCB_ATOM_STRING, 8, m_bar.wmname.length(), m_bar.wmname.c_str());
|
||||||
xcb_icccm_set_wm_class(m_connection, m_window, 21, "lemonbuddy\0Lemonbuddy");
|
xcb_icccm_set_wm_class(m_connection, m_window, 21, "lemonbuddy\0Lemonbuddy");
|
||||||
}
|
|
||||||
|
|
||||||
m_log.trace("bar: Set _NET_WM_WINDOW_TYPE");
|
m_log.trace("bar: Set _NET_WM_WINDOW_TYPE");
|
||||||
{
|
wm_util::set_windowtype(m_connection, m_window, {_NET_WM_WINDOW_TYPE_DOCK});
|
||||||
const uint32_t win_types[1] = {_NET_WM_WINDOW_TYPE_DOCK};
|
|
||||||
m_connection.change_property(
|
|
||||||
XCB_PROP_MODE_REPLACE, m_window, _NET_WM_WINDOW_TYPE, XCB_ATOM_ATOM, 32, 1, win_types);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_log.trace("bar: Set _NET_WM_STATE");
|
m_log.trace("bar: Set _NET_WM_STATE");
|
||||||
{
|
wm_util::set_wmstate(m_connection, m_window, {_NET_WM_STATE_STICKY, _NET_WM_STATE_ABOVE});
|
||||||
const uint32_t win_states[2] = {_NET_WM_STATE_STICKY, _NET_WM_STATE_ABOVE};
|
|
||||||
m_connection.change_property(
|
m_log.trace("bar: Set _NET_WM_DESKTOP");
|
||||||
XCB_PROP_MODE_REPLACE, m_window, _NET_WM_STATE, XCB_ATOM_ATOM, 32, 2, win_states);
|
wm_util::set_wmdesktop(m_connection, m_window, -1u);
|
||||||
}
|
|
||||||
|
m_log.trace("bar: Set _NET_WM_PID");
|
||||||
|
wm_util::set_wmpid(m_connection, m_window, getpid());
|
||||||
|
|
||||||
m_log.trace("bar: Set _NET_WM_STRUT_PARTIAL");
|
m_log.trace("bar: Set _NET_WM_STRUT_PARTIAL");
|
||||||
{
|
{
|
||||||
@ -255,20 +259,6 @@ void bar::bootstrap(bool nodraw) { // {{{
|
|||||||
XCB_ATOM_CARDINAL, 32, 12, value_list);
|
XCB_ATOM_CARDINAL, 32, 12, value_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_log.trace("bar: Set _NET_WM_DESKTOP");
|
|
||||||
{
|
|
||||||
const uint32_t value_list[1]{-1u};
|
|
||||||
m_connection.change_property(
|
|
||||||
XCB_PROP_MODE_REPLACE, m_window, _NET_WM_DESKTOP, XCB_ATOM_CARDINAL, 32, 1, value_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_log.trace("bar: Set _NET_WM_PID");
|
|
||||||
{
|
|
||||||
const uint32_t value_list[1]{uint32_t(getpid())};
|
|
||||||
m_connection.change_property(
|
|
||||||
XCB_PROP_MODE_REPLACE, m_window, _NET_WM_PID, XCB_ATOM_CARDINAL, 32, 1, value_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_log.trace("bar: Create pixmap");
|
m_log.trace("bar: Create pixmap");
|
||||||
{
|
{
|
||||||
m_connection.create_pixmap(
|
m_connection.create_pixmap(
|
||||||
@ -278,8 +268,8 @@ void bar::bootstrap(bool nodraw) { // {{{
|
|||||||
|
|
||||||
m_log.trace("bar: Map window");
|
m_log.trace("bar: Map window");
|
||||||
{
|
{
|
||||||
m_connection.flush();
|
|
||||||
m_connection.map_window(m_window);
|
m_connection.map_window(m_window);
|
||||||
|
m_connection.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
@ -336,14 +326,59 @@ void bar::bootstrap(bool nodraw) { // {{{
|
|||||||
uint32_t mask = 0;
|
uint32_t mask = 0;
|
||||||
uint32_t value_list[32];
|
uint32_t value_list[32];
|
||||||
xcb_params_gc_t params;
|
xcb_params_gc_t params;
|
||||||
|
m_gcontexts.emplace(gc(i), gcontext{m_connection, m_connection.generate_id()});
|
||||||
|
|
||||||
XCB_AUX_ADD_PARAM(&mask, ¶ms, foreground, colors[i - 1]);
|
XCB_AUX_ADD_PARAM(&mask, ¶ms, foreground, colors[i - 1]);
|
||||||
XCB_AUX_ADD_PARAM(&mask, ¶ms, graphics_exposures, 0);
|
XCB_AUX_ADD_PARAM(&mask, ¶ms, graphics_exposures, 0);
|
||||||
|
|
||||||
xutils::pack_values(mask, ¶ms, value_list);
|
xutils::pack_values(mask, ¶ms, value_list);
|
||||||
m_gcontexts.emplace(gc(i), gcontext{m_connection, m_connection.generate_id()});
|
|
||||||
m_connection.create_gc(m_gcontexts.at(gc(i)), m_pixmap, mask, value_list);
|
m_connection.create_gc(m_gcontexts.at(gc(i)), m_pixmap, mask, value_list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// Setup root pixmap {{{
|
||||||
|
|
||||||
|
m_log.trace("bar: Setup root pixmap");
|
||||||
|
{
|
||||||
|
// graphics_util::get_root_pixmap(m_connection, &m_rootpixmap);
|
||||||
|
// graphics_util::simple_gc(m_connection, m_pixmap, &m_root_gc);
|
||||||
|
//
|
||||||
|
// if (!m_rootpixmap.pixmap || !m_pixmap || !m_root_gc) {
|
||||||
|
// m_log.warn("Failed to get root pixmap for bar window background");
|
||||||
|
// } else {
|
||||||
|
// m_log.trace("bar: rootpixmap=%x (%dx%d+%d+%d)", m_rootpixmap.pixmap, m_rootpixmap.width,
|
||||||
|
// m_rootpixmap.height, m_rootpixmap.x, m_rootpixmap.y);
|
||||||
|
//
|
||||||
|
// m_connection.copy_area(m_rootpixmap.pixmap, m_pixmap, m_root_gc, m_bar.x, m_bar.y, 0, 0,
|
||||||
|
// m_bar.width, m_bar.height);
|
||||||
|
//
|
||||||
|
// auto image_reply = m_connection.get_image(
|
||||||
|
// XCB_IMAGE_FORMAT_Z_PIXMAP, m_pixmap, 0, 0, m_bar.width, m_bar.height, XAllPlanes());
|
||||||
|
//
|
||||||
|
// std::vector<uint8_t> image_data;
|
||||||
|
// std::back_insert_iterator<decltype(image_data)> back_it(image_data);
|
||||||
|
// std::copy(image_reply.data().begin(), image_reply.data().end(), back_it);
|
||||||
|
//
|
||||||
|
// m_connection.put_image(XCB_IMAGE_FORMAT_Z_PIXMAP, m_pixmap, m_root_gc, m_bar.width,
|
||||||
|
// m_bar.height, 0, 0, 0, image_reply->depth, image_data.size(), image_data.data());
|
||||||
|
//
|
||||||
|
// m_connection.copy_area(m_rootpixmap.pixmap, m_pixmap, m_root_gc, m_bar.x, m_bar.y, 0, 0,
|
||||||
|
// m_bar.width, m_bar.height);
|
||||||
|
//
|
||||||
|
// uint32_t mask = 0;
|
||||||
|
// uint32_t values[16];
|
||||||
|
// xcb_params_cw_t params;
|
||||||
|
// XCB_AUX_ADD_PARAM(&mask, ¶ms, back_pixmap, m_pixmap);
|
||||||
|
// xutils::pack_values(mask, ¶ms, values);
|
||||||
|
// m_connection.change_window_attributes_checked(m_window, mask, values);
|
||||||
|
//
|
||||||
|
// m_connection.copy_area(
|
||||||
|
// m_pixmap, m_window, m_root_gc, m_bar.x, m_bar.y, 0, 0, m_bar.width, m_bar.height);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
// Load fonts {{{
|
// Load fonts {{{
|
||||||
|
|
||||||
@ -376,7 +411,46 @@ void bar::bootstrap(bool nodraw) { // {{{
|
|||||||
m_fontmanager->allocate_color(m_bar.foreground, true);
|
m_fontmanager->allocate_color(m_bar.foreground, true);
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
// Set tray settings {{{
|
// Connect signal handlers {{{
|
||||||
|
|
||||||
|
m_log.trace("bar: Attach parser callbacks");
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
g_signals::parser::alignment_change = bind(&bar::on_alignment_change, this, placeholders::_1);
|
||||||
|
g_signals::parser::attribute_set = bind(&bar::on_attribute_set, this, placeholders::_1);
|
||||||
|
g_signals::parser::attribute_unset = bind(&bar::on_attribute_unset, this, placeholders::_1);
|
||||||
|
g_signals::parser::attribute_toggle = bind(&bar::on_attribute_toggle, this, placeholders::_1);
|
||||||
|
g_signals::parser::action_block_open = bind(&bar::on_action_block_open, this, placeholders::_1, placeholders::_2);
|
||||||
|
g_signals::parser::action_block_close = bind(&bar::on_action_block_close, this, placeholders::_1);
|
||||||
|
g_signals::parser::color_change = bind(&bar::on_color_change, this, placeholders::_1, placeholders::_2);
|
||||||
|
g_signals::parser::font_change = bind(&bar::on_font_change, this, placeholders::_1);
|
||||||
|
g_signals::parser::pixel_offset = bind(&bar::on_pixel_offset, this, placeholders::_1);
|
||||||
|
g_signals::parser::ascii_text_write = bind(&bar::draw_character, this, placeholders::_1);
|
||||||
|
g_signals::parser::unicode_text_write = bind(&bar::draw_character, this, placeholders::_1);
|
||||||
|
g_signals::parser::string_write = bind(&bar::draw_textstring, this, placeholders::_1, placeholders::_2);
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// Attach event sink to registry {{{
|
||||||
|
|
||||||
|
m_log.trace("bar: Aattaching sink to registry");
|
||||||
|
m_connection.attach_sink(this, 1);
|
||||||
|
m_sinkattached = true;
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
if (!nodraw) {
|
||||||
|
bootstrap_tray();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_connection.flush();
|
||||||
|
} // }}}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup tray manager
|
||||||
|
*/
|
||||||
|
void bar::bootstrap_tray() { // {{{
|
||||||
|
auto bs = m_conf.bar_section();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto tray_position = m_conf.get<string>(bs, "tray-position");
|
auto tray_position = m_conf.get<string>(bs, "tray-position");
|
||||||
@ -393,7 +467,12 @@ void bar::bootstrap(bool nodraw) { // {{{
|
|||||||
m_tray.align = alignment::NONE;
|
m_tray.align = alignment::NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_tray.align != alignment::NONE) {
|
if (m_tray.align == alignment::NONE) {
|
||||||
|
m_log.warn("Disabling tray manager (reason: disabled in config)");
|
||||||
|
m_traymanager.reset();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_tray.height = m_bar.height;
|
m_tray.height = m_bar.height;
|
||||||
m_tray.height -= m_borders.at(border::BOTTOM).size;
|
m_tray.height -= m_borders.at(border::BOTTOM).size;
|
||||||
m_tray.height -= m_borders.at(border::TOP).size;
|
m_tray.height -= m_borders.at(border::TOP).size;
|
||||||
@ -426,11 +505,20 @@ void bar::bootstrap(bool nodraw) { // {{{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set user-defined background color
|
// Set user-defined background color
|
||||||
auto tray_bg = m_conf.get<string>(bs, "tray-background", "");
|
m_conf.get<bool>(bs, "tray-transparent", m_tray.transparent);
|
||||||
if (!tray_bg.empty()) {
|
|
||||||
m_tray.background = color::parse(tray_bg);
|
if (m_tray.transparent) {
|
||||||
|
m_tray.background = 0;
|
||||||
} else {
|
} else {
|
||||||
m_tray.background = m_bar.background;
|
auto bg = m_conf.get<string>(bs, "tray-background", "");
|
||||||
|
if (!bg.empty()) {
|
||||||
|
m_tray.background = color::parse(bg, g_colorempty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (color_util::alpha_channel(m_tray.background) == 0) {
|
||||||
|
m_tray.transparent = true;
|
||||||
|
m_tray.background = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add user-defined padding
|
// Add user-defined padding
|
||||||
@ -463,38 +551,34 @@ void bar::bootstrap(bool nodraw) { // {{{
|
|||||||
|
|
||||||
// Put the tray next to the bar in the window stack
|
// Put the tray next to the bar in the window stack
|
||||||
m_tray.sibling = m_window;
|
m_tray.sibling = m_window;
|
||||||
|
|
||||||
|
try {
|
||||||
|
m_log.trace("controller: Setup tray manager");
|
||||||
|
m_traymanager->bootstrap(tray());
|
||||||
|
} catch (const std::exception& err) {
|
||||||
|
m_log.err(err.what());
|
||||||
|
m_log.warn("Failed to setup tray, disabling...");
|
||||||
|
m_traymanager.reset();
|
||||||
|
}
|
||||||
|
} // }}}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Activate tray manager
|
||||||
|
*/
|
||||||
|
void bar::activate_tray() { // {{{
|
||||||
|
if (!m_traymanager) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
m_log.trace("controller: Activate tray manager");
|
||||||
// Connect signal handlers {{{
|
|
||||||
|
|
||||||
m_log.trace("bar: Attach parser callbacks");
|
try {
|
||||||
|
m_traymanager->activate();
|
||||||
// clang-format off
|
} catch (const std::exception& err) {
|
||||||
g_signals::parser::alignment_change = bind(&bar::on_alignment_change, this, placeholders::_1);
|
m_log.err(err.what());
|
||||||
g_signals::parser::attribute_set = bind(&bar::on_attribute_set, this, placeholders::_1);
|
m_log.err("Failed to activate tray manager, disabling...");
|
||||||
g_signals::parser::attribute_unset = bind(&bar::on_attribute_unset, this, placeholders::_1);
|
m_traymanager.reset();
|
||||||
g_signals::parser::attribute_toggle = bind(&bar::on_attribute_toggle, this, placeholders::_1);
|
}
|
||||||
g_signals::parser::action_block_open = bind(&bar::on_action_block_open, this, placeholders::_1, placeholders::_2);
|
|
||||||
g_signals::parser::action_block_close = bind(&bar::on_action_block_close, this, placeholders::_1);
|
|
||||||
g_signals::parser::color_change = bind(&bar::on_color_change, this, placeholders::_1, placeholders::_2);
|
|
||||||
g_signals::parser::font_change = bind(&bar::on_font_change, this, placeholders::_1);
|
|
||||||
g_signals::parser::pixel_offset = bind(&bar::on_pixel_offset, this, placeholders::_1);
|
|
||||||
g_signals::parser::ascii_text_write = bind(&bar::draw_character, this, placeholders::_1);
|
|
||||||
g_signals::parser::unicode_text_write = bind(&bar::draw_character, this, placeholders::_1);
|
|
||||||
g_signals::parser::string_write = bind(&bar::draw_textstring, this, placeholders::_1, placeholders::_2);
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
// Attach event sink to registry {{{
|
|
||||||
|
|
||||||
m_log.trace("bar: Aattaching sink to registry");
|
|
||||||
m_connection.attach_sink(this, 1);
|
|
||||||
m_sinkattached = true;
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
|
|
||||||
m_connection.flush();
|
|
||||||
} // }}}
|
} // }}}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -542,8 +626,8 @@ void bar::parse(string data, bool force) { // {{{
|
|||||||
|
|
||||||
draw_background();
|
draw_background();
|
||||||
|
|
||||||
if (m_tray.align == alignment::LEFT && m_tray.slots)
|
if (m_tray.align == alignment::LEFT && m_tray.configured_slots)
|
||||||
m_xpos += ((m_tray.width + m_tray.spacing) * m_tray.slots) + m_tray.spacing;
|
m_xpos += ((m_tray.width + m_tray.spacing) * m_tray.configured_slots) + m_tray.spacing;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
parser parser(m_bar);
|
parser parser(m_bar);
|
||||||
@ -552,8 +636,9 @@ void bar::parse(string data, bool force) { // {{{
|
|||||||
m_log.err("Unrecognized syntax token '%s'", err.what());
|
m_log.err("Unrecognized syntax token '%s'", err.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_tray.align == alignment::RIGHT && m_tray.slots)
|
if (m_tray.align == alignment::RIGHT && m_tray.configured_slots)
|
||||||
draw_shift(m_xpos, ((m_tray.width + m_tray.spacing) * m_tray.slots) + m_tray.spacing);
|
draw_shift(
|
||||||
|
m_xpos, ((m_tray.width + m_tray.spacing) * m_tray.configured_slots) + m_tray.spacing);
|
||||||
|
|
||||||
draw_border(border::ALL);
|
draw_border(border::ALL);
|
||||||
|
|
||||||
@ -569,16 +654,16 @@ void bar::parse(string data, bool force) { // {{{
|
|||||||
void bar::flush() { // {{{
|
void bar::flush() { // {{{
|
||||||
m_connection.copy_area(
|
m_connection.copy_area(
|
||||||
m_pixmap, m_window, m_gcontexts.at(gc::FG), 0, 0, 0, 0, m_bar.width, m_bar.height);
|
m_pixmap, m_window, m_gcontexts.at(gc::FG), 0, 0, 0, 0, m_bar.width, m_bar.height);
|
||||||
m_connection.copy_area(
|
|
||||||
m_pixmap, m_window, m_gcontexts.at(gc::BT), 0, 0, 0, 0, m_bar.width, m_bar.height);
|
// m_connection.copy_area(
|
||||||
m_connection.copy_area(
|
// m_pixmap, m_window, m_root_gc, m_bar.x, m_bar.y, 0, 0, m_bar.width, m_bar.height);
|
||||||
m_pixmap, m_window, m_gcontexts.at(gc::BB), 0, 0, 0, 0, m_bar.width, m_bar.height);
|
|
||||||
m_connection.copy_area(
|
|
||||||
m_pixmap, m_window, m_gcontexts.at(gc::BL), 0, 0, 0, 0, m_bar.width, m_bar.height);
|
|
||||||
m_connection.copy_area(
|
|
||||||
m_pixmap, m_window, m_gcontexts.at(gc::BR), 0, 0, 0, 0, m_bar.width, m_bar.height);
|
|
||||||
m_connection.flush();
|
m_connection.flush();
|
||||||
|
|
||||||
|
if (g_signals::bar::redraw) {
|
||||||
|
g_signals::bar::redraw();
|
||||||
|
}
|
||||||
|
|
||||||
#if DEBUG and DRAW_CLICKABLE_AREA_HINTS
|
#if DEBUG and DRAW_CLICKABLE_AREA_HINTS
|
||||||
map<alignment, int> hint_num{{
|
map<alignment, int> hint_num{{
|
||||||
{alignment::LEFT, 0}, {alignment::CENTER, 0}, {alignment::RIGHT, 0},
|
{alignment::LEFT, 0}, {alignment::CENTER, 0}, {alignment::RIGHT, 0},
|
||||||
@ -617,6 +702,13 @@ void bar::flush() { // {{{
|
|||||||
}
|
}
|
||||||
} // }}}
|
} // }}}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh the bar window by clearing and redrawing the pixmaps
|
||||||
|
*/
|
||||||
|
void bar::refresh_window() { // {{{
|
||||||
|
m_log.info("Refresh bar window");
|
||||||
|
} // }}}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event handler for XCB_BUTTON_PRESS events
|
* Event handler for XCB_BUTTON_PRESS events
|
||||||
*
|
*
|
||||||
@ -693,8 +785,12 @@ void bar::handle(const evt::expose& evt) { // {{{
|
|||||||
* Some might call it a dirty hack, others a crappy
|
* Some might call it a dirty hack, others a crappy
|
||||||
* solution... I choose to call it a masterpiece! Plus
|
* solution... I choose to call it a masterpiece! Plus
|
||||||
* it's not really any overhead worth talking about.
|
* it's not really any overhead worth talking about.
|
||||||
|
*
|
||||||
|
* Also tracks the root pixmap
|
||||||
*/
|
*/
|
||||||
void bar::handle(const evt::property_notify& evt) { // {{{
|
void bar::handle(const evt::property_notify& evt) { // {{{
|
||||||
|
m_log.trace("bar: property_notify");
|
||||||
|
|
||||||
if (evt->window == m_window && evt->atom == WM_STATE) {
|
if (evt->window == m_window && evt->atom == WM_STATE) {
|
||||||
if (!g_signals::bar::visibility_change) {
|
if (!g_signals::bar::visibility_change) {
|
||||||
return;
|
return;
|
||||||
@ -713,6 +809,12 @@ void bar::handle(const evt::property_notify& evt) { // {{{
|
|||||||
} catch (const std::exception& err) {
|
} catch (const std::exception& err) {
|
||||||
m_log.warn("Failed to emit bar window's visibility change event");
|
m_log.warn("Failed to emit bar window's visibility change event");
|
||||||
}
|
}
|
||||||
|
} else if (evt->atom == _XROOTMAP_ID) {
|
||||||
|
refresh_window();
|
||||||
|
} else if (evt->atom == _XSETROOT_ID) {
|
||||||
|
refresh_window();
|
||||||
|
} else if (evt->atom == ESETROOT_PMAP_ID) {
|
||||||
|
refresh_window();
|
||||||
}
|
}
|
||||||
} // }}}
|
} // }}}
|
||||||
|
|
||||||
@ -744,6 +846,7 @@ int bar::width_inner() { // {{{
|
|||||||
void bar::on_alignment_change(alignment align) { // {{{
|
void bar::on_alignment_change(alignment align) { // {{{
|
||||||
if (align == m_bar.align)
|
if (align == m_bar.align)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_log.trace_x("bar: alignment_change(%i)", static_cast<int>(align));
|
m_log.trace_x("bar: alignment_change(%i)", static_cast<int>(align));
|
||||||
m_bar.align = align;
|
m_bar.align = align;
|
||||||
|
|
||||||
@ -876,9 +979,9 @@ void bar::on_pixel_offset(int px) { // {{{
|
|||||||
* Proess systray report
|
* Proess systray report
|
||||||
*/
|
*/
|
||||||
void bar::on_tray_report(uint16_t slots) { // {{{
|
void bar::on_tray_report(uint16_t slots) { // {{{
|
||||||
if (m_tray.slots != slots) {
|
if (m_tray.configured_slots != slots) {
|
||||||
m_log.trace("bar: tray_report(%lu)", slots);
|
m_log.trace("bar: tray_report(%lu)", slots);
|
||||||
m_tray.slots = slots;
|
m_tray.configured_slots = slots;
|
||||||
|
|
||||||
if (!m_prevdata.empty()) {
|
if (!m_prevdata.empty()) {
|
||||||
parse(m_prevdata, true);
|
parse(m_prevdata, true);
|
||||||
@ -999,9 +1102,7 @@ int bar::draw_shift(int x, int chr_width) { // {{{
|
|||||||
* Draw text character
|
* Draw text character
|
||||||
*/
|
*/
|
||||||
void bar::draw_character(uint16_t character) { // {{{
|
void bar::draw_character(uint16_t character) { // {{{
|
||||||
// TODO: cache
|
|
||||||
auto& font = m_fontmanager->match_char(character);
|
auto& font = m_fontmanager->match_char(character);
|
||||||
|
|
||||||
if (!font) {
|
if (!font) {
|
||||||
m_log.warn("No suitable font found for character at index %i", character);
|
m_log.warn("No suitable font found for character at index %i", character);
|
||||||
return;
|
return;
|
||||||
@ -1012,7 +1113,6 @@ void bar::draw_character(uint16_t character) { // {{{
|
|||||||
m_fontmanager->set_gcontext_font(m_gcontexts.at(gc::FG), m_gcfont);
|
m_fontmanager->set_gcontext_font(m_gcontexts.at(gc::FG), m_gcfont);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: cache
|
|
||||||
auto chr_width = m_fontmanager->char_width(font, character);
|
auto chr_width = m_fontmanager->char_width(font, character);
|
||||||
|
|
||||||
// Avoid odd glyph width's for center-aligned text
|
// Avoid odd glyph width's for center-aligned text
|
||||||
@ -1029,9 +1129,9 @@ void bar::draw_character(uint16_t character) { // {{{
|
|||||||
auto color = m_fontmanager->xftcolor();
|
auto color = m_fontmanager->xftcolor();
|
||||||
XftDrawString16(m_xftdraw, &color, font->xft, x, y, &character, 1);
|
XftDrawString16(m_xftdraw, &color, font->xft, x, y, &character, 1);
|
||||||
} else {
|
} else {
|
||||||
character = (character >> 8) | (character << 8);
|
uint16_t ucs = ((character >> 8) | (character << 8));
|
||||||
draw_util::xcb_poly_text_16_patched(
|
draw_util::xcb_poly_text_16_patched(
|
||||||
m_connection, m_pixmap, m_gcontexts.at(gc::FG), x, y, 1, &character);
|
m_connection, m_pixmap, m_gcontexts.at(gc::FG), x, y, 1, &ucs);
|
||||||
}
|
}
|
||||||
|
|
||||||
draw_lines(x, chr_width);
|
draw_lines(x, chr_width);
|
||||||
|
@ -59,10 +59,6 @@ controller::~controller() {
|
|||||||
m_bar.reset();
|
m_bar.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_traymanager) {
|
|
||||||
m_traymanager.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_log.info("Interrupting X event loop");
|
m_log.info("Interrupting X event loop");
|
||||||
m_connection.send_dummy_event(m_connection.root());
|
m_connection.send_dummy_event(m_connection.root());
|
||||||
|
|
||||||
@ -97,7 +93,7 @@ void controller::bootstrap(bool writeback, bool dump_wmname) {
|
|||||||
// break the blocking wait call when cleaning up
|
// break the blocking wait call when cleaning up
|
||||||
m_log.trace("controller: Listen for events on the root window");
|
m_log.trace("controller: Listen for events on the root window");
|
||||||
try {
|
try {
|
||||||
const uint32_t value_list[1]{XCB_EVENT_MASK_STRUCTURE_NOTIFY};
|
const uint32_t value_list[2]{XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_STRUCTURE_NOTIFY};
|
||||||
m_connection.change_window_attributes_checked(
|
m_connection.change_window_attributes_checked(
|
||||||
m_connection.root(), XCB_CW_EVENT_MASK, value_list);
|
m_connection.root(), XCB_CW_EVENT_MASK, value_list);
|
||||||
} catch (const std::exception& err) {
|
} catch (const std::exception& err) {
|
||||||
@ -124,23 +120,6 @@ void controller::bootstrap(bool writeback, bool dump_wmname) {
|
|||||||
m_eventloop->set_input_db(bind(&controller::on_unrecognized_action, this, placeholders::_1));
|
m_eventloop->set_input_db(bind(&controller::on_unrecognized_action, this, placeholders::_1));
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
if (m_writeback) {
|
|
||||||
m_log.trace("controller: Disabling tray (reason: stdout mode)");
|
|
||||||
m_traymanager.reset();
|
|
||||||
} else if (m_bar->tray().align == alignment::NONE) {
|
|
||||||
m_log.trace("controller: Disabling tray (reason: tray-position)");
|
|
||||||
m_traymanager.reset();
|
|
||||||
} else {
|
|
||||||
m_log.trace("controller: Setup tray manager");
|
|
||||||
m_traymanager->bootstrap(m_bar->tray());
|
|
||||||
}
|
|
||||||
} catch (const std::exception& err) {
|
|
||||||
m_log.err(err.what());
|
|
||||||
m_log.warn("Failed to setup tray, disabling...");
|
|
||||||
m_traymanager.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_log.trace("controller: Setup user-defined modules");
|
m_log.trace("controller: Setup user-defined modules");
|
||||||
bootstrap_modules();
|
bootstrap_modules();
|
||||||
}
|
}
|
||||||
@ -157,11 +136,6 @@ bool controller::run() {
|
|||||||
install_sigmask();
|
install_sigmask();
|
||||||
install_confwatch();
|
install_confwatch();
|
||||||
|
|
||||||
// Activate traymanager in separate thread
|
|
||||||
if (!m_writeback && m_traymanager) {
|
|
||||||
m_threads.emplace_back(thread(&controller::activate_tray, this));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Listen for X events in separate thread
|
// Listen for X events in separate thread
|
||||||
if (!m_writeback) {
|
if (!m_writeback) {
|
||||||
m_threads.emplace_back(thread(&controller::wait_for_xevent, this));
|
m_threads.emplace_back(thread(&controller::wait_for_xevent, this));
|
||||||
@ -260,6 +234,9 @@ void controller::install_confwatch() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the config inotify watch
|
||||||
|
*/
|
||||||
void controller::uninstall_confwatch() {
|
void controller::uninstall_confwatch() {
|
||||||
try {
|
try {
|
||||||
if (m_confwatch) {
|
if (m_confwatch) {
|
||||||
@ -271,7 +248,7 @@ void controller::uninstall_confwatch() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: docstring
|
* Wait for termination signal
|
||||||
*/
|
*/
|
||||||
void controller::wait_for_signal() {
|
void controller::wait_for_signal() {
|
||||||
m_log.trace("controller: Wait for signal");
|
m_log.trace("controller: Wait for signal");
|
||||||
@ -292,7 +269,8 @@ void controller::wait_for_signal() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: docstring
|
* Wait for X events and forward them to
|
||||||
|
* the event registry
|
||||||
*/
|
*/
|
||||||
void controller::wait_for_xevent() {
|
void controller::wait_for_xevent() {
|
||||||
m_log.trace("controller: Listen for X events");
|
m_log.trace("controller: Listen for X events");
|
||||||
@ -319,21 +297,6 @@ void controller::wait_for_xevent() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: docstring
|
|
||||||
*/
|
|
||||||
void controller::activate_tray() {
|
|
||||||
m_log.trace("controller: Activate tray manager");
|
|
||||||
|
|
||||||
try {
|
|
||||||
m_traymanager->activate();
|
|
||||||
} catch (const std::exception& err) {
|
|
||||||
m_log.err(err.what());
|
|
||||||
m_log.err("Failed to activate tray manager, disabling...");
|
|
||||||
m_traymanager.reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create and initialize bar modules
|
* Create and initialize bar modules
|
||||||
*/
|
*/
|
||||||
@ -433,7 +396,7 @@ void controller::on_mouse_event(string input) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: docstring
|
* Callback for actions not handled internally by a module
|
||||||
*/
|
*/
|
||||||
void controller::on_unrecognized_action(string input) {
|
void controller::on_unrecognized_action(string input) {
|
||||||
try {
|
try {
|
||||||
@ -453,7 +416,7 @@ void controller::on_unrecognized_action(string input) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: docstring
|
* Callback for module content update
|
||||||
*/
|
*/
|
||||||
void controller::on_update() {
|
void controller::on_update() {
|
||||||
string contents{""};
|
string contents{""};
|
||||||
@ -520,6 +483,11 @@ void controller::on_update() {
|
|||||||
} else {
|
} else {
|
||||||
m_bar->parse(contents);
|
m_bar->parse(contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!m_trayactivated) {
|
||||||
|
m_trayactivated = true;
|
||||||
|
m_bar->activate_tray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LEMONBUDDY_NS_END
|
LEMONBUDDY_NS_END
|
||||||
|
@ -7,6 +7,7 @@ LEMONBUDDY_NS
|
|||||||
*/
|
*/
|
||||||
callback<string> g_signals::bar::action_click = nullptr;
|
callback<string> g_signals::bar::action_click = nullptr;
|
||||||
callback<bool> g_signals::bar::visibility_change = nullptr;
|
callback<bool> g_signals::bar::visibility_change = nullptr;
|
||||||
|
callback<> g_signals::bar::redraw = nullptr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signals used to communicate with the input parser
|
* Signals used to communicate with the input parser
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#include <X11/Xlib-xcb.h>
|
#include <X11/Xlib-xcb.h>
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
#include "components/command_line.hpp"
|
#include "components/command_line.hpp"
|
||||||
|
@ -16,13 +16,13 @@ color::color(string hex) : m_source(hex) {
|
|||||||
throw application_error("Cannot create color from empty hex");
|
throw application_error("Cannot create color from empty hex");
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t value = std::strtoul(&hex[1], nullptr, 16);
|
m_value = std::strtoul(&hex[1], nullptr, 16);
|
||||||
|
|
||||||
// Premultiply alpha
|
// Premultiply alpha
|
||||||
auto a = color_util::alpha_channel(value);
|
auto a = color_util::alpha_channel(m_value);
|
||||||
auto r = color_util::red_channel(value) * a / 255;
|
auto r = color_util::red_channel(m_value) * a / 255;
|
||||||
auto g = color_util::green_channel(value) * a / 255;
|
auto g = color_util::green_channel(m_value) * a / 255;
|
||||||
auto b = color_util::blue_channel(value) * a / 255;
|
auto b = color_util::blue_channel(m_value) * a / 255;
|
||||||
|
|
||||||
m_color = (a << 24) | (r << 16) | (g << 8) | b;
|
m_color = (a << 24) | (r << 16) | (g << 8) | b;
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,13 @@ namespace draw_util {
|
|||||||
*/
|
*/
|
||||||
void fill(connection& c, xcb_drawable_t d, xcb_gcontext_t g, int16_t x, int16_t y, uint16_t w,
|
void fill(connection& c, xcb_drawable_t d, xcb_gcontext_t g, int16_t x, int16_t y, uint16_t w,
|
||||||
uint16_t h) {
|
uint16_t h) {
|
||||||
array<xcb_rectangle_t, 1> rects{{xcb_rectangle_t({x, y, w, h})}};
|
xcb_rectangle_t rect;
|
||||||
c.poly_fill_rectangle(d, g, rects.size(), rects.data());
|
rect.x = x;
|
||||||
|
rect.y = y;
|
||||||
|
rect.width = w;
|
||||||
|
rect.height = h;
|
||||||
|
const xcb_rectangle_t rects[1]{rect};
|
||||||
|
c.poly_fill_rectangle(d, g, 1, rects);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
50
src/x11/wm.cpp
Normal file
50
src/x11/wm.cpp
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#include <xcb/xcb_icccm.h>
|
||||||
|
|
||||||
|
#include "x11/atoms.hpp"
|
||||||
|
#include "x11/wm.hpp"
|
||||||
|
|
||||||
|
LEMONBUDDY_NS
|
||||||
|
|
||||||
|
namespace wm_util {
|
||||||
|
void set_wmname(connection& conn, xcb_window_t win, string wm_name, string wm_class) {
|
||||||
|
xcb_icccm_set_wm_name(conn, win, XCB_ATOM_STRING, 8, wm_name.length(), wm_name.c_str());
|
||||||
|
xcb_icccm_set_wm_class(conn, win, wm_class.length(), wm_class.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_wmprotocols(connection& conn, xcb_window_t win, vector<xcb_atom_t> flags) {
|
||||||
|
xcb_icccm_set_wm_protocols(conn, win, WM_PROTOCOLS, flags.size(), flags.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_windowtype(connection& conn, xcb_window_t win, vector<xcb_atom_t> types) {
|
||||||
|
conn.change_property(XCB_PROP_MODE_REPLACE, win, _NET_WM_WINDOW_TYPE, XCB_ATOM_ATOM, 32,
|
||||||
|
types.size(), types.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_wmstate(connection& conn, xcb_window_t win, vector<xcb_atom_t> states) {
|
||||||
|
conn.change_property(
|
||||||
|
XCB_PROP_MODE_REPLACE, win, _NET_WM_STATE, XCB_ATOM_ATOM, 32, states.size(), states.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_wmpid(connection& conn, xcb_window_t win, pid_t pid) {
|
||||||
|
pid = getpid();
|
||||||
|
conn.change_property(XCB_PROP_MODE_REPLACE, win, _NET_WM_PID, XCB_ATOM_CARDINAL, 32, 1, &pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_wmdesktop(connection& conn, xcb_window_t win, uint32_t desktop) {
|
||||||
|
const uint32_t value_list[1]{desktop};
|
||||||
|
conn.change_property(
|
||||||
|
XCB_PROP_MODE_REPLACE, win, _NET_WM_DESKTOP, XCB_ATOM_CARDINAL, 32, 1, value_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_trayorientation(connection& conn, xcb_window_t win, uint32_t orientation) {
|
||||||
|
conn.change_property(XCB_PROP_MODE_REPLACE, win, _NET_SYSTEM_TRAY_ORIENTATION,
|
||||||
|
_NET_SYSTEM_TRAY_ORIENTATION, 32, 1, &orientation);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_trayvisual(connection& conn, xcb_window_t win, xcb_visualid_t visual) {
|
||||||
|
conn.change_property(
|
||||||
|
XCB_PROP_MODE_REPLACE, win, _NET_SYSTEM_TRAY_VISUAL, XCB_ATOM_VISUALID, 32, 1, &visual);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LEMONBUDDY_NS_END
|
@ -24,7 +24,7 @@ namespace xlib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Colormap create_colormap(int screen) {
|
Colormap create_colormap(int screen) {
|
||||||
return XCreateColormap(get_display(), XRootWindow(get_display(), screen), get_visual(), screen);
|
return XDefaultColormap(get_display(), screen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "x11/xutils.hpp"
|
#include "x11/xutils.hpp"
|
||||||
|
#include "x11/connection.hpp"
|
||||||
#include "x11/xlib.hpp"
|
#include "x11/xlib.hpp"
|
||||||
|
|
||||||
LEMONBUDDY_NS
|
LEMONBUDDY_NS
|
||||||
@ -17,10 +18,12 @@ namespace xutils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void pack_values(uint32_t mask, const uint32_t* src, uint32_t* dest) {
|
void pack_values(uint32_t mask, const uint32_t* src, uint32_t* dest) {
|
||||||
for (; mask; mask >>= 1, src++)
|
for (; mask; mask >>= 1, src++) {
|
||||||
if (mask & 1)
|
if (mask & 1) {
|
||||||
*dest++ = *src;
|
*dest++ = *src;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void pack_values(uint32_t mask, const xcb_params_cw_t* src, uint32_t* dest) {
|
void pack_values(uint32_t mask, const xcb_params_cw_t* src, uint32_t* dest) {
|
||||||
xutils::pack_values(mask, reinterpret_cast<const uint32_t*>(src), dest);
|
xutils::pack_values(mask, reinterpret_cast<const uint32_t*>(src), dest);
|
||||||
@ -30,9 +33,18 @@ namespace xutils {
|
|||||||
xutils::pack_values(mask, reinterpret_cast<const uint32_t*>(src), dest);
|
xutils::pack_values(mask, reinterpret_cast<const uint32_t*>(src), dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pack_values(uint32_t mask, const xcb_params_configure_window_t * src, uint32_t* dest) {
|
void pack_values(uint32_t mask, const xcb_params_configure_window_t* src, uint32_t* dest) {
|
||||||
xutils::pack_values(mask, reinterpret_cast<const uint32_t*>(src), dest);
|
xutils::pack_values(mask, reinterpret_cast<const uint32_t*>(src), dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void visibility_notify(connection& conn, const xcb_window_t& win, xcb_visibility_t state) {
|
||||||
|
auto notify = memory_util::make_malloc_ptr<xcb_visibility_notify_event_t>(32);
|
||||||
|
notify->response_type = XCB_VISIBILITY_NOTIFY;
|
||||||
|
notify->window = win;
|
||||||
|
notify->state = state;
|
||||||
|
const char* data = reinterpret_cast<const char*>(notify.get());
|
||||||
|
conn.send_event(true, win, XCB_EVENT_MASK_NO_EVENT, data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LEMONBUDDY_NS_END
|
LEMONBUDDY_NS_END
|
||||||
|
Loading…
Reference in New Issue
Block a user