Fill the windows in the examples with a solid color

Fixes #776.
This commit is contained in:
John Nunley 2023-06-19 11:46:38 -07:00 committed by GitHub
parent 4748890935
commit b2a46d0439
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 264 additions and 19 deletions

View file

@ -63,6 +63,9 @@ smol_str = "0.2.0"
image = { version = "0.24.0", default-features = false, features = ["png"] }
simple_logger = { version = "2.1.0", default_features = false }
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dev-dependencies]
softbuffer = "0.3.0"
[target.'cfg(target_os = "android")'.dependencies]
# Coordinate the next winit release with android-ndk-rs: https://github.com/rust-windowing/winit/issues/1995
android-activity = "0.4.0"

View file

@ -73,10 +73,6 @@ Winit provides the following features, which can be enabled in your `Cargo.toml`
Note that windows don't appear on Wayland until you draw/present to them.
`winit` doesn't do drawing, try the examples in [`glutin`] instead.
[`glutin`]: https://github.com/rust-windowing/glutin
#### WebAssembly
To run the web example: `cargo run-wasm --example web`

View file

@ -34,6 +34,8 @@ skip = [
{ name = "bitflags" }, # the ecosystem is in the process of migrating.
{ name = "nix" }, # differing version - as of 2023-03-02 whis can be solved with `cargo update && cargo update -p calloop --precise 0.10.2`
{ name = "memoffset"}, # due to different nix versions.
{ name = "memmap2" }, # sctk uses a different version until the next update
{ name = "libloading" }, # x11rb uses a different version until the next update
{ name = "syn" }, # https://github.com/rust-mobile/ndk/issues/392 and https://github.com/rustwasm/wasm-bindgen/issues/3390
{ name = "miniz_oxide"}, # https://github.com/rust-lang/flate2-rs/issues/340
{ name = "redox_syscall" }, # https://gitlab.redox-os.org/redox-os/orbclient/-/issues/46

View file

@ -1,3 +1,7 @@
#[cfg(any(x11_platform, macos_platform, windows_platform))]
#[path = "util/fill.rs"]
mod fill;
#[cfg(any(x11_platform, macos_platform, windows_platform))]
fn main() {
use std::collections::HashMap;
@ -70,6 +74,10 @@ fn main() {
}
_ => (),
}
} else if let Event::RedrawRequested(wid) = event {
if let Some(window) = windows.get(&wid) {
fill::fill_window(window);
}
}
})
}

View file

@ -14,6 +14,9 @@ use winit::{
window::WindowBuilder,
};
#[path = "util/fill.rs"]
mod fill;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Mode {
Wait,
@ -100,7 +103,9 @@ fn main() {
control_flow.set_exit();
}
}
Event::RedrawRequested(_window_id) => {}
Event::RedrawRequested(_window_id) => {
fill::fill_window(&window);
}
Event::RedrawEventsCleared => {
match mode {
Mode::Wait => control_flow.set_wait(),

View file

@ -7,6 +7,9 @@ use winit::{
window::{CursorIcon, WindowBuilder},
};
#[path = "util/fill.rs"]
mod fill;
fn main() {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();
@ -46,6 +49,9 @@ fn main() {
} => {
control_flow.set_exit();
}
Event::RedrawRequested(_) => {
fill::fill_window(&window);
}
_ => (),
}
});

View file

@ -8,6 +8,9 @@ use winit::{
window::{CursorGrabMode, WindowBuilder},
};
#[path = "util/fill.rs"]
mod fill;
fn main() {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();
@ -67,6 +70,7 @@ fn main() {
},
_ => (),
},
Event::RedrawRequested(_) => fill::fill_window(&window),
_ => (),
}
});

View file

@ -9,6 +9,9 @@ fn main() {
window::WindowBuilder,
};
#[path = "util/fill.rs"]
mod fill;
#[derive(Debug, Clone, Copy)]
enum CustomEvent {
Timer,
@ -17,7 +20,7 @@ fn main() {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoopBuilder::<CustomEvent>::with_user_event().build();
let _window = WindowBuilder::new()
let window = WindowBuilder::new()
.with_title("A fantastic window!")
.build(&event_loop)
.unwrap();
@ -44,6 +47,9 @@ fn main() {
event: WindowEvent::CloseRequested,
..
} => control_flow.set_exit(),
Event::RedrawRequested(_) => {
fill::fill_window(&window);
}
_ => (),
}
});

