Update Smithay (DnD rework, primary GPU improvement)

This commit is contained in:
Ivan Molodetskikh 2025-12-18 11:56:26 +03:00
parent f913219f94
commit 7ca46b44b2
4 changed files with 66 additions and 45 deletions

4
Cargo.lock generated
View file

@ -3423,7 +3423,7 @@ checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c"
[[package]]
name = "smithay"
version = "0.7.0"
source = "git+https://github.com/Smithay/smithay.git#d743e1a317fa0f01d1c4cadd96d277a1ec7b59d9"
source = "git+https://github.com/Smithay/smithay.git#6329f5b21693c53b0370cc7f62523ea4d0a42073"
dependencies = [
"aliasable",
"appendlist",
@ -3497,7 +3497,7 @@ dependencies = [
[[package]]
name = "smithay-drm-extras"
version = "0.1.0"
source = "git+https://github.com/Smithay/smithay.git#d743e1a317fa0f01d1c4cadd96d277a1ec7b59d9"
source = "git+https://github.com/Smithay/smithay.git#6329f5b21693c53b0370cc7f62523ea4d0a42073"
dependencies = [
"drm",
"libdisplay-info",

View file

@ -13,16 +13,16 @@ use smithay::backend::allocator::dmabuf::Dmabuf;
use smithay::backend::drm::DrmNode;
use smithay::backend::input::{InputEvent, TabletToolDescriptor};
use smithay::desktop::{PopupKind, PopupManager};
use smithay::input::pointer::{CursorIcon, CursorImageStatus, PointerHandle};
use smithay::input::dnd::{self, DnDGrab, DndGrabHandler, DndTarget};
use smithay::input::pointer::{CursorIcon, CursorImageStatus, Focus, PointerHandle};
use smithay::input::{keyboard, Seat, SeatHandler, SeatState};
use smithay::output::Output;
use smithay::reexports::rustix::fs::{fcntl_setfl, OFlags};
use smithay::reexports::wayland_protocols_wlr::screencopy::v1::server::zwlr_screencopy_manager_v1::ZwlrScreencopyManagerV1;
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, Point, Rectangle};
use smithay::utils::{Logical, Point, Rectangle, Serial};
use smithay::wayland::compositor::{get_parent, with_states};
use smithay::wayland::dmabuf::{DmabufGlobal, DmabufHandler, DmabufState, ImportNotifier};
use smithay::wayland::drm_lease::{
@ -41,8 +41,7 @@ use smithay::wayland::security_context::{
SecurityContext, SecurityContextHandler, SecurityContextListenerSource,
};
use smithay::wayland::selection::data_device::{
set_data_device_focus, ClientDndGrabHandler, DataDeviceHandler, DataDeviceState,
ServerDndGrabHandler,
set_data_device_focus, DataDeviceHandler, DataDeviceState, WaylandDndGrabHandler,
};
use smithay::wayland::selection::ext_data_control::{
DataControlHandler as ExtDataControlHandler, DataControlState as ExtDataControlState,
@ -314,23 +313,51 @@ impl DataDeviceHandler for State {
}
}
impl ClientDndGrabHandler for State {
fn started(
impl WaylandDndGrabHandler for State {
fn dnd_requested<S: dnd::Source>(
&mut self,
_source: Option<WlDataSource>,
source: S,
icon: Option<WlSurface>,
_seat: Seat<Self>,
seat: Seat<Self>,
serial: Serial,
type_: dnd::GrabType,
) {
self.niri.dnd_icon = icon.map(|surface| DndIcon {
surface,
offset: Point::new(0, 0),
});
match type_ {
dnd::GrabType::Pointer => {
let pointer = seat.get_pointer().unwrap();
let start_data = pointer.grab_start_data().unwrap();
let grab =
DnDGrab::new_pointer(&self.niri.display_handle, start_data, source, seat);
pointer.set_grab(self, grab, serial, Focus::Keep);
}
dnd::GrabType::Touch => {
let touch = seat.get_touch().unwrap();
let start_data = touch.grab_start_data().unwrap();
let grab = DnDGrab::new_touch(&self.niri.display_handle, start_data, source, seat);
touch.set_grab(self, grab, serial);
}
}
// FIXME: more granular
self.niri.queue_redraw_all();
}
}
fn dropped(&mut self, target: Option<WlSurface>, validated: bool, _seat: Seat<Self>) {
trace!("client dropped, target: {target:?}, validated: {validated}");
impl DndGrabHandler for State {
fn dropped(
&mut self,
target: Option<DndTarget<'_, Self>>,
validated: bool,
_seat: Seat<Self>,
location: Point<f64, Logical>,
) {
let target: Option<&WlSurface> = target.map(DndTarget::into_inner);
trace!("dnd dropped, target: {target:?}, validated: {validated}");
// End DnD before activating a specific window below so that it takes precedence.
self.niri.layout.dnd_end();
@ -339,7 +366,7 @@ impl ClientDndGrabHandler for State {
// example. On successful drop, additionally activate the target window.
let mut activate_output = true;
if let Some(target) = validated.then_some(target).flatten() {
let root = self.niri.find_root_shell_surface(&target);
let root = self.niri.find_root_shell_surface(target);
if let Some((mapped, _)) = self.niri.layout.find_window_and_output(&root) {
let window = mapped.window.clone();
self.niri.layout.activate_window(&window);
@ -349,19 +376,10 @@ impl ClientDndGrabHandler for State {
}
if activate_output {
// Find the output from cursor coordinates.
//
// FIXME: uhhh, we can't actually properly tell if the DnD comes from pointer or touch,
// and if it comes from touch, then what the coordinates are. Need to pass more
// parameters from Smithay I guess.
//
// Assume that hidden pointer means touch DnD.
if self.niri.pointer_visibility.is_visible() {
// We can't even get the current pointer location because it's locked (we're deep
// in the grab call stack here). So use the last known one.
if let Some(output) = &self.niri.pointer_contents.output {
self.niri.layout.focus_output(output);
}
// Find the output from drop coordinates.
if let Some((output, _)) = self.niri.output_under(location) {
let output = output.clone();
self.niri.layout.focus_output(&output);
}
}
@ -371,8 +389,6 @@ impl ClientDndGrabHandler for State {
}
}
impl ServerDndGrabHandler for State {}
delegate_data_device!(State);
impl PrimarySelectionHandler for State {

View file

@ -24,7 +24,6 @@ use smithay::wayland::compositor::{
};
use smithay::wayland::dmabuf::get_dmabuf;
use smithay::wayland::input_method::InputMethodSeat;
use smithay::wayland::selection::data_device::DnDGrab;
use smithay::wayland::shell::kde::decoration::{KdeDecorationHandler, KdeDecorationState};
use smithay::wayland::shell::wlr_layer::{self, Layer};
use smithay::wayland::shell::xdg::decoration::XdgDecorationHandler;
@ -85,7 +84,7 @@ impl XdgShellHandler for State {
if focus.id().same_client_as(&wl_surface.id()) {
// Deny move requests from DnD grabs to work around
// https://gitlab.gnome.org/GNOME/gtk/-/issues/7113
let is_dnd_grab = grab.as_any().is::<DnDGrab<Self>>();
let is_dnd_grab = Self::is_dnd_grab(grab.as_any());
if !is_dnd_grab {
grab_start_data =
@ -105,7 +104,7 @@ impl XdgShellHandler for State {
if focus.id().same_client_as(&wl_surface.id()) {
// Deny move requests from DnD grabs to work around
// https://gitlab.gnome.org/GNOME/gtk/-/issues/7113
let is_dnd_grab = grab.as_any().is::<DnDGrab<Self>>();
let is_dnd_grab = Self::is_dnd_grab(grab.as_any());
if !is_dnd_grab {
grab_start_data =

View file

@ -19,6 +19,7 @@ use smithay::backend::input::{
TabletToolTipState, TouchEvent,
};
use smithay::backend::libinput::LibinputInputBackend;
use smithay::input::dnd::DnDGrab;
use smithay::input::keyboard::{keysyms, FilterResult, Keysym, Layout, ModifiersState};
use smithay::input::pointer::{
AxisFrame, ButtonEvent, CursorIcon, CursorImageStatus, Focus, GestureHoldBeginEvent,
@ -31,10 +32,11 @@ use smithay::input::touch::{
};
use smithay::input::SeatHandler;
use smithay::output::Output;
use smithay::reexports::wayland_server::protocol::wl_data_source::WlDataSource;
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
use smithay::utils::{Logical, Point, Rectangle, Transform, SERIAL_COUNTER};
use smithay::wayland::keyboard_shortcuts_inhibit::KeyboardShortcutsInhibitor;
use smithay::wayland::pointer_constraints::{with_pointer_constraint, PointerConstraint};
use smithay::wayland::selection::data_device::DnDGrab;
use smithay::wayland::tablet_manager::{TabletDescriptor, TabletSeatTrait};
use touch_overview_grab::TouchOverviewGrab;
@ -2583,10 +2585,9 @@ impl State {
self.niri.maybe_activate_pointer_constraint();
// Inform the layout of an ongoing DnD operation.
let mut is_dnd_grab = false;
pointer.with_grab(|_, grab| {
is_dnd_grab = grab.as_any().is::<DnDGrab<Self>>();
});
let is_dnd_grab = pointer
.with_grab(|_, grab| Self::is_dnd_grab(grab.as_any()))
.unwrap_or(false);
if is_dnd_grab {
if let Some((output, pos_within_output)) = self.niri.output_under(new_pos) {
let output = output.clone();
@ -2682,10 +2683,9 @@ impl State {
self.niri.tablet_cursor_location = None;
// Inform the layout of an ongoing DnD operation.
let mut is_dnd_grab = false;
pointer.with_grab(|_, grab| {
is_dnd_grab = grab.as_any().is::<DnDGrab<Self>>();
});
let is_dnd_grab = pointer
.with_grab(|_, grab| Self::is_dnd_grab(grab.as_any()))
.unwrap_or(false);
if is_dnd_grab {
if let Some((output, pos_within_output)) = self.niri.output_under(pos) {
let output = output.clone();
@ -4212,10 +4212,9 @@ impl State {
);
// Inform the layout of an ongoing DnD operation.
let mut is_dnd_grab = false;
handle.with_grab(|_, grab| {
is_dnd_grab = grab.as_any().is::<DnDGrab<Self>>();
});
let is_dnd_grab = handle
.with_grab(|_, grab| Self::is_dnd_grab(grab.as_any()))
.unwrap_or(false);
if is_dnd_grab {
if let Some((output, pos_within_output)) = self.niri.output_under(pos) {
let output = output.clone();
@ -4256,6 +4255,13 @@ impl State {
self.do_action(action, true);
}
}
pub fn is_dnd_grab(grab: &dyn Any) -> bool {
// Normal DnD
grab.is::<DnDGrab<Self, WlDataSource, WlSurface>>()
// Null-source DnD: weston-dnd --self-only
|| grab.is::<DnDGrab<Self, WlSurface, WlSurface>>()
}
}
/// Check whether the key should be intercepted and mark intercepted