Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support to wlr_layer_shell #4044

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions src/platform/wayland.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
//! * `wayland-csd-adwaita` (default).
//! * `wayland-csd-adwaita-crossfont`.
//! * `wayland-csd-adwaita-notitle`.
#[cfg(wayland_platform)]
use sctk::shell::wlr_layer::{Anchor, KeyboardInteractivity, Layer};

use crate::event_loop::{ActiveEventLoop, EventLoop, EventLoopBuilder};
use crate::monitor::MonitorHandle;
pub use crate::window::Theme;
Expand Down Expand Up @@ -87,6 +90,21 @@ 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;

#[cfg(wayland_platform)]
fn with_anchor(self, anchor: Anchor) -> Self;

#[cfg(wayland_platform)]
fn with_exclusive_zone(self, exclusive_zone: i32) -> Self;

#[cfg(wayland_platform)]
fn with_margin(self, top: i32, right: i32, bottom: i32, left: i32) -> Self;

#[cfg(wayland_platform)]
fn with_keyboard_interactivity(self, keyboard_interactivity: KeyboardInteractivity) -> Self;

#[cfg(wayland_platform)]
fn with_layer(self, layer: Layer) -> Self;
}

impl WindowAttributesExtWayland for WindowAttributes {
Expand All @@ -96,6 +114,44 @@ impl WindowAttributesExtWayland for WindowAttributes {
Some(crate::platform_impl::ApplicationName::new(general.into(), instance.into()));
self
}

#[inline]
#[cfg(wayland_platform)]
fn with_anchor(mut self, anchor: Anchor) -> Self {
self.platform_specific.wayland.anchor = Some(anchor);
self
}

#[inline]
#[cfg(wayland_platform)]
fn with_exclusive_zone(mut self, exclusive_zone: i32) -> Self {
self.platform_specific.wayland.exclusive_zone = Some(exclusive_zone);
self
}

#[inline]
#[cfg(wayland_platform)]
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]
#[cfg(wayland_platform)]
fn with_keyboard_interactivity(
mut self,
keyboard_interactivity: KeyboardInteractivity,
) -> Self {
self.platform_specific.wayland.keyboard_interactivity = Some(keyboard_interactivity);
self
}

#[inline]
#[cfg(wayland_platform)]
fn with_layer(mut self, layer: Layer) -> Self {
self.platform_specific.wayland.layer = Some(layer);
self
}
}

/// Additional methods on `MonitorHandle` that are specific to Wayland.
Expand Down
21 changes: 21 additions & 0 deletions src/platform_impl/linux/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use std::time::Duration;
#[cfg(x11_platform)]
use std::{ffi::CStr, mem::MaybeUninit, os::raw::*, sync::Arc, sync::Mutex};

use sctk::shell::wlr_layer::{Anchor, KeyboardInteractivity, Layer};
use smol_str::SmolStr;

pub(crate) use self::common::xkb::{physicalkey_to_scancode, scancode_to_physicalkey};
Expand Down Expand Up @@ -69,6 +70,8 @@ pub struct PlatformSpecificWindowAttributes {
pub activation_token: Option<ActivationToken>,
#[cfg(x11_platform)]
pub x11: X11WindowAttributes,
#[cfg(wayland_platform)]
pub wayland: WaylandWindowAttributes,
}

#[derive(Clone, Debug, PartialEq)]
Expand All @@ -84,6 +87,16 @@ 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 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 @@ -99,6 +112,14 @@ impl Default for PlatformSpecificWindowAttributes {
x11_window_types: vec![XWindowType::Normal],
embed_window: None,
},
#[cfg(wayland_platform)]
wayland: WaylandWindowAttributes {
layer: None,
margin: None,
anchor: None,
exclusive_zone: None,
keyboard_interactivity: None,
},
}
}
}
Expand Down
47 changes: 47 additions & 0 deletions src/platform_impl/linux/wayland/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use sctk::reexports::client::{Connection, Proxy, QueueHandle};
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 @@ -61,6 +62,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 @@ -171,6 +175,8 @@ impl WinitState {
xdg_shell: XdgShell::bind(globals, queue_handle).map_err(|err| os_error!(err))?,
xdg_activation: XdgActivationState::bind(globals, queue_handle).ok(),

layer_shell: LayerShell::bind(globals, queue_handle).map_err(|err| os_error!(err))?,

windows: Default::default(),
window_requests: Default::default(),
window_compositor_updates: Vec::new(),
Expand Down Expand Up @@ -308,6 +314,46 @@ 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 @@ -435,3 +481,4 @@ sctk::delegate_registry!(WinitState);
sctk::delegate_shm!(WinitState);
sctk::delegate_xdg_shell!(WinitState);
sctk::delegate_xdg_window!(WinitState);
sctk::delegate_layer!(WinitState);
Loading
Loading