Skip to content

Commit 414f09d

Browse files
committed
changes based on rust-windowing#4044
1 parent 114512b commit 414f09d

File tree

7 files changed

+757
-228
lines changed

7 files changed

+757
-228
lines changed

src/platform/wayland.rs

+50-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
//! * `wayland-csd-adwaita` (default).
1414
//! * `wayland-csd-adwaita-crossfont`.
1515
//! * `wayland-csd-adwaita-notitle`.
16+
use sctk::shell::wlr_layer::{Anchor, KeyboardInteractivity, Layer};
17+
use crate::dpi::{LogicalPosition, LogicalSize};
1618
use crate::event_loop::{ActiveEventLoop, EventLoop, EventLoopBuilder};
1719
use crate::monitor::MonitorHandle;
1820
use crate::window::{Window, WindowAttributes};
@@ -85,7 +87,15 @@ pub trait WindowAttributesExtWayland {
8587
///
8688
/// For details about application ID conventions, see the
8789
/// [Desktop Entry Spec](https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#desktop-file-id)
88-
fn with_name(self, general: impl Into<String>, instance: impl Into<String>) -> Self;
90+
fn with_name(self, general: impl Into<String>, instance: impl Into<String>) -> Self; fn with_anchor(self, anchor: Anchor) -> Self;
91+
fn with_exclusive_zone(self, exclusive_zone: i32) -> Self;
92+
fn with_margin(self, top: i32, right: i32, bottom: i32, left: i32) -> Self;
93+
fn with_keyboard_interactivity(self, keyboard_interactivity: KeyboardInteractivity) -> Self;
94+
fn with_layer(self, layer: Layer) -> Self;
95+
#[cfg(wayland_platform)]
96+
fn with_region(self, position: LogicalPosition<i32>, size: LogicalSize<i32>) -> Self;
97+
#[cfg(wayland_platform)]
98+
fn with_output(self, output: u32) -> Self;
8999
}
90100

91101
impl WindowAttributesExtWayland for WindowAttributes {
@@ -95,6 +105,45 @@ impl WindowAttributesExtWayland for WindowAttributes {
95105
Some(crate::platform_impl::ApplicationName::new(general.into(), instance.into()));
96106
self
97107
}
108+
fn with_anchor(mut self, anchor: Anchor) -> Self {
109+
self.platform_specific.wayland.anchor = Some(anchor);
110+
self
111+
}
112+
#[inline]
113+
fn with_exclusive_zone(mut self, exclusive_zone: i32) -> Self {
114+
self.platform_specific.wayland.exclusive_zone = Some(exclusive_zone);
115+
self
116+
}
117+
#[inline]
118+
fn with_margin(mut self, top: i32, right: i32, bottom: i32, left: i32) -> Self {
119+
self.platform_specific.wayland.margin = Some((top, right, bottom, left));
120+
self
121+
}
122+
#[inline]
123+
fn with_keyboard_interactivity(
124+
mut self,
125+
keyboard_interactivity: KeyboardInteractivity,
126+
) -> Self {
127+
self.platform_specific.wayland.keyboard_interactivity = Some(keyboard_interactivity);
128+
self
129+
}
130+
#[inline]
131+
fn with_layer(mut self, layer: Layer) -> Self {
132+
self.platform_specific.wayland.layer = Some(layer);
133+
self
134+
}
135+
#[inline]
136+
#[cfg(wayland_platform)]
137+
fn with_region(mut self, position: LogicalPosition<i32>, size: LogicalSize<i32>) -> Self {
138+
self.platform_specific.wayland.region = Some((position, size));
139+
self
140+
}
141+
#[inline]
142+
#[cfg(wayland_platform)]
143+
fn with_output(mut self, output: u32) -> Self {
144+
self.platform_specific.wayland.output = Some(output);
145+
self
146+
}
98147
}
99148

100149
/// Additional methods on `MonitorHandle` that are specific to Wayland.

src/platform_impl/linux/mod.rs

+26
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#[cfg(all(not(x11_platform), not(wayland_platform)))]
44
compile_error!("Please select a feature to build for unix: `x11`, `wayland`");
55

6+
use dpi::{LogicalPosition, LogicalSize};
7+
use sctk::shell::wlr_layer::{Anchor, KeyboardInteractivity, Layer};
68
use std::collections::VecDeque;
79
use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, RawFd};
810
use std::sync::Arc;
@@ -75,6 +77,8 @@ pub struct PlatformSpecificWindowAttributes {
7577
pub activation_token: Option<ActivationToken>,
7678
#[cfg(x11_platform)]
7779
pub x11: X11WindowAttributes,
80+
#[cfg(wayland_platform)]
81+
pub wayland: WaylandWindowAttributes,
7882
}
7983

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

97+
#[derive(Clone, Debug, PartialEq)]
98+
#[cfg(wayland_platform)]
99+
pub struct WaylandWindowAttributes {
100+
pub layer: Option<Layer>,
101+
pub anchor: Option<Anchor>,
102+
pub output: Option<u32>,
103+
pub region: Option<(LogicalPosition<i32>, LogicalSize<i32>)>,
104+
pub exclusive_zone: Option<i32>,
105+
pub margin: Option<(i32, i32, i32, i32)>,
106+
pub keyboard_interactivity: Option<KeyboardInteractivity>,
107+
}
108+
93109
#[cfg_attr(not(x11_platform), allow(clippy::derivable_impls))]
94110
impl Default for PlatformSpecificWindowAttributes {
95111
fn default() -> Self {
@@ -105,6 +121,16 @@ impl Default for PlatformSpecificWindowAttributes {
105121
x11_window_types: vec![XWindowType::Normal],
106122
embed_window: None,
107123
},
124+
#[cfg(wayland_platform)]
125+
wayland: WaylandWindowAttributes {
126+
layer: None,
127+
margin: None,
128+
anchor: None,
129+
output: None,
130+
region: None,
131+
exclusive_zone: None,
132+
keyboard_interactivity: None,
133+
},
108134
}
109135
}
110136
}

src/platform_impl/linux/wayland/output.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,18 @@ impl MonitorHandle {
9292
#[inline]
9393
pub fn video_modes(&self) -> impl Iterator<Item = PlatformVideoModeHandle> {
9494
let output_data = self.proxy.data::<OutputData>().unwrap();
95-
let modes = output_data.with_output_info(|info| info.modes.clone());
95+
// let modes = output_data.with_output_info(|info| info.modes.clone());
96+
let (size, modes) =
97+
output_data.with_output_info(|info| (info.logical_size, info.modes.clone()));
9698

9799
let monitor = self.clone();
98100

99101
modes.into_iter().map(move |mode| {
100102
PlatformVideoModeHandle::Wayland(VideoModeHandle {
101-
size: (mode.dimensions.0 as u32, mode.dimensions.1 as u32).into(),
103+
size: size
104+
.map(|(x, y)| (x as u32, y as u32))
105+
.unwrap_or_else(|| (mode.dimensions.0 as u32, mode.dimensions.1 as u32))
106+
.into(),
102107
refresh_rate_millihertz: mode.refresh_rate as u32,
103108
bit_depth: 32,
104109
monitor: monitor.clone(),

src/platform_impl/linux/wayland/state.rs

+43
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use sctk::output::{OutputHandler, OutputState};
1616
use sctk::registry::{ProvidesRegistryState, RegistryState};
1717
use sctk::seat::pointer::ThemedPointer;
1818
use sctk::seat::SeatState;
19+
use sctk::shell::wlr_layer::{LayerShell, LayerShellHandler, LayerSurface, LayerSurfaceConfigure};
1920
use sctk::shell::xdg::window::{Window, WindowConfigure, WindowHandler};
2021
use sctk::shell::xdg::XdgShell;
2122
use sctk::shell::WaylandSurface;
@@ -63,6 +64,9 @@ pub struct WinitState {
6364
/// The XDG shell that is used for windows.
6465
pub xdg_shell: XdgShell,
6566

67+
/// The layer shell for layer surfaces
68+
pub layer_shell: LayerShell,
69+
6670
/// The currently present windows.
6771
pub windows: RefCell<AHashMap<WindowId, Arc<Mutex<WindowState>>>>,
6872

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

177+
layer_shell: LayerShell::bind(globals, queue_handle).map_err(WaylandError::Bind)?,
178+
173179
windows: Default::default(),
174180
window_requests: Default::default(),
175181
window_compositor_updates: Vec::new(),
@@ -306,6 +312,42 @@ impl WindowHandler for WinitState {
306312
}
307313
}
308314

315+
impl LayerShellHandler for WinitState {
316+
fn closed(&mut self, _: &Connection, _: &QueueHandle<Self>, layer: &LayerSurface) {
317+
let window_id = super::make_wid(layer.wl_surface());
318+
Self::queue_close(&mut self.window_compositor_updates, window_id);
319+
}
320+
fn configure(
321+
&mut self,
322+
_: &Connection,
323+
_: &QueueHandle<Self>,
324+
layer: &LayerSurface,
325+
configure: LayerSurfaceConfigure,
326+
_serial: u32,
327+
) {
328+
let window_id = super::make_wid(layer.wl_surface());
329+
let pos = if let Some(pos) =
330+
self.window_compositor_updates.iter().position(|update| update.window_id == window_id)
331+
{
332+
pos
333+
} else {
334+
self.window_compositor_updates.push(WindowCompositorUpdate::new(window_id));
335+
self.window_compositor_updates.len() - 1
336+
};
337+
// Populate the configure to the window.
338+
//
339+
// XXX the size on the window will be updated right before dispatching the size to the user.
340+
self.windows
341+
.get_mut()
342+
.get_mut(&window_id)
343+
.expect("got configure for dead window.")
344+
.lock()
345+
.unwrap()
346+
.configure_layer(configure);
347+
self.window_compositor_updates[pos].resized = true;
348+
}
349+
}
350+
309351
impl OutputHandler for WinitState {
310352
fn output_state(&mut self) -> &mut OutputState {
311353
&mut self.output_state
@@ -433,3 +475,4 @@ sctk::delegate_registry!(WinitState);
433475
sctk::delegate_shm!(WinitState);
434476
sctk::delegate_xdg_shell!(WinitState);
435477
sctk::delegate_xdg_window!(WinitState);
478+
sctk::delegate_layer!(WinitState);

0 commit comments

Comments
 (0)