- Replaced pass-by-value std::string parameters with const std::string& or std::string_view to prevent SSO overallocations. - Refactored static mapping functions in UPower to return std::string_view instead of constructing std::string literals, enabling perfect cache locality. - Optimized string concatenation in hot loops (network IPs, inhibitor lists, sway window marks) by using std::string::append() and pre-reserving capacity instead of overloaded operator+ which produces temporary heap instances. These optimizations reduce high-frequency memory churn and overall heap fragmentation within the main rendering loops. Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
112 lines
4.2 KiB
C++
112 lines
4.2 KiB
C++
#include "modules/hyprland/windowcreationpayload.hpp"
|
|
|
|
#include <json/value.h>
|
|
#include <spdlog/spdlog.h>
|
|
|
|
#include <string>
|
|
#include <utility>
|
|
#include <variant>
|
|
|
|
#include "modules/hyprland/workspaces.hpp"
|
|
|
|
namespace waybar::modules::hyprland {
|
|
|
|
WindowCreationPayload::WindowCreationPayload(Json::Value const& client_data)
|
|
: m_window(std::make_pair(client_data["class"].asString(), client_data["title"].asString())),
|
|
m_windowAddress(client_data["address"].asString()),
|
|
m_workspaceName(client_data["workspace"]["name"].asString()) {
|
|
clearAddr();
|
|
clearWorkspaceName();
|
|
}
|
|
|
|
WindowCreationPayload::WindowCreationPayload(const std::string& workspace_name,
|
|
WindowAddress window_address, WindowRepr window_repr)
|
|
: m_window(std::move(window_repr)),
|
|
m_windowAddress(std::move(window_address)),
|
|
m_workspaceName(std::move(workspace_name)) {
|
|
clearAddr();
|
|
clearWorkspaceName();
|
|
}
|
|
|
|
WindowCreationPayload::WindowCreationPayload(const std::string& workspace_name,
|
|
WindowAddress window_address,
|
|
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_windowAddress(std::move(window_address)),
|
|
m_workspaceName(std::move(workspace_name)),
|
|
m_isActive(is_active) {
|
|
clearAddr();
|
|
clearWorkspaceName();
|
|
}
|
|
|
|
void WindowCreationPayload::clearAddr() {
|
|
// substr(2, ...) is necessary because Hyprland's JSON follows this format:
|
|
// 0x{ADDR}
|
|
// While Hyprland's IPC follows this format:
|
|
// {ADDR}
|
|
static const std::string ADDR_PREFIX = "0x";
|
|
static const int ADDR_PREFIX_LEN = ADDR_PREFIX.length();
|
|
|
|
if (m_windowAddress.starts_with(ADDR_PREFIX)) {
|
|
m_windowAddress =
|
|
m_windowAddress.substr(ADDR_PREFIX_LEN, m_windowAddress.length() - ADDR_PREFIX_LEN);
|
|
}
|
|
}
|
|
|
|
void WindowCreationPayload::clearWorkspaceName() {
|
|
// The workspace name may optionally feature "special:" at the beginning.
|
|
// If so, we need to remove it because the workspace is saved WITHOUT the
|
|
// special qualifier. The reasoning is that not all of Hyprland's IPC events
|
|
// use this qualifier, so it's better to be consistent about our uses.
|
|
|
|
static const std::string SPECIAL_QUALIFIER_PREFIX = "special:";
|
|
static const int SPECIAL_QUALIFIER_PREFIX_LEN = SPECIAL_QUALIFIER_PREFIX.length();
|
|
|
|
if (m_workspaceName.starts_with(SPECIAL_QUALIFIER_PREFIX)) {
|
|
m_workspaceName = m_workspaceName.substr(
|
|
SPECIAL_QUALIFIER_PREFIX_LEN, m_workspaceName.length() - SPECIAL_QUALIFIER_PREFIX_LEN);
|
|
}
|
|
|
|
std::size_t spaceFound = m_workspaceName.find(' ');
|
|
if (spaceFound != std::string::npos) {
|
|
m_workspaceName.erase(m_workspaceName.begin() + spaceFound, m_workspaceName.end());
|
|
}
|
|
}
|
|
|
|
bool WindowCreationPayload::isEmpty(Workspaces& workspace_manager) {
|
|
if (std::holds_alternative<Repr>(m_window)) {
|
|
return std::get<Repr>(m_window).empty();
|
|
}
|
|
if (std::holds_alternative<ClassAndTitle>(m_window)) {
|
|
auto [window_class, window_title] = std::get<ClassAndTitle>(m_window);
|
|
return (window_class.empty() &&
|
|
(!workspace_manager.windowRewriteConfigUsesTitle() || window_title.empty()));
|
|
}
|
|
// Unreachable
|
|
spdlog::error("WorkspaceWindow::isEmpty: Unreachable");
|
|
throw std::runtime_error("WorkspaceWindow::isEmpty: Unreachable");
|
|
}
|
|
|
|
int WindowCreationPayload::incrementTimeSpentUncreated() { return m_timeSpentUncreated++; }
|
|
|
|
void WindowCreationPayload::moveToWorkspace(std::string& new_workspace_name) {
|
|
m_workspaceName = new_workspace_name;
|
|
}
|
|
|
|
WindowRepr WindowCreationPayload::repr(Workspaces& workspace_manager) {
|
|
if (std::holds_alternative<Repr>(m_window)) {
|
|
return std::get<Repr>(m_window);
|
|
}
|
|
if (std::holds_alternative<ClassAndTitle>(m_window)) {
|
|
auto const& [window_class, window_title] = std::get<ClassAndTitle>(m_window);
|
|
return {m_windowAddress, window_class, window_title,
|
|
workspace_manager.getRewrite(window_class, window_title), m_isActive};
|
|
}
|
|
// Unreachable
|
|
spdlog::error("WorkspaceWindow::repr: Unreachable");
|
|
throw std::runtime_error("WorkspaceWindow::repr: Unreachable");
|
|
}
|
|
|
|
} // namespace waybar::modules::hyprland
|