mirror of
https://github.com/danbulant/cushy
synced 2026-06-18 14:01:10 +00:00
parent
8f5ce94a87
commit
b57188f80f
9 changed files with 346 additions and 20 deletions
|
|
@ -251,6 +251,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- `OverlayLayer::dismiss_all()` dismisses all overlays immediately.
|
||||
- `Menu` is a new widget type that can be shown in an `OverlayLayer` to create
|
||||
contextual menus or other popup menus.
|
||||
- `PendingApp::new` is a new function that accepts an `AppRuntime` implementor.
|
||||
This abstraction is how Cushy provides the optional integration for `tokio`.
|
||||
- Features `tokio` and `tokio-multi-thread` enable the tokio integration for
|
||||
this crate and expose a new type `TokioRuntime`. The `DefaultRuntime`
|
||||
automatically will use the `TokioRuntime` if either feature is enabled.
|
||||
|
||||
When the `tokio` integration is enabled, `tokio::spawn` is able to be invoked
|
||||
from all Cushy code safely.
|
||||
|
||||
[plotters]: https://github.com/plotters-rs/plotters
|
||||
|
||||
|
|
|
|||
69
Cargo.lock
generated
69
Cargo.lock
generated
|
|
@ -18,6 +18,15 @@ version = "0.1.8"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046"
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
|
|
@ -248,6 +257,21 @@ dependencies = [
|
|||
"arrayvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit-set"
|
||||
version = "0.5.3"
|
||||
|
|
@ -652,6 +676,7 @@ dependencies = [
|
|||
"png",
|
||||
"pollster",
|
||||
"rand",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"unicode-segmentation",
|
||||
|
|
@ -941,6 +966,12 @@ dependencies = [
|
|||
"weezl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
|
||||
|
||||
[[package]]
|
||||
name = "gl_generator"
|
||||
version = "0.14.0"
|
||||
|
|
@ -1262,7 +1293,7 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
|
|||
[[package]]
|
||||
name = "kludgine"
|
||||
version = "0.7.0"
|
||||
source = "git+https://github.com/khonsulabs/kludgine#d98e0d6d2fa9e40e0c6a9d5b9b5c8079ba3a2e62"
|
||||
source = "git+https://github.com/khonsulabs/kludgine#eed5d9e5c51ab9c29bb6014ca282852504d2ac87"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"alot",
|
||||
|
|
@ -1697,6 +1728,16 @@ dependencies = [
|
|||
"libm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum"
|
||||
version = "0.7.2"
|
||||
|
|
@ -1783,6 +1824,15 @@ dependencies = [
|
|||
"objc2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.32.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.19.0"
|
||||
|
|
@ -2358,6 +2408,12 @@ version = "0.19.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3cd14fd5e3b777a7422cca79358c57a8f6e3a703d9ac187448d0daf220c2407f"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
|
|
@ -2744,6 +2800,17 @@ version = "0.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.37.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"num_cpus",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.8.12"
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ default = ["tracing-output", "roboto-flex"]
|
|||
tracing-output = ["dep:tracing-subscriber"]
|
||||
roboto-flex = []
|
||||
plotters = ["dep:plotters", "kludgine/plotters"]
|
||||
tokio = ["dep:tokio"]
|
||||
tokio-multi-thread = ["tokio", "tokio/rt-multi-thread"]
|
||||
|
||||
[dependencies]
|
||||
# kludgine = { version = "0.7.0", features = ["app"] }
|
||||
|
|
@ -30,6 +32,7 @@ interner = "0.2.1"
|
|||
kempt = "0.2.1"
|
||||
intentional = "0.1.0"
|
||||
tracing = "0.1.40"
|
||||
tokio = { version = "1.37.0", optional = true, features = ["rt"] }
|
||||
|
||||
tracing-subscriber = { version = "0.3", optional = true, features = [
|
||||
"env-filter",
|
||||
|
|
@ -67,11 +70,16 @@ opt-level = 2
|
|||
|
||||
[dev-dependencies]
|
||||
rand = "0.8.5"
|
||||
tokio = { version = "1.37.0", features = ["time"] }
|
||||
|
||||
[[example]]
|
||||
name = "plotters"
|
||||
required-features = ["plotters"]
|
||||
|
||||
[[example]]
|
||||
name = "tokio"
|
||||
required-features = ["tokio"]
|
||||
|
||||
[profile.release]
|
||||
# debug = true
|
||||
# opt-level = "s"
|
||||
|
|
|
|||
31
examples/tokio.rs
Normal file
31
examples/tokio.rs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
use std::time::Duration;
|
||||
|
||||
use cushy::value::{Destination, Dynamic};
|
||||
use cushy::widget::MakeWidget;
|
||||
use cushy::widgets::progress::Progressable;
|
||||
use cushy::{Open, PendingApp, TokioRuntime};
|
||||
use tokio::time::sleep;
|
||||
|
||||
fn main() {
|
||||
let app = PendingApp::new(TokioRuntime::default());
|
||||
let progress = Dynamic::new(0_u8);
|
||||
let progress_bar = progress.clone().progress_bar();
|
||||
"Press Me"
|
||||
.into_button()
|
||||
.on_click(move |_| {
|
||||
tokio::spawn(do_something(progress.clone()));
|
||||
})
|
||||
.and(progress_bar)
|
||||
.into_rows()
|
||||
.centered()
|
||||
.expand()
|
||||
.run_in(app)
|
||||
.expect("error starting Cushy");
|
||||
}
|
||||
|
||||
async fn do_something(progress: Dynamic<u8>) {
|
||||
for i in 0..u8::MAX {
|
||||
progress.set(i);
|
||||
sleep(Duration::from_millis(10)).await
|
||||
}
|
||||
}
|
||||
|
|
@ -59,20 +59,26 @@ use crate::animation::easings::Linear;
|
|||
use crate::styles::{Component, RequireInvalidation};
|
||||
use crate::utils::run_in_bg;
|
||||
use crate::value::{Destination, Dynamic, Source};
|
||||
use crate::Cushy;
|
||||
|
||||
static ANIMATIONS: Mutex<Animating> = Mutex::new(Animating::new());
|
||||
static NEW_ANIMATIONS: Condvar = Condvar::new();
|
||||
|
||||
fn thread_state() -> MutexGuard<'static, Animating> {
|
||||
pub(crate) fn spawn(app: Cushy) {
|
||||
let _ignored = thread_state(Some(app));
|
||||
}
|
||||
|
||||
fn thread_state(app: Option<Cushy>) -> MutexGuard<'static, Animating> {
|
||||
static THREAD: OnceLock<()> = OnceLock::new();
|
||||
THREAD.get_or_init(|| {
|
||||
thread::spawn(animation_thread);
|
||||
THREAD.get_or_init(move || {
|
||||
thread::spawn(move || animation_thread(app.as_ref()));
|
||||
});
|
||||
ANIMATIONS.lock()
|
||||
}
|
||||
|
||||
fn animation_thread() {
|
||||
let mut state = thread_state();
|
||||
fn animation_thread(app: Option<&Cushy>) {
|
||||
let _guard = app.as_ref().map(|app| app.enter_runtime());
|
||||
let mut state = thread_state(None);
|
||||
loop {
|
||||
if state.running.is_empty() {
|
||||
state.last_updated = None;
|
||||
|
|
@ -104,7 +110,7 @@ fn animation_thread() {
|
|||
.checked_duration_since(Instant::now())
|
||||
.unwrap_or(Duration::from_millis(16)),
|
||||
);
|
||||
state = thread_state();
|
||||
state = thread_state(None);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -456,7 +462,7 @@ where
|
|||
|
||||
impl Spawn for Box<dyn Animate> {
|
||||
fn spawn(self) -> AnimationHandle {
|
||||
thread_state().spawn(self)
|
||||
thread_state(None).spawn(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -512,7 +518,7 @@ impl AnimationHandle {
|
|||
/// This has the same effect as dropping the handle.
|
||||
pub fn clear(&mut self) {
|
||||
if let Some(id) = self.0.take() {
|
||||
thread_state().remove_animation(id);
|
||||
thread_state(None).remove_animation(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -524,7 +530,7 @@ impl AnimationHandle {
|
|||
/// through completion without needing to hold onto the handle.
|
||||
pub fn detach(mut self) {
|
||||
if let Some(id) = self.0.take() {
|
||||
thread_state().run_unattached(id);
|
||||
thread_state(None).run_unattached(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -533,7 +539,7 @@ impl AnimationHandle {
|
|||
pub fn is_running(&self) -> bool {
|
||||
let Some(id) = self.0 else { return false };
|
||||
|
||||
thread_state().running.contains(&id)
|
||||
thread_state(None).running.contains(&id)
|
||||
}
|
||||
|
||||
/// Returns true if this animation is complete.
|
||||
|
|
|
|||
194
src/app.rs
194
src/app.rs
|
|
@ -1,9 +1,11 @@
|
|||
use std::marker::PhantomData;
|
||||
use std::sync::Arc;
|
||||
|
||||
use arboard::Clipboard;
|
||||
use kludgine::app::{AppEvent, AsApplication};
|
||||
use parking_lot::{Mutex, MutexGuard};
|
||||
|
||||
use crate::animation;
|
||||
use crate::fonts::FontCollection;
|
||||
use crate::window::sealed::WindowCommand;
|
||||
use crate::window::WindowHandle;
|
||||
|
|
@ -15,6 +17,14 @@ pub struct PendingApp {
|
|||
}
|
||||
|
||||
impl PendingApp {
|
||||
/// Returns a new app using the provided runtime.
|
||||
pub fn new<Runtime: AppRuntime>(runtime: Runtime) -> Self {
|
||||
Self {
|
||||
app: kludgine::app::PendingApp::default(),
|
||||
cushy: Cushy::new(BoxedRuntime(Box::new(runtime))),
|
||||
}
|
||||
}
|
||||
|
||||
/// The shared resources this application utilizes.
|
||||
#[must_use]
|
||||
pub const fn cushy(&self) -> &Cushy {
|
||||
|
|
@ -24,16 +34,15 @@ impl PendingApp {
|
|||
|
||||
impl Run for PendingApp {
|
||||
fn run(self) -> crate::Result {
|
||||
let _guard = self.cushy.enter_runtime();
|
||||
animation::spawn(self.cushy.clone());
|
||||
self.app.run()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for PendingApp {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
app: kludgine::app::PendingApp::default(),
|
||||
cushy: Cushy::new(),
|
||||
}
|
||||
Self::new(DefaultRuntime::default())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -50,20 +59,178 @@ impl AsApplication<AppEvent<WindowCommand>> for PendingApp {
|
|||
}
|
||||
}
|
||||
|
||||
/// A runtime associated with the Cushy application.
|
||||
///
|
||||
/// This trait is how Cushy adds optional support for `tokio`.
|
||||
pub trait AppRuntime: Send + Clone + 'static {
|
||||
/// The guard type returned from entering the context of the app's runtime.
|
||||
type Guard<'a>;
|
||||
|
||||
/// Enter the application's rutime context.
|
||||
fn enter(&self) -> Self::Guard<'_>;
|
||||
}
|
||||
|
||||
/// A default application runtime.
|
||||
///
|
||||
/// When the `tokio` feature is enabled, a tokio runtime is spawned when this
|
||||
/// runtime is used in Cushy.
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct DefaultRuntime {
|
||||
#[cfg(feature = "tokio")]
|
||||
tokio: TokioRuntime,
|
||||
_private: (),
|
||||
}
|
||||
|
||||
impl AppRuntime for DefaultRuntime {
|
||||
type Guard<'a> = DefaultRuntimeGuard<'a>;
|
||||
|
||||
fn enter(&self) -> Self::Guard<'_> {
|
||||
DefaultRuntimeGuard {
|
||||
#[cfg(feature = "tokio")]
|
||||
_tokio: self.tokio.enter(),
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DefaultRuntimeGuard<'a> {
|
||||
#[cfg(feature = "tokio")]
|
||||
_tokio: ::tokio::runtime::EnterGuard<'a>,
|
||||
_phantom: PhantomData<&'a ()>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "tokio")]
|
||||
mod tokio {
|
||||
use std::future::Future;
|
||||
use std::ops::Deref;
|
||||
use std::task::Poll;
|
||||
use std::thread;
|
||||
|
||||
use tokio::runtime::{self, Handle};
|
||||
|
||||
use super::AppRuntime;
|
||||
use crate::Lazy;
|
||||
|
||||
/// A spawned `tokio` runtime.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TokioRuntime {
|
||||
pub(crate) handle: Handle,
|
||||
}
|
||||
|
||||
impl From<Handle> for TokioRuntime {
|
||||
fn from(handle: Handle) -> Self {
|
||||
Self { handle }
|
||||
}
|
||||
}
|
||||
|
||||
static TOKIO: Lazy<Handle> = Lazy::new(|| {
|
||||
#[cfg(feature = "tokio-multi-thread")]
|
||||
let mut rt = runtime::Builder::new_multi_thread();
|
||||
#[cfg(not(feature = "tokio-multi-thread"))]
|
||||
let mut rt = runtime::Builder::new_current_thread();
|
||||
let runtime = rt
|
||||
.enable_all()
|
||||
.build()
|
||||
.expect("failure to initialize tokio");
|
||||
let handle = runtime.handle().clone();
|
||||
thread::Builder::new()
|
||||
.name(String::from("tokio"))
|
||||
.spawn(move || {
|
||||
runtime.block_on(BlockForever);
|
||||
})
|
||||
.expect("error spawning tokio thread");
|
||||
handle
|
||||
});
|
||||
|
||||
impl Default for TokioRuntime {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
handle: TOKIO.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for TokioRuntime {
|
||||
type Target = Handle;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.handle
|
||||
}
|
||||
}
|
||||
|
||||
struct BlockForever;
|
||||
impl Future for BlockForever {
|
||||
type Output = ();
|
||||
|
||||
fn poll(
|
||||
self: std::pin::Pin<&mut Self>,
|
||||
_cx: &mut std::task::Context<'_>,
|
||||
) -> Poll<Self::Output> {
|
||||
Poll::<()>::Pending
|
||||
}
|
||||
}
|
||||
|
||||
impl AppRuntime for TokioRuntime {
|
||||
type Guard<'a> = tokio::runtime::EnterGuard<'a>;
|
||||
|
||||
fn enter(&self) -> Self::Guard<'_> {
|
||||
self.handle.enter()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "tokio")]
|
||||
pub use tokio::TokioRuntime;
|
||||
|
||||
struct BoxedRuntime(Box<dyn BoxableRuntime>);
|
||||
|
||||
impl Clone for BoxedRuntime {
|
||||
fn clone(&self) -> Self {
|
||||
self.0.cloned()
|
||||
}
|
||||
}
|
||||
|
||||
trait BoxableRuntime: Send {
|
||||
fn enter_runtime(&self) -> RuntimeGuard<'_>;
|
||||
fn cloned(&self) -> BoxedRuntime;
|
||||
}
|
||||
|
||||
impl<T> BoxableRuntime for T
|
||||
where
|
||||
T: AppRuntime,
|
||||
for<'a> T::Guard<'a>: BoxableGuard<'a>,
|
||||
{
|
||||
fn enter_runtime(&self) -> RuntimeGuard<'_> {
|
||||
RuntimeGuard(Box::new(AppRuntime::enter(self)))
|
||||
}
|
||||
|
||||
fn cloned(&self) -> BoxedRuntime {
|
||||
BoxedRuntime(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub struct RuntimeGuard<'a>(Box<dyn BoxableGuard<'a> + 'a>);
|
||||
|
||||
trait BoxableGuard<'a> {}
|
||||
impl<'a, T> BoxableGuard<'a> for T {}
|
||||
|
||||
/// Shared resources for a GUI application.
|
||||
#[derive(Clone)]
|
||||
pub struct Cushy {
|
||||
pub(crate) clipboard: Option<Arc<Mutex<Clipboard>>>,
|
||||
pub(crate) fonts: FontCollection,
|
||||
runtime: BoxedRuntime,
|
||||
}
|
||||
|
||||
impl Cushy {
|
||||
pub(crate) fn new() -> Self {
|
||||
fn new(runtime: BoxedRuntime) -> Self {
|
||||
Self {
|
||||
clipboard: Clipboard::new()
|
||||
.ok()
|
||||
.map(|clipboard| Arc::new(Mutex::new(clipboard))),
|
||||
fonts: FontCollection::default(),
|
||||
runtime,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -79,6 +246,23 @@ impl Cushy {
|
|||
pub fn fonts(&self) -> &FontCollection {
|
||||
&self.fonts
|
||||
}
|
||||
|
||||
/// Enters the application's runtime context.
|
||||
///
|
||||
/// When the `tokio` feature is enabled, the guard returned by this function
|
||||
/// allows for functions like `tokio::spawn` to work for the current thread.
|
||||
/// Outside of application startup, this function shouldn't need to be
|
||||
/// called unless you are manually spawning threads.
|
||||
#[must_use]
|
||||
pub fn enter_runtime(&self) -> RuntimeGuard<'_> {
|
||||
self.runtime.0.enter_runtime()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Cushy {
|
||||
fn default() -> Self {
|
||||
Self::new(BoxedRuntime(Box::<DefaultRuntime>::default()))
|
||||
}
|
||||
}
|
||||
|
||||
/// A type that is a Cushy application.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use crate::value::{Dynamic, DynamicReader, ForEach, Source, WeakDynamic};
|
|||
use crate::widget::{MakeWidget, WidgetInstance, WidgetList};
|
||||
use crate::widgets::grid::{Grid, GridWidgets};
|
||||
use crate::window::Window;
|
||||
use crate::{Open, PendingApp};
|
||||
use crate::{Application, Open, PendingApp};
|
||||
|
||||
/// A widget that can provide extra information when debugging.
|
||||
#[derive(Clone, Default)]
|
||||
|
|
@ -117,7 +117,7 @@ impl DebugContext {
|
|||
impl Open for DebugContext {
|
||||
fn open<App>(self, app: &mut App) -> crate::Result<Option<crate::window::WindowHandle>>
|
||||
where
|
||||
App: crate::Application + ?Sized,
|
||||
App: Application + ?Sized,
|
||||
{
|
||||
self.into_window().open(app)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,9 @@ pub mod widgets;
|
|||
pub mod window;
|
||||
use std::ops::{Add, AddAssign, Sub, SubAssign};
|
||||
|
||||
pub use app::{App, Application, Cushy, Open, PendingApp, Run};
|
||||
#[cfg(feature = "tokio")]
|
||||
pub use app::TokioRuntime;
|
||||
pub use app::{App, AppRuntime, Application, Cushy, DefaultRuntime, Open, PendingApp, Run};
|
||||
use figures::units::UPx;
|
||||
use figures::{Fraction, ScreenUnit, Size, Zero};
|
||||
use kludgine::app::winit::error::EventLoopError;
|
||||
|
|
|
|||
|
|
@ -1211,6 +1211,8 @@ where
|
|||
where
|
||||
W: PlatformWindowImplementation,
|
||||
{
|
||||
let cushy = self.cushy.clone();
|
||||
let _guard = cushy.enter_runtime();
|
||||
if let Some(theme) = &mut self.theme {
|
||||
if theme.has_updated() {
|
||||
self.current_theme = theme.get();
|
||||
|
|
@ -1320,6 +1322,8 @@ where
|
|||
where
|
||||
W: PlatformWindowImplementation,
|
||||
{
|
||||
let cushy = self.cushy.clone();
|
||||
let _guard = cushy.enter_runtime();
|
||||
if self.behavior.close_requested(&mut RunningWindow::new(
|
||||
window,
|
||||
kludgine.id(),
|
||||
|
|
@ -1362,6 +1366,8 @@ where
|
|||
where
|
||||
W: PlatformWindowImplementation,
|
||||
{
|
||||
let cushy = self.cushy.clone();
|
||||
let _guard = cushy.enter_runtime();
|
||||
let mut window = RunningWindow::new(
|
||||
window,
|
||||
kludgine.id(),
|
||||
|
|
@ -1410,6 +1416,8 @@ where
|
|||
where
|
||||
W: PlatformWindowImplementation,
|
||||
{
|
||||
let cushy = self.cushy.clone();
|
||||
let _guard = cushy.enter_runtime();
|
||||
let mut window = RunningWindow::new(
|
||||
window,
|
||||
kludgine.id(),
|
||||
|
|
@ -1451,6 +1459,8 @@ where
|
|||
where
|
||||
W: PlatformWindowImplementation,
|
||||
{
|
||||
let cushy = self.cushy.clone();
|
||||
let _guard = cushy.enter_runtime();
|
||||
let mut window = RunningWindow::new(
|
||||
window,
|
||||
kludgine.id(),
|
||||
|
|
@ -1493,6 +1503,8 @@ where
|
|||
) where
|
||||
W: PlatformWindowImplementation,
|
||||
{
|
||||
let cushy = self.cushy.clone();
|
||||
let _guard = cushy.enter_runtime();
|
||||
let mut window = RunningWindow::new(
|
||||
window,
|
||||
kludgine.id(),
|
||||
|
|
@ -1548,6 +1560,8 @@ where
|
|||
where
|
||||
W: PlatformWindowImplementation,
|
||||
{
|
||||
let cushy = self.cushy.clone();
|
||||
let _guard = cushy.enter_runtime();
|
||||
if self.cursor.widget.take().is_some() {
|
||||
let mut window = RunningWindow::new(
|
||||
window,
|
||||
|
|
@ -1585,6 +1599,8 @@ where
|
|||
where
|
||||
W: PlatformWindowImplementation,
|
||||
{
|
||||
let cushy = self.cushy.clone();
|
||||
let _guard = cushy.enter_runtime();
|
||||
let mut window = RunningWindow::new(
|
||||
window,
|
||||
kludgine.id(),
|
||||
|
|
@ -1703,6 +1719,8 @@ where
|
|||
context: Self::Context,
|
||||
) -> Self {
|
||||
let settings = context.settings.borrow_mut();
|
||||
let cushy = settings.cushy.clone();
|
||||
let _guard = cushy.enter_runtime();
|
||||
let mut window = RunningWindow::new(
|
||||
window,
|
||||
graphics.id(),
|
||||
|
|
@ -1784,6 +1802,8 @@ where
|
|||
window: kludgine::app::Window<'_, WindowCommand>,
|
||||
kludgine: &mut Kludgine,
|
||||
) -> bool {
|
||||
let cushy = self.cushy.clone();
|
||||
let _guard = cushy.enter_runtime();
|
||||
Self::request_close(
|
||||
&mut self.should_close,
|
||||
&mut self.behavior,
|
||||
|
|
@ -2532,7 +2552,7 @@ impl CushyWindowBuilder {
|
|||
window,
|
||||
&mut kludgine::Graphics::new(&mut kludgine, device, queue),
|
||||
sealed::WindowSettings {
|
||||
cushy: Cushy::new(),
|
||||
cushy: Cushy::default(),
|
||||
redraw_status: InvalidationStatus::default(),
|
||||
title: Value::default(),
|
||||
attributes: None,
|
||||
|
|
|
|||
Loading…
Reference in a new issue