chore: Update msrv to 1.74 and test it in CI (#1050)

This commit is contained in:
Fabian-Lars
2025-02-21 19:54:37 +01:00
committed by GitHub
parent 8c8f0e8b79
commit 3664513621
38 changed files with 3260 additions and 155 deletions

5
.changes/msrv.md Normal file
View File

@@ -0,0 +1,5 @@
---
tao: patch
---
Raised MSRV to 1.74

View File

@@ -47,8 +47,6 @@ jobs:
key: ${{ matrix.platform.target }}-cargo-stable key: ${{ matrix.platform.target }}-cargo-stable
- uses: dtolnay/rust-toolchain@stable - uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.platform.target }}
- name: Install Gtk (ubuntu only) - name: Install Gtk (ubuntu only)
if: matrix.platform.os == 'ubuntu-latest' if: matrix.platform.os == 'ubuntu-latest'
@@ -64,6 +62,10 @@ jobs:
if: contains(matrix.platform.target, 'android') if: contains(matrix.platform.target, 'android')
run: cargo install cargo-apk run: cargo install cargo-apk
- uses: dtolnay/rust-toolchain@1.74
with:
targets: ${{ matrix.platform.target }}
- name: Check documentation - name: Check documentation
shell: bash shell: bash
run: cargo $CMD doc --no-deps --target ${{ matrix.platform.target }} $OPTIONS --features $FEATURES run: cargo $CMD doc --no-deps --target ${{ matrix.platform.target }} $OPTIONS --features $FEATURES

1
.gitignore vendored
View File

@@ -2,7 +2,6 @@
# Copyright 2021-2023 Tauri Programme within The Commons Conservancy # Copyright 2021-2023 Tauri Programme within The Commons Conservancy
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
Cargo.lock
target/ target/
rls/ rls/
.vscode/ .vscode/

3127
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -7,7 +7,7 @@ authors = [
"The winit contributors" "The winit contributors"
] ]
edition = "2021" edition = "2021"
rust-version = "1.70" rust-version = "1.74"
keywords = [ "windowing" ] keywords = [ "windowing" ]
license = "Apache-2.0" license = "Apache-2.0"
readme = "README.md" readme = "README.md"

View File

