mirror of
https://github.com/storytold/lightcraft.git
synced 2026-10-24 10:09:01 -06:00
Merge pull request #370 from storytold/claude/fix-260-startup-failure-dialog
Part of #260: a desktop start that fails says why, in a message box naming the log
This commit is contained in:
@@ -523,11 +523,15 @@ fn main() -> eframe::Result {
|
||||
}
|
||||
// The log file: opened after the arguments, so `--version`, `--help` and a usage error leave
|
||||
// no file behind. Records logged until now are written to it first.
|
||||
let mut log_file = None;
|
||||
if let Some(logger) = logger {
|
||||
// a --memory session writes nothing (issue #164), a log file included
|
||||
match log_dir().filter(|_| !in_memory) {
|
||||
Some(dir) => match logger.attach_dir(&dir) {
|
||||
Ok(path) => log::info!("LightCraft {}, log file {}", env!("CARGO_PKG_VERSION"), path.display()),
|
||||
Ok(path) => {
|
||||
log::info!("LightCraft {}, log file {}", env!("CARGO_PKG_VERSION"), path.display());
|
||||
log_file = Some(path);
|
||||
}
|
||||
// The file sink has given up by now, so this goes to standard error only.
|
||||
Err(e) => log::warn!("no log file: {e}"),
|
||||
},
|
||||
@@ -535,6 +539,10 @@ fn main() -> eframe::Result {
|
||||
}
|
||||
}
|
||||
let (prefs, prefs_warning, keep_prefs_file) = load_prefs(in_memory);
|
||||
// the saved language from the start, so a failed start is reported in it too
|
||||
if let Some(ui) = &prefs {
|
||||
lightcraft_ui_egui::i18n::set_language(ui.language);
|
||||
}
|
||||
// --library, else the library last opened from Settings, else the default location
|
||||
let library_dir = library_dir.or_else(|| {
|
||||
prefs
|
||||
@@ -564,7 +572,7 @@ fn main() -> eframe::Result {
|
||||
wgpu_options: window_wgpu_options(),
|
||||
..Default::default()
|
||||
};
|
||||
eframe::run_native(
|
||||
let started = eframe::run_native(
|
||||
"LightCraft",
|
||||
options,
|
||||
Box::new(move |cc| {
|
||||
@@ -618,7 +626,28 @@ fn main() -> eframe::Result {
|
||||
menu,
|
||||
)))
|
||||
}),
|
||||
)
|
||||
);
|
||||
if let Err(e) = &started {
|
||||
startup_failed(&e.to_string(), log_file.as_deref());
|
||||
}
|
||||
started
|
||||
}
|
||||
|
||||
/// The window could not start (e.g. no usable graphics device): say so in the log and in a native
|
||||
/// message box naming the log file, instead of exiting without a trace — the release builds have
|
||||
/// no console on Windows, and an app started from Finder shows no standard error (issue #260).
|
||||
fn startup_failed(error: &str, log_file: Option<&std::path::Path>) {
|
||||
log::error!("LightCraft could not open its window: {error}");
|
||||
if std::env::var_os("LIGHTCRAFT_NO_PREFS").is_some() {
|
||||
return; // tests and scripts: no dialog to click away
|
||||
}
|
||||
let (title, text) = lightcraft_ui_egui::i18n::startup_failed_message(error, log_file.map(|p| p.display().to_string()).as_deref());
|
||||
let _ = rfd::MessageDialog::new()
|
||||
.set_level(rfd::MessageLevel::Error)
|
||||
.set_title(title)
|
||||
.set_description(text)
|
||||
.set_buttons(rfd::MessageButtons::Ok)
|
||||
.show();
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
"Imported {} photo{}": "{} Foto{} importiert",
|
||||
"Insert at the cursor (also written {})": "An Cursorposition einfügen (auch als {} geschrieben)",
|
||||
"Label Set: {name}": "Farbmarkierungssatz: {name}",
|
||||
"LightCraft could not open its window: {e}": "LightCraft konnte sein Fenster nicht öffnen: {e}",
|
||||
"LightCraft could not open its window: {e}\n\nThe log file has the details: {path}": "LightCraft konnte sein Fenster nicht öffnen: {e}\n\nEinzelheiten stehen in der Protokolldatei: {path}",
|
||||
"MIT OR Apache-2.0. Fonts: {} (OFL). Icons: original.": "MIT ODER Apache-2.0. Schriften: {} (OFL). Symbole: eigene Gestaltung.",
|
||||
"Matches: {}": "Treffer: {}",
|
||||
"Merging… {stage} {:.0}%": "Wird zusammengefügt… {stage} {:.0}%",
|
||||
|
||||
@@ -753,6 +753,7 @@
|
||||
"LightCraft Preset": "LightCraft-Vorgabe",
|
||||
"LightCraft Presets": "LightCraft-Vorgaben",
|
||||
"LightCraft Website": "LightCraft-Website",
|
||||
"LightCraft could not start": "LightCraft konnte nicht starten",
|
||||
"LightCraft couldn't find where to keep your library.": "LightCraft konnte keinen Speicherort für deine Bibliothek finden.",
|
||||
"LightCraft couldn't open the library at": "LightCraft konnte die Bibliothek nicht öffnen unter",
|
||||
"LightCraft no longer crashes at launch on Windows PCs whose Vulkan driver is broken (issue #136, e.g. some Intel UHD": "LightCraft stürzt beim Start auf Windows-PCs mit defektem Vulkan-Treiber nicht mehr ab (Issue #136, etwa bestimmte Intel-UHD-630-Treiber).",
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
"Imported {n} preset{}": "{n}件のプリセットを読み込みました{:.0}",
|
||||
"Imported {n} preset{}, {f} file{} not readable": "{n}件のプリセットを読み込みました{:.0}。{f}件は読み込めません{:.0}",
|
||||
"Imported {} photo{}": "{}枚を読み込みました{:.0}",
|
||||
"LightCraft could not open its window: {e}": "LightCraftのウィンドウを開けませんでした: {e}",
|
||||
"LightCraft could not open its window: {e}\n\nThe log file has the details: {path}": "LightCraftのウィンドウを開けませんでした: {e}\n\n詳しくはログファイルをご覧ください: {path}",
|
||||
"Matches: {}": "一致条件:{}",
|
||||
"Merging… {stage} {:.0}%": "合成中… {stage} {:.0}%",
|
||||
"Move {what} to Recently Deleted?": "{what}を「最近削除した写真」に移動しますか?",
|
||||
|
||||
@@ -531,6 +531,7 @@
|
||||
"Library State": "ライブラリの状態",
|
||||
"Library saved": "ライブラリを保存しました",
|
||||
"Licence:": "ライセンス:",
|
||||
"LightCraft could not start": "LightCraftを起動できませんでした",
|
||||
"Line delta": "行数の増減",
|
||||
"Linear": "リニア",
|
||||
"Lines +/−": "行数 +/−",
|
||||
|
||||
@@ -46,6 +46,8 @@
|
||||
"Imported {n} preset{}, {f} file{} not readable": "Importadas {n} predefinição{:.0}, {f} arquivo{:.0} não legível",
|
||||
"Imported {} photo{}": "Importadas {} foto{:.0}",
|
||||
"Label Set: {name}": "Conjunto de rótulos: {name}",
|
||||
"LightCraft could not open its window: {e}": "O LightCraft não conseguiu abrir sua janela: {e}",
|
||||
"LightCraft could not open its window: {e}\n\nThe log file has the details: {path}": "O LightCraft não conseguiu abrir sua janela: {e}\n\nO arquivo de log tem os detalhes: {path}",
|
||||
"Matches: {}": "Correspondências: {}",
|
||||
"Merging… {stage} {:.0}%": "Mesclando… {stage} {:.0}%",
|
||||
"Move {what} to Recently Deleted?": "Mover {what} para Excluídos recentemente?",
|
||||
|
||||
@@ -721,6 +721,7 @@
|
||||
"LightCraft Preset": "Predefinição do LightCraft",
|
||||
"LightCraft Presets": "Predefinições do LightCraft",
|
||||
"LightCraft Website": "Site do LightCraft",
|
||||
"LightCraft could not start": "Não foi possível iniciar o LightCraft",
|
||||
"LightCraft couldn't find where to keep your library.": "O LightCraft não conseguiu encontrar onde guardar sua biblioteca.",
|
||||
"LightCraft couldn't open the library at": "O LightCraft não conseguiu abrir a biblioteca em",
|
||||
"LightCraft on GitHub": "LightCraft no GitHub",
|
||||
|
||||
@@ -71,6 +71,8 @@
|
||||
"Insert at the cursor (also written {})": "Вставить в позицию курсора (также пишется как {})",
|
||||
"Label Set: {name}": "Набор меток: {name}",
|
||||
"LightCraft can't decode this raw variant yet ({}). You're editing the camera's embedded JPEG preview, which already includes the camera's picture style (e.g. Monochrome) and white balance.": "LightCraft пока не умеет декодировать этот вариант RAW ({}). Вы редактируете встроенный в файл JPEG-просмотр камеры, в котором уже применены стиль изображения камеры (например, «Монохром») и баланс белого.",
|
||||
"LightCraft could not open its window: {e}": "LightCraft не удалось открыть окно: {e}",
|
||||
"LightCraft could not open its window: {e}\n\nThe log file has the details: {path}": "LightCraft не удалось открыть окно: {e}\n\nПодробности в файле журнала: {path}",
|
||||
"MIT OR Apache-2.0. Fonts: {} (OFL). Icons: original.": "MIT OR Apache-2.0. Шрифты: {} (OFL). Значки: оригинальные.",
|
||||
"Matches: {}": "Совпадения: {}",
|
||||
"Merging… {stage} {:.0}%": "Слияние… {stage} {:.0}%",
|
||||
|
||||
@@ -590,6 +590,7 @@
|
||||
"LightCraft Preset": "Пресет LightCraft",
|
||||
"LightCraft Presets": "Пресеты LightCraft",
|
||||
"LightCraft Website": "Сайт LightCraft",
|
||||
"LightCraft could not start": "Не удалось запустить LightCraft",
|
||||
"LightCraft couldn't find where to keep your library.": "LightCraft не удалось найти место для хранения вашей библиотеки.",
|
||||
"LightCraft couldn't open the library at": "LightCraft не удалось открыть библиотеку в",
|
||||
"LightCraft on GitHub": "LightCraft на GitHub",
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
"Imported {n} preset{}": "已导入 {n} 个预设{0:.0}",
|
||||
"Imported {n} preset{}, {f} file{} not readable": "已导入 {n} 个预设,{f} 个文件无法读取{0:.0}{1:.0}",
|
||||
"Imported {} photo{}": "已导入 {0} 张照片{1:.0}",
|
||||
"LightCraft could not open its window: {e}": "LightCraft 无法打开窗口:{e}",
|
||||
"LightCraft could not open its window: {e}\n\nThe log file has the details: {path}": "LightCraft 无法打开窗口:{e}\n\n详细信息见日志文件:{path}",
|
||||
"Matches: {}": "匹配项:{0}",
|
||||
"Merging… {stage} {:.0}%": "合成中… {stage} {0:.0}%",
|
||||
"Move {what} to Recently Deleted?": "将 {what} 移到最近删除?",
|
||||
|
||||
@@ -523,6 +523,7 @@
|
||||
"Lens Blur": "镜头模糊",
|
||||
"Library saved": "图库已保存",
|
||||
"Licence:": "许可证:",
|
||||
"LightCraft could not start": "LightCraft 无法启动",
|
||||
"Line delta": "行数差",
|
||||
"Linear": "线性",
|
||||
"Lines +/−": "行数 +/−",
|
||||
|
||||
@@ -43,6 +43,8 @@
|
||||
"Imported {n} preset{}, {f} file{} not readable": "已匯入 {n} 個預設集{:.0},{f} 個檔案無法讀取{:.0}",
|
||||
"Imported {} photo{}": "已匯入 {} 張照片{:.0}",
|
||||
"Label Set: {name}": "標籤集:{name}",
|
||||
"LightCraft could not open its window: {e}": "LightCraft 無法開啟視窗:{e}",
|
||||
"LightCraft could not open its window: {e}\n\nThe log file has the details: {path}": "LightCraft 無法開啟視窗:{e}\n\n詳細資訊請見記錄檔:{path}",
|
||||
"Matches: {}": "符合條件:{}",
|
||||
"Merging… {stage} {:.0}%": "正在合併… {stage} {:.0}%",
|
||||
"Move {what} to Recently Deleted?": "要將{what}移至「最近刪除」嗎?",
|
||||
|
||||
@@ -523,6 +523,7 @@
|
||||
"Lens Blur": "鏡頭模糊",
|
||||
"Library saved": "照片庫已儲存",
|
||||
"Licence:": "授權:",
|
||||
"LightCraft could not start": "LightCraft 無法啟動",
|
||||
"Line delta": "行數差",
|
||||
"Linear": "線性",
|
||||
"Lines +/−": "行數 +/−",
|
||||
|
||||
@@ -189,6 +189,16 @@ include!(concat!(env!("OUT_DIR"), "/tr-formats.rs"));
|
||||
|
||||
/// A stock preset's or profile's name in the UI language; an imported or user-edited name stays
|
||||
/// exactly as its owner wrote it.
|
||||
/// The title and text of the message box shown when the desktop app's window can't start
|
||||
/// (issue #260), in the UI language: the error and, when there is one, the log file to look in.
|
||||
pub fn startup_failed_message(error: &str, log_file: Option<&str>) -> (String, String) {
|
||||
let text = match log_file {
|
||||
Some(path) => tr_format!("LightCraft could not open its window: {e}\n\nThe log file has the details: {path}", e = error, path = path),
|
||||
None => tr_format!("LightCraft could not open its window: {e}", e = error),
|
||||
};
|
||||
(tr("LightCraft could not start").to_string(), text)
|
||||
}
|
||||
|
||||
pub fn builtin_label(source: &str, builtin: bool) -> &str {
|
||||
if builtin { tr(source) } else { source }
|
||||
}
|
||||
@@ -404,6 +414,16 @@ mod tests {
|
||||
}
|
||||
|
||||
/// Locale tags are matched leniently, so a system locale reaches a shipped language.
|
||||
/// The message box for a desktop start that failed (issue #260) names the error and the log
|
||||
/// file, in the UI language.
|
||||
#[test]
|
||||
fn startup_failure_message_names_the_error_and_the_log() {
|
||||
let (title, text) = startup_failed_message("no adapter", Some("/home/a/.config/lightcraft/logs/lightcraft.log"));
|
||||
assert_eq!(title, "LightCraft could not start");
|
||||
assert!(text.contains("no adapter") && text.ends_with("lightcraft.log"), "{text}");
|
||||
assert!(!startup_failed_message("no adapter", None).1.contains("log file"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn locale_tags_normalize() {
|
||||
assert_eq!(Locale::parse_tag("en"), Some(Locale::En));
|
||||
|
||||
@@ -63,6 +63,8 @@
|
||||
promise, instead of filtering whatever album or folder was open, which often showed nothing (issue #341).
|
||||
|
||||
### Reliability
|
||||
- If the desktop app can't open its window (for example when no graphics device can be used), it now says so in a
|
||||
message box that names the log file, instead of quitting without a trace (issue #260).
|
||||
- On macOS, single-key shortcuts that appear in the menu bar now work: E, C, H, M, ⇧P, I, K, D, ratings 0–5,
|
||||
labels 6–9, P / U and the rest did nothing, because macOS only passes ⌘ / ⌃ combinations and function keys
|
||||
to the menu bar and the app ignored those keys, assuming the menu bar would handle them. Keys outside the menus
|
||||
|
||||
Reference in New Issue
Block a user