mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-23 02:05:33 +07:00
handle role specific buffer offset
This commit is contained in:
committed by
Ivan Molodetskikh
parent
80bb0d5876
commit
eb190e3f94
Generated
+2
-10
@@ -3346,12 +3346,6 @@ dependencies = [
|
|||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "scan_fmt"
|
|
||||||
version = "0.2.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0b53b0a5db882a8e2fdaae0a43f7b39e7e9082389e978398bdf223a55b581248"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "schemars"
|
name = "schemars"
|
||||||
version = "0.8.21"
|
version = "0.8.21"
|
||||||
@@ -3528,7 +3522,7 @@ checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "smithay"
|
name = "smithay"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
source = "git+https://github.com/Smithay/smithay.git#f364c73cae953aebfa189075e9f118f9008e100b"
|
source = "git+https://github.com/Smithay/smithay.git#b29ff8fdbfa3a15b777d36a7c5f19f86dfe5c94c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"appendlist",
|
"appendlist",
|
||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
@@ -3545,7 +3539,6 @@ dependencies = [
|
|||||||
"gl_generator",
|
"gl_generator",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"input",
|
"input",
|
||||||
"lazy_static",
|
|
||||||
"libc",
|
"libc",
|
||||||
"libloading",
|
"libloading",
|
||||||
"libseat",
|
"libseat",
|
||||||
@@ -3555,7 +3548,6 @@ dependencies = [
|
|||||||
"profiling",
|
"profiling",
|
||||||
"rand",
|
"rand",
|
||||||
"rustix 0.38.37",
|
"rustix 0.38.37",
|
||||||
"scan_fmt",
|
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
@@ -3602,7 +3594,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "smithay-drm-extras"
|
name = "smithay-drm-extras"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/Smithay/smithay.git#f364c73cae953aebfa189075e9f118f9008e100b"
|
source = "git+https://github.com/Smithay/smithay.git#b29ff8fdbfa3a15b777d36a7c5f19f86dfe5c94c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"drm",
|
"drm",
|
||||||
"libdisplay-info",
|
"libdisplay-info",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use std::collections::hash_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
|
|
||||||
use smithay::backend::renderer::utils::{on_commit_buffer_handler, with_renderer_surface_state};
|
use smithay::backend::renderer::utils::{on_commit_buffer_handler, with_renderer_surface_state};
|
||||||
use smithay::input::pointer::CursorImageStatus;
|
use smithay::input::pointer::{CursorImageStatus, CursorImageSurfaceData};
|
||||||
use smithay::reexports::calloop::Interest;
|
use smithay::reexports::calloop::Interest;
|
||||||
use smithay::reexports::wayland_server::protocol::wl_buffer;
|
use smithay::reexports::wayland_server::protocol::wl_buffer;
|
||||||
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
|
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
|
||||||
@@ -297,13 +297,52 @@ impl CompositorHandler for State {
|
|||||||
&self.niri.cursor_manager.cursor_image(),
|
&self.niri.cursor_manager.cursor_image(),
|
||||||
CursorImageStatus::Surface(s) if s == &root_surface
|
CursorImageStatus::Surface(s) if s == &root_surface
|
||||||
) {
|
) {
|
||||||
|
// In case the cursor surface has been committed handle the role specific
|
||||||
|
// buffer offset by applying the offset on the cursor image hotspot
|
||||||
|
if surface == &root_surface {
|
||||||
|
with_states(surface, |states| {
|
||||||
|
let cursor_image_attributes = states.data_map.get::<CursorImageSurfaceData>();
|
||||||
|
|
||||||
|
if let Some(mut cursor_image_attributes) =
|
||||||
|
cursor_image_attributes.map(|attrs| attrs.lock().unwrap())
|
||||||
|
{
|
||||||
|
let buffer_delta = states
|
||||||
|
.cached_state
|
||||||
|
.get::<SurfaceAttributes>()
|
||||||
|
.current()
|
||||||
|
.buffer_delta
|
||||||
|
.take();
|
||||||
|
if let Some(buffer_delta) = buffer_delta {
|
||||||
|
cursor_image_attributes.hotspot -= buffer_delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: granular redraws for cursors.
|
// FIXME: granular redraws for cursors.
|
||||||
self.niri.queue_redraw_all();
|
self.niri.queue_redraw_all();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This might be a DnD icon surface.
|
// This might be a DnD icon surface.
|
||||||
if self.niri.dnd_icon.as_ref() == Some(&root_surface) {
|
if matches!(&self.niri.dnd_icon, Some(icon) if icon.surface == root_surface) {
|
||||||
|
let dnd_icon = self.niri.dnd_icon.as_mut().unwrap();
|
||||||
|
|
||||||
|
// In case the dnd surface has been committed handle the role specific
|
||||||
|
// buffer offset by applying the offset on the dnd icon offset
|
||||||
|
if surface == &dnd_icon.surface {
|
||||||
|
with_states(&dnd_icon.surface, |states| {
|
||||||
|
let buffer_delta = states
|
||||||
|
.cached_state
|
||||||
|
.get::<SurfaceAttributes>()
|
||||||
|
.current()
|
||||||
|
.buffer_delta
|
||||||
|
.take()
|
||||||
|
.unwrap_or_default();
|
||||||
|
dnd_icon.offset += buffer_delta;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: granular redraws for cursors.
|
// FIXME: granular redraws for cursors.
|
||||||
self.niri.queue_redraw_all();
|
self.niri.queue_redraw_all();
|
||||||
return;
|
return;
|
||||||
|
|||||||
+22
-4
@@ -12,7 +12,9 @@ use smithay::backend::allocator::dmabuf::Dmabuf;
|
|||||||
use smithay::backend::drm::DrmNode;
|
use smithay::backend::drm::DrmNode;
|
||||||
use smithay::backend::input::TabletToolDescriptor;
|
use smithay::backend::input::TabletToolDescriptor;
|
||||||
use smithay::desktop::{PopupKind, PopupManager};
|
use smithay::desktop::{PopupKind, PopupManager};
|
||||||
use smithay::input::pointer::{CursorIcon, CursorImageStatus, PointerHandle};
|
use smithay::input::pointer::{
|
||||||
|
CursorIcon, CursorImageStatus, CursorImageSurfaceData, PointerHandle,
|
||||||
|
};
|
||||||
use smithay::input::{keyboard, Seat, SeatHandler, SeatState};
|
use smithay::input::{keyboard, Seat, SeatHandler, SeatState};
|
||||||
use smithay::output::Output;
|
use smithay::output::Output;
|
||||||
use smithay::reexports::rustix::fs::{fcntl_setfl, OFlags};
|
use smithay::reexports::rustix::fs::{fcntl_setfl, OFlags};
|
||||||
@@ -22,7 +24,7 @@ use smithay::reexports::wayland_server::protocol::wl_data_source::WlDataSource;
|
|||||||
use smithay::reexports::wayland_server::protocol::wl_output::WlOutput;
|
use smithay::reexports::wayland_server::protocol::wl_output::WlOutput;
|
||||||
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
|
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
|
||||||
use smithay::reexports::wayland_server::Resource;
|
use smithay::reexports::wayland_server::Resource;
|
||||||
use smithay::utils::{Logical, Rectangle, Size};
|
use smithay::utils::{Logical, Point, Rectangle, Size};
|
||||||
use smithay::wayland::compositor::with_states;
|
use smithay::wayland::compositor::with_states;
|
||||||
use smithay::wayland::dmabuf::{DmabufGlobal, DmabufHandler, DmabufState, ImportNotifier};
|
use smithay::wayland::dmabuf::{DmabufGlobal, DmabufHandler, DmabufState, ImportNotifier};
|
||||||
use smithay::wayland::drm_lease::{
|
use smithay::wayland::drm_lease::{
|
||||||
@@ -64,7 +66,7 @@ use smithay::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub use crate::handlers::xdg_shell::KdeDecorationsModeState;
|
pub use crate::handlers::xdg_shell::KdeDecorationsModeState;
|
||||||
use crate::niri::{ClientState, State};
|
use crate::niri::{ClientState, DndIcon, State};
|
||||||
use crate::protocols::foreign_toplevel::{
|
use crate::protocols::foreign_toplevel::{
|
||||||
self, ForeignToplevelHandler, ForeignToplevelManagerState,
|
self, ForeignToplevelHandler, ForeignToplevelManagerState,
|
||||||
};
|
};
|
||||||
@@ -225,7 +227,23 @@ impl ClientDndGrabHandler for State {
|
|||||||
icon: Option<WlSurface>,
|
icon: Option<WlSurface>,
|
||||||
_seat: Seat<Self>,
|
_seat: Seat<Self>,
|
||||||
) {
|
) {
|
||||||
self.niri.dnd_icon = icon;
|
let offset = if let CursorImageStatus::Surface(ref surface) =
|
||||||
|
self.niri.cursor_manager.cursor_image()
|
||||||
|
{
|
||||||
|
with_states(surface, |states| {
|
||||||
|
let hotspot = states
|
||||||
|
.data_map
|
||||||
|
.get::<CursorImageSurfaceData>()
|
||||||
|
.unwrap()
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.hotspot;
|
||||||
|
Point::from((-hotspot.x, -hotspot.y))
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
(0, 0).into()
|
||||||
|
};
|
||||||
|
self.niri.dnd_icon = icon.map(|surface| DndIcon { surface, offset });
|
||||||
// FIXME: more granular
|
// FIXME: more granular
|
||||||
self.niri.queue_redraw_all();
|
self.niri.queue_redraw_all();
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-7
@@ -11,7 +11,7 @@ use niri_ipc::LayoutSwitchTarget;
|
|||||||
use smithay::backend::input::{
|
use smithay::backend::input::{
|
||||||
AbsolutePositionEvent, Axis, AxisSource, ButtonState, Device, DeviceCapability, Event,
|
AbsolutePositionEvent, Axis, AxisSource, ButtonState, Device, DeviceCapability, Event,
|
||||||
GestureBeginEvent, GestureEndEvent, GesturePinchUpdateEvent as _, GestureSwipeUpdateEvent as _,
|
GestureBeginEvent, GestureEndEvent, GesturePinchUpdateEvent as _, GestureSwipeUpdateEvent as _,
|
||||||
InputBackend, InputEvent, KeyState, KeyboardKeyEvent, MouseButton, PointerAxisEvent,
|
InputBackend, InputEvent, KeyState, KeyboardKeyEvent, Keycode, MouseButton, PointerAxisEvent,
|
||||||
PointerButtonEvent, PointerMotionEvent, ProximityState, TabletToolButtonEvent, TabletToolEvent,
|
PointerButtonEvent, PointerMotionEvent, ProximityState, TabletToolButtonEvent, TabletToolEvent,
|
||||||
TabletToolProximityEvent, TabletToolTipEvent, TabletToolTipState, TouchEvent,
|
TabletToolProximityEvent, TabletToolTipEvent, TabletToolTipState, TouchEvent,
|
||||||
};
|
};
|
||||||
@@ -2305,10 +2305,10 @@ impl State {
|
|||||||
/// to them from being delivered.
|
/// to them from being delivered.
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn should_intercept_key(
|
fn should_intercept_key(
|
||||||
suppressed_keys: &mut HashSet<u32>,
|
suppressed_keys: &mut HashSet<Keycode>,
|
||||||
bindings: &Binds,
|
bindings: &Binds,
|
||||||
comp_mod: CompositorMod,
|
comp_mod: CompositorMod,
|
||||||
key_code: u32,
|
key_code: Keycode,
|
||||||
modified: Keysym,
|
modified: Keysym,
|
||||||
raw: Option<Keysym>,
|
raw: Option<Keysym>,
|
||||||
pressed: bool,
|
pressed: bool,
|
||||||
@@ -2754,8 +2754,8 @@ mod tests {
|
|||||||
// The key_code we pick is arbitrary, the only thing
|
// The key_code we pick is arbitrary, the only thing
|
||||||
// that matters is that they are different between cases.
|
// that matters is that they are different between cases.
|
||||||
|
|
||||||
let close_key_code = close_keysym.into();
|
let close_key_code = Keycode::from(close_keysym.raw() + 8u32);
|
||||||
let close_key_event = |suppr: &mut HashSet<u32>, mods: ModifiersState, pressed| {
|
let close_key_event = |suppr: &mut HashSet<Keycode>, mods: ModifiersState, pressed| {
|
||||||
should_intercept_key(
|
should_intercept_key(
|
||||||
suppr,
|
suppr,
|
||||||
&bindings,
|
&bindings,
|
||||||
@@ -2771,12 +2771,12 @@ mod tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Key event with the code which can't trigger any action.
|
// Key event with the code which can't trigger any action.
|
||||||
let none_key_event = |suppr: &mut HashSet<u32>, mods: ModifiersState, pressed| {
|
let none_key_event = |suppr: &mut HashSet<Keycode>, mods: ModifiersState, pressed| {
|
||||||
should_intercept_key(
|
should_intercept_key(
|
||||||
suppr,
|
suppr,
|
||||||
&bindings,
|
&bindings,
|
||||||
comp_mod,
|
comp_mod,
|
||||||
Keysym::l.into(),
|
Keycode::from(Keysym::l.raw() + 8),
|
||||||
Keysym::l,
|
Keysym::l,
|
||||||
Some(Keysym::l),
|
Some(Keysym::l),
|
||||||
pressed,
|
pressed,
|
||||||
|
|||||||
+25
-15
@@ -17,6 +17,7 @@ use niri_config::{
|
|||||||
DEFAULT_BACKGROUND_COLOR,
|
DEFAULT_BACKGROUND_COLOR,
|
||||||
};
|
};
|
||||||
use smithay::backend::allocator::Fourcc;
|
use smithay::backend::allocator::Fourcc;
|
||||||
|
use smithay::backend::input::Keycode;
|
||||||
use smithay::backend::renderer::damage::OutputDamageTracker;
|
use smithay::backend::renderer::damage::OutputDamageTracker;
|
||||||
use smithay::backend::renderer::element::memory::MemoryRenderBufferRenderElement;
|
use smithay::backend::renderer::element::memory::MemoryRenderBufferRenderElement;
|
||||||
use smithay::backend::renderer::element::solid::{SolidColorBuffer, SolidColorRenderElement};
|
use smithay::backend::renderer::element::solid::{SolidColorBuffer, SolidColorRenderElement};
|
||||||
@@ -248,7 +249,7 @@ pub struct Niri {
|
|||||||
|
|
||||||
pub seat: Seat<State>,
|
pub seat: Seat<State>,
|
||||||
/// Scancodes of the keys to suppress.
|
/// Scancodes of the keys to suppress.
|
||||||
pub suppressed_keys: HashSet<u32>,
|
pub suppressed_keys: HashSet<Keycode>,
|
||||||
pub bind_cooldown_timers: HashMap<Key, RegistrationToken>,
|
pub bind_cooldown_timers: HashMap<Key, RegistrationToken>,
|
||||||
pub bind_repeat_timer: Option<RegistrationToken>,
|
pub bind_repeat_timer: Option<RegistrationToken>,
|
||||||
pub keyboard_focus: KeyboardFocus,
|
pub keyboard_focus: KeyboardFocus,
|
||||||
@@ -259,7 +260,7 @@ pub struct Niri {
|
|||||||
pub cursor_manager: CursorManager,
|
pub cursor_manager: CursorManager,
|
||||||
pub cursor_texture_cache: CursorTextureCache,
|
pub cursor_texture_cache: CursorTextureCache,
|
||||||
pub cursor_shape_manager_state: CursorShapeManagerState,
|
pub cursor_shape_manager_state: CursorShapeManagerState,
|
||||||
pub dnd_icon: Option<WlSurface>,
|
pub dnd_icon: Option<DndIcon>,
|
||||||
pub pointer_focus: PointerFocus,
|
pub pointer_focus: PointerFocus,
|
||||||
/// Whether the pointer is hidden, for example due to a previous touch input.
|
/// Whether the pointer is hidden, for example due to a previous touch input.
|
||||||
///
|
///
|
||||||
@@ -304,6 +305,12 @@ pub struct Niri {
|
|||||||
pub mapped_cast_output: HashMap<Window, Output>,
|
pub mapped_cast_output: HashMap<Window, Output>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct DndIcon {
|
||||||
|
pub surface: WlSurface,
|
||||||
|
pub offset: Point<i32, Logical>,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct OutputState {
|
pub struct OutputState {
|
||||||
pub global: GlobalId,
|
pub global: GlobalId,
|
||||||
pub frame_clock: FrameClock,
|
pub frame_clock: FrameClock,
|
||||||
@@ -2588,8 +2595,8 @@ impl Niri {
|
|||||||
|
|
||||||
let output_scale = Scale::from(output.current_scale().fractional_scale());
|
let output_scale = Scale::from(output.current_scale().fractional_scale());
|
||||||
|
|
||||||
let (mut pointer_elements, pointer_pos) = match render_cursor {
|
let mut pointer_elements = match render_cursor {
|
||||||
RenderCursor::Hidden => (vec![], pointer_pos.to_physical_precise_round(output_scale)),
|
RenderCursor::Hidden => vec![],
|
||||||
RenderCursor::Surface { surface, hotspot } => {
|
RenderCursor::Surface { surface, hotspot } => {
|
||||||
let pointer_pos =
|
let pointer_pos =
|
||||||
(pointer_pos - hotspot.to_f64()).to_physical_precise_round(output_scale);
|
(pointer_pos - hotspot.to_f64()).to_physical_precise_round(output_scale);
|
||||||
@@ -2603,7 +2610,7 @@ impl Niri {
|
|||||||
Kind::Cursor,
|
Kind::Cursor,
|
||||||
);
|
);
|
||||||
|
|
||||||
(pointer_elements, pointer_pos)
|
pointer_elements
|
||||||
}
|
}
|
||||||
RenderCursor::Named {
|
RenderCursor::Named {
|
||||||
icon,
|
icon,
|
||||||
@@ -2619,7 +2626,7 @@ impl Niri {
|
|||||||
let mut pointer_elements = vec![];
|
let mut pointer_elements = vec![];
|
||||||
let pointer_element = match MemoryRenderBufferRenderElement::from_buffer(
|
let pointer_element = match MemoryRenderBufferRenderElement::from_buffer(
|
||||||
renderer,
|
renderer,
|
||||||
pointer_pos.to_f64(),
|
pointer_pos,
|
||||||
&texture,
|
&texture,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
@@ -2636,14 +2643,16 @@ impl Niri {
|
|||||||
pointer_elements.push(OutputRenderElements::NamedPointer(element));
|
pointer_elements.push(OutputRenderElements::NamedPointer(element));
|
||||||
}
|
}
|
||||||
|
|
||||||
(pointer_elements, pointer_pos)
|
pointer_elements
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(dnd_icon) = &self.dnd_icon {
|
if let Some(dnd_icon) = self.dnd_icon.as_ref() {
|
||||||
|
let pointer_pos =
|
||||||
|
(pointer_pos + dnd_icon.offset.to_f64()).to_physical_precise_round(output_scale);
|
||||||
pointer_elements.extend(render_elements_from_surface_tree(
|
pointer_elements.extend(render_elements_from_surface_tree(
|
||||||
renderer,
|
renderer,
|
||||||
dnd_icon,
|
&dnd_icon.surface,
|
||||||
pointer_pos,
|
pointer_pos,
|
||||||
output_scale,
|
output_scale,
|
||||||
1.,
|
1.,
|
||||||
@@ -2684,6 +2693,7 @@ impl Niri {
|
|||||||
let dnd = self
|
let dnd = self
|
||||||
.dnd_icon
|
.dnd_icon
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
.map(|icon| &icon.surface)
|
||||||
.map(|surface| (surface, bbox_from_surface_tree(surface, surface_pos)));
|
.map(|surface| (surface, bbox_from_surface_tree(surface, surface_pos)));
|
||||||
|
|
||||||
// FIXME we basically need to pick the largest scale factor across the overlapping
|
// FIXME we basically need to pick the largest scale factor across the overlapping
|
||||||
@@ -2745,7 +2755,7 @@ impl Niri {
|
|||||||
}
|
}
|
||||||
cursor_image => {
|
cursor_image => {
|
||||||
// There's no cursor surface, but there might be a DnD icon.
|
// There's no cursor surface, but there might be a DnD icon.
|
||||||
let Some(surface) = &self.dnd_icon else {
|
let Some(surface) = self.dnd_icon.as_ref().map(|icon| &icon.surface) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -3267,7 +3277,7 @@ impl Niri {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(surface) = &self.dnd_icon {
|
if let Some(surface) = self.dnd_icon.as_ref().map(|icon| &icon.surface) {
|
||||||
with_surface_tree_downward(
|
with_surface_tree_downward(
|
||||||
surface,
|
surface,
|
||||||
(),
|
(),
|
||||||
@@ -3405,7 +3415,7 @@ impl Niri {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(surface) = &self.dnd_icon {
|
if let Some(surface) = self.dnd_icon.as_ref().map(|icon| &icon.surface) {
|
||||||
send_dmabuf_feedback_surface_tree(
|
send_dmabuf_feedback_surface_tree(
|
||||||
surface,
|
surface,
|
||||||
output,
|
output,
|
||||||
@@ -3507,7 +3517,7 @@ impl Niri {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(surface) = &self.dnd_icon {
|
if let Some(surface) = self.dnd_icon.as_ref().map(|icon| &icon.surface) {
|
||||||
send_frames_surface_tree(
|
send_frames_surface_tree(
|
||||||
surface,
|
surface,
|
||||||
output,
|
output,
|
||||||
@@ -3575,7 +3585,7 @@ impl Niri {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(surface) = &self.dnd_icon {
|
if let Some(surface) = &self.dnd_icon.as_ref().map(|icon| &icon.surface) {
|
||||||
send_frames_surface_tree(
|
send_frames_surface_tree(
|
||||||
surface,
|
surface,
|
||||||
output,
|
output,
|
||||||
@@ -3614,7 +3624,7 @@ impl Niri {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(surface) = &self.dnd_icon {
|
if let Some(surface) = self.dnd_icon.as_ref().map(|icon| &icon.surface) {
|
||||||
take_presentation_feedback_surface_tree(
|
take_presentation_feedback_surface_tree(
|
||||||
surface,
|
surface,
|
||||||
&mut feedback,
|
&mut feedback,
|
||||||
|
|||||||
Reference in New Issue
Block a user