feat: overlap notify
This commit is contained in:
parent
6e91eabf4c
commit
301892aaa5
11 changed files with 441 additions and 51 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
mod layer;
|
mod layer;
|
||||||
mod output;
|
mod output;
|
||||||
|
mod overlap_notify;
|
||||||
mod popup;
|
mod popup;
|
||||||
mod seat;
|
mod seat;
|
||||||
mod session_lock;
|
mod session_lock;
|
||||||
|
|
@ -12,6 +13,7 @@ use cctk::sctk::reexports::client::protocol::{
|
||||||
|
|
||||||
pub use layer::*;
|
pub use layer::*;
|
||||||
pub use output::*;
|
pub use output::*;
|
||||||
|
pub use overlap_notify::*;
|
||||||
pub use popup::*;
|
pub use popup::*;
|
||||||
pub use seat::*;
|
pub use seat::*;
|
||||||
pub use session_lock::*;
|
pub use session_lock::*;
|
||||||
|
|
@ -26,6 +28,8 @@ pub enum Event {
|
||||||
Popup(PopupEvent, WlSurface, Id),
|
Popup(PopupEvent, WlSurface, Id),
|
||||||
/// output event
|
/// output event
|
||||||
Output(OutputEvent, WlOutput),
|
Output(OutputEvent, WlOutput),
|
||||||
|
/// Overlap notify event
|
||||||
|
OverlapNotify(overlap_notify::OverlapNotifyEvent),
|
||||||
/// window event
|
/// window event
|
||||||
Window(WindowEvent),
|
Window(WindowEvent),
|
||||||
/// Seat Event
|
/// Seat Event
|
||||||
|
|
|
||||||
21
core/src/event/wayland/overlap_notify.rs
Normal file
21
core/src/event/wayland/overlap_notify.rs
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
use cctk::{sctk::shell::wlr_layer::Layer, wayland_protocols::ext::foreign_toplevel_list::v1::client::ext_foreign_toplevel_handle_v1::ExtForeignToplevelHandleV1};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub enum OverlapNotifyEvent {
|
||||||
|
OverlapToplevelAdd {
|
||||||
|
toplevel: ExtForeignToplevelHandleV1,
|
||||||
|
logical_rect: crate::Rectangle,
|
||||||
|
},
|
||||||
|
OverlapToplevelRemove {
|
||||||
|
toplevel: ExtForeignToplevelHandleV1,
|
||||||
|
},
|
||||||
|
OverlapLayerAdd {
|
||||||
|
identifier: String,
|
||||||
|
exclusive: u32,
|
||||||
|
layer: Option<Layer>,
|
||||||
|
logical_rect: crate::Rectangle,
|
||||||
|
},
|
||||||
|
OverlapLayerRemove {
|
||||||
|
identifier: String,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
|
use iced_core::window::Id;
|
||||||
|
|
||||||
/// activation Actions
|
/// activation Actions
|
||||||
pub mod activation;
|
pub mod activation;
|
||||||
|
|
||||||
|
|
@ -22,21 +24,26 @@ pub enum Action {
|
||||||
Activation(activation::Action),
|
Activation(activation::Action),
|
||||||
/// session lock
|
/// session lock
|
||||||
SessionLock(session_lock::Action),
|
SessionLock(session_lock::Action),
|
||||||
|
/// Overlap Notify
|
||||||
|
OverlapNotify(Id, bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for Action {
|
impl Debug for Action {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Self::LayerSurface(arg0) => {
|
Action::LayerSurface(arg0) => {
|
||||||
f.debug_tuple("LayerSurface").field(arg0).finish()
|
f.debug_tuple("LayerSurface").field(arg0).finish()
|
||||||
}
|
}
|
||||||
Self::Popup(arg0) => f.debug_tuple("Popup").field(arg0).finish(),
|
Action::Popup(arg0) => f.debug_tuple("Popup").field(arg0).finish(),
|
||||||
Self::Activation(arg0) => {
|
Action::Activation(arg0) => {
|
||||||
f.debug_tuple("Activation").field(arg0).finish()
|
f.debug_tuple("Activation").field(arg0).finish()
|
||||||
}
|
}
|
||||||
Self::SessionLock(arg0) => {
|
Action::SessionLock(arg0) => {
|
||||||
f.debug_tuple("SessionLock").field(arg0).finish()
|
f.debug_tuple("SessionLock").field(arg0).finish()
|
||||||
}
|
}
|
||||||
|
Action::OverlapNotify(id, _) => {
|
||||||
|
f.debug_tuple("OverlapNotify").field(id).finish()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,5 +2,6 @@
|
||||||
|
|
||||||
pub mod activation;
|
pub mod activation;
|
||||||
pub mod layer_surface;
|
pub mod layer_surface;
|
||||||
|
pub mod overlap_notify;
|
||||||
pub mod popup;
|
pub mod popup;
|
||||||
pub mod session_lock;
|
pub mod session_lock;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
use iced_futures::core::window::Id;
|
||||||
|
use iced_runtime::{
|
||||||
|
platform_specific::{self, wayland},
|
||||||
|
task, Action, Task,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Request subscription for overlap notification events on the surface
|
||||||
|
pub fn overlap_notify<Message>(id: Id, enable: bool) -> Task<Message> {
|
||||||
|
task::effect(Action::PlatformSpecific(
|
||||||
|
platform_specific::Action::Wayland(wayland::Action::OverlapNotify(
|
||||||
|
id, enable,
|
||||||
|
)),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
@ -7,6 +7,7 @@ use crate::platform_specific::SurfaceIdWrapper;
|
||||||
use crate::{
|
use crate::{
|
||||||
Control,
|
Control,
|
||||||
futures::futures::channel::mpsc,
|
futures::futures::channel::mpsc,
|
||||||
|
handlers::overlap::OverlapNotifyV1,
|
||||||
platform_specific::wayland::{
|
platform_specific::wayland::{
|
||||||
handlers::{
|
handlers::{
|
||||||
wp_fractional_scaling::FractionalScalingManager,
|
wp_fractional_scaling::FractionalScalingManager,
|
||||||
|
|
@ -17,25 +18,29 @@ use crate::{
|
||||||
subsurface_widget::SubsurfaceState,
|
subsurface_widget::SubsurfaceState,
|
||||||
};
|
};
|
||||||
|
|
||||||
use raw_window_handle::HasDisplayHandle;
|
|
||||||
use cctk::sctk::reexports::calloop_wayland_source::WaylandSource;
|
use cctk::sctk::reexports::calloop_wayland_source::WaylandSource;
|
||||||
use cctk::sctk::{
|
use cctk::{
|
||||||
activation::ActivationState,
|
sctk::{
|
||||||
compositor::CompositorState,
|
activation::ActivationState,
|
||||||
globals::GlobalData,
|
compositor::CompositorState,
|
||||||
output::OutputState,
|
globals::GlobalData,
|
||||||
reexports::{
|
output::OutputState,
|
||||||
calloop::{self, EventLoop},
|
reexports::{
|
||||||
client::{
|
calloop::{self, EventLoop},
|
||||||
ConnectError, Connection, Proxy, globals::registry_queue_init,
|
client::{
|
||||||
|
ConnectError, Connection, Proxy, globals::registry_queue_init,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
registry::RegistryState,
|
||||||
|
seat::SeatState,
|
||||||
|
session_lock::SessionLockState,
|
||||||
|
shell::{WaylandSurface, wlr_layer::LayerShell, xdg::XdgShell},
|
||||||
|
shm::Shm,
|
||||||
},
|
},
|
||||||
registry::RegistryState,
|
toplevel_info::ToplevelInfoState,
|
||||||
seat::SeatState,
|
toplevel_management::ToplevelManagerState,
|
||||||
session_lock::SessionLockState,
|
|
||||||
shell::{WaylandSurface, wlr_layer::LayerShell, xdg::XdgShell},
|
|
||||||
shm::Shm,
|
|
||||||
};
|
};
|
||||||
|
use raw_window_handle::HasDisplayHandle;
|
||||||
use state::{FrameStatus, SctkWindow};
|
use state::{FrameStatus, SctkWindow};
|
||||||
#[cfg(feature = "a11y")]
|
#[cfg(feature = "a11y")]
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
@ -188,7 +193,6 @@ impl SctkEventLoop {
|
||||||
event_loop,
|
event_loop,
|
||||||
state: SctkState {
|
state: SctkState {
|
||||||
connection,
|
connection,
|
||||||
registry_state,
|
|
||||||
seat_state: SeatState::new(&globals, &qh),
|
seat_state: SeatState::new(&globals, &qh),
|
||||||
output_state: OutputState::new(&globals, &qh),
|
output_state: OutputState::new(&globals, &qh),
|
||||||
compositor_state: CompositorState::bind(&globals, &qh)
|
compositor_state: CompositorState::bind(&globals, &qh)
|
||||||
|
|
@ -201,6 +205,16 @@ impl SctkEventLoop {
|
||||||
activation_state: ActivationState::bind(&globals, &qh).ok(),
|
activation_state: ActivationState::bind(&globals, &qh).ok(),
|
||||||
session_lock_state: SessionLockState::new(&globals, &qh),
|
session_lock_state: SessionLockState::new(&globals, &qh),
|
||||||
session_lock: None,
|
session_lock: None,
|
||||||
|
overlap_notify: OverlapNotifyV1::bind(&globals, &qh).ok(),
|
||||||
|
toplevel_info: ToplevelInfoState::try_new(
|
||||||
|
®istry_state,
|
||||||
|
&qh,
|
||||||
|
),
|
||||||
|
toplevel_manager: ToplevelManagerState::try_new(
|
||||||
|
®istry_state,
|
||||||
|
&qh,
|
||||||
|
),
|
||||||
|
registry_state,
|
||||||
|
|
||||||
queue_handle: qh,
|
queue_handle: qh,
|
||||||
loop_handle,
|
loop_handle,
|
||||||
|
|
@ -228,6 +242,7 @@ impl SctkEventLoop {
|
||||||
pending_popup: Default::default(),
|
pending_popup: Default::default(),
|
||||||
activation_token_ctr: 0,
|
activation_token_ctr: 0,
|
||||||
token_senders: HashMap::new(),
|
token_senders: HashMap::new(),
|
||||||
|
overlap_notifications: HashMap::new(),
|
||||||
},
|
},
|
||||||
_features: Default::default(),
|
_features: Default::default(),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
Control,
|
Control,
|
||||||
handlers::activation::IcedRequestData,
|
handlers::{
|
||||||
|
activation::IcedRequestData,
|
||||||
|
overlap::{OverlapNotificationV1, OverlapNotifyV1},
|
||||||
|
},
|
||||||
platform_specific::{
|
platform_specific::{
|
||||||
Event,
|
Event,
|
||||||
wayland::{
|
wayland::{
|
||||||
|
|
@ -39,10 +42,11 @@ use iced_runtime::{
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use cctk::sctk::{
|
use cctk::{cosmic_protocols::overlap_notify::v1::client::zcosmic_overlap_notification_v1::ZcosmicOverlapNotificationV1, sctk::{
|
||||||
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},
|
||||||
|
|
@ -74,15 +78,16 @@ use cctk::sctk::{
|
||||||
WaylandSurface,
|
WaylandSurface,
|
||||||
wlr_layer::{
|
wlr_layer::{
|
||||||
Anchor, KeyboardInteractivity, Layer, LayerShell, LayerSurface,
|
Anchor, KeyboardInteractivity, Layer, LayerShell, LayerSurface,
|
||||||
LayerSurfaceConfigure,
|
LayerSurfaceConfigure, SurfaceKind,
|
||||||
},
|
},
|
||||||
xdg::{
|
xdg::{
|
||||||
XdgPositioner, XdgShell,
|
XdgPositioner, XdgShell,
|
||||||
popup::{Popup, PopupConfigure},
|
popup::{Popup, PopupConfigure},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
shm::{Shm, multi::MultiPool},
|
shm::{multi::MultiPool, Shm},
|
||||||
};
|
}, toplevel_info::ToplevelInfoState, toplevel_management::ToplevelManagerState};
|
||||||
|
|
||||||
use wayland_protocols::{
|
use wayland_protocols::{
|
||||||
wp::{
|
wp::{
|
||||||
fractional_scale::v1::client::wp_fractional_scale_v1::WpFractionalScaleV1,
|
fractional_scale::v1::client::wp_fractional_scale_v1::WpFractionalScaleV1,
|
||||||
|
|
@ -325,7 +330,11 @@ pub struct SctkState {
|
||||||
/// a memory pool
|
/// a memory pool
|
||||||
pub(crate) _multipool: Option<MultiPool<WlSurface>>,
|
pub(crate) _multipool: Option<MultiPool<WlSurface>>,
|
||||||
|
|
||||||
// all present outputs
|
/// all notification objects
|
||||||
|
pub(crate) overlap_notifications:
|
||||||
|
HashMap<ObjectId, ZcosmicOverlapNotificationV1>,
|
||||||
|
|
||||||
|
/// all present outputs
|
||||||
pub(crate) outputs: Vec<WlOutput>,
|
pub(crate) outputs: Vec<WlOutput>,
|
||||||
// though (for now) only one seat will be active in an iced application at a time, all ought to be tracked
|
// though (for now) only one seat will be active in an iced application at a time, all ought to be tracked
|
||||||
// Active seat is the first seat in the list
|
// Active seat is the first seat in the list
|
||||||
|
|
@ -378,6 +387,9 @@ pub struct SctkState {
|
||||||
pub(crate) to_commit: HashMap<core::window::Id, WlSurface>,
|
pub(crate) to_commit: HashMap<core::window::Id, WlSurface>,
|
||||||
pub(crate) destroyed: HashSet<core::window::Id>,
|
pub(crate) destroyed: HashSet<core::window::Id>,
|
||||||
pub(crate) pending_popup: Option<(SctkPopupSettings, usize)>,
|
pub(crate) pending_popup: Option<(SctkPopupSettings, usize)>,
|
||||||
|
pub(crate) overlap_notify: Option<OverlapNotifyV1>,
|
||||||
|
pub(crate) toplevel_info: Option<ToplevelInfoState>,
|
||||||
|
pub(crate) toplevel_manager: Option<ToplevelManagerState>,
|
||||||
|
|
||||||
pub(crate) activation_token_ctr: u32,
|
pub(crate) activation_token_ctr: u32,
|
||||||
pub(crate) token_senders: HashMap<u32, oneshot::Sender<Option<String>>>,
|
pub(crate) token_senders: HashMap<u32, oneshot::Sender<Option<String>>>,
|
||||||
|
|
@ -1175,6 +1187,27 @@ impl SctkState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Action::OverlapNotify(id, enabled) => {
|
||||||
|
if let Some(layer_surface) = self.layer_surfaces.iter_mut().find(|l| l.id == id) {
|
||||||
|
let Some(overlap_notify_state) = self.overlap_notify.as_ref() else {
|
||||||
|
tracing::error!("Overlap notify is not supported.");
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
let my_id = layer_surface.surface.wl_surface().id();
|
||||||
|
if enabled && !self.overlap_notifications.contains_key(&my_id) {
|
||||||
|
let SurfaceKind::Wlr(wlr) = &layer_surface.surface.kind() else {
|
||||||
|
tracing::error!("Overlap notify is not supported for non wlr surface.");
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
let notification = overlap_notify_state.notify.notify_on_overlap(wlr, &self.queue_handle, OverlapNotificationV1 { surface: layer_surface.surface.wl_surface().clone() });
|
||||||
|
_ = self.overlap_notifications.insert(my_id, notification);
|
||||||
|
} else {
|
||||||
|
_ = self.overlap_notifications.remove(&my_id);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tracing::error!("Overlap notify subscription cannot be created for surface. No matching layer surface found.");
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,12 @@
|
||||||
pub mod activation;
|
pub mod activation;
|
||||||
pub mod compositor;
|
pub mod compositor;
|
||||||
pub mod output;
|
pub mod output;
|
||||||
// pub mod overlap;
|
pub mod overlap;
|
||||||
pub mod seat;
|
pub mod seat;
|
||||||
pub mod session_lock;
|
pub mod session_lock;
|
||||||
pub mod shell;
|
pub mod shell;
|
||||||
pub mod subcompositor;
|
pub mod subcompositor;
|
||||||
|
pub mod toplevel;
|
||||||
pub mod wp_fractional_scaling;
|
pub mod wp_fractional_scaling;
|
||||||
pub mod wp_viewporter;
|
pub mod wp_viewporter;
|
||||||
|
|
||||||
|
|
|
||||||
117
winit/src/platform_specific/wayland/handlers/overlap.rs
Normal file
117
winit/src/platform_specific/wayland/handlers/overlap.rs
Normal file
|
|
@ -0,0 +1,117 @@
|
||||||
|
use cctk::{
|
||||||
|
cosmic_protocols::overlap_notify::v1::client::{
|
||||||
|
zcosmic_overlap_notification_v1::{self, ZcosmicOverlapNotificationV1},
|
||||||
|
zcosmic_overlap_notify_v1::ZcosmicOverlapNotifyV1,
|
||||||
|
}, sctk::shell::wlr_layer::Layer, wayland_client::{
|
||||||
|
self, event_created_child,
|
||||||
|
globals::{BindError, GlobalList},
|
||||||
|
protocol::wl_surface::WlSurface,
|
||||||
|
Connection, Dispatch, Proxy, QueueHandle,
|
||||||
|
}, wayland_protocols::ext::foreign_toplevel_list::v1::client::ext_foreign_toplevel_handle_v1::ExtForeignToplevelHandleV1
|
||||||
|
};
|
||||||
|
use cctk::sctk::globals::GlobalData;
|
||||||
|
use iced_futures::core::Rectangle;
|
||||||
|
|
||||||
|
use crate::{event_loop::state::SctkState, sctk_event::SctkEvent};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct OverlapNotifyV1 {
|
||||||
|
pub(crate) notify: ZcosmicOverlapNotifyV1,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OverlapNotifyV1 {
|
||||||
|
pub fn bind(
|
||||||
|
globals: &GlobalList,
|
||||||
|
qh: &QueueHandle<SctkState>,
|
||||||
|
) -> Result<OverlapNotifyV1, BindError> {
|
||||||
|
let notify = globals.bind(qh, 1..=1, GlobalData)?;
|
||||||
|
Ok(OverlapNotifyV1 { notify })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Dispatch<ZcosmicOverlapNotifyV1, GlobalData, SctkState>
|
||||||
|
for OverlapNotifyV1
|
||||||
|
{
|
||||||
|
fn event(
|
||||||
|
_: &mut SctkState,
|
||||||
|
_: &ZcosmicOverlapNotifyV1,
|
||||||
|
_: <ZcosmicOverlapNotifyV1 as Proxy>::Event,
|
||||||
|
_: &GlobalData,
|
||||||
|
_: &Connection,
|
||||||
|
_: &QueueHandle<SctkState>,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct OverlapNotificationV1 {
|
||||||
|
pub surface: WlSurface,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Dispatch<ZcosmicOverlapNotificationV1, OverlapNotificationV1, SctkState>
|
||||||
|
for OverlapNotificationV1
|
||||||
|
{
|
||||||
|
fn event(
|
||||||
|
state: &mut SctkState,
|
||||||
|
_: &ZcosmicOverlapNotificationV1,
|
||||||
|
event: <ZcosmicOverlapNotificationV1 as Proxy>::Event,
|
||||||
|
data: &OverlapNotificationV1,
|
||||||
|
_: &Connection,
|
||||||
|
_: &QueueHandle<SctkState>,
|
||||||
|
) {
|
||||||
|
let surface = data.surface.clone();
|
||||||
|
|
||||||
|
state.sctk_events.push(match event {
|
||||||
|
zcosmic_overlap_notification_v1::Event::ToplevelEnter {
|
||||||
|
toplevel,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
} => SctkEvent::OverlapToplevelAdd {
|
||||||
|
surface,
|
||||||
|
toplevel,
|
||||||
|
logical_rect: Rectangle::new(
|
||||||
|
(x as f32, y as f32).into(),
|
||||||
|
(width as f32, height as f32).into(),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
zcosmic_overlap_notification_v1::Event::ToplevelLeave {
|
||||||
|
toplevel,
|
||||||
|
} => {
|
||||||
|
SctkEvent::OverlapToplevelRemove { surface, toplevel }
|
||||||
|
}
|
||||||
|
zcosmic_overlap_notification_v1::Event::LayerEnter {
|
||||||
|
identifier,
|
||||||
|
exclusive,
|
||||||
|
layer,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
} => SctkEvent::OverlapLayerAdd { surface, identifier, exclusive, layer: match layer {
|
||||||
|
wayland_client::WEnum::Value(v) => match v {
|
||||||
|
cctk::sctk::reexports::protocols_wlr::layer_shell::v1::client::zwlr_layer_shell_v1::Layer::Background => Some(Layer::Background),
|
||||||
|
cctk::sctk::reexports::protocols_wlr::layer_shell::v1::client::zwlr_layer_shell_v1::Layer::Bottom => Some(Layer::Bottom),
|
||||||
|
cctk::sctk::reexports::protocols_wlr::layer_shell::v1::client::zwlr_layer_shell_v1::Layer::Top => Some(Layer::Top),
|
||||||
|
cctk::sctk::reexports::protocols_wlr::layer_shell::v1::client::zwlr_layer_shell_v1::Layer::Overlay => Some(Layer::Overlay),
|
||||||
|
_ => Default::default(),
|
||||||
|
},
|
||||||
|
wayland_client::WEnum::Unknown(_) => Default::default(),
|
||||||
|
}, logical_rect: Rectangle::new(
|
||||||
|
(x as f32, y as f32).into(),
|
||||||
|
(width as f32, height as f32).into(),
|
||||||
|
), },
|
||||||
|
zcosmic_overlap_notification_v1::Event::LayerLeave {
|
||||||
|
identifier,
|
||||||
|
} => SctkEvent::OverlapLayerRemove { identifier, surface },
|
||||||
|
_ => unimplemented!(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
event_created_child!(SctkState, ZcosmicOverlapNotifyV1, [
|
||||||
|
0 => (ExtForeignToplevelHandleV1, Default::default())
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
wayland_client::delegate_dispatch!(SctkState: [ZcosmicOverlapNotifyV1: GlobalData] => OverlapNotifyV1);
|
||||||
|
wayland_client::delegate_dispatch!(SctkState: [ZcosmicOverlapNotificationV1: OverlapNotificationV1] => OverlapNotificationV1);
|
||||||
67
winit/src/platform_specific/wayland/handlers/toplevel.rs
Normal file
67
winit/src/platform_specific/wayland/handlers/toplevel.rs
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
use cctk::{
|
||||||
|
cosmic_protocols::{
|
||||||
|
toplevel_info::v1::client::zcosmic_toplevel_handle_v1,
|
||||||
|
toplevel_management::v1::client::zcosmic_toplevel_manager_v1,
|
||||||
|
},
|
||||||
|
toplevel_info::{ToplevelInfoHandler, ToplevelInfoState},
|
||||||
|
toplevel_management::ToplevelManagerHandler,
|
||||||
|
wayland_client::{self, WEnum},
|
||||||
|
};
|
||||||
|
use wayland_client::{Connection, QueueHandle};
|
||||||
|
|
||||||
|
use crate::event_loop::state::SctkState;
|
||||||
|
|
||||||
|
impl ToplevelManagerHandler for SctkState {
|
||||||
|
fn toplevel_manager_state(
|
||||||
|
&mut self,
|
||||||
|
) -> &mut cctk::toplevel_management::ToplevelManagerState {
|
||||||
|
self.toplevel_manager.as_mut().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn capabilities(
|
||||||
|
&mut self,
|
||||||
|
_conn: &Connection,
|
||||||
|
_: &QueueHandle<Self>,
|
||||||
|
_capabilities: Vec<
|
||||||
|
WEnum<zcosmic_toplevel_manager_v1::ZcosmicToplelevelManagementCapabilitiesV1>,
|
||||||
|
>,
|
||||||
|
) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToplevelInfoHandler for SctkState {
|
||||||
|
fn toplevel_info_state(&mut self) -> &mut ToplevelInfoState {
|
||||||
|
self.toplevel_info.as_mut().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_toplevel(
|
||||||
|
&mut self,
|
||||||
|
_conn: &Connection,
|
||||||
|
_qh: &QueueHandle<Self>,
|
||||||
|
_toplevel: &zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1,
|
||||||
|
) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_toplevel(
|
||||||
|
&mut self,
|
||||||
|
_conn: &Connection,
|
||||||
|
_qh: &QueueHandle<Self>,
|
||||||
|
_toplevel: &zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1,
|
||||||
|
) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
fn toplevel_closed(
|
||||||
|
&mut self,
|
||||||
|
_conn: &Connection,
|
||||||
|
_qh: &QueueHandle<Self>,
|
||||||
|
_toplevel: &zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1,
|
||||||
|
) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cctk::delegate_toplevel_info!(SctkState);
|
||||||
|
cctk::delegate_toplevel_manager!(SctkState);
|
||||||
|
|
@ -20,9 +20,12 @@ use iced_futures::{
|
||||||
Clipboard as _,
|
Clipboard as _,
|
||||||
event::{
|
event::{
|
||||||
PlatformSpecific,
|
PlatformSpecific,
|
||||||
wayland::{LayerEvent, PopupEvent, SessionLockEvent},
|
wayland::{
|
||||||
|
LayerEvent, OverlapNotifyEvent, PopupEvent, SessionLockEvent,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
event,
|
||||||
futures::channel::mpsc,
|
futures::channel::mpsc,
|
||||||
};
|
};
|
||||||
use iced_graphics::{Compositor, compositor};
|
use iced_graphics::{Compositor, compositor};
|
||||||
|
|
@ -37,30 +40,33 @@ use iced_runtime::{
|
||||||
user_interface,
|
user_interface,
|
||||||
};
|
};
|
||||||
|
|
||||||
use cctk::sctk::{
|
use cctk::{
|
||||||
output::OutputInfo,
|
cosmic_protocols::overlap_notify::v1::client::zcosmic_overlap_notification_v1,
|
||||||
reexports::{
|
sctk::{
|
||||||
calloop::channel,
|
output::OutputInfo,
|
||||||
client::{
|
reexports::{
|
||||||
Proxy, QueueHandle,
|
calloop::channel,
|
||||||
backend::ObjectId,
|
client::{
|
||||||
protocol::{
|
Proxy, QueueHandle,
|
||||||
wl_display::WlDisplay, wl_keyboard::WlKeyboard,
|
backend::ObjectId,
|
||||||
wl_output::WlOutput, wl_pointer::WlPointer, wl_seat::WlSeat,
|
protocol::{
|
||||||
wl_surface::WlSurface, wl_touch::WlTouch,
|
wl_display::WlDisplay, wl_keyboard::WlKeyboard,
|
||||||
|
wl_output::WlOutput, wl_pointer::WlPointer,
|
||||||
|
wl_seat::WlSeat, wl_surface::WlSurface, wl_touch::WlTouch,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
csd_frame::WindowManagerCapabilities,
|
||||||
|
},
|
||||||
|
seat::{
|
||||||
|
Capability,
|
||||||
|
keyboard::{KeyEvent, Modifiers},
|
||||||
|
pointer::{PointerEvent, PointerEventKind},
|
||||||
|
},
|
||||||
|
session_lock::SessionLockSurfaceConfigure,
|
||||||
|
shell::{
|
||||||
|
wlr_layer::{Layer, LayerSurfaceConfigure},
|
||||||
|
xdg::{popup::PopupConfigure, window::WindowConfigure},
|
||||||
},
|
},
|
||||||
csd_frame::WindowManagerCapabilities,
|
|
||||||
},
|
|
||||||
seat::{
|
|
||||||
Capability,
|
|
||||||
keyboard::{KeyEvent, Modifiers},
|
|
||||||
pointer::{PointerEvent, PointerEventKind},
|
|
||||||
},
|
|
||||||
session_lock::SessionLockSurfaceConfigure,
|
|
||||||
shell::{
|
|
||||||
wlr_layer::LayerSurfaceConfigure,
|
|
||||||
xdg::{popup::PopupConfigure, window::WindowConfigure},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
|
|
@ -68,7 +74,10 @@ use std::{
|
||||||
num::NonZeroU32,
|
num::NonZeroU32,
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
use wayland_protocols::wp::viewporter::client::wp_viewport::WpViewport;
|
use wayland_protocols::{
|
||||||
|
ext::foreign_toplevel_list::v1::client::ext_foreign_toplevel_handle_v1::ExtForeignToplevelHandleV1,
|
||||||
|
wp::viewporter::client::wp_viewport::WpViewport,
|
||||||
|
};
|
||||||
use winit::{
|
use winit::{
|
||||||
dpi::PhysicalSize, event::WindowEvent, event_loop::EventLoopProxy,
|
dpi::PhysicalSize, event::WindowEvent, event_loop::EventLoopProxy,
|
||||||
window::WindowId,
|
window::WindowId,
|
||||||
|
|
@ -120,6 +129,26 @@ pub enum SctkEvent {
|
||||||
variant: LayerSurfaceEventVariant,
|
variant: LayerSurfaceEventVariant,
|
||||||
id: WlSurface,
|
id: WlSurface,
|
||||||
},
|
},
|
||||||
|
OverlapToplevelAdd {
|
||||||
|
surface: WlSurface,
|
||||||
|
toplevel: ExtForeignToplevelHandleV1,
|
||||||
|
logical_rect: iced_runtime::core::Rectangle,
|
||||||
|
},
|
||||||
|
OverlapToplevelRemove {
|
||||||
|
surface: WlSurface,
|
||||||
|
toplevel: ExtForeignToplevelHandleV1,
|
||||||
|
},
|
||||||
|
OverlapLayerAdd {
|
||||||
|
surface: WlSurface,
|
||||||
|
identifier: String,
|
||||||
|
exclusive: u32,
|
||||||
|
layer: Option<Layer>,
|
||||||
|
logical_rect: iced_runtime::core::Rectangle,
|
||||||
|
},
|
||||||
|
OverlapLayerRemove {
|
||||||
|
surface: WlSurface,
|
||||||
|
identifier: String,
|
||||||
|
},
|
||||||
PopupEvent {
|
PopupEvent {
|
||||||
variant: PopupEventVariant,
|
variant: PopupEventVariant,
|
||||||
/// this may be the Id of a window or layer surface
|
/// this may be the Id of a window or layer surface
|
||||||
|
|
@ -1195,6 +1224,87 @@ impl SctkEvent {
|
||||||
SctkEvent::Subcompositor(s) => {
|
SctkEvent::Subcompositor(s) => {
|
||||||
*subsurface_state = Some(s);
|
*subsurface_state = Some(s);
|
||||||
}
|
}
|
||||||
|
SctkEvent::OverlapToplevelAdd {
|
||||||
|
surface,
|
||||||
|
toplevel,
|
||||||
|
logical_rect,
|
||||||
|
} => {
|
||||||
|
if let Some(id) = surface_ids.get(&surface.id()) {
|
||||||
|
events.push((
|
||||||
|
Some(id.inner()),
|
||||||
|
iced_runtime::core::Event::PlatformSpecific(
|
||||||
|
PlatformSpecific::Wayland(
|
||||||
|
wayland::Event::OverlapNotify(
|
||||||
|
OverlapNotifyEvent::OverlapToplevelAdd {
|
||||||
|
toplevel,
|
||||||
|
logical_rect,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SctkEvent::OverlapToplevelRemove { surface, toplevel } => {
|
||||||
|
if let Some(id) = surface_ids.get(&surface.id()) {
|
||||||
|
events.push((
|
||||||
|
Some(id.inner()),
|
||||||
|
iced_runtime::core::Event::PlatformSpecific(
|
||||||
|
PlatformSpecific::Wayland(
|
||||||
|
wayland::Event::OverlapNotify(
|
||||||
|
OverlapNotifyEvent::OverlapToplevelRemove {
|
||||||
|
toplevel,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SctkEvent::OverlapLayerAdd {
|
||||||
|
surface,
|
||||||
|
identifier,
|
||||||
|
exclusive,
|
||||||
|
layer,
|
||||||
|
logical_rect,
|
||||||
|
} => {
|
||||||
|
if let Some(id) = surface_ids.get(&surface.id()) {
|
||||||
|
events.push((
|
||||||
|
Some(id.inner()),
|
||||||
|
iced_runtime::core::Event::PlatformSpecific(
|
||||||
|
PlatformSpecific::Wayland(
|
||||||
|
wayland::Event::OverlapNotify(
|
||||||
|
OverlapNotifyEvent::OverlapLayerAdd {
|
||||||
|
identifier,
|
||||||
|
exclusive,
|
||||||
|
layer,
|
||||||
|
logical_rect,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SctkEvent::OverlapLayerRemove {
|
||||||
|
surface,
|
||||||
|
identifier,
|
||||||
|
} => {
|
||||||
|
if let Some(id) = surface_ids.get(&surface.id()) {
|
||||||
|
events.push((
|
||||||
|
Some(id.inner()),
|
||||||
|
iced_runtime::core::Event::PlatformSpecific(
|
||||||
|
PlatformSpecific::Wayland(
|
||||||
|
wayland::Event::OverlapNotify(
|
||||||
|
OverlapNotifyEvent::OverlapLayerRemove {
|
||||||
|
identifier,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue