diff --git a/CHANGELOG.md b/CHANGELOG.md index 89be3b5..2121e38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -68,6 +68,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `WrapperWidget::activate`'s default implementation now activates the wrapped widget. - `Space` now intercepts mouse events if its color has a non-zero alpha channel. +- `Image` now honors `CornerRadius`. Thanks to @danbulant for this change! ### Fixed @@ -203,6 +204,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Dimension::is_unbounded` is a new helper that returns true if neither the start or end is bounded. - `&String` and `Cow<'_, str>` now implement `MakeWidget`. +- Cargo feature `native-dialogs` has been added to enable native dialogs to be + shown by Cushy applications. +- `PendingApp::with_on_unrecoverable_error` allows overriding the default + behavior when an unrecoverable error occurs. Previously, all unrecoverable + errors resulted in a panic. The new default behavior uses the `native-dialogs` + feature when enabled to display the error using a system-native message + dialog. - `MessageBox` displays a prompt to the user in a `Modal` layer, above a `WindowHandle`, or in an `App`. When shown above a window or app, the `rfd` crate is used to use the native system dialogs. diff --git a/Cargo.lock b/Cargo.lock index 4ce290d..255e175 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "ab_glyph" -version = "0.2.28" +version = "0.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79faae4620f45232f599d9bc7b290f88247a0834162c4495ab2f02d60004adfb" +checksum = "ec3672c180e71eeaaac3a541fbbc5f5ad4def8b747c595ad30d674e43049f7b0" dependencies = [ "ab_glyph_rasterizer", "owned_ttf_parser", @@ -124,7 +124,7 @@ checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "appit" version = "0.4.0" -source = "git+https://github.com/khonsulabs/appit#662cebf193a9adc1b2f19cf048fb8a359f74059a" +source = "git+https://github.com/khonsulabs/appit#be6918d5ebb6a2ad7911f621bb7db3676ce8b290" dependencies = [ "darkmode", "winit", @@ -617,9 +617,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.24" +version = "1.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812acba72f0a070b003d3697490d2b55b837230ae7c6c6497f05cc2ddbb8d938" +checksum = "2e80e3b6a3ab07840e1cae9b0666a63970dc28e8ed5ffbcdacbfc760c281bfc1" dependencies = [ "jobserver", "libc", @@ -1267,24 +1267,24 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", ] [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-lite" @@ -1301,9 +1301,9 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", @@ -1312,21 +1312,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-core", "futures-io", @@ -1729,7 +1729,7 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" [[package]] name = "kludgine" version = "0.11.0" -source = "git+https://github.com/khonsulabs/kludgine#58e83f1200375673300918c82f622c499a4028fa" +source = "git+https://github.com/khonsulabs/kludgine#3ce7d43f8870a3455f46ab2c2fba997ca36a1f60" dependencies = [ "ahash", "alot", @@ -2412,12 +2412,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.1" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1" -dependencies = [ - "portable-atomic", -] +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "orbclient" @@ -2446,11 +2443,11 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "owned_ttf_parser" -version = "0.24.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "490d3a563d3122bf7c911a59b0add9389e5ec0f5f0c3ac6b91ff235a0e6a7f90" +checksum = "22ec719bbf3b2a81c109a4e20b1f129b5566b7dce654bc3872f6a05abf82b2c4" dependencies = [ - "ttf-parser 0.24.1", + "ttf-parser 0.25.0", ] [[package]] @@ -2562,18 +2559,18 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.5" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +checksum = "baf123a161dde1e524adf36f90bc5d8d3462824a9c43553ad07a8183161189ec" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.5" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +checksum = "a4502d8515ca9f32f1fb543d987f63d95a14934883db45bdb48060b6b69257f8" dependencies = [ "proc-macro2", "quote", @@ -2661,12 +2658,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2" -[[package]] -name = "portable-atomic" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" - [[package]] name = "ppv-lite86" version = "0.2.20" @@ -3598,9 +3589,9 @@ checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8" [[package]] name = "ttf-parser" -version = "0.24.1" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be21190ff5d38e8b4a2d3b6a3ae57f612cc39c96e83cedeaf7abc338a8bac4a" +checksum = "5902c5d130972a0000f60860bfbf46f7ca3db5391eddfedd1b8728bd9dc96c0e" [[package]] name = "typenum" diff --git a/src/app.rs b/src/app.rs index 33751d0..76baca6 100644 --- a/src/app.rs +++ b/src/app.rs @@ -6,7 +6,7 @@ use std::time::Duration; use arboard::Clipboard; use kludgine::app::winit::error::EventLoopError; -use kludgine::app::{AppEvent, AsApplication, ExecutingApp, Monitors}; +use kludgine::app::{AppEvent, AsApplication, ExecutingApp, Monitors, UnrecoverableError}; use parking_lot::{Mutex, MutexGuard}; use crate::fonts::FontCollection; @@ -59,12 +59,34 @@ impl PendingApp { /// [`with_tracing()`](Self::with_tracing)/[`initialize_tracing()`](Self::initialize_tracing) /// to enable Cushy's built-in trace handling. pub fn new(runtime: Runtime) -> Self { + let mut app = kludgine::app::PendingApp::default(); + app.on_unrecoverable_error(Self::unrecoverable_error); Self { - app: kludgine::app::PendingApp::default(), + app, cushy: Cushy::new(BoxedRuntime(Box::new(runtime))), } } + /// Sets the error handler that is invoked when Cushy encounters an error + /// that it cannot recover from. + /// + /// # Default Behavior + /// + /// If `native-dialogs` is enabled, the default handler will display the + /// error using a system-native message dialog. Otherwise, the default + /// handler will panic. + /// + /// Calling this function will override the default behavior with + /// `on_error`. + #[must_use] + pub fn with_on_unrecoverable_error(mut self, on_error: F) -> Self + where + F: FnMut(UnrecoverableError) + 'static, + { + self.app.on_unrecoverable_error(on_error); + self + } + /// Installs a global `tracing` Subscriber and returns self. #[must_use] pub fn with_tracing(self) -> Self { @@ -110,6 +132,23 @@ impl PendingApp { }); }); } + + #[cfg(feature = "native-dialogs")] + #[allow(clippy::needless_pass_by_value)] + fn unrecoverable_error(err: UnrecoverableError) { + let _ = rfd::MessageDialog::new() + .set_title("An unrecoverable error has occurred") + .set_description(err.to_string()) + .set_level(rfd::MessageLevel::Error) + .show(); + exit(-1); + } + + #[cfg(not(feature = "native-dialogs"))] + #[allow(clippy::needless_pass_by_value)] + fn unrecoverable_error(err: UnrecoverableError) { + unreachable!("error initializing window: {err}"); + } } impl Run for PendingApp {