refactor: Cleanup

This commit is contained in:
Michael Carlberg 2016-12-21 23:22:02 +01:00
parent 185363056a
commit bc9b9f0d12
32 changed files with 276 additions and 311 deletions

View File

@ -70,3 +70,18 @@ endif()
if(NOT DEFINED CMAKE_INSTALL_INCLUDEDIR)
set(CMAKE_INSTALL_INCLUDEDIR include)
endif()
# Custom build type ; SANITIZE
SET(CMAKE_CXX_FLAGS_SANITIZE "-O1 -g -fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls"
CACHE STRING "Flags used by the C++ compiler during sanitize builds." FORCE)
SET(CMAKE_C_FLAGS_SANITIZE ""
CACHE STRING "Flags used by the C compiler during sanitize builds." FORCE)
SET(CMAKE_EXE_LINKER_FLAGS_SANITIZE ""
CACHE STRING "Flags used for linking binaries during sanitize builds." FORCE)
SET(CMAKE_SHARED_LINKER_FLAGS_SANITIZE ""
CACHE STRING "Flags used by the shared libraries linker during sanitize builds." FORCE)
MARK_AS_ADVANCED(
CMAKE_CXX_FLAGS_SANITIZE
CMAKE_C_FLAGS_SANITIZE
CMAKE_EXE_LINKER_FLAGS_SANITIZE
CMAKE_SHARED_LINKER_FLAGS_SANITIZE)

View File