View file

@ -8,6 +8,9 @@ use winit::{
window::{Window, WindowBuilder, WindowId},
};
#[path = "util/fill.rs"]
mod fill;
fn main() {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();
@ -58,6 +61,13 @@ fn main() {
}
_ => (),
},
Event::RedrawRequested(wid) => {
if wid == window_1.id() {
fill::fill_window(&window_1);
} else if wid == window_2.id() {
fill::fill_window(&window_2);
}
}
_ => (),
});
}

View file

@ -9,6 +9,9 @@ use winit::window::{Fullscreen, WindowBuilder};
#[cfg(target_os = "macos")]
use winit::platform::macos::WindowExtMacOS;
#[path = "util/fill.rs"]
mod fill;
fn main() {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();
@ -123,6 +126,9 @@ fn main() {
},
_ => (),
},
Event::RedrawRequested(_) => {
fill::fill_window(&window);
}
_ => {}
}
});

View file

@ -8,11 +8,14 @@ use winit::{
window::WindowBuilder,
};
#[path = "util/fill.rs"]
mod fill;
fn main() {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();
let _window = WindowBuilder::new()
let window = WindowBuilder::new()
.with_title("Your faithful window")
.build(&event_loop)
.unwrap();
@ -79,6 +82,9 @@ fn main() {
_ => (),
}
}
Event::RedrawRequested(_) => {
fill::fill_window(&window);
}
_ => (),
}
});

View file

@ -10,6 +10,9 @@ use winit::{
window::{ImePurpose, WindowBuilder},
};
#[path = "util/fill.rs"]
mod fill;
fn main() {
SimpleLogger::new()
.with_level(LevelFilter::Trace)
@ -97,6 +100,9 @@ fn main() {
println!("\nIME purpose: {ime_purpose:?}\n");
}
}
Event::RedrawRequested(_) => {
fill::fill_window(&window);
}
_ => (),
}
});

View file

@ -18,10 +18,13 @@ fn main() {
#[cfg(any(target_os = "macos", target_os = "windows", target_os = "linux"))]
fn main() {
#[path = "util/fill.rs"]
mod fill;
simple_logger::SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();
let _window = WindowBuilder::new()
let window = WindowBuilder::new()
.with_inner_size(LogicalSize::new(400.0, 200.0))
.build(&event_loop)
.unwrap();
@ -53,6 +56,9 @@ fn main() {
}
_ => (),
},
Event::RedrawRequested(_) => {
fill::fill_window(&window);
}
_ => (),
};
});

View file

@ -7,6 +7,9 @@ use winit::{
window::WindowBuilder,
};
#[path = "util/fill.rs"]
mod fill;
fn main() {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();
@ -56,6 +59,9 @@ In other words, the deltas indicate the direction in which to move the content (
},
_ => (),
},
Event::RedrawRequested(_) => {
fill::fill_window(&window);
}
_ => (),
}
});

View file

@ -10,6 +10,9 @@ use winit::{
window::Window,
};
#[path = "util/fill.rs"]
mod fill;
fn main() {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();
@ -56,6 +59,11 @@ fn main() {
_ => (),
}
}
Event::RedrawRequested(window_id) => {
if let Some(window) = windows.get(&window_id) {
fill::fill_window(window);
}
}
_ => (),
}
})

View file

@ -7,6 +7,9 @@ use winit::{
window::WindowBuilder,
};
#[path = "util/fill.rs"]
mod fill;
fn main() {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();
@ -34,6 +37,7 @@ fn main() {
},
Event::RedrawRequested(_) => {
println!("\nredrawing!\n");
fill::fill_window(&window);
}
_ => (),
}

View file

