diff --git a/.clang-tidy b/.clang-tidy index b558598b..d28a1322 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -16,6 +16,7 @@ Checks: ' -modernize-raw-string-literal, -modernize-use-bool-literals, -modernize-use-trailing-return-type, + -readability-identifier-length, -readability-implicit-bool-cast, -readability-else-after-return, -readability-named-parameter, @@ -26,7 +27,8 @@ Checks: ' -cppcoreguidelines-pro-type-reinterpret-cast, -cppcoreguidelines-pro-type-union-access, -cppcoreguidelines-pro-type-cstyle-cast, - -cppcoreguidelines-pro-bounds-constant-array-index + -cppcoreguidelines-pro-bounds-constant-array-index, + -cppcoreguidelines-owning-memory, ' CheckOptions: diff --git a/.gitignore b/.gitignore index 4385459f..e514ef36 100644 --- a/.gitignore +++ b/.gitignore @@ -8,5 +8,8 @@ .tags *.user +# clangd +/.cache + polybar-*.tar *.cache diff --git a/CHANGELOG.md b/CHANGELOG.md index c557059d..98aea186 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `custom/text`: The `content` setting and all its properties are deprecated in favor of `format` with the same functionality. ([`#2676`](https://github.com/polybar/polybar/pull/2676)) ### Added +- Added support for format-i for each hook-i defined in ipc module ([`#2775`](https://github.com/polybar/polybar/issues/2775), [`#2810`](https://github.com/polybar/polybar/pull/2810)) by [@madhavpcm](https://github.com/madhavpcm). - `internal/temperature`: `%temperature-k%` token displays the temperature in kelvin ([`#2774`](https://github.com/polybar/polybar/discussions/2774), [`#2784`](https://github.com/polybar/polybar/pull/2784)) - `internal/pulseaudio`: `reverse-scroll` option ([`#2664`](https://github.com/polybar/polybar/pull/2664)) - `custom/script`: Repeat interval for script failure (`interval-fail`) and `exec-if` (`interval-if`) ([`#943`](https://github.com/polybar/polybar/issues/943), [`#2606`](https://github.com/polybar/polybar/issues/2606), [`#2630`](https://github.com/polybar/polybar/pull/2630)) @@ -30,8 +31,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - `internal/fs`: Use `/` as a fallback if no mountpoints are specified ([`#2572`](https://github.com/polybar/polybar/issues/2572), [`#2705`](https://github.com/polybar/polybar/pull/2705)) -- `internal/backlight`: Detect backlight if none specified ([`#2572`](https://github.com/polybar/polybar/issues/2572), [`#2728`](https://github.com/polybar/polybar/pull/2728)) +- `internal/backlight`: + - Detect backlight if none specified ([`#2572`](https://github.com/polybar/polybar/issues/2572), [`#2728`](https://github.com/polybar/polybar/pull/2728)) + - `use-actual-brightness` defaults to `true` for `amdgpu` backlights ([`#2835`](https://github.com/polybar/polybar/issues/2835), [`2839`](https://github.com/polybar/polybar/pull/2839)) - Providing a negative min-width to a token adds right-padding ([`#2789`](https://github.com/polybar/polybar/issues/2789), [`#2801`](https://github.com/polybar/polybar/pull/2801)) by [@VanillaViking](https://github.com/VanillaViking). +- Changed fuzzy match option on i3 and bspwm modules to find longest match instead of the first match ([`#2831`](https://github.com/polybar/polybar/pull/2831), [`#2829`](https://github.com/polybar/polybar/issues/2829)) by [@Ron0Studios](https://github.com/ron0studios/). ### Fixed - Waiting for double click interval on modules that don't have a double click action ([`#2663`](https://github.com/polybar/polybar/issues/2663), [`#2695`](https://github.com/polybar/polybar/pull/2695)) diff --git a/cmake/cxx.cmake b/cmake/cxx.cmake index ecc0194f..f9b3db45 100644 --- a/cmake/cxx.cmake +++ b/cmake/cxx.cmake @@ -24,11 +24,11 @@ set(THREADS_PREFER_PTHREAD_FLAG ON) set(POLYBAR_FLAGS "" CACHE STRING "C++ compiler flags used for compiling polybar") -list(APPEND cxx_base -Wall -Wextra -Wpedantic) -list(APPEND cxx_debug -DDEBUG -g2) +list(APPEND cxx_base -Wall -Wextra -Wpedantic -Wdeprecated-copy-dtor) +list(APPEND cxx_debug -DDEBUG -g2 -Og) list(APPEND cxx_minsizerel "") -list(APPEND cxx_sanitize -O0 -g -fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer -fno-optimize-sibling-calls) -list(APPEND cxx_coverage --coverage) +list(APPEND cxx_sanitize ${cxx_debug} -O0 -fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer -fno-optimize-sibling-calls) +list(APPEND cxx_coverage ${cxx_debug} --coverage) list(APPEND cxx_linker_base "") list(APPEND cxx_linker_minsizerel "") @@ -79,8 +79,6 @@ elseif(CXXLIB_GCC) list(APPEND cxx_linker_base -lstdc++) endif() -# Custom build type 'Coverage', inherits the debug flags -list(APPEND cxx_coverage ${cxx_debug} ${cxx_coverage}) SET(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_DEBUG} ${CMAKE_CXX_FLAGS_COVERAGE}") SET(CMAKE_EXE_LINKER_FLAGS_COVERAGE "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${CMAKE_EXE_LINKER_FLAGS_COVERAGE}") SET(CMAKE_SHARED_LINKER_FLAGS_COVERAGE "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} ${CMAKE_SHARED_LINKER_FLAGS_COVERAGE}") diff --git a/include/components/bar.hpp b/include/components/bar.hpp index 60331e54..3e5f3f1a 100644 --- a/include/components/bar.hpp +++ b/include/components/bar.hpp @@ -107,10 +107,10 @@ class bar : public xpp::event::sink m_dblclicks; - eventloop::TimerHandle& m_leftclick_timer{m_loop.handle()}; - eventloop::TimerHandle& m_middleclick_timer{m_loop.handle()}; - eventloop::TimerHandle& m_rightclick_timer{m_loop.handle()}; - eventloop::TimerHandle& m_dim_timer{m_loop.handle()}; + eventloop::timer_handle_t m_leftclick_timer{m_loop.handle()}; + eventloop::timer_handle_t m_middleclick_timer{m_loop.handle()}; + eventloop::timer_handle_t m_rightclick_timer{m_loop.handle()}; + eventloop::timer_handle_t m_dim_timer{m_loop.handle()}; bool m_visible{true}; }; diff --git a/include/components/controller.hpp b/include/components/controller.hpp index 70edcaf7..1fc5ebc4 100644 --- a/include/components/controller.hpp +++ b/include/components/controller.hpp @@ -55,7 +55,7 @@ class controller : public signal_receiver([this]() { notifier_handler(); })}; + eventloop::async_handle_t m_notifier{m_loop.handle([this]() { notifier_handler(); })}; /** * Notification data for the controller. diff --git a/include/components/eventloop.hpp b/include/components/eventloop.hpp index 7c1908e2..1446ffa3 100644 --- a/include/components/eventloop.hpp +++ b/include/components/eventloop.hpp @@ -3,6 +3,7 @@ #include #include +#include #include "common.hpp" #include "components/logger.hpp" @@ -36,12 +37,12 @@ namespace eventloop { get()->data = this; } - Self& leak(std::unique_ptr h) { + void leak(std::shared_ptr h) { lifetime_extender = std::move(h); - return *lifetime_extender; } void unleak() { + reset_callbacks(); lifetime_extender.reset(); } @@ -73,6 +74,15 @@ namespace eventloop { } protected: + ~Handle() = default; + + /** + * Resets all callbacks stored in the handle as part of closing the handle. + * + * This releases any lambda captures, breaking possible cyclic dependencies in shared_ptr. + */ + virtual void reset_callbacks() = 0; + /** * Generic callback function that can be used for all uv handle callbacks. * @@ -128,14 +138,14 @@ namespace eventloop { uv_loop_t* uv_loop; /** - * The handle stores the unique_ptr to itself so that it effectively leaks memory. + * The handle stores the shared_ptr to itself so that it effectively leaks memory. * * This saves us from having to guarantee that the handle's lifetime extends to at least after it is closed. * * Once the handle is closed, either explicitly or by walking all handles when the loop shuts down, this reference * is reset and the object is explicitly destroyed. */ - std::unique_ptr lifetime_extender; + std::shared_ptr lifetime_extender; }; struct ErrorEvent { @@ -144,54 +154,32 @@ namespace eventloop { using cb_error = cb_event; - class WriteRequest : public non_copyable_mixin { + class WriteRequest : public non_copyable_mixin, public non_movable_mixin { public: using cb_write = cb_void; - WriteRequest(cb_write user_cb, cb_error err_cb) : write_callback(user_cb), write_err_cb(err_cb) { - get()->data = this; - }; + WriteRequest(cb_write&& user_cb, cb_error&& err_cb); - static WriteRequest& create(cb_write user_cb, cb_error err_cb) { - auto r = std::make_unique(user_cb, err_cb); - return r->leak(std::move(r)); - }; + static WriteRequest& create(cb_write&& user_cb, cb_error&& err_cb); - uv_write_t* get() { - return &req; - } + uv_write_t* get(); /** * Trigger the write callback. * * After that, this object is destroyed. */ - void trigger(int status) { - if (status < 0) { - if (write_err_cb) { - write_err_cb(ErrorEvent{status}); - } - } else { - if (write_callback) { - write_callback(); - } - } - - unleak(); - } + void trigger(int status); protected: - WriteRequest& leak(std::unique_ptr h) { - lifetime_extender = std::move(h); - return *lifetime_extender; - } + WriteRequest& leak(std::unique_ptr h); - void unleak() { - lifetime_extender.reset(); - } + void unleak(); + + void reset_callbacks(); private: - uv_write_t req; + uv_write_t req{}; cb_write write_callback; cb_error write_err_cb; @@ -208,13 +196,16 @@ namespace eventloop { int signum; }; - class SignalHandle : public Handle { + class SignalHandle final : public Handle { public: using Handle::Handle; using cb = cb_event; void init(); - void start(int signum, cb user_cb); + void start(int signum, cb&& user_cb); + + protected: + void reset_callbacks() override; private: cb callback; @@ -224,15 +215,18 @@ namespace eventloop { uv_poll_event event; }; - class PollHandle : public Handle { + class PollHandle final : public Handle { public: using Handle::Handle; using cb = cb_event; void init(int fd); - void start(int events, cb user_cb, cb_error err_cb); + void start(int events, cb&& user_cb, cb_error&& err_cb); static void poll_callback(uv_poll_t*, int status, int events); + protected: + void reset_callbacks() override; + private: cb callback; cb_error err_cb; @@ -243,41 +237,50 @@ namespace eventloop { uv_fs_event event; }; - class FSEventHandle : public Handle { + class FSEventHandle final : public Handle { public: using Handle::Handle; using cb = cb_event; void init(); - void start(const string& path, int flags, cb user_cb, cb_error err_cb); + void start(const string& path, int flags, cb&& user_cb, cb_error&& err_cb); static void fs_event_callback(uv_fs_event_t*, const char* path, int events, int status); + protected: + void reset_callbacks() override; + private: cb callback; cb_error err_cb; }; - class TimerHandle : public Handle { + class TimerHandle final : public Handle { public: using Handle::Handle; using cb = cb_void; void init(); - void start(uint64_t timeout, uint64_t repeat, cb user_cb); + void start(uint64_t timeout, uint64_t repeat, cb&& user_cb); void stop(); + protected: + void reset_callbacks() override; + private: cb callback; }; - class AsyncHandle : public Handle { + class AsyncHandle final : public Handle { public: using Handle::Handle; using cb = cb_void; - void init(cb user_cb); + void init(cb&& user_cb); void send(); + protected: + void reset_callbacks() override; + private: cb callback; }; @@ -295,9 +298,9 @@ namespace eventloop { using cb_read_eof = cb_void; using cb_connection = cb_void; - void listen(int backlog, cb_connection user_cb, cb_error err_cb) { - this->connection_callback = user_cb; - this->connection_err_cb = err_cb; + void listen(int backlog, cb_connection&& user_cb, cb_error&& err_cb) { + this->connection_callback = std::move(user_cb); + this->connection_err_cb = std::move(err_cb); UV(uv_listen, this->template get(), backlog, connection_cb); }; @@ -316,11 +319,11 @@ namespace eventloop { UV(uv_accept, this->template get(), client.template get()); } - void read_start(cb_read fun, cb_void eof_cb, cb_error err_cb) { - this->read_callback = fun; - this->read_eof_cb = eof_cb; - this->read_err_cb = err_cb; - UV(uv_read_start, this->template get(), &this->alloc_callback, read_cb); + void read_start(cb_read&& fun, cb_void&& eof_cb, cb_error&& err_cb) { + this->read_callback = std::move(fun); + this->read_eof_cb = std::move(eof_cb); + this->read_err_cb = std::move(err_cb); + UV(uv_read_start, this->template get(), &this->alloc_callback, &read_cb); }; static void read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) { @@ -340,8 +343,8 @@ namespace eventloop { } }; - void write(const vector& data, WriteRequest::cb_write user_cb = {}, cb_error err_cb = {}) { - WriteRequest& req = WriteRequest::create(user_cb, err_cb); + void write(const vector& data, WriteRequest::cb_write&& user_cb = {}, cb_error&& err_cb = {}) { + WriteRequest& req = WriteRequest::create(std::move(user_cb), std::move(err_cb)); uv_buf_t buf{(char*)data.data(), data.size()}; @@ -349,6 +352,17 @@ namespace eventloop { [](uv_write_t* r, int status) { static_cast(r->data)->trigger(status); }); } + protected: + ~StreamHandle() = default; + + void reset_callbacks() override { + read_callback = nullptr; + read_eof_cb = nullptr; + read_err_cb = nullptr; + connection_callback = nullptr; + connection_err_cb = nullptr; + } + private: /** * Callback for receiving data @@ -371,7 +385,7 @@ namespace eventloop { cb_error connection_err_cb; }; - class PipeHandle : public StreamHandle { + class PipeHandle final : public StreamHandle { public: using StreamHandle::StreamHandle; using cb_connect = cb_void; @@ -381,7 +395,10 @@ namespace eventloop { void bind(const string& path); - void connect(const string& name, cb_connect user_cb, cb_error err_cb); + void connect(const string& name, cb_connect&& user_cb, cb_error&& err_cb); + + protected: + void reset_callbacks() override; private: static void connect_cb(uv_connect_t* req, int status); @@ -390,13 +407,16 @@ namespace eventloop { cb_connect connect_callback; }; - class PrepareHandle : public Handle { + class PrepareHandle final : public Handle { public: using Handle::Handle; using cb = cb_void; void init(); - void start(cb user_cb); + void start(cb&& user_cb); + + protected: + void reset_callbacks() override; private: static void connect_cb(uv_connect_t* req, int status); @@ -404,6 +424,14 @@ namespace eventloop { cb callback; }; + using signal_handle_t = shared_ptr; + using poll_handle_t = shared_ptr; + using fs_event_handle_t = shared_ptr; + using timer_handle_t = shared_ptr; + using async_handle_t = shared_ptr; + using pipe_handle_t = shared_ptr; + using prepare_handle_t = shared_ptr; + class loop : public non_copyable_mixin, public non_movable_mixin { public: loop(); @@ -413,10 +441,11 @@ namespace eventloop { uint64_t now() const; template - H& handle(Args... args) { - auto ptr = make_unique(get()); + shared_ptr handle(Args&&... args) { + auto ptr = make_shared(get()); ptr->init(std::forward(args)...); - return ptr->leak(std::move(ptr)); + ptr->leak(ptr); + return ptr; } uv_loop_t* get() const; diff --git a/include/drawtypes/iconset.hpp b/include/drawtypes/iconset.hpp index 242f2923..5f6a8036 100644 --- a/include/drawtypes/iconset.hpp +++ b/include/drawtypes/iconset.hpp @@ -21,6 +21,6 @@ namespace drawtypes { }; using iconset_t = shared_ptr; -} // namespace drawtypes +} // namespace drawtypes POLYBAR_NS_END diff --git a/include/errors.hpp b/include/errors.hpp index 2ca554bb..654f4459 100644 --- a/include/errors.hpp +++ b/include/errors.hpp @@ -8,14 +8,13 @@ POLYBAR_NS -using std::strerror; using std::exception; using std::runtime_error; +using std::strerror; class application_error : public runtime_error { public: explicit application_error(const string& message, int code = 0) : runtime_error(message), code(code) {} - virtual ~application_error() {} int code{0}; }; @@ -24,7 +23,6 @@ class system_error : public application_error { explicit system_error() : application_error(strerror(errno), errno) {} explicit system_error(const string& message) : application_error(message + " (reason: " + strerror(errno) + ")", errno) {} - virtual ~system_error() {} }; #define DEFINE_CHILD_ERROR(error, parent) \ diff --git a/include/ipc/ipc.hpp b/include/ipc/ipc.hpp index 7e2e0068..fb642ac8 100644 --- a/include/ipc/ipc.hpp +++ b/include/ipc/ipc.hpp @@ -42,14 +42,14 @@ namespace ipc { const logger& m_log; eventloop::loop& m_loop; - eventloop::PipeHandle& socket; + eventloop::pipe_handle_t socket; class connection : public non_copyable_mixin, public non_movable_mixin { public: using cb = std::function&)>; connection(eventloop::loop& loop, cb msg_callback); ~connection(); - eventloop::PipeHandle& client_pipe; + eventloop::pipe_handle_t client_pipe; decoder dec; }; @@ -79,7 +79,7 @@ namespace ipc { struct fifo { fifo(eventloop::loop& loop, ipc& ipc, const string& path); ~fifo(); - eventloop::PipeHandle& pipe_handle; + eventloop::pipe_handle_t pipe_handle; }; unique_ptr ipc_pipe; diff --git a/include/modules/ipc.hpp b/include/modules/ipc.hpp index b59f17c4..0990c4de 100644 --- a/include/modules/ipc.hpp +++ b/include/modules/ipc.hpp @@ -29,6 +29,7 @@ namespace modules { void start() override; void update(); string get_output(); + string get_format() const; bool build(builder* builder, const string& tag) const; void on_message(const string& message); @@ -63,6 +64,6 @@ namespace modules { int m_current_hook{-1}; void exec_hook(); }; -} // namespace modules +} // namespace modules POLYBAR_NS_END diff --git a/include/modules/meta/all.hpp b/include/modules/meta/all.hpp new file mode 100644 index 00000000..38e92b42 --- /dev/null +++ b/include/modules/meta/all.hpp @@ -0,0 +1,46 @@ +#pragma once + +/** + * Header file to include the headers for all modules. + */ + +#include "modules/backlight.hpp" +#include "modules/battery.hpp" +#include "modules/bspwm.hpp" +#include "modules/counter.hpp" +#include "modules/cpu.hpp" +#include "modules/date.hpp" +#include "modules/fs.hpp" +#include "modules/ipc.hpp" +#include "modules/memory.hpp" +#include "modules/menu.hpp" +#include "modules/meta/base.hpp" +#include "modules/script.hpp" +#include "modules/temperature.hpp" +#include "modules/text.hpp" +#include "modules/tray.hpp" +#include "modules/xbacklight.hpp" +#include "modules/xwindow.hpp" +#include "modules/xworkspaces.hpp" +#if ENABLE_I3 +#include "modules/i3.hpp" +#endif +#if ENABLE_MPD +#include "modules/mpd.hpp" +#endif +#if ENABLE_NETWORK +#include "modules/network.hpp" +#endif +#if ENABLE_ALSA +#include "modules/alsa.hpp" +#endif +#if ENABLE_PULSEAUDIO +#include "modules/pulseaudio.hpp" +#endif +#if ENABLE_CURL +#include "modules/github.hpp" +#endif +#if ENABLE_XKEYBOARD +#include "modules/xkeyboard.hpp" +#endif +#include "modules/unsupported.hpp" diff --git a/include/modules/meta/factory.hpp b/include/modules/meta/factory.hpp index 693320e9..0c3c96ba 100644 --- a/include/modules/meta/factory.hpp +++ b/include/modules/meta/factory.hpp @@ -1,115 +1,24 @@ #pragma once #include "common.hpp" -#include "modules/backlight.hpp" -#include "modules/battery.hpp" -#include "modules/bspwm.hpp" -#include "modules/counter.hpp" -#include "modules/cpu.hpp" -#include "modules/date.hpp" -#include "modules/fs.hpp" -#include "modules/ipc.hpp" -#include "modules/memory.hpp" -#include "modules/menu.hpp" +#include "components/logger.hpp" +#include "components/types.hpp" #include "modules/meta/base.hpp" -#include "modules/script.hpp" -#if DEBUG -#include "modules/systray.hpp" -#endif -#include "modules/temperature.hpp" -#include "modules/text.hpp" -#include "modules/tray.hpp" -#include "modules/xbacklight.hpp" -#include "modules/xwindow.hpp" -#include "modules/xworkspaces.hpp" -#if ENABLE_I3 -#include "modules/i3.hpp" -#endif -#if ENABLE_MPD -#include "modules/mpd.hpp" -#endif -#if ENABLE_NETWORK -#include "modules/network.hpp" -#endif -#if ENABLE_ALSA -#include "modules/alsa.hpp" -#endif -#if ENABLE_PULSEAUDIO -#include "modules/pulseaudio.hpp" -#endif -#if ENABLE_CURL -#include "modules/github.hpp" -#endif -#if ENABLE_XKEYBOARD -#include "modules/xkeyboard.hpp" -#endif -#include "modules/unsupported.hpp" POLYBAR_NS -using namespace modules; +namespace modules { + using module_t = shared_ptr; -namespace { - module_interface* make_module(string&& name, const bar_settings& bar, string module_name, const logger& m_log) { - if (name == counter_module::TYPE) { - return new counter_module(bar, move(module_name)); - } else if (name == backlight_module::TYPE) { - return new backlight_module(bar, move(module_name)); - } else if (name == battery_module::TYPE) { - return new battery_module(bar, move(module_name)); - } else if (name == bspwm_module::TYPE) { - return new bspwm_module(bar, move(module_name)); - } else if (name == cpu_module::TYPE) { - return new cpu_module(bar, move(module_name)); - } else if (name == date_module::TYPE) { - return new date_module(bar, move(module_name)); - } else if (name == github_module::TYPE) { - return new github_module(bar, move(module_name)); - } else if (name == fs_module::TYPE) { - return new fs_module(bar, move(module_name)); - } else if (name == memory_module::TYPE) { - return new memory_module(bar, move(module_name)); - } else if (name == i3_module::TYPE) { - return new i3_module(bar, move(module_name)); - } else if (name == mpd_module::TYPE) { - return new mpd_module(bar, move(module_name)); - } else if (name == "internal/volume") { - m_log.warn("internal/volume is deprecated, use %s instead", string(alsa_module::TYPE)); - return new alsa_module(bar, move(module_name)); - } else if (name == alsa_module::TYPE) { - return new alsa_module(bar, move(module_name)); - } else if (name == pulseaudio_module::TYPE) { - return new pulseaudio_module(bar, move(module_name)); - } else if (name == network_module::TYPE) { - return new network_module(bar, move(module_name)); -#if DEBUG - } else if (name == systray_module::TYPE) { - return new systray_module(bar, move(module_name)); -#endif - } else if (name == temperature_module::TYPE) { - return new temperature_module(bar, move(module_name)); - } else if (name == xbacklight_module::TYPE) { - return new xbacklight_module(bar, move(module_name)); - } else if (name == xkeyboard_module::TYPE) { - return new xkeyboard_module(bar, move(module_name)); - } else if (name == xwindow_module::TYPE) { - return new xwindow_module(bar, move(module_name)); - } else if (name == xworkspaces_module::TYPE) { - return new xworkspaces_module(bar, move(module_name)); - } else if (name == tray_module::TYPE) { - return new tray_module(bar, move(module_name)); - } else if (name == text_module::TYPE) { - return new text_module(bar, move(module_name)); - } else if (name == script_module::TYPE) { - return new script_module(bar, move(module_name)); - } else if (name == menu_module::TYPE) { - return new menu_module(bar, move(module_name)); - } else if (name == ipc_module::TYPE) { - return new ipc_module(bar, move(module_name)); - } else { - throw application_error("Unknown module: " + name); - } - } -} // namespace + /** + * Creates a new module instance. + * + * @param type The type of the module (as given by each module's TYPE field) + * @param bar An instance of the @ref bar_settings + * @param module_name The user-specified module name + * @param log A @ref logger instance + */ + module_t make_module(string&& type, const bar_settings& bar, string module_name, const logger& log); +} // namespace modules POLYBAR_NS_END diff --git a/include/modules/meta/inotify_module.hpp b/include/modules/meta/inotify_module.hpp index 06b165f7..fc226cc8 100644 --- a/include/modules/meta/inotify_module.hpp +++ b/include/modules/meta/inotify_module.hpp @@ -55,7 +55,6 @@ namespace modules { watches.back().attach(w.second); } } catch (const system_error& e) { - watches.clear(); this->m_log.err("%s: Error while creating inotify watch (what: %s)", this->name(), e.what()); CAST_MOD(Impl)->sleep(0.1s); return; @@ -67,11 +66,6 @@ namespace modules { if (w.poll(1000 / watches.size())) { auto event = w.get_event(); - - for (auto&& w : watches) { - w.remove(true); - } - if (CAST_MOD(Impl)->on_event(event)) { CAST_MOD(Impl)->broadcast(); } @@ -79,8 +73,9 @@ namespace modules { return; } - if (!this->running()) + if (!this->running()) { break; + } } CAST_MOD(Impl)->idle(); } diff --git a/include/modules/systray.hpp b/include/modules/systray.hpp deleted file mode 100644 index d58bffd5..00000000 --- a/include/modules/systray.hpp +++ /dev/null @@ -1,41 +0,0 @@ -#if DEBUG -#pragma once - -#include "modules/meta/static_module.hpp" - -POLYBAR_NS - -class connection; - -namespace modules { - /** - * Module used to display information about the - * currently active X window. - */ - class systray_module : public static_module { - public: - explicit systray_module(const bar_settings&, string); - - void update(); - bool build(builder* builder, const string& tag) const; - - static constexpr auto TYPE = "internal/systray"; - - static constexpr auto EVENT_TOGGLE = "toggle"; - - protected: - void action_toggle(); - - private: - static constexpr const char* TAG_LABEL_TOGGLE{""}; - static constexpr const char* TAG_TRAY_CLIENTS{""}; - - connection& m_connection; - label_t m_label; - - bool m_hidden{false}; - }; -} // namespace modules - -POLYBAR_NS_END -#endif diff --git a/include/utils/inotify.hpp b/include/utils/inotify.hpp index e2db3d0a..8722b606 100644 --- a/include/utils/inotify.hpp +++ b/include/utils/inotify.hpp @@ -6,6 +6,7 @@ #include #include "common.hpp" +#include "utils/mixins.hpp" POLYBAR_NS @@ -18,16 +19,19 @@ struct inotify_event { int mask = 0; }; -class inotify_watch { +class inotify_watch : public non_copyable_mixin { public: explicit inotify_watch(string path); ~inotify_watch(); + inotify_watch(inotify_watch&& other) noexcept; + inotify_watch& operator=(inotify_watch&& other) noexcept; + void attach(int mask = IN_MODIFY); void remove(bool force = false); bool poll(int wait_ms = 1000) const; inotify_event get_event() const; - const string path() const; + string path() const; int get_file_descriptor() const; protected: diff --git a/include/utils/mixins.hpp b/include/utils/mixins.hpp index f3d82590..1df342d2 100644 --- a/include/utils/mixins.hpp +++ b/include/utils/mixins.hpp @@ -13,8 +13,8 @@ class non_copyable_mixin { non_copyable_mixin& operator=(const non_copyable_mixin&) = delete; protected: - non_copyable_mixin() {} - ~non_copyable_mixin() {} + non_copyable_mixin() = default; + ~non_copyable_mixin() = default; }; /** @@ -26,8 +26,8 @@ class non_movable_mixin { non_movable_mixin& operator=(non_movable_mixin&&) = delete; protected: - non_movable_mixin() {} - ~non_movable_mixin() {} + non_movable_mixin() = default; + ~non_movable_mixin() = default; }; POLYBAR_NS_END diff --git a/include/x11/connection.hpp b/include/x11/connection.hpp index 4d7e0006..e554279c 100644 --- a/include/x11/connection.hpp +++ b/include/x11/connection.hpp @@ -43,8 +43,6 @@ namespace detail { m_root_window = screen_of_display(s)->root; } - virtual ~connection_base() {} - void operator()(const shared_ptr& error) const override { check(error); } diff --git a/include/x11/tray_manager.hpp b/include/x11/tray_manager.hpp index 9d3a7805..877dd470 100644 --- a/include/x11/tray_manager.hpp +++ b/include/x11/tray_manager.hpp @@ -23,8 +23,6 @@ #define SYSTEM_TRAY_BEGIN_MESSAGE 1 #define SYSTEM_TRAY_CANCEL_MESSAGE 2 -#define TRAY_PLACEHOLDER "" - POLYBAR_NS namespace chrono = std::chrono; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0f36aeb8..d879ae43 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -94,8 +94,8 @@ set(POLY_SOURCES ${src_dir}/modules/memory.cpp ${src_dir}/modules/menu.cpp ${src_dir}/modules/meta/base.cpp + ${src_dir}/modules/meta/factory.cpp ${src_dir}/modules/script.cpp - ${src_dir}/modules/systray.cpp ${src_dir}/modules/temperature.cpp ${src_dir}/modules/text.cpp ${src_dir}/modules/xbacklight.cpp diff --git a/src/components/bar.cpp b/src/components/bar.cpp index e060baaa..3a08e03f 100644 --- a/src/components/bar.cpp +++ b/src/components/bar.cpp @@ -695,12 +695,12 @@ void bar::handle(const evt::destroy_notify& evt) { */ void bar::handle(const evt::enter_notify&) { if (m_opts.dimmed) { - m_dim_timer.start(25, 0, [this]() { + m_dim_timer->start(25, 0, [this]() { m_opts.dimmed = false; m_sig.emit(dim_window{1.0}); }); - } else if (m_dim_timer.is_active()) { - m_dim_timer.stop(); + } else if (m_dim_timer->is_active()) { + m_dim_timer->stop(); } } @@ -714,7 +714,7 @@ void bar::handle(const evt::leave_notify&) { // Only trigger dimming, if the dim-value is not fully opaque. if (m_opts.dimvalue < 1.0) { if (!m_opts.dimmed) { - m_dim_timer.start(3000, 0, [this]() { + m_dim_timer->start(3000, 0, [this]() { m_opts.dimmed = true; m_sig.emit(dim_window{double(m_opts.dimvalue)}); }); @@ -823,11 +823,11 @@ void bar::handle(const evt::button_press& evt) { if (!has_dblclick) { trigger_click(btn, pos); } else if (btn == mousebtn::LEFT) { - check_double(m_leftclick_timer, btn, pos); + check_double(*m_leftclick_timer, btn, pos); } else if (btn == mousebtn::MIDDLE) { - check_double(m_middleclick_timer, btn, pos); + check_double(*m_middleclick_timer, btn, pos); } else if (btn == mousebtn::RIGHT) { - check_double(m_rightclick_timer, btn, pos); + check_double(*m_rightclick_timer, btn, pos); } else { trigger_click(btn, pos); } diff --git a/src/components/controller.cpp b/src/components/controller.cpp index 3b88addb..55f66ab3 100644 --- a/src/components/controller.cpp +++ b/src/components/controller.cpp @@ -11,6 +11,7 @@ #include "components/types.hpp" #include "events/signal.hpp" #include "events/signal_emitter.hpp" +#include "modules/meta/all.hpp" #include "modules/meta/base.hpp" #include "modules/meta/event_handler.hpp" #include "modules/meta/factory.hpp" @@ -25,6 +26,7 @@ POLYBAR_NS using namespace eventloop; +using namespace modules; /** * Build controller instance @@ -133,7 +135,7 @@ void controller::trigger_update(bool force) { } void controller::trigger_notification() { - m_notifier.send(); + m_notifier->send(); } void controller::stop(bool reload) { @@ -175,12 +177,12 @@ void controller::signal_handler(int signum) { } void controller::create_config_watcher(const string& filename) { - auto& fs_event_handler = m_loop.handle(); - fs_event_handler.start( + auto fs_event_handle = m_loop.handle(); + fs_event_handle->start( filename, 0, [this](const auto& e) { confwatch_handler(e.path); }, - [this, &fs_event_handler](const auto& e) { + [this, &handle = *fs_event_handle](const auto& e) { m_log.err("libuv error while watching included file for changes: %s", uv_strerror(e.status)); - fs_event_handler.close(); + handle.close(); }); } @@ -254,16 +256,16 @@ void controller::read_events(bool confwatch) { start_modules(); - auto& x_poll_handle = m_loop.handle(m_connection.get_file_descriptor()); - x_poll_handle.start( + auto x_poll_handle = m_loop.handle(m_connection.get_file_descriptor()); + x_poll_handle->start( UV_READABLE, [this](const auto&) { conn_cb(); }, [this](const auto& e) { m_log.err("libuv error while polling X connection: "s + uv_strerror(e.status)); stop(false); }); - auto& x_prepare_handle = m_loop.handle(); - x_prepare_handle.start([this]() { + auto x_prepare_handle = m_loop.handle(); + x_prepare_handle->start([this]() { /* * We have to also handle events in the prepare handle (which runs right * before polling for IO) to process any already queued X events which @@ -274,8 +276,8 @@ void controller::read_events(bool confwatch) { }); for (auto s : {SIGINT, SIGQUIT, SIGTERM, SIGUSR1, SIGALRM}) { - auto& signal_handle = m_loop.handle(); - signal_handle.start(s, [this](const auto& e) { signal_handler(e.signum); }); + auto signal_handle = m_loop.handle(); + signal_handle->start(s, [this](const auto& e) { signal_handler(e.signum); }); } if (confwatch) { @@ -288,8 +290,8 @@ void controller::read_events(bool confwatch) { if (!m_snapshot_dst.empty()) { // Trigger a single screenshot after 3 seconds - auto& timer_handle = m_loop.handle(); - timer_handle.start(3000, 0, [this]() { screenshot_handler(); }); + auto timer_handle = m_loop.handle(); + timer_handle->start(3000, 0, [this]() { screenshot_handler(); }); } /* @@ -628,9 +630,7 @@ size_t controller::setup_modules(alignment align) { } m_log.notice("Loading module '%s' of type '%s'", module_name, type); - auto ptr = make_module(move(type), m_bar->settings(), module_name, m_log); - module_t module = shared_ptr(ptr); - ptr = nullptr; + module_t module = modules::make_module(move(type), m_bar->settings(), module_name, m_log); m_modules.push_back(module); m_blocks[align].push_back(module); diff --git a/src/components/eventloop.cpp b/src/components/eventloop.cpp index e48f7029..42fd5c67 100644 --- a/src/components/eventloop.cpp +++ b/src/components/eventloop.cpp @@ -1,6 +1,7 @@ #include "components/eventloop.hpp" #include +#include #include "errors.hpp" @@ -46,15 +47,64 @@ namespace eventloop { } } + // WriteRequest {{{ + WriteRequest::WriteRequest(cb_write&& user_cb, cb_error&& err_cb) + : write_callback(std::move(user_cb)), write_err_cb(std::move(err_cb)) { + get()->data = this; + } + + WriteRequest& WriteRequest::create(cb_write&& user_cb, cb_error&& err_cb) { + auto r = std::make_unique(std::move(user_cb), std::move(err_cb)); + return r->leak(std::move(r)); + } + + uv_write_t* WriteRequest::get() { + return &req; + } + + void WriteRequest::trigger(int status) { + if (status < 0) { + if (write_err_cb) { + write_err_cb(ErrorEvent{status}); + } + } else { + if (write_callback) { + write_callback(); + } + } + + unleak(); + } + + WriteRequest& WriteRequest::leak(std::unique_ptr h) { + lifetime_extender = std::move(h); + return *lifetime_extender; + } + + void WriteRequest::unleak() { + reset_callbacks(); + lifetime_extender.reset(); + } + + void WriteRequest::reset_callbacks() { + write_callback = nullptr; + write_err_cb = nullptr; + } + // }}} + // SignalHandle {{{ void SignalHandle::init() { UV(uv_signal_init, loop(), get()); } - void SignalHandle::start(int signum, cb user_cb) { - this->callback = user_cb; + void SignalHandle::start(int signum, cb&& user_cb) { + this->callback = std::move(user_cb); UV(uv_signal_start, get(), event_cb, signum); } + + void SignalHandle::reset_callbacks() { + callback = nullptr; + } // }}} // PollHandle {{{ @@ -62,9 +112,9 @@ namespace eventloop { UV(uv_poll_init, loop(), get(), fd); } - void PollHandle::start(int events, cb user_cb, cb_error err_cb) { - this->callback = user_cb; - this->err_cb = err_cb; + void PollHandle::start(int events, cb&& user_cb, cb_error&& err_cb) { + this->callback = std::move(user_cb); + this->err_cb = std::move(err_cb); UV(uv_poll_start, get(), events, &poll_callback); } @@ -77,6 +127,11 @@ namespace eventloop { self.callback(PollEvent{(uv_poll_event)events}); } + + void PollHandle::reset_callbacks() { + callback = nullptr; + err_cb = nullptr; + } // }}} // FSEventHandle {{{ @@ -84,9 +139,9 @@ namespace eventloop { UV(uv_fs_event_init, loop(), get()); } - void FSEventHandle::start(const string& path, int flags, cb user_cb, cb_error err_cb) { - this->callback = user_cb; - this->err_cb = err_cb; + void FSEventHandle::start(const string& path, int flags, cb&& user_cb, cb_error&& err_cb) { + this->callback = std::move(user_cb); + this->err_cb = std::move(err_cb); UV(uv_fs_event_start, get(), fs_event_callback, path.c_str(), flags); } @@ -100,6 +155,10 @@ namespace eventloop { self.callback(FSEvent{path, (uv_fs_event)events}); } + void FSEventHandle::reset_callbacks() { + callback = nullptr; + err_cb = nullptr; + } // }}} // PipeHandle {{{ @@ -115,9 +174,9 @@ namespace eventloop { UV(uv_pipe_bind, get(), path.c_str()); } - void PipeHandle::connect(const string& name, cb_connect user_cb, cb_error err_cb) { - this->connect_callback = user_cb; - this->connect_err_cb = err_cb; + void PipeHandle::connect(const string& name, cb_connect&& user_cb, cb_error&& err_cb) { + this->connect_callback = std::move(user_cb); + this->connect_err_cb = std::move(err_cb); uv_pipe_connect(new uv_connect_t(), get(), name.c_str(), connect_cb); } @@ -132,6 +191,12 @@ namespace eventloop { delete req; } + + void PipeHandle::reset_callbacks() { + StreamHandle::reset_callbacks(); + connect_callback = nullptr; + connect_err_cb = nullptr; + } // }}} // TimerHandle {{{ @@ -139,25 +204,33 @@ namespace eventloop { UV(uv_timer_init, loop(), get()); } - void TimerHandle::start(uint64_t timeout, uint64_t repeat, cb user_cb) { - this->callback = user_cb; + void TimerHandle::start(uint64_t timeout, uint64_t repeat, cb&& user_cb) { + this->callback = std::move(user_cb); UV(uv_timer_start, get(), void_event_cb<&TimerHandle::callback>, timeout, repeat); } void TimerHandle::stop() { UV(uv_timer_stop, get()); } + + void TimerHandle::reset_callbacks() { + callback = nullptr; + } // }}} // AsyncHandle {{{ - void AsyncHandle::init(cb user_cb) { - this->callback = user_cb; + void AsyncHandle::init(cb&& user_cb) { + this->callback = std::move(user_cb); UV(uv_async_init, loop(), get(), void_event_cb<&AsyncHandle::callback>); } void AsyncHandle::send() { UV(uv_async_send, get()); } + + void AsyncHandle::reset_callbacks() { + callback = nullptr; + } // }}} // PrepareHandle {{{ @@ -165,10 +238,14 @@ namespace eventloop { UV(uv_prepare_init, loop(), get()); } - void PrepareHandle::start(cb user_cb) { - this->callback = user_cb; + void PrepareHandle::start(cb&& user_cb) { + this->callback = std::move(user_cb); UV(uv_prepare_start, get(), void_event_cb<&PrepareHandle::callback>); } + + void PrepareHandle::reset_callbacks() { + callback = nullptr; + } // }}} // eventloop {{{ diff --git a/src/drawtypes/iconset.cpp b/src/drawtypes/iconset.cpp index 55426eed..283be114 100644 --- a/src/drawtypes/iconset.cpp +++ b/src/drawtypes/iconset.cpp @@ -1,5 +1,7 @@ #include "drawtypes/iconset.hpp" +#include + POLYBAR_NS namespace drawtypes { @@ -20,11 +22,22 @@ namespace drawtypes { // If fuzzy matching is turned on, try that first before returning the fallback. if (fuzzy_match) { + // works by finding the *longest* matching icon to the given workspace id + size_t max_size = -1; + label_t max_label; + for (auto const& icon : m_icons) { if (id.find(icon.first) != std::string::npos) { - return icon.second; + if (icon.first.length() > max_size || !max_label) { + max_size = icon.first.length(); + max_label = icon.second; + } } } + + if (max_label) { + return max_label; + } } return m_icons.find(fallback_id)->second; @@ -33,6 +46,6 @@ namespace drawtypes { iconset::operator bool() { return !m_icons.empty(); } -} // namespace drawtypes +} // namespace drawtypes POLYBAR_NS_END diff --git a/src/ipc/ipc.cpp b/src/ipc/ipc.cpp index 66506f15..191a6a5f 100644 --- a/src/ipc/ipc.cpp +++ b/src/ipc/ipc.cpp @@ -57,12 +57,12 @@ namespace ipc { m_log.info("Opening ipc socket at '%s'", sock_path); m_log.notice("Listening for IPC messages (PID: %d)", getpid()); - socket.bind(sock_path); - socket.listen( + socket->bind(sock_path); + socket->listen( 4, [this]() { on_connection(); }, [this](const auto& e) { m_log.err("libuv error while listening to IPC socket: %s", uv_strerror(e.status)); - socket.close(); + socket->close(); }); } @@ -124,7 +124,7 @@ namespace ipc { } else { response = encode(TYPE_ERR, "Unrecognized IPC message type " + to_string(type)); } - c.client_pipe.write( + c.client_pipe->write( response, [this, &c]() { remove_client(c); }, [this, &c](const auto& e) { m_log.err("ipc: libuv error while writing to IPC socket: %s", uv_strerror(e.status)); @@ -133,16 +133,16 @@ namespace ipc { }); auto& c = *connection; - socket.accept(c.client_pipe); + socket->accept(*c.client_pipe); - c.client_pipe.read_start( + c.client_pipe->read_start( [this, &c](const auto& e) { try { c.dec.on_read((const uint8_t*)e.data, e.len); } catch (const decoder::error& e) { m_log.err("ipc: Failed to decode IPC message (reason: %s)", e.what()); - c.client_pipe.write( + c.client_pipe->write( encode(TYPE_ERR, "Invalid binary message format: "s + e.what()), [this, &c]() { remove_client(c); }, [this, &c](const auto& e) { m_log.err("ipc: libuv error while writing to IPC socket: %s", uv_strerror(e.status)); @@ -171,7 +171,7 @@ namespace ipc { }) {} ipc::connection::~connection() { - client_pipe.close(); + client_pipe->close(); } ipc::fifo::fifo(loop& loop, ipc& ipc, const string& path) : pipe_handle(loop.handle()) { @@ -180,8 +180,8 @@ namespace ipc { throw system_error("Failed to open pipe '" + path + "'"); } - pipe_handle.open(fd); - pipe_handle.read_start([&ipc](const auto& e) mutable { ipc.receive_data(string(e.data, e.len)); }, + pipe_handle->open(fd); + pipe_handle->read_start([&ipc](const auto& e) mutable { ipc.receive_data(string(e.data, e.len)); }, [&ipc]() { ipc.receive_eof(); }, [&ipc](const auto& e) mutable { ipc.m_log.err("libuv error while listening to IPC channel: %s", uv_strerror(e.status)); @@ -190,7 +190,7 @@ namespace ipc { } ipc::fifo::~fifo() { - pipe_handle.close(); + pipe_handle->close(); } /** @@ -215,6 +215,6 @@ namespace ipc { trigger_legacy_ipc(string_util::trim(std::move(m_pipe_buffer), '\n')); m_pipe_buffer.clear(); } -} // namespace ipc +} // namespace ipc POLYBAR_NS_END diff --git a/src/modules/backlight.cpp b/src/modules/backlight.cpp index 4e4c47da..abdcd8e4 100644 --- a/src/modules/backlight.cpp +++ b/src/modules/backlight.cpp @@ -70,13 +70,7 @@ namespace modules { // Build path to the sysfs folder the current/maximum brightness values are located m_path_backlight = string_util::replace(PATH_BACKLIGHT, "%card%", card); - /* - * amdgpu drivers set the actual_brightness in a different scale than [0, max_brightness] - * The only sensible way is to use the 'brightness' file instead - * Ref: https://github.com/Alexays/Waybar/issues/335 - */ - bool card_is_amdgpu = (card.substr(0, 9) == "amdgpu_bl"); - m_use_actual_brightness = m_conf.get(name(), "use-actual-brightness", !card_is_amdgpu); + m_use_actual_brightness = m_conf.get(name(), "use-actual-brightness", m_use_actual_brightness); std::string brightness_type = (m_use_actual_brightness ? "actual_brightness" : "brightness"); auto path_backlight_val = m_path_backlight + "/" + brightness_type; diff --git a/src/modules/ipc.cpp b/src/modules/ipc.cpp index b8627036..41ee3fea 100644 --- a/src/modules/ipc.cpp +++ b/src/modules/ipc.cpp @@ -59,8 +59,12 @@ namespace modules { for (auto& hook : m_hooks) { hook->command = pid_token(hook->command); } - m_formatter->add(DEFAULT_FORMAT, TAG_OUTPUT, {TAG_OUTPUT}); + + for (size_t i = 0; i < m_hooks.size(); i++) { + string format_i = "format-" + to_string(i); + m_formatter->add_optional(format_i, {TAG_OUTPUT}); + } } /** @@ -103,6 +107,17 @@ namespace modules { return m_builder->flush(); } + string ipc_module::get_format() const { + if (m_current_hook != -1 && (size_t)m_current_hook < m_hooks.size()) { + string format_i = "format-" + to_string(m_current_hook); + if (m_formatter->has_format(format_i)) { + return format_i; + } else { + return DEFAULT_FORMAT; + } + } + return DEFAULT_FORMAT; + } /** * Output content retrieved from hook commands */ @@ -150,7 +165,8 @@ namespace modules { } } catch (const std::invalid_argument& err) { m_log.err( - "%s: Hook action received '%s' cannot be converted to a valid hook index. Defined hooks goes from 0 to %zu.", + "%s: Hook action received '%s' cannot be converted to a valid hook index. Defined hooks goes from 0 to " + "%zu.", name(), data, m_hooks.size() - 1); } } diff --git a/src/modules/meta/factory.cpp b/src/modules/meta/factory.cpp new file mode 100644 index 00000000..07a52710 --- /dev/null +++ b/src/modules/meta/factory.cpp @@ -0,0 +1,86 @@ +#include "modules/meta/factory.hpp" + +#include "modules/meta/all.hpp" + +POLYBAR_NS + +namespace modules { + + /** + * Function pointer for creating a module. + */ + using factory_fun = module_t (*)(const bar_settings&, string&&); + using factory_map = map; + + /** + * Creates a factory function for constructing a module. + * + * @tparam M name of the module class + */ + template + static constexpr factory_fun get_factory() { + return [](const bar_settings& bar, string&& module_name) -> module_t { + return make_shared(bar, move(module_name)); + }; + } + + /** + * Creates an entry for the factories map. + * + * Each entry is a pair containing the module type and the factory function. + * + * @tparam M name of the module class + */ + template + static factory_map::value_type map_entry() { + return std::make_pair(std::string(M::TYPE), get_factory()); + } + + /** + * Factory function for each module type. + */ + static const factory_map factories = { + map_entry(), + map_entry(), + map_entry(), + map_entry(), + map_entry(), + map_entry(), + map_entry(), + map_entry(), + map_entry(), + map_entry(), + map_entry(), + map_entry(), + map_entry(), + map_entry(), + map_entry(), + map_entry(), + map_entry(), + map_entry(), + map_entry(), + map_entry(), + map_entry(), + map_entry(), + map_entry(), + map_entry(), + }; + + module_t make_module(string&& type, const bar_settings& bar, string module_name, const logger& log) { + string actual_type = type; + + if (type == "internal/volume") { + log.warn("internal/volume is deprecated, use %s instead", string(alsa_module::TYPE)); + actual_type = alsa_module::TYPE; + } + + auto it = factories.find(actual_type); + if (it != factories.end()) { + return it->second(bar, std::move(module_name)); + } else { + throw application_error("Unknown module: " + type); + } + } +} // namespace modules + +POLYBAR_NS_END diff --git a/src/modules/systray.cpp b/src/modules/systray.cpp deleted file mode 100644 index 6ffa732f..00000000 --- a/src/modules/systray.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#if DEBUG -#include "modules/systray.hpp" - -#include "drawtypes/label.hpp" -#include "modules/meta/base.inl" -#include "x11/connection.hpp" -#include "x11/tray_manager.hpp" - -POLYBAR_NS - -namespace modules { - template class module; - - /** - * Construct module - */ - systray_module::systray_module(const bar_settings& bar, string name_) - : static_module(bar, move(name_)), m_connection(connection::make()) { - m_router->register_action(EVENT_TOGGLE, [this]() { action_toggle(); }); - - // Add formats and elements - m_formatter->add(DEFAULT_FORMAT, TAG_LABEL_TOGGLE, {TAG_LABEL_TOGGLE, TAG_TRAY_CLIENTS}); - - if (m_formatter->has(TAG_LABEL_TOGGLE)) { - m_label = load_label(m_conf, name(), TAG_LABEL_TOGGLE); - } - } - - /** - * Update - */ - void systray_module::update() { - if (m_label) { - m_label->reset_tokens(); - m_label->replace_token("%title%", ""); - } - - broadcast(); - } - - /** - * Build output - */ - bool systray_module::build(builder* builder, const string& tag) const { - if (tag == TAG_LABEL_TOGGLE) { - builder->action(mousebtn::LEFT, *this, EVENT_TOGGLE, "", m_label); - } else if (tag == TAG_TRAY_CLIENTS && !m_hidden) { - builder->node(TRAY_PLACEHOLDER); - } else { - return false; - } - return true; - } - - /** - * Handle input event - */ - void systray_module::action_toggle() { - m_hidden = !m_hidden; - broadcast(); - } -} // namespace modules - -POLYBAR_NS_END -#endif diff --git a/src/polybar-msg.cpp b/src/polybar-msg.cpp index f1a9c127..7cc5d81a 100644 --- a/src/polybar-msg.cpp +++ b/src/polybar-msg.cpp @@ -262,11 +262,11 @@ int run(int argc, char** argv) { */ int idx = decoders.size() - 1; - auto& conn = loop.handle(); - conn.connect( + auto conn = loop.handle(); + conn->connect( channel, [&conn, &decoders, pid, type, payload, channel, idx]() { - on_connection(conn, decoders[idx], pid, type, payload); + on_connection(*conn, decoders[idx], pid, type, payload); }, [&](const auto& e) { fprintf(stderr, "%s: Failed to connect to '%s' (err: '%s')\n", exec, channel.c_str(), uv_strerror(e.status)); diff --git a/src/utils/inotify.cpp b/src/utils/inotify.cpp index ccd75a9e..6445149b 100644 --- a/src/utils/inotify.cpp +++ b/src/utils/inotify.cpp @@ -24,6 +24,21 @@ inotify_watch::~inotify_watch() { } } +inotify_watch::inotify_watch(inotify_watch&& other) noexcept { + std::swap(m_path, other.m_path); + std::swap(m_wd, other.m_wd); + std::swap(m_fd, other.m_fd); + std::swap(m_mask, other.m_mask); +} + +inotify_watch& inotify_watch::operator=(inotify_watch&& other) noexcept { + std::swap(m_path, other.m_path); + std::swap(m_wd, other.m_wd); + std::swap(m_fd, other.m_fd); + std::swap(m_mask, other.m_mask); + return *this; +} + /** * Attach inotify watch */ @@ -101,7 +116,7 @@ inotify_event inotify_watch::get_event() const { /** * Get watch file path */ -const string inotify_watch::path() const { +string inotify_watch::path() const { return m_path; } diff --git a/tests/unit_tests/drawtypes/iconset.cpp b/tests/unit_tests/drawtypes/iconset.cpp index 8cc53d24..31a0e5d8 100644 --- a/tests/unit_tests/drawtypes/iconset.cpp +++ b/tests/unit_tests/drawtypes/iconset.cpp @@ -16,3 +16,26 @@ TEST(IconSet, fuzzyMatchExactMatchFirst) { EXPECT_EQ("10", ret->get()); } + +TEST(IconSet, fuzzyMatchLargestSubstring) { + iconset_t icons = make_shared(); + + icons->add("1", make_shared