mirror of
https://github.com/hyprwm/Hyprland
synced 2025-12-28 00:30:15 +01:00
i18n: init localization for ANR, Permissions and Notifications (#12316)
Adds localization support for en, it, pl and jp --------- Co-authored-by: Mihai Fufezan <mihai@fufexan.net> Co-authored-by: Aaron Blasko <blaskoazzolaaaron@gmail.com>
This commit is contained in:
parent
cb47eb1d11
commit
e616e595ae
12 changed files with 302 additions and 67 deletions
|
|
@ -108,7 +108,7 @@ find_package(OpenGL REQUIRED COMPONENTS ${GLES_VERSION})
|
|||
pkg_check_modules(aquamarine_dep REQUIRED IMPORTED_TARGET aquamarine>=0.9.3)
|
||||
pkg_check_modules(hyprlang_dep REQUIRED IMPORTED_TARGET hyprlang>=0.3.2)
|
||||
pkg_check_modules(hyprcursor_dep REQUIRED IMPORTED_TARGET hyprcursor>=0.1.7)
|
||||
pkg_check_modules(hyprutils_dep REQUIRED IMPORTED_TARGET hyprutils>=0.8.2)
|
||||
pkg_check_modules(hyprutils_dep REQUIRED IMPORTED_TARGET hyprutils>=0.10.2)
|
||||
pkg_check_modules(hyprgraphics_dep REQUIRED IMPORTED_TARGET hyprgraphics>=0.1.6)
|
||||
|
||||
string(REPLACE "." ";" AQ_VERSION_LIST ${aquamarine_dep_VERSION})
|
||||
|
|
|
|||
6
flake.lock
generated
6
flake.lock
generated
|
|
@ -261,11 +261,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1762387740,
|
||||
"narHash": "sha256-gQ9zJ+pUI4o+Gh4Z6jhJll7jjCSwi8ZqJIhCE2oqwhQ=",
|
||||
"lastModified": 1762812168,
|
||||
"narHash": "sha256-pY+dUqi2AYpH0HHT2JFzt1qWoJQBWtBdzzcL1ZK5Mwo=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprutils",
|
||||
"rev": "926689ddb9c0a8787e58c02c765a62e32d63d1f7",
|
||||
"rev": "cb3e797fde5c748164eb70d9859336141136a166",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@
|
|||
#include "debug/HyprNotificationOverlay.hpp"
|
||||
#include "debug/HyprDebugOverlay.hpp"
|
||||
#include "helpers/MonitorFrameScheduler.hpp"
|
||||
#include "i18n/Engine.hpp"
|
||||
|
||||
#include <hyprutils/string/String.hpp>
|
||||
#include <aquamarine/input/Input.hpp>
|
||||
|
|
@ -2765,22 +2766,19 @@ void CCompositor::performUserChecks() {
|
|||
const auto CURRENT_DESKTOP_ENV = getenv("XDG_CURRENT_DESKTOP");
|
||||
if (!CURRENT_DESKTOP_ENV || std::string{CURRENT_DESKTOP_ENV} != "Hyprland") {
|
||||
g_pHyprNotificationOverlay->addNotification(
|
||||
std::format("Your XDG_CURRENT_DESKTOP environment seems to be managed externally, and the current value is {}.\nThis might cause issues unless it's intentional.",
|
||||
CURRENT_DESKTOP_ENV ? CURRENT_DESKTOP_ENV : "unset"),
|
||||
CHyprColor{}, 15000, ICON_WARNING);
|
||||
I18n::i18nEngine()->localize(I18n::TXT_KEY_NOTIF_EXTERNAL_XDG_DESKTOP, {{"value", CURRENT_DESKTOP_ENV ? CURRENT_DESKTOP_ENV : "unset"}}), CHyprColor{}, 15000,
|
||||
ICON_WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
if (!*PNOCHECKGUIUTILS) {
|
||||
if (!NFsUtils::executableExistsInPath("hyprland-dialog")) {
|
||||
g_pHyprNotificationOverlay->addNotification(
|
||||
"Your system does not have hyprland-guiutils installed. This is a runtime dependency for some dialogs. Consider installing it.", CHyprColor{}, 15000, ICON_WARNING);
|
||||
g_pHyprNotificationOverlay->addNotification(I18n::i18nEngine()->localize(I18n::TXT_KEY_NOTIF_NO_GUIUTILS), CHyprColor{}, 15000, ICON_WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
if (g_pHyprOpenGL->m_failedAssetsNo > 0) {
|
||||
g_pHyprNotificationOverlay->addNotification(std::format("Hyprland failed to load {} essential asset{}, blame your distro's packager for doing a bad job at packaging!",
|
||||
g_pHyprOpenGL->m_failedAssetsNo, g_pHyprOpenGL->m_failedAssetsNo > 1 ? "s" : ""),
|
||||
g_pHyprNotificationOverlay->addNotification(I18n::i18nEngine()->localize(I18n::TXT_KEY_NOTIF_FAILED_ASSETS, {{"count", std::to_string(g_pHyprOpenGL->m_failedAssetsNo)}}),
|
||||
CHyprColor{1.0, 0.1, 0.1, 1.0}, 15000, ICON_ERROR);
|
||||
}
|
||||
}
|
||||
|
|
@ -2905,10 +2903,8 @@ void CCompositor::checkMonitorOverlaps() {
|
|||
for (const auto& m : m_monitors) {
|
||||
if (!monitorRegion.copy().intersect(m->logicalBox()).empty()) {
|
||||
Debug::log(ERR, "Monitor {}: detected overlap with layout", m->m_name);
|
||||
g_pHyprNotificationOverlay->addNotification(std::format("Your monitor layout is set up incorrectly. Monitor {} overlaps with other monitor(s) in the "
|
||||
"layout.\nPlease see the wiki (Monitors page) for more. This will cause issues.",
|
||||
m->m_name),
|
||||
CHyprColor{}, 15000, ICON_WARNING);
|
||||
g_pHyprNotificationOverlay->addNotification(I18n::i18nEngine()->localize(I18n::TXT_KEY_NOTIF_INVALID_MONITOR_LAYOUT, {{"name", m->m_name}}), CHyprColor{}, 15000,
|
||||
ICON_WARNING);
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "../managers/animation/DesktopAnimationManager.hpp"
|
||||
#include "../managers/input/InputManager.hpp"
|
||||
#include "../hyprerror/HyprError.hpp"
|
||||
#include "../i18n/Engine.hpp"
|
||||
#include "sync/SyncTimeline.hpp"
|
||||
#include "time/Time.hpp"
|
||||
#include "../desktop/LayerSurface.hpp"
|
||||
|
|
@ -811,8 +812,8 @@ bool CMonitor::applyMonitorRule(SMonitorRule* pMonitorRule, bool force) {
|
|||
if (!m_state.test())
|
||||
continue;
|
||||
|
||||
auto errorMessage =
|
||||
std::format("Monitor {} failed to set any requested modes, falling back to mode {:X0}@{:.2f}Hz", m_name, mode->pixelSize, mode->refreshRate / 1000.f);
|
||||
auto errorMessage = I18n::i18nEngine()->localize(I18n::TXT_KEY_NOTIF_MONITOR_MODE_FAIL,
|
||||
{{"name", m_name}, {"mode", std::format("{:X0}@{:.2f}Hz", mode->pixelSize, mode->refreshRate / 1000.f)}});
|
||||
Debug::log(WARN, errorMessage);
|
||||
g_pHyprNotificationOverlay->addNotification(errorMessage, CHyprColor(0xff0000ff), 5000, ICON_WARNING);
|
||||
|
||||
|
|
@ -939,8 +940,10 @@ bool CMonitor::applyMonitorRule(SMonitorRule* pMonitorRule, bool force) {
|
|||
Debug::log(ERR, "Invalid scale passed to monitor, {} found suggestion {}", m_scale, searchScale);
|
||||
static auto PDISABLENOTIFICATION = CConfigValue<Hyprlang::INT>("misc:disable_scale_notification");
|
||||
if (!*PDISABLENOTIFICATION)
|
||||
g_pHyprNotificationOverlay->addNotification(std::format("Invalid scale passed to monitor: {}, using suggested scale: {}", m_scale, searchScale),
|
||||
CHyprColor(1.0, 0.0, 0.0, 1.0), 5000, ICON_WARNING);
|
||||
g_pHyprNotificationOverlay->addNotification(
|
||||
I18n::i18nEngine()->localize(I18n::TXT_KEY_NOTIF_MONITOR_AUTO_SCALE,
|
||||
{{"name", m_name}, {"scale", std::format("{:.2f}", m_scale)}, {"fixed_scale", std::format("{:.2f}", searchScale)}}),
|
||||
CHyprColor(1.0, 0.0, 0.0, 1.0), 5000, ICON_WARNING);
|
||||
}
|
||||
m_scale = searchScale;
|
||||
}
|
||||
|
|
|
|||
175
src/i18n/Engine.cpp
Normal file
175
src/i18n/Engine.cpp
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
#include "Engine.hpp"
|
||||
|
||||
#include <hyprutils/i18n/I18nEngine.hpp>
|
||||
|
||||
using namespace I18n;
|
||||
using namespace Hyprutils::I18n;
|
||||
|
||||
static SP<Hyprutils::I18n::CI18nEngine> huEngine;
|
||||
static std::string localeStr;
|
||||
|
||||
//
|
||||
SP<I18n::CI18nEngine> I18n::i18nEngine() {
|
||||
static SP<I18n::CI18nEngine> engine = makeShared<I18n::CI18nEngine>();
|
||||
return engine;
|
||||
}
|
||||
|
||||
I18n::CI18nEngine::CI18nEngine() {
|
||||
huEngine = makeShared<Hyprutils::I18n::CI18nEngine>();
|
||||
huEngine->setFallbackLocale("en_US");
|
||||
localeStr = huEngine->getSystemLocale().locale();
|
||||
|
||||
// en_US (English)
|
||||
huEngine->registerEntry("en_US", TXT_KEY_ANR_TITLE, "Application Not Responding");
|
||||
huEngine->registerEntry("en_US", TXT_KEY_ANR_CONTENT, "An application {title} - {class} is not responding.\nWhat do you want to do with it?");
|
||||
huEngine->registerEntry("en_US", TXT_KEY_ANR_OPTION_TERMINATE, "Terminate");
|
||||
huEngine->registerEntry("en_US", TXT_KEY_ANR_OPTION_WAIT, "Wait");
|
||||
huEngine->registerEntry("en_US", TXT_KEY_ANR_PROP_UNKNOWN, "(unknown)");
|
||||
|
||||
huEngine->registerEntry("en_US", TXT_KEY_PERMISSION_REQUEST_UNKNOWN, "An application <b>{app}</b> is requesting an unknown permission.");
|
||||
huEngine->registerEntry("en_US", TXT_KEY_PERMISSION_REQUEST_SCREENCOPY, "An application <b>{app}</b> is trying to capture your screen.\n\nDo you want to allow it to?");
|
||||
huEngine->registerEntry("en_US", TXT_KEY_PERMISSION_REQUEST_PLUGIN, "An application <b>{app}</b> is trying to load a plugin: <b>{plugin}</b>.\n\nDo you want to allow it to?");
|
||||
huEngine->registerEntry("en_US", TXT_KEY_PERMISSION_REQUEST_KEYBOARD, "A new keyboard has been detected: <b>{keyboard}</b>.\n\nDo you want to allow it to operate?");
|
||||
huEngine->registerEntry("en_US", TXT_KEY_PERMISSION_UNKNOWN_NAME, "(unknown)");
|
||||
huEngine->registerEntry("en_US", TXT_KEY_PERMISSION_TITLE, "Permission request");
|
||||
huEngine->registerEntry("en_US", TXT_KEY_PERMISSION_PERSISTENCE_HINT, "Hint: you can set persistent rules for these in the Hyprland config file.");
|
||||
huEngine->registerEntry("en_US", TXT_KEY_PERMISSION_ALLOW, "Allow");
|
||||
huEngine->registerEntry("en_US", TXT_KEY_PERMISSION_ALLOW_AND_REMEMBER, "Allow and remember");
|
||||
huEngine->registerEntry("en_US", TXT_KEY_PERMISSION_ALLOW_ONCE, "Allow once");
|
||||
huEngine->registerEntry("en_US", TXT_KEY_PERMISSION_DENY, "Deny");
|
||||
huEngine->registerEntry("en_US", TXT_KEY_PERMISSION_UNKNOWN_WAYLAND_APP, "Unknown application (wayland client ID {wayland_id})");
|
||||
|
||||
huEngine->registerEntry(
|
||||
"en_US", TXT_KEY_NOTIF_EXTERNAL_XDG_DESKTOP,
|
||||
"Your XDG_CURRENT_DESKTOP environment seems to be managed externally, and the current value is {value}.\nThis might cause issues unless it's intentional.");
|
||||
huEngine->registerEntry("en_US", TXT_KEY_NOTIF_NO_GUIUTILS,
|
||||
"Your system does not have hyprland-guiutils installed. This is a runtime dependency for some dialogs. Consider installing it.");
|
||||
huEngine->registerEntry("en_US", TXT_KEY_NOTIF_FAILED_ASSETS, [](const Hyprutils::I18n::translationVarMap& vars) {
|
||||
int assetsNo = std::stoi(vars.at("count"));
|
||||
if (assetsNo <= 1)
|
||||
return "Hyprland failed to load {count} essential asset, blame your distro's packager for doing a bad job at packaging!";
|
||||
return "Hyprland failed to load {count} essential assets, blame your distro's packager for doing a bad job at packaging!";
|
||||
});
|
||||
huEngine->registerEntry("en_US", TXT_KEY_NOTIF_INVALID_MONITOR_LAYOUT,
|
||||
"Your monitor layout is set up incorrectly. Monitor {name} overlaps with other monitor(s) in the layout.\nPlease see the wiki (Monitors page) for "
|
||||
"more. This <b>will</b> cause issues.");
|
||||
huEngine->registerEntry("en_US", TXT_KEY_NOTIF_MONITOR_MODE_FAIL, "Monitor {name} failed to set any requested modes, falling back to mode {mode}.");
|
||||
huEngine->registerEntry("en_US", TXT_KEY_NOTIF_MONITOR_AUTO_SCALE, "Invalid scale passed to monitor {name}: {scale}, using suggested scale: {fixed_scale}");
|
||||
huEngine->registerEntry("en_US", TXT_KEY_NOTIF_FAILED_TO_LOAD_PLUGIN, "Failed to load plugin {name}: {error}");
|
||||
huEngine->registerEntry("en_US", TXT_KEY_NOTIF_CM_RELOAD_FAILED, "CM shader reload failed, falling back to rgba/rgbx.");
|
||||
huEngine->registerEntry("en_US", TXT_KEY_NOTIF_WIDE_COLOR_NOT_10B, "Monitor {name}: wide color gamut is enabled but the display is not in 10-bit mode.");
|
||||
|
||||
// it_IT (Italian)
|
||||
huEngine->registerEntry("it_IT", TXT_KEY_ANR_TITLE, "L'applicazione non risponde");
|
||||
huEngine->registerEntry("it_IT", TXT_KEY_ANR_CONTENT, "Un'applicazione {title} - {class} non risponde.\nCosa vuoi fare?");
|
||||
huEngine->registerEntry("it_IT", TXT_KEY_ANR_OPTION_TERMINATE, "Termina");
|
||||
huEngine->registerEntry("it_IT", TXT_KEY_ANR_OPTION_WAIT, "Attendi");
|
||||
huEngine->registerEntry("it_IT", TXT_KEY_ANR_PROP_UNKNOWN, "(sconosciuto)");
|
||||
|
||||
huEngine->registerEntry("it_IT", TXT_KEY_PERMISSION_REQUEST_UNKNOWN, "Un'applicazione <b>{app}</b> richiede un'autorizzazione sconosciuta.");
|
||||
huEngine->registerEntry("it_IT", TXT_KEY_PERMISSION_REQUEST_SCREENCOPY, "Un'applicazione <b>{app}</b> sta provando a catturare il tuo schermo.\n\nGlie lo vuoi permettere?");
|
||||
huEngine->registerEntry("it_IT", TXT_KEY_PERMISSION_REQUEST_PLUGIN,
|
||||
"Un'applicazione <b>{app}</b> sta provando a caricare un plugin: <b>{plugin}</b>.\n\nGlie lo vuoi permettere?");
|
||||
huEngine->registerEntry("it_IT", TXT_KEY_PERMISSION_REQUEST_KEYBOARD, "È stata rilevata una nuova tastiera: <b>{keyboard}</b>.\n\nLe vuoi permettere di operare?");
|
||||
huEngine->registerEntry("it_IT", TXT_KEY_PERMISSION_UNKNOWN_NAME, "(sconosciuto)");
|
||||
huEngine->registerEntry("it_IT", TXT_KEY_PERMISSION_TITLE, "Richiesta di autorizzazione");
|
||||
huEngine->registerEntry("it_IT", TXT_KEY_PERMISSION_PERSISTENCE_HINT, "Consiglio: Puoi impostare una regola persistente nel tuo file di configurazione di Hyprland.");
|
||||
huEngine->registerEntry("it_IT", TXT_KEY_PERMISSION_ALLOW, "Permetti");
|
||||
huEngine->registerEntry("it_IT", TXT_KEY_PERMISSION_ALLOW_AND_REMEMBER, "Permetti e ricorda");
|
||||
huEngine->registerEntry("it_IT", TXT_KEY_PERMISSION_ALLOW_ONCE, "Permetti una volta");
|
||||
huEngine->registerEntry("it_IT", TXT_KEY_PERMISSION_DENY, "Nega");
|
||||
huEngine->registerEntry("it_IT", TXT_KEY_PERMISSION_UNKNOWN_WAYLAND_APP, "Applicazione sconosciuta (wayland client ID {wayland_id})");
|
||||
|
||||
huEngine->registerEntry("it_IT", TXT_KEY_NOTIF_EXTERNAL_XDG_DESKTOP,
|
||||
"L'ambiente XDG_CURRENT_DESKTOP sembra essere gestito esternamente, il valore attuale è {value}.\nSe non è voluto, potrebbe causare problemi.");
|
||||
huEngine->registerEntry("it_IT", TXT_KEY_NOTIF_NO_GUIUTILS,
|
||||
"Sembra che hyprland-guiutils non sia installato. È una dipendenza richiesta per alcuni dialoghi che potresti voler installare.");
|
||||
huEngine->registerEntry("it_IT", TXT_KEY_NOTIF_FAILED_ASSETS,
|
||||
"Hyprland non ha potuto caricare {count} asset, dai la colpa al packager della tua distribuzione per il suo cattivo lavoro!");
|
||||
huEngine->registerEntry("it_IT", TXT_KEY_NOTIF_INVALID_MONITOR_LAYOUT,
|
||||
"I tuoi schermi sono configurati incorrettamente. Lo schermo {name} si sovrappone con altri nel layout.\nConsulta la wiki (voce Schermi) per "
|
||||
"altre informazioni. Questo <b>causerà</b> problemi.");
|
||||
huEngine->registerEntry("it_IT", TXT_KEY_NOTIF_MONITOR_MODE_FAIL, "Lo schermo {name} non ha potuto impostare alcuna modalità richiesta, sarà usata la modalità {mode}.");
|
||||
huEngine->registerEntry("it_IT", TXT_KEY_NOTIF_MONITOR_AUTO_SCALE,
|
||||
"Fattore di scala non valido per lo schermo {name}: {scale}, utilizzando il fattore suggerito: {fixed_scale}");
|
||||
huEngine->registerEntry("it_IT", TXT_KEY_NOTIF_FAILED_TO_LOAD_PLUGIN, "Impossibile caricare il plugin {name}: {error}");
|
||||
huEngine->registerEntry("it_IT", TXT_KEY_NOTIF_CM_RELOAD_FAILED, "Impossibile ricaricare gli shader CM, sarà usato rgba/rgbx.");
|
||||
huEngine->registerEntry("it_IT", TXT_KEY_NOTIF_WIDE_COLOR_NOT_10B, "Schermo {name}: la gamma di colori ampia è abilitata ma lo schermo non è in modalità 10-bit.");
|
||||
|
||||
// ja_JP (Japanese)
|
||||
huEngine->registerEntry("ja_JP", TXT_KEY_ANR_TITLE, "アプリは応答しません");
|
||||
huEngine->registerEntry("ja_JP", TXT_KEY_ANR_CONTENT, "アプリ {title} ー {class}は応答しません。\n何をしたいですか?");
|
||||
huEngine->registerEntry("ja_JP", TXT_KEY_ANR_OPTION_TERMINATE, "強制終了");
|
||||
huEngine->registerEntry("ja_JP", TXT_KEY_ANR_OPTION_WAIT, "待機");
|
||||
huEngine->registerEntry("ja_JP", TXT_KEY_ANR_PROP_UNKNOWN, "(不明)");
|
||||
|
||||
huEngine->registerEntry("ja_JP", TXT_KEY_PERMISSION_REQUEST_UNKNOWN, "アプリ<b>{app}</b>は不明な許可を要求します。");
|
||||
huEngine->registerEntry("ja_JP", TXT_KEY_PERMISSION_REQUEST_SCREENCOPY, "アプリ<b>{app}</b>は画面へのアクセスを要求します。\n\n許可したいですか?");
|
||||
huEngine->registerEntry("ja_JP", TXT_KEY_PERMISSION_REQUEST_PLUGIN, "アプリ<b>{app}</b>は以下のプラグインをロード許可を要求します:<b>{plugin}</b>。\n\n許可したいですか?");
|
||||
huEngine->registerEntry("ja_JP", TXT_KEY_PERMISSION_REQUEST_KEYBOARD, "新しいキーボードを見つけた:<b>{keyboard}</b>。\n\n稼働を許可したいですか?");
|
||||
huEngine->registerEntry("ja_JP", TXT_KEY_PERMISSION_UNKNOWN_NAME, "(不明)");
|
||||
huEngine->registerEntry("ja_JP", TXT_KEY_PERMISSION_TITLE, "許可要求");
|
||||
huEngine->registerEntry("ja_JP", TXT_KEY_PERMISSION_PERSISTENCE_HINT, "ヒント:Hyprlandのコンフィグで通常の許可や却下を設定できます。");
|
||||
huEngine->registerEntry("ja_JP", TXT_KEY_PERMISSION_ALLOW, "許可");
|
||||
huEngine->registerEntry("ja_JP", TXT_KEY_PERMISSION_ALLOW_AND_REMEMBER, "保存して許可");
|
||||
huEngine->registerEntry("ja_JP", TXT_KEY_PERMISSION_ALLOW_ONCE, "一度許可");
|
||||
huEngine->registerEntry("ja_JP", TXT_KEY_PERMISSION_DENY, "却下");
|
||||
huEngine->registerEntry("ja_JP", TXT_KEY_PERMISSION_UNKNOWN_WAYLAND_APP, "不明なアプリ (waylandクライアントID {wayland_id})");
|
||||
|
||||
huEngine->registerEntry("ja_JP", TXT_KEY_NOTIF_EXTERNAL_XDG_DESKTOP,
|
||||
"エンバイアロンメント変数「XDG_CURRENT_DESKTOP」は外部から「{value}」に設定しました。\n意図的ではなければ、問題は発生可能性があります。");
|
||||
huEngine->registerEntry("ja_JP", TXT_KEY_NOTIF_NO_GUIUTILS, "システムにhyprland-guiutilsはインストールしていません。このパッケージをインストールしてください。");
|
||||
huEngine->registerEntry("ja_JP", TXT_KEY_NOTIF_FAILED_ASSETS,
|
||||
"{count}つの根本的なアセットをロードできませんでした。これはパッケージャーのせいだから、パッケージャーに文句してください。");
|
||||
huEngine->registerEntry(
|
||||
"ja_JP", TXT_KEY_NOTIF_INVALID_MONITOR_LAYOUT,
|
||||
"画面の位置設定は誤用です。画面{name}は他の画面の区域と重ね合わせます。\nウィキのモニターページで詳細を確認してください。これは<b>絶対に</b>問題になります。");
|
||||
huEngine->registerEntry("ja_JP", TXT_KEY_NOTIF_MONITOR_MODE_FAIL, "画面{name}は設定したモードを正常に受け入れませんでした。{mode}を使いました。");
|
||||
huEngine->registerEntry("ja_JP", TXT_KEY_NOTIF_MONITOR_AUTO_SCALE, "画面{name}のスケールは無効:{scale}、代わりにおすすめのスケール{fixed_scale}を使いました。");
|
||||
huEngine->registerEntry("ja_JP", TXT_KEY_NOTIF_FAILED_TO_LOAD_PLUGIN, "プラグイン{name}のロード失敗: {error}");
|
||||
huEngine->registerEntry("ja_JP", TXT_KEY_NOTIF_CM_RELOAD_FAILED, "CMシェーダーのリロード失敗、rgba/rgbxを使いました。");
|
||||
huEngine->registerEntry("ja_JP", TXT_KEY_NOTIF_WIDE_COLOR_NOT_10B, "画面{name}:広い色域は設定していますけど、画面は10ビットモードに設定されていません。");
|
||||
|
||||
// pl_PL (Polish)
|
||||
huEngine->registerEntry("pl_PL", TXT_KEY_ANR_TITLE, "Aplikacja Nie Odpowiada");
|
||||
huEngine->registerEntry("pl_PL", TXT_KEY_ANR_CONTENT, "Aplikacja {title} - {class} nie odpowiada.\nCo chcesz z nią zrobić?");
|
||||
huEngine->registerEntry("pl_PL", TXT_KEY_ANR_OPTION_TERMINATE, "Zakończ proces");
|
||||
huEngine->registerEntry("pl_PL", TXT_KEY_ANR_OPTION_WAIT, "Czekaj");
|
||||
huEngine->registerEntry("pl_PL", TXT_KEY_ANR_PROP_UNKNOWN, "(nieznane)");
|
||||
|
||||
huEngine->registerEntry("pl_PL", TXT_KEY_PERMISSION_REQUEST_UNKNOWN, "Aplikacja <b>{app}</b> prosi o pozwolenie na nieznany typ operacji.");
|
||||
huEngine->registerEntry("pl_PL", TXT_KEY_PERMISSION_REQUEST_SCREENCOPY, "Aplikacja <b>{app}</b> prosi o dostęp do twojego ekranu.\n\nCzy chcesz jej na to pozwolić?");
|
||||
huEngine->registerEntry("pl_PL", TXT_KEY_PERMISSION_REQUEST_PLUGIN, "Aplikacja <b>{app}</b> próbuje załadować plugin: <b>{plugin}</b>.\n\nCzy chcesz jej na to pozwolić?");
|
||||
huEngine->registerEntry("pl_PL", TXT_KEY_PERMISSION_REQUEST_KEYBOARD, "Wykryto nową klawiaturę: <b>{keyboard}</b>.\n\nCzy chcesz jej pozwolić operować?");
|
||||
huEngine->registerEntry("pl_PL", TXT_KEY_PERMISSION_UNKNOWN_NAME, "(nieznane)");
|
||||
huEngine->registerEntry("pl_PL", TXT_KEY_PERMISSION_TITLE, "Prośba o pozwolenie");
|
||||
huEngine->registerEntry("pl_PL", TXT_KEY_PERMISSION_PERSISTENCE_HINT, "Podpowiedź: możesz ustawić stałe zasady w konfiguracji Hyprland'a.");
|
||||
huEngine->registerEntry("pl_PL", TXT_KEY_PERMISSION_ALLOW, "Zezwól");
|
||||
huEngine->registerEntry("pl_PL", TXT_KEY_PERMISSION_ALLOW_AND_REMEMBER, "Zezwól i zapamiętaj");
|
||||
huEngine->registerEntry("pl_PL", TXT_KEY_PERMISSION_ALLOW_ONCE, "Zezwól raz");
|
||||
huEngine->registerEntry("pl_PL", TXT_KEY_PERMISSION_DENY, "Odmów");
|
||||
huEngine->registerEntry("pl_PL", TXT_KEY_PERMISSION_UNKNOWN_WAYLAND_APP, "Nieznana aplikacja (ID klienta wayland {wayland_id})");
|
||||
|
||||
huEngine->registerEntry("pl_PL", TXT_KEY_NOTIF_EXTERNAL_XDG_DESKTOP,
|
||||
"Zmienna środowiska XDG_CURRENT_DESKTOP została ustawiona zewnętrznie na {value}.\nTo może sprawić problemy, chyba, że jest celowe.");
|
||||
huEngine->registerEntry("pl_PL", TXT_KEY_NOTIF_NO_GUIUTILS, "Twój system nie ma hyprland-guiutils zainstalowanych, co może sprawić problemy. Zainstaluj pakiet.");
|
||||
huEngine->registerEntry("pl_PL", TXT_KEY_NOTIF_FAILED_ASSETS, [](const Hyprutils::I18n::translationVarMap& vars) {
|
||||
int assetsNo = std::stoi(vars.at("count"));
|
||||
if (assetsNo == 1)
|
||||
return "Nie udało się załadować {count} kluczowego zasobu, wiń swojego packager'a za robienie słabej roboty!";
|
||||
|
||||
return "Nie udało się załadować {count} kluczowych zasobów, wiń swojego packager'a za robienie słabej roboty!";
|
||||
});
|
||||
huEngine->registerEntry("pl_PL", TXT_KEY_NOTIF_INVALID_MONITOR_LAYOUT,
|
||||
"Pozycje twoich monitorów nie są ustawione poprawnie. Monitor {name} wchodzi na inne monitory.\nWejdź na wiki (stronę Monitory) "
|
||||
"po więcej. To <b>będzie</b> sprawiać problemy.");
|
||||
huEngine->registerEntry("pl_PL", TXT_KEY_NOTIF_MONITOR_MODE_FAIL, "Monitor {name} nie zaakceptował żadnego wybranego programu. Użyto {mode}.");
|
||||
huEngine->registerEntry("pl_PL", TXT_KEY_NOTIF_MONITOR_AUTO_SCALE, "Nieprawidłowa skala dla monitora {name}: {scale}, użyto proponowanej skali: {fixed_scale}");
|
||||
huEngine->registerEntry("pl_PL", TXT_KEY_NOTIF_FAILED_TO_LOAD_PLUGIN, "Nie udało się załadować plugin'a {name}: {error}");
|
||||
huEngine->registerEntry("pl_PL", TXT_KEY_NOTIF_CM_RELOAD_FAILED, "Nie udało się przeładować shader'a CM, użyto rgba/rgbx.");
|
||||
huEngine->registerEntry("pl_PL", TXT_KEY_NOTIF_WIDE_COLOR_NOT_10B, "Monitor {name}: skonfigurowano szeroką głębię barw, ale monitor nie jest w trybie 10-bit.");
|
||||
}
|
||||
|
||||
std::string I18n::CI18nEngine::localize(eI18nKeys key, const Hyprutils::I18n::translationVarMap& vars) {
|
||||
return huEngine->localizeEntry(localeStr, key, vars);
|
||||
}
|
||||
50
src/i18n/Engine.hpp
Normal file
50
src/i18n/Engine.hpp
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
#pragma once
|
||||
|
||||
#include "../helpers/memory/Memory.hpp"
|
||||
#include <unordered_map>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace I18n {
|
||||
|
||||
enum eI18nKeys : uint8_t {
|
||||
TXT_KEY_ANR_TITLE = 0,
|
||||
TXT_KEY_ANR_CONTENT,
|
||||
TXT_KEY_ANR_OPTION_TERMINATE,
|
||||
TXT_KEY_ANR_OPTION_WAIT,
|
||||
TXT_KEY_ANR_PROP_UNKNOWN,
|
||||
|
||||
TXT_KEY_PERMISSION_REQUEST_UNKNOWN,
|
||||
TXT_KEY_PERMISSION_REQUEST_SCREENCOPY,
|
||||
TXT_KEY_PERMISSION_REQUEST_PLUGIN,
|
||||
TXT_KEY_PERMISSION_REQUEST_KEYBOARD,
|
||||
TXT_KEY_PERMISSION_UNKNOWN_NAME,
|
||||
TXT_KEY_PERMISSION_TITLE,
|
||||
TXT_KEY_PERMISSION_PERSISTENCE_HINT,
|
||||
TXT_KEY_PERMISSION_ALLOW,
|
||||
TXT_KEY_PERMISSION_ALLOW_AND_REMEMBER,
|
||||
TXT_KEY_PERMISSION_ALLOW_ONCE,
|
||||
TXT_KEY_PERMISSION_DENY,
|
||||
TXT_KEY_PERMISSION_UNKNOWN_WAYLAND_APP,
|
||||
|
||||
TXT_KEY_NOTIF_EXTERNAL_XDG_DESKTOP,
|
||||
TXT_KEY_NOTIF_NO_GUIUTILS,
|
||||
TXT_KEY_NOTIF_FAILED_ASSETS,
|
||||
TXT_KEY_NOTIF_INVALID_MONITOR_LAYOUT,
|
||||
TXT_KEY_NOTIF_MONITOR_MODE_FAIL,
|
||||
TXT_KEY_NOTIF_MONITOR_AUTO_SCALE,
|
||||
TXT_KEY_NOTIF_FAILED_TO_LOAD_PLUGIN,
|
||||
TXT_KEY_NOTIF_CM_RELOAD_FAILED,
|
||||
TXT_KEY_NOTIF_WIDE_COLOR_NOT_10B,
|
||||
};
|
||||
|
||||
class CI18nEngine {
|
||||
public:
|
||||
CI18nEngine();
|
||||
~CI18nEngine() = default;
|
||||
|
||||
std::string localize(eI18nKeys key, const std::unordered_map<std::string, std::string>& vars = {});
|
||||
};
|
||||
|
||||
SP<CI18nEngine> i18nEngine();
|
||||
};
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
#include "./eventLoop/EventLoopManager.hpp"
|
||||
#include "../config/ConfigValue.hpp"
|
||||
#include "../xwayland/XSurface.hpp"
|
||||
#include "../i18n/Engine.hpp"
|
||||
|
||||
using namespace Hyprutils::OS;
|
||||
|
||||
|
|
@ -83,7 +84,7 @@ void CANRManager::onTick() {
|
|||
|
||||
if (data->missedResponses >= *PANRTHRESHOLD) {
|
||||
if (!data->isRunning() && !data->dialogSaidWait) {
|
||||
data->runDialog("Application Not Responding", firstWindow->m_title, firstWindow->m_class, data->getPid());
|
||||
data->runDialog(firstWindow->m_title, firstWindow->m_class, data->getPid());
|
||||
|
||||
for (const auto& w : g_pCompositor->m_windows) {
|
||||
if (!w->m_isMapped)
|
||||
|
|
@ -176,16 +177,29 @@ CANRManager::SANRData::~SANRData() {
|
|||
killDialog();
|
||||
}
|
||||
|
||||
void CANRManager::SANRData::runDialog(const std::string& title, const std::string& appName, const std::string appClass, pid_t dialogWmPID) {
|
||||
void CANRManager::SANRData::runDialog(const std::string& appName, const std::string appClass, pid_t dialogWmPID) {
|
||||
if (dialogBox && dialogBox->isRunning())
|
||||
killDialog();
|
||||
|
||||
dialogBox = CAsyncDialogBox::create(title,
|
||||
std::format("Application {} with class of {} is not responding.\nWhat do you want to do with it?", appName.empty() ? "unknown" : appName,
|
||||
appClass.empty() ? "unknown" : appClass),
|
||||
std::vector<std::string>{"Terminate", "Wait"});
|
||||
const auto OPTION_TERMINATE_STR = I18n::i18nEngine()->localize(I18n::TXT_KEY_ANR_OPTION_TERMINATE, {});
|
||||
const auto OPTION_WAIT_STR = I18n::i18nEngine()->localize(I18n::TXT_KEY_ANR_OPTION_WAIT, {});
|
||||
|
||||
dialogBox->open()->then([dialogWmPID, this](SP<CPromiseResult<std::string>> r) {
|
||||
dialogBox =
|
||||
CAsyncDialogBox::create(I18n::i18nEngine()->localize(I18n::TXT_KEY_ANR_TITLE, {}),
|
||||
I18n::i18nEngine()->localize(I18n::TXT_KEY_ANR_CONTENT,
|
||||
{
|
||||
//
|
||||
{"class", appClass.empty() ? I18n::i18nEngine()->localize(I18n::TXT_KEY_ANR_PROP_UNKNOWN, {}) : appClass}, //
|
||||
{"title", appName.empty() ? I18n::i18nEngine()->localize(I18n::TXT_KEY_ANR_PROP_UNKNOWN, {}) : appName} //
|
||||
}),
|
||||
std::vector<std::string>{
|
||||
//
|
||||
OPTION_TERMINATE_STR, //
|
||||
OPTION_WAIT_STR //
|
||||
} //
|
||||
);
|
||||
|
||||
dialogBox->open()->then([dialogWmPID, this, OPTION_TERMINATE_STR, OPTION_WAIT_STR](SP<CPromiseResult<std::string>> r) {
|
||||
if (r->hasError()) {
|
||||
Debug::log(ERR, "CANRManager::SANRData::runDialog: error spawning dialog");
|
||||
return;
|
||||
|
|
@ -193,9 +207,9 @@ void CANRManager::SANRData::runDialog(const std::string& title, const std::strin
|
|||
|
||||
const auto& result = r->result();
|
||||
|
||||
if (result.starts_with("Terminate"))
|
||||
if (result.starts_with(OPTION_TERMINATE_STR))
|
||||
::kill(dialogWmPID, SIGKILL);
|
||||
else if (result.starts_with("Wait"))
|
||||
else if (result.starts_with(OPTION_WAIT_STR))
|
||||
dialogSaidWait = true;
|
||||
else
|
||||
Debug::log(ERR, "CANRManager::SANRData::runDialog: lambda: unrecognized result: {}", result);
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ class CANRManager {
|
|||
bool dialogSaidWait = false;
|
||||
SP<CAsyncDialogBox> dialogBox;
|
||||
|
||||
void runDialog(const std::string& title, const std::string& appName, const std::string appClass, pid_t dialogWmPID);
|
||||
void runDialog(const std::string& appName, const std::string appClass, pid_t dialogWmPID);
|
||||
bool isRunning();
|
||||
void killDialog();
|
||||
bool isDefunct() const;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "../../Compositor.hpp"
|
||||
#include "../../config/ConfigValue.hpp"
|
||||
#include "../../helpers/MiscFunctions.hpp"
|
||||
#include "../../i18n/Engine.hpp"
|
||||
|
||||
#include <hyprutils/string/String.hpp>
|
||||
using namespace Hyprutils::String;
|
||||
|
|
@ -57,17 +58,6 @@ static const char* permissionToString(eDynamicPermissionType type) {
|
|||
return "error";
|
||||
}
|
||||
|
||||
static const char* permissionToHumanString(eDynamicPermissionType type) {
|
||||
switch (type) {
|
||||
case PERMISSION_TYPE_UNKNOWN: return "An application <b>{}</b> is requesting an unknown permission.";
|
||||
case PERMISSION_TYPE_SCREENCOPY: return "An application <b>{}</b> is trying to capture your screen.<br/><br/>Do you want to allow it to do so?";
|
||||
case PERMISSION_TYPE_PLUGIN: return "An application <b>{}</b> is trying to load a plugin: <b>{}</b>.<br/><br/>Do you want to load it?";
|
||||
case PERMISSION_TYPE_KEYBOARD: return "A new keyboard has been plugged in: {}.<br/><br/>Do you want to allow it to operate?";
|
||||
}
|
||||
|
||||
return "error";
|
||||
}
|
||||
|
||||
static const char* specialPidToString(eSpecialPidTypes type) {
|
||||
switch (type) {
|
||||
case SPECIAL_PID_TYPE_CONFIG: return "config";
|
||||
|
|
@ -244,39 +234,41 @@ void CDynamicPermissionManager::askForPermission(wl_client* client, const std::s
|
|||
|
||||
rule->m_pid = pid;
|
||||
|
||||
std::string description = "";
|
||||
std::string appName = "";
|
||||
if (binaryPath.empty())
|
||||
description = std::format(std::runtime_format(permissionToHumanString(type)), std::format("unknown application (wayland client ID 0x{:x})", rc<uintptr_t>(client)));
|
||||
appName = I18n::i18nEngine()->localize(I18n::TXT_KEY_PERMISSION_UNKNOWN_WAYLAND_APP, {{"wayland_id", std::format("{:x}", rc<uintptr_t>(client))}});
|
||||
else if (client) {
|
||||
std::string binaryName = binaryPath.contains("/") ? binaryPath.substr(binaryPath.find_last_of('/') + 1) : binaryPath;
|
||||
description = std::format(std::runtime_format(permissionToHumanString(type)), std::format("{}</b> ({})", binaryName, binaryPath));
|
||||
appName = binaryPath.contains("/") ? binaryPath.substr(binaryPath.find_last_of('/') + 1) : binaryPath;
|
||||
} else {
|
||||
std::string lookup = "";
|
||||
if (pid < 0)
|
||||
lookup = specialPidToString(sc<eSpecialPidTypes>(pid));
|
||||
appName = specialPidToString(sc<eSpecialPidTypes>(pid));
|
||||
else {
|
||||
const auto LOOKUP = binaryNameForPid(pid);
|
||||
lookup = LOOKUP.value_or("Unknown");
|
||||
}
|
||||
|
||||
if (type == PERMISSION_TYPE_PLUGIN) {
|
||||
const auto LOOKUP = binaryNameForPid(pid);
|
||||
description = std::format(std::runtime_format(permissionToHumanString(type)), lookup, binaryPath);
|
||||
} else {
|
||||
const auto LOOKUP = binaryNameForPid(pid);
|
||||
description = std::format(std::runtime_format(permissionToHumanString(type)), lookup, binaryPath);
|
||||
appName = LOOKUP.value_or(I18n::i18nEngine()->localize(I18n::TXT_KEY_PERMISSION_UNKNOWN_NAME));
|
||||
}
|
||||
}
|
||||
|
||||
std::string description = "";
|
||||
switch (rule->m_type) {
|
||||
case PERMISSION_TYPE_SCREENCOPY: description = I18n::i18nEngine()->localize(I18n::TXT_KEY_PERMISSION_REQUEST_SCREENCOPY, {{"app", appName}}); break;
|
||||
case PERMISSION_TYPE_PLUGIN: description = I18n::i18nEngine()->localize(I18n::TXT_KEY_PERMISSION_REQUEST_SCREENCOPY, {{"app", appName}, {"plugin", binaryPath}}); break;
|
||||
case PERMISSION_TYPE_KEYBOARD: description = I18n::i18nEngine()->localize(I18n::TXT_KEY_PERMISSION_REQUEST_KEYBOARD, {{"keyboard", binaryPath}}); break;
|
||||
case PERMISSION_TYPE_UNKNOWN: description = I18n::i18nEngine()->localize(I18n::TXT_KEY_PERMISSION_REQUEST_UNKNOWN, {{"app", appName}}); break;
|
||||
}
|
||||
|
||||
std::vector<std::string> options;
|
||||
const auto ALLOW = I18n::i18nEngine()->localize(I18n::TXT_KEY_PERMISSION_ALLOW);
|
||||
const auto ALLOW_AND_REMEMBER = I18n::i18nEngine()->localize(I18n::TXT_KEY_PERMISSION_ALLOW_AND_REMEMBER);
|
||||
const auto ALLOW_ONCE = I18n::i18nEngine()->localize(I18n::TXT_KEY_PERMISSION_ALLOW_ONCE);
|
||||
const auto DENY = I18n::i18nEngine()->localize(I18n::TXT_KEY_PERMISSION_DENY);
|
||||
|
||||
if (!binaryPath.empty() && client) {
|
||||
description += "<br/><br/><i>Hint: you can set persistent rules for these in the Hyprland config file.</i>";
|
||||
options = {"Deny", "Allow and remember app", "Allow once"};
|
||||
description += std::format("<br/><br/><i>{}</i>", I18n::i18nEngine()->localize(I18n::TXT_KEY_PERMISSION_PERSISTENCE_HINT));
|
||||
options = {DENY, ALLOW_AND_REMEMBER, ALLOW_ONCE};
|
||||
} else
|
||||
options = {"Deny", "Allow"};
|
||||
options = {DENY, ALLOW};
|
||||
|
||||
rule->m_dialogBox = CAsyncDialogBox::create("Permission request", description, options);
|
||||
rule->m_dialogBox = CAsyncDialogBox::create(I18n::i18nEngine()->localize(I18n::TXT_KEY_PERMISSION_TITLE), description, options);
|
||||
rule->m_dialogBox->m_priority = true;
|
||||
|
||||
if (!rule->m_dialogBox) {
|
||||
|
|
@ -286,7 +278,7 @@ void CDynamicPermissionManager::askForPermission(wl_client* client, const std::s
|
|||
}
|
||||
|
||||
rule->m_promise = rule->m_dialogBox->open();
|
||||
rule->m_promise->then([r = WP<CDynamicPermissionRule>(rule), binaryPath](SP<CPromiseResult<std::string>> pr) {
|
||||
rule->m_promise->then([r = WP<CDynamicPermissionRule>(rule), binaryPath, ALLOW, ALLOW_AND_REMEMBER, ALLOW_ONCE, DENY](SP<CPromiseResult<std::string>> pr) {
|
||||
if (!r)
|
||||
return;
|
||||
|
||||
|
|
@ -303,15 +295,15 @@ void CDynamicPermissionManager::askForPermission(wl_client* client, const std::s
|
|||
|
||||
Debug::log(TRACE, "CDynamicPermissionRule: user returned {}", result);
|
||||
|
||||
if (result.starts_with("Allow once"))
|
||||
if (result.starts_with(ALLOW_ONCE))
|
||||
r->m_allowMode = PERMISSION_RULE_ALLOW_MODE_ALLOW;
|
||||
else if (result.starts_with("Deny")) {
|
||||
else if (result.starts_with(DENY)) {
|
||||
r->m_allowMode = PERMISSION_RULE_ALLOW_MODE_DENY;
|
||||
r->m_binaryPath = binaryPath;
|
||||
} else if (result.starts_with("Allow and remember")) {
|
||||
} else if (result.starts_with(ALLOW_AND_REMEMBER)) {
|
||||
r->m_allowMode = PERMISSION_RULE_ALLOW_MODE_ALLOW;
|
||||
r->m_binaryPath = binaryPath;
|
||||
} else if (result.starts_with("Allow"))
|
||||
} else if (result.starts_with(ALLOW))
|
||||
r->m_allowMode = PERMISSION_RULE_ALLOW_MODE_ALLOW;
|
||||
|
||||
if (r->m_promiseResolverForExternal)
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include "../managers/eventLoop/EventLoopManager.hpp"
|
||||
#include "../managers/permissions/DynamicPermissionManager.hpp"
|
||||
#include "../debug/HyprNotificationOverlay.hpp"
|
||||
#include "../i18n/Engine.hpp"
|
||||
|
||||
CPluginSystem::CPluginSystem() {
|
||||
g_pFunctionHookSystem = makeUnique<CHookSystem>();
|
||||
|
|
@ -224,7 +225,8 @@ void CPluginSystem::updateConfigPlugins(const std::vector<std::string>& plugins,
|
|||
if (result->hasError()) {
|
||||
const auto NAME = path.contains('/') ? path.substr(path.find_last_of('/') + 1) : path;
|
||||
Debug::log(ERR, "CPluginSystem::updateConfigPlugins: failed to load plugin {}: {}", NAME, result->error());
|
||||
g_pHyprNotificationOverlay->addNotification(std::format("Failed to load plugin {}: {}", NAME, result->error()), CHyprColor{0, 0, 0, 0}, 5000, ICON_ERROR);
|
||||
g_pHyprNotificationOverlay->addNotification(I18n::i18nEngine()->localize(I18n::TXT_KEY_NOTIF_FAILED_TO_LOAD_PLUGIN, {{"name", NAME}, {"error", result->error()}}),
|
||||
CHyprColor{0, 0, 0, 0}, 5000, ICON_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include "../managers/CursorManager.hpp"
|
||||
#include "../helpers/fs/FsUtils.hpp"
|
||||
#include "../helpers/MainLoopExecutor.hpp"
|
||||
#include "../i18n/Engine.hpp"
|
||||
#include "debug/HyprNotificationOverlay.hpp"
|
||||
#include "hyprerror/HyprError.hpp"
|
||||
#include "pass/TexPassElement.hpp"
|
||||
|
|
@ -1006,7 +1007,7 @@ bool CHyprOpenGLImpl::initShaders() {
|
|||
|
||||
prog = createProgram(shaders->TEXVERTSRC, TEXFRAGSRCCM, true, true);
|
||||
if (m_shadersInitialized && m_cmSupported && prog == 0)
|
||||
g_pHyprNotificationOverlay->addNotification("CM shader reload failed, falling back to rgba/rgbx", CHyprColor{}, 15000, ICON_WARNING);
|
||||
g_pHyprNotificationOverlay->addNotification(I18n::i18nEngine()->localize(I18n::TXT_KEY_NOTIF_CM_RELOAD_FAILED), CHyprColor{}, 15000, ICON_WARNING);
|
||||
|
||||
m_cmSupported = prog > 0;
|
||||
if (m_cmSupported) {
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include "../hyprerror/HyprError.hpp"
|
||||
#include "../debug/HyprDebugOverlay.hpp"
|
||||
#include "../debug/HyprNotificationOverlay.hpp"
|
||||
#include "../i18n/Engine.hpp"
|
||||
#include "helpers/CursorShapes.hpp"
|
||||
#include "helpers/Monitor.hpp"
|
||||
#include "pass/TexPassElement.hpp"
|
||||
|
|
@ -1576,7 +1577,8 @@ bool CHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) {
|
|||
Debug::log(WARN, "Wide color gamut is enabled but the display is not in 10bit mode");
|
||||
static bool shown = false;
|
||||
if (!shown) {
|
||||
g_pHyprNotificationOverlay->addNotification("Wide color gamut is enabled but the display is not in 10bit mode", CHyprColor{}, 15000, ICON_WARNING);
|
||||
g_pHyprNotificationOverlay->addNotification(I18n::i18nEngine()->localize(I18n::TXT_KEY_NOTIF_WIDE_COLOR_NOT_10B, {{"name", pMonitor->m_name}}), CHyprColor{}, 15000,
|
||||
ICON_WARNING);
|
||||
shown = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue