Compare commits
10 commits
b961e8e941
...
261cda5401
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
261cda5401 | ||
|
|
a610ac9c7a | ||
|
|
0370cadd67 | ||
|
|
ed46dd031d | ||
|
|
6c9a2d4e9b | ||
|
|
ec30b8004f | ||
|
|
43f4760b0e | ||
|
|
66dc0eab25 | ||
|
|
b961e4877d | ||
|
|
f98ccf8efc |
20 changed files with 495 additions and 69 deletions
25
Cargo.toml
25
Cargo.toml
|
|
@ -8,22 +8,22 @@ edition = "2024"
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
repository = "https://github.com/rust-windowing/winit"
|
repository = "https://github.com/rust-windowing/winit"
|
||||||
rust-version = "1.85"
|
rust-version = "1.85"
|
||||||
version = "0.31.0-beta.1"
|
version = "0.31.0-beta.2"
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
# Workspace dependencies.
|
# Workspace dependencies.
|
||||||
# `winit` has no version here to allow using it in dev deps for docs.
|
# `winit` has no version here to allow using it in dev deps for docs.
|
||||||
winit = { path = "winit" }
|
winit = { path = "winit" }
|
||||||
winit-android = { version = "=0.31.0-beta.1", path = "winit-android" }
|
winit-android = { version = "=0.31.0-beta.2", path = "winit-android" }
|
||||||
winit-appkit = { version = "=0.31.0-beta.1", path = "winit-appkit" }
|
winit-appkit = { version = "=0.31.0-beta.2", path = "winit-appkit" }
|
||||||
winit-common = { version = "=0.31.0-beta.1", path = "winit-common" }
|
winit-common = { version = "=0.31.0-beta.2", path = "winit-common" }
|
||||||
winit-core = { version = "=0.31.0-beta.1", path = "winit-core" }
|
winit-core = { version = "=0.31.0-beta.2", path = "winit-core" }
|
||||||
winit-orbital = { version = "=0.31.0-beta.1", path = "winit-orbital" }
|
winit-orbital = { version = "=0.31.0-beta.2", path = "winit-orbital" }
|
||||||
winit-uikit = { version = "=0.31.0-beta.1", path = "winit-uikit" }
|
winit-uikit = { version = "=0.31.0-beta.2", path = "winit-uikit" }
|
||||||
winit-wayland = { version = "=0.31.0-beta.1", path = "winit-wayland", default-features = false }
|
winit-wayland = { version = "=0.31.0-beta.2", path = "winit-wayland", default-features = false }
|
||||||
winit-web = { version = "=0.31.0-beta.1", path = "winit-web" }
|
winit-web = { version = "=0.31.0-beta.2", path = "winit-web" }
|
||||||
winit-win32 = { version = "=0.31.0-beta.1", path = "winit-win32" }
|
winit-win32 = { version = "=0.31.0-beta.2", path = "winit-win32" }
|
||||||
winit-x11 = { version = "=0.31.0-beta.1", path = "winit-x11" }
|
winit-x11 = { version = "=0.31.0-beta.2", path = "winit-x11" }
|
||||||
|
|
||||||
# Core dependencies.
|
# Core dependencies.
|
||||||
bitflags = "2"
|
bitflags = "2"
|
||||||
|
|
@ -80,7 +80,8 @@ xkbcommon-dl = "0.4.2"
|
||||||
|
|
||||||
# Orbital dependencies.
|
# Orbital dependencies.
|
||||||
orbclient = { version = "0.3.47", default-features = false }
|
orbclient = { version = "0.3.47", default-features = false }
|
||||||
redox_syscall = "0.5.7"
|
redox_syscall = "0.7"
|
||||||
|
libredox = "0.1.12"
|
||||||
|
|
||||||
# Web dependencies.
|
# Web dependencies.
|
||||||
atomic-waker = "1"
|
atomic-waker = "1"
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[dependencies]
|
[dependencies]
|
||||||
winit = "0.31.0-beta.1"
|
winit = "0.31.0-beta.2"
|
||||||
```
|
```
|
||||||
|
|
||||||
## [Documentation](https://docs.rs/winit)
|
## [Documentation](https://docs.rs/winit)
|
||||||
|
|
|
||||||
135
src/platform_impl/linux/wayland/dnd.rs
Normal file
135
src/platform_impl/linux/wayland/dnd.rs
Normal file
|
|
@ -0,0 +1,135 @@
|
||||||
|
use sctk::data_device_manager::{
|
||||||
|
data_device::DataDeviceHandler, data_offer::DataOfferHandler, data_source::DataSourceHandler,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::platform_impl::wayland::state::WinitState;
|
||||||
|
|
||||||
|
impl DataDeviceHandler for WinitState {
|
||||||
|
fn enter(
|
||||||
|
&mut self,
|
||||||
|
conn: &wayland_client::Connection,
|
||||||
|
qh: &wayland_client::QueueHandle<Self>,
|
||||||
|
data_device: &wayland_client::protocol::wl_data_device::WlDataDevice,
|
||||||
|
x: f64,
|
||||||
|
y: f64,
|
||||||
|
wl_surface: &wayland_client::protocol::wl_surface::WlSurface,
|
||||||
|
) {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn leave(
|
||||||
|
&mut self,
|
||||||
|
conn: &wayland_client::Connection,
|
||||||
|
qh: &wayland_client::QueueHandle<Self>,
|
||||||
|
data_device: &wayland_client::protocol::wl_data_device::WlDataDevice,
|
||||||
|
) {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn motion(
|
||||||
|
&mut self,
|
||||||
|
conn: &wayland_client::Connection,
|
||||||
|
qh: &wayland_client::QueueHandle<Self>,
|
||||||
|
data_device: &wayland_client::protocol::wl_data_device::WlDataDevice,
|
||||||
|
x: f64,
|
||||||
|
y: f64,
|
||||||
|
) {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn selection(
|
||||||
|
&mut self,
|
||||||
|
conn: &wayland_client::Connection,
|
||||||
|
qh: &wayland_client::QueueHandle<Self>,
|
||||||
|
data_device: &wayland_client::protocol::wl_data_device::WlDataDevice,
|
||||||
|
) {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn drop_performed(
|
||||||
|
&mut self,
|
||||||
|
conn: &wayland_client::Connection,
|
||||||
|
qh: &wayland_client::QueueHandle<Self>,
|
||||||
|
data_device: &wayland_client::protocol::wl_data_device::WlDataDevice,
|
||||||
|
) {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DataOfferHandler for WinitState {
|
||||||
|
fn source_actions(
|
||||||
|
&mut self,
|
||||||
|
conn: &wayland_client::Connection,
|
||||||
|
qh: &wayland_client::QueueHandle<Self>,
|
||||||
|
offer: &mut sctk::data_device_manager::data_offer::DragOffer,
|
||||||
|
actions: wayland_client::protocol::wl_data_device_manager::DndAction,
|
||||||
|
) {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn selected_action(
|
||||||
|
&mut self,
|
||||||
|
conn: &wayland_client::Connection,
|
||||||
|
qh: &wayland_client::QueueHandle<Self>,
|
||||||
|
offer: &mut sctk::data_device_manager::data_offer::DragOffer,
|
||||||
|
actions: wayland_client::protocol::wl_data_device_manager::DndAction,
|
||||||
|
) {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DataSourceHandler for WinitState {
|
||||||
|
fn accept_mime(
|
||||||
|
&mut self,
|
||||||
|
conn: &wayland_client::Connection,
|
||||||
|
qh: &wayland_client::QueueHandle<Self>,
|
||||||
|
source: &wayland_client::protocol::wl_data_source::WlDataSource,
|
||||||
|
mime: Option<String>,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send_request(
|
||||||
|
&mut self,
|
||||||
|
conn: &wayland_client::Connection,
|
||||||
|
qh: &wayland_client::QueueHandle<Self>,
|
||||||
|
source: &wayland_client::protocol::wl_data_source::WlDataSource,
|
||||||
|
mime: String,
|
||||||
|
fd: sctk::data_device_manager::WritePipe,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cancelled(
|
||||||
|
&mut self,
|
||||||
|
conn: &wayland_client::Connection,
|
||||||
|
qh: &wayland_client::QueueHandle<Self>,
|
||||||
|
source: &wayland_client::protocol::wl_data_source::WlDataSource,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dnd_dropped(
|
||||||
|
&mut self,
|
||||||
|
conn: &wayland_client::Connection,
|
||||||
|
qh: &wayland_client::QueueHandle<Self>,
|
||||||
|
source: &wayland_client::protocol::wl_data_source::WlDataSource,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dnd_finished(
|
||||||
|
&mut self,
|
||||||
|
conn: &wayland_client::Connection,
|
||||||
|
qh: &wayland_client::QueueHandle<Self>,
|
||||||
|
source: &wayland_client::protocol::wl_data_source::WlDataSource,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn action(
|
||||||
|
&mut self,
|
||||||
|
conn: &wayland_client::Connection,
|
||||||
|
qh: &wayland_client::QueueHandle<Self>,
|
||||||
|
source: &wayland_client::protocol::wl_data_source::WlDataSource,
|
||||||
|
action: wayland_client::protocol::wl_data_device_manager::DndAction,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sctk::delegate_data_device!(WinitState);
|
||||||
|
|
@ -63,7 +63,7 @@
|
||||||
//! with `cargo apk`, then the minimal changes would be:
|
//! with `cargo apk`, then the minimal changes would be:
|
||||||
//! 1. Remove `ndk-glue` from your `Cargo.toml`
|
//! 1. Remove `ndk-glue` from your `Cargo.toml`
|
||||||
//! 2. Enable the `"android-native-activity"` feature for Winit: `winit = { version =
|
//! 2. Enable the `"android-native-activity"` feature for Winit: `winit = { version =
|
||||||
//! "0.31.0-beta.1", features = [ "android-native-activity" ] }`
|
//! "0.31.0-beta.2", features = [ "android-native-activity" ] }`
|
||||||
//! 3. Add an `android_main` entrypoint (as above), instead of using the '`[ndk_glue::main]` proc
|
//! 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
|
//! macro from `ndk-macros` (optionally add a dependency on `android_logger` and initialize
|
||||||
//! logging as above).
|
//! logging as above).
|
||||||
|
|
|
||||||
|
|
@ -368,6 +368,18 @@ pub enum WindowEvent {
|
||||||
surface_size_writer: SurfaceSizeWriter,
|
surface_size_writer: SurfaceSizeWriter,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// The suggested bounds of the window's surface has changed.
|
||||||
|
///
|
||||||
|
/// Contains the new bounds of the surface
|
||||||
|
///
|
||||||
|
/// - **iOS / Android / Web / Orbital / Windows:** Unsupported.
|
||||||
|
SuggestedBounds(Option<PhysicalSize<u32>>),
|
||||||
|
|
||||||
|
/// The window state has changed.
|
||||||
|
///
|
||||||
|
/// - **iOS / Android / Web / Orbital / Windows:** Unsupported.
|
||||||
|
WindowStateChanged,
|
||||||
|
|
||||||
/// The system window theme has changed.
|
/// The system window theme has changed.
|
||||||
///
|
///
|
||||||
/// Applications might wish to react to this to change the theme of the content of the window
|
/// Applications might wish to react to this to change the theme of the content of the window
|
||||||
|
|
|
||||||
|
|
@ -881,7 +881,8 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug {
|
||||||
/// ## Platform-specific
|
/// ## Platform-specific
|
||||||
///
|
///
|
||||||
/// - **Android / iOS / X11 / Web / Windows:** Unsupported.
|
/// - **Android / iOS / X11 / Web / Windows:** Unsupported.
|
||||||
/// - **Wayland:** Only works with org_kde_kwin_blur_manager protocol.
|
/// - **Wayland:** Only works with `org_kde_kwin_blur_manager` or
|
||||||
|
/// `ext_background_effect_manager_v1` protocol.
|
||||||
fn set_blur(&self, blur: bool);
|
fn set_blur(&self, blur: bool);
|
||||||
|
|
||||||
/// Modifies the window's visibility.
|
/// Modifies the window's visibility.
|
||||||
|
|
|
||||||
|
|
@ -23,3 +23,4 @@ winit-core.workspace = true
|
||||||
# Platform-specific
|
# Platform-specific
|
||||||
orbclient.workspace = true
|
orbclient.workspace = true
|
||||||
redox_syscall.workspace = true
|
redox_syscall.workspace = true
|
||||||
|
libredox.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -639,7 +639,13 @@ impl EventLoop {
|
||||||
|
|
||||||
// Wait for event if needed.
|
// Wait for event if needed.
|
||||||
let mut event = syscall::Event::default();
|
let mut event = syscall::Event::default();
|
||||||
self.window_target.event_socket.read(&mut event).unwrap();
|
loop {
|
||||||
|
match self.window_target.event_socket.read(&mut event) {
|
||||||
|
Ok(_) => break,
|
||||||
|
Err(syscall::Error { errno: syscall::EINTR }) => continue,
|
||||||
|
Err(err) => unreachable!("failed to read event: {}", err),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: handle spurious wakeups (redraw caused wakeup but redraw already handled)
|
// TODO: handle spurious wakeups (redraw caused wakeup but redraw already handled)
|
||||||
match requested_resume {
|
match requested_resume {
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ impl RedoxSocket {
|
||||||
// example, the seek would change in a potentially unpredictable way if either read or write
|
// example, the seek would change in a potentially unpredictable way if either read or write
|
||||||
// were called at the same time by multiple threads.
|
// were called at the same time by multiple threads.
|
||||||
fn open_raw(path: &str) -> syscall::Result<Self> {
|
fn open_raw(path: &str) -> syscall::Result<Self> {
|
||||||
let fd = syscall::open(path, syscall::O_RDWR | syscall::O_CLOEXEC)?;
|
let fd = libredox::call::open(path, libredox::flag::O_RDWR | libredox::flag::O_CLOEXEC, 0)?;
|
||||||
Ok(Self { fd })
|
Ok(Self { fd })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -97,7 +97,7 @@ struct WindowProperties<'a> {
|
||||||
|
|
||||||
impl<'a> WindowProperties<'a> {
|
impl<'a> WindowProperties<'a> {
|
||||||
fn new(path: &'a str) -> Self {
|
fn new(path: &'a str) -> Self {
|
||||||
// orbital:flags/x/y/w/h/t
|
// /scheme/orbital/flags/x/y/w/h/t
|
||||||
let mut parts = path.splitn(6, '/');
|
let mut parts = path.splitn(6, '/');
|
||||||
let flags = parts.next().unwrap_or("");
|
let flags = parts.next().unwrap_or("");
|
||||||
let x = parts.next().map_or(0, |part| part.parse::<i32>().unwrap_or(0));
|
let x = parts.next().map_or(0, |part| part.parse::<i32>().unwrap_or(0));
|
||||||
|
|
|
||||||
|
|
@ -379,6 +379,27 @@ impl EventLoop {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if compositor_update.suggested_bounds {
|
||||||
|
let suggested_bounds = self.with_state(|state| {
|
||||||
|
let windows = state.windows.get_mut();
|
||||||
|
let window = windows.get(&window_id).unwrap().lock().unwrap();
|
||||||
|
|
||||||
|
window
|
||||||
|
.last_configure
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|c| c.suggested_bounds)
|
||||||
|
.map(|b| dpi::LogicalSize::new(b.0, b.1).to_physical(window.scale_factor()))
|
||||||
|
.clone()
|
||||||
|
});
|
||||||
|
let event = WindowEvent::SuggestedBounds(suggested_bounds);
|
||||||
|
app.window_event(&self.active_event_loop, window_id, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
if compositor_update.xdg_window_state.take().is_some() {
|
||||||
|
let event = WindowEvent::WindowStateChanged;
|
||||||
|
app.window_event(&self.active_event_loop, window_id, event);
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: Rescale changed the physical size which winit operates in, thus we should
|
// NOTE: Rescale changed the physical size which winit operates in, thus we should
|
||||||
// resize.
|
// resize.
|
||||||
if compositor_update.resized || compositor_update.scale_changed {
|
if compositor_update.resized || compositor_update.scale_changed {
|
||||||
|
|
|
||||||
|
|
@ -14,12 +14,16 @@
|
||||||
//! * `wayland-csd-adwaita-crossfont`.
|
//! * `wayland-csd-adwaita-crossfont`.
|
||||||
//! * `wayland-csd-adwaita-notitle`.
|
//! * `wayland-csd-adwaita-notitle`.
|
||||||
//! * `wayland-csd-adwaita-notitlebar`.
|
//! * `wayland-csd-adwaita-notitlebar`.
|
||||||
|
use std::any::Any;
|
||||||
use std::ffi::c_void;
|
use std::ffi::c_void;
|
||||||
|
use std::marker::PhantomData;
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
use dpi::{LogicalSize, PhysicalSize};
|
use dpi::{LogicalSize, PhysicalSize};
|
||||||
|
use rwh_06::HandleError;
|
||||||
use sctk::reexports::client::Proxy;
|
use sctk::reexports::client::Proxy;
|
||||||
use sctk::reexports::client::protocol::wl_surface::WlSurface;
|
use sctk::reexports::client::protocol::wl_surface::WlSurface;
|
||||||
|
use sctk::reexports::csd_frame::WindowState;
|
||||||
use sctk::shm::slot::{Buffer, CreateBufferError, SlotPool};
|
use sctk::shm::slot::{Buffer, CreateBufferError, SlotPool};
|
||||||
use wayland_client::protocol::wl_shm::Format;
|
use wayland_client::protocol::wl_shm::Format;
|
||||||
use winit_core::event_loop::ActiveEventLoop as CoreActiveEventLoop;
|
use winit_core::event_loop::ActiveEventLoop as CoreActiveEventLoop;
|
||||||
|
|
@ -72,12 +76,37 @@ pub trait EventLoopBuilderExtWayland {
|
||||||
fn with_any_thread(&mut self, any_thread: bool) -> &mut Self;
|
fn with_any_thread(&mut self, any_thread: bool) -> &mut Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct XdgSurfaceHandle<'a> {
|
||||||
|
raw: NonNull<c_void>,
|
||||||
|
_marker: PhantomData<&'a ()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> XdgSurfaceHandle<'a> {
|
||||||
|
/// Create a `XdgSurfaceHandle` from a [`NonNull<c_void>`]
|
||||||
|
pub unsafe fn borrow_raw(raw: NonNull<c_void>) -> Self {
|
||||||
|
Self { raw, _marker: PhantomData }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the underlying raw xdg_surface handle.
|
||||||
|
pub fn as_raw(&self) -> NonNull<c_void> {
|
||||||
|
self.raw
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait HasXdgSurfaceHandle {
|
||||||
|
fn xdg_surface_handle(&self) -> Result<XdgSurfaceHandle<'_>, HandleError>;
|
||||||
|
}
|
||||||
|
|
||||||
/// Additional methods on [`Window`] that are specific to Wayland.
|
/// Additional methods on [`Window`] that are specific to Wayland.
|
||||||
///
|
///
|
||||||
/// [`Window`]: crate::window::Window
|
/// [`Window`]: crate::window::Window
|
||||||
pub trait WindowExtWayland {
|
pub trait WindowExtWayland {
|
||||||
/// Returns `xdg_toplevel` of the window or [`None`] if the window is X11 window.
|
/// Returns `xdg_toplevel` of the window or [`None`] if the window is X11 window.
|
||||||
fn xdg_toplevel(&self) -> Option<NonNull<c_void>>;
|
fn xdg_toplevel(&self) -> Option<NonNull<c_void>>;
|
||||||
|
|
||||||
|
fn xdg_surface_handle<'a>(&'a self) -> Option<&dyn HasXdgSurfaceHandle>;
|
||||||
|
|
||||||
|
fn window_state(&self) -> Option<WindowState>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowExtWayland for dyn CoreWindow + '_ {
|
impl WindowExtWayland for dyn CoreWindow + '_ {
|
||||||
|
|
@ -85,6 +114,15 @@ impl WindowExtWayland for dyn CoreWindow + '_ {
|
||||||
fn xdg_toplevel(&self) -> Option<NonNull<c_void>> {
|
fn xdg_toplevel(&self) -> Option<NonNull<c_void>> {
|
||||||
self.cast_ref::<Window>()?.xdg_toplevel()
|
self.cast_ref::<Window>()?.xdg_toplevel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn xdg_surface_handle(&self) -> Option<&dyn HasXdgSurfaceHandle> {
|
||||||
|
Some(self.cast_ref::<Window>()? as &dyn HasXdgSurfaceHandle)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn window_state(&self) -> Option<WindowState> {
|
||||||
|
self.cast_ref::<Window>()?.xdg_window_state()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ use crate::seat::{
|
||||||
PointerConstraintsState, PointerGesturesState, RelativePointerState, TextInputState,
|
PointerConstraintsState, PointerGesturesState, RelativePointerState, TextInputState,
|
||||||
WinitPointerData, WinitPointerDataExt, WinitSeatState,
|
WinitPointerData, WinitPointerDataExt, WinitSeatState,
|
||||||
};
|
};
|
||||||
use crate::types::kwin_blur::KWinBlurManager;
|
use crate::types::bgr_effects::BgrEffectManager;
|
||||||
use crate::types::wp_fractional_scaling::FractionalScalingManager;
|
use crate::types::wp_fractional_scaling::FractionalScalingManager;
|
||||||
use crate::types::wp_tablet_input_v2::TabletManager;
|
use crate::types::wp_tablet_input_v2::TabletManager;
|
||||||
use crate::types::wp_viewporter::ViewporterState;
|
use crate::types::wp_viewporter::ViewporterState;
|
||||||
|
|
@ -116,8 +116,8 @@ pub struct WinitState {
|
||||||
/// Fractional scaling manager.
|
/// Fractional scaling manager.
|
||||||
pub fractional_scaling_manager: Option<FractionalScalingManager>,
|
pub fractional_scaling_manager: Option<FractionalScalingManager>,
|
||||||
|
|
||||||
/// KWin blur manager.
|
/// Blur manager.
|
||||||
pub kwin_blur_manager: Option<KWinBlurManager>,
|
pub blur_manager: Option<BgrEffectManager>,
|
||||||
|
|
||||||
/// Loop handle to re-register event sources, such as keyboard repeat.
|
/// Loop handle to re-register event sources, such as keyboard repeat.
|
||||||
pub loop_handle: LoopHandle<'static, Self>,
|
pub loop_handle: LoopHandle<'static, Self>,
|
||||||
|
|
@ -192,7 +192,7 @@ impl WinitState {
|
||||||
window_events_sink: Default::default(),
|
window_events_sink: Default::default(),
|
||||||
viewporter_state,
|
viewporter_state,
|
||||||
fractional_scaling_manager,
|
fractional_scaling_manager,
|
||||||
kwin_blur_manager: KWinBlurManager::new(globals, queue_handle).ok(),
|
blur_manager: BgrEffectManager::new(globals, queue_handle).ok(),
|
||||||
|
|
||||||
seats,
|
seats,
|
||||||
text_input_state: TextInputState::new(globals, queue_handle).ok(),
|
text_input_state: TextInputState::new(globals, queue_handle).ok(),
|
||||||
|
|
@ -301,15 +301,24 @@ impl WindowHandler for WinitState {
|
||||||
self.window_compositor_updates.len() - 1
|
self.window_compositor_updates.len() - 1
|
||||||
};
|
};
|
||||||
|
|
||||||
// Populate the configure to the window.
|
let mut winit_window = self
|
||||||
self.window_compositor_updates[pos].resized |= self
|
|
||||||
.windows
|
.windows
|
||||||
.get_mut()
|
.get_mut()
|
||||||
.get_mut(&window_id)
|
.get_mut(&window_id)
|
||||||
.expect("got configure for dead window.")
|
.expect("got configure for dead window.")
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap();
|
||||||
.configure(configure, &self.shm, &self.subcompositor_state);
|
// Populate the configure to the window.
|
||||||
|
|
||||||
|
self.window_compositor_updates[pos].suggested_bounds |= configure.suggested_bounds
|
||||||
|
!= winit_window.last_configure.as_ref().and_then(|last| last.suggested_bounds);
|
||||||
|
|
||||||
|
if winit_window.last_configure.as_ref().is_none_or(|last| last.state != configure.state) {
|
||||||
|
self.window_compositor_updates[pos].xdg_window_state = Some(configure.state);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.window_compositor_updates[pos].resized |=
|
||||||
|
winit_window.configure(configure, &self.shm, &self.subcompositor_state);
|
||||||
|
|
||||||
// NOTE: configure demands wl_surface::commit, however winit doesn't commit on behalf of the
|
// NOTE: configure demands wl_surface::commit, however winit doesn't commit on behalf of the
|
||||||
// users, since it can break a lot of things, thus it'll ask users to redraw instead.
|
// users, since it can break a lot of things, thus it'll ask users to redraw instead.
|
||||||
|
|
@ -437,11 +446,24 @@ pub struct WindowCompositorUpdate {
|
||||||
|
|
||||||
/// Close the window.
|
/// Close the window.
|
||||||
pub close_window: bool,
|
pub close_window: bool,
|
||||||
|
|
||||||
|
/// New suggested bounds.
|
||||||
|
pub suggested_bounds: bool,
|
||||||
|
|
||||||
|
/// New xdg window state.
|
||||||
|
pub xdg_window_state: Option<sctk::reexports::csd_frame::WindowState>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowCompositorUpdate {
|
impl WindowCompositorUpdate {
|
||||||
fn new(window_id: WindowId) -> Self {
|
fn new(window_id: WindowId) -> Self {
|
||||||
Self { window_id, resized: false, scale_changed: false, close_window: false }
|
Self {
|
||||||
|
window_id,
|
||||||
|
resized: false,
|
||||||
|
scale_changed: false,
|
||||||
|
close_window: false,
|
||||||
|
suggested_bounds: false,
|
||||||
|
xdg_window_state: None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
85
winit-wayland/src/types/bgr_effects.rs
Normal file
85
winit-wayland/src/types/bgr_effects.rs
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
use sctk::compositor::Region;
|
||||||
|
use sctk::reexports::client::QueueHandle;
|
||||||
|
use sctk::reexports::client::globals::{BindError, GlobalList};
|
||||||
|
use sctk::reexports::client::protocol::wl_surface::WlSurface;
|
||||||
|
use sctk::reexports::protocols::ext::background_effect::v1::client::ext_background_effect_surface_v1::ExtBackgroundEffectSurfaceV1;
|
||||||
|
use wayland_protocols_plasma::blur::client::org_kde_kwin_blur::OrgKdeKwinBlur;
|
||||||
|
|
||||||
|
use crate::state::WinitState;
|
||||||
|
use crate::types::ext_background_effect::ExtBackgroundEffectManager;
|
||||||
|
use crate::types::kwin_blur::KWinBlurManager;
|
||||||
|
|
||||||
|
/// Wrapper around various background effects for [`WlSurface`].
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum BgrEffectManager {
|
||||||
|
Ext(ExtBackgroundEffectManager),
|
||||||
|
KWin(KWinBlurManager),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BgrEffectManager {
|
||||||
|
pub fn new(
|
||||||
|
globals: &GlobalList,
|
||||||
|
queue_handle: &QueueHandle<WinitState>,
|
||||||
|
) -> Result<Self, BindError> {
|
||||||
|
ExtBackgroundEffectManager::new(globals, queue_handle)
|
||||||
|
.map(Self::Ext)
|
||||||
|
.or_else(|_| KWinBlurManager::new(globals, queue_handle).map(Self::KWin))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a new blur effect for the surface.
|
||||||
|
pub fn new_blur_effect(
|
||||||
|
&mut self,
|
||||||
|
surface: &WlSurface,
|
||||||
|
queue_handle: &QueueHandle<WinitState>,
|
||||||
|
) -> SurfaceBlurEffect {
|
||||||
|
match self {
|
||||||
|
BgrEffectManager::Ext(mgr) => SurfaceBlurEffect::Ext(mgr.blur(surface, queue_handle)),
|
||||||
|
BgrEffectManager::KWin(mgr) => SurfaceBlurEffect::Kwin(
|
||||||
|
mgr.blur(surface, queue_handle),
|
||||||
|
mgr.clone(),
|
||||||
|
surface.clone(),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum SurfaceBlurEffect {
|
||||||
|
Ext(ExtBackgroundEffectSurfaceV1),
|
||||||
|
Kwin(OrgKdeKwinBlur, KWinBlurManager, WlSurface),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SurfaceBlurEffect {
|
||||||
|
/// Returns `true` if the main surface commit is required.
|
||||||
|
///
|
||||||
|
/// `None` clears the blur.
|
||||||
|
#[must_use]
|
||||||
|
pub fn set_blur(&self, region: Option<&Region>) -> bool {
|
||||||
|
let region = region.map(|region| region.wl_region());
|
||||||
|
match self {
|
||||||
|
SurfaceBlurEffect::Ext(surface) => {
|
||||||
|
surface.set_blur_region(region);
|
||||||
|
true
|
||||||
|
},
|
||||||
|
SurfaceBlurEffect::Kwin(blur, ..) => {
|
||||||
|
blur.set_region(region);
|
||||||
|
blur.commit();
|
||||||
|
true
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for SurfaceBlurEffect {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
match self {
|
||||||
|
SurfaceBlurEffect::Ext(surface) => surface.destroy(),
|
||||||
|
SurfaceBlurEffect::Kwin(blur, mgr, wl_surface) => {
|
||||||
|
blur.set_region(None);
|
||||||
|
blur.commit();
|
||||||
|
blur.release();
|
||||||
|
mgr.unset(wl_surface);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
59
winit-wayland/src/types/ext_background_effect.rs
Normal file
59
winit-wayland/src/types/ext_background_effect.rs
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
use sctk::globals::GlobalData;
|
||||||
|
use sctk::reexports::client::globals::{BindError, GlobalList};
|
||||||
|
use sctk::reexports::client::protocol::wl_surface::WlSurface;
|
||||||
|
use sctk::reexports::client::{Connection, Dispatch, Proxy, QueueHandle, delegate_dispatch};
|
||||||
|
use wayland_protocols::ext::background_effect::v1::client::ext_background_effect_manager_v1::ExtBackgroundEffectManagerV1;
|
||||||
|
use wayland_protocols::ext::background_effect::v1::client::ext_background_effect_surface_v1::ExtBackgroundEffectSurfaceV1;
|
||||||
|
|
||||||
|
use crate::state::WinitState;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct ExtBackgroundEffectManager {
|
||||||
|
manager: ExtBackgroundEffectManagerV1,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExtBackgroundEffectManager {
|
||||||
|
pub fn new(
|
||||||
|
globals: &GlobalList,
|
||||||
|
queue_handle: &QueueHandle<WinitState>,
|
||||||
|
) -> Result<Self, BindError> {
|
||||||
|
let manager = globals.bind(queue_handle, 1..=1, GlobalData)?;
|
||||||
|
Ok(Self { manager })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn blur(
|
||||||
|
&mut self,
|
||||||
|
surface: &WlSurface,
|
||||||
|
queue_handle: &QueueHandle<WinitState>,
|
||||||
|
) -> ExtBackgroundEffectSurfaceV1 {
|
||||||
|
self.manager.get_background_effect(surface, queue_handle, ())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Dispatch<ExtBackgroundEffectManagerV1, GlobalData, WinitState> for ExtBackgroundEffectManager {
|
||||||
|
fn event(
|
||||||
|
_: &mut WinitState,
|
||||||
|
_: &ExtBackgroundEffectManagerV1,
|
||||||
|
_: <ExtBackgroundEffectManagerV1 as Proxy>::Event,
|
||||||
|
_: &GlobalData,
|
||||||
|
_: &Connection,
|
||||||
|
_: &QueueHandle<WinitState>,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Dispatch<ExtBackgroundEffectSurfaceV1, (), WinitState> for ExtBackgroundEffectManager {
|
||||||
|
fn event(
|
||||||
|
_: &mut WinitState,
|
||||||
|
_: &ExtBackgroundEffectSurfaceV1,
|
||||||
|
_: <ExtBackgroundEffectSurfaceV1 as Proxy>::Event,
|
||||||
|
_: &(),
|
||||||
|
_: &Connection,
|
||||||
|
_: &QueueHandle<WinitState>,
|
||||||
|
) {
|
||||||
|
// There is no event
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate_dispatch!(WinitState: [ExtBackgroundEffectManagerV1: GlobalData] => ExtBackgroundEffectManager);
|
||||||
|
delegate_dispatch!(WinitState: [ExtBackgroundEffectSurfaceV1: ()] => ExtBackgroundEffectManager);
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
//! Wayland protocol implementation boilerplate.
|
//! Wayland protocol implementation boilerplate.
|
||||||
|
|
||||||
|
pub mod bgr_effects;
|
||||||
pub mod cursor;
|
pub mod cursor;
|
||||||
|
pub mod ext_background_effect;
|
||||||
pub mod kwin_blur;
|
pub mod kwin_blur;
|
||||||
pub mod wp_fractional_scaling;
|
pub mod wp_fractional_scaling;
|
||||||
pub mod wp_tablet_input_v2;
|
pub mod wp_tablet_input_v2;
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ use sctk::reexports::client::protocol::wl_surface::WlSurface;
|
||||||
use sctk::reexports::client::{Proxy, QueueHandle};
|
use sctk::reexports::client::{Proxy, QueueHandle};
|
||||||
use sctk::reexports::protocols::xdg::activation::v1::client::xdg_activation_v1::XdgActivationV1;
|
use sctk::reexports::protocols::xdg::activation::v1::client::xdg_activation_v1::XdgActivationV1;
|
||||||
use sctk::shell::WaylandSurface;
|
use sctk::shell::WaylandSurface;
|
||||||
|
use sctk::shell::xdg::XdgSurface;
|
||||||
use sctk::shell::xdg::window::{Window as SctkWindow, WindowDecorations};
|
use sctk::shell::xdg::window::{Window as SctkWindow, WindowDecorations};
|
||||||
use tracing::warn;
|
use tracing::warn;
|
||||||
use winit_core::cursor::Cursor;
|
use winit_core::cursor::Cursor;
|
||||||
|
|
@ -30,7 +31,7 @@ use super::event_loop::sink::EventSink;
|
||||||
use super::output::MonitorHandle;
|
use super::output::MonitorHandle;
|
||||||
use super::state::WinitState;
|
use super::state::WinitState;
|
||||||
use super::types::xdg_activation::XdgActivationTokenData;
|
use super::types::xdg_activation::XdgActivationTokenData;
|
||||||
use crate::{WindowAttributesWayland, output};
|
use crate::{HasXdgSurfaceHandle, WindowAttributesWayland, XdgSurfaceHandle, output};
|
||||||
|
|
||||||
pub(crate) mod state;
|
pub(crate) mod state;
|
||||||
|
|
||||||
|
|
@ -127,7 +128,8 @@ impl Window {
|
||||||
// Set transparency hint.
|
// Set transparency hint.
|
||||||
window_state.set_transparent(attributes.transparent);
|
window_state.set_transparent(attributes.transparent);
|
||||||
|
|
||||||
window_state.set_blur(attributes.blur);
|
// Set blur.
|
||||||
|
let _ = window_state.set_blur(attributes.blur);
|
||||||
|
|
||||||
// Set the decorations hint.
|
// Set the decorations hint.
|
||||||
window_state.set_decorate(attributes.decorations);
|
window_state.set_decorate(attributes.decorations);
|
||||||
|
|
@ -251,6 +253,11 @@ impl Window {
|
||||||
pub fn surface(&self) -> &WlSurface {
|
pub fn surface(&self) -> &WlSurface {
|
||||||
self.window.wl_surface()
|
self.window.wl_surface()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn xdg_window_state(&self) -> Option<sctk::reexports::csd_frame::WindowState> {
|
||||||
|
self.window_state.lock().unwrap().last_configure.as_ref().map(|c| c.state)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Window {
|
impl Drop for Window {
|
||||||
|
|
@ -485,7 +492,9 @@ impl CoreWindow for Window {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn set_blur(&self, blur: bool) {
|
fn set_blur(&self, blur: bool) {
|
||||||
self.window_state.lock().unwrap().set_blur(blur);
|
if self.window_state.lock().unwrap().set_blur(blur) {
|
||||||
|
self.request_redraw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
@ -655,6 +664,17 @@ impl CoreWindow for Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl HasXdgSurfaceHandle for Window {
|
||||||
|
fn xdg_surface_handle(&self) -> Result<XdgSurfaceHandle<'_>, rwh_06::HandleError> {
|
||||||
|
let raw = {
|
||||||
|
let ptr = self.window.xdg_surface().id().as_ptr();
|
||||||
|
std::ptr::NonNull::new(ptr as *mut _).expect("wl_surface will never be null")
|
||||||
|
};
|
||||||
|
|
||||||
|
unsafe { Ok(XdgSurfaceHandle::borrow_raw(raw)) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The request from the window to the event loop.
|
/// The request from the window to the event loop.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct WindowRequests {
|
pub struct WindowRequests {
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ use sctk::shm::slot::SlotPool;
|
||||||
use sctk::subcompositor::SubcompositorState;
|
use sctk::subcompositor::SubcompositorState;
|
||||||
use tracing::{info, warn};
|
use tracing::{info, warn};
|
||||||
use wayland_protocols::xdg::toplevel_icon::v1::client::xdg_toplevel_icon_manager_v1::XdgToplevelIconManagerV1;
|
use wayland_protocols::xdg::toplevel_icon::v1::client::xdg_toplevel_icon_manager_v1::XdgToplevelIconManagerV1;
|
||||||
use wayland_protocols_plasma::blur::client::org_kde_kwin_blur::OrgKdeKwinBlur;
|
|
||||||
use winit_core::cursor::{CursorIcon, CustomCursor as CoreCustomCursor};
|
use winit_core::cursor::{CursorIcon, CustomCursor as CoreCustomCursor};
|
||||||
use winit_core::error::{NotSupportedError, RequestError};
|
use winit_core::error::{NotSupportedError, RequestError};
|
||||||
use winit_core::window::{
|
use winit_core::window::{
|
||||||
|
|
@ -43,8 +42,8 @@ use crate::seat::{
|
||||||
ZwpTextInputV3Ext,
|
ZwpTextInputV3Ext,
|
||||||
};
|
};
|
||||||
use crate::state::{WindowCompositorUpdate, WinitState};
|
use crate::state::{WindowCompositorUpdate, WinitState};
|
||||||
|
use crate::types::bgr_effects::{BgrEffectManager, SurfaceBlurEffect};
|
||||||
use crate::types::cursor::{CustomCursor, SelectedCursor, WaylandCustomCursor};
|
use crate::types::cursor::{CustomCursor, SelectedCursor, WaylandCustomCursor};
|
||||||
use crate::types::kwin_blur::KWinBlurManager;
|
|
||||||
use crate::types::xdg_toplevel_icon_manager::ToplevelIcon;
|
use crate::types::xdg_toplevel_icon_manager::ToplevelIcon;
|
||||||
|
|
||||||
#[cfg(feature = "sctk-adwaita")]
|
#[cfg(feature = "sctk-adwaita")]
|
||||||
|
|
@ -155,8 +154,8 @@ pub struct WindowState {
|
||||||
|
|
||||||
viewport: Option<WpViewport>,
|
viewport: Option<WpViewport>,
|
||||||
fractional_scale: Option<WpFractionalScaleV1>,
|
fractional_scale: Option<WpFractionalScaleV1>,
|
||||||
blur: Option<OrgKdeKwinBlur>,
|
blur: Option<SurfaceBlurEffect>,
|
||||||
blur_manager: Option<KWinBlurManager>,
|
blur_manager: Option<BgrEffectManager>,
|
||||||
|
|
||||||
/// Whether the client side decorations have pending move operations.
|
/// Whether the client side decorations have pending move operations.
|
||||||
///
|
///
|
||||||
|
|
@ -205,7 +204,7 @@ impl WindowState {
|
||||||
toplevel_icon: None,
|
toplevel_icon: None,
|
||||||
xdg_toplevel_icon_manager,
|
xdg_toplevel_icon_manager,
|
||||||
blur: None,
|
blur: None,
|
||||||
blur_manager: winit_state.kwin_blur_manager.clone(),
|
blur_manager: winit_state.blur_manager.clone(),
|
||||||
compositor,
|
compositor,
|
||||||
handle,
|
handle,
|
||||||
csd_fails: false,
|
csd_fails: false,
|
||||||
|
|
@ -704,6 +703,13 @@ impl WindowState {
|
||||||
// Set surface size without the borders.
|
// Set surface size without the borders.
|
||||||
viewport.set_destination(self.size.width as _, self.size.height as _);
|
viewport.set_destination(self.size.width as _, self.size.height as _);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update blur region with new size.
|
||||||
|
if self.blur.is_some() {
|
||||||
|
// NOTE: either user resized or configure, in both cases
|
||||||
|
// the redraw scheduling is done on the caller side.
|
||||||
|
let _ = self.set_blur(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the scale factor of the window.
|
/// Get the scale factor of the window.
|
||||||
|
|
@ -1063,20 +1069,37 @@ impl WindowState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make window background blurred
|
/// Make window background blurred.
|
||||||
#[inline]
|
///
|
||||||
pub fn set_blur(&mut self, blurred: bool) {
|
/// Returns `true` if redraw is required.
|
||||||
if blurred && self.blur.is_none() {
|
#[must_use]
|
||||||
if let Some(blur_manager) = self.blur_manager.as_ref() {
|
pub fn set_blur(&mut self, blurred: bool) -> bool {
|
||||||
let blur = blur_manager.blur(self.window.wl_surface(), &self.queue_handle);
|
if !blurred {
|
||||||
blur.commit();
|
self.blur = None;
|
||||||
self.blur = Some(blur);
|
return true;
|
||||||
} else {
|
}
|
||||||
info!("Blur manager unavailable, unable to change blur")
|
|
||||||
}
|
let mgr = match self.blur_manager.as_mut() {
|
||||||
} else if !blurred && self.blur.is_some() {
|
Some(mgr) => mgr,
|
||||||
self.blur_manager.as_ref().unwrap().unset(self.window.wl_surface());
|
None => {
|
||||||
self.blur.take().unwrap().release();
|
info!("Blur manager unavailable, unable to change blur");
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let blur = match self.blur.as_ref() {
|
||||||
|
Some(blur) => blur,
|
||||||
|
None => {
|
||||||
|
self.blur = Some(mgr.new_blur_effect(self.window.wl_surface(), &self.queue_handle));
|
||||||
|
self.blur.as_ref().unwrap()
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Ok(region) = Region::new(&*self.compositor) {
|
||||||
|
region.add(0, 0, i32::MAX, i32::MAX);
|
||||||
|
blur.set_blur(Some(®ion))
|
||||||
|
} else {
|
||||||
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1174,10 +1197,6 @@ impl WindowState {
|
||||||
|
|
||||||
impl Drop for WindowState {
|
impl Drop for WindowState {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if let Some(blur) = self.blur.take() {
|
|
||||||
blur.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(fs) = self.fractional_scale.take() {
|
if let Some(fs) = self.fractional_scale.take() {
|
||||||
fs.destroy();
|
fs.destroy();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -557,7 +557,9 @@ impl ApplicationHandler for Application {
|
||||||
| WindowEvent::DragDropped { .. }
|
| WindowEvent::DragDropped { .. }
|
||||||
| WindowEvent::Destroyed
|
| WindowEvent::Destroyed
|
||||||
| WindowEvent::Ime(_)
|
| WindowEvent::Ime(_)
|
||||||
| WindowEvent::Moved(_) => (),
|
| WindowEvent::Moved(_)
|
||||||
|
| WindowEvent::SuggestedBounds(_)
|
||||||
|
| WindowEvent::WindowStateChanged => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,18 +39,3 @@ The migration guide could reference other migration examples in the current
|
||||||
changelog entry.
|
changelog entry.
|
||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- Add `EventLoopExtRegister::register_app` for being explicit about how the event loop runs on Web.
|
|
||||||
- Add `EventLoopExtNeverReturn::run_app_never_return` for being explicit about how the event loop runs on iOS.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- On Web, avoid throwing an exception in `EventLoop::run_app`, instead preferring to return to the caller.
|
|
||||||
This requires passing a `'static` application to ensure that the application state will live as long as necessary.
|
|
||||||
- On Web, the event loop can now always be re-created once it has finished running.
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- Fixed panic when calling `Window::set_ime_allowed`.
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,20 @@
|
||||||
|
## 0.31.0-beta.2
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Add `EventLoopExtRegister::register_app` for being explicit about how the event loop runs on Web.
|
||||||
|
- Add `EventLoopExtNeverReturn::run_app_never_return` for being explicit about how the event loop runs on iOS.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- On Web, avoid throwing an exception in `EventLoop::run_app`, instead preferring to return to the caller.
|
||||||
|
This requires passing a `'static` application to ensure that the application state will live as long as necessary.
|
||||||
|
- On Web, the event loop can now always be re-created once it has finished running.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed panic when calling `Window::set_ime_allowed`.
|
||||||
|
|
||||||
## 0.31.0-beta.1
|
## 0.31.0-beta.1
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue