refactor(clang-tidy): Apply fixes

This commit is contained in:
Michael Carlberg 2016-11-25 13:55:15 +01:00
parent 0128014d44
commit ff9be848c7
119 changed files with 1752 additions and 1046 deletions

View File

@ -1,5 +1,5 @@
--- ---
Checks: '-*,performance-faster-string-find,performance-for-range-copy,readability-*,modernize-*,-modernize-raw-string-literal,-modernize-use-bool-literals,-readability-implicit-bool-cast,-readability-else-after-return,-readability-named-parameter' Checks: '-*,performance-*,readability-*,modernize-use-*,-modernize-raw-string-literal,-modernize-use-bool-literals,-readability-implicit-bool-cast,-readability-else-after-return,-readability-named-parameter'
CheckOptions: CheckOptions:
- key: modernize-loop-convert.NamingStyle - key: modernize-loop-convert.NamingStyle
value: lower_case value: lower_case

View File

@ -21,7 +21,6 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic-errors") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic-errors")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-stack-protector")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffunction-sections -fdata-sections") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffunction-sections -fdata-sections")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0")

View File

@ -9,6 +9,7 @@
#include "common.hpp" #include "common.hpp"
#include "config.hpp" #include "config.hpp"
#include "errors.hpp"
#include "utils/concurrency.hpp" #include "utils/concurrency.hpp"
#define MAX_LINEAR_DB_SCALE 24 #define MAX_LINEAR_DB_SCALE 24
@ -40,17 +41,17 @@ class alsa_ctl_interface {
void process_events(); void process_events();
private: private:
int m_numid = 0; int m_numid{0};
concurrency_util::spin_lock m_lock; std::mutex m_lock;
snd_hctl_t* m_hctl = nullptr; snd_hctl_t* m_hctl{nullptr};
snd_hctl_elem_t* m_elem = nullptr; snd_hctl_elem_t* m_elem{nullptr};
snd_ctl_t* m_ctl = nullptr; snd_ctl_t* m_ctl{nullptr};
snd_ctl_elem_info_t* m_info = nullptr; snd_ctl_elem_info_t* m_info{nullptr};
snd_ctl_elem_value_t* m_value = nullptr; snd_ctl_elem_value_t* m_value{nullptr};
snd_ctl_elem_id_t* m_id = nullptr; snd_ctl_elem_id_t* m_id{nullptr};
}; };
// }}} // }}}
@ -58,7 +59,7 @@ class alsa_ctl_interface {
class alsa_mixer { class alsa_mixer {
public: public:
explicit alsa_mixer(string mixer_control_name); explicit alsa_mixer(const string& mixer_control_name);
~alsa_mixer(); ~alsa_mixer();
string get_name(); string get_name();
@ -77,10 +78,10 @@ class alsa_mixer {
private: private:
string m_name; string m_name;
concurrency_util::spin_lock m_lock; std::mutex m_lock;
snd_mixer_t* m_hardwaremixer = nullptr; snd_mixer_t* m_hardwaremixer{nullptr};
snd_mixer_elem_t* m_mixerelement = nullptr; snd_mixer_elem_t* m_mixerelement{nullptr};
}; };
// }}} // }}}

View File

@ -5,6 +5,7 @@
#include <chrono> #include <chrono>
#include "common.hpp" #include "common.hpp"
#include "errors.hpp"
POLYBAR_NS POLYBAR_NS

View File

@ -12,6 +12,7 @@
#include "common.hpp" #include "common.hpp"
#include "config.hpp" #include "config.hpp"
#include "errors.hpp"
POLYBAR_NS POLYBAR_NS
@ -20,7 +21,7 @@ namespace chrono = std::chrono;
namespace net { namespace net {
DEFINE_ERROR(network_error); DEFINE_ERROR(network_error);
bool is_wireless_interface(string ifname); bool is_wireless_interface(const string& ifname);
// types {{{ // types {{{

View File

@ -5,7 +5,6 @@
#endif #endif
#include <boost/di.hpp> #include <boost/di.hpp>
#include <cerrno>
#include <cstring> #include <cstring>
#include <map> #include <map>
#include <memory> #include <memory>
@ -42,10 +41,6 @@
POLYBAR_NS POLYBAR_NS
//==================================================
// Include common types (i.e, unclutter editor!)
//==================================================
namespace di = boost::di; namespace di = boost::di;
namespace placeholders = std::placeholders; namespace placeholders = std::placeholders;
@ -66,32 +61,5 @@ using std::array;
using std::map; using std::map;
using std::vector; using std::vector;
using std::to_string; using std::to_string;
using std::strerror;
using std::exception;
//==================================================
// Errors and exceptions
//==================================================
class application_error : public std::runtime_error {
public:
int m_code;
explicit application_error(string&& message, int code = 0)
: std::runtime_error(forward<string>(message)), m_code(code) {}
};
class system_error : public application_error {
public:
explicit system_error() : application_error(strerror(errno), errno) {}
explicit system_error(string&& message)
: application_error(forward<string>(message) + " (reason: " + strerror(errno) + ")", errno) {}
};
#define DEFINE_CHILD_ERROR(error, parent) \
class error : public parent { \
using parent::parent; \
}
#define DEFINE_ERROR(error) DEFINE_CHILD_ERROR(error, application_error)
POLYBAR_NS_END POLYBAR_NS_END

View File

@ -3,6 +3,7 @@
#include "common.hpp" #include "common.hpp"
#include "components/config.hpp" #include "components/config.hpp"
#include "components/types.hpp" #include "components/types.hpp"
#include "errors.hpp"
#include "utils/concurrency.hpp" #include "utils/concurrency.hpp"
#include "utils/throttle.hpp" #include "utils/throttle.hpp"
#include "x11/connection.hpp" #include "x11/connection.hpp"
@ -28,7 +29,7 @@ class bar : public xpp::event::sink<evt::button_press, evt::expose, evt::propert
const bar_settings settings() const; const bar_settings settings() const;
void parse(string data, bool force = false); void parse(const string& data, bool force = false);
protected: protected:
void setup_monitor(); void setup_monitor();

View File

@ -31,7 +31,7 @@ class builder {
void append(string text); void append(string text);
void node(string str, bool add_space = false); void node(string str, bool add_space = false);
void node(string str, int font_index, bool add_space = false); void node(string str, int font_index, bool add_space = false);
void node(label_t label, bool add_space = false); void node(const label_t& label, bool add_space = false);
void offset(int pixels = 0); void offset(int pixels = 0);
void space(int width = DEFAULT_SPACING); void space(int width = DEFAULT_SPACING);
void remove_trailing_space(int width = DEFAULT_SPACING); void remove_trailing_space(int width = DEFAULT_SPACING);
@ -42,15 +42,15 @@ class builder {
void color(string color); void color(string color);
void color_alpha(string alpha); void color_alpha(string alpha);
void color_close(); void color_close();
void line_color(string color); void line_color(const string& color);
void line_color_close(); void line_color_close();
void overline_color(string color); void overline_color(string color);
void overline_color_close(); void overline_color_close();
void underline_color(string color); void underline_color(string color);
void underline_color_close(); void underline_color_close();
void overline(string color = ""); void overline(const string& color = "");
void overline_close(); void overline_close();
void underline(string color = ""); void underline(const string& color = "");
void underline_close(); void underline_close();
void cmd(mousebtn index, string action, bool condition = true); void cmd(mousebtn index, string action, bool condition = true);
void cmd_close(); void cmd_close();
@ -59,7 +59,7 @@ class builder {
string background_hex(); string background_hex();
string foreground_hex(); string foreground_hex();
void tag_open(syntaxtag tag, string value); void tag_open(syntaxtag tag, const string& value);
void tag_open(attribute attr); void tag_open(attribute attr);
void tag_close(syntaxtag tag); void tag_close(syntaxtag tag);
void tag_close(attribute attr); void tag_close(attribute attr);

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "common.hpp" #include "common.hpp"
#include "errors.hpp"
POLYBAR_NS POLYBAR_NS
@ -40,15 +41,15 @@ namespace command_line {
bool has(const string& option) const; bool has(const string& option) const;
string get(string opt) const; string get(string opt) const;
bool compare(string opt, string val) const; bool compare(string opt, const string& val) const;
protected: protected:
auto is_short(string option, string opt_short) const; auto is_short(const string& option, const string& opt_short) const;
auto is_long(string option, string opt_long) const; auto is_long(const string& option, const string& opt_long) const;
auto is(string option, string opt_short, string opt_long) const; auto is(const string& option, string opt_short, string opt_long) const;
auto parse_value(string input, string input_next, choices values) const; auto parse_value(string input, const string& input_next, choices values) const;
void parse(string input, string input_next = ""); void parse(const string& input, const string& input_next = "");
private: private:
string m_synopsis; string m_synopsis;

View File

@ -7,6 +7,7 @@
#include "common.hpp" #include "common.hpp"
#include "components/logger.hpp" #include "components/logger.hpp"
#include "errors.hpp"
#include "utils/env.hpp" #include "utils/env.hpp"
#include "utils/string.hpp" #include "utils/string.hpp"
#include "x11/xresources.hpp" #include "x11/xresources.hpp"
@ -30,7 +31,7 @@ class config {
string bar_section() const; string bar_section() const;
vector<string> defined_bars() const; vector<string> defined_bars() const;
string build_path(const string& section, const string& key) const; string build_path(const string& section, const string& key) const;
void warn_deprecated(string section, string key, string replacement) const; void warn_deprecated(const string& section, const string& key, string replacement) const;
/** /**
* Get parameter for the current bar by name * Get parameter for the current bar by name

View File

@ -52,7 +52,7 @@ class controller {
void bootstrap_modules(); void bootstrap_modules();
void on_ipc_action(const ipc_action& message); void on_ipc_action(const ipc_action& message);
void on_mouse_event(string input); void on_mouse_event(const string& input);
void on_unrecognized_action(string input); void on_unrecognized_action(string input);
void on_update(); void on_update();

View File

@ -49,7 +49,7 @@ class eventloop {
void forward_event(entry_t evt); void forward_event(entry_t evt);
void on_update(); void on_update();
void on_input(string input); void on_input(char* input);
void on_check(); void on_check();
void on_quit(); void on_quit();

View File

@ -42,9 +42,9 @@ class ipc {
protected: protected:
void parse(const string& payload) const; void parse(const string& payload) const;
void delegate(const ipc_command& msg) const; void delegate(const ipc_command& message) const;
void delegate(const ipc_hook& msg) const; void delegate(const ipc_hook& message) const;
void delegate(const ipc_action& msg) const; void delegate(const ipc_action& message) const;
private: private:
const logger& m_log; const logger& m_log;

View File

@ -15,7 +15,7 @@ enum class loglevel {
TRACE, TRACE,
}; };
loglevel parse_loglevel_name(string name); loglevel parse_loglevel_name(const string& name);
class logger { class logger {
public: public:

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "common.hpp" #include "common.hpp"
#include "errors.hpp"
POLYBAR_NS POLYBAR_NS
@ -24,9 +25,9 @@ class parser {
protected: protected:
uint32_t parse_color(string s, uint32_t fallback = 0); uint32_t parse_color(string s, uint32_t fallback = 0);
int8_t parse_fontindex(string s); int8_t parse_fontindex(string s);
attribute parse_attr(const char s); attribute parse_attr(const char attr);
mousebtn parse_action_btn(string data); mousebtn parse_action_btn(string data);
string parse_action_cmd(string data); string parse_action_cmd(const string& data);
private: private:
const logger& m_log; const logger& m_log;

View File

@ -44,7 +44,7 @@ class renderer {
void draw_character(const uint16_t character); void draw_character(const uint16_t character);
void draw_textstring(const char* text, const size_t len); void draw_textstring(const char* text, const size_t len);
void begin_action(const mousebtn btn, const string cmd); void begin_action(const mousebtn btn, const string& cmd);
void end_action(const mousebtn btn); void end_action(const mousebtn btn);
const vector<action_block> get_actions(); const vector<action_block> get_actions();

View File

@ -38,7 +38,8 @@ namespace drawtypes {
using animation_t = shared_ptr<animation>; using animation_t = shared_ptr<animation>;
animation_t load_animation(const config& conf, string section, string name = "animation", bool required = true); animation_t load_animation(
const config& conf, const string& section, string name = "animation", bool required = true);
} }
POLYBAR_NS_END POLYBAR_NS_END

View File

@ -10,8 +10,8 @@ namespace drawtypes {
class iconset : public non_copyable_mixin<iconset> { class iconset : public non_copyable_mixin<iconset> {
public: public:
void add(string id, icon_t&& icon); void add(string id, icon_t&& icon);
bool has(string id); bool has(const string& id);
icon_t get(string id, string fallback_id = ""); icon_t get(const string& id, const string& fallback_id = "");
operator bool(); operator bool();
protected: protected:

View File

@ -59,8 +59,8 @@ namespace drawtypes {
operator bool(); operator bool();
label_t clone(); label_t clone();
void reset_tokens(); void reset_tokens();
bool has_token(string token); bool has_token(const string& token);
void replace_token(string token, string replacement); void replace_token(const string& token, string replacement);
void replace_defined_values(const label_t& label); void replace_defined_values(const label_t& label);
void copy_undefined(const label_t& label); void copy_undefined(const label_t& label);
@ -69,7 +69,7 @@ namespace drawtypes {
const vector<struct bounds> m_token_bounds; const vector<struct bounds> m_token_bounds;
}; };
label_t load_label(const config& conf, string section, string name, bool required = true, string def = ""); label_t load_label(const config& conf, const string& section, string name, bool required = true, string def = "");
label_t load_optional_label(const config& conf, string section, string name, string def = ""); label_t load_optional_label(const config& conf, string section, string name, string def = "");

View File

@ -12,7 +12,7 @@ POLYBAR_NS
namespace drawtypes { namespace drawtypes {
class progressbar : public non_copyable_mixin<progressbar> { class progressbar : public non_copyable_mixin<progressbar> {
public: public:
explicit progressbar(const bar_settings bar, int width, string format); explicit progressbar(const bar_settings& bar, int width, string format);
void set_fill(icon_t&& fill); void set_fill(icon_t&& fill);
void set_empty(icon_t&& empty); void set_empty(icon_t&& empty);
@ -40,7 +40,7 @@ namespace drawtypes {
using progressbar_t = shared_ptr<progressbar>; using progressbar_t = shared_ptr<progressbar>;
progressbar_t load_progressbar(const bar_settings& bar, const config& conf, string section, string name); progressbar_t load_progressbar(const bar_settings& bar, const config& conf, const string& section, string name);
} }
POLYBAR_NS_END POLYBAR_NS_END

View File

@ -24,7 +24,7 @@ namespace drawtypes {
using ramp_t = shared_ptr<ramp>; using ramp_t = shared_ptr<ramp>;
ramp_t load_ramp(const config& conf, string section, string name, bool required = true); ramp_t load_ramp(const config& conf, const string& section, string name, bool required = true);
} }
POLYBAR_NS_END POLYBAR_NS_END

32
include/errors.hpp Normal file
View File

@ -0,0 +1,32 @@
#pragma once
#include <cerrno>
#include "common.hpp"
POLYBAR_NS
using std::strerror;
using std::exception;
using std::runtime_error;
class application_error : public runtime_error {
public:
explicit application_error(const string& message, int code = 0) : runtime_error(message), code(code) {}
int code{0};
};
class system_error : public application_error {
public:
explicit system_error() : application_error(strerror(errno), errno) {}
explicit system_error(const string& message)
: application_error(message + " (reason: " + strerror(errno) + ")", errno) {}
};
#define DEFINE_CHILD_ERROR(error, parent) \
class error : public parent { \
using parent::parent; \
}
#define DEFINE_ERROR(error) DEFINE_CHILD_ERROR(error, application_error)
POLYBAR_NS_END

View File

@ -8,7 +8,7 @@ POLYBAR_NS
namespace modules { namespace modules {
struct brightness_handle { struct brightness_handle {
void filepath(string path); void filepath(const string& path);
float read() const; float read() const;
private: private:
@ -22,7 +22,7 @@ namespace modules {
void setup(); void setup();
void idle(); void idle();
bool on_event(inotify_event* event); bool on_event(inotify_event* event);
bool build(builder* builder, string tag) const; bool build(builder* builder, const string& tag) const;
private: private:
static constexpr auto TAG_LABEL = "<label>"; static constexpr auto TAG_LABEL = "<label>";

View File

@ -34,7 +34,7 @@ namespace modules {
void idle(); void idle();
bool on_event(inotify_event* event); bool on_event(inotify_event* event);
string get_format() const; string get_format() const;
bool build(builder* builder, string tag) const; bool build(builder* builder, const string& tag) const;
protected: protected:
int current_percentage(); int current_percentage();

View File

@ -46,7 +46,7 @@ namespace modules {
bool has_event(); bool has_event();
bool update(); bool update();
string get_output(); string get_output();
bool build(builder* builder, string tag) const; bool build(builder* builder, const string& tag) const;
bool handle_event(string cmd); bool handle_event(string cmd);
bool receive_events() const { bool receive_events() const {
return true; return true;

View File

@ -11,7 +11,7 @@ namespace modules {
void setup(); void setup();
bool update(); bool update();
bool build(builder* builder, string tag) const; bool build(builder* builder, const string& tag) const;
private: private:
static constexpr auto TAG_COUNTER = "<counter>"; static constexpr auto TAG_COUNTER = "<counter>";

View File

@ -24,7 +24,7 @@ namespace modules {
void setup(); void setup();
bool update(); bool update();
bool build(builder* builder, string tag) const; bool build(builder* builder, const string& tag) const;
protected: protected:
bool read_values(); bool read_values();

View File

@ -11,7 +11,7 @@ namespace modules {
void setup(); void setup();
bool update(); bool update();
bool build(builder* builder, string tag) const; bool build(builder* builder, const string& tag) const;
bool handle_event(string cmd); bool handle_event(string cmd);
bool receive_events() const; bool receive_events() const;

View File

@ -43,7 +43,7 @@ namespace modules {
bool update(); bool update();
string get_format() const; string get_format() const;
string get_output(); string get_output();
bool build(builder* builder, string tag) const; bool build(builder* builder, const string& tag) const;
private: private:
static constexpr auto FORMAT_MOUNTED = "format-mounted"; static constexpr auto FORMAT_MOUNTED = "format-mounted";

View File

@ -44,7 +44,7 @@ namespace modules {
void stop(); void stop();
bool has_event(); bool has_event();
bool update(); bool update();
bool build(builder* builder, string tag) const; bool build(builder* builder, const string& tag) const;
bool handle_event(string cmd); bool handle_event(string cmd);
bool receive_events() const { bool receive_events() const {
return true; return true;

View File

@ -29,8 +29,8 @@ namespace modules {
void setup(); void setup();
string get_output(); string get_output();
bool build(builder* builder, string tag) const; bool build(builder* builder, const string& tag) const;
void on_message(const ipc_hook& msg); void on_message(const ipc_hook& message);
private: private:
static constexpr auto TAG_OUTPUT = "<output>"; static constexpr auto TAG_OUTPUT = "<output>";

View File

@ -16,7 +16,7 @@ namespace modules {
void setup(); void setup();
bool update(); bool update();
bool build(builder* builder, string tag) const; bool build(builder* builder, const string& tag) const;
private: private:
static constexpr auto TAG_LABEL = "<label>"; static constexpr auto TAG_LABEL = "<label>";

View File

@ -19,7 +19,7 @@ namespace modules {
using static_module::static_module; using static_module::static_module;
void setup(); void setup();
bool build(builder* builder, string tag) const; bool build(builder* builder, const string& tag) const;
bool handle_event(string cmd); bool handle_event(string cmd);
bool receive_events() const; bool receive_events() const;

View File

@ -9,6 +9,7 @@
#include "components/config.hpp" #include "components/config.hpp"
#include "components/logger.hpp" #include "components/logger.hpp"
#include "components/types.hpp" #include "components/types.hpp"
#include "errors.hpp"
#include "utils/concurrency.hpp" #include "utils/concurrency.hpp"
#include "utils/functional.hpp" #include "utils/functional.hpp"
#include "utils/inotify.hpp" #include "utils/inotify.hpp"
@ -78,9 +79,9 @@ namespace modules {
explicit module_formatter(const config& conf, string modname) : m_conf(conf), m_modname(modname) {} explicit module_formatter(const config& conf, string modname) : m_conf(conf), m_modname(modname) {}
void add(string name, string fallback, vector<string>&& tags, vector<string>&& whitelist = {}); void add(string name, string fallback, vector<string>&& tags, vector<string>&& whitelist = {});
bool has(string tag, string format_name); bool has(const string& tag, const string& format_name);
bool has(string tag); bool has(const string& tag);
shared_ptr<module_format> get(string format_name); shared_ptr<module_format> get(const string& format_name);
protected: protected:
const config& m_conf; const config& m_conf;

View File

@ -26,7 +26,7 @@ namespace modules {
bool update(); bool update();
string get_format() const; string get_format() const;
string get_output(); string get_output();
bool build(builder* builder, string tag) const; bool build(builder* builder, const string& tag) const;
bool handle_event(string cmd); bool handle_event(string cmd);
bool receive_events() const; bool receive_events() const;

View File

@ -17,7 +17,7 @@ namespace modules {
void teardown(); void teardown();
bool update(); bool update();
string get_format() const; string get_format() const;
bool build(builder* builder, string tag) const; bool build(builder* builder, const string& tag) const;
protected: protected:
void subthread_routine(); void subthread_routine();

View File

@ -24,7 +24,7 @@ namespace modules {
bool has_event(); bool has_event();
bool update(); bool update();
string get_output(); string get_output();
bool build(builder* builder, string tag) const; bool build(builder* builder, const string& tag) const;
protected: protected:
static constexpr auto TAG_OUTPUT = "<output>"; static constexpr auto TAG_OUTPUT = "<output>";

View File

@ -17,7 +17,7 @@ namespace modules {
void setup(); void setup();
bool update(); bool update();
string get_format() const; string get_format() const;
bool build(builder* builder, string tag) const; bool build(builder* builder, const string& tag) const;
private: private:
static constexpr auto TAG_LABEL = "<label>"; static constexpr auto TAG_LABEL = "<label>";

View File

@ -4,6 +4,14 @@
#endif #endif
#include "modules/meta/base.hpp" #include "modules/meta/base.hpp"
#include "modules/meta/base.inl"
#if not(ENABLE_ALSA && ENABLE_I3 && ENABLE_MPD)
#include "modules/meta/event_module.inl"
#endif
#if not ENABLE_NETWORK
#include "modules/meta/timer_module.inl"
#endif
POLYBAR_NS POLYBAR_NS

View File

@ -24,7 +24,7 @@ namespace modules {
bool update(); bool update();
string get_format() const; string get_format() const;
string get_output(); string get_output();
bool build(builder* builder, string tag) const; bool build(builder* builder, const string& tag) const;
bool handle_event(string cmd); bool handle_event(string cmd);
bool receive_events() const; bool receive_events() const;
@ -49,8 +49,8 @@ namespace modules {
label_t m_label_volume; label_t m_label_volume;
label_t m_label_muted; label_t m_label_muted;
map<mixer, mixer_t> m_mixers; map<mixer, mixer_t> m_mixer;
map<control, control_t> m_controls; map<control, control_t> m_ctrl;
int m_headphoneid{0}; int m_headphoneid{0};
bool m_mapped{false}; bool m_mapped{false};
stateflag m_muted{false}; stateflag m_muted{false};

View File

@ -25,16 +25,14 @@ namespace modules {
*/ */
class xbacklight_module : public static_module<xbacklight_module>, public xpp::event::sink<evt::randr_notify> { class xbacklight_module : public static_module<xbacklight_module>, public xpp::event::sink<evt::randr_notify> {
public: public:
using static_module::static_module; xbacklight_module(const bar_settings& bar, const logger& logger, const config& config, string name);
xbacklight_module(const bar_settings bar, const logger& logger, const config& config, string name);
void setup(); void setup();
void teardown(); void teardown();
void handle(const evt::randr_notify& evt); void handle(const evt::randr_notify& evt);
void update(); void update();
string get_output(); string get_output();
bool build(builder* builder, string tag) const; bool build(builder* builder, const string& tag) const;
bool handle_event(string cmd); bool handle_event(string cmd);
bool receive_events() const { bool receive_events() const {
return true; return true;

View File

@ -77,7 +77,7 @@ namespace modules {
void handle(const evt::property_notify& evt); void handle(const evt::property_notify& evt);
void update(); void update();
string get_output(); string get_output();
bool build(builder* builder, string tag) const; bool build(builder* builder, const string& tag) const;
private: private:
static constexpr auto TAG_LABEL = "<label>"; static constexpr auto TAG_LABEL = "<label>";

View File

@ -28,7 +28,7 @@ namespace bspwm_util {
string get_socket_path(); string get_socket_path();
payload_t make_payload(string cmd); payload_t make_payload(const string& cmd);
connection_t make_connection(); connection_t make_connection();
connection_t make_subscriber(); connection_t make_subscriber();
} }

View File

@ -26,8 +26,8 @@ namespace file_util {
string m_mode; string m_mode;
}; };
bool exists(string filename); bool exists(const string& filename);
string get_contents(string filename); string get_contents(const string& filename);
void set_block(int fd); void set_block(int fd);
void set_nonblock(int fd); void set_nonblock(int fd);
bool is_fifo(string filename); bool is_fifo(string filename);

View File

@ -11,7 +11,7 @@ POLYBAR_NS
namespace i3_util { namespace i3_util {
using connection_t = i3ipc::connection; using connection_t = i3ipc::connection;
vector<xcb_window_t> root_windows(connection& conn, string output_name = ""); vector<xcb_window_t> root_windows(connection& conn, const string& output_name = "");
bool restack_above_root(connection& conn, const monitor_t& mon, const xcb_window_t win); bool restack_above_root(connection& conn, const monitor_t& mon, const xcb_window_t win);
} }

View File

@ -10,10 +10,10 @@ namespace io_util {
string readline(int read_fd, int& bytes_read); string readline(int read_fd, int& bytes_read);
string readline(int read_fd); string readline(int read_fd);
size_t write(int write_fd, string data); size_t write(int write_fd, const string& data);
size_t writeline(int write_fd, string data); size_t writeline(int write_fd, const string& data);
void tail(int read_fd, function<void(string)> callback); void tail(int read_fd, const function<void(string)>& callback);
void tail(int read_fd, int writeback_fd); void tail(int read_fd, int writeback_fd);
bool poll(int fd, short int events, int timeout_ms = 1); bool poll(int fd, short int events, int timeout_ms = 1);

View File

@ -8,7 +8,7 @@ namespace process_util {
bool in_parent_process(pid_t pid); bool in_parent_process(pid_t pid);
bool in_forked_process(pid_t pid); bool in_forked_process(pid_t pid);
void exec(string cmd); void exec(const string& cmd);
pid_t wait_for_completion(pid_t process_id, int* status_addr, int waitflags = 0); pid_t wait_for_completion(pid_t process_id, int* status_addr, int waitflags = 0);
pid_t wait_for_completion(int* status_addr, int waitflags = 0); pid_t wait_for_completion(int* status_addr, int waitflags = 0);

View File

@ -16,7 +16,7 @@ namespace socket_util {
int disconnect(); int disconnect();
ssize_t send(const void* data, size_t len, int flags = 0); ssize_t send(const void* data, size_t len, int flags = 0);
ssize_t send(string data, int flags = 0); ssize_t send(const string& data, int flags = 0);
string receive(const ssize_t receive_bytes, ssize_t& bytes_received_addr, int flags = 0); string receive(const ssize_t receive_bytes, ssize_t& bytes_received_addr, int flags = 0);
bool poll(short int events = POLLIN, int timeout_ms = -1); bool poll(short int events = POLLIN, int timeout_ms = -1);

View File

@ -16,8 +16,10 @@ namespace string_util {
string upper(const string& s); string upper(const string& s);
string lower(const string& s); string lower(const string& s);
bool compare(const string& s1, const string& s2); bool compare(const string& s1, const string& s2);
string replace(const string& haystack, string needle, string repl, size_t start = 0, size_t end = string::npos); string replace(
string replace_all(const string& haystack, string needle, string repl, size_t start = 0, size_t end = string::npos); const string& haystack, const string& needle, const string& reply, size_t start = 0, size_t end = string::npos);
string replace_all(
const string& haystack, const string& needle, const string& reply, size_t start = 0, size_t end = string::npos);
string replace_all_bounded(const string& haystack, string needle, string replacement, size_t min, size_t max, string replace_all_bounded(const string& haystack, string needle, string replacement, size_t min, size_t max,
size_t start = 0, size_t end = string::npos); size_t start = 0, size_t end = string::npos);
string squeeze(const string& haystack, char needle); string squeeze(const string& haystack, char needle);
@ -27,13 +29,13 @@ namespace string_util {
string rtrim(const string& haystack, char needle); string rtrim(const string& haystack, char needle);
string trim(const string& haystack, char needle); string trim(const string& haystack, char needle);
string join(vector<string> strs, string delim); string join(vector<string> strs, string delim);
vector<string>& split_into(string s, char delim, vector<string>& container); vector<string>& split_into(const string& s, char delim, vector<string>& container);
vector<string> split(const string& s, char delim); vector<string> split(const string& s, char delim);
size_t find_nth(string haystack, size_t pos, string needle, size_t nth); size_t find_nth(const string& haystack, size_t pos, const string& needle, size_t nth);
string floatval(float value, int decimals = 2, bool fixed = false, string locale = ""); string floatval(float value, int decimals = 2, bool fixed = false, const string& locale = "");
string filesize(unsigned long long bytes, int decimals = 2, bool fixed = false, string locale = ""); string filesize(unsigned long long bytes, int decimals = 2, bool fixed = false, const string& locale = "");
string from_stream(const std::basic_ostream<char>& os); string from_stream(const std::basic_ostream<char>& os);
hash_type hash(string src); hash_type hash(const string& src);
} }
POLYBAR_NS_END POLYBAR_NS_END

View File

@ -65,10 +65,10 @@ class connection : public xpp_connection {
shared_ptr<xcb_client_message_event_t> make_client_message(xcb_atom_t type, xcb_window_t target) const; shared_ptr<xcb_client_message_event_t> make_client_message(xcb_atom_t type, xcb_window_t target) const;
void send_client_message(shared_ptr<xcb_client_message_event_t> message, xcb_window_t target, void send_client_message(const shared_ptr<xcb_client_message_event_t>& message, xcb_window_t target,
uint32_t event_mask = 0xFFFFFF, bool propagate = false) const; uint32_t event_mask = 0xFFFFFF, bool propagate = false) const;
void send_dummy_event(xcb_window_t t, uint32_t ev = XCB_EVENT_MASK_STRUCTURE_NOTIFY) const; void send_dummy_event(xcb_window_t target, uint32_t event = XCB_EVENT_MASK_STRUCTURE_NOTIFY) const;
boost::optional<xcb_visualtype_t*> visual_type(xcb_screen_t* screen, int match_depth = 32); boost::optional<xcb_visualtype_t*> visual_type(xcb_screen_t* screen, int match_depth = 32);

View File

@ -42,7 +42,7 @@ class font_manager {
explicit font_manager(connection& conn, const logger& logger); explicit font_manager(connection& conn, const logger& logger);
~font_manager(); ~font_manager();
bool load(string name, int8_t fontindex = DEFAULT_FONT_INDEX, int8_t offset_y = 0); bool load(const string& name, int8_t fontindex = DEFAULT_FONT_INDEX, int8_t offset_y = 0);
void set_preferred_font(int8_t index); void set_preferred_font(int8_t index);

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <xcb/xcb.h> #include <xcb/xcb.h>
#include <chrono>
#include "common.hpp" #include "common.hpp"
#include "components/logger.hpp" #include "components/logger.hpp"
@ -20,6 +21,9 @@
POLYBAR_NS POLYBAR_NS
namespace chrono = std::chrono;
using namespace std::chrono_literals;
// fwd declarations // fwd declarations
class connection; class connection;
struct xembed_data; struct xembed_data;
@ -100,6 +104,7 @@ class tray_manager : public xpp::event::sink<evt::expose, evt::visibility_notify
void bootstrap(tray_settings settings); void bootstrap(tray_settings settings);
void activate(); void activate();
void activate_delayed(chrono::duration<double, std::milli> delay = 1s);
void deactivate(bool clear_selection = true); void deactivate(bool clear_selection = true);
void reconfigure(); void reconfigure();
@ -118,6 +123,7 @@ class tray_manager : public xpp::event::sink<evt::expose, evt::visibility_notify
void acquire_selection(); void acquire_selection();
void notify_clients(); void notify_clients();
void notify_clients_delayed(chrono::duration<double, std::milli> delay = 1s);
void track_selection_owner(xcb_window_t owner); void track_selection_owner(xcb_window_t owner);
void process_docking_request(xcb_window_t win); void process_docking_request(xcb_window_t win);
@ -168,8 +174,9 @@ class tray_manager : public xpp::event::sink<evt::expose, evt::visibility_notify
stateflag m_activated{false}; stateflag m_activated{false};
stateflag m_mapped{false}; stateflag m_mapped{false};
stateflag m_hidden{false}; stateflag m_hidden{false};
stateflag m_acquired_selection{false};
thread m_delayed_activation; thread m_delaythread;
bool m_restacked{false}; bool m_restacked{false};

View File

@ -9,7 +9,7 @@ POLYBAR_NS
class connection; class connection;
namespace wm_util { namespace wm_util {
void set_wmname(connection& conn, xcb_window_t win, string wm_name, string wm_class); void set_wmname(connection& conn, xcb_window_t win, const string& wm_name, const string& wm_class);
void set_wmprotocols(connection& conn, xcb_window_t win, vector<xcb_atom_t> flags); void set_wmprotocols(connection& conn, xcb_window_t win, vector<xcb_atom_t> flags);
void set_windowtype(connection& conn, xcb_window_t win, vector<xcb_atom_t> types); void set_windowtype(connection& conn, xcb_window_t win, vector<xcb_atom_t> types);
void set_wmstate(connection& conn, xcb_window_t win, vector<xcb_atom_t> states); void set_wmstate(connection& conn, xcb_window_t win, vector<xcb_atom_t> states);

View File

@ -15,7 +15,7 @@ class xresource_manager {
int get_int(string name, int fallback = 0) const; int get_int(string name, int fallback = 0) const;
protected: protected:
string load_value(string key, string res_type, size_t n) const; string load_value(const string& key, const string& res_type, size_t n) const;
private: private:
char* m_manager = nullptr; char* m_manager = nullptr;

View File

@ -6,36 +6,52 @@ POLYBAR_NS
// class : alsa_ctl_interface {{{ // class : alsa_ctl_interface {{{
alsa_ctl_interface::alsa_ctl_interface(int numid) : m_numid(numid) { alsa_ctl_interface::alsa_ctl_interface(int numid) : m_numid(numid) {
int err = 0;
snd_ctl_elem_info_alloca(&m_info); snd_ctl_elem_info_alloca(&m_info);
snd_ctl_elem_value_alloca(&m_value); snd_ctl_elem_value_alloca(&m_value);
snd_ctl_elem_id_alloca(&m_id); snd_ctl_elem_id_alloca(&m_id);
if (m_info == nullptr) {
throw alsa_ctl_interface_error("Failed to allocate alsa_ctl info");
}
if (m_value == nullptr) {
throw alsa_ctl_interface_error("Failed to allocate alsa_ctl value");
}
if (m_id == nullptr) {
throw alsa_ctl_interface_error("Failed to allocate alsa_ctl id");
}
snd_ctl_elem_id_set_numid(m_id, m_numid); snd_ctl_elem_id_set_numid(m_id, m_numid);
snd_ctl_elem_info_set_id(m_info, m_id); snd_ctl_elem_info_set_id(m_info, m_id);
if ((err = snd_ctl_open(&m_ctl, ALSA_SOUNDCARD, SND_CTL_NONBLOCK | SND_CTL_READONLY)) < 0) int err = 0;
throw_exception<alsa_ctl_interface_error>("Could not open control '" + string{ALSA_SOUNDCARD} + "'", err);
if ((err = snd_ctl_elem_info(m_ctl, m_info)) < 0) if ((err = snd_ctl_open(&m_ctl, ALSA_SOUNDCARD, SND_CTL_NONBLOCK | SND_CTL_READONLY)) < 0) {
throw_exception<alsa_ctl_interface_error>("Could not open control '" + string{ALSA_SOUNDCARD} + "'", err);
}
if ((err = snd_ctl_elem_info(m_ctl, m_info)) < 0) {
throw_exception<alsa_ctl_interface_error>("Could not get control datal", err); throw_exception<alsa_ctl_interface_error>("Could not get control datal", err);
}
snd_ctl_elem_info_get_id(m_info, m_id); snd_ctl_elem_info_get_id(m_info, m_id);
if ((err = snd_hctl_open(&m_hctl, ALSA_SOUNDCARD, 0)) < 0) if ((err = snd_hctl_open(&m_hctl, ALSA_SOUNDCARD, 0)) < 0) {
throw_exception<alsa_ctl_interface_error>("Failed to open hctl", err); throw_exception<alsa_ctl_interface_error>("Failed to open hctl", err);
if ((err = snd_hctl_load(m_hctl)) < 0) }
if (m_hctl == nullptr || (err = snd_hctl_load(m_hctl)) < 0) {
throw_exception<alsa_ctl_interface_error>("Failed to load hctl", err); throw_exception<alsa_ctl_interface_error>("Failed to load hctl", err);
if ((m_elem = snd_hctl_find_elem(m_hctl, m_id)) == nullptr) }
if ((m_elem = snd_hctl_find_elem(m_hctl, m_id)) == nullptr) {
throw alsa_ctl_interface_error("Could not find control with id " + to_string(snd_ctl_elem_id_get_numid(m_id))); throw alsa_ctl_interface_error("Could not find control with id " + to_string(snd_ctl_elem_id_get_numid(m_id)));
}
if ((err = snd_ctl_subscribe_events(m_ctl, 1)) < 0) if ((err = snd_ctl_subscribe_events(m_ctl, 1)) < 0) {
throw alsa_ctl_interface_error("Could not subscribe to events: " + to_string(snd_ctl_elem_id_get_numid(m_id))); throw alsa_ctl_interface_error("Could not subscribe to events: " + to_string(snd_ctl_elem_id_get_numid(m_id)));
}
} }
alsa_ctl_interface::~alsa_ctl_interface() { alsa_ctl_interface::~alsa_ctl_interface() {
std::lock_guard<concurrency_util::spin_lock> guard(m_lock); std::lock_guard<std::mutex> guard(m_lock);
snd_ctl_close(m_ctl); snd_ctl_close(m_ctl);
snd_hctl_close(m_hctl); snd_hctl_close(m_hctl);
} }
@ -47,20 +63,27 @@ int alsa_ctl_interface::get_numid() {
bool alsa_ctl_interface::wait(int timeout) { bool alsa_ctl_interface::wait(int timeout) {
assert(m_ctl); assert(m_ctl);
std::lock_guard<concurrency_util::spin_lock> guard(m_lock); if (!m_lock.try_lock()) {
return false;
}
std::lock_guard<std::mutex> guard(m_lock, std::adopt_lock);
int err = 0; int err = 0;
if ((err = snd_ctl_wait(m_ctl, timeout)) < 0) if ((err = snd_ctl_wait(m_ctl, timeout)) < 0) {
throw_exception<alsa_ctl_interface_error>("Failed to wait for events", err); throw_exception<alsa_ctl_interface_error>("Failed to wait for events", err);
}
snd_ctl_event_t* event; snd_ctl_event_t* event;
snd_ctl_event_alloca(&event); snd_ctl_event_alloca(&event);
if ((err = snd_ctl_read(m_ctl, event)) < 0) if ((err = snd_ctl_read(m_ctl, event)) < 0) {
return false; return false;
if (snd_ctl_event_get_type(event) != SND_CTL_EVENT_ELEM) }
if (snd_ctl_event_get_type(event) != SND_CTL_EVENT_ELEM) {
return false; return false;
}
auto mask = snd_ctl_event_elem_get_mask(event); auto mask = snd_ctl_event_elem_get_mask(event);
@ -71,11 +94,16 @@ bool alsa_ctl_interface::test_device_plugged() {
assert(m_elem); assert(m_elem);
assert(m_value); assert(m_value);
std::lock_guard<concurrency_util::spin_lock> guard(m_lock); if (!m_lock.try_lock()) {
return false;
}
std::lock_guard<std::mutex> guard(m_lock, std::adopt_lock);
int err = 0; int err = 0;
if ((err = snd_hctl_elem_read(m_elem, m_value)) < 0) if ((err = snd_hctl_elem_read(m_elem, m_value)) < 0) {
throw_exception<alsa_ctl_interface_error>("Could not read control value", err); throw_exception<alsa_ctl_interface_error>("Could not read control value", err);
}
return snd_ctl_elem_value_get_boolean(m_value, 0); return snd_ctl_elem_value_get_boolean(m_value, 0);
} }
@ -86,33 +114,45 @@ void alsa_ctl_interface::process_events() {
// }}} // }}}
// class : alsa_mixer {{{ // class : alsa_mixer {{{
alsa_mixer::alsa_mixer(string mixer_control_name) : m_name(mixer_control_name) { alsa_mixer::alsa_mixer(const string& mixer_control_name) : m_name(mixer_control_name) {
snd_mixer_selem_id_t* mixer_id; if (m_name.empty()) {
throw alsa_mixer_error("Invalid control name");
}
snd_mixer_selem_id_t* mixer_id{nullptr};
snd_mixer_selem_id_alloca(&mixer_id); snd_mixer_selem_id_alloca(&mixer_id);
if (mixer_id == nullptr) {
throw alsa_mixer_error("Failed to allocate mixer id");
}
int err = 0; int err = 0;
if ((err = snd_mixer_open(&m_hardwaremixer, 1)) < 0) if ((err = snd_mixer_open(&m_hardwaremixer, 1)) < 0) {
throw_exception<alsa_mixer_error>("Failed to open hardware mixer", err); throw_exception<alsa_mixer_error>("Failed to open hardware mixer", err);
if ((err = snd_mixer_attach(m_hardwaremixer, ALSA_SOUNDCARD)) < 0) }
if ((err = snd_mixer_attach(m_hardwaremixer, ALSA_SOUNDCARD)) < 0) {
throw_exception<alsa_mixer_error>("Failed to attach hardware mixer control", err); throw_exception<alsa_mixer_error>("Failed to attach hardware mixer control", err);
if ((err = snd_mixer_selem_register(m_hardwaremixer, nullptr, nullptr)) < 0) }
if ((err = snd_mixer_selem_register(m_hardwaremixer, nullptr, nullptr)) < 0) {
throw_exception<alsa_mixer_error>("Failed to register simple mixer element", err); throw_exception<alsa_mixer_error>("Failed to register simple mixer element", err);
if ((err = snd_mixer_load(m_hardwaremixer)) < 0) }
if ((err = snd_mixer_load(m_hardwaremixer)) < 0) {
throw_exception<alsa_mixer_error>("Failed to load mixer", err); throw_exception<alsa_mixer_error>("Failed to load mixer", err);
}
snd_mixer_selem_id_set_index(mixer_id, 0); snd_mixer_selem_id_set_index(mixer_id, 0);
snd_mixer_selem_id_set_name(mixer_id, mixer_control_name.c_str()); snd_mixer_selem_id_set_name(mixer_id, m_name.c_str());
if ((m_mixerelement = snd_mixer_find_selem(m_hardwaremixer, mixer_id)) == nullptr) if ((m_mixerelement = snd_mixer_find_selem(m_hardwaremixer, mixer_id)) == nullptr) {
throw alsa_mixer_error("Cannot find simple element"); throw alsa_mixer_error("Cannot find simple element");
}
// log_trace("Successfully initialized mixer: "+ mixer_control_name); // log_trace("Successfully initialized mixer: "+ string{m_name});
} }
alsa_mixer::~alsa_mixer() { alsa_mixer::~alsa_mixer() {
std::lock_guard<concurrency_util::spin_lock> guard(m_lock); std::lock_guard<std::mutex> guard(m_lock);
snd_mixer_elem_remove(m_mixerelement); snd_mixer_elem_remove(m_mixerelement);
snd_mixer_detach(m_hardwaremixer, ALSA_SOUNDCARD); snd_mixer_detach(m_hardwaremixer, ALSA_SOUNDCARD);
snd_mixer_close(m_hardwaremixer); snd_mixer_close(m_hardwaremixer);
@ -125,12 +165,17 @@ string alsa_mixer::get_name() {
bool alsa_mixer::wait(int timeout) { bool alsa_mixer::wait(int timeout) {
assert(m_hardwaremixer); assert(m_hardwaremixer);
std::unique_lock<concurrency_util::spin_lock> guard(m_lock); if (!m_lock.try_lock()) {
return false;
}
std::unique_lock<std::mutex> guard(m_lock, std::adopt_lock);
int err = 0; int err = 0;
if ((err = snd_mixer_wait(m_hardwaremixer, timeout)) < 0) if ((err = snd_mixer_wait(m_hardwaremixer, timeout)) < 0) {
throw_exception<alsa_mixer_error>("Failed to wait for events", err); throw_exception<alsa_mixer_error>("Failed to wait for events", err);
}
guard.unlock(); guard.unlock();
@ -138,18 +183,28 @@ bool alsa_mixer::wait(int timeout) {
} }
int alsa_mixer::process_events() { int alsa_mixer::process_events() {
std::lock_guard<concurrency_util::spin_lock> guard(m_lock); if (!m_lock.try_lock()) {
return false;
}
std::lock_guard<std::mutex> guard(m_lock, std::adopt_lock);
int num_events = snd_mixer_handle_events(m_hardwaremixer); int num_events = snd_mixer_handle_events(m_hardwaremixer);
if (num_events < 0) if (num_events < 0) {
throw_exception<alsa_mixer_error>("Failed to process pending events", num_events); throw_exception<alsa_mixer_error>("Failed to process pending events", num_events);
}
return num_events; return num_events;
} }
int alsa_mixer::get_volume() { int alsa_mixer::get_volume() {
std::lock_guard<concurrency_util::spin_lock> guard(m_lock); if (!m_lock.try_lock()) {
return 0;
}
std::lock_guard<std::mutex> guard(m_lock, std::adopt_lock);
long chan_n = 0, vol_total = 0, vol, vol_min, vol_max; long chan_n = 0, vol_total = 0, vol, vol_min, vol_max;
snd_mixer_selem_get_playback_volume_range(m_mixerelement, &vol_min, &vol_max); snd_mixer_selem_get_playback_volume_range(m_mixerelement, &vol_min, &vol_max);
@ -166,7 +221,12 @@ int alsa_mixer::get_volume() {
} }
int alsa_mixer::get_normalized_volume() { int alsa_mixer::get_normalized_volume() {
std::lock_guard<concurrency_util::spin_lock> guard(m_lock); if (!m_lock.try_lock()) {
return 0;
}
std::lock_guard<std::mutex> guard(m_lock, std::adopt_lock);
long chan_n = 0, vol_total = 0, vol, vol_min, vol_max; long chan_n = 0, vol_total = 0, vol, vol_min, vol_max;
double normalized, min_norm; double normalized, min_norm;
@ -180,8 +240,9 @@ int alsa_mixer::get_normalized_volume() {
} }
} }
if (vol_max - vol_min <= MAX_LINEAR_DB_SCALE * 100) if (vol_max - vol_min <= MAX_LINEAR_DB_SCALE * 100) {
return math_util::percentage(vol_total / chan_n, vol_min, vol_max); return math_util::percentage(vol_total / chan_n, vol_min, vol_max);
}
normalized = pow10((vol_total / chan_n - vol_max) / 6000.0); normalized = pow10((vol_total / chan_n - vol_max) / 6000.0);
if (vol_min != SND_CTL_TLV_DB_GAIN_MUTE) { if (vol_min != SND_CTL_TLV_DB_GAIN_MUTE) {
@ -193,10 +254,15 @@ int alsa_mixer::get_normalized_volume() {
} }
void alsa_mixer::set_volume(float percentage) { void alsa_mixer::set_volume(float percentage) {
if (is_muted()) if (is_muted()) {
return; return;
}
std::lock_guard<concurrency_util::spin_lock> guard(m_lock); if (!m_lock.try_lock()) {
return;
}
std::lock_guard<std::mutex> guard(m_lock, std::adopt_lock);
long vol_min, vol_max; long vol_min, vol_max;
snd_mixer_selem_get_playback_volume_range(m_mixerelement, &vol_min, &vol_max); snd_mixer_selem_get_playback_volume_range(m_mixerelement, &vol_min, &vol_max);
@ -205,10 +271,15 @@ void alsa_mixer::set_volume(float percentage) {
} }
void alsa_mixer::set_normalized_volume(float percentage) { void alsa_mixer::set_normalized_volume(float percentage) {
if (is_muted()) if (is_muted()) {
return; return;
}
std::lock_guard<concurrency_util::spin_lock> guard(m_lock); if (!m_lock.try_lock()) {
return;
}
std::lock_guard<std::mutex> guard(m_lock, std::adopt_lock);
long vol_min, vol_max; long vol_min, vol_max;
double min_norm; double min_norm;
@ -230,20 +301,37 @@ void alsa_mixer::set_normalized_volume(float percentage) {
} }
void alsa_mixer::set_mute(bool mode) { void alsa_mixer::set_mute(bool mode) {
std::lock_guard<concurrency_util::spin_lock> guard(m_lock); if (!m_lock.try_lock()) {
return;
}
std::lock_guard<std::mutex> guard(m_lock, std::adopt_lock);
snd_mixer_selem_set_playback_switch_all(m_mixerelement, mode); snd_mixer_selem_set_playback_switch_all(m_mixerelement, mode);
} }
void alsa_mixer::toggle_mute() { void alsa_mixer::toggle_mute() {
std::lock_guard<concurrency_util::spin_lock> guard(m_lock); if (!m_lock.try_lock()) {
return;
}
std::lock_guard<std::mutex> guard(m_lock, std::adopt_lock);
int state; int state;
snd_mixer_selem_get_playback_switch(m_mixerelement, SND_MIXER_SCHN_MONO, &state); snd_mixer_selem_get_playback_switch(m_mixerelement, SND_MIXER_SCHN_MONO, &state);
snd_mixer_selem_set_playback_switch_all(m_mixerelement, !state); snd_mixer_selem_set_playback_switch_all(m_mixerelement, !state);
} }
bool alsa_mixer::is_muted() { bool alsa_mixer::is_muted() {
std::lock_guard<concurrency_util::spin_lock> guard(m_lock); if (!m_lock.try_lock()) {
return false;
}
std::lock_guard<std::mutex> guard(m_lock, std::adopt_lock);
int state = 0; int state = 0;
for (int i = 0; i <= SND_MIXER_SCHN_LAST; i++) { for (int i = 0; i <= SND_MIXER_SCHN_LAST; i++) {
if (snd_mixer_selem_has_playback_channel(m_mixerelement, static_cast<snd_mixer_selem_channel_id_t>(i))) { if (snd_mixer_selem_has_playback_channel(m_mixerelement, static_cast<snd_mixer_selem_channel_id_t>(i))) {
int state_ = 0; int state_ = 0;

View File

@ -1,5 +1,6 @@
#include <cassert> #include <cassert>
#include <thread> #include <thread>
#include <utility>
#include "adapters/mpd.hpp" #include "adapters/mpd.hpp"
#include "components/logger.hpp" #include "components/logger.hpp"
@ -9,15 +10,17 @@ POLYBAR_NS
namespace mpd { namespace mpd {
void check_connection(mpd_connection* conn) { void check_connection(mpd_connection* conn) {
if (conn == nullptr) if (conn == nullptr) {
throw client_error("Not connected to MPD server", MPD_ERROR_STATE); throw client_error("Not connected to MPD server", MPD_ERROR_STATE);
} }
}
void check_errors(mpd_connection* conn) { void check_errors(mpd_connection* conn) {
mpd_error code = mpd_connection_get_error(conn); mpd_error code = mpd_connection_get_error(conn);
if (code == MPD_ERROR_SUCCESS) if (code == MPD_ERROR_SUCCESS) {
return; return;
}
auto msg = mpd_connection_get_error_message(conn); auto msg = mpd_connection_get_error_message(conn);
@ -34,9 +37,10 @@ namespace mpd {
namespace details { namespace details {
void mpd_connection_deleter::operator()(mpd_connection* conn) { void mpd_connection_deleter::operator()(mpd_connection* conn) {
if (conn != nullptr) if (conn != nullptr) {
mpd_connection_free(conn); mpd_connection_free(conn);
} }
}
void mpd_status_deleter::operator()(mpd_status* status) { void mpd_status_deleter::operator()(mpd_status* status) {
mpd_status_free(status); mpd_status_free(status);
@ -51,30 +55,33 @@ namespace mpd {
// class: mpdsong {{{ // class: mpdsong {{{
mpdsong::operator bool() { mpdsong::operator bool() {
return m_song.get() != nullptr; return m_song != nullptr;
} }
string mpdsong::get_artist() { string mpdsong::get_artist() {
assert(m_song); assert(m_song);
auto tag = mpd_song_get_tag(m_song.get(), MPD_TAG_ARTIST, 0); auto tag = mpd_song_get_tag(m_song.get(), MPD_TAG_ARTIST, 0);
if (tag == nullptr) if (tag == nullptr) {
return ""; return "";
}
return string{tag}; return string{tag};
} }
string mpdsong::get_album() { string mpdsong::get_album() {
assert(m_song); assert(m_song);
auto tag = mpd_song_get_tag(m_song.get(), MPD_TAG_ALBUM, 0); auto tag = mpd_song_get_tag(m_song.get(), MPD_TAG_ALBUM, 0);
if (tag == nullptr) if (tag == nullptr) {
return ""; return "";
}
return string{tag}; return string{tag};
} }
string mpdsong::get_title() { string mpdsong::get_title() {
assert(m_song); assert(m_song);
auto tag = mpd_song_get_tag(m_song.get(), MPD_TAG_TITLE, 0); auto tag = mpd_song_get_tag(m_song.get(), MPD_TAG_TITLE, 0);
if (tag == nullptr) if (tag == nullptr) {
return ""; return "";
}
return string{tag}; return string{tag};
} }
@ -88,7 +95,7 @@ namespace mpd {
mpdconnection::mpdconnection( mpdconnection::mpdconnection(
const logger& logger, string host, unsigned int port, string password, unsigned int timeout) const logger& logger, string host, unsigned int port, string password, unsigned int timeout)
: m_log(logger), m_host(host), m_port(port), m_password(password), m_timeout(timeout) {} : m_log(logger), m_host(move(host)), m_port(port), m_password(move(password)), m_timeout(timeout) {}
void mpdconnection::connect() { void mpdconnection::connect() {
try { try {
@ -118,14 +125,16 @@ namespace mpd {
} }
bool mpdconnection::connected() { bool mpdconnection::connected() {
if (!m_connection) if (!m_connection) {
return false; return false;
return m_connection.get() != nullptr; }
return m_connection != nullptr;
} }
bool mpdconnection::retry_connection(int interval) { bool mpdconnection::retry_connection(int interval) {
if (connected()) if (connected()) {
return true; return true;
}
while (true) { while (true) {
try { try {
@ -146,8 +155,9 @@ namespace mpd {
void mpdconnection::idle() { void mpdconnection::idle() {
check_connection(m_connection.get()); check_connection(m_connection.get());
if (m_idle) if (m_idle) {
return; return;
}
mpd_send_idle(m_connection.get()); mpd_send_idle(m_connection.get());
check_errors(m_connection.get()); check_errors(m_connection.get());
m_idle = true; m_idle = true;
@ -188,8 +198,8 @@ namespace mpd {
mpd_song_t song{mpd_recv_song(m_connection.get()), mpd_song_t::deleter_type{}}; mpd_song_t song{mpd_recv_song(m_connection.get()), mpd_song_t::deleter_type{}};
mpd_response_finish(m_connection.get()); mpd_response_finish(m_connection.get());
check_errors(m_connection.get()); check_errors(m_connection.get());
if (song.get() != nullptr) { if (song != nullptr) {
return make_unique<mpdsong>(std::move(song)); return make_unique<mpdsong>(move(song));
} }
return unique_ptr<mpdsong>{}; return unique_ptr<mpdsong>{};
} }
@ -314,9 +324,10 @@ namespace mpd {
mpdstatus::mpdstatus(mpdconnection* conn, bool autoupdate) { mpdstatus::mpdstatus(mpdconnection* conn, bool autoupdate) {
fetch_data(conn); fetch_data(conn);
if (autoupdate) if (autoupdate) {
update(-1, conn); update(-1, conn);
} }
}
void mpdstatus::fetch_data(mpdconnection* conn) { void mpdstatus::fetch_data(mpdconnection* conn) {
m_status.reset(mpd_run_status(*conn)); m_status.reset(mpd_run_status(*conn));
@ -331,8 +342,9 @@ namespace mpd {
} }
void mpdstatus::update(int event, mpdconnection* connection) { void mpdstatus::update(int event, mpdconnection* connection) {
if (connection == nullptr || (event & (MPD_IDLE_PLAYER | MPD_IDLE_OPTIONS | MPD_IDLE_PLAYLIST)) == false) if (connection == nullptr || !static_cast<bool>(event & (MPD_IDLE_PLAYER | MPD_IDLE_OPTIONS | MPD_IDLE_PLAYLIST))) {
return; return;
}
fetch_data(connection); fetch_data(connection);
@ -396,8 +408,9 @@ namespace mpd {
} }
unsigned mpdstatus::get_elapsed_percentage() { unsigned mpdstatus::get_elapsed_percentage() {
if (m_total_time == 0) if (m_total_time == 0) {
return 0; return 0;
}
return static_cast<int>(float(m_elapsed_time) / float(m_total_time) * 100.0 + 0.5f); return static_cast<int>(float(m_elapsed_time) / float(m_total_time) * 100.0 + 0.5f);
} }
@ -414,8 +427,9 @@ namespace mpd {
} }
int mpdstatus::get_seek_position(int percentage) { int mpdstatus::get_seek_position(int percentage) {
if (m_total_time == 0) if (m_total_time == 0) {
return 0; return 0;
}
math_util::cap<int>(0, 100, percentage); math_util::cap<int>(0, 100, percentage);
return float(m_total_time) * percentage / 100.0f + 0.5f; return float(m_total_time) * percentage / 100.0f + 0.5f;
} }

View File

@ -6,15 +6,16 @@
#include <iomanip> #include <iomanip>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <utility>
#include <limits.h>
#include <linux/ethtool.h> #include <linux/ethtool.h>
#include <linux/if_link.h> #include <linux/if_link.h>
#include <linux/sockios.h> #include <linux/sockios.h>
#include <net/if.h> #include <net/if.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <signal.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <climits>
#include <csignal>
#ifdef inline #ifdef inline
#undef inline #undef inline
@ -32,7 +33,7 @@ namespace net {
/** /**
* Test if interface with given name is a wireless device * Test if interface with given name is a wireless device
*/ */
bool is_wireless_interface(string ifname) { bool is_wireless_interface(const string& ifname) {
return file_util::exists("/sys/class/net/" + ifname + "/wireless"); return file_util::exists("/sys/class/net/" + ifname + "/wireless");
} }
@ -41,11 +42,13 @@ namespace net {
/** /**
* Construct network interface * Construct network interface
*/ */
network::network(string interface) : m_interface(interface) { network::network(string interface) : m_interface(move(interface)) {
if (if_nametoindex(m_interface.c_str()) == 0) if (if_nametoindex(m_interface.c_str()) == 0) {
throw network_error("Invalid network interface \"" + m_interface + "\""); throw network_error("Invalid network interface \"" + m_interface + "\"");
if ((m_socketfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) }
if ((m_socketfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
throw network_error("Failed to open socket"); throw network_error("Failed to open socket");
}
check_tuntap(); check_tuntap();
} }
@ -53,9 +56,10 @@ namespace net {
* Destruct network interface * Destruct network interface
*/ */
network::~network() { network::~network() {
if (m_socketfd != -1) if (m_socketfd != -1) {
close(m_socketfd); close(m_socketfd);
} }
}
/** /**
* Query device driver for information * Query device driver for information
@ -63,8 +67,9 @@ namespace net {
bool network::query(bool accumulate) { bool network::query(bool accumulate) {
struct ifaddrs* ifaddr; struct ifaddrs* ifaddr;
if (getifaddrs(&ifaddr) == -1 || ifaddr == nullptr) if (getifaddrs(&ifaddr) == -1 || ifaddr == nullptr) {
return false; return false;
}
m_status.previous = m_status.current; m_status.previous = m_status.current;
m_status.current.transmitted = 0; m_status.current.transmitted = 0;
@ -72,12 +77,15 @@ namespace net {
m_status.current.time = chrono::system_clock::now(); m_status.current.time = chrono::system_clock::now();
for (auto ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) { for (auto ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == nullptr) if (ifa->ifa_addr == nullptr) {
continue; continue;
}
if (m_interface.compare(0, m_interface.length(), ifa->ifa_name) != 0) if (m_interface.compare(0, m_interface.length(), ifa->ifa_name) != 0) {
if (!accumulate || (ifa->ifa_data == nullptr && ifa->ifa_addr->sa_family != AF_PACKET)) if (!accumulate || (ifa->ifa_data == nullptr && ifa->ifa_addr->sa_family != AF_PACKET)) {
continue; continue;
}
}
switch (ifa->ifa_addr->sa_family) { switch (ifa->ifa_addr->sa_family) {
case AF_INET: case AF_INET:
@ -87,11 +95,13 @@ namespace net {
break; break;
case AF_PACKET: case AF_PACKET:
if (ifa->ifa_data == nullptr) if (ifa->ifa_data == nullptr) {
continue; continue;
}
struct rtnl_link_stats* link_state = reinterpret_cast<decltype(link_state)>(ifa->ifa_data); struct rtnl_link_stats* link_state = reinterpret_cast<decltype(link_state)>(ifa->ifa_data);
if (link_state == nullptr) if (link_state == nullptr) {
continue; continue;
}
m_status.current.transmitted += link_state->tx_bytes; m_status.current.transmitted += link_state->tx_bytes;
m_status.current.received += link_state->rx_bytes; m_status.current.received += link_state->rx_bytes;
break; break;
@ -153,17 +163,19 @@ namespace net {
request.ifr_data = reinterpret_cast<caddr_t>(&driver); request.ifr_data = reinterpret_cast<caddr_t>(&driver);
if (ioctl(m_socketfd, SIOCETHTOOL, &request) == -1) if (ioctl(m_socketfd, SIOCETHTOOL, &request) == -1) {
return; return;
}
// Check if it's a TUN/TAP device // Check if it's a TUN/TAP device
if (strncmp(driver.bus_info, "tun", 3) == 0) if (strncmp(driver.bus_info, "tun", 3) == 0) {
m_tuntap = true; m_tuntap = true;
else if (strncmp(driver.bus_info, "tap", 3) == 0) } else if (strncmp(driver.bus_info, "tap", 3) == 0) {
m_tuntap = true; m_tuntap = true;
else } else {
m_tuntap = false; m_tuntap = false;
} }
}
/** /**
* Test if the network interface is in a valid state * Test if the network interface is in a valid state
@ -200,10 +212,11 @@ namespace net {
* Query device driver for information * Query device driver for information
*/ */
bool wired_network::query(bool accumulate) { bool wired_network::query(bool accumulate) {
if (m_tuntap) if (m_tuntap) {
return true; return true;
else if (!network::query(accumulate)) } else if (!network::query(accumulate)) {
return false; return false;
}
struct ifreq request; struct ifreq request;
struct ethtool_cmd data; struct ethtool_cmd data;
@ -212,8 +225,9 @@ namespace net {
data.cmd = ETHTOOL_GSET; data.cmd = ETHTOOL_GSET;
request.ifr_data = reinterpret_cast<caddr_t>(&data); request.ifr_data = reinterpret_cast<caddr_t>(&data);
if (ioctl(m_socketfd, SIOCETHTOOL, &request) == -1) if (ioctl(m_socketfd, SIOCETHTOOL, &request) == -1) {
return false; return false;
}
m_linkspeed = data.speed; m_linkspeed = data.speed;
@ -224,8 +238,9 @@ namespace net {
* Check current connection state * Check current connection state
*/ */
bool wired_network::connected() const { bool wired_network::connected() const {
if (!m_tuntap && !network::test_interface()) if (!m_tuntap && !network::test_interface()) {
return false; return false;
}
struct ethtool_value data; struct ethtool_value data;
struct ifreq request; struct ifreq request;
@ -234,8 +249,9 @@ namespace net {
data.cmd = ETHTOOL_GLINK; data.cmd = ETHTOOL_GLINK;
request.ifr_data = reinterpret_cast<caddr_t>(&data); request.ifr_data = reinterpret_cast<caddr_t>(&data);
if (ioctl(m_socketfd, SIOCETHTOOL, &request) == -1) if (ioctl(m_socketfd, SIOCETHTOOL, &request) == -1) {
return false; return false;
}
return data.data != 0; return data.data != 0;
} }
@ -256,22 +272,26 @@ namespace net {
* about the current connection * about the current connection
*/ */
bool wireless_network::query(bool accumulate) { bool wireless_network::query(bool accumulate) {
if (!network::query(accumulate)) if (!network::query(accumulate)) {
return false; return false;
}
auto socket_fd = iw_sockets_open(); auto socket_fd = iw_sockets_open();
if (socket_fd == -1) if (socket_fd == -1) {
return false; return false;
}
struct iwreq req; struct iwreq req;
if (iw_get_ext(socket_fd, m_interface.c_str(), SIOCGIWMODE, &req) == -1) if (iw_get_ext(socket_fd, m_interface.c_str(), SIOCGIWMODE, &req) == -1) {
return false; return false;
}
// Ignore interfaces in ad-hoc mode // Ignore interfaces in ad-hoc mode
if (req.u.mode == IW_MODE_ADHOC) if (req.u.mode == IW_MODE_ADHOC) {
return false; return false;
}
query_essid(socket_fd); query_essid(socket_fd);
query_quality(socket_fd); query_quality(socket_fd);
@ -285,8 +305,9 @@ namespace net {
* Check current connection state * Check current connection state
*/ */
bool wireless_network::connected() const { bool wireless_network::connected() const {
if (!network::test_interface()) if (!network::test_interface()) {
return false; return false;
}
return !m_essid.empty(); return !m_essid.empty();
} }
@ -337,18 +358,22 @@ namespace net {
iwstats stats; iwstats stats;
// Fill range // Fill range
if (iw_get_range_info(socket_fd, m_interface.c_str(), &range) == -1) if (iw_get_range_info(socket_fd, m_interface.c_str(), &range) == -1) {
return; return;
}
// Fill stats // Fill stats
if (iw_get_stats(socket_fd, m_interface.c_str(), &stats, &range, 1) == -1) if (iw_get_stats(socket_fd, m_interface.c_str(), &stats, &range, 1) == -1) {
return; return;
}
// Check if the driver supplies the quality value // Check if the driver supplies the quality value
if (stats.qual.updated & IW_QUAL_QUAL_INVALID) if (stats.qual.updated & IW_QUAL_QUAL_INVALID) {
return; return;
}
// Check if the driver supplies the quality level value // Check if the driver supplies the quality level value
if (stats.qual.updated & IW_QUAL_LEVEL_INVALID) if (stats.qual.updated & IW_QUAL_LEVEL_INVALID) {
return; return;
}
// Check if the link quality has been uodated // Check if the link quality has been uodated
if (stats.qual.updated & IW_QUAL_QUAL_UPDATED) { if (stats.qual.updated & IW_QUAL_QUAL_UPDATED) {

View File

@ -71,8 +71,9 @@ void bar::bootstrap(bool nodraw) {
m_opts.wmname = m_conf.get<string>(bs, "wm-name", "polybar-" + bs.substr(4) + "_" + m_opts.monitor->name); m_opts.wmname = m_conf.get<string>(bs, "wm-name", "polybar-" + bs.substr(4) + "_" + m_opts.monitor->name);
m_opts.wmname = string_util::replace(m_opts.wmname, " ", "-"); m_opts.wmname = string_util::replace(m_opts.wmname, " ", "-");
if (m_conf.get<bool>(bs, "bottom", false)) if (m_conf.get<bool>(bs, "bottom", false)) {
m_opts.origin = edge::BOTTOM; m_opts.origin = edge::BOTTOM;
}
GET_CONFIG_VALUE(bs, m_opts.force_docking, "dock"); GET_CONFIG_VALUE(bs, m_opts.force_docking, "dock");
GET_CONFIG_VALUE(bs, m_opts.spacing, "spacing"); GET_CONFIG_VALUE(bs, m_opts.spacing, "spacing");
@ -196,14 +197,15 @@ void bar::bootstrap_tray() {
auto bs = m_conf.bar_section(); auto bs = m_conf.bar_section();
auto tray_position = m_conf.get<string>(bs, "tray-position", ""); auto tray_position = m_conf.get<string>(bs, "tray-position", "");
if (tray_position == "left") if (tray_position == "left") {
settings.align = alignment::LEFT; settings.align = alignment::LEFT;
else if (tray_position == "right") } else if (tray_position == "right") {
settings.align = alignment::RIGHT; settings.align = alignment::RIGHT;
else if (tray_position == "center") } else if (tray_position == "center") {
settings.align = alignment::CENTER; settings.align = alignment::CENTER;
else } else {
settings.align = alignment::NONE; settings.align = alignment::NONE;
}
if (settings.align == alignment::NONE) { if (settings.align == alignment::NONE) {
m_log.warn("Disabling tray manager (reason: disabled in config)"); m_log.warn("Disabling tray manager (reason: disabled in config)");
@ -275,12 +277,12 @@ void bar::bootstrap_tray() {
auto offset_x = atoi(offset_x_def.c_str()); auto offset_x = atoi(offset_x_def.c_str());
auto offset_y = atoi(offset_y_def.c_str()); auto offset_y = atoi(offset_y_def.c_str());
if (offset_x != 0 && offset_x_def.find("%") != string::npos) { if (offset_x != 0 && offset_x_def.find('%') != string::npos) {
offset_x = math_util::percentage_to_value<int>(offset_x, m_opts.monitor->w); offset_x = math_util::percentage_to_value<int>(offset_x, m_opts.monitor->w);
offset_x -= settings.width / 2; offset_x -= settings.width / 2;
} }
if (offset_y != 0 && offset_y_def.find("%") != string::npos) { if (offset_y != 0 && offset_y_def.find('%') != string::npos) {
offset_y = math_util::percentage_to_value<int>(offset_y, m_opts.monitor->h); offset_y = math_util::percentage_to_value<int>(offset_y, m_opts.monitor->h);
offset_y -= settings.width / 2; offset_y -= settings.width / 2;
} }
@ -348,26 +350,28 @@ const bar_settings bar::settings() const {
* @param data Input string * @param data Input string
* @param force Unless true, do not parse unchanged data * @param force Unless true, do not parse unchanged data
*/ */
void bar::parse(string data, bool force) { void bar::parse(const string& data, bool force) {
if (!m_mutex.try_lock()) { if (!m_mutex.try_lock()) {
return; return;
} }
std::lock_guard<std::mutex> guard(m_mutex, std::adopt_lock); std::lock_guard<std::mutex> guard(m_mutex, std::adopt_lock);
if (data == m_lastinput && !force) if (data == m_lastinput && !force) {
return; return;
}
m_lastinput = data; m_lastinput = data;
m_renderer->begin(); m_renderer->begin();
if (m_trayclients) { if (m_trayclients) {
if (m_tray && m_trayalign == alignment::LEFT) if (m_tray && m_trayalign == alignment::LEFT) {
m_renderer->reserve_space(edge::LEFT, m_tray->settings().configured_w); m_renderer->reserve_space(edge::LEFT, m_tray->settings().configured_w);
else if (m_tray && m_trayalign == alignment::RIGHT) } else if (m_tray && m_trayalign == alignment::RIGHT) {
m_renderer->reserve_space(edge::RIGHT, m_tray->settings().configured_w); m_renderer->reserve_space(edge::RIGHT, m_tray->settings().configured_w);
} }
}
m_renderer->fill_background(); m_renderer->fill_background();
@ -394,22 +398,22 @@ void bar::configure_geom() {
auto offsety = m_conf.get<string>(m_conf.bar_section(), "offset-y", ""); auto offsety = m_conf.get<string>(m_conf.bar_section(), "offset-y", "");
// look for user-defined width // look for user-defined width
if ((m_opts.size.w = atoi(w.c_str())) && w.find("%") != string::npos) { if ((m_opts.size.w = atoi(w.c_str())) && w.find('%') != string::npos) {
m_opts.size.w = math_util::percentage_to_value<int>(m_opts.size.w, m_opts.monitor->w); m_opts.size.w = math_util::percentage_to_value<int>(m_opts.size.w, m_opts.monitor->w);
} }
// look for user-defined height // look for user-defined height
if ((m_opts.size.h = atoi(h.c_str())) && h.find("%") != string::npos) { if ((m_opts.size.h = atoi(h.c_str())) && h.find('%') != string::npos) {
m_opts.size.h = math_util::percentage_to_value<int>(m_opts.size.h, m_opts.monitor->h); m_opts.size.h = math_util::percentage_to_value<int>(m_opts.size.h, m_opts.monitor->h);
} }
// look for user-defined offset-x // look for user-defined offset-x
if ((m_opts.offset.x = atoi(offsetx.c_str())) != 0 && offsetx.find("%") != string::npos) { if ((m_opts.offset.x = atoi(offsetx.c_str())) != 0 && offsetx.find('%') != string::npos) {
m_opts.offset.x = math_util::percentage_to_value<int>(m_opts.offset.x, m_opts.monitor->w); m_opts.offset.x = math_util::percentage_to_value<int>(m_opts.offset.x, m_opts.monitor->w);
} }
// look for user-defined offset-y // look for user-defined offset-y
if ((m_opts.offset.y = atoi(offsety.c_str())) != 0 && offsety.find("%") != string::npos) { if ((m_opts.offset.y = atoi(offsety.c_str())) != 0 && offsety.find('%') != string::npos) {
m_opts.offset.y = math_util::percentage_to_value<int>(m_opts.offset.y, m_opts.monitor->h); m_opts.offset.y = math_util::percentage_to_value<int>(m_opts.offset.y, m_opts.monitor->h);
} }
@ -421,13 +425,16 @@ void bar::configure_geom() {
m_opts.size.h += m_opts.borders[edge::TOP].size; m_opts.size.h += m_opts.borders[edge::TOP].size;
m_opts.size.h += m_opts.borders[edge::BOTTOM].size; m_opts.size.h += m_opts.borders[edge::BOTTOM].size;
if (m_opts.origin == edge::BOTTOM) if (m_opts.origin == edge::BOTTOM) {
m_opts.pos.y = m_opts.monitor->y + m_opts.monitor->h - m_opts.size.h - m_opts.offset.y; m_opts.pos.y = m_opts.monitor->y + m_opts.monitor->h - m_opts.size.h - m_opts.offset.y;
}
if (m_opts.size.w <= 0 || m_opts.size.w > m_opts.monitor->w) if (m_opts.size.w <= 0 || m_opts.size.w > m_opts.monitor->w) {
throw application_error("Resulting bar width is out of bounds"); throw application_error("Resulting bar width is out of bounds");
if (m_opts.size.h <= 0 || m_opts.size.h > m_opts.monitor->h) }
if (m_opts.size.h <= 0 || m_opts.size.h > m_opts.monitor->h) {
throw application_error("Resulting bar height is out of bounds"); throw application_error("Resulting bar height is out of bounds");
}
m_opts.size.w = math_util::cap<int>(m_opts.size.w, 0, m_opts.monitor->w); m_opts.size.w = math_util::cap<int>(m_opts.size.w, 0, m_opts.monitor->w);
m_opts.size.h = math_util::cap<int>(m_opts.size.h, 0, m_opts.monitor->h); m_opts.size.h = math_util::cap<int>(m_opts.size.h, 0, m_opts.monitor->h);
@ -604,10 +611,11 @@ void bar::handle(const evt::button_press& evt) {
m_log.trace_x("action.start_x = %i", action.start_x); m_log.trace_x("action.start_x = %i", action.start_x);
m_log.trace_x("action.end_x = %i", action.end_x); m_log.trace_x("action.end_x = %i", action.end_x);
if (g_signals::bar::action_click) if (g_signals::bar::action_click) {
g_signals::bar::action_click(action.command); g_signals::bar::action_click(action.command);
else } else {
m_log.warn("No signal handler's connected to 'action_click'"); m_log.warn("No signal handler's connected to 'action_click'");
}
return; return;
} }
@ -652,14 +660,15 @@ void bar::handle(const evt::property_notify& evt) {
try { try {
auto attr = m_connection.get_window_attributes(m_window); auto attr = m_connection.get_window_attributes(m_window);
if (attr->map_state == XCB_MAP_STATE_VIEWABLE) if (attr->map_state == XCB_MAP_STATE_VIEWABLE) {
g_signals::bar::visibility_change(true); g_signals::bar::visibility_change(true);
else if (attr->map_state == XCB_MAP_STATE_UNVIEWABLE) } else if (attr->map_state == XCB_MAP_STATE_UNVIEWABLE) {
g_signals::bar::visibility_change(false); g_signals::bar::visibility_change(false);
else if (attr->map_state == XCB_MAP_STATE_UNMAPPED) } else if (attr->map_state == XCB_MAP_STATE_UNMAPPED) {
g_signals::bar::visibility_change(false); g_signals::bar::visibility_change(false);
else } else {
g_signals::bar::visibility_change(true); g_signals::bar::visibility_change(true);
}
} catch (const exception& err) { } catch (const exception& err) {
m_log.warn("Failed to emit bar window's visibility change event"); m_log.warn("Failed to emit bar window's visibility change event");
} }

View File

@ -1,3 +1,5 @@
#include <utility>
#include "components/builder.hpp" #include "components/builder.hpp"
#include "drawtypes/label.hpp" #include "drawtypes/label.hpp"
@ -12,20 +14,27 @@ POLYBAR_NS
* This will also close any unclosed tags * This will also close any unclosed tags
*/ */
string builder::flush() { string builder::flush() {
if (m_tags[syntaxtag::B]) if (m_tags[syntaxtag::B]) {
background_close(); background_close();
if (m_tags[syntaxtag::F]) }
if (m_tags[syntaxtag::F]) {
color_close(); color_close();
if (m_tags[syntaxtag::T]) }
if (m_tags[syntaxtag::T]) {
font_close(); font_close();
if (m_tags[syntaxtag::o]) }
if (m_tags[syntaxtag::o]) {
overline_color_close(); overline_color_close();
if (m_tags[syntaxtag::u]) }
if (m_tags[syntaxtag::u]) {
underline_color_close(); underline_color_close();
if ((m_attributes >> static_cast<uint8_t>(attribute::UNDERLINE)) & 1U) }
if ((m_attributes >> static_cast<uint8_t>(attribute::UNDERLINE)) & 1U) {
underline_close(); underline_close();
if ((m_attributes >> static_cast<uint8_t>(attribute::OVERLINE)) & 1U) }
if ((m_attributes >> static_cast<uint8_t>(attribute::OVERLINE)) & 1U) {
overline_close(); overline_close();
}
while (m_tags[syntaxtag::A]) { while (m_tags[syntaxtag::A]) {
cmd_close(); cmd_close();
@ -46,12 +55,13 @@ string builder::flush() {
* Insert raw text string * Insert raw text string
*/ */
void builder::append(string text) { void builder::append(string text) {
string str(text); string str(move(text));
size_t len{str.length()}; size_t len{str.length()};
if (len > 2 && str[0] == '"' && str[len - 1] == '"') if (len > 2 && str[0] == '"' && str[len - 1] == '"') {
m_output += str.substr(1, len - 2); m_output += str.substr(1, len - 2);
else } else {
m_output += str; m_output += str;
}
} }
/** /**
@ -61,7 +71,7 @@ void builder::append(string text) {
*/ */
void builder::node(string str, bool add_space) { void builder::node(string str, bool add_space) {
string::size_type n, m; string::size_type n, m;
string s(str); string s(move(str));
while (true) { while (true) {
if (s.empty()) { if (s.empty()) {
@ -71,18 +81,19 @@ void builder::node(string str, bool add_space) {
color_close(); color_close();
s.erase(0, 5); s.erase(0, 5);
} else if ((n = s.find("%{F#")) == 0 && (m = s.find("}")) != string::npos) { } else if ((n = s.find("%{F#")) == 0 && (m = s.find('}')) != string::npos) {
if (m - n - 4 == 2) if (m - n - 4 == 2) {
color_alpha(s.substr(n + 3, m - 3)); color_alpha(s.substr(n + 3, m - 3));
else } else {
color(s.substr(n + 3, m - 3)); color(s.substr(n + 3, m - 3));
}
s.erase(n, m + 1); s.erase(n, m + 1);
} else if ((n = s.find("%{B-}")) == 0) { } else if ((n = s.find("%{B-}")) == 0) {
background_close(); background_close();
s.erase(0, 5); s.erase(0, 5);
} else if ((n = s.find("%{B#")) == 0 && (m = s.find("}")) != string::npos) { } else if ((n = s.find("%{B#")) == 0 && (m = s.find('}')) != string::npos) {
background(s.substr(n + 3, m - 3)); background(s.substr(n + 3, m - 3));
s.erase(n, m + 1); s.erase(n, m + 1);
@ -90,7 +101,7 @@ void builder::node(string str, bool add_space) {
font_close(); font_close();
s.erase(0, 5); s.erase(0, 5);
} else if ((n = s.find("%{T")) == 0 && (m = s.find("}")) != string::npos) { } else if ((n = s.find("%{T")) == 0 && (m = s.find('}')) != string::npos) {
font(std::atoi(s.substr(n + 3, m - 3).c_str())); font(std::atoi(s.substr(n + 3, m - 3).c_str()));
s.erase(n, m + 1); s.erase(n, m + 1);
@ -106,15 +117,15 @@ void builder::node(string str, bool add_space) {
overline_color_close(); overline_color_close();
s.erase(0, 5); s.erase(0, 5);
} else if ((n = s.find("%{u#")) == 0 && (m = s.find("}")) != string::npos) { } else if ((n = s.find("%{u#")) == 0 && (m = s.find('}')) != string::npos) {
underline_color(s.substr(n + 3, m - 3)); underline_color(s.substr(n + 3, m - 3));
s.erase(n, m + 1); s.erase(n, m + 1);
} else if ((n = s.find("%{o#")) == 0 && (m = s.find("}")) != string::npos) { } else if ((n = s.find("%{o#")) == 0 && (m = s.find('}')) != string::npos) {
overline_color(s.substr(n + 3, m - 3)); overline_color(s.substr(n + 3, m - 3));
s.erase(n, m + 1); s.erase(n, m + 1);
} else if ((n = s.find("%{U#")) == 0 && (m = s.find("}")) != string::npos) { } else if ((n = s.find("%{U#")) == 0 && (m = s.find('}')) != string::npos) {
line_color(s.substr(n + 3, m - 3)); line_color(s.substr(n + 3, m - 3));
s.erase(n, m + 1); s.erase(n, m + 1);
@ -138,7 +149,7 @@ void builder::node(string str, bool add_space) {
cmd_close(); cmd_close();
s.erase(0, 4); s.erase(0, 4);
} else if ((n = s.find("%{")) == 0 && (m = s.find("}")) != string::npos) { } else if ((n = s.find("%{")) == 0 && (m = s.find('}')) != string::npos) {
append(s.substr(n, m + 1)); append(s.substr(n, m + 1));
s.erase(n, m + 1); s.erase(n, m + 1);
@ -146,14 +157,17 @@ void builder::node(string str, bool add_space) {
append(s.substr(0, n)); append(s.substr(0, n));
s.erase(0, n); s.erase(0, n);
} else } else {
break; break;
} }
}
if (!s.empty()) if (!s.empty()) {
append(s); append(s);
if (add_space) }
if (add_space) {
space(); space();
}
} }
/** /**
@ -163,16 +177,17 @@ void builder::node(string str, bool add_space) {
*/ */
void builder::node(string str, int font_index, bool add_space) { void builder::node(string str, int font_index, bool add_space) {
font(font_index); font(font_index);
node(str, add_space); node(move(str), add_space);
font_close(); font_close();
} }
/** /**
* Insert tags for given label * Insert tags for given label
*/ */
void builder::node(label_t label, bool add_space) { void builder::node(const label_t& label, bool add_space) {
if (!label || !*label) if (!label || !*label) {
return; return;
}
string text{label->get()}; string text{label->get()};
@ -186,50 +201,63 @@ void builder::node(label_t label, bool add_space) {
// underline_close(); // underline_close();
// TODO: Replace with margin-left // TODO: Replace with margin-left
if (label->m_margin > 0) if (label->m_margin > 0) {
space(label->m_margin); space(label->m_margin);
}
if (!label->m_overline.empty()) if (!label->m_overline.empty()) {
overline(label->m_overline); overline(label->m_overline);
if (!label->m_underline.empty()) }
if (!label->m_underline.empty()) {
underline(label->m_underline); underline(label->m_underline);
}
if (!label->m_background.empty()) if (!label->m_background.empty()) {
background(label->m_background); background(label->m_background);
if (!label->m_foreground.empty()) }
if (!label->m_foreground.empty()) {
color(label->m_foreground); color(label->m_foreground);
}
// TODO: Replace with padding-left // TODO: Replace with padding-left
if (label->m_padding > 0) if (label->m_padding > 0) {
space(label->m_padding); space(label->m_padding);
}
node(text, label->m_font, add_space); node(text, label->m_font, add_space);
// TODO: Replace with padding-right // TODO: Replace with padding-right
if (label->m_padding > 0) if (label->m_padding > 0) {
space(label->m_padding); space(label->m_padding);
}
if (!label->m_background.empty()) if (!label->m_background.empty()) {
background_close(); background_close();
if (!label->m_foreground.empty()) }
if (!label->m_foreground.empty()) {
color_close(); color_close();
}
if (!label->m_underline.empty() || (label->m_margin > 0 && m_tags[syntaxtag::u] > 0)) if (!label->m_underline.empty() || (label->m_margin > 0 && m_tags[syntaxtag::u] > 0)) {
underline_close(); underline_close();
if (!label->m_overline.empty() || (label->m_margin > 0 && m_tags[syntaxtag::o] > 0)) }
if (!label->m_overline.empty() || (label->m_margin > 0 && m_tags[syntaxtag::o] > 0)) {
overline_close(); overline_close();
}
// TODO: Replace with margin-right // TODO: Replace with margin-right
if (label->m_margin > 0) if (label->m_margin > 0) {
space(label->m_margin); space(label->m_margin);
}
} }
/** /**
* Insert tag that will offset the contents by given pixels * Insert tag that will offset the contents by given pixels
*/ */
void builder::offset(int pixels) { void builder::offset(int pixels) {
if (pixels == 0) if (pixels == 0) {
return; return;
}
tag_open(syntaxtag::O, to_string(pixels)); tag_open(syntaxtag::O, to_string(pixels));
} }
@ -237,10 +265,12 @@ void builder::offset(int pixels) {
* Insert spaces * Insert spaces
*/ */
void builder::space(int width) { void builder::space(int width) {
if (width == DEFAULT_SPACING) if (width == DEFAULT_SPACING) {
width = m_bar.spacing; width = m_bar.spacing;
if (width <= 0) }
if (width <= 0) {
return; return;
}
string str(width, ' '); string str(width, ' ');
append(str); append(str);
} }
@ -249,14 +279,17 @@ void builder::space(int width) {
* Remove trailing space * Remove trailing space
*/ */
void builder::remove_trailing_space(int width) { void builder::remove_trailing_space(int width) {
if (width == DEFAULT_SPACING) if (width == DEFAULT_SPACING) {
width = m_bar.spacing; width = m_bar.spacing;
if (width <= 0) }
if (width <= 0) {
return; return;
}
string::size_type spacing = width; string::size_type spacing = width;
string str(spacing, ' '); string str(spacing, ' ');
if (m_output.length() >= spacing && m_output.substr(m_output.length() - spacing) == str) if (m_output.length() >= spacing && m_output.substr(m_output.length() - spacing) == str) {
m_output = m_output.substr(0, m_output.length() - spacing); m_output = m_output.substr(0, m_output.length() - spacing);
}
} }
/** /**
@ -279,7 +312,7 @@ void builder::font_close() {
* Insert tag to alter the current background color * Insert tag to alter the current background color
*/ */
void builder::background(string color) { void builder::background(string color) {
if (color.length() == 2 || (color.find("#") == 0 && color.length() == 3)) { if (color.length() == 2 || (color.find('#') == 0 && color.length() == 3)) {
string bg{background_hex()}; string bg{background_hex()};
color = "#" + color.substr(color.length() - 2); color = "#" + color.substr(color.length() - 2);
color += bg.substr(bg.length() - (bg.length() < 6 ? 3 : 6)); color += bg.substr(bg.length() - (bg.length() < 6 ? 3 : 6));
@ -304,7 +337,7 @@ void builder::background_close() {
* Insert tag to alter the current foreground color * Insert tag to alter the current foreground color
*/ */
void builder::color(string color) { void builder::color(string color) {
if (color.length() == 2 || (color.find("#") == 0 && color.length() == 3)) { if (color.length() == 2 || (color.find('#') == 0 && color.length() == 3)) {
string fg{foreground_hex()}; string fg{foreground_hex()};
color = "#" + color.substr(color.length() - 2); color = "#" + color.substr(color.length() - 2);
color += fg.substr(fg.length() - (fg.length() < 6 ? 3 : 6)); color += fg.substr(fg.length() - (fg.length() < 6 ? 3 : 6));
@ -323,7 +356,7 @@ void builder::color(string color) {
void builder::color_alpha(string alpha) { void builder::color_alpha(string alpha) {
string val{foreground_hex()}; string val{foreground_hex()};
if (alpha.find("#") == std::string::npos) { if (alpha.find('#') == std::string::npos) {
alpha = "#" + alpha; alpha = "#" + alpha;
} }
@ -350,7 +383,7 @@ void builder::color_close() {
/** /**
* Insert tag to alter the current overline/underline color * Insert tag to alter the current overline/underline color
*/ */
void builder::line_color(string color) { void builder::line_color(const string& color) {
overline_color(color); overline_color(color);
underline_color(color); underline_color(color);
} }
@ -402,11 +435,12 @@ void builder::underline_color_close() {
/** /**
* Insert tag to enable the overline attribute * Insert tag to enable the overline attribute
*/ */
void builder::overline(string color) { void builder::overline(const string& color) {
if (!color.empty()) if (!color.empty()) {
overline_color(color); overline_color(color);
else } else {
tag_open(attribute::OVERLINE); tag_open(attribute::OVERLINE);
}
} }
/** /**
@ -419,11 +453,12 @@ void builder::overline_close() {
/** /**
* Insert tag to enable the underline attribute * Insert tag to enable the underline attribute
*/ */
void builder::underline(string color) { void builder::underline(const string& color) {
if (!color.empty()) if (!color.empty()) {
underline_color(color); underline_color(color);
else } else {
tag_open(attribute::UNDERLINE); tag_open(attribute::UNDERLINE);
}
} }
/** /**
@ -439,8 +474,9 @@ void builder::underline_close() {
void builder::cmd(mousebtn index, string action, bool condition) { void builder::cmd(mousebtn index, string action, bool condition) {
int button = static_cast<int>(index); int button = static_cast<int>(index);
if (!condition || action.empty()) if (!condition || action.empty()) {
return; return;
}
action = string_util::replace_all(action, ":", "\\:"); action = string_util::replace_all(action, ":", "\\:");
action = string_util::replace_all(action, "$", "\\$"); action = string_util::replace_all(action, "$", "\\$");
@ -462,8 +498,9 @@ void builder::cmd_close() {
* Get default background hex string * Get default background hex string
*/ */
string builder::background_hex() { string builder::background_hex() {
if (m_background.empty()) if (m_background.empty()) {
m_background = color_util::hex<uint16_t>(m_bar.background); m_background = color_util::hex<uint16_t>(m_bar.background);
}
return m_background; return m_background;
} }
@ -471,17 +508,19 @@ string builder::background_hex() {
* Get default foreground hex string * Get default foreground hex string
*/ */
string builder::foreground_hex() { string builder::foreground_hex() {
if (m_foreground.empty()) if (m_foreground.empty()) {
m_foreground = color_util::hex<uint16_t>(m_bar.foreground); m_foreground = color_util::hex<uint16_t>(m_bar.foreground);
}
return m_foreground; return m_foreground;
} }
/** /**
* Insert directive to change value of given tag * Insert directive to change value of given tag
*/ */
void builder::tag_open(syntaxtag tag, string value) { void builder::tag_open(syntaxtag tag, const string& value) {
if (m_tags.find(tag) == m_tags.end()) if (m_tags.find(tag) == m_tags.end()) {
m_tags[tag] = 0; m_tags[tag] = 0;
}
m_tags[tag]++; m_tags[tag]++;
@ -519,8 +558,9 @@ void builder::tag_open(syntaxtag tag, string value) {
* Insert directive to use given attribute unless already set * Insert directive to use given attribute unless already set
*/ */
void builder::tag_open(attribute attr) { void builder::tag_open(attribute attr) {
if ((m_attributes >> static_cast<uint8_t>(attr)) & 1U) if ((m_attributes >> static_cast<uint8_t>(attr)) & 1U) {
return; return;
}
m_attributes |= 1U << static_cast<uint8_t>(attr); m_attributes |= 1U << static_cast<uint8_t>(attr);
@ -540,8 +580,9 @@ void builder::tag_open(attribute attr) {
* Insert directive to reset given tag if it's open and closable * Insert directive to reset given tag if it's open and closable
*/ */
void builder::tag_close(syntaxtag tag) { void builder::tag_close(syntaxtag tag) {
if (m_tags.find(tag) == m_tags.end() || !m_tags[tag]) if (m_tags.find(tag) == m_tags.end() || !m_tags[tag]) {
return; return;
}
m_tags[tag]--; m_tags[tag]--;
@ -577,8 +618,9 @@ void builder::tag_close(syntaxtag tag) {
* Insert directive to remove given attribute if set * Insert directive to remove given attribute if set
*/ */
void builder::tag_close(attribute attr) { void builder::tag_close(attribute attr) {
if (!((m_attributes >> static_cast<uint8_t>(attr)) & 1U)) if (!((m_attributes >> static_cast<uint8_t>(attr)) & 1U)) {
return; return;
}
m_attributes &= ~(1U << static_cast<uint8_t>(attr)); m_attributes &= ~(1U << static_cast<uint8_t>(attr));

View File

@ -1,6 +1,7 @@
#include <algorithm> #include <algorithm>
#include <iomanip> #include <iomanip>
#include <iostream> #include <iostream>
#include <utility>
#include "components/command_line.hpp" #include "components/command_line.hpp"
@ -16,8 +17,8 @@ void cliparser::usage() const {
// which is used to align the description fields // which is used to align the description fields
size_t maxlen{0}; size_t maxlen{0};
for (auto it = m_opts.begin(); it != m_opts.end(); ++it) { for (const auto& m_opt : m_opts) {
size_t len{it->flag_long.length() + it->flag.length() + 4}; size_t len{m_opt.flag_long.length() + m_opt.flag.length() + 4};
maxlen = len > maxlen ? len : maxlen; maxlen = len > maxlen ? len : maxlen;
} }
@ -72,60 +73,62 @@ bool cliparser::has(const string& option) const {
* Gets the value defined for given option * Gets the value defined for given option
*/ */
string cliparser::get(string opt) const { string cliparser::get(string opt) const {
if (has(forward<string>(opt))) if (has(forward<string>(opt))) {
return m_optvalues.find(opt)->second; return m_optvalues.find(opt)->second;
}
return ""; return "";
} }
/** /**
* Compare option value with given string * Compare option value with given string
*/ */
bool cliparser::compare(string opt, string val) const { bool cliparser::compare(string opt, const string& val) const {
return get(opt) == val; return get(move(opt)) == val;
} }
/** /**
* Compare option with its short version * Compare option with its short version
*/ */
auto cliparser::is_short(string option, string opt_short) const { auto cliparser::is_short(const string& option, const string& opt_short) const {
return option.compare(0, opt_short.length(), opt_short) == 0; return option.compare(0, opt_short.length(), opt_short) == 0;
} }
/** /**
* Compare option with its long version * Compare option with its long version
*/ */
auto cliparser::is_long(string option, string opt_long) const { auto cliparser::is_long(const string& option, const string& opt_long) const {
return option.compare(0, opt_long.length(), opt_long) == 0; return option.compare(0, opt_long.length(), opt_long) == 0;
} }
/** /**
* Compare option with both versions * Compare option with both versions
*/ */
auto cliparser::is(string option, string opt_short, string opt_long) const { auto cliparser::is(const string& option, string opt_short, string opt_long) const {
return is_short(option, opt_short) || is_long(option, opt_long); return is_short(option, move(opt_short)) || is_long(option, move(opt_long));
} }
/** /**
* Parse option value * Parse option value
*/ */
auto cliparser::parse_value(string input, string input_next, choices values) const { auto cliparser::parse_value(string input, const string& input_next, choices values) const {
string opt = input; string opt = move(input);
size_t pos; size_t pos;
string value; string value;
if (input_next.empty() && opt.compare(0, 2, "--") != 0) if (input_next.empty() && opt.compare(0, 2, "--") != 0) {
throw value_error("Missing value for " + opt); throw value_error("Missing value for " + opt);
else if ((pos = opt.find("=")) == string::npos && opt.compare(0, 2, "--") == 0) } else if ((pos = opt.find('=')) == string::npos && opt.compare(0, 2, "--") == 0) {
throw value_error("Missing value for " + opt); throw value_error("Missing value for " + opt);
else if (pos == string::npos && !input_next.empty()) } else if (pos == string::npos && !input_next.empty()) {
value = input_next; value = input_next;
else { } else {
value = opt.substr(pos + 1); value = opt.substr(pos + 1);
opt = opt.substr(0, pos); opt = opt.substr(0, pos);
} }
if (!values.empty() && std::find(values.begin(), values.end(), value) == values.end()) if (!values.empty() && std::find(values.begin(), values.end(), value) == values.end()) {
throw value_error("Invalid value '" + value + "' for argument " + string{opt}); throw value_error("Invalid value '" + value + "' for argument " + string{opt});
}
return value; return value;
} }
@ -133,21 +136,22 @@ auto cliparser::parse_value(string input, string input_next, choices values) con
/** /**
* Parse and validate passed arguments and flags * Parse and validate passed arguments and flags
*/ */
void cliparser::parse(string input, string input_next) { void cliparser::parse(const string& input, const string& input_next) {
if (m_skipnext) { if (m_skipnext) {
m_skipnext = false; m_skipnext = false;
if (!input_next.empty()) if (!input_next.empty()) {
return; return;
} }
}
for (auto&& opt : m_opts) { for (auto&& opt : m_opts) {
if (is(input, opt.flag, opt.flag_long)) { if (is(input, opt.flag, opt.flag_long)) {
if (opt.token.empty()) { if (opt.token.empty()) {
m_optvalues.insert(std::make_pair(opt.flag_long.substr(2), "")); m_optvalues.insert(make_pair(opt.flag_long.substr(2), ""));
} else { } else {
auto value = parse_value(input, input_next, opt.values); auto value = parse_value(input, input_next, opt.values);
m_skipnext = (value == input_next); m_skipnext = (value == input_next);
m_optvalues.insert(std::make_pair(opt.flag_long.substr(2), value)); m_optvalues.insert(make_pair(opt.flag_long.substr(2), value));
} }
return; return;

View File

@ -1,4 +1,5 @@
#include <algorithm> #include <algorithm>
#include <utility>
#include "components/config.hpp" #include "components/config.hpp"
#include "utils/env.hpp" #include "utils/env.hpp"
@ -13,10 +14,11 @@ POLYBAR_NS
*/ */
void config::load(string file, string barname) { void config::load(string file, string barname) {
m_file = file; m_file = file;
m_current_bar = barname; m_current_bar = move(barname);
if (!file_util::exists(file)) if (!file_util::exists(file)) {
throw application_error("Could not find config file: " + file); throw application_error("Could not find config file: " + file);
}
try { try {
boost::property_tree::read_ini(file, m_ptree); boost::property_tree::read_ini(file, m_ptree);
@ -25,13 +27,16 @@ void config::load(string file, string barname) {
} }
auto bars = defined_bars(); auto bars = defined_bars();
if (std::find(bars.begin(), bars.end(), m_current_bar) == bars.end()) if (std::find(bars.begin(), bars.end(), m_current_bar) == bars.end()) {
throw application_error("Undefined bar: " + m_current_bar); throw application_error("Undefined bar: " + m_current_bar);
}
if (env_util::has("XDG_CONFIG_HOME")) if (env_util::has("XDG_CONFIG_HOME")) {
file = string_util::replace(file, env_util::get("XDG_CONFIG_HOME"), "$XDG_CONFIG_HOME"); file = string_util::replace(file, env_util::get("XDG_CONFIG_HOME"), "$XDG_CONFIG_HOME");
if (env_util::has("HOME")) }
if (env_util::has("HOME")) {
file = string_util::replace(file, env_util::get("HOME"), "~"); file = string_util::replace(file, env_util::get("HOME"), "~");
}
m_logger.trace("config: Loaded %s", file); m_logger.trace("config: Loaded %s", file);
m_logger.trace("config: Current bar section: [%s]", bar_section()); m_logger.trace("config: Current bar section: [%s]", bar_section());
@ -58,9 +63,10 @@ vector<string> config::defined_bars() const {
vector<string> bars; vector<string> bars;
for (auto&& p : m_ptree) { for (auto&& p : m_ptree) {
if (p.first.compare(0, 4, "bar/") == 0) if (p.first.compare(0, 4, "bar/") == 0) {
bars.emplace_back(p.first.substr(4)); bars.emplace_back(p.first.substr(4));
} }
}
return bars; return bars;
} }
@ -75,10 +81,10 @@ string config::build_path(const string& section, const string& key) const {
/** /**
* Print a deprecation warning if the given parameter is set * Print a deprecation warning if the given parameter is set
*/ */
void config::warn_deprecated(string section, string key, string replacement) const { void config::warn_deprecated(const string& section, const string& key, string replacement) const {
try { try {
auto value = get<string>(section, key); auto value = get<string>(section, key);
m_logger.warn("The config parameter `%s.%s` is deprecated, use `%s` instead.", section, key, replacement); m_logger.warn("The config parameter `%s.%s` is deprecated, use `%s` instead.", section, key, move(replacement));
} catch (const key_error& err) { } catch (const key_error& err) {
} }
} }

View File

@ -100,14 +100,16 @@ controller::~controller() {
if (!m_threads.empty()) { if (!m_threads.empty()) {
m_log.info("Joining active threads"); m_log.info("Joining active threads");
for (auto&& thread : m_threads) { for (auto&& thread : m_threads) {
if (thread.joinable()) if (thread.joinable()) {
thread.join(); thread.join();
} }
} }
}
m_log.info("Waiting for spawned processes"); m_log.info("Waiting for spawned processes");
while (process_util::notify_childprocess()) while (process_util::notify_childprocess()) {
; ;
}
m_connection.flush(); m_connection.flush();
} }
@ -222,14 +224,16 @@ void controller::install_sigmask() {
sigaddset(&m_waitmask, SIGTERM); sigaddset(&m_waitmask, SIGTERM);
sigaddset(&m_waitmask, SIGUSR1); sigaddset(&m_waitmask, SIGUSR1);
if (pthread_sigmask(SIG_BLOCK, &m_waitmask, nullptr) == -1) if (pthread_sigmask(SIG_BLOCK, &m_waitmask, nullptr) == -1) {
throw system_error(); throw system_error();
}
sigemptyset(&m_ignmask); sigemptyset(&m_ignmask);
sigaddset(&m_ignmask, SIGPIPE); sigaddset(&m_ignmask, SIGPIPE);
if (pthread_sigmask(SIG_BLOCK, &m_ignmask, nullptr) == -1) if (pthread_sigmask(SIG_BLOCK, &m_ignmask, nullptr) == -1) {
throw system_error(); throw system_error();
}
} }
/** /**
@ -238,16 +242,18 @@ void controller::install_sigmask() {
void controller::uninstall_sigmask() { void controller::uninstall_sigmask() {
m_log.trace("controller: Set pthread_sigmask to unblock term signals"); m_log.trace("controller: Set pthread_sigmask to unblock term signals");
if (pthread_sigmask(SIG_UNBLOCK, &m_waitmask, nullptr) == -1) if (pthread_sigmask(SIG_UNBLOCK, &m_waitmask, nullptr) == -1) {
throw system_error(); throw system_error();
}
} }
/** /**
* Listen for changes to the config file * Listen for changes to the config file
*/ */
void controller::install_confwatch() { void controller::install_confwatch() {
if (!m_running) if (!m_running) {
return; return;
}
if (!m_confwatch) { if (!m_confwatch) {
m_log.trace("controller: Config watch not set, skip..."); m_log.trace("controller: Config watch not set, skip...");
@ -256,8 +262,9 @@ void controller::install_confwatch() {
m_threads.emplace_back([&] { m_threads.emplace_back([&] {
try { try {
if (!m_running) if (!m_running) {
return; return;
}
m_log.trace("controller: Attach config watch"); m_log.trace("controller: Attach config watch");
m_confwatch->attach(IN_MODIFY); m_confwatch->attach(IN_MODIFY);
@ -374,50 +381,52 @@ void controller::bootstrap_modules() {
auto type = m_conf.get<string>("module/" + module_name, "type"); auto type = m_conf.get<string>("module/" + module_name, "type");
module_t module; module_t module;
if (type == "internal/counter") if (type == "internal/counter") {
module.reset(new counter_module(bar, m_log, m_conf, module_name)); module.reset(new counter_module(bar, m_log, m_conf, module_name));
else if (type == "internal/backlight") } else if (type == "internal/backlight") {
module.reset(new backlight_module(bar, m_log, m_conf, module_name)); module.reset(new backlight_module(bar, m_log, m_conf, module_name));
else if (type == "internal/battery") } else if (type == "internal/battery") {
module.reset(new battery_module(bar, m_log, m_conf, module_name)); module.reset(new battery_module(bar, m_log, m_conf, module_name));
else if (type == "internal/bspwm") } else if (type == "internal/bspwm") {
module.reset(new bspwm_module(bar, m_log, m_conf, module_name)); module.reset(new bspwm_module(bar, m_log, m_conf, module_name));
else if (type == "internal/cpu") } else if (type == "internal/cpu") {
module.reset(new cpu_module(bar, m_log, m_conf, module_name)); module.reset(new cpu_module(bar, m_log, m_conf, module_name));
else if (type == "internal/date") } else if (type == "internal/date") {
module.reset(new date_module(bar, m_log, m_conf, module_name)); module.reset(new date_module(bar, m_log, m_conf, module_name));
else if (type == "internal/fs") } else if (type == "internal/fs") {
module.reset(new fs_module(bar, m_log, m_conf, module_name)); module.reset(new fs_module(bar, m_log, m_conf, module_name));
else if (type == "internal/memory") } else if (type == "internal/memory") {
module.reset(new memory_module(bar, m_log, m_conf, module_name)); module.reset(new memory_module(bar, m_log, m_conf, module_name));
else if (type == "internal/i3") } else if (type == "internal/i3") {
module.reset(new i3_module(bar, m_log, m_conf, module_name)); module.reset(new i3_module(bar, m_log, m_conf, module_name));
else if (type == "internal/mpd") } else if (type == "internal/mpd") {
module.reset(new mpd_module(bar, m_log, m_conf, module_name)); module.reset(new mpd_module(bar, m_log, m_conf, module_name));
else if (type == "internal/volume") } else if (type == "internal/volume") {
module.reset(new volume_module(bar, m_log, m_conf, module_name)); module.reset(new volume_module(bar, m_log, m_conf, module_name));
else if (type == "internal/network") } else if (type == "internal/network") {
module.reset(new network_module(bar, m_log, m_conf, module_name)); module.reset(new network_module(bar, m_log, m_conf, module_name));
else if (type == "internal/temperature") } else if (type == "internal/temperature") {
module.reset(new temperature_module(bar, m_log, m_conf, module_name)); module.reset(new temperature_module(bar, m_log, m_conf, module_name));
else if (type == "internal/xbacklight") } else if (type == "internal/xbacklight") {
module.reset(new xbacklight_module(bar, m_log, m_conf, module_name)); module.reset(new xbacklight_module(bar, m_log, m_conf, module_name));
else if (type == "internal/xwindow") } else if (type == "internal/xwindow") {
module.reset(new xwindow_module(bar, m_log, m_conf, module_name)); module.reset(new xwindow_module(bar, m_log, m_conf, module_name));
else if (type == "custom/text") } else if (type == "custom/text") {
module.reset(new text_module(bar, m_log, m_conf, module_name)); module.reset(new text_module(bar, m_log, m_conf, module_name));
else if (type == "custom/script") } else if (type == "custom/script") {
module.reset(new script_module(bar, m_log, m_conf, module_name)); module.reset(new script_module(bar, m_log, m_conf, module_name));
else if (type == "custom/menu") } else if (type == "custom/menu") {
module.reset(new menu_module(bar, m_log, m_conf, module_name)); module.reset(new menu_module(bar, m_log, m_conf, module_name));
else if (type == "custom/ipc") { } else if (type == "custom/ipc") {
if (!m_ipc) if (!m_ipc) {
throw application_error("Inter-process messaging needs to be enabled"); throw application_error("Inter-process messaging needs to be enabled");
}
module.reset(new ipc_module(bar, m_log, m_conf, module_name)); module.reset(new ipc_module(bar, m_log, m_conf, module_name));
m_ipc->attach_callback( m_ipc->attach_callback(
bind(&ipc_module::on_message, static_cast<ipc_module*>(module.get()), placeholders::_1)); bind(&ipc_module::on_message, static_cast<ipc_module*>(module.get()), placeholders::_1));
} else } else {
throw application_error("Unknown module: " + module_name); throw application_error("Unknown module: " + module_name);
}
module->set_update_cb( module->set_update_cb(
bind(&eventloop::enqueue, m_eventloop.get(), eventloop::entry_t{static_cast<int>(event_type::UPDATE)})); bind(&eventloop::enqueue, m_eventloop.get(), eventloop::entry_t{static_cast<int>(event_type::UPDATE)}));
@ -435,8 +444,9 @@ void controller::bootstrap_modules() {
} }
} }
if (module_count == 0) if (module_count == 0) {
throw application_error("No modules created"); throw application_error("No modules created");
}
} }
/** /**
@ -460,7 +470,7 @@ void controller::on_ipc_action(const ipc_action& message) {
/** /**
* Callback for clicked bar actions * Callback for clicked bar actions
*/ */
void controller::on_mouse_event(string input) { void controller::on_mouse_event(const string& input) {
eventloop::entry_t evt{static_cast<int>(event_type::INPUT)}; eventloop::entry_t evt{static_cast<int>(event_type::INPUT)};
if (input.length() > sizeof(evt.data)) { if (input.length() > sizeof(evt.data)) {
@ -497,7 +507,7 @@ void controller::on_unrecognized_action(string input) {
void controller::on_update() { void controller::on_update() {
const bar_settings& bar{m_bar->settings()}; const bar_settings& bar{m_bar->settings()};
string contents{""}; string contents;
string separator{bar.separator}; string separator{bar.separator};
string padding_left(bar.padding.left, ' '); string padding_left(bar.padding.left, ' ');
@ -512,33 +522,39 @@ void controller::on_update() {
bool is_center = false; bool is_center = false;
bool is_right = false; bool is_right = false;
if (block.first == alignment::LEFT) if (block.first == alignment::LEFT) {
is_left = true; is_left = true;
else if (block.first == alignment::CENTER) } else if (block.first == alignment::CENTER) {
is_center = true; is_center = true;
else if (block.first == alignment::RIGHT) } else if (block.first == alignment::RIGHT) {
is_right = true; is_right = true;
}
for (const auto& module : block.second) { for (const auto& module : block.second) {
auto module_contents = module->contents(); auto module_contents = module->contents();
if (module_contents.empty()) if (module_contents.empty()) {
continue; continue;
}
if (!block_contents.empty() && !separator.empty()) if (!block_contents.empty() && !separator.empty()) {
block_contents += separator; block_contents += separator;
}
if (!(is_left && module == block.second.front())) if (!(is_left && module == block.second.front())) {
block_contents += string(margin_left, ' '); block_contents += string(margin_left, ' ');
}
block_contents += module->contents(); block_contents += module->contents();
if (!(is_right && module == block.second.back())) if (!(is_right && module == block.second.back())) {
block_contents += string(margin_right, ' '); block_contents += string(margin_right, ' ');
} }
}
if (block_contents.empty()) if (block_contents.empty()) {
continue; continue;
}
if (is_left) { if (is_left) {
contents += "%{l}"; contents += "%{l}";

View File

@ -28,7 +28,7 @@ eventloop::~eventloop() noexcept {
bool eventloop::enqueue(const entry_t& i) { bool eventloop::enqueue(const entry_t& i) {
bool enqueued; bool enqueued;
if ((enqueued = m_queue.enqueue(i)) == false) { if (!(enqueued = m_queue.enqueue(i))) {
m_log.warn("Failed to queue event (%d)", i.type); m_log.warn("Failed to queue event (%d)", i.type);
} }
@ -74,10 +74,12 @@ void eventloop::run(std::chrono::duration<double, std::milli> timeframe, int lim
forward_event(evt); forward_event(evt);
if (match_event(next, event_type::NONE)) if (match_event(next, event_type::NONE)) {
continue; continue;
if (compare_events(evt, next)) }
if (compare_events(evt, next)) {
continue; continue;
}
forward_event(next); forward_event(next);
} }
@ -112,7 +114,7 @@ void eventloop::set_input_db(callback<string>&& cb) {
* Add module to alignment block * Add module to alignment block
*/ */
void eventloop::add_module(const alignment pos, module_t&& module) { void eventloop::add_module(const alignment pos, module_t&& module) {
modulemap_t::iterator it = m_modules.lower_bound(pos); auto it = m_modules.lower_bound(pos);
if (it != m_modules.end() && !(m_modules.key_comp()(pos, it->first))) { if (it != m_modules.end() && !(m_modules.key_comp()(pos, it->first))) {
it->second.emplace_back(forward<module_t>(module)); it->second.emplace_back(forward<module_t>(module));
@ -193,13 +195,20 @@ void eventloop::on_update() {
/** /**
* Handler for enqueued INPUT events * Handler for enqueued INPUT events
*/ */
void eventloop::on_input(string input) { void eventloop::on_input(char* input) {
m_log.trace("eventloop: Received INPUT event"); m_log.trace("eventloop: Received INPUT event");
if (!m_modulelock.try_lock()) {
return;
}
std::lock_guard<std::mutex> guard(m_modulelock, std::adopt_lock);
for (auto&& block : m_modules) { for (auto&& block : m_modules) {
for (auto&& module : block.second) { for (auto&& module : block.second) {
if (!module->receive_events()) if (!module->receive_events()) {
continue; continue;
}
if (module->handle_event(input)) { if (module->handle_event(input)) {
return; return;
} }
@ -223,10 +232,11 @@ void eventloop::on_check() {
for (auto&& block : m_modules) { for (auto&& block : m_modules) {
for (auto&& module : block.second) { for (auto&& module : block.second) {
if (module->running()) if (module->running()) {
return; return;
} }
} }
}
m_log.warn("No running modules..."); m_log.warn("No running modules...");
stop(); stop();

View File

@ -90,30 +90,39 @@ void ipc::parse(const string& payload) const {
* Send ipc message to attached listeners * Send ipc message to attached listeners
*/ */
void ipc::delegate(const ipc_command& message) const { void ipc::delegate(const ipc_command& message) const {
if (!m_command_callbacks.empty()) if (!m_command_callbacks.empty()) {
for (auto&& callback : m_command_callbacks) callback(message); for (auto&& callback : m_command_callbacks) {
else callback(message);
}
} else {
m_log.warn("Unhandled message (payload=%s)", message.payload); m_log.warn("Unhandled message (payload=%s)", message.payload);
}
} }
/** /**
* Send ipc message to attached listeners * Send ipc message to attached listeners
*/ */
void ipc::delegate(const ipc_hook& message) const { void ipc::delegate(const ipc_hook& message) const {
if (!m_hook_callbacks.empty()) if (!m_hook_callbacks.empty()) {
for (auto&& callback : m_hook_callbacks) callback(message); for (auto&& callback : m_hook_callbacks) {
else callback(message);
}
} else {
m_log.warn("Unhandled message (payload=%s)", message.payload); m_log.warn("Unhandled message (payload=%s)", message.payload);
}
} }
/** /**
* Send ipc message to attached listeners * Send ipc message to attached listeners
*/ */
void ipc::delegate(const ipc_action& message) const { void ipc::delegate(const ipc_action& message) const {
if (!m_action_callbacks.empty()) if (!m_action_callbacks.empty()) {
for (auto&& callback : m_action_callbacks) callback(message); for (auto&& callback : m_action_callbacks) {
else callback(message);
}
} else {
m_log.warn("Unhandled message (payload=%s)", message.payload); m_log.warn("Unhandled message (payload=%s)", message.payload);
}
} }
POLYBAR_NS_END POLYBAR_NS_END

View File

@ -1,6 +1,9 @@
#include <unistd.h> #include <unistd.h>
#include <utility>
#include "components/logger.hpp" #include "components/logger.hpp"
#include "errors.hpp"
#include "utils/string.hpp" #include "utils/string.hpp"
POLYBAR_NS POLYBAR_NS
@ -28,8 +31,9 @@ logger::logger(loglevel level) : m_level(level) {
*/ */
void logger::verbosity(loglevel level) { void logger::verbosity(loglevel level) {
#ifndef DEBUG #ifndef DEBUG
if (level == loglevel::TRACE) if (level == loglevel::TRACE) {
throw application_error("not a debug build: trace disabled..."); throw application_error("not a debug build: trace disabled...");
}
#endif #endif
m_level = level; m_level = level;
} }
@ -38,23 +42,24 @@ void logger::verbosity(loglevel level) {
* Set output verbosity by loglevel name * Set output verbosity by loglevel name
*/ */
void logger::verbosity(string level) { void logger::verbosity(string level) {
verbosity(parse_loglevel_name(level)); verbosity(parse_loglevel_name(move(level)));
} }
/** /**
* Convert given loglevel name to its enum type counterpart * Convert given loglevel name to its enum type counterpart
*/ */
loglevel parse_loglevel_name(string name) { loglevel parse_loglevel_name(const string& name) {
if (string_util::compare(name, "error")) if (string_util::compare(name, "error")) {
return loglevel::ERROR; return loglevel::ERROR;
else if (string_util::compare(name, "warning")) } else if (string_util::compare(name, "warning")) {
return loglevel::WARNING; return loglevel::WARNING;
else if (string_util::compare(name, "info")) } else if (string_util::compare(name, "info")) {
return loglevel::INFO; return loglevel::INFO;
else if (string_util::compare(name, "trace")) } else if (string_util::compare(name, "trace")) {
return loglevel::TRACE; return loglevel::TRACE;
else } else {
return loglevel::NONE; return loglevel::NONE;
}
} }
POLYBAR_NS_END POLYBAR_NS_END

View File

@ -39,12 +39,13 @@ void parser::operator()(string data) {
m_log.trace_x("parser: %s", data); m_log.trace_x("parser: %s", data);
while (data.length()) { while (data.length()) {
if (data.compare(0, 2, "%{") == 0 && (pos = data.find("}")) != string::npos) { if (data.compare(0, 2, "%{") == 0 && (pos = data.find('}')) != string::npos) {
codeblock(data.substr(2, pos - 2)); codeblock(data.substr(2, pos - 2));
data.erase(0, pos + 1); data.erase(0, pos + 1);
} else { } else {
if ((pos = data.find("%{")) == string::npos) if ((pos = data.find("%{")) == string::npos) {
pos = data.length(); pos = data.length();
}
data.erase(0, text(data.substr(0, pos))); data.erase(0, text(data.substr(0, pos)));
} }
} }
@ -63,8 +64,9 @@ void parser::codeblock(string data) {
while (data.length()) { while (data.length()) {
data = string_util::ltrim(data, ' '); data = string_util::ltrim(data, ' ');
if (data.empty()) if (data.empty()) {
break; break;
}
char tag{data[0]}; char tag{data[0]};
string value; string value;
@ -72,10 +74,11 @@ void parser::codeblock(string data) {
// Remove the tag // Remove the tag
data.erase(0, 1); data.erase(0, 1);
if ((pos = data.find_first_of(" }")) != string::npos) if ((pos = data.find_first_of(" }")) != string::npos) {
value = data.substr(0, pos); value = data.substr(0, pos);
else } else {
value = data; value = data;
}
switch (tag) { switch (tag) {
case 'B': case 'B':
@ -145,8 +148,9 @@ void parser::codeblock(string data) {
g_signals::parser::action_block_open(btn, value); g_signals::parser::action_block_open(btn, value);
// make sure we strip the correct length (btn+wrapping colons) // make sure we strip the correct length (btn+wrapping colons)
if (value[0] != ':') if (value[0] != ':') {
value += "0"; value += "0";
}
value += "::"; value += "::";
} else if (!m_actions.empty()) { } else if (!m_actions.empty()) {
g_signals::parser::action_block_close(parse_action_btn(value)); g_signals::parser::action_block_close(parse_action_btn(value));
@ -158,9 +162,10 @@ void parser::codeblock(string data) {
throw unrecognized_token("Unrecognized token '" + string{tag} + "'"); throw unrecognized_token("Unrecognized token '" + string{tag} + "'");
} }
if (!data.empty()) if (!data.empty()) {
data.erase(0, !value.empty() ? value.length() : 1); data.erase(0, !value.empty() ? value.length() : 1);
} }
}
} }
/** /**
@ -176,8 +181,9 @@ size_t parser::text(string data) {
data.erase(next_tag); data.erase(next_tag);
} }
size_t n = 0; size_t n = 0;
while (utf[n] != '\0' && utf[++n] < 0x80) while (utf[n] != '\0' && utf[++n] < 0x80) {
; ;
}
g_signals::parser::string_write(data.substr(0, n).c_str(), n); g_signals::parser::string_write(data.substr(0, n).c_str(), n);
return n; return n;
} else if ((utf[0] & 0xe0) == 0xc0) { // 2 byte utf-8 sequence } else if ((utf[0] & 0xe0) == 0xc0) { // 2 byte utf-8 sequence
@ -206,8 +212,9 @@ size_t parser::text(string data) {
*/ */
uint32_t parser::parse_color(string s, uint32_t fallback) { uint32_t parser::parse_color(string s, uint32_t fallback) {
uint32_t color{0}; uint32_t color{0};
if (s.empty() || s[0] == '-' || (color = color_util::parse(s, fallback)) == fallback) if (s.empty() || s[0] == '-' || (color = color_util::parse(s, fallback)) == fallback) {
return fallback; return fallback;
}
return color_util::premultiply_alpha(color); return color_util::premultiply_alpha(color);
} }
@ -220,7 +227,7 @@ int8_t parser::parse_fontindex(string s) {
} }
try { try {
return std::stoul(s.c_str(), nullptr, 10); return std::stoul(s, nullptr, 10);
} catch (const std::invalid_argument& err) { } catch (const std::invalid_argument& err) {
return -1; return -1;
} }
@ -244,25 +251,28 @@ attribute parser::parse_attr(const char attr) {
* Process action button token and convert it to the correct value * Process action button token and convert it to the correct value
*/ */
mousebtn parser::parse_action_btn(string data) { mousebtn parser::parse_action_btn(string data) {
if (data[0] == ':') if (data[0] == ':') {
return mousebtn::LEFT; return mousebtn::LEFT;
else if (isdigit(data[0])) } else if (isdigit(data[0])) {
return static_cast<mousebtn>(data[0] - '0'); return static_cast<mousebtn>(data[0] - '0');
else if (!m_actions.empty()) } else if (!m_actions.empty()) {
return static_cast<mousebtn>(m_actions.back()); return static_cast<mousebtn>(m_actions.back());
else } else {
return mousebtn::NONE; return mousebtn::NONE;
}
} }
/** /**
* Process action command string * Process action command string
*/ */
string parser::parse_action_cmd(string data) { string parser::parse_action_cmd(const string& data) {
size_t start, end; size_t start, end;
if ((start = data.find(':')) == string::npos) if ((start = data.find(':')) == string::npos) {
return ""; return "";
if ((end = data.find(':', start + 1)) == string::npos) }
if ((end = data.find(':', start + 1)) == string::npos) {
return ""; return "";
}
return string_util::trim(data.substr(start, end), ':'); return string_util::trim(data.substr(start, end), ':');
} }

View File

@ -1,5 +1,6 @@
#include "components/renderer.hpp" #include "components/renderer.hpp"
#include "components/logger.hpp" #include "components/logger.hpp"
#include "errors.hpp"
#include "x11/connection.hpp" #include "x11/connection.hpp"
#include "x11/draw.hpp" #include "x11/draw.hpp"
#include "x11/fonts.hpp" #include "x11/fonts.hpp"
@ -100,29 +101,34 @@ renderer::renderer(connection& conn, const logger& logger, unique_ptr<font_manag
auto fonts_loaded = false; auto fonts_loaded = false;
auto fontindex = 0; auto fontindex = 0;
if (fonts.empty()) if (fonts.empty()) {
m_log.warn("No fonts specified, using fallback font \"fixed\""); m_log.warn("No fonts specified, using fallback font \"fixed\"");
}
for (auto f : fonts) { for (const auto& f : fonts) {
fontindex++; fontindex++;
vector<string> fd{string_util::split(f, ';')}; vector<string> fd{string_util::split(f, ';')};
string pattern{fd[0]}; string pattern{fd[0]};
int offset{0}; int offset{0};
if (fd.size() > 1) if (fd.size() > 1) {
offset = std::stoi(fd[1], 0, 10); offset = std::stoi(fd[1], nullptr, 10);
if (m_fontmanager->load(pattern, fontindex, offset))
fonts_loaded = true;
else
m_log.warn("Unable to load font '%s'", fd[0]);
} }
if (!fonts_loaded && !fonts.empty()) if (m_fontmanager->load(pattern, fontindex, offset)) {
m_log.warn("Unable to load fonts, using fallback font \"fixed\""); fonts_loaded = true;
} else {
m_log.warn("Unable to load font '%s'", fd[0]);
}
}
if (!fonts_loaded && !m_fontmanager->load("fixed")) if (!fonts_loaded && !fonts.empty()) {
m_log.warn("Unable to load fonts, using fallback font \"fixed\"");
}
if (!fonts_loaded && !m_fontmanager->load("fixed")) {
throw application_error("Unable to load fonts"); throw application_error("Unable to load fonts");
}
m_fontmanager->allocate_color(m_bar.foreground, true); m_fontmanager->allocate_color(m_bar.foreground, true);
} }
@ -423,8 +429,9 @@ void renderer::draw_character(uint16_t character) {
// Avoid odd glyph width's for center-aligned text // Avoid odd glyph width's for center-aligned text
// since it breaks the positioning of clickable area's // since it breaks the positioning of clickable area's
if (m_alignment == alignment::CENTER && width % 2) if (m_alignment == alignment::CENTER && width % 2) {
width++; width++;
}
auto x = shift_content(width); auto x = shift_content(width);
auto y = m_rect.height / 2 + font->height / 2 - font->descent + font->offset_y; auto y = m_rect.height / 2 + font->height / 2 - font->descent + font->offset_y;
@ -468,8 +475,9 @@ void renderer::draw_textstring(const char* text, size_t len) {
// Avoid odd glyph width's for center-aligned text // Avoid odd glyph width's for center-aligned text
// since it breaks the positioning of clickable area's // since it breaks the positioning of clickable area's
if (m_alignment == alignment::CENTER && width % 2) if (m_alignment == alignment::CENTER && width % 2) {
width++; width++;
}
auto x = shift_content(width); auto x = shift_content(width);
auto y = m_rect.height / 2 + font->height / 2 - font->descent + font->offset_y; auto y = m_rect.height / 2 + font->height / 2 - font->descent + font->offset_y;
@ -479,8 +487,8 @@ void renderer::draw_textstring(const char* text, size_t len) {
const FcChar16* drawchars = static_cast<const FcChar16*>(chars.data()); const FcChar16* drawchars = static_cast<const FcChar16*>(chars.data());
XftDrawString16(m_fontmanager->xftdraw(), &color, font->xft, x, y, drawchars, chars.size()); XftDrawString16(m_fontmanager->xftdraw(), &color, font->xft, x, y, drawchars, chars.size());
} else { } else {
for (size_t i = 0; i < chars.size(); i++) { for (unsigned short& i : chars) {
chars[i] = ((chars[i] >> 8) | (chars[i] << 8)); i = ((i >> 8) | (i << 8));
} }
draw_util::xcb_poly_text_16_patched( draw_util::xcb_poly_text_16_patched(
@ -492,15 +500,16 @@ void renderer::draw_textstring(const char* text, size_t len) {
/** /**
* Create new action block at the current position * Create new action block at the current position
*/ */
void renderer::begin_action(const mousebtn btn, const string cmd) { void renderer::begin_action(const mousebtn btn, const string& cmd) {
action_block action{}; action_block action{};
action.button = btn; action.button = btn;
action.align = m_alignment; action.align = m_alignment;
action.start_x = m_currentx; action.start_x = m_currentx;
action.command = string_util::replace_all(cmd, ":", "\\:"); action.command = string_util::replace_all(cmd, ":", "\\:");
action.active = true; action.active = true;
if (action.button == mousebtn::NONE) if (action.button == mousebtn::NONE) {
action.button = mousebtn::LEFT; action.button = mousebtn::LEFT;
}
m_log.trace_x("renderer: begin_action(%i, %s)", static_cast<uint8_t>(action.button), cmd.c_str()); m_log.trace_x("renderer: begin_action(%i, %s)", static_cast<uint8_t>(action.button), cmd.c_str());
m_actions.emplace_back(action); m_actions.emplace_back(action);
} }
@ -512,8 +521,9 @@ void renderer::end_action(const mousebtn btn) {
int16_t clickable_width{0}; int16_t clickable_width{0};
for (auto action = m_actions.rbegin(); action != m_actions.rend(); action++) { for (auto action = m_actions.rbegin(); action != m_actions.rend(); action++) {
if (!action->active || action->align != m_alignment || action->button != btn) if (!action->active || action->align != m_alignment || action->button != btn) {
continue; continue;
}
action->active = false; action->active = false;
@ -581,8 +591,9 @@ int16_t renderer::shift_content(int16_t x, const int16_t shift_x) {
// Translate pos of clickable areas // Translate pos of clickable areas
if (m_alignment != alignment::LEFT) { if (m_alignment != alignment::LEFT) {
for (auto&& action : m_actions) { for (auto&& action : m_actions) {
if (action.active || action.align != m_alignment) if (action.active || action.align != m_alignment) {
continue; continue;
}
action.start_x -= delta; action.start_x -= delta;
action.end_x -= delta; action.end_x -= delta;
} }

View File

@ -26,10 +26,12 @@ namespace drawtypes {
auto now = chrono::system_clock::now(); auto now = chrono::system_clock::now();
auto diff = chrono::duration_cast<chrono::milliseconds>(now - m_lastupdate); auto diff = chrono::duration_cast<chrono::milliseconds>(now - m_lastupdate);
if (diff.count() < m_framerate_ms) if (diff.count() < m_framerate_ms) {
return; return;
if (++m_frame >= m_framecount) }
if (++m_frame >= m_framecount) {
m_frame = 0; m_frame = 0;
}
m_lastupdate = now; m_lastupdate = now;
} }
@ -38,7 +40,7 @@ namespace drawtypes {
* Create an animation by loading values * Create an animation by loading values
* from the configuration * from the configuration
*/ */
animation_t load_animation(const config& conf, string section, string name, bool required) { animation_t load_animation(const config& conf, const string& section, string name, bool required) {
vector<icon_t> vec; vector<icon_t> vec;
vector<string> frames; vector<string> frames;
@ -46,10 +48,11 @@ namespace drawtypes {
auto anim_defaults = load_optional_icon(conf, section, name); auto anim_defaults = load_optional_icon(conf, section, name);
if (required) if (required) {
frames = conf.get_list<string>(section, name); frames = conf.get_list<string>(section, name);
else } else {
frames = conf.get_list<string>(section, name, {}); frames = conf.get_list<string>(section, name, {});
}
for (size_t i = 0; i < frames.size(); i++) { for (size_t i = 0; i < frames.size(); i++) {
vec.emplace_back(forward<icon_t>(load_optional_icon(conf, section, name + "-" + to_string(i), frames[i]))); vec.emplace_back(forward<icon_t>(load_optional_icon(conf, section, name + "-" + to_string(i), frames[i])));
@ -58,7 +61,7 @@ namespace drawtypes {
auto framerate = conf.get<int>(section, name + "-framerate", 1000); auto framerate = conf.get<int>(section, name + "-framerate", 1000);
return animation_t{new animation(move(vec), framerate)}; return make_shared<animation>(move(vec), framerate);
} }
} }

View File

@ -7,19 +7,20 @@ namespace drawtypes {
m_icons.emplace(id, forward<decltype(icon)>(icon)); m_icons.emplace(id, forward<decltype(icon)>(icon));
} }
bool iconset::has(string id) { bool iconset::has(const string& id) {
return m_icons.find(id) != m_icons.end(); return m_icons.find(id) != m_icons.end();
} }
icon_t iconset::get(string id, string fallback_id) { icon_t iconset::get(const string& id, const string& fallback_id) {
auto icon = m_icons.find(id); auto icon = m_icons.find(id);
if (icon == m_icons.end()) if (icon == m_icons.end()) {
return m_icons.find(fallback_id)->second; return m_icons.find(fallback_id)->second;
}
return icon->second; return icon->second;
} }
iconset::operator bool() { iconset::operator bool() {
return m_icons.size() > 0; return !m_icons.empty();
} }
} }

View File

@ -1,3 +1,5 @@
#include <utility>
#include "drawtypes/label.hpp" #include "drawtypes/label.hpp"
POLYBAR_NS POLYBAR_NS
@ -12,55 +14,68 @@ namespace drawtypes {
} }
label_t label::clone() { label_t label::clone() {
return label_t{new label(m_text, m_foreground, m_background, m_underline, m_overline, m_font, m_padding, m_margin, return make_shared<label>(m_text, m_foreground, m_background, m_underline, m_overline, m_font, m_padding, m_margin,
m_maxlen, m_ellipsis, m_token_bounds)}; m_maxlen, m_ellipsis, m_token_bounds);
} }
void label::reset_tokens() { void label::reset_tokens() {
m_tokenized = m_text; m_tokenized = m_text;
} }
bool label::has_token(string token) { bool label::has_token(const string& token) {
return m_text.find(token) != string::npos; return m_text.find(token) != string::npos;
} }
void label::replace_token(string token, string replacement) { void label::replace_token(const string& token, string replacement) {
if (!has_token(token)) if (!has_token(token)) {
return; return;
}
for (auto&& bound : m_token_bounds) { for (auto&& bound : m_token_bounds) {
if (token != bound.token) if (token != bound.token) {
continue; continue;
m_tokenized = string_util::replace_all_bounded(m_tokenized, token, replacement, bound.min, bound.max); }
m_tokenized = string_util::replace_all_bounded(m_tokenized, token, move(replacement), bound.min, bound.max);
} }
} }
void label::replace_defined_values(const label_t& label) { void label::replace_defined_values(const label_t& label) {
if (!label->m_foreground.empty()) if (!label->m_foreground.empty()) {
m_foreground = label->m_foreground; m_foreground = label->m_foreground;
if (!label->m_background.empty()) }
if (!label->m_background.empty()) {
m_background = label->m_background; m_background = label->m_background;
if (!label->m_underline.empty()) }
if (!label->m_underline.empty()) {
m_underline = label->m_underline; m_underline = label->m_underline;
if (!label->m_overline.empty()) }
if (!label->m_overline.empty()) {
m_overline = label->m_overline; m_overline = label->m_overline;
} }
}
void label::copy_undefined(const label_t& label) { void label::copy_undefined(const label_t& label) {
if (m_foreground.empty() && !label->m_foreground.empty()) if (m_foreground.empty() && !label->m_foreground.empty()) {
m_foreground = label->m_foreground; m_foreground = label->m_foreground;
if (m_background.empty() && !label->m_background.empty()) }
if (m_background.empty() && !label->m_background.empty()) {
m_background = label->m_background; m_background = label->m_background;
if (m_underline.empty() && !label->m_underline.empty()) }
if (m_underline.empty() && !label->m_underline.empty()) {
m_underline = label->m_underline; m_underline = label->m_underline;
if (m_overline.empty() && !label->m_overline.empty()) }
if (m_overline.empty() && !label->m_overline.empty()) {
m_overline = label->m_overline; m_overline = label->m_overline;
if (m_font == 0 && label->m_font != 0) }
if (m_font == 0 && label->m_font != 0) {
m_font = label->m_font; m_font = label->m_font;
if (m_padding == 0 && label->m_padding != 0) }
if (m_padding == 0 && label->m_padding != 0) {
m_padding = label->m_padding; m_padding = label->m_padding;
if (m_margin == 0 && label->m_margin != 0) }
if (m_margin == 0 && label->m_margin != 0) {
m_margin = label->m_margin; m_margin = label->m_margin;
}
if (m_maxlen == 0 && label->m_maxlen != 0) { if (m_maxlen == 0 && label->m_maxlen != 0) {
m_maxlen = label->m_maxlen; m_maxlen = label->m_maxlen;
m_ellipsis = label->m_ellipsis; m_ellipsis = label->m_ellipsis;
@ -70,7 +85,7 @@ namespace drawtypes {
/** /**
* Create a label by loading values from the configuration * Create a label by loading values from the configuration
*/ */
label_t load_label(const config& conf, string section, string name, bool required, string def) { label_t load_label(const config& conf, const string& section, string name, bool required, string def) {
vector<struct bounds> bound; vector<struct bounds> bound;
size_t start, end, pos; size_t start, end, pos;
@ -78,10 +93,11 @@ namespace drawtypes {
string text; string text;
if (required) if (required) {
text = conf.get<string>(section, name); text = conf.get<string>(section, name);
else } else {
text = conf.get<string>(section, name, def); text = conf.get<string>(section, name, move(def));
}
string line{text}; string line{text};
@ -98,8 +114,9 @@ namespace drawtypes {
bound.emplace_back(bounds{token, 0, 0}); bound.emplace_back(bounds{token, 0, 0});
// find min delimiter // find min delimiter
if ((pos = token.find(':')) == string::npos) if ((pos = token.find(':')) == string::npos) {
continue; continue;
}
// strip min/max specifiers from the label string token // strip min/max specifiers from the label string token
bound.back().token = token.substr(0, pos) + '%'; bound.back().token = token.substr(0, pos) + '%';
@ -112,8 +129,9 @@ namespace drawtypes {
} }
// find max delimiter // find max delimiter
if ((pos = token.find(':', pos + 1)) == string::npos) if ((pos = token.find(':', pos + 1)) == string::npos) {
continue; continue;
}
try { try {
bound.back().max = std::stoul(&token[pos + 1], nullptr, 10); bound.back().max = std::stoul(&token[pos + 1], nullptr, 10);
@ -122,12 +140,13 @@ namespace drawtypes {
} }
// ignore max lengths less than min // ignore max lengths less than min
if (bound.back().max < bound.back().min) if (bound.back().max < bound.back().min) {
bound.back().max = 0; bound.back().max = 0;
} }
}
// clang-format off // clang-format off
return label_t{new label_t::element_type(text, return make_shared<label>(text,
conf.get<string>(section, name + "-foreground", ""), conf.get<string>(section, name + "-foreground", ""),
conf.get<string>(section, name + "-background", ""), conf.get<string>(section, name + "-background", ""),
conf.get<string>(section, name + "-underline", ""), conf.get<string>(section, name + "-underline", ""),
@ -137,7 +156,7 @@ namespace drawtypes {
conf.get<int>(section, name + "-margin", 0), conf.get<int>(section, name + "-margin", 0),
conf.get<size_t>(section, name + "-maxlen", 0), conf.get<size_t>(section, name + "-maxlen", 0),
conf.get<bool>(section, name + "-ellipsis", true), conf.get<bool>(section, name + "-ellipsis", true),
bound)}; bound);
// clang-format on // clang-format on
} }
@ -145,21 +164,21 @@ namespace drawtypes {
* Create a label by loading optional values from the configuration * Create a label by loading optional values from the configuration
*/ */
label_t load_optional_label(const config& conf, string section, string name, string def) { label_t load_optional_label(const config& conf, string section, string name, string def) {
return load_label(conf, section, name, false, def); return load_label(conf, move(section), move(name), false, move(def));
} }
/** /**
* Create an icon by loading values from the configuration * Create an icon by loading values from the configuration
*/ */
icon_t load_icon(const config& conf, string section, string name, bool required, string def) { icon_t load_icon(const config& conf, string section, string name, bool required, string def) {
return load_label(conf, section, name, required, def); return load_label(conf, move(section), move(name), required, move(def));
} }
/** /**
* Create an icon by loading optional values from the configuration * Create an icon by loading optional values from the configuration
*/ */
icon_t load_optional_icon(const config& conf, string section, string name, string def) { icon_t load_optional_icon(const config& conf, string section, string name, string def) {
return load_icon(conf, section, name, false, def); return load_icon(conf, move(section), move(name), false, move(def));
} }
} }

View File

@ -1,3 +1,5 @@
#include <utility>
#include "components/types.hpp" #include "components/types.hpp"
#include "x11/color.hpp" #include "x11/color.hpp"
@ -7,8 +9,8 @@
POLYBAR_NS POLYBAR_NS
namespace drawtypes { namespace drawtypes {
progressbar::progressbar(const bar_settings bar, int width, string format) progressbar::progressbar(const bar_settings& bar, int width, string format)
: m_builder(make_unique<builder>(bar)), m_format(format), m_width(width) {} : m_builder(make_unique<builder>(bar)), m_format(move(format)), m_width(width) {}
void progressbar::set_fill(icon_t&& fill) { void progressbar::set_fill(icon_t&& fill) {
m_fill = forward<decltype(fill)>(fill); m_fill = forward<decltype(fill)>(fill);
@ -19,8 +21,9 @@ namespace drawtypes {
} }
void progressbar::set_indicator(icon_t&& indicator) { void progressbar::set_indicator(icon_t&& indicator) {
if (!m_indicator && indicator.get()) if (!m_indicator && indicator.get()) {
m_width--; m_width--;
}
m_indicator = forward<decltype(indicator)>(indicator); m_indicator = forward<decltype(indicator)>(indicator);
} }
@ -31,11 +34,12 @@ namespace drawtypes {
void progressbar::set_colors(vector<string>&& colors) { void progressbar::set_colors(vector<string>&& colors) {
m_colors = forward<decltype(colors)>(colors); m_colors = forward<decltype(colors)>(colors);
if (m_colors.empty()) if (m_colors.empty()) {
m_colorstep = 1; m_colorstep = 1;
else } else {
m_colorstep = m_width / m_colors.size(); m_colorstep = m_width / m_colors.size();
} }
}
string progressbar::output(float percentage) { string progressbar::output(float percentage) {
string output{m_format}; string output{m_format};
@ -54,7 +58,9 @@ namespace drawtypes {
output = string_util::replace_all(output, "%indicator%", m_builder->flush()); output = string_util::replace_all(output, "%indicator%", m_builder->flush());
// Output empty icons // Output empty icons
while (empty_width--) m_builder->node(m_empty); while (empty_width--) {
m_builder->node(m_empty);
}
output = string_util::replace_all(output, "%empty%", m_builder->flush()); output = string_util::replace_all(output, "%empty%", m_builder->flush());
return output; return output;
@ -68,8 +74,9 @@ namespace drawtypes {
} else if (m_gradient) { } else if (m_gradient) {
size_t color = 0; size_t color = 0;
for (size_t i = 0; i < fill_width; i++) { for (size_t i = 0; i < fill_width; i++) {
if (i % m_colorstep == 0 && color < m_colors.size()) if (i % m_colorstep == 0 && color < m_colors.size()) {
m_fill->m_foreground = m_colors[color++]; m_fill->m_foreground = m_colors[color++];
}
m_builder->node(m_fill); m_builder->node(m_fill);
} }
} else { } else {
@ -85,17 +92,19 @@ namespace drawtypes {
* Create a progressbar by loading values * Create a progressbar by loading values
* from the configuration * from the configuration
*/ */
progressbar_t load_progressbar(const bar_settings& bar, const config& conf, string section, string name) { progressbar_t load_progressbar(const bar_settings& bar, const config& conf, const string& section, string name) {
// Remove the start and end tag from the name in case a format tag is passed // Remove the start and end tag from the name in case a format tag is passed
name = string_util::ltrim(string_util::rtrim(name, '>'), '<'); name = string_util::ltrim(string_util::rtrim(name, '>'), '<');
string format = "%fill%%indicator%%empty%"; string format = "%fill%%indicator%%empty%";
unsigned int width; unsigned int width;
if ((format = conf.get<decltype(format)>(section, name + "-format", format)).empty()) if ((format = conf.get<decltype(format)>(section, name + "-format", format)).empty()) {
throw application_error("Invalid format defined at [" + conf.build_path(section, name) + "]"); throw application_error("Invalid format defined at [" + conf.build_path(section, name) + "]");
if ((width = conf.get<decltype(width)>(section, name + "-width")) < 1) }
if ((width = conf.get<decltype(width)>(section, name + "-width")) < 1) {
throw application_error("Invalid width defined at [" + conf.build_path(section, name) + "]"); throw application_error("Invalid width defined at [" + conf.build_path(section, name) + "]");
}
progressbar_t progressbar{new progressbar_t::element_type(bar, width, format)}; progressbar_t progressbar{new progressbar_t::element_type(bar, width, format)};
progressbar->set_gradient(conf.get<bool>(section, name + "-gradient", true)); progressbar->set_gradient(conf.get<bool>(section, name + "-gradient", true));
@ -105,22 +114,27 @@ namespace drawtypes {
icon_t icon_fill; icon_t icon_fill;
icon_t icon_indicator; icon_t icon_indicator;
if (format.find("%empty%") != string::npos) if (format.find("%empty%") != string::npos) {
icon_empty = load_icon(conf, section, name + "-empty"); icon_empty = load_icon(conf, section, name + "-empty");
if (format.find("%fill%") != string::npos) }
if (format.find("%fill%") != string::npos) {
icon_fill = load_icon(conf, section, name + "-fill"); icon_fill = load_icon(conf, section, name + "-fill");
if (format.find("%indicator%") != string::npos) }
if (format.find("%indicator%") != string::npos) {
icon_indicator = load_icon(conf, section, name + "-indicator"); icon_indicator = load_icon(conf, section, name + "-indicator");
}
// If a foreground/background color is defined for the indicator // If a foreground/background color is defined for the indicator
// but not for the empty icon we use the bar's default colors to // but not for the empty icon we use the bar's default colors to
// avoid color bleed // avoid color bleed
if (icon_empty && icon_indicator) { if (icon_empty && icon_indicator) {
if (!icon_indicator->m_background.empty() && icon_empty->m_background.empty()) if (!icon_indicator->m_background.empty() && icon_empty->m_background.empty()) {
icon_empty->m_background = color_util::hex<uint16_t>(bar.background); icon_empty->m_background = color_util::hex<uint16_t>(bar.background);
if (!icon_indicator->m_foreground.empty() && icon_empty->m_foreground.empty()) }
if (!icon_indicator->m_foreground.empty() && icon_empty->m_foreground.empty()) {
icon_empty->m_foreground = color_util::hex<uint16_t>(bar.foreground); icon_empty->m_foreground = color_util::hex<uint16_t>(bar.foreground);
} }
}
progressbar->set_empty(move(icon_empty)); progressbar->set_empty(move(icon_empty));
progressbar->set_fill(move(icon_fill)); progressbar->set_fill(move(icon_fill));

View File

@ -25,7 +25,7 @@ namespace drawtypes {
* Create a ramp by loading values * Create a ramp by loading values
* from the configuration * from the configuration
*/ */
ramp_t load_ramp(const config& conf, string section, string name, bool required) { ramp_t load_ramp(const config& conf, const string& section, string name, bool required) {
name = string_util::ltrim(string_util::rtrim(name, '>'), '<'); name = string_util::ltrim(string_util::rtrim(name, '>'), '<');
auto ramp_defaults = load_optional_icon(conf, section, name); auto ramp_defaults = load_optional_icon(conf, section, name);
@ -33,10 +33,11 @@ namespace drawtypes {
vector<icon_t> vec; vector<icon_t> vec;
vector<string> icons; vector<string> icons;
if (required) if (required) {
icons = conf.get_list<string>(section, name); icons = conf.get_list<string>(section, name);
else } else {
icons = conf.get_list<string>(section, name, {}); icons = conf.get_list<string>(section, name, {});
}
for (size_t i = 0; i < icons.size(); i++) { for (size_t i = 0; i < icons.size(); i++) {
auto icon = load_optional_icon(conf, section, name + "-" + to_string(i), icons[i]); auto icon = load_optional_icon(conf, section, name + "-" + to_string(i), icons[i]);
@ -44,7 +45,7 @@ namespace drawtypes {
vec.emplace_back(move(icon)); vec.emplace_back(move(icon));
} }
return ramp_t{new ramp_t::element_type(move(vec))}; return make_shared<ramp>(move(vec));
} }
} }

View File

@ -126,10 +126,11 @@ int main(int argc, char** argv) {
ctrl->run(); ctrl->run();
if (ctrl->completed()) { if (ctrl->completed()) {
quit = true; throw exit_success{};
} else { } else {
logger.info("Reloading application..."); logger.info("Reloading application...");
} }
} catch (const exit_success& term) { } catch (const exit_success& term) {
exit_code = EXIT_SUCCESS; exit_code = EXIT_SUCCESS;
quit = true; quit = true;

View File

@ -14,14 +14,15 @@ namespace modules {
template class module<backlight_module>; template class module<backlight_module>;
template class inotify_module<backlight_module>; template class inotify_module<backlight_module>;
void brightness_handle::filepath(string path) { void brightness_handle::filepath(const string& path) {
if (!file_util::exists(path)) if (!file_util::exists(path)) {
throw module_error("The file '" + path + "' does not exist"); throw module_error("The file '" + path + "' does not exist");
}
m_path = path; m_path = path;
} }
float brightness_handle::read() const { float brightness_handle::read() const {
return std::strtof(file_util::get_contents(m_path).c_str(), 0); return std::strtof(file_util::get_contents(m_path).c_str(), nullptr);
} }
void backlight_module::setup() { void backlight_module::setup() {
@ -31,12 +32,15 @@ namespace modules {
// Add formats and elements // Add formats and elements
m_formatter->add(DEFAULT_FORMAT, TAG_LABEL, {TAG_LABEL, TAG_BAR, TAG_RAMP}); m_formatter->add(DEFAULT_FORMAT, TAG_LABEL, {TAG_LABEL, TAG_BAR, TAG_RAMP});
if (m_formatter->has(TAG_LABEL)) if (m_formatter->has(TAG_LABEL)) {
m_label = load_optional_label(m_conf, name(), TAG_LABEL, "%percentage%"); m_label = load_optional_label(m_conf, name(), TAG_LABEL, "%percentage%");
if (m_formatter->has(TAG_BAR)) }
if (m_formatter->has(TAG_BAR)) {
m_progressbar = load_progressbar(m_bar, m_conf, name(), TAG_BAR); m_progressbar = load_progressbar(m_bar, m_conf, name(), TAG_BAR);
if (m_formatter->has(TAG_RAMP)) }
if (m_formatter->has(TAG_RAMP)) {
m_ramp = load_ramp(m_conf, name(), TAG_RAMP); m_ramp = load_ramp(m_conf, name(), TAG_RAMP);
}
// Build path to the file where the current/maximum brightness value is located // Build path to the file where the current/maximum brightness value is located
m_val.filepath(string_util::replace(PATH_BACKLIGHT_VAL, "%card%", card)); m_val.filepath(string_util::replace(PATH_BACKLIGHT_VAL, "%card%", card));
@ -51,8 +55,9 @@ namespace modules {
} }
bool backlight_module::on_event(inotify_event* event) { bool backlight_module::on_event(inotify_event* event) {
if (event != nullptr) if (event != nullptr) {
m_log.trace("%s: %s", name(), event->filename); m_log.trace("%s: %s", name(), event->filename);
}
m_percentage = static_cast<int>(m_val.read() / m_max.read() * 100.0f + 0.5f); m_percentage = static_cast<int>(m_val.read() / m_max.read() * 100.0f + 0.5f);
@ -64,15 +69,16 @@ namespace modules {
return true; return true;
} }
bool backlight_module::build(builder* builder, string tag) const { bool backlight_module::build(builder* builder, const string& tag) const {
if (tag == TAG_BAR) if (tag == TAG_BAR) {
builder->node(m_progressbar->output(m_percentage)); builder->node(m_progressbar->output(m_percentage));
else if (tag == TAG_RAMP) } else if (tag == TAG_RAMP) {
builder->node(m_ramp->get_by_percentage(m_percentage)); builder->node(m_ramp->get_by_percentage(m_percentage));
else if (tag == TAG_LABEL) } else if (tag == TAG_LABEL) {
builder->node(m_label); builder->node(m_label);
else } else {
return false; return false;
}
return true; return true;
} }
} }

View File

@ -27,37 +27,46 @@ namespace modules {
auto path_adapter = string_util::replace(PATH_ADAPTER, "%adapter%", adapter) + "/"; auto path_adapter = string_util::replace(PATH_ADAPTER, "%adapter%", adapter) + "/";
auto path_battery = string_util::replace(PATH_BATTERY, "%battery%", battery) + "/"; auto path_battery = string_util::replace(PATH_BATTERY, "%battery%", battery) + "/";
if (!file_util::exists(path_adapter + "online")) if (!file_util::exists(path_adapter + "online")) {
throw module_error("The file '" + path_adapter + "online' does not exist"); throw module_error("The file '" + path_adapter + "online' does not exist");
}
m_valuepath[battery_value::ADAPTER] = path_adapter + "online"; m_valuepath[battery_value::ADAPTER] = path_adapter + "online";
if (!file_util::exists(path_battery + "capacity")) if (!file_util::exists(path_battery + "capacity")) {
throw module_error("The file '" + path_battery + "capacity' does not exist"); throw module_error("The file '" + path_battery + "capacity' does not exist");
}
m_valuepath[battery_value::CAPACITY_PERC] = path_battery + "capacity"; m_valuepath[battery_value::CAPACITY_PERC] = path_battery + "capacity";
if (!file_util::exists(path_battery + "voltage_now")) if (!file_util::exists(path_battery + "voltage_now")) {
throw module_error("The file '" + path_battery + "voltage_now' does not exist"); throw module_error("The file '" + path_battery + "voltage_now' does not exist");
}
m_valuepath[battery_value::VOLTAGE] = path_battery + "voltage_now"; m_valuepath[battery_value::VOLTAGE] = path_battery + "voltage_now";
for (auto&& file : vector<string>{"charge", "energy"}) { for (auto&& file : vector<string>{"charge", "energy"}) {
if (file_util::exists(path_battery + file + "_now")) if (file_util::exists(path_battery + file + "_now")) {
m_valuepath[battery_value::CAPACITY] = path_battery + file + "_now"; m_valuepath[battery_value::CAPACITY] = path_battery + file + "_now";
if (file_util::exists(path_battery + file + "_full")) }
if (file_util::exists(path_battery + file + "_full")) {
m_valuepath[battery_value::CAPACITY_MAX] = path_battery + file + "_full"; m_valuepath[battery_value::CAPACITY_MAX] = path_battery + file + "_full";
} }
if (m_valuepath[battery_value::CAPACITY].empty())
throw module_error("The file '" + path_battery + "[charge|energy]_now' does not exist");
if (m_valuepath[battery_value::CAPACITY_MAX].empty())
throw module_error("The file '" + path_battery + "[charge|energy]_full' does not exist");
for (auto&& file : vector<string>{"current", "power"}) {
if (file_util::exists(path_battery + file + "_now"))
m_valuepath[battery_value::RATE] = path_battery + file + "_now";
} }
if (m_valuepath[battery_value::RATE].empty()) if (m_valuepath[battery_value::CAPACITY].empty()) {
throw module_error("The file '" + path_battery + "[charge|energy]_now' does not exist");
}
if (m_valuepath[battery_value::CAPACITY_MAX].empty()) {
throw module_error("The file '" + path_battery + "[charge|energy]_full' does not exist");
}
for (auto&& file : vector<string>{"current", "power"}) {
if (file_util::exists(path_battery + file + "_now")) {
m_valuepath[battery_value::RATE] = path_battery + file + "_now";
}
}
if (m_valuepath[battery_value::RATE].empty()) {
throw module_error("The file '" + path_battery + "[current|power]_now' does not exist"); throw module_error("The file '" + path_battery + "[current|power]_now' does not exist");
}
m_fullat = m_conf.get<int>(name(), "full-at", 100); m_fullat = m_conf.get<int>(name(), "full-at", 100);
m_interval = chrono::duration<double>{m_conf.get<float>(name(), "poll-interval", 5.0f)}; m_interval = chrono::duration<double>{m_conf.get<float>(name(), "poll-interval", 5.0f)};
@ -74,18 +83,24 @@ namespace modules {
FORMAT_DISCHARGING, TAG_LABEL_DISCHARGING, {TAG_BAR_CAPACITY, TAG_RAMP_CAPACITY, TAG_LABEL_DISCHARGING}); FORMAT_DISCHARGING, TAG_LABEL_DISCHARGING, {TAG_BAR_CAPACITY, TAG_RAMP_CAPACITY, TAG_LABEL_DISCHARGING});
m_formatter->add(FORMAT_FULL, TAG_LABEL_FULL, {TAG_BAR_CAPACITY, TAG_RAMP_CAPACITY, TAG_LABEL_FULL}); m_formatter->add(FORMAT_FULL, TAG_LABEL_FULL, {TAG_BAR_CAPACITY, TAG_RAMP_CAPACITY, TAG_LABEL_FULL});
if (m_formatter->has(TAG_ANIMATION_CHARGING, FORMAT_CHARGING)) if (m_formatter->has(TAG_ANIMATION_CHARGING, FORMAT_CHARGING)) {
m_animation_charging = load_animation(m_conf, name(), TAG_ANIMATION_CHARGING); m_animation_charging = load_animation(m_conf, name(), TAG_ANIMATION_CHARGING);
if (m_formatter->has(TAG_BAR_CAPACITY)) }
if (m_formatter->has(TAG_BAR_CAPACITY)) {
m_bar_capacity = load_progressbar(m_bar, m_conf, name(), TAG_BAR_CAPACITY); m_bar_capacity = load_progressbar(m_bar, m_conf, name(), TAG_BAR_CAPACITY);
if (m_formatter->has(TAG_RAMP_CAPACITY)) }
if (m_formatter->has(TAG_RAMP_CAPACITY)) {
m_ramp_capacity = load_ramp(m_conf, name(), TAG_RAMP_CAPACITY); m_ramp_capacity = load_ramp(m_conf, name(), TAG_RAMP_CAPACITY);
if (m_formatter->has(TAG_LABEL_CHARGING, FORMAT_CHARGING)) }
if (m_formatter->has(TAG_LABEL_CHARGING, FORMAT_CHARGING)) {
m_label_charging = load_optional_label(m_conf, name(), TAG_LABEL_CHARGING, "%percentage%"); m_label_charging = load_optional_label(m_conf, name(), TAG_LABEL_CHARGING, "%percentage%");
if (m_formatter->has(TAG_LABEL_DISCHARGING, FORMAT_DISCHARGING)) }
if (m_formatter->has(TAG_LABEL_DISCHARGING, FORMAT_DISCHARGING)) {
m_label_discharging = load_optional_label(m_conf, name(), TAG_LABEL_DISCHARGING, "%percentage%"); m_label_discharging = load_optional_label(m_conf, name(), TAG_LABEL_DISCHARGING, "%percentage%");
if (m_formatter->has(TAG_LABEL_FULL, FORMAT_FULL)) }
if (m_formatter->has(TAG_LABEL_FULL, FORMAT_FULL)) {
m_label_full = load_optional_label(m_conf, name(), TAG_LABEL_FULL, "%percentage%"); m_label_full = load_optional_label(m_conf, name(), TAG_LABEL_FULL, "%percentage%");
}
// Create inotify watches // Create inotify watches
watch(m_valuepath[battery_value::CAPACITY_PERC], IN_ACCESS); watch(m_valuepath[battery_value::CAPACITY_PERC], IN_ACCESS);
@ -93,8 +108,9 @@ namespace modules {
// Setup time if token is used // Setup time if token is used
if (m_label_charging->has_token("%time%") || m_label_discharging->has_token("%time%")) { if (m_label_charging->has_token("%time%") || m_label_discharging->has_token("%time%")) {
if (!m_bar.locale.empty()) if (!m_bar.locale.empty()) {
setlocale(LC_TIME, m_bar.locale.c_str()); setlocale(LC_TIME, m_bar.locale.c_str());
}
m_timeformat = m_conf.get<string>(name(), "time-format", "%H:%M:%S"); m_timeformat = m_conf.get<string>(name(), "time-format", "%H:%M:%S");
} }
} }
@ -167,14 +183,16 @@ namespace modules {
string time_remaining; string time_remaining;
if (m_state == battery_state::CHARGING && m_label_charging) { if (m_state == battery_state::CHARGING && m_label_charging) {
if (!m_timeformat.empty()) if (!m_timeformat.empty()) {
time_remaining = current_time(); time_remaining = current_time();
}
m_label_charging->reset_tokens(); m_label_charging->reset_tokens();
m_label_charging->replace_token("%percentage%", to_string(m_percentage) + "%"); m_label_charging->replace_token("%percentage%", to_string(m_percentage) + "%");
m_label_charging->replace_token("%time%", time_remaining); m_label_charging->replace_token("%time%", time_remaining);
} else if (m_state == battery_state::DISCHARGING && m_label_discharging) { } else if (m_state == battery_state::DISCHARGING && m_label_discharging) {
if (!m_timeformat.empty()) if (!m_timeformat.empty()) {
time_remaining = current_time(); time_remaining = current_time();
}
m_label_discharging->reset_tokens(); m_label_discharging->reset_tokens();
m_label_discharging->replace_token("%percentage%", to_string(m_percentage) + "%"); m_label_discharging->replace_token("%percentage%", to_string(m_percentage) + "%");
m_label_discharging->replace_token("%time%", time_remaining); m_label_discharging->replace_token("%time%", time_remaining);
@ -190,32 +208,34 @@ namespace modules {
* Get the output format based on state * Get the output format based on state
*/ */
string battery_module::get_format() const { string battery_module::get_format() const {
if (m_state == battery_state::FULL) if (m_state == battery_state::FULL) {
return FORMAT_FULL; return FORMAT_FULL;
else if (m_state == battery_state::CHARGING) } else if (m_state == battery_state::CHARGING) {
return FORMAT_CHARGING; return FORMAT_CHARGING;
else } else {
return FORMAT_DISCHARGING; return FORMAT_DISCHARGING;
} }
}
/** /**
* Generate the module output using defined drawtypes * Generate the module output using defined drawtypes
*/ */
bool battery_module::build(builder* builder, string tag) const { bool battery_module::build(builder* builder, const string& tag) const {
if (tag == TAG_ANIMATION_CHARGING) if (tag == TAG_ANIMATION_CHARGING) {
builder->node(m_animation_charging->get()); builder->node(m_animation_charging->get());
else if (tag == TAG_BAR_CAPACITY) { } else if (tag == TAG_BAR_CAPACITY) {
builder->node(m_bar_capacity->output(m_percentage)); builder->node(m_bar_capacity->output(m_percentage));
} else if (tag == TAG_RAMP_CAPACITY) } else if (tag == TAG_RAMP_CAPACITY) {
builder->node(m_ramp_capacity->get_by_percentage(m_percentage)); builder->node(m_ramp_capacity->get_by_percentage(m_percentage));
else if (tag == TAG_LABEL_CHARGING) } else if (tag == TAG_LABEL_CHARGING) {
builder->node(m_label_charging); builder->node(m_label_charging);
else if (tag == TAG_LABEL_DISCHARGING) } else if (tag == TAG_LABEL_DISCHARGING) {
builder->node(m_label_discharging); builder->node(m_label_discharging);
else if (tag == TAG_LABEL_FULL) } else if (tag == TAG_LABEL_FULL) {
builder->node(m_label_full); builder->node(m_label_full);
else } else {
return false; return false;
}
return true; return true;
} }
@ -273,15 +293,16 @@ namespace modules {
} }
struct tm t { struct tm t {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr
}; };
if (rate && volt && cap) { if (rate && volt && cap) {
cap = cap * 1000 / volt; cap = cap * 1000 / volt;
rate = rate * 1000 / volt; rate = rate * 1000 / volt;
if (!rate) if (!rate) {
rate = -1; rate = -1;
}
chrono::seconds sec{3600 * cap / rate}; chrono::seconds sec{3600 * cap / rate};

View File

@ -64,13 +64,13 @@ namespace modules {
make_pair(state_mode::MODE_NODE_PRIVATE, load_optional_label(m_conf, name(), "label-private"))); make_pair(state_mode::MODE_NODE_PRIVATE, load_optional_label(m_conf, name(), "label-private")));
} }
m_icons = iconset_t{new iconset()}; m_icons = make_shared<iconset>();
m_icons->add(DEFAULT_WS_ICON, icon_t{new icon(m_conf.get<string>(name(), DEFAULT_WS_ICON, ""))}); m_icons->add(DEFAULT_WS_ICON, make_shared<label>(m_conf.get<string>(name(), DEFAULT_WS_ICON, "")));
for (auto workspace : m_conf.get_list<string>(name(), "ws-icon", {})) { for (const auto& workspace : m_conf.get_list<string>(name(), "ws-icon", {})) {
auto vec = string_util::split(workspace, ';'); auto vec = string_util::split(workspace, ';');
if (vec.size() == 2) { if (vec.size() == 2) {
m_icons->add(vec[0], icon_t{new icon{vec[1]}}); m_icons->add(vec[0], make_shared<label>(vec[1]));
} }
} }
} // }}} } // }}}
@ -98,23 +98,28 @@ namespace modules {
ssize_t bytes = 0; ssize_t bytes = 0;
string data = m_subscriber->receive(BUFSIZ - 1, bytes, 0); string data = m_subscriber->receive(BUFSIZ - 1, bytes, 0);
if (bytes == 0) if (bytes == 0) {
return false; return false;
}
data = string_util::strip_trailing_newline(data); data = string_util::strip_trailing_newline(data);
unsigned long pos; unsigned long pos;
while ((pos = data.find("\n")) != string::npos) data.erase(pos); while ((pos = data.find('\n')) != string::npos) {
data.erase(pos);
}
if (data.empty()) if (data.empty()) {
return false; return false;
}
const auto prefix = string{BSPWM_STATUS_PREFIX}; const auto prefix = string{BSPWM_STATUS_PREFIX};
// If there were more than 1 row available in the channel // If there were more than 1 row available in the channel
// we'll strip out the old updates // we'll strip out the old updates
if ((pos = data.find_last_of(prefix)) > 0) if ((pos = data.find_last_of(prefix)) > 0) {
data = data.substr(pos); data = data.substr(pos);
}
if (data.compare(0, prefix.length(), prefix) != 0) { if (data.compare(0, prefix.length(), prefix) != 0) {
m_log.err("%s: Unknown status '%s'", name(), data); m_log.err("%s: Unknown status '%s'", name(), data);
@ -122,8 +127,9 @@ namespace modules {
} }
unsigned long hash; unsigned long hash;
if ((hash = string_util::hash(data)) == m_hash) if ((hash = string_util::hash(data)) == m_hash) {
return false; return false;
}
m_hash = hash; m_hash = hash;
// Extract the string for the defined monitor // Extract the string for the defined monitor
@ -131,16 +137,21 @@ namespace modules {
const auto needle_active = ":M" + m_bar.monitor->name + ":"; const auto needle_active = ":M" + m_bar.monitor->name + ":";
const auto needle_inactive = ":m" + m_bar.monitor->name + ":"; const auto needle_inactive = ":m" + m_bar.monitor->name + ":";
if ((pos = data.find(prefix)) != string::npos) if ((pos = data.find(prefix)) != string::npos) {
data = data.replace(pos, prefix.length(), ":"); data = data.replace(pos, prefix.length(), ":");
if ((pos = data.find(needle_active)) != string::npos) }
if ((pos = data.find(needle_active)) != string::npos) {
data.erase(0, pos + 1); data.erase(0, pos + 1);
if ((pos = data.find(needle_inactive)) != string::npos) }
if ((pos = data.find(needle_inactive)) != string::npos) {
data.erase(0, pos + 1); data.erase(0, pos + 1);
if ((pos = data.find(":m", 1)) != string::npos) }
if ((pos = data.find(":m", 1)) != string::npos) {
data.erase(pos); data.erase(pos);
if ((pos = data.find(":M", 1)) != string::npos) }
if ((pos = data.find(":M", 1)) != string::npos) {
data.erase(pos); data.erase(pos);
}
} else if ((pos = data.find(prefix)) != string::npos) { } else if ((pos = data.find(prefix)) != string::npos) {
data = data.replace(pos, prefix.length(), ":"); data = data.replace(pos, prefix.length(), ":");
} else { } else {
@ -156,7 +167,7 @@ namespace modules {
continue; continue;
} }
auto value = tag.size() > 0 ? tag.substr(1) : ""; auto value = !tag.empty() ? tag.substr(1) : "";
auto workspace_flag = state_ws::WORKSPACE_NONE; auto workspace_flag = state_ws::WORKSPACE_NONE;
auto mode_flag = state_mode::MODE_NONE; auto mode_flag = state_mode::MODE_NONE;
@ -310,7 +321,7 @@ namespace modules {
return output; return output;
} // }}} } // }}}
bool bspwm_module::build(builder* builder, string tag) const { // {{{ bool bspwm_module::build(builder* builder, const string& tag) const { // {{{
if (tag == TAG_LABEL_MONITOR) { if (tag == TAG_LABEL_MONITOR) {
builder->node(m_monitors[m_index]->label); builder->node(m_monitors[m_index]->label);
return true; return true;

View File

@ -19,7 +19,7 @@ namespace modules {
return true; return true;
} }
bool counter_module::build(builder* builder, string tag) const { bool counter_module::build(builder* builder, const string& tag) const {
if (tag == TAG_COUNTER) { if (tag == TAG_COUNTER) {
builder->node(to_string(m_counter)); builder->node(to_string(m_counter));
return true; return true;

View File

@ -19,14 +19,18 @@ namespace modules {
m_formatter->add(DEFAULT_FORMAT, TAG_LABEL, {TAG_LABEL, TAG_BAR_LOAD, TAG_RAMP_LOAD, TAG_RAMP_LOAD_PER_CORE}); m_formatter->add(DEFAULT_FORMAT, TAG_LABEL, {TAG_LABEL, TAG_BAR_LOAD, TAG_RAMP_LOAD, TAG_RAMP_LOAD_PER_CORE});
if (m_formatter->has(TAG_BAR_LOAD)) if (m_formatter->has(TAG_BAR_LOAD)) {
m_barload = load_progressbar(m_bar, m_conf, name(), TAG_BAR_LOAD); m_barload = load_progressbar(m_bar, m_conf, name(), TAG_BAR_LOAD);
if (m_formatter->has(TAG_RAMP_LOAD)) }
if (m_formatter->has(TAG_RAMP_LOAD)) {
m_rampload = load_ramp(m_conf, name(), TAG_RAMP_LOAD); m_rampload = load_ramp(m_conf, name(), TAG_RAMP_LOAD);
if (m_formatter->has(TAG_RAMP_LOAD_PER_CORE)) }
if (m_formatter->has(TAG_RAMP_LOAD_PER_CORE)) {
m_rampload_core = load_ramp(m_conf, name(), TAG_RAMP_LOAD_PER_CORE); m_rampload_core = load_ramp(m_conf, name(), TAG_RAMP_LOAD_PER_CORE);
if (m_formatter->has(TAG_LABEL)) }
if (m_formatter->has(TAG_LABEL)) {
m_label = load_optional_label(m_conf, name(), TAG_LABEL, "%percentage%"); m_label = load_optional_label(m_conf, name(), TAG_LABEL, "%percentage%");
}
// warmup // warmup
read_values(); read_values();
@ -34,16 +38,18 @@ namespace modules {
} }
bool cpu_module::update() { bool cpu_module::update() {
if (!read_values()) if (!read_values()) {
return false; return false;
}
m_total = 0.0f; m_total = 0.0f;
m_load.clear(); m_load.clear();
auto cores_n = m_cputimes.size(); auto cores_n = m_cputimes.size();
if (!cores_n) if (!cores_n) {
return false; return false;
}
for (size_t i = 0; i < cores_n; i++) { for (size_t i = 0; i < cores_n; i++) {
auto load = get_load(i); auto load = get_load(i);
@ -61,23 +67,25 @@ namespace modules {
return true; return true;
} }
bool cpu_module::build(builder* builder, string tag) const { bool cpu_module::build(builder* builder, const string& tag) const {
if (tag == TAG_LABEL) if (tag == TAG_LABEL) {
builder->node(m_label); builder->node(m_label);
else if (tag == TAG_BAR_LOAD) } else if (tag == TAG_BAR_LOAD) {
builder->node(m_barload->output(m_total)); builder->node(m_barload->output(m_total));
else if (tag == TAG_RAMP_LOAD) } else if (tag == TAG_RAMP_LOAD) {
builder->node(m_rampload->get_by_percentage(m_total)); builder->node(m_rampload->get_by_percentage(m_total));
else if (tag == TAG_RAMP_LOAD_PER_CORE) { } else if (tag == TAG_RAMP_LOAD_PER_CORE) {
auto i = 0; auto i = 0;
for (auto&& load : m_load) { for (auto&& load : m_load) {
if (i++ > 0) if (i++ > 0) {
builder->space(1); builder->space(1);
}
builder->node(m_rampload_core->get_by_percentage(load)); builder->node(m_rampload_core->get_by_percentage(load));
} }
builder->node(builder->flush()); builder->node(builder->flush());
} else } else {
return false; return false;
}
return true; return true;
} }
@ -91,16 +99,17 @@ namespace modules {
while (std::getline(in, str) && str.compare(0, 3, "cpu") == 0) { while (std::getline(in, str) && str.compare(0, 3, "cpu") == 0) {
// skip line with accumulated value // skip line with accumulated value
if (str.compare(0, 4, "cpu ") == 0) if (str.compare(0, 4, "cpu ") == 0) {
continue; continue;
}
auto values = string_util::split(str, ' '); auto values = string_util::split(str, ' ');
m_cputimes.emplace_back(new cpu_time); m_cputimes.emplace_back(new cpu_time);
m_cputimes.back()->user = std::stoull(values[1].c_str(), 0, 10); m_cputimes.back()->user = std::stoull(values[1], nullptr, 10);
m_cputimes.back()->nice = std::stoull(values[2].c_str(), 0, 10); m_cputimes.back()->nice = std::stoull(values[2], nullptr, 10);
m_cputimes.back()->system = std::stoull(values[3].c_str(), 0, 10); m_cputimes.back()->system = std::stoull(values[3], nullptr, 10);
m_cputimes.back()->idle = std::stoull(values[4].c_str(), 0, 10); m_cputimes.back()->idle = std::stoull(values[4], nullptr, 10);
m_cputimes.back()->total = m_cputimes.back()->total =
m_cputimes.back()->user + m_cputimes.back()->nice + m_cputimes.back()->system + m_cputimes.back()->idle; m_cputimes.back()->user + m_cputimes.back()->nice + m_cputimes.back()->system + m_cputimes.back()->idle;
} }
@ -112,10 +121,11 @@ namespace modules {
} }
float cpu_module::get_load(size_t core) const { float cpu_module::get_load(size_t core) const {
if (m_cputimes.empty() || m_cputimes_prev.empty()) if (m_cputimes.empty() || m_cputimes_prev.empty()) {
return 0; return 0;
else if (core >= m_cputimes.size() || core >= m_cputimes_prev.size()) } else if (core >= m_cputimes.size() || core >= m_cputimes_prev.size()) {
return 0; return 0;
}
auto& last = m_cputimes[core]; auto& last = m_cputimes[core];
auto& prev = m_cputimes_prev[core]; auto& prev = m_cputimes_prev[core];
@ -125,8 +135,9 @@ namespace modules {
auto diff = last->total - prev->total; auto diff = last->total - prev->total;
if (diff == 0) if (diff == 0) {
return 0; return 0;
}
float percentage = 100.0f * (diff - (last_idle - prev_idle)) / diff; float percentage = 100.0f * (diff - (last_idle - prev_idle)) / diff;

View File

@ -10,8 +10,9 @@ namespace modules {
template class timer_module<date_module>; template class timer_module<date_module>;
void date_module::setup() { void date_module::setup() {
if (!m_bar.locale.empty()) if (!m_bar.locale.empty()) {
setlocale(LC_TIME, m_bar.locale.c_str()); setlocale(LC_TIME, m_bar.locale.c_str());
}
m_interval = chrono::duration<double>(m_conf.get<float>(name(), "interval", 1)); m_interval = chrono::duration<double>(m_conf.get<float>(name(), "interval", 1));
@ -22,8 +23,9 @@ namespace modules {
} }
bool date_module::update() { bool date_module::update() {
if (!m_formatter->has(TAG_DATE)) if (!m_formatter->has(TAG_DATE)) {
return false; return false;
}
auto time = std::time(nullptr); auto time = std::time(nullptr);
auto date_format = m_toggled ? m_formatalt : m_format; auto date_format = m_toggled ? m_formatalt : m_format;
@ -31,21 +33,23 @@ namespace modules {
std::strftime(buffer, sizeof(buffer), date_format.c_str(), std::localtime(&time)); std::strftime(buffer, sizeof(buffer), date_format.c_str(), std::localtime(&time));
if (std::strncmp(buffer, m_buffer, sizeof(buffer)) == 0) if (std::strncmp(buffer, m_buffer, sizeof(buffer)) == 0) {
return false; return false;
else } else {
std::memmove(m_buffer, buffer, sizeof(buffer)); std::memmove(m_buffer, buffer, sizeof(buffer));
}
return true; return true;
} }
bool date_module::build(builder* builder, string tag) const { bool date_module::build(builder* builder, const string& tag) const {
if (tag != TAG_DATE) { if (tag != TAG_DATE) {
return false; return false;
} }
if (!m_formatalt.empty()) if (!m_formatalt.empty()) {
m_builder->cmd(mousebtn::LEFT, EVENT_TOGGLE); m_builder->cmd(mousebtn::LEFT, EVENT_TOGGLE);
}
builder->node(m_buffer); builder->node(m_buffer);

View File

@ -33,17 +33,22 @@ namespace modules {
FORMAT_MOUNTED, TAG_LABEL_MOUNTED, {TAG_LABEL_MOUNTED, TAG_BAR_FREE, TAG_BAR_USED, TAG_RAMP_CAPACITY}); FORMAT_MOUNTED, TAG_LABEL_MOUNTED, {TAG_LABEL_MOUNTED, TAG_BAR_FREE, TAG_BAR_USED, TAG_RAMP_CAPACITY});
m_formatter->add(FORMAT_UNMOUNTED, TAG_LABEL_UNMOUNTED, {TAG_LABEL_UNMOUNTED}); m_formatter->add(FORMAT_UNMOUNTED, TAG_LABEL_UNMOUNTED, {TAG_LABEL_UNMOUNTED});
if (m_formatter->has(TAG_LABEL_MOUNTED)) if (m_formatter->has(TAG_LABEL_MOUNTED)) {
m_labelmounted = load_optional_label(m_conf, name(), TAG_LABEL_MOUNTED, "%mountpoint% %percentage_free%"); m_labelmounted = load_optional_label(m_conf, name(), TAG_LABEL_MOUNTED, "%mountpoint% %percentage_free%");
if (m_formatter->has(TAG_LABEL_UNMOUNTED)) }
if (m_formatter->has(TAG_LABEL_UNMOUNTED)) {
m_labelunmounted = load_optional_label(m_conf, name(), TAG_LABEL_UNMOUNTED, "%mountpoint% is not mounted"); m_labelunmounted = load_optional_label(m_conf, name(), TAG_LABEL_UNMOUNTED, "%mountpoint% is not mounted");
if (m_formatter->has(TAG_BAR_FREE)) }
if (m_formatter->has(TAG_BAR_FREE)) {
m_barfree = load_progressbar(m_bar, m_conf, name(), TAG_BAR_FREE); m_barfree = load_progressbar(m_bar, m_conf, name(), TAG_BAR_FREE);
if (m_formatter->has(TAG_BAR_USED)) }
if (m_formatter->has(TAG_BAR_USED)) {
m_barused = load_progressbar(m_bar, m_conf, name(), TAG_BAR_USED); m_barused = load_progressbar(m_bar, m_conf, name(), TAG_BAR_USED);
if (m_formatter->has(TAG_RAMP_CAPACITY)) }
if (m_formatter->has(TAG_RAMP_CAPACITY)) {
m_rampcapacity = load_ramp(m_conf, name(), TAG_RAMP_CAPACITY); m_rampcapacity = load_ramp(m_conf, name(), TAG_RAMP_CAPACITY);
} }
}
/** /**
* Update values by reading mtab entries * Update values by reading mtab entries
@ -100,8 +105,9 @@ namespace modules {
string output; string output;
for (m_index = 0; m_index < m_mounts.size(); ++m_index) { for (m_index = 0; m_index < m_mounts.size(); ++m_index) {
if (!output.empty()) if (!output.empty()) {
m_builder->space(m_spacing); m_builder->space(m_spacing);
}
output += timer_module::get_output(); output += timer_module::get_output();
} }
@ -118,7 +124,7 @@ namespace modules {
/** /**
* Output content using configured format tags * Output content using configured format tags
*/ */
bool fs_module::build(builder* builder, string tag) const { bool fs_module::build(builder* builder, const string& tag) const {
auto& mount = m_mounts[m_index]; auto& mount = m_mounts[m_index];
if (tag == TAG_BAR_FREE) { if (tag == TAG_BAR_FREE) {

View File

@ -41,13 +41,14 @@ namespace modules {
make_pair(i3_flag::WORKSPACE_URGENT, load_optional_label(m_conf, name(), "label-urgent", DEFAULT_WS_LABEL))); make_pair(i3_flag::WORKSPACE_URGENT, load_optional_label(m_conf, name(), "label-urgent", DEFAULT_WS_LABEL)));
} }
m_icons = iconset_t{new iconset()}; m_icons = make_shared<iconset>();
m_icons->add(DEFAULT_WS_ICON, icon_t{new icon(m_conf.get<string>(name(), DEFAULT_WS_ICON, ""))}); m_icons->add(DEFAULT_WS_ICON, make_shared<label>(m_conf.get<string>(name(), DEFAULT_WS_ICON, "")));
for (auto workspace : m_conf.get_list<string>(name(), "ws-icon", {})) { for (const auto& workspace : m_conf.get_list<string>(name(), "ws-icon", {})) {
auto vec = string_util::split(workspace, ';'); auto vec = string_util::split(workspace, ';');
if (vec.size() == 2) if (vec.size() == 2) {
m_icons->add(vec[0], icon_t{new icon{vec[1]}}); m_icons->add(vec[0], make_shared<label>(vec[1]));
}
} }
try { try {
@ -82,11 +83,12 @@ namespace modules {
vector<shared_ptr<i3ipc::workspace_t>> sorted = workspaces; vector<shared_ptr<i3ipc::workspace_t>> sorted = workspaces;
string focused_output; string focused_output;
for (auto&& workspace : workspaces) for (auto&& workspace : workspaces) {
if (workspace->focused) { if (workspace->focused) {
focused_output = workspace->output; focused_output = workspace->output;
break; break;
} }
}
if (m_indexsort) { if (m_indexsort) {
using ws_t = shared_ptr<i3ipc::workspace_t>; using ws_t = shared_ptr<i3ipc::workspace_t>;
@ -98,31 +100,35 @@ namespace modules {
} }
for (auto&& workspace : sorted) { for (auto&& workspace : sorted) {
if (m_pinworkspaces && workspace->output != m_bar.monitor->name) if (m_pinworkspaces && workspace->output != m_bar.monitor->name) {
continue; continue;
}
auto flag = i3_flag::WORKSPACE_NONE; auto flag = i3_flag::WORKSPACE_NONE;
if (workspace->focused) if (workspace->focused) {
flag = i3_flag::WORKSPACE_FOCUSED; flag = i3_flag::WORKSPACE_FOCUSED;
else if (workspace->urgent) } else if (workspace->urgent) {
flag = i3_flag::WORKSPACE_URGENT; flag = i3_flag::WORKSPACE_URGENT;
else if (!workspace->visible || (workspace->visible && workspace->output != focused_output)) } else if (!workspace->visible || (workspace->visible && workspace->output != focused_output)) {
flag = i3_flag::WORKSPACE_UNFOCUSED; flag = i3_flag::WORKSPACE_UNFOCUSED;
else } else {
flag = i3_flag::WORKSPACE_VISIBLE; flag = i3_flag::WORKSPACE_VISIBLE;
}
string wsname{workspace->name}; string wsname{workspace->name};
// Remove workspace numbers "0:" // Remove workspace numbers "0:"
if (m_strip_wsnumbers) if (m_strip_wsnumbers) {
wsname.erase(0, string_util::find_nth(wsname, 0, ":", 1) + 1); wsname.erase(0, string_util::find_nth(wsname, 0, ":", 1) + 1);
}
// Trim leading and trailing whitespace // Trim leading and trailing whitespace
wsname = string_util::trim(wsname, ' '); wsname = string_util::trim(wsname, ' ');
// Cap at configured max length // Cap at configured max length
if (m_wsname_maxlen > 0 && wsname.length() > m_wsname_maxlen) if (m_wsname_maxlen > 0 && wsname.length() > m_wsname_maxlen) {
wsname.erase(m_wsname_maxlen); wsname.erase(m_wsname_maxlen);
}
auto icon = m_icons->get(workspace->name, DEFAULT_WS_ICON); auto icon = m_icons->get(workspace->name, DEFAULT_WS_ICON);
auto label = m_statelabels.find(flag)->second->clone(); auto label = m_statelabels.find(flag)->second->clone();
@ -132,7 +138,7 @@ namespace modules {
label->replace_token("%name%", wsname); label->replace_token("%name%", wsname);
label->replace_token("%icon%", icon->get()); label->replace_token("%icon%", icon->get());
label->replace_token("%index%", to_string(workspace->num)); label->replace_token("%index%", to_string(workspace->num));
m_workspaces.emplace_back(make_unique<i3_workspace>(workspace->num, flag, std::move(label))); m_workspaces.emplace_back(make_unique<i3_workspace>(workspace->num, flag, move(label)));
} }
return true; return true;
@ -142,9 +148,10 @@ namespace modules {
} }
} // }}} } // }}}
bool i3_module::build(builder* builder, string tag) const { // {{{ bool i3_module::build(builder* builder, const string& tag) const { // {{{
if (tag != TAG_LABEL_STATE) if (tag != TAG_LABEL_STATE) {
return false; return false;
}
if (m_scroll) { if (m_scroll) {
builder->cmd(mousebtn::SCROLL_DOWN, EVENT_SCROLL_DOWN); builder->cmd(mousebtn::SCROLL_DOWN, EVENT_SCROLL_DOWN);
@ -153,11 +160,11 @@ namespace modules {
for (auto&& ws : m_workspaces) { for (auto&& ws : m_workspaces) {
if (m_click) { if (m_click) {
builder->cmd(mousebtn::LEFT, string{EVENT_CLICK} + to_string(ws.get()->index)); builder->cmd(mousebtn::LEFT, string{EVENT_CLICK} + to_string(ws->index));
builder->node(ws.get()->label); builder->node(ws->label);
builder->cmd_close(); builder->cmd_close();
} else { } else {
builder->node(ws.get()->label); builder->node(ws->label);
} }
} }
@ -170,8 +177,9 @@ namespace modules {
} // }}} } // }}}
bool i3_module::handle_event(string cmd) { // {{{ bool i3_module::handle_event(string cmd) { // {{{
if (cmd.compare(0, 2, EVENT_PREFIX) != 0) if (cmd.compare(0, 2, EVENT_PREFIX) != 0) {
return false; return false;
}
try { try {
i3_util::connection_t ipc; i3_util::connection_t ipc;

View File

@ -39,16 +39,21 @@ namespace modules {
* Wrap the output with defined mouse actions * Wrap the output with defined mouse actions
*/ */
string ipc_module::get_output() { string ipc_module::get_output() {
if (!m_actions[mousebtn::LEFT].empty()) if (!m_actions[mousebtn::LEFT].empty()) {
m_builder->cmd(mousebtn::LEFT, m_actions[mousebtn::LEFT]); m_builder->cmd(mousebtn::LEFT, m_actions[mousebtn::LEFT]);
if (!m_actions[mousebtn::MIDDLE].empty()) }
if (!m_actions[mousebtn::MIDDLE].empty()) {
m_builder->cmd(mousebtn::MIDDLE, m_actions[mousebtn::MIDDLE]); m_builder->cmd(mousebtn::MIDDLE, m_actions[mousebtn::MIDDLE]);
if (!m_actions[mousebtn::RIGHT].empty()) }
if (!m_actions[mousebtn::RIGHT].empty()) {
m_builder->cmd(mousebtn::RIGHT, m_actions[mousebtn::RIGHT]); m_builder->cmd(mousebtn::RIGHT, m_actions[mousebtn::RIGHT]);
if (!m_actions[mousebtn::SCROLL_UP].empty()) }
if (!m_actions[mousebtn::SCROLL_UP].empty()) {
m_builder->cmd(mousebtn::SCROLL_UP, m_actions[mousebtn::SCROLL_UP]); m_builder->cmd(mousebtn::SCROLL_UP, m_actions[mousebtn::SCROLL_UP]);
if (!m_actions[mousebtn::SCROLL_DOWN].empty()) }
if (!m_actions[mousebtn::SCROLL_DOWN].empty()) {
m_builder->cmd(mousebtn::SCROLL_DOWN, m_actions[mousebtn::SCROLL_DOWN]); m_builder->cmd(mousebtn::SCROLL_DOWN, m_actions[mousebtn::SCROLL_DOWN]);
}
m_builder->append(module::get_output()); m_builder->append(module::get_output());
@ -58,11 +63,12 @@ namespace modules {
/** /**
* Output content retrieved from hook commands * Output content retrieved from hook commands
*/ */
bool ipc_module::build(builder* builder, string tag) const { bool ipc_module::build(builder* builder, const string& tag) const {
if (tag == TAG_OUTPUT) if (tag == TAG_OUTPUT) {
builder->node(m_output); builder->node(m_output);
else } else {
return false; return false;
}
return true; return true;
} }

View File

@ -17,13 +17,16 @@ namespace modules {
m_formatter->add(DEFAULT_FORMAT, TAG_LABEL, {TAG_LABEL, TAG_BAR_USED, TAG_BAR_FREE}); m_formatter->add(DEFAULT_FORMAT, TAG_LABEL, {TAG_LABEL, TAG_BAR_USED, TAG_BAR_FREE});
if (m_formatter->has(TAG_BAR_USED)) if (m_formatter->has(TAG_BAR_USED)) {
m_bars[memtype::USED] = load_progressbar(m_bar, m_conf, name(), TAG_BAR_USED); m_bars[memtype::USED] = load_progressbar(m_bar, m_conf, name(), TAG_BAR_USED);
if (m_formatter->has(TAG_BAR_FREE)) }
if (m_formatter->has(TAG_BAR_FREE)) {
m_bars[memtype::FREE] = load_progressbar(m_bar, m_conf, name(), TAG_BAR_FREE); m_bars[memtype::FREE] = load_progressbar(m_bar, m_conf, name(), TAG_BAR_FREE);
if (m_formatter->has(TAG_LABEL)) }
if (m_formatter->has(TAG_LABEL)) {
m_label = load_optional_label(m_conf, name(), TAG_LABEL, "%percentage_used%"); m_label = load_optional_label(m_conf, name(), TAG_LABEL, "%percentage_used%");
} }
}
bool memory_module::update() { bool memory_module::update() {
float kb_total; float kb_total;
@ -42,7 +45,7 @@ namespace modules {
while (std::getline(in, str) && i++ < 3) { while (std::getline(in, str) && i++ < 3) {
size_t off = str.find_first_of("1234567890", str.find(':')); size_t off = str.find_first_of("1234567890", str.find(':'));
buffer << std::strtol(&str[off], 0, 10) << std::endl; buffer << std::strtol(&str[off], nullptr, 10) << std::endl;
} }
buffer >> rdbuf; buffer >> rdbuf;
@ -57,10 +60,11 @@ namespace modules {
m_log.err("Failed to read memory values (what: %s)", e.what()); m_log.err("Failed to read memory values (what: %s)", e.what());
} }
if (kb_total > 0) if (kb_total > 0) {
m_perc[memtype::FREE] = (kb_avail / kb_total) * 100.0f + 0.5f; m_perc[memtype::FREE] = (kb_avail / kb_total) * 100.0f + 0.5f;
else } else {
m_perc[memtype::FREE] = 0; m_perc[memtype::FREE] = 0;
}
m_perc[memtype::USED] = 100 - m_perc[memtype::FREE]; m_perc[memtype::USED] = 100 - m_perc[memtype::FREE];
@ -88,15 +92,16 @@ namespace modules {
return true; return true;
} }
bool memory_module::build(builder* builder, string tag) const { bool memory_module::build(builder* builder, const string& tag) const {
if (tag == TAG_BAR_USED) if (tag == TAG_BAR_USED) {
builder->node(m_bars.at(memtype::USED)->output(m_perc.at(memtype::USED))); builder->node(m_bars.at(memtype::USED)->output(m_perc.at(memtype::USED)));
else if (tag == TAG_BAR_FREE) } else if (tag == TAG_BAR_FREE) {
builder->node(m_bars.at(memtype::FREE)->output(m_perc.at(memtype::FREE))); builder->node(m_bars.at(memtype::FREE)->output(m_perc.at(memtype::FREE)));
else if (tag == TAG_LABEL) } else if (tag == TAG_LABEL) {
builder->node(m_label); builder->node(m_label);
else } else {
return false; return false;
}
return true; return true;
} }
} }

View File

@ -24,14 +24,16 @@ namespace modules {
m_labelseparator = load_optional_label(m_conf, name(), "label-separator", ""); m_labelseparator = load_optional_label(m_conf, name(), "label-separator", "");
if (!m_formatter->has(TAG_MENU)) if (!m_formatter->has(TAG_MENU)) {
return; return;
}
while (true) { while (true) {
string level_param{"menu-" + to_string(m_levels.size())}; string level_param{"menu-" + to_string(m_levels.size())};
if (m_conf.get<string>(name(), level_param + "-0", "").empty()) if (m_conf.get<string>(name(), level_param + "-0", "").empty()) {
break; break;
}
m_log.trace("%s: Creating menu level %i", name(), m_levels.size()); m_log.trace("%s: Creating menu level %i", name(), m_levels.size());
m_levels.emplace_back(make_unique<menu_tree>()); m_levels.emplace_back(make_unique<menu_tree>());
@ -39,19 +41,20 @@ namespace modules {
while (true) { while (true) {
string item_param{level_param + "-" + to_string(m_levels.back()->items.size())}; string item_param{level_param + "-" + to_string(m_levels.back()->items.size())};
if (m_conf.get<string>(name(), item_param, "").empty()) if (m_conf.get<string>(name(), item_param, "").empty()) {
break; break;
}
m_log.trace("%s: Creating menu level item %i", name(), m_levels.back()->items.size()); m_log.trace("%s: Creating menu level item %i", name(), m_levels.back()->items.size());
auto item = make_unique<menu_tree_item>(); auto item = make_unique<menu_tree_item>();
item->label = load_label(m_conf, name(), item_param); item->label = load_label(m_conf, name(), item_param);
item->exec = m_conf.get<string>(name(), item_param + "-exec", EVENT_MENU_CLOSE); item->exec = m_conf.get<string>(name(), item_param + "-exec", EVENT_MENU_CLOSE);
m_levels.back()->items.emplace_back(std::move(item)); m_levels.back()->items.emplace_back(move(item));
} }
} }
} }
bool menu_module::build(builder* builder, string tag) const { bool menu_module::build(builder* builder, const string& tag) const {
if (tag == TAG_LABEL_TOGGLE && m_level == -1) { if (tag == TAG_LABEL_TOGGLE && m_level == -1) {
builder->cmd(mousebtn::LEFT, string(EVENT_MENU_OPEN) + "0"); builder->cmd(mousebtn::LEFT, string(EVENT_MENU_OPEN) + "0");
builder->node(m_labelopen); builder->node(m_labelopen);
@ -62,10 +65,12 @@ namespace modules {
builder->cmd_close(); builder->cmd_close();
} else if (tag == TAG_MENU && m_level > -1) { } else if (tag == TAG_MENU && m_level > -1) {
for (auto&& item : m_levels[m_level]->items) { for (auto&& item : m_levels[m_level]->items) {
if (item != m_levels[m_level]->items.front()) if (item != m_levels[m_level]->items.front()) {
builder->space(); builder->space();
if (*m_labelseparator) }
if (*m_labelseparator) {
builder->node(m_labelseparator, true); builder->node(m_labelseparator, true);
}
builder->cmd(mousebtn::LEFT, item->exec); builder->cmd(mousebtn::LEFT, item->exec);
builder->node(item->label); builder->node(item->label);
builder->cmd_close(); builder->cmd_close();
@ -77,16 +82,19 @@ namespace modules {
} }
bool menu_module::handle_event(string cmd) { bool menu_module::handle_event(string cmd) {
if (cmd.compare(0, 4, "menu") != 0) if (cmd.compare(0, 4, "menu") != 0) {
return false; return false;
}
// broadcast update when leaving leaving the function // broadcast update when leaving leaving the function
auto exit_handler = scope_util::make_exit_handler<>([this]() { auto exit_handler = scope_util::make_exit_handler<>([this]() {
if (!m_threads.empty()) { if (!m_threads.empty()) {
m_log.trace("%s: Cleaning up previous broadcast threads", name()); m_log.trace("%s: Cleaning up previous broadcast threads", name());
for (auto&& thread : m_threads) for (auto&& thread : m_threads) {
if (thread.joinable()) if (thread.joinable()) {
thread.join(); thread.join();
}
}
m_threads.clear(); m_threads.clear();
} }
@ -97,9 +105,9 @@ namespace modules {
if (cmd.compare(0, strlen(EVENT_MENU_OPEN), EVENT_MENU_OPEN) == 0) { if (cmd.compare(0, strlen(EVENT_MENU_OPEN), EVENT_MENU_OPEN) == 0) {
auto level = cmd.substr(strlen(EVENT_MENU_OPEN)); auto level = cmd.substr(strlen(EVENT_MENU_OPEN));
if (level.empty()) if (level.empty()) {
level = "0"; level = "0";
}
m_level = std::atoi(level.c_str()); m_level = std::atoi(level.c_str());
m_log.info("%s: Opening menu level '%i'", name(), static_cast<int>(m_level)); m_log.info("%s: Opening menu level '%i'", name(), static_cast<int>(m_level));

View File

@ -1,5 +1,7 @@
#include "modules/meta/base.hpp" #include <utility>
#include "components/builder.hpp" #include "components/builder.hpp"
#include "modules/meta/base.hpp"
POLYBAR_NS POLYBAR_NS
@ -7,35 +9,48 @@ namespace modules {
// module_format {{{ // module_format {{{
string module_format::decorate(builder* builder, string output) { string module_format::decorate(builder* builder, string output) {
if (offset != 0) if (offset != 0) {
builder->offset(offset); builder->offset(offset);
if (margin > 0) }
if (margin > 0) {
builder->space(margin); builder->space(margin);
if (!bg.empty()) }
if (!bg.empty()) {
builder->background(bg); builder->background(bg);
if (!fg.empty()) }
if (!fg.empty()) {
builder->color(fg); builder->color(fg);
if (!ul.empty()) }
if (!ul.empty()) {
builder->underline(ul); builder->underline(ul);
if (!ol.empty()) }
if (!ol.empty()) {
builder->overline(ol); builder->overline(ol);
if (padding > 0) }
if (padding > 0) {
builder->space(padding); builder->space(padding);
}
builder->append(output); builder->append(move(output));
if (padding > 0) if (padding > 0) {
builder->space(padding); builder->space(padding);
if (!ol.empty()) }
if (!ol.empty()) {
builder->overline_close(); builder->overline_close();
if (!ul.empty()) }
if (!ul.empty()) {
builder->underline_close(); builder->underline_close();
if (!fg.empty()) }
if (!fg.empty()) {
builder->color_close(); builder->color_close();
if (!bg.empty()) }
if (!bg.empty()) {
builder->background_close(); builder->background_close();
if (margin > 0) }
if (margin > 0) {
builder->space(margin); builder->space(margin);
}
return builder->flush(); return builder->flush();
} }
@ -46,7 +61,7 @@ namespace modules {
void module_formatter::add(string name, string fallback, vector<string>&& tags, vector<string>&& whitelist) { void module_formatter::add(string name, string fallback, vector<string>&& tags, vector<string>&& whitelist) {
auto format = make_unique<module_format>(); auto format = make_unique<module_format>();
format->value = m_conf.get<string>(m_modname, name, fallback); format->value = m_conf.get<string>(m_modname, name, move(fallback));
format->fg = m_conf.get<string>(m_modname, name + "-foreground", ""); format->fg = m_conf.get<string>(m_modname, name + "-foreground", "");
format->bg = m_conf.get<string>(m_modname, name + "-background", ""); format->bg = m_conf.get<string>(m_modname, name + "-background", "");
format->ul = m_conf.get<string>(m_modname, name + "-underline", ""); format->ul = m_conf.get<string>(m_modname, name + "-underline", "");
@ -58,36 +73,43 @@ namespace modules {
format->tags.swap(tags); format->tags.swap(tags);
for (auto&& tag : string_util::split(format->value, ' ')) { for (auto&& tag : string_util::split(format->value, ' ')) {
if (tag[0] != '<' || tag[tag.length() - 1] != '>') if (tag[0] != '<' || tag[tag.length() - 1] != '>') {
continue; continue;
if (find(format->tags.begin(), format->tags.end(), tag) != format->tags.end()) }
if (find(format->tags.begin(), format->tags.end(), tag) != format->tags.end()) {
continue; continue;
if (find(whitelist.begin(), whitelist.end(), tag) != whitelist.end()) }
if (find(whitelist.begin(), whitelist.end(), tag) != whitelist.end()) {
continue; continue;
}
throw undefined_format_tag("[" + m_modname + "] Undefined \"" + name + "\" tag: " + tag); throw undefined_format_tag("[" + m_modname + "] Undefined \"" + name + "\" tag: " + tag);
} }
m_formats.insert(make_pair(name, move(format))); m_formats.insert(make_pair(name, move(format)));
} }
bool module_formatter::has(string tag, string format_name) { bool module_formatter::has(const string& tag, const string& format_name) {
auto format = m_formats.find(format_name); auto format = m_formats.find(format_name);
if (format == m_formats.end()) if (format == m_formats.end()) {
throw undefined_format(format_name.c_str()); throw undefined_format(format_name);
}
return format->second->value.find(tag) != string::npos; return format->second->value.find(tag) != string::npos;
} }
bool module_formatter::has(string tag) { bool module_formatter::has(const string& tag) {
for (auto&& format : m_formats) for (auto&& format : m_formats) {
if (format.second->value.find(tag) != string::npos) if (format.second->value.find(tag) != string::npos) {
return true; return true;
}
}
return false; return false;
} }
shared_ptr<module_format> module_formatter::get(string format_name) { shared_ptr<module_format> module_formatter::get(const string& format_name) {
auto format = m_formats.find(format_name); auto format = m_formats.find(format_name);
if (format == m_formats.end()) if (format == m_formats.end()) {
throw undefined_format("Format \"" + format_name + "\" has not been added"); throw undefined_format("Format \"" + format_name + "\" has not been added");
}
return format->second; return format->second;
} }

View File

@ -30,42 +30,56 @@ namespace modules {
m_formatter->add(FORMAT_OFFLINE, "", {TAG_LABEL_OFFLINE}); m_formatter->add(FORMAT_OFFLINE, "", {TAG_LABEL_OFFLINE});
m_icons = iconset_t{new iconset()}; m_icons = make_shared<iconset>();
if (m_formatter->has(TAG_ICON_PLAY) || m_formatter->has(TAG_TOGGLE) || m_formatter->has(TAG_TOGGLE_STOP)) if (m_formatter->has(TAG_ICON_PLAY) || m_formatter->has(TAG_TOGGLE) || m_formatter->has(TAG_TOGGLE_STOP)) {
m_icons->add("play", load_icon(m_conf, name(), TAG_ICON_PLAY)); m_icons->add("play", load_icon(m_conf, name(), TAG_ICON_PLAY));
if (m_formatter->has(TAG_ICON_PAUSE) || m_formatter->has(TAG_TOGGLE)) }
if (m_formatter->has(TAG_ICON_PAUSE) || m_formatter->has(TAG_TOGGLE)) {
m_icons->add("pause", load_icon(m_conf, name(), TAG_ICON_PAUSE)); m_icons->add("pause", load_icon(m_conf, name(), TAG_ICON_PAUSE));
if (m_formatter->has(TAG_ICON_STOP) || m_formatter->has(TAG_TOGGLE_STOP)) }
if (m_formatter->has(TAG_ICON_STOP) || m_formatter->has(TAG_TOGGLE_STOP)) {
m_icons->add("stop", load_icon(m_conf, name(), TAG_ICON_STOP)); m_icons->add("stop", load_icon(m_conf, name(), TAG_ICON_STOP));
if (m_formatter->has(TAG_ICON_PREV)) }
if (m_formatter->has(TAG_ICON_PREV)) {
m_icons->add("prev", load_icon(m_conf, name(), TAG_ICON_PREV)); m_icons->add("prev", load_icon(m_conf, name(), TAG_ICON_PREV));
if (m_formatter->has(TAG_ICON_NEXT)) }
if (m_formatter->has(TAG_ICON_NEXT)) {
m_icons->add("next", load_icon(m_conf, name(), TAG_ICON_NEXT)); m_icons->add("next", load_icon(m_conf, name(), TAG_ICON_NEXT));
if (m_formatter->has(TAG_ICON_SEEKB)) }
if (m_formatter->has(TAG_ICON_SEEKB)) {
m_icons->add("seekb", load_icon(m_conf, name(), TAG_ICON_SEEKB)); m_icons->add("seekb", load_icon(m_conf, name(), TAG_ICON_SEEKB));
if (m_formatter->has(TAG_ICON_SEEKF)) }
if (m_formatter->has(TAG_ICON_SEEKF)) {
m_icons->add("seekf", load_icon(m_conf, name(), TAG_ICON_SEEKF)); m_icons->add("seekf", load_icon(m_conf, name(), TAG_ICON_SEEKF));
if (m_formatter->has(TAG_ICON_RANDOM)) }
if (m_formatter->has(TAG_ICON_RANDOM)) {
m_icons->add("random", load_icon(m_conf, name(), TAG_ICON_RANDOM)); m_icons->add("random", load_icon(m_conf, name(), TAG_ICON_RANDOM));
if (m_formatter->has(TAG_ICON_REPEAT)) }
if (m_formatter->has(TAG_ICON_REPEAT)) {
m_icons->add("repeat", load_icon(m_conf, name(), TAG_ICON_REPEAT)); m_icons->add("repeat", load_icon(m_conf, name(), TAG_ICON_REPEAT));
if (m_formatter->has(TAG_ICON_REPEAT_ONE)) }
if (m_formatter->has(TAG_ICON_REPEAT_ONE)) {
m_icons->add("repeat_one", load_icon(m_conf, name(), TAG_ICON_REPEAT_ONE)); m_icons->add("repeat_one", load_icon(m_conf, name(), TAG_ICON_REPEAT_ONE));
}
if (m_formatter->has(TAG_LABEL_SONG)) if (m_formatter->has(TAG_LABEL_SONG)) {
m_label_song = load_optional_label(m_conf, name(), TAG_LABEL_SONG, "%artist% - %title%"); m_label_song = load_optional_label(m_conf, name(), TAG_LABEL_SONG, "%artist% - %title%");
if (m_formatter->has(TAG_LABEL_TIME)) }
if (m_formatter->has(TAG_LABEL_TIME)) {
m_label_time = load_optional_label(m_conf, name(), TAG_LABEL_TIME, "%elapsed% / %total%"); m_label_time = load_optional_label(m_conf, name(), TAG_LABEL_TIME, "%elapsed% / %total%");
}
if (m_formatter->has(TAG_ICON_RANDOM) || m_formatter->has(TAG_ICON_REPEAT) || if (m_formatter->has(TAG_ICON_RANDOM) || m_formatter->has(TAG_ICON_REPEAT) ||
m_formatter->has(TAG_ICON_REPEAT_ONE)) { m_formatter->has(TAG_ICON_REPEAT_ONE)) {
m_toggle_on_color = m_conf.get<string>(name(), "toggle-on-foreground", ""); m_toggle_on_color = m_conf.get<string>(name(), "toggle-on-foreground", "");
m_toggle_off_color = m_conf.get<string>(name(), "toggle-off-foreground", ""); m_toggle_off_color = m_conf.get<string>(name(), "toggle-off-foreground", "");
} }
if (m_formatter->has(TAG_LABEL_OFFLINE, FORMAT_OFFLINE)) if (m_formatter->has(TAG_LABEL_OFFLINE, FORMAT_OFFLINE)) {
m_label_offline = load_label(m_conf, name(), TAG_LABEL_OFFLINE); m_label_offline = load_label(m_conf, name(), TAG_LABEL_OFFLINE);
if (m_formatter->has(TAG_BAR_PROGRESS)) }
if (m_formatter->has(TAG_BAR_PROGRESS)) {
m_bar_progress = load_progressbar(m_bar, m_conf, name(), TAG_BAR_PROGRESS); m_bar_progress = load_progressbar(m_bar, m_conf, name(), TAG_BAR_PROGRESS);
}
// }}} // }}}
@ -90,9 +104,9 @@ namespace modules {
} }
void mpd_module::idle() { void mpd_module::idle() {
if (connected()) if (connected()) {
sleep(80ms); sleep(80ms);
else { } else {
sleep(2s); sleep(2s);
} }
} }
@ -107,21 +121,25 @@ namespace modules {
} }
try { try {
if (!m_mpd) if (!m_mpd) {
m_mpd = make_unique<mpdconnection>(m_log, m_host, m_port, m_pass); m_mpd = make_unique<mpdconnection>(m_log, m_host, m_port, m_pass);
if (!connected()) }
if (!connected()) {
m_mpd->connect(); m_mpd->connect();
}
} catch (const mpd_exception& err) { } catch (const mpd_exception& err) {
m_log.trace("%s: %s", name(), err.what()); m_log.trace("%s: %s", name(), err.what());
m_mpd.reset(); m_mpd.reset();
return def; return def;
} }
if (!connected()) if (!connected()) {
return def; return def;
}
if (!m_status) if (!m_status) {
m_status = m_mpd->get_status_safe(); m_status = m_mpd->get_status_safe();
}
try { try {
m_mpd->idle(); m_mpd->idle();
@ -156,12 +174,13 @@ namespace modules {
} }
bool mpd_module::update() { bool mpd_module::update() {
if (connected()) if (connected()) {
m_statebroadcasted = mpd::connection_state::CONNECTED; m_statebroadcasted = mpd::connection_state::CONNECTED;
else if (!connected() && m_statebroadcasted != mpd::connection_state::DISCONNECTED) } else if (!connected() && m_statebroadcasted != mpd::connection_state::DISCONNECTED) {
m_statebroadcasted = mpd::connection_state::DISCONNECTED; m_statebroadcasted = mpd::connection_state::DISCONNECTED;
else if (!connected()) } else if (!connected()) {
return false; return false;
}
if (!m_status) { if (!m_status) {
if (connected() && (m_status = m_mpd->get_status_safe())) { if (connected() && (m_status = m_mpd->get_status_safe())) {
@ -208,13 +227,16 @@ namespace modules {
m_label_time->replace_token("%total%", total_str); m_label_time->replace_token("%total%", total_str);
} }
if (m_icons->has("random")) if (m_icons->has("random")) {
m_icons->get("random")->m_foreground = m_status && m_status->random() ? m_toggle_on_color : m_toggle_off_color; m_icons->get("random")->m_foreground = m_status && m_status->random() ? m_toggle_on_color : m_toggle_off_color;
if (m_icons->has("repeat")) }
if (m_icons->has("repeat")) {
m_icons->get("repeat")->m_foreground = m_status && m_status->repeat() ? m_toggle_on_color : m_toggle_off_color; m_icons->get("repeat")->m_foreground = m_status && m_status->repeat() ? m_toggle_on_color : m_toggle_off_color;
if (m_icons->has("repeat_one")) }
if (m_icons->has("repeat_one")) {
m_icons->get("repeat_one")->m_foreground = m_icons->get("repeat_one")->m_foreground =
m_status && 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; return true;
} }
@ -232,7 +254,7 @@ namespace modules {
} }
} }
bool mpd_module::build(builder* builder, string tag) const { bool mpd_module::build(builder* builder, const string& tag) const {
bool is_playing = false; bool is_playing = false;
bool is_paused = false; bool is_paused = false;
bool is_stopped = true; bool is_stopped = true;
@ -241,13 +263,16 @@ namespace modules {
if (m_status) { if (m_status) {
elapsed_percentage = m_status->get_elapsed_percentage(); elapsed_percentage = m_status->get_elapsed_percentage();
if (m_status->match_state(mpdstate::PLAYING)) if (m_status->match_state(mpdstate::PLAYING)) {
is_playing = true; is_playing = true;
if (m_status->match_state(mpdstate::PAUSED)) }
if (m_status->match_state(mpdstate::PAUSED)) {
is_paused = true; is_paused = true;
if (!(m_status->match_state(mpdstate::STOPPED))) }
if (!(m_status->match_state(mpdstate::STOPPED))) {
is_stopped = false; is_stopped = false;
} }
}
auto icon_cmd = [&builder](string cmd, icon_t icon) { auto icon_cmd = [&builder](string cmd, icon_t icon) {
builder->cmd(mousebtn::LEFT, cmd); builder->cmd(mousebtn::LEFT, cmd);
@ -255,42 +280,44 @@ namespace modules {
builder->cmd_close(); builder->cmd_close();
}; };
if (tag == TAG_LABEL_SONG && !is_stopped) if (tag == TAG_LABEL_SONG && !is_stopped) {
builder->node(m_label_song); builder->node(m_label_song);
else if (tag == TAG_LABEL_TIME && !is_stopped) } else if (tag == TAG_LABEL_TIME && !is_stopped) {
builder->node(m_label_time); builder->node(m_label_time);
else if (tag == TAG_BAR_PROGRESS && !is_stopped) } else if (tag == TAG_BAR_PROGRESS && !is_stopped) {
builder->node(m_bar_progress->output(elapsed_percentage)); builder->node(m_bar_progress->output(elapsed_percentage));
else if (tag == TAG_LABEL_OFFLINE) } else if (tag == TAG_LABEL_OFFLINE) {
builder->node(m_label_offline); builder->node(m_label_offline);
else if (tag == TAG_ICON_RANDOM) } else if (tag == TAG_ICON_RANDOM) {
icon_cmd(EVENT_RANDOM, m_icons->get("random")); icon_cmd(EVENT_RANDOM, m_icons->get("random"));
else if (tag == TAG_ICON_REPEAT) } else if (tag == TAG_ICON_REPEAT) {
icon_cmd(EVENT_REPEAT, m_icons->get("repeat")); icon_cmd(EVENT_REPEAT, m_icons->get("repeat"));
else if (tag == TAG_ICON_REPEAT_ONE) } else if (tag == TAG_ICON_REPEAT_ONE) {
icon_cmd(EVENT_REPEAT_ONE, m_icons->get("repeat_one")); icon_cmd(EVENT_REPEAT_ONE, m_icons->get("repeat_one"));
else if (tag == TAG_ICON_PREV) } else if (tag == TAG_ICON_PREV) {
icon_cmd(EVENT_PREV, m_icons->get("prev")); icon_cmd(EVENT_PREV, m_icons->get("prev"));
else if ((tag == TAG_ICON_STOP || tag == TAG_TOGGLE_STOP) && (is_playing || is_paused)) } else if ((tag == TAG_ICON_STOP || tag == TAG_TOGGLE_STOP) && (is_playing || is_paused)) {
icon_cmd(EVENT_STOP, m_icons->get("stop")); icon_cmd(EVENT_STOP, m_icons->get("stop"));
else if ((tag == TAG_ICON_PAUSE || tag == TAG_TOGGLE) && is_playing) } else if ((tag == TAG_ICON_PAUSE || tag == TAG_TOGGLE) && is_playing) {
icon_cmd(EVENT_PAUSE, m_icons->get("pause")); icon_cmd(EVENT_PAUSE, m_icons->get("pause"));
else if ((tag == TAG_ICON_PLAY || tag == TAG_TOGGLE || tag == TAG_TOGGLE_STOP) && !is_playing) } else if ((tag == TAG_ICON_PLAY || tag == TAG_TOGGLE || tag == TAG_TOGGLE_STOP) && !is_playing) {
icon_cmd(EVENT_PLAY, m_icons->get("play")); icon_cmd(EVENT_PLAY, m_icons->get("play"));
else if (tag == TAG_ICON_NEXT) } else if (tag == TAG_ICON_NEXT) {
icon_cmd(EVENT_NEXT, m_icons->get("next")); icon_cmd(EVENT_NEXT, m_icons->get("next"));
else if (tag == TAG_ICON_SEEKB) } else if (tag == TAG_ICON_SEEKB) {
icon_cmd(string(EVENT_SEEK).append("-5"), m_icons->get("seekb")); icon_cmd(string(EVENT_SEEK).append("-5"), m_icons->get("seekb"));
else if (tag == TAG_ICON_SEEKF) } else if (tag == TAG_ICON_SEEKF) {
icon_cmd(string(EVENT_SEEK).append("+5"), m_icons->get("seekf")); icon_cmd(string(EVENT_SEEK).append("+5"), m_icons->get("seekf"));
else } else {
return false; return false;
}
return true; return true;
} }
bool mpd_module::handle_event(string cmd) { bool mpd_module::handle_event(string cmd) {
if (cmd.compare(0, 3, "mpd") != 0) if (cmd.compare(0, 3, "mpd") != 0) {
return false; return false;
}
try { try {
auto mpd = make_unique<mpdconnection>(m_log, m_host, m_port, m_pass); auto mpd = make_unique<mpdconnection>(m_log, m_host, m_port, m_pass);
@ -298,27 +325,28 @@ namespace modules {
auto status = mpd->get_status(); auto status = mpd->get_status();
if (cmd == EVENT_PLAY) if (cmd == EVENT_PLAY) {
mpd->play(); mpd->play();
else if (cmd == EVENT_PAUSE) } else if (cmd == EVENT_PAUSE) {
mpd->pause(!(status->match_state(mpdstate::PAUSED))); mpd->pause(!(status->match_state(mpdstate::PAUSED)));
else if (cmd == EVENT_STOP) } else if (cmd == EVENT_STOP) {
mpd->stop(); mpd->stop();
else if (cmd == EVENT_PREV) } else if (cmd == EVENT_PREV) {
mpd->prev(); mpd->prev();
else if (cmd == EVENT_NEXT) } else if (cmd == EVENT_NEXT) {
mpd->next(); mpd->next();
else if (cmd == EVENT_REPEAT_ONE) } else if (cmd == EVENT_REPEAT_ONE) {
mpd->set_single(!status->single()); mpd->set_single(!status->single());
else if (cmd == EVENT_REPEAT) } else if (cmd == EVENT_REPEAT) {
mpd->set_repeat(!status->repeat()); mpd->set_repeat(!status->repeat());
else if (cmd == EVENT_RANDOM) } else if (cmd == EVENT_RANDOM) {
mpd->set_random(!status->random()); mpd->set_random(!status->random());
else if (cmd.compare(0, strlen(EVENT_SEEK), EVENT_SEEK) == 0) { } else if (cmd.compare(0, strlen(EVENT_SEEK), EVENT_SEEK) == 0) {
auto s = cmd.substr(strlen(EVENT_SEEK)); auto s = cmd.substr(strlen(EVENT_SEEK));
int percentage = 0; int percentage = 0;
if (s.empty()) if (s.empty()) {
return false; return false;
}
if (s[0] == '+') { if (s[0] == '+') {
percentage = status->get_elapsed_percentage() + std::atoi(s.substr(1).c_str()); percentage = status->get_elapsed_percentage() + std::atoi(s.substr(1).c_str());
} else if (s[0] == '-') { } else if (s[0] == '-') {
@ -327,8 +355,9 @@ namespace modules {
percentage = std::atoi(s.c_str()); percentage = std::atoi(s.c_str());
} }
mpd->seek(status->get_songid(), status->get_seek_position(percentage)); mpd->seek(status->get_songid(), status->get_seek_position(percentage));
} else } else {
return false; return false;
}
} catch (const mpd_exception& err) { } catch (const mpd_exception& err) {
m_log.err("%s: %s", name(), err.what()); m_log.err("%s: %s", name(), err.what());
m_mpd.reset(); m_mpd.reset();

View File

@ -29,10 +29,12 @@ namespace modules {
m_formatter->add(FORMAT_DISCONNECTED, TAG_LABEL_DISCONNECTED, {TAG_LABEL_DISCONNECTED}); m_formatter->add(FORMAT_DISCONNECTED, TAG_LABEL_DISCONNECTED, {TAG_LABEL_DISCONNECTED});
// Create elements for format-connected // Create elements for format-connected
if (m_formatter->has(TAG_RAMP_SIGNAL, FORMAT_CONNECTED)) if (m_formatter->has(TAG_RAMP_SIGNAL, FORMAT_CONNECTED)) {
m_ramp_signal = load_ramp(m_conf, name(), TAG_RAMP_SIGNAL); m_ramp_signal = load_ramp(m_conf, name(), TAG_RAMP_SIGNAL);
if (m_formatter->has(TAG_RAMP_QUALITY, FORMAT_CONNECTED)) }
if (m_formatter->has(TAG_RAMP_QUALITY, FORMAT_CONNECTED)) {
m_ramp_quality = load_ramp(m_conf, name(), TAG_RAMP_QUALITY); m_ramp_quality = load_ramp(m_conf, name(), TAG_RAMP_QUALITY);
}
if (m_formatter->has(TAG_LABEL_CONNECTED, FORMAT_CONNECTED)) { if (m_formatter->has(TAG_LABEL_CONNECTED, FORMAT_CONNECTED)) {
m_label[connection_state::CONNECTED] = m_label[connection_state::CONNECTED] =
load_optional_label(m_conf, name(), TAG_LABEL_CONNECTED, "%ifname% %local_ip%"); load_optional_label(m_conf, name(), TAG_LABEL_CONNECTED, "%ifname% %local_ip%");
@ -53,20 +55,23 @@ namespace modules {
if (m_formatter->has(TAG_LABEL_PACKETLOSS, FORMAT_PACKETLOSS)) { if (m_formatter->has(TAG_LABEL_PACKETLOSS, FORMAT_PACKETLOSS)) {
m_label[connection_state::PACKETLOSS] = load_optional_label(m_conf, name(), TAG_LABEL_PACKETLOSS, ""); m_label[connection_state::PACKETLOSS] = load_optional_label(m_conf, name(), TAG_LABEL_PACKETLOSS, "");
} }
if (m_formatter->has(TAG_ANIMATION_PACKETLOSS, FORMAT_PACKETLOSS)) if (m_formatter->has(TAG_ANIMATION_PACKETLOSS, FORMAT_PACKETLOSS)) {
m_animation_packetloss = load_animation(m_conf, name(), TAG_ANIMATION_PACKETLOSS); m_animation_packetloss = load_animation(m_conf, name(), TAG_ANIMATION_PACKETLOSS);
} }
}
// Get an intstance of the network interface // Get an intstance of the network interface
if (net::is_wireless_interface(m_interface)) if (net::is_wireless_interface(m_interface)) {
m_wireless = net::wireless_t{new net::wireless_t::element_type(m_interface)}; m_wireless = make_unique<net::wireless_network>(m_interface);
else } else {
m_wired = net::wired_t{new net::wired_t::element_type(m_interface)}; m_wired = make_unique<net::wired_network>(m_interface);
};
// We only need to start the subthread if the packetloss animation is used // We only need to start the subthread if the packetloss animation is used
if (m_animation_packetloss) if (m_animation_packetloss) {
m_threads.emplace_back(thread(&network_module::subthread_routine, this)); m_threads.emplace_back(thread(&network_module::subthread_routine, this));
} }
}
void network_module::teardown() { void network_module::teardown() {
m_wireless.reset(); m_wireless.reset();
@ -121,38 +126,42 @@ namespace modules {
} }
}; };
if (m_label[connection_state::CONNECTED]) if (m_label[connection_state::CONNECTED]) {
replace_tokens(m_label[connection_state::CONNECTED]); replace_tokens(m_label[connection_state::CONNECTED]);
if (m_label[connection_state::PACKETLOSS]) }
if (m_label[connection_state::PACKETLOSS]) {
replace_tokens(m_label[connection_state::PACKETLOSS]); replace_tokens(m_label[connection_state::PACKETLOSS]);
}
return true; return true;
} }
string network_module::get_format() const { string network_module::get_format() const {
if (!m_connected) if (!m_connected) {
return FORMAT_DISCONNECTED; return FORMAT_DISCONNECTED;
else if (m_packetloss && m_ping_nth_update > 0) } else if (m_packetloss && m_ping_nth_update > 0) {
return FORMAT_PACKETLOSS; return FORMAT_PACKETLOSS;
else } else {
return FORMAT_CONNECTED; return FORMAT_CONNECTED;
} }
}
bool network_module::build(builder* builder, string tag) const { bool network_module::build(builder* builder, const string& tag) const {
if (tag == TAG_LABEL_CONNECTED) if (tag == TAG_LABEL_CONNECTED) {
builder->node(m_label.at(connection_state::CONNECTED)); builder->node(m_label.at(connection_state::CONNECTED));
else if (tag == TAG_LABEL_DISCONNECTED) } else if (tag == TAG_LABEL_DISCONNECTED) {
builder->node(m_label.at(connection_state::DISCONNECTED)); builder->node(m_label.at(connection_state::DISCONNECTED));
else if (tag == TAG_LABEL_PACKETLOSS) } else if (tag == TAG_LABEL_PACKETLOSS) {
builder->node(m_label.at(connection_state::PACKETLOSS)); builder->node(m_label.at(connection_state::PACKETLOSS));
else if (tag == TAG_ANIMATION_PACKETLOSS) } else if (tag == TAG_ANIMATION_PACKETLOSS) {
builder->node(m_animation_packetloss->get()); builder->node(m_animation_packetloss->get());
else if (tag == TAG_RAMP_SIGNAL) } else if (tag == TAG_RAMP_SIGNAL) {
builder->node(m_ramp_signal->get_by_percentage(m_signal)); builder->node(m_ramp_signal->get_by_percentage(m_signal));
else if (tag == TAG_RAMP_QUALITY) } else if (tag == TAG_RAMP_QUALITY) {
builder->node(m_ramp_quality->get_by_percentage(m_quality)); builder->node(m_ramp_quality->get_by_percentage(m_quality));
else } else {
return false; return false;
}
return true; return true;
} }
@ -161,8 +170,9 @@ namespace modules {
const auto dur = chrono::duration<double>(framerate); const auto dur = chrono::duration<double>(framerate);
while (running()) { while (running()) {
if (m_connected && m_packetloss) if (m_connected && m_packetloss) {
broadcast(); broadcast();
}
sleep(dur); sleep(dur);
} }

View File

@ -38,16 +38,18 @@ namespace modules {
} }
void script_module::idle() { void script_module::idle() {
if (!m_tail) if (!m_tail) {
sleep(m_interval); sleep(m_interval);
else if (!m_command || !m_command->is_running()) } else if (!m_command || !m_command->is_running()) {
sleep(m_interval); sleep(m_interval);
} }
}
bool script_module::has_event() { bool script_module::has_event() {
// Non tail commands should always run // Non tail commands should always run
if (!m_tail) if (!m_tail) {
return true; return true;
}
try { try {
if (!m_command || !m_command->is_running()) { if (!m_command || !m_command->is_running()) {
@ -62,11 +64,13 @@ namespace modules {
throw module_error("Failed to execute tail command, stopping module..."); throw module_error("Failed to execute tail command, stopping module...");
} }
if (!m_command) if (!m_command) {
return false; return false;
}
if ((m_output = m_command->readline()) == m_prev) if ((m_output = m_command->readline()) == m_prev) {
return false; return false;
}
m_prev = m_output; m_prev = m_output;
@ -75,8 +79,9 @@ namespace modules {
bool script_module::update() { bool script_module::update() {
// Tailing commands always update // Tailing commands always update
if (m_tail) if (m_tail) {
return true; return true;
}
try { try {
if (m_command && m_command->is_running()) { if (m_command && m_command->is_running()) {
@ -95,18 +100,20 @@ namespace modules {
throw module_error("Failed to execute command, stopping module..."); throw module_error("Failed to execute command, stopping module...");
} }
if (m_output == m_prev) if (m_output == m_prev) {
return false; return false;
}
m_prev = m_output; m_prev = m_output;
return true; return true;
} }
string script_module::get_output() { string script_module::get_output() {
if (m_output.empty()) if (m_output.empty()) {
return " "; return " ";
// Truncate output to the defined max length // Truncate output to the defined max length
}
if (m_maxlen > 0 && m_output.length() > m_maxlen) { if (m_maxlen > 0 && m_output.length() > m_maxlen) {
m_output.erase(m_maxlen); m_output.erase(m_maxlen);
m_output += m_ellipsis ? "..." : ""; m_output += m_ellipsis ? "..." : "";
@ -123,7 +130,7 @@ namespace modules {
return m_builder->flush(); return m_builder->flush();
} }
bool script_module::build(builder* builder, string tag) const { bool script_module::build(builder* builder, const string& tag) const {
if (tag == TAG_OUTPUT) { if (tag == TAG_OUTPUT) {
builder->node(m_output); builder->node(m_output);
return true; return true;

View File

@ -21,19 +21,23 @@ namespace modules {
m_path = string_util::replace(PATH_TEMPERATURE_INFO, "%zone%", to_string(m_zone)); m_path = string_util::replace(PATH_TEMPERATURE_INFO, "%zone%", to_string(m_zone));
if (!file_util::exists(m_path)) if (!file_util::exists(m_path)) {
throw module_error("The file '" + m_path + "' does not exist"); throw module_error("The file '" + m_path + "' does not exist");
}
m_formatter->add(DEFAULT_FORMAT, TAG_LABEL, {TAG_LABEL, TAG_RAMP}); m_formatter->add(DEFAULT_FORMAT, TAG_LABEL, {TAG_LABEL, TAG_RAMP});
m_formatter->add(FORMAT_WARN, TAG_LABEL_WARN, {TAG_LABEL_WARN, TAG_RAMP}); m_formatter->add(FORMAT_WARN, TAG_LABEL_WARN, {TAG_LABEL_WARN, TAG_RAMP});
if (m_formatter->has(TAG_LABEL)) if (m_formatter->has(TAG_LABEL)) {
m_label[temp_state::NORMAL] = load_optional_label(m_conf, name(), TAG_LABEL, "%temperature%"); m_label[temp_state::NORMAL] = load_optional_label(m_conf, name(), TAG_LABEL, "%temperature%");
if (m_formatter->has(TAG_LABEL_WARN)) }
if (m_formatter->has(TAG_LABEL_WARN)) {
m_label[temp_state::WARN] = load_optional_label(m_conf, name(), TAG_LABEL_WARN, "%temperature%"); m_label[temp_state::WARN] = load_optional_label(m_conf, name(), TAG_LABEL_WARN, "%temperature%");
if (m_formatter->has(TAG_RAMP)) }
if (m_formatter->has(TAG_RAMP)) {
m_ramp = load_ramp(m_conf, name(), TAG_RAMP); m_ramp = load_ramp(m_conf, name(), TAG_RAMP);
} }
}
bool temperature_module::update() { bool temperature_module::update() {
m_temp = std::atoi(file_util::get_contents(m_path).c_str()) / 1000.0f + 0.5f; m_temp = std::atoi(file_util::get_contents(m_path).c_str()) / 1000.0f + 0.5f;
@ -44,30 +48,34 @@ namespace modules {
label->replace_token("%temperature%", to_string(m_temp) + "°C"); label->replace_token("%temperature%", to_string(m_temp) + "°C");
}; };
if (m_label[temp_state::NORMAL]) if (m_label[temp_state::NORMAL]) {
replace_tokens(m_label[temp_state::NORMAL]); replace_tokens(m_label[temp_state::NORMAL]);
if (m_label[temp_state::WARN]) }
if (m_label[temp_state::WARN]) {
replace_tokens(m_label[temp_state::WARN]); replace_tokens(m_label[temp_state::WARN]);
}
return true; return true;
} }
string temperature_module::get_format() const { string temperature_module::get_format() const {
if (m_temp > m_tempwarn) if (m_temp > m_tempwarn) {
return FORMAT_WARN; return FORMAT_WARN;
else } else {
return DEFAULT_FORMAT; return DEFAULT_FORMAT;
} }
}
bool temperature_module::build(builder* builder, string tag) const { bool temperature_module::build(builder* builder, const string& tag) const {
if (tag == TAG_LABEL) if (tag == TAG_LABEL) {
builder->node(m_label.at(temp_state::NORMAL)); builder->node(m_label.at(temp_state::NORMAL));
else if (tag == TAG_LABEL_WARN) } else if (tag == TAG_LABEL_WARN) {
builder->node(m_label.at(temp_state::WARN)); builder->node(m_label.at(temp_state::WARN));
else if (tag == TAG_RAMP) } else if (tag == TAG_RAMP) {
builder->node(m_ramp->get_by_percentage(m_perc)); builder->node(m_ramp->get_by_percentage(m_perc));
else } else {
return false; return false;
}
return true; return true;
} }
} }

View File

@ -12,8 +12,9 @@ namespace modules {
void text_module::setup() { void text_module::setup() {
m_formatter->add("content", "", {}); m_formatter->add("content", "", {});
if (m_formatter->get("content")->value.empty()) if (m_formatter->get("content")->value.empty()) {
throw module_error(name() + ".content is empty or undefined"); throw module_error(name() + ".content is empty or undefined");
}
m_formatter->get("content")->value = m_formatter->get("content")->value =
string_util::replace_all(m_formatter->get("content")->value, " ", BUILDER_SPACE_TOKEN); string_util::replace_all(m_formatter->get("content")->value, " ", BUILDER_SPACE_TOKEN);
@ -30,16 +31,21 @@ namespace modules {
auto scroll_up = m_conf.get<string>(name(), "scroll-up", ""); auto scroll_up = m_conf.get<string>(name(), "scroll-up", "");
auto scroll_down = m_conf.get<string>(name(), "scroll-down", ""); auto scroll_down = m_conf.get<string>(name(), "scroll-down", "");
if (!click_left.empty()) if (!click_left.empty()) {
m_builder->cmd(mousebtn::LEFT, click_left); m_builder->cmd(mousebtn::LEFT, click_left);
if (!click_middle.empty()) }
if (!click_middle.empty()) {
m_builder->cmd(mousebtn::MIDDLE, click_middle); m_builder->cmd(mousebtn::MIDDLE, click_middle);
if (!click_right.empty()) }
if (!click_right.empty()) {
m_builder->cmd(mousebtn::RIGHT, click_right); m_builder->cmd(mousebtn::RIGHT, click_right);
if (!scroll_up.empty()) }
if (!scroll_up.empty()) {
m_builder->cmd(mousebtn::SCROLL_UP, scroll_up); m_builder->cmd(mousebtn::SCROLL_UP, scroll_up);
if (!scroll_down.empty()) }
if (!scroll_down.empty()) {
m_builder->cmd(mousebtn::SCROLL_DOWN, scroll_down); m_builder->cmd(mousebtn::SCROLL_DOWN, scroll_down);
}
m_builder->append(module::get_output()); m_builder->append(module::get_output());

View File

@ -25,26 +25,34 @@ namespace modules {
GET_CONFIG_VALUE(name(), headphone_mixer_name, "headphone-mixer"); GET_CONFIG_VALUE(name(), headphone_mixer_name, "headphone-mixer");
GET_CONFIG_VALUE(name(), m_mapped, "mapped"); GET_CONFIG_VALUE(name(), m_mapped, "mapped");
if (!headphone_mixer_name.empty()) if (!headphone_mixer_name.empty()) {
REQ_CONFIG_VALUE(name(), m_headphoneid, "headphone-id"); REQ_CONFIG_VALUE(name(), m_headphoneid, "headphone-id");
}
if (string_util::compare(speaker_mixer_name, "master")) if (string_util::compare(speaker_mixer_name, "master")) {
throw module_error("Master mixer is already defined"); throw module_error("Master mixer is already defined");
if (string_util::compare(headphone_mixer_name, "master")) }
if (string_util::compare(headphone_mixer_name, "master")) {
throw module_error("Master mixer is already defined"); throw module_error("Master mixer is already defined");
}
// Setup mixers // Setup mixers
try { try {
if (!master_mixer_name.empty()) if (!master_mixer_name.empty()) {
m_mixers[mixer::MASTER].reset(new mixer_t::element_type{master_mixer_name}); m_mixer[mixer::MASTER].reset(new mixer_t::element_type{master_mixer_name});
if (!speaker_mixer_name.empty()) }
m_mixers[mixer::SPEAKER].reset(new mixer_t::element_type{speaker_mixer_name}); if (!speaker_mixer_name.empty()) {
if (!headphone_mixer_name.empty()) m_mixer[mixer::SPEAKER].reset(new mixer_t::element_type{speaker_mixer_name});
m_mixers[mixer::HEADPHONE].reset(new mixer_t::element_type{headphone_mixer_name}); }
if (m_mixers[mixer::HEADPHONE]) if (!headphone_mixer_name.empty()) {
m_controls[control::HEADPHONE].reset(new control_t::element_type{m_headphoneid}); m_mixer[mixer::HEADPHONE].reset(new mixer_t::element_type{headphone_mixer_name});
if (m_mixers.empty()) }
if (m_mixer[mixer::HEADPHONE]) {
m_ctrl[control::HEADPHONE].reset(new control_t::element_type{m_headphoneid});
}
if (m_mixer.empty()) {
throw module_error("No configured mixers"); throw module_error("No configured mixers");
}
} catch (const alsa_mixer_error& err) { } catch (const alsa_mixer_error& err) {
throw module_error(err.what()); throw module_error(err.what());
} catch (const alsa_ctl_interface_error& err) { } catch (const alsa_ctl_interface_error& err) {
@ -55,12 +63,15 @@ namespace modules {
m_formatter->add(FORMAT_VOLUME, TAG_LABEL_VOLUME, {TAG_RAMP_VOLUME, TAG_LABEL_VOLUME, TAG_BAR_VOLUME}); m_formatter->add(FORMAT_VOLUME, TAG_LABEL_VOLUME, {TAG_RAMP_VOLUME, TAG_LABEL_VOLUME, TAG_BAR_VOLUME});
m_formatter->add(FORMAT_MUTED, TAG_LABEL_MUTED, {TAG_RAMP_VOLUME, TAG_LABEL_MUTED, TAG_BAR_VOLUME}); m_formatter->add(FORMAT_MUTED, TAG_LABEL_MUTED, {TAG_RAMP_VOLUME, TAG_LABEL_MUTED, TAG_BAR_VOLUME});
if (m_formatter->has(TAG_BAR_VOLUME)) if (m_formatter->has(TAG_BAR_VOLUME)) {
m_bar_volume = load_progressbar(m_bar, m_conf, name(), TAG_BAR_VOLUME); m_bar_volume = load_progressbar(m_bar, m_conf, name(), TAG_BAR_VOLUME);
if (m_formatter->has(TAG_LABEL_VOLUME, FORMAT_VOLUME)) }
if (m_formatter->has(TAG_LABEL_VOLUME, FORMAT_VOLUME)) {
m_label_volume = load_optional_label(m_conf, name(), TAG_LABEL_VOLUME, "%percentage%"); m_label_volume = load_optional_label(m_conf, name(), TAG_LABEL_VOLUME, "%percentage%");
if (m_formatter->has(TAG_LABEL_MUTED, FORMAT_MUTED)) }
if (m_formatter->has(TAG_LABEL_MUTED, FORMAT_MUTED)) {
m_label_muted = load_optional_label(m_conf, name(), TAG_LABEL_MUTED, "%percentage%"); m_label_muted = load_optional_label(m_conf, name(), TAG_LABEL_MUTED, "%percentage%");
}
if (m_formatter->has(TAG_RAMP_VOLUME)) { if (m_formatter->has(TAG_RAMP_VOLUME)) {
m_ramp_volume = load_ramp(m_conf, name(), TAG_RAMP_VOLUME); m_ramp_volume = load_ramp(m_conf, name(), TAG_RAMP_VOLUME);
m_ramp_headphones = load_ramp(m_conf, name(), TAG_RAMP_HEADPHONES, false); m_ramp_headphones = load_ramp(m_conf, name(), TAG_RAMP_HEADPHONES, false);
@ -68,20 +79,24 @@ namespace modules {
} }
void volume_module::teardown() { void volume_module::teardown() {
m_mixers.clear(); m_mixer.clear();
} }
bool volume_module::has_event() { bool volume_module::has_event() {
// Poll for mixer and control events // Poll for mixer and control events
try { try {
if (m_mixers[mixer::MASTER] && m_mixers[mixer::MASTER]->wait(25)) if (m_mixer[mixer::MASTER] && m_mixer[mixer::MASTER]->wait(25)) {
return true; return true;
if (m_mixers[mixer::SPEAKER] && m_mixers[mixer::SPEAKER]->wait(25)) }
if (m_mixer[mixer::SPEAKER] && m_mixer[mixer::SPEAKER]->wait(25)) {
return true; return true;
if (m_mixers[mixer::HEADPHONE] && m_mixers[mixer::HEADPHONE]->wait(25)) }
if (m_mixer[mixer::HEADPHONE] && m_mixer[mixer::HEADPHONE]->wait(25)) {
return true; return true;
if (m_controls[control::HEADPHONE] && m_controls[control::HEADPHONE]->wait(25)) }
if (m_ctrl[control::HEADPHONE] && m_ctrl[control::HEADPHONE]->wait(25)) {
return true; return true;
}
} catch (const alsa_exception& e) { } catch (const alsa_exception& e) {
m_log.err("%s: %s", name(), e.what()); m_log.err("%s: %s", name(), e.what());
} }
@ -91,35 +106,53 @@ namespace modules {
bool volume_module::update() { bool volume_module::update() {
// Consume pending events // Consume pending events
if (m_mixers[mixer::MASTER]) if (m_mixer[mixer::MASTER]) {
m_mixers[mixer::MASTER]->process_events(); m_mixer[mixer::MASTER]->process_events();
if (m_mixers[mixer::SPEAKER]) }
m_mixers[mixer::SPEAKER]->process_events(); if (m_mixer[mixer::SPEAKER]) {
if (m_mixers[mixer::HEADPHONE]) m_mixer[mixer::SPEAKER]->process_events();
m_mixers[mixer::HEADPHONE]->process_events(); }
if (m_controls[control::HEADPHONE]) if (m_mixer[mixer::HEADPHONE]) {
m_controls[control::HEADPHONE]->process_events(); m_mixer[mixer::HEADPHONE]->process_events();
}
if (m_ctrl[control::HEADPHONE]) {
m_ctrl[control::HEADPHONE]->process_events();
}
// Get volume, mute and headphone state // Get volume, mute and headphone state
m_volume = 100; m_volume = 100;
m_muted = false; m_muted = false;
m_headphones = false; m_headphones = false;
if (m_mixers[mixer::MASTER]) { try {
m_volume = m_volume * (m_mapped ? m_mixers[mixer::MASTER]->get_normalized_volume() / 100.0f if (m_mixer[mixer::MASTER]) {
: m_mixers[mixer::MASTER]->get_volume() / 100.0f); m_volume = m_volume * (m_mapped ? m_mixer[mixer::MASTER]->get_normalized_volume() / 100.0f
m_muted = m_muted || m_mixers[mixer::MASTER]->is_muted(); : m_mixer[mixer::MASTER]->get_volume() / 100.0f);
m_muted = m_muted || m_mixer[mixer::MASTER]->is_muted();
}
} catch (const alsa_exception& err) {
m_log.err("%s: Failed to query master mixer (%s)", name(), err.what());
} }
if (m_controls[control::HEADPHONE] && m_controls[control::HEADPHONE]->test_device_plugged()) { try {
if (m_ctrl[control::HEADPHONE] && m_ctrl[control::HEADPHONE]->test_device_plugged()) {
m_headphones = true; m_headphones = true;
m_volume = m_volume * (m_mapped ? m_mixers[mixer::HEADPHONE]->get_normalized_volume() / 100.0f m_volume = m_volume * (m_mapped ? m_mixer[mixer::HEADPHONE]->get_normalized_volume() / 100.0f
: m_mixers[mixer::HEADPHONE]->get_volume() / 100.0f); : m_mixer[mixer::HEADPHONE]->get_volume() / 100.0f);
m_muted = m_muted || m_mixers[mixer::HEADPHONE]->is_muted(); m_muted = m_muted || m_mixer[mixer::HEADPHONE]->is_muted();
} else if (m_mixers[mixer::SPEAKER]) { }
m_volume = m_volume * (m_mapped ? m_mixers[mixer::SPEAKER]->get_normalized_volume() / 100.0f } catch (const alsa_exception& err) {
: m_mixers[mixer::SPEAKER]->get_volume() / 100.0f); m_log.err("%s: Failed to query headphone mixer (%s)", name(), err.what());
m_muted = m_muted || m_mixers[mixer::SPEAKER]->is_muted(); }
try {
if (!m_headphones && m_mixer[mixer::SPEAKER]) {
m_volume = m_volume * (m_mapped ? m_mixer[mixer::SPEAKER]->get_normalized_volume() / 100.0f
: m_mixer[mixer::SPEAKER]->get_volume() / 100.0f);
m_muted = m_muted || m_mixer[mixer::SPEAKER]->is_muted();
}
} catch (const alsa_exception& err) {
m_log.err("%s: Failed to query speaker mixer (%s)", name(), err.what());
} }
// Replace label tokens // Replace label tokens
@ -143,48 +176,58 @@ namespace modules {
string volume_module::get_output() { string volume_module::get_output() {
m_builder->cmd(mousebtn::LEFT, EVENT_TOGGLE_MUTE); m_builder->cmd(mousebtn::LEFT, EVENT_TOGGLE_MUTE);
if (!m_muted && m_volume < 100) if (!m_muted && m_volume < 100) {
m_builder->cmd(mousebtn::SCROLL_UP, EVENT_VOLUME_UP); m_builder->cmd(mousebtn::SCROLL_UP, EVENT_VOLUME_UP);
if (!m_muted && m_volume > 0) }
if (!m_muted && m_volume > 0) {
m_builder->cmd(mousebtn::SCROLL_DOWN, EVENT_VOLUME_DOWN); m_builder->cmd(mousebtn::SCROLL_DOWN, EVENT_VOLUME_DOWN);
}
m_builder->append(module::get_output()); m_builder->append(module::get_output());
return m_builder->flush(); return m_builder->flush();
} }
bool volume_module::build(builder* builder, string tag) const { bool volume_module::build(builder* builder, const string& tag) const {
if (tag == TAG_BAR_VOLUME) if (tag == TAG_BAR_VOLUME) {
builder->node(m_bar_volume->output(m_volume)); builder->node(m_bar_volume->output(m_volume));
else if (tag == TAG_RAMP_VOLUME && (!m_headphones || !*m_ramp_headphones)) } else if (tag == TAG_RAMP_VOLUME && (!m_headphones || !*m_ramp_headphones)) {
builder->node(m_ramp_volume->get_by_percentage(m_volume)); builder->node(m_ramp_volume->get_by_percentage(m_volume));
else if (tag == TAG_RAMP_VOLUME && m_headphones && *m_ramp_headphones) } else if (tag == TAG_RAMP_VOLUME && m_headphones && *m_ramp_headphones) {
builder->node(m_ramp_headphones->get_by_percentage(m_volume)); builder->node(m_ramp_headphones->get_by_percentage(m_volume));
else if (tag == TAG_LABEL_VOLUME) } else if (tag == TAG_LABEL_VOLUME) {
builder->node(m_label_volume); builder->node(m_label_volume);
else if (tag == TAG_LABEL_MUTED) } else if (tag == TAG_LABEL_MUTED) {
builder->node(m_label_muted); builder->node(m_label_muted);
else } else {
return false; return false;
}
return true; return true;
} }
bool volume_module::handle_event(string cmd) { bool volume_module::handle_event(string cmd) {
if (cmd.compare(0, 3, EVENT_PREFIX) != 0) if (cmd.compare(0, 3, EVENT_PREFIX) != 0) {
return false; return false;
if (!m_mixers[mixer::MASTER]) }
if (!m_mixer[mixer::MASTER]) {
return false; return false;
}
vector<mixer_t> mixers;
if (m_mixers[mixer::MASTER])
mixers.emplace_back(new mixer_t::element_type(m_mixers[mixer::MASTER]->get_name()));
if (m_mixers[mixer::HEADPHONE] && m_headphones)
mixers.emplace_back(new mixer_t::element_type(m_mixers[mixer::HEADPHONE]->get_name()));
if (m_mixers[mixer::SPEAKER] && !m_headphones)
mixers.emplace_back(new mixer_t::element_type(m_mixers[mixer::SPEAKER]->get_name()));
try { try {
vector<mixer_t> mixers;
bool headphones{m_headphones};
if (m_mixer[mixer::MASTER] && !m_mixer[mixer::MASTER]->get_name().empty()) {
mixers.emplace_back(new mixer_t::element_type(m_mixer[mixer::MASTER]->get_name()));
}
if (m_mixer[mixer::HEADPHONE] && !m_mixer[mixer::HEADPHONE]->get_name().empty() && headphones) {
mixers.emplace_back(new mixer_t::element_type(m_mixer[mixer::HEADPHONE]->get_name()));
}
if (m_mixer[mixer::SPEAKER] && !m_mixer[mixer::SPEAKER]->get_name().empty() && !headphones) {
mixers.emplace_back(new mixer_t::element_type(m_mixer[mixer::SPEAKER]->get_name()));
}
if (cmd.compare(0, strlen(EVENT_TOGGLE_MUTE), EVENT_TOGGLE_MUTE) == 0) { if (cmd.compare(0, strlen(EVENT_TOGGLE_MUTE), EVENT_TOGGLE_MUTE) == 0) {
for (auto&& mixer : mixers) { for (auto&& mixer : mixers) {
mixer->set_mute(m_muted || mixers[0]->is_muted()); mixer->set_mute(m_muted || mixers[0]->is_muted());
@ -202,7 +245,13 @@ namespace modules {
} else { } else {
return false; return false;
} }
} catch (const std::exception& err) {
for (auto&& mixer : mixers) {
if (mixer->wait(0)) {
mixer->process_events();
}
}
} catch (const exception& err) {
m_log.err("%s: Failed to handle command (%s)", name(), err.what()); m_log.err("%s: Failed to handle command (%s)", name(), err.what());
} }

View File

@ -18,7 +18,7 @@ namespace modules {
/** /**
* Construct module * Construct module
*/ */
xbacklight_module::xbacklight_module(const bar_settings bar, const logger& logger, const config& config, string name) xbacklight_module::xbacklight_module(const bar_settings& bar, const logger& logger, const config& config, string name)
: static_module<xbacklight_module>(bar, logger, config, name) : static_module<xbacklight_module>(bar, logger, config, name)
, m_connection(configure_connection().create<connection&>()) {} , m_connection(configure_connection().create<connection&>()) {}
@ -67,12 +67,15 @@ namespace modules {
// Add formats and elements // Add formats and elements
m_formatter->add(DEFAULT_FORMAT, TAG_LABEL, {TAG_LABEL, TAG_BAR, TAG_RAMP}); m_formatter->add(DEFAULT_FORMAT, TAG_LABEL, {TAG_LABEL, TAG_BAR, TAG_RAMP});
if (m_formatter->has(TAG_LABEL)) if (m_formatter->has(TAG_LABEL)) {
m_label = load_optional_label(m_conf, name(), TAG_LABEL, "%percentage%"); m_label = load_optional_label(m_conf, name(), TAG_LABEL, "%percentage%");
if (m_formatter->has(TAG_BAR)) }
if (m_formatter->has(TAG_BAR)) {
m_progressbar = load_progressbar(m_bar, m_conf, name(), TAG_BAR); m_progressbar = load_progressbar(m_bar, m_conf, name(), TAG_BAR);
if (m_formatter->has(TAG_RAMP)) }
if (m_formatter->has(TAG_RAMP)) {
m_ramp = load_ramp(m_conf, name(), TAG_RAMP); m_ramp = load_ramp(m_conf, name(), TAG_RAMP);
}
// Trigger the initial draw event // Trigger the initial draw event
update(); update();
@ -89,18 +92,19 @@ namespace modules {
* Handler for XCB_RANDR_NOTIFY events * Handler for XCB_RANDR_NOTIFY events
*/ */
void xbacklight_module::handle(const evt::randr_notify& evt) { void xbacklight_module::handle(const evt::randr_notify& evt) {
if (evt->subCode != XCB_RANDR_NOTIFY_OUTPUT_PROPERTY) if (evt->subCode != XCB_RANDR_NOTIFY_OUTPUT_PROPERTY) {
return; return;
else if (evt->u.op.status != XCB_PROPERTY_NEW_VALUE) } else if (evt->u.op.status != XCB_PROPERTY_NEW_VALUE) {
return; return;
else if (evt->u.op.window != m_proxy) } else if (evt->u.op.window != m_proxy) {
return; return;
else if (evt->u.op.output != m_output->output) } else if (evt->u.op.output != m_output->output) {
return; return;
else if (evt->u.op.atom != m_output->backlight.atom) } else if (evt->u.op.atom != m_output->backlight.atom) {
return; return;
else if (evt->u.op.timestamp <= m_timestamp) } else if (evt->u.op.timestamp <= m_timestamp) {
return; return;
}
// Store the timestamp with a throttle offset (ms) // Store the timestamp with a throttle offset (ms)
m_timestamp = evt->u.op.timestamp + 50; m_timestamp = evt->u.op.timestamp + 50;
@ -133,10 +137,12 @@ namespace modules {
* Generate the module output * Generate the module output
*/ */
string xbacklight_module::get_output() { string xbacklight_module::get_output() {
if (m_scroll && m_percentage < 100) if (m_scroll && m_percentage < 100) {
m_builder->cmd(mousebtn::SCROLL_UP, EVENT_SCROLLUP); m_builder->cmd(mousebtn::SCROLL_UP, EVENT_SCROLLUP);
if (m_scroll && m_percentage > 0) }
if (m_scroll && m_percentage > 0) {
m_builder->cmd(mousebtn::SCROLL_DOWN, EVENT_SCROLLDOWN); m_builder->cmd(mousebtn::SCROLL_DOWN, EVENT_SCROLLDOWN);
}
m_builder->append(static_module::get_output()); m_builder->append(static_module::get_output());
@ -146,15 +152,16 @@ namespace modules {
/** /**
* Output content as defined in the config * Output content as defined in the config
*/ */
bool xbacklight_module::build(builder* builder, string tag) const { bool xbacklight_module::build(builder* builder, const string& tag) const {
if (tag == TAG_BAR) if (tag == TAG_BAR) {
builder->node(m_progressbar->output(m_percentage)); builder->node(m_progressbar->output(m_percentage));
else if (tag == TAG_RAMP) } else if (tag == TAG_RAMP) {
builder->node(m_ramp->get_by_percentage(m_percentage)); builder->node(m_ramp->get_by_percentage(m_percentage));
else if (tag == TAG_LABEL) } else if (tag == TAG_LABEL) {
builder->node(m_label); builder->node(m_label);
else } else {
return false; return false;
}
return true; return true;
} }

View File

@ -113,7 +113,7 @@ namespace modules {
/** /**
* Output content as defined in the config * Output content as defined in the config
*/ */
bool xwindow_module::build(builder* builder, string tag) const { bool xwindow_module::build(builder* builder, const string& tag) const {
if (tag == TAG_LABEL) { if (tag == TAG_LABEL) {
builder->node(m_label); builder->node(m_label);
} else { } else {

View File

@ -1,5 +1,6 @@
#include <sys/un.h> #include <sys/un.h>
#include "errors.hpp"
#include "utils/bspwm.hpp" #include "utils/bspwm.hpp"
#include "utils/env.hpp" #include "utils/env.hpp"
@ -41,10 +42,12 @@ namespace bspwm_util {
for (auto&& root : root_windows(conn)) { for (auto&& root : root_windows(conn)) {
auto geom = conn.get_geometry(root); auto geom = conn.get_geometry(root);
if (mon->x != geom->x || mon->y != geom->y) if (mon->x != geom->x || mon->y != geom->y) {
continue; continue;
if (mon->w != geom->width || mon->h != geom->height) }
if (mon->w != geom->width || mon->h != geom->height) {
continue; continue;
}
const uint32_t value_mask = XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE; const uint32_t value_mask = XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE;
const uint32_t value_list[2]{root, XCB_STACK_MODE_ABOVE}; const uint32_t value_list[2]{root, XCB_STACK_MODE_ABOVE};
@ -68,16 +71,18 @@ namespace bspwm_util {
string get_socket_path() { string get_socket_path() {
string env_path; string env_path;
if ((env_path = env_util::get("BSPWM_SOCKET")).empty() == false) if (!(env_path = env_util::get("BSPWM_SOCKET")).empty()) {
return env_path; return env_path;
}
struct sockaddr_un sa; struct sockaddr_un sa;
char* host = nullptr; char* host = nullptr;
int dsp = 0; int dsp = 0;
int scr = 0; int scr = 0;
if (xcb_parse_display(nullptr, &host, &dsp, &scr) == 0) if (xcb_parse_display(nullptr, &host, &dsp, &scr) == 0) {
return BSPWM_SOCKET_PATH; return BSPWM_SOCKET_PATH;
}
snprintf(sa.sun_path, sizeof(sa.sun_path), "/tmp/bspwm%s_%i_%i-socket", host, dsp, scr); snprintf(sa.sun_path, sizeof(sa.sun_path), "/tmp/bspwm%s_%i_%i-socket", host, dsp, scr);
free(host); free(host);
@ -89,7 +94,7 @@ namespace bspwm_util {
* Generate a payload object with properly formatted data * Generate a payload object with properly formatted data
* ready to be sent to the bspwm ipc controller * ready to be sent to the bspwm ipc controller
*/ */
payload_t make_payload(string cmd) { payload_t make_payload(const string& cmd) {
payload_t payload{new payload_t::element_type{}}; payload_t payload{new payload_t::element_type{}};
auto size = sizeof(payload->data); auto size = sizeof(payload->data);
int offset = 0; int offset = 0;
@ -135,8 +140,9 @@ namespace bspwm_util {
connection_t make_subscriber() { connection_t make_subscriber() {
auto conn = make_connection(); auto conn = make_connection();
auto payload = make_payload("subscribe report"); auto payload = make_payload("subscribe report");
if (conn->send(payload->data, payload->len, 0) == 0) if (conn->send(payload->data, payload->len, 0) == 0) {
throw system_error("Failed to initialize subscriber"); throw system_error("Failed to initialize subscriber");
}
return conn; return conn;
} }
} }

View File

@ -1,7 +1,9 @@
#include <sys/wait.h> #include <sys/wait.h>
#include <unistd.h> #include <unistd.h>
#include <csignal> #include <csignal>
#include <utility>
#include "errors.hpp"
#include "utils/command.hpp" #include "utils/command.hpp"
#include "utils/io.hpp" #include "utils/io.hpp"
#include "utils/process.hpp" #include "utils/process.hpp"
@ -10,50 +12,65 @@ POLYBAR_NS
namespace command_util { namespace command_util {
command::command(const logger& logger, string cmd) : m_log(logger), m_cmd("/usr/bin/env\nsh\n-c\n" + cmd) { command::command(const logger& logger, string cmd) : m_log(logger), m_cmd("/usr/bin/env\nsh\n-c\n" + cmd) {
if (pipe(m_stdin) != 0) if (pipe(m_stdin) != 0) {
throw command_strerror("Failed to allocate input stream"); throw command_strerror("Failed to allocate input stream");
if (pipe(m_stdout) != 0) }
if (pipe(m_stdout) != 0) {
throw command_strerror("Failed to allocate output stream"); throw command_strerror("Failed to allocate output stream");
} }
}
command::~command() { command::~command() {
if (is_running()) if (is_running()) {
terminate(); terminate();
}
if (m_stdin[PIPE_READ] > 0) if (m_stdin[PIPE_READ] > 0) {
close(m_stdin[PIPE_READ]); close(m_stdin[PIPE_READ]);
if (m_stdin[PIPE_WRITE] > 0) }
if (m_stdin[PIPE_WRITE] > 0) {
close(m_stdin[PIPE_WRITE]); close(m_stdin[PIPE_WRITE]);
if (m_stdout[PIPE_READ] > 0) }
if (m_stdout[PIPE_READ] > 0) {
close(m_stdout[PIPE_READ]); close(m_stdout[PIPE_READ]);
if (m_stdout[PIPE_WRITE] > 0) }
if (m_stdout[PIPE_WRITE] > 0) {
close(m_stdout[PIPE_WRITE]); close(m_stdout[PIPE_WRITE]);
} }
}
/** /**
* Execute the command * Execute the command
*/ */
int command::exec(bool wait_for_completion) { int command::exec(bool wait_for_completion) {
if ((m_forkpid = fork()) == -1) if ((m_forkpid = fork()) == -1) {
throw system_error("Failed to fork process"); throw system_error("Failed to fork process");
}
if (process_util::in_forked_process(m_forkpid)) { if (process_util::in_forked_process(m_forkpid)) {
if (dup2(m_stdin[PIPE_READ], STDIN_FILENO) == -1) if (dup2(m_stdin[PIPE_READ], STDIN_FILENO) == -1) {
throw command_strerror("Failed to redirect stdin in child process"); throw command_strerror("Failed to redirect stdin in child process");
if (dup2(m_stdout[PIPE_WRITE], STDOUT_FILENO) == -1) }
if (dup2(m_stdout[PIPE_WRITE], STDOUT_FILENO) == -1) {
throw command_strerror("Failed to redirect stdout in child process"); throw command_strerror("Failed to redirect stdout in child process");
if (dup2(m_stdout[PIPE_WRITE], STDERR_FILENO) == -1) }
if (dup2(m_stdout[PIPE_WRITE], STDERR_FILENO) == -1) {
throw command_strerror("Failed to redirect stderr in child process"); throw command_strerror("Failed to redirect stderr in child process");
}
// Close file descriptors that won't be used by the child // Close file descriptors that won't be used by the child
if ((m_stdin[PIPE_READ] = close(m_stdin[PIPE_READ])) == -1) if ((m_stdin[PIPE_READ] = close(m_stdin[PIPE_READ])) == -1) {
throw command_strerror("Failed to close fd"); throw command_strerror("Failed to close fd");
if ((m_stdin[PIPE_WRITE] = close(m_stdin[PIPE_WRITE])) == -1) }
if ((m_stdin[PIPE_WRITE] = close(m_stdin[PIPE_WRITE])) == -1) {
throw command_strerror("Failed to close fd"); throw command_strerror("Failed to close fd");
if ((m_stdout[PIPE_READ] = close(m_stdout[PIPE_READ])) == -1) }
if ((m_stdout[PIPE_READ] = close(m_stdout[PIPE_READ])) == -1) {
throw command_strerror("Failed to close fd"); throw command_strerror("Failed to close fd");
if ((m_stdout[PIPE_WRITE] = close(m_stdout[PIPE_WRITE])) == -1) }
if ((m_stdout[PIPE_WRITE] = close(m_stdout[PIPE_WRITE])) == -1) {
throw command_strerror("Failed to close fd"); throw command_strerror("Failed to close fd");
}
// Make sure SIGTERM is raised // Make sure SIGTERM is raised
process_util::unblock_signal(SIGTERM); process_util::unblock_signal(SIGTERM);
@ -64,10 +81,12 @@ namespace command_util {
throw command_error("Exec failed"); throw command_error("Exec failed");
} else { } else {
// Close file descriptors that won't be used by the parent // Close file descriptors that won't be used by the parent
if ((m_stdin[PIPE_READ] = close(m_stdin[PIPE_READ])) == -1) if ((m_stdin[PIPE_READ] = close(m_stdin[PIPE_READ])) == -1) {
throw command_strerror("Failed to close fd"); throw command_strerror("Failed to close fd");
if ((m_stdout[PIPE_WRITE] = close(m_stdout[PIPE_WRITE])) == -1) }
if ((m_stdout[PIPE_WRITE] = close(m_stdout[PIPE_WRITE])) == -1) {
throw command_strerror("Failed to close fd"); throw command_strerror("Failed to close fd");
}
if (wait_for_completion) { if (wait_for_completion) {
auto status = wait(); auto status = wait();
@ -97,8 +116,9 @@ namespace command_util {
* Check if command is running * Check if command is running
*/ */
bool command::is_running() { bool command::is_running() {
if (m_forkpid > 0) if (m_forkpid > 0) {
return process_util::wait_for_completion_nohang(m_forkpid, &m_forkstatus) > -1; return process_util::wait_for_completion_nohang(m_forkpid, &m_forkstatus) > -1;
}
return false; return false;
} }
@ -111,18 +131,19 @@ namespace command_util {
process_util::wait_for_completion(m_forkpid, &m_forkstatus, WCONTINUED | WUNTRACED); process_util::wait_for_completion(m_forkpid, &m_forkstatus, WCONTINUED | WUNTRACED);
if (WIFEXITED(m_forkstatus) && m_forkstatus > 0) if (WIFEXITED(m_forkstatus) && m_forkstatus > 0) {
m_log.warn("command: Exited with failed status %d", WEXITSTATUS(m_forkstatus)); m_log.warn("command: Exited with failed status %d", WEXITSTATUS(m_forkstatus));
else if (WIFEXITED(m_forkstatus)) } else if (WIFEXITED(m_forkstatus)) {
m_log.trace("command: Exited with status %d", WEXITSTATUS(m_forkstatus)); m_log.trace("command: Exited with status %d", WEXITSTATUS(m_forkstatus));
else if (WIFSIGNALED(m_forkstatus)) } else if (WIFSIGNALED(m_forkstatus)) {
m_log.trace("command: killed by signal %d", WTERMSIG(m_forkstatus)); m_log.trace("command: killed by signal %d", WTERMSIG(m_forkstatus));
else if (WIFSTOPPED(m_forkstatus)) } else if (WIFSTOPPED(m_forkstatus)) {
m_log.trace("command: Stopped by signal %d", WSTOPSIG(m_forkstatus)); m_log.trace("command: Stopped by signal %d", WSTOPSIG(m_forkstatus));
else if (WIFCONTINUED(m_forkstatus) == true) } else if (WIFCONTINUED(m_forkstatus)) {
m_log.trace("command: Continued"); m_log.trace("command: Continued");
else } else {
break; break;
}
} while (!WIFEXITED(m_forkstatus) && !WIFSIGNALED(m_forkstatus)); } while (!WIFEXITED(m_forkstatus) && !WIFSIGNALED(m_forkstatus));
return m_forkstatus; return m_forkstatus;
@ -135,7 +156,7 @@ namespace command_util {
* end until the stream is closed * end until the stream is closed
*/ */
void command::tail(callback<string> callback) { void command::tail(callback<string> callback) {
io_util::tail(m_stdout[PIPE_READ], callback); io_util::tail(m_stdout[PIPE_READ], move(callback));
} }
/** /**
@ -143,7 +164,7 @@ namespace command_util {
*/ */
int command::writeline(string data) { int command::writeline(string data) {
std::lock_guard<concurrency_util::spin_lock> lck(m_pipelock); std::lock_guard<concurrency_util::spin_lock> lck(m_pipelock);
return io_util::writeline(m_stdin[PIPE_WRITE], data); return io_util::writeline(m_stdin[PIPE_WRITE], move(data));
} }
/** /**

View File

@ -1,4 +1,5 @@
#include <thread> #include <thread>
#include <utility>
#include "utils/env.hpp" #include "utils/env.hpp"
@ -11,7 +12,7 @@ namespace env_util {
string get(const char* var, string fallback) { string get(const char* var, string fallback) {
const char* value{std::getenv(var)}; const char* value{std::getenv(var)};
return value != nullptr ? value : fallback; return value != nullptr ? value : move(fallback);
} }
} }

View File

@ -1,9 +1,10 @@
#include "utils/file.hpp"
#include <fcntl.h> #include <fcntl.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <fstream> #include <fstream>
#include "errors.hpp"
#include "utils/file.hpp"
#include "utils/scope.hpp" #include "utils/scope.hpp"
POLYBAR_NS POLYBAR_NS
@ -13,9 +14,10 @@ namespace file_util {
* Destructor: close file handler * Destructor: close file handler
*/ */
file_ptr::~file_ptr() { file_ptr::~file_ptr() {
if (m_ptr != nullptr) if (m_ptr != nullptr) {
fclose(m_ptr); fclose(m_ptr);
} }
}
/** /**
* Logical operator testing if the file handler was created * Logical operator testing if the file handler was created
@ -34,7 +36,7 @@ namespace file_util {
/** /**
* Checks if the given file exist * Checks if the given file exist
*/ */
bool exists(string filename) { bool exists(const string& filename) {
struct stat buffer; struct stat buffer;
return stat(filename.c_str(), &buffer) == 0; return stat(filename.c_str(), &buffer) == 0;
} }
@ -42,7 +44,7 @@ namespace file_util {
/** /**
* Gets the contents of the given file * Gets the contents of the given file
*/ */
string get_contents(string filename) { string get_contents(const string& filename) {
try { try {
std::ifstream ifs(filename); std::ifstream ifs(filename);
string contents((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>())); string contents((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
@ -58,9 +60,10 @@ namespace file_util {
void set_block(int fd) { void set_block(int fd) {
int flags = fcntl(fd, F_GETFL, 0); int flags = fcntl(fd, F_GETFL, 0);
flags &= ~O_NONBLOCK; flags &= ~O_NONBLOCK;
if (fcntl(fd, F_SETFL, flags) == -1) if (fcntl(fd, F_SETFL, flags) == -1) {
throw system_error("Failed to unset O_NONBLOCK"); throw system_error("Failed to unset O_NONBLOCK");
} }
}
/** /**
* Puts the given file descriptor into non-blocking mode * Puts the given file descriptor into non-blocking mode
@ -68,9 +71,10 @@ namespace file_util {
void set_nonblock(int fd) { void set_nonblock(int fd) {
int flags = fcntl(fd, F_GETFL, 0); int flags = fcntl(fd, F_GETFL, 0);
flags |= O_NONBLOCK; flags |= O_NONBLOCK;
if (fcntl(fd, F_SETFL, flags) == -1) if (fcntl(fd, F_SETFL, flags) == -1) {
throw system_error("Failed to set O_NONBLOCK"); throw system_error("Failed to set O_NONBLOCK");
} }
}
/** /**
* Checks if the given file is a named pipe * Checks if the given file is a named pipe

View File

@ -14,7 +14,7 @@ namespace i3_util {
/** /**
* Get all i3 root windows * Get all i3 root windows
*/ */
vector<xcb_window_t> root_windows(connection& conn, string output_name) { vector<xcb_window_t> root_windows(connection& conn, const string& output_name) {
vector<xcb_window_t> roots; vector<xcb_window_t> roots;
auto children = conn.query_tree(conn.screen()->root).children(); auto children = conn.query_tree(conn.screen()->root).children();

View File

@ -1,5 +1,6 @@
#include <unistd.h> #include <unistd.h>
#include "errors.hpp"
#include "utils/inotify.hpp" #include "utils/inotify.hpp"
#include "utils/memory.hpp" #include "utils/memory.hpp"
@ -10,20 +11,24 @@ namespace inotify_util {
* Destructor * Destructor
*/ */
inotify_watch::~inotify_watch() noexcept { inotify_watch::~inotify_watch() noexcept {
if (m_wd != -1) if (m_wd != -1) {
inotify_rm_watch(m_fd, m_wd); inotify_rm_watch(m_fd, m_wd);
if (m_fd != -1) }
if (m_fd != -1) {
close(m_fd); close(m_fd);
} }
}
/** /**
* Attach inotify watch * Attach inotify watch
*/ */
void inotify_watch::attach(int mask) { void inotify_watch::attach(int mask) {
if (m_fd == -1 && (m_fd = inotify_init()) == -1) if (m_fd == -1 && (m_fd = inotify_init()) == -1) {
throw system_error("Failed to allocate inotify fd"); throw system_error("Failed to allocate inotify fd");
if ((m_wd = inotify_add_watch(m_fd, m_path.c_str(), mask)) == -1) }
if ((m_wd = inotify_add_watch(m_fd, m_path.c_str(), mask)) == -1) {
throw system_error("Failed to attach inotify watch"); throw system_error("Failed to attach inotify watch");
}
m_mask |= mask; m_mask |= mask;
} }
@ -31,8 +36,9 @@ namespace inotify_util {
* Remove inotify watch * Remove inotify watch
*/ */
void inotify_watch::remove() { void inotify_watch::remove() {
if (inotify_rm_watch(m_fd, m_wd) == -1) if (inotify_rm_watch(m_fd, m_wd) == -1) {
throw system_error("Failed to remove inotify watch"); throw system_error("Failed to remove inotify watch");
}
m_wd = -1; m_wd = -1;
m_mask = 0; m_mask = 0;
} }
@ -43,8 +49,9 @@ namespace inotify_util {
* @brief A wait_ms of -1 blocks until an event is fired * @brief A wait_ms of -1 blocks until an event is fired
*/ */
bool inotify_watch::poll(int wait_ms) { bool inotify_watch::poll(int wait_ms) {
if (m_fd == -1) if (m_fd == -1) {
return false; return false;
}
struct pollfd fds[1]; struct pollfd fds[1];
fds[0].fd = m_fd; fds[0].fd = m_fd;
@ -61,8 +68,9 @@ namespace inotify_util {
unique_ptr<event_t> inotify_watch::get_event() { unique_ptr<event_t> inotify_watch::get_event() {
auto event = make_unique<event_t>(); auto event = make_unique<event_t>();
if (m_fd == -1 || m_wd == -1) if (m_fd == -1 || m_wd == -1) {
return event; return event;
}
char buffer[1024]; char buffer[1024];
size_t bytes = read(m_fd, buffer, 1024); size_t bytes = read(m_fd, buffer, 1024);

View File

@ -1,10 +1,11 @@
#include <fcntl.h> #include <fcntl.h>
#include <poll.h> #include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include <cstdio>
#include <cstdlib>
#include "errors.hpp"
#include "utils/io.hpp" #include "utils/io.hpp"
#include "utils/string.hpp" #include "utils/string.hpp"
@ -14,8 +15,9 @@ namespace io_util {
string read(int read_fd, int bytes_to_read, int& bytes_read_loc, int& status_loc) { string read(int read_fd, int bytes_to_read, int& bytes_read_loc, int& status_loc) {
char buffer[BUFSIZ - 1]; char buffer[BUFSIZ - 1];
if (bytes_to_read == -1) if (bytes_to_read == -1) {
bytes_to_read = sizeof(buffer); bytes_to_read = sizeof(buffer);
}
status_loc = 0; status_loc = 0;
@ -43,17 +45,19 @@ namespace io_util {
bytes_read = 0; bytes_read = 0;
while ((bytes = ::read(read_fd, &char_, 1)) > 0) { while ((bytes = ::read(read_fd, &char_, 1)) > 0) {
if (bytes <= 0) if (bytes <= 0) {
break; break;
if (char_ == '\n' || char_ == '\x00') }
if (char_ == '\n' || char_ == '\x00') {
break; break;
}
bytes_read += bytes; bytes_read += bytes;
buffer << char_; buffer << char_;
} }
if (bytes_read <= 0) if (bytes_read <= 0) {
return ""; return "";
}
return string_util::strip_trailing_newline(buffer.str()); return string_util::strip_trailing_newline(buffer.str());
} }
@ -62,25 +66,28 @@ namespace io_util {
return readline(read_fd, bytes_read); return readline(read_fd, bytes_read);
} }
size_t write(int write_fd, string data) { size_t write(int write_fd, const string& data) {
return ::write(write_fd, data.c_str(), strlen(data.c_str())); return ::write(write_fd, data.c_str(), strlen(data.c_str()));
} }
size_t writeline(int write_fd, string data) { size_t writeline(int write_fd, const string& data) {
if (data.length() == 0) if (data.length() == 0) {
return -1; return -1;
if (data.substr(data.length() - 1, 1) != "\n") }
if (data.substr(data.length() - 1, 1) != "\n") {
return io_util::write(write_fd, data + "\n"); return io_util::write(write_fd, data + "\n");
else } else {
return io_util::write(write_fd, data); return io_util::write(write_fd, data);
} }
}
void tail(int read_fd, function<void(string)> callback) { void tail(int read_fd, const function<void(string)>& callback) {
int bytes_read; int bytes_read;
while (true) { while (true) {
auto line = io_util::readline(read_fd, bytes_read); auto line = io_util::readline(read_fd, bytes_read);
if (bytes_read <= 0) if (bytes_read <= 0) {
break; break;
}
callback(line); callback(line);
} }
} }

Some files were not shown because too many files have changed in this diff Show More