#include "../include/Config.hpp" #include "../include/Storage.hpp" #include namespace QuickMedia { static bool config_initialized = false; static Config *config = nullptr; static float scale = 1.0f; static bool scale_set = false; static const int XFT_DPI_DEFAULT = 96; // Returns XFT_DPI_DEFAULT on error static int xrdb_get_dpi() { int xft_dpi = XFT_DPI_DEFAULT; FILE *xrdb_query = popen("xrdb -query", "r"); if(!xrdb_query) return xft_dpi; char line[512]; while(fgets(line, sizeof(line), xrdb_query)) { int line_length = strlen(line); if(line_length > 0 && line[line_length - 1] == '\n') { line[line_length - 1] = '\0'; line_length--; } if(line_length > 8 && memcmp(line, "Xft.dpi:", 8) == 0) { int xft_dpi_file = atoi(line + 8); if(xft_dpi_file > 0) { xft_dpi = xft_dpi_file; break; } } } pclose(xrdb_query); return xft_dpi; } static float get_ui_scale() { if(scale_set) return scale; char *gdk_scale = getenv("GDK_SCALE"); if(gdk_scale) { setlocale(LC_ALL, "C"); // Sigh... stupid C scale = atof(gdk_scale); if(scale < 0.0001f) scale = 1.0f; } else { scale = (float)xrdb_get_dpi() / (float)XFT_DPI_DEFAULT; } scale_set = true; return scale; } // No-op if this has already been called before static void init_config() { if(config_initialized) return; config_initialized = true; // Wtf? can't use static non-pointer config because it causes a segfault when setting config.theme. // It looks like a libc bug??? crashes for both gcc and clang. config = new Config(); config->scale = get_ui_scale(); Path config_path = get_storage_dir().join("config.json"); if(get_file_type(config_path) != FileType::REGULAR) { return; } Json::Value json_root; if(!read_file_as_json(config_path, json_root) || !json_root.isObject()) { fprintf(stderr, "Warning: failed to parse config file: %s\n", config_path.data.c_str()); return; } const Json::Value &search_json = json_root["search"]; if(search_json.isObject()) { const Json::Value &font_size_json = search_json["font_size"]; if(font_size_json.isNumeric()) config->search.font_size = font_size_json.asDouble(); } const Json::Value &tab_json = json_root["tab"]; if(tab_json.isObject()) { const Json::Value &font_size_json = tab_json["font_size"]; if(font_size_json.isNumeric()) config->tab.font_size = font_size_json.asDouble(); } const Json::Value &body_json = json_root["body"]; if(body_json.isObject()) { const Json::Value &title_font_size = body_json["title_font_size"]; if(title_font_size.isNumeric()) config->body.title_font_size = title_font_size.asDouble(); const Json::Value &author_font_size = body_json["author_font_size"]; if(author_font_size.isNumeric()) config->body.author_font_size = author_font_size.asDouble(); const Json::Value &description_font_size = body_json["description_font_size"]; if(description_font_size.isNumeric()) config->body.description_font_size = description_font_size.asDouble(); const Json::Value ×tamp_font_size = body_json["timestamp_font_size"]; if(timestamp_font_size.isNumeric()) config->body.timestamp_font_size = timestamp_font_size.asDouble(); const Json::Value &reaction_font_size = body_json["reaction_font_size"]; if(reaction_font_size.isNumeric()) config->body.reaction_font_size = reaction_font_size.asDouble(); const Json::Value &embedded_load_font_size = body_json["embedded_load_font_size"]; if(embedded_load_font_size.isNumeric()) config->body.embedded_load_font_size = embedded_load_font_size.asDouble(); } const Json::Value &input_json = json_root["input"]; if(input_json.isObject()) { const Json::Value &font_size_json = input_json["font_size"]; if(font_size_json.isNumeric()) config->input.font_size = font_size_json.asDouble(); } const Json::Value &use_system_fonts_json = json_root["use_system_fonts"]; if(use_system_fonts_json.isBool()) config->use_system_fonts = use_system_fonts_json.asBool(); const Json::Value &use_system_mpv_config = json_root["use_system_mpv_config"]; if(use_system_mpv_config.isBool()) config->use_system_mpv_config = use_system_mpv_config.asBool(); const Json::Value &theme_json = json_root["theme"]; if(theme_json.isString()) config->theme = theme_json.asString(); const Json::Value &scale_json = json_root["scale"]; if(scale_json.isNumeric()) config->scale = scale_json.asDouble(); else config->scale = get_ui_scale(); const Json::Value &font_scale = json_root["font_scale"]; if(font_scale.isNumeric()) config->font_scale = font_scale.asDouble(); } const Config& get_config() { init_config(); return *config; } }