Update smithay for DnD updates
This commit is contained in:
parent
3ddc9421e4
commit
77d3605fb9
12 changed files with 340 additions and 99 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -4952,7 +4952,7 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smithay"
|
name = "smithay"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
source = "git+https://github.com/smithay/smithay.git?rev=d40ada5#d40ada55eceac04fb1c752f0f17b0c32cf24fbb1"
|
source = "git+https://github.com/smithay/smithay.git?rev=593b2d5#593b2d5fb32a24652d8cde12b53d6871d1bd2275"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aliasable",
|
"aliasable",
|
||||||
"appendlist",
|
"appendlist",
|
||||||
|
|
|
||||||
|
|
@ -146,4 +146,4 @@ cosmic-protocols = { git = "https://github.com/pop-os//cosmic-protocols", branch
|
||||||
cosmic-client-toolkit = { git = "https://github.com/pop-os//cosmic-protocols", branch = "main" }
|
cosmic-client-toolkit = { git = "https://github.com/pop-os//cosmic-protocols", branch = "main" }
|
||||||
|
|
||||||
[patch.crates-io]
|
[patch.crates-io]
|
||||||
smithay = { git = "https://github.com/smithay/smithay.git", rev = "d40ada5" }
|
smithay = { git = "https://github.com/smithay/smithay.git", rev = "593b2d5" }
|
||||||
|
|
|
||||||
|
|
@ -287,6 +287,12 @@ fn format_pointer_focus(focus: Option<PointerFocusTarget>) -> String {
|
||||||
}
|
}
|
||||||
_ => format!("Surface {}", surface.id().protocol_id()),
|
_ => format!("Surface {}", surface.id().protocol_id()),
|
||||||
},
|
},
|
||||||
|
Some(X11Surface { surface, toplevel }) => match toplevel {
|
||||||
|
Some(window) => {
|
||||||
|
format!("Window {} ({})", surface.window_id(), window.title())
|
||||||
|
}
|
||||||
|
_ => format!("X11Surface {}", surface.window_id()),
|
||||||
|
},
|
||||||
Some(StackUI(stack)) => format!(
|
Some(StackUI(stack)) => format!(
|
||||||
"Stack SSD {} ({})",
|
"Stack SSD {} ({})",
|
||||||
match stack.active().0.underlying_surface() {
|
match stack.active().0.underlying_surface() {
|
||||||
|
|
|
||||||
|
|
@ -502,18 +502,34 @@ impl State {
|
||||||
ptr.frame(self);
|
ptr.frame(self);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if let PointerFocusTarget::WlSurface { surface, .. } = surface {
|
match surface {
|
||||||
if under_from_surface_tree(
|
PointerFocusTarget::WlSurface { surface, .. } => {
|
||||||
surface,
|
if under_from_surface_tree(
|
||||||
position.as_logical() - surface_loc.to_f64(),
|
surface,
|
||||||
(0, 0),
|
position.as_logical() - surface_loc.to_f64(),
|
||||||
WindowSurfaceType::ALL,
|
(0, 0),
|
||||||
)
|
WindowSurfaceType::ALL,
|
||||||
.is_none()
|
)
|
||||||
{
|
.is_none()
|
||||||
ptr.frame(self);
|
{
|
||||||
return;
|
ptr.frame(self);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
PointerFocusTarget::X11Surface { surface, .. } => {
|
||||||
|
if surface
|
||||||
|
.surface_under(
|
||||||
|
position.as_logical() - surface_loc.to_f64(),
|
||||||
|
(0, 0),
|
||||||
|
WindowSurfaceType::ALL,
|
||||||
|
)
|
||||||
|
.is_none()
|
||||||
|
{
|
||||||
|
ptr.frame(self);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
if let Some(region) = confine_region {
|
if let Some(region) = confine_region {
|
||||||
if !region
|
if !region
|
||||||
|
|
@ -2243,21 +2259,18 @@ impl State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Stage::OverrideRedirect { surface, location } => {
|
Stage::OverrideRedirect { surface, location } => {
|
||||||
if let Some(surface) = surface.wl_surface() {
|
if let Some((_, surface_loc)) = surface.surface_under(
|
||||||
if let Some((surface, surface_loc)) = under_from_surface_tree(
|
global_pos.as_logical(),
|
||||||
&surface,
|
location.as_logical(),
|
||||||
global_pos.as_logical(),
|
WindowSurfaceType::ALL,
|
||||||
location.as_logical(),
|
) {
|
||||||
WindowSurfaceType::ALL,
|
return ControlFlow::Break(Ok(Some((
|
||||||
) {
|
PointerFocusTarget::X11Surface {
|
||||||
return ControlFlow::Break(Ok(Some((
|
surface: surface.clone(),
|
||||||
PointerFocusTarget::WlSurface {
|
toplevel: None,
|
||||||
surface,
|
},
|
||||||
toplevel: None,
|
surface_loc.as_global().to_f64(),
|
||||||
},
|
))));
|
||||||
surface_loc.as_global().to_f64(),
|
|
||||||
))));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Stage::StickyPopups(floating_layer) => {
|
Stage::StickyPopups(floating_layer) => {
|
||||||
|
|
|
||||||
|
|
@ -523,18 +523,14 @@ impl CosmicStack {
|
||||||
|
|
||||||
let active_window = &p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)];
|
let active_window = &p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)];
|
||||||
stack_ui.or_else(|| {
|
stack_ui.or_else(|| {
|
||||||
active_window
|
active_window.focus_under(relative_pos, surface_type).map(
|
||||||
.0
|
|(target, surface_offset)| {
|
||||||
.surface_under(relative_pos, surface_type)
|
|
||||||
.map(|(surface, surface_offset)| {
|
|
||||||
(
|
(
|
||||||
PointerFocusTarget::WlSurface {
|
target,
|
||||||
surface,
|
|
||||||
toplevel: Some(active_window.clone().into()),
|
|
||||||
},
|
|
||||||
surface_offset.to_f64() + Point::from((0., TAB_HEIGHT as f64)),
|
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::{
|
use std::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
sync::{
|
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) {
|
pub fn on_commit(&self) {
|
||||||
self.0.on_commit();
|
self.0.on_commit();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -281,17 +281,9 @@ impl CosmicWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
window_ui.or_else(|| {
|
window_ui.or_else(|| {
|
||||||
p.window.0.surface_under(relative_pos, surface_type).map(
|
p.window
|
||||||
|(surface, surface_offset)| {
|
.focus_under(relative_pos, surface_type)
|
||||||
(
|
.map(|(target, surface_offset)| (target, offset + surface_offset))
|
||||||
PointerFocusTarget::WlSurface {
|
|
||||||
surface,
|
|
||||||
toplevel: Some(p.window.clone().into()),
|
|
||||||
},
|
|
||||||
(offset + surface_offset.to_f64()),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,8 @@
|
||||||
use std::{borrow::Cow, sync::Weak, time::Duration};
|
use std::{
|
||||||
|
borrow::Cow,
|
||||||
|
sync::{Arc, Weak},
|
||||||
|
time::Duration,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
shell::{
|
shell::{
|
||||||
|
|
@ -16,6 +20,7 @@ use smithay::{
|
||||||
desktop::{LayerSurface, PopupKind, WindowSurface, WindowSurfaceType, space::SpaceElement},
|
desktop::{LayerSurface, PopupKind, WindowSurface, WindowSurfaceType, space::SpaceElement},
|
||||||
input::{
|
input::{
|
||||||
Seat,
|
Seat,
|
||||||
|
dnd::{DndFocus, OfferData, Source},
|
||||||
keyboard::{KeyboardTarget, KeysymHandle, ModifiersState},
|
keyboard::{KeyboardTarget, KeysymHandle, ModifiersState},
|
||||||
pointer::{
|
pointer::{
|
||||||
AxisFrame, ButtonEvent, GestureHoldBeginEvent, GestureHoldEndEvent,
|
AxisFrame, ButtonEvent, GestureHoldBeginEvent, GestureHoldEndEvent,
|
||||||
|
|
@ -29,11 +34,14 @@ use smithay::{
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
reexports::wayland_server::{
|
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},
|
utils::{IsAlive, Logical, Point, Serial, Transform},
|
||||||
wayland::{seat::WaylandFocus, session_lock::LockSurface},
|
wayland::{seat::WaylandFocus, selection::data_device::WlOfferData, session_lock::LockSurface},
|
||||||
xwayland::{X11Surface, xwm::XwmId},
|
xwayland::{
|
||||||
|
X11Surface,
|
||||||
|
xwm::{XwmId, XwmOfferData},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
|
@ -42,6 +50,10 @@ pub enum PointerFocusTarget {
|
||||||
surface: WlSurface,
|
surface: WlSurface,
|
||||||
toplevel: Option<PointerFocusToplevel>,
|
toplevel: Option<PointerFocusToplevel>,
|
||||||
},
|
},
|
||||||
|
X11Surface {
|
||||||
|
surface: X11Surface,
|
||||||
|
toplevel: Option<CosmicSurface>,
|
||||||
|
},
|
||||||
StackUI(CosmicStack),
|
StackUI(CosmicStack),
|
||||||
WindowUI(CosmicWindow),
|
WindowUI(CosmicWindow),
|
||||||
ResizeFork(ResizeForkTarget),
|
ResizeFork(ResizeForkTarget),
|
||||||
|
|
@ -82,16 +94,32 @@ impl From<KeyboardFocusTarget> for PointerFocusTarget {
|
||||||
match target {
|
match target {
|
||||||
KeyboardFocusTarget::Element(elem) => {
|
KeyboardFocusTarget::Element(elem) => {
|
||||||
let window = elem.active_window();
|
let window = elem.active_window();
|
||||||
let surface = window.wl_surface().unwrap();
|
|
||||||
PointerFocusTarget::WlSurface {
|
if let Some(xsurface) = window.x11_surface() {
|
||||||
surface: surface.into_owned(),
|
PointerFocusTarget::X11Surface {
|
||||||
toplevel: Some(window.into()),
|
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 {
|
KeyboardFocusTarget::LayerSurface(layer) => PointerFocusTarget::WlSurface {
|
||||||
surface: layer.wl_surface().clone(),
|
surface: layer.wl_surface().clone(),
|
||||||
toplevel: None,
|
toplevel: None,
|
||||||
|
|
@ -113,6 +141,7 @@ impl PointerFocusTarget {
|
||||||
fn inner_pointer_target(&self) -> &dyn PointerTarget<State> {
|
fn inner_pointer_target(&self) -> &dyn PointerTarget<State> {
|
||||||
match self {
|
match self {
|
||||||
PointerFocusTarget::WlSurface { surface, .. } => surface,
|
PointerFocusTarget::WlSurface { surface, .. } => surface,
|
||||||
|
PointerFocusTarget::X11Surface { surface, .. } => surface,
|
||||||
PointerFocusTarget::StackUI(u) => u,
|
PointerFocusTarget::StackUI(u) => u,
|
||||||
PointerFocusTarget::WindowUI(u) => u,
|
PointerFocusTarget::WindowUI(u) => u,
|
||||||
PointerFocusTarget::ResizeFork(f) => f,
|
PointerFocusTarget::ResizeFork(f) => f,
|
||||||
|
|
@ -123,6 +152,7 @@ impl PointerFocusTarget {
|
||||||
fn inner_touch_target(&self) -> &dyn TouchTarget<State> {
|
fn inner_touch_target(&self) -> &dyn TouchTarget<State> {
|
||||||
match self {
|
match self {
|
||||||
PointerFocusTarget::WlSurface { surface, .. } => surface,
|
PointerFocusTarget::WlSurface { surface, .. } => surface,
|
||||||
|
PointerFocusTarget::X11Surface { surface, .. } => surface,
|
||||||
PointerFocusTarget::StackUI(u) => u,
|
PointerFocusTarget::StackUI(u) => u,
|
||||||
PointerFocusTarget::WindowUI(u) => u,
|
PointerFocusTarget::WindowUI(u) => u,
|
||||||
PointerFocusTarget::ResizeFork(f) => f,
|
PointerFocusTarget::ResizeFork(f) => f,
|
||||||
|
|
@ -148,9 +178,9 @@ impl PointerFocusTarget {
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
WindowSurface::X11(x11_surface) => Some((
|
WindowSurface::X11(x11_surface) => Some((
|
||||||
Self::WlSurface {
|
Self::X11Surface {
|
||||||
surface: x11_surface.wl_surface()?,
|
surface: x11_surface.clone(),
|
||||||
toplevel: Some(surface.clone().into()),
|
toplevel: Some(surface.clone()),
|
||||||
},
|
},
|
||||||
Point::default(),
|
Point::default(),
|
||||||
)),
|
)),
|
||||||
|
|
@ -173,6 +203,10 @@ impl PointerFocusTarget {
|
||||||
.find(|(w, _)| w.wl_surface().map(|s2| s == *s2).unwrap_or(false))
|
.find(|(w, _)| w.wl_surface().map(|s2| s == *s2).unwrap_or(false))
|
||||||
.map(|(s, _)| s)
|
.map(|(s, _)| s)
|
||||||
}),
|
}),
|
||||||
|
PointerFocusTarget::X11Surface {
|
||||||
|
toplevel: Some(surface),
|
||||||
|
..
|
||||||
|
} => Some(surface.clone()),
|
||||||
PointerFocusTarget::StackUI(stack) => Some(stack.active()),
|
PointerFocusTarget::StackUI(stack) => Some(stack.active()),
|
||||||
PointerFocusTarget::WindowUI(window) => Some(window.surface()),
|
PointerFocusTarget::WindowUI(window) => Some(window.surface()),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
|
@ -184,6 +218,9 @@ impl PointerFocusTarget {
|
||||||
PointerFocusTarget::WlSurface { surface, .. } => {
|
PointerFocusTarget::WlSurface { surface, .. } => {
|
||||||
surface.client().is_some_and(|c| c == *client)
|
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,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -263,6 +300,7 @@ impl IsAlive for PointerFocusTarget {
|
||||||
match self {
|
match self {
|
||||||
// XXX? does this change anything
|
// XXX? does this change anything
|
||||||
PointerFocusTarget::WlSurface { surface, .. } => surface.alive(),
|
PointerFocusTarget::WlSurface { surface, .. } => surface.alive(),
|
||||||
|
PointerFocusTarget::X11Surface { surface, .. } => surface.alive(),
|
||||||
PointerFocusTarget::StackUI(e) => e.alive(),
|
PointerFocusTarget::StackUI(e) => e.alive(),
|
||||||
PointerFocusTarget::WindowUI(e) => e.alive(),
|
PointerFocusTarget::WindowUI(e) => e.alive(),
|
||||||
PointerFocusTarget::ResizeFork(f) => f.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 {
|
impl KeyboardTarget<State> for KeyboardFocusTarget {
|
||||||
fn enter(
|
fn enter(
|
||||||
&self,
|
&self,
|
||||||
|
|
@ -550,6 +728,7 @@ impl WaylandFocus for PointerFocusTarget {
|
||||||
fn wl_surface(&self) -> Option<Cow<'_, WlSurface>> {
|
fn wl_surface(&self) -> Option<Cow<'_, WlSurface>> {
|
||||||
Some(match self {
|
Some(match self {
|
||||||
PointerFocusTarget::WlSurface { surface, .. } => Cow::Borrowed(surface),
|
PointerFocusTarget::WlSurface { surface, .. } => Cow::Borrowed(surface),
|
||||||
|
PointerFocusTarget::X11Surface { surface, .. } => Cow::Owned(surface.wl_surface()?),
|
||||||
PointerFocusTarget::ResizeFork(_)
|
PointerFocusTarget::ResizeFork(_)
|
||||||
| PointerFocusTarget::StackUI(_)
|
| PointerFocusTarget::StackUI(_)
|
||||||
| PointerFocusTarget::WindowUI(_)
|
| PointerFocusTarget::WindowUI(_)
|
||||||
|
|
@ -561,15 +740,16 @@ impl WaylandFocus for PointerFocusTarget {
|
||||||
fn same_client_as(&self, object_id: &ObjectId) -> bool {
|
fn same_client_as(&self, object_id: &ObjectId) -> bool {
|
||||||
match self {
|
match self {
|
||||||
PointerFocusTarget::WlSurface { surface, .. } => surface.id().same_client_as(object_id),
|
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
|
PointerFocusTarget::StackUI(stack) => stack
|
||||||
.active()
|
.active()
|
||||||
.wl_surface()
|
.wl_surface()
|
||||||
.map(|s| s.id().same_client_as(object_id))
|
.is_some_and(|s| s.id().same_client_as(object_id)),
|
||||||
.unwrap_or(false),
|
|
||||||
PointerFocusTarget::WindowUI(window) => window
|
PointerFocusTarget::WindowUI(window) => window
|
||||||
.wl_surface()
|
.wl_surface()
|
||||||
.map(|s| s.id().same_client_as(object_id))
|
.is_some_and(|s| s.id().same_client_as(object_id)),
|
||||||
.unwrap_or(false),
|
|
||||||
PointerFocusTarget::ResizeFork(_) | PointerFocusTarget::ZoomUI(_) => false,
|
PointerFocusTarget::ResizeFork(_) | PointerFocusTarget::ZoomUI(_) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -908,19 +908,12 @@ impl Workspace {
|
||||||
let geometry = self.fullscreen_geometry().unwrap();
|
let geometry = self.fullscreen_geometry().unwrap();
|
||||||
return fullscreen
|
return fullscreen
|
||||||
.surface
|
.surface
|
||||||
.0
|
.focus_under(
|
||||||
.surface_under(
|
|
||||||
(location - geometry.loc.to_f64()).as_logical(),
|
(location - geometry.loc.to_f64()).as_logical(),
|
||||||
WindowSurfaceType::TOPLEVEL | WindowSurfaceType::SUBSURFACE,
|
WindowSurfaceType::TOPLEVEL | WindowSurfaceType::SUBSURFACE,
|
||||||
)
|
)
|
||||||
.map(|(surface, surface_offset)| {
|
.map(|(target, surface_offset)| {
|
||||||
(
|
(target, (geometry.loc.to_f64() + surface_offset.as_local()))
|
||||||
PointerFocusTarget::WlSurface {
|
|
||||||
surface,
|
|
||||||
toplevel: Some(fullscreen.surface.clone().into()),
|
|
||||||
},
|
|
||||||
(geometry.loc + surface_offset.as_local()).to_f64(),
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,15 +5,14 @@ use smithay::{
|
||||||
delegate_data_device,
|
delegate_data_device,
|
||||||
input::{
|
input::{
|
||||||
Seat,
|
Seat,
|
||||||
pointer::{CursorImageStatus, CursorImageSurfaceData},
|
dnd::{DnDGrab, DndGrabHandler, DndTarget, GrabType},
|
||||||
|
pointer::{CursorImageStatus, CursorImageSurfaceData, Focus},
|
||||||
},
|
},
|
||||||
reexports::wayland_server::protocol::{wl_data_source::WlDataSource, wl_surface::WlSurface},
|
reexports::wayland_server::protocol::wl_surface::WlSurface,
|
||||||
utils::{IsAlive, Logical, Point},
|
utils::{IsAlive, Logical, Point},
|
||||||
wayland::{
|
wayland::{
|
||||||
compositor::{self, SurfaceAttributes},
|
compositor::{self, SurfaceAttributes},
|
||||||
selection::data_device::{
|
selection::data_device::{DataDeviceHandler, DataDeviceState, WaylandDndGrabHandler},
|
||||||
ClientDndGrabHandler, DataDeviceHandler, DataDeviceState, ServerDndGrabHandler,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
@ -60,12 +59,14 @@ pub fn on_commit(surface: &WlSurface, seat: &Seat<State>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClientDndGrabHandler for State {
|
impl WaylandDndGrabHandler for State {
|
||||||
fn started(
|
fn dnd_requested<S: smithay::input::dnd::Source>(
|
||||||
&mut self,
|
&mut self,
|
||||||
_source: Option<WlDataSource>,
|
source: S,
|
||||||
icon: Option<WlSurface>,
|
icon: Option<WlSurface>,
|
||||||
seat: Seat<Self>,
|
seat: Seat<Self>,
|
||||||
|
serial: smithay::utils::Serial,
|
||||||
|
type_: GrabType,
|
||||||
) {
|
) {
|
||||||
let user_data = seat.user_data();
|
let user_data = seat.user_data();
|
||||||
user_data.insert_if_missing_threadsafe::<Mutex<Option<DnDIcon>>, _>(Default::default);
|
user_data.insert_if_missing_threadsafe::<Mutex<Option<DnDIcon>>, _>(Default::default);
|
||||||
|
|
@ -89,19 +90,46 @@ impl ClientDndGrabHandler for State {
|
||||||
.get::<Mutex<Option<DnDIcon>>>()
|
.get::<Mutex<Option<DnDIcon>>>()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap() = icon.map(|surface| DnDIcon { surface, offset })
|
.unwrap() = icon.map(|surface| DnDIcon { surface, offset });
|
||||||
}
|
|
||||||
|
|
||||||
fn dropped(&mut self, _target: Option<WlSurface>, _validated: bool, seat: Seat<Self>) {
|
match type_ {
|
||||||
seat.user_data()
|
GrabType::Pointer => {
|
||||||
.get::<Mutex<Option<DnDIcon>>>()
|
let pointer = seat.get_pointer().unwrap();
|
||||||
.unwrap()
|
let start_data = pointer.grab_start_data().unwrap();
|
||||||
.lock()
|
pointer.set_grab(
|
||||||
.unwrap()
|
self,
|
||||||
.take();
|
DnDGrab::new_pointer(&self.common.display_handle, start_data, source, seat),
|
||||||
|
serial,
|
||||||
|
Focus::Keep,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
GrabType::Touch => {
|
||||||
|
let touch = seat.get_touch().unwrap();
|
||||||
|
let start_data = touch.grab_start_data().unwrap();
|
||||||
|
touch.set_grab(
|
||||||
|
self,
|
||||||
|
DnDGrab::new_touch(&self.common.display_handle, start_data, source, seat),
|
||||||
|
serial,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl ServerDndGrabHandler for State {}
|
|
||||||
|
impl DndGrabHandler for State {
|
||||||
|
fn dropped(
|
||||||
|
&mut self,
|
||||||
|
_target: Option<DndTarget<'_, Self>>,
|
||||||
|
_validated: bool,
|
||||||
|
seat: Seat<Self>,
|
||||||
|
_location: Point<f64, Logical>,
|
||||||
|
) {
|
||||||
|
if let Some(icon) = seat.user_data().get::<Mutex<Option<DnDIcon>>>() {
|
||||||
|
icon.lock().unwrap().take();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl DataDeviceHandler for State {
|
impl DataDeviceHandler for State {
|
||||||
fn data_device_state(&mut self) -> &mut DataDeviceState {
|
fn data_device_state(&mut self) -> &mut DataDeviceState {
|
||||||
&mut self.common.data_device_state
|
&mut self.common.data_device_state
|
||||||
|
|
|
||||||
|
|
@ -71,9 +71,7 @@ impl SelectionHandler for State {
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.and_then(|xstate| xstate.xwm.as_mut())
|
.and_then(|xstate| xstate.xwm.as_mut())
|
||||||
{
|
{
|
||||||
if let Err(err) =
|
if let Err(err) = xwm.send_selection(target, mime_type, fd) {
|
||||||
xwm.send_selection(target, mime_type, fd, self.common.event_loop_handle.clone())
|
|
||||||
{
|
|
||||||
warn!(?err, "Failed to send selection (X11 -> Wayland).");
|
warn!(?err, "Failed to send selection (X11 -> Wayland).");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -114,6 +114,7 @@ impl State {
|
||||||
|
|
||||||
let wm = match X11Wm::start_wm(
|
let wm = match X11Wm::start_wm(
|
||||||
data.common.event_loop_handle.clone(),
|
data.common.event_loop_handle.clone(),
|
||||||
|
&data.common.display_handle,
|
||||||
x11_socket,
|
x11_socket,
|
||||||
client.clone(),
|
client.clone(),
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue