diff --git a/src/shell/element/stack.rs b/src/shell/element/stack.rs index 9ee25a6d..358fd98c 100644 --- a/src/shell/element/stack.rs +++ b/src/shell/element/stack.rs @@ -102,7 +102,6 @@ pub struct CosmicStackInternal { reenter: Arc, potential_drag: Arc>>, override_alive: Arc, - last_seat: Arc, Serial)>>>, geometry: Arc>>>, mask: Arc>>, } @@ -155,7 +154,6 @@ impl CosmicStack { reenter: Arc::new(AtomicBool::new(false)), potential_drag: Arc::new(Mutex::new(None)), override_alive: Arc::new(AtomicBool::new(true)), - last_seat: Arc::new(Mutex::new(None)), geometry: Arc::new(Mutex::new(None)), mask: Arc::new(Mutex::new(None)), }, @@ -768,10 +766,11 @@ impl Program for CosmicStackInternal { &mut self, message: Self::Message, loop_handle: &LoopHandle<'static, crate::state::State>, + last_seat: Option<&(Seat, Serial)>, ) -> Task { match message { Message::DragStart => { - if let Some((seat, serial)) = self.last_seat.lock().unwrap().clone() { + if let Some((seat, serial)) = last_seat.cloned() { let active = self.active.load(Ordering::SeqCst); if let Some(surface) = self.windows.lock().unwrap()[active] .wl_surface() @@ -831,7 +830,7 @@ impl Program for CosmicStackInternal { self.scroll_to_focus.store(false, Ordering::SeqCst); } Message::Menu => { - if let Some((seat, serial)) = self.last_seat.lock().unwrap().clone() { + if let Some((seat, serial)) = last_seat.cloned() { let active = self.active.load(Ordering::SeqCst); if let Some(surface) = self.windows.lock().unwrap()[active] .wl_surface() @@ -886,7 +885,7 @@ impl Program for CosmicStackInternal { } } Message::TabMenu(idx) => { - if let Some((seat, serial)) = self.last_seat.lock().unwrap().clone() { + if let Some((seat, serial)) = last_seat.cloned() { if let Some(surface) = self.windows.lock().unwrap()[idx] .wl_surface() .map(Cow::into_owned) @@ -1338,12 +1337,7 @@ impl PointerTarget for CosmicStack { fn button(&self, seat: &Seat, data: &mut State, event: &ButtonEvent) { match self.0.with_program(|p| p.current_focus()) { - Some(Focus::Header) => { - self.0.with_program(|p| { - *p.last_seat.lock().unwrap() = Some((seat.clone(), event.serial)); - }); - PointerTarget::button(&self.0, seat, data, event) - } + Some(Focus::Header) => PointerTarget::button(&self.0, seat, data, event), Some(x) => { let serial = event.serial; let seat = seat.clone(); @@ -1523,7 +1517,6 @@ impl TouchTarget for CosmicStack { fn down(&self, seat: &Seat, data: &mut State, event: &DownEvent, seq: Serial) { let mut event = event.clone(); let active_window_geo = self.0.with_program(|p| { - *p.last_seat.lock().unwrap() = Some((seat.clone(), event.serial)); p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)].geometry() }); event.location -= active_window_geo.loc.to_f64(); diff --git a/src/shell/element/window.rs b/src/shell/element/window.rs index ac27add1..3937e1cd 100644 --- a/src/shell/element/window.rs +++ b/src/shell/element/window.rs @@ -77,7 +77,6 @@ pub struct CosmicWindowInternal { activated: Arc, /// TODO: This needs to be per seat pointer_entered: Arc, - last_seat: Arc, Serial)>>>, last_title: Arc>, } @@ -88,7 +87,6 @@ impl fmt::Debug for CosmicWindowInternal { .field("activated", &self.activated.load(Ordering::SeqCst)) .field("pointer_entered", &self.pointer_entered) // skip seat to avoid loop - .field("last_seat", &"...") .finish() } } @@ -189,7 +187,6 @@ impl CosmicWindow { window, activated: Arc::new(AtomicBool::new(false)), pointer_entered: Arc::new(AtomicU8::new(0)), - last_seat: Arc::new(Mutex::new(None)), last_title: Arc::new(Mutex::new(last_title)), }, (width, SSD_HEIGHT), @@ -427,10 +424,11 @@ impl Program for CosmicWindowInternal { &mut self, message: Self::Message, loop_handle: &LoopHandle<'static, crate::state::State>, + last_seat: Option<&(Seat, Serial)>, ) -> Task { match message { Message::DragStart => { - if let Some((seat, serial)) = self.last_seat.lock().unwrap().clone() { + if let Some((seat, serial)) = last_seat.cloned() { if let Some(surface) = self.window.wl_surface().map(Cow::into_owned) { loop_handle.insert_idle(move |state| { let res = state.common.shell.write().unwrap().move_request( @@ -480,7 +478,7 @@ impl Program for CosmicWindowInternal { } Message::Close => self.window.close(), Message::Menu => { - if let Some((seat, serial)) = self.last_seat.lock().unwrap().clone() { + if let Some((seat, serial)) = last_seat.cloned() { if let Some(surface) = self.window.wl_surface().map(Cow::into_owned) { loop_handle.insert_idle(move |state| { let shell = state.common.shell.read().unwrap(); @@ -731,12 +729,7 @@ impl PointerTarget for CosmicWindow { fn button(&self, seat: &Seat, data: &mut State, event: &ButtonEvent) { match self.0.with_program(|p| p.current_focus()) { - Some(Focus::Header) => { - self.0.with_program(|p| { - *p.last_seat.lock().unwrap() = Some((seat.clone(), event.serial)); - }); - PointerTarget::button(&self.0, seat, data, event) - } + Some(Focus::Header) => PointerTarget::button(&self.0, seat, data, event), Some(x) => { let serial = event.serial; let seat = seat.clone(); @@ -871,7 +864,6 @@ impl TouchTarget for CosmicWindow { let mut event = event.clone(); self.0.with_program(|p| { event.location -= p.window.geometry().loc.to_f64(); - *p.last_seat.lock().unwrap() = Some((seat.clone(), event.serial)); }); TouchTarget::down(&self.0, seat, data, &event, seq) } diff --git a/src/utils/iced.rs b/src/utils/iced.rs index e025e143..e939a864 100644 --- a/src/utils/iced.rs +++ b/src/utils/iced.rs @@ -107,8 +107,9 @@ pub trait Program { &mut self, message: Self::Message, loop_handle: &LoopHandle<'static, crate::state::State>, + last_seat: Option<&(Seat, Serial)>, ) -> Task { - let _ = (message, loop_handle); + let _ = (message, loop_handle, last_seat); Task::none() } fn view(&self) -> cosmic::Element<'_, Self::Message>; @@ -128,18 +129,24 @@ pub trait Program { } } -struct ProgramWrapper(P, LoopHandle<'static, crate::state::State>); +struct ProgramWrapper { + program: P, + evlh: LoopHandle<'static, crate::state::State>, + last_seat: Arc, Serial)>>>, +} + impl IcedProgram for ProgramWrapper

{ type Message =

::Message; type Renderer = cosmic::Renderer; type Theme = cosmic::Theme; fn update(&mut self, message: Self::Message) -> Task { - self.0.update(message, &self.1) + let last_seat = self.last_seat.lock().unwrap(); + self.program.update(message, &self.evlh, last_seat.as_ref()) } fn view(&self) -> cosmic::Element<'_, Self::Message> { - self.0.view() + self.program.view() } } @@ -151,6 +158,7 @@ pub(crate) struct IcedElementInternal { // state size: Size, + last_seat: Arc, Serial)>>>, cursor_pos: Option>, touch_map: HashMap, @@ -185,7 +193,11 @@ impl Clone for IcedElementInternal

{ let mut debug = Debug::new(); let state = State::new( ID.clone(), - ProgramWrapper(self.state.program().0.clone(), handle.clone()), + ProgramWrapper { + program: self.state.program().program.clone(), + evlh: handle.clone(), + last_seat: self.last_seat.clone(), + }, IcedSize::new(self.size.w as f32, self.size.h as f32), &mut renderer, &mut debug, @@ -196,6 +208,7 @@ impl Clone for IcedElementInternal

{ buffers: self.buffers.clone(), pending_update: self.pending_update.clone(), size: self.size.clone(), + last_seat: self.last_seat.clone(), cursor_pos: self.cursor_pos.clone(), touch_map: self.touch_map.clone(), theme: self.theme.clone(), @@ -243,12 +256,17 @@ impl IcedElement

{ theme: cosmic::Theme, ) -> IcedElement

{ let size = size.into(); + let last_seat = Arc::new(Mutex::new(None)); let mut renderer = cosmic::Renderer::new(cosmic::font::default(), Pixels(16.0)); let mut debug = Debug::new(); let state = State::new( ID.clone(), - ProgramWrapper(program, handle.clone()), + ProgramWrapper { + program, + evlh: handle.clone(), + last_seat: last_seat.clone(), + }, IcedSize::new(size.w as f32, size.h as f32), &mut renderer, &mut debug, @@ -268,6 +286,7 @@ impl IcedElement

{ pending_update: None, size, cursor_pos: None, + last_seat, touch_map: HashMap::new(), theme, renderer, @@ -285,12 +304,12 @@ impl IcedElement

{ pub fn with_program(&self, func: impl FnOnce(&P) -> R) -> R { let internal = self.0.lock().unwrap(); - func(&internal.state.program().0) + func(&internal.state.program().program) } pub fn minimum_size(&self) -> Size { let internal = self.0.lock().unwrap(); - let element = internal.state.program().0.view(); + let element = internal.state.program().program.view(); let node = element .as_widget() .layout( @@ -349,6 +368,14 @@ impl IcedElement

{ } internal.update(true); } + + pub fn current_size(&self) -> Size { + self.0.lock().unwrap().size + } + + pub fn queue_message(&self, msg: P::Message) { + self.0.lock().unwrap().state.queue_message(msg); + } } impl IcedElement

{ @@ -411,7 +438,7 @@ impl IcedElementInternal

{ impl PointerTarget for IcedElement

{ fn enter( &self, - _seat: &Seat, + seat: &Seat, _data: &mut crate::state::State, event: &MotionEvent, ) { @@ -425,12 +452,13 @@ impl PointerTarget for IcedEle .queue_event(Event::Mouse(MouseEvent::CursorMoved { position })); // TODO: Update iced widgets to handle touch using event position, not cursor_pos internal.cursor_pos = Some(event.location); + *internal.last_seat.lock().unwrap() = Some((seat.clone(), event.serial)); let _ = internal.update(true); } fn motion( &self, - _seat: &Seat, + seat: &Seat, _data: &mut crate::state::State, event: &MotionEvent, ) { @@ -440,6 +468,7 @@ impl PointerTarget for IcedEle .state .queue_event(Event::Mouse(MouseEvent::CursorMoved { position })); internal.cursor_pos = Some(event.location); + *internal.last_seat.lock().unwrap() = Some((seat.clone(), event.serial)); let _ = internal.update(true); } @@ -453,7 +482,7 @@ impl PointerTarget for IcedEle fn button( &self, - _seat: &Seat, + seat: &Seat, _data: &mut crate::state::State, event: &ButtonEvent, ) { @@ -468,6 +497,7 @@ impl PointerTarget for IcedEle ButtonState::Pressed => MouseEvent::ButtonPressed(button), ButtonState::Released => MouseEvent::ButtonReleased(button), })); + *internal.last_seat.lock().unwrap() = Some((seat.clone(), event.serial)); let _ = internal.update(true); } @@ -573,10 +603,10 @@ impl PointerTarget for IcedEle impl TouchTarget for IcedElement

{ fn down( &self, - _seat: &Seat, + seat: &Seat, _data: &mut crate::state::State, event: &DownEvent, - _seq: Serial, + seq: Serial, ) { let mut internal = self.0.lock().unwrap(); let id = Finger(i32::from(event.slot) as u64); @@ -586,19 +616,21 @@ impl TouchTarget for IcedEleme .queue_event(Event::Touch(TouchEvent::FingerPressed { id, position })); internal.touch_map.insert(id, position); internal.cursor_pos = Some(event.location); + *internal.last_seat.lock().unwrap() = Some((seat.clone(), seq)); let _ = internal.update(true); } fn up( &self, - _seat: &Seat, + seat: &Seat, _data: &mut crate::state::State, event: &UpEvent, - _seq: Serial, + seq: Serial, ) { let mut internal = self.0.lock().unwrap(); let id = Finger(i32::from(event.slot) as u64); if let Some(position) = internal.touch_map.remove(&id) { + *internal.last_seat.lock().unwrap() = Some((seat.clone(), seq)); internal .state .queue_event(Event::Touch(TouchEvent::FingerLifted { id, position })); @@ -608,14 +640,15 @@ impl TouchTarget for IcedEleme fn motion( &self, - _seat: &Seat, + seat: &Seat, _data: &mut crate::state::State, event: &TouchMotionEvent, - _seq: Serial, + seq: Serial, ) { let mut internal = self.0.lock().unwrap(); let id = Finger(i32::from(event.slot) as u64); let position = IcedPoint::new(event.location.x as f32, event.location.y as f32); + *internal.last_seat.lock().unwrap() = Some((seat.clone(), seq)); internal .state .queue_event(Event::Touch(TouchEvent::FingerMoved { id, position })); @@ -872,7 +905,7 @@ where tiny_skia::PixmapMut::from_bytes(buf, size.w as u32, size.h as u32) .expect("Failed to create pixel map"); - let background_color = state_ref.program().0.background_color(theme); + let background_color = state_ref.program().program.background_color(theme); let bounds = IcedSize::new(size.w as u32, size.h as u32); let viewport = Viewport::with_physical_size(bounds, scale.x); let scale_x = scale.x as f32; @@ -934,10 +967,12 @@ where ) }) .collect::>(); - state_ref - .program() - .0 - .foreground(&mut pixels, &damage, scale.x as f32, theme); + state_ref.program().program.foreground( + &mut pixels, + &damage, + scale.x as f32, + theme, + ); Result::<_, ()>::Ok(damage) });