feat: overlap notify
This commit is contained in:
parent
6e91eabf4c
commit
301892aaa5
11 changed files with 441 additions and 51 deletions
|
|
@ -7,6 +7,7 @@ use crate::platform_specific::SurfaceIdWrapper;
|
|||
use crate::{
|
||||
Control,
|
||||
futures::futures::channel::mpsc,
|
||||
handlers::overlap::OverlapNotifyV1,
|
||||
platform_specific::wayland::{
|
||||
handlers::{
|
||||
wp_fractional_scaling::FractionalScalingManager,
|
||||
|
|
@ -17,25 +18,29 @@ use crate::{
|
|||
subsurface_widget::SubsurfaceState,
|
||||
};
|
||||
|
||||
use raw_window_handle::HasDisplayHandle;
|
||||
use cctk::sctk::reexports::calloop_wayland_source::WaylandSource;
|
||||
use cctk::sctk::{
|
||||
activation::ActivationState,
|
||||
compositor::CompositorState,
|
||||
globals::GlobalData,
|
||||
output::OutputState,
|
||||
reexports::{
|
||||
calloop::{self, EventLoop},
|
||||
client::{
|
||||
ConnectError, Connection, Proxy, globals::registry_queue_init,
|
||||
use cctk::{
|
||||
sctk::{
|
||||
activation::ActivationState,
|
||||
compositor::CompositorState,
|
||||
globals::GlobalData,
|
||||
output::OutputState,
|
||||
reexports::{
|
||||
calloop::{self, EventLoop},
|
||||
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,
|
||||
seat::SeatState,
|
||||
session_lock::SessionLockState,
|
||||
shell::{WaylandSurface, wlr_layer::LayerShell, xdg::XdgShell},
|
||||
shm::Shm,
|
||||
toplevel_info::ToplevelInfoState,
|
||||
toplevel_management::ToplevelManagerState,
|
||||
};
|
||||
use raw_window_handle::HasDisplayHandle;
|
||||
use state::{FrameStatus, SctkWindow};
|
||||
#[cfg(feature = "a11y")]
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
|
@ -188,7 +193,6 @@ impl SctkEventLoop {
|
|||
event_loop,
|
||||
state: SctkState {
|
||||
connection,
|
||||
registry_state,
|
||||
seat_state: SeatState::new(&globals, &qh),
|
||||
output_state: OutputState::new(&globals, &qh),
|
||||
compositor_state: CompositorState::bind(&globals, &qh)
|
||||
|
|
@ -201,6 +205,16 @@ impl SctkEventLoop {
|
|||
activation_state: ActivationState::bind(&globals, &qh).ok(),
|
||||
session_lock_state: SessionLockState::new(&globals, &qh),
|
||||
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,
|
||||
loop_handle,
|
||||
|
|
@ -228,6 +242,7 @@ impl SctkEventLoop {
|
|||
pending_popup: Default::default(),
|
||||
activation_token_ctr: 0,
|
||||
token_senders: HashMap::new(),
|
||||
overlap_notifications: HashMap::new(),
|
||||
},
|
||||
_features: Default::default(),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
use crate::{
|
||||
Control,
|
||||
handlers::activation::IcedRequestData,
|
||||
handlers::{
|
||||
activation::IcedRequestData,
|
||||
overlap::{OverlapNotificationV1, OverlapNotifyV1},
|
||||
},
|
||||
platform_specific::{
|
||||
Event,
|
||||
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},
|
||||
compositor::CompositorState,
|
||||
error::GlobalError,
|
||||
globals::GlobalData,
|
||||
output::OutputState,
|
||||
reexports::{
|
||||
calloop::{LoopHandle, timer::TimeoutAction},
|
||||
|
|
@ -74,15 +78,16 @@ use cctk::sctk::{
|
|||
WaylandSurface,
|
||||
wlr_layer::{
|
||||
Anchor, KeyboardInteractivity, Layer, LayerShell, LayerSurface,
|
||||
LayerSurfaceConfigure,
|
||||
LayerSurfaceConfigure, SurfaceKind,
|
||||
},
|
||||
xdg::{
|
||||
XdgPositioner, XdgShell,
|
||||
popup::{Popup, PopupConfigure},
|
||||
},
|
||||
},
|
||||
shm::{Shm, multi::MultiPool},
|
||||
};
|
||||
shm::{multi::MultiPool, Shm},
|
||||
}, toplevel_info::ToplevelInfoState, toplevel_management::ToplevelManagerState};
|
||||
|
||||
use wayland_protocols::{
|
||||
wp::{
|
||||
fractional_scale::v1::client::wp_fractional_scale_v1::WpFractionalScaleV1,
|
||||
|
|
@ -325,7 +330,11 @@ pub struct SctkState {
|
|||
/// a memory pool
|
||||
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>,
|
||||
// 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
|
||||
|
|
@ -378,6 +387,9 @@ pub struct SctkState {
|
|||
pub(crate) to_commit: HashMap<core::window::Id, WlSurface>,
|
||||
pub(crate) destroyed: HashSet<core::window::Id>,
|
||||
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) 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(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue