wayland/decorations: Fix early requests with kde-protocol
This commit is contained in:
parent
359c3ad899
commit
c5708cd607
2 changed files with 80 additions and 9 deletions
|
|
@ -33,6 +33,7 @@ use smithay::{
|
||||||
shell::server::xdg_toplevel::State as ToplevelState,
|
shell::server::xdg_toplevel::State as ToplevelState,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
wayland_protocols_misc::server_decoration::server::org_kde_kwin_server_decoration::Mode as KdeMode,
|
||||||
wayland_server::protocol::wl_surface::WlSurface,
|
wayland_server::protocol::wl_surface::WlSurface,
|
||||||
},
|
},
|
||||||
utils::{
|
utils::{
|
||||||
|
|
@ -50,7 +51,7 @@ use tracing::trace;
|
||||||
use crate::{
|
use crate::{
|
||||||
state::{State, SurfaceDmabufFeedback},
|
state::{State, SurfaceDmabufFeedback},
|
||||||
utils::prelude::*,
|
utils::prelude::*,
|
||||||
wayland::handlers::decoration::PreferredDecorationMode,
|
wayland::handlers::decoration::{KdeDecorationData, PreferredDecorationMode},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
|
@ -216,20 +217,29 @@ impl CosmicSurface {
|
||||||
pub fn is_decorated(&self, pending: bool) -> bool {
|
pub fn is_decorated(&self, pending: bool) -> bool {
|
||||||
match self.0.underlying_surface() {
|
match self.0.underlying_surface() {
|
||||||
WindowSurface::Wayland(toplevel) => {
|
WindowSurface::Wayland(toplevel) => {
|
||||||
if pending {
|
let xdg_state = if pending {
|
||||||
toplevel.with_pending_state(|pending| {
|
toplevel.with_pending_state(|pending| {
|
||||||
pending
|
pending
|
||||||
.decoration_mode
|
.decoration_mode
|
||||||
.map(|mode| mode == DecorationMode::ClientSide)
|
.map(|mode| mode == DecorationMode::ClientSide)
|
||||||
.unwrap_or(true)
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
toplevel
|
toplevel
|
||||||
.current_state()
|
.current_state()
|
||||||
.decoration_mode
|
.decoration_mode
|
||||||
.map(|mode| mode == DecorationMode::ClientSide)
|
.map(|mode| mode == DecorationMode::ClientSide)
|
||||||
.unwrap_or(true)
|
};
|
||||||
}
|
|
||||||
|
xdg_state
|
||||||
|
.or_else(|| {
|
||||||
|
with_states(toplevel.wl_surface(), |states| {
|
||||||
|
states
|
||||||
|
.data_map
|
||||||
|
.get::<KdeDecorationData>()
|
||||||
|
.map(|data| data.lock().unwrap().mode != KdeMode::Server)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.unwrap_or(true)
|
||||||
}
|
}
|
||||||
WindowSurface::X11(surface) => surface.is_decorated(),
|
WindowSurface::X11(surface) => surface.is_decorated(),
|
||||||
}
|
}
|
||||||
|
|
@ -247,11 +257,25 @@ impl CosmicSurface {
|
||||||
toplevel.with_pending_state(|pending| {
|
toplevel.with_pending_state(|pending| {
|
||||||
pending.decoration_mode = Some(DecorationMode::ServerSide);
|
pending.decoration_mode = Some(DecorationMode::ServerSide);
|
||||||
});
|
});
|
||||||
|
with_states(toplevel.wl_surface(), |data| {
|
||||||
|
if let Some(kde_data) = data.data_map.get::<KdeDecorationData>() {
|
||||||
|
for obj in kde_data.lock().unwrap().objs.iter() {
|
||||||
|
obj.mode(KdeMode::Server);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
let previous_mode = PreferredDecorationMode::mode(&self.0);
|
let previous_mode = PreferredDecorationMode::mode(&self.0);
|
||||||
toplevel.with_pending_state(|pending| {
|
toplevel.with_pending_state(|pending| {
|
||||||
pending.decoration_mode = previous_mode;
|
pending.decoration_mode = previous_mode;
|
||||||
});
|
});
|
||||||
|
with_states(toplevel.wl_surface(), |data| {
|
||||||
|
if let Some(kde_data) = data.data_map.get::<KdeDecorationData>() {
|
||||||
|
for obj in kde_data.lock().unwrap().objs.iter() {
|
||||||
|
obj.mode(KdeMode::Server);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WindowSurface::X11(_surface) => {}
|
WindowSurface::X11(_surface) => {}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use std::cell::RefCell;
|
use std::{cell::RefCell, sync::Mutex};
|
||||||
|
|
||||||
use smithay::{
|
use smithay::{
|
||||||
delegate_kde_decoration, delegate_xdg_decoration,
|
delegate_kde_decoration, delegate_xdg_decoration,
|
||||||
|
|
@ -11,6 +11,7 @@ use smithay::{
|
||||||
wayland_server::protocol::wl_surface::WlSurface,
|
wayland_server::protocol::wl_surface::WlSurface,
|
||||||
},
|
},
|
||||||
wayland::{
|
wayland::{
|
||||||
|
compositor::with_states,
|
||||||
seat::WaylandFocus,
|
seat::WaylandFocus,
|
||||||
shell::{
|
shell::{
|
||||||
kde::decoration::{KdeDecorationHandler, KdeDecorationState},
|
kde::decoration::{KdeDecorationHandler, KdeDecorationState},
|
||||||
|
|
@ -54,6 +55,22 @@ impl PreferredDecorationMode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type KdeDecorationData = Mutex<KdeDecorationSurfaceState>;
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct KdeDecorationSurfaceState {
|
||||||
|
pub mode: KdeMode,
|
||||||
|
pub objs: Vec<OrgKdeKwinServerDecoration>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for KdeDecorationSurfaceState {
|
||||||
|
fn default() -> Self {
|
||||||
|
KdeDecorationSurfaceState {
|
||||||
|
mode: KdeMode::Client,
|
||||||
|
objs: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new_decoration(mapped: &CosmicMapped, surface: &WlSurface) -> KdeMode {
|
pub fn new_decoration(mapped: &CosmicMapped, surface: &WlSurface) -> KdeMode {
|
||||||
if mapped.is_stack() {
|
if mapped.is_stack() {
|
||||||
if let Some((window, _)) = mapped
|
if let Some((window, _)) = mapped
|
||||||
|
|
@ -143,10 +160,22 @@ impl KdeDecorationHandler for State {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_decoration(&mut self, surface: &WlSurface, decoration: &OrgKdeKwinServerDecoration) {
|
fn new_decoration(&mut self, surface: &WlSurface, decoration: &OrgKdeKwinServerDecoration) {
|
||||||
|
with_states(surface, |states| {
|
||||||
|
states
|
||||||
|
.data_map
|
||||||
|
.get_or_insert::<KdeDecorationData, _>(Default::default)
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.objs
|
||||||
|
.push(decoration.clone())
|
||||||
|
});
|
||||||
|
|
||||||
let shell = self.common.shell.read();
|
let shell = self.common.shell.read();
|
||||||
if let Some(mapped) = shell.element_for_surface(surface) {
|
if let Some(mapped) = shell.element_for_surface(surface) {
|
||||||
let mode = new_decoration(mapped, surface);
|
let mode = new_decoration(mapped, surface);
|
||||||
decoration.mode(mode);
|
decoration.mode(mode);
|
||||||
|
} else {
|
||||||
|
decoration.mode(KdeMode::Client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -157,8 +186,16 @@ impl KdeDecorationHandler for State {
|
||||||
mode: WEnum<KdeMode>,
|
mode: WEnum<KdeMode>,
|
||||||
) {
|
) {
|
||||||
if let WEnum::Value(mode) = mode {
|
if let WEnum::Value(mode) = mode {
|
||||||
|
with_states(surface, |states| {
|
||||||
|
states
|
||||||
|
.data_map
|
||||||
|
.get_or_insert::<KdeDecorationData, _>(Default::default)
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.mode = mode
|
||||||
|
});
|
||||||
|
|
||||||
let shell = self.common.shell.read();
|
let shell = self.common.shell.read();
|
||||||
// TODO: We need to store this value until it gets mapped and apply it then, if it is not mapped yet.
|
|
||||||
if let Some(mapped) = shell.element_for_surface(surface) {
|
if let Some(mapped) = shell.element_for_surface(surface) {
|
||||||
request_mode(
|
request_mode(
|
||||||
mapped,
|
mapped,
|
||||||
|
|
@ -168,12 +205,22 @@ impl KdeDecorationHandler for State {
|
||||||
_ => XdgMode::ClientSide,
|
_ => XdgMode::ClientSide,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
decoration.mode(mode);
|
|
||||||
}
|
}
|
||||||
|
decoration.mode(mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn release(&mut self, _decoration: &OrgKdeKwinServerDecoration, surface: &WlSurface) {
|
fn release(&mut self, decoration: &OrgKdeKwinServerDecoration, surface: &WlSurface) {
|
||||||
|
with_states(surface, |states| {
|
||||||
|
states
|
||||||
|
.data_map
|
||||||
|
.get_or_insert::<KdeDecorationData, _>(Default::default)
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.objs
|
||||||
|
.retain(|obj| obj != decoration);
|
||||||
|
});
|
||||||
|
|
||||||
let shell = self.common.shell.read();
|
let shell = self.common.shell.read();
|
||||||
if let Some(mapped) = shell.element_for_surface(surface) {
|
if let Some(mapped) = shell.element_for_surface(surface) {
|
||||||
unset_mode(mapped, surface)
|
unset_mode(mapped, surface)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue