diff --git a/cmake/build/core.cmake b/cmake/build/core.cmake index c2053628..0c442477 100644 --- a/cmake/build/core.cmake +++ b/cmake/build/core.cmake @@ -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) diff --git a/cmake/build/summary.cmake b/cmake/build/summary.cmake index 2a690e6f..af71bc52 100644 --- a/cmake/build/summary.cmake +++ b/cmake/build/summary.cmake @@ -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() diff --git a/include/common.hpp b/include/common.hpp index 8417cbdf..dcce0f53 100644 --- a/include/common.hpp +++ b/include/common.hpp @@ -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 diff --git a/include/components/controller.hpp b/include/components/controller.hpp index 8d1b801a..d071ce6e 100644 --- a/include/components/controller.hpp +++ b/include/components/controller.hpp @@ -79,6 +79,9 @@ class controller : public signal_receiver m_confwatch; unique_ptr m_command; + shared_ptr m_fdevent_rd; + shared_ptr m_fdevent_wr; + /** * @brief Controls weather the output gets printed to stdout */ diff --git a/include/modules/meta/event_module.hpp b/include/modules/meta/event_module.hpp index c26bbcd1..d40c92df 100644 --- a/include/modules/meta/event_module.hpp +++ b/include/modules/meta/event_module.hpp @@ -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; diff --git a/include/modules/meta/inotify_module.hpp b/include/modules/meta/inotify_module.hpp index 6e21692c..36149170 100644 --- a/include/modules/meta/inotify_module.hpp +++ b/include/modules/meta/inotify_module.hpp @@ -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 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(); } diff --git a/include/modules/meta/timer_module.hpp b/include/modules/meta/timer_module.hpp index 73f6cd59..2a95a72d 100644 --- a/include/modules/meta/timer_module.hpp +++ b/include/modules/meta/timer_module.hpp @@ -1,13 +1,9 @@ #pragma once -#include - #include "modules/meta/base.hpp" POLYBAR_NS -namespace chrono = std::chrono; - namespace modules { using interval_t = chrono::duration; @@ -21,27 +17,27 @@ namespace modules { } protected: - interval_t m_interval{1}; - void runner() { try { - while (CONST_MOD(Impl).running()) { - { - std::lock_guard guard(this->m_updatelock); + while (this->running()) { + std::unique_lock 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}; }; } diff --git a/include/utils/memory.hpp b/include/utils/memory.hpp index 32281264..f95cea34 100644 --- a/include/utils/memory.hpp +++ b/include/utils/memory.hpp @@ -6,15 +6,16 @@ POLYBAR_NS +template +using malloc_ptr_t = shared_ptr; + namespace memory_util { /** * Create a shared pointer using malloc/free */ - template - inline auto make_malloc_ptr(size_t size = sizeof(T), Deleter deleter = free) { - shared_ptr ptr{static_cast(malloc(size)), deleter}; - memset(ptr.get(), 0, size); - return ptr; + template + inline malloc_ptr_t make_malloc_ptr(Deleter deleter = free) { + return malloc_ptr_t(static_cast(calloc(1, Size)), deleter); } /** @@ -24,9 +25,6 @@ namespace memory_util { inline auto countof(T& p) { return sizeof(p) / sizeof(p[0]); } - - template - using malloc_ptr_t = shared_ptr; } POLYBAR_NS_END diff --git a/include/x11/connection.hpp b/include/x11/connection.hpp index 62774cb5..92305ac2 100644 --- a/include/x11/connection.hpp +++ b/include/x11/connection.hpp @@ -17,10 +17,9 @@ using xpp_connection = xpp::connection; 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&& evt) const; + void dispatch_event(const shared_ptr& evt) const; template - void wait_for_response(function check_event) { - shared_ptr evt; + void wait_for_response(function check_event) { + shared_ptr 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_poll_for_event(*this), free)) == nullptr) { continue; } else if (evt->response_type != ResponseType) { continue; - } else if (check_event(reinterpret_cast(*(evt.get())))) { + } else if (check_event(reinterpret_cast(&*evt))) { break; } } diff --git a/include/x11/draw.hpp b/include/x11/draw.hpp index 05f4650f..151fb485 100644 --- a/include/x11/draw.hpp +++ b/include/x11/draw.hpp @@ -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 diff --git a/include/x11/ewmh.hpp b/include/x11/ewmh.hpp index 7ec30e37..02d10a3c 100644 --- a/include/x11/ewmh.hpp +++ b/include/x11/ewmh.hpp @@ -9,7 +9,7 @@ POLYBAR_NS struct position; -using ewmh_connection_t = memory_util::malloc_ptr_t; +using ewmh_connection_t = malloc_ptr_t; namespace ewmh_util { ewmh_connection_t initialize(); diff --git a/include/x11/fonts.hpp b/include/x11/fonts.hpp index 2cdb50d7..69e86ad6 100644 --- a/include/x11/fonts.hpp +++ b/include/x11/fonts.hpp @@ -38,9 +38,7 @@ struct font_ref { vector width_lut{}; unordered_map 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; static make_type make(); - explicit font_manager( - connection& conn, const logger& logger, shared_ptr&& dsp, shared_ptr&& 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&& 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, xcb_gcontext_t, xcb_font_t*); - protected: bool open_xcb_font(const shared_ptr& font, string fontname); @@ -79,12 +74,14 @@ class font_manager { bool has_glyph_xft(const shared_ptr& font, const uint16_t chr); bool has_glyph_xcb(const shared_ptr& 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 m_display; - shared_ptr m_visual; + Display* m_display{nullptr}; + Visual* m_visual{nullptr}; Colormap m_colormap; map> m_fonts{}; diff --git a/include/x11/tray_client.hpp b/include/x11/tray_client.hpp index 6e3ffef8..8cdc2d35 100644 --- a/include/x11/tray_client.hpp +++ b/include/x11/tray_client.hpp @@ -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 m_xembed; -bool m_mapped{false}; + shared_ptr 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 diff --git a/include/x11/xlib.hpp b/include/x11/xlib.hpp index 6a44cf77..2644095a 100644 --- a/include/x11/xlib.hpp +++ b/include/x11/xlib.hpp @@ -7,23 +7,23 @@ POLYBAR_NS namespace xlib { - shared_ptr get_display(); - shared_ptr 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_lock(); - - protected: - shared_ptr m_display; - }; - inline auto make_display_lock(); } diff --git a/include/x11/xresources.hpp b/include/x11/xresources.hpp index d05b7c51..008fd279 100644 --- a/include/x11/xresources.hpp +++ b/include/x11/xresources.hpp @@ -12,7 +12,7 @@ class xresource_manager { using make_type = const xresource_manager&; static make_type make(); - explicit xresource_manager(shared_ptr&&); + 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 m_display; + Display* m_display{nullptr}; XrmDatabase m_db; char* m_manager{nullptr}; }; diff --git a/include/x11/xutils.hpp b/include/x11/xutils.hpp index a86108ed..790d8a66 100644 --- a/include/x11/xutils.hpp +++ b/include/x11/xutils.hpp @@ -17,8 +17,7 @@ namespace xutils { } }; - shared_ptr 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); diff --git a/src/components/controller.cpp b/src/components/controller.cpp index e91b22e7..234174c8 100644 --- a/src/components/controller.cpp +++ b/src/components/controller.cpp @@ -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(module)) != nullptr) { + if ((module_input_handler = dynamic_cast(&*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 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 evt{}; + while ((evt = shared_ptr(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()); + } } } diff --git a/src/components/ipc.cpp b/src/components/ipc.cpp index fe022def..f2061c61 100644 --- a/src/components/ipc.cpp +++ b/src/components/ipc.cpp @@ -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 diff --git a/src/components/parser.cpp b/src/components/parser.cpp index 076a133d..5e0255b6 100644 --- a/src/components/parser.cpp +++ b/src/components/parser.cpp @@ -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(&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((utf[0] & 0x1f) << 6 | (utf[1] & 0x3f))}); + m_sig.emit(write_text_unicode{static_cast(((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((utf[0] & 0xf) << 12 | (utf[1] & 0x3f) << 6 | (utf[2] & 0x3f))}); + m_sig.emit(write_text_unicode{static_cast(((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(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(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(0xfffd)}); return 6; } + // clang-format on if (utf[0] < 0x80) { m_sig.emit(write_text_ascii{utf[0]}); diff --git a/src/components/renderer.cpp b/src/components/renderer.cpp index 2604249e..627af684 100644 --- a/src/components/renderer.cpp +++ b/src/components/renderer.cpp @@ -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()); diff --git a/src/components/screen.cpp b/src/components/screen.cpp index 04a3316f..4f2bb1df 100644 --- a/src/components/screen.cpp +++ b/src/components/screen.cpp @@ -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([&](const evt& evt) -> bool { return evt.window == m_proxy; }); + m_connection.wait_for_response([&](const evt* evt) -> bool { return evt->window == m_proxy; }); m_connection.clear_event_mask(m_root); // Finally attach the sink the process randr events diff --git a/src/main.cpp b/src/main.cpp index e9fb1fb5..4a5c86b1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -47,14 +47,14 @@ int main(int argc, char** argv) { XInitThreads(); // Store the xcb connection pointer with a disconnect deleter - shared_ptr xcbconn{xutils::get_connection().get(), xutils::xcb_connection_deleter{}}; + shared_ptr 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(); diff --git a/src/modules/battery.cpp b/src/modules/battery.cpp index bc0b188f..f8be74ad 100644 --- a/src/modules/battery.cpp +++ b/src/modules/battery.cpp @@ -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(); } /** diff --git a/src/x11/connection.cpp b/src/x11/connection.cpp index 0174c8f0..7034466b 100644 --- a/src/x11/connection.cpp +++ b/src/x11/connection.cpp @@ -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( - *factory_util::singleton>(conn, conn_fd)); + *factory_util::singleton>(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 */ shared_ptr connection::make_client_message(xcb_atom_t type, xcb_window_t target) const { - auto client_message = memory_util::make_malloc_ptr(size_t{32}); + auto client_message = memory_util::make_malloc_ptr(); client_message->response_type = XCB_CLIENT_MESSAGE; client_message->format = 32; @@ -131,8 +128,7 @@ shared_ptr connection::make_client_message(xcb_atom_ */ void connection::send_client_message(const shared_ptr& message, xcb_window_t target, uint32_t event_mask, bool propagate) const { - const char* data = reinterpret_cast(message.get()); - send_event(propagate, target, event_mask, data); + send_event(propagate, target, event_mask, reinterpret_cast(&*message)); flush(); } @@ -184,8 +180,8 @@ string connection::error_str(int error_code) { /** * Dispatch event through the registry */ -void connection::dispatch_event(shared_ptr&& evt) const { - m_registry.dispatch(forward(evt)); +void connection::dispatch_event(const shared_ptr& evt) const { + m_registry.dispatch(evt); } POLYBAR_NS_END diff --git a/src/x11/draw.cpp b/src/x11/draw.cpp index 2864858f..4118f3d8 100644 --- a/src/x11/draw.cpp +++ b/src/x11/draw.cpp @@ -1,9 +1,5 @@ -#include - -#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(&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(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 diff --git a/src/x11/ewmh.cpp b/src/x11/ewmh.cpp index 9abcf6d0..2147b8d6 100644 --- a/src/x11/ewmh.cpp +++ b/src/x11/ewmh.cpp @@ -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( - 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* 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) { diff --git a/src/x11/fonts.cpp b/src/x11/fonts.cpp index 55dd44b9..1bfd4d62 100644 --- a/src/x11/fonts.cpp +++ b/src/x11/fonts.cpp @@ -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&& dsp, shared_ptr&& 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(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&& v) { - m_visual = forward(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, const uint16 void font_manager::drawtext(const shared_ptr& 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(calloc(num_chars, sizeof(uint16_t))); + vector 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, 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, 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, const ui } XGlyphInfo extents{}; - FT_UInt glyph{XftCharIndex(m_display.get(), font->xft, static_cast(chr))}; + FT_UInt glyph{XftCharIndex(m_display, font->xft, static_cast(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, const ui bool font_manager::has_glyph_xft(const shared_ptr& font, const uint16_t chr) { if (!font || font->xft == nullptr) { return false; - } else if (XftCharExists(m_display.get(), font->xft, static_cast(chr)) == FcFalse) { + } else if (XftCharExists(m_display, font->xft, static_cast(chr)) == FcFalse) { return false; } else { return true; @@ -298,4 +291,23 @@ bool font_manager::has_glyph_xcb(const shared_ptr& 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(&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(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 diff --git a/src/x11/tray_client.cpp b/src/x11/tray_client.cpp index 026759d3..e9b6b866 100644 --- a/src/x11/tray_client.cpp +++ b/src/x11/tray_client.cpp @@ -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(32); + auto notify = memory_util::make_malloc_ptr(); notify->response_type = XCB_CONFIGURE_NOTIFY; notify->event = m_window; notify->window = m_window; diff --git a/src/x11/tray_manager.cpp b/src/x11/tray_manager.cpp index 373eb92a..d87022e8 100644 --- a/src/x11/tray_manager.cpp +++ b/src/x11/tray_manager.cpp @@ -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..."); diff --git a/src/x11/xlib.cpp b/src/x11/xlib.cpp index 7bde195a..9740df7c 100644 --- a/src/x11/xlib.cpp +++ b/src/x11/xlib.cpp @@ -1,44 +1,43 @@ +#include + #include "x11/xlib.hpp" #include "utils/factory.hpp" POLYBAR_NS namespace xlib { - shared_ptr g_display_ptr; - shared_ptr g_visual_ptr; - - shared_ptr get_display() { - if (!g_display_ptr) { - g_display_ptr = shared_ptr(XOpenDisplay(nullptr), factory_util::null_deleter); + namespace detail { + display_lock::display_lock(Display* display) : m_display(forward(display)) { + XLockDisplay(m_display); + } + + display_lock::~display_lock() { + XUnlockDisplay(m_display); } - return g_display_ptr; } - shared_ptr 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; + if (!visual) { XVisualInfo info{}; - if (XMatchVisualInfo(get_display().get(), screen, depth, TrueColor, &info)) { - g_visual_ptr = shared_ptr(info.visual, [=](Visual* v) { XFree(v); }); + if (XMatchVisualInfo(get_display(), screen, depth, TrueColor, &info)) { + visual = shared_ptr(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) : m_display(forward(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(get_display()); + return make_unique(get_display()); } } diff --git a/src/x11/xresources.cpp b/src/x11/xresources.cpp index d6d96c98..54846c09 100644 --- a/src/x11/xresources.cpp +++ b/src/x11/xresources.cpp @@ -19,10 +19,10 @@ xresource_manager::make_type xresource_manager::make() { /** * Construct manager instance */ -xresource_manager::xresource_manager(shared_ptr&& dsp) : m_display(forward(dsp)) { +xresource_manager::xresource_manager(Display* dsp) : m_display(forward(dsp)) { XrmInitialize(); - if ((m_manager = XResourceManagerString(m_display.get())) != nullptr) { + if ((m_manager = XResourceManagerString(m_display)) != nullptr) { m_db = XrmGetStringDatabase(m_manager); } } diff --git a/src/x11/xutils.cpp b/src/x11/xutils.cpp index 660f4e58..7a48d96e 100644 --- a/src/x11/xutils.cpp +++ b/src/x11/xutils.cpp @@ -10,29 +10,13 @@ POLYBAR_NS namespace xutils { - shared_ptr g_connection_fd; - shared_ptr g_connection_ptr; - - shared_ptr get_connection() { - if (!g_connection_ptr) { - shared_ptr dsp{xlib::get_display()}; - - if (dsp) { - XSetEventQueueOwner(dsp.get(), XCBOwnsEventQueue); - g_connection_ptr = shared_ptr(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(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(32); + auto notify = memory_util::make_malloc_ptr(); notify->response_type = XCB_VISIBILITY_NOTIFY; notify->window = win; notify->state = state; - const char* data = reinterpret_cast(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(&*notify)); } void compton_shadow_exclude(connection& conn, const xcb_window_t& win) {