@ -2,7 +2,7 @@
#[cfg(not(wasm_platform))]
fn main() {
use std::{thread, time};
use std::{sync::Arc, thread, time};
use simple_logger::SimpleLogger;
use winit::{
@ -11,17 +11,26 @@ fn main() {
window::WindowBuilder,
};
#[path = "util/fill.rs"]
mod fill;
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();
let window = {
let window = WindowBuilder::new()
.with_title("A fantastic window!")
.build(&event_loop)
.unwrap();
Arc::new(window)
};
thread::spawn(move || loop {
thread::spawn({
let window = window.clone();
move || loop {
thread::sleep(time::Duration::from_secs(1));
window.request_redraw();
}
});
event_loop.run(move |event, _, control_flow| {
@ -36,6 +45,7 @@ fn main() {
} => control_flow.set_exit(),
Event::RedrawRequested(_) => {
println!("\nredrawing!\n");
fill::fill_window(&window);
}
_ => (),
}

View file

@ -9,6 +9,9 @@ use winit::{
window::WindowBuilder,
};
#[path = "util/fill.rs"]
mod fill;
fn main() {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();
@ -45,6 +48,9 @@ fn main() {
}
_ => (),
},
Event::RedrawRequested(_) => {
fill::fill_window(&window);
}
_ => (),
};
});

View file

@ -8,6 +8,9 @@ use winit::{
window::{Theme, WindowBuilder},
};
#[path = "util/fill.rs"]
mod fill;
fn main() {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();
@ -66,6 +69,10 @@ fn main() {
}
_ => (),
},
Event::RedrawRequested(_) => {
println!("\nredrawing!\n");
fill::fill_window(&window);
}
_ => (),
}
});

View file

@ -13,11 +13,14 @@ use winit::{
window::WindowBuilder,
};
#[path = "util/fill.rs"]
mod fill;
fn main() {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();
let _window = WindowBuilder::new()
let window = WindowBuilder::new()
.with_title("A fantastic window!")
.build(&event_loop)
.unwrap();
@ -39,6 +42,9 @@ fn main() {
event: WindowEvent::CloseRequested,
..
} => control_flow.set_exit(),
Event::RedrawRequested(_) => {
fill::fill_window(&window);
}
_ => (),
}
});

View file

@ -5,11 +5,14 @@ use winit::{
window::WindowBuilder,
};
#[path = "util/fill.rs"]
mod fill;
fn main() {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();
let _window = WindowBuilder::new()
let window = WindowBuilder::new()
.with_title("Touchpad gestures")
.build(&event_loop)
.unwrap();
@ -41,6 +44,8 @@ fn main() {
}
_ => (),
}
} else if let Event::RedrawRequested(_) = event {
fill::fill_window(&window);
}
});
}

View file

@ -7,6 +7,9 @@ use winit::{
window::WindowBuilder,
};
#[path = "util/fill.rs"]
mod fill;
fn main() {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();
@ -28,6 +31,9 @@ fn main() {
event: WindowEvent::CloseRequested,
..
} => control_flow.set_exit(),
Event::RedrawRequested(_) => {
fill::fill_window(&window);
}
_ => (),
}
});

81
examples/util/fill.rs Normal file
View file

@ -0,0 +1,81 @@
//! Fill the window buffer with a solid color.
//!
//! Launching a window without drawing to it has unpredictable results varying from platform to
//! platform. In order to have well-defined examples, this module provides an easy way to
//! fill the window buffer with a solid color.
//!
//! The `softbuffer` crate is used, largely because of its ease of use. `glutin` or `wgpu` could
//! also be used to fill the window buffer, but they are more complicated to use.
use winit::window::Window;
#[cfg(not(any(target_os = "android", target_os = "ios")))]
pub(super) fn fill_window(window: &Window) {
use softbuffer::{Context, Surface};
use std::cell::RefCell;
use std::collections::HashMap;
use std::num::NonZeroU32;
use winit::window::WindowId;
/// The graphics context used to draw to a window.
struct GraphicsContext {
/// The global softbuffer context.
context: Context,
/// The hash map of window IDs to surfaces.
surfaces: HashMap<WindowId, Surface>,
}
impl GraphicsContext {
fn new(w: &Window) -> Self {
Self {
context: unsafe { Context::new(w) }.expect("Failed to create a softbuffer context"),
surfaces: HashMap::new(),
}
}
fn surface(&mut self, w: &Window) -> &mut Surface {
self.surfaces.entry(w.id()).or_insert_with(|| {
unsafe { Surface::new(&self.context, w) }
.expect("Failed to create a softbuffer surface")
})
}
}
thread_local! {
/// A static, thread-local map of graphics contexts to open windows.
static GC: RefCell<Option<GraphicsContext>> = RefCell::new(None);
}
GC.with(|gc| {
// Either get the last context used or create a new one.
let mut gc = gc.borrow_mut();
let surface = gc
.get_or_insert_with(|| GraphicsContext::new(window))
.surface(window);
// Fill a buffer with a solid color.
const DARK_GRAY: u32 = 0xFF181818;
let size = window.inner_size();
surface
.resize(
NonZeroU32::new(size.width).expect("Width must be greater than zero"),
NonZeroU32::new(size.height).expect("Height must be greater than zero"),
)
.expect("Failed to resize the softbuffer surface");
let mut buffer = surface
.buffer_mut()
.expect("Failed to get the softbuffer buffer");
buffer.fill(DARK_GRAY);
buffer
.present()
.expect("Failed to present the softbuffer buffer");
})
}
#[cfg(any(target_os = "android", target_os = "ios"))]
pub(super) fn fill_window(_window: &Window) {
// No-op on mobile platforms.
}

View file

@ -7,6 +7,9 @@ use winit::{
window::WindowBuilder,
};
#[path = "util/fill.rs"]
mod fill;
fn main() {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();
@ -29,6 +32,9 @@ fn main() {
Event::MainEventsCleared => {
window.request_redraw();
}
Event::RedrawRequested(_) => {
fill::fill_window(&window);
}
_ => (),
}
});

View file

@ -11,6 +11,9 @@ use winit::{
window::{WindowBuilder, WindowButtons},
};
#[path = "util/fill.rs"]
mod fill;
fn main() {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();
@ -63,6 +66,9 @@ fn main() {
event: WindowEvent::CloseRequested,
window_id,
} if window_id == window.id() => control_flow.set_exit(),
Event::RedrawRequested(_) => {
fill::fill_window(&window);
}
_ => (),
}
});

View file

@ -11,6 +11,9 @@ use winit::{
window::{Fullscreen, WindowBuilder},
};
#[path = "util/fill.rs"]
mod fill;
fn main() {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();
@ -131,6 +134,9 @@ fn main() {
event: WindowEvent::CloseRequested,
window_id,
} if window_id == window.id() => control_flow.set_exit(),
Event::RedrawRequested(_) => {
fill::fill_window(&window);
}
_ => (),
}
});

View file

@ -10,6 +10,9 @@ use winit::{
const BORDER: f64 = 8.0;
#[path = "util/fill.rs"]
mod fill;
fn main() {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();
@ -65,6 +68,9 @@ fn main() {
}
_ => (),
},
Event::RedrawRequested(_) => {
fill::fill_window(&window);
}
_ => (),
});
}

View file

@ -9,6 +9,9 @@ use winit::{
window::{Icon, WindowBuilder},
};
#[path = "util/fill.rs"]
mod fill;
fn main() {
SimpleLogger::new().init().unwrap();
@ -42,6 +45,8 @@ fn main() {
}
_ => (),
}
} else if let Event::RedrawRequested(_) = event {
fill::fill_window(&window);
}
});
}

View file

@ -8,6 +8,9 @@ use winit::{
window::WindowBuilder,
};
#[path = "util/fill.rs"]
mod fill;
fn main() {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();
@ -52,6 +55,9 @@ fn main() {
window.set_resize_increments(new_increments);
}
Event::MainEventsCleared => window.request_redraw(),
Event::RedrawRequested(_) => {
fill::fill_window(&window);
}
_ => (),
}
});

View file

@ -19,10 +19,14 @@ fn main() {
platform::run_return::EventLoopExtRunReturn,
window::WindowBuilder,
};
#[path = "util/fill.rs"]
mod fill;
let mut event_loop = EventLoop::new();
SimpleLogger::new().init().unwrap();
let _window = WindowBuilder::new()
let window = WindowBuilder::new()
.with_title("A fantastic window!")
.build(&event_loop)
.unwrap();
@ -48,6 +52,9 @@ fn main() {
Event::MainEventsCleared => {
control_flow.set_exit();
}
Event::RedrawRequested(_) => {
fill::fill_window(&window);
}
_ => (),
}
});