aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock12
-rw-r--r--src/handlers/compositor.rs43
-rw-r--r--src/handlers/mod.rs26
-rw-r--r--src/input/mod.rs14
-rw-r--r--src/niri.rs40
5 files changed, 97 insertions, 38 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 00bedd34..ff7baa64 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3347,12 +3347,6 @@ dependencies = [
]
[[package]]
-name = "scan_fmt"
-version = "0.2.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b53b0a5db882a8e2fdaae0a43f7b39e7e9082389e978398bdf223a55b581248"
-
-[[package]]
name = "schemars"
version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3528,7 +3522,7 @@ checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c"
[[package]]
name = "smithay"
version = "0.3.0"
-source = "git+https://github.com/Smithay/smithay.git#f364c73cae953aebfa189075e9f118f9008e100b"
+source = "git+https://github.com/Smithay/smithay.git#b29ff8fdbfa3a15b777d36a7c5f19f86dfe5c94c"
dependencies = [
"appendlist",
"bitflags 2.6.0",
@@ -3545,7 +3539,6 @@ dependencies = [
"gl_generator",
"indexmap",
"input",
- "lazy_static",
"libc",
"libloading",
"libseat",
@@ -3555,7 +3548,6 @@ dependencies = [
"profiling",
"rand",
"rustix 0.38.37",
- "scan_fmt",
"smallvec",
"tempfile",
"thiserror",
@@ -3602,7 +3594,7 @@ dependencies = [
[[package]]
name = "smithay-drm-extras"
version = "0.1.0"
-source = "git+https://github.com/Smithay/smithay.git#f364c73cae953aebfa189075e9f118f9008e100b"
+source = "git+https://github.com/Smithay/smithay.git#b29ff8fdbfa3a15b777d36a7c5f19f86dfe5c94c"
dependencies = [
"drm",
"libdisplay-info",
diff --git a/src/handlers/compositor.rs b/src/handlers/compositor.rs
index 57be5ad3..ceb22b78 100644
--- a/src/handlers/compositor.rs
+++ b/src/handlers/compositor.rs
@@ -1,7 +1,7 @@
use std::collections::hash_map::Entry;
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::wayland_server::protocol::wl_buffer;
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
@@ -297,13 +297,52 @@ impl CompositorHandler for State {
&self.niri.cursor_manager.cursor_image(),
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.
self.niri.queue_redraw_all();
return;
}
// 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.
self.niri.queue_redraw_all();
return;
diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs
index 3e0bb18f..63bde132 100644
--- a/src/handlers/mod.rs
+++ b/src/handlers/mod.rs
@@ -12,7 +12,9 @@ use smithay::backend::allocator::dmabuf::Dmabuf;
use smithay::backend::drm::DrmNode;
use smithay::backend::input::TabletToolDescriptor;
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::output::Output;
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_surface::WlSurface;
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::dmabuf::{DmabufGlobal, DmabufHandler, DmabufState, ImportNotifier};
use smithay::wayland::drm_lease::{
@@ -64,7 +66,7 @@ use smithay::{
};
pub use crate::handlers::xdg_shell::KdeDecorationsModeState;
-use crate::niri::{ClientState, State};
+use crate::niri::{ClientState, DndIcon, State};
use crate::protocols::foreign_toplevel::{
self, ForeignToplevelHandler, ForeignToplevelManagerState,
};
@@ -225,7 +227,23 @@ impl ClientDndGrabHandler for State {
icon: Option<WlSurface>,
_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
self.niri.queue_redraw_all();
}
diff --git a/src/input/mod.rs b/src/input/mod.rs
index 7fc606ba..afa215ff 100644
--- a/src/input/mod.rs
+++ b/src/input/mod.rs
@@ -11,7 +11,7 @@ use niri_ipc::LayoutSwitchTarget;
use smithay::backend::input::{
AbsolutePositionEvent, Axis, AxisSource, ButtonState, Device, DeviceCapability, Event,
GestureBeginEvent, GestureEndEvent, GesturePinchUpdateEvent as _, GestureSwipeUpdateEvent as _,
- InputBackend, InputEvent, KeyState, KeyboardKeyEvent, MouseButton, PointerAxisEvent,
+ InputBackend, InputEvent, KeyState, KeyboardKeyEvent, Keycode, MouseButton, PointerAxisEvent,
PointerButtonEvent, PointerMotionEvent, ProximityState, TabletToolButtonEvent, TabletToolEvent,
TabletToolProximityEvent, TabletToolTipEvent, TabletToolTipState, TouchEvent,
};
@@ -2305,10 +2305,10 @@ impl State {
/// to them from being delivered.
#[allow(clippy::too_many_arguments)]
fn should_intercept_key(
- suppressed_keys: &mut HashSet<u32>,
+ suppressed_keys: &mut HashSet<Keycode>,
bindings: &Binds,
comp_mod: CompositorMod,
- key_code: u32,
+ key_code: Keycode,
modified: Keysym,
raw: Option<Keysym>,
pressed: bool,
@@ -2754,8 +2754,8 @@ mod tests {
// The key_code we pick is arbitrary, the only thing
// that matters is that they are different between cases.
- let close_key_code = close_keysym.into();
- let close_key_event = |suppr: &mut HashSet<u32>, mods: ModifiersState, pressed| {
+ let close_key_code = Keycode::from(close_keysym.raw() + 8u32);
+ let close_key_event = |suppr: &mut HashSet<Keycode>, mods: ModifiersState, pressed| {
should_intercept_key(
suppr,
&bindings,
@@ -2771,12 +2771,12 @@ mod tests {
};
// 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(
suppr,
&bindings,
comp_mod,
- Keysym::l.into(),
+ Keycode::from(Keysym::l.raw() + 8),
Keysym::l,
Some(Keysym::l),
pressed,
diff --git a/src/niri.rs b/src/niri.rs
index bdebe8bd..a2c81ae6 100644
--- a/src/niri.rs
+++ b/src/niri.rs
@@ -17,6 +17,7 @@ use niri_config::{
DEFAULT_BACKGROUND_COLOR,
};
use smithay::backend::allocator::Fourcc;
+use smithay::backend::input::Keycode;
use smithay::backend::renderer::damage::OutputDamageTracker;
use smithay::backend::renderer::element::memory::MemoryRenderBufferRenderElement;
use smithay::backend::renderer::element::solid::{SolidColorBuffer, SolidColorRenderElement};
@@ -248,7 +249,7 @@ pub struct Niri {
pub seat: Seat<State>,
/// 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_repeat_timer: Option<RegistrationToken>,
pub keyboard_focus: KeyboardFocus,
@@ -259,7 +260,7 @@ pub struct Niri {
pub cursor_manager: CursorManager,
pub cursor_texture_cache: CursorTextureCache,
pub cursor_shape_manager_state: CursorShapeManagerState,
- pub dnd_icon: Option<WlSurface>,
+ pub dnd_icon: Option<DndIcon>,
pub pointer_focus: PointerFocus,
/// 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>,
}
+#[derive(Debug)]
+pub struct DndIcon {
+ pub surface: WlSurface,
+ pub offset: Point<i32, Logical>,
+}
+
pub struct OutputState {
pub global: GlobalId,
pub frame_clock: FrameClock,
@@ -2588,8 +2595,8 @@ impl Niri {
let output_scale = Scale::from(output.current_scale().fractional_scale());
- let (mut pointer_elements, pointer_pos) = match render_cursor {
- RenderCursor::Hidden => (vec![], pointer_pos.to_physical_precise_round(output_scale)),
+ let mut pointer_elements = match render_cursor {
+ RenderCursor::Hidden => vec![],
RenderCursor::Surface { surface, hotspot } => {
let pointer_pos =
(pointer_pos - hotspot.to_f64()).to_physical_precise_round(output_scale);
@@ -2603,7 +2610,7 @@ impl Niri {
Kind::Cursor,
);
- (pointer_elements, pointer_pos)
+ pointer_elements
}
RenderCursor::Named {
icon,
@@ -2619,7 +2626,7 @@ impl Niri {
let mut pointer_elements = vec![];
let pointer_element = match MemoryRenderBufferRenderElement::from_buffer(
renderer,
- pointer_pos.to_f64(),
+ pointer_pos,
&texture,
None,
None,
@@ -2636,14 +2643,16 @@ impl Niri {
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(
renderer,
- dnd_icon,
+ &dnd_icon.surface,
pointer_pos,
output_scale,
1.,
@@ -2684,6 +2693,7 @@ impl Niri {
let dnd = self
.dnd_icon
.as_ref()
+ .map(|icon| &icon.surface)
.map(|surface| (surface, bbox_from_surface_tree(surface, surface_pos)));
// FIXME we basically need to pick the largest scale factor across the overlapping
@@ -2745,7 +2755,7 @@ impl Niri {
}
cursor_image => {
// 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;
};
@@ -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(
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(
surface,
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(
surface,
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(
surface,
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(
surface,
&mut feedback,