Update smithay for DnD updates
This commit is contained in:
parent
3ddc9421e4
commit
77d3605fb9
12 changed files with 340 additions and 99 deletions
|
|
@ -523,18 +523,14 @@ impl CosmicStack {
|
|||
|
||||
let active_window = &p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)];
|
||||
stack_ui.or_else(|| {
|
||||
active_window
|
||||
.0
|
||||
.surface_under(relative_pos, surface_type)
|
||||
.map(|(surface, surface_offset)| {
|
||||
active_window.focus_under(relative_pos, surface_type).map(
|
||||
|(target, surface_offset)| {
|
||||
(
|
||||
PointerFocusTarget::WlSurface {
|
||||
surface,
|
||||
toplevel: Some(active_window.clone().into()),
|
||||
},
|
||||
target,
|
||||
surface_offset.to_f64() + Point::from((0., TAB_HEIGHT as f64)),
|
||||
)
|
||||
})
|
||||
},
|
||||
)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
use crate::wayland::protocols::corner_radius::CacheableCorners;
|
||||
use crate::{
|
||||
shell::focus::target::PointerFocusTarget, wayland::protocols::corner_radius::CacheableCorners,
|
||||
};
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
sync::{
|
||||
|
|
@ -618,6 +620,38 @@ impl CosmicSurface {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn focus_under(
|
||||
&self,
|
||||
relative_pos: Point<f64, Logical>,
|
||||
surface_type: WindowSurfaceType,
|
||||
) -> Option<(PointerFocusTarget, Point<f64, Logical>)> {
|
||||
if let Some(xsurface) = self.x11_surface() {
|
||||
xsurface
|
||||
.surface_under(relative_pos, Point::default(), surface_type)
|
||||
.map(|(_surface, surface_offset)| {
|
||||
(
|
||||
PointerFocusTarget::X11Surface {
|
||||
surface: xsurface.clone(),
|
||||
toplevel: Some(self.clone()),
|
||||
},
|
||||
surface_offset.to_f64(),
|
||||
)
|
||||
})
|
||||
} else {
|
||||
self.0
|
||||
.surface_under(relative_pos, surface_type)
|
||||
.map(|(surface, surface_offset)| {
|
||||
(
|
||||
PointerFocusTarget::WlSurface {
|
||||
surface,
|
||||
toplevel: Some(self.clone().into()),
|
||||
},
|
||||
surface_offset.to_f64(),
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn on_commit(&self) {
|
||||
self.0.on_commit();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -281,17 +281,9 @@ impl CosmicWindow {
|
|||
}
|
||||
|
||||
window_ui.or_else(|| {
|
||||
p.window.0.surface_under(relative_pos, surface_type).map(
|
||||
|(surface, surface_offset)| {
|
||||
(
|
||||
PointerFocusTarget::WlSurface {
|
||||
surface,
|
||||
toplevel: Some(p.window.clone().into()),
|
||||
},
|
||||
(offset + surface_offset.to_f64()),
|
||||
)
|
||||
},
|
||||
)
|
||||
p.window
|
||||
.focus_under(relative_pos, surface_type)
|
||||
.map(|(target, surface_offset)| (target, offset + surface_offset))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
use std::{borrow::Cow, sync::Weak, time::Duration};
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
sync::{Arc, Weak},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
shell::{
|
||||
|
|
@ -16,6 +20,7 @@ use smithay::{
|
|||
desktop::{LayerSurface, PopupKind, WindowSurface, WindowSurfaceType, space::SpaceElement},
|
||||
input::{
|
||||
Seat,
|
||||
dnd::{DndFocus, OfferData, Source},
|
||||
keyboard::{KeyboardTarget, KeysymHandle, ModifiersState},
|
||||
pointer::{
|
||||
AxisFrame, ButtonEvent, GestureHoldBeginEvent, GestureHoldEndEvent,
|
||||
|
|
@ -29,11 +34,14 @@ use smithay::{
|
|||
},
|
||||
},
|
||||
reexports::wayland_server::{
|
||||
Client, Resource, backend::ObjectId, protocol::wl_surface::WlSurface,
|
||||
Client, DisplayHandle, Resource, backend::ObjectId, protocol::wl_surface::WlSurface,
|
||||
},
|
||||
utils::{IsAlive, Logical, Point, Serial, Transform},
|
||||
wayland::{seat::WaylandFocus, session_lock::LockSurface},
|
||||
xwayland::{X11Surface, xwm::XwmId},
|
||||
wayland::{seat::WaylandFocus, selection::data_device::WlOfferData, session_lock::LockSurface},
|
||||
xwayland::{
|
||||
X11Surface,
|
||||
xwm::{XwmId, XwmOfferData},
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
|
|
@ -42,6 +50,10 @@ pub enum PointerFocusTarget {
|
|||
surface: WlSurface,
|
||||
toplevel: Option<PointerFocusToplevel>,
|
||||
},
|
||||
X11Surface {
|
||||
surface: X11Surface,
|
||||
toplevel: Option<CosmicSurface>,
|
||||
},
|
||||
StackUI(CosmicStack),
|
||||
WindowUI(CosmicWindow),
|
||||
ResizeFork(ResizeForkTarget),
|
||||
|
|
@ -82,16 +94,32 @@ impl From<KeyboardFocusTarget> for PointerFocusTarget {
|
|||
match target {
|
||||
KeyboardFocusTarget::Element(elem) => {
|
||||
let window = elem.active_window();
|
||||
let surface = window.wl_surface().unwrap();
|
||||
PointerFocusTarget::WlSurface {
|
||||
surface: surface.into_owned(),
|
||||
toplevel: Some(window.into()),
|
||||
|
||||
if let Some(xsurface) = window.x11_surface() {
|
||||
PointerFocusTarget::X11Surface {
|
||||
surface: xsurface.clone(),
|
||||
toplevel: Some(window),
|
||||
}
|
||||
} else {
|
||||
PointerFocusTarget::WlSurface {
|
||||
surface: window.wl_surface().unwrap().into_owned(),
|
||||
toplevel: Some(window.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
KeyboardFocusTarget::Fullscreen(elem) => {
|
||||
if let Some(xsurface) = elem.x11_surface() {
|
||||
PointerFocusTarget::X11Surface {
|
||||
surface: xsurface.clone(),
|
||||
toplevel: Some(elem),
|
||||
}
|
||||
} else {
|
||||
PointerFocusTarget::WlSurface {
|
||||
surface: elem.wl_surface().unwrap().into_owned(),
|
||||
toplevel: Some(elem.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
KeyboardFocusTarget::Fullscreen(elem) => PointerFocusTarget::WlSurface {
|
||||
surface: elem.wl_surface().unwrap().into_owned(),
|
||||
toplevel: Some(elem.into()),
|
||||
},
|
||||
KeyboardFocusTarget::LayerSurface(layer) => PointerFocusTarget::WlSurface {
|
||||
surface: layer.wl_surface().clone(),
|
||||
toplevel: None,
|
||||
|
|
@ -113,6 +141,7 @@ impl PointerFocusTarget {
|
|||
fn inner_pointer_target(&self) -> &dyn PointerTarget<State> {
|
||||
match self {
|
||||
PointerFocusTarget::WlSurface { surface, .. } => surface,
|
||||
PointerFocusTarget::X11Surface { surface, .. } => surface,
|
||||
PointerFocusTarget::StackUI(u) => u,
|
||||
PointerFocusTarget::WindowUI(u) => u,
|
||||
PointerFocusTarget::ResizeFork(f) => f,
|
||||
|
|
@ -123,6 +152,7 @@ impl PointerFocusTarget {
|
|||
fn inner_touch_target(&self) -> &dyn TouchTarget<State> {
|
||||
match self {
|
||||
PointerFocusTarget::WlSurface { surface, .. } => surface,
|
||||
PointerFocusTarget::X11Surface { surface, .. } => surface,
|
||||
PointerFocusTarget::StackUI(u) => u,
|
||||
PointerFocusTarget::WindowUI(u) => u,
|
||||
PointerFocusTarget::ResizeFork(f) => f,
|
||||
|
|
@ -148,9 +178,9 @@ impl PointerFocusTarget {
|
|||
)
|
||||
}),
|
||||
WindowSurface::X11(x11_surface) => Some((
|
||||
Self::WlSurface {
|
||||
surface: x11_surface.wl_surface()?,
|
||||
toplevel: Some(surface.clone().into()),
|
||||
Self::X11Surface {
|
||||
surface: x11_surface.clone(),
|
||||
toplevel: Some(surface.clone()),
|
||||
},
|
||||
Point::default(),
|
||||
)),
|
||||
|
|
@ -173,6 +203,10 @@ impl PointerFocusTarget {
|
|||
.find(|(w, _)| w.wl_surface().map(|s2| s == *s2).unwrap_or(false))
|
||||
.map(|(s, _)| s)
|
||||
}),
|
||||
PointerFocusTarget::X11Surface {
|
||||
toplevel: Some(surface),
|
||||
..
|
||||
} => Some(surface.clone()),
|
||||
PointerFocusTarget::StackUI(stack) => Some(stack.active()),
|
||||
PointerFocusTarget::WindowUI(window) => Some(window.surface()),
|
||||
_ => None,
|
||||
|
|
@ -184,6 +218,9 @@ impl PointerFocusTarget {
|
|||
PointerFocusTarget::WlSurface { surface, .. } => {
|
||||
surface.client().is_some_and(|c| c == *client)
|
||||
}
|
||||
PointerFocusTarget::X11Surface { surface, .. } => surface
|
||||
.wl_surface()
|
||||
.is_some_and(|s| s.client().is_some_and(|c| c == *client)),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
@ -263,6 +300,7 @@ impl IsAlive for PointerFocusTarget {
|
|||
match self {
|
||||
// XXX? does this change anything
|
||||
PointerFocusTarget::WlSurface { surface, .. } => surface.alive(),
|
||||
PointerFocusTarget::X11Surface { surface, .. } => surface.alive(),
|
||||
PointerFocusTarget::StackUI(e) => e.alive(),
|
||||
PointerFocusTarget::WindowUI(e) => e.alive(),
|
||||
PointerFocusTarget::ResizeFork(f) => f.alive(),
|
||||
|
|
@ -459,6 +497,146 @@ impl TouchTarget<State> for PointerFocusTarget {
|
|||
}
|
||||
}
|
||||
|
||||
pub enum CosmicOfferData<S: Source> {
|
||||
Wl(WlOfferData<S>),
|
||||
X11(XwmOfferData<S>),
|
||||
}
|
||||
|
||||
impl<S: Source> OfferData for CosmicOfferData<S> {
|
||||
fn disable(&self) {
|
||||
match self {
|
||||
CosmicOfferData::Wl(data) => data.disable(),
|
||||
CosmicOfferData::X11(data) => data.disable(),
|
||||
}
|
||||
}
|
||||
|
||||
fn drop(&self) {
|
||||
match self {
|
||||
CosmicOfferData::Wl(data) => data.drop(),
|
||||
CosmicOfferData::X11(data) => data.drop(),
|
||||
}
|
||||
}
|
||||
|
||||
fn validated(&self) -> bool {
|
||||
match self {
|
||||
CosmicOfferData::Wl(data) => data.validated(),
|
||||
CosmicOfferData::X11(data) => data.validated(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DndFocus<State> for PointerFocusTarget {
|
||||
type OfferData<S>
|
||||
= CosmicOfferData<S>
|
||||
where
|
||||
S: Source;
|
||||
|
||||
fn enter<S: Source>(
|
||||
&self,
|
||||
data: &mut State,
|
||||
dh: &DisplayHandle,
|
||||
source: Arc<S>,
|
||||
seat: &Seat<State>,
|
||||
location: Point<f64, Logical>,
|
||||
serial: &Serial,
|
||||
) -> Option<CosmicOfferData<S>> {
|
||||
match self {
|
||||
PointerFocusTarget::WlSurface { surface, .. } => {
|
||||
DndFocus::enter(surface, data, dh, source, seat, location, serial)
|
||||
.map(CosmicOfferData::Wl)
|
||||
}
|
||||
PointerFocusTarget::X11Surface { surface, .. } => {
|
||||
DndFocus::enter(surface, data, dh, source, seat, location, serial)
|
||||
.map(CosmicOfferData::X11)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn motion<S: Source>(
|
||||
&self,
|
||||
data: &mut State,
|
||||
offer: Option<&mut CosmicOfferData<S>>,
|
||||
seat: &Seat<State>,
|
||||
location: Point<f64, Logical>,
|
||||
time: u32,
|
||||
) {
|
||||
match self {
|
||||
PointerFocusTarget::WlSurface { surface, .. } => {
|
||||
let offer = match offer {
|
||||
Some(CosmicOfferData::Wl(offer)) => Some(offer),
|
||||
None => None,
|
||||
_ => return,
|
||||
};
|
||||
DndFocus::motion(surface, data, offer, seat, location, time)
|
||||
}
|
||||
PointerFocusTarget::X11Surface { surface, .. } => {
|
||||
let offer = match offer {
|
||||
Some(CosmicOfferData::X11(offer)) => Some(offer),
|
||||
None => None,
|
||||
_ => return,
|
||||
};
|
||||
DndFocus::motion(surface, data, offer, seat, location, time)
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn leave<S: Source>(
|
||||
&self,
|
||||
data: &mut State,
|
||||
offer: Option<&mut CosmicOfferData<S>>,
|
||||
seat: &Seat<State>,
|
||||
) {
|
||||
match self {
|
||||
PointerFocusTarget::WlSurface { surface, .. } => {
|
||||
let offer = match offer {
|
||||
Some(CosmicOfferData::Wl(offer)) => Some(offer),
|
||||
None => None,
|
||||
_ => return,
|
||||
};
|
||||
DndFocus::leave(surface, data, offer, seat)
|
||||
}
|
||||
PointerFocusTarget::X11Surface { surface, .. } => {
|
||||
let offer = match offer {
|
||||
Some(CosmicOfferData::X11(offer)) => Some(offer),
|
||||
None => None,
|
||||
_ => return,
|
||||
};
|
||||
DndFocus::leave(surface, data, offer, seat)
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn drop<S: Source>(
|
||||
&self,
|
||||
data: &mut State,
|
||||
offer: Option<&mut CosmicOfferData<S>>,
|
||||
seat: &Seat<State>,
|
||||
) {
|
||||
match self {
|
||||
PointerFocusTarget::WlSurface { surface, .. } => {
|
||||
let offer = match offer {
|
||||
Some(CosmicOfferData::Wl(offer)) => Some(offer),
|
||||
None => None,
|
||||
_ => return,
|
||||
};
|
||||
DndFocus::drop(surface, data, offer, seat)
|
||||
}
|
||||
PointerFocusTarget::X11Surface { surface, .. } => {
|
||||
let offer = match offer {
|
||||
Some(CosmicOfferData::X11(offer)) => Some(offer),
|
||||
None => None,
|
||||
_ => return,
|
||||
};
|
||||
DndFocus::drop(surface, data, offer, seat)
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl KeyboardTarget<State> for KeyboardFocusTarget {
|
||||
fn enter(
|
||||
&self,
|
||||
|
|
@ -550,6 +728,7 @@ impl WaylandFocus for PointerFocusTarget {
|
|||
fn wl_surface(&self) -> Option<Cow<'_, WlSurface>> {
|
||||
Some(match self {
|
||||
PointerFocusTarget::WlSurface { surface, .. } => Cow::Borrowed(surface),
|
||||
PointerFocusTarget::X11Surface { surface, .. } => Cow::Owned(surface.wl_surface()?),
|
||||
PointerFocusTarget::ResizeFork(_)
|
||||
| PointerFocusTarget::StackUI(_)
|
||||
| PointerFocusTarget::WindowUI(_)
|
||||
|
|
@ -561,15 +740,16 @@ impl WaylandFocus for PointerFocusTarget {
|
|||
fn same_client_as(&self, object_id: &ObjectId) -> bool {
|
||||
match self {
|
||||
PointerFocusTarget::WlSurface { surface, .. } => surface.id().same_client_as(object_id),
|
||||
PointerFocusTarget::X11Surface { surface, .. } => surface
|
||||
.wl_surface()
|
||||
.is_some_and(|s| s.id().same_client_as(object_id)),
|
||||
PointerFocusTarget::StackUI(stack) => stack
|
||||
.active()
|
||||
.wl_surface()
|
||||
.map(|s| s.id().same_client_as(object_id))
|
||||
.unwrap_or(false),
|
||||
.is_some_and(|s| s.id().same_client_as(object_id)),
|
||||
PointerFocusTarget::WindowUI(window) => window
|
||||
.wl_surface()
|
||||
.map(|s| s.id().same_client_as(object_id))
|
||||
.unwrap_or(false),
|
||||
.is_some_and(|s| s.id().same_client_as(object_id)),
|
||||
PointerFocusTarget::ResizeFork(_) | PointerFocusTarget::ZoomUI(_) => false,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -908,19 +908,12 @@ impl Workspace {
|
|||
let geometry = self.fullscreen_geometry().unwrap();
|
||||
return fullscreen
|
||||
.surface
|
||||
.0
|
||||
.surface_under(
|
||||
.focus_under(
|
||||
(location - geometry.loc.to_f64()).as_logical(),
|
||||
WindowSurfaceType::TOPLEVEL | WindowSurfaceType::SUBSURFACE,
|
||||
)
|
||||
.map(|(surface, surface_offset)| {
|
||||
(
|
||||
PointerFocusTarget::WlSurface {
|
||||
surface,
|
||||
toplevel: Some(fullscreen.surface.clone().into()),
|
||||
},
|
||||
(geometry.loc + surface_offset.as_local()).to_f64(),
|
||||
)
|
||||
.map(|(target, surface_offset)| {
|
||||
(target, (geometry.loc.to_f64() + surface_offset.as_local()))
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue