wayland/decorations: Fix xdg-decoration state always shadowing kde-decorations
This commit is contained in:
parent
c5708cd607
commit
b5e60fcde5
2 changed files with 81 additions and 110 deletions
|
|
@ -217,6 +217,13 @@ 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) => {
|
||||||
|
let kde_state = with_states(toplevel.wl_surface(), |states| {
|
||||||
|
states
|
||||||
|
.data_map
|
||||||
|
.get::<KdeDecorationData>()
|
||||||
|
.and_then(|data| data.lock().unwrap().mode.map(|m| m != KdeMode::Server))
|
||||||
|
});
|
||||||
|
|
||||||
let xdg_state = if pending {
|
let xdg_state = if pending {
|
||||||
toplevel.with_pending_state(|pending| {
|
toplevel.with_pending_state(|pending| {
|
||||||
pending
|
pending
|
||||||
|
|
@ -230,16 +237,7 @@ impl CosmicSurface {
|
||||||
.map(|mode| mode == DecorationMode::ClientSide)
|
.map(|mode| mode == DecorationMode::ClientSide)
|
||||||
};
|
};
|
||||||
|
|
||||||
xdg_state
|
kde_state.or(xdg_state).unwrap_or(true)
|
||||||
.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(),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ use smithay::{
|
||||||
};
|
};
|
||||||
use wayland_backend::protocol::WEnum;
|
use wayland_backend::protocol::WEnum;
|
||||||
|
|
||||||
use crate::{shell::CosmicMapped, state::State};
|
use crate::state::State;
|
||||||
|
|
||||||
pub struct PreferredDecorationMode(RefCell<Option<XdgMode>>);
|
pub struct PreferredDecorationMode(RefCell<Option<XdgMode>>);
|
||||||
|
|
||||||
|
|
@ -58,89 +58,58 @@ impl PreferredDecorationMode {
|
||||||
pub type KdeDecorationData = Mutex<KdeDecorationSurfaceState>;
|
pub type KdeDecorationData = Mutex<KdeDecorationSurfaceState>;
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct KdeDecorationSurfaceState {
|
pub struct KdeDecorationSurfaceState {
|
||||||
pub mode: KdeMode,
|
pub mode: Option<KdeMode>,
|
||||||
pub objs: Vec<OrgKdeKwinServerDecoration>,
|
pub objs: Vec<OrgKdeKwinServerDecoration>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for KdeDecorationSurfaceState {
|
impl Default for KdeDecorationSurfaceState {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
KdeDecorationSurfaceState {
|
KdeDecorationSurfaceState {
|
||||||
mode: KdeMode::Client,
|
mode: None,
|
||||||
objs: Vec::new(),
|
objs: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_decoration(mapped: &CosmicMapped, surface: &WlSurface) -> KdeMode {
|
|
||||||
if mapped.is_stack() {
|
|
||||||
if let Some((window, _)) = mapped
|
|
||||||
.windows()
|
|
||||||
.find(|(window, _)| window.wl_surface().as_deref() == Some(surface))
|
|
||||||
{
|
|
||||||
if let Some(toplevel) = window.0.toplevel() {
|
|
||||||
toplevel
|
|
||||||
.with_pending_state(|state| state.decoration_mode = Some(XdgMode::ServerSide));
|
|
||||||
toplevel.send_configure();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
KdeMode::Server
|
|
||||||
} else {
|
|
||||||
if let Some((window, _)) = mapped
|
|
||||||
.windows()
|
|
||||||
.find(|(window, _)| window.wl_surface().as_deref() == Some(surface))
|
|
||||||
{
|
|
||||||
if let Some(toplevel) = window.0.toplevel() {
|
|
||||||
toplevel
|
|
||||||
.with_pending_state(|state| state.decoration_mode = Some(XdgMode::ClientSide));
|
|
||||||
toplevel.send_configure();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
KdeMode::Client
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn request_mode(mapped: &CosmicMapped, surface: &WlSurface, mode: XdgMode) {
|
|
||||||
if let Some((window, _)) = mapped
|
|
||||||
.windows()
|
|
||||||
.find(|(window, _)| window.wl_surface().as_deref() == Some(surface))
|
|
||||||
{
|
|
||||||
if let Some(toplevel) = window.0.toplevel() {
|
|
||||||
PreferredDecorationMode::update(&window.0, Some(mode));
|
|
||||||
toplevel.with_pending_state(|state| {
|
|
||||||
state.decoration_mode = Some(mode);
|
|
||||||
});
|
|
||||||
toplevel.send_configure();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn unset_mode(mapped: &CosmicMapped, surface: &WlSurface) {
|
|
||||||
if let Some((window, _)) = mapped
|
|
||||||
.windows()
|
|
||||||
.find(|(window, _)| window.wl_surface().as_deref() == Some(surface))
|
|
||||||
{
|
|
||||||
if let Some(toplevel) = window.0.toplevel() {
|
|
||||||
PreferredDecorationMode::update(&window.0, None);
|
|
||||||
toplevel.with_pending_state(|state| {
|
|
||||||
state.decoration_mode = None;
|
|
||||||
});
|
|
||||||
toplevel.send_configure();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl XdgDecorationHandler for State {
|
impl XdgDecorationHandler for State {
|
||||||
fn new_decoration(&mut self, toplevel: ToplevelSurface) {
|
fn new_decoration(&mut self, toplevel: ToplevelSurface) {
|
||||||
let shell = self.common.shell.read();
|
let shell = self.common.shell.read();
|
||||||
if let Some(mapped) = shell.element_for_surface(toplevel.wl_surface()) {
|
if let Some(mapped) = shell.element_for_surface(toplevel.wl_surface()) {
|
||||||
new_decoration(mapped, toplevel.wl_surface());
|
let mode = if mapped.is_stack() {
|
||||||
|
XdgMode::ServerSide
|
||||||
|
} else {
|
||||||
|
XdgMode::ClientSide
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some((window, _)) = mapped
|
||||||
|
.windows()
|
||||||
|
.find(|(window, _)| window.wl_surface().as_deref() == Some(toplevel.wl_surface()))
|
||||||
|
{
|
||||||
|
if let Some(toplevel) = window.0.toplevel() {
|
||||||
|
toplevel.with_pending_state(|state| {
|
||||||
|
state.decoration_mode = Some(mode);
|
||||||
|
});
|
||||||
|
toplevel.send_configure();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn request_mode(&mut self, toplevel: ToplevelSurface, mode: XdgMode) {
|
fn request_mode(&mut self, toplevel: ToplevelSurface, mode: XdgMode) {
|
||||||
let shell = self.common.shell.read();
|
let shell = self.common.shell.read();
|
||||||
if let Some(mapped) = shell.element_for_surface(toplevel.wl_surface()) {
|
if let Some(mapped) = shell.element_for_surface(toplevel.wl_surface()) {
|
||||||
request_mode(mapped, toplevel.wl_surface(), mode);
|
if let Some((window, _)) = mapped
|
||||||
|
.windows()
|
||||||
|
.find(|(window, _)| window.wl_surface().as_deref() == Some(toplevel.wl_surface()))
|
||||||
|
{
|
||||||
|
if let Some(toplevel) = window.0.toplevel() {
|
||||||
|
PreferredDecorationMode::update(&window.0, Some(mode));
|
||||||
|
toplevel.with_pending_state(|state| {
|
||||||
|
state.decoration_mode = Some(mode);
|
||||||
|
});
|
||||||
|
toplevel.send_configure();
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
toplevel.with_pending_state(|state| state.decoration_mode = Some(mode));
|
toplevel.with_pending_state(|state| state.decoration_mode = Some(mode));
|
||||||
}
|
}
|
||||||
|
|
@ -149,7 +118,18 @@ impl XdgDecorationHandler for State {
|
||||||
fn unset_mode(&mut self, toplevel: ToplevelSurface) {
|
fn unset_mode(&mut self, toplevel: ToplevelSurface) {
|
||||||
let shell = self.common.shell.read();
|
let shell = self.common.shell.read();
|
||||||
if let Some(mapped) = shell.element_for_surface(toplevel.wl_surface()) {
|
if let Some(mapped) = shell.element_for_surface(toplevel.wl_surface()) {
|
||||||
unset_mode(mapped, toplevel.wl_surface())
|
if let Some((window, _)) = mapped
|
||||||
|
.windows()
|
||||||
|
.find(|(window, _)| window.wl_surface().as_deref() == Some(toplevel.wl_surface()))
|
||||||
|
{
|
||||||
|
if let Some(toplevel) = window.0.toplevel() {
|
||||||
|
PreferredDecorationMode::update(&window.0, None);
|
||||||
|
toplevel.with_pending_state(|state| {
|
||||||
|
state.decoration_mode = None;
|
||||||
|
});
|
||||||
|
toplevel.send_configure();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -160,23 +140,30 @@ impl KdeDecorationHandler for State {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_decoration(&mut self, surface: &WlSurface, decoration: &OrgKdeKwinServerDecoration) {
|
fn new_decoration(&mut self, surface: &WlSurface, decoration: &OrgKdeKwinServerDecoration) {
|
||||||
|
let mode = if let Some(mapped) = self.common.shell.read().element_for_surface(surface) {
|
||||||
|
if mapped.is_stack() {
|
||||||
|
KdeMode::Server
|
||||||
|
} else {
|
||||||
|
KdeMode::Client
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
KdeMode::Client
|
||||||
|
};
|
||||||
|
|
||||||
with_states(surface, |states| {
|
with_states(surface, |states| {
|
||||||
states
|
let mut state = states
|
||||||
.data_map
|
.data_map
|
||||||
.get_or_insert::<KdeDecorationData, _>(Default::default)
|
.get_or_insert_threadsafe::<KdeDecorationData, _>(Default::default)
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap();
|
||||||
.objs
|
|
||||||
.push(decoration.clone())
|
state.objs.push(decoration.clone());
|
||||||
|
if state.mode.is_none() {
|
||||||
|
state.mode = Some(mode)
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let shell = self.common.shell.read();
|
decoration.mode(mode);
|
||||||
if let Some(mapped) = shell.element_for_surface(surface) {
|
|
||||||
let mode = new_decoration(mapped, surface);
|
|
||||||
decoration.mode(mode);
|
|
||||||
} else {
|
|
||||||
decoration.mode(KdeMode::Client);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn request_mode(
|
fn request_mode(
|
||||||
|
|
@ -189,42 +176,28 @@ impl KdeDecorationHandler for State {
|
||||||
with_states(surface, |states| {
|
with_states(surface, |states| {
|
||||||
states
|
states
|
||||||
.data_map
|
.data_map
|
||||||
.get_or_insert::<KdeDecorationData, _>(Default::default)
|
.get_or_insert_threadsafe::<KdeDecorationData, _>(Default::default)
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.mode = mode
|
.mode = Some(mode);
|
||||||
});
|
});
|
||||||
|
|
||||||
let shell = self.common.shell.read();
|
|
||||||
if let Some(mapped) = shell.element_for_surface(surface) {
|
|
||||||
request_mode(
|
|
||||||
mapped,
|
|
||||||
surface,
|
|
||||||
match mode {
|
|
||||||
KdeMode::Server => XdgMode::ServerSide,
|
|
||||||
_ => 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| {
|
with_states(surface, |states| {
|
||||||
states
|
let mut state = states
|
||||||
.data_map
|
.data_map
|
||||||
.get_or_insert::<KdeDecorationData, _>(Default::default)
|
.get_or_insert_threadsafe::<KdeDecorationData, _>(Default::default)
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap();
|
||||||
.objs
|
|
||||||
.retain(|obj| obj != decoration);
|
|
||||||
});
|
|
||||||
|
|
||||||
let shell = self.common.shell.read();
|
state.objs.retain(|obj| obj != decoration);
|
||||||
if let Some(mapped) = shell.element_for_surface(surface) {
|
if state.objs.is_empty() {
|
||||||
unset_mode(mapped, surface)
|
state.mode.take();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue