Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
dzhou121 committed Nov 28, 2023
2 parents 7608048 + 0be2bb0 commit 0e4ac14
Show file tree
Hide file tree
Showing 24 changed files with 397 additions and 295 deletions.
3 changes: 0 additions & 3 deletions .gitmodules

This file was deleted.

12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,19 @@ Unreleased` header.

# Unreleased

- On macOS, add services menu.
- On macOS, remove spurious error logging when handling `Fn`.

# 0.29.4

- Fix crash when running iOS app on macOS.
- On X11, check common alternative cursor names when loading cursor.
- On X11, reload the DPI after a property change event.
- On Windows, fix so `drag_window` and `drag_resize_window` can be called from another thread.
- On Windows, fix `set_control_flow` in `AboutToWait` not being taken in account.
- On macOS, send a `Resized` event after each `ScaleFactorChanged` event.
- On Wayland, fix `wl_surface` being destroyed before associated objects.
- On macOS, fix assertion when pressing `Fn` key.

# 0.29.3

Expand Down
15 changes: 11 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "winit"
version = "0.29.3"
version = "0.29.4"
authors = ["The winit contributors", "Pierre Krieger <[email protected]>"]
description = "Cross-platform window creation library."
edition = "2021"
Expand All @@ -13,7 +13,14 @@ categories = ["gui"]
rust-version = "1.65.0"

[package.metadata.docs.rs]
features = ["rwh_04", "rwh_05", "rwh_06", "serde"]
features = [
"rwh_04",
"rwh_05",
"rwh_06",
"serde",
# Enabled to get docs to compile
"android-native-activity",
]
default-target = "x86_64-unknown-linux-gnu"
# These are all tested in CI
targets = [
Expand Down Expand Up @@ -54,7 +61,7 @@ cfg_aliases = "0.1.1"

[dependencies]
bitflags = "2"
cursor-icon = "1.0.0"
cursor-icon = "1.1.0"
log = "0.4"
mint = { version = "0.5.6", optional = true }
once_cell = "1.12"
Expand All @@ -74,7 +81,7 @@ softbuffer = "0.3.0"

[target.'cfg(target_os = "android")'.dependencies]
android-activity = "0.5.0"
ndk = "0.8.0"
ndk = { version = "0.8.0", default-features = false }
ndk-sys = "0.5.0"

[target.'cfg(any(target_os = "ios", target_os = "macos"))'.dependencies]
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

```toml
[dependencies]
winit = "0.29.3"
winit = "0.29.4"
```

## [Documentation](https://docs.rs/winit)
Expand Down Expand Up @@ -157,7 +157,7 @@ For more details, refer to these `android-activity` [example applications](https

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.29.3", features = [ "android-native-activity" ] }`
2. Enable the `"android-native-activity"` feature for Winit: `winit = { version = "0.29.4", 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 logging as above).
4. Pass a clone of the `AndroidApp` that your application receives to Winit when building your event loop (as shown above).

Expand Down
1 change: 1 addition & 0 deletions clippy.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ disallowed-methods = [
{ path = "web_sys::HtmlCanvasElement::set_height", reason = "Winit shouldn't touch the internal canvas size" },
{ path = "web_sys::Window::document", reason = "cache this to reduce calls to JS" },
{ path = "web_sys::Window::get_computed_style", reason = "cache this to reduce calls to JS" },
{ path = "web_sys::HtmlElement::style", reason = "cache this to reduce calls to JS" },
{ path = "web_sys::Element::request_fullscreen", reason = "Doesn't account for compatibility with Safari" },
{ path = "web_sys::Document::exit_fullscreen", reason = "Doesn't account for compatibility with Safari" },
{ path = "web_sys::Document::fullscreen_element", reason = "Doesn't account for compatibility with Safari" },
Expand Down
6 changes: 1 addition & 5 deletions src/icon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,7 @@ impl fmt::Display for BadIcon {
}
}

impl Error for BadIcon {
fn source(&self) -> Option<&(dyn Error + 'static)> {
Some(self)
}
}
impl Error for BadIcon {}

#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct RgbaIcon {
Expand Down
5 changes: 5 additions & 0 deletions src/platform/android.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,5 +84,10 @@ impl<T> EventLoopBuilderExtAndroid for EventLoopBuilder<T> {
/// use winit::platform::android::activity::AndroidApp;
/// ```
pub mod activity {
// We enable the `"native-activity"` feature just so that we can build the
// docs, but it'll be very confusing for users to see the docs with that
// feature enabled, so we avoid inlining it so that they're forced to view
// it on the crate's own docs.rs page.
#[doc(no_inline)]
pub use android_activity::*;
}
14 changes: 11 additions & 3 deletions src/platform_impl/ios/app_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,10 @@ impl AppState {
)
}

fn has_terminated(&self) -> bool {
matches!(self.state(), AppStateImpl::Terminated)
}

fn will_launch_transition(&mut self, queued_event_handler: Box<dyn EventHandler>) {
let (queued_windows, queued_events, queued_gpu_redraws) = match self.take_state() {
AppStateImpl::NotLaunched {
Expand Down Expand Up @@ -243,7 +247,7 @@ impl AppState {
fn wakeup_transition(&mut self) -> Option<EventWrapper> {
// before `AppState::did_finish_launching` is called, pretend there is no running
// event loop.
if !self.has_launched() {
if !self.has_launched() || self.has_terminated() {
return None;
}

Expand Down Expand Up @@ -390,7 +394,7 @@ impl AppState {
}

fn events_cleared_transition(&mut self) {
if !self.has_launched() {
if !self.has_launched() || self.has_terminated() {
return;
}
let (waiting_event_handler, old) = match self.take_state() {
Expand Down Expand Up @@ -586,6 +590,10 @@ pub(crate) fn handle_nonuser_events<I: IntoIterator<Item = EventWrapper>>(
events: I,
) {
let mut this = AppState::get_mut(mtm);
if this.has_terminated() {
return;
}

let (mut event_handler, active_control_flow, processing_redraws) =
match this.try_user_callback_transition() {
UserCallbackTransitionResult::ReentrancyPrevented { queued_events } => {
Expand Down Expand Up @@ -737,7 +745,7 @@ fn handle_user_events(mtm: MainThreadMarker) {

pub fn handle_main_events_cleared(mtm: MainThreadMarker) {
let mut this = AppState::get_mut(mtm);
if !this.has_launched() {
if !this.has_launched() || this.has_terminated() {
return;
}
match this.state_mut() {
Expand Down
4 changes: 2 additions & 2 deletions src/platform_impl/ios/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ fn setup_control_flow_observers() {
#[allow(non_upper_case_globals)]
match activity {
kCFRunLoopBeforeWaiting => app_state::handle_main_events_cleared(mtm),
kCFRunLoopExit => unimplemented!(), // not expected to ever happen
kCFRunLoopExit => {} // may happen when running on macOS
_ => unreachable!(),
}
}
Expand All @@ -304,7 +304,7 @@ fn setup_control_flow_observers() {
#[allow(non_upper_case_globals)]
match activity {
kCFRunLoopBeforeWaiting => app_state::handle_events_cleared(mtm),
kCFRunLoopExit => unimplemented!(), // not expected to ever happen
kCFRunLoopExit => {} // may happen when running on macOS
_ => unreachable!(),
}
}
Expand Down
21 changes: 7 additions & 14 deletions src/platform_impl/linux/wayland/window/state.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//! The state of the window, which is shared with the event-loop.
use std::mem::ManuallyDrop;
use std::num::NonZeroU32;
use std::sync::{Arc, Weak};
use std::time::Duration;
Expand Down Expand Up @@ -55,9 +54,6 @@ pub struct WindowState {
/// The connection to Wayland server.
pub connection: Connection,

/// The underlying SCTK window.
pub window: ManuallyDrop<Window>,

/// The window frame, which is created from the configure request.
frame: Option<WinitFrame>,

Expand Down Expand Up @@ -149,6 +145,9 @@ pub struct WindowState {
///
/// The value is the serial of the event triggered moved.
has_pending_move: Option<u32>,

/// The underlying SCTK window.
pub window: Window,
}

impl WindowState {
Expand Down Expand Up @@ -206,7 +205,7 @@ impl WindowState {
title: String::default(),
transparent: false,
viewport,
window: ManuallyDrop::new(window),
window,
}
}

Expand Down Expand Up @@ -271,7 +270,7 @@ impl WindowState {
&& !self.csd_fails
{
match WinitFrame::new(
&*self.window,
&self.window,
shm,
subcompositor.clone(),
self.queue_handle.clone(),
Expand Down Expand Up @@ -1026,13 +1025,6 @@ impl WindowState {

impl Drop for WindowState {
fn drop(&mut self) {
let surface = self.window.wl_surface().clone();
unsafe {
ManuallyDrop::drop(&mut self.window);
}

// Cleanup objects.

if let Some(blur) = self.blur.take() {
blur.release();
}
Expand All @@ -1045,7 +1037,8 @@ impl Drop for WindowState {
viewport.destroy();
}

surface.destroy();
// NOTE: the wl_surface used by the window is being cleaned up when
// dropping SCTK `Window`.
}
}

Expand Down
114 changes: 48 additions & 66 deletions src/platform_impl/linux/x11/event_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,14 @@ impl<T: 'static> EventProcessor<T> {
event: WindowEvent::Destroyed,
});
}
ffi::PropertyNotify => {
let xev: &ffi::XPropertyEvent = xev.as_ref();
let atom = xev.atom as xproto::Atom;

if atom == xproto::Atom::from(xproto::AtomEnum::RESOURCE_MANAGER) {
self.process_dpi_change(&mut callback);
}
}

ffi::VisibilityNotify => {
let xev: &ffi::XVisibilityEvent = xev.as_ref();
Expand Down Expand Up @@ -1306,72 +1314,7 @@ impl<T: 'static> EventProcessor<T> {
}
}
if event_type == self.randr_event_offset as c_int {
// In the future, it would be quite easy to emit monitor hotplug events.
let prev_list = wt.xconn.invalidate_cached_monitor_list();
if let Some(prev_list) = prev_list {
let new_list = wt
.xconn
.available_monitors()
.expect("Failed to get monitor list");
for new_monitor in new_list {
// Previous list may be empty, in case of disconnecting and
// reconnecting the only one monitor. We still need to emit events in
// this case.
let maybe_prev_scale_factor = prev_list
.iter()
.find(|prev_monitor| prev_monitor.name == new_monitor.name)
.map(|prev_monitor| prev_monitor.scale_factor);
if Some(new_monitor.scale_factor) != maybe_prev_scale_factor {
for (window_id, window) in wt.windows.borrow().iter() {
if let Some(window) = window.upgrade() {
// Check if the window is on this monitor
let monitor =
window.shared_state_lock().last_monitor.clone();
if monitor.name == new_monitor.name {
let (width, height) = window.inner_size_physical();
let (new_width, new_height) = window.adjust_for_dpi(
// If we couldn't determine the previous scale
// factor (e.g., because all monitors were closed
// before), just pick whatever the current monitor
// has set as a baseline.
maybe_prev_scale_factor
.unwrap_or(monitor.scale_factor),
new_monitor.scale_factor,
width,
height,
&window.shared_state_lock(),
);

let window_id = crate::window::WindowId(*window_id);
let old_inner_size = PhysicalSize::new(width, height);
let inner_size = Arc::new(Mutex::new(
PhysicalSize::new(new_width, new_height),
));
callback(Event::WindowEvent {
window_id,
event: WindowEvent::ScaleFactorChanged {
scale_factor: new_monitor.scale_factor,
inner_size_writer: InnerSizeWriter::new(
Arc::downgrade(&inner_size),
),
},
});

let new_inner_size = *inner_size.lock().unwrap();
drop(inner_size);

if new_inner_size != old_inner_size {
let (new_width, new_height) = new_inner_size.into();
window.request_inner_size_physical(
new_width, new_height,
);
}
}
}
}
}
}
}
self.process_dpi_change(&mut callback);
}
}
}
Expand Down Expand Up @@ -1464,6 +1407,45 @@ impl<T: 'static> EventProcessor<T> {
});
}
}

fn process_dpi_change<F>(&self, callback: &mut F)
where
F: FnMut(Event<T>),
{
let wt = get_xtarget(&self.target);

// In the future, it would be quite easy to emit monitor hotplug events.
let prev_list = {
let prev_list = wt.xconn.invalidate_cached_monitor_list();
match prev_list {
Some(prev_list) => prev_list,
None => return,
}
};

let new_list = wt
.xconn
.available_monitors()
.expect("Failed to get monitor list");
for new_monitor in new_list {
// Previous list may be empty, in case of disconnecting and
// reconnecting the only one monitor. We still need to emit events in
// this case.
let maybe_prev_scale_factor = prev_list
.iter()
.find(|prev_monitor| prev_monitor.name == new_monitor.name)
.map(|prev_monitor| prev_monitor.scale_factor);
if Some(new_monitor.scale_factor) != maybe_prev_scale_factor {
for window in wt.windows.borrow().iter().filter_map(|(_, w)| w.upgrade()) {
window.refresh_dpi_for_monitor(
&new_monitor,
maybe_prev_scale_factor,
&mut *callback,
)
}
}
}
}
}

fn is_first_touch(first: &mut Option<u64>, num: &mut u32, id: u64, phase: TouchPhase) -> bool {
Expand Down
Loading

0 comments on commit 0e4ac14

Please sign in to comment.