@@ -51,11 +51,11 @@ fn main() {
event: event:
KeyEvent { KeyEvent {
state: ElementState::Released, state: ElementState::Released,
logical_key, logical_key: Key::Character("x"),
.. ..
}, },
.. ..
} if logical_key == Key::Character("x") => { } => {
switched = !switched; switched = !switched;
name_windows(entered_id, switched, &window_1, &window_2); name_windows(entered_id, switched, &window_1, &window_2);
println!("Switched!") println!("Switched!")

View File

@@ -52,23 +52,31 @@ fn main() {
.. ..
} => match key_str { } => match key_str {
"e" => { "e" => {
size_constraints.min_width = size_constraints.min_width = size_constraints
(!size_constraints.min_width.is_some()).then_some(LogicalUnit::new(min_width).into()); .min_width
.is_none()
.then_some(LogicalUnit::new(min_width).into());
window.set_inner_size_constraints(size_constraints); window.set_inner_size_constraints(size_constraints);
} }
"f" => { "f" => {
size_constraints.max_width = size_constraints.max_width = size_constraints
(!size_constraints.max_width.is_some()).then_some(LogicalUnit::new(max_width).into()); .max_width
.is_none()
.then_some(LogicalUnit::new(max_width).into());
window.set_inner_size_constraints(size_constraints); window.set_inner_size_constraints(size_constraints);
} }
"p" => { "p" => {
size_constraints.min_height = size_constraints.min_height = size_constraints
(!size_constraints.min_height.is_some()).then_some(LogicalUnit::new(min_height).into()); .min_height
.is_none()
.then_some(LogicalUnit::new(min_height).into());
window.set_inner_size_constraints(size_constraints); window.set_inner_size_constraints(size_constraints);
} }
"v" => { "v" => {
size_constraints.max_height = size_constraints.max_height = size_constraints
(!size_constraints.max_height.is_some()).then_some(LogicalUnit::new(max_height).into()); .max_height
.is_none()
.then_some(LogicalUnit::new(max_height).into());
window.set_inner_size_constraints(size_constraints); window.set_inner_size_constraints(size_constraints);
} }
_ => {} _ => {}

View File

@@ -40,7 +40,7 @@ fn main() {
// We need to update our chosen video mode if the window // We need to update our chosen video mode if the window
// was moved to an another monitor, so that the window // was moved to an another monitor, so that the window
// appears on this monitor instead when we go fullscreen // appears on this monitor instead when we go fullscreen
let previous_video_mode = video_modes.iter().cloned().nth(video_mode_id); let previous_video_mode = video_modes.iter().nth(video_mode_id).cloned();
video_modes = window.current_monitor().unwrap().video_modes().collect(); video_modes = window.current_monitor().unwrap().video_modes().collect();
video_mode_id = video_mode_id.min(video_modes.len()); video_mode_id = video_mode_id.min(video_modes.len());
let video_mode = video_modes.iter().nth(video_mode_id); let video_mode = video_modes.iter().nth(video_mode_id);

View File

@@ -2,7 +2,6 @@
// Copyright 2021-2023 Tauri Programme within The Commons Conservancy // Copyright 2021-2023 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
use std::env::current_dir;
use tao::{ use tao::{
event::{ElementState, Event, KeyEvent, WindowEvent}, event::{ElementState, Event, KeyEvent, WindowEvent},
event_loop::{ControlFlow, EventLoop}, event_loop::{ControlFlow, EventLoop},
@@ -80,7 +79,7 @@ fn main() {
if modifiers.is_empty() { if modifiers.is_empty() {
#[cfg(windows)] #[cfg(windows)]
{ {
let mut path = current_dir().unwrap(); let mut path = std::env::current_dir().unwrap();
path.push("./examples/icon.ico"); path.push("./examples/icon.ico");
let icon = Icon::from_path(path, Some(PhysicalSize::new(32, 32))).unwrap(); let icon = Icon::from_path(path, Some(PhysicalSize::new(32, 32))).unwrap();

View File

@@ -32,7 +32,7 @@ fn main() {
let child_window_builder = WindowBuilder::new().with_inner_size(LogicalSize::new(200, 200)); let child_window_builder = WindowBuilder::new().with_inner_size(LogicalSize::new(200, 200));
#[cfg(any(target_os = "windows", target_os = "macos"))] #[cfg(any(target_os = "windows", target_os = "macos"))]
let child_window_builder = child_window_builder.with_parent_window(parent_window.clone()); let child_window_builder = child_window_builder.with_parent_window(parent_window);
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
let child_window_builder = child_window_builder.with_transient_for(parent_window); let child_window_builder = child_window_builder.with_transient_for(parent_window);
@@ -48,8 +48,10 @@ fn main() {
match event { match event {
Event::NewEvents(StartCause::Init) => println!("TAO application started!"), Event::NewEvents(StartCause::Init) => println!("TAO application started!"),
Event::WindowEvent { Event::WindowEvent {
event, window_id, .. event: WindowEvent::CloseRequested,
} if event == WindowEvent::CloseRequested => { window_id,
..
} => {
println!("Window {window_id:?} has received the signal to close"); println!("Window {window_id:?} has received the signal to close");
// This drop the window, causing it to close. // This drop the window, causing it to close.
windows.remove(&window_id); windows.remove(&window_id);

View File

@@ -31,7 +31,7 @@ fn main() {
} => { } => {
println!("on reopen, has visible windows: {has_visible_windows}"); println!("on reopen, has visible windows: {has_visible_windows}");
if !has_visible_windows { if !has_visible_windows {
window = Some(Window::new(&event_loop).unwrap()) window = Some(Window::new(event_loop).unwrap())
} }
} }
Event::MainEventsCleared => { Event::MainEventsCleared => {

View File

@@ -28,8 +28,8 @@ fn main() {
event_loop.run(move |event, _, control_flow| { event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Wait; *control_flow = ControlFlow::Wait;
match event { if let Event::WindowEvent { event, .. } = event {
Event::WindowEvent { event, .. } => match event { match event {
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit, WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
WindowEvent::KeyboardInput { WindowEvent::KeyboardInput {
event: KeyEvent { physical_key, .. }, event: KeyEvent { physical_key, .. },
@@ -44,8 +44,7 @@ fn main() {
println!("Theme is changed: {theme:?}") println!("Theme is changed: {theme:?}")
} }
_ => (), _ => (),
}, }
_ => (),
} }
}); });
} }

View File

@@ -112,9 +112,9 @@ pub enum Event<'a, T: 'static> {
/// ## Platform-specific /// ## Platform-specific
/// ///
/// - **Linux: This is triggered by `draw` signal of the gtk window. It can be used to detect if /// - **Linux: This is triggered by `draw` signal of the gtk window. It can be used to detect if
/// the window is requested to redraw. But widgets it contains are usually not tied to its signal. /// the window is requested to redraw. But widgets it contains are usually not tied to its signal.
/// So if you really want to draw each component, please consider using `connect_draw` method /// So if you really want to draw each component, please consider using `connect_draw` method
/// from [`WidgetExt`] directly.** /// from [`WidgetExt`] directly.**
/// ///
/// [`WidgetExt`]: https://gtk-rs.org/gtk3-rs/stable/latest/docs/gtk/prelude/trait.WidgetExt.html /// [`WidgetExt`]: https://gtk-rs.org/gtk3-rs/stable/latest/docs/gtk/prelude/trait.WidgetExt.html
RedrawRequested(WindowId), RedrawRequested(WindowId),
@@ -426,7 +426,7 @@ pub enum WindowEvent<'a> {
impl Clone for WindowEvent<'static> { impl Clone for WindowEvent<'static> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
use self::WindowEvent::*; use self::WindowEvent::*;
return match self { match self {
Resized(size) => Resized(*size), Resized(size) => Resized(*size),
Moved(pos) => Moved(*pos), Moved(pos) => Moved(*pos),
CloseRequested => CloseRequested, CloseRequested => CloseRequested,
@@ -511,7 +511,7 @@ impl Clone for WindowEvent<'static> {
unreachable!("Static event can't be about scale factor changing") unreachable!("Static event can't be about scale factor changing")
} }
DecorationsClick => DecorationsClick, DecorationsClick => DecorationsClick,
}; }
} }
} }
@@ -708,11 +708,11 @@ pub struct KeyEvent {
/// This has two use cases: /// This has two use cases:
/// - Allows querying whether the current input is a Dead key. /// - Allows querying whether the current input is a Dead key.
/// - Allows handling key-bindings on platforms which don't /// - Allows handling key-bindings on platforms which don't
/// support `key_without_modifiers`. /// support `key_without_modifiers`.
/// ///
/// ## Platform-specific /// ## Platform-specific
/// - **Web:** Dead keys might be reported as the real key instead /// - **Web:** Dead keys might be reported as the real key instead
/// of `Dead` depending on the browser/OS. /// of `Dead` depending on the browser/OS.
pub logical_key: keyboard::Key<'static>, pub logical_key: keyboard::Key<'static>,
/// Contains the text produced by this keypress. /// Contains the text produced by this keypress.
@@ -852,7 +852,7 @@ pub enum Force {
altitude_angle: Option<f64>, altitude_angle: Option<f64>,
}, },
/// If the platform reports the force as normalized, we have no way of /// If the platform reports the force as normalized, we have no way of
/// knowing how much pressure 1.0 corresponds to we know it's the maximum /// knowing how much pressure 1.0 corresponds to - we know it's the maximum
/// amount of force, but as to how much force, you might either have to /// amount of force, but as to how much force, you might either have to
/// press really really hard, or not hard at all, depending on the device. /// press really really hard, or not hard at all, depending on the device.
Normalized(f64), Normalized(f64),

View File

@@ -168,9 +168,10 @@ impl WindowExtMacOS for Window {
/// Corresponds to `NSApplicationActivationPolicy`. /// Corresponds to `NSApplicationActivationPolicy`.
#[non_exhaustive] #[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq, Default)]
pub enum ActivationPolicy { pub enum ActivationPolicy {
/// Corresponds to `NSApplicationActivationPolicyRegular`. /// Corresponds to `NSApplicationActivationPolicyRegular`.
#[default]
Regular, Regular,
/// Corresponds to `NSApplicationActivationPolicyAccessory`. /// Corresponds to `NSApplicationActivationPolicyAccessory`.
Accessory, Accessory,
@@ -178,12 +179,6 @@ pub enum ActivationPolicy {
Prohibited, Prohibited,
} }
impl Default for ActivationPolicy {
fn default() -> Self {
ActivationPolicy::Regular
}
}
/// Additional methods on `WindowBuilder` that are specific to MacOS. /// Additional methods on `WindowBuilder` that are specific to MacOS.
/// ///
/// **Note:** Properties dealing with the titlebar will be overwritten by the `with_decorations` method /// **Note:** Properties dealing with the titlebar will be overwritten by the `with_decorations` method

View File

@@ -125,7 +125,6 @@ impl<T> EventLoopBuilderExtWindows for EventLoopBuilder<T> {
} }
#[inline] #[inline]
fn with_theme(&mut self, theme: Option<Theme>) -> &mut Self { fn with_theme(&mut self, theme: Option<Theme>) -> &mut Self {
self.platform_specific.preferred_theme = theme; self.platform_specific.preferred_theme = theme;
self self

View File

@@ -2,14 +2,6 @@
// Copyright 2021-2023 Tauri Programme within The Commons Conservancy // Copyright 2021-2023 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
#![cfg(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd"
))]
mod device; mod device;
mod event_loop; mod event_loop;
mod icon; mod icon;

View File

@@ -110,13 +110,12 @@ extern "C" fn application_will_terminate(_: &Object, _: Sel, _: id) {
trace!("Completed `applicationWillTerminate`"); trace!("Completed `applicationWillTerminate`");
} }
extern "C" fn application_open_urls(_: &Object, _: Sel, _: id, urls: &NSArray<NSURL>) -> () { extern "C" fn application_open_urls(_: &Object, _: Sel, _: id, urls: &NSArray<NSURL>) {
trace!("Trigger `application:openURLs:`"); trace!("Trigger `application:openURLs:`");
let urls = unsafe { let urls = unsafe {
(0..urls.count()) (0..urls.count())
.map(|i| url::Url::parse(&urls.objectAtIndex(i).absoluteString().unwrap().to_string())) .flat_map(|i| url::Url::parse(&urls.objectAtIndex(i).absoluteString().unwrap().to_string()))
.flatten()
.collect::<Vec<_>>() .collect::<Vec<_>>()
}; };
trace!("Get `application:openURLs:` URLs: {:?}", urls); trace!("Get `application:openURLs:` URLs: {:?}", urls);

View File

@@ -203,7 +203,7 @@ impl Handler {
if let Some(ref mut callback) = *self.callback.lock().unwrap() { if let Some(ref mut callback) = *self.callback.lock().unwrap() {
match wrapper { match wrapper {
EventWrapper::StaticEvent(event) => { EventWrapper::StaticEvent(event) => {
callback.handle_nonuser_event(event, &mut *self.control_flow.lock().unwrap()) callback.handle_nonuser_event(event, &mut self.control_flow.lock().unwrap())
} }
EventWrapper::EventProxy(proxy) => self.handle_proxy(proxy, callback), EventWrapper::EventProxy(proxy) => self.handle_proxy(proxy, callback),
} }
@@ -212,7 +212,7 @@ impl Handler {
fn handle_user_events(&self) { fn handle_user_events(&self) {
if let Some(ref mut callback) = *self.callback.lock().unwrap() { if let Some(ref mut callback) = *self.callback.lock().unwrap() {
callback.handle_user_events(&mut *self.control_flow.lock().unwrap()); callback.handle_user_events(&mut self.control_flow.lock().unwrap());
} }
} }
@@ -224,7 +224,7 @@ impl Handler {
scale_factor: f64, scale_factor: f64,
) { ) {
let mut size = suggested_size.to_physical(scale_factor); let mut size = suggested_size.to_physical(scale_factor);
let old_size = size.clone(); let old_size = size;
let event = Event::WindowEvent { let event = Event::WindowEvent {
window_id: WindowId(get_window_id(ns_window)), window_id: WindowId(get_window_id(ns_window)),
event: WindowEvent::ScaleFactorChanged { event: WindowEvent::ScaleFactorChanged {
@@ -233,7 +233,7 @@ impl Handler {
}, },
}; };
callback.handle_nonuser_event(event, &mut *self.control_flow.lock().unwrap()); callback.handle_nonuser_event(event, &mut self.control_flow.lock().unwrap());
if old_size != size { if old_size != size {
let logical_size = size.to_logical(scale_factor); let logical_size = size.to_logical(scale_factor);
@@ -437,7 +437,7 @@ unsafe fn window_activation_hack(ns_app: &NSApplication) {
// And call `makeKeyAndOrderFront` if it was called on the window in `UnownedWindow::new` // And call `makeKeyAndOrderFront` if it was called on the window in `UnownedWindow::new`
// This way we preserve the user's desired initial visiblity status // This way we preserve the user's desired initial visiblity status
// TODO: Also filter on the type/"level" of the window, and maybe other things? // TODO: Also filter on the type/"level" of the window, and maybe other things?
if ns_window.isVisible() == true { if ns_window.isVisible() {
trace!("Activating visible window"); trace!("Activating visible window");
ns_window.makeKeyAndOrderFront(None); ns_window.makeKeyAndOrderFront(None);
} else { } else {

View File

@@ -6,10 +6,7 @@ pub fn set_badge_label(label: Option<String>) {
// SAFETY: TODO // SAFETY: TODO
let mtm = unsafe { MainThreadMarker::new_unchecked() }; let mtm = unsafe { MainThreadMarker::new_unchecked() };
unsafe { unsafe {
let label = match label { let label = label.map(|label| NSString::from_str(&label));
None => None,
Some(label) => Some(NSString::from_str(&label)),
};
let dock_tile: id = msg_send![&NSApp(mtm), dockTile]; let dock_tile: id = msg_send![&NSApp(mtm), dockTile];
let _: () = msg_send![dock_tile, setBadgeLabel: label.as_deref()]; let _: () = msg_send![dock_tile, setBadgeLabel: label.as_deref()];
} }

View File

@@ -18,7 +18,6 @@ use crossbeam_channel::{self as channel, Receiver, Sender};
use objc2::{msg_send_id, rc::Retained}; use objc2::{msg_send_id, rc::Retained};
use objc2_app_kit::{NSApp, NSApplication, NSEventModifierFlags, NSEventSubtype, NSEventType}; use objc2_app_kit::{NSApp, NSApplication, NSEventModifierFlags, NSEventSubtype, NSEventType};
use objc2_foundation::{MainThreadMarker, NSAutoreleasePool, NSInteger, NSPoint, NSTimeInterval}; use objc2_foundation::{MainThreadMarker, NSAutoreleasePool, NSInteger, NSPoint, NSTimeInterval};
use scopeguard::defer;
use crate::{ use crate::{
dpi::PhysicalPosition, dpi::PhysicalPosition,
@@ -333,7 +332,7 @@ impl<T> Proxy<T> {
let rl = CFRunLoopGetMain(); let rl = CFRunLoopGetMain();
let mut context: CFRunLoopSourceContext = mem::zeroed(); let mut context: CFRunLoopSourceContext = mem::zeroed();
context.perform = Some(event_loop_proxy_handler); context.perform = Some(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); CFRunLoopAddSource(rl, source, kCFRunLoopCommonModes);
CFRunLoopWakeUp(rl); CFRunLoopWakeUp(rl);

View File

@@ -39,7 +39,7 @@ pub const YES: Bool = Bool::YES;
#[allow(deprecated)] #[allow(deprecated)]
pub const NO: Bool = Bool::NO; pub const NO: Bool = Bool::NO;
pub const NSNotFound: NSInteger = NSInteger::max_value(); pub const NSNotFound: NSInteger = NSInteger::MAX;
pub const kCGBaseWindowLevelKey: NSInteger = 0; pub const kCGBaseWindowLevelKey: NSInteger = 0;
pub const kCGMinimumWindowLevelKey: NSInteger = 1; pub const kCGMinimumWindowLevelKey: NSInteger = 1;

View File

@@ -2,8 +2,6 @@
// Copyright 2021-2023 Tauri Programme within The Commons Conservancy // Copyright 2021-2023 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
#![cfg(target_os = "macos")]
mod app; mod app;
mod app_delegate; mod app_delegate;
mod app_state; mod app_state;
@@ -73,7 +71,7 @@ impl Deref for Window {
type Target = UnownedWindow; type Target = UnownedWindow;
#[inline] #[inline]
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
&*self.window &self.window
} }
} }

View File

@@ -169,7 +169,7 @@ pub fn from_point(x: f64, y: f64) -> Option<MonitorHandle> {
} }
} }
} }
return None; None
} }
impl fmt::Debug for MonitorHandle { impl fmt::Debug for MonitorHandle {

View File

@@ -232,13 +232,13 @@ pub fn setup_control_flow_observers(panic_info: Weak<PanicInfo>) {
let run_loop = RunLoop::get(); let run_loop = RunLoop::get();
run_loop.add_observer( run_loop.add_observer(
kCFRunLoopEntry | kCFRunLoopAfterWaiting, kCFRunLoopEntry | kCFRunLoopAfterWaiting,
CFIndex::min_value(), CFIndex::MIN,
control_flow_begin_handler, control_flow_begin_handler,
&mut context as *mut _, &mut context as *mut _,
); );
run_loop.add_observer( run_loop.add_observer(
kCFRunLoopExit | kCFRunLoopBeforeWaiting, kCFRunLoopExit | kCFRunLoopBeforeWaiting,
CFIndex::max_value(), CFIndex::MAX,
control_flow_end_handler, control_flow_end_handler,
&mut context as *mut _, &mut context as *mut _,
); );
@@ -267,7 +267,7 @@ impl Default for EventLoopWaker {
// future, but that gets changed to fire immediately in did_finish_launching // future, but that gets changed to fire immediately in did_finish_launching
let timer = CFRunLoopTimerCreate( let timer = CFRunLoopTimerCreate(
ptr::null_mut(), ptr::null_mut(),
std::f64::MAX, f64::MAX,
0.000_000_1, 0.000_000_1,
0, 0,
0, 0,
@@ -282,11 +282,11 @@ impl Default for EventLoopWaker {
impl EventLoopWaker { impl EventLoopWaker {
pub fn stop(&mut self) { pub fn stop(&mut self) {
unsafe { CFRunLoopTimerSetNextFireDate(self.timer, std::f64::MAX) } unsafe { CFRunLoopTimerSetNextFireDate(self.timer, f64::MAX) }
} }
pub fn start(&mut self) { pub fn start(&mut self) {
unsafe { CFRunLoopTimerSetNextFireDate(self.timer, std::f64::MIN) } unsafe { CFRunLoopTimerSetNextFireDate(self.timer, f64::MIN) }
} }
pub fn start_at(&mut self, instant: Instant) { pub fn start_at(&mut self, instant: Instant) {

View File

@@ -77,10 +77,7 @@ fn get_exist_progress_indicator(dock_tile: id) -> Option<id> {
return None; return None;
} }
let subviews: Option<Retained<NSArray>> = msg_send_id![content_view, subviews]; let subviews: Option<Retained<NSArray>> = msg_send_id![content_view, subviews];
if subviews.is_none() { let subviews = subviews?;
return None;
}
let subviews = subviews.unwrap();
for idx in 0..subviews.count() { for idx in 0..subviews.count() {
let subview: id = msg_send![&subviews, objectAtIndex: idx]; let subview: id = msg_send![&subviews, objectAtIndex: idx];

View File

@@ -67,7 +67,7 @@ pub unsafe fn set_style_mask_async(
let ns_window = MainThreadSafe(ns_window.retain()); let ns_window = MainThreadSafe(ns_window.retain());
let ns_view = MainThreadSafe(ns_view.retain()); let ns_view = MainThreadSafe(ns_view.retain());
Queue::main().exec_async(move || { Queue::main().exec_async(move || {
set_style_mask(&*ns_window, &*ns_view, mask); set_style_mask(&ns_window, &ns_view, mask);
}); });
} }
pub unsafe fn set_style_mask_sync(ns_window: &NSWindow, ns_view: &NSView, mask: NSWindowStyleMask) { pub unsafe fn set_style_mask_sync(ns_window: &NSWindow, ns_view: &NSView, mask: NSWindowStyleMask) {
@@ -77,7 +77,7 @@ pub unsafe fn set_style_mask_sync(ns_window: &NSWindow, ns_view: &NSView, mask:
let ns_window = MainThreadSafe(ns_window.retain()); let ns_window = MainThreadSafe(ns_window.retain());
let ns_view = MainThreadSafe(ns_view.retain()); let ns_view = MainThreadSafe(ns_view.retain());
Queue::main().exec_sync(move || { Queue::main().exec_sync(move || {
set_style_mask(&*ns_window, &*ns_view, mask); set_style_mask(&ns_window, &ns_view, mask);
}) })
} }
} }
@@ -131,7 +131,7 @@ pub unsafe fn toggle_full_screen_async(
if let Some(shared_state) = shared_state.upgrade() { if let Some(shared_state) = shared_state.upgrade() {
trace!("Locked shared state in `toggle_full_screen_callback`"); trace!("Locked shared state in `toggle_full_screen_callback`");
let mut shared_state_lock = shared_state.lock().unwrap(); let mut shared_state_lock = shared_state.lock().unwrap();
(*shared_state_lock).saved_style = Some(curr_mask); shared_state_lock.saved_style = Some(curr_mask);
trace!("Unlocked shared state in `toggle_full_screen_callback`"); trace!("Unlocked shared state in `toggle_full_screen_callback`");
} }
} }

View File

@@ -15,7 +15,9 @@ use std::{cell::RefCell, ffi::c_void, ptr::null_mut};
use crate::window::CursorIcon; use crate::window::CursorIcon;
#[derive(Default)]
pub enum Cursor { pub enum Cursor {
#[default]
Default, Default,
Native(&'static str), Native(&'static str),
Undocumented(&'static str), Undocumented(&'static str),
@@ -77,12 +79,6 @@ impl From<CursorIcon> for Cursor {
} }
} }
impl Default for Cursor {
fn default() -> Self {
Cursor::Default
}
}
impl Cursor { impl Cursor {
pub unsafe fn load(&self) -> id { pub unsafe fn load(&self) -> id {
match self { match self {
@@ -153,7 +149,7 @@ pub unsafe fn invisible_cursor() -> id {
thread_local! { thread_local! {
// We can't initialize this at startup. // We can't initialize this at startup.
static CURSOR_OBJECT: RefCell<id> = RefCell::new(nil); static CURSOR_OBJECT: RefCell<id> = const { RefCell::new(nil) };
} }
CURSOR_OBJECT.with(|cursor_obj| { CURSOR_OBJECT.with(|cursor_obj| {

View File

@@ -241,7 +241,8 @@ fn create_window(
backing: NSBackingStoreType::NSBackingStoreBuffered, backing: NSBackingStoreType::NSBackingStoreBuffered,
defer: NO, defer: NO,
]; ];
let res = ns_window.map(|ns_window| {
ns_window.map(|ns_window| {
let title = NSString::from_str(&attrs.title); let title = NSString::from_str(&attrs.title);
ns_window.setReleasedWhenClosed(false); ns_window.setReleasedWhenClosed(false);
ns_window.setTitle(&title); ns_window.setTitle(&title);
@@ -323,16 +324,16 @@ fn create_window(
} }
ns_window ns_window
}); })
res
} }
} }
pub(super) fn get_ns_theme() -> Theme { pub(super) fn get_ns_theme() -> Theme {
unsafe { unsafe {
let mut appearances: Vec<Retained<NSString>> = Vec::new(); let appearances: Vec<Retained<NSString>> = vec![
appearances.push(NSString::from_str("NSAppearanceNameAqua")); NSString::from_str("NSAppearanceNameAqua"),
appearances.push(NSString::from_str("NSAppearanceNameDarkAqua")); NSString::from_str("NSAppearanceNameDarkAqua"),
];
let app_class = class!(NSApplication); let app_class = class!(NSApplication);
let app: id = msg_send![app_class, sharedApplication]; let app: id = msg_send![app_class, sharedApplication];
let has_theme: bool = msg_send![app, respondsToSelector: sel!(effectiveAppearance)]; let has_theme: bool = msg_send![app, respondsToSelector: sel!(effectiveAppearance)];
@@ -396,16 +397,13 @@ lazy_static! {
extern "C" fn send_event(this: &Object, _sel: Sel, event: &NSEvent) { extern "C" fn send_event(this: &Object, _sel: Sel, event: &NSEvent) {
unsafe { unsafe {
let event_type = event.r#type(); let event_type = event.r#type();
match event_type { if event_type == NSEventType::LeftMouseDown {
NSEventType::LeftMouseDown => { // When wkwebview is set on NSWindow, `WindowBuilder::with_movable_by_window_background` is not working.
// When wkwebview is set on NSWindow, `WindowBuilder::with_movable_by_window_background` is not working. // Because of this, we need to invoke `[NSWindow performWindowDragWithEvent]` in NSLeftMouseDown event.
// Because of this, we need to invoke `[NSWindow performWindowDragWithEvent]` in NSLeftMouseDown event. let is_movable_window: bool = msg_send![this, isMovableByWindowBackground];
let is_movable_window: bool = msg_send![this, isMovableByWindowBackground]; if is_movable_window {
if is_movable_window { let _: () = msg_send![this, performWindowDragWithEvent: event];
let _: () = msg_send![this, performWindowDragWithEvent: event];
}
} }
_ => (),
} }
let superclass = util::superclass(this); let superclass = util::superclass(this);
let _: () = msg_send![super(this, superclass), sendEvent: event]; let _: () = msg_send![super(this, superclass), sendEvent: event];
@@ -554,7 +552,7 @@ impl UnownedWindow {
.inner_size .inner_size
.map(|size| size.to_physical(scale_factor)); .map(|size| size.to_physical(scale_factor));
let cloned_preferred_theme = win_attribs.preferred_theme.clone(); let cloned_preferred_theme = win_attribs.preferred_theme;
let window = Arc::new(UnownedWindow { let window = Arc::new(UnownedWindow {
ns_view, ns_view,
@@ -726,8 +724,8 @@ impl UnownedWindow {
pub fn set_max_inner_size(&self, dimensions: Option<Size>) { pub fn set_max_inner_size(&self, dimensions: Option<Size>) {
let dimensions = dimensions.unwrap_or(Logical(LogicalSize { let dimensions = dimensions.unwrap_or(Logical(LogicalSize {
width: std::f32::MAX as f64, width: f32::MAX as f64,
height: std::f32::MAX as f64, height: f32::MAX as f64,
})); }));
let scale_factor = self.scale_factor(); let scale_factor = self.scale_factor();
unsafe { unsafe {

View File

@@ -469,7 +469,7 @@ fn dur2timeout(dur: Duration) -> u32 {
}) })
}) })
.map(|ms| { .map(|ms| {
if ms > u32::max_value() as u64 { if ms > u32::MAX as u64 {
INFINITE INFINITE
} else { } else {
ms as u32 ms as u32
@@ -1591,7 +1591,10 @@ unsafe fn public_window_callback_inner<T: 'static>(
let htouch = HTOUCHINPUT(lparam.0 as _); let htouch = HTOUCHINPUT(lparam.0 as _);
if GetTouchInputInfo( if GetTouchInputInfo(
htouch, htouch,
mem::transmute(uninit_inputs), mem::transmute::<
&mut [std::mem::MaybeUninit<windows::Win32::UI::Input::Touch::TOUCHINPUT>],
&mut [windows::Win32::UI::Input::Touch::TOUCHINPUT],
>(uninit_inputs),
mem::size_of::<TOUCHINPUT>() as i32, mem::size_of::<TOUCHINPUT>() as i32,
) )
.is_ok() .is_ok()
@@ -2140,6 +2143,8 @@ unsafe fn public_window_callback_inner<T: 'static>(
if edges & ABE_BOTTOM != 0 { if edges & ABE_BOTTOM != 0 {
rect.bottom -= 1; rect.bottom -= 1;
} }
// FIXME:
#[allow(clippy::bad_bit_mask)]
if edges & ABE_LEFT != 0 { if edges & ABE_LEFT != 0 {
rect.left += 1; rect.left += 1;
} }
@@ -2427,6 +2432,8 @@ unsafe extern "system" fn thread_event_target_callback<T: 'static>(
if subclass_removed { if subclass_removed {
mem::drop(subclass_input); mem::drop(subclass_input);
} else { } else {
// FIXME: this seems to leak intentionally?
#[allow(unused_must_use)]
Box::into_raw(subclass_input); Box::into_raw(subclass_input);
} }
result result

View File

@@ -423,7 +423,7 @@ impl<T> BufferedEvent<T> {
match self { match self {
Self::Event(event) => dispatch(event), Self::Event(event) => dispatch(event),
Self::ScaleFactorChanged(window_id, scale_factor, mut new_inner_size) => { Self::ScaleFactorChanged(window_id, scale_factor, mut new_inner_size) => {
let os_inner_size = new_inner_size.clone(); let os_inner_size = new_inner_size;
dispatch(Event::WindowEvent { dispatch(Event::WindowEvent {
window_id, window_id,

View File

@@ -29,7 +29,7 @@ impl RgbaIcon {
let pixels = let pixels =
unsafe { std::slice::from_raw_parts_mut(rgba.as_mut_ptr() as *mut Pixel, pixel_count) }; unsafe { std::slice::from_raw_parts_mut(rgba.as_mut_ptr() as *mut Pixel, pixel_count) };
for pixel in pixels { for pixel in pixels {
and_mask.push(pixel.a.wrapping_sub(std::u8::MAX)); // invert alpha channel and_mask.push(pixel.a.wrapping_sub(u8::MAX)); // invert alpha channel
pixel.to_bgra(); pixel.to_bgra();
} }
assert_eq!(and_mask.len(), pixel_count); assert_eq!(and_mask.len(), pixel_count);

View File

@@ -2,8 +2,6 @@
// Copyright 2021-2023 Tauri Programme within The Commons Conservancy // Copyright 2021-2023 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
#![cfg(target_os = "windows")]
use windows::Win32::{ use windows::Win32::{
Foundation::{HANDLE, HWND}, Foundation::{HANDLE, HWND},
UI::WindowsAndMessaging::HMENU, UI::WindowsAndMessaging::HMENU,

View File

@@ -22,7 +22,7 @@ pub fn get_raw_input_device_list() -> Option<Vec<RAWINPUTDEVICELIST>> {
let mut num_devices = 0; let mut num_devices = 0;
let status = unsafe { GetRawInputDeviceList(None, &mut num_devices, list_size) }; let status = unsafe { GetRawInputDeviceList(None, &mut num_devices, list_size) };
if status == u32::max_value() { if status == u32::MAX {
return None; return None;
} }
@@ -31,7 +31,7 @@ pub fn get_raw_input_device_list() -> Option<Vec<RAWINPUTDEVICELIST>> {
let num_stored = let num_stored =
unsafe { GetRawInputDeviceList(Some(buffer.as_ptr() as _), &mut num_devices, list_size) }; unsafe { GetRawInputDeviceList(Some(buffer.as_ptr() as _), &mut num_devices, list_size) };
if num_stored == u32::max_value() { if num_stored == u32::MAX {
return None; return None;
} }
@@ -80,7 +80,7 @@ pub fn get_raw_input_device_info(handle: HANDLE) -> Option<RawDeviceInfo> {
) )
}; };
if status == u32::max_value() || status == 0 { if status == u32::MAX || status == 0 {
return None; return None;
} }
@@ -109,7 +109,7 @@ pub fn get_raw_input_device_name(handle: HANDLE) -> Option<String> {
) )
}; };
if status == u32::max_value() || status == 0 { if status == u32::MAX || status == 0 {
return None; return None;
} }
@@ -174,7 +174,7 @@ pub fn get_raw_input_data(handle: HRAWINPUT) -> Option<RAWINPUT> {
) )
}; };
if status == u32::max_value() || status == 0 { if status == u32::MAX || status == 0 {
return None; return None;
} }

View File

@@ -400,7 +400,7 @@ pub fn PRIMARYLANGID(hkl: HKL) -> u32 {
#[allow(non_snake_case)] #[allow(non_snake_case)]
#[inline] #[inline]
pub fn RGB<T: Into<u32>>(r: T, g: T, b: T) -> COLORREF { pub fn RGB<T: Into<u32>>(r: T, g: T, b: T) -> COLORREF {
COLORREF(r.into() | g.into() << 8 | b.into() << 16) COLORREF(r.into() | (g.into() << 8) | (b.into() << 16))
} }
pub unsafe extern "system" fn call_default_window_proc( pub unsafe extern "system" fn call_default_window_proc(

View File

@@ -174,7 +174,7 @@ impl Window {
#[inline] #[inline]
pub fn set_focus(&self) { pub fn set_focus(&self) {
let window = self.window.clone(); let window = self.window;
let window_flags = self.window_state.lock().window_flags(); let window_flags = self.window_state.lock().window_flags();
let is_visible = window_flags.contains(WindowFlags::VISIBLE); let is_visible = window_flags.contains(WindowFlags::VISIBLE);
@@ -711,7 +711,7 @@ impl Window {
#[inline] #[inline]
pub fn set_fullscreen(&self, fullscreen: Option<Fullscreen>) { pub fn set_fullscreen(&self, fullscreen: Option<Fullscreen>) {
let window = self.window.clone(); let window = self.window;
let window_state = Arc::clone(&self.window_state); let window_state = Arc::clone(&self.window_state);
let mut window_state_lock = window_state.lock(); let mut window_state_lock = window_state.lock();
@@ -963,7 +963,7 @@ impl Window {
#[inline] #[inline]
pub fn request_user_attention(&self, request_type: Option<UserAttentionType>) { pub fn request_user_attention(&self, request_type: Option<UserAttentionType>) {
let window = self.window.clone(); let window = self.window;
let active_window_handle = unsafe { GetActiveWindow() }; let active_window_handle = unsafe { GetActiveWindow() };
if window.0 == active_window_handle { if window.0 == active_window_handle {
// active window could be minimized, so we skip requesting attention // active window could be minimized, so we skip requesting attention
@@ -1025,7 +1025,7 @@ impl Window {
vk, vk,
scancode, scancode,
Some(&kbd_state), Some(&kbd_state),
mem::transmute(char_buff.as_mut()), mem::transmute::<&mut [std::mem::MaybeUninit<u16>], &mut [u16]>(char_buff.as_mut()),
0, 0,
); );
} }
@@ -1094,9 +1094,7 @@ impl Window {
let taskbar: ITaskbarList = let taskbar: ITaskbarList =
unsafe { CoCreateInstance(&TaskbarList, None, CLSCTX_SERVER).unwrap() }; unsafe { CoCreateInstance(&TaskbarList, None, CLSCTX_SERVER).unwrap() };
let icon = icon let icon = icon.map(|i| i.inner.as_raw_handle()).unwrap_or_default();
.map(|i| i.inner.as_raw_handle())
.unwrap_or(HICON::default());
unsafe { unsafe {
taskbar taskbar
@@ -1107,7 +1105,7 @@ impl Window {
#[inline] #[inline]
pub fn set_undecorated_shadow(&self, shadow: bool) { pub fn set_undecorated_shadow(&self, shadow: bool) {
let window = self.window.clone(); let window = self.window;
let window_state = Arc::clone(&self.window_state); let window_state = Arc::clone(&self.window_state);
self.thread_executor.execute_in_thread(move || { self.thread_executor.execute_in_thread(move || {
@@ -1474,7 +1472,7 @@ thread_local! {
} }
}; };
static TASKBAR_LIST: RefCell<Option<ITaskbarList2>> = RefCell::new(None); static TASKBAR_LIST: RefCell<Option<ITaskbarList2>> = const { RefCell::new(None) };
} }
pub fn com_initialized() { pub fn com_initialized() {

View File

@@ -150,15 +150,15 @@ pub struct WindowAttributes {
/// ## Platform-specific /// ## Platform-specific
/// ///
/// - **macOS**: The top left corner position of the window content, the window's "inner" /// - **macOS**: The top left corner position of the window content, the window's "inner"
/// position. The window title bar will be placed above it. /// position. The window title bar will be placed above it.
/// The window will be positioned such that it fits on screen, maintaining /// The window will be positioned such that it fits on screen, maintaining
/// set `inner_size` if any. /// set `inner_size` if any.
/// If you need to precisely position the top left corner of the whole window you have to /// If you need to precisely position the top left corner of the whole window you have to
/// use [`Window::set_outer_position`] after creating the window. /// use [`Window::set_outer_position`] after creating the window.
/// - **Windows**: The top left corner position of the window title bar, the window's "outer" /// - **Windows**: The top left corner position of the window title bar, the window's "outer"
/// position. /// position.
/// There may be a small gap between this position and the window due to the specifics of the /// There may be a small gap between this position and the window due to the specifics of the
/// Window Manager. /// Window Manager.
/// - **Linux**: The top left corner of the window, the window's "outer" position. /// - **Linux**: The top left corner of the window, the window's "outer" position.
/// - **Linux(Wayland)**: Unsupported. /// - **Linux(Wayland)**: Unsupported.
/// - **Others**: Ignored. /// - **Others**: Ignored.
@@ -859,11 +859,11 @@ impl Window {
/// ## Platform-specific /// ## Platform-specific
/// ///
/// - **Linux:** Most size methods like maximized are async and do not work well with calling /// - **Linux:** Most size methods like maximized are async and do not work well with calling
/// sequentailly. For setting inner or outer size, you don't need to set resizable to true before /// sequentailly. For setting inner or outer size, you don't need to set resizable to true before
/// it. It can resize no matter what. But if you insist to do so, it has a `100, 100` minimum /// it. It can resize no matter what. But if you insist to do so, it has a `100, 100` minimum
/// limitation somehow. For maximizing, it requires resizable is true. If you really want to set /// limitation somehow. For maximizing, it requires resizable is true. If you really want to set
/// resizable to false after it. You might need a mechanism to check the window is really /// resizable to false after it. You might need a mechanism to check the window is really
/// maximized. /// maximized.
/// - **iOS / Android:** Unsupported. /// - **iOS / Android:** Unsupported.
#[inline] #[inline]
pub fn set_resizable(&self, resizable: bool) { pub fn set_resizable(&self, resizable: bool) {
@@ -1394,8 +1394,10 @@ impl rwh_06::HasDisplayHandle for Window {
#[non_exhaustive] #[non_exhaustive]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Default)]
pub enum CursorIcon { pub enum CursorIcon {
/// The platform-dependent default cursor. /// The platform-dependent default cursor.
#[default]
Default, Default,
/// A simple crosshair. /// A simple crosshair.
Crosshair, Crosshair,
@@ -1450,12 +1452,6 @@ pub enum CursorIcon {
RowResize, RowResize,
} }
impl Default for CursorIcon {
fn default() -> Self {
CursorIcon::Default
}
}
/// Fullscreen modes. /// Fullscreen modes.
#[non_exhaustive] #[non_exhaustive]
#[allow(clippy::large_enum_variant)] #[allow(clippy::large_enum_variant)]
@@ -1476,7 +1472,7 @@ pub enum Theme {
} }
#[non_exhaustive] #[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq, Default)]
pub enum UserAttentionType { pub enum UserAttentionType {
/// ## Platform-specific /// ## Platform-specific
/// - **macOS:** Bounces the dock icon until the application is in focus. /// - **macOS:** Bounces the dock icon until the application is in focus.
@@ -1485,15 +1481,10 @@ pub enum UserAttentionType {
/// ## Platform-specific /// ## Platform-specific
/// - **macOS:** Bounces the dock icon once. /// - **macOS:** Bounces the dock icon once.
/// - **Windows:** Flashes the taskbar button until the application is in focus. /// - **Windows:** Flashes the taskbar button until the application is in focus.
#[default]
Informational, Informational,
} }
impl Default for UserAttentionType {
fn default() -> Self {
UserAttentionType::Informational
}
}
/// Window size constraints /// Window size constraints
#[derive(Clone, Copy, PartialEq, Debug, Default)] #[derive(Clone, Copy, PartialEq, Debug, Default)]
pub struct WindowSizeConstraints { pub struct WindowSizeConstraints {

View File

@@ -4,7 +4,7 @@ description = "Proc macros for tao"
version = "0.1.3" version = "0.1.3"
edition = "2021" edition = "2021"
authors = [ "Tauri Programme within The Commons Conservancy" ] authors = [ "Tauri Programme within The Commons Conservancy" ]
rust-version = "1.56" rust-version = "1.74"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
readme = "../README.md" readme = "../README.md"
repository = "https://github.com/tauri-apps/tao" repository = "https://github.com/tauri-apps/tao"

View File

@@ -185,8 +185,8 @@ impl Parse for AndroidFnInput {
/// } /// }
/// ``` /// ```
/// ///
/// - [`JNIEnv`]: https://docs.rs/jni/latest/jni/struct.JNIEnv.html /// [`JNIEnv`]: https://docs.rs/jni/latest/jni/struct.JNIEnv.html
/// - [`JClass`]: https://docs.rs/jni/latest/jni/objects/struct.JClass.html /// [`JClass`]: https://docs.rs/jni/latest/jni/objects/struct.JClass.html
#[proc_macro] #[proc_macro]
pub fn android_fn(tokens: TokenStream) -> TokenStream { pub fn android_fn(tokens: TokenStream) -> TokenStream {
let tokens = parse_macro_input!(tokens as AndroidFnInput); let tokens = parse_macro_input!(tokens as AndroidFnInput);