diff --git a/include/events/signal.hpp b/include/events/signal.hpp index cdad4bca..efcf755e 100644 --- a/include/events/signal.hpp +++ b/include/events/signal.hpp @@ -5,34 +5,18 @@ #include "components/ipc.hpp" #include "components/parser.hpp" #include "components/types.hpp" -#include "events/types.hpp" #include "utils/functional.hpp" POLYBAR_NS -// fwd decl {{{ - +// fwd enum class mousebtn : uint8_t; enum class syntaxtag : uint8_t; enum class alignment : uint8_t; enum class attribute : uint8_t; -// }}} - -#define DEFINE_SIGNAL(id, name) \ - struct name : public detail::base_signal { \ - using base_type::base_type; \ - } - -#define DEFINE_VALUE_SIGNAL(id, name, type) \ - struct name : public detail::value_signal { \ - using base_type::base_type; \ - } - namespace signals { namespace detail { - // definition : signal {{{ - class signal { public: explicit signal() = default; @@ -40,98 +24,161 @@ namespace signals { virtual size_t size() const = 0; }; - // }}} - // definition : base_signal {{{ - - template + template class base_signal : public signal { public: - using base_type = base_signal; + using base_type = base_signal; explicit base_signal() = default; - virtual ~base_signal() {} - static uint8_t id() { - return Id; - } - virtual size_t size() const override { return sizeof(Derived); }; }; - // }}} - // definition : value_signal {{{ - - template - class value_signal : public base_signal { + template + class value_signal : public base_signal { public: - using base_type = value_signal; + using base_type = value_signal; using value_type = ValueType; - explicit value_signal() {} - explicit value_signal(ValueType&& data) { - memcpy(m_data, &data, sizeof(data)); + template + explicit value_signal(void* data) : m_data(data), m_size(Size) {} + + template + explicit value_signal(ValueType data) : m_size(Size) { + m_data = new char[Size]; + m_alloced = true; + memcpy(m_data, static_cast(&data), Size); } - virtual ~value_signal() {} - - const ValueType* operator()() const { - return reinterpret_cast(&m_data); + virtual ~value_signal() { + if (m_alloced) { + delete[] static_cast(m_data); + } } - const ValueType* data() const { - return reinterpret_cast(&m_data); + + void* data() const { + return m_data; + } + size_t size() const { + return m_size; + } + inline ValueType cast() const { + return *static_cast(m_data); } private: - char m_data[sizeof(ValueType)]; + void* m_data; + size_t m_size; + bool m_alloced{false}; }; - - // }}} } namespace eventqueue { - DEFINE_SIGNAL(1, exit_terminate); - DEFINE_SIGNAL(2, exit_reload); - DEFINE_SIGNAL(3, notify_change); - DEFINE_SIGNAL(4, check_state); - DEFINE_SIGNAL(5, update); + struct exit_terminate : public detail::base_signal { + using base_type::base_type; + }; + struct exit_reload : public detail::base_signal { + using base_type::base_type; + }; + struct notify_change : public detail::base_signal { + using base_type::base_type; + }; + struct check_state : public detail::base_signal { + using base_type::base_type; + }; + struct update : public detail::base_signal { + using base_type::base_type; + }; } namespace ipc { - DEFINE_VALUE_SIGNAL(20, command, string); - DEFINE_VALUE_SIGNAL(21, hook, string); - DEFINE_VALUE_SIGNAL(22, action, string); + struct command : public detail::value_signal { + using base_type::base_type; + }; + struct hook : public detail::value_signal { + using base_type::base_type; + }; + struct action : public detail::value_signal { + using base_type::base_type; + }; } namespace ui { - DEFINE_SIGNAL(50, tick); - DEFINE_VALUE_SIGNAL(51, button_press, string); - DEFINE_VALUE_SIGNAL(52, visibility_change, bool); - DEFINE_VALUE_SIGNAL(53, dim_window, double); - DEFINE_SIGNAL(54, shade_window); - DEFINE_SIGNAL(55, unshade_window); + struct tick : public detail::base_signal { + using base_type::base_type; + }; + struct button_press : public detail::value_signal { + using base_type::base_type; + }; + struct visibility_change : public detail::value_signal { + using base_type::base_type; + }; + struct dim_window : public detail::value_signal { + using base_type::base_type; + }; + struct shade_window : public detail::base_signal { + using base_type::base_type; + }; + struct unshade_window : public detail::base_signal { + using base_type::base_type; + }; + } + + namespace ui_tray { + struct mapped_clients : public detail::value_signal { + using base_type::base_type; + }; } namespace parser { - using parser_t = polybar::parser; - - DEFINE_VALUE_SIGNAL(70, change_background, uint32_t); - DEFINE_VALUE_SIGNAL(71, change_foreground, uint32_t); - DEFINE_VALUE_SIGNAL(72, change_underline, uint32_t); - DEFINE_VALUE_SIGNAL(73, change_overline, uint32_t); - DEFINE_VALUE_SIGNAL(74, change_font, uint8_t); - DEFINE_VALUE_SIGNAL(75, change_alignment, alignment); - DEFINE_VALUE_SIGNAL(76, offset_pixel, int16_t); - DEFINE_VALUE_SIGNAL(77, attribute_set, attribute); - DEFINE_VALUE_SIGNAL(78, attribute_unset, attribute); - DEFINE_VALUE_SIGNAL(79, attribute_toggle, attribute); - DEFINE_VALUE_SIGNAL(80, action_begin, action); - DEFINE_VALUE_SIGNAL(81, action_end, mousebtn); - DEFINE_VALUE_SIGNAL(82, write_text_ascii, uint16_t); - DEFINE_VALUE_SIGNAL(83, write_text_unicode, uint16_t); - DEFINE_VALUE_SIGNAL(84, write_text_string, parser_t::packet); + struct change_background : public detail::value_signal { + using base_type::base_type; + }; + struct change_foreground : public detail::value_signal { + using base_type::base_type; + }; + struct change_underline : public detail::value_signal { + using base_type::base_type; + }; + struct change_overline : public detail::value_signal { + using base_type::base_type; + }; + struct change_font : public detail::value_signal { + using base_type::base_type; + }; + struct change_alignment : public detail::value_signal { + using base_type::base_type; + }; + struct offset_pixel : public detail::value_signal { + using base_type::base_type; + }; + struct attribute_set : public detail::value_signal { + using base_type::base_type; + }; + struct attribute_unset : public detail::value_signal { + using base_type::base_type; + }; + struct attribute_toggle : public detail::value_signal { + using base_type::base_type; + }; + struct action_begin : public detail::value_signal { + using base_type::base_type; + }; + struct action_end : public detail::value_signal { + using base_type::base_type; + }; + struct write_text_ascii : public detail::value_signal { + using base_type::base_type; + }; + struct write_text_unicode : public detail::value_signal { + using base_type::base_type; + }; + struct write_text_string : public detail::value_signal { + using base_type::base_type; + }; } } diff --git a/include/events/signal_emitter.hpp b/include/events/signal_emitter.hpp index 85fbbf1c..f651c6e4 100644 --- a/include/events/signal_emitter.hpp +++ b/include/events/signal_emitter.hpp @@ -2,8 +2,6 @@ #include "common.hpp" #include "events/signal_receiver.hpp" -#include "utils/factory.hpp" -#include "utils/mixins.hpp" POLYBAR_NS @@ -55,8 +53,8 @@ class signal_emitter { protected: template - uint8_t id() const { - return Signal::id(); + std::type_index id() const { + return typeid(Signal); } template @@ -70,7 +68,7 @@ class signal_emitter { attach(s); } - void attach(signal_receiver_interface* s, uint8_t id) { + void attach(signal_receiver_interface* s, std::type_index id) { g_signal_receivers[id].emplace(s->priority(), s); } @@ -85,7 +83,7 @@ class signal_emitter { detach(s); } - void detach(signal_receiver_interface* d, uint8_t id) { + void detach(signal_receiver_interface* d, std::type_index id) { try { auto& prio_map = g_signal_receivers.at(id); const auto& prio_sink_pair = prio_map.equal_range(d->priority()); diff --git a/include/events/signal_fwd.hpp b/include/events/signal_fwd.hpp index 10888b7c..2b331eea 100644 --- a/include/events/signal_fwd.hpp +++ b/include/events/signal_fwd.hpp @@ -4,10 +4,16 @@ POLYBAR_NS +class signal_emitter; +class signal_receiver_interface; template class signal_receiver; namespace signals { + namespace detail { + class signal; + } + namespace eventqueue { struct exit_terminate; struct exit_reload; @@ -28,6 +34,9 @@ namespace signals { struct shade_window; struct unshade_window; } + namespace ui_tray { + struct mapped_clients; + } namespace parser { struct change_background; struct change_foreground; diff --git a/include/events/signal_receiver.hpp b/include/events/signal_receiver.hpp index 3fa39d0c..2b584f13 100644 --- a/include/events/signal_receiver.hpp +++ b/include/events/signal_receiver.hpp @@ -2,6 +2,8 @@ #include #include +#include +#include #include "common.hpp" @@ -45,6 +47,6 @@ class signal_receiver : public signal_receiver_interface, } }; -using signal_receivers_t = std::unordered_map; +using signal_receivers_t = std::unordered_map; POLYBAR_NS_END diff --git a/src/components/bar.cpp b/src/components/bar.cpp index f6e45e45..96651f95 100644 --- a/src/components/bar.cpp +++ b/src/components/bar.cpp @@ -514,7 +514,7 @@ void bar::handle(const evt::leave_notify&) { if (!m_opts.dimmed) { m_taskqueue->defer_unique("window-dim", 3s, [&](size_t) { m_opts.dimmed = true; - m_sig.emit(dim_window{double{m_opts.dimvalue}}); + m_sig.emit(dim_window{m_opts.dimvalue}); }); } } @@ -722,8 +722,8 @@ bool bar::on(const sig_ui::tick&) { } bool bar::on(const sig_ui::dim_window& sig) { - m_opts.dimmed = *sig.data() != 1.0; - set_wm_window_opacity(m_connection, m_opts.window, *sig.data() * 0xFFFFFFFF); + m_opts.dimmed = sig.cast() != 1.0; + set_wm_window_opacity(m_connection, m_opts.window, sig.cast() * 0xFFFFFFFF); m_connection.flush(); return false; } diff --git a/src/components/controller.cpp b/src/components/controller.cpp index aada0aef..b408f79e 100644 --- a/src/components/controller.cpp +++ b/src/components/controller.cpp @@ -531,7 +531,7 @@ bool controller::on(const sig_ev::check_state&) { * Process ui button press event */ bool controller::on(const sig_ui::button_press& evt) { - string input{*evt()}; + string input{evt.cast()}; if (input.empty()) { m_log.err("Cannot enqueue empty input"); @@ -546,7 +546,7 @@ bool controller::on(const sig_ui::button_press& evt) { * Process ipc action messages */ bool controller::on(const sig_ipc::action& evt) { - string action{*evt()}; + string action{evt.cast()}; if (action.empty()) { m_log.err("Cannot enqueue empty ipc action"); @@ -562,7 +562,7 @@ bool controller::on(const sig_ipc::action& evt) { * Process ipc command messages */ bool controller::on(const sig_ipc::command& evt) { - string command{*evt()}; + string command{evt.cast()}; if (command.empty()) { return false; @@ -583,7 +583,7 @@ bool controller::on(const sig_ipc::command& evt) { * Process ipc hook messages */ bool controller::on(const sig_ipc::hook& evt) { - string hook{*evt()}; + string hook{evt.cast()}; for (const auto& block : m_modules) { for (const auto& module : block.second) { diff --git a/src/components/parser.cpp b/src/components/parser.cpp index 562140e8..04993cff 100644 --- a/src/components/parser.cpp +++ b/src/components/parser.cpp @@ -184,7 +184,7 @@ size_t parser::text(string&& data) { } pkt.length = len; - m_sig.emit(write_text_string{move(pkt)}); + m_sig.emit(write_text_string{static_cast(&pkt)}); } if (pos > 0) { diff --git a/src/components/renderer.cpp b/src/components/renderer.cpp index 1580c7fe..d906a9d4 100644 --- a/src/components/renderer.cpp +++ b/src/components/renderer.cpp @@ -530,7 +530,7 @@ void renderer::debug_hints() { #endif bool renderer::on(const change_background& evt) { - const uint32_t color{*evt()}; + const uint32_t color{evt.cast()}; if (m_colors[gc::BG] == color) { m_log.trace_x("renderer: ignoring unchanged background color(#%08x)", color); @@ -545,7 +545,7 @@ bool renderer::on(const change_background& evt) { } bool renderer::on(const change_foreground& evt) { - const uint32_t color{*evt()}; + const uint32_t color{evt.cast()}; if (m_colors[gc::FG] == color) { m_log.trace_x("renderer: ignoring unchanged foreground color(#%08x)", color); @@ -560,7 +560,7 @@ bool renderer::on(const change_foreground& evt) { } bool renderer::on(const change_underline& evt) { - const uint32_t color{*evt()}; + const uint32_t color{evt.cast()}; if (m_colors[gc::UL] == color) { m_log.trace_x("renderer: ignoring unchanged underline color(#%08x)", color); @@ -574,7 +574,7 @@ bool renderer::on(const change_underline& evt) { } bool renderer::on(const change_overline& evt) { - const uint32_t color{*evt()}; + const uint32_t color{evt.cast()}; if (m_colors[gc::OL] == color) { m_log.trace_x("renderer: ignoring unchanged overline color(#%08x)", color); @@ -588,7 +588,7 @@ bool renderer::on(const change_overline& evt) { } bool renderer::on(const change_font& evt) { - const uint8_t font{*evt()}; + const uint8_t font{evt.cast()}; if (m_fontindex == font) { m_log.trace_x("renderer: ignoring unchanged font index(%i)", static_cast(font)); @@ -602,7 +602,7 @@ bool renderer::on(const change_font& evt) { } bool renderer::on(const change_alignment& evt) { - auto align = static_cast(*evt()); + auto align = static_cast(evt.cast()); if (align == m_alignment) { m_log.trace_x("renderer: ignoring unchanged alignment(%i)", static_cast(align)); @@ -616,30 +616,30 @@ bool renderer::on(const change_alignment& evt) { } bool renderer::on(const offset_pixel& evt) { - shift_content(*evt()); + shift_content(evt.cast()); return true; } bool renderer::on(const attribute_set& evt) { - m_log.trace_x("renderer: attribute_set(%i, %i)", static_cast(*evt()), true); - m_attributes |= 1U << static_cast(*evt()); + m_log.trace_x("renderer: attribute_set(%i, %i)", static_cast(evt.cast()), true); + m_attributes |= 1U << static_cast(evt.cast()); return true; } bool renderer::on(const attribute_unset& evt) { - m_log.trace_x("renderer: attribute_unset(%i, %i)", static_cast(*evt()), true); - m_attributes &= ~(1U << static_cast(*evt())); + m_log.trace_x("renderer: attribute_unset(%i, %i)", static_cast(evt.cast()), true); + m_attributes &= ~(1U << static_cast(evt.cast())); return true; } bool renderer::on(const attribute_toggle& evt) { - m_log.trace_x("renderer: attribute_toggle(%i)", static_cast(*evt())); - m_attributes ^= 1U << static_cast(*evt()); + m_log.trace_x("renderer: attribute_toggle(%i)", static_cast(evt.cast())); + m_attributes ^= 1U << static_cast(evt.cast()); return true; } bool renderer::on(const action_begin& evt) { - auto a = static_cast(*evt()); + auto a = static_cast(evt.cast()); action_block action{}; action.button = a.button; action.align = m_alignment; @@ -658,7 +658,7 @@ bool renderer::on(const action_begin& evt) { } bool renderer::on(const action_end& evt) { - auto btn = static_cast(*evt()); + auto btn = static_cast(evt.cast()); int16_t clickable_width{0}; for (auto action = m_actions.rbegin(); action != m_actions.rend(); action++) { @@ -695,19 +695,19 @@ bool renderer::on(const action_end& evt) { } bool renderer::on(const write_text_ascii& evt) { - const uint16_t data[1]{*evt()}; + const uint16_t data[1]{evt.cast()}; draw_textstring(data, 1); return true; } bool renderer::on(const write_text_unicode& evt) { - const uint16_t data[1]{*evt()}; + const uint16_t data[1]{evt.cast()}; draw_textstring(data, 1); return true; } bool renderer::on(const write_text_string& evt) { - auto pkt = static_cast(*evt()); + auto pkt = *static_cast(evt.data()); draw_textstring(pkt.data, pkt.length); return true; } diff --git a/src/events/signal_emitter.cpp b/src/events/signal_emitter.cpp index 0a87b8d7..e153944b 100644 --- a/src/events/signal_emitter.cpp +++ b/src/events/signal_emitter.cpp @@ -1,4 +1,5 @@ #include "events/signal_emitter.hpp" +#include "utils/factory.hpp" POLYBAR_NS diff --git a/src/x11/tray_manager.cpp b/src/x11/tray_manager.cpp index 36912804..f39bd5e4 100644 --- a/src/x11/tray_manager.cpp +++ b/src/x11/tray_manager.cpp @@ -1093,10 +1093,11 @@ void tray_manager::handle(const evt::map_notify& evt) { m_log.trace("tray: Received map_notify"); m_log.trace("tray: Set client mapped"); find_client(evt->window)->mapped(true); - - if (mapped_clients() > m_opts.configured_slots) { + size_t clientcount{mapped_clients()}; + if (clientcount > m_opts.configured_slots) { reconfigure(); } + m_sig.emit(signals::ui_tray::mapped_clients{clientcount}); } } @@ -1111,7 +1112,8 @@ void tray_manager::handle(const evt::unmap_notify& evt) { } else if (m_activated && is_embedded(evt->window)) { m_log.trace("tray: Received unmap_notify"); m_log.trace("tray: Set client unmapped"); - find_client(evt->window)->mapped(true); + find_client(evt->window)->mapped(false); + m_sig.emit(signals::ui_tray::mapped_clients{mapped_clients()}); } } @@ -1121,7 +1123,7 @@ void tray_manager::handle(const evt::unmap_notify& evt) { * toggle the tray window whenever the visibility of the bar window changes. */ bool tray_manager::on(const visibility_change& evt) { - bool visible{*evt()}; + bool visible{evt.cast()}; size_t clients{mapped_clients()}; m_log.trace("tray: visibility_change (state=%i, activated=%i, mapped=%i, hidden=%i)", visible, @@ -1146,7 +1148,7 @@ bool tray_manager::on(const visibility_change& evt) { bool tray_manager::on(const dim_window& evt) { if (m_activated) { - wm_util::set_wm_window_opacity(m_connection, m_tray, *evt.data() * 0xFFFFFFFF); + wm_util::set_wm_window_opacity(m_connection, m_tray, evt.cast() * 0xFFFFFFFF); m_connection.flush(); } // let the event bubble