From 01b912c0dbe6c0a46701d62dd4f3dd0110f70b70 Mon Sep 17 00:00:00 2001 From: Poly Date: Sun, 1 May 2022 02:28:56 +0200 Subject: [PATCH 01/11] wayland: Replace fallback CSD with proper one --- CHANGELOG.md | 1 + Cargo.toml | 3 ++- FEATURES.md | 2 +- src/platform_impl/linux/wayland/seat/pointer/mod.rs | 3 ++- src/platform_impl/linux/wayland/window/mod.rs | 5 +++-- src/platform_impl/linux/wayland/window/shim.rs | 7 ++++--- 6 files changed, 13 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 589642daa1..5cced85b5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ And please only add new entries to the top of this list, right below the `# Unre sent a cancel or frame event. - On iOS, send `RedrawEventsCleared` even if there are no redraw events, consistent with other platforms. - **Breaking:** Replaced `Window::with_app_id` and `Window::with_class` with `Window::with_name` on `WindowBuilderExtUnix`. +- On Wayland, fallback CSD was replaced with proper one. - On Wayland and X11, fix window not resizing with `Window::set_inner_size` after calling `Window:set_resizable(false)`. - On Windows, fix wrong fullscreen monitors being recognized when handling WM_WINDOWPOSCHANGING messages diff --git a/Cargo.toml b/Cargo.toml index 0fee93fe47..37fdc0f854 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ targets = ["i686-pc-windows-msvc", "x86_64-pc-windows-msvc", "i686-unknown-linux [features] default = ["x11", "wayland", "wayland-dlopen"] x11 = ["x11-dl", "mio", "percent-encoding", "parking_lot"] -wayland = ["wayland-client", "wayland-protocols", "sctk"] +wayland = ["wayland-client", "wayland-protocols", "sctk", "sctk-adwaita"] wayland-dlopen = ["sctk/dlopen", "wayland-client/dlopen"] [dependencies] @@ -90,6 +90,7 @@ features = [ wayland-client = { version = "0.29", default_features = false, features = ["use_system_lib"], optional = true } wayland-protocols = { version = "0.29", features = [ "staging_protocols"], optional = true } sctk = { package = "smithay-client-toolkit", version = "0.15.4", default_features = false, features = ["calloop"], optional = true } +sctk-adwaita = { version = "0.3", optional = true } mio = { version = "0.8", features = ["os-ext"], optional = true } x11-dl = { version = "2.18.5", optional = true } percent-encoding = { version = "2.0", optional = true } diff --git a/FEATURES.md b/FEATURES.md index 15aacb6b6b..02625f064e 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -173,7 +173,7 @@ Legend: |Window initialization |✔️ |✔️ |▢[#5] |✔️ |▢[#33]|▢[#33] |✔️ | |Providing pointer to init OpenGL |✔️ |✔️ |✔️ |✔️ |✔️ |✔️ |**N/A**| |Providing pointer to init Vulkan |✔️ |✔️ |✔️ |✔️ |✔️ |❓ |**N/A**| -|Window decorations |✔️ |✔️ |✔️ |▢[#306] |**N/A**|**N/A**|**N/A**| +|Window decorations |✔️ |✔️ |✔️ |✔️ |**N/A**|**N/A**|**N/A**| |Window decorations toggle |✔️ |✔️ |✔️ |✔️ |**N/A**|**N/A**|**N/A**| |Window resizing |✔️ |▢[#219]|✔️ |▢[#306] |**N/A**|**N/A**|✔️ | |Window resize increments |❌ |❌ |❌ |❌ |❌ |❌ |**N/A**| diff --git a/src/platform_impl/linux/wayland/seat/pointer/mod.rs b/src/platform_impl/linux/wayland/seat/pointer/mod.rs index 0542ba2f8b..b805a5c756 100644 --- a/src/platform_impl/linux/wayland/seat/pointer/mod.rs +++ b/src/platform_impl/linux/wayland/seat/pointer/mod.rs @@ -13,7 +13,8 @@ use sctk::reexports::protocols::unstable::pointer_constraints::v1::client::zwp_p use sctk::reexports::protocols::unstable::pointer_constraints::v1::client::zwp_confined_pointer_v1::ZwpConfinedPointerV1; use sctk::seat::pointer::{ThemeManager, ThemedPointer}; -use sctk::window::{FallbackFrame, Window}; +use sctk::window::Window; +use sctk_adwaita::AdwaitaFrame; use crate::event::ModifiersState; use crate::platform_impl::wayland::event_loop::WinitState; diff --git a/src/platform_impl/linux/wayland/window/mod.rs b/src/platform_impl/linux/wayland/window/mod.rs index 4cff918f3e..42ba79f8ab 100644 --- a/src/platform_impl/linux/wayland/window/mod.rs +++ b/src/platform_impl/linux/wayland/window/mod.rs @@ -8,7 +8,8 @@ use sctk::reexports::client::Display; use sctk::reexports::calloop; use raw_window_handle::WaylandHandle; -use sctk::window::{Decorations, FallbackFrame}; +use sctk::window::Decorations; +use sctk_adwaita::AdwaitaFrame; use crate::dpi::{LogicalSize, PhysicalPosition, PhysicalSize, Position, Size}; use crate::error::{ExternalError, NotSupportedError, OsError as RootOsError}; @@ -105,7 +106,7 @@ impl Window { let theme_manager = event_loop_window_target.theme_manager.clone(); let mut window = event_loop_window_target .env - .create_window::( + .create_window::( surface.clone(), Some(theme_manager), (width, height), diff --git a/src/platform_impl/linux/wayland/window/shim.rs b/src/platform_impl/linux/wayland/window/shim.rs index 90695be533..6d583b2069 100644 --- a/src/platform_impl/linux/wayland/window/shim.rs +++ b/src/platform_impl/linux/wayland/window/shim.rs @@ -8,7 +8,8 @@ use sctk::reexports::protocols::staging::xdg_activation::v1::client::xdg_activat use sctk::reexports::protocols::staging::xdg_activation::v1::client::xdg_activation_v1::XdgActivationV1; use sctk::environment::Environment; -use sctk::window::{Decorations, FallbackFrame, Window}; +use sctk::window::{Decorations, Window}; +use sctk_adwaita::AdwaitaFrame; use crate::dpi::{LogicalPosition, LogicalSize}; @@ -143,7 +144,7 @@ impl WindowUpdate { /// and react to events. pub struct WindowHandle { /// An actual window. - pub window: Window, + pub window: Window, /// The current size of the window. pub size: Arc>>, @@ -182,7 +183,7 @@ pub struct WindowHandle { impl WindowHandle { pub fn new( env: &Environment, - window: Window, + window: Window, size: Arc>>, pending_window_requests: Arc>>, ) -> Self { From 9be89fbe3820db088b516483fe3683718501103f Mon Sep 17 00:00:00 2001 From: Poly Date: Sun, 1 May 2022 02:26:07 +0200 Subject: [PATCH 02/11] wayland: Add API for changing FrameConfig --- src/platform/unix.rs | 30 +++++++++++++++++++ src/platform_impl/linux/mod.rs | 7 +++++ src/platform_impl/linux/wayland/window/mod.rs | 12 +++++++- .../linux/wayland/window/shim.rs | 11 ++++++- 4 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/platform/unix.rs b/src/platform/unix.rs index 508cafb54e..f9a7590052 100644 --- a/src/platform/unix.rs +++ b/src/platform/unix.rs @@ -32,6 +32,9 @@ pub use crate::platform_impl::x11; #[cfg(feature = "x11")] pub use crate::platform_impl::{x11::util::WindowType as XWindowType, XNotSupported}; +#[cfg(feature = "wayland")] +pub use sctk_adwaita::FrameConfig; + /// Additional methods on `EventLoopWindowTarget` that are specific to Unix. pub trait EventLoopWindowTargetExtUnix { /// True if the `EventLoopWindowTarget` uses Wayland. @@ -179,6 +182,12 @@ pub trait WindowExtUnix { #[cfg(feature = "wayland")] fn wayland_display(&self) -> Option<*mut raw::c_void>; + /// Updates FrameConfig of a window. + /// + /// Usually used to switch a theme. + #[cfg(feature = "wayland")] + fn wayland_set_csd_config(&self, config: FrameConfig); + /// Check if the window is ready for drawing /// /// It is a remnant of a previous implementation detail for the @@ -261,6 +270,16 @@ impl WindowExtUnix for Window { } } + #[inline] + #[cfg(feature = "wayland")] + fn wayland_set_csd_config(&self, config: FrameConfig) { + match self.window { + LinuxWindow::Wayland(ref w) => w.set_csd_config(config), + #[cfg(feature = "x11")] + _ => {} + } + } + #[inline] fn is_ready(&self) -> bool { true @@ -299,6 +318,10 @@ pub trait WindowBuilderExtUnix { #[cfg(feature = "x11")] fn with_gtk_theme_variant(self, variant: String) -> Self; + /// Build window with certain FrameConfig (aka Theme) + #[cfg(feature = "wayland")] + fn with_wayland_csd_config(self, config: FrameConfig) -> Self; + /// Build window with resize increment hint. Only implemented on X11. /// /// ``` @@ -375,6 +398,13 @@ impl WindowBuilderExtUnix for WindowBuilder { self } + #[inline] + #[cfg(feature = "wayland")] + fn with_wayland_csd_config(mut self, config: FrameConfig) -> Self { + self.platform_specific.csd_config = Some(config); + self + } + #[inline] #[cfg(feature = "x11")] fn with_resize_increments>(mut self, increments: S) -> Self { diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index 78765756ce..5f55def6e2 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -9,8 +9,11 @@ #[cfg(all(not(feature = "x11"), not(feature = "wayland")))] compile_error!("Please select a feature to build for unix: `x11`, `wayland`"); +#[cfg(feature = "wayland")] +use sctk_adwaita::FrameConfig; #[cfg(feature = "wayland")] use std::error::Error; + use std::{collections::VecDeque, env, fmt}; #[cfg(feature = "x11")] use std::{ffi::CStr, mem::MaybeUninit, os::raw::*, sync::Arc}; @@ -101,6 +104,8 @@ pub struct PlatformSpecificWindowBuilderAttributes { pub x11_window_types: Vec, #[cfg(feature = "x11")] pub gtk_theme_variant: Option, + #[cfg(feature = "wayland")] + pub csd_config: Option, } impl Default for PlatformSpecificWindowBuilderAttributes { @@ -121,6 +126,8 @@ impl Default for PlatformSpecificWindowBuilderAttributes { x11_window_types: vec![XWindowType::Normal], #[cfg(feature = "x11")] gtk_theme_variant: None, + #[cfg(feature = "wayland")] + csd_config: None, } } } diff --git a/src/platform_impl/linux/wayland/window/mod.rs b/src/platform_impl/linux/wayland/window/mod.rs index 42ba79f8ab..327cb179a8 100644 --- a/src/platform_impl/linux/wayland/window/mod.rs +++ b/src/platform_impl/linux/wayland/window/mod.rs @@ -9,7 +9,7 @@ use sctk::reexports::calloop; use raw_window_handle::WaylandHandle; use sctk::window::Decorations; -use sctk_adwaita::AdwaitaFrame; +use sctk_adwaita::{AdwaitaFrame, FrameConfig}; use crate::dpi::{LogicalSize, PhysicalPosition, PhysicalSize, Position, Size}; use crate::error::{ExternalError, NotSupportedError, OsError as RootOsError}; @@ -140,6 +140,11 @@ impl Window { ) .map_err(|_| os_error!(OsError::WaylandMisc("failed to create window.")))?; + // Set CSD frame config + if let Some(config) = platform_attributes.csd_config { + window.set_frame_config(config); + } + // Set decorations. if attributes.decorations { window.set_decorate(Decorations::FollowServer); @@ -381,6 +386,11 @@ impl Window { self.decorated.load(Ordering::Relaxed) } + #[inline] + pub fn set_csd_config(&self, config: FrameConfig) { + self.send_request(WindowRequest::CsdConfig(config)); + } + #[inline] pub fn set_minimized(&self, minimized: bool) { // You can't unminimize the window on Wayland. diff --git a/src/platform_impl/linux/wayland/window/shim.rs b/src/platform_impl/linux/wayland/window/shim.rs index 6d583b2069..914c7dbe17 100644 --- a/src/platform_impl/linux/wayland/window/shim.rs +++ b/src/platform_impl/linux/wayland/window/shim.rs @@ -9,7 +9,7 @@ use sctk::reexports::protocols::staging::xdg_activation::v1::client::xdg_activat use sctk::environment::Environment; use sctk::window::{Decorations, Window}; -use sctk_adwaita::AdwaitaFrame; +use sctk_adwaita::{AdwaitaFrame, FrameConfig}; use crate::dpi::{LogicalPosition, LogicalSize}; @@ -54,6 +54,9 @@ pub enum WindowRequest { /// Request decorations change. Decorate(bool), + /// Request decorations change. + CsdConfig(FrameConfig), + /// Make the window resizeable. Resizeable(bool), @@ -419,6 +422,12 @@ pub fn handle_window_requests(winit_state: &mut WinitState) { let window_update = window_updates.get_mut(window_id).unwrap(); window_update.refresh_frame = true; } + WindowRequest::CsdConfig(config) => { + window_handle.window.set_frame_config(config); + + let window_update = window_updates.get_mut(window_id).unwrap(); + window_update.refresh_frame = true; + } WindowRequest::Resizeable(resizeable) => { window_handle.window.set_resizable(resizeable); From ab55e954f3ce39740a990819c7d93bc54db4604f Mon Sep 17 00:00:00 2001 From: Poly Date: Sun, 1 May 2022 20:21:58 +0200 Subject: [PATCH 03/11] wayland: Remove sctk-adwaita reexports --- src/platform/unix.rs | 20 +++++++++---------- src/platform_impl/linux/mod.rs | 6 +++--- src/platform_impl/linux/wayland/window/mod.rs | 12 +++++++---- .../linux/wayland/window/shim.rs | 10 +++++++--- 4 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/platform/unix.rs b/src/platform/unix.rs index f9a7590052..13bd7b4607 100644 --- a/src/platform/unix.rs +++ b/src/platform/unix.rs @@ -33,7 +33,7 @@ pub use crate::platform_impl::x11; pub use crate::platform_impl::{x11::util::WindowType as XWindowType, XNotSupported}; #[cfg(feature = "wayland")] -pub use sctk_adwaita::FrameConfig; +pub use crate::window::Theme; /// Additional methods on `EventLoopWindowTarget` that are specific to Unix. pub trait EventLoopWindowTargetExtUnix { @@ -182,11 +182,9 @@ pub trait WindowExtUnix { #[cfg(feature = "wayland")] fn wayland_display(&self) -> Option<*mut raw::c_void>; - /// Updates FrameConfig of a window. - /// - /// Usually used to switch a theme. + /// Updates [`Theme`] of window decorations. #[cfg(feature = "wayland")] - fn wayland_set_csd_config(&self, config: FrameConfig); + fn wayland_set_csd_theme(&self, config: Theme); /// Check if the window is ready for drawing /// @@ -272,9 +270,9 @@ impl WindowExtUnix for Window { #[inline] #[cfg(feature = "wayland")] - fn wayland_set_csd_config(&self, config: FrameConfig) { + fn wayland_set_csd_theme(&self, theme: Theme) { match self.window { - LinuxWindow::Wayland(ref w) => w.set_csd_config(config), + LinuxWindow::Wayland(ref w) => w.set_csd_theme(theme), #[cfg(feature = "x11")] _ => {} } @@ -318,9 +316,9 @@ pub trait WindowBuilderExtUnix { #[cfg(feature = "x11")] fn with_gtk_theme_variant(self, variant: String) -> Self; - /// Build window with certain FrameConfig (aka Theme) + /// Build window with certain decoration [`Theme`] #[cfg(feature = "wayland")] - fn with_wayland_csd_config(self, config: FrameConfig) -> Self; + fn with_wayland_csd_theme(self, theme: Theme) -> Self; /// Build window with resize increment hint. Only implemented on X11. /// @@ -400,8 +398,8 @@ impl WindowBuilderExtUnix for WindowBuilder { #[inline] #[cfg(feature = "wayland")] - fn with_wayland_csd_config(mut self, config: FrameConfig) -> Self { - self.platform_specific.csd_config = Some(config); + fn with_wayland_csd_theme(mut self, theme: Theme) -> Self { + self.platform_specific.csd_theme = Some(theme); self } diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index 5f55def6e2..31516562b7 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -10,7 +10,7 @@ compile_error!("Please select a feature to build for unix: `x11`, `wayland`"); #[cfg(feature = "wayland")] -use sctk_adwaita::FrameConfig; +use crate::window::Theme; #[cfg(feature = "wayland")] use std::error::Error; @@ -105,7 +105,7 @@ pub struct PlatformSpecificWindowBuilderAttributes { #[cfg(feature = "x11")] pub gtk_theme_variant: Option, #[cfg(feature = "wayland")] - pub csd_config: Option, + pub csd_theme: Option, } impl Default for PlatformSpecificWindowBuilderAttributes { @@ -127,7 +127,7 @@ impl Default for PlatformSpecificWindowBuilderAttributes { #[cfg(feature = "x11")] gtk_theme_variant: None, #[cfg(feature = "wayland")] - csd_config: None, + csd_theme: None, } } } diff --git a/src/platform_impl/linux/wayland/window/mod.rs b/src/platform_impl/linux/wayland/window/mod.rs index 327cb179a8..f9979293cf 100644 --- a/src/platform_impl/linux/wayland/window/mod.rs +++ b/src/platform_impl/linux/wayland/window/mod.rs @@ -18,7 +18,7 @@ use crate::platform_impl::{ MonitorHandle as PlatformMonitorHandle, OsError, PlatformSpecificWindowBuilderAttributes as PlatformAttributes, }; -use crate::window::{CursorIcon, Fullscreen, UserAttentionType, WindowAttributes}; +use crate::window::{CursorIcon, Fullscreen, Theme, UserAttentionType, WindowAttributes}; use super::env::WindowingFeatures; use super::event_loop::WinitState; @@ -141,7 +141,11 @@ impl Window { .map_err(|_| os_error!(OsError::WaylandMisc("failed to create window.")))?; // Set CSD frame config - if let Some(config) = platform_attributes.csd_config { + if let Some(theme) = platform_attributes.csd_theme { + let config = match theme { + Theme::Light => FrameConfig::light(), + Theme::Dark => FrameConfig::dark(), + }; window.set_frame_config(config); } @@ -387,8 +391,8 @@ impl Window { } #[inline] - pub fn set_csd_config(&self, config: FrameConfig) { - self.send_request(WindowRequest::CsdConfig(config)); + pub fn set_csd_theme(&self, theme: Theme) { + self.send_request(WindowRequest::CsdThemeVariant(theme)); } #[inline] diff --git a/src/platform_impl/linux/wayland/window/shim.rs b/src/platform_impl/linux/wayland/window/shim.rs index 914c7dbe17..396582f3b5 100644 --- a/src/platform_impl/linux/wayland/window/shim.rs +++ b/src/platform_impl/linux/wayland/window/shim.rs @@ -20,7 +20,7 @@ use crate::platform_impl::wayland::event_loop::WinitState; use crate::platform_impl::wayland::seat::pointer::WinitPointer; use crate::platform_impl::wayland::seat::text_input::TextInputHandler; use crate::platform_impl::wayland::WindowId; -use crate::window::{CursorIcon, UserAttentionType}; +use crate::window::{CursorIcon, Theme, UserAttentionType}; /// A request to SCTK window from Winit window. #[derive(Debug, Clone)] @@ -55,7 +55,7 @@ pub enum WindowRequest { Decorate(bool), /// Request decorations change. - CsdConfig(FrameConfig), + CsdThemeVariant(Theme), /// Make the window resizeable. Resizeable(bool), @@ -422,7 +422,11 @@ pub fn handle_window_requests(winit_state: &mut WinitState) { let window_update = window_updates.get_mut(window_id).unwrap(); window_update.refresh_frame = true; } - WindowRequest::CsdConfig(config) => { + WindowRequest::CsdThemeVariant(theme) => { + let config = match theme { + Theme::Light => FrameConfig::light(), + Theme::Dark => FrameConfig::dark(), + }; window_handle.window.set_frame_config(config); let window_update = window_updates.get_mut(window_id).unwrap(); From e1b75d0f3b1ea40ce28b4af1d3dbef6c61f5115d Mon Sep 17 00:00:00 2001 From: Poly Date: Mon, 2 May 2022 18:18:40 +0200 Subject: [PATCH 04/11] wayland: Make sctk-adwaita optional --- Cargo.toml | 5 ++-- .../linux/wayland/seat/pointer/mod.rs | 4 +-- src/platform_impl/linux/wayland/window/mod.rs | 11 +++++-- .../linux/wayland/window/shim.rs | 30 ++++++++++++------- 4 files changed, 33 insertions(+), 17 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 37fdc0f854..8fdd49b23a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,10 +17,11 @@ default-target = "x86_64-unknown-linux-gnu" targets = ["i686-pc-windows-msvc", "x86_64-pc-windows-msvc", "i686-unknown-linux-gnu", "x86_64-unknown-linux-gnu", "x86_64-apple-darwin", "wasm32-unknown-unknown"] [features] -default = ["x11", "wayland", "wayland-dlopen"] +default = ["x11", "wayland", "wayland-dlopen", "wayland-csd-adwaita"] x11 = ["x11-dl", "mio", "percent-encoding", "parking_lot"] -wayland = ["wayland-client", "wayland-protocols", "sctk", "sctk-adwaita"] +wayland = ["wayland-client", "wayland-protocols", "sctk"] wayland-dlopen = ["sctk/dlopen", "wayland-client/dlopen"] +wayland-csd-adwaita = ["sctk-adwaita"] [dependencies] instant = { version = "0.1", features = ["wasm-bindgen"] } diff --git a/src/platform_impl/linux/wayland/seat/pointer/mod.rs b/src/platform_impl/linux/wayland/seat/pointer/mod.rs index b805a5c756..7ec116405b 100644 --- a/src/platform_impl/linux/wayland/seat/pointer/mod.rs +++ b/src/platform_impl/linux/wayland/seat/pointer/mod.rs @@ -14,10 +14,10 @@ use sctk::reexports::protocols::unstable::pointer_constraints::v1::client::zwp_c use sctk::seat::pointer::{ThemeManager, ThemedPointer}; use sctk::window::Window; -use sctk_adwaita::AdwaitaFrame; use crate::event::ModifiersState; use crate::platform_impl::wayland::event_loop::WinitState; +use crate::platform_impl::wayland::window::WinitFrame; use crate::window::CursorIcon; mod data; @@ -157,7 +157,7 @@ impl WinitPointer { } } - pub fn drag_window(&self, window: &Window) { + pub fn drag_window(&self, window: &Window) { // WlPointer::setart_interactive_move() expects the last serial of *any* // pointer event (compare to set_cursor()). window.start_interactive_move(&self.seat, self.latest_serial.get()); diff --git a/src/platform_impl/linux/wayland/window/mod.rs b/src/platform_impl/linux/wayland/window/mod.rs index f9979293cf..531557a700 100644 --- a/src/platform_impl/linux/wayland/window/mod.rs +++ b/src/platform_impl/linux/wayland/window/mod.rs @@ -9,7 +9,6 @@ use sctk::reexports::calloop; use raw_window_handle::WaylandHandle; use sctk::window::Decorations; -use sctk_adwaita::{AdwaitaFrame, FrameConfig}; use crate::dpi::{LogicalSize, PhysicalPosition, PhysicalSize, Position, Size}; use crate::error::{ExternalError, NotSupportedError, OsError as RootOsError}; @@ -29,6 +28,11 @@ pub mod shim; use shim::{WindowHandle, WindowRequest, WindowUpdate}; +#[cfg(feature = "sctk-adwaita")] +pub type WinitFrame = sctk_adwaita::AdwaitaFrame; +#[cfg(not(feature = "sctk-adwaita"))] +pub type WinitFrame = sctk::window::FallbackFrame; + pub struct Window { /// Window id. window_id: WindowId, @@ -106,7 +110,7 @@ impl Window { let theme_manager = event_loop_window_target.theme_manager.clone(); let mut window = event_loop_window_target .env - .create_window::( + .create_window::( surface.clone(), Some(theme_manager), (width, height), @@ -141,7 +145,10 @@ impl Window { .map_err(|_| os_error!(OsError::WaylandMisc("failed to create window.")))?; // Set CSD frame config + #[cfg(feature = "sctk-adwaita")] if let Some(theme) = platform_attributes.csd_theme { + use sctk_adwaita::FrameConfig; + let config = match theme { Theme::Light => FrameConfig::light(), Theme::Dark => FrameConfig::dark(), diff --git a/src/platform_impl/linux/wayland/window/shim.rs b/src/platform_impl/linux/wayland/window/shim.rs index 396582f3b5..904d0d30c0 100644 --- a/src/platform_impl/linux/wayland/window/shim.rs +++ b/src/platform_impl/linux/wayland/window/shim.rs @@ -9,7 +9,6 @@ use sctk::reexports::protocols::staging::xdg_activation::v1::client::xdg_activat use sctk::environment::Environment; use sctk::window::{Decorations, Window}; -use sctk_adwaita::{AdwaitaFrame, FrameConfig}; use crate::dpi::{LogicalPosition, LogicalSize}; @@ -22,6 +21,8 @@ use crate::platform_impl::wayland::seat::text_input::TextInputHandler; use crate::platform_impl::wayland::WindowId; use crate::window::{CursorIcon, Theme, UserAttentionType}; +use super::WinitFrame; + /// A request to SCTK window from Winit window. #[derive(Debug, Clone)] pub enum WindowRequest { @@ -147,7 +148,7 @@ impl WindowUpdate { /// and react to events. pub struct WindowHandle { /// An actual window. - pub window: Window, + pub window: Window, /// The current size of the window. pub size: Arc>>, @@ -186,7 +187,7 @@ pub struct WindowHandle { impl WindowHandle { pub fn new( env: &Environment, - window: Window, + window: Window, size: Arc>>, pending_window_requests: Arc>>, ) -> Self { @@ -423,14 +424,21 @@ pub fn handle_window_requests(winit_state: &mut WinitState) { window_update.refresh_frame = true; } WindowRequest::CsdThemeVariant(theme) => { - let config = match theme { - Theme::Light => FrameConfig::light(), - Theme::Dark => FrameConfig::dark(), - }; - window_handle.window.set_frame_config(config); - - let window_update = window_updates.get_mut(window_id).unwrap(); - window_update.refresh_frame = true; + #[cfg(feature = "sctk-adwaita")] + { + use sctk_adwaita::FrameConfig; + + let config = match theme { + Theme::Light => FrameConfig::light(), + Theme::Dark => FrameConfig::dark(), + }; + window_handle.window.set_frame_config(config); + + let window_update = window_updates.get_mut(window_id).unwrap(); + window_update.refresh_frame = true; + } + #[cfg(not(feature = "sctk-adwaita"))] + let _ = theme; } WindowRequest::Resizeable(resizeable) => { window_handle.window.set_resizable(resizeable); From d7fecabcddedb6bf513abb0a84d52a5feca2c453 Mon Sep 17 00:00:00 2001 From: Poly Date: Mon, 2 May 2022 21:18:33 +0200 Subject: [PATCH 05/11] wayland: Make title rendering optional --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index 8fdd49b23a..734d46e827 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ x11 = ["x11-dl", "mio", "percent-encoding", "parking_lot"] wayland = ["wayland-client", "wayland-protocols", "sctk"] wayland-dlopen = ["sctk/dlopen", "wayland-client/dlopen"] wayland-csd-adwaita = ["sctk-adwaita"] +wayland-csd-title = ["sctk-adwaita/title"] [dependencies] instant = { version = "0.1", features = ["wasm-bindgen"] } From 3372fef810e8bdd262494f3749cfc9d6388b287a Mon Sep 17 00:00:00 2001 From: Poly Date: Fri, 13 May 2022 22:54:55 +0200 Subject: [PATCH 06/11] Address review comments --- CHANGELOG.md | 4 +++ src/platform_impl/linux/wayland/window/mod.rs | 6 ++--- .../linux/wayland/window/shim.rs | 26 ++++++++----------- 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cced85b5f..8bd1ca6129 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,10 @@ And please only add new entries to the top of this list, right below the `# Unre - On iOS, send `RedrawEventsCleared` even if there are no redraw events, consistent with other platforms. - **Breaking:** Replaced `Window::with_app_id` and `Window::with_class` with `Window::with_name` on `WindowBuilderExtUnix`. - On Wayland, fallback CSD was replaced with proper one. + - `WindowBuilderExtUnix::with_wayland_csd_theme` used to set color theme in builder. + - `WindowExtUnix::wayland_set_csd_theme` used to change color theme on the fly. + - `wayland-csd-adwaita` feature that enables proper CSD. + - `wayland-csd-title` feature that enables title rendering, uses FreeType system library. - On Wayland and X11, fix window not resizing with `Window::set_inner_size` after calling `Window:set_resizable(false)`. - On Windows, fix wrong fullscreen monitors being recognized when handling WM_WINDOWPOSCHANGING messages diff --git a/src/platform_impl/linux/wayland/window/mod.rs b/src/platform_impl/linux/wayland/window/mod.rs index 531557a700..d8e93d8e37 100644 --- a/src/platform_impl/linux/wayland/window/mod.rs +++ b/src/platform_impl/linux/wayland/window/mod.rs @@ -147,11 +147,9 @@ impl Window { // Set CSD frame config #[cfg(feature = "sctk-adwaita")] if let Some(theme) = platform_attributes.csd_theme { - use sctk_adwaita::FrameConfig; - let config = match theme { - Theme::Light => FrameConfig::light(), - Theme::Dark => FrameConfig::dark(), + Theme::Light => sctk_adwaita::FrameConfig::light(), + Theme::Dark => sctk_adwaita::FrameConfig::dark(), }; window.set_frame_config(config); } diff --git a/src/platform_impl/linux/wayland/window/shim.rs b/src/platform_impl/linux/wayland/window/shim.rs index 904d0d30c0..b9defe0eb6 100644 --- a/src/platform_impl/linux/wayland/window/shim.rs +++ b/src/platform_impl/linux/wayland/window/shim.rs @@ -423,23 +423,19 @@ pub fn handle_window_requests(winit_state: &mut WinitState) { let window_update = window_updates.get_mut(window_id).unwrap(); window_update.refresh_frame = true; } + #[cfg(feature = "sctk-adwaita")] WindowRequest::CsdThemeVariant(theme) => { - #[cfg(feature = "sctk-adwaita")] - { - use sctk_adwaita::FrameConfig; - - let config = match theme { - Theme::Light => FrameConfig::light(), - Theme::Dark => FrameConfig::dark(), - }; - window_handle.window.set_frame_config(config); - - let window_update = window_updates.get_mut(window_id).unwrap(); - window_update.refresh_frame = true; - } - #[cfg(not(feature = "sctk-adwaita"))] - let _ = theme; + let config = match theme { + Theme::Light => sctk_adwaita::FrameConfig::light(), + Theme::Dark => sctk_adwaita::FrameConfig::dark(), + }; + window_handle.window.set_frame_config(config); + + let window_update = window_updates.get_mut(window_id).unwrap(); + window_update.refresh_frame = true; } + #[cfg(not(feature = "sctk-adwaita"))] + WindowRequest::CsdThemeVariant(_) => {} WindowRequest::Resizeable(resizeable) => { window_handle.window.set_resizable(resizeable); From a4d096a6c49036380a70d429c539a755ca84d9b9 Mon Sep 17 00:00:00 2001 From: Poly Date: Fri, 13 May 2022 23:01:37 +0200 Subject: [PATCH 07/11] Fix random unrelated build error --- src/platform/unix.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/platform/unix.rs b/src/platform/unix.rs index 13bd7b4607..e99d8e2dbb 100644 --- a/src/platform/unix.rs +++ b/src/platform/unix.rs @@ -73,7 +73,6 @@ impl EventLoopWindowTargetExtUnix for EventLoopWindowTarget { } #[inline] - #[doc(hidden)] #[cfg(feature = "x11")] fn xlib_xconnection(&self) -> Option> { match self.p { @@ -228,7 +227,6 @@ impl WindowExtUnix for Window { } #[inline] - #[doc(hidden)] #[cfg(feature = "x11")] fn xlib_xconnection(&self) -> Option> { match self.window { From dc59381090ba4814a9dc6d016ec2ba8818d16092 Mon Sep 17 00:00:00 2001 From: Poly Date: Thu, 19 May 2022 21:12:30 +0200 Subject: [PATCH 08/11] Introduce `WINIT_WAYLAND_CSD_THEME` env variable --- CHANGELOG.md | 1 + Cargo.toml | 2 +- src/platform/unix.rs | 6 ++++++ src/platform_impl/linux/wayland/window/mod.rs | 14 ++++++++++++++ 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8bd1ca6129..795168df11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,7 @@ And please only add new entries to the top of this list, right below the `# Unre - On Wayland, fallback CSD was replaced with proper one. - `WindowBuilderExtUnix::with_wayland_csd_theme` used to set color theme in builder. - `WindowExtUnix::wayland_set_csd_theme` used to change color theme on the fly. + - `WINIT_WAYLAND_CSD_THEME` env variable was added, it can be used to set "dark"/"light" theme in apps that don't expose theme setting. - `wayland-csd-adwaita` feature that enables proper CSD. - `wayland-csd-title` feature that enables title rendering, uses FreeType system library. - On Wayland and X11, fix window not resizing with `Window::set_inner_size` after calling `Window:set_resizable(false)`. diff --git a/Cargo.toml b/Cargo.toml index 734d46e827..82bedecd7e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -92,7 +92,7 @@ features = [ wayland-client = { version = "0.29", default_features = false, features = ["use_system_lib"], optional = true } wayland-protocols = { version = "0.29", features = [ "staging_protocols"], optional = true } sctk = { package = "smithay-client-toolkit", version = "0.15.4", default_features = false, features = ["calloop"], optional = true } -sctk-adwaita = { version = "0.3", optional = true } +sctk-adwaita = { version = "0.3.5", optional = true } mio = { version = "0.8", features = ["os-ext"], optional = true } x11-dl = { version = "2.18.5", optional = true } percent-encoding = { version = "2.0", optional = true } diff --git a/src/platform/unix.rs b/src/platform/unix.rs index e99d8e2dbb..81b06ad07b 100644 --- a/src/platform/unix.rs +++ b/src/platform/unix.rs @@ -182,6 +182,9 @@ pub trait WindowExtUnix { fn wayland_display(&self) -> Option<*mut raw::c_void>; /// Updates [`Theme`] of window decorations. + /// + /// You can also use `WINIT_WAYLAND_CSD_THEME` env variable to set the theme. + /// Possible values for env variable are: "dark" and light" #[cfg(feature = "wayland")] fn wayland_set_csd_theme(&self, config: Theme); @@ -315,6 +318,9 @@ pub trait WindowBuilderExtUnix { fn with_gtk_theme_variant(self, variant: String) -> Self; /// Build window with certain decoration [`Theme`] + /// + /// You can also use `WINIT_WAYLAND_CSD_THEME` env variable to set the theme. + /// Possible values for env variable are: "dark" and light" #[cfg(feature = "wayland")] fn with_wayland_csd_theme(self, theme: Theme) -> Self; diff --git a/src/platform_impl/linux/wayland/window/mod.rs b/src/platform_impl/linux/wayland/window/mod.rs index d8e93d8e37..70ed02f921 100644 --- a/src/platform_impl/linux/wayland/window/mod.rs +++ b/src/platform_impl/linux/wayland/window/mod.rs @@ -33,6 +33,8 @@ pub type WinitFrame = sctk_adwaita::AdwaitaFrame; #[cfg(not(feature = "sctk-adwaita"))] pub type WinitFrame = sctk::window::FallbackFrame; +const WAYLAND_CSD_THEME_ENV_VAR: &str = "WINIT_WAYLAND_CSD_THEME"; + pub struct Window { /// Window id. window_id: WindowId, @@ -152,6 +154,18 @@ impl Window { Theme::Dark => sctk_adwaita::FrameConfig::dark(), }; window.set_frame_config(config); + } else { + if let Ok(env) = std::env::var(WAYLAND_CSD_THEME_ENV_VAR) { + match env.to_lowercase().as_str() { + "dark" => { + window.set_frame_config(sctk_adwaita::FrameConfig::dark()); + } + "light" => { + window.set_frame_config(sctk_adwaita::FrameConfig::light()); + } + _ => {} + } + } } // Set decorations. From 9373c9fc5e1a6ebc202defad43951a84e2d71a19 Mon Sep 17 00:00:00 2001 From: Poly Date: Thu, 19 May 2022 22:28:30 +0200 Subject: [PATCH 09/11] Address review comments . --- .github/workflows/ci.yml | 3 +++ CHANGELOG.md | 10 ++++---- Cargo.toml | 4 ++-- src/platform_impl/linux/wayland/window/mod.rs | 24 +++++++++---------- 4 files changed, 21 insertions(+), 20 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1076aa5655..f62d3031d8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -65,6 +65,9 @@ jobs: - name: Install GCC Multilib if: (matrix.platform.os == 'ubuntu-latest') && contains(matrix.platform.target, 'i686') run: sudo apt-get update && sudo apt-get install gcc-multilib + - name: Install Freetype & FontConfig + if: matrix.platform.os == 'ubuntu-latest' + run: sudo apt-get update && sudo apt-get install pkg-config libfreetype6-dev libfontconfig1-dev cmake - name: Install cargo-apk if: contains(matrix.platform.target, 'android') run: cargo install cargo-apk diff --git a/CHANGELOG.md b/CHANGELOG.md index 795168df11..eeea562954 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,12 +39,12 @@ And please only add new entries to the top of this list, right below the `# Unre sent a cancel or frame event. - On iOS, send `RedrawEventsCleared` even if there are no redraw events, consistent with other platforms. - **Breaking:** Replaced `Window::with_app_id` and `Window::with_class` with `Window::with_name` on `WindowBuilderExtUnix`. -- On Wayland, fallback CSD was replaced with proper one. - - `WindowBuilderExtUnix::with_wayland_csd_theme` used to set color theme in builder. - - `WindowExtUnix::wayland_set_csd_theme` used to change color theme on the fly. +- On Wayland, fallback CSD was replaced with proper one; + - `WindowBuilderExtUnix::with_wayland_csd_theme` to set color theme in builder. + - `WindowExtUnix::wayland_set_csd_theme` to set color theme when creating a window. - `WINIT_WAYLAND_CSD_THEME` env variable was added, it can be used to set "dark"/"light" theme in apps that don't expose theme setting. - - `wayland-csd-adwaita` feature that enables proper CSD. - - `wayland-csd-title` feature that enables title rendering, uses FreeType system library. + - `wayland-csd-adwaita` feature that enables proper CSD with title rendering using FreeType system library. + - `wayland-csd-adwaita-notitle` feature that enables CSD but without title rendering. - On Wayland and X11, fix window not resizing with `Window::set_inner_size` after calling `Window:set_resizable(false)`. - On Windows, fix wrong fullscreen monitors being recognized when handling WM_WINDOWPOSCHANGING messages diff --git a/Cargo.toml b/Cargo.toml index 82bedecd7e..38f4a71f2d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,8 +21,8 @@ default = ["x11", "wayland", "wayland-dlopen", "wayland-csd-adwaita"] x11 = ["x11-dl", "mio", "percent-encoding", "parking_lot"] wayland = ["wayland-client", "wayland-protocols", "sctk"] wayland-dlopen = ["sctk/dlopen", "wayland-client/dlopen"] -wayland-csd-adwaita = ["sctk-adwaita"] -wayland-csd-title = ["sctk-adwaita/title"] +wayland-csd-adwaita = ["sctk-adwaita", "sctk-adwaita/title"] +wayland-csd-adwaita-notitle = ["sctk-adwaita"] [dependencies] instant = { version = "0.1", features = ["wasm-bindgen"] } diff --git a/src/platform_impl/linux/wayland/window/mod.rs b/src/platform_impl/linux/wayland/window/mod.rs index 70ed02f921..7bd988547f 100644 --- a/src/platform_impl/linux/wayland/window/mod.rs +++ b/src/platform_impl/linux/wayland/window/mod.rs @@ -33,6 +33,7 @@ pub type WinitFrame = sctk_adwaita::AdwaitaFrame; #[cfg(not(feature = "sctk-adwaita"))] pub type WinitFrame = sctk::window::FallbackFrame; +#[cfg(feature = "sctk-adwaita")] const WAYLAND_CSD_THEME_ENV_VAR: &str = "WINIT_WAYLAND_CSD_THEME"; pub struct Window { @@ -148,24 +149,21 @@ impl Window { // Set CSD frame config #[cfg(feature = "sctk-adwaita")] - if let Some(theme) = platform_attributes.csd_theme { + { + let theme = platform_attributes.csd_theme.unwrap_or_else(|| { + let env = std::env::var(WAYLAND_CSD_THEME_ENV_VAR).unwrap_or_default(); + match env.to_lowercase().as_str() { + "dark" => Theme::Dark, + _ => Theme::Light, + } + }); + let config = match theme { Theme::Light => sctk_adwaita::FrameConfig::light(), Theme::Dark => sctk_adwaita::FrameConfig::dark(), }; + window.set_frame_config(config); - } else { - if let Ok(env) = std::env::var(WAYLAND_CSD_THEME_ENV_VAR) { - match env.to_lowercase().as_str() { - "dark" => { - window.set_frame_config(sctk_adwaita::FrameConfig::dark()); - } - "light" => { - window.set_frame_config(sctk_adwaita::FrameConfig::light()); - } - _ => {} - } - } } // Set decorations. From 7dbc420f88629c29488319ae6c9619f8551ada86 Mon Sep 17 00:00:00 2001 From: Poly Date: Fri, 20 May 2022 01:32:13 +0200 Subject: [PATCH 10/11] Fix CI --- .github/workflows/ci.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f62d3031d8..10eabd8f74 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,6 +42,7 @@ jobs: env: RUST_BACKTRACE: 1 CARGO_INCREMENTAL: 0 + PKG_CONFIG_ALLOW_CROSS: 1 RUSTFLAGS: "-C debuginfo=0 --deny warnings" OPTIONS: ${{ matrix.platform.options }} FEATURES: ${{ format(',{0}', matrix.platform.features ) }} @@ -62,12 +63,12 @@ jobs: rust-version: ${{ matrix.rust_version }}${{ matrix.platform.host }} targets: ${{ matrix.platform.target }} + - name: Install Linux dependencies + if: (matrix.platform.os == 'ubuntu-latest') + run: sudo apt-get update && sudo apt-get install pkg-config cmake libfreetype6-dev libfontconfig1-dev - name: Install GCC Multilib if: (matrix.platform.os == 'ubuntu-latest') && contains(matrix.platform.target, 'i686') - run: sudo apt-get update && sudo apt-get install gcc-multilib - - name: Install Freetype & FontConfig - if: matrix.platform.os == 'ubuntu-latest' - run: sudo apt-get update && sudo apt-get install pkg-config libfreetype6-dev libfontconfig1-dev cmake + run: sudo dpkg --add-architecture i386 && sudo apt-get update && sudo apt-get install g++-multilib gcc-multilib libfreetype6-dev:i386 libfontconfig1-dev:i386 - name: Install cargo-apk if: contains(matrix.platform.target, 'android') run: cargo install cargo-apk From c841d3d5dc5a4dcecd41ae05f170299ea0542c91 Mon Sep 17 00:00:00 2001 From: Poly Date: Fri, 20 May 2022 01:48:25 +0200 Subject: [PATCH 11/11] Apply the patch --- CHANGELOG.md | 2 +- src/platform_impl/linux/wayland/window/mod.rs | 17 +++++++++++------ src/platform_impl/linux/wayland/window/shim.rs | 6 +----- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eeea562954..c229c6f1fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,7 +39,7 @@ And please only add new entries to the top of this list, right below the `# Unre sent a cancel or frame event. - On iOS, send `RedrawEventsCleared` even if there are no redraw events, consistent with other platforms. - **Breaking:** Replaced `Window::with_app_id` and `Window::with_class` with `Window::with_name` on `WindowBuilderExtUnix`. -- On Wayland, fallback CSD was replaced with proper one; +- On Wayland, fallback CSD was replaced with proper one: - `WindowBuilderExtUnix::with_wayland_csd_theme` to set color theme in builder. - `WindowExtUnix::wayland_set_csd_theme` to set color theme when creating a window. - `WINIT_WAYLAND_CSD_THEME` env variable was added, it can be used to set "dark"/"light" theme in apps that don't expose theme setting. diff --git a/src/platform_impl/linux/wayland/window/mod.rs b/src/platform_impl/linux/wayland/window/mod.rs index 7bd988547f..601d9c8a1a 100644 --- a/src/platform_impl/linux/wayland/window/mod.rs +++ b/src/platform_impl/linux/wayland/window/mod.rs @@ -158,12 +158,7 @@ impl Window { } }); - let config = match theme { - Theme::Light => sctk_adwaita::FrameConfig::light(), - Theme::Dark => sctk_adwaita::FrameConfig::dark(), - }; - - window.set_frame_config(config); + window.set_frame_config(theme.into()); } // Set decorations. @@ -577,3 +572,13 @@ impl Drop for Window { self.send_request(WindowRequest::Close); } } + +#[cfg(feature = "sctk-adwaita")] +impl From for sctk_adwaita::FrameConfig { + fn from(theme: Theme) -> Self { + match theme { + Theme::Light => sctk_adwaita::FrameConfig::light(), + Theme::Dark => sctk_adwaita::FrameConfig::dark(), + } + } +} diff --git a/src/platform_impl/linux/wayland/window/shim.rs b/src/platform_impl/linux/wayland/window/shim.rs index b9defe0eb6..03d64e63d0 100644 --- a/src/platform_impl/linux/wayland/window/shim.rs +++ b/src/platform_impl/linux/wayland/window/shim.rs @@ -425,11 +425,7 @@ pub fn handle_window_requests(winit_state: &mut WinitState) { } #[cfg(feature = "sctk-adwaita")] WindowRequest::CsdThemeVariant(theme) => { - let config = match theme { - Theme::Light => sctk_adwaita::FrameConfig::light(), - Theme::Dark => sctk_adwaita::FrameConfig::dark(), - }; - window_handle.window.set_frame_config(config); + window_handle.window.set_frame_config(theme.into()); let window_update = window_updates.get_mut(window_id).unwrap(); window_update.refresh_frame = true;