Merge pull request #4898 from khaneliman/memory

perf(memory): optimize string operations; remove deep copies, memdup, and icon theme rescanning
This commit is contained in:
Alexis Rouillard
2026-03-04 22:40:55 +01:00
committed by GitHub
33 changed files with 75 additions and 69 deletions

Binary file not shown.

View File

@@ -22,7 +22,7 @@ class Disk : public ALabel {
std::string path_; std::string path_;
std::string unit_; std::string unit_;
float calc_specific_divisor(const std::string divisor); float calc_specific_divisor(const std::string& divisor);
}; };
} // namespace waybar::modules } // namespace waybar::modules

View File

@@ -40,10 +40,11 @@ struct WindowRepr {
class WindowCreationPayload { class WindowCreationPayload {
public: public:
WindowCreationPayload(std::string workspace_name, WindowAddress window_address, WindowCreationPayload(const std::string& workspace_name, WindowAddress window_address,
WindowRepr window_repr); WindowRepr window_repr);
WindowCreationPayload(std::string workspace_name, WindowAddress window_address, WindowCreationPayload(const std::string& workspace_name, WindowAddress window_address,
std::string window_class, std::string window_title, bool is_active); const std::string& window_class, const std::string& window_title,
bool is_active);
WindowCreationPayload(Json::Value const& client_data); WindowCreationPayload(Json::Value const& client_data);
int incrementTimeSpentUncreated(); int incrementTimeSpentUncreated();

View File

@@ -59,7 +59,7 @@ class Workspaces : public AModule, public EventHandler {
enum class ActiveWindowPosition { NONE, FIRST, LAST }; enum class ActiveWindowPosition { NONE, FIRST, LAST };
auto activeWindowPosition() const -> ActiveWindowPosition { return m_activeWindowPosition; } auto activeWindowPosition() const -> ActiveWindowPosition { return m_activeWindowPosition; }
std::string getRewrite(std::string window_class, std::string window_title); std::string getRewrite(const std::string& window_class, const std::string& window_title);
std::string& getWindowSeparator() { return m_formatWindowSeparator; } std::string& getWindowSeparator() { return m_formatWindowSeparator; }
bool isWorkspaceIgnored(std::string const& workspace_name); bool isWorkspaceIgnored(std::string const& workspace_name);

View File

@@ -44,7 +44,7 @@ class MPD : public ALabel {
std::string getFilename() const; std::string getFilename() const;
void setLabel(); void setLabel();
std::string getStateIcon() const; std::string getStateIcon() const;
std::string getOptionIcon(std::string optionName, bool activated) const; std::string getOptionIcon(const std::string& optionName, bool activated) const;
// GUI-side methods // GUI-side methods
bool handlePlayPause(GdkEventButton* const&); bool handlePlayPause(GdkEventButton* const&);

View File

@@ -30,7 +30,7 @@ class Host {
static void itemUnregistered(SnWatcher*, const gchar*, gpointer); static void itemUnregistered(SnWatcher*, const gchar*, gpointer);
std::tuple<std::string, std::string> getBusNameAndObjectPath(const std::string); std::tuple<std::string, std::string> getBusNameAndObjectPath(const std::string);
void addRegisteredItem(std::string service); void addRegisteredItem(const std::string& service);
std::vector<std::unique_ptr<Item>> items_; std::vector<std::unique_ptr<Item>> items_;
const std::string bus_name_; const std::string bus_name_;

View File

@@ -37,7 +37,7 @@ class BarIpcClient {
void onModeUpdate(bool visible_by_modifier); void onModeUpdate(bool visible_by_modifier);
void onUrgencyUpdate(bool visible_by_urgency); void onUrgencyUpdate(bool visible_by_urgency);
void update(); void update();
bool isModuleEnabled(std::string name); bool isModuleEnabled(const std::string& name);
Bar& bar_; Bar& bar_;
util::JsonParser parser_; util::JsonParser parser_;

View File

@@ -47,7 +47,7 @@ class Language : public ALabel, public sigc::trackable {
void onEvent(const struct Ipc::ipc_response&); void onEvent(const struct Ipc::ipc_response&);
void onCmd(const struct Ipc::ipc_response&); void onCmd(const struct Ipc::ipc_response&);
auto set_current_layout(std::string current_layout) -> void; auto set_current_layout(const std::string& current_layout) -> void;
auto init_layouts_map(const std::vector<std::string>& used_layouts) -> void; auto init_layouts_map(const std::vector<std::string>& used_layouts) -> void;
const static std::string XKB_LAYOUT_NAMES_KEY; const static std::string XKB_LAYOUT_NAMES_KEY;

View File

@@ -27,7 +27,7 @@ class Workspaces : public AModule, public sigc::trackable {
static constexpr std::string_view persistent_workspace_switch_cmd_ = static constexpr std::string_view persistent_workspace_switch_cmd_ =
R"(workspace {} "{}"; move workspace to output "{}"; workspace {} "{}")"; R"(workspace {} "{}"; move workspace to output "{}"; workspace {} "{}")";
static int convertWorkspaceNameToNum(std::string name); static int convertWorkspaceNameToNum(const std::string& name);
static int windowRewritePriorityFunction(std::string const& window_rule); static int windowRewritePriorityFunction(std::string const& window_rule);
void onCmd(const struct Ipc::ipc_response&); void onCmd(const struct Ipc::ipc_response&);
@@ -40,7 +40,7 @@ class Workspaces : public AModule, public sigc::trackable {
std::string getIcon(const std::string&, const Json::Value&); std::string getIcon(const std::string&, const Json::Value&);
std::string getCycleWorkspace(std::vector<Json::Value>::iterator, bool prev) const; std::string getCycleWorkspace(std::vector<Json::Value>::iterator, bool prev) const;
uint16_t getWorkspaceIndex(const std::string& name) const; uint16_t getWorkspaceIndex(const std::string& name) const;
static std::string trimWorkspaceName(std::string); static std::string trimWorkspaceName(const std::string&);
bool handleScroll(GdkEventScroll* /*unused*/) override; bool handleScroll(GdkEventScroll* /*unused*/) override;
const Bar& bar_; const Bar& bar_;

View File

@@ -3,10 +3,10 @@
#include <glibmm/dispatcher.h> #include <glibmm/dispatcher.h>
#include <sigc++/signal.h> #include <sigc++/signal.h>
#include <cstddef>
#include <functional> #include <functional>
#include <mutex> #include <mutex>
#include <queue> #include <queue>
#include <cstddef>
#include <thread> #include <thread>
#include <tuple> #include <tuple>
#include <type_traits> #include <type_traits>

View File

@@ -72,8 +72,7 @@ class SleeperThread {
std::unique_lock lk(mutex_); std::unique_lock lk(mutex_);
CancellationGuard cancel_lock; CancellationGuard cancel_lock;
return condvar_.wait(lk, [this] { return condvar_.wait(lk, [this] {
return signal_.load(std::memory_order_relaxed) || return signal_.load(std::memory_order_relaxed) || !do_run_.load(std::memory_order_relaxed);
!do_run_.load(std::memory_order_relaxed);
}); });
} }
@@ -87,8 +86,7 @@ class SleeperThread {
wait_end = now + dur; wait_end = now + dur;
} }
return condvar_.wait_until(lk, wait_end, [this] { return condvar_.wait_until(lk, wait_end, [this] {
return signal_.load(std::memory_order_relaxed) || return signal_.load(std::memory_order_relaxed) || !do_run_.load(std::memory_order_relaxed);
!do_run_.load(std::memory_order_relaxed);
}); });
} }
@@ -98,8 +96,7 @@ class SleeperThread {
std::unique_lock lk(mutex_); std::unique_lock lk(mutex_);
CancellationGuard cancel_lock; CancellationGuard cancel_lock;
return condvar_.wait_until(lk, time_point, [this] { return condvar_.wait_until(lk, time_point, [this] {
return signal_.load(std::memory_order_relaxed) || return signal_.load(std::memory_order_relaxed) || !do_run_.load(std::memory_order_relaxed);
!do_run_.load(std::memory_order_relaxed);
}); });
} }

View File

@@ -71,6 +71,7 @@ CFFI::CFFI(const std::string& name, const std::string& id, const Json::Value& co
// Prepare config_entries array // Prepare config_entries array
std::vector<ffi::wbcffi_config_entry> config_entries; std::vector<ffi::wbcffi_config_entry> config_entries;
config_entries.reserve(keys.size());
for (size_t i = 0; i < keys.size(); i++) { for (size_t i = 0; i < keys.size(); i++) {
config_entries.push_back({keys[i].c_str(), config_entries_stringstor[i].c_str()}); config_entries.push_back({keys[i].c_str(), config_entries_stringstor[i].c_str()});
} }

View File

@@ -26,7 +26,7 @@ std::vector<float> waybar::modules::CpuFrequency::parseCpuFrequencies() {
if (std::filesystem::exists(cpufreq_dir)) { if (std::filesystem::exists(cpufreq_dir)) {
std::vector<std::string> frequency_files = {"/cpuinfo_min_freq", "/cpuinfo_max_freq"}; std::vector<std::string> frequency_files = {"/cpuinfo_min_freq", "/cpuinfo_max_freq"};
for (auto& p : std::filesystem::directory_iterator(cpufreq_dir)) { for (auto& p : std::filesystem::directory_iterator(cpufreq_dir)) {
for (auto freq_file : frequency_files) { for (const auto& freq_file : frequency_files) {
std::string freq_file_path = p.path().string() + freq_file; std::string freq_file_path = p.path().string() + freq_file;
if (std::filesystem::exists(freq_file_path)) { if (std::filesystem::exists(freq_file_path)) {
std::string freq_value; std::string freq_value;

View File

@@ -92,7 +92,7 @@ auto waybar::modules::Disk::update() -> void {
ALabel::update(); ALabel::update();
} }
float waybar::modules::Disk::calc_specific_divisor(std::string divisor) { float waybar::modules::Disk::calc_specific_divisor(const std::string& divisor) {
if (divisor == "kB") { if (divisor == "kB") {
return 1000.0; return 1000.0;
} else if (divisor == "kiB") { } else if (divisor == "kiB") {

View File

@@ -124,7 +124,7 @@ auto Window::getActiveWorkspace(const std::string& monitorName) -> Workspace {
const auto monitors = IPC::inst().getSocket1JsonReply("monitors"); const auto monitors = IPC::inst().getSocket1JsonReply("monitors");
if (monitors.isArray()) { if (monitors.isArray()) {
auto monitor = std::ranges::find_if( auto monitor = std::ranges::find_if(
monitors, [&](Json::Value monitor) { return monitor["name"] == monitorName; }); monitors, [&](const Json::Value& monitor) { return monitor["name"] == monitorName; });
if (monitor == std::end(monitors)) { if (monitor == std::end(monitors)) {
spdlog::warn("Monitor not found: {}", monitorName); spdlog::warn("Monitor not found: {}", monitorName);
return Workspace{ return Workspace{
@@ -139,7 +139,7 @@ auto Window::getActiveWorkspace(const std::string& monitorName) -> Workspace {
const auto workspaces = IPC::inst().getSocket1JsonReply("workspaces"); const auto workspaces = IPC::inst().getSocket1JsonReply("workspaces");
if (workspaces.isArray()) { if (workspaces.isArray()) {
auto workspace = std::ranges::find_if( auto workspace = std::ranges::find_if(
workspaces, [&](Json::Value workspace) { return workspace["id"] == id; }); workspaces, [&](const Json::Value& workspace) { return workspace["id"] == id; });
if (workspace == std::end(workspaces)) { if (workspace == std::end(workspaces)) {
spdlog::warn("No workspace with id {}", id); spdlog::warn("No workspace with id {}", id);
return Workspace{ return Workspace{
@@ -190,7 +190,7 @@ void Window::queryActiveWorkspace() {
const auto clients = m_ipc.getSocket1JsonReply("clients"); const auto clients = m_ipc.getSocket1JsonReply("clients");
if (clients.isArray()) { if (clients.isArray()) {
auto activeWindow = std::ranges::find_if( auto activeWindow = std::ranges::find_if(
clients, [&](Json::Value window) { return window["address"] == workspace_.last_window; }); clients, [&](const Json::Value& window) { return window["address"] == workspace_.last_window; });
if (activeWindow == std::end(clients)) { if (activeWindow == std::end(clients)) {
focused_ = false; focused_ = false;
@@ -200,19 +200,19 @@ void Window::queryActiveWorkspace() {
windowData_ = WindowData::parse(*activeWindow); windowData_ = WindowData::parse(*activeWindow);
updateAppIconName(windowData_.class_name, windowData_.initial_class_name); updateAppIconName(windowData_.class_name, windowData_.initial_class_name);
std::vector<Json::Value> workspaceWindows; std::vector<Json::Value> workspaceWindows;
std::ranges::copy_if(clients, std::back_inserter(workspaceWindows), [&](Json::Value window) { std::ranges::copy_if(clients, std::back_inserter(workspaceWindows), [&](const Json::Value& window) {
return window["workspace"]["id"] == workspace_.id && window["mapped"].asBool(); return window["workspace"]["id"] == workspace_.id && window["mapped"].asBool();
}); });
swallowing_ = std::ranges::any_of(workspaceWindows, [&](Json::Value window) { swallowing_ = std::ranges::any_of(workspaceWindows, [&](const Json::Value& window) {
return !window["swallowing"].isNull() && window["swallowing"].asString() != "0x0"; return !window["swallowing"].isNull() && window["swallowing"].asString() != "0x0";
}); });
std::vector<Json::Value> visibleWindows; std::vector<Json::Value> visibleWindows;
std::ranges::copy_if(workspaceWindows, std::back_inserter(visibleWindows), std::ranges::copy_if(workspaceWindows, std::back_inserter(visibleWindows),
[&](Json::Value window) { return !window["hidden"].asBool(); }); [&](const Json::Value& window) { return !window["hidden"].asBool(); });
solo_ = 1 == std::count_if(visibleWindows.begin(), visibleWindows.end(), solo_ = 1 == std::count_if(visibleWindows.begin(), visibleWindows.end(),
[&](Json::Value window) { return !window["floating"].asBool(); }); [&](const Json::Value& window) { return !window["floating"].asBool(); });
allFloating_ = std::ranges::all_of( allFloating_ = std::ranges::all_of(
visibleWindows, [&](Json::Value window) { return window["floating"].asBool(); }); visibleWindows, [&](const Json::Value& window) { return window["floating"].asBool(); });
fullscreen_ = windowData_.fullscreen; fullscreen_ = windowData_.fullscreen;
// Fullscreen windows look like they are solo // Fullscreen windows look like they are solo

View File

@@ -79,7 +79,7 @@ auto WindowCount::getActiveWorkspace(const std::string& monitorName) -> Workspac
const auto monitors = m_ipc.getSocket1JsonReply("monitors"); const auto monitors = m_ipc.getSocket1JsonReply("monitors");
if (monitors.isArray()) { if (monitors.isArray()) {
auto monitor = std::ranges::find_if( auto monitor = std::ranges::find_if(
monitors, [&](Json::Value monitor) { return monitor["name"] == monitorName; }); monitors, [&](const Json::Value& monitor) { return monitor["name"] == monitorName; });
if (monitor == std::end(monitors)) { if (monitor == std::end(monitors)) {
spdlog::warn("Monitor not found: {}", monitorName); spdlog::warn("Monitor not found: {}", monitorName);
return Workspace{ return Workspace{
@@ -93,7 +93,7 @@ auto WindowCount::getActiveWorkspace(const std::string& monitorName) -> Workspac
const auto workspaces = m_ipc.getSocket1JsonReply("workspaces"); const auto workspaces = m_ipc.getSocket1JsonReply("workspaces");
if (workspaces.isArray()) { if (workspaces.isArray()) {
auto workspace = std::ranges::find_if( auto workspace = std::ranges::find_if(
workspaces, [&](Json::Value workspace) { return workspace["id"] == id; }); workspaces, [&](const Json::Value& workspace) { return workspace["id"] == id; });
if (workspace == std::end(workspaces)) { if (workspace == std::end(workspaces)) {
spdlog::warn("No workspace with id {}", id); spdlog::warn("No workspace with id {}", id);
return Workspace{ return Workspace{

View File

@@ -19,7 +19,7 @@ WindowCreationPayload::WindowCreationPayload(Json::Value const& client_data)
clearWorkspaceName(); clearWorkspaceName();
} }
WindowCreationPayload::WindowCreationPayload(std::string workspace_name, WindowCreationPayload::WindowCreationPayload(const std::string& workspace_name,
WindowAddress window_address, WindowRepr window_repr) WindowAddress window_address, WindowRepr window_repr)
: m_window(std::move(window_repr)), : m_window(std::move(window_repr)),
m_windowAddress(std::move(window_address)), m_windowAddress(std::move(window_address)),
@@ -28,9 +28,10 @@ WindowCreationPayload::WindowCreationPayload(std::string workspace_name,
clearWorkspaceName(); clearWorkspaceName();
} }
WindowCreationPayload::WindowCreationPayload(std::string workspace_name, WindowCreationPayload::WindowCreationPayload(const std::string& workspace_name,
WindowAddress window_address, std::string window_class, WindowAddress window_address,
std::string window_title, bool is_active) const std::string& window_class,
const std::string& window_title, bool is_active)
: m_window(std::make_pair(std::move(window_class), std::move(window_title))), : m_window(std::make_pair(std::move(window_class), std::move(window_title))),
m_windowAddress(std::move(window_address)), m_windowAddress(std::move(window_address)),
m_workspaceName(std::move(workspace_name)), m_workspaceName(std::move(workspace_name)),

View File

@@ -96,7 +96,7 @@ bool Workspace::handleClicked(GdkEventButton* bt) const {
void Workspace::initializeWindowMap(const Json::Value& clients_data) { void Workspace::initializeWindowMap(const Json::Value& clients_data) {
m_windowMap.clear(); m_windowMap.clear();
for (auto client : clients_data) { for (const auto& client : clients_data) {
if (client["workspace"]["id"].asInt() == id()) { if (client["workspace"]["id"].asInt() == id()) {
insertWindow({client}); insertWindow({client});
} }

View File

@@ -155,7 +155,8 @@ void Workspaces::extendOrphans(int workspaceId, Json::Value const& clientsJson)
} }
} }
std::string Workspaces::getRewrite(std::string window_class, std::string window_title) { std::string Workspaces::getRewrite(const std::string& window_class,
const std::string& window_title) {
std::string windowReprKey; std::string windowReprKey;
if (windowRewriteConfigUsesTitle()) { if (windowRewriteConfigUsesTitle()) {
windowReprKey = fmt::format("class<{}> title<{}>", window_class, window_title); windowReprKey = fmt::format("class<{}> title<{}>", window_class, window_title);
@@ -196,7 +197,7 @@ void Workspaces::initializeWorkspaces() {
auto const workspacesJson = m_ipc.getSocket1JsonReply("workspaces"); auto const workspacesJson = m_ipc.getSocket1JsonReply("workspaces");
auto const clientsJson = m_ipc.getSocket1JsonReply("clients"); auto const clientsJson = m_ipc.getSocket1JsonReply("clients");
for (Json::Value workspaceJson : workspacesJson) { for (const auto& workspaceJson : workspacesJson) {
std::string workspaceName = workspaceJson["name"].asString(); std::string workspaceName = workspaceJson["name"].asString();
if ((allOutputs() || m_bar.output->name == workspaceJson["monitor"].asString()) && if ((allOutputs() || m_bar.output->name == workspaceJson["monitor"].asString()) &&
(!workspaceName.starts_with("special") || showSpecial()) && (!workspaceName.starts_with("special") || showSpecial()) &&
@@ -400,7 +401,7 @@ void Workspaces::onWorkspaceCreated(std::string const& payload, Json::Value cons
auto const workspaceRules = m_ipc.getSocket1JsonReply("workspacerules"); auto const workspaceRules = m_ipc.getSocket1JsonReply("workspacerules");
auto const workspacesJson = m_ipc.getSocket1JsonReply("workspaces"); auto const workspacesJson = m_ipc.getSocket1JsonReply("workspaces");
for (Json::Value workspaceJson : workspacesJson) { for (auto workspaceJson : workspacesJson) {
const auto currentId = workspaceJson["id"].asInt(); const auto currentId = workspaceJson["id"].asInt();
if (currentId == *workspaceId) { if (currentId == *workspaceId) {
std::string workspaceName = workspaceJson["name"].asString(); std::string workspaceName = workspaceJson["name"].asString();
@@ -1003,7 +1004,7 @@ void Workspaces::setUrgentWorkspace(std::string const& windowaddress) {
const Json::Value clientsJson = m_ipc.getSocket1JsonReply("clients"); const Json::Value clientsJson = m_ipc.getSocket1JsonReply("clients");
int workspaceId = -1; int workspaceId = -1;
for (Json::Value clientJson : clientsJson) { for (const auto& clientJson : clientsJson) {
if (clientJson["address"].asString().ends_with(windowaddress)) { if (clientJson["address"].asString().ends_with(windowaddress)) {
workspaceId = clientJson["workspace"]["id"].asInt(); workspaceId = clientJson["workspace"]["id"].asInt();
break; break;

View File

@@ -85,7 +85,8 @@ auto getInhibitors(const Json::Value& config) -> std::string {
if (config["what"].isArray()) { if (config["what"].isArray()) {
inhibitors = checkInhibitor(config["what"][0].asString()); inhibitors = checkInhibitor(config["what"][0].asString());
for (decltype(config["what"].size()) i = 1; i < config["what"].size(); ++i) { for (decltype(config["what"].size()) i = 1; i < config["what"].size(); ++i) {
inhibitors += ":" + checkInhibitor(config["what"][i].asString()); inhibitors.append(":");
inhibitors.append(checkInhibitor(config["what"][i].asString()));
} }
return inhibitors; return inhibitors;
} }

View File

@@ -239,7 +239,8 @@ std::string waybar::modules::MPD::getStateIcon() const {
} }
} }
std::string waybar::modules::MPD::getOptionIcon(std::string optionName, bool activated) const { std::string waybar::modules::MPD::getOptionIcon(const std::string& optionName,
bool activated) const {
if (!config_[optionName + "-icons"].isObject()) { if (!config_[optionName + "-icons"].isObject()) {
return ""; return "";
} }

View File

@@ -109,6 +109,7 @@ Mpris::Mpris(const std::string& id, const Json::Value& config)
player_ = config_["player"].asString(); player_ = config_["player"].asString();
} }
if (config_["ignored-players"].isArray()) { if (config_["ignored-players"].isArray()) {
ignored_players_.reserve(config_["ignored-players"].size());
for (const auto& item : config_["ignored-players"]) { for (const auto& item : config_["ignored-players"]) {
if (item.isString()) { if (item.isString()) {
ignored_players_.push_back(item.asString()); ignored_players_.push_back(item.asString());

View File

@@ -321,6 +321,7 @@ auto waybar::modules::Network::update() -> void {
} else if (addr_pref_ == ip_addr_pref::IPV6) { } else if (addr_pref_ == ip_addr_pref::IPV6) {
final_ipaddr_ = ipaddr6_; final_ipaddr_ = ipaddr6_;
} else if (addr_pref_ == ip_addr_pref::IPV4_6) { } else if (addr_pref_ == ip_addr_pref::IPV4_6) {
final_ipaddr_.reserve(ipaddr_.length() + ipaddr6_.length() + 1);
final_ipaddr_ = ipaddr_; final_ipaddr_ = ipaddr_;
final_ipaddr_ += '\n'; final_ipaddr_ += '\n';
final_ipaddr_ += ipaddr6_; final_ipaddr_ += ipaddr6_;

View File

@@ -32,6 +32,7 @@ void Language::updateFromIPC() {
auto ipcLock = gIPC->lockData(); auto ipcLock = gIPC->lockData();
layouts_.clear(); layouts_.clear();
layouts_.reserve(gIPC->keyboardLayoutNames().size());
for (const auto& fullName : gIPC->keyboardLayoutNames()) layouts_.push_back(getLayout(fullName)); for (const auto& fullName : gIPC->keyboardLayoutNames()) layouts_.push_back(getLayout(fullName));
current_idx_ = gIPC->keyboardLayoutCurrent(); current_idx_ = gIPC->keyboardLayoutCurrent();

View File

@@ -132,7 +132,7 @@ std::tuple<std::string, std::string> Host::getBusNameAndObjectPath(const std::st
return {service, "/StatusNotifierItem"}; return {service, "/StatusNotifierItem"};
} }
void Host::addRegisteredItem(std::string service) { void Host::addRegisteredItem(const std::string& service) {
std::string bus_name, object_path; std::string bus_name, object_path;
std::tie(bus_name, object_path) = getBusNameAndObjectPath(service); std::tie(bus_name, object_path) = getBusNameAndObjectPath(service);
auto it = std::find_if(items_.begin(), items_.end(), [&bus_name, &object_path](const auto& item) { auto it = std::find_if(items_.begin(), items_.end(), [&bus_name, &object_path](const auto& item) {

View File

@@ -336,11 +336,20 @@ Glib::RefPtr<Gdk::Pixbuf> Item::extractPixBuf(GVariant* variant) {
if (array != nullptr) { if (array != nullptr) {
g_free(array); g_free(array);
} }
#if GLIB_MAJOR_VERSION >= 2 && GLIB_MINOR_VERSION >= 68 // We must allocate our own array because the data from GVariant is read-only
array = static_cast<guchar*>(g_memdup2(data, size)); // and we need to modify it to convert ARGB to RGBA.
#else array = static_cast<guchar*>(g_malloc(size));
array = static_cast<guchar*>(g_memdup(data, size));
#endif // Copy and convert ARGB to RGBA in one pass to avoid g_memdup2 overhead
const guchar* src = static_cast<const guchar*>(data);
for (gsize i = 0; i < size; i += 4) {
guchar alpha = src[i];
array[i] = src[i + 1];
array[i + 1] = src[i + 2];
array[i + 2] = src[i + 3];
array[i + 3] = alpha;
}
lwidth = width; lwidth = width;
lheight = height; lheight = height;
} }
@@ -349,14 +358,6 @@ Glib::RefPtr<Gdk::Pixbuf> Item::extractPixBuf(GVariant* variant) {
} }
g_variant_iter_free(it); g_variant_iter_free(it);
if (array != nullptr) { if (array != nullptr) {
/* argb to rgba */
for (uint32_t i = 0; i < 4U * lwidth * lheight; i += 4) {
guchar alpha = array[i];
array[i] = array[i + 1];
array[i + 1] = array[i + 2];
array[i + 2] = array[i + 3];
array[i + 3] = alpha;
}
return Gdk::Pixbuf::create_from_data(array, Gdk::Colorspace::COLORSPACE_RGB, true, 8, lwidth, return Gdk::Pixbuf::create_from_data(array, Gdk::Colorspace::COLORSPACE_RGB, true, 8, lwidth,
lheight, 4 * lwidth, &pixbuf_data_deleter); lheight, 4 * lwidth, &pixbuf_data_deleter);
} }
@@ -422,8 +423,6 @@ Glib::RefPtr<Gdk::Pixbuf> Item::getIconPixbuf() {
} }
Glib::RefPtr<Gdk::Pixbuf> Item::getIconByName(const std::string& name, int request_size) { Glib::RefPtr<Gdk::Pixbuf> Item::getIconByName(const std::string& name, int request_size) {
icon_theme->rescan_if_needed();
if (!icon_theme_path.empty()) { if (!icon_theme_path.empty()) {
auto icon_info = icon_theme->lookup_icon(name.c_str(), request_size, auto icon_info = icon_theme->lookup_icon(name.c_str(), request_size,
Gtk::IconLookupFlags::ICON_LOOKUP_FORCE_SIZE); Gtk::IconLookupFlags::ICON_LOOKUP_FORCE_SIZE);

View File

@@ -60,7 +60,7 @@ BarIpcClient::BarIpcClient(waybar::Bar& bar) : bar_{bar} {
}); });
} }
bool BarIpcClient::isModuleEnabled(std::string name) { bool BarIpcClient::isModuleEnabled(const std::string& name) {
for (const auto& section : {"modules-left", "modules-center", "modules-right"}) { for (const auto& section : {"modules-left", "modules-center", "modules-right"}) {
if (const auto& modules = bar_.config.get(section, {}); modules.isArray()) { if (const auto& modules = bar_.config.get(section, {}); modules.isArray()) {
for (const auto& module : modules) { for (const auto& module : modules) {

View File

@@ -124,7 +124,7 @@ auto Language::update() -> void {
ALabel::update(); ALabel::update();
} }
auto Language::set_current_layout(std::string current_layout) -> void { auto Language::set_current_layout(const std::string& current_layout) -> void {
label_.get_style_context()->remove_class(layout_.short_name); label_.get_style_context()->remove_class(layout_.short_name);
layout_ = layouts_map_[current_layout]; layout_ = layouts_map_[current_layout];
label_.get_style_context()->add_class(layout_.short_name); label_.get_style_context()->add_class(layout_.short_name);

View File

@@ -184,9 +184,9 @@ std::tuple<std::string, std::string, std::string, std::string> getWindowInfo(
continue; continue;
} }
if (!marks.empty()) { if (!marks.empty()) {
marks += ','; marks.append(",");
} }
marks += m.asString(); marks.append(m.asString());
} }
} }
return {app_id, app_class, shell, marks}; return {app_id, app_class, shell, marks};

View File

@@ -10,7 +10,7 @@ namespace waybar::modules::sway {
// Helper function to assign a number to a workspace, just like sway. In fact // Helper function to assign a number to a workspace, just like sway. In fact
// this is taken quite verbatim from `sway/ipc-json.c`. // this is taken quite verbatim from `sway/ipc-json.c`.
int Workspaces::convertWorkspaceNameToNum(std::string name) { int Workspaces::convertWorkspaceNameToNum(const std::string& name) {
if (isdigit(name[0]) != 0) { if (isdigit(name[0]) != 0) {
errno = 0; errno = 0;
char* endptr = nullptr; char* endptr = nullptr;
@@ -487,7 +487,7 @@ std::string Workspaces::getCycleWorkspace(std::vector<Json::Value>::iterator it,
return (*it)["name"].asString(); return (*it)["name"].asString();
} }
std::string Workspaces::trimWorkspaceName(std::string name) { std::string Workspaces::trimWorkspaceName(const std::string& name) {
std::size_t found = name.find(':'); std::size_t found = name.find(':');
if (found != std::string::npos) { if (found != std::string::npos) {
return name.substr(found + 1); return name.substr(found + 1);

View File

@@ -95,7 +95,7 @@ UPower::~UPower() {
removeDevices(); removeDevices();
} }
static const std::string getDeviceStatus(UpDeviceState& state) { static std::string_view getDeviceStatus(UpDeviceState& state) {
switch (state) { switch (state) {
case UP_DEVICE_STATE_CHARGING: case UP_DEVICE_STATE_CHARGING:
case UP_DEVICE_STATE_PENDING_CHARGE: case UP_DEVICE_STATE_PENDING_CHARGE:
@@ -112,7 +112,7 @@ static const std::string getDeviceStatus(UpDeviceState& state) {
} }
} }
static const std::string getDeviceIcon(UpDeviceKind& kind) { static std::string_view getDeviceIcon(UpDeviceKind& kind) {
switch (kind) { switch (kind) {
case UP_DEVICE_KIND_LINE_POWER: case UP_DEVICE_KIND_LINE_POWER:
return "ac-adapter-symbolic"; return "ac-adapter-symbolic";
@@ -212,7 +212,8 @@ auto UPower::update() -> void {
// Remove last status if it exists // Remove last status if it exists
if (!lastStatus_.empty() && box_.get_style_context()->has_class(lastStatus_)) if (!lastStatus_.empty() && box_.get_style_context()->has_class(lastStatus_))
box_.get_style_context()->remove_class(lastStatus_); box_.get_style_context()->remove_class(lastStatus_);
if (!box_.get_style_context()->has_class(status)) box_.get_style_context()->add_class(status); if (!box_.get_style_context()->has_class(std::string(status)))
box_.get_style_context()->add_class(std::string(status));
lastStatus_ = status; lastStatus_ = status;
if (devices_.size() == 0 && !upDeviceValid && hideIfEmpty_) { if (devices_.size() == 0 && !upDeviceValid && hideIfEmpty_) {

View File

@@ -21,7 +21,6 @@ Glib::RefPtr<Gdk::Pixbuf> DefaultGtkIconThemeWrapper::load_icon(
const std::lock_guard<std::mutex> lock(default_theme_mutex); const std::lock_guard<std::mutex> lock(default_theme_mutex);
auto default_theme = Gtk::IconTheme::get_default(); auto default_theme = Gtk::IconTheme::get_default();
default_theme->rescan_if_needed();
auto icon_info = default_theme->lookup_icon(name, tmp_size, flags); auto icon_info = default_theme->lookup_icon(name, tmp_size, flags);

View File

@@ -4,11 +4,12 @@
#include <catch2/catch.hpp> #include <catch2/catch.hpp>
#endif #endif
#include <chrono>
#include <sys/wait.h> #include <sys/wait.h>
#include <thread>
#include <unistd.h> #include <unistd.h>
#include <chrono>
#include <thread>
#include "util/sleeper_thread.hpp" #include "util/sleeper_thread.hpp"
namespace waybar::util { namespace waybar::util {