mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2024-12-26 21:58:10 +01:00
Fix pointer clamping regression and also update Smithay
This commit is contained in:
parent
058350db43
commit
4b3839e380
8 changed files with 124 additions and 117 deletions
24
Cargo.lock
generated
24
Cargo.lock
generated
|
@ -737,9 +737,9 @@ checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
|
|||
|
||||
[[package]]
|
||||
name = "drm"
|
||||
version = "0.11.1"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0f8a69e60d75ae7dab4ef26a59ca99f2a89d4c142089b537775ae0c198bdcde"
|
||||
checksum = "98888c4bbd601524c11a7ed63f814b8825f420514f78e96f752c437ae9cbb5d1"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bytemuck",
|
||||
|
@ -750,9 +750,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "drm-ffi"
|
||||
version = "0.7.1"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41334f8405792483e32ad05fbb9c5680ff4e84491883d2947a4757dc54cb2ac6"
|
||||
checksum = "97c98727e48b7ccb4f4aea8cfe881e5b07f702d17b7875991881b41af7278d53"
|
||||
dependencies = [
|
||||
"drm-sys",
|
||||
"rustix",
|
||||
|
@ -766,9 +766,9 @@ checksum = "0aafbcdb8afc29c1a7ee5fbe53b5d62f4565b35a042a662ca9fecd0b54dae6f4"
|
|||
|
||||
[[package]]
|
||||
name = "drm-sys"
|
||||
version = "0.6.1"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2d09ff881f92f118b11105ba5e34ff8f4adf27b30dae8f12e28c193af1c83176"
|
||||
checksum = "fd39dde40b6e196c2e8763f23d119ddb1a8714534bf7d77fa97a65b0feda3986"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"linux-raw-sys 0.6.4",
|
||||
|
@ -974,11 +974,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gbm"
|
||||
version = "0.14.2"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "313702b30cdeb83ddc72bc14dcee67803cd0ae2d12282ea06e368c25a900c844"
|
||||
checksum = "45bf55ba6dd53ad0ac115046ff999c5324c283444ee6e0be82454c4e8eb2f36a"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bitflags 2.5.0",
|
||||
"drm",
|
||||
"drm-fourcc",
|
||||
"gbm-sys",
|
||||
|
@ -1370,7 +1370,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets 0.52.4",
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2300,7 +2300,7 @@ checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c"
|
|||
[[package]]
|
||||
name = "smithay"
|
||||
version = "0.3.0"
|
||||
source = "git+https://github.com/Smithay/smithay?rev=c293ec7#c293ec730fa66b53b8e16cffac94e9d0c8870a2c"
|
||||
source = "git+https://github.com/Smithay/smithay?rev=f3e442c#f3e442c28830ad752a5ca197ec1fb885af09f3ab"
|
||||
dependencies = [
|
||||
"appendlist",
|
||||
"ash",
|
||||
|
@ -2375,7 +2375,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "smithay-drm-extras"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/Smithay/smithay?rev=c293ec7#c293ec730fa66b53b8e16cffac94e9d0c8870a2c"
|
||||
source = "git+https://github.com/Smithay/smithay?rev=f3e442c#f3e442c28830ad752a5ca197ec1fb885af09f3ab"
|
||||
dependencies = [
|
||||
"drm",
|
||||
"edid-rs",
|
||||
|
|
|
@ -49,7 +49,7 @@ keywords = ["wayland", "compositor", "smithay", "lua"]
|
|||
[dependencies]
|
||||
# Smithay
|
||||
smithay = { workspace = true }
|
||||
smithay-drm-extras = { git = "https://github.com/Smithay/smithay", rev = "c293ec7" }
|
||||
smithay-drm-extras = { git = "https://github.com/Smithay/smithay", rev = "f3e442c" }
|
||||
# Tracing
|
||||
tracing = { workspace = true }
|
||||
tracing-subscriber = { workspace = true }
|
||||
|
@ -89,7 +89,7 @@ gag = "1.0.0"
|
|||
|
||||
[workspace.dependencies.smithay]
|
||||
git = "https://github.com/Smithay/smithay"
|
||||
rev = "c293ec7"
|
||||
rev = "f3e442c"
|
||||
default-features = false
|
||||
features = [
|
||||
"desktop",
|
||||
|
|
|
@ -5,7 +5,6 @@ use smithay::backend::renderer::test::DummyRenderer;
|
|||
use smithay::backend::renderer::ImportMemWl;
|
||||
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
|
||||
use smithay::utils::{Physical, Size};
|
||||
use std::ffi::OsString;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use smithay::{
|
||||
|
@ -119,13 +118,7 @@ pub fn setup_dummy(
|
|||
|
||||
state.pinnacle.space.map_output(&output, (0, 0));
|
||||
|
||||
if let Err(err) = state.pinnacle.xwayland.start(
|
||||
state.pinnacle.loop_handle.clone(),
|
||||
None,
|
||||
std::iter::empty::<(OsString, OsString)>(),
|
||||
true,
|
||||
|_| {},
|
||||
) {
|
||||
if let Err(err) = state.pinnacle.start_xwayland() {
|
||||
tracing::error!("Failed to start XWayland: {err}");
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ mod gamma;
|
|||
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
ffi::OsString,
|
||||
path::{Path, PathBuf},
|
||||
time::Duration,
|
||||
};
|
||||
|
@ -684,13 +683,7 @@ pub fn setup_udev(
|
|||
});
|
||||
});
|
||||
|
||||
if let Err(err) = state.pinnacle.xwayland.start(
|
||||
state.pinnacle.loop_handle.clone(),
|
||||
None,
|
||||
std::iter::empty::<(OsString, OsString)>(),
|
||||
true,
|
||||
|_| {},
|
||||
) {
|
||||
if let Err(err) = state.pinnacle.start_xwayland() {
|
||||
error!("Failed to start XWayland: {err}");
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
use std::{ffi::OsString, path::PathBuf, time::Duration};
|
||||
use std::{path::PathBuf, time::Duration};
|
||||
|
||||
use anyhow::{anyhow, ensure};
|
||||
use smithay::{
|
||||
|
@ -201,13 +201,7 @@ pub fn setup_winit(
|
|||
|
||||
state.pinnacle.space.map_output(&output, (0, 0));
|
||||
|
||||
if let Err(err) = state.pinnacle.xwayland.start(
|
||||
state.pinnacle.loop_handle.clone(),
|
||||
None,
|
||||
std::iter::empty::<(OsString, OsString)>(),
|
||||
true,
|
||||
|_| {},
|
||||
) {
|
||||
if let Err(err) = state.pinnacle.start_xwayland() {
|
||||
error!("Failed to start XWayland: {err}");
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
use std::{process::Stdio, time::Duration};
|
||||
|
||||
use anyhow::anyhow;
|
||||
use smithay::{
|
||||
desktop::Window,
|
||||
utils::{Logical, Point, Rectangle, SERIAL_COUNTER},
|
||||
utils::{Logical, Point, Rectangle, Size, SERIAL_COUNTER},
|
||||
wayland::{
|
||||
seat::WaylandFocus,
|
||||
selection::{
|
||||
|
@ -19,12 +22,13 @@ use smithay::{
|
|||
},
|
||||
xwayland::{
|
||||
xwm::{Reorder, WmWindowType, XwmId},
|
||||
X11Surface, X11Wm, XwmHandler,
|
||||
X11Surface, X11Wm, XWayland, XWaylandEvent, XwmHandler,
|
||||
},
|
||||
};
|
||||
use tracing::{debug, error, trace, warn};
|
||||
|
||||
use crate::{
|
||||
cursor::Cursor,
|
||||
focus::keyboard::KeyboardFocusTarget,
|
||||
state::{Pinnacle, State, WithState},
|
||||
window::{window_state::FloatingOrTiled, WindowElement},
|
||||
|
@ -585,3 +589,66 @@ fn should_float(surface: &X11Surface) -> bool {
|
|||
});
|
||||
surface.is_popup() || is_popup_by_type || is_popup_by_size
|
||||
}
|
||||
|
||||
impl Pinnacle {
|
||||
pub fn start_xwayland(&mut self) -> anyhow::Result<()> {
|
||||
// TODO: xwayland keybaord grab state
|
||||
|
||||
let (xwayland, client) = XWayland::spawn(
|
||||
&self.display_handle,
|
||||
None,
|
||||
std::iter::empty::<(String, String)>(),
|
||||
true,
|
||||
Stdio::null(),
|
||||
Stdio::null(),
|
||||
|_| (),
|
||||
)?;
|
||||
|
||||
let display_handle = self.display_handle.clone();
|
||||
|
||||
self.loop_handle
|
||||
.insert_source(xwayland, move |event, _, state| match event {
|
||||
XWaylandEvent::Ready {
|
||||
x11_socket,
|
||||
display_number,
|
||||
} => {
|
||||
let mut wm = X11Wm::start_wm(
|
||||
state.pinnacle.loop_handle.clone(),
|
||||
display_handle.clone(),
|
||||
x11_socket,
|
||||
client.clone(),
|
||||
)
|
||||
.expect("failed to attach x11wm");
|
||||
|
||||
let cursor = Cursor::load();
|
||||
let image = cursor.get_image(1, Duration::ZERO);
|
||||
wm.set_cursor(
|
||||
&image.pixels_rgba,
|
||||
Size::from((image.width as u16, image.height as u16)),
|
||||
Point::from((image.xhot as u16, image.yhot as u16)),
|
||||
)
|
||||
.expect("failed to set xwayland default cursor");
|
||||
|
||||
tracing::debug!("setting xwm and xdisplay");
|
||||
|
||||
state.pinnacle.xwm = Some(wm);
|
||||
state.pinnacle.xdisplay = Some(display_number);
|
||||
|
||||
std::env::set_var("DISPLAY", format!(":{display_number}"));
|
||||
|
||||
if let Err(err) = state.pinnacle.start_config(Some(
|
||||
state.pinnacle.config.dir(&state.pinnacle.xdg_base_dirs),
|
||||
)) {
|
||||
panic!("failed to start config: {err}");
|
||||
}
|
||||
}
|
||||
XWaylandEvent::Error => {
|
||||
warn!("XWayland crashed on startup");
|
||||
}
|
||||
})
|
||||
.map(|_| ())
|
||||
.map_err(|err| {
|
||||
anyhow!("Failed to insert the XWaylandSource into the event loop: {err}")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
53
src/input.rs
53
src/input.rs
|
@ -644,7 +644,7 @@ impl State {
|
|||
return;
|
||||
};
|
||||
|
||||
let mut pointer_loc = pointer.current_location();
|
||||
let pointer_loc = pointer.current_location();
|
||||
|
||||
let mut pointer_confined_to: Option<(
|
||||
WlSurface,
|
||||
|
@ -712,18 +712,14 @@ impl State {
|
|||
}
|
||||
}
|
||||
|
||||
pointer_loc += event.delta();
|
||||
let mut new_pointer_loc = pointer_loc + event.delta();
|
||||
|
||||
// clamp to screen limits
|
||||
// this event is never generated by winit
|
||||
let output_locs = self
|
||||
.pinnacle
|
||||
.space
|
||||
.outputs()
|
||||
.flat_map(|op| self.pinnacle.space.output_geometry(op));
|
||||
pointer_loc = clamp_coords_inside_rects(pointer_loc, output_locs);
|
||||
|
||||
let surface_under = self.pinnacle.pointer_focus_target_under(pointer_loc);
|
||||
new_pointer_loc = constrain_point_inside_rects(new_pointer_loc, output_locs);
|
||||
|
||||
if let Some((surf, surf_loc, region)) = pointer_confined_to {
|
||||
let region = region.or_else(|| {
|
||||
|
@ -755,27 +751,30 @@ impl State {
|
|||
}
|
||||
}
|
||||
|
||||
pointer_loc = clamp_coords_inside_rects(pointer_loc, region_rects);
|
||||
new_pointer_loc = constrain_point_inside_rects(new_pointer_loc, region_rects);
|
||||
}
|
||||
}
|
||||
|
||||
self.pinnacle.maybe_activate_pointer_constraint(pointer_loc);
|
||||
self.pinnacle
|
||||
.maybe_activate_pointer_constraint(new_pointer_loc);
|
||||
|
||||
if let Some(output) = self
|
||||
.pinnacle
|
||||
.space
|
||||
.output_under(pointer_loc)
|
||||
.output_under(new_pointer_loc)
|
||||
.next()
|
||||
.cloned()
|
||||
{
|
||||
self.pinnacle.output_focus_stack.set_focus(output);
|
||||
}
|
||||
|
||||
let surface_under = self.pinnacle.pointer_focus_target_under(new_pointer_loc);
|
||||
|
||||
pointer.motion(
|
||||
self,
|
||||
surface_under.clone(),
|
||||
&MotionEvent {
|
||||
location: pointer_loc,
|
||||
location: new_pointer_loc,
|
||||
serial: SERIAL_COUNTER.next_serial(),
|
||||
time: event.time_msec(),
|
||||
},
|
||||
|
@ -802,26 +801,42 @@ impl State {
|
|||
/// Clamp the given point within the given rects.
|
||||
///
|
||||
/// This returns the nearest point inside the rects.
|
||||
fn clamp_coords_inside_rects(
|
||||
fn constrain_point_inside_rects(
|
||||
pos: Point<f64, Logical>,
|
||||
rects: impl IntoIterator<Item = Rectangle<i32, Logical>>,
|
||||
) -> Point<f64, Logical> {
|
||||
let (pos_x, pos_y) = pos.into();
|
||||
|
||||
let nearest_points = rects.into_iter().map(|rect| {
|
||||
let loc = rect.loc;
|
||||
let size = rect.size;
|
||||
let pos_x = pos_x.clamp(loc.x as f64, (loc.x + size.w - 1) as f64);
|
||||
let pos_y = pos_y.clamp(loc.y as f64, (loc.y + size.h - 1) as f64);
|
||||
(pos_x, pos_y)
|
||||
// TODO: replace with constrain once fix is merged
|
||||
// let pos = pos.constrain(rect.to_f64());
|
||||
// (rect, pos.x, pos.y)
|
||||
let pos_x = pos_x.clamp(rect.loc.x as f64, (rect.loc.x + rect.size.w) as f64);
|
||||
let pos_y = pos_y.clamp(rect.loc.y as f64, (rect.loc.y + rect.size.h) as f64);
|
||||
(rect, pos_x, pos_y)
|
||||
});
|
||||
|
||||
let nearest_point = nearest_points.min_by(|(x1, y1), (x2, y2)| {
|
||||
let nearest_point = nearest_points.min_by(|(_, x1, y1), (_, x2, y2)| {
|
||||
f64::total_cmp(
|
||||
&((pos_x - x1).powi(2) + (pos_y - y1).powi(2)).sqrt(),
|
||||
&((pos_x - x2).powi(2) + (pos_y - y2).powi(2)).sqrt(),
|
||||
)
|
||||
});
|
||||
|
||||
nearest_point.map(|point| point.into()).unwrap_or(pos)
|
||||
nearest_point
|
||||
.map(|(rect, mut x, mut y)| {
|
||||
let rect = rect.to_f64();
|
||||
|
||||
// If the passed in point is to the right/bottom, nudge the nearest point by 1
|
||||
// in the other direction to make it actually inside the rect and not touching
|
||||
// its edge.
|
||||
if pos_x >= rect.loc.x + rect.size.w {
|
||||
x -= 1.0;
|
||||
}
|
||||
if pos_y >= rect.loc.y + rect.size.h {
|
||||
y -= 1.0;
|
||||
}
|
||||
(x, y).into()
|
||||
})
|
||||
.unwrap_or(pos)
|
||||
}
|
||||
|
|
61
src/state.rs
61
src/state.rs
|
@ -4,7 +4,6 @@ use crate::{
|
|||
api::signal::SignalState,
|
||||
backend::Backend,
|
||||
config::Config,
|
||||
cursor::Cursor,
|
||||
focus::OutputFocusStack,
|
||||
grab::resize_grab::ResizeSurfaceState,
|
||||
layout::LayoutState,
|
||||
|
@ -24,7 +23,7 @@ use smithay::{
|
|||
Display, DisplayHandle,
|
||||
},
|
||||
},
|
||||
utils::{Clock, Monotonic, Point, Size},
|
||||
utils::{Clock, Monotonic},
|
||||
wayland::{
|
||||
compositor::{self, CompositorClientState, CompositorState},
|
||||
dmabuf::DmabufFeedback,
|
||||
|
@ -41,9 +40,9 @@ use smithay::{
|
|||
socket::ListeningSocketSource,
|
||||
viewporter::ViewporterState,
|
||||
},
|
||||
xwayland::{X11Wm, XWayland, XWaylandEvent},
|
||||
xwayland::X11Wm,
|
||||
};
|
||||
use std::{cell::RefCell, path::PathBuf, sync::Arc, time::Duration};
|
||||
use std::{cell::RefCell, path::PathBuf, sync::Arc};
|
||||
use sysinfo::{ProcessRefreshKind, RefreshKind};
|
||||
use tracing::{error, info, warn};
|
||||
use xdg::BaseDirectories;
|
||||
|
@ -103,7 +102,6 @@ pub struct Pinnacle {
|
|||
pub config: Config,
|
||||
|
||||
// xwayland stuff
|
||||
pub xwayland: XWayland,
|
||||
pub xwm: Option<X11Wm>,
|
||||
pub xdisplay: Option<u32>,
|
||||
|
||||
|
@ -186,58 +184,6 @@ impl State {
|
|||
|
||||
seat.add_keyboard(XkbConfig::default(), 500, 25)?;
|
||||
|
||||
let xwayland = {
|
||||
let (xwayland, channel) = XWayland::new(&display_handle);
|
||||
let dh_clone = display_handle.clone();
|
||||
|
||||
let res = loop_handle.insert_source(channel, move |event, _, state| match event {
|
||||
XWaylandEvent::Ready {
|
||||
connection,
|
||||
client,
|
||||
client_fd: _,
|
||||
display,
|
||||
} => {
|
||||
let mut wm = X11Wm::start_wm(
|
||||
state.pinnacle.loop_handle.clone(),
|
||||
dh_clone.clone(),
|
||||
connection,
|
||||
client,
|
||||
)
|
||||
.expect("failed to attach x11wm");
|
||||
|
||||
let cursor = Cursor::load();
|
||||
let image = cursor.get_image(1, Duration::ZERO);
|
||||
wm.set_cursor(
|
||||
&image.pixels_rgba,
|
||||
Size::from((image.width as u16, image.height as u16)),
|
||||
Point::from((image.xhot as u16, image.yhot as u16)),
|
||||
)
|
||||
.expect("failed to set xwayland default cursor");
|
||||
|
||||
tracing::debug!("setting xwm and xdisplay");
|
||||
|
||||
state.pinnacle.xwm = Some(wm);
|
||||
state.pinnacle.xdisplay = Some(display);
|
||||
|
||||
std::env::set_var("DISPLAY", format!(":{display}"));
|
||||
|
||||
if let Err(err) = state.pinnacle.start_config(Some(
|
||||
state.pinnacle.config.dir(&state.pinnacle.xdg_base_dirs),
|
||||
)) {
|
||||
panic!("failed to start config: {err}");
|
||||
}
|
||||
}
|
||||
XWaylandEvent::Exited => {
|
||||
state.pinnacle.xwm.take();
|
||||
}
|
||||
});
|
||||
if let Err(err) = res {
|
||||
error!("Failed to insert XWayland source into loop: {err}");
|
||||
}
|
||||
xwayland
|
||||
};
|
||||
tracing::debug!("xwayland set up");
|
||||
|
||||
let primary_selection_state = PrimarySelectionState::new::<Self>(&display_handle);
|
||||
|
||||
let data_control_state = DataControlState::new::<Self, _>(
|
||||
|
@ -300,7 +246,6 @@ impl State {
|
|||
windows: Vec::new(),
|
||||
new_windows: Vec::new(),
|
||||
|
||||
xwayland,
|
||||
xwm: None,
|
||||
xdisplay: None,
|
||||
|
||||
|
|
Loading…
Reference in a new issue