feat: subsurfaces
This commit is contained in:
parent
0f37c9922d
commit
93bc4bbd88
33 changed files with 1898 additions and 2651 deletions
|
|
@ -1,9 +1,9 @@
|
|||
use iced_futures::futures::channel::oneshot::Sender;
|
||||
use cctk::sctk::{
|
||||
activation::{ActivationHandler, RequestData, RequestDataExt},
|
||||
delegate_activation,
|
||||
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;
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ impl KeyboardHandler for SctkState {
|
|||
_raw: &[u32],
|
||||
_keysyms: &[Keysym],
|
||||
) {
|
||||
self.request_redraw(surface);
|
||||
let (i, mut is_active, seat) = {
|
||||
let (i, is_active, my_seat) =
|
||||
match self.seats.iter_mut().enumerate().find_map(|(i, s)| {
|
||||
|
|
@ -32,36 +31,49 @@ impl KeyboardHandler for SctkState {
|
|||
Some((i, s)) => (i, i == 0, s),
|
||||
None => return,
|
||||
};
|
||||
|
||||
let surface = if let Some(subsurface) =
|
||||
self.subsurfaces.iter().find(|s| {
|
||||
s.steals_keyboard_focus && s.instance.parent == surface.id()
|
||||
}) {
|
||||
&subsurface.instance.wl_surface
|
||||
} else {
|
||||
surface
|
||||
};
|
||||
_ = my_seat.kbd_focus.replace(surface.clone());
|
||||
|
||||
let seat = my_seat.seat.clone();
|
||||
(i, is_active, seat)
|
||||
};
|
||||
|
||||
// TODO Ashley: thoroughly test this
|
||||
// swap the active seat to be the current seat if the current "active" seat is not focused on the application anyway
|
||||
if !is_active && self.seats[0].kbd_focus.is_none() {
|
||||
is_active = true;
|
||||
self.seats.swap(0, i);
|
||||
}
|
||||
self.request_redraw(&surface);
|
||||
|
||||
if is_active {
|
||||
let id = winit::window::WindowId::from_raw(
|
||||
surface.id().as_ptr() as usize
|
||||
);
|
||||
if self.windows.iter().any(|w| w.window.id() == id) {
|
||||
return;
|
||||
let surfaces = self.subsurfaces.iter().filter_map(|s| {
|
||||
(s.instance.parent == surface.id()).then(|| &s.instance.wl_surface)
|
||||
});
|
||||
for surface in surfaces.chain(std::iter::once(surface)) {
|
||||
if is_active {
|
||||
let id = winit::window::WindowId::from_raw(
|
||||
surface.id().as_ptr() as usize,
|
||||
);
|
||||
if self.windows.iter().any(|w| w.window.id() == id) {
|
||||
continue;
|
||||
}
|
||||
self.sctk_events.push(SctkEvent::Winit(
|
||||
id,
|
||||
winit::event::WindowEvent::Focused(true),
|
||||
));
|
||||
self.sctk_events.push(SctkEvent::KeyboardEvent {
|
||||
variant: KeyboardEventVariant::Enter(surface.clone()),
|
||||
kbd_id: keyboard.clone(),
|
||||
seat_id: seat.clone(),
|
||||
surface: surface.clone(),
|
||||
});
|
||||
}
|
||||
self.sctk_events.push(SctkEvent::Winit(
|
||||
id,
|
||||
winit::event::WindowEvent::Focused(true),
|
||||
));
|
||||
self.sctk_events.push(SctkEvent::KeyboardEvent {
|
||||
variant: KeyboardEventVariant::Enter(surface.clone()),
|
||||
kbd_id: keyboard.clone(),
|
||||
seat_id: seat,
|
||||
surface: surface.clone(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -91,38 +103,42 @@ impl KeyboardHandler for SctkState {
|
|||
_ = my_seat.kbd_focus.take();
|
||||
(is_active, seat, kbd)
|
||||
};
|
||||
|
||||
if is_active {
|
||||
self.sctk_events.push(SctkEvent::KeyboardEvent {
|
||||
variant: KeyboardEventVariant::Leave(surface.clone()),
|
||||
kbd_id: kbd,
|
||||
seat_id: seat,
|
||||
surface: surface.clone(),
|
||||
});
|
||||
// if there is another seat with a keyboard focused on a surface make that the new active seat
|
||||
if let Some(i) =
|
||||
self.seats.iter().position(|s| s.kbd_focus.is_some())
|
||||
{
|
||||
self.seats.swap(0, i);
|
||||
let s = &self.seats[0];
|
||||
let id = winit::window::WindowId::from_raw(
|
||||
surface.id().as_ptr() as usize,
|
||||
);
|
||||
if self.windows.iter().any(|w| w.window.id() == id) {
|
||||
return;
|
||||
}
|
||||
self.sctk_events.push(SctkEvent::Winit(
|
||||
id,
|
||||
winit::event::WindowEvent::Focused(true),
|
||||
));
|
||||
let surfaces = self.subsurfaces.iter().filter_map(|s| {
|
||||
(s.instance.parent == surface.id()).then(|| &s.instance.wl_surface)
|
||||
});
|
||||
for surface in surfaces.chain(std::iter::once(surface)) {
|
||||
if is_active {
|
||||
self.sctk_events.push(SctkEvent::KeyboardEvent {
|
||||
variant: KeyboardEventVariant::Enter(
|
||||
s.kbd_focus.clone().unwrap(),
|
||||
),
|
||||
kbd_id: s.kbd.clone().unwrap(),
|
||||
seat_id: s.seat.clone(),
|
||||
variant: KeyboardEventVariant::Leave(surface.clone()),
|
||||
kbd_id: kbd.clone(),
|
||||
seat_id: seat.clone(),
|
||||
surface: surface.clone(),
|
||||
})
|
||||
});
|
||||
// if there is another seat with a keyboard focused on a surface make that the new active seat
|
||||
if let Some(i) =
|
||||
self.seats.iter().position(|s| s.kbd_focus.is_some())
|
||||
{
|
||||
self.seats.swap(0, i);
|
||||
let s = &self.seats[0];
|
||||
let id = winit::window::WindowId::from_raw(
|
||||
surface.id().as_ptr() as usize,
|
||||
);
|
||||
if self.windows.iter().any(|w| w.window.id() == id) {
|
||||
continue;
|
||||
}
|
||||
self.sctk_events.push(SctkEvent::Winit(
|
||||
id,
|
||||
winit::event::WindowEvent::Focused(true),
|
||||
));
|
||||
self.sctk_events.push(SctkEvent::KeyboardEvent {
|
||||
variant: KeyboardEventVariant::Enter(
|
||||
s.kbd_focus.clone().unwrap(),
|
||||
),
|
||||
kbd_id: s.kbd.clone().unwrap(),
|
||||
seat_id: s.seat.clone(),
|
||||
surface: surface.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -150,35 +166,20 @@ impl KeyboardHandler for SctkState {
|
|||
let kbd_id = keyboard.clone();
|
||||
_ = my_seat.last_kbd_press.replace((event.clone(), serial));
|
||||
if is_active {
|
||||
// FIXME can't create winit key events because of private field
|
||||
// if let Some(id) = id {
|
||||
// let physical_key = raw_keycode_to_physicalkey(event.raw_code);
|
||||
// let (logical_key, location) =
|
||||
// keysym_to_vkey_location(event.keysym);
|
||||
// self.sctk_events.push(SctkEvent::Winit(
|
||||
// id,
|
||||
// winit::event::WindowEvent::KeyboardInput {
|
||||
// device_id: Default::default(),
|
||||
// event: winit::event::KeyEvent {
|
||||
// physical_key,
|
||||
// logical_key,
|
||||
// text: event.utf8.map(|s| s.into()),
|
||||
// location,
|
||||
// state: winit::event::ElementState::Pressed,
|
||||
// repeat: false, // TODO we don't have this info...
|
||||
// },
|
||||
// is_synthetic: false,
|
||||
// },
|
||||
// ))
|
||||
// }
|
||||
if let Some(surface) = my_seat.kbd_focus.clone() {
|
||||
self.request_redraw(&surface);
|
||||
self.sctk_events.push(SctkEvent::KeyboardEvent {
|
||||
variant: KeyboardEventVariant::Press(event),
|
||||
kbd_id,
|
||||
seat_id,
|
||||
surface,
|
||||
let surfaces = self.subsurfaces.iter().filter_map(|s| {
|
||||
(s.instance.parent == surface.id())
|
||||
.then(|| &s.instance.wl_surface)
|
||||
});
|
||||
for surface in surfaces.chain(std::iter::once(&surface)) {
|
||||
self.sctk_events.push(SctkEvent::KeyboardEvent {
|
||||
variant: KeyboardEventVariant::Press(event.clone()),
|
||||
kbd_id: kbd_id.clone(),
|
||||
seat_id: seat_id.clone(),
|
||||
surface: surface.clone(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -208,12 +209,18 @@ impl KeyboardHandler for SctkState {
|
|||
if is_active {
|
||||
if let Some(surface) = my_seat.kbd_focus.clone() {
|
||||
self.request_redraw(&surface);
|
||||
self.sctk_events.push(SctkEvent::KeyboardEvent {
|
||||
variant: KeyboardEventVariant::Release(event),
|
||||
kbd_id,
|
||||
seat_id,
|
||||
surface,
|
||||
let surfaces = self.subsurfaces.iter().filter_map(|s| {
|
||||
(s.instance.parent == surface.id())
|
||||
.then(|| &s.instance.wl_surface)
|
||||
});
|
||||
for surface in surfaces.chain(std::iter::once(&surface)) {
|
||||
self.sctk_events.push(SctkEvent::KeyboardEvent {
|
||||
variant: KeyboardEventVariant::Release(event.clone()),
|
||||
kbd_id: kbd_id.clone(),
|
||||
seat_id: seat_id.clone(),
|
||||
surface: surface.clone(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -244,12 +251,20 @@ impl KeyboardHandler for SctkState {
|
|||
if is_active {
|
||||
if let Some(surface) = my_seat.kbd_focus.clone() {
|
||||
self.request_redraw(&surface);
|
||||
self.sctk_events.push(SctkEvent::KeyboardEvent {
|
||||
variant: KeyboardEventVariant::Modifiers(modifiers),
|
||||
kbd_id,
|
||||
seat_id,
|
||||
surface,
|
||||
let surfaces = self.subsurfaces.iter().filter_map(|s| {
|
||||
(s.instance.parent == surface.id())
|
||||
.then(|| &s.instance.wl_surface)
|
||||
});
|
||||
for surface in surfaces.chain(std::iter::once(&surface)) {
|
||||
self.sctk_events.push(SctkEvent::KeyboardEvent {
|
||||
variant: KeyboardEventVariant::Modifiers(
|
||||
modifiers.clone(),
|
||||
),
|
||||
kbd_id: kbd_id.clone(),
|
||||
seat_id: seat_id.clone(),
|
||||
surface: surface.clone(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ use cctk::sctk::{
|
|||
CursorIcon, PointerEvent, PointerEventKind, PointerHandler,
|
||||
},
|
||||
};
|
||||
use iced_futures::core::Point;
|
||||
use winit::{
|
||||
dpi::PhysicalPosition,
|
||||
event::{
|
||||
|
|
@ -56,6 +57,7 @@ impl PointerHandler for SctkState {
|
|||
if self.windows.iter().any(|w| w.window.id() == id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let entry = self
|
||||
.frame_status
|
||||
.entry(e.surface.id())
|
||||
|
|
@ -63,6 +65,7 @@ impl PointerHandler for SctkState {
|
|||
if matches!(entry, FrameStatus::Received) {
|
||||
*entry = FrameStatus::Ready;
|
||||
}
|
||||
|
||||
if let PointerEventKind::Motion { time } = &e.kind {
|
||||
self.sctk_events.push(SctkEvent::PointerEvent {
|
||||
variant: PointerEvent {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ use crate::{
|
|||
event_loop::state::SctkState, sctk_event::SctkEvent,
|
||||
},
|
||||
};
|
||||
use iced_runtime::core::{touch, Point};
|
||||
use cctk::sctk::{
|
||||
delegate_touch,
|
||||
reexports::client::{
|
||||
|
|
@ -15,6 +14,7 @@ use cctk::sctk::{
|
|||
},
|
||||
seat::touch::TouchHandler,
|
||||
};
|
||||
use iced_runtime::core::{touch, Point};
|
||||
|
||||
impl TouchHandler for SctkState {
|
||||
fn down(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use crate::platform_specific::wayland::{
|
||||
handlers::SctkState, sctk_event::SctkEvent,
|
||||
use crate::{
|
||||
event_loop::state::CommonSurface,
|
||||
platform_specific::wayland::{handlers::SctkState, sctk_event::SctkEvent},
|
||||
};
|
||||
use cctk::sctk::{
|
||||
delegate_session_lock,
|
||||
|
|
@ -15,8 +16,9 @@ impl SessionLockHandler for SctkState {
|
|||
&mut self,
|
||||
_conn: &Connection,
|
||||
_qh: &QueueHandle<Self>,
|
||||
_session_lock: SessionLock,
|
||||
session_lock: SessionLock,
|
||||
) {
|
||||
self.session_lock = Some(session_lock);
|
||||
self.sctk_events.push(SctkEvent::SessionLocked);
|
||||
}
|
||||
|
||||
|
|
@ -44,8 +46,21 @@ impl SessionLockHandler for SctkState {
|
|||
Some(l) => l,
|
||||
None => return,
|
||||
};
|
||||
lock_surface
|
||||
.update_viewport(configure.new_size.0, configure.new_size.1);
|
||||
|
||||
let first = lock_surface.last_configure.is_none();
|
||||
_ = lock_surface.last_configure.replace(configure.clone());
|
||||
|
||||
self.sctk_events.push(SctkEvent::SessionLockSurfaceCreated {
|
||||
queue_handle: self.queue_handle.clone(),
|
||||
surface: CommonSurface::Lock(
|
||||
lock_surface.session_lock_surface.clone(),
|
||||
),
|
||||
native_id: lock_surface.id,
|
||||
common: lock_surface.common.clone(),
|
||||
display: self.connection.display(),
|
||||
});
|
||||
self.sctk_events
|
||||
.push(SctkEvent::SessionLockSurfaceConfigure {
|
||||
surface: session_lock_surface.wl_surface().clone(),
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use cctk::sctk::{
|
|||
delegate_xdg_popup, reexports::client::Proxy,
|
||||
shell::xdg::popup::PopupHandler,
|
||||
};
|
||||
use winit::dpi::LogicalSize;
|
||||
|
||||
impl PopupHandler for SctkState {
|
||||
fn configure(
|
||||
|
|
@ -24,6 +25,9 @@ impl PopupHandler for SctkState {
|
|||
};
|
||||
let first = sctk_popup.last_configure.is_none();
|
||||
_ = sctk_popup.last_configure.replace(configure.clone());
|
||||
let mut guard = sctk_popup.common.lock().unwrap();
|
||||
guard.size =
|
||||
LogicalSize::new(configure.width as u32, configure.height as u32);
|
||||
|
||||
self.sctk_events.push(SctkEvent::PopupEvent {
|
||||
variant: PopupEventVariant::Configure(
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
use cctk::{
|
||||
cosmic_protocols::{
|
||||
toplevel_management::v1::client::zcosmic_toplevel_manager_v1,
|
||||
},
|
||||
cosmic_protocols::toplevel_management::v1::client::zcosmic_toplevel_manager_v1,
|
||||
toplevel_info::{ToplevelInfoHandler, ToplevelInfoState},
|
||||
toplevel_management::ToplevelManagerHandler,
|
||||
wayland_client::{self, WEnum},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue