iced: Track last seat/serial for grabs
This commit is contained in:
parent
6fd1a48e60
commit
df9441804d
3 changed files with 66 additions and 46 deletions
|
|
@ -102,7 +102,6 @@ pub struct CosmicStackInternal {
|
|||
reenter: Arc<AtomicBool>,
|
||||
potential_drag: Arc<Mutex<Option<usize>>>,
|
||||
override_alive: Arc<AtomicBool>,
|
||||
last_seat: Arc<Mutex<Option<(Seat<State>, Serial)>>>,
|
||||
geometry: Arc<Mutex<Option<Rectangle<i32, Global>>>>,
|
||||
mask: Arc<Mutex<Option<tiny_skia::Mask>>>,
|
||||
}
|
||||
|
|
@ -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<State>, Serial)>,
|
||||
) -> Task<Self::Message> {
|
||||
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<State> for CosmicStack {
|
|||
|
||||
fn button(&self, seat: &Seat<State>, 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<State> for CosmicStack {
|
|||
fn down(&self, seat: &Seat<State>, 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();
|
||||
|
|
|
|||
|
|
@ -77,7 +77,6 @@ pub struct CosmicWindowInternal {
|
|||
activated: Arc<AtomicBool>,
|
||||
/// TODO: This needs to be per seat
|
||||
pointer_entered: Arc<AtomicU8>,
|
||||
last_seat: Arc<Mutex<Option<(Seat<State>, Serial)>>>,
|
||||
last_title: Arc<Mutex<String>>,
|
||||
}
|
||||
|
||||
|
|
@ -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<State>, Serial)>,
|
||||
) -> Task<Self::Message> {
|
||||
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<State> for CosmicWindow {
|
|||
|
||||
fn button(&self, seat: &Seat<State>, 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<State> 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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,8 +107,9 @@ pub trait Program {
|
|||
&mut self,
|
||||
message: Self::Message,
|
||||
loop_handle: &LoopHandle<'static, crate::state::State>,
|
||||
last_seat: Option<&(Seat<crate::state::State>, Serial)>,
|
||||
) -> Task<Self::Message> {
|
||||
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: Program>(P, LoopHandle<'static, crate::state::State>);
|
||||
struct ProgramWrapper<P: Program> {
|
||||
program: P,
|
||||
evlh: LoopHandle<'static, crate::state::State>,
|
||||
last_seat: Arc<Mutex<Option<(Seat<crate::state::State>, Serial)>>>,
|
||||
}
|
||||
|
||||
impl<P: Program> IcedProgram for ProgramWrapper<P> {
|
||||
type Message = <P as Program>::Message;
|
||||
type Renderer = cosmic::Renderer;
|
||||
type Theme = cosmic::Theme;
|
||||
|
||||
fn update(&mut self, message: Self::Message) -> Task<Self::Message> {
|
||||
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<P: Program + Send + 'static> {
|
|||
|
||||
// state
|
||||
size: Size<i32, Logical>,
|
||||
last_seat: Arc<Mutex<Option<(Seat<crate::state::State>, Serial)>>>,
|
||||
cursor_pos: Option<Point<f64, Logical>>,
|
||||
touch_map: HashMap<Finger, IcedPoint>,
|
||||
|
||||
|
|
@ -185,7 +193,11 @@ impl<P: Program + Send + Clone + 'static> Clone for IcedElementInternal<P> {
|
|||
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<P: Program + Send + Clone + 'static> Clone for IcedElementInternal<P> {
|
|||
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<P: Program + Send + 'static> IcedElement<P> {
|
|||
theme: cosmic::Theme,
|
||||
) -> IcedElement<P> {
|
||||
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<P: Program + Send + 'static> IcedElement<P> {
|
|||
pending_update: None,
|
||||
size,
|
||||
cursor_pos: None,
|
||||
last_seat,
|
||||
touch_map: HashMap::new(),
|
||||
theme,
|
||||
renderer,
|
||||
|
|
@ -285,12 +304,12 @@ impl<P: Program + Send + 'static> IcedElement<P> {
|
|||
|
||||
pub fn with_program<R>(&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<i32, Logical> {
|
||||
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<P: Program + Send + 'static> IcedElement<P> {
|
|||
}
|
||||
internal.update(true);
|
||||
}
|
||||
|
||||
pub fn current_size(&self) -> Size<i32, Logical> {
|
||||
self.0.lock().unwrap().size
|
||||
}
|
||||
|
||||
pub fn queue_message(&self, msg: P::Message) {
|
||||
self.0.lock().unwrap().state.queue_message(msg);
|
||||
}
|
||||
}
|
||||
|
||||
impl<P: Program + Send + 'static + Clone> IcedElement<P> {
|
||||
|
|
@ -411,7 +438,7 @@ impl<P: Program + Send + 'static> IcedElementInternal<P> {
|
|||
impl<P: Program + Send + 'static> PointerTarget<crate::state::State> for IcedElement<P> {
|
||||
fn enter(
|
||||
&self,
|
||||
_seat: &Seat<crate::state::State>,
|
||||
seat: &Seat<crate::state::State>,
|
||||
_data: &mut crate::state::State,
|
||||
event: &MotionEvent,
|
||||
) {
|
||||
|
|
@ -425,12 +452,13 @@ impl<P: Program + Send + 'static> PointerTarget<crate::state::State> 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<crate::state::State>,
|
||||
seat: &Seat<crate::state::State>,
|
||||
_data: &mut crate::state::State,
|
||||
event: &MotionEvent,
|
||||
) {
|
||||
|
|
@ -440,6 +468,7 @@ impl<P: Program + Send + 'static> PointerTarget<crate::state::State> 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<P: Program + Send + 'static> PointerTarget<crate::state::State> for IcedEle
|
|||
|
||||
fn button(
|
||||
&self,
|
||||
_seat: &Seat<crate::state::State>,
|
||||
seat: &Seat<crate::state::State>,
|
||||
_data: &mut crate::state::State,
|
||||
event: &ButtonEvent,
|
||||
) {
|
||||
|
|
@ -468,6 +497,7 @@ impl<P: Program + Send + 'static> PointerTarget<crate::state::State> 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<P: Program + Send + 'static> PointerTarget<crate::state::State> for IcedEle
|
|||
impl<P: Program + Send + 'static> TouchTarget<crate::state::State> for IcedElement<P> {
|
||||
fn down(
|
||||
&self,
|
||||
_seat: &Seat<crate::state::State>,
|
||||
seat: &Seat<crate::state::State>,
|
||||
_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<P: Program + Send + 'static> TouchTarget<crate::state::State> 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<crate::state::State>,
|
||||
seat: &Seat<crate::state::State>,
|
||||
_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<P: Program + Send + 'static> TouchTarget<crate::state::State> for IcedEleme
|
|||
|
||||
fn motion(
|
||||
&self,
|
||||
_seat: &Seat<crate::state::State>,
|
||||
seat: &Seat<crate::state::State>,
|
||||
_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::<Vec<_>>();
|
||||
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)
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue