Compare commits

..

No commits in common. "backup/pre-rebase-iced-20260702" and "master" have entirely different histories.

55 changed files with 488 additions and 192 deletions

76
Cargo.lock generated
View file

@ -1070,6 +1070,7 @@ dependencies = [
[[package]] [[package]]
name = "clipboard_macos" name = "clipboard_macos"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c"
dependencies = [ dependencies = [
"objc", "objc",
"objc-foundation", "objc-foundation",
@ -1079,12 +1080,22 @@ dependencies = [
[[package]] [[package]]
name = "clipboard_wayland" name = "clipboard_wayland"
version = "0.2.2" version = "0.2.2"
source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c"
dependencies = [ dependencies = [
"dnd", "dnd",
"mime 0.1.0", "mime 0.1.0",
"smithay-clipboard", "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]] [[package]]
name = "clock" name = "clock"
version = "0.1.0" version = "0.1.0"
@ -1277,6 +1288,7 @@ dependencies = [
[[package]] [[package]]
name = "cosmic-client-toolkit" name = "cosmic-client-toolkit"
version = "0.2.0" version = "0.2.0"
source = "git+https://github.com/pop-os/cosmic-protocols?rev=160b086#160b086abe03cd34a8a375d7fbe47b24308d1f38"
dependencies = [ dependencies = [
"bitflags 2.11.0", "bitflags 2.11.0",
"cosmic-protocols", "cosmic-protocols",
@ -1289,6 +1301,7 @@ dependencies = [
[[package]] [[package]]
name = "cosmic-protocols" name = "cosmic-protocols"
version = "0.2.0" version = "0.2.0"
source = "git+https://github.com/pop-os/cosmic-protocols?rev=160b086#160b086abe03cd34a8a375d7fbe47b24308d1f38"
dependencies = [ dependencies = [
"bitflags 2.11.0", "bitflags 2.11.0",
"wayland-backend", "wayland-backend",
@ -1301,7 +1314,8 @@ dependencies = [
[[package]] [[package]]
name = "cosmic-text" name = "cosmic-text"
version = "0.19.0" version = "0.18.2"
source = "git+https://github.com/pop-os/cosmic-text.git#4d74f795cc771fdcc7ea0f9cacba63fcf036fad6"
dependencies = [ dependencies = [
"bitflags 2.11.0", "bitflags 2.11.0",
"fontdb", "fontdb",
@ -1319,7 +1333,6 @@ dependencies = [
"unicode-linebreak", "unicode-linebreak",
"unicode-script", "unicode-script",
"unicode-segmentation", "unicode-segmentation",
"unicode-width",
] ]
[[package]] [[package]]
@ -1426,6 +1439,7 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
[[package]] [[package]]
name = "cryoglyph" name = "cryoglyph"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/glyphon.git?tag=cosmic-0.14#c49de15bce4d8254ac136d1be9911960cc85ce12"
dependencies = [ dependencies = [
"cosmic-text", "cosmic-text",
"etagere", "etagere",
@ -1602,6 +1616,7 @@ dependencies = [
[[package]] [[package]]
name = "dnd" name = "dnd"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c"
dependencies = [ dependencies = [
"bitflags 2.11.0", "bitflags 2.11.0",
"mime 0.1.0", "mime 0.1.0",
@ -1636,6 +1651,30 @@ dependencies = [
[[package]] [[package]]
name = "dpi" name = "dpi"
version = "0.1.2" 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]] [[package]]
name = "drm-fourcc" name = "drm-fourcc"
@ -1643,6 +1682,16 @@ version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0aafbcdb8afc29c1a7ee5fbe53b5d62f4565b35a042a662ca9fecd0b54dae6f4" 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]] [[package]]
name = "editor" name = "editor"
version = "0.1.0" version = "0.1.0"
@ -3781,6 +3830,12 @@ version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
[[package]]
name = "linux-raw-sys"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a385b1be4e5c3e362ad2ffa73c392e53f031eaa5b7d648e64cd87f27f6063d7"
[[package]] [[package]]
name = "linux-raw-sys" name = "linux-raw-sys"
version = "0.12.1" version = "0.12.1"
@ -4006,6 +4061,7 @@ dependencies = [
[[package]] [[package]]
name = "mime" name = "mime"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c"
dependencies = [ dependencies = [
"smithay-clipboard", "smithay-clipboard",
] ]
@ -6226,6 +6282,7 @@ dependencies = [
[[package]] [[package]]
name = "smithay-clipboard" name = "smithay-clipboard"
version = "0.8.0" version = "0.8.0"
source = "git+https://github.com/pop-os/smithay-clipboard?tag=sctk-0.20#859b02c88f45c554049a67c6ddeec1692ce0e20b"
dependencies = [ dependencies = [
"libc", "libc",
"raw-window-handle", "raw-window-handle",
@ -6283,12 +6340,14 @@ dependencies = [
[[package]] [[package]]
name = "softbuffer" name = "softbuffer"
version = "0.4.1" version = "0.4.1"
source = "git+https://github.com/pop-os/softbuffer?tag=cosmic-4.0#a3f77e251e7422803f693df6e3fc313c010c4dcb"
dependencies = [ dependencies = [
"as-raw-xcb-connection", "as-raw-xcb-connection",
"bytemuck", "bytemuck",
"cfg_aliases", "cfg_aliases",
"cocoa", "cocoa",
"core-graphics", "core-graphics",
"drm",
"fastrand", "fastrand",
"foreign-types 0.5.0", "foreign-types 0.5.0",
"js-sys", "js-sys",
@ -7957,10 +8016,12 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]] [[package]]
name = "window_clipboard" name = "window_clipboard"
version = "0.4.1" version = "0.4.1"
source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c"
dependencies = [ dependencies = [
"clipboard-win", "clipboard-win",
"clipboard_macos", "clipboard_macos",
"clipboard_wayland", "clipboard_wayland",
"clipboard_x11",
"dnd", "dnd",
"mime 0.1.0", "mime 0.1.0",
"raw-window-handle", "raw-window-handle",
@ -8528,6 +8589,7 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
[[package]] [[package]]
name = "winit" name = "winit"
version = "0.31.0-beta.2" version = "0.31.0-beta.2"
source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366"
dependencies = [ dependencies = [
"bitflags 2.11.0", "bitflags 2.11.0",
"cfg_aliases", "cfg_aliases",
@ -8553,6 +8615,7 @@ dependencies = [
[[package]] [[package]]
name = "winit-android" name = "winit-android"
version = "0.31.0-beta.2" version = "0.31.0-beta.2"
source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366"
dependencies = [ dependencies = [
"android-activity", "android-activity",
"bitflags 2.11.0", "bitflags 2.11.0",
@ -8567,6 +8630,7 @@ dependencies = [
[[package]] [[package]]
name = "winit-appkit" name = "winit-appkit"
version = "0.31.0-beta.2" version = "0.31.0-beta.2"
source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366"
dependencies = [ dependencies = [
"bitflags 2.11.0", "bitflags 2.11.0",
"block2 0.6.2", "block2 0.6.2",
@ -8588,6 +8652,7 @@ dependencies = [
[[package]] [[package]]
name = "winit-common" name = "winit-common"
version = "0.31.0-beta.2" version = "0.31.0-beta.2"
source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366"
dependencies = [ dependencies = [
"memmap2 0.9.10", "memmap2 0.9.10",
"objc2 0.6.4", "objc2 0.6.4",
@ -8602,6 +8667,7 @@ dependencies = [
[[package]] [[package]]
name = "winit-core" name = "winit-core"
version = "0.31.0-beta.2" version = "0.31.0-beta.2"
source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366"
dependencies = [ dependencies = [
"bitflags 2.11.0", "bitflags 2.11.0",
"cursor-icon", "cursor-icon",
@ -8615,6 +8681,7 @@ dependencies = [
[[package]] [[package]]
name = "winit-orbital" name = "winit-orbital"
version = "0.31.0-beta.2" version = "0.31.0-beta.2"
source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366"
dependencies = [ dependencies = [
"bitflags 2.11.0", "bitflags 2.11.0",
"dpi", "dpi",
@ -8630,6 +8697,7 @@ dependencies = [
[[package]] [[package]]
name = "winit-uikit" name = "winit-uikit"
version = "0.31.0-beta.2" version = "0.31.0-beta.2"
source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366"
dependencies = [ dependencies = [
"bitflags 2.11.0", "bitflags 2.11.0",
"block2 0.6.2", "block2 0.6.2",
@ -8649,6 +8717,7 @@ dependencies = [
[[package]] [[package]]
name = "winit-wayland" name = "winit-wayland"
version = "0.31.0-beta.2" version = "0.31.0-beta.2"
source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366"
dependencies = [ dependencies = [
"ahash", "ahash",
"bitflags 2.11.0", "bitflags 2.11.0",
@ -8674,6 +8743,7 @@ dependencies = [
[[package]] [[package]]
name = "winit-web" name = "winit-web"
version = "0.31.0-beta.2" version = "0.31.0-beta.2"
source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366"
dependencies = [ dependencies = [
"atomic-waker", "atomic-waker",
"bitflags 2.11.0", "bitflags 2.11.0",
@ -8695,6 +8765,7 @@ dependencies = [
[[package]] [[package]]
name = "winit-win32" name = "winit-win32"
version = "0.31.0-beta.2" version = "0.31.0-beta.2"
source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366"
dependencies = [ dependencies = [
"bitflags 2.11.0", "bitflags 2.11.0",
"cursor-icon", "cursor-icon",
@ -8710,6 +8781,7 @@ dependencies = [
[[package]] [[package]]
name = "winit-x11" name = "winit-x11"
version = "0.31.0-beta.2" version = "0.31.0-beta.2"
source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366"
dependencies = [ dependencies = [
"bitflags 2.11.0", "bitflags 2.11.0",
"bytemuck", "bytemuck",

View file

@ -238,10 +238,10 @@ async-std = "1.0"
bitflags = "2.5" bitflags = "2.5"
bytemuck = { version = "1.0", features = ["derive"] } bytemuck = { version = "1.0", features = ["derive"] }
bytes = "1.6" bytes = "1.6"
cosmic-text = { path = "../../cosmic-text" } cosmic-text = { git = "https://github.com/pop-os/cosmic-text.git" }
# cosmic-text = "0.10" # cosmic-text = "0.10"
dark-light = "1.0" dark-light = "1.0"
cryoglyph = { package = "cryoglyph", path = "../../glyphon" } cryoglyph = { package = "cryoglyph", git = "https://github.com/pop-os/glyphon.git", tag = "cosmic-0.14" }
resvg = "0.45" resvg = "0.45"
web-sys = "0.3.69" web-sys = "0.3.69"
guillotiere = "0.6" guillotiere = "0.6"
@ -275,11 +275,8 @@ tiny-skia = { version = "0.11", default-features = false, features = [
"std", "std",
"simd", "simd",
] } ] }
cctk = { path = "../../cosmic-protocols/client-toolkit", package = "cosmic-client-toolkit" } cctk = { git = "https://github.com/pop-os/cosmic-protocols", package = "cosmic-client-toolkit", rev = "160b086" }
# Yoda: default-features=false drops softbuffer's x11 / x11-dlopen (pulled softbuffer = { git = "https://github.com/pop-os/softbuffer", tag = "cosmic-4.0" }
# tiny-xlib + as-raw-xcb-connection). The wayland + wayland-dlopen features
# are re-activated via iced_tiny_skia's own `wayland` feature propagation.
softbuffer = { path = "../../softbuffer", default-features = false }
syntect = "5.2" syntect = "5.2"
tokio = "1.0" tokio = "1.0"
tracing = "0.1" tracing = "0.1"
@ -305,40 +302,13 @@ wayland-client = { version = "0.31.5" }
winapi = "0.3" winapi = "0.3"
# window_clipboard = "0.4.1" # window_clipboard = "0.4.1"
# Yoda: window_clipboard pinned to our public fork that has x11 gated behind window_clipboard = { git = "https://github.com/pop-os/window_clipboard.git", tag = "sctk-0.20" }
# an opt-in feature. default-features=false + features=["wayland"] drops dnd = { git = "https://github.com/pop-os/window_clipboard.git", tag = "sctk-0.20" }
# clipboard_x11 + x11rb from the build. Branch yoda-x11-optional on mime = { git = "https://github.com/pop-os/window_clipboard.git", tag = "sctk-0.20" }
# https://forge.aditua.com/leyoda/window_clipboard. winit = { git = "https://github.com/pop-os/winit.git", tag = "cosmic-0.14" }
window_clipboard = { path = "../../window_clipboard", default-features = false, features = ["wayland"] } winit-core = { git = "https://github.com/pop-os/winit.git", tag = "cosmic-0.14" }
dnd = { path = "../../window_clipboard/dnd" }
mime = { path = "../../window_clipboard/mime" }
# Yoda: default-features = false drops winit's x11 default, which otherwise
# pulls winit-x11, x11-dl, tiny-xlib, as-raw-xcb-connection. Our Wayland-only
# fork doesn't need any of that — the wayland + wayland-dlopen features are
# re-enabled via iced_winit's own feature propagation from libcosmic-yoda.
winit = { path = "../../winit/winit", default-features = false }
winit-core = { path = "../../winit/winit-core" }
cursor-icon = "1.1.0" cursor-icon = "1.1.0"
[patch.'https://github.com/pop-os/softbuffer']
softbuffer = { path = "../../softbuffer" }
[patch.'https://github.com/pop-os/smithay-clipboard']
smithay-clipboard = { path = "../../smithay-clipboard" }
[patch.'https://github.com/pop-os/winit.git']
dpi = { path = "../../winit/dpi" }
winit = { path = "../../winit/winit" }
winit-android = { path = "../../winit/winit-android" }
winit-appkit = { path = "../../winit/winit-appkit" }
winit-common = { path = "../../winit/winit-common" }
winit-core = { path = "../../winit/winit-core" }
winit-orbital = { path = "../../winit/winit-orbital" }
winit-uikit = { path = "../../winit/winit-uikit" }
winit-wayland = { path = "../../winit/winit-wayland" }
winit-web = { path = "../../winit/winit-web" }
winit-win32 = { path = "../../winit/winit-win32" }
winit-x11 = { path = "../../winit/winit-x11" }
[workspace.lints.rust] [workspace.lints.rust]
rust_2018_idioms = { level = "deny", priority = -1 } rust_2018_idioms = { level = "deny", priority = -1 }

View file

@ -1,4 +1,4 @@
use crate::event::Event; use crate::event::{self, Event};
use crate::id::Id; use crate::id::Id;
use crate::layout; use crate::layout;
use crate::mouse; use crate::mouse;

View file

@ -3,7 +3,7 @@ use crate::mouse;
use crate::overlay; use crate::overlay;
use crate::renderer; use crate::renderer;
use crate::widget; use crate::widget;
use crate::{Clipboard, Event, Layout, Overlay, Shell, Size}; use crate::{Clipboard, Event, Layout, Overlay, Point, Rectangle, Shell, Size};
/// An [`Overlay`] container that displays multiple overlay [`overlay::Element`] /// An [`Overlay`] container that displays multiple overlay [`overlay::Element`]
/// children. /// children.

View file

@ -63,3 +63,13 @@ impl Default for Settings {
} }
} }
#[cfg(feature = "winit")]
impl From<Settings> for iced_winit::Settings {
fn from(settings: Settings) -> iced_winit::Settings {
iced_winit::Settings {
id: settings.id,
fonts: settings.fonts,
is_daemon: settings.is_daemon,
}
}
}

View file

@ -4,7 +4,7 @@ use super::Operation;
use crate::{ use crate::{
Rectangle, Rectangle,
id::Id, id::Id,
widget::operation::Outcome, widget::operation::{Outcome, focusable::Count},
}; };
/// Produces an [`Operation`] that searches for the Id /// Produces an [`Operation`] that searches for the Id

View file

@ -25,12 +25,13 @@ use crate::layout;
use crate::mouse; use crate::mouse;
use crate::renderer; use crate::renderer;
use crate::text::paragraph::{self, Paragraph}; use crate::text::paragraph::{self, Paragraph};
use crate::text::{self}; use crate::text::{self, Fragment};
use crate::widget::tree::{self, Tree}; use crate::widget::tree::{self, Tree};
use crate::{ use crate::{
Color, Element, Layout, Length, Pixels, Rectangle, Size, Theme, Widget, Color, Element, Layout, Length, Pixels, Rectangle, Size, Theme, Widget,
}; };
use std::borrow::Cow;
pub use text::{Alignment, Ellipsize, LineHeight, Shaping, Wrapping}; pub use text::{Alignment, Ellipsize, LineHeight, Shaping, Wrapping};
/// A bunch of text. /// A bunch of text.

View file

@ -2,6 +2,8 @@
#[cfg(feature = "image")] #[cfg(feature = "image")]
use crate::core::Bytes; use crate::core::Bytes;
use crate::core::Color;
use crate::core::Radians;
use crate::core::Rectangle; use crate::core::Rectangle;
use crate::core::image; use crate::core::image;
use crate::core::svg; use crate::core::svg;

View file

@ -1,8 +1,10 @@
//! Access the clipboard. //! Access the clipboard.
use std::any::Any;
use dnd::{DndDestinationRectangle, DndSurface}; use dnd::{DndDestinationRectangle, DndSurface};
use window_clipboard::mime::AllowedMimeTypes; use iced_core::clipboard::DndSource;
use window_clipboard::mime::{AllowedMimeTypes, AsMimeTypes};
use crate::{oneshot, task, Action, Task}; use crate::{oneshot, task, Action, Task};

View file

@ -28,6 +28,7 @@ pub use task::Task;
pub use user_interface::UserInterface; pub use user_interface::UserInterface;
pub use window::Window; pub use window::Window;
use crate::core::Color;
use crate::futures::futures::channel::oneshot; use crate::futures::futures::channel::oneshot;
use std::borrow::Cow; use std::borrow::Cow;

View file

@ -1,12 +1,14 @@
use std::any::Any;
use std::fmt; use std::fmt;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use std::sync::Arc;
use cctk::sctk::reexports::protocols::xdg::shell::client::xdg_positioner::{ use cctk::sctk::reexports::protocols::xdg::shell::client::xdg_positioner::{
Anchor, Gravity, Anchor, Gravity,
}; };
use iced_core::layout::Limits; use iced_core::layout::Limits;
use iced_core::window::Id; use iced_core::window::Id;
use iced_core::Rectangle; use iced_core::{Element, Rectangle};
/// Popup creation details /// Popup creation details
#[derive(Debug, Clone)] #[derive(Debug, Clone)]

View file

@ -1,9 +1,14 @@
use std::any::Any;
use std::fmt; use std::fmt;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use std::sync::Arc;
use cctk::sctk::reexports::protocols::xdg::shell::client::xdg_positioner::Gravity; use cctk::sctk::reexports::protocols::xdg::shell::client::xdg_positioner::{
Anchor, Gravity,
};
use iced_core::layout::Limits;
use iced_core::window::Id; use iced_core::window::Id;
use iced_core::{Point, Rectangle, Size}; use iced_core::{Element, Point, Rectangle, Size};
/// Subsurface creation details /// Subsurface creation details
#[derive(Debug, Clone)] #[derive(Debug, Clone)]

View file

@ -57,7 +57,7 @@ impl Pipeline {
let width_scale = bounds.width / image.width() as f32; let width_scale = bounds.width / image.width() as f32;
let height_scale = bounds.height / image.height() as f32; let height_scale = bounds.height / image.height() as f32;
let _quality = match filter_method { let quality = match filter_method {
raster::FilterMethod::Linear => tiny_skia::FilterQuality::Bilinear, raster::FilterMethod::Linear => tiny_skia::FilterQuality::Bilinear,
raster::FilterMethod::Nearest => tiny_skia::FilterQuality::Nearest, raster::FilterMethod::Nearest => tiny_skia::FilterQuality::Nearest,
}; };

View file

@ -25,11 +25,6 @@ svg = ["iced_graphics/svg", "resvg/text"]
web-colors = ["iced_graphics/web-colors"] web-colors = ["iced_graphics/web-colors"]
webgl = ["wgpu/webgl"] webgl = ["wgpu/webgl"]
strict-assertions = [] strict-assertions = []
# Yoda: opt-in X11 backend. Pulls tiny-xlib/as-raw-xcb-connection/x11rb
# (which otherwise were unconditional direct deps on unix). Wayland-only
# 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"]
[dependencies] [dependencies]
iced_debug.workspace = true iced_debug.workspace = true
@ -62,9 +57,9 @@ wayland-protocols.workspace = true
wayland-backend = { version = "0.3.3", features = ["client_system"] } wayland-backend = { version = "0.3.3", features = ["client_system"] }
wayland-client = { version = "0.31.2" } wayland-client = { version = "0.31.2" }
wayland-sys = { version = "0.31.1", features = ["dlopen"] } wayland-sys = { version = "0.31.1", features = ["dlopen"] }
as-raw-xcb-connection = { version = "1.0.1", optional = true } as-raw-xcb-connection = "1.0.1"
tiny-xlib = { version = "0.2.3", optional = true } tiny-xlib = "0.2.3"
x11rb = { version = "0.13.1", optional = true, features = [ x11rb = { version = "0.13.1", features = [
"allow-unsafe-code", "allow-unsafe-code",
"dl-libxcb", "dl-libxcb",
"dri3", "dri3",

View file

@ -1,3 +1,4 @@
use crate::core::Radians;
use crate::core::{ use crate::core::{
self, Background, Color, Point, Rectangle, Svg, Transformation, renderer, self, Background, Color, Point, Rectangle, Svg, Transformation, renderer,
}; };

View file

@ -64,8 +64,8 @@ pub use geometry::Geometry;
use crate::core::renderer; use crate::core::renderer;
use crate::core::{ use crate::core::{
Background, Color, Font, Pixels, Point, Rectangle, Size, Background, Color, Font, Pixels, Point, Radians, Rectangle, Size,
Transformation, Transformation, Vector, image::FilterMethod,
}; };
use crate::graphics::mesh; use crate::graphics::mesh;
use crate::graphics::text::{Editor, Paragraph}; use crate::graphics::text::{Editor, Paragraph};
@ -671,6 +671,50 @@ impl Renderer {
}); });
} }
fn draw_overlay(
&mut self,
overlay: &[impl AsRef<str>],
viewport: &Viewport,
) {
use crate::core::Renderer as _;
use crate::core::alignment;
use crate::core::text::Renderer as _;
self.with_layer(
Rectangle::with_size(viewport.logical_size()),
|renderer| {
for (i, line) in overlay.iter().enumerate() {
let text = crate::core::Text {
content: line.as_ref().to_owned(),
bounds: viewport.logical_size(),
size: Pixels(20.0),
line_height: core::text::LineHeight::default(),
font: Font::MONOSPACE,
align_x: core::text::Alignment::Left,
align_y: alignment::Vertical::Top,
shaping: core::text::Shaping::Advanced,
wrapping: core::text::Wrapping::Word,
ellipsize: core::text::Ellipsize::None,
};
renderer.fill_text(
text.clone(),
Point::new(11.0, 11.0 + 25.0 * i as f32),
Color::from_rgba(0.9, 0.9, 0.9, 1.0),
Rectangle::with_size(Size::INFINITE),
);
renderer.fill_text(
text,
Point::new(11.0, 11.0 + 25.0 * i as f32)
+ Vector::new(-1.0, -1.0),
Color::BLACK,
Rectangle::with_size(Size::INFINITE),
);
}
},
);
}
} }
impl core::Renderer for Renderer { impl core::Renderer for Renderer {

View file

@ -7,7 +7,7 @@ pub mod compositor;
not(target_os = "redox") not(target_os = "redox")
))] ))]
mod wayland; mod wayland;
#[cfg(all(unix, feature = "x11", not(target_os = "macos"), not(target_os = "redox")))] #[cfg(all(unix, not(target_os = "macos"), not(target_os = "redox")))]
mod x11; mod x11;
pub use compositor::Compositor; pub use compositor::Compositor;

View file

@ -16,8 +16,9 @@ use crate::{Engine, Renderer};
not(target_os = "redox") not(target_os = "redox")
))] ))]
use super::wayland::get_wayland_device_ids; use super::wayland::get_wayland_device_ids;
#[cfg(all(unix, feature = "x11", not(target_os = "macos"), not(target_os = "redox")))] #[cfg(all(unix, not(target_os = "macos"), not(target_os = "redox")))]
use super::x11::get_x11_device_ids; use super::x11::get_x11_device_ids;
use std::future::Future;
/// A window graphics backend for iced powered by `wgpu`. /// A window graphics backend for iced powered by `wgpu`.
pub struct Compositor { pub struct Compositor {
@ -71,10 +72,8 @@ impl Compositor {
not(target_os = "redox") not(target_os = "redox")
))] ))]
let ids = compatible_window.as_ref().and_then(|window| { let ids = compatible_window.as_ref().and_then(|window| {
let w = get_wayland_device_ids(window); get_wayland_device_ids(window)
#[cfg(feature = "x11")] .or_else(|| get_x11_device_ids(window))
let w = w.or_else(|| get_x11_device_ids(window));
w
}); });
// HACK: // HACK:
@ -138,6 +137,12 @@ impl Compositor {
.clone() .clone()
.and_then(|window| instance.create_surface(window).ok()); .and_then(|window| instance.create_surface(window).ok());
let mut adapter_options = wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::from_env()
.unwrap_or(wgpu::PowerPreference::HighPerformance),
compatible_surface: compatible_surface.as_ref(),
force_fallback_adapter: false,
};
let mut adapter = None; let mut adapter = None;
#[cfg_attr(not(unix), allow(dead_code))] #[cfg_attr(not(unix), allow(dead_code))]
if std::env::var_os("WGPU_ADAPTER_NAME").is_none() { if std::env::var_os("WGPU_ADAPTER_NAME").is_none() {
@ -199,7 +204,7 @@ impl Compositor {
.await; .await;
compatible_surface = compatible_window compatible_surface = compatible_window
.and_then(|window| instance.create_surface(window).ok()); .and_then(|window| instance.create_surface(window).ok());
let adapter_options = wgpu::RequestAdapterOptions { adapter_options = wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::from_env() power_preference: wgpu::PowerPreference::from_env()
.unwrap_or(wgpu::PowerPreference::HighPerformance), .unwrap_or(wgpu::PowerPreference::HighPerformance),
compatible_surface: compatible_surface.as_ref(), compatible_surface: compatible_surface.as_ref(),

View file

@ -599,7 +599,7 @@ where
(x + width) as f64, (x + width) as f64,
(y + height) as f64, (y + height) as f64,
); );
let _is_hovered = state.state.downcast_ref::<State>().is_hovered; let is_hovered = state.state.downcast_ref::<State>().is_hovered;
let mut node = Node::new(Role::Button); let mut node = Node::new(Role::Button);
node.add_action(Action::Focus); node.add_action(Action::Focus);

View file

@ -536,7 +536,7 @@ where
}; };
let bounds = layout.bounds(); let bounds = layout.bounds();
let _is_hovered = cursor.is_over(bounds); let is_hovered = cursor.is_over(bounds);
let Rectangle { let Rectangle {
x, x,
y, y,

View file

@ -35,7 +35,7 @@ use crate::core::{
color, color,
}; };
use iced_runtime::{Task, task}; use iced_runtime::{Action, Task, task};
/// A widget that aligns its contents inside of its boundaries. /// A widget that aligns its contents inside of its boundaries.
/// ///
@ -601,7 +601,7 @@ pub fn visible_bounds(id: Id) -> Task<Option<Rectangle>> {
operate: &mut dyn FnMut(&mut dyn Operation<Option<Rectangle>>), operate: &mut dyn FnMut(&mut dyn Operation<Option<Rectangle>>),
) { ) {
self.depth += 1; self.depth += 1;
operate(self); self.traverse(operate);
self.depth -= 1; self.depth -= 1;
} }

View file

@ -293,8 +293,8 @@ fn drawing_bounds<Renderer, Handle>(
content_fit: ContentFit, content_fit: ContentFit,
rotation: Rotation, rotation: Rotation,
scale: f32, scale: f32,
_opacity: f32, opacity: f32,
_border_radius: [f32; 4], border_radius: [f32; 4],
) -> Rectangle ) -> Rectangle
where where
Renderer: image::Renderer<Handle = Handle>, Renderer: image::Renderer<Handle = Handle>,

View file

@ -1,6 +1,7 @@
//! Keyed columns distribute content vertically while keeping continuity. //! Keyed columns distribute content vertically while keeping continuity.
//! Distribute content vertically. //! Distribute content vertically.
use crate::core::event;
use crate::core::layout; use crate::core::layout;
use crate::core::mouse; use crate::core::mouse;
use crate::core::overlay; use crate::core::overlay;

View file

@ -5,6 +5,7 @@ pub mod component;
#[allow(deprecated)] #[allow(deprecated)]
pub use component::Component; pub use component::Component;
use iced_renderer::core::widget::Operation;
mod cache; mod cache;
@ -14,7 +15,7 @@ use crate::core::mouse;
use crate::core::overlay; use crate::core::overlay;
use crate::core::renderer; use crate::core::renderer;
use crate::core::widget::tree::{self, Tree}; use crate::core::widget::tree::{self, Tree};
use crate::core::widget::Widget; use crate::core::widget::{self, Widget};
use crate::core::{ use crate::core::{
self, Clipboard, Event, Length, Rectangle, Shell, Size, Vector, self, Clipboard, Event, Length, Rectangle, Shell, Size, Vector,
}; };

View file

@ -10,6 +10,7 @@ use crate::core::{
self, Clipboard, Element, Length, Rectangle, Shell, Size, Vector, Widget, self, Clipboard, Element, Length, Rectangle, Shell, Size, Vector, Widget,
}; };
use iced_renderer::core::widget::Operation;
use ouroboros::self_referencing; use ouroboros::self_referencing;
use std::cell::RefCell; use std::cell::RefCell;
use std::marker::PhantomData; use std::marker::PhantomData;
@ -526,11 +527,11 @@ where
renderer: &Renderer, renderer: &Renderer,
dnd_rectangles: &mut core::clipboard::DndDestinationRectangles, dnd_rectangles: &mut core::clipboard::DndDestinationRectangles,
) { ) {
let tree = tree let mut tree = tree
.state .state
.downcast_ref::<Rc<RefCell<Option<Tree>>>>() .downcast_ref::<Rc<RefCell<Option<Tree>>>>()
.borrow_mut(); .borrow_mut();
let tree = tree.as_ref().unwrap(); let mut tree = tree.as_ref().unwrap();
self.with_element(|element| { self.with_element(|element| {
element.as_widget().drag_destinations( element.as_widget().drag_destinations(
&tree.children[0], &tree.children[0],

View file

@ -1,5 +1,5 @@
#![allow(missing_docs)] #![allow(missing_docs)]
use crate::core::event::Event; use crate::core::event::{self, Event};
use crate::core::layout; use crate::core::layout;
use crate::core::mouse; use crate::core::mouse;
use crate::core::overlay; use crate::core::overlay;
@ -366,7 +366,7 @@ where
self.visible_elements self.visible_elements
.iter_mut() .iter_mut()
.zip(&mut state.visible_layouts) .zip(&mut state.visible_layouts)
.for_each(|(element, (index, layout, tree))| { .map(|(element, (index, layout, tree))| {
element.as_widget_mut().update( element.as_widget_mut().update(
tree, tree,
event, event,

View file

@ -2,6 +2,7 @@
use iced_renderer::core::mouse::Click; use iced_renderer::core::mouse::Click;
use crate::core::event;
use crate::core::layout; use crate::core::layout;
use crate::core::mouse; use crate::core::mouse;
use crate::core::overlay; use crate::core::overlay;

View file

@ -575,7 +575,7 @@ where
align_x: text::Alignment::Default, align_x: text::Alignment::Default,
align_y: alignment::Vertical::Center, align_y: alignment::Vertical::Center,
shaping: self.text_shaping, shaping: self.text_shaping,
wrapping: self.text_wrap, wrapping: text::Wrapping::default(),
ellipsize: text::Ellipsize::default(), ellipsize: text::Ellipsize::default(),
}, },
Point::new(bounds.x + self.padding.left, bounds.center_y()), Point::new(bounds.x + self.padding.left, bounds.center_y()),

View file

@ -6,7 +6,7 @@ use crate::core::renderer;
use crate::core::widget::{self, Tree}; use crate::core::widget::{self, Tree};
use crate::core::{ use crate::core::{
self, Clipboard, Element, Event, Layout, Point, Rectangle, Shell, Size, self, Clipboard, Element, Event, Layout, Point, Rectangle, Shell, Size,
Vector, Vector, event,
}; };
use crate::pane_grid::{Draggable, TitleBar}; use crate::pane_grid::{Draggable, TitleBar};

View file

@ -27,6 +27,7 @@ use iced_runtime::core::widget::Id;
#[cfg(feature = "a11y")] #[cfg(feature = "a11y")]
use std::borrow::Cow; use std::borrow::Cow;
use crate::core::event;
use crate::core::keyboard; use crate::core::keyboard;
use crate::core::layout; use crate::core::layout;
use crate::core::mouse; use crate::core::mouse;
@ -932,7 +933,7 @@ where
let had_input_method = shell.input_method().is_enabled(); let had_input_method = shell.input_method().is_enabled();
let c_event = match event.clone() { let mut c_event = match event.clone() {
Event::Dnd(dnd::DndEvent::Offer( Event::Dnd(dnd::DndEvent::Offer(
id, id,
dnd::OfferEvent::Enter { dnd::OfferEvent::Enter {
@ -1585,7 +1586,7 @@ where
return A11yTree::default(); return A11yTree::default();
} }
let window = layout.bounds(); let window = layout.bounds();
let _is_hovered = cursor.is_over(window); let is_hovered = cursor.is_over(window);
let Rectangle { let Rectangle {
x, x,
y, y,
@ -1669,7 +1670,7 @@ where
})) }))
{ {
let scrollbar_bounds = scrollbar.total_bounds; let scrollbar_bounds = scrollbar.total_bounds;
let _is_hovered = cursor.is_over(scrollbar_bounds); let is_hovered = cursor.is_over(scrollbar_bounds);
let Rectangle { let Rectangle {
x, x,
y, y,

View file

@ -695,7 +695,7 @@ where
}; };
let bounds = layout.bounds(); let bounds = layout.bounds();
let _is_hovered = cursor.is_over(bounds); let is_hovered = cursor.is_over(bounds);
let Rectangle { let Rectangle {
x, x,
y, y,
@ -732,14 +732,18 @@ where
node.set_labelled_by(label.clone()); node.set_labelled_by(label.clone());
} }
let Ok(min) = self.range.start().clone().try_into(); if let Ok(min) = self.range.start().clone().try_into() {
node.set_min_numeric_value(min); node.set_min_numeric_value(min);
let Ok(max) = self.range.end().clone().try_into(); }
node.set_max_numeric_value(max); if let Ok(max) = self.range.end().clone().try_into() {
let Ok(value) = self.value.clone().try_into(); node.set_max_numeric_value(max);
node.set_numeric_value(value); }
let Ok(step) = self.step.clone().try_into(); if let Ok(value) = self.value.clone().try_into() {
node.set_numeric_value_step(step); node.set_numeric_value(value);
}
if let Ok(step) = self.step.clone().try_into() {
node.set_numeric_value_step(step);
}
// TODO: This could be a setting on the slider // TODO: This could be a setting on the slider
node.set_live(iced_accessibility::accesskit::Live::Polite); node.set_live(iced_accessibility::accesskit::Live::Polite);

View file

@ -1,5 +1,6 @@
//! Display content on top of other content. //! Display content on top of other content.
use crate::core::event;
use crate::core::layout; use crate::core::layout;
use crate::core::mouse; use crate::core::mouse;
use crate::core::overlay; use crate::core::overlay;

View file

@ -31,6 +31,7 @@ use crate::core::{
#[cfg(feature = "a11y")] #[cfg(feature = "a11y")]
use std::borrow::Cow; use std::borrow::Cow;
use std::marker::PhantomData;
use std::path::PathBuf; use std::path::PathBuf;
pub use crate::core::svg::Handle; pub use crate::core::svg::Handle;

View file

@ -1,5 +1,6 @@
use crate::container; use crate::container;
use crate::core::event;
use crate::core::layout; use crate::core::layout;
use crate::core::mouse; use crate::core::mouse;
use crate::core::overlay; use crate::core::overlay;

View file

@ -37,6 +37,7 @@ use std::borrow::Cow;
use iced_runtime::core::border::Radius; use iced_runtime::core::border::Radius;
use crate::core::alignment; use crate::core::alignment;
use crate::core::border;
use crate::core::layout; use crate::core::layout;
use crate::core::mouse; use crate::core::mouse;
use crate::core::renderer; use crate::core::renderer;
@ -508,7 +509,7 @@ where
let space = style.handle_margin; let space = style.handle_margin;
let _toggler_background_bounds = Rectangle { let toggler_background_bounds = Rectangle {
x: bounds.x, x: bounds.x,
y: bounds.y, y: bounds.y,
width: bounds.width, width: bounds.width,
@ -528,7 +529,7 @@ where
style.background, style.background,
); );
let _padding = (style.padding_ratio * bounds.height).round(); let padding = (style.padding_ratio * bounds.height).round();
let toggler_foreground_bounds = Rectangle { let toggler_foreground_bounds = Rectangle {
x: bounds.x x: bounds.x
+ if self.is_toggled { + if self.is_toggled {
@ -569,7 +570,7 @@ where
}; };
let bounds = layout.bounds(); let bounds = layout.bounds();
let _is_hovered = cursor.is_over(bounds); let is_hovered = cursor.is_over(bounds);
let Rectangle { let Rectangle {
x, x,
y, y,

View file

@ -4,10 +4,11 @@ use crate::futures::futures::channel::mpsc;
use iced_accessibility::accesskit::{ use iced_accessibility::accesskit::{
ActivationHandler, Node, NodeId, Role, Tree, TreeId, TreeUpdate, ActivationHandler, Node, NodeId, Role, Tree, TreeId, TreeUpdate,
}; };
use iced_accessibility::accesskit_winit::Adapter;
use iced_runtime::core; use iced_runtime::core;
pub struct WinitActivationHandler { pub struct WinitActivationHandler {
pub(crate) proxy: mpsc::UnboundedSender<Control>, pub proxy: mpsc::UnboundedSender<Control>,
pub title: String, pub title: String,
} }
@ -33,7 +34,7 @@ impl ActivationHandler for WinitActivationHandler {
pub struct WinitActionHandler { pub struct WinitActionHandler {
pub id: core::window::Id, pub id: core::window::Id,
pub(crate) proxy: mpsc::UnboundedSender<Control>, pub proxy: mpsc::UnboundedSender<Control>,
} }
impl iced_accessibility::accesskit::ActionHandler for WinitActionHandler { impl iced_accessibility::accesskit::ActionHandler for WinitActionHandler {
@ -48,7 +49,7 @@ impl iced_accessibility::accesskit::ActionHandler for WinitActionHandler {
} }
pub struct WinitDeactivationHandler { pub struct WinitDeactivationHandler {
pub(crate) proxy: mpsc::UnboundedSender<Control>, pub proxy: mpsc::UnboundedSender<Control>,
} }
impl iced_accessibility::accesskit::DeactivationHandler impl iced_accessibility::accesskit::DeactivationHandler

View file

@ -25,7 +25,7 @@ const DRAG_RESIZE_SUPPORTED: bool = false;
/// If supported by winit, returns a closure that implements cursor resize support. /// If supported by winit, returns a closure that implements cursor resize support.
pub fn event_func( pub fn event_func(
_window: &dyn winit::window::Window, window: &dyn winit::window::Window,
border_size: f64, border_size: f64,
) -> Option< ) -> Option<
Box< Box<

View file

@ -1,7 +1,7 @@
//! Access the clipboard. //! Access the clipboard.
use std::sync::Mutex; use std::sync::Mutex;
use std::borrow::Cow; use std::{any::Any, borrow::Cow};
use crate::Control; use crate::Control;

View file

@ -3,6 +3,9 @@
//! [`winit`]: https://github.com/rust-windowing/winit //! [`winit`]: https://github.com/rust-windowing/winit
//! [`iced_runtime`]: https://github.com/iced-rs/iced/tree/0.14/runtime //! [`iced_runtime`]: https://github.com/iced-rs/iced/tree/0.14/runtime
use crate::core::input_method; use crate::core::input_method;
use std::hash::DefaultHasher;
use std::hash::Hash;
use std::hash::Hasher;
use std::sync::Arc; use std::sync::Arc;
use crate::core::keyboard; use crate::core::keyboard;
@ -11,6 +14,7 @@ use crate::core::theme;
use crate::core::touch; use crate::core::touch;
use crate::core::window; use crate::core::window;
use crate::core::{Event, Point, Size}; use crate::core::{Event, Point, Size};
use iced_futures::core::event::PlatformSpecific;
use winit::dpi::PhysicalPosition; use winit::dpi::PhysicalPosition;
use winit::event::ButtonSource; use winit::event::ButtonSource;
use winit::event::ElementState; use winit::event::ElementState;
@ -23,7 +27,7 @@ use winit::keyboard::SmolStr;
pub fn window_attributes( pub fn window_attributes(
settings: window::Settings, settings: window::Settings,
title: &str, title: &str,
_scale_factor: f64, scale_factor: f64,
primary_monitor: Option<winit::monitor::MonitorHandle>, primary_monitor: Option<winit::monitor::MonitorHandle>,
_id: Option<String>, _id: Option<String>,
) -> winit::window::WindowAttributes { ) -> winit::window::WindowAttributes {
@ -392,8 +396,8 @@ pub fn window_event(
Ime::Commit(content) => input_method::Event::Commit(content), Ime::Commit(content) => input_method::Event::Commit(content),
Ime::Disabled => input_method::Event::Closed, Ime::Disabled => input_method::Event::Closed,
Ime::DeleteSurrounding { Ime::DeleteSurrounding {
before_bytes: _, before_bytes,
after_bytes: _, after_bytes,
} => todo!(), } => todo!(),
})), })),
WindowEvent::Focused(focused) => Some(Event::Window(if focused { WindowEvent::Focused(focused) => Some(Event::Window(if focused {
@ -407,7 +411,7 @@ pub fn window_event(
WindowEvent::DragDropped { paths, .. } => { WindowEvent::DragDropped { paths, .. } => {
Some(Event::Window(window::Event::FileDropped(paths.clone()))) Some(Event::Window(window::Event::FileDropped(paths.clone())))
} }
WindowEvent::DragLeft { position: _ } => { WindowEvent::DragLeft { position } => {
Some(Event::Window(window::Event::FilesHoveredLeft)) Some(Event::Window(window::Event::FilesHoveredLeft))
} }
@ -638,6 +642,10 @@ pub fn mouse_interaction(
Interaction::AllScroll => winit_core::cursor::CursorIcon::AllScroll, Interaction::AllScroll => winit_core::cursor::CursorIcon::AllScroll,
Interaction::ZoomIn => winit_core::cursor::CursorIcon::ZoomIn, Interaction::ZoomIn => winit_core::cursor::CursorIcon::ZoomIn,
Interaction::ZoomOut => winit_core::cursor::CursorIcon::ZoomOut, Interaction::ZoomOut => winit_core::cursor::CursorIcon::ZoomOut,
Interaction::Cell => winit_core::cursor::CursorIcon::Cell,
Interaction::Move => winit_core::cursor::CursorIcon::Move,
Interaction::Copy => winit_core::cursor::CursorIcon::Copy,
Interaction::Help => winit_core::cursor::CursorIcon::Help,
Interaction::Hidden => { Interaction::Hidden => {
return None; return None;
} }
@ -696,10 +704,10 @@ enum TouchInternal {
/// ///
/// [`winit`]: https://github.com/rust-windowing/winit /// [`winit`]: https://github.com/rust-windowing/winit
/// [`iced`]: https://github.com/iced-rs/iced/tree/0.12 /// [`iced`]: https://github.com/iced-rs/iced/tree/0.12
fn touch_event( pub fn touch_event(
finger: FingerId, finger: FingerId,
state: TouchInternal, state: TouchInternal,
_force: Option<Force>, force: Option<Force>,
position: Option<PhysicalPosition<f64>>, position: Option<PhysicalPosition<f64>>,
scale_factor: f64, scale_factor: f64,
) -> touch::Event { ) -> touch::Event {
@ -1073,7 +1081,6 @@ pub fn physical_key(
/// ///
/// [`winit`]: https://github.com/rust-windowing/winit /// [`winit`]: https://github.com/rust-windowing/winit
/// [`iced`]: https://github.com/iced-rs/iced/tree/0.12 /// [`iced`]: https://github.com/iced-rs/iced/tree/0.12
#[allow(deprecated)] // KeyCode::Super/Hyper/Turbo: legacy spec, no Meta variant in this enum
pub fn key_code( pub fn key_code(
key_code: winit::keyboard::KeyCode, key_code: winit::keyboard::KeyCode,
) -> Option<keyboard::key::Code> { ) -> Option<keyboard::key::Code> {
@ -1278,7 +1285,6 @@ pub fn key_code(
}) })
} }
#[allow(deprecated)] // KeyCode::Super/Hyper/Turbo: legacy spec, no Meta variant in this enum
pub fn winit_key_code( pub fn winit_key_code(
key_code: keyboard::key::Code, key_code: keyboard::key::Code,
) -> Option<winit::keyboard::KeyCode> { ) -> Option<winit::keyboard::KeyCode> {
@ -1589,10 +1595,7 @@ pub fn resize_direction(
} }
} }
// Fields are passed through to winit via `IconProvider: AsAny` for potential
// downcast; they are not read directly here.
#[derive(Debug)] #[derive(Debug)]
#[allow(dead_code)]
pub struct RawImage(Vec<u8>, Size<u32>); pub struct RawImage(Vec<u8>, Size<u32>);
impl IconProvider for RawImage {} impl IconProvider for RawImage {}
impl From<RawImage> for winit_core::icon::Icon { impl From<RawImage> for winit_core::icon::Icon {

View file

@ -53,6 +53,7 @@ mod window;
pub use clipboard::Clipboard; pub use clipboard::Clipboard;
pub use error::Error; pub use error::Error;
pub use proxy::Proxy; pub use proxy::Proxy;
use winit::dpi::LogicalSize;
use winit::dpi::PhysicalPosition; use winit::dpi::PhysicalPosition;
use winit::dpi::PhysicalSize; use winit::dpi::PhysicalSize;
@ -157,8 +158,7 @@ where
let (boot_sender, boot_receiver) = oneshot::channel(); let (boot_sender, boot_receiver) = oneshot::channel();
let (control_sender, control_receiver) = mpsc::unbounded(); let (control_sender, control_receiver) = mpsc::unbounded();
// Sender side currently not wired to a producer; receiver gets default. let (system_theme_sender, system_theme_receiver) = oneshot::channel();
let (_system_theme_sender, system_theme_receiver) = oneshot::channel();
let instance = Box::pin(run_instance::<P>( let instance = Box::pin(run_instance::<P>(
program, program,
@ -179,6 +179,9 @@ where
struct BootConfig { struct BootConfig {
sender: oneshot::Sender<()>, sender: oneshot::Sender<()>,
fonts: Vec<Cow<'static, [u8]>>,
graphics_settings: graphics::Settings,
is_wayland: bool,
} }
struct Runner<Message: 'static, F> { struct Runner<Message: 'static, F> {
instance: std::pin::Pin<Box<F>>, instance: std::pin::Pin<Box<F>>,
@ -188,7 +191,7 @@ where
sender: mpsc::UnboundedSender<Event<Message>>, sender: mpsc::UnboundedSender<Event<Message>>,
receiver: mpsc::UnboundedReceiver<Control>, receiver: mpsc::UnboundedReceiver<Control>,
error: Option<Error>, error: Option<Error>,
#[cfg(feature = "a11y")] system_theme: Option<oneshot::Sender<theme::Mode>>,
control_sender: mpsc::UnboundedSender<Control>, control_sender: mpsc::UnboundedSender<Control>,
#[cfg(feature = "a11y")] #[cfg(feature = "a11y")]
@ -205,13 +208,16 @@ where
context, context,
boot: Some(BootConfig { boot: Some(BootConfig {
sender: boot_sender, sender: boot_sender,
fonts: settings.fonts,
graphics_settings,
is_wayland,
}), }),
id: settings.id, id: settings.id,
sender: event_sender, sender: event_sender,
receiver: control_receiver, receiver: control_receiver,
#[cfg(feature = "a11y")]
control_sender: control_sender.clone(), control_sender: control_sender.clone(),
error: None, error: None,
system_theme: Some(system_theme_sender),
#[cfg(feature = "a11y")] #[cfg(feature = "a11y")]
adapters: Default::default(), adapters: Default::default(),
@ -314,7 +320,12 @@ where
event_loop: &dyn winit::event_loop::ActiveEventLoop, event_loop: &dyn winit::event_loop::ActiveEventLoop,
) { ) {
// create initial window // create initial window
let Some(BootConfig { sender }) = self.boot.take() let Some(BootConfig {
sender,
fonts,
graphics_settings,
is_wayland,
}) = self.boot.take()
else { else {
return; return;
}; };
@ -352,8 +363,6 @@ where
where where
F: Future<Output = ()>, F: Future<Output = ()>,
{ {
// TODO(yoda): migrate try_next → try_recv (futures-channel API change).
#[allow(deprecated)]
fn process_event( fn process_event(
&mut self, &mut self,
event_loop: &dyn winit::event_loop::ActiveEventLoop, event_loop: &dyn winit::event_loop::ActiveEventLoop,
@ -627,7 +636,10 @@ where
#[cfg(feature = "a11y")] #[cfg(feature = "a11y")]
fn init_adapter(&mut self, event_loop: &(dyn winit::event_loop::ActiveEventLoop + 'static), id: core::window::Id, window: Arc<dyn winit::window::Window + 'static>) { fn init_adapter(&mut self, event_loop: &(dyn winit::event_loop::ActiveEventLoop + 'static), id: core::window::Id, window: Arc<dyn winit::window::Window + 'static>) {
use crate::a11y::*; use crate::a11y::*;
use iced_accessibility::accesskit::{
ActivationHandler, Node, NodeId, Role,
Tree, TreeUpdate,
};
use iced_accessibility::accesskit_winit::Adapter; use iced_accessibility::accesskit_winit::Adapter;
let node_id = let node_id =
@ -681,7 +693,6 @@ where
} }
} }
#[allow(hidden_glob_reexports)] // intentional: internal Event shadows winit::event::Event from `pub use winit`
enum Event<Message: 'static> { enum Event<Message: 'static> {
WindowCreated { WindowCreated {
id: window::Id, id: window::Id,
@ -789,6 +800,9 @@ async fn run_instance<P>(
> = None; > = None;
let mut dnd_surface_id: Option<window::Id> = None; let mut dnd_surface_id: Option<window::Id> = None;
#[cfg(feature = "a11y")]
let mut a11y_enabled = false;
#[cfg(all(feature = "linux-theme-detection", target_os = "linux"))] #[cfg(all(feature = "linux-theme-detection", target_os = "linux"))]
let mut system_theme = { let mut system_theme = {
let to_mode = |color_scheme| match color_scheme { let to_mode = |color_scheme| match color_scheme {
@ -1381,6 +1395,7 @@ async fn run_instance<P>(
} }
let mut uis_stale = false; let mut uis_stale = false;
let mut resized = false;
for (id, window) in window_manager.iter_mut() { for (id, window) in window_manager.iter_mut() {
if skip && !window.resize_enabled { if skip && !window.resize_enabled {
continue; continue;
@ -1433,6 +1448,7 @@ async fn run_instance<P>(
// FIXME what to do when we are stuck in a configure event/resize request loop // FIXME what to do when we are stuck in a configure event/resize request loop
// We don't have control over how winit handles this. // We don't have control over how winit handles this.
window.resize_enabled = true; window.resize_enabled = true;
resized = true;
needs_redraw = true; needs_redraw = true;
let s = winit::dpi::Size::Logical( let s = winit::dpi::Size::Logical(
requested_size.cast(), requested_size.cast(),
@ -1647,8 +1663,8 @@ async fn run_instance<P>(
events.push((Some(id), conversion::a11y(action_request))); events.push((Some(id), conversion::a11y(action_request)));
} }
#[cfg(feature = "a11y")] #[cfg(feature = "a11y")]
Event::AccessibilityEnabled(_enabled) => { Event::AccessibilityEnabled(enabled) => {
// a11y enable signal currently unused at this layer a11y_enabled = enabled;
} }
Event::PlatformSpecific(e) => { Event::PlatformSpecific(e) => {
crate::platform_specific::handle_event( crate::platform_specific::handle_event(

View file

@ -1,11 +1,14 @@
//! Wayland specific shell //! Wayland specific shell
//! //!
use std::collections::HashMap; use std::{borrow::Cow, collections::HashMap, sync::Arc};
use iced_graphics::compositor; #[cfg(all(feature = "cctk", target_os = "linux"))]
use cctk::sctk::reexports::client::Connection;
use iced_graphics::{Compositor, compositor};
use iced_runtime::{ use iced_runtime::{
core::{Vector, window}, user_interface, core::{Vector, window},
platform_specific, user_interface,
}; };
use winit::raw_window_handle::HasWindowHandle; use winit::raw_window_handle::HasWindowHandle;
@ -14,6 +17,8 @@ pub mod wayland;
#[cfg(all(feature = "cctk", target_os = "linux"))] #[cfg(all(feature = "cctk", target_os = "linux"))]
pub use wayland::*; pub use wayland::*;
#[cfg(all(feature = "cctk", target_os = "linux"))]
use wayland_backend::client::Backend;
use crate::{CreateCompositor, Program, WindowManager}; use crate::{CreateCompositor, Program, WindowManager};
@ -148,12 +153,9 @@ impl PlatformSpecific {
) -> Option<Box<dyn HasWindowHandle + Send + Sync + 'static>> { ) -> Option<Box<dyn HasWindowHandle + Send + Sync + 'static>> {
#[cfg(all(feature = "cctk", target_os = "linux"))] #[cfg(all(feature = "cctk", target_os = "linux"))]
{ {
self.wayland.create_surface() return self.wayland.create_surface();
}
#[cfg(not(all(feature = "cctk", target_os = "linux")))]
{
None
} }
None
} }
pub(crate) fn update_surface_shm( pub(crate) fn update_surface_shm(

View file

@ -0,0 +1,56 @@
/// Set by the user callback given to the [`EventLoop::run`] method.
///
/// Indicates the desired behavior of the event loop after [`Event::RedrawEventsCleared`] is emitted.
///
/// Defaults to [`Poll`].
///
/// ## Persistency
///
/// Almost every change is persistent between multiple calls to the event loop closure within a
/// given run loop. The only exception to this is [`ExitWithCode`] which, once set, cannot be unset.
/// Changes are **not** persistent between multiple calls to `run_return` - issuing a new call will
/// reset the control flow to [`Poll`].
///
/// [`ExitWithCode`]: Self::ExitWithCode
/// [`Poll`]: Self::Poll
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ControlFlow {
/// When the current loop iteration finishes, immediately begin a new iteration regardless of
/// whether or not new events are available to process.
///
/// ## Platform-specific
///
/// - **Web:** Events are queued and usually sent when `requestAnimationFrame` fires but sometimes
/// the events in the queue may be sent before the next `requestAnimationFrame` callback, for
/// example when the scaling of the page has changed. This should be treated as an implementation
/// detail which should not be relied on.
Poll,
/// When the current loop iteration finishes, suspend the thread until another event arrives.
Wait,
/// When the current loop iteration finishes, suspend the thread until either another event
/// arrives or the given time is reached.
///
/// Useful for implementing efficient timers. Applications which want to render at the display's
/// native refresh rate should instead use [`Poll`] and the VSync functionality of a graphics API
/// to reduce odds of missed frames.
///
/// [`Poll`]: Self::Poll
WaitUntil(std::time::Instant),
/// Send a [`LoopDestroyed`] event and stop the event loop. This variant is *sticky* - once set,
/// `control_flow` cannot be changed from `ExitWithCode`, and any future attempts to do so will
/// result in the `control_flow` parameter being reset to `ExitWithCode`.
///
/// The contained number will be used as exit code. The [`Exit`] constant is a shortcut for this
/// with exit code 0.
///
/// ## Platform-specific
///
/// - **Android / iOS / WASM:** The supplied exit code is unused.
/// - **Unix:** On most Unix-like platforms, only the 8 least significant bits will be used,
/// which can cause surprises with negative exit values (`-42` would end up as `214`). See
/// [`std::process::exit`].
///
/// [`LoopDestroyed`]: Event::LoopDestroyed
/// [`Exit`]: ControlFlow::Exit
ExitWithCode(i32),
}

View file

@ -1,5 +1,9 @@
pub mod control_flow;
pub mod proxy;
pub mod state; pub mod state;
#[cfg(feature = "a11y")]
use crate::platform_specific::SurfaceIdWrapper;
use crate::{ use crate::{
Control, Control,
futures::futures::channel::mpsc, futures::futures::channel::mpsc,
@ -29,7 +33,7 @@ use cctk::{
reexports::{ reexports::{
calloop::{self, EventLoop}, calloop::{self, EventLoop},
client::{ client::{
Connection, Proxy, globals::registry_queue_init, ConnectError, Connection, Proxy, globals::registry_queue_init,
}, },
}, },
registry::RegistryState, registry::RegistryState,
@ -42,6 +46,8 @@ use cctk::{
}; };
use raw_window_handle::HasDisplayHandle; use raw_window_handle::HasDisplayHandle;
use state::{FrameStatus, SctkWindow, send_event}; use state::{FrameStatus, SctkWindow, send_event};
#[cfg(feature = "a11y")]
use std::sync::{Arc, Mutex};
use std::{ use std::{
collections::{HashMap, HashSet}, collections::{HashMap, HashSet},
fmt::Debug, fmt::Debug,
@ -65,8 +71,8 @@ pub struct SctkEventLoop {
pub(crate) state: SctkState, pub(crate) state: SctkState,
} }
#[allow(dead_code)] // payloads kept for Debug; not inspected programmatically
pub enum Error { pub enum Error {
Connect(ConnectError),
Calloop(calloop::Error), Calloop(calloop::Error),
Global(GlobalError), Global(GlobalError),
NoDisplayHandle, NoDisplayHandle,

View file

@ -0,0 +1,66 @@
use cctk::sctk::reexports::calloop;
use iced_futures::futures::{
channel::mpsc,
task::{Context, Poll},
Sink,
};
use std::pin::Pin;
/// An event loop proxy that implements `Sink`.
#[derive(Debug)]
pub struct Proxy<Message: 'static> {
raw: calloop::channel::Sender<Message>,
}
impl<Message: 'static> Clone for Proxy<Message> {
fn clone(&self) -> Self {
Self {
raw: self.raw.clone(),
}
}
}
impl<Message: 'static> Proxy<Message> {
/// Creates a new [`Proxy`] from an `EventLoopProxy`.
pub fn new(raw: calloop::channel::Sender<Message>) -> Self {
Self { raw }
}
/// send an event
pub fn send_event(&self, message: Message) {
let _ = self.raw.send(message);
}
}
impl<Message: 'static> Sink<Message> for Proxy<Message> {
type Error = mpsc::SendError;
fn poll_ready(
self: Pin<&mut Self>,
_cx: &mut Context<'_>,
) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}
fn start_send(
self: Pin<&mut Self>,
message: Message,
) -> Result<(), Self::Error> {
let _ = self.raw.send(message);
Ok(())
}
fn poll_flush(
self: Pin<&mut Self>,
_cx: &mut Context<'_>,
) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}
fn poll_close(
self: Pin<&mut Self>,
_cx: &mut Context<'_>,
) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}
}

View file

@ -30,11 +30,12 @@ use std::{
convert::Infallible, convert::Infallible,
fmt::Debug, fmt::Debug,
sync::{Arc, Mutex, atomic::AtomicU32}, sync::{Arc, Mutex, atomic::AtomicU32},
thread::panicking,
time::Duration, time::Duration,
}; };
use wayland_backend::client::ObjectId; use wayland_backend::client::ObjectId;
use winit::{ use winit::{
dpi::LogicalSize, dpi::{LogicalPosition, LogicalSize},
platform::wayland::WindowExtWayland, platform::wayland::WindowExtWayland,
}; };
@ -50,6 +51,7 @@ use cctk::{
activation::{ActivationState, RequestData}, activation::{ActivationState, RequestData},
compositor::CompositorState, compositor::CompositorState,
error::GlobalError, error::GlobalError,
globals::GlobalData,
output::OutputState, output::OutputState,
reexports::{ reexports::{
calloop::{LoopHandle, timer::TimeoutAction}, calloop::{LoopHandle, timer::TimeoutAction},
@ -231,6 +233,9 @@ impl CommonSurface {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Common { pub struct Common {
pub(crate) fractional_scale: Option<f64>, pub(crate) fractional_scale: Option<f64>,
pub(crate) has_focus: bool,
pub(crate) ime_pos: LogicalPosition<u32>,
pub(crate) ime_size: LogicalSize<u32>,
pub(crate) size: LogicalSize<u32>, pub(crate) size: LogicalSize<u32>,
pub(crate) requested_size: (Option<u32>, Option<u32>), pub(crate) requested_size: (Option<u32>, Option<u32>),
pub(crate) wp_viewport: Option<WpViewport>, pub(crate) wp_viewport: Option<WpViewport>,
@ -240,6 +245,9 @@ impl Default for Common {
fn default() -> Self { fn default() -> Self {
Self { Self {
fractional_scale: Default::default(), fractional_scale: Default::default(),
has_focus: Default::default(),
ime_pos: Default::default(),
ime_size: Default::default(),
size: LogicalSize::new(1, 1), size: LogicalSize::new(1, 1),
requested_size: (None, None), requested_size: (None, None),
wp_viewport: None, wp_viewport: None,
@ -332,6 +340,7 @@ pub struct SctkPopupData {
pub(crate) parent: PopupParent, pub(crate) parent: PopupParent,
pub(crate) toplevel: WlSurface, pub(crate) toplevel: WlSurface,
pub(crate) positioner: Arc<XdgPositioner>, pub(crate) positioner: Arc<XdgPositioner>,
pub(crate) grab: bool,
} }
#[derive(Debug)] #[derive(Debug)]
@ -872,6 +881,7 @@ impl SctkState {
parent: parent.clone(), parent: parent.clone(),
toplevel: toplevel.clone(), toplevel: toplevel.clone(),
positioner: positioner.clone(), positioner: positioner.clone(),
grab: settings.grab,
}, },
last_configure: None, last_configure: None,
_pending_requests: Default::default(), _pending_requests: Default::default(),
@ -1256,7 +1266,7 @@ impl SctkState {
let timer = cctk::sctk::reexports::calloop::timer::Timer::from_duration(Duration::from_millis(30)); let timer = cctk::sctk::reexports::calloop::timer::Timer::from_duration(Duration::from_millis(30));
let queue_handle = self.queue_handle.clone(); let queue_handle = self.queue_handle.clone();
_ = self.loop_handle.insert_source(timer, move |_, _, state| { _ = self.loop_handle.insert_source(timer, move |_, _, state| {
let Some((popup, attempt)) = state.pending_popup.take() else { let Some((mut popup, attempt)) = state.pending_popup.take() else {
return TimeoutAction::Drop; return TimeoutAction::Drop;
}; };
@ -1531,6 +1541,7 @@ impl SctkState {
SctkEvent::SubsurfaceEvent (crate::sctk_event::SubsurfaceEventVariant::Created{ SctkEvent::SubsurfaceEvent (crate::sctk_event::SubsurfaceEventVariant::Created{
parent_id, parent_id,
parent, parent,
surface: subsurface,
qh: self.queue_handle.clone(), qh: self.queue_handle.clone(),
common_surface, common_surface,
surface_id: subsurface_settings.id, surface_id: subsurface_settings.id,

View file

@ -3,6 +3,7 @@ use cctk::sctk::{
delegate_activation, delegate_activation,
reexports::client::protocol::{wl_seat::WlSeat, wl_surface::WlSurface}, reexports::client::protocol::{wl_seat::WlSeat, wl_surface::WlSurface},
}; };
use iced_futures::futures::channel::oneshot::Sender;
use crate::platform_specific::wayland::event_loop::state::SctkState; use crate::platform_specific::wayland::event_loop::state::SctkState;

View file

@ -18,7 +18,7 @@ impl SeatHandler for SctkState {
fn new_seat( fn new_seat(
&mut self, &mut self,
_conn: &cctk::sctk::reexports::client::Connection, _conn: &cctk::sctk::reexports::client::Connection,
_qh: &cctk::sctk::reexports::client::QueueHandle<Self>, qh: &cctk::sctk::reexports::client::QueueHandle<Self>,
seat: cctk::sctk::reexports::client::protocol::wl_seat::WlSeat, seat: cctk::sctk::reexports::client::protocol::wl_seat::WlSeat,
) { ) {
self.sctk_events.push(SctkEvent::SeatEvent { self.sctk_events.push(SctkEvent::SeatEvent {

View file

@ -1,13 +1,17 @@
use cctk::{sctk, cosmic_protocols::corner_radius::v1::client::{ use cctk::{sctk, cosmic_protocols::{
corner_radius::v1::client::{
cosmic_corner_radius_manager_v1::CosmicCornerRadiusManagerV1, cosmic_corner_radius_manager_v1::CosmicCornerRadiusManagerV1,
cosmic_corner_radius_toplevel_v1::CosmicCornerRadiusToplevelV1, cosmic_corner_radius_toplevel_v1::CosmicCornerRadiusToplevelV1,
}}; },
overlap_notify::v1::client::zcosmic_overlap_notification_v1::ZcosmicOverlapNotificationV1,
}};
use sctk::reexports::{ use sctk::reexports::{
client::{Connection, Dispatch, Proxy}, client::{Connection, Dispatch, Proxy},
}; };
use crate::event_loop::state::SctkState; use crate::event_loop::state::SctkState;
use crate::platform_specific::wayland::SctkEvent;
impl Dispatch<CosmicCornerRadiusManagerV1, ()> for SctkState { impl Dispatch<CosmicCornerRadiusManagerV1, ()> for SctkState {
fn event( fn event(
@ -27,7 +31,7 @@ impl
> for SctkState > for SctkState
{ {
fn event( fn event(
_state: &mut Self, state: &mut Self,
_proxy: &CosmicCornerRadiusToplevelV1, _proxy: &CosmicCornerRadiusToplevelV1,
event: <CosmicCornerRadiusToplevelV1 as Proxy>::Event, event: <CosmicCornerRadiusToplevelV1 as Proxy>::Event,
_data: &(), _data: &(),

View file

@ -16,9 +16,10 @@ use cctk::sctk::reexports::client::protocol::wl_surface::WlSurface;
use cctk::sctk::seat::keyboard::Modifiers; use cctk::sctk::seat::keyboard::Modifiers;
use cursor_icon::CursorIcon; use cursor_icon::CursorIcon;
use iced_futures::futures::channel::mpsc; use iced_futures::futures::channel::mpsc;
use iced_graphics::compositor; use iced_graphics::{Compositor, compositor};
use iced_runtime::core::{Vector, window}; use iced_runtime::core::{Vector, window};
use raw_window_handle::{HasDisplayHandle, HasWindowHandle, RawWindowHandle}; use raw_window_handle::{DisplayHandle, HasDisplayHandle, HasWindowHandle};
use raw_window_handle::{HasRawDisplayHandle, RawWindowHandle};
use sctk_event::SctkEvent; use sctk_event::SctkEvent;
use std::{collections::HashMap, sync::Arc}; use std::{collections::HashMap, sync::Arc};
use subsurface_widget::{SubsurfaceInstance, SubsurfaceState}; use subsurface_widget::{SubsurfaceInstance, SubsurfaceState};
@ -105,7 +106,7 @@ impl PlatformSpecific {
display: OwnedDisplayHandle, display: OwnedDisplayHandle,
) -> Self { ) -> Self {
self.wayland.winit_event_sender = Some(tx); self.wayland.winit_event_sender = Some(tx);
self.wayland.conn = match display.display_handle().map(|h| h.as_raw()) { self.wayland.conn = match display.raw_display_handle() {
Ok(raw_window_handle::RawDisplayHandle::Wayland( Ok(raw_window_handle::RawDisplayHandle::Wayland(
wayland_display_handle, wayland_display_handle,
)) => { )) => {
@ -188,12 +189,12 @@ impl WaylandSpecific {
winit_event_sender, winit_event_sender,
proxy, proxy,
sender, sender,
display_handle: _, display_handle,
conn: _, conn,
surface_ids, surface_ids,
modifiers, modifiers,
subsurface_state, subsurface_state,
surface_subsurfaces: _, surface_subsurfaces,
} = self; } = self;
match e { match e {
@ -236,7 +237,7 @@ impl WaylandSpecific {
&mut self, &mut self,
keep: F, keep: F,
) { ) {
self.surface_subsurfaces.retain(|k, _v| keep(*k)) self.surface_subsurfaces.retain(|k, v| keep(*k))
} }
pub(crate) fn clear_subsurface_list(&mut self) { pub(crate) fn clear_subsurface_list(&mut self) {
@ -249,7 +250,7 @@ impl WaylandSpecific {
wl_surface: &WlSurface, wl_surface: &WlSurface,
) { ) {
let subsurfaces = crate::subsurface_widget::take_subsurfaces(); let subsurfaces = crate::subsurface_widget::take_subsurfaces();
let entry = self.surface_subsurfaces.entry(id); let mut entry = self.surface_subsurfaces.entry(id);
let surface_subsurfaces = entry.or_default(); let surface_subsurfaces = entry.or_default();
let Some(subsurface_state) = self.subsurface_state.as_mut() else { let Some(subsurface_state) = self.subsurface_state.as_mut() else {
return; return;

View file

@ -4,7 +4,7 @@ use crate::{
SurfaceIdWrapper, UserInterfaces, SurfaceIdWrapper, UserInterfaces,
wayland::{ wayland::{
conversion::{ conversion::{
modifiers_to_native, modifiers_to_native, pointer_axis_to_native,
pointer_button_to_native, pointer_button_to_native,
}, },
keymap::{self, keysym_to_key}, keymap::{self, keysym_to_key},
@ -25,9 +25,10 @@ use iced_futures::{
}, },
}, },
}, },
event,
futures::{SinkExt, channel::mpsc}, futures::{SinkExt, channel::mpsc},
}; };
use iced_graphics::compositor; use iced_graphics::{Compositor, compositor};
use iced_runtime::{ use iced_runtime::{
core::{ core::{
Point, Point,
@ -39,7 +40,9 @@ use iced_runtime::{
user_interface, user_interface,
}; };
use cctk::sctk::{ use cctk::{
cosmic_protocols::overlap_notify::v1::client::zcosmic_overlap_notification_v1,
sctk::{
output::OutputInfo, output::OutputInfo,
reexports::{ reexports::{
calloop::channel, calloop::channel,
@ -64,8 +67,11 @@ use cctk::sctk::{
wlr_layer::{Layer, LayerSurfaceConfigure}, wlr_layer::{Layer, LayerSurfaceConfigure},
xdg::{popup::PopupConfigure, window::WindowConfigure}, xdg::{popup::PopupConfigure, window::WindowConfigure},
}, },
}; },
wayland_client::protocol::wl_subsurface::WlSubsurface,
};
use std::{ use std::{
any::Any,
collections::HashMap, collections::HashMap,
num::NonZeroU32, num::NonZeroU32,
sync::{Arc, Mutex}, sync::{Arc, Mutex},
@ -282,6 +288,7 @@ pub enum SubsurfaceEventVariant {
Created { Created {
parent_id: window::Id, parent_id: window::Id,
parent: WlSurface, parent: WlSurface,
surface: WlSurface,
qh: QueueHandle<SctkState>, qh: QueueHandle<SctkState>,
common_surface: CommonSurface, common_surface: CommonSurface,
surface_id: SurfaceId, surface_id: SurfaceId,
@ -509,7 +516,7 @@ impl SctkEvent {
), ),
), ),
), ),
SurfaceIdWrapper::Window(_id) => { SurfaceIdWrapper::Window(id) => {
Some(iced_runtime::core::Event::Window( Some(iced_runtime::core::Event::Window(
window::Event::Unfocused, window::Event::Unfocused,
)) ))
@ -537,7 +544,7 @@ impl SctkEvent {
), ),
), ),
), ),
SurfaceIdWrapper::Subsurface(_id) => None, SurfaceIdWrapper::Subsurface(id) => None,
}) })
{ {
events.push(( events.push((
@ -571,7 +578,7 @@ impl SctkEvent {
), ),
), ),
), ),
SurfaceIdWrapper::Window(_id) => { SurfaceIdWrapper::Window(id) => {
Some(iced_runtime::core::Event::Window( Some(iced_runtime::core::Event::Window(
window::Event::Focused, window::Event::Focused,
)) ))
@ -1508,6 +1515,7 @@ impl SctkEvent {
common, common,
z, z,
parent, parent,
surface: _,
qh, qh,
surface_id, surface_id,
display, display,

View file

@ -57,7 +57,9 @@ use wayland_protocols::wp::{
}; };
use winit::window::WindowId; use winit::window::WindowId;
use crate::platform_specific::event_loop::state::SctkState; use crate::platform_specific::{
SurfaceIdWrapper, event_loop::state::SctkState,
};
#[derive(Debug)] #[derive(Debug)]
pub struct Plane { pub struct Plane {
@ -407,10 +409,7 @@ impl SubsurfaceState {
.unwrap(); .unwrap();
canvas[0..width as usize * height as usize * 4].copy_from_slice(data); canvas[0..width as usize * height as usize * 4].copy_from_slice(data);
surface.damage_buffer(0, 0, width as i32, height as i32); surface.damage_buffer(0, 0, width as i32, height as i32);
if let Err(err) = buffer.attach_to(&surface) { buffer.attach_to(&surface);
log::warn!("failed to attach shm buffer to subsurface: {err}");
return;
}
surface.offset(offset.x as i32, offset.y as i32); surface.offset(offset.x as i32, offset.y as i32);
wp_viewport.set_destination( wp_viewport.set_destination(
(width as f64 / scale) as i32, (width as f64 / scale) as i32,
@ -623,7 +622,7 @@ impl Drop for SubsurfaceState {
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct SubsurfaceInstance { pub(crate) struct SubsurfaceInstance {
pub(crate) wl_surface: WlSurface, pub(crate) wl_surface: WlSurface,
pub(crate) wl_subsurface: WlSubsurface, pub(crate) wl_subsurface: WlSubsurface,
pub(crate) wp_viewport: WpViewport, pub(crate) wp_viewport: WpViewport,

View file

@ -1,9 +1,9 @@
use crate::platform_specific::wayland::Action; use crate::platform_specific::wayland::Action;
use cctk::sctk::reexports::{ use cctk::sctk::reexports::{
calloop::channel, calloop::{LoopHandle, channel},
client::{ client::{
Proxy, QueueHandle, Proxy, QueueHandle,
protocol::wl_display::WlDisplay, protocol::{wl_display::WlDisplay, wl_surface::WlSurface},
}, },
}; };
use raw_window_handle::HandleError; use raw_window_handle::HandleError;
@ -91,7 +91,7 @@ impl winit::window::Window for SctkWinitWindow {
} }
} }
fn set_cursor_visible(&self, _visible: bool) { fn set_cursor_visible(&self, visible: bool) {
// TODO // TODO
} }
@ -203,35 +203,35 @@ impl winit::window::Window for SctkWinitWindow {
// TODO refer to winit for implementation // TODO refer to winit for implementation
} }
fn set_outer_position(&self, _position: winit::dpi::Position) {} fn set_outer_position(&self, position: winit::dpi::Position) {}
fn outer_size(&self) -> winit::dpi::PhysicalSize<u32> { fn outer_size(&self) -> winit::dpi::PhysicalSize<u32> {
// XXX not applicable to wrapped surfaces // XXX not applicable to wrapped surfaces
Default::default() Default::default()
} }
fn set_min_surface_size(&self, _min_size: Option<winit::dpi::Size>) { fn set_min_surface_size(&self, min_size: Option<winit::dpi::Size>) {
// XXX not applicable to wrapped surfaces // XXX not applicable to wrapped surfaces
} }
fn set_max_surface_size(&self, _max_size: Option<winit::dpi::Size>) { fn set_max_surface_size(&self, max_size: Option<winit::dpi::Size>) {
// XXX not applicable to wrapped surfaces // XXX not applicable to wrapped surfaces
} }
fn set_surface_resize_increments( fn set_surface_resize_increments(
&self, &self,
_increments: Option<winit::dpi::Size>, increments: Option<winit::dpi::Size>,
) { ) {
log::warn!( log::warn!(
"`set_surface_resize_increments` is not implemented for Wayland" "`set_surface_resize_increments` is not implemented for Wayland"
) )
} }
fn set_title(&self, _title: &str) { fn set_title(&self, title: &str) {
// XXX not applicable to wrapped surfaces // XXX not applicable to wrapped surfaces
} }
fn set_transparent(&self, _transparent: bool) { fn set_transparent(&self, transparent: bool) {
todo!() todo!()
} }
@ -304,19 +304,19 @@ impl winit::window::Window for SctkWinitWindow {
)); ));
} }
fn set_visible(&self, _visible: bool) {} fn set_visible(&self, visible: bool) {}
fn is_visible(&self) -> Option<bool> { fn is_visible(&self) -> Option<bool> {
None None
} }
fn set_resizable(&self, _resizable: bool) {} fn set_resizable(&self, resizable: bool) {}
fn is_resizable(&self) -> bool { fn is_resizable(&self) -> bool {
false false
} }
fn set_enabled_buttons(&self, _buttons: winit::window::WindowButtons) { fn set_enabled_buttons(&self, buttons: winit::window::WindowButtons) {
// TODO v5 of xdg_shell. // TODO v5 of xdg_shell.
} }
@ -324,7 +324,7 @@ impl winit::window::Window for SctkWinitWindow {
WindowButtons::all() WindowButtons::all()
} }
fn set_minimized(&self, _minimized: bool) { fn set_minimized(&self, minimized: bool) {
// XXX not applicable to the wrapped surfaces // XXX not applicable to the wrapped surfaces
} }
@ -333,7 +333,7 @@ impl winit::window::Window for SctkWinitWindow {
None None
} }
fn set_maximized(&self, _maximized: bool) { fn set_maximized(&self, maximized: bool) {
// XXX can't minimize the wrapped surfaces // XXX can't minimize the wrapped surfaces
} }
@ -344,7 +344,7 @@ impl winit::window::Window for SctkWinitWindow {
fn set_fullscreen( fn set_fullscreen(
&self, &self,
_fullscreen: Option<winit_core::monitor::Fullscreen>, fullscreen: Option<winit_core::monitor::Fullscreen>,
) { ) {
// XXX can't fullscreen the wrapped surfaces // XXX can't fullscreen the wrapped surfaces
} }
@ -354,7 +354,7 @@ impl winit::window::Window for SctkWinitWindow {
None None
} }
fn set_decorations(&self, _decorations: bool) { fn set_decorations(&self, decorations: bool) {
// XXX no decorations supported for the wrapped surfaces // XXX no decorations supported for the wrapped surfaces
} }
@ -362,26 +362,26 @@ impl winit::window::Window for SctkWinitWindow {
false false
} }
fn set_window_level(&self, _level: winit::window::WindowLevel) {} fn set_window_level(&self, level: winit::window::WindowLevel) {}
fn set_window_icon(&self, _window_icon: Option<winit_core::icon::Icon>) {} fn set_window_icon(&self, window_icon: Option<winit_core::icon::Icon>) {}
fn focus_window(&self) {} fn focus_window(&self) {}
fn request_user_attention( fn request_user_attention(
&self, &self,
_request_type: Option<winit::window::UserAttentionType>, request_type: Option<winit::window::UserAttentionType>,
) { ) {
// XXX can't request attention on wrapped surfaces // XXX can't request attention on wrapped surfaces
} }
fn set_theme(&self, _theme: Option<winit::window::Theme>) {} fn set_theme(&self, theme: Option<winit::window::Theme>) {}
fn theme(&self) -> Option<winit::window::Theme> { fn theme(&self) -> Option<winit::window::Theme> {
None None
} }
fn set_content_protected(&self, _protected: bool) {} fn set_content_protected(&self, protected: bool) {}
fn title(&self) -> String { fn title(&self) -> String {
String::new() String::new()
@ -434,14 +434,14 @@ impl winit::window::Window for SctkWinitWindow {
fn set_cursor_position( fn set_cursor_position(
&self, &self,
_position: winit::dpi::Position, position: winit::dpi::Position,
) -> Result<(), winit::error::RequestError> { ) -> Result<(), winit::error::RequestError> {
todo!() todo!()
} }
fn set_cursor_grab( fn set_cursor_grab(
&self, &self,
_mode: winit::window::CursorGrabMode, mode: winit::window::CursorGrabMode,
) -> Result<(), winit::error::RequestError> { ) -> Result<(), winit::error::RequestError> {
todo!() todo!()
} }
@ -452,7 +452,7 @@ impl winit::window::Window for SctkWinitWindow {
fn request_ime_update( fn request_ime_update(
&self, &self,
_request: winit::window::ImeRequest, request: winit::window::ImeRequest,
) -> Result<(), winit::window::ImeRequestError> { ) -> Result<(), winit::window::ImeRequestError> {
todo!() todo!()
} }

View file

@ -8,6 +8,7 @@ use crate::futures::futures::{
use crate::graphics::shell; use crate::graphics::shell;
use crate::runtime::Action; use crate::runtime::Action;
use crate::runtime::window; use crate::runtime::window;
use std::hash::DefaultHasher;
use std::pin::Pin; use std::pin::Pin;
/// An event loop proxy with backpressure that implements `Sink`. /// An event loop proxy with backpressure that implements `Sink`.
@ -33,7 +34,7 @@ impl<T: 'static> Proxy<T> {
const MAX_SIZE: usize = 100; const MAX_SIZE: usize = 100;
/// Creates a new [`Proxy`] from an `EventLoopProxy`. /// Creates a new [`Proxy`] from an `EventLoopProxy`.
pub(crate) fn new( pub fn new(
raw: winit::event_loop::EventLoopProxy, raw: winit::event_loop::EventLoopProxy,
event_sender: mpsc::UnboundedSender<Event<T>>, event_sender: mpsc::UnboundedSender<Event<T>>,
) -> (Self, impl Future<Output = ()>) { ) -> (Self, impl Future<Output = ()>) {

View file

@ -14,7 +14,7 @@ use crate::core::text;
use crate::core::theme::{self, Base}; use crate::core::theme::{self, Base};
use crate::core::time::Instant; use crate::core::time::Instant;
use crate::core::{ use crate::core::{
Color, InputMethod, Padding, Point, Rectangle, Size, Text, Vector, Color, Element, InputMethod, Padding, Point, Rectangle, Size, Text, Vector,
}; };
use crate::graphics::Compositor; use crate::graphics::Compositor;
use crate::program::{self, Program}; use crate::program::{self, Program};
@ -26,6 +26,10 @@ use winit::monitor::MonitorHandle;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::sync::Arc; use std::sync::Arc;
pub(crate) type ViewFn<M, T, R> = Arc<
Box<dyn Fn() -> Option<Element<'static, M, T, R>> + Send + Sync + 'static>,
>;
pub struct WindowManager<P, C> pub struct WindowManager<P, C>
where where
P: Program, P: Program,
@ -321,10 +325,6 @@ where
} }
} }
// TODO(yoda): migrate to Window::request_ime_update(ImeRequest::*).
// Legacy set_ime_* still functional but deprecated; full migration
// requires ImeCapabilities + ImeRequestData reshape.
#[allow(deprecated)]
fn enable_ime( fn enable_ime(
&mut self, &mut self,
cursor: Rectangle, cursor: Rectangle,
@ -355,7 +355,6 @@ where
} }
} }
#[allow(deprecated)] // see TODO on enable_ime
fn disable_ime(&mut self) { fn disable_ime(&mut self) {
if self.ime_state.is_some() { if self.ime_state.is_some() {
self.raw.set_ime_allowed(false); self.raw.set_ime_allowed(false);

View file

@ -97,7 +97,6 @@ where
self.ready = ready; self.ready = ready;
} }
#[cfg(feature = "a11y")]
pub(crate) fn set_a11y_ready(&mut self, ready: bool) { pub(crate) fn set_a11y_ready(&mut self, ready: bool) {
self.a11y_ready = ready; self.a11y_ready = ready;
} }