chore: Upgrade to latest libcosmic
This commit is contained in:
parent
1d51da4ed3
commit
20f4dcb466
5 changed files with 910 additions and 653 deletions
1225
Cargo.lock
generated
1225
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -30,8 +30,11 @@ libsystemd = { version = "0.5", optional = true }
|
||||||
wayland-backend = "0.1.0"
|
wayland-backend = "0.1.0"
|
||||||
wayland-scanner = "0.30.0"
|
wayland-scanner = "0.30.0"
|
||||||
cosmic-protocols = { git = "https://github.com/pop-os/cosmic-protocols", branch = "main", default-features = false, features = ["server"] }
|
cosmic-protocols = { git = "https://github.com/pop-os/cosmic-protocols", branch = "main", default-features = false, features = ["server"] }
|
||||||
libcosmic = { git = "https://github.com/pop-os/libcosmic", rev = "24709e9c3b", default-features = false, features = ["softbuffer"] }
|
libcosmic = { git = "https://github.com/pop-os/libcosmic", rev = "31f7e97d5b", default-features = false, features = ["tiny_skia"] }
|
||||||
iced_softbuffer = { git = "https://github.com/pop-os/libcosmic", rev = "24709e9c3b" }
|
iced_core = { git = "https://github.com/pop-os/libcosmic", rev = "31f7e97d5b" }
|
||||||
|
iced_renderer = { git = "https://github.com/pop-os/libcosmic", rev = "31f7e97d5b" }
|
||||||
|
iced_tiny_skia = { git = "https://github.com/pop-os/libcosmic", rev = "31f7e97d5b" }
|
||||||
|
tiny-skia = "0.9"
|
||||||
ordered-float = "3.0"
|
ordered-float = "3.0"
|
||||||
glow = "0.11.2"
|
glow = "0.11.2"
|
||||||
tracing-subscriber = { version = "0.3.16", features = ["env-filter", "tracing-log"] }
|
tracing-subscriber = { version = "0.3.16", features = ["env-filter", "tracing-log"] }
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@ pub struct CosmicStackInternal {
|
||||||
pointer_entered: Option<Arc<AtomicU8>>,
|
pointer_entered: Option<Arc<AtomicU8>>,
|
||||||
previous_pointer: Arc<AtomicUsize>,
|
previous_pointer: Arc<AtomicUsize>,
|
||||||
last_location: Arc<Mutex<Option<(Point<f64, Logical>, Serial, u32)>>>,
|
last_location: Arc<Mutex<Option<(Point<f64, Logical>, Serial, u32)>>>,
|
||||||
|
mask: Arc<Mutex<Option<tiny_skia::Mask>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CosmicStackInternal {
|
impl CosmicStackInternal {
|
||||||
|
|
@ -110,6 +111,7 @@ impl CosmicStack {
|
||||||
pointer_entered: None,
|
pointer_entered: None,
|
||||||
previous_pointer: Arc::new(AtomicUsize::new(0)),
|
previous_pointer: Arc::new(AtomicUsize::new(0)),
|
||||||
last_location: Arc::new(Mutex::new(None)),
|
last_location: Arc::new(Mutex::new(None)),
|
||||||
|
mask: Arc::new(Mutex::new(None)),
|
||||||
},
|
},
|
||||||
(width, TAB_HEIGHT),
|
(width, TAB_HEIGHT),
|
||||||
handle,
|
handle,
|
||||||
|
|
@ -273,6 +275,50 @@ impl Program for CosmicStackInternal {
|
||||||
fn view(&self) -> Element<'_, Self::Message> {
|
fn view(&self) -> Element<'_, Self::Message> {
|
||||||
cosmic::iced::widget::text("TODO").into()
|
cosmic::iced::widget::text("TODO").into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn clip_mask(&self, size: Size<i32, smithay::utils::Buffer>, scale: f32) -> tiny_skia::Mask {
|
||||||
|
let mut mask = self.mask.lock().unwrap();
|
||||||
|
if mask.is_none() {
|
||||||
|
let mut new_mask = tiny_skia::Mask::new(size.w as u32, size.h as u32).unwrap();
|
||||||
|
|
||||||
|
let mut pb = tiny_skia::PathBuilder::new();
|
||||||
|
let radius = 8. * scale;
|
||||||
|
let (w, h) = (size.w as f32, size.h as f32);
|
||||||
|
|
||||||
|
pb.move_to(0., h); // lower-left
|
||||||
|
|
||||||
|
// upper-left rounded corner
|
||||||
|
pb.line_to(0., radius);
|
||||||
|
pb.quad_to(0., 0., radius, 0.);
|
||||||
|
|
||||||
|
// upper-right rounded corner
|
||||||
|
pb.line_to(w - radius, 0.);
|
||||||
|
pb.quad_to(w, 0., w, radius);
|
||||||
|
|
||||||
|
pb.line_to(w, h); // lower-right
|
||||||
|
|
||||||
|
let path = pb.finish().unwrap();
|
||||||
|
new_mask.fill_path(
|
||||||
|
&path,
|
||||||
|
tiny_skia::FillRule::EvenOdd,
|
||||||
|
true,
|
||||||
|
Default::default(),
|
||||||
|
);
|
||||||
|
|
||||||
|
*mask = Some(new_mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
mask.clone().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn background_color(&self) -> iced_core::Color {
|
||||||
|
iced_core::Color {
|
||||||
|
r: 0.1176,
|
||||||
|
g: 0.1176,
|
||||||
|
b: 0.1176,
|
||||||
|
a: 1.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IsAlive for CosmicStack {
|
impl IsAlive for CosmicStack {
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,8 @@ use crate::{
|
||||||
wayland::handlers::screencopy::ScreencopySessions,
|
wayland::handlers::screencopy::ScreencopySessions,
|
||||||
};
|
};
|
||||||
use calloop::LoopHandle;
|
use calloop::LoopHandle;
|
||||||
use cosmic::iced_native::Command;
|
use cosmic::iced::Command;
|
||||||
use cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_session_v1::InputType;
|
use cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_session_v1::InputType;
|
||||||
use iced_softbuffer::native::raqote::{DrawOptions, DrawTarget, PathBuilder, SolidSource, Source};
|
|
||||||
use smithay::{
|
use smithay::{
|
||||||
backend::{
|
backend::{
|
||||||
input::KeyState,
|
input::KeyState,
|
||||||
|
|
@ -35,7 +34,10 @@ use smithay::{
|
||||||
Seat,
|
Seat,
|
||||||
},
|
},
|
||||||
output::Output,
|
output::Output,
|
||||||
utils::{IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size, Transform},
|
utils::{
|
||||||
|
Buffer as BufferCoords, IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size,
|
||||||
|
Transform,
|
||||||
|
},
|
||||||
wayland::seat::WaylandFocus,
|
wayland::seat::WaylandFocus,
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
|
|
@ -65,6 +67,7 @@ impl fmt::Debug for CosmicWindow {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct CosmicWindowInternal {
|
pub struct CosmicWindowInternal {
|
||||||
pub(super) window: CosmicSurface,
|
pub(super) window: CosmicSurface,
|
||||||
|
mask: Arc<Mutex<Option<tiny_skia::Mask>>>,
|
||||||
/// TODO: This needs to be per seat
|
/// TODO: This needs to be per seat
|
||||||
pointer_entered: Arc<AtomicU8>,
|
pointer_entered: Arc<AtomicU8>,
|
||||||
last_seat: Arc<Mutex<Option<(Seat<State>, Serial)>>>,
|
last_seat: Arc<Mutex<Option<(Seat<State>, Serial)>>>,
|
||||||
|
|
@ -119,6 +122,7 @@ impl CosmicWindow {
|
||||||
CosmicWindow(IcedElement::new(
|
CosmicWindow(IcedElement::new(
|
||||||
CosmicWindowInternal {
|
CosmicWindowInternal {
|
||||||
window,
|
window,
|
||||||
|
mask: Arc::new(Mutex::new(None)),
|
||||||
pointer_entered: Arc::new(AtomicU8::new(Focus::None as u8)),
|
pointer_entered: Arc::new(AtomicU8::new(Focus::None as u8)),
|
||||||
last_seat: Arc::new(Mutex::new(None)),
|
last_seat: Arc::new(Mutex::new(None)),
|
||||||
last_title: Arc::new(Mutex::new(last_title)),
|
last_title: Arc::new(Mutex::new(last_title)),
|
||||||
|
|
@ -141,6 +145,7 @@ impl CosmicWindow {
|
||||||
p.window
|
p.window
|
||||||
.set_geometry(Rectangle::from_loc_and_size(loc, size));
|
.set_geometry(Rectangle::from_loc_and_size(loc, size));
|
||||||
});
|
});
|
||||||
|
self.0.with_program(|p| p.mask.lock().unwrap().take());
|
||||||
self.0.resize(Size::from((geo.size.w, SSD_HEIGHT)));
|
self.0.resize(Size::from((geo.size.w, SSD_HEIGHT)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -218,12 +223,15 @@ impl Program for CosmicWindowInternal {
|
||||||
Command::none()
|
Command::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn background(&self, target: &mut DrawTarget<&mut [u32]>) {
|
fn clip_mask(&self, size: Size<i32, smithay::utils::Buffer>, scale: f32) -> tiny_skia::Mask {
|
||||||
let radius = 8.;
|
let mut mask = self.mask.lock().unwrap();
|
||||||
let (w, h) = (target.width() as f32, target.height() as f32);
|
if mask.is_none() {
|
||||||
|
let mut new_mask = tiny_skia::Mask::new(size.w as u32, size.h as u32).unwrap();
|
||||||
|
|
||||||
|
let mut pb = tiny_skia::PathBuilder::new();
|
||||||
|
let radius = 8. * scale;
|
||||||
|
let (w, h) = (size.w as f32, size.h as f32);
|
||||||
|
|
||||||
if !(self.window.is_maximized() || self.window.is_fullscreen()) {
|
|
||||||
let mut pb = PathBuilder::new();
|
|
||||||
pb.move_to(0., h); // lower-left
|
pb.move_to(0., h); // lower-left
|
||||||
|
|
||||||
// upper-left rounded corner
|
// upper-left rounded corner
|
||||||
|
|
@ -236,17 +244,63 @@ impl Program for CosmicWindowInternal {
|
||||||
|
|
||||||
pb.line_to(w, h); // lower-right
|
pb.line_to(w, h); // lower-right
|
||||||
|
|
||||||
let path = pb.finish();
|
let path = pb.finish().unwrap();
|
||||||
target.push_clip(&path);
|
new_mask.fill_path(
|
||||||
|
&path,
|
||||||
|
tiny_skia::FillRule::EvenOdd,
|
||||||
|
true,
|
||||||
|
Default::default(),
|
||||||
|
);
|
||||||
|
|
||||||
|
*mask = Some(new_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mask.clone().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn background_color(&self) -> iced_core::Color {
|
||||||
if self.window.is_activated() {
|
if self.window.is_activated() {
|
||||||
target.clear(SolidSource::from_unpremultiplied_argb(u8::MAX, 30, 30, 30));
|
iced_core::Color {
|
||||||
|
r: 0.1176,
|
||||||
|
g: 0.1176,
|
||||||
|
b: 0.1176,
|
||||||
|
a: 1.0,
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
target.clear(SolidSource::from_unpremultiplied_argb(u8::MAX, 39, 39, 39));
|
iced_core::Color {
|
||||||
|
r: 0.153,
|
||||||
|
g: 0.153,
|
||||||
|
b: 0.153,
|
||||||
|
a: 1.0,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
target.pop_clip();
|
fn foreground(
|
||||||
|
&self,
|
||||||
|
pixels: &mut tiny_skia::PixmapMut<'_>,
|
||||||
|
damage: &[Rectangle<i32, BufferCoords>],
|
||||||
|
) {
|
||||||
|
if !self.window.is_activated() {
|
||||||
|
let mask = self.mask.lock().unwrap();
|
||||||
|
let mut paint = tiny_skia::Paint::default();
|
||||||
|
paint.set_color_rgba8(0, 0, 0, 102);
|
||||||
|
|
||||||
|
for rect in damage {
|
||||||
|
pixels.fill_rect(
|
||||||
|
tiny_skia::Rect::from_xywh(
|
||||||
|
rect.loc.x as f32,
|
||||||
|
rect.loc.y as f32,
|
||||||
|
rect.size.w as f32,
|
||||||
|
rect.size.h as f32,
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
&paint,
|
||||||
|
Default::default(),
|
||||||
|
mask.as_ref(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view(&self) -> cosmic::Element<'_, Self::Message> {
|
fn view(&self) -> cosmic::Element<'_, Self::Message> {
|
||||||
|
|
@ -257,42 +311,6 @@ impl Program for CosmicWindowInternal {
|
||||||
.on_close(Message::Close)
|
.on_close(Message::Close)
|
||||||
.into_element()
|
.into_element()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foreground(&self, target: &mut DrawTarget<&mut [u32]>) {
|
|
||||||
if !self.window.is_activated() {
|
|
||||||
let radius = 8.;
|
|
||||||
let (w, h) = (target.width() as f32, target.height() as f32);
|
|
||||||
|
|
||||||
if !(self.window.is_maximized() || self.window.is_fullscreen()) {
|
|
||||||
let mut pb = PathBuilder::new();
|
|
||||||
pb.move_to(0., h); // lower-left
|
|
||||||
|
|
||||||
// upper-left rounded corner
|
|
||||||
pb.line_to(0., radius);
|
|
||||||
pb.quad_to(0., 0., radius, 0.);
|
|
||||||
|
|
||||||
// upper-right rounded corner
|
|
||||||
pb.line_to(w - radius, 0.);
|
|
||||||
pb.quad_to(w, 0., w, radius);
|
|
||||||
|
|
||||||
pb.line_to(w, h); // lower-right
|
|
||||||
|
|
||||||
let path = pb.finish();
|
|
||||||
target.push_clip(&path);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut options = DrawOptions::new();
|
|
||||||
options.alpha = 0.4;
|
|
||||||
target.fill_rect(
|
|
||||||
0.,
|
|
||||||
0.,
|
|
||||||
w,
|
|
||||||
h,
|
|
||||||
&Source::Solid(SolidSource::from_unpremultiplied_argb(u8::MAX, 0, 0, 0)),
|
|
||||||
&options,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IsAlive for CosmicWindow {
|
impl IsAlive for CosmicWindow {
|
||||||
|
|
@ -329,6 +347,7 @@ impl SpaceElement for CosmicWindow {
|
||||||
}
|
}
|
||||||
fn set_activate(&self, activated: bool) {
|
fn set_activate(&self, activated: bool) {
|
||||||
SpaceElement::set_activate(&self.0, activated);
|
SpaceElement::set_activate(&self.0, activated);
|
||||||
|
self.0.force_redraw();
|
||||||
self.0
|
self.0
|
||||||
.with_program(|p| SpaceElement::set_activate(&p.window, activated));
|
.with_program(|p| SpaceElement::set_activate(&p.window, activated));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,25 +5,28 @@ use std::{
|
||||||
sync::{mpsc::Receiver, Arc, Mutex},
|
sync::{mpsc::Receiver, Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use cosmic::Renderer as IcedRenderer;
|
|
||||||
use cosmic::Theme;
|
|
||||||
use cosmic::{
|
use cosmic::{
|
||||||
iced_native::{
|
iced::{
|
||||||
command::Action,
|
|
||||||
event::Event,
|
event::Event,
|
||||||
keyboard::{Event as KeyboardEvent, Modifiers as IcedModifiers},
|
keyboard::{Event as KeyboardEvent, Modifiers as IcedModifiers},
|
||||||
mouse::{Button as MouseButton, Event as MouseEvent, ScrollDelta},
|
mouse::{Button as MouseButton, Event as MouseEvent, ScrollDelta},
|
||||||
program::{Program as IcedProgram, State},
|
|
||||||
renderer::Style,
|
|
||||||
window::{Event as WindowEvent, Id},
|
window::{Event as WindowEvent, Id},
|
||||||
Command, Debug, Point as IcedPoint, Size as IcedSize,
|
Command, Point as IcedPoint, Rectangle as IcedRectangle, Size as IcedSize,
|
||||||
},
|
},
|
||||||
Element,
|
iced_runtime::{
|
||||||
|
command::Action,
|
||||||
|
program::{Program as IcedProgram, State},
|
||||||
|
Debug,
|
||||||
|
},
|
||||||
|
Renderer as IcedRenderer, Theme,
|
||||||
};
|
};
|
||||||
use iced_softbuffer::{
|
use iced_core::{renderer::Style, Color};
|
||||||
native::{raqote::DrawTarget, *},
|
use iced_renderer::Backend as BackendWrapper;
|
||||||
|
use iced_tiny_skia::{
|
||||||
|
graphics::{damage, Primitive, Viewport},
|
||||||
Backend,
|
Backend,
|
||||||
};
|
};
|
||||||
|
pub type Element<'a, Message> = cosmic::iced::Element<'a, Message, IcedRenderer>;
|
||||||
|
|
||||||
use ordered_float::OrderedFloat;
|
use ordered_float::OrderedFloat;
|
||||||
use smithay::{
|
use smithay::{
|
||||||
|
|
@ -47,7 +50,10 @@ use smithay::{
|
||||||
output::Output,
|
output::Output,
|
||||||
reexports::calloop::RegistrationToken,
|
reexports::calloop::RegistrationToken,
|
||||||
reexports::calloop::{self, futures::Scheduler, LoopHandle},
|
reexports::calloop::{self, futures::Scheduler, LoopHandle},
|
||||||
utils::{IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size, Transform},
|
utils::{
|
||||||
|
Buffer as BufferCoords, IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size,
|
||||||
|
Transform,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -88,11 +94,15 @@ pub trait Program {
|
||||||
}
|
}
|
||||||
fn view(&self) -> Element<'_, Self::Message>;
|
fn view(&self) -> Element<'_, Self::Message>;
|
||||||
|
|
||||||
fn background(&self, target: &mut DrawTarget<&mut [u32]>) {
|
fn clip_mask(&self, size: Size<i32, BufferCoords>, scale: f32) -> tiny_skia::Mask;
|
||||||
let _ = target;
|
fn background_color(&self) -> Color;
|
||||||
}
|
|
||||||
fn foreground(&self, target: &mut DrawTarget<&mut [u32]>) {
|
fn foreground(
|
||||||
let _ = target;
|
&self,
|
||||||
|
pixels: &mut tiny_skia::PixmapMut<'_>,
|
||||||
|
damage: &[Rectangle<i32, BufferCoords>],
|
||||||
|
) {
|
||||||
|
let _ = (pixels, damage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -105,7 +115,7 @@ impl<P: Program> IcedProgram for ProgramWrapper<P> {
|
||||||
self.0.update(message, &self.1)
|
self.0.update(message, &self.1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view(&self) -> Element<'_, Self::Message> {
|
fn view(&self, _id: Id) -> Element<'_, Self::Message> {
|
||||||
self.0.view()
|
self.0.view()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -113,7 +123,7 @@ impl<P: Program> IcedProgram for ProgramWrapper<P> {
|
||||||
struct IcedElementInternal<P: Program + Send + 'static> {
|
struct IcedElementInternal<P: Program + Send + 'static> {
|
||||||
// draw buffer
|
// draw buffer
|
||||||
outputs: Vec<Output>,
|
outputs: Vec<Output>,
|
||||||
buffers: HashMap<OrderedFloat<f64>, (MemoryRenderBuffer, bool)>,
|
buffers: HashMap<OrderedFloat<f64>, (MemoryRenderBuffer, Option<(Vec<Primitive>, Color)>)>,
|
||||||
|
|
||||||
// state
|
// state
|
||||||
size: Size<i32, Logical>,
|
size: Size<i32, Logical>,
|
||||||
|
|
@ -163,10 +173,12 @@ impl<P: Program + Send + 'static> IcedElement<P> {
|
||||||
handle: LoopHandle<'static, crate::state::Data>,
|
handle: LoopHandle<'static, crate::state::Data>,
|
||||||
) -> IcedElement<P> {
|
) -> IcedElement<P> {
|
||||||
let size = size.into();
|
let size = size.into();
|
||||||
let mut renderer = IcedRenderer::new(Backend::new());
|
let mut renderer =
|
||||||
|
IcedRenderer::new(BackendWrapper::TinySkia(Backend::new(Default::default())));
|
||||||
let mut debug = Debug::new();
|
let mut debug = Debug::new();
|
||||||
|
|
||||||
let state = State::new(
|
let state = State::new(
|
||||||
|
Id(0),
|
||||||
ProgramWrapper(program, handle.clone()),
|
ProgramWrapper(program, handle.clone()),
|
||||||
IcedSize::new(size.w as f32, size.h as f32),
|
IcedSize::new(size.w as f32, size.h as f32),
|
||||||
&mut renderer,
|
&mut renderer,
|
||||||
|
|
@ -217,7 +229,7 @@ impl<P: Program + Send + 'static> IcedElement<P> {
|
||||||
}
|
}
|
||||||
|
|
||||||
internal_ref.size = size;
|
internal_ref.size = size;
|
||||||
for (scale, (buffer, needs_redraw)) in internal_ref.buffers.iter_mut() {
|
for (scale, (buffer, old_primitives)) in internal_ref.buffers.iter_mut() {
|
||||||
let buffer_size = internal_ref
|
let buffer_size = internal_ref
|
||||||
.size
|
.size
|
||||||
.to_f64()
|
.to_f64()
|
||||||
|
|
@ -225,15 +237,19 @@ impl<P: Program + Send + 'static> IcedElement<P> {
|
||||||
.to_i32_round();
|
.to_i32_round();
|
||||||
*buffer =
|
*buffer =
|
||||||
MemoryRenderBuffer::new(Fourcc::Argb8888, buffer_size, 1, Transform::Normal, None);
|
MemoryRenderBuffer::new(Fourcc::Argb8888, buffer_size, 1, Transform::Normal, None);
|
||||||
*needs_redraw = true;
|
*old_primitives = None;
|
||||||
}
|
}
|
||||||
internal_ref.update(true);
|
internal_ref.update(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn force_update(&self) {
|
pub fn force_update(&self) {
|
||||||
|
self.0.lock().unwrap().update(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn force_redraw(&self) {
|
||||||
let mut internal = self.0.lock().unwrap();
|
let mut internal = self.0.lock().unwrap();
|
||||||
for (_buffer, ref mut needs_redraw) in internal.buffers.values_mut() {
|
for (_buffer, ref mut old_primitives) in internal.buffers.values_mut() {
|
||||||
*needs_redraw = true;
|
*old_primitives = None;
|
||||||
}
|
}
|
||||||
internal.update(true);
|
internal.update(true);
|
||||||
}
|
}
|
||||||
|
|
@ -255,6 +271,7 @@ impl<P: Program + Send + 'static> IcedElementInternal<P> {
|
||||||
let actions = self
|
let actions = self
|
||||||
.state
|
.state
|
||||||
.update(
|
.update(
|
||||||
|
Id(0),
|
||||||
IcedSize::new(self.size.w as f32, self.size.h as f32),
|
IcedSize::new(self.size.w as f32, self.size.h as f32),
|
||||||
IcedPoint::new(cursor_pos.x as f32, cursor_pos.y as f32),
|
IcedPoint::new(cursor_pos.x as f32, cursor_pos.y as f32),
|
||||||
&mut self.renderer,
|
&mut self.renderer,
|
||||||
|
|
@ -262,17 +279,12 @@ impl<P: Program + Send + 'static> IcedElementInternal<P> {
|
||||||
&Style {
|
&Style {
|
||||||
text_color: self.theme.cosmic().on_bg_color().into(),
|
text_color: self.theme.cosmic().on_bg_color().into(),
|
||||||
},
|
},
|
||||||
&mut cosmic::iced_native::clipboard::Null,
|
&mut iced_core::clipboard::Null,
|
||||||
&mut self.debug,
|
&mut self.debug,
|
||||||
)
|
)
|
||||||
.1
|
.1
|
||||||
.map(|command| command.actions());
|
.map(|command| command.actions());
|
||||||
|
|
||||||
if actions.is_some() {
|
|
||||||
for (_buffer, ref mut needs_redraw) in self.buffers.values_mut() {
|
|
||||||
*needs_redraw = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let actions = actions.unwrap_or_default();
|
let actions = actions.unwrap_or_default();
|
||||||
actions
|
actions
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
@ -468,7 +480,7 @@ impl<P: Program + Send + 'static> SpaceElement for IcedElement<P> {
|
||||||
fn set_activate(&self, activated: bool) {
|
fn set_activate(&self, activated: bool) {
|
||||||
let mut internal = self.0.lock().unwrap();
|
let mut internal = self.0.lock().unwrap();
|
||||||
internal.state.queue_event(Event::Window(
|
internal.state.queue_event(Event::Window(
|
||||||
Id::MAIN,
|
Id(0),
|
||||||
if activated {
|
if activated {
|
||||||
WindowEvent::Focused
|
WindowEvent::Focused
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -497,7 +509,7 @@ impl<P: Program + Send + 'static> SpaceElement for IcedElement<P> {
|
||||||
Transform::Normal,
|
Transform::Normal,
|
||||||
None,
|
None,
|
||||||
),
|
),
|
||||||
true,
|
None,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -547,7 +559,7 @@ impl<P: Program + Send + 'static> SpaceElement for IcedElement<P> {
|
||||||
Transform::Normal,
|
Transform::Normal,
|
||||||
None,
|
None,
|
||||||
),
|
),
|
||||||
true,
|
None,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -570,64 +582,80 @@ where
|
||||||
alpha: f32,
|
alpha: f32,
|
||||||
) -> Vec<C> {
|
) -> Vec<C> {
|
||||||
let mut internal = self.0.lock().unwrap();
|
let mut internal = self.0.lock().unwrap();
|
||||||
|
let _ = internal.update(false);
|
||||||
let _ = internal.update(false); // TODO
|
|
||||||
|
|
||||||
// makes partial borrows easier
|
// makes partial borrows easier
|
||||||
let internal_ref = &mut *internal;
|
let internal_ref = &mut *internal;
|
||||||
if let Some((buffer, ref mut needs_redraw)) =
|
if let Some((buffer, ref mut old_primitives)) =
|
||||||
internal_ref.buffers.get_mut(&OrderedFloat(scale.x))
|
internal_ref.buffers.get_mut(&OrderedFloat(scale.x))
|
||||||
{
|
{
|
||||||
let size = internal_ref
|
let size: Size<i32, BufferCoords> = internal_ref
|
||||||
.size
|
.size
|
||||||
.to_f64()
|
.to_f64()
|
||||||
.to_buffer(scale.x, Transform::Normal)
|
.to_buffer(scale.x, Transform::Normal)
|
||||||
.to_i32_round();
|
.to_i32_round();
|
||||||
|
|
||||||
if *needs_redraw && size.w > 0 && size.h > 0 {
|
if size.w > 0 && size.h > 0 {
|
||||||
let renderer = &mut internal_ref.renderer;
|
let renderer = &mut internal_ref.renderer;
|
||||||
let state_ref = &internal_ref.state;
|
let state_ref = &internal_ref.state;
|
||||||
|
let mut clip_mask = state_ref.program().0.clip_mask(size, scale.x as f32);
|
||||||
|
let overlay = internal_ref.debug.overlay();
|
||||||
|
|
||||||
buffer
|
buffer
|
||||||
.render()
|
.render()
|
||||||
.draw(move |buf| {
|
.draw(move |buf| {
|
||||||
let mut target = raqote::DrawTarget::from_backing(
|
let mut pixels =
|
||||||
size.w,
|
tiny_skia::PixmapMut::from_bytes(buf, size.w as u32, size.h as u32)
|
||||||
size.h,
|
.expect("Failed to create pixel map");
|
||||||
bytemuck::cast_slice_mut::<_, u32>(buf),
|
|
||||||
);
|
|
||||||
|
|
||||||
target.clear(raqote::SolidSource::from_unpremultiplied_argb(0, 0, 0, 0));
|
|
||||||
state_ref.program().0.background(&mut target);
|
|
||||||
|
|
||||||
let draw_options = raqote::DrawOptions {
|
|
||||||
// Default to antialiasing off for now
|
|
||||||
antialias: raqote::AntialiasMode::None,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
// Having at least one clip fixes some font rendering issues
|
|
||||||
target.push_clip_rect(raqote::IntRect::new(
|
|
||||||
raqote::IntPoint::new(0, 0),
|
|
||||||
raqote::IntPoint::new(size.w, size.h),
|
|
||||||
));
|
|
||||||
|
|
||||||
renderer.with_primitives(|backend, primitives| {
|
renderer.with_primitives(|backend, primitives| {
|
||||||
for primitive in primitives.iter() {
|
let BackendWrapper::TinySkia(ref mut backend) = backend;
|
||||||
draw_primitive(
|
let background_color = state_ref.program().0.background_color();
|
||||||
&mut target,
|
let bounds = IcedSize::new(size.w as u32, size.h as u32);
|
||||||
&draw_options,
|
let viewport = Viewport::with_physical_size(bounds, scale.x);
|
||||||
backend,
|
|
||||||
scale.x as f32,
|
|
||||||
primitive,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
state_ref.program().0.foreground(&mut target);
|
let mut damage = old_primitives
|
||||||
Result::<_, ()>::Ok(vec![Rectangle::from_loc_and_size((0, 0), size)])
|
.as_ref()
|
||||||
|
.and_then(|(last_primitives, last_color)| {
|
||||||
|
(last_color == &background_color)
|
||||||
|
.then(|| damage::list(last_primitives, primitives))
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
vec![IcedRectangle::with_size(viewport.logical_size())]
|
||||||
|
});
|
||||||
|
damage = damage::group(damage, scale.x as f32, bounds);
|
||||||
|
|
||||||
|
if !damage.is_empty() {
|
||||||
|
backend.draw(
|
||||||
|
&mut pixels,
|
||||||
|
&mut clip_mask,
|
||||||
|
primitives,
|
||||||
|
&viewport,
|
||||||
|
&damage,
|
||||||
|
background_color,
|
||||||
|
&overlay,
|
||||||
|
);
|
||||||
|
|
||||||
|
*old_primitives = Some((primitives.to_vec(), background_color));
|
||||||
|
}
|
||||||
|
|
||||||
|
let damage = damage
|
||||||
|
.into_iter()
|
||||||
|
.map(|x| x.snap())
|
||||||
|
.map(|damage_rect| {
|
||||||
|
Rectangle::from_loc_and_size(
|
||||||
|
(damage_rect.x as i32, damage_rect.y as i32),
|
||||||
|
(damage_rect.width as i32, damage_rect.height as i32),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
state_ref.program().0.foreground(&mut pixels, &damage);
|
||||||
|
|
||||||
|
Result::<_, ()>::Ok(damage)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
*needs_redraw = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(buffer) = MemoryRenderBufferRenderElement::from_buffer(
|
if let Ok(buffer) = MemoryRenderBufferRenderElement::from_buffer(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue