Skip to content

Commit

Permalink
changes based on rust-windowing#4044
Browse files Browse the repository at this point in the history
  • Loading branch information
danbulant committed Jan 5, 2025
1 parent 114512b commit 414f09d
Show file tree
Hide file tree
Showing 7 changed files with 757 additions and 228 deletions.
51 changes: 50 additions & 1 deletion src/platform/wayland.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
//! * `wayland-csd-adwaita` (default).
//! * `wayland-csd-adwaita-crossfont`.
//! * `wayland-csd-adwaita-notitle`.
use sctk::shell::wlr_layer::{Anchor, KeyboardInteractivity, Layer};
use crate::dpi::{LogicalPosition, LogicalSize};
use crate::event_loop::{ActiveEventLoop, EventLoop, EventLoopBuilder};
use crate::monitor::MonitorHandle;
use crate::window::{Window, WindowAttributes};
Expand Down Expand Up @@ -85,7 +87,15 @@ pub trait WindowAttributesExtWayland {
///
/// For details about application ID conventions, see the
/// [Desktop Entry Spec](https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#desktop-file-id)
fn with_name(self, general: impl Into<String>, instance: impl Into<String>) -> Self;
fn with_name(self, general: impl Into<String>, instance: impl Into<String>) -> Self; fn with_anchor(self, anchor: Anchor) -> Self;
fn with_exclusive_zone(self, exclusive_zone: i32) -> Self;
fn with_margin(self, top: i32, right: i32, bottom: i32, left: i32) -> Self;
fn with_keyboard_interactivity(self, keyboard_interactivity: KeyboardInteractivity) -> Self;
fn with_layer(self, layer: Layer) -> Self;
#[cfg(wayland_platform)]
fn with_region(self, position: LogicalPosition<i32>, size: LogicalSize<i32>) -> Self;
#[cfg(wayland_platform)]
fn with_output(self, output: u32) -> Self;
}

impl WindowAttributesExtWayland for WindowAttributes {
Expand All @@ -95,6 +105,45 @@ impl WindowAttributesExtWayland for WindowAttributes {
Some(crate::platform_impl::ApplicationName::new(general.into(), instance.into()));
self
}
fn with_anchor(mut self, anchor: Anchor) -> Self {
self.platform_specific.wayland.anchor = Some(anchor);
self
}
#[inline]
fn with_exclusive_zone(mut self, exclusive_zone: i32) -> Self {
self.platform_specific.wayland.exclusive_zone = Some(exclusive_zone);
self
}
#[inline]
fn with_margin(mut self, top: i32, right: i32, bottom: i32, left: i32) -> Self {
self.platform_specific.wayland.margin = Some((top, right, bottom, left));
self
}
#[inline]
fn with_keyboard_interactivity(
mut self,
keyboard_interactivity: KeyboardInteractivity,
) -> Self {
self.platform_specific.wayland.keyboard_interactivity = Some(keyboard_interactivity);
self
}
#[inline]
fn with_layer(mut self, layer: Layer) -> Self {
self.platform_specific.wayland.layer = Some(layer);
self
}
#[inline]
#[cfg(wayland_platform)]
fn with_region(mut self, position: LogicalPosition<i32>, size: LogicalSize<i32>) -> Self {
self.platform_specific.wayland.region = Some((position, size));
self
}
#[inline]
#[cfg(wayland_platform)]
fn with_output(mut self, output: u32) -> Self {
self.platform_specific.wayland.output = Some(output);
self
}
}

/// Additional methods on `MonitorHandle` that are specific to Wayland.
Expand Down
26 changes: 26 additions & 0 deletions src/platform_impl/linux/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#[cfg(all(not(x11_platform), not(wayland_platform)))]
compile_error!("Please select a feature to build for unix: `x11`, `wayland`");

use dpi::{LogicalPosition, LogicalSize};
use sctk::shell::wlr_layer::{Anchor, KeyboardInteractivity, Layer};
use std::collections::VecDeque;
use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, RawFd};
use std::sync::Arc;
Expand Down Expand Up @@ -75,6 +77,8 @@ pub struct PlatformSpecificWindowAttributes {
pub activation_token: Option<ActivationToken>,
#[cfg(x11_platform)]
pub x11: X11WindowAttributes,
#[cfg(wayland_platform)]
pub wayland: WaylandWindowAttributes,
}

#[derive(Clone, Debug)]
Expand All @@ -90,6 +94,18 @@ pub struct X11WindowAttributes {
pub embed_window: Option<x11rb::protocol::xproto::Window>,
}

#[derive(Clone, Debug, PartialEq)]
#[cfg(wayland_platform)]
pub struct WaylandWindowAttributes {
pub layer: Option<Layer>,
pub anchor: Option<Anchor>,
pub output: Option<u32>,
pub region: Option<(LogicalPosition<i32>, LogicalSize<i32>)>,
pub exclusive_zone: Option<i32>,
pub margin: Option<(i32, i32, i32, i32)>,
pub keyboard_interactivity: Option<KeyboardInteractivity>,
}

