Merge remote-tracking branch 'upstream/master' into yoda-wayland-only

# Conflicts:
#	Cargo.lock
#	Cargo.toml
#	wgpu/Cargo.toml
#	wgpu/src/window/compositor.rs
This commit is contained in:
Lionel DARNIS 2026-08-19 21:44:35 +02:00
commit d24bcd0272
36 changed files with 475 additions and 209 deletions

117
Cargo.lock generated
View file

@ -787,6 +787,13 @@ dependencies = [
"cfg_aliases",
]
[[package]]
name = "build_helpers"
version = "0.14.0"
dependencies = [
"cfg_aliases",
]
[[package]]
name = "built"
version = "0.8.0"
@ -1076,6 +1083,7 @@ dependencies = [
[[package]]
name = "clipboard_macos"
version = "0.1.0"
source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c"
dependencies = [
"objc",
"objc-foundation",
@ -1085,12 +1093,22 @@ dependencies = [
[[package]]
name = "clipboard_wayland"
version = "0.2.2"
source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c"
dependencies = [
"dnd",
"mime 0.1.0",
"smithay-clipboard",
]
[[package]]
name = "clipboard_x11"
version = "0.4.2"
source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c"
dependencies = [
"thiserror 1.0.69",
"x11rb",
]
[[package]]
name = "clock"
version = "0.1.0"
@ -1283,6 +1301,7 @@ dependencies = [
[[package]]
name = "cosmic-client-toolkit"
version = "0.2.0"
source = "git+https://github.com/pop-os/cosmic-protocols?rev=32283d7#32283d76a8d0342da74c4cc022a533c52dcf378f"
dependencies = [
"bitflags 2.11.0",
"cosmic-protocols",
@ -1295,6 +1314,7 @@ dependencies = [
[[package]]
name = "cosmic-protocols"
version = "0.2.0"
source = "git+https://github.com/pop-os/cosmic-protocols?rev=32283d7#32283d76a8d0342da74c4cc022a533c52dcf378f"
dependencies = [
"bitflags 2.11.0",
"wayland-backend",
@ -1308,6 +1328,8 @@ dependencies = [
[[package]]
name = "cosmic-text"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be17b688510d934ce13f48a2beba700e11583e281e0fda99c22bb256a14eda73"
dependencies = [
"bitflags 2.11.0",
"fontdb",
@ -1325,7 +1347,6 @@ dependencies = [
"unicode-linebreak",
"unicode-script",
"unicode-segmentation",
"unicode-width",
]
[[package]]
@ -1432,6 +1453,7 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
[[package]]
name = "cryoglyph"
version = "0.1.0"
source = "git+https://github.com/iced-rs/cryoglyph.git?rev=e429a025df36ab8145708acb309080ae3deec17a#e429a025df36ab8145708acb309080ae3deec17a"
dependencies = [
"cosmic-text",
"etagere",
@ -1608,6 +1630,7 @@ dependencies = [
[[package]]
name = "dnd"
version = "0.1.0"
source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c"
dependencies = [
"bitflags 2.11.0",
"mime 0.1.0",
@ -1642,6 +1665,30 @@ dependencies = [
[[package]]
name = "dpi"
version = "0.1.2"
source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366"
[[package]]
name = "drm"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0f8a69e60d75ae7dab4ef26a59ca99f2a89d4c142089b537775ae0c198bdcde"
dependencies = [
"bitflags 2.11.0",
"bytemuck",
"drm-ffi",
"drm-fourcc",
"rustix 0.38.44",
]
[[package]]
name = "drm-ffi"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41334f8405792483e32ad05fbb9c5680ff4e84491883d2947a4757dc54cb2ac6"
dependencies = [
"drm-sys",
"rustix 0.38.44",
]
[[package]]
name = "drm-fourcc"
@ -1649,6 +1696,16 @@ version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0aafbcdb8afc29c1a7ee5fbe53b5d62f4565b35a042a662ca9fecd0b54dae6f4"
[[package]]
name = "drm-sys"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d09ff881f92f118b11105ba5e34ff8f4adf27b30dae8f12e28c193af1c83176"
dependencies = [
"libc",
"linux-raw-sys 0.6.5",
]
[[package]]
name = "editor"
version = "0.1.0"
@ -2371,7 +2428,7 @@ dependencies = [
"log",
"presser",
"thiserror 2.0.18",
"windows 0.62.2",
"windows 0.57.0",
]
[[package]]
@ -2907,6 +2964,7 @@ dependencies = [
name = "iced"
version = "0.14.0"
dependencies = [
"build_helpers",
"criterion",
"dnd",
"iced_accessibility",
@ -2958,6 +3016,7 @@ version = "0.14.0"
dependencies = [
"approx",
"bitflags 2.11.0",
"build_helpers",
"bytes",
"cosmic-client-toolkit",
"dnd",
@ -3064,6 +3123,7 @@ dependencies = [
name = "iced_runtime"
version = "0.14.0"
dependencies = [
"build_helpers",
"bytes",
"cosmic-client-toolkit",
"dnd",
@ -3131,6 +3191,7 @@ version = "0.14.0"
dependencies = [
"as-raw-xcb-connection",
"bitflags 2.11.0",
"build_helpers",
"bytemuck",
"cosmic-client-toolkit",
"cryoglyph",
@ -3145,6 +3206,7 @@ dependencies = [
"resvg",
"rustc-hash 2.1.2",
"rustix 0.38.44",
"smithay-client-toolkit 0.20.0",
"thiserror 2.0.18",
"tiny-xlib",
"wayland-backend",
@ -3159,6 +3221,7 @@ dependencies = [
name = "iced_widget"
version = "0.14.2"
dependencies = [
"build_helpers",
"cosmic-client-toolkit",
"dnd",
"iced_accessibility",
@ -3180,6 +3243,7 @@ dependencies = [
name = "iced_winit"
version = "0.14.0"
dependencies = [
"build_helpers",
"cosmic-client-toolkit",
"cursor-icon",
"dnd",
@ -3736,14 +3800,14 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
[[package]]
name = "libredox"
version = "0.1.18"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c943259e342f1e06ff2da7a83eabdfe7f92ce10262688dbf1895ff0b3e6e4652"
checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c"
dependencies = [
"bitflags 2.11.0",
"libc",
"plain",
"redox_syscall 0.9.0",
"redox_syscall 0.7.4",
]
[[package]]
@ -3773,6 +3837,12 @@ version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
[[package]]
name = "linux-raw-sys"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a385b1be4e5c3e362ad2ffa73c392e53f031eaa5b7d648e64cd87f27f6063d7"
[[package]]
name = "linux-raw-sys"
version = "0.12.1"
@ -3998,6 +4068,7 @@ dependencies = [
[[package]]
name = "mime"
version = "0.1.0"
source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c"
dependencies = [
"smithay-clipboard",
]
@ -5423,16 +5494,6 @@ dependencies = [
"font-types",
]
[[package]]
name = "redox_event"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5018d583d6d2f5499352aea8d177e9067d1eb03ab17c78169d5ba7a30001b15"
dependencies = [
"bitflags 2.11.0",
"libredox",
]
[[package]]
name = "redox_syscall"
version = "0.5.18"
@ -5444,9 +5505,9 @@ dependencies = [
[[package]]
name = "redox_syscall"
version = "0.9.0"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5102a6aaa05aa011a238e178e6bca86d2cb56fc9f586d37cb80f5bca6e07759"
checksum = "f450ad9c3b1da563fb6948a8e0fb0fb9269711c9c73d9ea1de5058c79c8d643a"
dependencies = [
"bitflags 2.11.0",
]
@ -6228,6 +6289,7 @@ dependencies = [
[[package]]
name = "smithay-clipboard"
version = "0.8.0"
source = "git+https://github.com/pop-os/smithay-clipboard?tag=sctk-0.20#859b02c88f45c554049a67c6ddeec1692ce0e20b"
dependencies = [
"libc",
"raw-window-handle",
@ -6285,12 +6347,14 @@ dependencies = [
[[package]]
name = "softbuffer"
version = "0.4.1"
source = "git+https://github.com/pop-os/softbuffer?tag=cosmic-4.0#a3f77e251e7422803f693df6e3fc313c010c4dcb"
dependencies = [
"as-raw-xcb-connection",
"bytemuck",
"cfg_aliases",
"cocoa",
"core-graphics",
"drm",
"fastrand",
"foreign-types 0.5.0",
"js-sys",
@ -7958,10 +8022,12 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "window_clipboard"
version = "0.4.1"
source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c"
dependencies = [
"clipboard-win",
"clipboard_macos",
"clipboard_wayland",
"clipboard_x11",
"dnd",
"mime 0.1.0",
"raw-window-handle",
@ -8465,6 +8531,7 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
[[package]]
name = "winit"
version = "0.31.0-beta.2"
source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366"
dependencies = [
"bitflags 2.11.0",
"cfg_aliases",
@ -8490,6 +8557,7 @@ dependencies = [
[[package]]
name = "winit-android"
version = "0.31.0-beta.2"
source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366"
dependencies = [
"android-activity",
"bitflags 2.11.0",
@ -8504,6 +8572,7 @@ dependencies = [
[[package]]
name = "winit-appkit"
version = "0.31.0-beta.2"
source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366"
dependencies = [
"bitflags 2.11.0",
"block2 0.6.2",
@ -8525,6 +8594,7 @@ dependencies = [
[[package]]
name = "winit-common"
version = "0.31.0-beta.2"
source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366"
dependencies = [
"memmap2 0.9.10",
"objc2 0.6.4",
@ -8539,6 +8609,7 @@ dependencies = [
[[package]]
name = "winit-core"
version = "0.31.0-beta.2"
source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366"
dependencies = [
"bitflags 2.11.0",
"cursor-icon",
@ -8552,13 +8623,14 @@ dependencies = [
[[package]]
name = "winit-orbital"
version = "0.31.0-beta.2"
source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366"
dependencies = [
"bitflags 2.11.0",
"dpi",
"libredox",
"orbclient",
"raw-window-handle",
"redox_event",
"redox_syscall 0.7.4",
"smol_str",
"tracing",
"winit-core",
@ -8567,6 +8639,7 @@ dependencies = [
[[package]]
name = "winit-uikit"
version = "0.31.0-beta.2"
source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366"
dependencies = [
"bitflags 2.11.0",
"block2 0.6.2",
@ -8586,6 +8659,7 @@ dependencies = [
[[package]]
name = "winit-wayland"
version = "0.31.0-beta.2"
source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366"
dependencies = [
"ahash",
"bitflags 2.11.0",
@ -8611,6 +8685,7 @@ dependencies = [
[[package]]
name = "winit-web"
version = "0.31.0-beta.2"
source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366"
dependencies = [
"atomic-waker",
"bitflags 2.11.0",
@ -8632,6 +8707,7 @@ dependencies = [
[[package]]
name = "winit-win32"
version = "0.31.0-beta.2"
source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366"
dependencies = [
"bitflags 2.11.0",
"cursor-icon",
@ -8647,6 +8723,7 @@ dependencies = [
[[package]]
name = "winit-x11"
version = "0.31.0-beta.2"
source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366"
dependencies = [
"bitflags 2.11.0",
"bytemuck",
@ -9191,7 +9268,3 @@ dependencies = [
"syn",
"winnow 0.7.15",
]
[[patch.unused]]
name = "cosmic-freedesktop-icons"
version = "0.4.0"

View file

@ -118,13 +118,17 @@ winit = [
"iced_accessibility?/accesskit_winit",
"iced_program/winit",
]
wayland = ["iced_renderer/wayland", "iced_winit/wayland"]
cctk = ["iced_winit/cctk", "iced_widget/cctk", "iced_core/cctk", "wayland"]
# Enables the sctk shell.
wayland = [
"iced_renderer/wayland",
"iced_winit/wayland",
"iced_runtime/wayland",
"iced_widget/wayland",
"iced_core/wayland",
]
[dependencies]
iced_devtools.workspace = true
iced_devtools.optional = true
iced_debug.workspace = true
iced_program.workspace = true
@ -134,10 +138,9 @@ iced_renderer.workspace = true
iced_runtime.workspace = true
iced_widget.workspace = true
iced_winit.workspace = true
iced_devtools.optional = true
iced_winit.optional = true
iced_tester.workspace = true
iced_tester.optional = true
iced_winit.optional = true
iced_highlighter.workspace = true
iced_highlighter.optional = true
iced_accessibility.workspace = true
@ -190,6 +193,7 @@ members = [
"winit",
"examples/*",
"accessibility",
"build_helpers",
]
exclude = ["examples/integration"]
@ -363,3 +367,6 @@ useless_conversion = "deny"
[workspace.lints.rustdoc]
broken_intra_doc_links = "forbid"
[build-dependencies]
build_helpers = { path = "./build_helpers" }

3
build.rs Normal file
View file

@ -0,0 +1,3 @@
fn main() {
build_helpers::cfg_aliases_setup();
}

17
build_helpers/Cargo.toml Normal file
View file

@ -0,0 +1,17 @@
[package]
name = "build_helpers"
version.workspace = true
authors.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
homepage.workspace = true
categories.workspace = true
keywords.workspace = true
rust-version.workspace = true
[dependencies]
cfg_aliases = { version = "0.2.1" }
[lints]
workspace = true

24
build_helpers/src/lib.rs Normal file
View file

@ -0,0 +1,24 @@
use cfg_aliases::cfg_aliases;
pub fn cfg_aliases_setup() {
// The script doesn't depend on our code
println!("cargo:rerun-if-changed=build.rs");
// Setup cfg aliases
cfg_aliases! {
// Systems.
android_platform: { target_os = "android" },
wasm_platform: { all(target_family = "wasm", not(target_os = "emscripten")) },
macos_platform: { target_os = "macos" },
ios_platform: { target_os = "ios" },
windows_platform: { target_os = "windows" },
apple: { any(target_os = "ios", target_os = "macos") },
free_unix: { all(unix, not(apple), not(android_platform), not(target_os = "emscripten")) },
redox: { target_os = "redox" },
// Native displays.
wayland_platform: { all(feature = "wayland", free_unix, not(wasm), not(redox)) },
xdg_portal: { all(feature = "xdg-portal", free_unix, not(wasm), not(redox)) },
orbital_platform: { redox },
}
}

View file

@ -19,6 +19,7 @@ crisp = []
basic-shaping = []
advanced-shaping = []
a11y = ["iced_accessibility"]
wayland = ["cctk"]
[dependencies]
palette = "0.7"
@ -43,8 +44,6 @@ window_clipboard.workspace = true
dnd.workspace = true
mime.workspace = true
cctk.workspace = true
cctk.optional = true
# /TODO(POP)
[dependencies.iced_accessibility]
version = "0.1.0"
@ -56,3 +55,10 @@ raw-window-handle.workspace = true
[dev-dependencies]
approx = "0.5"
[target.'cfg(all(unix, not(any(target_os = "redox", target_family = "wasm", target_os = "android", target_vendor = "apple"))))'.dependencies]
cctk.workspace = true
cctk.optional = true
[build-dependencies]
build_helpers = { path = "../build_helpers" }

3
core/build.rs Normal file
View file

@ -0,0 +1,3 @@
fn main() {
build_helpers::cfg_aliases_setup();
}

View file

@ -7,7 +7,8 @@ use crate::keyboard;
use crate::mouse;
use crate::touch;
use crate::window;
#[cfg(all(feature = "cctk", target_os = "linux"))]
#[cfg(wayland_platform)]
/// A platform specific event for wayland
pub mod wayland;
/// A user interface event.
@ -49,7 +50,7 @@ pub enum Event {
/// A platform specific event
#[derive(Debug, Clone, PartialEq)]
pub enum PlatformSpecific {
#[cfg(all(feature = "cctk", target_os = "linux"))]
#[cfg(wayland_platform)]
/// A Wayland specific event
Wayland(wayland::Event),
}

View file

@ -446,11 +446,22 @@ where
| Event::Touch(touch::Event::FingerPressed { .. })
) {
if cursor.position_over(bounds).is_none() {
let was_visible = state.focused
|| state.keyboard_focused
|| state
.selection
.as_ref()
.is_some_and(|sel| sel.anchor != sel.end);
state.focused = false;
state.keyboard_focused = false;
if let Some(sel) = &mut state.selection {
sel.clear();
}
if was_visible {
shell.request_redraw();
}
}
}
@ -511,6 +522,7 @@ where
state.focused = true;
state.keyboard_focused = false;
shell.capture_event();
shell.request_redraw();
}
}
@ -520,6 +532,7 @@ where
state.focused = true;
state.keyboard_focused = false;
shell.capture_event();
shell.request_redraw();
}
}
@ -544,7 +557,15 @@ where
position.y - anchor.y,
);
sel.end = hit_to_grapheme(paragraph, relative, content);
let end = hit_to_grapheme(paragraph, relative, content);
// Only the drag reaching a new grapheme changes what
// is drawn; plain motion inside one does not.
if end != sel.end {
sel.end = end;
shell.request_redraw();
}
shell.capture_event();
}
}
@ -587,6 +608,7 @@ where
sel.anchor = 0;
sel.end = grapheme_count;
shell.capture_event();
shell.request_redraw();
return;
}
_ => {}
@ -613,6 +635,7 @@ where
sel.end = pos;
}
shell.capture_event();
shell.request_redraw();
}
keyboard::Key::Named(keyboard::key::Named::ArrowRight) => {
let by_word = is_jump_modifier(*modifiers);
@ -633,6 +656,7 @@ where
sel.end = pos;
}
shell.capture_event();
shell.request_redraw();
}
keyboard::Key::Named(keyboard::key::Named::Home) => {
if modifiers.shift() {
@ -642,6 +666,7 @@ where
sel.end = 0;
}
shell.capture_event();
shell.request_redraw();
}
keyboard::Key::Named(keyboard::key::Named::End) => {
if modifiers.shift() {
@ -651,6 +676,7 @@ where
sel.end = grapheme_count;
}
shell.capture_event();
shell.request_redraw();
}
_ => {}
}

View file

@ -83,13 +83,20 @@ impl<T: Layer> Stack<T> {
/// Pushes a new clipping region in the [`Stack`]; creating a new layer in the
/// process.
pub fn push_clip(&mut self, bounds: Rectangle) {
let bounds = bounds * self.transformation();
let bounds = bounds
.intersection(&self.layers[self.current].bounds())
.unwrap_or(Rectangle {
width: 0.0,
height: 0.0,
..bounds
});
self.previous.push(self.current);
self.current = self.active_count;
self.active_count += 1;
let bounds = bounds * self.transformation();
if self.current == self.layers.len() {
self.layers.push(T::with_bounds(bounds));
} else {

View file

@ -17,7 +17,7 @@ workspace = true
debug = []
selector = ["dep:iced_selector"]
a11y = ["iced_accessibility", "iced_core/a11y"]
cctk = ["iced_core/cctk", "dep:cctk"]
wayland = ["iced_core/wayland", "dep:cctk"]
[dependencies]
bytes.workspace = true
@ -33,9 +33,14 @@ sipper.optional = true
iced_selector.workspace = true
iced_selector.optional = true
iced_futures.features = ["thread-pool"]
cctk.workspace = true
cctk.optional = true
iced_accessibility.workspace = true
iced_accessibility.optional = true
window_clipboard.workspace = true
dnd.workspace = true
[target.'cfg(all(unix, not(any(target_os = "redox", target_family = "wasm", target_os = "android", target_vendor = "apple"))))'.dependencies]
cctk.workspace = true
cctk.optional = true
[build-dependencies]
build_helpers = { path = "../build_helpers" }

3
runtime/build.rs Normal file
View file

@ -0,0 +1,3 @@
fn main() {
build_helpers::cfg_aliases_setup();
}

View file

@ -2,23 +2,23 @@
use std::fmt;
#[cfg(all(feature = "cctk", target_os = "linux"))]
#[cfg(wayland_platform)]
/// Platform specific actions defined for wayland
pub mod wayland;
/// Platform specific actions defined for wayland
pub enum Action {
/// Wayland Specific Actions
#[cfg(all(feature = "cctk", target_os = "linux"))]
#[cfg(wayland_platform)]
Wayland(wayland::Action),
}
impl fmt::Debug for Action {
fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
#[cfg(all(feature = "cctk", target_os = "linux"))]
#[cfg(wayland_platform)]
Action::Wayland(action) => action.fmt(_f),
#[cfg(not(all(feature = "cctk", target_os = "linux")))]
#[cfg(not(wayland_platform))]
_ => Ok(()),
}
}

View file

@ -222,7 +222,7 @@ pub fn frames() -> Subscription<(Id, Instant)> {
_ => None,
})
}
#[cfg(all(feature = "cctk", target_os = "linux"))]
#[cfg(wayland_platform)]
/// Subscribes to the frames of the window of the running application.
///
/// The resulting [`Subscription`] will produce items at a rate equal to the

View file

@ -606,7 +606,7 @@ pub mod font {
pub mod event {
//! Handle events of a user interface.
pub use crate::core::event::PlatformSpecific;
#[cfg(all(feature = "cctk", target_os = "linux"))]
#[cfg(wayland_platform)]
pub use crate::core::event::wayland;
pub use crate::core::event::{Event, Status};
pub use iced_futures::event::{listen, listen_raw, listen_with};

View file

@ -263,6 +263,10 @@ impl Engine {
} else {
// Draw corners that have too small border radii as having no border radius,
// but mask them with the rounded rectangle with the correct border radius.
if path_bounds.width < 1.0 || path_bounds.height < 1.0 {
return;
}
let mut temp_pixmap = tiny_skia::Pixmap::new(
path_bounds.width as u32,
path_bounds.height as u32,

View file

@ -30,6 +30,7 @@ strict-assertions = []
# builds just leave this off — window/x11.rs and the DRI3 device-id
# fallback in window/compositor.rs are cfg-gated on it.
x11 = ["dep:as-raw-xcb-connection", "dep:tiny-xlib", "dep:x11rb"]
wayland = ["cctk"]
[dependencies]
iced_debug.workspace = true
@ -70,3 +71,6 @@ x11rb = { version = "0.13.1", optional = true, features = [
"dri3",
"randr",
] }
[build-dependencies]
build_helpers = { path = "../build_helpers" }

3
wgpu/build.rs Normal file
View file

@ -0,0 +1,3 @@
fn main() {
build_helpers::cfg_aliases_setup();
}

View file

@ -1,11 +1,6 @@
//! Display rendering results on windows.
pub mod compositor;
#[cfg(all(
unix,
feature = "cctk",
not(target_os = "macos"),
not(target_os = "redox")
))]
#[cfg(wayland_platform)]
mod wayland;
#[cfg(all(unix, feature = "x11", not(target_os = "macos"), not(target_os = "redox")))]
mod x11;

View file

@ -9,16 +9,10 @@ use crate::graphics::{self, Shell, Viewport};
use crate::settings::{self, Settings};
use crate::{Engine, Renderer};
#[cfg(all(
unix,
feature = "cctk",
not(target_os = "macos"),
not(target_os = "redox")
))]
#[cfg(wayland_platform)]
use super::wayland::get_wayland_device_ids;
#[cfg(all(unix, feature = "x11", not(target_os = "macos"), not(target_os = "redox")))]
use super::x11::get_x11_device_ids;
use std::future::Future;
/// A window graphics backend for iced powered by `wgpu`.
pub struct Compositor {
@ -65,12 +59,7 @@ impl Compositor {
compatible_window: Option<W>,
shell: Shell,
) -> Result<Self, Error> {
#[cfg(all(
unix,
feature = "cctk",
not(target_os = "macos"),
not(target_os = "redox")
))]
#[cfg(wayland_platform)]
let ids = compatible_window.as_ref().and_then(|window| {
let w = get_wayland_device_ids(window);
#[cfg(feature = "x11")]
@ -78,23 +67,13 @@ impl Compositor {
w
});
#[cfg(all(
unix,
not(feature = "cctk"),
not(target_os = "macos"),
not(target_os = "redox")
))]
let ids = compatible_window
.as_ref()
.and_then(|window| get_x11_device_ids(window));
// HACK:
// 1. If we specifically didn't select an nvidia gpu
// 2. and the user didn't specifically request an nvidia gpu
// 3. and the user didn't set an adapter name,
// 4. and the user didn't request the high power pref
// => don't load the nvidia icd, as it might power on the gpu in hybrid setups causing severe delays
#[cfg(all(unix, not(target_os = "macos"), not(target_os = "redox")))]
#[cfg(wayland_platform)]
if !matches!(ids, Some((0x10de, _)))
&& std::env::var_os("__NV_PRIME_RENDER_OFFLOAD")
.is_none_or(|var| var == "0")
@ -154,11 +133,7 @@ impl Compositor {
let mut adapter = None;
#[cfg_attr(not(unix), allow(dead_code))]
if std::env::var_os("WGPU_ADAPTER_NAME").is_none() {
#[cfg(all(
unix,
not(target_os = "macos"),
not(target_os = "redox")
))]
#[cfg(wayland_platform)]
if let Some((vendor_id, device_id)) = ids {
adapter = instance
.enumerate_adapters(settings.backends)

View file

@ -1,3 +1,5 @@
#![allow(unexpected_cfgs)]
use std::{
fs,
io::{BufRead, BufReader},
@ -144,7 +146,9 @@ pub fn get_x11_device_ids<W: Window>(window: &W) -> Option<(u16, u16)> {
{
let stat =
stat(Path::new("/dev/dri").join(device)).ok()?;
let dev = stat.st_rdev;
// Hack (u64 as u64) for E2K CPU architecture
#[allow(clippy::unnecessary_cast)]
let dev = stat.st_rdev as u64;
return super::ids_from_dev(dev);
}
}
@ -165,7 +169,9 @@ pub fn get_x11_device_ids<W: Window>(window: &W) -> Option<(u16, u16)> {
let dri3 = conn.dri3_open(root, x11rb::NONE).ok()?.reply().ok()?;
let device_fd = dri3.device_fd;
let stat = fstat(device_fd).ok()?;
let dev = stat.st_rdev;
// Hack (u64 as u64) for E2K CPU architecture
#[allow(clippy::unnecessary_cast)]
let dev = stat.st_rdev as u64;
super::ids_from_dev(dev)
}
}

View file

@ -29,15 +29,13 @@ highlighter = ["dep:iced_highlighter"]
advanced = []
crisp = []
a11y = ["iced_accessibility"]
cctk = ["iced_runtime/cctk", "dep:cctk"]
wayland = ["iced_runtime/wayland", "dep:cctk"]
[dependencies]
iced_renderer.workspace = true
iced_runtime.workspace = true
iced_accessibility.workspace = true
iced_accessibility.optional = true
cctk.workspace = true
cctk.optional = true
num-traits.workspace = true
log.workspace = true
rustc-hash.workspace = true
@ -57,3 +55,10 @@ pulldown-cmark.optional = true
iced_highlighter.workspace = true
iced_highlighter.optional = true
[target.'cfg(all(unix, not(any(target_os = "redox", target_family = "wasm", target_os = "android", target_vendor = "apple"))))'.dependencies]
cctk.workspace = true
cctk.optional = true
[build-dependencies]
build_helpers = { path = "../build_helpers" }

3
widget/build.rs Normal file
View file

@ -0,0 +1,3 @@
fn main() {
build_helpers::cfg_aliases_setup();
}

View file

@ -60,6 +60,7 @@ where
width: Length,
height: Length,
position: Point,
overflow: bool,
}
impl<'a, Message, Theme, Renderer> Pin<'a, Message, Theme, Renderer>
@ -75,6 +76,7 @@ where
width: Length::Fill,
height: Length::Fill,
position: Point::ORIGIN,
overflow: false,
}
}
@ -107,6 +109,12 @@ where
self.position.y = y.into().0;
self
}
/// Sets whether the [`Pin`] can overflow its boundaries.
pub fn overflow(mut self, overflow: bool) -> Self {
self.overflow = overflow;
self
}
}
impl<Message, Theme, Renderer> Widget<Message, Theme, Renderer>
@ -145,8 +153,12 @@ where
) -> layout::Node {
let limits = limits.width(self.width).height(self.height);
let available =
limits.max() - Size::new(self.position.x, self.position.y);
let available =
if self.overflow {
limits.max()
} else {
limits.max() - Size::new(self.position.x, self.position.y)
};
let node = self
.content

View file

@ -110,6 +110,8 @@ where
height: f32,
class: Theme::Class<'a>,
status: Option<Status>,
handle_width: f32,
handle_height: f32,
}
impl<'a, T, Message, Theme> Slider<'a, T, Message, Theme>
@ -119,7 +121,13 @@ where
Theme: Catalog,
{
/// The default height of a [`Slider`].
pub const DEFAULT_HEIGHT: f32 = 16.0;
pub const DEFAULT_HEIGHT: f32 = 26.0;
/// The default max height of a [`Handle`].
pub const DEFAULT_MAX_HANDLE_HEIGHT: f32 = 26.0;
/// The default max width of a [`Handle`].
pub const DEFAULT_MAX_HANDLE_WIDTH: f32 = 26.0;
/// Creates a new [`Slider`].
///
@ -165,6 +173,8 @@ where
height: Self::DEFAULT_HEIGHT,
class: Theme::default(),
status: None,
handle_width: Self::DEFAULT_MAX_HANDLE_WIDTH,
handle_height: Self::DEFAULT_MAX_HANDLE_HEIGHT,
}
}
@ -207,6 +217,24 @@ where
self
}
/// Sets the max width of the [`Handle`].
///
/// Theme can be used to change the size and shape of handle
/// but width of handle defined in theme will not exceed this width
pub fn handle_width(mut self, width: impl Into<Pixels>) -> Self {
self.handle_width = width.into().0;
self
}
/// Sets the max height of the [`Handle`].
///
/// Theme can be used to change the size and shape of handle
/// but height of handle defined in theme will not exceed this height
pub fn handle_height(mut self, height: impl Into<Pixels>) -> Self {
self.handle_height = height.into().0;
self
}
/// Sets the step size of the [`Slider`].
pub fn step(mut self, step: impl Into<T>) -> Self {
self.step = step.into();
@ -323,8 +351,15 @@ where
let mut update = || {
let current_value = self.value;
self.handle_width = self.handle_width.min(layout.bounds().width);
self.handle_height = self.handle_height.min(layout.bounds().height);
let locate = |cursor_position: Point| -> Option<T> {
let bounds = layout.bounds();
let bounds = Rectangle {
x: layout.bounds().x + self.handle_width / 2.0,
width: layout.bounds().width - self.handle_width,
..layout.bounds()
};
if cursor_position.x <= bounds.x {
Some(*self.range.start())
@ -509,54 +544,30 @@ where
_cursor: mouse::Cursor,
_viewport: &Rectangle,
) {
let bounds = layout.bounds();
let bounds = Rectangle {
x: layout.bounds().x + self.handle_width / 2.0,
width: layout.bounds().width - self.handle_width,
..layout.bounds()
};
let style =
theme.style(&self.class, self.status.unwrap_or(Status::Active));
let border_width = style
.handle
.border_width
.min(bounds.height / 2.0)
.min(bounds.width / 2.0);
let (handle_width, handle_height, handle_border_radius) =
let (mut handle_width, mut handle_height, handle_border_radius) =
match style.handle.shape {
HandleShape::Circle { radius } => {
let radius = (radius)
.max(2.0 * border_width)
.min(bounds.height / 2.0)
.min(bounds.width / 2.0 + 2.0 * border_width);
(radius * 2.0, radius * 2.0, Radius::from(radius))
}
HandleShape::Rectangle {
height,
width,
border_radius,
} => {
let width = (f32::from(width)).max(2.0 * border_width);
let height = (f32::from(height)).max(2.0 * border_width);
let mut border_radius: [f32; 4] = border_radius.into();
for r in &mut border_radius {
*r = (*r)
.min(height / 2.0)
.min(width / 2.0)
.max(*r * (width + border_width * 2.0) / width);
}
(
width,
height,
Radius {
top_left: border_radius[0],
top_right: border_radius[1],
bottom_right: border_radius[2],
bottom_left: border_radius[3],
},
)
}
} => (f32::from(width), f32::from(height), border_radius),
};
handle_width = handle_width.min(self.handle_width);
handle_height = handle_height.min(self.handle_height);
let value = self.value.into() as f32;
let (range_start, range_end) = {
let (start, end) = self.range.clone().into_inner();
@ -567,8 +578,7 @@ where
let offset = if range_start >= range_end {
0.0
} else {
(bounds.width - handle_width) * (value - range_start)
/ (range_end - range_start)
bounds.width * (value - range_start) / (range_end - range_start)
};
let rail_y = bounds.y + bounds.height / 2.0;
@ -590,7 +600,8 @@ where
x: bounds.x + offset,
y: rail_y + 6.0,
width: BREAKPOINT_WIDTH,
height: 8.0,
height: 8.0_f32
.min(bounds.y + bounds.height - (rail_y + 6.0)),
},
border: Border {
radius: 0.0.into(),
@ -607,9 +618,9 @@ where
renderer::Quad {
bounds: Rectangle {
x: bounds.x,
y: rail_y - style.rail.width / 2.0,
width: offset + handle_width / 2.0,
height: style.rail.width,
y: rail_y - (style.rail.width).min(bounds.height) / 2.0,
width: offset,
height: (style.rail.width).min(bounds.height),
},
border: style.rail.border,
..renderer::Quad::default()
@ -622,10 +633,10 @@ where
renderer.fill_quad(
renderer::Quad {
bounds: Rectangle {
x: bounds.x + offset + handle_width / 2.0,
y: rail_y - style.rail.width / 2.0,
width: bounds.width - offset - handle_width / 2.0,
height: style.rail.width,
x: bounds.x + offset,
y: rail_y - (style.rail.width).min(bounds.height) / 2.0,
width: bounds.width - offset,
height: (style.rail.width).min(bounds.height),
},
border: style.rail.border,
..renderer::Quad::default()
@ -637,7 +648,7 @@ where
renderer.fill_quad(
renderer::Quad {
bounds: Rectangle {
x: bounds.x + offset,
x: bounds.x + offset - handle_width / 2.0,
y: rail_y - (handle_height / 2.0),
width: handle_width,
height: handle_height,

View file

@ -14,7 +14,18 @@ keywords.workspace = true
workspace = true
[features]
wayland = ["winit/wayland", "wayland-csd-adwaita"]
wayland = [
"winit/wayland",
"wayland-csd-adwaita",
"wayland-protocols",
"raw-window-handle",
"iced_runtime/wayland",
"wayland-backend",
"xkbcommon",
"xkbcommon-dl",
"xkeysym",
"dep:cctk",
]
default = ["x11", "wayland-dlopen"]
debug = ["iced_debug/enable"]
sysinfo = ["dep:sysinfo"]
@ -26,17 +37,6 @@ program = []
wayland-dlopen = ["winit/wayland-dlopen"]
wayland-csd-adwaita = ["winit/wayland-csd-adwaita"]
a11y = ["iced_accessibility", "iced_runtime/a11y"]
cctk = [
"wayland",
"wayland-protocols",
"raw-window-handle",
"iced_runtime/cctk",
"wayland-backend",
"xkbcommon",
"xkbcommon-dl",
"xkeysym",
"dep:cctk",
]
# Prevents multiple separate process instances.
single-instance = []
@ -64,7 +64,8 @@ iced_debug.workspace = true
iced_program.workspace = true
[target.'cfg(target_os = "linux")'.dependencies]
[target.'cfg(all(unix, not(any(target_os = "redox", target_family = "wasm", target_os = "android", target_vendor = "apple"))))'.dependencies]
mundy.workspace = true
mundy.optional = true
@ -89,3 +90,6 @@ winapi.workspace = true
web-sys.workspace = true
web-sys.features = ["Document", "Window", "HtmlCanvasElement"]
wasm-bindgen-futures.workspace = true
[build-dependencies]
build_helpers = { path = "../build_helpers" }

3
winit/build.rs Normal file
View file

@ -0,0 +1,3 @@
fn main() {
build_helpers::cfg_aliases_setup();
}

View file

@ -49,7 +49,10 @@ pub fn event_func(
position,
..
} => {
if !window.is_decorated() {
let resizable = !window.is_decorated()
&& !window.is_maximized()
&& window.fullscreen().is_none();
if resizable {
let location = cursor_resize_direction(
window.surface_size(),
*position,

View file

@ -92,7 +92,7 @@ impl Clipboard {
})
.unwrap_or(State::Unavailable);
#[cfg(target_os = "linux")]
#[cfg(wayland_platform)]
if let State::Connected { clipboard, .. } = &state {
clipboard.init_dnd(Box::new(sender));
}

View file

@ -23,6 +23,33 @@ use winit::event::Force;
use winit::icon::IconProvider;
use winit::keyboard::SmolStr;
/// Returns the activation token provided by the compositor, if any.
///
/// The token is single-use, so it is only ever handed out to the first window.
#[cfg(target_os = "linux")]
fn take_activation_token() -> Option<winit::window::ActivationToken> {
use std::sync::Mutex;
use std::sync::OnceLock;
use winit::platform::startup_notify::reset_activation_token_env;
static TOKEN: OnceLock<Mutex<Option<winit::window::ActivationToken>>> =
OnceLock::new();
TOKEN
.get_or_init(|| {
let token = std::env::var("XDG_ACTIVATION_TOKEN")
.ok()
.map(winit::window::ActivationToken::from_raw);
reset_activation_token_env();
Mutex::new(token)
})
.lock()
.ok()
.and_then(|mut token| token.take())
}
/// Converts some [`window::Settings`] into some `WindowAttributes` from `winit`.
pub fn window_attributes(
settings: window::Settings,
@ -182,12 +209,19 @@ pub fn window_attributes(
{
use winit::platform::wayland::WindowAttributesWayland;
attributes = attributes.with_platform_attributes(Box::new(
WindowAttributesWayland::default().with_name(
let mut wayland_attributes = WindowAttributesWayland::default()
.with_name(
&settings.platform_specific.application_id,
&settings.platform_specific.application_id,
),
));
);
if let Some(token) = take_activation_token() {
wayland_attributes =
wayland_attributes.with_activation_token(token);
}
attributes = attributes
.with_platform_attributes(Box::new(wayland_attributes));
}
}
@ -424,7 +458,7 @@ pub fn window_event(
WindowEvent::ScaleFactorChanged { scale_factor, .. } => {
Some(Event::Window(window::Event::Rescaled(scale_factor as f32)))
}
#[cfg(all(feature = "cctk", target_os = "linux"))]
#[cfg(wayland_platform)]
WindowEvent::SuggestedBounds(bounds) => {
let size = bounds.map(|bounds| {
let size = bounds.to_logical(scale_factor);
@ -437,7 +471,7 @@ pub fn window_event(
),
)))
}
#[cfg(all(feature = "cctk", target_os = "linux"))]
#[cfg(wayland_platform)]
WindowEvent::WindowStateChanged => {
use cctk::sctk::reexports::csd_frame::WindowState;
use winit::platform::wayland::WindowExtWayland;
@ -1491,7 +1525,7 @@ pub fn winit_key_code(
})
}
#[cfg(all(feature = "cctk", target_os = "linux"))]
#[cfg(wayland_platform)]
fn winit_native_key_code(
keycode: keyboard::key::NativeCode,
) -> winit::keyboard::NativeKeyCode {
@ -1515,7 +1549,7 @@ fn winit_native_key_code(
}
/// Reconstruct the raw keycode
#[cfg(all(feature = "cctk", target_os = "linux"))]
#[cfg(wayland_platform)]
pub fn physical_to_scancode(physical: keyboard::key::Physical) -> Option<u32> {
let Some(physical_key) = (match physical {
keyboard::key::Physical::Code(code) => {

View file

@ -47,7 +47,6 @@ mod window;
pub use clipboard::Clipboard;
pub use error::Error;
pub use proxy::Proxy;
use winit::dpi::LogicalSize;
use winit::dpi::PhysicalPosition;
use winit::dpi::PhysicalSize;
@ -92,10 +91,10 @@ where
let event_loop = EventLoop::new().expect("Create event loop");
#[cfg(all(feature = "cctk", target_os = "linux"))]
#[cfg(wayland_platform)]
let is_wayland =
winit::platform::wayland::EventLoopExtWayland::is_wayland(&event_loop);
#[cfg(not(all(feature = "cctk", target_os = "linux")))]
#[cfg(not(wayland_platform))]
let is_wayland = false;
// TODO this is new..
@ -262,7 +261,7 @@ where
| winit::event::WindowEvent::Moved(_)
);
#[cfg(all(feature = "cctk", target_os = "linux"))]
#[cfg(wayland_platform)]
{
if matches!(event, WindowEvent::RedrawRequested) {
for id in
@ -577,10 +576,7 @@ where
.expect("Send event");
}
Control::Winit(id, e) => {
#[cfg(all(
feature = "cctk",
target_os = "linux"
))]
#[cfg(wayland_platform)]
{
if matches!(e, WindowEvent::RedrawRequested)
{
@ -776,7 +772,7 @@ async fn run_instance<P>(
let mut platform_specific_handler =
crate::platform_specific::PlatformSpecific::default();
#[cfg(all(feature = "cctk", target_os = "linux"))]
#[cfg(wayland_platform)]
if is_wayland {
platform_specific_handler = platform_specific_handler.with_wayland(
control_sender.clone(),
@ -861,6 +857,8 @@ async fn run_instance<P>(
&mut is_window_opening,
&mut system_theme,
&mut platform_specific_handler,
&mut dnd_surface,
&mut dnd_surface_id,
is_daemon,
)
};
@ -887,7 +885,7 @@ async fn run_instance<P>(
on_open,
resize_border,
} => {
#[cfg(all(feature = "cctk", target_os = "linux"))]
#[cfg(wayland_platform)]
platform_specific_handler.send_wayland(
platform_specific::Action::TrackWindow(window.clone(), id),
);
@ -1056,7 +1054,7 @@ async fn run_instance<P>(
continue;
}
// XX must force update to corner radius before the surface is committed.
#[cfg(all(feature = "cctk", target_os = "linux"))]
#[cfg(wayland_platform)]
if (window.surface_version != window.state.surface_version()
|| window.logical_size() != window.state.logical_size())
&& !crate::subsurface_widget::is_subsurface(window_id)
@ -1395,8 +1393,7 @@ async fn run_instance<P>(
true
}
});
let no_window_events = window_events.is_empty();
#[cfg(all(feature = "cctk", target_os = "linux"))]
#[cfg(wayland_platform)]
window_events.push(core::Event::PlatformSpecific(
core::event::PlatformSpecific::Wayland(
core::event::wayland::Event::RequestResize,
@ -1413,8 +1410,7 @@ async fn run_instance<P>(
&mut clipboard,
&mut messages,
);
let mut needs_redraw =
!no_window_events || !messages.is_empty();
let mut needs_redraw = !messages.is_empty();
if let Some(requested_size) =
clipboard.requested_logical_size.lock().unwrap().take()
{
@ -1470,8 +1466,17 @@ async fn run_instance<P>(
mouse_interaction,
..
} => {
let mouse_changed =
window.mouse_interaction != mouse_interaction;
window.update_mouse(mouse_interaction);
if mouse_changed {
window.request_redraw(
core::window::RedrawRequest::NextFrame,
);
}
#[cfg(not(feature = "unconditional-rendering"))]
window.request_redraw(_redraw_request);
}
@ -2074,6 +2079,10 @@ fn run_action<'a, P, C>(
is_window_opening: &mut bool,
system_theme: &mut theme::Mode,
platform_specific: &mut crate::platform_specific::PlatformSpecific,
dnd_surface: &mut Option<
Arc<Box<dyn HasWindowHandle + Send + Sync + 'static>>,
>,
dnd_surface_id: &mut Option<window::Id>,
is_daemon: bool,
) -> bool
where
@ -2128,7 +2137,7 @@ where
_ = control_sender.start_send(Control::Cleanup(id)).ok();
}
let proxy = clipboard.proxy();
#[cfg(all(feature = "cctk", target_os = "linux"))]
#[cfg(wayland_platform)]
platform_specific
.send_wayland(platform_specific::Action::RemoveWindow(id));
if let Some(window) = window_manager.remove(id) {
@ -2589,6 +2598,10 @@ where
}
iced_runtime::dnd::DndAction::EndDnd => {
clipboard.end_dnd();
*dnd_surface = None;
if let Some(id) = dnd_surface_id.take() {
platform_specific.retain_subsurfaces(|other| other != id);
}
}
iced_runtime::dnd::DndAction::PeekDnd(m, channel) => {
let data = clipboard.peek_dnd(m);

View file

@ -1,24 +1,20 @@
//! Wayland specific shell
//!
use std::{borrow::Cow, collections::HashMap, sync::Arc};
use std::collections::HashMap;
#[cfg(all(feature = "cctk", target_os = "linux"))]
use cctk::sctk::reexports::client::Connection;
use iced_graphics::{Compositor, compositor};
use iced_graphics::compositor;
use iced_runtime::{
core::{Vector, window},
platform_specific, user_interface,
user_interface,
};
use winit::raw_window_handle::HasWindowHandle;
#[cfg(all(feature = "cctk", target_os = "linux"))]
#[cfg(wayland_platform)]
pub mod wayland;
#[cfg(all(feature = "cctk", target_os = "linux"))]
#[cfg(wayland_platform)]
pub use wayland::*;
#[cfg(all(feature = "cctk", target_os = "linux"))]
use wayland_backend::client::Backend;
use crate::{CreateCompositor, Program, WindowManager};
@ -35,7 +31,7 @@ pub type UserInterfaces<'a, P> = HashMap<
#[derive(Debug)]
pub enum Event {
#[cfg(all(feature = "cctk", target_os = "linux"))]
#[cfg(wayland_platform)]
Wayland(sctk_event::SctkEvent),
}
@ -61,7 +57,7 @@ impl SurfaceIdWrapper {
#[derive(Debug, Default)]
pub struct PlatformSpecific {
#[cfg(all(feature = "cctk", target_os = "linux"))]
#[cfg(wayland_platform)]
wayland: WaylandSpecific,
}
@ -71,7 +67,7 @@ impl PlatformSpecific {
action: iced_runtime::platform_specific::Action,
) {
match action {
#[cfg(all(feature = "cctk", target_os = "linux"))]
#[cfg(wayland_platform)]
iced_runtime::platform_specific::Action::Wayland(a) => {
self.send_wayland(wayland::Action::Action(a));
}
@ -82,14 +78,14 @@ impl PlatformSpecific {
&mut self,
keep: F,
) {
#[cfg(all(feature = "cctk", target_os = "linux"))]
#[cfg(wayland_platform)]
{
self.wayland.retain_subsurfaces(keep);
}
}
pub(crate) fn clear_subsurface_list(&mut self) {
#[cfg(all(feature = "cctk", target_os = "linux"))]
#[cfg(wayland_platform)]
{
self.wayland.clear_subsurface_list();
}
@ -100,7 +96,7 @@ impl PlatformSpecific {
id: window::Id,
window: &dyn HasWindowHandle,
) {
#[cfg(all(feature = "cctk", target_os = "linux"))]
#[cfg(wayland_platform)]
{
use cctk::sctk::reexports::client::{
Proxy, protocol::wl_surface::WlSurface,
@ -151,7 +147,7 @@ impl PlatformSpecific {
pub(crate) fn create_surface(
&mut self,
) -> Option<Box<dyn HasWindowHandle + Send + Sync + 'static>> {
#[cfg(all(feature = "cctk", target_os = "linux"))]
#[cfg(wayland_platform)]
{
self.wayland.create_surface()
}
@ -170,7 +166,7 @@ impl PlatformSpecific {
data: &[u8],
offset: Vector,
) {
#[cfg(all(feature = "cctk", target_os = "linux"))]
#[cfg(wayland_platform)]
{
return self.wayland.update_surface_shm(
surface, width, height, scale, data, offset,
@ -198,7 +194,7 @@ pub(crate) async fn handle_event<'a, 'b, P>(
P: Program,
{
match e {
#[cfg(all(feature = "cctk", target_os = "linux"))]
#[cfg(wayland_platform)]
Event::Wayland(e) => {
platform_specific
.wayland

View file

@ -874,6 +874,11 @@ impl SctkState {
_ = wl_surface.frame(&self.queue_handle, wl_surface.clone());
if let Some(old) = self.blur_surfaces.remove(&settings.id) {
old.destroy();
}
_ = self.corner_radii.remove(&settings.id);
if let Some(blur) = self.pending_blur.remove(&settings.id) {
self.apply_blur(settings.id, Some(blur), &wl_surface);
}
@ -1011,6 +1016,12 @@ impl SctkState {
layer_surface.set_input_region(Some(&region));
region.destroy();
}
if let Some(old) = self.blur_surfaces.remove(&id) {
old.destroy();
}
_ = self.corner_radii.remove(&id);
if let Some(blur) = self.pending_blur.remove(&id) {
self.apply_blur(id, Some(blur), &wl_surface);
}
@ -1268,11 +1279,11 @@ impl SctkState {
|| self.layer_surfaces.iter().any(|l| l.id == settings.parent && p.data.parent.wl_surface() == l.surface.wl_surface()))
) {
let existing = &mut self.popups[existing];
let size = if settings.positioner.size.is_none() {
log::info!("No configured popup size");
(1, 1)
let size = if let Some(size) = settings.positioner.size {
size
} else {
settings.positioner.size.unwrap()
let guard = existing.common.lock().unwrap();
(guard.size.width, guard.size.height)
};
let Ok(positioner) = XdgPositioner::new(&self.xdg_shell_state)
.map_err(PopupCreationError::PositionerCreationFailed) else {
@ -1392,7 +1403,7 @@ impl SctkState {
},
};
let mut to_destroy = vec![sctk_popup];
// TODO optionally destroy parents if they request to be destroyed with children
while let Some(popup_to_destroy_last) = to_destroy.last().and_then(|popup| self
.popups
.iter()
@ -1839,6 +1850,7 @@ impl SctkState {
s: &WlSurface,
) {
let existing_blur = self.blur_surfaces.entry(id);
match (existing_blur, rectangles) {
(Entry::Occupied(occupied_entry), None) => {
let blur_surface = occupied_entry.remove();
@ -2021,6 +2033,11 @@ impl SctkState {
region.destroy();
}
if let Some(old) = self.blur_surfaces.remove(&settings.id) {
old.destroy();
}
_ = self.corner_radii.remove(&settings.id);
if let Some(blur) = self.pending_blur.remove(&settings.id) {
_ = self.apply_blur(settings.id, Some(blur), &wl_surface);
}

View file

@ -1,8 +1,5 @@
use crate::{
event_loop::state::FrameStatus,
platform_specific::wayland::{
event_loop::state::SctkState, sctk_event::SctkEvent,
},
use crate::platform_specific::wayland::{
event_loop::state::SctkState, sctk_event::SctkEvent,
};
use cctk::sctk::{
delegate_pointer,
@ -50,14 +47,6 @@ impl PointerHandler for SctkState {
continue;
}
let entry = self
.frame_status
.entry(e.surface.id())
.or_insert(FrameStatus::RequestedRedraw);
if matches!(entry, FrameStatus::Received) {
*entry = FrameStatus::Ready;
}
self.sctk_events.push(SctkEvent::PointerEvent {
variant: PointerEvent {
surface: e.surface.clone(),

View file

@ -27,6 +27,15 @@ impl LayerShellHandler for SctkState {
None => return,
};
if let Some(id) = self.id_map.remove(&layer.surface.wl_surface().id()) {
if let Some(blurred) = self.blur_surfaces.remove(&id) {
blurred.destroy();
}
_ = self.corner_radii.remove(&id);
_ = self.destroyed.insert(id);
}
self.sctk_events.push(SctkEvent::LayerSurfaceEvent {
variant: LayerSurfaceEventVariant::Done,
id: layer.surface.wl_surface().clone(),

View file

@ -84,6 +84,11 @@ impl PopupHandler for SctkState {
for popup in to_destroy.into_iter().rev() {
if let Some(id) = self.id_map.remove(&popup.popup.wl_surface().id())
{
if let Some(blurred) = self.blur_surfaces.remove(&id) {
blurred.destroy();
}
_ = self.corner_radii.remove(&id);
_ = self.destroyed.insert(id);
}