wl_surface: move dnd logic to separate module
This commit is contained in:
parent
f871ea1d67
commit
af15e20e9b
6 changed files with 93 additions and 45 deletions
|
|
@ -370,14 +370,7 @@ impl dyn GfxFramebuffer {
|
|||
}
|
||||
}
|
||||
if let Some(dnd_icon) = seat.dnd_icon() {
|
||||
let extents = dnd_icon.extents.get().move_(
|
||||
x.round_down() + dnd_icon.buf_x.get(),
|
||||
y.round_down() + dnd_icon.buf_y.get(),
|
||||
);
|
||||
if extents.intersects(&rect) {
|
||||
let (x, y) = rect.translate(extents.x1(), extents.y1());
|
||||
renderer.render_surface(&dnd_icon, x, y, None);
|
||||
}
|
||||
dnd_icon.render(&mut renderer, &rect, x.round_down(), y.round_down());
|
||||
}
|
||||
if render_cursor {
|
||||
let cursor_user_group = seat.cursor_group();
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use {
|
|||
IterableIpcVtable, OfferData, Role,
|
||||
},
|
||||
wl_seat::{WlSeatError, WlSeatGlobal},
|
||||
wl_surface::{SurfaceRole, WlSurfaceError},
|
||||
wl_surface::WlSurfaceError,
|
||||
},
|
||||
leaks::Tracker,
|
||||
object::{Object, Version},
|
||||
|
|
@ -115,8 +115,7 @@ impl WlDataDeviceRequestHandler for WlDataDevice {
|
|||
};
|
||||
let icon = if req.icon.is_some() {
|
||||
let icon = self.client.lookup(req.icon)?;
|
||||
icon.set_role(SurfaceRole::DndIcon)?;
|
||||
Some(icon)
|
||||
Some(icon.into_dnd_icon(&self.seat)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ use {
|
|||
zwp_pointer_gesture_swipe_v1::ZwpPointerGestureSwipeV1,
|
||||
zwp_relative_pointer_v1::ZwpRelativePointerV1,
|
||||
},
|
||||
wl_surface::WlSurface,
|
||||
wl_surface::{dnd_icon::DndIcon, WlSurface},
|
||||
xdg_toplevel_drag_v1::XdgToplevelDragV1,
|
||||
},
|
||||
leaks::Tracker,
|
||||
|
|
@ -723,11 +723,11 @@ impl WlSeatGlobal {
|
|||
self: &Rc<Self>,
|
||||
origin: &Rc<WlSurface>,
|
||||
source: Option<Rc<WlDataSource>>,
|
||||
icon: Option<Rc<WlSurface>>,
|
||||
icon: Option<Rc<DndIcon>>,
|
||||
serial: u32,
|
||||
) -> Result<(), WlSeatError> {
|
||||
if let Some(icon) = &icon {
|
||||
icon.set_output(&self.pointer_cursor.output());
|
||||
icon.surface().set_output(&self.pointer_cursor.output());
|
||||
}
|
||||
self.pointer_owner
|
||||
.start_drag(self, origin, source, icon, serial)
|
||||
|
|
@ -819,7 +819,7 @@ impl WlSeatGlobal {
|
|||
self.primary_selection.get()
|
||||
}
|
||||
|
||||
pub fn dnd_icon(&self) -> Option<Rc<WlSurface>> {
|
||||
pub fn dnd_icon(&self) -> Option<Rc<DndIcon>> {
|
||||
self.pointer_owner.dnd_icon()
|
||||
}
|
||||
|
||||
|
|
@ -926,7 +926,7 @@ impl WlSeatGlobal {
|
|||
pub fn set_visible(&self, visible: bool) {
|
||||
self.cursor_user_group.set_visible(visible);
|
||||
if let Some(icon) = self.dnd_icon() {
|
||||
icon.set_visible(visible);
|
||||
icon.surface().set_visible(visible);
|
||||
}
|
||||
if let Some(tl_drag) = self.toplevel_drag() {
|
||||
if let Some(tl) = tl_drag.toplevel.get() {
|
||||
|
|
@ -965,7 +965,7 @@ impl WlSeatGlobal {
|
|||
impl CursorUserOwner for WlSeatGlobal {
|
||||
fn output_changed(&self, output: &Rc<OutputNode>) {
|
||||
if let Some(dnd) = self.pointer_owner.dnd_icon() {
|
||||
dnd.set_output(output);
|
||||
dnd.surface().set_output(output);
|
||||
}
|
||||
if let Some(drag) = self.pointer_owner.toplevel_drag() {
|
||||
if let Some(tl) = drag.toplevel.get() {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use {
|
|||
wl_pointer::PendingScroll, Dnd, DroppedDnd, WlSeatError, WlSeatGlobal, BTN_LEFT,
|
||||
BTN_RIGHT, CHANGE_CURSOR_MOVED, CHANGE_TREE,
|
||||
},
|
||||
wl_surface::WlSurface,
|
||||
wl_surface::{dnd_icon::DndIcon, WlSurface},
|
||||
xdg_toplevel_drag_v1::XdgToplevelDragV1,
|
||||
},
|
||||
state::DeviceHandlerData,
|
||||
|
|
@ -120,7 +120,7 @@ impl PointerOwnerHolder {
|
|||
seat: &Rc<WlSeatGlobal>,
|
||||
origin: &Rc<WlSurface>,
|
||||
source: Option<Rc<WlDataSource>>,
|
||||
icon: Option<Rc<WlSurface>>,
|
||||
icon: Option<Rc<DndIcon>>,
|
||||
serial: u32,
|
||||
) -> Result<(), WlSeatError> {
|
||||
self.owner
|
||||
|
|
@ -144,7 +144,7 @@ impl PointerOwnerHolder {
|
|||
self.owner.get().dnd_target_removed(seat);
|
||||
}
|
||||
|
||||
pub fn dnd_icon(&self) -> Option<Rc<WlSurface>> {
|
||||
pub fn dnd_icon(&self) -> Option<Rc<DndIcon>> {
|
||||
self.owner.get().dnd_icon()
|
||||
}
|
||||
|
||||
|
|
@ -211,7 +211,7 @@ trait PointerOwner {
|
|||
seat: &Rc<WlSeatGlobal>,
|
||||
origin: &Rc<WlSurface>,
|
||||
source: Option<Rc<WlDataSource>>,
|
||||
icon: Option<Rc<WlSurface>>,
|
||||
icon: Option<Rc<DndIcon>>,
|
||||
serial: u32,
|
||||
) -> Result<(), WlSeatError> {
|
||||
let _ = origin;
|
||||
|
|
@ -232,7 +232,7 @@ trait PointerOwner {
|
|||
fn dnd_target_removed(&self, seat: &Rc<WlSeatGlobal>) {
|
||||
self.cancel_dnd(seat);
|
||||
}
|
||||
fn dnd_icon(&self) -> Option<Rc<WlSurface>> {
|
||||
fn dnd_icon(&self) -> Option<Rc<DndIcon>> {
|
||||
None
|
||||
}
|
||||
fn toplevel_drag(&self) -> Option<Rc<XdgToplevelDragV1>> {
|
||||
|
|
@ -264,7 +264,7 @@ struct DndPointerOwner {
|
|||
button: u32,
|
||||
dnd: Dnd,
|
||||
target: CloneCell<Rc<dyn Node>>,
|
||||
icon: CloneCell<Option<Rc<WlSurface>>>,
|
||||
icon: CloneCell<Option<Rc<DndIcon>>>,
|
||||
pos_x: Cell<Fixed>,
|
||||
pos_y: Cell<Fixed>,
|
||||
}
|
||||
|
|
@ -446,7 +446,7 @@ impl<T: SimplePointerOwnerUsecase> PointerOwner for SimpleGrabPointerOwner<T> {
|
|||
seat: &Rc<WlSeatGlobal>,
|
||||
origin: &Rc<WlSurface>,
|
||||
src: Option<Rc<WlDataSource>>,
|
||||
icon: Option<Rc<WlSurface>>,
|
||||
icon: Option<Rc<DndIcon>>,
|
||||
serial: u32,
|
||||
) -> Result<(), WlSeatError> {
|
||||
self.usecase
|
||||
|
|
@ -486,7 +486,7 @@ impl PointerOwner for DndPointerOwner {
|
|||
}
|
||||
}
|
||||
if let Some(icon) = self.icon.get() {
|
||||
icon.set_dnd_icon_seat(seat.id(), None);
|
||||
icon.disable();
|
||||
}
|
||||
seat.pointer_owner.set_default_pointer_owner(seat);
|
||||
seat.tree_changed.trigger();
|
||||
|
|
@ -542,7 +542,7 @@ impl PointerOwner for DndPointerOwner {
|
|||
ipc::detach_seat(&**src, seat);
|
||||
}
|
||||
if let Some(icon) = self.icon.get() {
|
||||
icon.set_dnd_icon_seat(seat.id(), None);
|
||||
icon.disable();
|
||||
}
|
||||
seat.pointer_owner.set_default_pointer_owner(seat);
|
||||
seat.tree_changed.trigger();
|
||||
|
|
@ -558,7 +558,7 @@ impl PointerOwner for DndPointerOwner {
|
|||
seat.state.tree_changed();
|
||||
}
|
||||
|
||||
fn dnd_icon(&self) -> Option<Rc<WlSurface>> {
|
||||
fn dnd_icon(&self) -> Option<Rc<DndIcon>> {
|
||||
self.icon.get()
|
||||
}
|
||||
|
||||
|
|
@ -593,7 +593,7 @@ trait SimplePointerOwnerUsecase: Sized + Clone + 'static {
|
|||
seat: &Rc<WlSeatGlobal>,
|
||||
origin: &Rc<WlSurface>,
|
||||
src: Option<Rc<WlDataSource>>,
|
||||
icon: Option<Rc<WlSurface>>,
|
||||
icon: Option<Rc<DndIcon>>,
|
||||
serial: u32,
|
||||
) -> Result<(), WlSeatError> {
|
||||
let _ = grab;
|
||||
|
|
@ -638,7 +638,7 @@ impl SimplePointerOwnerUsecase for DefaultPointerUsecase {
|
|||
seat: &Rc<WlSeatGlobal>,
|
||||
origin: &Rc<WlSurface>,
|
||||
src: Option<Rc<WlDataSource>>,
|
||||
icon: Option<Rc<WlSurface>>,
|
||||
icon: Option<Rc<DndIcon>>,
|
||||
serial: u32,
|
||||
) -> Result<(), WlSeatError> {
|
||||
let button = match grab.buttons.iter().next() {
|
||||
|
|
@ -655,7 +655,7 @@ impl SimplePointerOwnerUsecase for DefaultPointerUsecase {
|
|||
return Ok(());
|
||||
}
|
||||
if let Some(icon) = &icon {
|
||||
icon.set_dnd_icon_seat(seat.id, Some(seat));
|
||||
icon.enable();
|
||||
}
|
||||
if let Some(new) = &src {
|
||||
ipc::attach_seat(&**new, seat, ipc::Role::Dnd)?;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
pub mod commit_timeline;
|
||||
pub mod cursor;
|
||||
pub mod dnd_icon;
|
||||
pub mod ext_session_lock_surface_v1;
|
||||
pub mod wl_subsurface;
|
||||
pub mod wp_alpha_modifier_surface_v1;
|
||||
|
|
@ -41,6 +42,7 @@ use {
|
|||
wl_surface::{
|
||||
commit_timeline::{ClearReason, CommitTimeline, CommitTimelineError},
|
||||
cursor::CursorSurface,
|
||||
dnd_icon::DndIcon,
|
||||
wl_subsurface::{PendingSubsurfaceData, SubsurfaceId, WlSubsurface},
|
||||
wp_alpha_modifier_surface_v1::WpAlphaModifierSurfaceV1,
|
||||
wp_fractional_scale_v1::WpFractionalScaleV1,
|
||||
|
|
@ -273,7 +275,7 @@ pub struct WlSurface {
|
|||
seat_state: NodeSeatState,
|
||||
toplevel: CloneCell<Option<Rc<dyn ToplevelNode>>>,
|
||||
cursors: SmallMap<CursorUserId, Rc<CursorSurface>, 1>,
|
||||
dnd_icons: SmallMap<SeatId, Rc<WlSeatGlobal>, 1>,
|
||||
dnd_icons: SmallMap<SeatId, Rc<DndIcon>, 1>,
|
||||
pub tracker: Tracker<Self>,
|
||||
idle_inhibitors: SmallMap<ZwpIdleInhibitorV1Id, Rc<ZwpIdleInhibitorV1>, 1>,
|
||||
viewporter: CloneCell<Option<Rc<WpViewport>>>,
|
||||
|
|
@ -758,6 +760,17 @@ impl WlSurface {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn into_dnd_icon(
|
||||
self: &Rc<Self>,
|
||||
seat: &Rc<WlSeatGlobal>,
|
||||
) -> Result<Rc<DndIcon>, WlSurfaceError> {
|
||||
self.set_role(SurfaceRole::DndIcon)?;
|
||||
Ok(Rc::new(DndIcon {
|
||||
surface: self.clone(),
|
||||
seat: seat.clone(),
|
||||
}))
|
||||
}
|
||||
|
||||
fn unset_ext(&self) {
|
||||
self.ext.set(self.client.state.none_surface_ext.clone());
|
||||
}
|
||||
|
|
@ -806,8 +819,8 @@ impl WlSurface {
|
|||
}
|
||||
|
||||
fn unset_dnd_icons(&self) {
|
||||
while let Some((_, seat)) = self.dnd_icons.pop() {
|
||||
seat.remove_dnd_icon()
|
||||
while let Some((_, dnd_icon)) = self.dnd_icons.pop() {
|
||||
dnd_icon.seat.remove_dnd_icon();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1349,18 +1362,6 @@ impl WlSurface {
|
|||
.consume_pending_child(self, child, &mut consume)
|
||||
}
|
||||
|
||||
pub fn set_dnd_icon_seat(&self, id: SeatId, seat: Option<&Rc<WlSeatGlobal>>) {
|
||||
match seat {
|
||||
None => {
|
||||
self.dnd_icons.remove(&id);
|
||||
}
|
||||
Some(seat) => {
|
||||
self.dnd_icons.insert(id, seat.clone());
|
||||
}
|
||||
}
|
||||
self.set_visible(self.dnd_icons.is_not_empty() && self.client.state.root_visible());
|
||||
}
|
||||
|
||||
pub fn alpha(&self) -> Option<f32> {
|
||||
self.alpha.get()
|
||||
}
|
||||
|
|
|
|||
55
src/ifs/wl_surface/dnd_icon.rs
Normal file
55
src/ifs/wl_surface/dnd_icon.rs
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
use {
|
||||
crate::{
|
||||
ifs::{wl_seat::WlSeatGlobal, wl_surface::WlSurface},
|
||||
rect::Rect,
|
||||
renderer::Renderer,
|
||||
},
|
||||
std::rc::Rc,
|
||||
};
|
||||
|
||||
pub struct DndIcon {
|
||||
pub(super) surface: Rc<WlSurface>,
|
||||
pub(super) seat: Rc<WlSeatGlobal>,
|
||||
}
|
||||
|
||||
impl DndIcon {
|
||||
pub fn surface(&self) -> &Rc<WlSurface> {
|
||||
&self.surface
|
||||
}
|
||||
|
||||
fn update_visible(&self) {
|
||||
let is_visible =
|
||||
self.surface.dnd_icons.is_not_empty() && self.surface.client.state.root_visible();
|
||||
self.surface.set_visible(is_visible);
|
||||
}
|
||||
|
||||
pub fn enable(self: &Rc<Self>) {
|
||||
self.surface.dnd_icons.insert(self.seat.id(), self.clone());
|
||||
self.update_visible();
|
||||
}
|
||||
|
||||
pub fn disable(self: &Rc<Self>) {
|
||||
self.surface.dnd_icons.remove(&self.seat.id());
|
||||
self.update_visible();
|
||||
}
|
||||
|
||||
pub fn surface_position(&self, seat_x: i32, seat_y: i32) -> (i32, i32) {
|
||||
(
|
||||
seat_x + self.surface.buf_x.get(),
|
||||
seat_y + self.surface.buf_y.get(),
|
||||
)
|
||||
}
|
||||
|
||||
fn extents(&self, x: i32, y: i32) -> Rect {
|
||||
let (x, y) = self.surface_position(x, y);
|
||||
self.surface.extents.get().move_(x, y)
|
||||
}
|
||||
|
||||
pub fn render(&self, renderer: &mut Renderer<'_>, cursor_rect: &Rect, x: i32, y: i32) {
|
||||
let extents = self.extents(x, y);
|
||||
if extents.intersects(&cursor_rect) {
|
||||
let (x, y) = cursor_rect.translate(extents.x1(), extents.y1());
|
||||
renderer.render_surface(&self.surface, x, y, None);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue