Comprehensive refactor of the cava module backend and frontends. Style & naming - Rename Cava -> CavaRaw; snake_case methods -> lowerCamelCase - Replace NULL with nullptr; replace C-style casts with static_cast - Add explicit standard-library includes (<memory>, <string>, <chrono>) - Fix missing trailing underscores on member variables Architecture - Remove Gtk::GLArea multiple inheritance in CavaGLSL (composition) - Return std::unique_ptr from factory; add doAction() to GLSL variant - Encapsulate thread timing arithmetic in AdaptiveDelay struct Thread safety & correctness - Replace raw sigc::signal with SafeSignal for cross-thread marshalling - Fix data race between loadConfig() and out_thread_ (recursive_mutex) - Fix audio_raw shallow-copy use-after-free via deep-copy AudioRaw payload - Make loadConfig() exception-safe with CavaConfigGuard RAII - Fix blocking read_thread_ race on shutdown (condition_variable + timeout join) - Fix isSilent() data race (acquire pthread mutex) - Eliminate doUpdate() recursion (iteration instead) - Guard audio_raw_clean() against uninitialized state - Fix format-icons underflow and cava_config buffer overflow - Store config by value to prevent dangling references on reload - Cache frontend config and refresh on runtime changes - Fix signed-char icon lookup bug on x86 - Prevent Json::Value mutation bloat via const-ref lookups - Broaden exception catches in worker threads (std::exception) Resource management & GL robustness - Fix OpenGL resource leaks (persist VBO/IBO/VAO; explicit destructor cleanup) - Fix shader error handling crashes (valid infoLog allocation) - Cache uniform locations instead of querying per frame - Fix gradient color uninitialized stack memory (zero-init + clamped count) - Fix shader time uniform integer division bug (float arithmetic) - Add explicit VAO bind in onRender() - Handle runtime surface config changes independently of shader changes - Clamp negative gradient_count before GL upload Follow-up - Singleton API split (inst() + configure()) intentionally deferred to a dedicated PR because it changes the public constructor contract.
80 lines
2.0 KiB
C++
80 lines
2.0 KiB
C++
#pragma once
|
|
|
|
#include <epoxy/gl.h>
|
|
#include <gtkmm/glarea.h>
|
|
#include <map>
|
|
#include <string>
|
|
#include <array>
|
|
|
|
#include <sigc++/connection.h>
|
|
|
|
#include "AModule.hpp"
|
|
#include "cava_backend.hpp"
|
|
|
|
namespace waybar::modules::cava {
|
|
|
|
class CavaGLSL final : public AModule {
|
|
public:
|
|
CavaGLSL(const std::string&, const Json::Value&);
|
|
~CavaGLSL();
|
|
auto doAction(const std::string& name) -> void override;
|
|
|
|
private:
|
|
using Action = void (CavaGLSL::*)();
|
|
|
|
Gtk::GLArea gl_area_;
|
|
std::shared_ptr<CavaBackend> backend_;
|
|
// Cached config params (deep-copied strings to avoid dangling char* on backend reload)
|
|
int sdl_width_{0};
|
|
int sdl_height_{0};
|
|
int bar_width_{0};
|
|
int bar_spacing_{0};
|
|
int gradient_count_{0};
|
|
std::string vertex_shader_;
|
|
std::string fragment_shader_;
|
|
std::string bcolor_;
|
|
std::string color_;
|
|
std::array<std::string, 8> gradient_colors_;
|
|
int frame_counter_{0};
|
|
bool silence_{false};
|
|
bool hide_on_silence_{false};
|
|
bool mapped_{false};
|
|
// Cava method
|
|
void pauseResume();
|
|
auto onUpdate(const CavaBackend::AudioRaw& input) -> void;
|
|
auto onSilence() -> void;
|
|
auto onBackendConfigChanged() -> void;
|
|
void cacheConfigParams(const ::cava::config_params& src);
|
|
// Member variable to store audio data
|
|
CavaBackend::AudioRaw m_data_;
|
|
GLuint shaderProgram_{0};
|
|
// OpenGL variables
|
|
GLuint fbo_{0};
|
|
GLuint texture_{0};
|
|
GLuint vbo_{0};
|
|
GLuint ibo_{0};
|
|
GLuint vao_{0};
|
|
GLint uniform_bars_;
|
|
GLint uniform_previous_bars_;
|
|
GLint uniform_bars_count_;
|
|
GLint uniform_time_;
|
|
GLint uniform_input_texture_;
|
|
// Methods
|
|
void onRealize();
|
|
bool onRender(const Glib::RefPtr<Gdk::GLContext>& context);
|
|
|
|
void initShaders();
|
|
void initSurface();
|
|
void initGLSL();
|
|
GLuint loadShader(const std::string& fileName, GLenum type);
|
|
void cleanupGL();
|
|
|
|
// ModuleActionMap
|
|
static const std::map<std::string, Action> actionMap_;
|
|
|
|
sigc::connection audio_raw_update_conn_;
|
|
sigc::connection silence_conn_;
|
|
sigc::connection config_changed_conn_;
|
|
};
|
|
} // namespace waybar::modules::cava
|