diff options
| author | Kirill Chibisov <contact@kchibisov.com> | 2023-10-26 00:15:46 +0400 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2023-10-29 13:58:48 +0400 |
| commit | 0a2052945e62c31585a3c7ec4c0efa84ebc5d312 (patch) | |
| tree | a339cae5e7ba362d7adf18c62948eb009a368d24 /src | |
| parent | 49a8f156f34434977358ea9f0a9cb97a753d857f (diff) | |
| download | niri-0a2052945e62c31585a3c7ec4c0efa84ebc5d312.tar.gz niri-0a2052945e62c31585a3c7ec4c0efa84ebc5d312.tar.bz2 niri-0a2052945e62c31585a3c7ec4c0efa84ebc5d312.zip | |
Add support for wl_compositor@v6
Diffstat (limited to 'src')
| -rw-r--r-- | src/backend/tty.rs | 5 | ||||
| -rw-r--r-- | src/backend/winit.rs | 13 | ||||
| -rw-r--r-- | src/handlers/compositor.rs | 15 | ||||
| -rw-r--r-- | src/handlers/layer_shell.rs | 8 | ||||
| -rw-r--r-- | src/handlers/mod.rs | 18 | ||||
| -rw-r--r-- | src/handlers/xdg_shell.rs | 16 | ||||
| -rw-r--r-- | src/layout.rs | 22 | ||||
| -rw-r--r-- | src/niri.rs | 29 |
8 files changed, 105 insertions, 21 deletions
diff --git a/src/backend/tty.rs b/src/backend/tty.rs index 52ec1ebd..1c3bbe44 100644 --- a/src/backend/tty.rs +++ b/src/backend/tty.rs @@ -529,9 +529,6 @@ impl Tty { .map(|info| (info.manufacturer, info.model)) .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( output_name.clone(), PhysicalProperties { @@ -541,7 +538,9 @@ impl Tty { make, }, ); + 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.set_preferred(wl_mode); diff --git a/src/backend/winit.rs b/src/backend/winit.rs index 1afb8d97..9bdf734b 100644 --- a/src/backend/winit.rs +++ b/src/backend/winit.rs @@ -45,13 +45,6 @@ impl Winit { .find(|o| o.name == "winit") .cloned() .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( "winit".to_string(), @@ -62,6 +55,12 @@ impl Winit { 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( Some(mode), Some(Transform::Flipped180), diff --git a/src/handlers/compositor.rs b/src/handlers/compositor.rs index 034f1ca5..71696d06 100644 --- a/src/handlers/compositor.rs +++ b/src/handlers/compositor.rs @@ -9,8 +9,9 @@ use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface; use smithay::reexports::wayland_server::{Client, Resource}; use smithay::wayland::buffer::BufferHandler; use smithay::wayland::compositor::{ - add_blocker, add_pre_commit_hook, get_parent, is_sync_subsurface, with_states, - BufferAssignment, CompositorClientState, CompositorHandler, CompositorState, SurfaceAttributes, + add_blocker, add_pre_commit_hook, get_parent, is_sync_subsurface, send_surface_state, + with_states, BufferAssignment, CompositorClientState, CompositorHandler, CompositorState, + SurfaceAttributes, }; use smithay::wayland::dmabuf::get_dmabuf; use smithay::wayland::shm::{ShmHandler, ShmState}; @@ -28,6 +29,16 @@ impl CompositorHandler for 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) { add_pre_commit_hook::<Self, _>(surface, move |state, _dh, surface| { let maybe_dmabuf = with_states(surface, |surface_data| { diff --git a/src/handlers/layer_shell.rs b/src/handlers/layer_shell.rs index 6e0ef318..a5b1d120 100644 --- a/src/handlers/layer_shell.rs +++ b/src/handlers/layer_shell.rs @@ -3,7 +3,7 @@ use smithay::desktop::{layer_map_for_output, LayerSurface, WindowSurfaceType}; use smithay::output::Output; use smithay::reexports::wayland_server::protocol::wl_output::WlOutput; 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::{ Layer, LayerSurface as WlrLayerSurface, LayerSurfaceData, WlrLayerShellHandler, WlrLayerShellState, @@ -92,6 +92,12 @@ impl State { .layer_for_surface(surface, WindowSurfaceType::TOPLEVEL) .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(); } drop(map); diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index 19742fcc..85e9e755 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -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::Resource; 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::input_method::{InputMethodHandler, PopupSurface}; use smithay::wayland::selection::data_device::{ @@ -71,6 +72,17 @@ delegate_text_input_manager!(State); impl InputMethodHandler for State { 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)) { warn!("error tracking ime popup {err:?}"); } @@ -216,5 +228,11 @@ pub fn configure_lock_surface(surface: &LockSurface, output: &Output) { let size = output_size(output); 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(); } diff --git a/src/handlers/xdg_shell.rs b/src/handlers/xdg_shell.rs index d0532a3b..d99fbdf0 100644 --- a/src/handlers/xdg_shell.rs +++ b/src/handlers/xdg_shell.rs @@ -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_surface::WlSurface; 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::xdg::decoration::XdgDecorationHandler; use smithay::wayland::shell::xdg::{ @@ -264,8 +264,18 @@ impl State { .initial_configure_sent }); if !initial_configure_sent { - // NOTE: This should never fail as the initial configure is always - // allowed. + if let Some(output) = popup.get_parent_surface().and_then(|parent| { + 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"); } } diff --git a/src/layout.rs b/src/layout.rs index 5c4a633e..ebfe0c1e 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -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::render_elements; 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 crate::animation::Animation; @@ -77,6 +77,7 @@ pub trait LayoutElement: SpaceElement + PartialEq + Clone { fn max_size(&self) -> Size<i32, Logical>; fn is_wl_surface(&self, wl_surface: &WlSurface) -> bool; fn has_ssd(&self) -> bool; + fn with_surfaces<F: FnMut(&WlSurface, &SurfaceData)>(&self, processor: F); } #[derive(Debug)] @@ -333,6 +334,10 @@ impl LayoutElement for Window { 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 { self.toplevel().current_state().decoration_mode == Some(zxdg_toplevel_decoration_v1::Mode::ServerSide) @@ -1903,6 +1908,7 @@ impl<W: LayoutElement> Workspace<W> { fn enter_output_for_window(&self, window: &W) { if let Some(output) = &self.output { // FIXME: proper overlap. + self.send_surface_state_for_window_tree(window, output); window.output_enter( output, 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(); + if let Some(output) = self.output.as_ref() { + self.send_surface_state_for_window_tree(window, output); + } + window.toplevel().with_pending_state(|state| { state.size = Some(size); 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 { if self.columns[idx].is_fullscreen { return 0; @@ -2890,6 +2908,8 @@ mod tests { false } + fn with_surfaces<F: FnMut(&WlSurface, &SurfaceData)>(&self, _processor: F) {} + fn has_ssd(&self) -> bool { false } diff --git a/src/niri.rs b/src/niri.rs index 91878e2e..db688266 100644 --- a/src/niri.rs +++ b/src/niri.rs @@ -49,8 +49,8 @@ use smithay::utils::{ SERIAL_COUNTER, }; use smithay::wayland::compositor::{ - with_states, with_surface_tree_downward, CompositorClientState, CompositorState, SurfaceData, - TraversalAction, + send_surface_state, with_states, with_surface_tree_downward, CompositorClientState, + CompositorState, SurfaceData, TraversalAction, }; use smithay::wayland::dmabuf::DmabufFeedback; use smithay::wayland::input_method::InputMethodManagerState; @@ -511,7 +511,7 @@ impl Niri { 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>( &display_handle, [WmCapabilities::Fullscreen], @@ -542,7 +542,7 @@ impl Niri { |_| true, ); 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 input_method_state = @@ -1163,6 +1163,7 @@ impl Niri { let pointer_pos = self.seat.get_pointer().unwrap().current_location(); + let mut dnd_scale = 1; for output in self.global_space.outputs() { let geo = self.global_space.output_geometry(output).unwrap(); @@ -1180,10 +1181,15 @@ impl Niri { if let Some(mut overlap) = geo.intersection(bbox) { overlap.loc -= surface_pos; + dnd_scale = dnd_scale.max(output.current_scale().integer_scale()); output_update(output, Some(overlap), surface); } else { output_update(output, None, surface); } + + with_states(surface, |data| { + send_surface_state(surface, data, dnd_scale, Transform::Normal); + }); } } CursorImageStatus::Surface(surface) => { @@ -1206,12 +1212,17 @@ impl Niri { .as_ref() .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() { let geo = self.global_space.output_geometry(output).unwrap(); // Compute pointer surface overlap. if let Some(mut overlap) = geo.intersection(bbox) { overlap.loc -= surface_pos; + cursor_scale = cursor_scale.max(output.current_scale().integer_scale()); output_update(output, Some(overlap), surface); } else { output_update(output, None, surface); @@ -1221,12 +1232,22 @@ impl Niri { if let Some((surface, bbox)) = dnd { if let Some(mut overlap) = geo.intersection(bbox) { overlap.loc -= surface_pos; + dnd_scale = dnd_scale.max(output.current_scale().integer_scale()); output_update(output, Some(overlap), surface); } else { 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); + }); + } } } } |
