mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-24 02:01:18 +07:00
Add dnd icon support
This commit is contained in:
+22
-1
@@ -4,6 +4,7 @@ mod xdg_shell;
|
||||
|
||||
use smithay::input::pointer::CursorImageStatus;
|
||||
use smithay::input::{Seat, SeatHandler, SeatState};
|
||||
use smithay::reexports::wayland_server::protocol::wl_data_source::WlDataSource;
|
||||
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
|
||||
use smithay::reexports::wayland_server::Resource;
|
||||
use smithay::wayland::data_device::{
|
||||
@@ -42,8 +43,28 @@ impl DataDeviceHandler for Niri {
|
||||
&self.data_device_state
|
||||
}
|
||||
}
|
||||
impl ClientDndGrabHandler for Niri {}
|
||||
|
||||
impl ClientDndGrabHandler for Niri {
|
||||
fn started(
|
||||
&mut self,
|
||||
_source: Option<WlDataSource>,
|
||||
icon: Option<WlSurface>,
|
||||
_seat: Seat<Self>,
|
||||
) {
|
||||
self.dnd_icon = icon;
|
||||
// FIXME: more granular
|
||||
self.queue_redraw_all();
|
||||
}
|
||||
|
||||
fn dropped(&mut self, _seat: Seat<Self>) {
|
||||
self.dnd_icon = None;
|
||||
// FIXME: more granular
|
||||
self.queue_redraw_all();
|
||||
}
|
||||
}
|
||||
|
||||
impl ServerDndGrabHandler for Niri {}
|
||||
|
||||
delegate_data_device!(Niri);
|
||||
|
||||
delegate_output!(Niri);
|
||||
|
||||
+33
-21
@@ -72,6 +72,7 @@ pub struct Niri {
|
||||
|
||||
pub pointer_buffer: SolidColorBuffer,
|
||||
pub cursor_image: CursorImageStatus,
|
||||
pub dnd_icon: Option<WlSurface>,
|
||||
}
|
||||
|
||||
pub struct OutputState {
|
||||
@@ -176,6 +177,7 @@ impl Niri {
|
||||
seat,
|
||||
pointer_buffer,
|
||||
cursor_image: CursorImageStatus::Default,
|
||||
dnd_icon: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,24 +334,9 @@ impl Niri {
|
||||
let output_pos = self.global_space.output_geometry(output).unwrap().loc;
|
||||
let pointer_pos = self.seat.get_pointer().unwrap().current_location() - output_pos.to_f64();
|
||||
|
||||
if let CursorImageStatus::Surface(surface) = &mut self.cursor_image {
|
||||
if !surface.alive() {
|
||||
self.cursor_image = CursorImageStatus::Default;
|
||||
}
|
||||
}
|
||||
|
||||
match &self.cursor_image {
|
||||
CursorImageStatus::Hidden => vec![],
|
||||
CursorImageStatus::Default => vec![OutputRenderElements::DefaultPointer(
|
||||
SolidColorRenderElement::from_buffer(
|
||||
&self.pointer_buffer,
|
||||
pointer_pos.to_physical_precise_round(1.),
|
||||
1.,
|
||||
1.,
|
||||
),
|
||||
)],
|
||||
CursorImageStatus::Surface(surface) => {
|
||||
let hotspot = with_states(surface, |states| {
|
||||
let hotspot = if let CursorImageStatus::Surface(surface) = &mut self.cursor_image {
|
||||
if surface.alive() {
|
||||
with_states(surface, |states| {
|
||||
states
|
||||
.data_map
|
||||
.get::<Mutex<CursorImageAttributes>>()
|
||||
@@ -357,12 +344,37 @@ impl Niri {
|
||||
.lock()
|
||||
.unwrap()
|
||||
.hotspot
|
||||
});
|
||||
let pos = (pointer_pos - hotspot.to_f64()).to_physical_precise_round(1.);
|
||||
})
|
||||
} else {
|
||||
self.cursor_image = CursorImageStatus::Default;
|
||||
(0, 0).into()
|
||||
}
|
||||
} else {
|
||||
(0, 0).into()
|
||||
};
|
||||
let pointer_pos = (pointer_pos - hotspot.to_f64()).to_physical_precise_round(1.);
|
||||
|
||||
render_elements_from_surface_tree(renderer, surface, pos, 1., 1.)
|
||||
let mut pointer_elements = match &self.cursor_image {
|
||||
CursorImageStatus::Hidden => vec![],
|
||||
CursorImageStatus::Default => vec![OutputRenderElements::DefaultPointer(
|
||||
SolidColorRenderElement::from_buffer(&self.pointer_buffer, pointer_pos, 1., 1.),
|
||||
)],
|
||||
CursorImageStatus::Surface(surface) => {
|
||||
render_elements_from_surface_tree(renderer, surface, pointer_pos, 1., 1.)
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(dnd_icon) = &self.dnd_icon {
|
||||
pointer_elements.extend(render_elements_from_surface_tree(
|
||||
renderer,
|
||||
dnd_icon,
|
||||
pointer_pos,
|
||||
1.,
|
||||
1.,
|
||||
));
|
||||
}
|
||||
|
||||
pointer_elements
|
||||
}
|
||||
|
||||
fn redraw(&mut self, backend: &mut dyn Backend, output: &Output) {
|
||||
|
||||
Reference in New Issue
Block a user