mirror of
https://github.com/rust-windowing/winit.git
synced 2026-06-26 22:53:15 -04:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
79aa95b212 | ||
|
|
ecd14688dc | ||
|
|
b512ed1e63 | ||
|
|
96388f4f6b | ||
|
|
1745b01502 | ||
|
|
54e974c090 | ||
|
|
b14d5c0c99 |
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "winit"
|
||||
version = "0.30.1"
|
||||
version = "0.30.2"
|
||||
authors = [
|
||||
"The winit contributors",
|
||||
"Pierre Krieger <pierre.krieger1708@gmail.com>",
|
||||
@@ -142,6 +142,7 @@ features = [
|
||||
"NSApplication",
|
||||
"NSBitmapImageRep",
|
||||
"NSButton",
|
||||
"NSColor",
|
||||
"NSControl",
|
||||
"NSCursor",
|
||||
"NSDragging",
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
winit = "0.30.1"
|
||||
winit = "0.30.2"
|
||||
```
|
||||
|
||||
## [Documentation](https://docs.rs/winit)
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
## 0.30.2
|
||||
|
||||
### Fixed
|
||||
|
||||
- On Web, fix `EventLoopProxy::send_event()` triggering event loop immediately
|
||||
when not called from inside the event loop. Now queues a microtask instead.
|
||||
- On Web, stop overwriting default cursor with `CursorIcon::Default`.
|
||||
- On Web, prevent crash when using `InnerSizeWriter::request_inner_size()`.
|
||||
- On macOS, fix not working opacity for entire window.
|
||||
|
||||
## 0.30.1
|
||||
|
||||
### Added
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
//! If your application is currently based on `NativeActivity` via the `ndk-glue` crate and building
|
||||
//! with `cargo apk`, then the minimal changes would be:
|
||||
//! 1. Remove `ndk-glue` from your `Cargo.toml`
|
||||
//! 2. Enable the `"android-native-activity"` feature for Winit: `winit = { version = "0.30.1",
|
||||
//! 2. Enable the `"android-native-activity"` feature for Winit: `winit = { version = "0.30.2",
|
||||
//! features = [ "android-native-activity" ] }`
|
||||
//! 3. Add an `android_main` entrypoint (as above), instead of using the '`[ndk_glue::main]` proc
|
||||
//! macro from `ndk-macros` (optionally add a dependency on `android_logger` and initialize
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#![cfg(android_platform)]
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::collections::VecDeque;
|
||||
use std::hash::Hash;
|
||||
|
||||
@@ -798,7 +798,7 @@ impl EventLoopWaker {
|
||||
// future, but that gets changed to fire immediately in did_finish_launching
|
||||
let timer = CFRunLoopTimerCreate(
|
||||
ptr::null_mut(),
|
||||
std::f64::MAX,
|
||||
f64::MAX,
|
||||
0.000_000_1,
|
||||
0,
|
||||
0,
|
||||
@@ -812,11 +812,11 @@ impl EventLoopWaker {
|
||||
}
|
||||
|
||||
fn stop(&mut self) {
|
||||
unsafe { CFRunLoopTimerSetNextFireDate(self.timer, std::f64::MAX) }
|
||||
unsafe { CFRunLoopTimerSetNextFireDate(self.timer, f64::MAX) }
|
||||
}
|
||||
|
||||
fn start(&mut self) {
|
||||
unsafe { CFRunLoopTimerSetNextFireDate(self.timer, std::f64::MIN) }
|
||||
unsafe { CFRunLoopTimerSetNextFireDate(self.timer, f64::MIN) }
|
||||
}
|
||||
|
||||
fn start_at(&mut self, instant: Instant) {
|
||||
|
||||
@@ -274,8 +274,7 @@ impl<T> EventLoopProxy<T> {
|
||||
cancel: None,
|
||||
perform: event_loop_proxy_handler,
|
||||
};
|
||||
let source =
|
||||
CFRunLoopSourceCreate(ptr::null_mut(), CFIndex::max_value() - 1, &mut context);
|
||||
let source = CFRunLoopSourceCreate(ptr::null_mut(), CFIndex::MAX - 1, &mut context);
|
||||
CFRunLoopAddSource(rl, source, kCFRunLoopCommonModes);
|
||||
CFRunLoopWakeUp(rl);
|
||||
|
||||
@@ -358,7 +357,7 @@ fn setup_control_flow_observers() {
|
||||
ptr::null_mut(),
|
||||
kCFRunLoopAfterWaiting,
|
||||
1, // repeat = true
|
||||
CFIndex::min_value(),
|
||||
CFIndex::MIN,
|
||||
control_flow_begin_handler,
|
||||
ptr::null_mut(),
|
||||
);
|
||||
@@ -378,7 +377,7 @@ fn setup_control_flow_observers() {
|
||||
ptr::null_mut(),
|
||||
kCFRunLoopExit | kCFRunLoopBeforeWaiting,
|
||||
1, // repeat = true
|
||||
CFIndex::max_value(),
|
||||
CFIndex::MAX,
|
||||
control_flow_end_handler,
|
||||
ptr::null_mut(),
|
||||
);
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#![cfg(ios_platform)]
|
||||
#![allow(clippy::let_unit_value)]
|
||||
|
||||
mod app_delegate;
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#![cfg(wayland_platform)]
|
||||
|
||||
//! Winit's Wayland backend.
|
||||
|
||||
use std::fmt::Display;
|
||||
|
||||
@@ -434,7 +434,7 @@ impl EventProcessor {
|
||||
let flags = xev.data.get_long(1);
|
||||
let version = flags >> 24;
|
||||
self.dnd.version = Some(version);
|
||||
let has_more_types = flags - (flags & (c_long::max_value() - 1)) == 1;
|
||||
let has_more_types = flags - (flags & (c_long::MAX - 1)) == 1;
|
||||
if !has_more_types {
|
||||
let type_list = vec![
|
||||
xev.data.get_long(2) as xproto::Atom,
|
||||
|
||||
@@ -158,7 +158,9 @@ struct PreeditCallbacks {
|
||||
impl PreeditCallbacks {
|
||||
pub fn new(client_data: ffi::XPointer) -> PreeditCallbacks {
|
||||
let start_callback = create_xim_callback(client_data, unsafe {
|
||||
mem::transmute(preedit_start_callback as usize)
|
||||
mem::transmute::<usize, unsafe extern "C" fn(ffi::XIM, *mut i8, *mut i8)>(
|
||||
preedit_start_callback as usize,
|
||||
)
|
||||
});
|
||||
let done_callback = create_xim_callback(client_data, preedit_done_callback);
|
||||
let caret_callback = create_xim_callback(client_data, preedit_caret_callback);
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#![cfg(x11_platform)]
|
||||
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::collections::{HashMap, HashSet, VecDeque};
|
||||
use std::ffi::CStr;
|
||||
|
||||
@@ -482,8 +482,7 @@ impl<T> EventLoopProxy<T> {
|
||||
cancel: None,
|
||||
perform: event_loop_proxy_handler,
|
||||
};
|
||||
let source =
|
||||
CFRunLoopSourceCreate(ptr::null_mut(), CFIndex::max_value() - 1, &mut context);
|
||||
let source = CFRunLoopSourceCreate(ptr::null_mut(), CFIndex::MAX - 1, &mut context);
|
||||
CFRunLoopAddSource(rl, source, kCFRunLoopCommonModes);
|
||||
CFRunLoopWakeUp(rl);
|
||||
|
||||
|
||||
@@ -214,13 +214,13 @@ pub fn setup_control_flow_observers(mtm: MainThreadMarker, panic_info: Weak<Pani
|
||||
};
|
||||
run_loop.add_observer(
|
||||
kCFRunLoopAfterWaiting,
|
||||
CFIndex::min_value(),
|
||||
CFIndex::MIN,
|
||||
control_flow_begin_handler,
|
||||
&mut context as *mut _,
|
||||
);
|
||||
run_loop.add_observer(
|
||||
kCFRunLoopExit | kCFRunLoopBeforeWaiting,
|
||||
CFIndex::max_value(),
|
||||
CFIndex::MAX,
|
||||
control_flow_end_handler,
|
||||
&mut context as *mut _,
|
||||
);
|
||||
@@ -260,7 +260,7 @@ impl EventLoopWaker {
|
||||
// future, but that gets changed to fire immediately in did_finish_launching
|
||||
let timer = CFRunLoopTimerCreate(
|
||||
ptr::null_mut(),
|
||||
std::f64::MAX,
|
||||
f64::MAX,
|
||||
0.000_000_1,
|
||||
0,
|
||||
0,
|
||||
@@ -275,14 +275,14 @@ impl EventLoopWaker {
|
||||
pub fn stop(&mut self) {
|
||||
if self.next_fire_date.is_some() {
|
||||
self.next_fire_date = None;
|
||||
unsafe { CFRunLoopTimerSetNextFireDate(self.timer, std::f64::MAX) }
|
||||
unsafe { CFRunLoopTimerSetNextFireDate(self.timer, f64::MAX) }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start(&mut self) {
|
||||
if self.next_fire_date != Some(self.start_instant) {
|
||||
self.next_fire_date = Some(self.start_instant);
|
||||
unsafe { CFRunLoopTimerSetNextFireDate(self.timer, std::f64::MIN) }
|
||||
unsafe { CFRunLoopTimerSetNextFireDate(self.timer, f64::MIN) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ use objc2::runtime::{AnyObject, ProtocolObject};
|
||||
use objc2::{declare_class, msg_send_id, mutability, sel, ClassType, DeclaredClass};
|
||||
use objc2_app_kit::{
|
||||
NSAppKitVersionNumber, NSAppKitVersionNumber10_12, NSAppearance, NSApplication,
|
||||
NSApplicationPresentationOptions, NSBackingStoreType, NSDraggingDestination,
|
||||
NSApplicationPresentationOptions, NSBackingStoreType, NSColor, NSDraggingDestination,
|
||||
NSFilenamesPboardType, NSPasteboard, NSRequestUserAttentionType, NSScreen, NSView,
|
||||
NSWindowButton, NSWindowDelegate, NSWindowFullScreenButton, NSWindowLevel,
|
||||
NSWindowOcclusionState, NSWindowOrderingMode, NSWindowSharingType, NSWindowStyleMask,
|
||||
@@ -613,6 +613,8 @@ fn new_window(
|
||||
|
||||
if attrs.transparent {
|
||||
window.setOpaque(false);
|
||||
// See `set_transparent` for details on why we do this.
|
||||
window.setBackgroundColor(unsafe { Some(&NSColor::clearColor()) });
|
||||
}
|
||||
|
||||
// register for drag and drop operations.
|
||||
@@ -821,7 +823,23 @@ impl WindowDelegate {
|
||||
}
|
||||
|
||||
pub fn set_transparent(&self, transparent: bool) {
|
||||
self.window().setOpaque(!transparent)
|
||||
// This is just a hint for Quartz, it doesn't actually speculate with window alpha.
|
||||
// Providing a wrong value here could result in visual artifacts, when the window is
|
||||
// transparent.
|
||||
self.window().setOpaque(!transparent);
|
||||
|
||||
// AppKit draws the window with a background color by default, which is usually really
|
||||
// nice, but gets in the way when we want to allow the contents of the window to be
|
||||
// transparent, as in that case, the transparent contents will just be drawn on top of
|
||||
// the background color. As such, to allow the window to be transparent, we must also set
|
||||
// the background color to one with an empty alpha channel.
|
||||
let color = if transparent {
|
||||
unsafe { NSColor::clearColor() }
|
||||
} else {
|
||||
unsafe { NSColor::windowBackgroundColor() }
|
||||
};
|
||||
|
||||
self.window().setBackgroundColor(Some(&color));
|
||||
}
|
||||
|
||||
pub fn set_blur(&self, blur: bool) {
|
||||
@@ -920,8 +938,8 @@ impl WindowDelegate {
|
||||
|
||||
pub fn set_max_inner_size(&self, dimensions: Option<Size>) {
|
||||
let dimensions = dimensions.unwrap_or(Size::Logical(LogicalSize {
|
||||
width: std::f32::MAX as f64,
|
||||
height: std::f32::MAX as f64,
|
||||
width: f32::MAX as f64,
|
||||
height: f32::MAX as f64,
|
||||
}));
|
||||
let scale_factor = self.scale_factor();
|
||||
let max_size = dimensions.to_logical::<CGFloat>(scale_factor);
|
||||
|
||||
@@ -103,7 +103,7 @@ pub struct WindowId {
|
||||
|
||||
impl WindowId {
|
||||
pub const fn dummy() -> Self {
|
||||
WindowId { fd: u64::max_value() }
|
||||
WindowId { fd: u64::MAX }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +68,12 @@ impl<T> Dispatcher<T> {
|
||||
// SAFETY: The `transmute` is necessary because `Closure` requires `'static`. This is
|
||||
// safe because this function won't return until `f` has finished executing. See
|
||||
// `Self::new()`.
|
||||
let closure = Closure(unsafe { std::mem::transmute(closure) });
|
||||
let closure = Closure(unsafe {
|
||||
std::mem::transmute::<
|
||||
Box<dyn FnOnce(&T) + Send>,
|
||||
Box<dyn FnOnce(&T) + Send + 'static>,
|
||||
>(closure)
|
||||
});
|
||||
|
||||
self.0.send(closure);
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use std::future;
|
||||
use std::num::NonZeroUsize;
|
||||
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
||||
use std::sync::Arc;
|
||||
use std::task::Poll;
|
||||
@@ -6,13 +7,13 @@ use std::task::Poll;
|
||||
use super::super::main_thread::MainThreadMarker;
|
||||
use super::{AtomicWaker, Wrapper};
|
||||
|
||||
pub struct WakerSpawner<T: 'static>(Wrapper<Handler<T>, Sender, usize>);
|
||||
pub struct WakerSpawner<T: 'static>(Wrapper<Handler<T>, Sender, NonZeroUsize>);
|
||||
|
||||
pub struct Waker<T: 'static>(Wrapper<Handler<T>, Sender, usize>);
|
||||
pub struct Waker<T: 'static>(Wrapper<Handler<T>, Sender, NonZeroUsize>);
|
||||
|
||||
struct Handler<T> {
|
||||
value: T,
|
||||
handler: fn(&T, usize),
|
||||
handler: fn(&T, NonZeroUsize, bool),
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -20,7 +21,11 @@ struct Sender(Arc<Inner>);
|
||||
|
||||
impl<T> WakerSpawner<T> {
|
||||
#[track_caller]
|
||||
pub fn new(main_thread: MainThreadMarker, value: T, handler: fn(&T, usize)) -> Option<Self> {
|
||||
pub fn new(
|
||||
main_thread: MainThreadMarker,
|
||||
value: T,
|
||||
handler: fn(&T, NonZeroUsize, bool),
|
||||
) -> Option<Self> {
|
||||
let inner = Arc::new(Inner {
|
||||
counter: AtomicUsize::new(0),
|
||||
waker: AtomicWaker::new(),
|
||||
@@ -37,7 +42,7 @@ impl<T> WakerSpawner<T> {
|
||||
|handler, count| {
|
||||
let handler = handler.borrow();
|
||||
let handler = handler.as_ref().unwrap();
|
||||
(handler.handler)(&handler.value, count);
|
||||
(handler.handler)(&handler.value, count, true);
|
||||
},
|
||||
{
|
||||
let inner = Arc::clone(&inner);
|
||||
@@ -46,29 +51,31 @@ impl<T> WakerSpawner<T> {
|
||||
while let Some(count) = future::poll_fn(|cx| {
|
||||
let count = inner.counter.swap(0, Ordering::Relaxed);
|
||||
|
||||
if count > 0 {
|
||||
Poll::Ready(Some(count))
|
||||
} else {
|
||||
inner.waker.register(cx.waker());
|
||||
match NonZeroUsize::new(count) {
|
||||
Some(count) => Poll::Ready(Some(count)),
|
||||
None => {
|
||||
inner.waker.register(cx.waker());
|
||||
|
||||
let count = inner.counter.swap(0, Ordering::Relaxed);
|
||||
let count = inner.counter.swap(0, Ordering::Relaxed);
|
||||
|
||||
if count > 0 {
|
||||
Poll::Ready(Some(count))
|
||||
} else {
|
||||
if inner.closed.load(Ordering::Relaxed) {
|
||||
return Poll::Ready(None);
|
||||
match NonZeroUsize::new(count) {
|
||||
Some(count) => Poll::Ready(Some(count)),
|
||||
None => {
|
||||
if inner.closed.load(Ordering::Relaxed) {
|
||||
return Poll::Ready(None);
|
||||
}
|
||||
|
||||
Poll::Pending
|
||||
},
|
||||
}
|
||||
|
||||
Poll::Pending
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
.await
|
||||
{
|
||||
let handler = handler.borrow();
|
||||
let handler = handler.as_ref().unwrap();
|
||||
(handler.handler)(&handler.value, count);
|
||||
(handler.handler)(&handler.value, count, false);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -107,7 +114,7 @@ impl<T> Drop for WakerSpawner<T> {
|
||||
|
||||
impl<T> Waker<T> {
|
||||
pub fn wake(&self) {
|
||||
self.0.send(1)
|
||||
self.0.send(NonZeroUsize::MIN)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -324,7 +324,11 @@ impl Inner {
|
||||
match &self.cursor {
|
||||
SelectedCursor::Icon(icon)
|
||||
| SelectedCursor::Loading { previous: Previous::Icon(icon), .. } => {
|
||||
self.style.set("cursor", icon.name())
|
||||
if let CursorIcon::Default = icon {
|
||||
self.style.remove("cursor")
|
||||
} else {
|
||||
self.style.set("cursor", icon.name())
|
||||
}
|
||||
},
|
||||
SelectedCursor::Loading { previous: Previous::Image(cursor), .. }
|
||||
| SelectedCursor::Image(cursor) => {
|
||||
|
||||
@@ -53,7 +53,11 @@ impl<T> EventLoop<T> {
|
||||
// SAFETY: The `transmute` is necessary because `run()` requires `'static`. This is safe
|
||||
// because this function will never return and all resources not cleaned up by the point we
|
||||
// `throw` will leak, making this actually `'static`.
|
||||
let handler = unsafe { std::mem::transmute(handler) };
|
||||
let handler = unsafe {
|
||||
std::mem::transmute::<Box<dyn FnMut(Event<()>)>, Box<dyn FnMut(Event<()>) + 'static>>(
|
||||
handler,
|
||||
)
|
||||
};
|
||||
self.elw.p.run(handler, false);
|
||||
|
||||
// Throw an exception to break out of Rust execution and use unreachable to tell the
|
||||
|
||||
@@ -14,12 +14,15 @@ use crate::platform_impl::platform::r#async::{DispatchRunner, Waker, WakerSpawne
|
||||
use crate::platform_impl::platform::window::Inner;
|
||||
use crate::window::WindowId;
|
||||
|
||||
use js_sys::Function;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::collections::{HashSet, VecDeque};
|
||||
use std::iter;
|
||||
use std::num::NonZeroUsize;
|
||||
use std::ops::Deref;
|
||||
use std::rc::{Rc, Weak};
|
||||
use wasm_bindgen::prelude::Closure;
|
||||
use wasm_bindgen::prelude::{wasm_bindgen, Closure};
|
||||
use wasm_bindgen::JsCast;
|
||||
use web_sys::{Document, KeyboardEvent, PageTransitionEvent, PointerEvent, WheelEvent};
|
||||
use web_time::{Duration, Instant};
|
||||
|
||||
@@ -133,12 +136,13 @@ impl Shared {
|
||||
let document = window.document().expect("Failed to obtain document");
|
||||
|
||||
Shared(Rc::<Execution>::new_cyclic(|weak| {
|
||||
let proxy_spawner = WakerSpawner::new(main_thread, weak.clone(), |runner, count| {
|
||||
if let Some(runner) = runner.upgrade() {
|
||||
Shared(runner).send_events(iter::repeat(Event::UserEvent(())).take(count))
|
||||
}
|
||||
})
|
||||
.expect("`EventLoop` has to be created in the main thread");
|
||||
let proxy_spawner =
|
||||
WakerSpawner::new(main_thread, weak.clone(), |runner, count, local| {
|
||||
if let Some(runner) = runner.upgrade() {
|
||||
Shared(runner).send_user_events(count, local)
|
||||
}
|
||||
})
|
||||
.expect("`EventLoop` has to be created in the main thread");
|
||||
|
||||
Execution {
|
||||
main_thread,
|
||||
@@ -460,6 +464,51 @@ impl Shared {
|
||||
self.send_events(iter::once(event));
|
||||
}
|
||||
|
||||
// Add a series of user events to the event loop runner
|
||||
//
|
||||
// This will schedule the event loop to wake up instead of waking it up immediately if its not
|
||||
// running.
|
||||
pub(crate) fn send_user_events(&self, count: NonZeroUsize, local: bool) {
|
||||
// If the event loop is closed, it should discard any new events
|
||||
if self.is_closed() {
|
||||
return;
|
||||
}
|
||||
|
||||
if local {
|
||||
// If the loop is not running and triggered locally, queue on next microtick.
|
||||
if let Ok(RunnerEnum::Running(ref runner)) =
|
||||
self.0.runner.try_borrow().as_ref().map(Deref::deref)
|
||||
{
|
||||
// If we're currently polling let `send_events` do its job.
|
||||
if !matches!(runner.state, State::Poll { .. }) {
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
#[wasm_bindgen(js_name = queueMicrotask)]
|
||||
fn queue_microtask(task: Function);
|
||||
}
|
||||
|
||||
queue_microtask(
|
||||
Closure::once_into_js({
|
||||
let this = Rc::downgrade(&self.0);
|
||||
move || {
|
||||
if let Some(shared) = this.upgrade() {
|
||||
Shared(shared).send_events(
|
||||
iter::repeat(Event::UserEvent(())).take(count.get()),
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
.unchecked_into(),
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.send_events(iter::repeat(Event::UserEvent(())).take(count.get()))
|
||||
}
|
||||
|
||||
// Add a series of events to the event loop runner
|
||||
//
|
||||
// It will determine if the event should be immediately sent to the user or buffered for later
|
||||
@@ -473,7 +522,7 @@ impl Shared {
|
||||
match self.0.runner.try_borrow().as_ref().map(Deref::deref) {
|
||||
Ok(RunnerEnum::Running(ref runner)) => {
|
||||
// If we're currently polling, queue this and wait for the poll() method to be
|
||||
// called
|
||||
// called.
|
||||
if let State::Poll { .. } = runner.state {
|
||||
process_immediately = false;
|
||||
}
|
||||
|
||||
@@ -427,8 +427,8 @@ impl Canvas {
|
||||
|
||||
pub(crate) fn on_resize_scale<S, R>(&mut self, scale_handler: S, size_handler: R)
|
||||
where
|
||||
S: 'static + FnMut(PhysicalSize<u32>, f64),
|
||||
R: 'static + FnMut(PhysicalSize<u32>),
|
||||
S: 'static + Fn(PhysicalSize<u32>, f64),
|
||||
R: 'static + Fn(PhysicalSize<u32>),
|
||||
{
|
||||
self.on_resize_scale = Some(ResizeScaleHandle::new(
|
||||
self.window().clone(),
|
||||
|
||||
@@ -16,7 +16,7 @@ use super::media_query_handle::MediaQueryListHandle;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct ResizeScaleHandle(Rc<RefCell<ResizeScaleInternal>>);
|
||||
pub struct ResizeScaleHandle(Rc<ResizeScaleInternal>);
|
||||
|
||||
impl ResizeScaleHandle {
|
||||
pub(crate) fn new<S, R>(
|
||||
@@ -28,8 +28,8 @@ impl ResizeScaleHandle {
|
||||
resize_handler: R,
|
||||
) -> Self
|
||||
where
|
||||
S: 'static + FnMut(PhysicalSize<u32>, f64),
|
||||
R: 'static + FnMut(PhysicalSize<u32>),
|
||||
S: 'static + Fn(PhysicalSize<u32>, f64),
|
||||
R: 'static + Fn(PhysicalSize<u32>),
|
||||
{
|
||||
Self(ResizeScaleInternal::new(
|
||||
window,
|
||||
@@ -42,7 +42,7 @@ impl ResizeScaleHandle {
|
||||
}
|
||||
|
||||
pub(crate) fn notify_resize(&self) {
|
||||
self.0.borrow_mut().notify()
|
||||
self.0.notify()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,11 +53,11 @@ struct ResizeScaleInternal {
|
||||
document: Document,
|
||||
canvas: HtmlCanvasElement,
|
||||
style: Style,
|
||||
mql: MediaQueryListHandle,
|
||||
mql: RefCell<MediaQueryListHandle>,
|
||||
observer: ResizeObserver,
|
||||
_observer_closure: Closure<dyn FnMut(Array, ResizeObserver)>,
|
||||
scale_handler: Box<dyn FnMut(PhysicalSize<u32>, f64)>,
|
||||
resize_handler: Box<dyn FnMut(PhysicalSize<u32>)>,
|
||||
scale_handler: Box<dyn Fn(PhysicalSize<u32>, f64)>,
|
||||
resize_handler: Box<dyn Fn(PhysicalSize<u32>)>,
|
||||
notify_scale: Cell<bool>,
|
||||
}
|
||||
|
||||
@@ -69,12 +69,12 @@ impl ResizeScaleInternal {
|
||||
style: Style,
|
||||
scale_handler: S,
|
||||
resize_handler: R,
|
||||
) -> Rc<RefCell<Self>>
|
||||
) -> Rc<Self>
|
||||
where
|
||||
S: 'static + FnMut(PhysicalSize<u32>, f64),
|
||||
R: 'static + FnMut(PhysicalSize<u32>),
|
||||
S: 'static + Fn(PhysicalSize<u32>, f64),
|
||||
R: 'static + Fn(PhysicalSize<u32>),
|
||||
{
|
||||
Rc::<RefCell<ResizeScaleInternal>>::new_cyclic(|weak_self| {
|
||||
Rc::<ResizeScaleInternal>::new_cyclic(|weak_self| {
|
||||
let mql = Self::create_mql(&window, {
|
||||
let weak_self = weak_self.clone();
|
||||
move |mql| {
|
||||
@@ -86,9 +86,7 @@ impl ResizeScaleInternal {
|
||||
|
||||
let weak_self = weak_self.clone();
|
||||
let observer_closure = Closure::new(move |entries: Array, _| {
|
||||
if let Some(rc_self) = weak_self.upgrade() {
|
||||
let mut this = rc_self.borrow_mut();
|
||||
|
||||
if let Some(this) = weak_self.upgrade() {
|
||||
let size = this.process_entry(entries);
|
||||
|
||||
if this.notify_scale.replace(false) {
|
||||
@@ -101,18 +99,18 @@ impl ResizeScaleInternal {
|
||||
});
|
||||
let observer = Self::create_observer(&canvas, observer_closure.as_ref());
|
||||
|
||||
RefCell::new(Self {
|
||||
Self {
|
||||
window,
|
||||
document,
|
||||
canvas,
|
||||
style,
|
||||
mql,
|
||||
mql: RefCell::new(mql),
|
||||
observer,
|
||||
_observer_closure: observer_closure,
|
||||
scale_handler: Box::new(scale_handler),
|
||||
resize_handler: Box::new(resize_handler),
|
||||
notify_scale: Cell::new(false),
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -152,7 +150,7 @@ impl ResizeScaleInternal {
|
||||
observer
|
||||
}
|
||||
|
||||
fn notify(&mut self) {
|
||||
fn notify(&self) {
|
||||
if !self.document.contains(Some(&self.canvas)) || self.style.get("display") == "none" {
|
||||
let size = PhysicalSize::new(0, 0);
|
||||
|
||||
@@ -200,10 +198,9 @@ impl ResizeScaleInternal {
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_scale(this: Rc<RefCell<Self>>, mql: &MediaQueryList) {
|
||||
let weak_self = Rc::downgrade(&this);
|
||||
let mut this = this.borrow_mut();
|
||||
let scale = super::scale_factor(&this.window);
|
||||
fn handle_scale(self: Rc<Self>, mql: &MediaQueryList) {
|
||||
let weak_self = Rc::downgrade(&self);
|
||||
let scale = super::scale_factor(&self.window);
|
||||
|
||||
// TODO: confirm/reproduce this problem, see:
|
||||
// <https://github.com/rust-windowing/winit/issues/2597>.
|
||||
@@ -217,15 +214,15 @@ impl ResizeScaleInternal {
|
||||
return;
|
||||
}
|
||||
|
||||
let new_mql = Self::create_mql(&this.window, move |mql| {
|
||||
let new_mql = Self::create_mql(&self.window, move |mql| {
|
||||
if let Some(rc_self) = weak_self.upgrade() {
|
||||
Self::handle_scale(rc_self, mql);
|
||||
}
|
||||
});
|
||||
this.mql = new_mql;
|
||||
self.mql.replace(new_mql);
|
||||
|
||||
this.notify_scale.set(true);
|
||||
this.notify();
|
||||
self.notify_scale.set(true);
|
||||
self.notify();
|
||||
}
|
||||
|
||||
fn process_entry(&self, entries: Array) -> PhysicalSize<u32> {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#![cfg(windows_platform)]
|
||||
|
||||
use smol_str::SmolStr;
|
||||
use windows_sys::Win32::Foundation::{HANDLE, HWND};
|
||||
use windows_sys::Win32::UI::WindowsAndMessaging::{HMENU, WINDOW_LONG_PTR_INDEX};
|
||||
|
||||
@@ -942,8 +942,7 @@ impl Window {
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **macOS:** If you're not drawing to the window yourself, you might have to set the
|
||||
/// background color of the window to enable transparency.
|
||||
/// - **macOS:** This will reset the window's background color.
|
||||
/// - **Web / iOS / Android:** Unsupported.
|
||||
/// - **X11:** Can only be set while building the window, with
|
||||
/// [`WindowAttributes::with_transparent`].
|
||||
|
||||
Reference in New Issue
Block a user