diff --git a/include/components/builder.hpp b/include/components/builder.hpp index ebf63f49..5cd8c89c 100644 --- a/include/components/builder.hpp +++ b/include/components/builder.hpp @@ -154,7 +154,7 @@ class builder { if (!label || !*label) return; - auto text = label->m_text; + auto text = label->get(); if (label->m_maxlen > 0 && text.length() > label->m_maxlen) { text = text.substr(0, label->m_maxlen) + "..."; diff --git a/include/components/types.hpp b/include/components/types.hpp index c1d66167..4b2f44dc 100644 --- a/include/components/types.hpp +++ b/include/components/types.hpp @@ -105,4 +105,7 @@ struct action_block { #endif }; +struct wmsettings_bspwm { +}; + LEMONBUDDY_NS_END diff --git a/include/drawtypes/label.hpp b/include/drawtypes/label.hpp index cf283f23..f12386b0 100644 --- a/include/drawtypes/label.hpp +++ b/include/drawtypes/label.hpp @@ -14,23 +14,21 @@ namespace drawtypes { class label : public non_copyable_mixin<label> { public: - string m_text{""}; - string m_foreground{""}; - string m_background{""}; - string m_underline{""}; - string m_overline{""}; - int m_font{0}; - int m_padding{0}; - int m_margin{0}; - size_t m_maxlen{0}; - bool m_ellipsis{true}; + string m_foreground; + string m_background; + string m_underline; + string m_overline; + int m_font = 0; + int m_padding = 0; + int m_margin = 0; + size_t m_maxlen = 0; + bool m_ellipsis = true; - explicit label(string text, int font) : m_text(text), m_font(font) {} + explicit label(string text, int font) : m_font(font), m_text(text), m_tokenized(m_text) {} explicit label(string text, string foreground = "", string background = "", string underline = "", string overline = "", int font = 0, int padding = 0, int margin = 0, size_t maxlen = 0, bool ellipsis = true) - : m_text(text) - , m_foreground(foreground) + : m_foreground(foreground) , m_background(background) , m_underline(underline) , m_overline(overline) @@ -38,7 +36,13 @@ namespace drawtypes { , m_padding(padding) , m_margin(margin) , m_maxlen(maxlen) - , m_ellipsis(ellipsis) {} + , m_ellipsis(ellipsis) + , m_text(text) + , m_tokenized(m_text) {} + + string get() const { + return m_tokenized; + } operator bool() { return !m_text.empty(); @@ -49,8 +53,12 @@ namespace drawtypes { m_padding, m_margin, m_maxlen, m_ellipsis)}; } + void reset_tokens() { + m_tokenized = m_text; + } + void replace_token(string token, string replacement) { - m_text = string_util::replace_all(m_text, token, replacement); + m_tokenized = string_util::replace_all(m_tokenized, token, replacement); } void replace_defined_values(label_t label) { @@ -63,6 +71,9 @@ namespace drawtypes { if (!label->m_overline.empty()) m_overline = label->m_overline; } + + private: + string m_text, m_tokenized; }; inline label_t get_config_label(const config& conf, string section, string name = "label", diff --git a/include/modules/backlight.hpp b/include/modules/backlight.hpp index c4a6a94f..6a5ba6e0 100644 --- a/include/modules/backlight.hpp +++ b/include/modules/backlight.hpp @@ -27,9 +27,6 @@ namespace modules { if (m_formatter->has(TAG_RAMP)) m_ramp = get_config_ramp(m_conf, name(), TAG_RAMP); - if (m_label) - m_tokenized = m_label->clone(); - // Build path to the file where the current/maximum brightness value is located m_path_val = string_util::replace(PATH_BACKLIGHT_VAL, "%card%", card); m_path_max = string_util::replace(PATH_BACKLIGHT_MAX, "%card%", card); @@ -55,22 +52,21 @@ namespace modules { m_percentage = static_cast<int>(float(m_val) / float(m_max) * 100.0f + 0.5f); - if (!m_label) - return true; - - m_tokenized->m_text = m_label->m_text; - m_tokenized->replace_token("%percentage%", to_string(m_percentage) + "%"); + if (m_label) { + m_label->reset_tokens(); + m_label->replace_token("%percentage%", to_string(m_percentage) + "%"); + } return true; } - bool build(builder* builder, string tag) { + bool build(builder* builder, string tag) const { if (tag == TAG_BAR) builder->node(m_progressbar->output(m_percentage)); else if (tag == TAG_RAMP) builder->node(m_ramp->get_by_percentage(m_percentage)); else if (tag == TAG_LABEL) - builder->node(m_tokenized); + builder->node(m_label); else return false; return true; @@ -87,7 +83,6 @@ namespace modules { ramp_t m_ramp; label_t m_label; - label_t m_tokenized; progressbar_t m_progressbar; string m_path_val; diff --git a/include/modules/battery.hpp b/include/modules/battery.hpp index bf0c3175..0c648026 100644 --- a/include/modules/battery.hpp +++ b/include/modules/battery.hpp @@ -57,16 +57,13 @@ namespace modules { if (m_formatter->has(TAG_LABEL_CHARGING, FORMAT_CHARGING)) { m_label_charging = get_optional_config_label(m_conf, name(), TAG_LABEL_CHARGING, "%percentage%"); - m_label_charging_tokenized = m_label_charging->clone(); } if (m_formatter->has(TAG_LABEL_DISCHARGING, FORMAT_DISCHARGING)) { m_label_discharging = get_optional_config_label(m_conf, name(), TAG_LABEL_DISCHARGING, "%percentage%"); - m_label_discharging_tokenized = m_label_discharging->clone(); } if (m_formatter->has(TAG_LABEL_FULL, FORMAT_FULL)) { m_label_full = get_optional_config_label(m_conf, name(), TAG_LABEL_FULL, "%percentage%"); - m_label_full_tokenized = m_label_full->clone(); } // }}} @@ -124,17 +121,17 @@ namespace modules { return false; } - if (m_label_charging_tokenized) { - m_label_charging_tokenized->m_text = m_label_charging->m_text; - m_label_charging_tokenized->replace_token("%percentage%", to_string(percentage) + "%"); + if (m_label_charging) { + m_label_charging->reset_tokens(); + m_label_charging->replace_token("%percentage%", to_string(percentage) + "%"); } - if (m_label_discharging_tokenized) { - m_label_discharging_tokenized->m_text = m_label_discharging->m_text; - m_label_discharging_tokenized->replace_token("%percentage%", to_string(percentage) + "%"); + if (m_label_discharging) { + m_label_discharging->reset_tokens(); + m_label_discharging->replace_token("%percentage%", to_string(percentage) + "%"); } - if (m_label_full_tokenized) { - m_label_full_tokenized->m_text = m_label_full->m_text; - m_label_full_tokenized->replace_token("%percentage%", to_string(percentage) + "%"); + if (m_label_full) { + m_label_full->reset_tokens(); + m_label_full->replace_token("%percentage%", to_string(percentage) + "%"); } m_state = state; @@ -143,7 +140,7 @@ namespace modules { return true; } - string get_format() { + string get_format() const { if (m_state == STATE_FULL) return FORMAT_FULL; else if (m_state == STATE_CHARGING) @@ -152,7 +149,7 @@ namespace modules { return FORMAT_DISCHARGING; } - bool build(builder* builder, string tag) { + bool build(builder* builder, string tag) const { if (tag == TAG_ANIMATION_CHARGING) builder->node(m_animation_charging->get()); else if (tag == TAG_BAR_CAPACITY) { @@ -160,11 +157,11 @@ namespace modules { } else if (tag == TAG_RAMP_CAPACITY) builder->node(m_ramp_capacity->get_by_percentage(m_percentage)); else if (tag == TAG_LABEL_CHARGING) - builder->node(m_label_charging_tokenized); + builder->node(m_label_charging); else if (tag == TAG_LABEL_DISCHARGING) - builder->node(m_label_discharging_tokenized); + builder->node(m_label_discharging); else if (tag == TAG_LABEL_FULL) - builder->node(m_label_full_tokenized); + builder->node(m_label_full); else return false; return true; @@ -222,11 +219,8 @@ namespace modules { ramp_t m_ramp_capacity; progressbar_t m_bar_capacity; label_t m_label_charging; - label_t m_label_charging_tokenized; label_t m_label_discharging; - label_t m_label_discharging_tokenized; label_t m_label_full; - label_t m_label_full_tokenized; string m_battery; string m_adapter; diff --git a/include/modules/bspwm.hpp b/include/modules/bspwm.hpp index b63b2915..050a8a14 100644 --- a/include/modules/bspwm.hpp +++ b/include/modules/bspwm.hpp @@ -269,8 +269,9 @@ namespace modules { if (!monitor_focused) label->replace_defined_values(m_statelabels.find(bspwm_flag::WORKSPACE_DIMMED)->second); + label->reset_tokens(); label->replace_token("%name%", value); - label->replace_token("%icon%", icon->m_text); + label->replace_token("%icon%", icon->get()); label->replace_token("%index%", to_string(++workspace_n)); m_workspaces.emplace_back(make_unique<bspwm_workspace>(workspace_flag, std::move(label))); @@ -286,14 +287,14 @@ namespace modules { return true; } - bool build(builder* builder, string tag) { + bool build(builder* builder, string tag) const { if (tag != TAG_LABEL_STATE) return false; int workspace_n = 0; for (auto&& ws : m_workspaces) { - if (!ws.get()->label->m_text.empty()) + if (!ws.get()->label->get().empty()) builder->cmd(mousebtn::LEFT, string(EVENT_CLICK) + to_string(++workspace_n)); builder->node(ws.get()->label); @@ -302,7 +303,7 @@ namespace modules { for (auto&& mode : m_modes) builder->node(mode); } - if (!ws.get()->label->m_text.empty()) + if (!ws.get()->label->get().empty()) builder->cmd_close(true); } diff --git a/include/modules/counter.hpp b/include/modules/counter.hpp index 4179ebc5..64a488ac 100644 --- a/include/modules/counter.hpp +++ b/include/modules/counter.hpp @@ -21,7 +21,7 @@ namespace modules { return true; } - bool build(builder* builder, string tag) { + bool build(builder* builder, string tag) const { if (tag == TAG_COUNTER) { builder->node(to_string(m_counter)); return true; diff --git a/include/modules/cpu.hpp b/include/modules/cpu.hpp index f197d143..1c0df5a4 100644 --- a/include/modules/cpu.hpp +++ b/include/modules/cpu.hpp @@ -37,10 +37,8 @@ namespace modules { m_rampload = get_config_ramp(m_conf, name(), TAG_RAMP_LOAD); if (m_formatter->has(TAG_RAMP_LOAD_PER_CORE)) m_rampload_core = get_config_ramp(m_conf, name(), TAG_RAMP_LOAD_PER_CORE); - if (m_formatter->has(TAG_LABEL)) { + if (m_formatter->has(TAG_LABEL)) m_label = get_optional_config_label(m_conf, name(), TAG_LABEL, "%percentage%"); - m_tokenized = m_label->clone(); - } // warmup read_values(); @@ -67,18 +65,17 @@ namespace modules { m_total = m_total / static_cast<float>(cores_n); - if (m_tokenized) { - m_tokenized->m_text = m_label->m_text; - m_tokenized->replace_token( - "%percentage%", to_string(static_cast<int>(m_total + 0.5f)) + "%"); + if (m_label) { + m_label->reset_tokens(); + m_label->replace_token("%percentage%", to_string(static_cast<int>(m_total + 0.5f)) + "%"); } return true; } - bool build(builder* builder, string tag) { + bool build(builder* builder, string tag) const { if (tag == TAG_LABEL) - builder->node(m_tokenized); + builder->node(m_label); else if (tag == TAG_BAR_LOAD) builder->node(m_barload->output(m_total)); else if (tag == TAG_RAMP_LOAD) @@ -127,7 +124,7 @@ namespace modules { return !m_cputimes.empty(); } - float get_load(size_t core) { + float get_load(size_t core) const { if (m_cputimes.empty() || m_cputimes_prev.empty()) return 0; else if (core >= m_cputimes.size() || core >= m_cputimes_prev.size()) @@ -159,7 +156,6 @@ namespace modules { ramp_t m_rampload; ramp_t m_rampload_core; label_t m_label; - label_t m_tokenized; vector<cpu_time_t> m_cputimes; vector<cpu_time_t> m_cputimes_prev; diff --git a/include/modules/date.hpp b/include/modules/date.hpp index 6f51cc9f..69d0eadb 100644 --- a/include/modules/date.hpp +++ b/include/modules/date.hpp @@ -46,7 +46,7 @@ namespace modules { return m_builder->flush(); } - bool build(builder* builder, string tag) { + bool build(builder* builder, string tag) const { if (tag == TAG_DATE) builder->node(m_buffer); return tag == TAG_DATE; diff --git a/include/modules/i3.hpp b/include/modules/i3.hpp index 5d3efef2..38e5ea66 100644 --- a/include/modules/i3.hpp +++ b/include/modules/i3.hpp @@ -167,9 +167,10 @@ namespace modules { auto icon = m_icons->get(workspace->name, DEFAULT_WS_ICON); auto label = m_statelabels.find(flag)->second->clone(); + label->reset_tokens(); label->replace_token("%output%", workspace->output); label->replace_token("%name%", wsname); - label->replace_token("%icon%", icon->m_text); + label->replace_token("%icon%", icon->get()); label->replace_token("%index%", to_string(workspace->num)); m_workspaces.emplace_back( make_unique<i3_workspace>(workspace->num, flag, std::move(label))); @@ -184,7 +185,7 @@ namespace modules { // }}} } - bool build(builder* builder, string tag) { + bool build(builder* builder, string tag) const { // Output workspace info {{{ if (tag != TAG_LABEL_STATE) diff --git a/include/modules/memory.hpp b/include/modules/memory.hpp index 1372ec6d..5d94cd79 100644 --- a/include/modules/memory.hpp +++ b/include/modules/memory.hpp @@ -25,11 +25,8 @@ namespace modules { m_bars[memtype::USED] = get_config_bar(m_bar, m_conf, name(), TAG_BAR_USED); if (m_formatter->has(TAG_BAR_FREE)) m_bars[memtype::FREE] = get_config_bar(m_bar, m_conf, name(), TAG_BAR_FREE); - - if (m_formatter->has(TAG_LABEL)) { + if (m_formatter->has(TAG_LABEL)) m_label = get_optional_config_label(m_conf, name(), TAG_LABEL, "%percentage_used%"); - m_tokenized = m_label->clone(); - } } bool update() { @@ -72,38 +69,36 @@ namespace modules { m_perc[memtype::USED] = 100 - m_perc[memtype::FREE]; // replace tokens - if (m_tokenized) { - m_tokenized->m_text = m_label->m_text; + if (m_label) { + m_label->reset_tokens(); auto replace_unit = [](label_t& label, string token, float value, string unit) { - if (label->m_text.find(token) == string::npos) - return; auto formatted = string_util::from_stream( stringstream() << std::setprecision(2) << std::fixed << value << " " << unit); label->replace_token(token, formatted); }; - replace_unit(m_tokenized, "%gb_used%", (kb_total - kb_avail) / 1024 / 1024, "GB"); - replace_unit(m_tokenized, "%gb_free%", kb_avail / 1024 / 1024, "GB"); - replace_unit(m_tokenized, "%gb_total%", kb_total / 1024 / 1024, "GB"); - replace_unit(m_tokenized, "%mb_used%", (kb_total - kb_avail) / 1024, "MB"); - replace_unit(m_tokenized, "%mb_free%", kb_avail / 1024, "MB"); - replace_unit(m_tokenized, "%mb_total%", kb_total / 1024, "MB"); + replace_unit(m_label, "%gb_used%", (kb_total - kb_avail) / 1024 / 1024, "GB"); + replace_unit(m_label, "%gb_free%", kb_avail / 1024 / 1024, "GB"); + replace_unit(m_label, "%gb_total%", kb_total / 1024 / 1024, "GB"); + replace_unit(m_label, "%mb_used%", (kb_total - kb_avail) / 1024, "MB"); + replace_unit(m_label, "%mb_free%", kb_avail / 1024, "MB"); + replace_unit(m_label, "%mb_total%", kb_total / 1024, "MB"); - m_tokenized->replace_token("%percentage_used%", to_string(m_perc[memtype::USED]) + "%"); - m_tokenized->replace_token("%percentage_free%", to_string(m_perc[memtype::FREE]) + "%"); + m_label->replace_token("%percentage_used%", to_string(m_perc[memtype::USED]) + "%"); + m_label->replace_token("%percentage_free%", to_string(m_perc[memtype::FREE]) + "%"); } return true; } - bool build(builder* builder, string tag) { + bool build(builder* builder, string tag) const { if (tag == TAG_BAR_USED) { - builder->node(m_bars[memtype::USED]->output(m_perc[memtype::USED])); + builder->node(m_bars.at(memtype::USED)->output(m_perc.at(memtype::USED))); } else if (tag == TAG_BAR_FREE) - builder->node(m_bars[memtype::FREE]->output(m_perc[memtype::FREE])); + builder->node(m_bars.at(memtype::FREE)->output(m_perc.at(memtype::FREE))); else if (tag == TAG_LABEL) - builder->node(m_tokenized); + builder->node(m_label); else return false; return true; @@ -115,7 +110,7 @@ namespace modules { static constexpr auto TAG_BAR_FREE = "<bar-free>"; label_t m_label; - label_t m_tokenized; + progressbar_t m_bar_free; map<memtype, progressbar_t> m_bars; map<memtype, int> m_perc; }; diff --git a/include/modules/menu.hpp b/include/modules/menu.hpp index 257b2e9f..250886c9 100644 --- a/include/modules/menu.hpp +++ b/include/modules/menu.hpp @@ -58,7 +58,7 @@ namespace modules { } } - bool build(builder* builder, string tag) { + bool build(builder* builder, string tag) const { if (tag == TAG_LABEL_TOGGLE && m_level == -1) { builder->cmd(mousebtn::LEFT, string(EVENT_MENU_OPEN) + "0"); builder->node(m_labelopen); diff --git a/include/modules/meta.hpp b/include/modules/meta.hpp index 7eb66e15..19778ed8 100644 --- a/include/modules/meta.hpp +++ b/include/modules/meta.hpp @@ -287,7 +287,7 @@ namespace modules { return ""; } - auto format_name = CAST_MODULE(Impl)->get_format(); + auto format_name = CONST_CAST_MODULE(Impl).get_format(); auto format = m_formatter->get(format_name); int i = 0; @@ -299,7 +299,7 @@ namespace modules { if (tag[0] == '<' && tag[tag.length() - 1] == '>') { if (i > 0) m_builder->space(format->spacing); - if (!(tag_built = CAST_MODULE(Impl)->build(m_builder.get(), tag)) && i > 0) + if (!(tag_built = CONST_CAST_MODULE(Impl).build(m_builder.get(), tag)) && i > 0) m_builder->remove_trailing_space(format->spacing); if (tag_built) i++; @@ -361,7 +361,7 @@ namespace modules { CAST_MODULE(Impl)->broadcast(); } - bool build(builder*, string) { + bool build(builder*, string) const { return true; } }; @@ -427,17 +427,14 @@ namespace modules { CAST_MODULE(Impl)->broadcast(); while (CONST_CAST_MODULE(Impl).enabled()) { - CAST_MODULE(Impl)->idle(); - { - std::lock_guard<threading_util::spin_lock> lck(this->update_lock); - - if (!CAST_MODULE(Impl)->has_event()) - continue; - if (!CAST_MODULE(Impl)->update()) - continue; + std::lock_guard<threading_util::spin_lock> lck(this->update_lock); + if (!CAST_MODULE(Impl)->has_event()) + CAST_MODULE(Impl)->idle(); + else if (!CAST_MODULE(Impl)->update()) + CAST_MODULE(Impl)->idle(); + else CAST_MODULE(Impl)->broadcast(); - } } } catch (const std::exception& err) { this->m_log.err("%s: %s", this->name(), err.what()); diff --git a/include/modules/mpd.hpp b/include/modules/mpd.hpp index acd8ce56..0d7e1a99 100644 --- a/include/modules/mpd.hpp +++ b/include/modules/mpd.hpp @@ -57,12 +57,10 @@ namespace modules { if (m_formatter->has(TAG_LABEL_SONG)) { m_label_song = get_optional_config_label(m_conf, name(), TAG_LABEL_SONG, "%artist% - %title%"); - m_label_song_tokenized = m_label_song->clone(); } if (m_formatter->has(TAG_LABEL_TIME)) { m_label_time = get_optional_config_label(m_conf, name(), TAG_LABEL_TIME, "%elapsed% / %total%"); - m_label_time_tokenized = m_label_time->clone(); } if (m_formatter->has(TAG_ICON_RANDOM) || m_formatter->has(TAG_ICON_REPEAT) || m_formatter->has(TAG_ICON_REPEAT_ONE)) { @@ -83,64 +81,58 @@ namespace modules { m_mpd = make_unique<mpdconnection>(m_log, m_host, m_port, m_pass); m_mpd->connect(); m_status = m_mpd->get_status(); - } catch (const mpd_exception& e) { - m_log.err("%s: %s", name(), e.what()); + } catch (const mpd_exception& err) { + m_log.err("%s: %s", name(), err.what()); + m_mpd.reset(); } } - void teardown() { - if (m_mpd && m_mpd->connected()) { - try { - m_mpd->disconnect(); - } catch (const mpd_exception& e) { - m_log.trace("%s: %s", name(), e.what()); - } - } else { - wakeup(); - } + inline bool connected() const { + return m_mpd && m_mpd->connected(); } void idle() { - if (m_mpd && m_mpd->connected()) + if (connected()) sleep(80ms); else { - sleep(10s); + sleep(2s); } } bool has_event() { - if (!m_mpd->connected()) { - m_connection_state_broadcasted = false; + if (!m_mpd) + m_mpd = make_unique<mpdconnection>(m_log, m_host, m_port, m_pass); - try { + try { + if (!connected()) m_mpd->connect(); - } catch (const mpd_exception& e) { - m_log.trace("%s: %s", name(), e.what()); - } - - if (!m_mpd->connected()) { - return false; - } + if (m_connection_state_broadcasted) + m_connection_state_broadcasted = false; + } catch (const mpd_exception& err) { + m_log.trace("%s: %s", name(), err.what()); + m_mpd.reset(); + return !m_connection_state_broadcasted; } + if (!connected()) + return !m_connection_state_broadcasted; + if (!m_status) m_status = m_mpd->get_status_safe(); try { m_mpd->idle(); - - int idle_flags; - + int idle_flags = 0; if ((idle_flags = m_mpd->noidle()) != 0) { m_status->update(idle_flags, m_mpd.get()); return true; } else if (m_status->match_state(mpdstate::PLAYING)) { m_status->update_timer(); } - } catch (const mpd_exception& e) { - m_log.err(e.what()); - m_mpd->disconnect(); - return true; + } catch (const mpd_exception& err) { + m_log.err(err.what()); + m_mpd.reset(); + return !m_connection_state_broadcasted; } if ((m_label_time || m_bar_progress) && m_status->match_state(mpdstate::PLAYING)) { @@ -156,12 +148,14 @@ namespace modules { } bool update() { - if (!m_mpd->connected()) - return true; - if (!m_status && !(m_status = m_mpd->get_status_safe())) - return true; - - m_connection_state_broadcasted = true; + if (m_connection_state_broadcasted) { + if (!connected()) + return false; + if (!m_status && !(m_status = m_mpd->get_status_safe())) + return false; + } else { + m_connection_state_broadcasted = true; + } string artist; string album; @@ -170,52 +164,55 @@ namespace modules { string total_str; try { - elapsed_str = m_status->get_formatted_elapsed(); - total_str = m_status->get_formatted_total(); - auto song = m_mpd->get_song(); - if (song && song.get()) { - artist = song->get_artist(); - album = song->get_album(); - title = song->get_title(); + if (m_status) { + elapsed_str = m_status->get_formatted_elapsed(); + total_str = m_status->get_formatted_total(); } - } catch (const mpd_exception& e) { - m_log.err(e.what()); - m_mpd->disconnect(); - return true; + if (m_mpd) { + auto song = m_mpd->get_song(); + if (song && song.get()) { + artist = song->get_artist(); + album = song->get_album(); + title = song->get_title(); + } + } + } catch (const mpd_exception& err) { + m_log.err(err.what()); + m_mpd.reset(); } - if (m_label_song_tokenized) { - m_label_song_tokenized->m_text = m_label_song->m_text; - m_label_song_tokenized->replace_token( + if (m_label_song) { + m_label_song->reset_tokens(); + m_label_song->replace_token( "%artist%", !artist.empty() ? artist : "untitled artist"); - m_label_song_tokenized->replace_token("%album%", !album.empty() ? album : "untitled album"); - m_label_song_tokenized->replace_token("%title%", !title.empty() ? title : "untitled track"); + m_label_song->replace_token("%album%", !album.empty() ? album : "untitled album"); + m_label_song->replace_token("%title%", !title.empty() ? title : "untitled track"); } - if (m_label_time_tokenized) { - m_label_time_tokenized->m_text = m_label_time->m_text; - m_label_time_tokenized->replace_token("%elapsed%", elapsed_str); - m_label_time_tokenized->replace_token("%total%", total_str); + if (m_label_time) { + m_label_time->reset_tokens(); + m_label_time->replace_token("%elapsed%", elapsed_str); + m_label_time->replace_token("%total%", total_str); } if (m_icons->has("random")) m_icons->get("random")->m_foreground = - m_status->random() ? m_toggle_on_color : m_toggle_off_color; + m_status && m_status->random() ? m_toggle_on_color : m_toggle_off_color; if (m_icons->has("repeat")) m_icons->get("repeat")->m_foreground = - m_status->repeat() ? m_toggle_on_color : m_toggle_off_color; + m_status && m_status->repeat() ? m_toggle_on_color : m_toggle_off_color; if (m_icons->has("repeat_one")) m_icons->get("repeat_one")->m_foreground = - m_status->single() ? m_toggle_on_color : m_toggle_off_color; + m_status && m_status->single() ? m_toggle_on_color : m_toggle_off_color; return true; } - string get_format() { - return m_mpd->connected() ? FORMAT_ONLINE : FORMAT_OFFLINE; + string get_format() const { + return connected() ? FORMAT_ONLINE : FORMAT_OFFLINE; } - bool build(builder* builder, string tag) { + bool build(builder* builder, string tag) const { bool is_playing = false; bool is_paused = false; bool is_stopped = true; @@ -239,9 +236,9 @@ namespace modules { }; if (tag == TAG_LABEL_SONG && !is_stopped) - builder->node(m_label_song_tokenized); + builder->node(m_label_song); else if (tag == TAG_LABEL_TIME && !is_stopped) - builder->node(m_label_time_tokenized); + builder->node(m_label_time); else if (tag == TAG_BAR_PROGRESS && !is_stopped) builder->node(m_bar_progress->output(elapsed_percentage)); else if (tag == TAG_LABEL_OFFLINE) @@ -312,8 +309,9 @@ namespace modules { mpd->seek(status->get_songid(), status->get_seek_position(percentage)); } else return false; - } catch (const mpd_exception& e) { - m_log.err("%s: %s", name(), e.what()); + } catch (const mpd_exception& err) { + m_log.err("%s: %s", name(), err.what()); + m_mpd.reset(); } return true; @@ -359,9 +357,7 @@ namespace modules { progressbar_t m_bar_progress; iconset_t m_icons; label_t m_label_song; - label_t m_label_song_tokenized; label_t m_label_time; - label_t m_label_time_tokenized; label_t m_label_offline; unique_ptr<mpdconnection> m_mpd; @@ -383,7 +379,7 @@ namespace modules { // This flag is used to let thru a broadcast once every time // the connection state changes - stateflag m_connection_state_broadcasted{true}; + stateflag m_connection_state_broadcasted{false}; }; } diff --git a/include/modules/network.hpp b/include/modules/network.hpp index c0d79fa2..389b5519 100644 --- a/include/modules/network.hpp +++ b/include/modules/network.hpp @@ -38,13 +38,13 @@ namespace modules { if (m_formatter->has(TAG_LABEL_CONNECTED, FORMAT_CONNECTED)) { m_label[connection_state::CONNECTED] = get_optional_config_label(m_conf, name(), TAG_LABEL_CONNECTED, "%ifname% %local_ip%"); - m_tokenized[connection_state::CONNECTED] = m_label[connection_state::CONNECTED]->clone(); } // Create elements for format-disconnected if (m_formatter->has(TAG_LABEL_DISCONNECTED, FORMAT_DISCONNECTED)) { m_label[connection_state::DISCONNECTED] = get_optional_config_label(m_conf, name(), TAG_LABEL_DISCONNECTED, ""); + m_label[connection_state::DISCONNECTED]->reset_tokens(); m_label[connection_state::DISCONNECTED]->replace_token("%ifname%", m_interface); } @@ -56,8 +56,6 @@ namespace modules { if (m_formatter->has(TAG_LABEL_PACKETLOSS, FORMAT_PACKETLOSS)) { m_label[connection_state::PACKETLOSS] = get_optional_config_label(m_conf, name(), TAG_LABEL_PACKETLOSS, ""); - m_tokenized[connection_state::PACKETLOSS] = - m_label[connection_state::PACKETLOSS]->clone(); } if (m_formatter->has(TAG_ANIMATION_PACKETLOSS, FORMAT_PACKETLOSS)) m_animation_packetloss = get_config_animation(m_conf, name(), TAG_ANIMATION_PACKETLOSS); @@ -112,6 +110,7 @@ namespace modules { // Update label contents const auto replace_tokens = [&](label_t& label) { + label->reset_tokens(); label->replace_token("%ifname%", m_interface); label->replace_token("%local_ip%", network->ip()); label->replace_token("%upspeed%", upspeed); @@ -126,22 +125,15 @@ namespace modules { } }; - if (m_label[connection_state::CONNECTED]) { - m_tokenized[connection_state::CONNECTED]->m_text = - m_label[connection_state::CONNECTED]->m_text; - replace_tokens(m_tokenized[connection_state::CONNECTED]); - } - - if (m_label[connection_state::PACKETLOSS]) { - m_tokenized[connection_state::PACKETLOSS]->m_text = - m_label[connection_state::PACKETLOSS]->m_text; - replace_tokens(m_tokenized[connection_state::PACKETLOSS]); - } + if (m_label[connection_state::CONNECTED]) + replace_tokens(m_label[connection_state::CONNECTED]); + if (m_label[connection_state::PACKETLOSS]) + replace_tokens(m_label[connection_state::PACKETLOSS]); return true; } - string get_format() { + string get_format() const { if (!m_connected) return FORMAT_DISCONNECTED; else if (m_packetloss && m_ping_nth_update > 0) @@ -150,13 +142,13 @@ namespace modules { return FORMAT_CONNECTED; } - bool build(builder* builder, string tag) { + bool build(builder* builder, string tag) const { if (tag == TAG_LABEL_CONNECTED) - builder->node(m_tokenized[connection_state::CONNECTED]); + builder->node(m_label.at(connection_state::CONNECTED)); else if (tag == TAG_LABEL_DISCONNECTED) - builder->node(m_label[connection_state::DISCONNECTED]); + builder->node(m_label.at(connection_state::DISCONNECTED)); else if (tag == TAG_LABEL_PACKETLOSS) - builder->node(m_tokenized[connection_state::PACKETLOSS]); + builder->node(m_label.at(connection_state::PACKETLOSS)); else if (tag == TAG_ANIMATION_PACKETLOSS) builder->node(m_animation_packetloss->get()); else if (tag == TAG_RAMP_SIGNAL) @@ -200,7 +192,6 @@ namespace modules { ramp_t m_ramp_quality; animation_t m_animation_packetloss; map<connection_state, label_t> m_label; - map<connection_state, label_t> m_tokenized; stateflag m_connected{false}; stateflag m_packetloss{false}; diff --git a/include/modules/script.hpp b/include/modules/script.hpp index c94c1be4..5f47d335 100644 --- a/include/modules/script.hpp +++ b/include/modules/script.hpp @@ -129,7 +129,7 @@ namespace modules { return m_builder->flush(); } - bool build(builder* builder, string tag) { + bool build(builder* builder, string tag) const { if (tag != TAG_OUTPUT) return false; builder->node(string_util::replace_all(m_output, "\n", "")); diff --git a/include/modules/text.hpp b/include/modules/text.hpp index 98768f60..e92390cb 100644 --- a/include/modules/text.hpp +++ b/include/modules/text.hpp @@ -19,7 +19,7 @@ namespace modules { string_util::replace_all(m_formatter->get("content")->value, " ", BUILDER_SPACE_TOKEN); } - string get_format() { + string get_format() const { return "content"; } diff --git a/include/modules/unsupported.hpp b/include/modules/unsupported.hpp index 34c42067..9379ad53 100644 --- a/include/modules/unsupported.hpp +++ b/include/modules/unsupported.hpp @@ -11,7 +11,7 @@ throw application_error("No built-in support for '" + string{MODULE_TYPE} + "'"); \ } \ void start() {} \ - bool build(builder*, string) { \ + bool build(builder*, string) const { \ return true; \ } \ } diff --git a/include/modules/volume.hpp b/include/modules/volume.hpp index 5254a4ab..4fce553e 100644 --- a/include/modules/volume.hpp +++ b/include/modules/volume.hpp @@ -98,11 +98,9 @@ namespace modules { if (m_formatter->has(TAG_LABEL_VOLUME, FORMAT_VOLUME)) { m_label_volume = get_optional_config_label(m_conf, name(), TAG_LABEL_VOLUME, "%percentage%"); - m_label_volume_tokenized = m_label_volume->clone(); } if (m_formatter->has(TAG_LABEL_MUTED, FORMAT_MUTED)) { m_label_muted = get_optional_config_label(m_conf, name(), TAG_LABEL_MUTED, "%percentage%"); - m_label_muted_tokenized = m_label_muted->clone(); } // }}} @@ -172,13 +170,13 @@ namespace modules { // }}} // Replace label tokens {{{ - if (m_label_volume_tokenized) { - m_label_volume_tokenized->m_text = m_label_volume->m_text; - m_label_volume_tokenized->replace_token("%percentage%", to_string(m_volume) + "%"); + if (m_label_volume) { + m_label_volume->reset_tokens(); + m_label_volume->replace_token("%percentage%", to_string(m_volume) + "%"); } - if (m_label_muted_tokenized) { - m_label_muted_tokenized->m_text = m_label_muted->m_text; - m_label_muted_tokenized->replace_token("%percentage%", to_string(m_volume) + "%"); + if (m_label_muted) { + m_label_muted->reset_tokens(); + m_label_muted->replace_token("%percentage%", to_string(m_volume) + "%"); } // }}} @@ -186,7 +184,7 @@ namespace modules { return true; } - string get_format() { + string get_format() const { return m_muted ? FORMAT_MUTED : FORMAT_VOLUME; } @@ -202,7 +200,7 @@ namespace modules { return m_builder->flush(); } - bool build(builder* builder, string tag) { + bool build(builder* builder, string tag) const { if (tag == TAG_BAR_VOLUME) builder->node(m_bar_volume->output(m_volume)); else if (tag == TAG_RAMP_VOLUME && (!m_headphones || !*m_ramp_headphones)) @@ -210,9 +208,9 @@ namespace modules { else if (tag == TAG_RAMP_VOLUME && m_headphones && *m_ramp_headphones) builder->node(m_ramp_headphones->get_by_percentage(m_volume)); else if (tag == TAG_LABEL_VOLUME) - builder->node(m_label_volume_tokenized); + builder->node(m_label_volume); else if (tag == TAG_LABEL_MUTED) - builder->node(m_label_muted_tokenized); + builder->node(m_label_muted); else return false; return true; @@ -283,9 +281,7 @@ namespace modules { ramp_t m_ramp_volume; ramp_t m_ramp_headphones; label_t m_label_volume; - label_t m_label_volume_tokenized; label_t m_label_muted; - label_t m_label_muted_tokenized; map<mixer, mixer_t> m_mixers; map<control, control_t> m_controls;