// gKeyMapper - GUI options that are not part of the mapping format. #include "settings.h" #include #include #include namespace gkeymapper { namespace { // Same shape as the mapping file next to it: a group and one key per option. const char* kGroup = "gui"; const char* kMinimizeToTray = "minimize-to-tray"; const char* kLanguage = "language"; // What the session had in LANGUAGE before this program touched it, so choosing // "follow the session" can put it back exactly. std::string sessionLanguage; bool sessionLanguageTaken = false; } // namespace std::string default_gui_config_path() { const char* home = std::getenv("HOME"); return std::string(home ? home : "") + "/.config/gKeyMapper/gui.conf"; } GuiSettings load_gui_settings() { GuiSettings settings; GKeyFile* file = g_key_file_new(); GError* error = nullptr; // A missing file is the normal first start, not an error. if (g_key_file_load_from_file(file, default_gui_config_path().c_str(), G_KEY_FILE_NONE, &error)) { GError* itemError = nullptr; const gboolean value = g_key_file_get_boolean(file, kGroup, kMinimizeToTray, &itemError); if (itemError == nullptr) { settings.minimizeToTray = value != FALSE; } g_clear_error(&itemError); g_autofree gchar* language = g_key_file_get_string(file, kGroup, kLanguage, nullptr); if (language != nullptr) { settings.language = language; } } g_clear_error(&error); g_key_file_unref(file); return settings; } void save_gui_settings(const GuiSettings& settings) { const std::string path = default_gui_config_path(); g_autofree gchar* directory = g_path_get_dirname(path.c_str()); g_mkdir_with_parents(directory, 0700); GKeyFile* file = g_key_file_new(); g_key_file_set_boolean(file, kGroup, kMinimizeToTray, settings.minimizeToTray); g_key_file_set_string(file, kGroup, kLanguage, settings.language.c_str()); GError* error = nullptr; if (!g_key_file_save_to_file(file, path.c_str(), &error)) { g_printerr("gkeymapper: could not write %s: %s\n", path.c_str(), error != nullptr ? error->message : "unknown error"); g_clear_error(&error); } g_key_file_unref(file); } void apply_gui_language(const std::string& language) { if (!sessionLanguageTaken) { const char* current = g_getenv("LANGUAGE"); sessionLanguage = current != nullptr ? current : ""; sessionLanguageTaken = true; } // gettext checks LANGUAGE before the locale, so it is the one knob to turn; // the shipped catalogs are small and the identity catalog for English means // an explicit "en" works on a German desktop too. if (language.empty()) { if (sessionLanguage.empty()) { g_unsetenv("LANGUAGE"); } else { g_setenv("LANGUAGE", sessionLanguage.c_str(), TRUE); } } else { g_setenv("LANGUAGE", language.c_str(), TRUE); } // setlocale re-reads the environment and bumps glibc's catalog counter, so // the next translated string comes out of the new catalog. setlocale(LC_ALL, ""); } } // namespace gkeymapper