Add support for wl_compositor@v6

This commit is contained in:
Kirill Chibisov
2023-10-26 00:15:46 +04:00
committed by Ivan Molodetskikh
parent 49a8f156f3
commit 0a2052945e
9 changed files with 121 additions and 37 deletions
Generated
+16 -16
View File
@@ -10,9 +10,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]] [[package]]
name = "ahash" name = "ahash"
version = "0.8.5" version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd7d5a2cecb58716e47d67d5703a249964b14c7be1ec3cad3affc295b2d1c35d" checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"getrandom", "getrandom",
@@ -535,9 +535,9 @@ dependencies = [
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.4.6" version = "4.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956" checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b"
dependencies = [ dependencies = [
"clap_builder", "clap_builder",
"clap_derive", "clap_derive",
@@ -545,9 +545,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_builder" name = "clap_builder"
version = "4.4.6" version = "4.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45" checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663"
dependencies = [ dependencies = [
"anstream", "anstream",
"anstyle", "anstyle",
@@ -557,9 +557,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_derive" name = "clap_derive"
version = "4.4.2" version = "4.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442"
dependencies = [ dependencies = [
"heck", "heck",
"proc-macro2", "proc-macro2",
@@ -569,9 +569,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_lex" name = "clap_lex"
version = "0.5.1" version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1"
[[package]] [[package]]
name = "colorchoice" name = "colorchoice"
@@ -2223,7 +2223,7 @@ checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a"
[[package]] [[package]]
name = "smithay" name = "smithay"
version = "0.3.0" version = "0.3.0"
source = "git+https://github.com/Smithay/smithay.git#76c014a569fada77eed361feeb472ab7f9498232" source = "git+https://github.com/Smithay/smithay.git#a82f899bfeeaaf420b9cea390cdab39b12ce702c"
dependencies = [ dependencies = [
"appendlist", "appendlist",
"bitflags 2.4.1", "bitflags 2.4.1",
@@ -2295,7 +2295,7 @@ dependencies = [
[[package]] [[package]]
name = "smithay-drm-extras" name = "smithay-drm-extras"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/Smithay/smithay.git#76c014a569fada77eed361feeb472ab7f9498232" source = "git+https://github.com/Smithay/smithay.git#a82f899bfeeaaf420b9cea390cdab39b12ce702c"
dependencies = [ dependencies = [
"drm", "drm",
"edid-rs", "edid-rs",
@@ -3293,18 +3293,18 @@ dependencies = [
[[package]] [[package]]
name = "zerocopy" name = "zerocopy"
version = "0.7.11" version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c19fae0c8a9efc6a8281f2e623db8af1db9e57852e04cde3e754dd2dc29340f" checksum = "81ba595b9f2772fbee2312de30eeb80ec773b4cb2f1e8098db024afadda6c06f"
dependencies = [ dependencies = [
"zerocopy-derive", "zerocopy-derive",
] ]
[[package]] [[package]]
name = "zerocopy-derive" name = "zerocopy-derive"
version = "0.7.11" version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc56589e9ddd1f1c28d4b4b5c773ce232910a6bb67a70133d61c9e347585efe9" checksum = "772666c41fb6dceaf520b564b962d738a8e1a83b41bd48945f50837aed78bb1d"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
+2 -3
View File
@@ -529,9 +529,6 @@ impl Tty {
.map(|info| (info.manufacturer, info.model)) .map(|info| (info.manufacturer, info.model))
.unwrap_or_else(|| ("Unknown".into(), "Unknown".into())); .unwrap_or_else(|| ("Unknown".into(), "Unknown".into()));
let scale = config.scale.clamp(0.1, 10.);
let scale = scale.max(1.).round() as i32;
let output = Output::new( let output = Output::new(
output_name.clone(), output_name.clone(),
PhysicalProperties { PhysicalProperties {
@@ -541,7 +538,9 @@ impl Tty {
make, make,
}, },
); );
let wl_mode = Mode::from(*mode); let wl_mode = Mode::from(*mode);
let scale = config.scale.clamp(1., 10.).ceil() as i32;
output.change_current_state(Some(wl_mode), None, Some(Scale::Integer(scale)), None); output.change_current_state(Some(wl_mode), None, Some(Scale::Integer(scale)), None);
output.set_preferred(wl_mode); output.set_preferred(wl_mode);
+6 -7
View File
@@ -45,13 +45,6 @@ impl Winit {
.find(|o| o.name == "winit") .find(|o| o.name == "winit")
.cloned() .cloned()
.unwrap_or_default(); .unwrap_or_default();
let scale = output_config.scale.clamp(0.1, 10.);
let scale = scale.max(1.).round() as i32;
let mode = Mode {
size: backend.window_size(),
refresh: 60_000,
};
let output = Output::new( let output = Output::new(
"winit".to_string(), "winit".to_string(),
@@ -62,6 +55,12 @@ impl Winit {
model: "Winit".into(), model: "Winit".into(),
}, },
); );
let mode = Mode {
size: backend.window_size(),
refresh: 60_000,
};
let scale = output_config.scale.clamp(1., 10.).ceil() as i32;
output.change_current_state( output.change_current_state(
Some(mode), Some(mode),
Some(Transform::Flipped180), Some(Transform::Flipped180),
+13 -2
View File
@@ -9,8 +9,9 @@ use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
use smithay::reexports::wayland_server::{Client, Resource}; use smithay::reexports::wayland_server::{Client, Resource};
use smithay::wayland::buffer::BufferHandler; use smithay::wayland::buffer::BufferHandler;
use smithay::wayland::compositor::{ use smithay::wayland::compositor::{
add_blocker, add_pre_commit_hook, get_parent, is_sync_subsurface, with_states, add_blocker, add_pre_commit_hook, get_parent, is_sync_subsurface, send_surface_state,
BufferAssignment, CompositorClientState, CompositorHandler, CompositorState, SurfaceAttributes, with_states, BufferAssignment, CompositorClientState, CompositorHandler, CompositorState,
SurfaceAttributes,
}; };
use smithay::wayland::dmabuf::get_dmabuf; use smithay::wayland::dmabuf::get_dmabuf;
use smithay::wayland::shm::{ShmHandler, ShmState}; use smithay::wayland::shm::{ShmHandler, ShmState};
@@ -28,6 +29,16 @@ impl CompositorHandler for State {
&client.get_data::<ClientState>().unwrap().compositor_state &client.get_data::<ClientState>().unwrap().compositor_state
} }
fn new_subsurface(&mut self, surface: &WlSurface, parent: &WlSurface) {
if let Some((_, output)) = self.niri.layout.find_window_and_output(parent) {
let scale = output.current_scale().integer_scale();
let transform = output.current_transform();
with_states(surface, |data| {
send_surface_state(surface, data, scale, transform);
});
}
}
fn new_surface(&mut self, surface: &WlSurface) { fn new_surface(&mut self, surface: &WlSurface) {
add_pre_commit_hook::<Self, _>(surface, move |state, _dh, surface| { add_pre_commit_hook::<Self, _>(surface, move |state, _dh, surface| {
let maybe_dmabuf = with_states(surface, |surface_data| { let maybe_dmabuf = with_states(surface, |surface_data| {
+7 -1
View File
@@ -3,7 +3,7 @@ use smithay::desktop::{layer_map_for_output, LayerSurface, WindowSurfaceType};
use smithay::output::Output; use smithay::output::Output;
use smithay::reexports::wayland_server::protocol::wl_output::WlOutput; use smithay::reexports::wayland_server::protocol::wl_output::WlOutput;
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface; use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
use smithay::wayland::compositor::with_states; use smithay::wayland::compositor::{send_surface_state, with_states};
use smithay::wayland::shell::wlr_layer::{ use smithay::wayland::shell::wlr_layer::{
Layer, LayerSurface as WlrLayerSurface, LayerSurfaceData, WlrLayerShellHandler, Layer, LayerSurface as WlrLayerSurface, LayerSurfaceData, WlrLayerShellHandler,
WlrLayerShellState, WlrLayerShellState,
@@ -92,6 +92,12 @@ impl State {
.layer_for_surface(surface, WindowSurfaceType::TOPLEVEL) .layer_for_surface(surface, WindowSurfaceType::TOPLEVEL)
.unwrap(); .unwrap();
let scale = output.current_scale().integer_scale();
let transform = output.current_transform();
with_states(surface, |data| {
send_surface_state(surface, data, scale, transform);
});
layer.layer_surface().send_configure(); layer.layer_surface().send_configure();
} }
drop(map); drop(map);
+18
View File
@@ -19,6 +19,7 @@ use smithay::reexports::wayland_server::protocol::wl_output::WlOutput;
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface; use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
use smithay::reexports::wayland_server::Resource; use smithay::reexports::wayland_server::Resource;
use smithay::utils::{Logical, Rectangle, Size}; use smithay::utils::{Logical, Rectangle, Size};
use smithay::wayland::compositor::{send_surface_state, with_states};
use smithay::wayland::dmabuf::{DmabufGlobal, DmabufHandler, DmabufState, ImportError}; use smithay::wayland::dmabuf::{DmabufGlobal, DmabufHandler, DmabufState, ImportError};
use smithay::wayland::input_method::{InputMethodHandler, PopupSurface}; use smithay::wayland::input_method::{InputMethodHandler, PopupSurface};
use smithay::wayland::selection::data_device::{ use smithay::wayland::selection::data_device::{
@@ -71,6 +72,17 @@ delegate_text_input_manager!(State);
impl InputMethodHandler for State { impl InputMethodHandler for State {
fn new_popup(&mut self, surface: PopupSurface) { fn new_popup(&mut self, surface: PopupSurface) {
if let Some((_, output)) = surface
.get_parent()
.and_then(|parent| self.niri.layout.find_window_and_output(&parent.surface))
{
let scale = output.current_scale().integer_scale();
let transform = output.current_transform();
let wl_surface = surface.wl_surface();
with_states(wl_surface, |data| {
send_surface_state(wl_surface, data, scale, transform);
});
}
if let Err(err) = self.niri.popups.track_popup(PopupKind::from(surface)) { if let Err(err) = self.niri.popups.track_popup(PopupKind::from(surface)) {
warn!("error tracking ime popup {err:?}"); warn!("error tracking ime popup {err:?}");
} }
@@ -216,5 +228,11 @@ pub fn configure_lock_surface(surface: &LockSurface, output: &Output) {
let size = output_size(output); let size = output_size(output);
states.size = Some(Size::from((size.w as u32, size.h as u32))); states.size = Some(Size::from((size.w as u32, size.h as u32)));
}); });
let scale = output.current_scale().integer_scale();
let transform = output.current_transform();
let wl_surface = surface.wl_surface();
with_states(wl_surface, |data| {
send_surface_state(wl_surface, data, scale, transform);
});
surface.send_configure(); surface.send_configure();
} }
+13 -3
View File
@@ -6,7 +6,7 @@ use smithay::reexports::wayland_server::protocol::wl_output;
use smithay::reexports::wayland_server::protocol::wl_seat::WlSeat; use smithay::reexports::wayland_server::protocol::wl_seat::WlSeat;
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface; use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
use smithay::utils::Serial; use smithay::utils::Serial;
use smithay::wayland::compositor::with_states; use smithay::wayland::compositor::{send_surface_state, with_states};
use smithay::wayland::shell::kde::decoration::{KdeDecorationHandler, KdeDecorationState}; use smithay::wayland::shell::kde::decoration::{KdeDecorationHandler, KdeDecorationState};
use smithay::wayland::shell::xdg::decoration::XdgDecorationHandler; use smithay::wayland::shell::xdg::decoration::XdgDecorationHandler;
use smithay::wayland::shell::xdg::{ use smithay::wayland::shell::xdg::{
@@ -264,8 +264,18 @@ impl State {
.initial_configure_sent .initial_configure_sent
}); });
if !initial_configure_sent { if !initial_configure_sent {
// NOTE: This should never fail as the initial configure is always if let Some(output) = popup.get_parent_surface().and_then(|parent| {
// allowed. self.niri
.layout
.find_window_and_output(&parent)
.map(|(_, output)| output)
}) {
let scale = output.current_scale().integer_scale();
let transform = output.current_transform();
with_states(surface, |data| {
send_surface_state(surface, data, scale, transform);
});
}
popup.send_configure().expect("initial configure failed"); popup.send_configure().expect("initial configure failed");
} }
} }
+21 -1
View File
@@ -52,7 +52,7 @@ use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel;
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface; use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
use smithay::render_elements; use smithay::render_elements;
use smithay::utils::{Logical, Point, Rectangle, Scale, Size}; use smithay::utils::{Logical, Point, Rectangle, Scale, Size};
use smithay::wayland::compositor::with_states; use smithay::wayland::compositor::{send_surface_state, with_states, SurfaceData};
use smithay::wayland::shell::xdg::SurfaceCachedState; use smithay::wayland::shell::xdg::SurfaceCachedState;
use crate::animation::Animation; use crate::animation::Animation;
@@ -77,6 +77,7 @@ pub trait LayoutElement: SpaceElement + PartialEq + Clone {
fn max_size(&self) -> Size<i32, Logical>; fn max_size(&self) -> Size<i32, Logical>;
fn is_wl_surface(&self, wl_surface: &WlSurface) -> bool; fn is_wl_surface(&self, wl_surface: &WlSurface) -> bool;
fn has_ssd(&self) -> bool; fn has_ssd(&self) -> bool;
fn with_surfaces<F: FnMut(&WlSurface, &SurfaceData)>(&self, processor: F);
} }
#[derive(Debug)] #[derive(Debug)]
@@ -333,6 +334,10 @@ impl LayoutElement for Window {
self.toplevel().wl_surface() == wl_surface self.toplevel().wl_surface() == wl_surface
} }
fn with_surfaces<F: FnMut(&WlSurface, &SurfaceData)>(&self, processor: F) {
self.with_surfaces(processor);
}
fn has_ssd(&self) -> bool { fn has_ssd(&self) -> bool {
self.toplevel().current_state().decoration_mode self.toplevel().current_state().decoration_mode
== Some(zxdg_toplevel_decoration_v1::Mode::ServerSide) == Some(zxdg_toplevel_decoration_v1::Mode::ServerSide)
@@ -1903,6 +1908,7 @@ impl<W: LayoutElement> Workspace<W> {
fn enter_output_for_window(&self, window: &W) { fn enter_output_for_window(&self, window: &W) {
if let Some(output) = &self.output { if let Some(output) = &self.output {
// FIXME: proper overlap. // FIXME: proper overlap.
self.send_surface_state_for_window_tree(window, output);
window.output_enter( window.output_enter(
output, output,
Rectangle::from_loc_and_size((0, 0), (i32::MAX, i32::MAX)), Rectangle::from_loc_and_size((0, 0), (i32::MAX, i32::MAX)),
@@ -1937,12 +1943,24 @@ impl<W: LayoutElement> Workspace<W> {
let bounds = self.toplevel_bounds(); let bounds = self.toplevel_bounds();
if let Some(output) = self.output.as_ref() {
self.send_surface_state_for_window_tree(window, output);
}
window.toplevel().with_pending_state(|state| { window.toplevel().with_pending_state(|state| {
state.size = Some(size); state.size = Some(size);
state.bounds = Some(bounds); state.bounds = Some(bounds);
}); });
} }
fn send_surface_state_for_window_tree(&self, window: &impl LayoutElement, output: &Output) {
let scale = output.current_scale().integer_scale();
let transform = output.current_transform();
window.with_surfaces(|surface, data| {
send_surface_state(surface, data, scale, transform);
});
}
fn compute_new_view_offset_for_column(&self, current_x: i32, idx: usize) -> i32 { fn compute_new_view_offset_for_column(&self, current_x: i32, idx: usize) -> i32 {
if self.columns[idx].is_fullscreen { if self.columns[idx].is_fullscreen {
return 0; return 0;
@@ -2890,6 +2908,8 @@ mod tests {
false false
} }
fn with_surfaces<F: FnMut(&WlSurface, &SurfaceData)>(&self, _processor: F) {}
fn has_ssd(&self) -> bool { fn has_ssd(&self) -> bool {
false false
} }
+25 -4
View File
@@ -49,8 +49,8 @@ use smithay::utils::{
SERIAL_COUNTER, SERIAL_COUNTER,
}; };
use smithay::wayland::compositor::{ use smithay::wayland::compositor::{
with_states, with_surface_tree_downward, CompositorClientState, CompositorState, SurfaceData, send_surface_state, with_states, with_surface_tree_downward, CompositorClientState,
TraversalAction, CompositorState, SurfaceData, TraversalAction,
}; };
use smithay::wayland::dmabuf::DmabufFeedback; use smithay::wayland::dmabuf::DmabufFeedback;
use smithay::wayland::input_method::InputMethodManagerState; use smithay::wayland::input_method::InputMethodManagerState;
@@ -511,7 +511,7 @@ impl Niri {
let layout = Layout::new(&config_); let layout = Layout::new(&config_);
let compositor_state = CompositorState::new::<State>(&display_handle); let compositor_state = CompositorState::new_v6::<State>(&display_handle);
let xdg_shell_state = XdgShellState::new_with_capabilities::<State>( let xdg_shell_state = XdgShellState::new_with_capabilities::<State>(
&display_handle, &display_handle,
[WmCapabilities::Fullscreen], [WmCapabilities::Fullscreen],
@@ -542,7 +542,7 @@ impl Niri {
|_| true, |_| true,
); );
let presentation_state = let presentation_state =
PresentationState::new::<State>(&display_handle, Monotonic::id() as u32); PresentationState::new::<State>(&display_handle, Monotonic::ID as u32);
let text_input_state = TextInputManagerState::new::<State>(&display_handle); let text_input_state = TextInputManagerState::new::<State>(&display_handle);
let input_method_state = let input_method_state =
@@ -1163,6 +1163,7 @@ impl Niri {
let pointer_pos = self.seat.get_pointer().unwrap().current_location(); let pointer_pos = self.seat.get_pointer().unwrap().current_location();
let mut dnd_scale = 1;
for output in self.global_space.outputs() { for output in self.global_space.outputs() {
let geo = self.global_space.output_geometry(output).unwrap(); let geo = self.global_space.output_geometry(output).unwrap();
@@ -1180,10 +1181,15 @@ impl Niri {
if let Some(mut overlap) = geo.intersection(bbox) { if let Some(mut overlap) = geo.intersection(bbox) {
overlap.loc -= surface_pos; overlap.loc -= surface_pos;
dnd_scale = dnd_scale.max(output.current_scale().integer_scale());
output_update(output, Some(overlap), surface); output_update(output, Some(overlap), surface);
} else { } else {
output_update(output, None, surface); output_update(output, None, surface);
} }
with_states(surface, |data| {
send_surface_state(surface, data, dnd_scale, Transform::Normal);
});
} }
} }
CursorImageStatus::Surface(surface) => { CursorImageStatus::Surface(surface) => {
@@ -1206,12 +1212,17 @@ impl Niri {
.as_ref() .as_ref()
.map(|surface| (surface, bbox_from_surface_tree(surface, surface_pos))); .map(|surface| (surface, bbox_from_surface_tree(surface, surface_pos)));
// FIXME we basically need to pick the largest scale factor across the overlapping
// outputs, this is how it's usually done in clients as well.
let mut cursor_scale = 1;
let mut dnd_scale = 1;
for output in self.global_space.outputs() { for output in self.global_space.outputs() {
let geo = self.global_space.output_geometry(output).unwrap(); let geo = self.global_space.output_geometry(output).unwrap();
// Compute pointer surface overlap. // Compute pointer surface overlap.
if let Some(mut overlap) = geo.intersection(bbox) { if let Some(mut overlap) = geo.intersection(bbox) {
overlap.loc -= surface_pos; overlap.loc -= surface_pos;
cursor_scale = cursor_scale.max(output.current_scale().integer_scale());
output_update(output, Some(overlap), surface); output_update(output, Some(overlap), surface);
} else { } else {
output_update(output, None, surface); output_update(output, None, surface);
@@ -1221,12 +1232,22 @@ impl Niri {
if let Some((surface, bbox)) = dnd { if let Some((surface, bbox)) = dnd {
if let Some(mut overlap) = geo.intersection(bbox) { if let Some(mut overlap) = geo.intersection(bbox) {
overlap.loc -= surface_pos; overlap.loc -= surface_pos;
dnd_scale = dnd_scale.max(output.current_scale().integer_scale());
output_update(output, Some(overlap), surface); output_update(output, Some(overlap), surface);
} else { } else {
output_update(output, None, surface); output_update(output, None, surface);
} }
} }
} }
with_states(surface, |data| {
send_surface_state(surface, data, cursor_scale, Transform::Normal);
});
if let Some((surface, _)) = dnd {
with_states(surface, |data| {
send_surface_state(surface, data, dnd_scale, Transform::Normal);
});
}
} }
} }
} }