wayland/decoration: Make default decoration mode configurable
This commit is contained in:
parent
a830784f11
commit
b407ed560a
3 changed files with 120 additions and 8 deletions
|
|
@ -66,6 +66,13 @@ impl Default for AppearanceConfig {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum DecorationPreference {
|
||||
#[default]
|
||||
ClientSide,
|
||||
ServerSide,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, CosmicConfigEntry)]
|
||||
#[version = 1]
|
||||
pub struct CosmicCompConfig {
|
||||
|
|
@ -104,6 +111,7 @@ pub struct CosmicCompConfig {
|
|||
/// Briefly magnify the cursor when the pointer is shaken, to help locate it
|
||||
pub cursor_shake_to_find: bool,
|
||||
pub activation_policy: ActivationPolicy,
|
||||
pub decoration_preference: DecorationPreference,
|
||||
}
|
||||
|
||||
impl Default for CosmicCompConfig {
|
||||
|
|
@ -143,6 +151,7 @@ impl Default for CosmicCompConfig {
|
|||
cursor_hide_timeout: None,
|
||||
cursor_shake_to_find: true,
|
||||
activation_policy: ActivationPolicy::default(),
|
||||
decoration_preference: DecorationPreference::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,8 +49,8 @@ mod types;
|
|||
use cosmic::config::CosmicTk;
|
||||
pub use cosmic_comp_config::EdidProduct;
|
||||
use cosmic_comp_config::{
|
||||
ActivationPolicy, AppearanceConfig, CosmicCompConfig, KeyboardConfig, TileBehavior, XkbConfig,
|
||||
XwaylandDescaling, XwaylandEavesdropping, ZoomConfig,
|
||||
ActivationPolicy, AppearanceConfig, CosmicCompConfig, DecorationPreference, KeyboardConfig,
|
||||
TileBehavior, XkbConfig, XwaylandDescaling, XwaylandEavesdropping, ZoomConfig,
|
||||
input::{DeviceState as InputDeviceState, InputConfig, TouchpadOverride},
|
||||
output::comp::{
|
||||
OutputConfig, OutputInfo, OutputState, OutputsConfig, TransformDef, load_outputs,
|
||||
|
|
@ -1000,6 +1000,13 @@ fn config_changed(config: cosmic_config::Config, keys: Vec<String>, state: &mut
|
|||
state.common.config.cosmic_conf.activation_policy = new;
|
||||
}
|
||||
}
|
||||
"decoration_preference" => {
|
||||
let new = get_config::<DecorationPreference>(&config, "decoration_preference");
|
||||
if new != state.common.config.cosmic_conf.decoration_preference {
|
||||
state.common.config.cosmic_conf.decoration_preference = new;
|
||||
state.update_decorations();
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use std::{cell::RefCell, sync::Mutex};
|
||||
|
||||
use cosmic_comp_config::DecorationPreference;
|
||||
use smithay::{
|
||||
desktop::Window,
|
||||
reexports::{
|
||||
|
|
@ -20,7 +21,7 @@ use smithay::{
|
|||
};
|
||||
use wayland_backend::protocol::WEnum;
|
||||
|
||||
use crate::state::State;
|
||||
use crate::{shell::CosmicMapped, state::State};
|
||||
|
||||
pub struct PreferredDecorationMode(RefCell<Option<XdgMode>>);
|
||||
|
||||
|
|
@ -29,7 +30,7 @@ impl PreferredDecorationMode {
|
|||
window
|
||||
.user_data()
|
||||
.get::<PreferredDecorationMode>()
|
||||
.is_none()
|
||||
.is_none_or(|mode| mode.0.borrow().is_none())
|
||||
}
|
||||
|
||||
pub fn mode(window: &Window) -> Option<XdgMode> {
|
||||
|
|
@ -53,6 +54,73 @@ impl PreferredDecorationMode {
|
|||
}
|
||||
}
|
||||
|
||||
impl State {
|
||||
pub fn default_decoration(&self) -> DecorationPreference {
|
||||
self.common.config.cosmic_conf.decoration_preference
|
||||
}
|
||||
|
||||
pub fn update_decorations(&self) {
|
||||
let shell = self.common.shell.read();
|
||||
|
||||
let update = |mapped: &CosmicMapped| {
|
||||
let mode = if mapped.is_stack() {
|
||||
XdgMode::ServerSide
|
||||
} else {
|
||||
XdgMode::from_preference(self.default_decoration())
|
||||
};
|
||||
for (window, _) in mapped.windows() {
|
||||
if PreferredDecorationMode::is_unset(&window.0) {
|
||||
if let Some(toplevel) = window.0.toplevel() {
|
||||
if toplevel.with_committed_state(|state| {
|
||||
state.is_some_and(|state| state.decoration_mode.is_some())
|
||||
}) {
|
||||
toplevel.with_pending_state(|state| {
|
||||
state.decoration_mode = Some(mode);
|
||||
});
|
||||
toplevel.send_configure();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for set in shell.workspaces.sets.values() {
|
||||
set.sticky_layer.mapped().for_each(update);
|
||||
}
|
||||
|
||||
for space in shell.workspaces.spaces() {
|
||||
space.mapped().for_each(update);
|
||||
space
|
||||
.minimized_windows
|
||||
.iter()
|
||||
.filter_map(|m| m.mapped())
|
||||
.for_each(update);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait FromDecorationPreference {
|
||||
fn from_preference(preference: DecorationPreference) -> Self;
|
||||
}
|
||||
|
||||
impl FromDecorationPreference for XdgMode {
|
||||
fn from_preference(preference: DecorationPreference) -> Self {
|
||||
match preference {
|
||||
DecorationPreference::ClientSide => XdgMode::ClientSide,
|
||||
DecorationPreference::ServerSide => XdgMode::ServerSide,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromDecorationPreference for KdeMode {
|
||||
fn from_preference(preference: DecorationPreference) -> Self {
|
||||
match preference {
|
||||
DecorationPreference::ClientSide => KdeMode::Client,
|
||||
DecorationPreference::ServerSide => KdeMode::Server,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type KdeDecorationData = Mutex<KdeDecorationSurfaceState>;
|
||||
#[derive(Debug, Default)]
|
||||
pub struct KdeDecorationSurfaceState {
|
||||
|
|
@ -67,7 +135,7 @@ impl XdgDecorationHandler for State {
|
|||
let mode = if mapped.is_stack() {
|
||||
XdgMode::ServerSide
|
||||
} else {
|
||||
XdgMode::ClientSide
|
||||
XdgMode::from_preference(self.default_decoration())
|
||||
};
|
||||
|
||||
if let Some((window, _)) = mapped
|
||||
|
|
@ -80,6 +148,10 @@ impl XdgDecorationHandler for State {
|
|||
});
|
||||
toplevel.send_configure();
|
||||
}
|
||||
} else {
|
||||
toplevel.with_pending_state(|state| {
|
||||
state.decoration_mode = Some(XdgMode::from_preference(self.default_decoration()))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -99,6 +171,13 @@ impl XdgDecorationHandler for State {
|
|||
}
|
||||
} else {
|
||||
toplevel.with_pending_state(|state| state.decoration_mode = Some(mode));
|
||||
if let Some(pending) = shell
|
||||
.pending_windows
|
||||
.iter()
|
||||
.find(|pending| pending.surface.0.toplevel().is_some_and(|t| t == &toplevel))
|
||||
{
|
||||
PreferredDecorationMode::update(&pending.surface.0, Some(mode));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -110,11 +189,28 @@ impl XdgDecorationHandler for State {
|
|||
.find(|(window, _)| window.wl_surface().as_deref() == Some(toplevel.wl_surface()))
|
||||
&& let Some(toplevel) = window.0.toplevel()
|
||||
{
|
||||
let mode = if mapped.is_stack() {
|
||||
XdgMode::ServerSide
|
||||
} else {
|
||||
XdgMode::from_preference(self.default_decoration())
|
||||
};
|
||||
|
||||
PreferredDecorationMode::update(&window.0, None);
|
||||
toplevel.with_pending_state(|state| {
|
||||
state.decoration_mode = None;
|
||||
state.decoration_mode = Some(mode);
|
||||
});
|
||||
toplevel.send_configure();
|
||||
} else {
|
||||
toplevel.with_pending_state(|state| {
|
||||
state.decoration_mode = Some(XdgMode::from_preference(self.default_decoration()))
|
||||
});
|
||||
if let Some(pending) = shell
|
||||
.pending_windows
|
||||
.iter()
|
||||
.find(|pending| pending.surface.0.toplevel().is_some_and(|t| t == &toplevel))
|
||||
{
|
||||
PreferredDecorationMode::update(&pending.surface.0, None);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -129,10 +225,10 @@ impl KdeDecorationHandler for State {
|
|||
if mapped.is_stack() {
|
||||
KdeMode::Server
|
||||
} else {
|
||||
KdeMode::Client
|
||||
KdeMode::from_preference(self.default_decoration())
|
||||
}
|
||||
} else {
|
||||
KdeMode::Client
|
||||
KdeMode::from_preference(self.default_decoration())
|
||||
};
|
||||
|
||||
with_states(surface, |states| {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue