mirror of
https://github.com/danbulant/appit
synced 2026-05-24 12:26:14 +00:00
parent
e69d979229
commit
5c1e667413
2 changed files with 27 additions and 1 deletions
|
|
@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file.
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- `WindowAttributes::delay_visible` is a new setting initializes the window
|
||||||
|
`visible: false` before showing it after the first successful redraw. The goal
|
||||||
|
is to avoid the OS drawing an empty window before the window behavior has
|
||||||
|
initialized. This new attribute defaults to true.
|
||||||
|
|
||||||
## v0.3.0 (2024-05-12)
|
## v0.3.0 (2024-05-12)
|
||||||
|
|
||||||
### Breaking Changes
|
### Breaking Changes
|
||||||
|
|
|
||||||
|
|
@ -149,6 +149,8 @@ pub struct WindowAttributes {
|
||||||
pub window_level: WindowLevel,
|
pub window_level: WindowLevel,
|
||||||
/// Whether the window is active or not.
|
/// Whether the window is active or not.
|
||||||
pub active: bool,
|
pub active: bool,
|
||||||
|
/// When true, this window will delay honoring the `visible` attribute until after the window behavior has been initialized and redrawn a single time.
|
||||||
|
pub delay_visible: bool,
|
||||||
/// Name of the application
|
/// Name of the application
|
||||||
///
|
///
|
||||||
/// - `WM_CLASS` on X11
|
/// - `WM_CLASS` on X11
|
||||||
|
|
@ -182,6 +184,7 @@ impl Default for WindowAttributes {
|
||||||
window_level: defaults.window_level,
|
window_level: defaults.window_level,
|
||||||
active: defaults.active,
|
active: defaults.active,
|
||||||
app_name: None,
|
app_name: None,
|
||||||
|
delay_visible: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -210,7 +213,7 @@ where
|
||||||
///
|
///
|
||||||
/// The only errors this funciton can return arise from
|
/// The only errors this funciton can return arise from
|
||||||
/// [`winit::window::WindowBuilder::build`].
|
/// [`winit::window::WindowBuilder::build`].
|
||||||
pub fn open(self) -> Result<Option<Window<AppMessage::Window>>, winit::error::OsError> {
|
pub fn open(mut self) -> Result<Option<Window<AppMessage::Window>>, winit::error::OsError> {
|
||||||
// The window's thread shouldn't ever block for long periods of time. To
|
// The window's thread shouldn't ever block for long periods of time. To
|
||||||
// avoid a "frozen" window causing massive memory allocations, we'll use
|
// avoid a "frozen" window causing massive memory allocations, we'll use
|
||||||
// a fixed-size channel and be cautious to not block the main event loop
|
// a fixed-size channel and be cautious to not block the main event loop
|
||||||
|
|
@ -218,6 +221,7 @@ where
|
||||||
let (sender, receiver) = mpsc::sync_channel(65536);
|
let (sender, receiver) = mpsc::sync_channel(65536);
|
||||||
let sender = Arc::new(sender);
|
let sender = Arc::new(sender);
|
||||||
let app = self.owner.as_application().app();
|
let app = self.owner.as_application().app();
|
||||||
|
let show_after_init = self.attributes.delay_visible && std::mem::replace(&mut self.attributes.visible, false);
|
||||||
let Some(winit) = self.owner.as_application_mut().open(
|
let Some(winit) = self.owner.as_application_mut().open(
|
||||||
self.attributes,
|
self.attributes,
|
||||||
sender.clone(),
|
sender.clone(),
|
||||||
|
|
@ -243,6 +247,7 @@ where
|
||||||
cursor_position: None,
|
cursor_position: None,
|
||||||
mouse_buttons: HashSet::default(),
|
mouse_buttons: HashSet::default(),
|
||||||
keys: HashSet::default(),
|
keys: HashSet::default(),
|
||||||
|
show_after_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
thread::spawn(move || running_window.run_with::<Behavior>(self.context));
|
thread::spawn(move || running_window.run_with::<Behavior>(self.context));
|
||||||
|
|
@ -292,6 +297,7 @@ where
|
||||||
focused: bool,
|
focused: bool,
|
||||||
theme: Theme,
|
theme: Theme,
|
||||||
modifiers: Modifiers,
|
modifiers: Modifiers,
|
||||||
|
show_after_init: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<AppMessage> RunningWindow<AppMessage>
|
impl<AppMessage> RunningWindow<AppMessage>
|
||||||
|
|
@ -448,6 +454,17 @@ where
|
||||||
// the entire app panics or not.
|
// the entire app panics or not.
|
||||||
let possible_panic = std::panic::catch_unwind(AssertUnwindSafe(move || {
|
let possible_panic = std::panic::catch_unwind(AssertUnwindSafe(move || {
|
||||||
let mut behavior = Behavior::initialize(&mut self, context);
|
let mut behavior = Behavior::initialize(&mut self, context);
|
||||||
|
|
||||||
|
// When it takes a while for a graphics stack to initialize, we can
|
||||||
|
// avoid showing a blank window due to our multi-threaded event
|
||||||
|
// handling by not showing the window until the graphics stack has
|
||||||
|
// been initialized.
|
||||||
|
if self.show_after_init {
|
||||||
|
self.next_redraw_target = None;
|
||||||
|
behavior.redraw(&mut self);
|
||||||
|
self.window.set_visible(true);
|
||||||
|
}
|
||||||
|
|
||||||
while !self.close {
|
while !self.close {
|
||||||
match self.process_messages_until_redraw(&mut behavior) {
|
match self.process_messages_until_redraw(&mut behavior) {
|
||||||
Ok(guard) => {
|
Ok(guard) => {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue