polybar/include/x11/xresources.hpp

65 lines
1.4 KiB
C++

#pragma once
#include "settings.hpp"
#if not WITH_XRM
#error "Not built with support for xcb-xrm..."
#endif
#include <xcb/xcb_xrm.h>
#include "common.hpp"
#include "errors.hpp"
#include "utils/string.hpp"
#include "x11/connection.hpp"
POLYBAR_NS
DEFINE_ERROR(xresource_error);
class xresource_manager {
public:
explicit xresource_manager(xcb_connection_t* conn) : m_xrm(xcb_xrm_database_from_default(conn)) {
if (m_xrm == nullptr) {
throw application_error("xcb_xrm_database_from_default()");
}
}
~xresource_manager() {
xcb_xrm_database_free(m_xrm);
}
operator bool() const {
return m_xrm != nullptr;
}
template <typename T>
T require(const char* name) const {
char* result{nullptr};
if (xcb_xrm_resource_get_string(m_xrm, string_util::replace(name, "*", ".").c_str(), nullptr, &result) == -1) {
throw xresource_error(sstream() << "X resource \"" << name << "\" not found");
} else if (result == nullptr) {
throw xresource_error(sstream() << "X resource \"" << name << "\" not found");
}
return convert<T>(string(result));
}
template <typename T>
T get(const char* name, const T& fallback) const {
try {
return convert<T>(require<T>(name));
} catch (const xresource_error) {
return fallback;
}
}
protected:
template <typename T>
T convert(string&& value) const;
private:
xcb_xrm_database_t* m_xrm;
};
POLYBAR_NS_END