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)]
|
#[derive(Clone, Debug, PartialEq, CosmicConfigEntry)]
|
||||||
#[version = 1]
|
#[version = 1]
|
||||||
pub struct CosmicCompConfig {
|
pub struct CosmicCompConfig {
|
||||||
|
|
@ -104,6 +111,7 @@ pub struct CosmicCompConfig {
|
||||||
/// Briefly magnify the cursor when the pointer is shaken, to help locate it
|
/// Briefly magnify the cursor when the pointer is shaken, to help locate it
|
||||||
pub cursor_shake_to_find: bool,
|
pub cursor_shake_to_find: bool,
|
||||||
pub activation_policy: ActivationPolicy,
|
pub activation_policy: ActivationPolicy,
|
||||||
|
pub decoration_preference: DecorationPreference,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for CosmicCompConfig {
|
impl Default for CosmicCompConfig {
|
||||||
|
|
@ -143,6 +151,7 @@ impl Default for CosmicCompConfig {
|
||||||
cursor_hide_timeout: None,
|
cursor_hide_timeout: None,
|
||||||
cursor_shake_to_find: true,
|
cursor_shake_to_find: true,
|
||||||
activation_policy: ActivationPolicy::default(),
|
activation_policy: ActivationPolicy::default(),
|
||||||
|
decoration_preference: DecorationPreference::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,8 @@ mod types;
|
||||||
use cosmic::config::CosmicTk;
|
use cosmic::config::CosmicTk;
|
||||||
pub use cosmic_comp_config::EdidProduct;
|
pub use cosmic_comp_config::EdidProduct;
|
||||||
use cosmic_comp_config::{
|
use cosmic_comp_config::{
|
||||||
ActivationPolicy, AppearanceConfig, CosmicCompConfig, KeyboardConfig, TileBehavior, XkbConfig,
|
ActivationPolicy, AppearanceConfig, CosmicCompConfig, DecorationPreference, KeyboardConfig,
|
||||||
XwaylandDescaling, XwaylandEavesdropping, ZoomConfig,
|
TileBehavior, XkbConfig, XwaylandDescaling, XwaylandEavesdropping, ZoomConfig,
|
||||||
input::{DeviceState as InputDeviceState, InputConfig, TouchpadOverride},
|
input::{DeviceState as InputDeviceState, InputConfig, TouchpadOverride},
|
||||||
output::comp::{
|
output::comp::{
|
||||||
OutputConfig, OutputInfo, OutputState, OutputsConfig, TransformDef, load_outputs,
|
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;
|
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 std::{cell::RefCell, sync::Mutex};
|
||||||
|
|
||||||
|
use cosmic_comp_config::DecorationPreference;
|
||||||
use smithay::{
|
use smithay::{
|
||||||
desktop::Window,
|
desktop::Window,
|
||||||
reexports::{
|
reexports::{
|
||||||
|
|
@ -20,7 +21,7 @@ use smithay::{
|
||||||
};
|
};
|
||||||
use wayland_backend::protocol::WEnum;
|
use wayland_backend::protocol::WEnum;
|
||||||
|
|
||||||
use crate::state::State;
|
use crate::{shell::CosmicMapped, state::State};
|
||||||
|
|
||||||
pub struct PreferredDecorationMode(RefCell<Option<XdgMode>>);
|
pub struct PreferredDecorationMode(RefCell<Option<XdgMode>>);
|
||||||
|
|
||||||
|
|
@ -29,7 +30,7 @@ impl PreferredDecorationMode {
|
||||||
window
|
window
|
||||||
.user_data()
|
.user_data()
|
||||||
.get::<PreferredDecorationMode>()
|
.get::<PreferredDecorationMode>()
|
||||||
.is_none()
|
.is_none_or(|mode| mode.0.borrow().is_none())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mode(window: &Window) -> Option<XdgMode> {
|
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>;
|
pub type KdeDecorationData = Mutex<KdeDecorationSurfaceState>;
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct KdeDecorationSurfaceState {
|
pub struct KdeDecorationSurfaceState {
|
||||||
|
|
@ -67,7 +135,7 @@ impl XdgDecorationHandler for State {
|
||||||
let mode = if mapped.is_stack() {
|
let mode = if mapped.is_stack() {
|
||||||
XdgMode::ServerSide
|
XdgMode::ServerSide
|
||||||
} else {
|
} else {
|
||||||
XdgMode::ClientSide
|
XdgMode::from_preference(self.default_decoration())
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some((window, _)) = mapped
|
if let Some((window, _)) = mapped
|
||||||
|
|
@ -80,6 +148,10 @@ impl XdgDecorationHandler for State {
|
||||||
});
|
});
|
||||||
toplevel.send_configure();
|
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 {
|
} else {
|
||||||
toplevel.with_pending_state(|state| state.decoration_mode = Some(mode));
|
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()))
|
.find(|(window, _)| window.wl_surface().as_deref() == Some(toplevel.wl_surface()))
|
||||||
&& let Some(toplevel) = window.0.toplevel()
|
&& 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);
|
PreferredDecorationMode::update(&window.0, None);
|
||||||
toplevel.with_pending_state(|state| {
|
toplevel.with_pending_state(|state| {
|
||||||
state.decoration_mode = None;
|
state.decoration_mode = Some(mode);
|
||||||
});
|
});
|
||||||
toplevel.send_configure();
|
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() {
|
if mapped.is_stack() {
|
||||||
KdeMode::Server
|
KdeMode::Server
|
||||||
} else {
|
} else {
|
||||||
KdeMode::Client
|
KdeMode::from_preference(self.default_decoration())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
KdeMode::Client
|
KdeMode::from_preference(self.default_decoration())
|
||||||
};
|
};
|
||||||
|
|
||||||
with_states(surface, |states| {
|
with_states(surface, |states| {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue