Skip to content

Commit

Permalink
On Wayland, make wl_subcompositor protocol optional
Browse files Browse the repository at this point in the history
This protocol is only used for (optional) Client Side Decorations
(where) the compositor still takes the burden of compositing various
window parts together, via subsurfaces that all belong to a single
window.

If this core protocol is not available, as is the case on gamescope,
disable CSD.
  • Loading branch information
MarijnS95 authored and kchibisov committed Dec 21, 2023
1 parent 5011a67 commit 8c4a6dd
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -16,6 +16,7 @@ Unreleased` header.
misinterpreted during a drag and drop operation.
- On X11, fix a bug where focusing the window would panic.
- On macOS, fix `refresh_rate_millihertz`.
- On Wayland, disable Client Side Decorations when `wl_subcompositor` is not supported.

# 0.29.4

Expand Down
15 changes: 10 additions & 5 deletions src/platform_impl/linux/wayland/state.rs
Expand Up @@ -50,7 +50,7 @@ pub struct WinitState {
pub compositor_state: Arc<CompositorState>,

/// The state of the subcompositor.
pub subcompositor_state: Arc<SubcompositorState>,
pub subcompositor_state: Option<Arc<SubcompositorState>>,

/// The seat state responsible for all sorts of input.
pub seat_state: SeatState,
Expand Down Expand Up @@ -124,12 +124,17 @@ impl WinitState {
let registry_state = RegistryState::new(globals);
let compositor_state =
CompositorState::bind(globals, queue_handle).map_err(WaylandError::Bind)?;
let subcompositor_state = SubcompositorState::bind(
let subcompositor_state = match SubcompositorState::bind(
compositor_state.wl_compositor().clone(),
globals,
queue_handle,
)
.map_err(WaylandError::Bind)?;
) {
Ok(c) => Some(c),
Err(e) => {
warn!("Subcompositor protocol not available, ignoring CSD: {e:?}");
None
}
};

let output_state = OutputState::new(globals, queue_handle);
let monitors = output_state.outputs().map(MonitorHandle::new).collect();
Expand All @@ -151,7 +156,7 @@ impl WinitState {
Ok(Self {
registry_state,
compositor_state: Arc::new(compositor_state),
subcompositor_state: Arc::new(subcompositor_state),
subcompositor_state: subcompositor_state.map(Arc::new),
output_state,
seat_state,
shm: Shm::bind(globals, queue_handle).map_err(WaylandError::Bind)?,
Expand Down
11 changes: 6 additions & 5 deletions src/platform_impl/linux/wayland/window/state.rs
Expand Up @@ -254,7 +254,7 @@ impl WindowState {
&mut self,
configure: WindowConfigure,
shm: &Shm,
subcompositor: &Arc<SubcompositorState>,
subcompositor: &Option<Arc<SubcompositorState>>,
event_sink: &mut EventSink,
) -> LogicalSize<u32> {
// NOTE: when using fractional scaling or wl_compositor@v6 the scaling
Expand All @@ -265,10 +265,11 @@ impl WindowState {
self.stateless_size = self.size;
}

if configure.decoration_mode == DecorationMode::Client
&& self.frame.is_none()
&& !self.csd_fails
{
if let Some(subcompositor) = subcompositor.as_ref().filter(|_| {
configure.decoration_mode == DecorationMode::Client
&& self.frame.is_none()
&& !self.csd_fails
}) {
match WinitFrame::new(
&self.window,
shm,
Expand Down

0 comments on commit 8c4a6dd

Please sign in to comment.