diff --git a/src/backend/render/cursor.rs b/src/backend/render/cursor.rs index a3d055fd..7f42488e 100644 --- a/src/backend/render/cursor.rs +++ b/src/backend/render/cursor.rs @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only -use crate::{utils::prelude::*, wayland::handlers::data_device::get_dnd_icon}; +use crate::utils::prelude::*; use smithay::{ backend::renderer::{Frame, ImportAll, ImportMem, Renderer, Texture}, desktop::space::{RenderElement, SpaceOutputTuple, SurfaceTree}, @@ -280,15 +280,6 @@ where R: Renderer + ImportAll + ImportMem, ::TextureId: Clone + 'static, { - // draw the dnd icon if applicable - { - if let Some(wl_surface) = get_dnd_icon(seat) { - if wl_surface.alive() { - return Some(draw_dnd_icon(wl_surface, location.to_i32_round()).into()); - } - } - } - // draw the cursor as relevant { // reset the cursor if the surface is no longer alive diff --git a/src/backend/render/mod.rs b/src/backend/render/mod.rs index d192a09a..59f90b8c 100644 --- a/src/backend/render/mod.rs +++ b/src/backend/render/mod.rs @@ -6,6 +6,7 @@ use crate::{ SeatMoveGrabState, MoveGrabRenderElement, }, + wayland::handlers::data_device::get_dnd_icon, }; #[cfg(feature = "debug")] use crate::{ @@ -143,6 +144,50 @@ pub fn needs_buffer_reset(output: &Output, state: &Common) -> bool { != will_render_custom } +pub fn cursor_custom_elements( + renderer: &mut R, + state: &Common, + output: &Output, + hardware_cursor: bool, +) -> Vec +where + R: AsGles2Renderer +{ + let mut custom_elements = Vec::new(); + + for seat in &state.seats { + let pointer = match seat.get_pointer() { + Some(ptr) => ptr, + None => continue, + }; + let location = state + .shell + .space_relative_output_geometry(pointer.current_location().to_i32_round(), output); + + if let Some(grab) = seat.user_data().get::().unwrap().borrow() + .as_ref().and_then(|state| state.render(seat, output)) + { + custom_elements.push(grab); + } + + if let Some(wl_surface) = get_dnd_icon(seat) { + custom_elements.push(cursor::draw_dnd_icon(wl_surface, location.to_i32_round()).into()); + } + + if let Some(cursor) = cursor::draw_cursor( + renderer.as_gles2(), + seat, + location, + &state.start_time, + !hardware_cursor, + ) { + custom_elements.push(cursor) + } + } + + custom_elements +} + pub fn render_output( gpu: Option<&DrmNode>, renderer: &mut R, @@ -273,31 +318,7 @@ where } } - for seat in &state.seats { - let pointer = match seat.get_pointer() { - Some(ptr) => ptr, - None => continue, - }; - let location = state - .shell - .space_relative_output_geometry(pointer.current_location().to_i32_round(), output); - - if let Some(grab) = seat.user_data().get::().unwrap().borrow() - .as_ref().and_then(|state| state.render(seat, output)) - { - custom_elements.push(grab); - } - - if let Some(cursor) = cursor::draw_cursor( - renderer.as_gles2(), - seat, - location, - &state.start_time, - !hardware_cursor, - ) { - custom_elements.push(cursor) - } - } + custom_elements.extend(cursor_custom_elements(renderer, state, output, hardware_cursor)); state.shell.spaces[space_idx].space.render_output( renderer, @@ -343,25 +364,7 @@ where custom_elements.push(fps_overlay.into()); } - for seat in &state.seats { - let pointer = match seat.get_pointer() { - Some(ptr) => ptr, - None => continue, - }; - let location = state - .shell - .space_relative_output_geometry(pointer.current_location().to_i32_round(), output); - - if let Some(cursor) = cursor::draw_cursor( - renderer.as_gles2(), - seat, - location, - &state.start_time, - !hardware_cursor, - ) { - custom_elements.push(cursor) - } - } + custom_elements.extend(cursor_custom_elements(renderer, state, output, hardware_cursor)); renderer .render(mode.size, transform, |renderer, frame| { diff --git a/src/wayland/handlers/data_device.rs b/src/wayland/handlers/data_device.rs index 4295b0d9..1e220de7 100644 --- a/src/wayland/handlers/data_device.rs +++ b/src/wayland/handlers/data_device.rs @@ -10,6 +10,7 @@ use smithay::{ }, seat::Seat, }, + utils::IsAlive }; use std::cell::RefCell; @@ -22,6 +23,7 @@ pub fn get_dnd_icon(seat: &Seat) -> Option { userdata .get::() .and_then(|x| x.surface.borrow().clone()) + .filter(IsAlive::alive) } impl ClientDndGrabHandler for State {