From 2e70cb7b4609303622184afdbaac3b02d90fca97 Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Fri, 14 Jun 2024 21:40:41 +0300 Subject: [PATCH] Handle KDE decorations in Mapped::has_ssd This fixes an issue with default CSD border being drawn for SSD rendering firefox, because only xdg decorations were checked. --- src/handlers/mod.rs | 1 + src/handlers/xdg_shell.rs | 39 ++++++++++++++++++++++++++++++++++++++- src/window/mapped.rs | 18 ++++++++++++++++-- 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index 74be4df..845faf0 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -62,6 +62,7 @@ use smithay::{ delegate_virtual_keyboard_manager, delegate_xdg_activation, }; +pub use crate::handlers::xdg_shell::KdeDecorationsModeState; use crate::niri::{ClientState, State}; use crate::protocols::foreign_toplevel::{ self, ForeignToplevelHandler, ForeignToplevelManagerState, diff --git a/src/handlers/xdg_shell.rs b/src/handlers/xdg_shell.rs index 3e6234f..30b2f5d 100644 --- a/src/handlers/xdg_shell.rs +++ b/src/handlers/xdg_shell.rs @@ -1,3 +1,5 @@ +use std::cell::Cell; + use smithay::desktop::{ find_popup_root_surface, get_popup_toplevel_coords, layer_map_for_output, utils, LayerSurface, PopupKeyboardGrab, PopupKind, PopupManager, PopupPointerGrab, PopupUngrabStrategy, Window, @@ -8,10 +10,11 @@ use smithay::output::Output; use smithay::reexports::wayland_protocols::xdg::decoration::zv1::server::zxdg_toplevel_decoration_v1; use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_positioner::ConstraintAdjustment; use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel::{self}; +use smithay::reexports::wayland_protocols_misc::server_decoration::server::org_kde_kwin_server_decoration; 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::reexports::wayland_server::Resource; +use smithay::reexports::wayland_server::{self, Resource, WEnum}; use smithay::utils::{Logical, Rectangle, Serial}; use smithay::wayland::compositor::{ add_pre_commit_hook, with_states, BufferAssignment, HookId, SurfaceAttributes, @@ -544,10 +547,44 @@ impl XdgDecorationHandler for State { } delegate_xdg_decoration!(State); +/// Whether KDE server decorations are in use. +#[derive(Default)] +pub struct KdeDecorationsModeState { + server: Cell, +} + +impl KdeDecorationsModeState { + pub fn is_server(&self) -> bool { + self.server.get() + } +} + impl KdeDecorationHandler for State { fn kde_decoration_state(&self) -> &KdeDecorationState { &self.niri.kde_decoration_state } + + fn request_mode( + &mut self, + surface: &WlSurface, + decoration: &org_kde_kwin_server_decoration::OrgKdeKwinServerDecoration, + mode: wayland_server::WEnum, + ) { + let WEnum::Value(mode) = mode else { + return; + }; + + decoration.mode(mode); + + with_states(surface, |states| { + let state = states + .data_map + .get_or_insert(KdeDecorationsModeState::default); + state + .server + .set(mode == org_kde_kwin_server_decoration::Mode::Server); + }); + } } delegate_kde_decoration!(State); diff --git a/src/window/mapped.rs b/src/window/mapped.rs index 6db13ad..ae5204e 100644 --- a/src/window/mapped.rs +++ b/src/window/mapped.rs @@ -17,6 +17,7 @@ use smithay::wayland::compositor::{remove_pre_commit_hook, with_states, HookId}; use smithay::wayland::shell::xdg::{SurfaceCachedState, ToplevelSurface}; use super::{ResolvedWindowRules, WindowRef}; +use crate::handlers::KdeDecorationsModeState; use crate::layout::{ InteractiveResizeData, LayoutElement, LayoutElementRenderElement, LayoutElementRenderSnapshot, }; @@ -422,8 +423,21 @@ impl LayoutElement for Mapped { } fn has_ssd(&self) -> bool { - self.toplevel().current_state().decoration_mode - == Some(zxdg_toplevel_decoration_v1::Mode::ServerSide) + let toplevel = self.toplevel(); + let mode = toplevel.current_state().decoration_mode; + + match mode { + Some(zxdg_toplevel_decoration_v1::Mode::ServerSide) => true, + // Check KDE decorations when XDG are not in use. + None => with_states(toplevel.wl_surface(), |states| { + states + .data_map + .get::() + .map(KdeDecorationsModeState::is_server) + == Some(true) + }), + _ => false, + } } fn output_enter(&self, output: &Output) {