refactor: Cleanup rendering
This commit is contained in:
parent
7018357e47
commit
9fdc22843b
@ -43,6 +43,7 @@ option(CXXLIB_GCC "Link against stdlibc++" OFF)
|
|||||||
option(BUILD_TESTS "Build testsuite" OFF)
|
option(BUILD_TESTS "Build testsuite" OFF)
|
||||||
option(DEBUG_LOGGER "Enable extra debug logging" OFF)
|
option(DEBUG_LOGGER "Enable extra debug logging" OFF)
|
||||||
option(VERBOSE_TRACELOG "Enable verbose trace logs" OFF)
|
option(VERBOSE_TRACELOG "Enable verbose trace logs" OFF)
|
||||||
|
option(DEBUG_HINTS "Enable hints rendering" OFF)
|
||||||
|
|
||||||
option(ENABLE_CCACHE "Enable ccache support" OFF)
|
option(ENABLE_CCACHE "Enable ccache support" OFF)
|
||||||
option(ENABLE_ALSA "Enable alsa support" ON)
|
option(ENABLE_ALSA "Enable alsa support" ON)
|
||||||
@ -82,4 +83,7 @@ set(SETTING_PATH_MESSAGING_FIFO "/tmp/polybar_mqueue.%pid%"
|
|||||||
set(SETTING_PATH_TEMPERATURE_INFO "/sys/class/thermal/thermal_zone%zone%/temp"
|
set(SETTING_PATH_TEMPERATURE_INFO "/sys/class/thermal/thermal_zone%zone%/temp"
|
||||||
CACHE STRING "Path to file containing the current temperature")
|
CACHE STRING "Path to file containing the current temperature")
|
||||||
|
|
||||||
|
set(DEBUG_HINTS_OFFSET_X 0 CACHE INTEGER "Debug hint offset x")
|
||||||
|
set(DEBUG_HINTS_OFFSET_Y 0 CACHE INTEGER "Debug hint offset y")
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
@ -47,6 +47,7 @@ message(STATUS "--------------------------")
|
|||||||
colored_option(STATUS " Build testsuite ${BUILD_TESTS}" BUILD_TESTS "32;1" "37;2")
|
colored_option(STATUS " Build testsuite ${BUILD_TESTS}" BUILD_TESTS "32;1" "37;2")
|
||||||
colored_option(STATUS " Debug logging ${DEBUG_LOGGER}" DEBUG_LOGGER "32;1" "37;2")
|
colored_option(STATUS " Debug logging ${DEBUG_LOGGER}" DEBUG_LOGGER "32;1" "37;2")
|
||||||
colored_option(STATUS " Verbose tracing ${VERBOSE_TRACELOG}" VERBOSE_TRACELOG "32;1" "37;2")
|
colored_option(STATUS " Verbose tracing ${VERBOSE_TRACELOG}" VERBOSE_TRACELOG "32;1" "37;2")
|
||||||
|
colored_option(STATUS " Draw debug hints ${DEBUG_HINTS}" DEBUG_HINTS "32;1" "37;2")
|
||||||
colored_option(STATUS " Enable ccache ${ENABLE_CCACHE}" ENABLE_CCACHE "32;1" "37;2")
|
colored_option(STATUS " Enable ccache ${ENABLE_CCACHE}" ENABLE_CCACHE "32;1" "37;2")
|
||||||
message(STATUS "--------------------------")
|
message(STATUS "--------------------------")
|
||||||
colored_option(STATUS " Enable alsa ${ENABLE_ALSA}" ENABLE_ALSA "32;1" "37;2")
|
colored_option(STATUS " Enable alsa ${ENABLE_ALSA}" ENABLE_ALSA "32;1" "37;2")
|
||||||
@ -58,20 +59,3 @@ colored_option(STATUS " Enable X RandR ${ENABLE_RANDR_EXT}" ENABLE_RANDR_E
|
|||||||
colored_option(STATUS " Enable X Render ${ENABLE_RENDER_EXT}" ENABLE_RENDER_EXT "32;1" "37;2")
|
colored_option(STATUS " Enable X Render ${ENABLE_RENDER_EXT}" ENABLE_RENDER_EXT "32;1" "37;2")
|
||||||
colored_option(STATUS " Enable X Damage ${ENABLE_DAMAGE_EXT}" ENABLE_DAMAGE_EXT "32;1" "37;2")
|
colored_option(STATUS " Enable X Damage ${ENABLE_DAMAGE_EXT}" ENABLE_DAMAGE_EXT "32;1" "37;2")
|
||||||
message(STATUS "--------------------------")
|
message(STATUS "--------------------------")
|
||||||
# message(STATUS " ALSA_SOUNDCARD ${SETTING_ALSA_SOUNDCARD}")
|
|
||||||
# message(STATUS " BSPWM_SOCKET_PATH ${SETTING_BSPWM_SOCKET_PATH}")
|
|
||||||
# message(STATUS " BSPWM_STATUS_PREFIX ${SETTING_BSPWM_STATUS_PREFIX}")
|
|
||||||
# message(STATUS " CONNECTION_TEST_IP ${SETTING_CONNECTION_TEST_IP}")
|
|
||||||
# message(STATUS " PATH_ADAPTER_STATUS ${SETTING_PATH_ADAPTER_STATUS}")
|
|
||||||
# message(STATUS " PATH_BACKLIGHT_VAL ${SETTING_PATH_BACKLIGHT_VAL}")
|
|
||||||
# message(STATUS " PATH_BACKLIGHT_MAX ${SETTING_PATH_BACKLIGHT_MAX}")
|
|
||||||
# message(STATUS " PATH_BATTERY_CAPACITY ${SETTING_PATH_BATTERY_CAPACITY}")
|
|
||||||
# message(STATUS " PATH_BATTERY_CAPACITY_MAX ${SETTING_PATH_BATTERY_CAPACITY_MAX}")
|
|
||||||
# message(STATUS " PATH_BATTERY_CAPACITY_PERC ${SETTING_PATH_BATTERY_CAPACITY_PERC}")
|
|
||||||
# message(STATUS " PATH_BATTERY_VOLTAGE ${SETTING_PATH_BATTERY_VOLTAGE}")
|
|
||||||
# message(STATUS " PATH_BATTERY_RATE ${SETTING_PATH_BATTERY_RATE}")
|
|
||||||
# message(STATUS " PATH_CPU_INFO ${SETTING_PATH_CPU_INFO}")
|
|
||||||
# message(STATUS " PATH_MEMORY_INFO ${SETTING_PATH_MEMORY_INFO}")
|
|
||||||
# message(STATUS " PATH_MESSAGING_FIFO ${SETTING_PATH_MESSAGING_FIFO}")
|
|
||||||
# message(STATUS " PATH_TEMPERATURE_INFO ${SETTING_PATH_TEMPERATURE_INFO}")
|
|
||||||
# message(STATUS "--------------------------")
|
|
||||||
|
@ -9,8 +9,10 @@ struct bar_settings;
|
|||||||
enum class attribute : uint8_t;
|
enum class attribute : uint8_t;
|
||||||
enum class mousebtn : uint8_t;
|
enum class mousebtn : uint8_t;
|
||||||
|
|
||||||
DEFINE_ERROR(unrecognized_token);
|
DEFINE_ERROR(parser_error);
|
||||||
DEFINE_ERROR(unrecognized_attribute);
|
DEFINE_CHILD_ERROR(unrecognized_token, parser_error);
|
||||||
|
DEFINE_CHILD_ERROR(unrecognized_attribute, parser_error);
|
||||||
|
DEFINE_CHILD_ERROR(unclosed_actionblocks, parser_error);
|
||||||
|
|
||||||
class parser {
|
class parser {
|
||||||
public:
|
public:
|
||||||
|
@ -21,7 +21,7 @@ class renderer {
|
|||||||
|
|
||||||
void begin();
|
void begin();
|
||||||
void end();
|
void end();
|
||||||
void redraw();
|
void flush(bool clear);
|
||||||
|
|
||||||
void reserve_space(edge side, uint16_t w);
|
void reserve_space(edge side, uint16_t w);
|
||||||
|
|
||||||
@ -36,7 +36,6 @@ class renderer {
|
|||||||
bool check_attribute(const attribute attr);
|
bool check_attribute(const attribute attr);
|
||||||
|
|
||||||
void fill_background();
|
void fill_background();
|
||||||
void fill_border(const map<edge, border_settings>& borders, edge border);
|
|
||||||
void fill_overline(int16_t x, uint16_t w);
|
void fill_overline(int16_t x, uint16_t w);
|
||||||
void fill_underline(int16_t x, uint16_t w);
|
void fill_underline(int16_t x, uint16_t w);
|
||||||
void fill_shift(const int16_t px);
|
void fill_shift(const int16_t px);
|
||||||
@ -49,10 +48,13 @@ class renderer {
|
|||||||
const vector<action_block> get_actions();
|
const vector<action_block> get_actions();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int16_t shift_content(const int16_t x, const int16_t shift_x);
|
int16_t shift_content(int16_t x, const int16_t shift_x);
|
||||||
int16_t shift_content(const int16_t shift_x);
|
int16_t shift_content(const int16_t shift_x);
|
||||||
|
|
||||||
void debughints();
|
#ifdef DEBUG_HINTS
|
||||||
|
vector<xcb_window_t> m_debughints;
|
||||||
|
void debug_hints();
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
connection& m_connection;
|
connection& m_connection;
|
||||||
@ -61,6 +63,8 @@ class renderer {
|
|||||||
|
|
||||||
const bar_settings& m_bar;
|
const bar_settings& m_bar;
|
||||||
|
|
||||||
|
xcb_rectangle_t m_rect{0, 0, 0U, 0U};
|
||||||
|
|
||||||
xcb_window_t m_window;
|
xcb_window_t m_window;
|
||||||
xcb_colormap_t m_colormap;
|
xcb_colormap_t m_colormap;
|
||||||
xcb_visualtype_t* m_visual;
|
xcb_visualtype_t* m_visual;
|
||||||
@ -79,9 +83,6 @@ class renderer {
|
|||||||
int8_t m_fontindex{DEFAULT_FONT_INDEX};
|
int8_t m_fontindex{DEFAULT_FONT_INDEX};
|
||||||
|
|
||||||
xcb_font_t m_gcfont{XCB_NONE};
|
xcb_font_t m_gcfont{XCB_NONE};
|
||||||
|
|
||||||
edge m_reserve_at{edge::NONE};
|
|
||||||
uint16_t m_reserve;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
di::injector<unique_ptr<renderer>> configure_renderer(const bar_settings& bar, const vector<string>& fonts);
|
di::injector<unique_ptr<renderer>> configure_renderer(const bar_settings& bar, const vector<string>& fonts);
|
||||||
|
@ -103,12 +103,14 @@ struct bar_settings {
|
|||||||
|
|
||||||
bool force_docking{false};
|
bool force_docking{false};
|
||||||
|
|
||||||
const xcb_rectangle_t inner_area(bool local_coords = false) const {
|
const xcb_rectangle_t inner_area(bool abspos = false) const {
|
||||||
xcb_rectangle_t rect{pos.x, pos.y, size.w, size.h};
|
xcb_rectangle_t rect{0, 0, size.w, size.h};
|
||||||
if (local_coords) {
|
|
||||||
rect.x = 0;
|
if (abspos) {
|
||||||
rect.y = 0;
|
rect.x = pos.x;
|
||||||
|
rect.y = pos.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
rect.y += borders.at(edge::TOP).size;
|
rect.y += borders.at(edge::TOP).size;
|
||||||
rect.height -= borders.at(edge::TOP).size;
|
rect.height -= borders.at(edge::TOP).size;
|
||||||
rect.height -= borders.at(edge::BOTTOM).size;
|
rect.height -= borders.at(edge::BOTTOM).size;
|
||||||
@ -126,9 +128,10 @@ struct action_block {
|
|||||||
mousebtn button{mousebtn::NONE};
|
mousebtn button{mousebtn::NONE};
|
||||||
string command;
|
string command;
|
||||||
bool active{true};
|
bool active{true};
|
||||||
#if DEBUG and DRAW_CLICKABLE_AREA_HINTS
|
|
||||||
xcb_window_t hint;
|
uint16_t width() const {
|
||||||
#endif
|
return end_x - start_x;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
POLYBAR_NS_END
|
POLYBAR_NS_END
|
||||||
|
@ -19,31 +19,28 @@
|
|||||||
|
|
||||||
#cmakedefine DEBUG_LOGGER
|
#cmakedefine DEBUG_LOGGER
|
||||||
#cmakedefine VERBOSE_TRACELOG
|
#cmakedefine VERBOSE_TRACELOG
|
||||||
|
#cmakedefine DEBUG_HINTS
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG_HINTS
|
||||||
#cmakedefine01 DRAW_CLICKABLE_AREA_HINTS
|
static const int DEBUG_HINTS_OFFSET_X{@DEBUG_HINTS_OFFSET_X@};
|
||||||
#cmakedefine DRAW_CLICKABLE_AREA_HINTS_OFFSET_Y @DRAW_CLICKABLE_AREA_HINTS_OFFSET_Y @
|
static const int DEBUG_HINTS_OFFSET_Y{@DEBUG_HINTS_OFFSET_Y@};
|
||||||
#ifndef DRAW_CLICKABLE_AREA_HINTS_OFFSET_Y
|
|
||||||
#define DRAW_CLICKABLE_AREA_HINTS_OFFSET_Y 0
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static constexpr const char* ALSA_SOUNDCARD{"default"};
|
static constexpr const char* ALSA_SOUNDCARD{"@SETTING_ALSA_SOUNDCARD@"};
|
||||||
static constexpr const char* BSPWM_SOCKET_PATH{"/tmp/bspwm_0_0-socket"};
|
static constexpr const char* BSPWM_SOCKET_PATH{"@SETTING_BSPWM_SOCKET_PATH@"};
|
||||||
static constexpr const char* BSPWM_STATUS_PREFIX{"W"};
|
static constexpr const char* BSPWM_STATUS_PREFIX{"@SETTING_BSPWM_STATUS_PREFIX@"};
|
||||||
static constexpr const char* CONNECTION_TEST_IP{"8.8.8.8"};
|
static constexpr const char* CONNECTION_TEST_IP{"@SETTING_CONNECTION_TEST_IP@"};
|
||||||
static constexpr const char* PATH_ADAPTER{"/sys/class/power_supply/%adapter%"};
|
static constexpr const char* PATH_ADAPTER{"@SETTING_PATH_ADAPTER@"};
|
||||||
static constexpr const char* PATH_BACKLIGHT_MAX{"/sys/class/backlight/%card%/max_brightness"};
|
static constexpr const char* PATH_BACKLIGHT_MAX{"@SETTING_PATH_BACKLIGHT_MAX@"};
|
||||||
static constexpr const char* PATH_BACKLIGHT_VAL{"/sys/class/backlight/%card%/brightness"};
|
static constexpr const char* PATH_BACKLIGHT_VAL{"@SETTING_PATH_BACKLIGHT_VAL@"};
|
||||||
static constexpr const char* PATH_BATTERY{"/sys/class/power_supply/%battery%"};
|
static constexpr const char* PATH_BATTERY{"@SETTING_PATH_BATTERY@"};
|
||||||
static constexpr const char* PATH_CPU_INFO{"/proc/stat"};
|
static constexpr const char* PATH_CPU_INFO{"@SETTING_PATH_CPU_INFO@"};
|
||||||
static constexpr const char* PATH_MEMORY_INFO{"/proc/meminfo"};
|
static constexpr const char* PATH_MEMORY_INFO{"@SETTING_PATH_MEMORY_INFO@"};
|
||||||
static constexpr const char* PATH_MESSAGING_FIFO{"/tmp/polybar_mqueue.%pid%"};
|
static constexpr const char* PATH_MESSAGING_FIFO{"@SETTING_PATH_MESSAGING_FIFO@"};
|
||||||
static constexpr const char* PATH_TEMPERATURE_INFO{"/sys/class/thermal/thermal_zone%zone%/temp"};
|
static constexpr const char* PATH_TEMPERATURE_INFO{"@SETTING_PATH_TEMPERATURE_INFO@"};
|
||||||
|
|
||||||
static constexpr const char* BUILDER_SPACE_TOKEN{"%__"};
|
|
||||||
|
|
||||||
static const int8_t DEFAULT_FONT_INDEX{-1};
|
static const int8_t DEFAULT_FONT_INDEX{-1};
|
||||||
|
static constexpr const char* BUILDER_SPACE_TOKEN{"%__"};
|
||||||
|
|
||||||
auto version_details = [](const std::vector<std::string>& args) {
|
auto version_details = [](const std::vector<std::string>& args) {
|
||||||
for (auto&& arg : args) {
|
for (auto&& arg : args) {
|
||||||
|
@ -80,10 +80,6 @@ namespace modules {
|
|||||||
chrono::system_clock::time_point m_lastsync;
|
chrono::system_clock::time_point m_lastsync;
|
||||||
float m_synctime = 1.0f;
|
float m_synctime = 1.0f;
|
||||||
|
|
||||||
string m_progress_fill;
|
|
||||||
string m_progress_empty;
|
|
||||||
string m_progress_indicator;
|
|
||||||
|
|
||||||
// This flag is used to let thru a broadcast once every time
|
// This flag is used to let thru a broadcast once every time
|
||||||
// the connection state changes
|
// the connection state changes
|
||||||
mpd::connection_state m_statebroadcasted;
|
mpd::connection_state m_statebroadcasted;
|
||||||
|
@ -8,7 +8,7 @@ struct cached_atom {
|
|||||||
xcb_atom_t* atom;
|
xcb_atom_t* atom;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern cached_atom ATOMS[33];
|
extern cached_atom ATOMS[34];
|
||||||
|
|
||||||
extern xcb_atom_t _NET_SUPPORTED;
|
extern xcb_atom_t _NET_SUPPORTED;
|
||||||
extern xcb_atom_t _NET_CURRENT_DESKTOP;
|
extern xcb_atom_t _NET_CURRENT_DESKTOP;
|
||||||
@ -43,3 +43,4 @@ extern xcb_atom_t BACKLIGHT;
|
|||||||
extern xcb_atom_t _XROOTMAP_ID;
|
extern xcb_atom_t _XROOTMAP_ID;
|
||||||
extern xcb_atom_t _XSETROOT_ID;
|
extern xcb_atom_t _XSETROOT_ID;
|
||||||
extern xcb_atom_t ESETROOT_PMAP_ID;
|
extern xcb_atom_t ESETROOT_PMAP_ID;
|
||||||
|
extern xcb_atom_t _COMPTON_SHADOW;
|
||||||
|
@ -6,11 +6,11 @@
|
|||||||
POLYBAR_NS
|
POLYBAR_NS
|
||||||
|
|
||||||
namespace draw_util {
|
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& conn, xcb_drawable_t d, xcb_gcontext_t g, const xcb_rectangle_t rect);
|
||||||
uint16_t h);
|
void fill(connection& conn, xcb_drawable_t d, xcb_gcontext_t g, int16_t x, int16_t y, uint16_t w, uint16_t h);
|
||||||
|
|
||||||
xcb_void_cookie_t xcb_poly_text_16_patched(xcb_connection_t* conn, xcb_drawable_t d,
|
xcb_void_cookie_t xcb_poly_text_16_patched(
|
||||||
xcb_gcontext_t gc, int16_t x, int16_t y, uint8_t len, uint16_t* str);
|
xcb_connection_t* conn, xcb_drawable_t d, xcb_gcontext_t gc, int16_t x, int16_t y, uint8_t len, uint16_t* str);
|
||||||
}
|
}
|
||||||
|
|
||||||
POLYBAR_NS_END
|
POLYBAR_NS_END
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "components/logger.hpp"
|
#include "components/logger.hpp"
|
||||||
#include "components/types.hpp"
|
#include "components/types.hpp"
|
||||||
#include "utils/concurrency.hpp"
|
#include "utils/concurrency.hpp"
|
||||||
|
#include "x11/events.hpp"
|
||||||
|
|
||||||
#define _NET_SYSTEM_TRAY_ORIENTATION_HORZ 0
|
#define _NET_SYSTEM_TRAY_ORIENTATION_HORZ 0
|
||||||
#define _NET_SYSTEM_TRAY_ORIENTATION_VERT 1
|
#define _NET_SYSTEM_TRAY_ORIENTATION_VERT 1
|
||||||
@ -99,7 +100,7 @@ class tray_manager : public xpp::event::sink<evt::expose, evt::visibility_notify
|
|||||||
|
|
||||||
void bootstrap(tray_settings settings);
|
void bootstrap(tray_settings settings);
|
||||||
void activate();
|
void activate();
|
||||||
void deactivate();
|
void deactivate(bool clear_selection = true);
|
||||||
void reconfigure();
|
void reconfigure();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -167,7 +168,6 @@ class tray_manager : public xpp::event::sink<evt::expose, evt::visibility_notify
|
|||||||
stateflag m_activated{false};
|
stateflag m_activated{false};
|
||||||
stateflag m_mapped{false};
|
stateflag m_mapped{false};
|
||||||
stateflag m_hidden{false};
|
stateflag m_hidden{false};
|
||||||
stateflag m_sinkattached{false};
|
|
||||||
|
|
||||||
thread m_delayed_activation;
|
thread m_delayed_activation;
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
|
#include "components/types.hpp"
|
||||||
#include "x11/connection.hpp"
|
#include "x11/connection.hpp"
|
||||||
|
|
||||||
POLYBAR_NS
|
POLYBAR_NS
|
||||||
@ -8,46 +9,108 @@ POLYBAR_NS
|
|||||||
using connection_t = connection;
|
using connection_t = connection;
|
||||||
|
|
||||||
struct cw_size {
|
struct cw_size {
|
||||||
cw_size(uint16_t w, uint16_t h) : w(w), h(h) {}
|
explicit cw_size(uint16_t w, uint16_t h) : w(w), h(h) {}
|
||||||
uint16_t w;
|
explicit cw_size(struct size size) : w(size.w), h(size.h) {}
|
||||||
uint16_t h;
|
uint16_t w{1};
|
||||||
|
uint16_t h{1};
|
||||||
};
|
};
|
||||||
struct cw_pos {
|
struct cw_pos {
|
||||||
cw_pos(int16_t x, int16_t y) : x(x), y(y) {}
|
explicit cw_pos(int16_t x, int16_t y) : x(x), y(y) {}
|
||||||
int16_t x;
|
explicit cw_pos(struct position pos) : x(pos.x), y(pos.y) {}
|
||||||
int16_t y;
|
int16_t x{0};
|
||||||
|
int16_t y{0};
|
||||||
};
|
};
|
||||||
struct cw_border {
|
struct cw_border {
|
||||||
cw_border(uint16_t border_width) : border_width(border_width) {}
|
explicit cw_border(uint16_t border_width) : border_width(border_width) {}
|
||||||
uint16_t border_width;
|
uint16_t border_width{0};
|
||||||
};
|
};
|
||||||
struct cw_class {
|
struct cw_class {
|
||||||
cw_class(uint16_t class_) : class_(class_) {}
|
explicit cw_class(uint16_t class_) : class_(class_) {}
|
||||||
uint16_t class_;
|
uint16_t class_{XCB_COPY_FROM_PARENT};
|
||||||
};
|
};
|
||||||
struct cw_parent {
|
struct cw_parent {
|
||||||
cw_parent(xcb_window_t parent) : parent(parent) {}
|
explicit cw_parent(xcb_window_t parent) : parent(parent) {}
|
||||||
xcb_window_t parent;
|
xcb_window_t parent{XCB_NONE};
|
||||||
};
|
};
|
||||||
struct cw_depth {
|
struct cw_depth {
|
||||||
cw_depth(uint8_t depth) : depth(depth) {}
|
explicit cw_depth(uint8_t depth) : depth(depth) {}
|
||||||
uint8_t depth;
|
uint8_t depth{XCB_COPY_FROM_PARENT};
|
||||||
};
|
};
|
||||||
struct cw_visual {
|
struct cw_visual {
|
||||||
cw_visual(xcb_visualid_t visualid) : visualid(visualid) {}
|
explicit cw_visual(xcb_visualid_t visualid) : visualid(visualid) {}
|
||||||
xcb_visualid_t visualid;
|
xcb_visualid_t visualid{XCB_COPY_FROM_PARENT};
|
||||||
};
|
};
|
||||||
struct cw_mask {
|
struct cw_mask {
|
||||||
cw_mask(uint32_t mask) : mask(mask) {}
|
explicit cw_mask(uint32_t mask) : mask(mask) {}
|
||||||
const uint32_t mask;
|
const uint32_t mask{0};
|
||||||
};
|
};
|
||||||
struct cw_params {
|
struct cw_params {
|
||||||
cw_params(const xcb_params_cw_t* params) : params(params) {}
|
explicit cw_params(const xcb_params_cw_t* params) : params(params) {}
|
||||||
const xcb_params_cw_t* params;
|
const xcb_params_cw_t* params{nullptr};
|
||||||
|
};
|
||||||
|
struct cw_params_back_pixel {
|
||||||
|
explicit cw_params_back_pixel(uint32_t value) : value(value) {}
|
||||||
|
uint32_t value{0};
|
||||||
|
};
|
||||||
|
struct cw_params_back_pixmap {
|
||||||
|
explicit cw_params_back_pixmap(uint32_t value) : value(value) {}
|
||||||
|
uint32_t value{0};
|
||||||
|
};
|
||||||
|
struct cw_params_backing_pixel {
|
||||||
|
explicit cw_params_backing_pixel(uint32_t value) : value(value) {}
|
||||||
|
uint32_t value{0};
|
||||||
|
};
|
||||||
|
struct cw_params_backing_planes {
|
||||||
|
explicit cw_params_backing_planes(uint32_t value) : value(value) {}
|
||||||
|
uint32_t value{0};
|
||||||
|
};
|
||||||
|
struct cw_params_backing_store {
|
||||||
|
explicit cw_params_backing_store(uint32_t value) : value(value) {}
|
||||||
|
uint32_t value{0};
|
||||||
|
};
|
||||||
|
struct cw_params_bit_gravity {
|
||||||
|
explicit cw_params_bit_gravity(uint32_t value) : value(value) {}
|
||||||
|
uint32_t value{0};
|
||||||
|
};
|
||||||
|
struct cw_params_border_pixel {
|
||||||
|
explicit cw_params_border_pixel(uint32_t value) : value(value) {}
|
||||||
|
uint32_t value{0};
|
||||||
|
};
|
||||||
|
struct cw_params_border_pixmap {
|
||||||
|
explicit cw_params_border_pixmap(uint32_t value) : value(value) {}
|
||||||
|
uint32_t value{0};
|
||||||
|
};
|
||||||
|
struct cw_params_colormap {
|
||||||
|
explicit cw_params_colormap(uint32_t value) : value(value) {}
|
||||||
|
uint32_t value{0};
|
||||||
|
};
|
||||||
|
struct cw_params_cursor {
|
||||||
|
explicit cw_params_cursor(uint32_t value) : value(value) {}
|
||||||
|
uint32_t value{0};
|
||||||
|
};
|
||||||
|
struct cw_params_dont_propagate {
|
||||||
|
explicit cw_params_dont_propagate(uint32_t value) : value(value) {}
|
||||||
|
uint32_t value{0};
|
||||||
|
};
|
||||||
|
struct cw_params_event_mask {
|
||||||
|
explicit cw_params_event_mask(uint32_t value) : value(value) {}
|
||||||
|
uint32_t value{0};
|
||||||
|
};
|
||||||
|
struct cw_params_override_redirect {
|
||||||
|
explicit cw_params_override_redirect(uint32_t value) : value(value) {}
|
||||||
|
uint32_t value{0};
|
||||||
|
};
|
||||||
|
struct cw_params_save_under {
|
||||||
|
explicit cw_params_save_under(uint32_t value) : value(value) {}
|
||||||
|
uint32_t value{0};
|
||||||
|
};
|
||||||
|
struct cw_params_win_gravity {
|
||||||
|
explicit cw_params_win_gravity(uint32_t value) : value(value) {}
|
||||||
|
uint32_t value{0};
|
||||||
};
|
};
|
||||||
struct cw_flush {
|
struct cw_flush {
|
||||||
cw_flush(bool checked = true) : checked(checked) {}
|
explicit cw_flush(bool checked = false) : checked(checked) {}
|
||||||
bool checked;
|
bool checked{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -55,7 +118,7 @@ struct cw_flush {
|
|||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
* @code cpp
|
* @code cpp
|
||||||
* auto win = winspec(conn)
|
* auto win = winspec(m_connection)
|
||||||
* << cw_size(100, 200)
|
* << cw_size(100, 200)
|
||||||
* << cw_pos(10, -20)
|
* << cw_pos(10, -20)
|
||||||
* << cw_border(9)
|
* << cw_border(9)
|
||||||
@ -66,90 +129,52 @@ struct cw_flush {
|
|||||||
*/
|
*/
|
||||||
class winspec {
|
class winspec {
|
||||||
public:
|
public:
|
||||||
explicit winspec(connection& conn, uint32_t id = XCB_NONE) : m_connection(conn), m_window(id) {}
|
explicit winspec(connection& conn);
|
||||||
|
explicit winspec(connection& conn, const xcb_window_t& window);
|
||||||
|
|
||||||
explicit operator xcb_window_t() const {
|
explicit operator xcb_window_t() const;
|
||||||
return m_window;
|
explicit operator xcb_rectangle_t() const;
|
||||||
}
|
|
||||||
|
|
||||||
explicit operator xcb_rectangle_t() const {
|
xcb_window_t operator<<(const cw_flush& f);
|
||||||
return {m_x, m_y, m_width, m_height};
|
|
||||||
}
|
|
||||||
|
|
||||||
winspec& operator<<(cw_size w) {
|
winspec& operator<<(const cw_size& size);
|
||||||
m_width = w.w;
|
winspec& operator<<(const cw_pos& p);
|
||||||
m_height = w.h;
|
winspec& operator<<(const cw_border& b);
|
||||||
return *this;
|
winspec& operator<<(const cw_class& c);
|
||||||
}
|
winspec& operator<<(const cw_parent& p);
|
||||||
winspec& operator<<(cw_pos p) {
|
winspec& operator<<(const cw_depth& d);
|
||||||
m_x = p.x;
|
winspec& operator<<(const cw_visual& v);
|
||||||
m_y = p.y;
|
winspec& operator<<(const cw_params_back_pixel& p);
|
||||||
return *this;
|
winspec& operator<<(const cw_params_back_pixmap& p);
|
||||||
}
|
winspec& operator<<(const cw_params_backing_pixel& p);
|
||||||
winspec& operator<<(cw_border b) {
|
winspec& operator<<(const cw_params_backing_planes& p);
|
||||||
m_border = b.border_width;
|
winspec& operator<<(const cw_params_backing_store& p);
|
||||||
return *this;
|
winspec& operator<<(const cw_params_bit_gravity& p);
|
||||||
}
|
winspec& operator<<(const cw_params_border_pixel& p);
|
||||||
winspec& operator<<(cw_class c) {
|
winspec& operator<<(const cw_params_border_pixmap& p);
|
||||||
m_class = c.class_;
|
winspec& operator<<(const cw_params_colormap& p);
|
||||||
return *this;
|
winspec& operator<<(const cw_params_cursor& p);
|
||||||
}
|
winspec& operator<<(const cw_params_dont_propagate& p);
|
||||||
winspec& operator<<(cw_parent p) {
|
winspec& operator<<(const cw_params_event_mask& p);
|
||||||
m_parent = p.parent;
|
winspec& operator<<(const cw_params_override_redirect& p);
|
||||||
return *this;
|
winspec& operator<<(const cw_params_save_under& p);
|
||||||
}
|
winspec& operator<<(const cw_params_win_gravity& p);
|
||||||
winspec& operator<<(cw_depth d) {
|
|
||||||
m_depth = d.depth;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
winspec& operator<<(cw_visual v) {
|
|
||||||
m_visual = v.visualid;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
winspec& operator<<(cw_mask m) {
|
|
||||||
m_mask = m.mask;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
winspec& operator<<(cw_params p) {
|
|
||||||
m_params = p.params;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
xcb_window_t operator<<(cw_flush f) {
|
|
||||||
if (!m_window) {
|
|
||||||
m_window = m_connection.generate_id();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t values[16]{0};
|
|
||||||
if (m_params != nullptr) {
|
|
||||||
xutils::pack_values(m_mask, m_params, values);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (f.checked) {
|
|
||||||
m_connection.create_window_checked(
|
|
||||||
m_depth, m_window, m_parent, m_x, m_y, m_width, m_height, m_border, m_class, m_visual, m_mask, values);
|
|
||||||
} else {
|
|
||||||
m_connection.create_window(
|
|
||||||
m_depth, m_window, m_parent, m_x, m_y, m_width, m_height, m_border, m_class, m_visual, m_mask, values);
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_window;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
connection& m_connection;
|
connection& m_connection;
|
||||||
uint32_t m_window;
|
|
||||||
uint32_t m_parent;
|
xcb_window_t m_window{XCB_NONE};
|
||||||
int16_t m_x;
|
uint32_t m_parent{XCB_NONE};
|
||||||
int16_t m_y;
|
|
||||||
uint16_t m_width;
|
|
||||||
uint16_t m_height;
|
|
||||||
uint8_t m_depth{XCB_COPY_FROM_PARENT};
|
uint8_t m_depth{XCB_COPY_FROM_PARENT};
|
||||||
uint16_t m_border{XCB_COPY_FROM_PARENT};
|
|
||||||
uint16_t m_class{XCB_COPY_FROM_PARENT};
|
uint16_t m_class{XCB_COPY_FROM_PARENT};
|
||||||
xcb_visualid_t m_visual;
|
xcb_visualid_t m_visual{XCB_COPY_FROM_PARENT};
|
||||||
uint32_t m_mask;
|
int16_t m_x{0};
|
||||||
const xcb_params_cw_t* m_params{nullptr};
|
int16_t m_y{0};
|
||||||
|
uint16_t m_width{1U};
|
||||||
|
uint16_t m_height{1U};
|
||||||
|
uint16_t m_border{0};
|
||||||
|
uint32_t m_mask{0};
|
||||||
|
xcb_params_cw_t m_params{};
|
||||||
};
|
};
|
||||||
|
|
||||||
POLYBAR_NS_END
|
POLYBAR_NS_END
|
||||||
|
@ -49,7 +49,9 @@ bar::bar(connection& conn, const config& config, const logger& logger, unique_pt
|
|||||||
*/
|
*/
|
||||||
bar::~bar() {
|
bar::~bar() {
|
||||||
std::lock_guard<std::mutex> guard(m_mutex);
|
std::lock_guard<std::mutex> guard(m_mutex);
|
||||||
|
g_signals::tray::report_slotcount = nullptr;
|
||||||
m_connection.detach_sink(this, 1);
|
m_connection.detach_sink(this, 1);
|
||||||
|
m_tray.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -147,6 +149,8 @@ void bar::bootstrap(bool nodraw) {
|
|||||||
m_renderer = configure_renderer(m_opts, m_conf.get_list<string>(bs, "font", {})).create<unique_ptr<renderer>>();
|
m_renderer = configure_renderer(m_opts, m_conf.get_list<string>(bs, "font", {})).create<unique_ptr<renderer>>();
|
||||||
m_window = m_renderer->window();
|
m_window = m_renderer->window();
|
||||||
|
|
||||||
|
m_log.info("Bar window: %s", m_connection.id(m_window));
|
||||||
|
|
||||||
restack_window();
|
restack_window();
|
||||||
reconfigure_window();
|
reconfigure_window();
|
||||||
|
|
||||||
@ -173,11 +177,10 @@ void bar::bootstrap(bool nodraw) {
|
|||||||
try {
|
try {
|
||||||
m_renderer->begin();
|
m_renderer->begin();
|
||||||
m_renderer->end();
|
m_renderer->end();
|
||||||
|
m_renderer->flush(false);
|
||||||
} catch (const exception& err) {
|
} catch (const exception& err) {
|
||||||
throw application_error("Failed to output empty bar window (reason: " + string{err.what()} + ")");
|
throw application_error("Failed to output empty bar window (reason: " + string{err.what()} + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
m_connection.flush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -239,7 +242,7 @@ void bar::bootstrap_tray() {
|
|||||||
} else if (settings.align == alignment::LEFT) {
|
} else if (settings.align == alignment::LEFT) {
|
||||||
settings.orig_x = m_opts.pos.x + m_opts.borders.at(edge::LEFT).size;
|
settings.orig_x = m_opts.pos.x + m_opts.borders.at(edge::LEFT).size;
|
||||||
} else if (settings.align == alignment::CENTER) {
|
} else if (settings.align == alignment::CENTER) {
|
||||||
settings.orig_x = m_opts.center.x - (settings.width / 2);
|
settings.orig_x = m_opts.pos.x + m_opts.center.x - (settings.width / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set user-defined background color
|
// Set user-defined background color
|
||||||
@ -357,6 +360,8 @@ void bar::parse(string data, bool force) {
|
|||||||
|
|
||||||
m_lastinput = data;
|
m_lastinput = data;
|
||||||
|
|
||||||
|
m_renderer->begin();
|
||||||
|
|
||||||
if (m_trayclients) {
|
if (m_trayclients) {
|
||||||
if (m_tray && m_trayalign == alignment::LEFT)
|
if (m_tray && m_trayalign == alignment::LEFT)
|
||||||
m_renderer->reserve_space(edge::LEFT, m_tray->settings().configured_w);
|
m_renderer->reserve_space(edge::LEFT, m_tray->settings().configured_w);
|
||||||
@ -364,21 +369,16 @@ void bar::parse(string data, bool force) {
|
|||||||
m_renderer->reserve_space(edge::RIGHT, m_tray->settings().configured_w);
|
m_renderer->reserve_space(edge::RIGHT, m_tray->settings().configured_w);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_renderer->begin();
|
m_renderer->fill_background();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
parser parser{m_log, m_opts};
|
parser parser{m_log, m_opts};
|
||||||
parser(data);
|
parser(data);
|
||||||
} catch (const unrecognized_token& err) {
|
} catch (const parser_error& err) {
|
||||||
m_log.err("Unrecognized syntax token '%s'", err.what());
|
m_log.err("Failed to parse contents (reason: %s)", err.what());
|
||||||
} catch (const unrecognized_attribute& err) {
|
|
||||||
m_log.err("Unrecognized attribute '%s'", err.what());
|
|
||||||
} catch (const exception& err) {
|
|
||||||
m_log.err("Error parsing contents (err: %s)", err.what());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_renderer->end();
|
m_renderer->end();
|
||||||
m_connection.flush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -432,12 +432,17 @@ void bar::configure_geom() {
|
|||||||
m_opts.size.w = math_util::cap<int>(m_opts.size.w, 0, m_opts.monitor->w);
|
m_opts.size.w = math_util::cap<int>(m_opts.size.w, 0, m_opts.monitor->w);
|
||||||
m_opts.size.h = math_util::cap<int>(m_opts.size.h, 0, m_opts.monitor->h);
|
m_opts.size.h = math_util::cap<int>(m_opts.size.h, 0, m_opts.monitor->h);
|
||||||
|
|
||||||
m_opts.center.y = m_opts.size.h + m_opts.borders[edge::TOP].size - m_opts.borders[edge::BOTTOM].size;
|
m_opts.center.y = m_opts.size.h;
|
||||||
|
m_opts.center.y -= m_opts.borders[edge::BOTTOM].size;
|
||||||
m_opts.center.y /= 2;
|
m_opts.center.y /= 2;
|
||||||
m_opts.center.x = m_opts.pos.x + m_opts.size.w - m_opts.borders[edge::RIGHT].size + m_opts.borders[edge::LEFT].size;
|
m_opts.center.y += m_opts.borders[edge::TOP].size;
|
||||||
m_opts.center.x /= 2;
|
|
||||||
|
|
||||||
m_log.info("Bar geometry %ix%i+%i+%i", m_opts.size.w, m_opts.size.h, m_opts.pos.x, m_opts.pos.y);
|
m_opts.center.x = m_opts.size.w;
|
||||||
|
m_opts.center.x -= m_opts.borders[edge::RIGHT].size;
|
||||||
|
m_opts.center.x /= 2;
|
||||||
|
m_opts.center.x += m_opts.borders[edge::LEFT].size;
|
||||||
|
|
||||||
|
m_log.info("Bar geometry: %ix%i+%i+%i", m_opts.size.w, m_opts.size.h, m_opts.pos.x, m_opts.pos.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -575,7 +580,8 @@ void bar::handle(const evt::button_press& evt) {
|
|||||||
|
|
||||||
m_log.trace_x("bar: Received button press: %i at pos(%i, %i)", evt->detail, evt->event_x, evt->event_y);
|
m_log.trace_x("bar: Received button press: %i at pos(%i, %i)", evt->detail, evt->event_x, evt->event_y);
|
||||||
|
|
||||||
mousebtn button = static_cast<mousebtn>(evt->detail);
|
const mousebtn button{static_cast<mousebtn>(evt->detail)};
|
||||||
|
const int16_t event_x{static_cast<int16_t>(evt->event_x - m_opts.inner_area().x)};
|
||||||
|
|
||||||
for (auto&& action : m_renderer->get_actions()) {
|
for (auto&& action : m_renderer->get_actions()) {
|
||||||
if (action.active) {
|
if (action.active) {
|
||||||
@ -584,11 +590,11 @@ void bar::handle(const evt::button_press& evt) {
|
|||||||
} else if (action.button != button) {
|
} else if (action.button != button) {
|
||||||
m_log.trace_x("bar: Ignoring action: button mismatch");
|
m_log.trace_x("bar: Ignoring action: button mismatch");
|
||||||
continue;
|
continue;
|
||||||
} else if (action.start_x > evt->event_x) {
|
} else if (action.start_x >= event_x) {
|
||||||
m_log.trace_x("bar: Ignoring action: start_x(%i) > event_x(%i)", action.start_x, evt->event_x);
|
m_log.trace_x("bar: Ignoring action: start_x(%i) > event_x(%i)", action.start_x, event_x);
|
||||||
continue;
|
continue;
|
||||||
} else if (action.end_x < evt->event_x) {
|
} else if (action.end_x <= event_x) {
|
||||||
m_log.trace_x("bar: Ignoring action: end_x(%i) < event_x(%i)", action.end_x, evt->event_x);
|
m_log.trace_x("bar: Ignoring action: end_x(%i) < event_x(%i)", action.end_x, event_x);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -617,7 +623,7 @@ void bar::handle(const evt::button_press& evt) {
|
|||||||
void bar::handle(const evt::expose& evt) {
|
void bar::handle(const evt::expose& evt) {
|
||||||
if (evt->window == m_window) {
|
if (evt->window == m_window) {
|
||||||
m_log.trace("bar: Received expose event");
|
m_log.trace("bar: Received expose event");
|
||||||
m_renderer->redraw();
|
m_renderer->flush(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,8 +12,6 @@ POLYBAR_NS
|
|||||||
* This will also close any unclosed tags
|
* This will also close any unclosed tags
|
||||||
*/
|
*/
|
||||||
string builder::flush() {
|
string builder::flush() {
|
||||||
if (m_tags[syntaxtag::A])
|
|
||||||
cmd_close();
|
|
||||||
if (m_tags[syntaxtag::B])
|
if (m_tags[syntaxtag::B])
|
||||||
background_close();
|
background_close();
|
||||||
if (m_tags[syntaxtag::F])
|
if (m_tags[syntaxtag::F])
|
||||||
@ -29,11 +27,15 @@ string builder::flush() {
|
|||||||
if ((m_attributes >> static_cast<uint8_t>(attribute::OVERLINE)) & 1U)
|
if ((m_attributes >> static_cast<uint8_t>(attribute::OVERLINE)) & 1U)
|
||||||
overline_close();
|
overline_close();
|
||||||
|
|
||||||
|
while (m_tags[syntaxtag::A]) {
|
||||||
|
cmd_close();
|
||||||
|
}
|
||||||
|
|
||||||
string output = m_output.data();
|
string output = m_output.data();
|
||||||
|
|
||||||
// reset values
|
// reset values
|
||||||
for (auto& counter : m_tags) counter.second = 0;
|
m_tags.clear();
|
||||||
for (auto& value : m_colors) value.second = "";
|
m_colors.clear();
|
||||||
m_output.clear();
|
m_output.clear();
|
||||||
m_fontindex = 1;
|
m_fontindex = 1;
|
||||||
|
|
||||||
@ -478,7 +480,9 @@ string builder::foreground_hex() {
|
|||||||
* Insert directive to change value of given tag
|
* Insert directive to change value of given tag
|
||||||
*/
|
*/
|
||||||
void builder::tag_open(syntaxtag tag, string value) {
|
void builder::tag_open(syntaxtag tag, string value) {
|
||||||
if (m_tags.find(tag) != m_tags.end())
|
if (m_tags.find(tag) == m_tags.end())
|
||||||
|
m_tags[tag] = 0;
|
||||||
|
|
||||||
m_tags[tag]++;
|
m_tags[tag]++;
|
||||||
|
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
@ -536,7 +540,7 @@ void builder::tag_open(attribute attr) {
|
|||||||
* Insert directive to reset given tag if it's open and closable
|
* Insert directive to reset given tag if it's open and closable
|
||||||
*/
|
*/
|
||||||
void builder::tag_close(syntaxtag tag) {
|
void builder::tag_close(syntaxtag tag) {
|
||||||
if (!m_tags[tag] || m_tags.find(tag) == m_tags.end())
|
if (m_tags.find(tag) == m_tags.end() || !m_tags[tag])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_tags[tag]--;
|
m_tags[tag]--;
|
||||||
|
@ -48,6 +48,10 @@ void parser::operator()(string data) {
|
|||||||
data.erase(0, text(data.substr(0, pos)));
|
data.erase(0, text(data.substr(0, pos)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!m_actions.empty()) {
|
||||||
|
throw unclosed_actionblocks(to_string(m_actions.size()) + " unclosed action block(s)");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -151,7 +155,7 @@ void parser::codeblock(string data) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw unrecognized_token(string{tag});
|
throw unrecognized_token("Unrecognized token '" + string{tag} + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data.empty())
|
if (!data.empty())
|
||||||
@ -232,7 +236,7 @@ attribute parser::parse_attr(const char attr) {
|
|||||||
case 'u':
|
case 'u':
|
||||||
return attribute::UNDERLINE;
|
return attribute::UNDERLINE;
|
||||||
default:
|
default:
|
||||||
throw unrecognized_attribute(string{attr});
|
throw unrecognized_token("Unrecognized attribute '" + string{attr} + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "x11/connection.hpp"
|
#include "x11/connection.hpp"
|
||||||
#include "x11/draw.hpp"
|
#include "x11/draw.hpp"
|
||||||
#include "x11/fonts.hpp"
|
#include "x11/fonts.hpp"
|
||||||
|
#include "x11/winspec.hpp"
|
||||||
#include "x11/xlib.hpp"
|
#include "x11/xlib.hpp"
|
||||||
#include "x11/xutils.hpp"
|
#include "x11/xutils.hpp"
|
||||||
|
|
||||||
@ -27,41 +28,44 @@ di::injector<unique_ptr<renderer>> configure_renderer(const bar_settings& bar, c
|
|||||||
*/
|
*/
|
||||||
renderer::renderer(connection& conn, const logger& logger, unique_ptr<font_manager> font_manager,
|
renderer::renderer(connection& conn, const logger& logger, unique_ptr<font_manager> font_manager,
|
||||||
const bar_settings& bar, const vector<string>& fonts)
|
const bar_settings& bar, const vector<string>& fonts)
|
||||||
: m_connection(conn), m_log(logger), m_fontmanager(forward<decltype(font_manager)>(font_manager)), m_bar(bar) {
|
: m_connection(conn)
|
||||||
auto screen = m_connection.screen();
|
, m_log(logger)
|
||||||
|
, m_fontmanager(forward<decltype(font_manager)>(font_manager))
|
||||||
|
, m_bar(bar)
|
||||||
|
, m_rect(bar.inner_area()) {
|
||||||
|
m_log.trace("renderer: Get TrueColor visual");
|
||||||
|
m_visual = m_connection.visual_type(m_connection.screen(), 32).get();
|
||||||
|
|
||||||
m_log.trace("renderer: Get true color visual");
|
m_log.trace("renderer: Allocate colormap");
|
||||||
m_visual = m_connection.visual_type(screen, 32).get();
|
|
||||||
|
|
||||||
m_log.trace("renderer: Create colormap");
|
|
||||||
m_colormap = m_connection.generate_id();
|
m_colormap = m_connection.generate_id();
|
||||||
m_connection.create_colormap(XCB_COLORMAP_ALLOC_NONE, m_colormap, screen->root, m_visual->visual_id);
|
m_connection.create_colormap(XCB_COLORMAP_ALLOC_NONE, m_colormap, m_connection.screen()->root, m_visual->visual_id);
|
||||||
|
|
||||||
m_window = m_connection.generate_id();
|
m_log.trace("renderer: Allocate output window");
|
||||||
m_log.trace("renderer: Create window (xid=%s)", m_connection.id(m_window));
|
|
||||||
{
|
{
|
||||||
uint32_t mask{0};
|
// clang-format off
|
||||||
uint32_t values[16]{0};
|
m_window = winspec(m_connection)
|
||||||
xcb_params_cw_t params;
|
<< cw_size(m_bar.size)
|
||||||
|
<< cw_pos(m_bar.pos)
|
||||||
XCB_AUX_ADD_PARAM(&mask, ¶ms, back_pixel, 0);
|
<< cw_depth(32)
|
||||||
XCB_AUX_ADD_PARAM(&mask, ¶ms, border_pixel, 0);
|
<< cw_visual(m_visual->visual_id)
|
||||||
XCB_AUX_ADD_PARAM(&mask, ¶ms, backing_store, XCB_BACKING_STORE_WHEN_MAPPED);
|
<< cw_class(XCB_WINDOW_CLASS_INPUT_OUTPUT)
|
||||||
XCB_AUX_ADD_PARAM(&mask, ¶ms, colormap, m_colormap);
|
<< cw_params_back_pixel(0)
|
||||||
XCB_AUX_ADD_PARAM(&mask, ¶ms, override_redirect, m_bar.force_docking);
|
<< cw_params_border_pixel(0)
|
||||||
XCB_AUX_ADD_PARAM(&mask, ¶ms, event_mask,
|
<< cw_params_backing_store(XCB_BACKING_STORE_WHEN_MAPPED)
|
||||||
XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS);
|
<< cw_params_colormap(m_colormap)
|
||||||
|
<< cw_params_event_mask(XCB_EVENT_MASK_PROPERTY_CHANGE
|
||||||
xutils::pack_values(mask, ¶ms, values);
|
|XCB_EVENT_MASK_EXPOSURE
|
||||||
m_connection.create_window(32, m_window, screen->root, m_bar.pos.x, m_bar.pos.y, m_bar.size.w, m_bar.size.h, 0,
|
|XCB_EVENT_MASK_BUTTON_PRESS)
|
||||||
XCB_WINDOW_CLASS_INPUT_OUTPUT, m_visual->visual_id, mask, values);
|
<< cw_params_override_redirect(m_bar.force_docking)
|
||||||
|
<< cw_flush(true);
|
||||||
|
// clang-format on
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_log.trace("renderer: Allocate window pixmap");
|
||||||
m_pixmap = m_connection.generate_id();
|
m_pixmap = m_connection.generate_id();
|
||||||
m_log.trace("renderer: Create pixmap (xid=%s)", m_connection.id(m_pixmap));
|
m_connection.create_pixmap(32, m_pixmap, m_window, m_rect.width, m_rect.height);
|
||||||
m_connection.create_pixmap(32, m_pixmap, m_window, m_bar.size.w, m_bar.size.h);
|
|
||||||
|
|
||||||
m_log.trace("renderer: Create gcontexts");
|
m_log.trace("renderer: Allocate graphic contexts");
|
||||||
{
|
{
|
||||||
// clang-format off
|
// clang-format off
|
||||||
vector<uint32_t> colors {
|
vector<uint32_t> colors {
|
||||||
@ -79,15 +83,14 @@ renderer::renderer(connection& conn, const logger& logger, unique_ptr<font_manag
|
|||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
uint32_t mask{0};
|
uint32_t mask{0};
|
||||||
uint32_t value_list[32]{0};
|
uint32_t value_list[32]{0};
|
||||||
xcb_params_gc_t params;
|
|
||||||
|
|
||||||
|
xcb_params_gc_t params;
|
||||||
XCB_AUX_ADD_PARAM(&mask, ¶ms, foreground, colors[i]);
|
XCB_AUX_ADD_PARAM(&mask, ¶ms, foreground, colors[i]);
|
||||||
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), m_connection.generate_id());
|
|
||||||
m_colors.emplace(gc(i), colors[i]);
|
m_colors.emplace(gc(i), colors[i]);
|
||||||
m_log.trace("renderer: Create gcontext (gc=%i, xid=%s)", i, m_connection.id(m_gcontexts.at(gc(i))));
|
m_gcontexts.emplace(gc(i), 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -138,19 +141,12 @@ xcb_window_t renderer::window() const {
|
|||||||
void renderer::begin() {
|
void renderer::begin() {
|
||||||
m_log.trace_x("renderer: begin");
|
m_log.trace_x("renderer: begin");
|
||||||
|
|
||||||
#if DEBUG and DRAW_CLICKABLE_AREA_HINTS
|
m_rect = m_bar.inner_area();
|
||||||
for (auto&& action : m_actions) {
|
m_alignment = alignment::NONE;
|
||||||
m_connection.destroy_window(action.hint);
|
m_currentx = 0;
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
m_currentx = m_bar.inner_area(true).x;
|
|
||||||
m_attributes = 0;
|
m_attributes = 0;
|
||||||
m_actions.clear();
|
m_actions.clear();
|
||||||
|
|
||||||
fill_border(m_bar.borders, edge::ALL);
|
|
||||||
fill_background();
|
|
||||||
|
|
||||||
m_fontmanager->create_xftdraw(m_pixmap, m_colormap);
|
m_fontmanager->create_xftdraw(m_pixmap, m_colormap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,33 +156,64 @@ void renderer::begin() {
|
|||||||
void renderer::end() {
|
void renderer::end() {
|
||||||
m_log.trace_x("renderer: end");
|
m_log.trace_x("renderer: end");
|
||||||
|
|
||||||
redraw();
|
|
||||||
m_fontmanager->destroy_xftdraw();
|
m_fontmanager->destroy_xftdraw();
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG_HINTS
|
||||||
debughints();
|
debug_hints();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_reserve = 0;
|
flush(false);
|
||||||
m_reserve_at = edge::NONE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Redraw window contents
|
* Redraw window contents
|
||||||
*/
|
*/
|
||||||
void renderer::redraw() {
|
void renderer::flush(bool clear) {
|
||||||
m_log.info("Redrawing");
|
const xcb_rectangle_t& r = m_rect;
|
||||||
|
|
||||||
xcb_rectangle_t r{0, 0, m_bar.size.w, m_bar.size.h};
|
xcb_rectangle_t top{0, 0, 0U, 0U};
|
||||||
|
top.x += m_bar.borders.at(edge::LEFT).size;
|
||||||
|
top.width += m_bar.size.w - m_bar.borders.at(edge::LEFT).size - m_bar.borders.at(edge::RIGHT).size;
|
||||||
|
top.height += m_bar.borders.at(edge::TOP).size;
|
||||||
|
|
||||||
if (m_reserve_at == edge::LEFT) {
|
xcb_rectangle_t bottom{0, 0, 0U, 0U};
|
||||||
r.x += m_reserve;
|
bottom.x += m_bar.borders.at(edge::LEFT).size;
|
||||||
r.width -= m_reserve;
|
bottom.y += m_bar.size.h - m_bar.borders.at(edge::BOTTOM).size;
|
||||||
} else if (m_reserve_at == edge::RIGHT) {
|
bottom.width += m_bar.size.w - m_bar.borders.at(edge::LEFT).size - m_bar.borders.at(edge::RIGHT).size;
|
||||||
r.width -= m_reserve;
|
bottom.height += m_bar.borders.at(edge::BOTTOM).size;
|
||||||
|
|
||||||
|
xcb_rectangle_t left{0, 0, 0U, 0U};
|
||||||
|
left.width += m_bar.borders.at(edge::LEFT).size;
|
||||||
|
left.height += m_bar.size.h;
|
||||||
|
|
||||||
|
xcb_rectangle_t right{0, 0, 0U, 0U};
|
||||||
|
right.x += m_bar.size.w - m_bar.borders.at(edge::RIGHT).size;
|
||||||
|
right.width += m_bar.borders.at(edge::RIGHT).size;
|
||||||
|
right.height += m_bar.size.h;
|
||||||
|
|
||||||
|
m_log.trace("renderer: clear window contents");
|
||||||
|
m_connection.clear_area(false, m_window, 0, 0, m_bar.size.w, m_bar.size.h);
|
||||||
|
|
||||||
|
m_log.trace("renderer: copy pixmap (clear=%i)", clear);
|
||||||
|
m_connection.copy_area(m_pixmap, m_window, m_gcontexts.at(gc::FG), 0, 0, r.x, r.y, r.width, r.height);
|
||||||
|
|
||||||
|
m_log.trace_x("renderer: draw top border (%lupx, %08x)", top.height, m_bar.borders.at(edge::TOP).color);
|
||||||
|
draw_util::fill(m_connection, m_window, m_gcontexts.at(gc::BT), top);
|
||||||
|
|
||||||
|
m_log.trace_x("renderer: draw bottom border (%lupx, %08x)", bottom.height, m_bar.borders.at(edge::BOTTOM).color);
|
||||||
|
draw_util::fill(m_connection, m_window, m_gcontexts.at(gc::BB), bottom);
|
||||||
|
|
||||||
|
m_log.trace_x("renderer: draw left border (%lupx, %08x)", left.width, m_bar.borders.at(edge::LEFT).color);
|
||||||
|
draw_util::fill(m_connection, m_window, m_gcontexts.at(gc::BL), left);
|
||||||
|
|
||||||
|
m_log.trace_x("renderer: draw right border (%lupx, %08x)", right.width, m_bar.borders.at(edge::RIGHT).color);
|
||||||
|
draw_util::fill(m_connection, m_window, m_gcontexts.at(gc::BR), right);
|
||||||
|
|
||||||
|
if (clear) {
|
||||||
|
m_connection.clear_area(false, m_pixmap, 0, 0, r.width, r.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_connection.copy_area(m_pixmap, m_window, m_gcontexts.at(gc::FG), r.x, r.y, r.x, r.y, r.width, r.height);
|
m_connection.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -194,8 +221,31 @@ void renderer::redraw() {
|
|||||||
*/
|
*/
|
||||||
void renderer::reserve_space(edge side, uint16_t w) {
|
void renderer::reserve_space(edge side, uint16_t w) {
|
||||||
m_log.trace_x("renderer: reserve_space(%i, %i)", static_cast<uint8_t>(side), w);
|
m_log.trace_x("renderer: reserve_space(%i, %i)", static_cast<uint8_t>(side), w);
|
||||||
m_reserve = w;
|
|
||||||
m_reserve_at = side;
|
switch (side) {
|
||||||
|
case edge::NONE:
|
||||||
|
break;
|
||||||
|
case edge::TOP:
|
||||||
|
m_rect.y += w;
|
||||||
|
m_rect.height -= w;
|
||||||
|
break;
|
||||||
|
case edge::BOTTOM:
|
||||||
|
m_rect.height -= w;
|
||||||
|
break;
|
||||||
|
case edge::LEFT:
|
||||||
|
m_rect.x += w;
|
||||||
|
m_rect.width -= w;
|
||||||
|
break;
|
||||||
|
case edge::RIGHT:
|
||||||
|
m_rect.width -= w;
|
||||||
|
break;
|
||||||
|
case edge::ALL:
|
||||||
|
m_rect.x += w;
|
||||||
|
m_rect.y += w;
|
||||||
|
m_rect.width -= w * 2;
|
||||||
|
m_rect.height -= w * 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -268,22 +318,9 @@ void renderer::set_alignment(const alignment align) {
|
|||||||
return m_log.trace_x("renderer: ignoring unchanged alignment(%i)", static_cast<uint8_t>(align));
|
return m_log.trace_x("renderer: ignoring unchanged alignment(%i)", static_cast<uint8_t>(align));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (align == alignment::LEFT) {
|
|
||||||
m_currentx = m_bar.borders.at(edge::LEFT).size;
|
|
||||||
} else if (align == alignment::RIGHT) {
|
|
||||||
m_currentx = m_bar.borders.at(edge::RIGHT).size;
|
|
||||||
} else {
|
|
||||||
m_currentx = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (align == alignment::LEFT && m_reserve_at == edge::LEFT) {
|
|
||||||
m_currentx += m_reserve;
|
|
||||||
} else if (align == alignment::RIGHT && m_reserve_at == edge::RIGHT) {
|
|
||||||
m_currentx += m_reserve;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_log.trace_x("renderer: set_alignment(%i)", static_cast<uint8_t>(align));
|
m_log.trace_x("renderer: set_alignment(%i)", static_cast<uint8_t>(align));
|
||||||
m_alignment = align;
|
m_alignment = align;
|
||||||
|
m_currentx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -319,52 +356,7 @@ bool renderer::check_attribute(const attribute attr) {
|
|||||||
*/
|
*/
|
||||||
void renderer::fill_background() {
|
void renderer::fill_background() {
|
||||||
m_log.trace_x("renderer: fill_background");
|
m_log.trace_x("renderer: fill_background");
|
||||||
|
draw_util::fill(m_connection, m_pixmap, m_gcontexts.at(gc::BG), 0, 0, m_rect.width, m_rect.height);
|
||||||
xcb_rectangle_t rect{0, 0, m_bar.size.w, m_bar.size.h};
|
|
||||||
|
|
||||||
if (m_reserve_at == edge::LEFT) {
|
|
||||||
rect.x += m_reserve;
|
|
||||||
rect.width -= m_reserve;
|
|
||||||
} else if (m_reserve_at == edge::RIGHT) {
|
|
||||||
rect.width -= m_reserve;
|
|
||||||
}
|
|
||||||
|
|
||||||
draw_util::fill(m_connection, m_pixmap, m_gcontexts.at(gc::BG), rect.x, rect.y, rect.width, rect.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fill border area
|
|
||||||
*/
|
|
||||||
void renderer::fill_border(const map<edge, border_settings>& borders, edge border) {
|
|
||||||
m_log.trace_x("renderer: fill_border(%i)", static_cast<uint8_t>(border));
|
|
||||||
|
|
||||||
for (auto&& b : borders) {
|
|
||||||
if (!b.second.size || (border != edge::ALL && b.first != border))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
switch (b.first) {
|
|
||||||
case edge::TOP:
|
|
||||||
draw_util::fill(m_connection, m_pixmap, m_gcontexts.at(gc::BT), borders.at(edge::LEFT).size, 0,
|
|
||||||
m_bar.size.w - borders.at(edge::LEFT).size - borders.at(edge::RIGHT).size, borders.at(edge::TOP).size);
|
|
||||||
break;
|
|
||||||
case edge::BOTTOM:
|
|
||||||
draw_util::fill(m_connection, m_pixmap, m_gcontexts.at(gc::BB), borders.at(edge::LEFT).size,
|
|
||||||
m_bar.size.h - borders.at(edge::BOTTOM).size,
|
|
||||||
m_bar.size.w - borders.at(edge::LEFT).size - borders.at(edge::RIGHT).size, borders.at(edge::BOTTOM).size);
|
|
||||||
break;
|
|
||||||
case edge::LEFT:
|
|
||||||
draw_util::fill(
|
|
||||||
m_connection, m_pixmap, m_gcontexts.at(gc::BL), 0, 0, borders.at(edge::LEFT).size, m_bar.size.h);
|
|
||||||
break;
|
|
||||||
case edge::RIGHT:
|
|
||||||
draw_util::fill(m_connection, m_pixmap, m_gcontexts.at(gc::BR), m_bar.size.w - borders.at(edge::RIGHT).size, 0,
|
|
||||||
borders.at(edge::RIGHT).size, m_bar.size.h);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -377,8 +369,7 @@ void renderer::fill_overline(int16_t x, uint16_t w) {
|
|||||||
return m_log.trace_x("renderer: not filling overline (size=0)");
|
return m_log.trace_x("renderer: not filling overline (size=0)");
|
||||||
}
|
}
|
||||||
m_log.trace_x("renderer: fill_overline(%i, #%08x)", m_bar.overline.size, m_colors[gc::OL]);
|
m_log.trace_x("renderer: fill_overline(%i, #%08x)", m_bar.overline.size, m_colors[gc::OL]);
|
||||||
const xcb_rectangle_t inner{m_bar.inner_area(true)};
|
draw_util::fill(m_connection, m_pixmap, m_gcontexts.at(gc::OL), x, 0, w, m_bar.overline.size);
|
||||||
draw_util::fill(m_connection, m_pixmap, m_gcontexts.at(gc::OL), x, inner.y, w, m_bar.overline.size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -391,8 +382,7 @@ void renderer::fill_underline(int16_t x, uint16_t w) {
|
|||||||
return m_log.trace_x("renderer: not filling underline (size=0)");
|
return m_log.trace_x("renderer: not filling underline (size=0)");
|
||||||
}
|
}
|
||||||
m_log.trace_x("renderer: fill_underline(%i, #%08x)", m_bar.underline.size, m_colors[gc::UL]);
|
m_log.trace_x("renderer: fill_underline(%i, #%08x)", m_bar.underline.size, m_colors[gc::UL]);
|
||||||
const xcb_rectangle_t inner{m_bar.inner_area(true)};
|
int16_t y{static_cast<int16_t>(m_rect.height - m_bar.underline.size)};
|
||||||
int16_t y{static_cast<int16_t>(inner.height - m_bar.underline.size)};
|
|
||||||
draw_util::fill(m_connection, m_pixmap, m_gcontexts.at(gc::UL), x, y, w, m_bar.underline.size);
|
draw_util::fill(m_connection, m_pixmap, m_gcontexts.at(gc::UL), x, y, w, m_bar.underline.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -407,7 +397,7 @@ void renderer::fill_shift(const int16_t px) {
|
|||||||
* Draw character glyph
|
* Draw character glyph
|
||||||
*/
|
*/
|
||||||
void renderer::draw_character(uint16_t character) {
|
void renderer::draw_character(uint16_t character) {
|
||||||
m_log.trace_x("renderer: draw_character(\"%c\")", character);
|
m_log.trace_x("renderer: draw_character");
|
||||||
|
|
||||||
auto& font = m_fontmanager->match_char(character);
|
auto& font = m_fontmanager->match_char(character);
|
||||||
|
|
||||||
@ -428,7 +418,7 @@ void renderer::draw_character(uint16_t character) {
|
|||||||
width++;
|
width++;
|
||||||
|
|
||||||
auto x = shift_content(width);
|
auto x = shift_content(width);
|
||||||
auto y = m_bar.center.y + font->height / 2 - font->descent + font->offset_y;
|
auto y = m_rect.height / 2 + font->height / 2 - font->descent + font->offset_y;
|
||||||
|
|
||||||
if (font->xft != nullptr) {
|
if (font->xft != nullptr) {
|
||||||
auto color = m_fontmanager->xftcolor();
|
auto color = m_fontmanager->xftcolor();
|
||||||
@ -473,7 +463,7 @@ void renderer::draw_textstring(const char* text, size_t len) {
|
|||||||
width++;
|
width++;
|
||||||
|
|
||||||
auto x = shift_content(width);
|
auto x = shift_content(width);
|
||||||
auto y = m_bar.center.y + font->height / 2 - font->descent + font->offset_y;
|
auto y = m_rect.height / 2 + font->height / 2 - font->descent + font->offset_y;
|
||||||
|
|
||||||
if (font->xft != nullptr) {
|
if (font->xft != nullptr) {
|
||||||
auto color = m_fontmanager->xftcolor();
|
auto color = m_fontmanager->xftcolor();
|
||||||
@ -510,32 +500,33 @@ void renderer::begin_action(const mousebtn btn, const string cmd) {
|
|||||||
* End action block at the current position
|
* End action block at the current position
|
||||||
*/
|
*/
|
||||||
void renderer::end_action(const mousebtn btn) {
|
void renderer::end_action(const mousebtn btn) {
|
||||||
for (auto action = m_actions.rbegin(); action != m_actions.rend(); action++) {
|
int16_t clickable_width{0};
|
||||||
if (!action->active || action->button != btn)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
m_log.trace_x("renderer: end_action(%i, %s)", static_cast<uint8_t>(btn), action->command.c_str());
|
for (auto action = m_actions.rbegin(); action != m_actions.rend(); action++) {
|
||||||
|
if (!action->active || action->align != m_alignment || action->button != btn)
|
||||||
|
continue;
|
||||||
|
|
||||||
action->active = false;
|
action->active = false;
|
||||||
|
|
||||||
if (action->align == alignment::LEFT) {
|
switch (action->align) {
|
||||||
|
case alignment::NONE:
|
||||||
|
break;
|
||||||
|
case alignment::LEFT:
|
||||||
action->end_x = m_currentx;
|
action->end_x = m_currentx;
|
||||||
} else if (action->align == alignment::CENTER) {
|
break;
|
||||||
int base_x{m_bar.size.w};
|
case alignment::CENTER:
|
||||||
int clickable_width{m_currentx - action->start_x};
|
clickable_width = m_currentx - action->start_x;
|
||||||
base_x -= m_bar.borders.at(edge::RIGHT).size;
|
action->start_x = m_rect.width / 2 - clickable_width / 2 + action->start_x / 2;
|
||||||
base_x /= 2;
|
|
||||||
base_x += m_bar.borders.at(edge::LEFT).size;
|
|
||||||
action->start_x = base_x - clickable_width / 2 + action->start_x / 2;
|
|
||||||
action->end_x = action->start_x + clickable_width;
|
action->end_x = action->start_x + clickable_width;
|
||||||
} else if (action->align == alignment::RIGHT) {
|
break;
|
||||||
int base_x{m_bar.size.w - m_bar.borders.at(edge::RIGHT).size};
|
case alignment::RIGHT:
|
||||||
if (m_reserve_at == edge::RIGHT)
|
action->start_x = m_rect.width - m_currentx + action->start_x;
|
||||||
base_x -= m_reserve;
|
action->end_x = m_rect.width;
|
||||||
action->start_x = base_x - m_currentx + action->start_x;
|
break;
|
||||||
action->end_x = base_x;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_log.trace_x("renderer: end_action(%i, %s, %i)", static_cast<uint8_t>(btn), action->command, action->width());
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -550,30 +541,33 @@ const vector<action_block> renderer::get_actions() {
|
|||||||
/**
|
/**
|
||||||
* Shift contents by given pixel value
|
* Shift contents by given pixel value
|
||||||
*/
|
*/
|
||||||
int16_t renderer::shift_content(const int16_t x, const int16_t shift_x) {
|
int16_t renderer::shift_content(int16_t x, const int16_t shift_x) {
|
||||||
m_log.trace_x("renderer: shift_content(%i)", shift_x);
|
m_log.trace_x("renderer: shift_content(%i)", shift_x);
|
||||||
|
|
||||||
int delta = shift_x;
|
int16_t delta{shift_x};
|
||||||
int x2{x};
|
int16_t base_x{0};
|
||||||
|
|
||||||
if (m_alignment == alignment::CENTER) {
|
switch (m_alignment) {
|
||||||
int base_x = m_bar.size.w;
|
case alignment::NONE:
|
||||||
base_x -= m_bar.borders.at(edge::RIGHT).size;
|
break;
|
||||||
base_x /= 2;
|
case alignment::LEFT:
|
||||||
base_x += m_bar.borders.at(edge::LEFT).size;
|
break;
|
||||||
m_connection.copy_area(
|
case alignment::CENTER:
|
||||||
m_pixmap, m_pixmap, m_gcontexts.at(gc::FG), base_x - x / 2, 0, base_x - (x + shift_x) / 2, 0, x, m_bar.size.h);
|
base_x = static_cast<int16_t>(m_rect.width / 2);
|
||||||
x2 = base_x - (x + shift_x) / 2 + x;
|
m_connection.copy_area(m_pixmap, m_pixmap, m_gcontexts.at(gc::FG), base_x - x / 2, 0, base_x - (x + shift_x) / 2,
|
||||||
|
0, x, m_rect.height);
|
||||||
|
x = base_x - (x + shift_x) / 2 + x;
|
||||||
delta /= 2;
|
delta /= 2;
|
||||||
} else if (m_alignment == alignment::RIGHT) {
|
break;
|
||||||
m_connection.copy_area(m_pixmap, m_pixmap, m_gcontexts.at(gc::FG), m_bar.size.w - x, 0, m_bar.size.w - x - shift_x,
|
case alignment::RIGHT:
|
||||||
0, x, m_bar.size.h);
|
base_x = static_cast<int16_t>(m_rect.width - x);
|
||||||
x2 = m_bar.size.w - shift_x - m_bar.borders.at(edge::RIGHT).size;
|
m_connection.copy_area(
|
||||||
if (m_reserve_at == edge::RIGHT)
|
m_pixmap, m_pixmap, m_gcontexts.at(gc::FG), base_x, 0, base_x - shift_x, 0, x, m_rect.height);
|
||||||
x2 -= m_reserve;
|
x = m_rect.width - shift_x;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
draw_util::fill(m_connection, m_pixmap, m_gcontexts.at(gc::BG), x2, 0, m_bar.size.w - x, m_bar.size.h);
|
draw_util::fill(m_connection, m_pixmap, m_gcontexts.at(gc::BG), x, 0, m_rect.width - x, m_rect.height);
|
||||||
|
|
||||||
// Translate pos of clickable areas
|
// Translate pos of clickable areas
|
||||||
if (m_alignment != alignment::LEFT) {
|
if (m_alignment != alignment::LEFT) {
|
||||||
@ -587,10 +581,10 @@ int16_t renderer::shift_content(const int16_t x, const int16_t shift_x) {
|
|||||||
|
|
||||||
m_currentx += shift_x;
|
m_currentx += shift_x;
|
||||||
|
|
||||||
fill_underline(x2, shift_x);
|
fill_underline(x, shift_x);
|
||||||
fill_overline(x2, shift_x);
|
fill_overline(x, shift_x);
|
||||||
|
|
||||||
return x2;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -600,39 +594,59 @@ int16_t renderer::shift_content(const int16_t shift_x) {
|
|||||||
return shift_content(m_currentx, shift_x);
|
return shift_content(m_currentx, shift_x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_HINTS
|
||||||
/**
|
/**
|
||||||
* Draw debugging hints onto the output window
|
* Draw debugging hints onto the output window
|
||||||
*/
|
*/
|
||||||
void renderer::debughints() {
|
void renderer::debug_hints() {
|
||||||
#if DEBUG and DRAW_CLICKABLE_AREA_HINTS
|
uint16_t border_width{1};
|
||||||
m_log.info("Drawing debug hints");
|
|
||||||
|
|
||||||
map<alignment, int> hint_num{{
|
map<alignment, int> hint_num{{
|
||||||
{alignment::LEFT, 0}, {alignment::CENTER, 0}, {alignment::RIGHT, 0},
|
// clang-format off
|
||||||
|
{alignment::LEFT, 0},
|
||||||
|
{alignment::CENTER, 0},
|
||||||
|
{alignment::RIGHT, 0},
|
||||||
|
// clang-format on
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
for (auto&& hintwin : m_debughints) {
|
||||||
|
m_connection.destroy_window(hintwin);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_debughints.clear();
|
||||||
|
|
||||||
for (auto&& action : m_actions) {
|
for (auto&& action : m_actions) {
|
||||||
if (action.active) {
|
if (action.active) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
hint_num[action.align]++;
|
uint8_t num{static_cast<uint8_t>(hint_num.find(action.align)->second++)};
|
||||||
|
int16_t x{static_cast<int16_t>(m_bar.pos.x + m_rect.x + action.start_x)};
|
||||||
|
int16_t y{static_cast<int16_t>(m_bar.pos.y + m_rect.y)};
|
||||||
|
uint16_t w{static_cast<uint16_t>(action.width() - border_width * 2)};
|
||||||
|
uint16_t h{static_cast<uint16_t>(m_rect.height - border_width * 2)};
|
||||||
|
|
||||||
auto x = action.start_x;
|
x += num * DEBUG_HINTS_OFFSET_X;
|
||||||
auto y = m_bar.y + hint_num[action.align]++ * DRAW_CLICKABLE_AREA_HINTS_OFFSET_Y;
|
y += num * DEBUG_HINTS_OFFSET_Y;
|
||||||
auto w = action.end_x - action.start_x - 2;
|
|
||||||
auto h = m_bar.size.h - 2;
|
|
||||||
|
|
||||||
const uint32_t mask = XCB_CW_BORDER_PIXEL | XCB_CW_OVERRIDE_REDIRECT;
|
xcb_window_t hintwin{m_connection.generate_id()};
|
||||||
const uint32_t border_color = hint_num[action.align] % 2 ? 0xff0000 : 0x00ff00;
|
m_debughints.emplace_back(hintwin);
|
||||||
const uint32_t values[2]{border_color, true};
|
|
||||||
|
|
||||||
action.hint = m_connection.generate_id();
|
// clang-format off
|
||||||
m_connection.create_window(m_screen->root_depth, action.hint, m_screen->root, x, y, w, h, 1,
|
winspec(m_connection, hintwin)
|
||||||
XCB_WINDOW_CLASS_INPUT_OUTPUT, m_screen->root_visual, mask, values);
|
<< cw_size(w, h)
|
||||||
m_connection.map_window(action.hint);
|
<< cw_pos(x, y)
|
||||||
|
<< cw_border(border_width)
|
||||||
|
<< cw_params_border_pixel(num % 2 ? 0xFFFF0000 : 0xFF00FF00)
|
||||||
|
<< cw_params_override_redirect(true)
|
||||||
|
<< cw_flush()
|
||||||
|
;
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
xutils::compton_shadow_exclude(m_connection, hintwin);
|
||||||
|
m_connection.map_window(hintwin);
|
||||||
|
m_log.info("Debug hint created (x=%i width=%i)", action.start_x, action.width());
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
POLYBAR_NS_END
|
POLYBAR_NS_END
|
||||||
|
@ -150,7 +150,7 @@ namespace modules {
|
|||||||
if (!m_muted && m_volume > 0)
|
if (!m_muted && m_volume > 0)
|
||||||
m_builder->cmd(mousebtn::SCROLL_DOWN, EVENT_VOLUME_DOWN);
|
m_builder->cmd(mousebtn::SCROLL_DOWN, EVENT_VOLUME_DOWN);
|
||||||
|
|
||||||
m_builder->node(module::get_output());
|
m_builder->append(module::get_output());
|
||||||
|
|
||||||
return m_builder->flush();
|
return m_builder->flush();
|
||||||
}
|
}
|
||||||
|
@ -133,21 +133,12 @@ namespace modules {
|
|||||||
* Generate the module output
|
* Generate the module output
|
||||||
*/
|
*/
|
||||||
string xbacklight_module::get_output() {
|
string xbacklight_module::get_output() {
|
||||||
if (m_scroll) {
|
if (m_scroll && m_percentage < 100)
|
||||||
if (m_percentage < 100)
|
|
||||||
m_builder->cmd(mousebtn::SCROLL_UP, EVENT_SCROLLUP);
|
m_builder->cmd(mousebtn::SCROLL_UP, EVENT_SCROLLUP);
|
||||||
if (m_percentage > 0)
|
if (m_scroll && m_percentage > 0)
|
||||||
m_builder->cmd(mousebtn::SCROLL_DOWN, EVENT_SCROLLDOWN);
|
m_builder->cmd(mousebtn::SCROLL_DOWN, EVENT_SCROLLDOWN);
|
||||||
|
|
||||||
m_builder->node(static_module::get_output());
|
m_builder->append(static_module::get_output());
|
||||||
|
|
||||||
if (m_percentage < 100)
|
|
||||||
m_builder->cmd_close();
|
|
||||||
if (m_percentage > 0)
|
|
||||||
m_builder->cmd_close();
|
|
||||||
} else {
|
|
||||||
m_builder->node(static_module::get_output());
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_builder->flush();
|
return m_builder->flush();
|
||||||
}
|
}
|
||||||
|
@ -36,9 +36,10 @@ xcb_atom_t BACKLIGHT;
|
|||||||
xcb_atom_t _XROOTMAP_ID;
|
xcb_atom_t _XROOTMAP_ID;
|
||||||
xcb_atom_t _XSETROOT_ID;
|
xcb_atom_t _XSETROOT_ID;
|
||||||
xcb_atom_t ESETROOT_PMAP_ID;
|
xcb_atom_t ESETROOT_PMAP_ID;
|
||||||
|
xcb_atom_t _COMPTON_SHADOW;
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
cached_atom ATOMS[33] = {
|
cached_atom ATOMS[34] = {
|
||||||
{"_NET_SUPPORTED", sizeof("_NET_SUPPORTED") - 1, &_NET_SUPPORTED},
|
{"_NET_SUPPORTED", sizeof("_NET_SUPPORTED") - 1, &_NET_SUPPORTED},
|
||||||
{"_NET_CURRENT_DESKTOP", sizeof("_NET_CURRENT_DESKTOP") - 1, &_NET_CURRENT_DESKTOP},
|
{"_NET_CURRENT_DESKTOP", sizeof("_NET_CURRENT_DESKTOP") - 1, &_NET_CURRENT_DESKTOP},
|
||||||
{"_NET_ACTIVE_WINDOW", sizeof("_NET_ACTIVE_WINDOW") - 1, &_NET_ACTIVE_WINDOW},
|
{"_NET_ACTIVE_WINDOW", sizeof("_NET_ACTIVE_WINDOW") - 1, &_NET_ACTIVE_WINDOW},
|
||||||
@ -72,5 +73,6 @@ cached_atom ATOMS[33] = {
|
|||||||
{"_XROOTMAP_ID", sizeof("_XROOTMAP_ID") - 1, &_XROOTMAP_ID},
|
{"_XROOTMAP_ID", sizeof("_XROOTMAP_ID") - 1, &_XROOTMAP_ID},
|
||||||
{"_XSETROOT_ID", sizeof("_XSETROOT_ID") - 1, &_XSETROOT_ID},
|
{"_XSETROOT_ID", sizeof("_XSETROOT_ID") - 1, &_XSETROOT_ID},
|
||||||
{"ESETROOT_PMAP_ID", sizeof("ESETROOT_PMAP_ID") - 1, &ESETROOT_PMAP_ID},
|
{"ESETROOT_PMAP_ID", sizeof("ESETROOT_PMAP_ID") - 1, &ESETROOT_PMAP_ID},
|
||||||
|
{"_COMPTON_SHADOW", sizeof("_COMPTON_SHADOW") - 1, &_COMPTON_SHADOW},
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
@ -10,15 +10,15 @@ namespace draw_util {
|
|||||||
/**
|
/**
|
||||||
* Fill region of drawable with color defined by gcontext
|
* Fill region of drawable with color defined by gcontext
|
||||||
*/
|
*/
|
||||||
void fill(connection& c, xcb_drawable_t d, xcb_gcontext_t g, int16_t x, int16_t y, uint16_t w,
|
void fill(connection& conn, xcb_drawable_t d, xcb_gcontext_t g, const xcb_rectangle_t rect) {
|
||||||
uint16_t h) {
|
conn.poly_fill_rectangle(d, g, 1, &rect);
|
||||||
xcb_rectangle_t rect;
|
}
|
||||||
rect.x = x;
|
|
||||||
rect.y = y;
|
/**
|
||||||
rect.width = w;
|
* Fill region of drawable with color defined by gcontext
|
||||||
rect.height = h;
|
*/
|
||||||
const xcb_rectangle_t rects[1]{rect};
|
void fill(connection& conn, xcb_drawable_t d, xcb_gcontext_t g, int16_t x, int16_t y, uint16_t w, uint16_t h) {
|
||||||
c.poly_fill_rectangle(d, g, 1, rects);
|
fill(conn, d, g, {x, y, w, h});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,8 +26,8 @@ namespace draw_util {
|
|||||||
*
|
*
|
||||||
* Code: http://wmdia.sourceforge.net/
|
* Code: http://wmdia.sourceforge.net/
|
||||||
*/
|
*/
|
||||||
xcb_void_cookie_t xcb_poly_text_16_patched(xcb_connection_t* conn, xcb_drawable_t d,
|
xcb_void_cookie_t xcb_poly_text_16_patched(
|
||||||
xcb_gcontext_t gc, int16_t x, int16_t y, uint8_t len, uint16_t* str) {
|
xcb_connection_t* conn, xcb_drawable_t d, xcb_gcontext_t gc, int16_t x, int16_t y, uint8_t len, uint16_t* str) {
|
||||||
static const xcb_protocol_request_t xcb_req = {
|
static const xcb_protocol_request_t xcb_req = {
|
||||||
5, // count
|
5, // count
|
||||||
0, // ext
|
0, // ext
|
||||||
|
@ -12,10 +12,10 @@
|
|||||||
#include "x11/color.hpp"
|
#include "x11/color.hpp"
|
||||||
#include "x11/connection.hpp"
|
#include "x11/connection.hpp"
|
||||||
#include "x11/draw.hpp"
|
#include "x11/draw.hpp"
|
||||||
#include "x11/events.hpp"
|
|
||||||
#include "x11/graphics.hpp"
|
#include "x11/graphics.hpp"
|
||||||
#include "x11/tray.hpp"
|
#include "x11/tray.hpp"
|
||||||
#include "x11/window.hpp"
|
#include "x11/window.hpp"
|
||||||
|
#include "x11/winspec.hpp"
|
||||||
#include "x11/wm.hpp"
|
#include "x11/wm.hpp"
|
||||||
#include "x11/xembed.hpp"
|
#include "x11/xembed.hpp"
|
||||||
|
|
||||||
@ -122,14 +122,11 @@ void tray_client::configure_notify(int16_t x, int16_t y) const { // {{{
|
|||||||
|
|
||||||
tray_manager::tray_manager(connection& conn, const logger& logger) : m_connection(conn), m_log(logger) {
|
tray_manager::tray_manager(connection& conn, const logger& logger) : m_connection(conn), m_log(logger) {
|
||||||
m_connection.attach_sink(this, 2);
|
m_connection.attach_sink(this, 2);
|
||||||
m_sinkattached = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tray_manager::~tray_manager() {
|
tray_manager::~tray_manager() {
|
||||||
if (m_activated)
|
|
||||||
deactivate();
|
|
||||||
if (m_sinkattached)
|
|
||||||
m_connection.detach_sink(this, 2);
|
m_connection.detach_sink(this, 2);
|
||||||
|
deactivate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -155,7 +152,7 @@ void tray_manager::activate() { // {{{
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_log.info("Activating tray_manager");
|
m_log.info("Activating tray manager");
|
||||||
m_activated = true;
|
m_activated = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -166,16 +163,11 @@ void tray_manager::activate() { // {{{
|
|||||||
set_traycolors();
|
set_traycolors();
|
||||||
} catch (const exception& err) {
|
} catch (const exception& err) {
|
||||||
m_log.err(err.what());
|
m_log.err(err.what());
|
||||||
m_log.err("Cannot activate tray_manager... failed to setup window");
|
m_log.err("Cannot activate tray manager... failed to setup window");
|
||||||
m_activated = false;
|
m_activated = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_sinkattached) {
|
|
||||||
m_connection.attach_sink(this, 2);
|
|
||||||
m_sinkattached = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Listen for visibility change events on the bar window
|
// Listen for visibility change events on the bar window
|
||||||
if (!m_restacked && !g_signals::bar::visibility_change) {
|
if (!m_restacked && !g_signals::bar::visibility_change) {
|
||||||
g_signals::bar::visibility_change = bind(&tray_manager::bar_visibility_change, this, std::placeholders::_1);
|
g_signals::bar::visibility_change = bind(&tray_manager::bar_visibility_change, this, std::placeholders::_1);
|
||||||
@ -185,12 +177,7 @@ void tray_manager::activate() { // {{{
|
|||||||
// notify clients waiting for a manager.
|
// notify clients waiting for a manager.
|
||||||
acquire_selection();
|
acquire_selection();
|
||||||
|
|
||||||
// If replacing an existing manager or if re-activating from getting
|
// Notify pending tray clients
|
||||||
// replaced, we delay the notification broadcast to allow the clients
|
|
||||||
// to get unembedded...
|
|
||||||
if (m_othermanager)
|
|
||||||
std::this_thread::sleep_for(std::chrono::seconds{1});
|
|
||||||
|
|
||||||
notify_clients();
|
notify_clients();
|
||||||
|
|
||||||
m_connection.flush();
|
m_connection.flush();
|
||||||
@ -199,12 +186,12 @@ void tray_manager::activate() { // {{{
|
|||||||
/**
|
/**
|
||||||
* Deactivate systray management
|
* Deactivate systray management
|
||||||
*/
|
*/
|
||||||
void tray_manager::deactivate() { // {{{
|
void tray_manager::deactivate(bool clear_selection) { // {{{
|
||||||
if (!m_activated) {
|
if (!m_activated) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_log.info("Deactivating tray_manager");
|
m_log.info("Deactivating tray manager");
|
||||||
m_activated = false;
|
m_activated = false;
|
||||||
|
|
||||||
if (m_delayed_activation.joinable())
|
if (m_delayed_activation.joinable())
|
||||||
@ -219,12 +206,10 @@ void tray_manager::deactivate() { // {{{
|
|||||||
g_signals::bar::visibility_change = nullptr;
|
g_signals::bar::visibility_change = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_connection.connection_has_error()) {
|
if (!m_connection.connection_has_error() && clear_selection) {
|
||||||
if (m_connection.get_selection_owner_unchecked(m_atom).owner<xcb_window_t>() == m_tray) {
|
|
||||||
m_log.trace("tray: Unset selection owner");
|
m_log.trace("tray: Unset selection owner");
|
||||||
m_connection.set_selection_owner(XCB_NONE, m_atom, XCB_CURRENT_TIME);
|
m_connection.set_selection_owner(XCB_NONE, m_atom, XCB_CURRENT_TIME);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
m_log.trace("tray: Unembed clients");
|
m_log.trace("tray: Unembed clients");
|
||||||
m_clients.clear();
|
m_clients.clear();
|
||||||
@ -255,6 +240,11 @@ void tray_manager::deactivate() { // {{{
|
|||||||
m_rootpixmap.pixmap = 0;
|
m_rootpixmap.pixmap = 0;
|
||||||
m_prevwidth = 0;
|
m_prevwidth = 0;
|
||||||
m_prevheight = 0;
|
m_prevheight = 0;
|
||||||
|
m_opts.configured_x = 0;
|
||||||
|
m_opts.configured_y = 0;
|
||||||
|
m_opts.configured_w = 0;
|
||||||
|
m_opts.configured_h = 0;
|
||||||
|
m_opts.configured_slots = 0;
|
||||||
|
|
||||||
m_connection.flush();
|
m_connection.flush();
|
||||||
} // }}}
|
} // }}}
|
||||||
@ -497,36 +487,24 @@ void tray_manager::query_atom() { // {{{
|
|||||||
* Create tray window
|
* Create tray window
|
||||||
*/
|
*/
|
||||||
void tray_manager::create_window() { // {{{
|
void tray_manager::create_window() { // {{{
|
||||||
auto scr = m_connection.screen();
|
m_log.trace("tray: Create tray window");
|
||||||
auto w = calculate_w();
|
|
||||||
auto h = calculate_h();
|
|
||||||
auto x = calculate_x(w);
|
|
||||||
auto y = calculate_y();
|
|
||||||
|
|
||||||
if (w < 1) {
|
auto win = winspec(m_connection, m_tray)
|
||||||
w = 1;
|
<< cw_size(calculate_w(), calculate_h())
|
||||||
}
|
<< cw_pos(calculate_x(calculate_w()), calculate_y())
|
||||||
|
<< cw_class(XCB_WINDOW_CLASS_INPUT_OUTPUT)
|
||||||
m_tray = m_connection.generate_id();
|
<< cw_params_backing_store(XCB_BACKING_STORE_WHEN_MAPPED)
|
||||||
m_log.trace("tray: Create tray window %s, (%ix%i+%i+%i)", m_connection.id(m_tray), w, h, x, y);
|
<< cw_params_event_mask(XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_STRUCTURE_NOTIFY)
|
||||||
|
<< cw_params_override_redirect(true)
|
||||||
uint32_t mask = 0;
|
;
|
||||||
uint32_t values[16];
|
|
||||||
xcb_params_cw_t params;
|
|
||||||
|
|
||||||
if (!m_opts.transparent) {
|
if (!m_opts.transparent) {
|
||||||
XCB_AUX_ADD_PARAM(&mask, ¶ms, back_pixel, m_opts.background);
|
win << cw_params_back_pixel(m_opts.background);
|
||||||
XCB_AUX_ADD_PARAM(&mask, ¶ms, border_pixel, m_opts.background);
|
win << cw_params_border_pixel(m_opts.background);
|
||||||
}
|
}
|
||||||
|
|
||||||
XCB_AUX_ADD_PARAM(&mask, ¶ms, backing_store, XCB_BACKING_STORE_WHEN_MAPPED);
|
m_tray = win << cw_flush();
|
||||||
XCB_AUX_ADD_PARAM(&mask, ¶ms, override_redirect, true);
|
m_log.info("Tray window: %s", m_connection.id(m_tray));
|
||||||
XCB_AUX_ADD_PARAM(&mask, ¶ms, event_mask, XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_STRUCTURE_NOTIFY);
|
|
||||||
|
|
||||||
xutils::pack_values(mask, ¶ms, values);
|
|
||||||
|
|
||||||
m_connection.create_window_checked(
|
|
||||||
scr->root_depth, m_tray, scr->root, x, y, w, h, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, scr->root_visual, mask, values);
|
|
||||||
|
|
||||||
xutils::compton_shadow_exclude(m_connection, m_tray);
|
xutils::compton_shadow_exclude(m_connection, m_tray);
|
||||||
} // }}}
|
} // }}}
|
||||||
@ -662,13 +640,14 @@ void tray_manager::set_traycolors() { // {{{
|
|||||||
* Acquire the systray selection
|
* Acquire the systray selection
|
||||||
*/
|
*/
|
||||||
void tray_manager::acquire_selection() { // {{{
|
void tray_manager::acquire_selection() { // {{{
|
||||||
xcb_window_t owner = m_connection.get_selection_owner_unchecked(m_atom)->owner;
|
xcb_window_t owner{m_connection.get_selection_owner_unchecked(m_atom)->owner};
|
||||||
|
|
||||||
if (owner == m_tray) {
|
if (owner == m_tray) {
|
||||||
m_log.info("tray: Already managing the systray selection");
|
m_log.info("tray: Already managing the systray selection");
|
||||||
return;
|
return;
|
||||||
} else if ((m_othermanager = owner)) {
|
} else if ((m_othermanager = owner)) {
|
||||||
m_log.info("Replacing selection manager %s", m_connection.id(owner));
|
m_log.info("Replacing selection manager %s", m_connection.id(owner));
|
||||||
|
std::this_thread::sleep_for(std::chrono::seconds{1});
|
||||||
}
|
}
|
||||||
|
|
||||||
m_log.trace("tray: Change selection owner to %s", m_connection.id(m_tray));
|
m_log.trace("tray: Change selection owner to %s", m_connection.id(m_tray));
|
||||||
@ -1011,7 +990,7 @@ void tray_manager::handle(const evt::selection_clear& evt) { // {{{
|
|||||||
m_othermanager = 0;
|
m_othermanager = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
deactivate();
|
deactivate(false);
|
||||||
} // }}}
|
} // }}}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1073,8 +1052,11 @@ void tray_manager::handle(const evt::reparent_notify& evt) { // {{{
|
|||||||
* Event callback : XCB_DESTROY_NOTIFY
|
* Event callback : XCB_DESTROY_NOTIFY
|
||||||
*/
|
*/
|
||||||
void tray_manager::handle(const evt::destroy_notify& evt) { // {{{
|
void tray_manager::handle(const evt::destroy_notify& evt) { // {{{
|
||||||
if (!m_activated && evt->window == m_othermanager) {
|
if (m_activated && evt->window == m_tray) {
|
||||||
|
deactivate();
|
||||||
|
} else if (!m_activated && evt->window == m_othermanager && evt->window != m_tray) {
|
||||||
m_log.trace("tray: Received destroy_notify");
|
m_log.trace("tray: Received destroy_notify");
|
||||||
|
std::this_thread::sleep_for(std::chrono::seconds{1});
|
||||||
m_log.info("Tray selection available... re-activating");
|
m_log.info("Tray selection available... re-activating");
|
||||||
activate();
|
activate();
|
||||||
window{m_connection, m_tray}.redraw();
|
window{m_connection, m_tray}.redraw();
|
||||||
@ -1131,8 +1113,10 @@ void tray_manager::handle(const evt::unmap_notify& evt) { // {{{
|
|||||||
}
|
}
|
||||||
m_log.trace("tray: Update container mapped flag");
|
m_log.trace("tray: Update container mapped flag");
|
||||||
m_mapped = false;
|
m_mapped = false;
|
||||||
|
if (!m_hidden) {
|
||||||
m_opts.configured_w = 0;
|
m_opts.configured_w = 0;
|
||||||
m_opts.configured_x = 0;
|
m_opts.configured_x = 0;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
auto client = find_client(evt->window);
|
auto client = find_client(evt->window);
|
||||||
if (client) {
|
if (client) {
|
||||||
|
133
src/x11/winspec.cpp
Normal file
133
src/x11/winspec.cpp
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
#include "x11/winspec.hpp"
|
||||||
|
|
||||||
|
POLYBAR_NS
|
||||||
|
|
||||||
|
winspec::winspec(connection& conn) : m_connection(conn) {}
|
||||||
|
winspec::winspec(connection& conn, const xcb_window_t& window) : m_connection(conn), m_window(window) {}
|
||||||
|
|
||||||
|
winspec::operator xcb_window_t() const {
|
||||||
|
return m_window;
|
||||||
|
}
|
||||||
|
winspec::operator xcb_rectangle_t() const {
|
||||||
|
return {m_x, m_y, m_width, m_height};
|
||||||
|
}
|
||||||
|
|
||||||
|
xcb_window_t winspec::operator<<(const cw_flush& f) {
|
||||||
|
uint32_t values[16]{0};
|
||||||
|
|
||||||
|
if (m_window == XCB_NONE)
|
||||||
|
m_window = m_connection.generate_id();
|
||||||
|
if (m_parent == XCB_NONE)
|
||||||
|
m_parent = m_connection.screen()->root;
|
||||||
|
|
||||||
|
if (m_width <= 0)
|
||||||
|
m_width = 1;
|
||||||
|
if (m_height <= 0)
|
||||||
|
m_height = 1;
|
||||||
|
|
||||||
|
xutils::pack_values(m_mask, &m_params, values);
|
||||||
|
|
||||||
|
if (f.checked) {
|
||||||
|
m_connection.create_window_checked(
|
||||||
|
m_depth, m_window, m_parent, m_x, m_y, m_width, m_height, m_border, m_class, m_visual, m_mask, values);
|
||||||
|
} else {
|
||||||
|
m_connection.create_window(
|
||||||
|
m_depth, m_window, m_parent, m_x, m_y, m_width, m_height, m_border, m_class, m_visual, m_mask, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_window;
|
||||||
|
}
|
||||||
|
|
||||||
|
winspec& winspec::operator<<(const cw_size& size) {
|
||||||
|
m_width = size.w;
|
||||||
|
m_height = size.h;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
winspec& winspec::operator<<(const cw_pos& p) {
|
||||||
|
m_x = p.x;
|
||||||
|
m_y = p.y;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
winspec& winspec::operator<<(const cw_border& b) {
|
||||||
|
m_border = b.border_width;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
winspec& winspec::operator<<(const cw_class& c) {
|
||||||
|
m_class = c.class_;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
winspec& winspec::operator<<(const cw_parent& p) {
|
||||||
|
m_parent = p.parent;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
winspec& winspec::operator<<(const cw_depth& d) {
|
||||||
|
m_depth = d.depth;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
winspec& winspec::operator<<(const cw_visual& v) {
|
||||||
|
m_visual = v.visualid;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
winspec& winspec::operator<<(const cw_params_back_pixel& p) {
|
||||||
|
XCB_AUX_ADD_PARAM(&m_mask, &m_params, back_pixel, p.value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
winspec& winspec::operator<<(const cw_params_back_pixmap& p) {
|
||||||
|
XCB_AUX_ADD_PARAM(&m_mask, &m_params, back_pixmap, p.value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
winspec& winspec::operator<<(const cw_params_backing_pixel& p) {
|
||||||
|
XCB_AUX_ADD_PARAM(&m_mask, &m_params, backing_pixel, p.value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
winspec& winspec::operator<<(const cw_params_backing_planes& p) {
|
||||||
|
XCB_AUX_ADD_PARAM(&m_mask, &m_params, backing_planes, p.value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
winspec& winspec::operator<<(const cw_params_backing_store& p) {
|
||||||
|
XCB_AUX_ADD_PARAM(&m_mask, &m_params, backing_store, p.value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
winspec& winspec::operator<<(const cw_params_bit_gravity& p) {
|
||||||
|
XCB_AUX_ADD_PARAM(&m_mask, &m_params, bit_gravity, p.value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
winspec& winspec::operator<<(const cw_params_border_pixel& p) {
|
||||||
|
XCB_AUX_ADD_PARAM(&m_mask, &m_params, border_pixel, p.value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
winspec& winspec::operator<<(const cw_params_border_pixmap& p) {
|
||||||
|
XCB_AUX_ADD_PARAM(&m_mask, &m_params, border_pixmap, p.value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
winspec& winspec::operator<<(const cw_params_colormap& p) {
|
||||||
|
XCB_AUX_ADD_PARAM(&m_mask, &m_params, colormap, p.value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
winspec& winspec::operator<<(const cw_params_cursor& p) {
|
||||||
|
XCB_AUX_ADD_PARAM(&m_mask, &m_params, cursor, p.value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
winspec& winspec::operator<<(const cw_params_dont_propagate& p) {
|
||||||
|
XCB_AUX_ADD_PARAM(&m_mask, &m_params, dont_propagate, p.value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
winspec& winspec::operator<<(const cw_params_event_mask& p) {
|
||||||
|
XCB_AUX_ADD_PARAM(&m_mask, &m_params, event_mask, p.value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
winspec& winspec::operator<<(const cw_params_override_redirect& p) {
|
||||||
|
XCB_AUX_ADD_PARAM(&m_mask, &m_params, override_redirect, p.value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
winspec& winspec::operator<<(const cw_params_save_under& p) {
|
||||||
|
XCB_AUX_ADD_PARAM(&m_mask, &m_params, save_under, p.value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
winspec& winspec::operator<<(const cw_params_win_gravity& p) {
|
||||||
|
XCB_AUX_ADD_PARAM(&m_mask, &m_params, win_gravity, p.value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
POLYBAR_NS_END
|
Loading…
Reference in New Issue
Block a user