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",
|
||||
]
|
||||
|
||||
[[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"
|
||||
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
|
||||
+22
-4
@@ -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();
|
||||
}
|
||||
|
||||
+7
-7
@@ -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,
|
||||
|
||||
+25
-15
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user