@ -17,7 +17,8 @@ message(STATUS " Compiler C: ${CMAKE_C_COMPILER}")
message(STATUS " Compiler C++: ${CMAKE_CXX_COMPILER}")
message(STATUS " Compiler flags: ${CMAKE_CXX_FLAGS}")
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER)
if(CMAKE_BUILD_TYPE_LOWER STREQUAL "debug")
message(STATUS " debug flags: ${CMAKE_CXX_FLAGS_DEBUG}")
if(NOT DEFINED ${DEBUG_LOGGER})
set(DEBUG_LOGGER ON)
@ -25,11 +26,13 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug")
if(NOT DEFINED ${ENABLE_CCACHE})
set(ENABLE_CCACHE ON)
endif()
elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
elseif(CMAKE_BUILD_TYPE_LOWER STREQUAL "release")
message(STATUS " release: ${CMAKE_CXX_FLAGS_RELEASE}")
elseif(CMAKE_BUILD_TYPE STREQUAL "MinSizeRel")
elseif(CMAKE_BUILD_TYPE_LOWER STREQUAL "sanitize")
message(STATUS " sanitize: ${CMAKE_CXX_FLAGS_SANITIZE}")
elseif(CMAKE_BUILD_TYPE_LOWER STREQUAL "minsizerel")
message(STATUS " minsizerel: ${CMAKE_CXX_FLAGS_MINSIZEREL}")
elseif(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
elseif(CMAKE_BUILD_TYPE_LOWER STREQUAL "relwithdebinfo")
message(STATUS " relwithdebinfo: ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
endif()

View File

@ -48,4 +48,8 @@ using std::array;
using std::vector;
using std::to_string;
constexpr size_t operator"" _z(unsigned long long n) {
return n;
}
POLYBAR_NS_END

View File

@ -79,6 +79,9 @@ class controller : public signal_receiver<SIGN_PRIORITY_CONTROLLER, sig_ev::proc
unique_ptr<inotify_watch> m_confwatch;
unique_ptr<command> m_command;
shared_ptr<file_descriptor> m_fdevent_rd;
shared_ptr<file_descriptor> m_fdevent_wr;
/**
* @brief Controls weather the output gets printed to stdout
*/

View File

@ -20,15 +20,15 @@ namespace modules {
// Warm up module output and
// send broadcast before entering
// the update loop
if (CONST_MOD(Impl).running()) {
if (this->running()) {
CAST_MOD(Impl)->update();
CAST_MOD(Impl)->broadcast();
}
while (CONST_MOD(Impl).running()) {
while (this->running()) {
CAST_MOD(Impl)->idle();
if (!CONST_MOD(Impl).running()) {
if (!this->running()) {
break;
}
@ -36,7 +36,7 @@ namespace modules {
if (!CAST_MOD(Impl)->has_event()) {
continue;
} else if (!CONST_MOD(Impl).running()) {
} else if (!this->running()) {
break;
} else if (!CAST_MOD(Impl)->update()) {
continue;

View File

@ -21,12 +21,12 @@ namespace modules {
// Warm up module output and
// send broadcast before entering
// the update loop
if (CONST_MOD(Impl).running()) {
if (this->running()) {
CAST_MOD(Impl)->on_event(nullptr);
CAST_MOD(Impl)->broadcast();
}
while (CONST_MOD(Impl).running()) {
while (this->running()) {
CAST_MOD(Impl)->poll_events();
}
} catch (const module_error& err) {
@ -37,7 +37,7 @@ namespace modules {
}
void watch(string path, int mask = IN_ALL_EVENTS) {
this->m_log.trace("%s: Attach inotify at %s", CONST_MOD(Impl).name(), path);
this->m_log.trace("%s: Attach inotify at %s", this->name(), path);
m_watchlist.insert(make_pair(path, mask));
}
@ -55,39 +55,39 @@ namespace modules {
}
} catch (const system_error& e) {
watches.clear();
this->m_log.err("%s: Error while creating inotify watch (what: %s)", CONST_MOD(Impl).name(), e.what());
this->m_log.err("%s: Error while creating inotify watch (what: %s)", this->name(), e.what());
CAST_MOD(Impl)->sleep(0.1s);
return;
}
while (CONST_MOD(Impl).running()) {
while (this->running()) {
std::unique_lock<std::mutex> guard(this->m_updatelock);
{
for (auto&& w : watches) {
this->m_log.trace_x("%s: Poll inotify watch %s", CONST_MOD(Impl).name(), w->path());
if (w->poll(1000 / watches.size())) {
auto event = w->get_event();
for (auto&& w : watches) {
this->m_log.trace_x("%s: Poll inotify watch %s", this->name(), w->path());
for (auto&& w : watches) {
try {
w->remove();
} catch (const system_error&) {
}
if (w->poll(1000 / watches.size())) {
auto event = w->get_event();
for (auto&& w : watches) {
try {
w->remove();
} catch (const system_error&) {
// ignore
}
if (CAST_MOD(Impl)->on_event(event.get()))
CAST_MOD(Impl)->broadcast();
CAST_MOD(Impl)->idle();
return;
}
if (!CONST_MOD(Impl).running())
break;
if (CAST_MOD(Impl)->on_event(event.get())) {
CAST_MOD(Impl)->broadcast();
}
CAST_MOD(Impl)->idle();
return;
}
if (!this->running())
break;
}
guard.unlock();
CAST_MOD(Impl)->idle();
}

View File

@ -1,13 +1,9 @@
#pragma once
#include <chrono>
#include "modules/meta/base.hpp"
POLYBAR_NS
namespace chrono = std::chrono;
namespace modules {
using interval_t = chrono::duration<double>;
@ -21,27 +17,27 @@ namespace modules {
}
protected:
interval_t m_interval{1};
void runner() {
try {
while (CONST_MOD(Impl).running()) {
{
std::lock_guard<std::mutex> guard(this->m_updatelock);
while (this->running()) {
std::unique_lock<std::mutex> guard(this->m_updatelock);
if (CAST_MOD(Impl)->update())
this->broadcast();
if (CAST_MOD(Impl)->update()) {
this->broadcast();
}
if (CONST_MOD(Impl).running()) {
if (this->running()) {
guard.unlock();
this->sleep(m_interval);
}
}
} catch (const module_error& err) {
this->halt(err.what());
} catch (const std::exception& err) {
} catch (const exception& err) {
this->halt(err.what());
}
}
protected:
interval_t m_interval{1};
};
}

View File

@ -6,15 +6,16 @@
POLYBAR_NS
template <typename T>
using malloc_ptr_t = shared_ptr<T>;
namespace memory_util {
/**
* Create a shared pointer using malloc/free
*/
template <typename T, typename Deleter = decltype(free)>
inline auto make_malloc_ptr(size_t size = sizeof(T), Deleter deleter = free) {
shared_ptr<T> ptr{static_cast<T*>(malloc(size)), deleter};
memset(ptr.get(), 0, size);
return ptr;
template <typename T, size_t Size = sizeof(T), typename Deleter = decltype(free)>
inline malloc_ptr_t<T> make_malloc_ptr(Deleter deleter = free) {
return malloc_ptr_t<T>(static_cast<T*>(calloc(1, Size)), deleter);
}
/**
@ -24,9 +25,6 @@ namespace memory_util {
inline auto countof(T& p) {
return sizeof(p) / sizeof(p[0]);
}
template <typename T>
using malloc_ptr_t = shared_ptr<T>;
}
POLYBAR_NS_END

View File

@ -17,10 +17,9 @@ using xpp_connection = xpp::connection<XPP_EXTENSION_LIST>;
class connection : public xpp_connection {
public:
using make_type = connection&;
static make_type make(xcb_connection_t* conn = nullptr, int conn_fd = 0);
explicit connection(xcb_connection_t* conn) : connection(conn, 0) {}
static make_type make(xcb_connection_t* conn = nullptr);
explicit connection(xcb_connection_t* conn) : xpp_connection(conn) {}
explicit connection(xcb_connection_t* conn, int connection_fd)
: xpp_connection(conn), m_connection_fd(file_util::make_file_descriptor(connection_fd)) {}
@ -49,11 +48,11 @@ class connection : public xpp_connection {
static string error_str(int error_code);
void dispatch_event(shared_ptr<xcb_generic_event_t>&& evt) const;
void dispatch_event(const shared_ptr<xcb_generic_event_t>& evt) const;
template <typename Event, uint32_t ResponseType>
void wait_for_response(function<bool(const Event&)> check_event) {
shared_ptr<xcb_generic_event_t> evt;
void wait_for_response(function<bool(const Event*)> check_event) {
shared_ptr<xcb_generic_event_t> evt{};
while (!connection_has_error()) {
fd_set fds;
FD_ZERO(&fds);
@ -61,11 +60,11 @@ class connection : public xpp_connection {
if (!select(*m_connection_fd + 1, &fds, nullptr, nullptr, nullptr)) {
continue;
} else if ((evt = poll_for_event()) == nullptr) {
} else if ((evt = shared_ptr<xcb_generic_event_t>(xcb_poll_for_event(*this), free)) == nullptr) {
continue;
} else if (evt->response_type != ResponseType) {
continue;
} else if (check_event(reinterpret_cast<const Event&>(*(evt.get())))) {
} else if (check_event(reinterpret_cast<const Event*>(&*evt))) {
break;
}
}

View File

@ -6,14 +6,9 @@
POLYBAR_NS
class connection;
namespace draw_util {
void fill(xcb_connection_t* c, xcb_drawable_t d, xcb_gcontext_t g, const xcb_rectangle_t rect);
void fill(xcb_connection_t* c, 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_gcontext_t gc, int16_t x, int16_t y, uint8_t len, uint16_t* str);
}
POLYBAR_NS_END

View File

@ -9,7 +9,7 @@ POLYBAR_NS
struct position;
using ewmh_connection_t = memory_util::malloc_ptr_t<xcb_ewmh_connection_t>;
using ewmh_connection_t = malloc_ptr_t<xcb_ewmh_connection_t>;
namespace ewmh_util {
ewmh_connection_t initialize();

View File

@ -38,9 +38,7 @@ struct font_ref {
vector<xcb_charinfo_t> width_lut{};
unordered_map<uint16_t, wchar_t> glyph_widths{};
static struct _deleter {
void operator()(font_ref* font);
} deleter;
static struct _deleter { void operator()(font_ref* font); } deleter;
};
class font_manager {
@ -48,14 +46,13 @@ class font_manager {
using make_type = unique_ptr<font_manager>;
static make_type make();
explicit font_manager(
connection& conn, const logger& logger, shared_ptr<Display>&& dsp, shared_ptr<Visual>&& vis, Colormap&& cm);
explicit font_manager(connection& conn, const logger& logger, Display* dsp, Visual* vis, Colormap&& cm);
~font_manager();
font_manager(const font_manager& o) = delete;
font_manager& operator=(const font_manager& o) = delete;
void set_visual(shared_ptr<Visual>&& v);
void set_visual(Visual* v);
void cleanup();
bool load(const string& name, uint8_t fontindex = 0, int8_t offset_y = 0);
@ -68,8 +65,6 @@ class font_manager {
void allocate_color(uint32_t color);
void allocate_color(XRenderColor color);
void set_gcontext_font(const shared_ptr<font_ref>& font, xcb_gcontext_t, xcb_font_t*);
protected:
bool open_xcb_font(const shared_ptr<font_ref>& font, string fontname);
@ -79,12 +74,14 @@ class font_manager {
bool has_glyph_xft(const shared_ptr<font_ref>& font, const uint16_t chr);
bool has_glyph_xcb(const shared_ptr<font_ref>& font, const uint16_t chr);
void xcb_poly_text_16(xcb_drawable_t d, xcb_gcontext_t gc, int16_t x, int16_t y, uint8_t len, uint16_t* str);
private:
connection& m_connection;
const logger& m_logger;
shared_ptr<Display> m_display;
shared_ptr<Visual> m_visual;
Display* m_display{nullptr};
Visual* m_visual{nullptr};
Colormap m_colormap;
map<uint8_t, shared_ptr<font_ref>> m_fonts{};

View File

@ -17,33 +17,32 @@ class tray_client {
tray_client(const tray_client& c) = default;
tray_client& operator=(tray_client& c) = default;
~tray_client();
~tray_client();
uint16_t width() const;
uint16_t height() const;
void clear_window() const;
uint16_t width() const;
uint16_t height() const;
void clear_window() const;
bool match(const xcb_window_t& win) const;
bool mapped() const;
void mapped(bool state);
bool match(const xcb_window_t& win) const;
bool mapped() const;
void mapped(bool state);
xcb_window_t window() const;
xembed_data* xembed() const;
xcb_window_t window() const;
xembed_data* xembed() const;
void ensure_state() const;
void reconfigure(int16_t x, int16_t y) const;
void configure_notify(int16_t x, int16_t y) const;
void ensure_state() const;
void reconfigure(int16_t x, int16_t y) const;
void configure_notify(int16_t x, int16_t y) const;
protected:
connection& m_connection;
xcb_window_t m_window{0};
protected:
connection& m_connection;
xcb_window_t m_window{0};
shared_ptr<xembed_data> m_xembed;
bool m_mapped{false};
shared_ptr<xembed_data> m_xembed;
bool m_mapped{false};
uint16_t m_width;
uint16_t m_height;
}
;
uint16_t m_width;
uint16_t m_height;
};
POLYBAR_NS_END

View File

@ -7,23 +7,23 @@
POLYBAR_NS
namespace xlib {
shared_ptr<Display> get_display();
shared_ptr<Visual> get_visual(int screen = 0, uint8_t depth = 32);
namespace detail {
/**
* RAII wrapper for Xlib display locking
*/
class display_lock {
public:
explicit display_lock(Display* display);
~display_lock();
protected:
Display* m_display;
};
}
Display* get_display();
Visual* get_visual(int screen = 0, uint8_t depth = 32);
Colormap create_colormap(int screen = 0);
/**
* RAII wrapper for Xlib display locking
*/
class display_lock {
public:
explicit display_lock(shared_ptr<Display>&& display);
~display_lock();
protected:
shared_ptr<Display> m_display;
};
inline auto make_display_lock();
}

View File

@ -12,7 +12,7 @@ class xresource_manager {
using make_type = const xresource_manager&;
static make_type make();
explicit xresource_manager(shared_ptr<Display>&&);
explicit xresource_manager(Display*);
~xresource_manager();
xresource_manager(const xresource_manager& o) = delete;
@ -26,7 +26,7 @@ class xresource_manager {
string load_value(const string& key, const string& res_type, size_t n) const;
private:
shared_ptr<Display> m_display;
Display* m_display{nullptr};
XrmDatabase m_db;
char* m_manager{nullptr};
};

View File

@ -17,8 +17,7 @@ namespace xutils {
}
};
shared_ptr<xcb_connection_t> get_connection();
int get_connection_fd();
xcb_connection_t* get_connection();
void pack_values(uint32_t mask, const uint32_t* src, uint32_t* dest);
void pack_values(uint32_t mask, const xcb_params_cw_t* src, uint32_t* dest);

View File

@ -62,6 +62,9 @@ controller::controller(connection& conn, signal_emitter& emitter, const logger&
throw system_error("Failed to create event channel pipes");
}
m_fdevent_rd = file_util::make_file_descriptor(g_eventpipe[PIPE_READ]);
m_fdevent_wr = file_util::make_file_descriptor(g_eventpipe[PIPE_WRITE]);
m_log.trace("controller: Install signal handler");
struct sigaction act {};
memset(&act, 0, sizeof(act));
@ -99,18 +102,13 @@ controller::controller(connection& conn, signal_emitter& emitter, const logger&
throw application_error("Inter-process messaging needs to be enabled");
}
auto module = make_module(move(type), m_bar->settings(), module_name);
module->set_update_cb([&] { enqueue(make_update_evt(false)); });
module->set_stop_cb([&] { enqueue(make_check_evt()); });
m_modules[align].emplace_back(make_module(move(type), m_bar->settings(), module_name));
input_handler* module_input_handler{nullptr};
if ((module_input_handler = dynamic_cast<input_handler*>(module)) != nullptr) {
if ((module_input_handler = dynamic_cast<input_handler*>(&*m_modules[align].back())) != nullptr) {
m_sig.attach(module_input_handler);
}
m_modules[align].emplace_back(move(module));
created_modules++;
} catch (const runtime_error& err) {
m_log.err("Disabling module \"%s\" (reason: %s)", module_name, err.what());
@ -157,7 +155,6 @@ bool controller::run(bool writeback) {
m_writeback = writeback;
m_log.info("Starting application");
m_sig.attach(this);
size_t started_modules{0};
for (const auto& block : m_modules) {
@ -165,6 +162,8 @@ bool controller::run(bool writeback) {
try {
m_log.info("Starting %s", module->name());
module->start();
module->set_update_cb([&] { enqueue(make_update_evt(false)); });
module->set_stop_cb([&] { enqueue(make_check_evt()); });
started_modules++;
} catch (const application_error& err) {
m_log.err("Failed to start '%s' (reason: %s)", module->name(), err.what());
@ -178,6 +177,8 @@ bool controller::run(bool writeback) {
m_connection.flush();
m_sig.attach(this);
read_events();
m_log.warn("Termination signal received, shutting down...");
@ -218,14 +219,13 @@ bool controller::enqueue(string&& input_data) {
* Read events from configured file descriptors
*/
void controller::read_events() {
int fd_connection{m_connection.get_file_descriptor()};
int fd_confwatch{0};
int fd_connection{0};
int fd_event{0};
int fd_ipc{0};
vector<int> fds;
fds.emplace_back((fd_event = g_eventpipe[PIPE_READ]));
fds.emplace_back((fd_connection = m_connection.get_file_descriptor()));
fds.emplace_back(*m_fdevent_rd);
fds.emplace_back(fd_connection);
if (m_confwatch) {
m_log.trace("controller: Attach config watch");
@ -237,6 +237,8 @@ void controller::read_events() {
fds.emplace_back((fd_ipc = m_ipc->get_file_descriptor()));
}
m_sig.emit(sig_ev::process_update{make_update_evt(true)});
while (!g_terminate) {
fd_set readfds{};
FD_ZERO(&readfds);
@ -256,10 +258,10 @@ void controller::read_events() {
}
// Process event on the internal fd
if (fd_event && FD_ISSET(fd_event, &readfds)) {
if (m_fdevent_rd && FD_ISSET(*m_fdevent_rd, &readfds)) {
process_eventqueue();
char buffer[BUFSIZ]{'\0'};
if (read(fd_event, &buffer, BUFSIZ) == -1) {
if (read(*m_fdevent_rd, &buffer, BUFSIZ) == -1) {
m_log.err("Failed to read from eventpipe (err: %s)", strerror(errno));
}
}
@ -273,12 +275,15 @@ void controller::read_events() {
// Process event on the xcb connection fd
if (fd_connection && FD_ISSET(fd_connection, &readfds)) {
try {
m_connection.dispatch_event(m_connection.wait_for_event());
} catch (xpp::connection_error& err) {
m_log.err("X connection error, terminating... (what: %s)", m_connection.error_str(err.code()));
} catch (const exception& err) {
m_log.err("Error in X event loop: %s", err.what());
shared_ptr<xcb_generic_event_t> evt{};
while ((evt = shared_ptr<xcb_generic_event_t>(xcb_poll_for_event(m_connection), free)) != nullptr) {
try {
m_connection.dispatch_event(evt);
} catch (xpp::connection_error& err) {
m_log.err("X connection error, terminating... (what: %s)", m_connection.error_str(err.code()));
} catch (const exception& err) {
m_log.err("Error in X event loop: %s", err.what());
}
}
}

View File

@ -40,6 +40,8 @@ ipc::ipc(signal_emitter& emitter, const logger& logger) : m_sig(emitter), m_log(
* Deconstruct ipc handler
*/
ipc::~ipc() {
m_fd.reset();
if (!m_path.empty()) {
m_log.trace("ipc: Removing file handle");
unlink(m_path.c_str());
@ -55,7 +57,7 @@ void ipc::receive_message() {
char buffer[BUFSIZ]{'\0'};
ssize_t bytes_read{0};
if ((bytes_read = read(*m_fd.get(), &buffer, BUFSIZ)) == -1) {
if ((bytes_read = read(*m_fd, &buffer, BUFSIZ)) == -1) {
m_log.err("Failed to read from ipc channel (err: %s)", strerror(errno));
}
@ -88,7 +90,7 @@ void ipc::receive_message() {
* Get the file descriptor to the ipc channel
*/
int ipc::get_file_descriptor() const {
return *m_fd.get();
return *m_fd;
}
POLYBAR_NS_END

View File

@ -164,6 +164,7 @@ void parser::codeblock(string&& data, const bar_settings& bar) {
size_t parser::text(string&& data) {
const uint8_t* utf{reinterpret_cast<const uint8_t*>(&data[0])};
// clang-format off
if (utf[0] < 0x80) {
size_t pos{0};
@ -188,23 +189,27 @@ size_t parser::text(string&& data) {
if (pos > 0) {
return pos;
}
} else if ((utf[0] & 0xe0) == 0xc0) { // 2 byte utf-8 sequence
m_sig.emit(write_text_unicode{static_cast<uint16_t>((utf[0] & 0x1f) << 6 | (utf[1] & 0x3f))});
m_sig.emit(write_text_unicode{static_cast<uint16_t>(((utf[0] & 0x1f) << 6) | (utf[1] & 0x3f))});
return 2;
} else if ((utf[0] & 0xf0) == 0xe0) { // 3 byte utf-8 sequence
m_sig.emit(
write_text_unicode{static_cast<uint16_t>((utf[0] & 0xf) << 12 | (utf[1] & 0x3f) << 6 | (utf[2] & 0x3f))});
m_sig.emit(write_text_unicode{static_cast<uint16_t>(((utf[0] & 0x0f) << 12) | ((utf[1] & 0x3f) << 6) | (utf[2] & 0x3f))});
return 3;
} else if ((utf[0] & 0xf8) == 0xf0) { // 4 byte utf-8 sequence
// m_sig.emit(write_text_unicode{((utf[0] & 0x07) << 18) | ((utf[1] & 0x3f) << 12) | ((utf[2] & 0x3f) << 6) | (utf[3] & 0x3f)});
m_sig.emit(write_text_unicode{static_cast<uint16_t>(0xfffd)});
return 4;
} else if ((utf[0] & 0xfc) == 0xf8) { // 5 byte utf-8 sequence
// m_sig.emit(write_text_unicode{((utf[0] & 0x03) << 24) | ((utf[1] & 0x3f) << 18) | ((utf[2] & 0x3f) << 12) | ((utf[3] & 0x3f) << 6) | (utf[4] & 0x3f)});
m_sig.emit(write_text_unicode{static_cast<uint16_t>(0xfffd)});
return 5;
} else if ((utf[0] & 0xfe) == 0xfc) { // 6 byte utf-8 sequence
// m_sig.emit(write_text_unicode{((utf[0] & 0x01) << 30) | ((utf[1] & 0x3f) << 24) | ((utf[2] & 0x3f) << 18) | ((utf[3] & 0x3f) << 12) | ((utf[4] & 0x3f) << 6) | (utf[5] & 0x3f)});
m_sig.emit(write_text_unicode{static_cast<uint16_t>(0xfffd)});
return 6;
}
// clang-format on
if (utf[0] < 0x80) {
m_sig.emit(write_text_ascii{utf[0]});

View File

@ -404,7 +404,9 @@ void renderer::draw_textstring(const uint16_t* text, size_t len) {
auto y = m_rect.height / 2 + font->height / 2 - font->descent + font->offset_y;
if (font->ptr != XCB_NONE && m_gcfont != font->ptr) {
m_fontmanager->set_gcontext_font(font, m_gcontexts.at(gc::FG), &m_gcfont);
const uint32_t v[1]{font->ptr};
m_connection.change_gc(m_gcontexts.at(gc::FG), XCB_GC_FONT, v);
m_gcfont = font->ptr;
}
m_fontmanager->drawtext(font, m_pixmap, m_gcontexts.at(gc::FG), x, y, chars.data(), chars.size());

View File

@ -58,7 +58,7 @@ screen::screen(connection& conn, signal_emitter& emitter, const logger& logger,
// Wait until the proxy window has been mapped
using evt = xcb_map_notify_event_t;
m_connection.wait_for_response<evt, XCB_MAP_NOTIFY>([&](const evt& evt) -> bool { return evt.window == m_proxy; });
m_connection.wait_for_response<evt, XCB_MAP_NOTIFY>([&](const evt* evt) -> bool { return evt->window == m_proxy; });
m_connection.clear_event_mask(m_root);
// Finally attach the sink the process randr events

View File

@ -47,14 +47,14 @@ int main(int argc, char** argv) {
XInitThreads();
// Store the xcb connection pointer with a disconnect deleter
shared_ptr<xcb_connection_t> xcbconn{xutils::get_connection().get(), xutils::xcb_connection_deleter{}};
shared_ptr<xcb_connection_t> xcbconn{xutils::get_connection(), xutils::xcb_connection_deleter{}};
if (!xcbconn) {
logger.err("A connection to X could not be established... ");
return EXIT_FAILURE;
}
connection& conn{connection::make(xcbconn.get())};
connection& conn{connection::make(&*xcbconn)};
conn.preload_atoms();
conn.query_extensions();

View File

@ -114,7 +114,7 @@ namespace modules {
* charging animation when the module is started
*/
void battery_module::start() {
inotify_module::start();
this->inotify_module::start();
m_threads.emplace_back(thread(&battery_module::subthread, this));
}
@ -145,7 +145,7 @@ namespace modules {
}
}
inotify_module::idle();
this->inotify_module::idle();
}
/**

View File

@ -13,15 +13,12 @@ POLYBAR_NS
/**
* Create instance
*/
connection::make_type connection::make(xcb_connection_t* conn, int conn_fd) {
connection::make_type connection::make(xcb_connection_t* conn) {
if (conn == nullptr) {
conn = xutils::get_connection().get();
}
if (conn_fd == 0) {
conn_fd = xutils::get_connection_fd();
conn = &*xutils::get_connection();
}
return static_cast<connection::make_type>(
*factory_util::singleton<std::remove_reference_t<connection::make_type>>(conn, conn_fd));
*factory_util::singleton<std::remove_reference_t<connection::make_type>>(conn, xcb_get_file_descriptor(conn)));
}
/**
@ -109,7 +106,7 @@ void connection::clear_event_mask(xcb_window_t win) {
* Creates an instance of shared_ptr<xcb_client_message_event_t>
*/
shared_ptr<xcb_client_message_event_t> connection::make_client_message(xcb_atom_t type, xcb_window_t target) const {
auto client_message = memory_util::make_malloc_ptr<xcb_client_message_event_t>(size_t{32});
auto client_message = memory_util::make_malloc_ptr<xcb_client_message_event_t, 32_z>();
client_message->response_type = XCB_CLIENT_MESSAGE;
client_message->format = 32;
@ -131,8 +128,7 @@ shared_ptr<xcb_client_message_event_t> connection::make_client_message(xcb_atom_
*/
void connection::send_client_message(const shared_ptr<xcb_client_message_event_t>& message, xcb_window_t target,
uint32_t event_mask, bool propagate) const {
const char* data = reinterpret_cast<decltype(data)>(message.get());
send_event(propagate, target, event_mask, data);
send_event(propagate, target, event_mask, reinterpret_cast<const char*>(&*message));
flush();
}
@ -184,8 +180,8 @@ string connection::error_str(int error_code) {
/**
* Dispatch event through the registry
*/
void connection::dispatch_event(shared_ptr<xcb_generic_event_t>&& evt) const {
m_registry.dispatch(forward<decltype(evt)>(evt));
void connection::dispatch_event(const shared_ptr<xcb_generic_event_t>& evt) const {
m_registry.dispatch(evt);
}
POLYBAR_NS_END

View File

@ -1,9 +1,5 @@
#include <xcb/xcbext.h>
#include "utils/string.hpp"
#include "x11/color.hpp"
#include "x11/connection.hpp"
#include "x11/draw.hpp"
#include "x11/connection.hpp"
POLYBAR_NS
@ -21,44 +17,6 @@ namespace draw_util {
void fill(xcb_connection_t* c, xcb_drawable_t d, xcb_gcontext_t g, int16_t x, int16_t y, uint16_t w, uint16_t h) {
fill(c, d, g, {x, y, w, h});
}
/**
* The xcb version of this function does not compose the correct request
*
* Code: http://wmdia.sourceforge.net/
*/
xcb_void_cookie_t xcb_poly_text_16_patched(
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 = {
5, // count
nullptr, // ext
XCB_POLY_TEXT_16, // opcode
1 // isvoid
};
struct iovec xcb_parts[7];
uint8_t xcb_lendelta[2];
xcb_void_cookie_t xcb_ret{};
xcb_poly_text_8_request_t xcb_out{};
xcb_out.pad0 = 0;
xcb_out.drawable = d;
xcb_out.gc = gc;
xcb_out.x = x;
xcb_out.y = y;
xcb_lendelta[0] = len;
xcb_lendelta[1] = 0;
xcb_parts[2].iov_base = reinterpret_cast<char*>(&xcb_out);
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = nullptr;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
xcb_parts[4].iov_base = xcb_lendelta;
xcb_parts[4].iov_len = sizeof(xcb_lendelta);
xcb_parts[5].iov_base = reinterpret_cast<char*>(str);
xcb_parts[5].iov_len = len * sizeof(int16_t);
xcb_parts[6].iov_base = nullptr;
xcb_parts[6].iov_len = -(xcb_parts[4].iov_len + xcb_parts[5].iov_len) & 3;
xcb_ret.sequence = xcb_send_request(conn, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
}
POLYBAR_NS_END

View File

@ -5,18 +5,15 @@
POLYBAR_NS
namespace ewmh_util {
ewmh_connection_t g_ewmh_connection{nullptr};
ewmh_connection_t g_connection{nullptr};
ewmh_connection_t initialize() {
if (!g_ewmh_connection) {
g_ewmh_connection = memory_util::make_malloc_ptr<xcb_ewmh_connection_t>(
sizeof(xcb_ewmh_connection_t), [=](xcb_ewmh_connection_t* c) { xcb_ewmh_connection_wipe(c); });
auto* conn = g_ewmh_connection.get();
xcb_ewmh_init_atoms_replies(conn, xcb_ewmh_init_atoms(xutils::get_connection().get(), conn), nullptr);
if (!g_connection) {
g_connection = memory_util::make_malloc_ptr<xcb_ewmh_connection_t>(
[=](xcb_ewmh_connection_t* c) { xcb_ewmh_connection_wipe(c); });
xcb_ewmh_init_atoms_replies(
&*g_connection, xcb_ewmh_init_atoms(xutils::get_connection(), &*g_connection), nullptr);
}
return g_ewmh_connection;
return g_connection;
}
bool supports(xcb_ewmh_connection_t* ewmh, xcb_atom_t atom, int screen) {

View File

@ -18,10 +18,10 @@ void font_ref::_deleter::operator()(font_ref* font) {
font->width_lut.clear();
if (font->xft != nullptr) {
XftFontClose(xlib::get_display().get(), font->xft);
XftFontClose(&*xlib::get_display(), font->xft);
}
if (font->ptr != XCB_NONE) {
xcb_close_font(xutils::get_connection().get(), font->ptr);
xcb_close_font(&*xutils::get_connection(), font->ptr);
}
delete font;
}
@ -34,8 +34,7 @@ font_manager::make_type font_manager::make() {
connection::make(), logger::make(), xlib::get_display(), xlib::get_visual(), xlib::create_colormap());
}
font_manager::font_manager(
connection& conn, const logger& logger, shared_ptr<Display>&& dsp, shared_ptr<Visual>&& vis, Colormap&& cm)
font_manager::font_manager(connection& conn, const logger& logger, Display* dsp, Visual* vis, Colormap&& cm)
: m_connection(conn)
, m_logger(logger)
, m_display(forward<decltype(dsp)>(dsp))
@ -50,14 +49,14 @@ font_manager::~font_manager() {
cleanup();
if (m_display) {
if (m_xftcolor_allocated) {
XftColorFree(m_display.get(), m_visual.get(), m_colormap, &m_xftcolor);
XftColorFree(m_display, m_visual, m_colormap, &m_xftcolor);
}
XFreeColormap(m_display.get(), m_colormap);
XFreeColormap(m_display, m_colormap);
}
}
void font_manager::set_visual(shared_ptr<Visual>&& v) {
m_visual = forward<decltype(v)>(v);
void font_manager::set_visual(Visual* v) {
m_visual = v;
}
void font_manager::cleanup() {
@ -90,7 +89,7 @@ bool font_manager::load(const string& name, uint8_t fontindex, int8_t offset_y)
}
if (font->ptr == XCB_NONE &&
(font->xft = XftFontOpenName(m_display.get(), m_connection.default_screen(), name.c_str())) != nullptr) {
(font->xft = XftFontOpenName(m_display, m_connection.default_screen(), name.c_str())) != nullptr) {
font->ascent = font->xft->ascent;
font->descent = font->xft->descent;
font->height = font->ascent + font->descent;
@ -174,16 +173,16 @@ uint8_t font_manager::glyph_width(const shared_ptr<font_ref>& font, const uint16
void font_manager::drawtext(const shared_ptr<font_ref>& font, xcb_pixmap_t pm, xcb_gcontext_t gc, int16_t x, int16_t y,
const uint16_t* chars, size_t num_chars) {
if (m_xftdraw == nullptr) {
m_xftdraw = XftDrawCreate(m_display.get(), pm, m_visual.get(), m_colormap);
m_xftdraw = XftDrawCreate(m_display, pm, m_visual, m_colormap);
}
if (font->xft != nullptr) {
XftDrawString16(m_xftdraw, &m_xftcolor, font->xft, x, y, chars, num_chars);
} else if (font->ptr != XCB_NONE) {
uint16_t* ucs = static_cast<uint16_t*>(calloc(num_chars, sizeof(uint16_t)));
vector<uint16_t> ucs(num_chars);
for (size_t i = 0; i < num_chars; i++) {
ucs[i] = ((chars[i] >> 8) | (chars[i] << 8));
ucs[i] = (chars[i] >> 8) | (chars[i] << 8);
}
draw_util::xcb_poly_text_16_patched(m_connection, pm, gc, x, y, num_chars, ucs);
xcb_poly_text_16(pm, gc, x, y, num_chars, ucs.data());
}
}
@ -200,20 +199,14 @@ void font_manager::allocate_color(uint32_t color) {
void font_manager::allocate_color(XRenderColor color) {
if (m_xftcolor_allocated) {
XftColorFree(m_display.get(), m_visual.get(), m_colormap, &m_xftcolor);
XftColorFree(m_display, m_visual, m_colormap, &m_xftcolor);
}
if (!(m_xftcolor_allocated = XftColorAllocValue(m_display.get(), m_visual.get(), m_colormap, &color, &m_xftcolor))) {
if (!(m_xftcolor_allocated = XftColorAllocValue(m_display, m_visual, m_colormap, &color, &m_xftcolor))) {
m_logger.err("Failed to allocate color");
}
}
void font_manager::set_gcontext_font(const shared_ptr<font_ref>& font, xcb_gcontext_t gc, xcb_font_t* xcb_font) {
const uint32_t val[1]{*xcb_font};
m_connection.change_gc(gc, XCB_GC_FONT, val);
*xcb_font = font->ptr;
}
bool font_manager::open_xcb_font(const shared_ptr<font_ref>& font, string fontname) {
try {
uint32_t font_id{m_connection.generate_id()};
@ -253,11 +246,11 @@ uint8_t font_manager::glyph_width_xft(const shared_ptr<font_ref>& font, const ui
}
XGlyphInfo extents{};
FT_UInt glyph{XftCharIndex(m_display.get(), font->xft, static_cast<FcChar32>(chr))};
FT_UInt glyph{XftCharIndex(m_display, font->xft, static_cast<FcChar32>(chr))};
XftFontLoadGlyphs(m_display.get(), font->xft, FcFalse, &glyph, 1);
XftGlyphExtents(m_display.get(), font->xft, &glyph, 1, &extents);
XftFontUnloadGlyphs(m_display.get(), font->xft, &glyph, 1);
XftFontLoadGlyphs(m_display, font->xft, FcFalse, &glyph, 1);
XftGlyphExtents(m_display, font->xft, &glyph, 1, &extents);
XftFontUnloadGlyphs(m_display, font->xft, &glyph, 1);
font->glyph_widths.emplace_hint(it, chr, extents.xOff); //.emplace_back(chr, extents.xOff);
@ -277,7 +270,7 @@ uint8_t font_manager::glyph_width_xcb(const shared_ptr<font_ref>& font, const ui
bool font_manager::has_glyph_xft(const shared_ptr<font_ref>& font, const uint16_t chr) {
if (!font || font->xft == nullptr) {
return false;
} else if (XftCharExists(m_display.get(), font->xft, static_cast<FcChar32>(chr)) == FcFalse) {
} else if (XftCharExists(m_display, font->xft, static_cast<FcChar32>(chr)) == FcFalse) {
return false;
} else {
return true;
@ -298,4 +291,23 @@ bool font_manager::has_glyph_xcb(const shared_ptr<font_ref>& font, const uint16_
}
}
void font_manager::xcb_poly_text_16(
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 = {5, nullptr, XCB_POLY_TEXT_16, 1};
xcb_poly_text_16_request_t req{XCB_POLY_TEXT_16, 0, len, d, gc, x, y};
uint8_t xcb_lendelta[2]{len, 0};
struct iovec xcb_parts[7]{};
xcb_parts[2].iov_base = reinterpret_cast<char*>(&req);
xcb_parts[2].iov_len = sizeof(req);
xcb_parts[3].iov_base = nullptr;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
xcb_parts[4].iov_base = xcb_lendelta;
xcb_parts[4].iov_len = sizeof(xcb_lendelta);
xcb_parts[5].iov_base = reinterpret_cast<char*>(str);
xcb_parts[5].iov_len = len * sizeof(int16_t);
xcb_parts[6].iov_base = nullptr;
xcb_parts[6].iov_len = -(xcb_parts[4].iov_len + xcb_parts[5].iov_len) & 3;
xcb_send_request(m_connection, 0, xcb_parts + 2, &xcb_req);
}
POLYBAR_NS_END

View File

@ -103,7 +103,7 @@ void tray_client::reconfigure(int16_t x, int16_t y) const {
* Respond to client resize requests
*/
void tray_client::configure_notify(int16_t x, int16_t y) const {
auto notify = memory_util::make_malloc_ptr<xcb_configure_notify_event_t>(32);
auto notify = memory_util::make_malloc_ptr<xcb_configure_notify_event_t, 32_z>();
notify->response_type = XCB_CONFIGURE_NOTIFY;
notify->event = m_window;
notify->window = m_window;

View File

@ -222,13 +222,16 @@ void tray_manager::activate() {
// notify clients waiting for a manager.
acquire_selection();
if (!m_acquired_selection) {
deactivate();
return;
}
// Send delayed notification
if (!m_firstactivation) {
notify_clients_delayed();
} else if (m_othermanager != XCB_NONE && m_othermanager != m_tray) {
notify_clients_delayed();
} else {
notify_clients();
} else {
notify_clients_delayed();
}
m_firstactivation = false;
@ -679,7 +682,6 @@ void tray_manager::set_tray_colors() {
*/
void tray_manager::acquire_selection() {
m_othermanager = XCB_NONE;
;
xcb_window_t owner;
try {
@ -691,21 +693,17 @@ void tray_manager::acquire_selection() {
if (owner == m_tray) {
m_log.trace("tray: Already managing the systray selection");
m_acquired_selection = true;
return;
} else if ((m_othermanager = owner) != XCB_NONE) {
m_log.warn("Systray selection already managed (window=%s)", m_connection.id(owner));
track_selection_owner(m_othermanager);
} else {
m_log.trace("tray: Change selection owner to %s", m_connection.id(m_tray));
m_connection.set_selection_owner_checked(m_tray, m_atom, XCB_CURRENT_TIME);
if (m_connection.get_selection_owner_unchecked(m_atom)->owner != m_tray) {
throw application_error("Failed to get control of the systray selection");
}
m_acquired_selection = true;
}
if ((m_othermanager = owner) != XCB_NONE) {
m_log.info("Replacing selection manager %s", m_connection.id(owner));
}
m_log.trace("tray: Change selection owner to %s", m_connection.id(m_tray));
m_connection.set_selection_owner_checked(m_tray, m_atom, XCB_CURRENT_TIME);
if (m_connection.get_selection_owner_unchecked(m_atom)->owner != m_tray) {
throw application_error("Failed to get control of the systray selection");
}
m_acquired_selection = true;
}
/**
@ -1072,7 +1070,7 @@ void tray_manager::handle(const evt::destroy_notify& evt) {
if (m_activated && evt->window == m_tray) {
deactivate();
} else if (!m_activated && evt->window == m_othermanager) {
m_log.info("Tray selection available... re-activating");
m_log.info("Systray selection unmanaged... re-activating");
activate();
} else if (m_activated && is_embedded(evt->window)) {
m_log.trace("tray: Received destroy_notify for client, remove...");

View File

@ -1,44 +1,43 @@
#include <X11/X.h>
#include "x11/xlib.hpp"
#include "utils/factory.hpp"
POLYBAR_NS
namespace xlib {
shared_ptr<Display> g_display_ptr;
shared_ptr<Visual> g_visual_ptr;
shared_ptr<Display> get_display() {
if (!g_display_ptr) {
g_display_ptr = shared_ptr<Display>(XOpenDisplay(nullptr), factory_util::null_deleter);
namespace detail {
display_lock::display_lock(Display* display) : m_display(forward<decltype(display)>(display)) {
XLockDisplay(m_display);
}
display_lock::~display_lock() {
XUnlockDisplay(m_display);
}
return g_display_ptr;
}
shared_ptr<Visual> get_visual(int screen, uint8_t depth) {
if (!g_visual_ptr) {
Display* get_display() {
static Display* display{XOpenDisplay(nullptr)};
return display;
}
Visual* get_visual(int screen, uint8_t depth) {
static shared_ptr<Visual> visual;
if (!visual) {
XVisualInfo info{};
if (XMatchVisualInfo(get_display().get(), screen, depth, TrueColor, &info)) {
g_visual_ptr = shared_ptr<Visual>(info.visual, [=](Visual* v) { XFree(v); });
if (XMatchVisualInfo(get_display(), screen, depth, TrueColor, &info)) {
visual = shared_ptr<Visual>(info.visual, [=](Visual* v) { XFree(v); });
}
}
return g_visual_ptr;
return &*visual;
}
Colormap create_colormap(int screen) {
return XDefaultColormap(get_display().get(), screen);
}
display_lock::display_lock(shared_ptr<Display>&& display) : m_display(forward<decltype(display)>(display)) {
XLockDisplay(m_display.get());
}
display_lock::~display_lock() {
XUnlockDisplay(m_display.get());
return XDefaultColormap(get_display(), screen);
}
inline auto make_display_lock() {
return make_unique<display_lock>(get_display());
return make_unique<detail::display_lock>(get_display());
}
}

View File

@ -19,10 +19,10 @@ xresource_manager::make_type xresource_manager::make() {
/**
* Construct manager instance
*/
xresource_manager::xresource_manager(shared_ptr<Display>&& dsp) : m_display(forward<decltype(dsp)>(dsp)) {
xresource_manager::xresource_manager(Display* dsp) : m_display(forward<decltype(dsp)>(dsp)) {
XrmInitialize();
if ((m_manager = XResourceManagerString(m_display.get())) != nullptr) {
if ((m_manager = XResourceManagerString(m_display)) != nullptr) {
m_db = XrmGetStringDatabase(m_manager);
}
}

View File

@ -10,29 +10,13 @@
POLYBAR_NS
namespace xutils {
shared_ptr<int> g_connection_fd;
shared_ptr<xcb_connection_t> g_connection_ptr;
shared_ptr<xcb_connection_t> get_connection() {
if (!g_connection_ptr) {
shared_ptr<Display> dsp{xlib::get_display()};
if (dsp) {
XSetEventQueueOwner(dsp.get(), XCBOwnsEventQueue);
g_connection_ptr = shared_ptr<xcb_connection_t>(XGetXCBConnection(dsp.get()), factory_util::null_deleter);
}
xcb_connection_t* get_connection() {
static xcb_connection_t* connection;
if (!connection) {
XSetEventQueueOwner(xlib::get_display(), XCBOwnsEventQueue);
connection = XGetXCBConnection(xlib::get_display());
}
return g_connection_ptr;
}
int get_connection_fd() {
if (!g_connection_fd) {
auto fd = xcb_get_file_descriptor(get_connection().get());
g_connection_fd = shared_ptr<int>(new int{fd}, factory_util::fd_deleter);
}
return *g_connection_fd.get();
return connection;
}
void pack_values(uint32_t mask, const uint32_t* src, uint32_t* dest) {
@ -56,12 +40,11 @@ namespace xutils {
}
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);
auto notify = memory_util::make_malloc_ptr<xcb_visibility_notify_event_t, 32_z>();
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);
conn.send_event(true, win, XCB_EVENT_MASK_NO_EVENT, reinterpret_cast<const char*>(&*notify));
}
void compton_shadow_exclude(connection& conn, const xcb_window_t& win) {