#[cfg_attr(not(x11_platform), allow(clippy::derivable_impls))]
impl Default for PlatformSpecificWindowAttributes {
fn default() -> Self {
Expand All @@ -105,6 +121,16 @@ impl Default for PlatformSpecificWindowAttributes {
x11_window_types: vec![XWindowType::Normal],
embed_window: None,
},
#[cfg(wayland_platform)]
wayland: WaylandWindowAttributes {
layer: None,
margin: None,
anchor: None,
output: None,
region: None,
exclusive_zone: None,
keyboard_interactivity: None,
},
}
}
}
Expand Down
9 changes: 7 additions & 2 deletions src/platform_impl/linux/wayland/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,18 @@ impl MonitorHandle {
#[inline]
pub fn video_modes(&self) -> impl Iterator<Item = PlatformVideoModeHandle> {
let output_data = self.proxy.data::<OutputData>().unwrap();
let modes = output_data.with_output_info(|info| info.modes.clone());
// let modes = output_data.with_output_info(|info| info.modes.clone());
let (size, modes) =
output_data.with_output_info(|info| (info.logical_size, info.modes.clone()));

let monitor = self.clone();

modes.into_iter().map(move |mode| {
PlatformVideoModeHandle::Wayland(VideoModeHandle {
size: (mode.dimensions.0 as u32, mode.dimensions.1 as u32).into(),
size: size
.map(|(x, y)| (x as u32, y as u32))
.unwrap_or_else(|| (mode.dimensions.0 as u32, mode.dimensions.1 as u32))
.into(),
refresh_rate_millihertz: mode.refresh_rate as u32,
bit_depth: 32,
monitor: monitor.clone(),
Expand Down
43 changes: 43 additions & 0 deletions src/platform_impl/linux/wayland/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use sctk::output::{OutputHandler, OutputState};
use sctk::registry::{ProvidesRegistryState, RegistryState};
use sctk::seat::pointer::ThemedPointer;
use sctk::seat::SeatState;
use sctk::shell::wlr_layer::{LayerShell, LayerShellHandler, LayerSurface, LayerSurfaceConfigure};
use sctk::shell::xdg::window::{Window, WindowConfigure, WindowHandler};
use sctk::shell::xdg::XdgShell;
use sctk::shell::WaylandSurface;
Expand Down Expand Up @@ -63,6 +64,9 @@ pub struct WinitState {
/// The XDG shell that is used for windows.
pub xdg_shell: XdgShell,

/// The layer shell for layer surfaces
pub layer_shell: LayerShell,

/// The currently present windows.
pub windows: RefCell<AHashMap<WindowId, Arc<Mutex<WindowState>>>>,

Expand Down Expand Up @@ -170,6 +174,8 @@ impl WinitState {
xdg_shell: XdgShell::bind(globals, queue_handle).map_err(WaylandError::Bind)?,
xdg_activation: XdgActivationState::bind(globals, queue_handle).ok(),

layer_shell: LayerShell::bind(globals, queue_handle).map_err(WaylandError::Bind)?,

windows: Default::default(),
window_requests: Default::default(),
window_compositor_updates: Vec::new(),
Expand Down Expand Up @@ -306,6 +312,42 @@ impl WindowHandler for WinitState {
}
}

impl LayerShellHandler for WinitState {
fn closed(&mut self, _: &Connection, _: &QueueHandle<Self>, layer: &LayerSurface) {
let window_id = super::make_wid(layer.wl_surface());
Self::queue_close(&mut self.window_compositor_updates, window_id);
}
fn configure(
&mut self,
_: &Connection,
_: &QueueHandle<Self>,
layer: &LayerSurface,
configure: LayerSurfaceConfigure,
_serial: u32,
) {
let window_id = super::make_wid(layer.wl_surface());
let pos = if let Some(pos) =
self.window_compositor_updates.iter().position(|update| update.window_id == window_id)
{
pos
} else {
self.window_compositor_updates.push(WindowCompositorUpdate::new(window_id));
self.window_compositor_updates.len() - 1
};
// Populate the configure to the window.
//
// XXX the size on the window will be updated right before dispatching the size to the user.
self.windows
.get_mut()
.get_mut(&window_id)
.expect("got configure for dead window.")
.lock()
.unwrap()
.configure_layer(configure);
self.window_compositor_updates[pos].resized = true;
}
}

impl OutputHandler for WinitState {
fn output_state(&mut self) -> &mut OutputState {
&mut self.output_state
Expand Down Expand Up @@ -433,3 +475,4 @@ sctk::delegate_registry!(WinitState);
sctk::delegate_shm!(WinitState);
sctk::delegate_xdg_shell!(WinitState);
sctk::delegate_xdg_window!(WinitState);
sctk::delegate_layer!(WinitState);
Loading

0 comments on commit 414f09d

Please sign in to comment.