feat: theme integration
refactor: only apply updates if there is a change in the theme refactor: include theme in state cleanup: theme integration
This commit is contained in:
parent
c16b86d1bf
commit
abbe94e6e1
24 changed files with 409 additions and 139 deletions
30
Cargo.lock
generated
30
Cargo.lock
generated
|
|
@ -576,7 +576,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cosmic-config"
|
name = "cosmic-config"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic/?rev=f91287d#f91287dec2297df41a339c1106850c4cf179f67f"
|
source = "git+https://github.com/pop-os/libcosmic/?branch=theme-dark-light-switching#0a63eaaff3091796e5f59ed0598f7b0616066e78"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atomicwrites",
|
"atomicwrites",
|
||||||
"calloop 0.12.2",
|
"calloop 0.12.2",
|
||||||
|
|
@ -591,7 +591,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cosmic-config-derive"
|
name = "cosmic-config-derive"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic/?rev=f91287d#f91287dec2297df41a339c1106850c4cf179f67f"
|
source = "git+https://github.com/pop-os/libcosmic/?branch=theme-dark-light-switching#0a63eaaff3091796e5f59ed0598f7b0616066e78"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
"syn 1.0.109",
|
"syn 1.0.109",
|
||||||
|
|
@ -632,7 +632,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cosmic-theme"
|
name = "cosmic-theme"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic/?rev=f91287d#f91287dec2297df41a339c1106850c4cf179f67f"
|
source = "git+https://github.com/pop-os/libcosmic/?branch=theme-dark-light-switching#0a63eaaff3091796e5f59ed0598f7b0616066e78"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"almost",
|
"almost",
|
||||||
"cosmic-config",
|
"cosmic-config",
|
||||||
|
|
@ -1801,7 +1801,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced"
|
name = "iced"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic/?rev=f91287d#f91287dec2297df41a339c1106850c4cf179f67f"
|
source = "git+https://github.com/pop-os/libcosmic/?branch=theme-dark-light-switching#0a63eaaff3091796e5f59ed0598f7b0616066e78"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"iced_core",
|
"iced_core",
|
||||||
"iced_futures",
|
"iced_futures",
|
||||||
|
|
@ -1814,7 +1814,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_core"
|
name = "iced_core"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic/?rev=f91287d#f91287dec2297df41a339c1106850c4cf179f67f"
|
source = "git+https://github.com/pop-os/libcosmic/?branch=theme-dark-light-switching#0a63eaaff3091796e5f59ed0598f7b0616066e78"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"instant",
|
"instant",
|
||||||
|
|
@ -1827,7 +1827,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_futures"
|
name = "iced_futures"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic/?rev=f91287d#f91287dec2297df41a339c1106850c4cf179f67f"
|
source = "git+https://github.com/pop-os/libcosmic/?branch=theme-dark-light-switching#0a63eaaff3091796e5f59ed0598f7b0616066e78"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures",
|
"futures",
|
||||||
"iced_core",
|
"iced_core",
|
||||||
|
|
@ -1839,7 +1839,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_graphics"
|
name = "iced_graphics"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic/?rev=f91287d#f91287dec2297df41a339c1106850c4cf179f67f"
|
source = "git+https://github.com/pop-os/libcosmic/?branch=theme-dark-light-switching#0a63eaaff3091796e5f59ed0598f7b0616066e78"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
|
|
@ -1857,7 +1857,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_renderer"
|
name = "iced_renderer"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic/?rev=f91287d#f91287dec2297df41a339c1106850c4cf179f67f"
|
source = "git+https://github.com/pop-os/libcosmic/?branch=theme-dark-light-switching#0a63eaaff3091796e5f59ed0598f7b0616066e78"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"iced_graphics",
|
"iced_graphics",
|
||||||
"iced_tiny_skia",
|
"iced_tiny_skia",
|
||||||
|
|
@ -1870,7 +1870,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_runtime"
|
name = "iced_runtime"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
source = "git+https://github.com/pop-os/libcosmic/?rev=f91287d#f91287dec2297df41a339c1106850c4cf179f67f"
|
source = "git+https://github.com/pop-os/libcosmic/?branch=theme-dark-light-switching#0a63eaaff3091796e5f59ed0598f7b0616066e78"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"iced_core",
|
"iced_core",
|
||||||
"iced_futures",
|
"iced_futures",
|
||||||
|
|
@ -1880,7 +1880,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_style"
|
name = "iced_style"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic/?rev=f91287d#f91287dec2297df41a339c1106850c4cf179f67f"
|
source = "git+https://github.com/pop-os/libcosmic/?branch=theme-dark-light-switching#0a63eaaff3091796e5f59ed0598f7b0616066e78"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"iced_core",
|
"iced_core",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
|
@ -1890,7 +1890,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_tiny_skia"
|
name = "iced_tiny_skia"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic/?rev=f91287d#f91287dec2297df41a339c1106850c4cf179f67f"
|
source = "git+https://github.com/pop-os/libcosmic/?branch=theme-dark-light-switching#0a63eaaff3091796e5f59ed0598f7b0616066e78"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"cosmic-text",
|
"cosmic-text",
|
||||||
|
|
@ -1908,7 +1908,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_wgpu"
|
name = "iced_wgpu"
|
||||||
version = "0.11.1"
|
version = "0.11.1"
|
||||||
source = "git+https://github.com/pop-os/libcosmic/?rev=f91287d#f91287dec2297df41a339c1106850c4cf179f67f"
|
source = "git+https://github.com/pop-os/libcosmic/?branch=theme-dark-light-switching#0a63eaaff3091796e5f59ed0598f7b0616066e78"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
|
|
@ -1930,7 +1930,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_widget"
|
name = "iced_widget"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
source = "git+https://github.com/pop-os/libcosmic/?rev=f91287d#f91287dec2297df41a339c1106850c4cf179f67f"
|
source = "git+https://github.com/pop-os/libcosmic/?branch=theme-dark-light-switching#0a63eaaff3091796e5f59ed0598f7b0616066e78"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"iced_renderer",
|
"iced_renderer",
|
||||||
"iced_runtime",
|
"iced_runtime",
|
||||||
|
|
@ -2242,7 +2242,7 @@ checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libcosmic"
|
name = "libcosmic"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic/?rev=f91287d#f91287dec2297df41a339c1106850c4cf179f67f"
|
source = "git+https://github.com/pop-os/libcosmic/?branch=theme-dark-light-switching#0a63eaaff3091796e5f59ed0598f7b0616066e78"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"apply",
|
"apply",
|
||||||
"cosmic-config",
|
"cosmic-config",
|
||||||
|
|
@ -4126,7 +4126,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "taffy"
|
name = "taffy"
|
||||||
version = "0.3.11"
|
version = "0.3.11"
|
||||||
source = "git+https://github.com/DioxusLabs/taffy#120bb7a2e501822b324fd48de955450ebbba1c1a"
|
source = "git+https://github.com/DioxusLabs/taffy?rev=65bedf#65bedf128ec8cef40c1a21b6f141f2c771842cca"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"grid",
|
"grid",
|
||||||
|
|
|
||||||
|
|
@ -36,10 +36,10 @@ libsystemd = { version = "0.6", optional = true }
|
||||||
wayland-backend = "0.3.2"
|
wayland-backend = "0.3.2"
|
||||||
wayland-scanner = "0.31.0"
|
wayland-scanner = "0.31.0"
|
||||||
cosmic-comp-config = { path = "cosmic-comp-config" }
|
cosmic-comp-config = { path = "cosmic-comp-config" }
|
||||||
cosmic-config = { git = "https://github.com/pop-os/libcosmic/", rev = "f91287d", features = ["calloop"] }
|
cosmic-config = { git = "https://github.com/pop-os/libcosmic/", features = ["calloop", "macro"], branch = "theme-dark-light-switching"}
|
||||||
cosmic-protocols = { git = "https://github.com/pop-os/cosmic-protocols", branch = "main", default-features = false, features = ["server"] }
|
cosmic-protocols = { git = "https://github.com/pop-os/cosmic-protocols", branch = "main", default-features = false, features = ["server"] }
|
||||||
libcosmic = { git = "https://github.com/pop-os/libcosmic/", rev = "f91287d", default-features = false }
|
libcosmic = { git = "https://github.com/pop-os/libcosmic/", default-features = false, branch = "theme-dark-light-switching" }
|
||||||
iced_tiny_skia = { git = "https://github.com/pop-os/libcosmic/", rev = "f91287d" }
|
iced_tiny_skia = { git = "https://github.com/pop-os/libcosmic/", branch = "theme-dark-light-switching" }
|
||||||
tiny-skia = "0.10"
|
tiny-skia = "0.10"
|
||||||
ordered-float = "4.0"
|
ordered-float = "4.0"
|
||||||
glow = "0.12.0"
|
glow = "0.12.0"
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
use crate::backend::render::element::AsGlowRenderer;
|
use crate::backend::render::element::AsGlowRenderer;
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::render::{workspace_elements, CLEAR_COLOR},
|
backend::render::workspace_elements,
|
||||||
config::OutputConfig,
|
config::OutputConfig,
|
||||||
shell::Shell,
|
shell::Shell,
|
||||||
state::{BackendData, ClientState, Common, Fps, SurfaceDmabufFeedback},
|
state::{BackendData, ClientState, Common, Fps, SurfaceDmabufFeedback},
|
||||||
|
|
@ -1241,8 +1241,12 @@ impl Surface {
|
||||||
})?;
|
})?;
|
||||||
self.fps.elements();
|
self.fps.elements();
|
||||||
|
|
||||||
let res =
|
let theme = state.theme.cosmic();
|
||||||
compositor.render_frame::<_, _, GlesTexture>(&mut renderer, &elements, CLEAR_COLOR);
|
let res = compositor.render_frame::<_, _, GlesTexture>(
|
||||||
|
&mut renderer,
|
||||||
|
&elements,
|
||||||
|
crate::theme::clear_color(&theme),
|
||||||
|
);
|
||||||
self.fps.render();
|
self.fps.render();
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
|
|
|
||||||
|
|
@ -78,11 +78,6 @@ pub type GlMultiFrame<'a, 'b, 'frame> =
|
||||||
MultiFrame<'a, 'a, 'b, 'frame, GbmGlesBackend<GlowRenderer>, GbmGlesBackend<GlowRenderer>>;
|
MultiFrame<'a, 'a, 'b, 'frame, GbmGlesBackend<GlowRenderer>, GbmGlesBackend<GlowRenderer>>;
|
||||||
pub type GlMultiError = MultiError<GbmGlesBackend<GlowRenderer>, GbmGlesBackend<GlowRenderer>>;
|
pub type GlMultiError = MultiError<GbmGlesBackend<GlowRenderer>, GbmGlesBackend<GlowRenderer>>;
|
||||||
|
|
||||||
pub static CLEAR_COLOR: [f32; 4] = [0.153, 0.161, 0.165, 1.0];
|
|
||||||
pub static GROUP_COLOR: [f32; 3] = [0.788, 0.788, 0.788];
|
|
||||||
pub static ACTIVE_GROUP_COLOR: [f32; 3] = [0.58, 0.922, 0.922];
|
|
||||||
pub static FOCUS_INDICATOR_COLOR: [f32; 3] = [0.580, 0.921, 0.921];
|
|
||||||
|
|
||||||
pub static OUTLINE_SHADER: &str = include_str!("./shaders/rounded_outline.frag");
|
pub static OUTLINE_SHADER: &str = include_str!("./shaders/rounded_outline.frag");
|
||||||
pub static RECTANGLE_SHADER: &str = include_str!("./shaders/rounded_rectangle.frag");
|
pub static RECTANGLE_SHADER: &str = include_str!("./shaders/rounded_rectangle.frag");
|
||||||
|
|
||||||
|
|
@ -164,6 +159,7 @@ impl IndicatorShader {
|
||||||
thickness: u8,
|
thickness: u8,
|
||||||
scale: f64,
|
scale: f64,
|
||||||
alpha: f32,
|
alpha: f32,
|
||||||
|
active_window_hint: [f32; 3],
|
||||||
) -> PixelShaderElement {
|
) -> PixelShaderElement {
|
||||||
let t = thickness as i32;
|
let t = thickness as i32;
|
||||||
element_geo.loc -= (t, t).into();
|
element_geo.loc -= (t, t).into();
|
||||||
|
|
@ -177,7 +173,7 @@ impl IndicatorShader {
|
||||||
thickness * 2,
|
thickness * 2,
|
||||||
alpha,
|
alpha,
|
||||||
scale,
|
scale,
|
||||||
FOCUS_INDICATOR_COLOR,
|
active_window_hint,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -413,13 +409,14 @@ where
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let theme = state.theme.cosmic();
|
||||||
if let Some(grab_elements) = seat
|
if let Some(grab_elements) = seat
|
||||||
.user_data()
|
.user_data()
|
||||||
.get::<SeatMoveGrabState>()
|
.get::<SeatMoveGrabState>()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.borrow()
|
.borrow()
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|state| state.render::<E, R>(renderer, seat, output))
|
.map(|state| state.render::<E, R>(renderer, seat, output, theme))
|
||||||
{
|
{
|
||||||
elements.extend(grab_elements);
|
elements.extend(grab_elements);
|
||||||
}
|
}
|
||||||
|
|
@ -449,6 +446,7 @@ where
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
puffin::profile_function!();
|
puffin::profile_function!();
|
||||||
|
|
||||||
|
let theme = state.theme.cosmic();
|
||||||
let mut elements = cursor_elements(renderer, state, output, cursor_mode);
|
let mut elements = cursor_elements(renderer, state, output, cursor_mode);
|
||||||
|
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
|
|
@ -544,6 +542,7 @@ where
|
||||||
} else {
|
} else {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
};
|
};
|
||||||
|
let active_hint = theme.active_hint as u8;
|
||||||
|
|
||||||
let offset = match previous.as_ref() {
|
let offset = match previous.as_ref() {
|
||||||
Some((previous, previous_idx, start)) => {
|
Some((previous, previous_idx, start)) => {
|
||||||
|
|
@ -584,7 +583,8 @@ where
|
||||||
(!move_active && is_active_space).then_some(&last_active_seat),
|
(!move_active && is_active_space).then_some(&last_active_seat),
|
||||||
overview.clone(),
|
overview.clone(),
|
||||||
resize_indicator.clone(),
|
resize_indicator.clone(),
|
||||||
state.config.static_conf.active_hint,
|
active_hint,
|
||||||
|
theme,
|
||||||
)
|
)
|
||||||
.map_err(|_| OutputNoMode)?;
|
.map_err(|_| OutputNoMode)?;
|
||||||
elements.extend(p_elements.into_iter().map(|p_element| {
|
elements.extend(p_elements.into_iter().map(|p_element| {
|
||||||
|
|
@ -641,7 +641,8 @@ where
|
||||||
(!move_active && is_active_space).then_some(&last_active_seat),
|
(!move_active && is_active_space).then_some(&last_active_seat),
|
||||||
overview,
|
overview,
|
||||||
resize_indicator,
|
resize_indicator,
|
||||||
state.config.static_conf.active_hint,
|
active_hint,
|
||||||
|
theme,
|
||||||
)
|
)
|
||||||
.map_err(|_| OutputNoMode)?;
|
.map_err(|_| OutputNoMode)?;
|
||||||
elements.extend(p_elements.into_iter().map(|p_element| {
|
elements.extend(p_elements.into_iter().map(|p_element| {
|
||||||
|
|
@ -913,7 +914,12 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer.bind(target).map_err(RenderError::Rendering)?;
|
renderer.bind(target).map_err(RenderError::Rendering)?;
|
||||||
let res = damage_tracker.render_output(renderer, age, &elements, CLEAR_COLOR);
|
let res = damage_tracker.render_output(
|
||||||
|
renderer,
|
||||||
|
age,
|
||||||
|
&elements,
|
||||||
|
crate::theme::clear_color(state.theme.cosmic()),
|
||||||
|
);
|
||||||
|
|
||||||
if let Some(fps) = fps.as_mut() {
|
if let Some(fps) = fps.as_mut() {
|
||||||
fps.render();
|
fps.render();
|
||||||
|
|
|
||||||
|
|
@ -50,10 +50,6 @@ pub struct StaticConfig {
|
||||||
#[serde(default = "default_workspace_layout")]
|
#[serde(default = "default_workspace_layout")]
|
||||||
pub workspace_layout: WorkspaceLayout,
|
pub workspace_layout: WorkspaceLayout,
|
||||||
pub tiling_enabled: bool,
|
pub tiling_enabled: bool,
|
||||||
#[serde(default = "default_active_hint")]
|
|
||||||
pub active_hint: u8,
|
|
||||||
#[serde(default = "default_gaps")]
|
|
||||||
pub gaps: (u8, u8),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Deserialize, Clone, Copy, PartialEq, Eq)]
|
||||||
|
|
@ -100,14 +96,6 @@ fn default_enabled() -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_active_hint() -> u8 {
|
|
||||||
4
|
|
||||||
}
|
|
||||||
|
|
||||||
fn default_gaps() -> (u8, u8) {
|
|
||||||
(0, 4)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn default_workspace_layout() -> WorkspaceLayout {
|
fn default_workspace_layout() -> WorkspaceLayout {
|
||||||
WorkspaceLayout::Vertical
|
WorkspaceLayout::Vertical
|
||||||
}
|
}
|
||||||
|
|
@ -219,8 +207,6 @@ impl Config {
|
||||||
workspace_amount: WorkspaceAmount::Dynamic,
|
workspace_amount: WorkspaceAmount::Dynamic,
|
||||||
workspace_layout: WorkspaceLayout::Vertical,
|
workspace_layout: WorkspaceLayout::Vertical,
|
||||||
tiling_enabled: false,
|
tiling_enabled: false,
|
||||||
active_hint: default_active_hint(),
|
|
||||||
gaps: default_gaps(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -214,7 +214,6 @@ impl State {
|
||||||
<B as InputBackend>::PointerAxisEvent: 'static,
|
<B as InputBackend>::PointerAxisEvent: 'static,
|
||||||
{
|
{
|
||||||
use smithay::backend::input::Event;
|
use smithay::backend::input::Event;
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
InputEvent::DeviceAdded { device } => {
|
InputEvent::DeviceAdded { device } => {
|
||||||
let seat = &mut self.common.last_active_seat();
|
let seat = &mut self.common.last_active_seat();
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ pub mod shell;
|
||||||
pub mod state;
|
pub mod state;
|
||||||
#[cfg(feature = "systemd")]
|
#[cfg(feature = "systemd")]
|
||||||
pub mod systemd;
|
pub mod systemd;
|
||||||
|
pub mod theme;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
pub mod wayland;
|
pub mod wayland;
|
||||||
pub mod xwayland;
|
pub mod xwayland;
|
||||||
|
|
@ -55,6 +56,10 @@ fn main() -> Result<()> {
|
||||||
// potentially tell the session we are setup now
|
// potentially tell the session we are setup now
|
||||||
session::setup_socket(event_loop.handle(), &state)?;
|
session::setup_socket(event_loop.handle(), &state)?;
|
||||||
|
|
||||||
|
if let Err(err) = theme::watch_theme(event_loop.handle()) {
|
||||||
|
warn!(?err, "Failed to watch theme");
|
||||||
|
}
|
||||||
|
|
||||||
// run the event loop
|
// run the event loop
|
||||||
event_loop.run(None, &mut state, |state| {
|
event_loop.run(None, &mut state, |state| {
|
||||||
// shall we shut down?
|
// shall we shut down?
|
||||||
|
|
|
||||||
|
|
@ -501,6 +501,7 @@ impl CosmicMapped {
|
||||||
pub fn convert_to_stack<'a>(
|
pub fn convert_to_stack<'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
(output, overlap): (&'a Output, Rectangle<i32, Logical>),
|
(output, overlap): (&'a Output, Rectangle<i32, Logical>),
|
||||||
|
theme: cosmic::Theme,
|
||||||
) {
|
) {
|
||||||
match &self.element {
|
match &self.element {
|
||||||
CosmicMappedInternal::Window(window) => {
|
CosmicMappedInternal::Window(window) => {
|
||||||
|
|
@ -508,7 +509,7 @@ impl CosmicMapped {
|
||||||
let activated = surface.is_activated(true);
|
let activated = surface.is_activated(true);
|
||||||
let handle = window.loop_handle();
|
let handle = window.loop_handle();
|
||||||
|
|
||||||
let stack = CosmicStack::new(std::iter::once(surface), handle);
|
let stack = CosmicStack::new(std::iter::once(surface), handle, theme);
|
||||||
if let Some(geo) = self.last_geometry.lock().unwrap().clone() {
|
if let Some(geo) = self.last_geometry.lock().unwrap().clone() {
|
||||||
stack.set_geometry(geo.to_global(&output));
|
stack.set_geometry(geo.to_global(&output));
|
||||||
}
|
}
|
||||||
|
|
@ -527,11 +528,12 @@ impl CosmicMapped {
|
||||||
&mut self,
|
&mut self,
|
||||||
surface: CosmicSurface,
|
surface: CosmicSurface,
|
||||||
(output, overlap): (&'a Output, Rectangle<i32, Logical>),
|
(output, overlap): (&'a Output, Rectangle<i32, Logical>),
|
||||||
|
theme: cosmic::Theme,
|
||||||
) {
|
) {
|
||||||
let handle = self.loop_handle();
|
let handle = self.loop_handle();
|
||||||
surface.try_force_undecorated(false);
|
surface.try_force_undecorated(false);
|
||||||
surface.set_tiled(false);
|
surface.set_tiled(false);
|
||||||
let window = CosmicWindow::new(surface, handle);
|
let window = CosmicWindow::new(surface, handle, theme);
|
||||||
|
|
||||||
if let Some(geo) = self.last_geometry.lock().unwrap().clone() {
|
if let Some(geo) = self.last_geometry.lock().unwrap().clone() {
|
||||||
window.set_geometry(geo.to_global(&output));
|
window.set_geometry(geo.to_global(&output));
|
||||||
|
|
@ -764,6 +766,22 @@ impl CosmicMapped {
|
||||||
popup_elements.into_iter().map(C::from).collect(),
|
popup_elements.into_iter().map(C::from).collect(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn update_theme(&self, theme: cosmic::Theme) {
|
||||||
|
match &self.element {
|
||||||
|
CosmicMappedInternal::Window(w) => w.set_theme(theme),
|
||||||
|
CosmicMappedInternal::Stack(s) => s.set_theme(theme),
|
||||||
|
CosmicMappedInternal::_GenericCatcher(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn force_redraw(&self) {
|
||||||
|
match &self.element {
|
||||||
|
CosmicMappedInternal::Window(w) => w.force_redraw(),
|
||||||
|
CosmicMappedInternal::Stack(s) => s.force_redraw(),
|
||||||
|
CosmicMappedInternal::_GenericCatcher(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IsAlive for CosmicMapped {
|
impl IsAlive for CosmicMapped {
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ pub fn resize_indicator(
|
||||||
direction: ResizeDirection,
|
direction: ResizeDirection,
|
||||||
config: &Config,
|
config: &Config,
|
||||||
evlh: LoopHandle<'static, crate::state::State>,
|
evlh: LoopHandle<'static, crate::state::State>,
|
||||||
|
theme: cosmic::Theme,
|
||||||
) -> ResizeIndicator {
|
) -> ResizeIndicator {
|
||||||
ResizeIndicator::new(
|
ResizeIndicator::new(
|
||||||
ResizeIndicatorInternal {
|
ResizeIndicatorInternal {
|
||||||
|
|
@ -49,6 +50,7 @@ pub fn resize_indicator(
|
||||||
},
|
},
|
||||||
Size::from((1, 1)),
|
Size::from((1, 1)),
|
||||||
evlh,
|
evlh,
|
||||||
|
theme,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -129,6 +129,7 @@ impl CosmicStack {
|
||||||
pub fn new<I: Into<CosmicSurface>>(
|
pub fn new<I: Into<CosmicSurface>>(
|
||||||
windows: impl Iterator<Item = I>,
|
windows: impl Iterator<Item = I>,
|
||||||
handle: LoopHandle<'static, crate::state::State>,
|
handle: LoopHandle<'static, crate::state::State>,
|
||||||
|
theme: cosmic::Theme,
|
||||||
) -> CosmicStack {
|
) -> CosmicStack {
|
||||||
let windows = windows.map(Into::into).collect::<Vec<_>>();
|
let windows = windows.map(Into::into).collect::<Vec<_>>();
|
||||||
assert!(!windows.is_empty());
|
assert!(!windows.is_empty());
|
||||||
|
|
@ -160,6 +161,7 @@ impl CosmicStack {
|
||||||
},
|
},
|
||||||
(width, TAB_HEIGHT),
|
(width, TAB_HEIGHT),
|
||||||
handle,
|
handle,
|
||||||
|
theme,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -544,6 +546,14 @@ impl CosmicStack {
|
||||||
popup_elements.into_iter().map(C::from).collect(),
|
popup_elements.into_iter().map(C::from).collect(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn set_theme(&self, theme: cosmic::Theme) {
|
||||||
|
self.0.set_theme(theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn force_redraw(&self) {
|
||||||
|
self.0.force_redraw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
|
@ -1056,11 +1066,12 @@ impl PointerTarget<State> for CosmicStack {
|
||||||
let mapped = CosmicMapped::from(CosmicWindow::new(
|
let mapped = CosmicMapped::from(CosmicWindow::new(
|
||||||
surface,
|
surface,
|
||||||
self.0.loop_handle(),
|
self.0.loop_handle(),
|
||||||
|
data.common.theme.clone(),
|
||||||
));
|
));
|
||||||
let elem_geo =
|
let elem_geo =
|
||||||
workspace.element_geometry(stack_mapped).unwrap();
|
workspace.element_geometry(stack_mapped).unwrap();
|
||||||
let indicator_thickness =
|
let indicator_thickness =
|
||||||
data.common.config.static_conf.active_hint;
|
data.common.theme.cosmic().active_hint as u8;
|
||||||
let was_tiled = workspace.is_tiled(stack_mapped);
|
let was_tiled = workspace.is_tiled(stack_mapped);
|
||||||
|
|
||||||
self.remove_idx(dragged_out);
|
self.remove_idx(dragged_out);
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,9 @@ pub type StackHover = IcedElement<StackHoverInternal>;
|
||||||
pub fn stack_hover(
|
pub fn stack_hover(
|
||||||
evlh: LoopHandle<'static, crate::state::State>,
|
evlh: LoopHandle<'static, crate::state::State>,
|
||||||
size: Size<i32, Logical>,
|
size: Size<i32, Logical>,
|
||||||
|
theme: cosmic::Theme,
|
||||||
) -> StackHover {
|
) -> StackHover {
|
||||||
StackHover::new(StackHoverInternal, size, evlh)
|
StackHover::new(StackHoverInternal, size, evlh, theme)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct StackHoverInternal;
|
pub struct StackHoverInternal;
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,11 @@ use smithay::utils::Size;
|
||||||
|
|
||||||
pub type SwapIndicator = IcedElement<SwapIndicatorInternal>;
|
pub type SwapIndicator = IcedElement<SwapIndicatorInternal>;
|
||||||
|
|
||||||
pub fn swap_indicator(evlh: LoopHandle<'static, crate::state::State>) -> SwapIndicator {
|
pub fn swap_indicator(
|
||||||
SwapIndicator::new(SwapIndicatorInternal, Size::from((1, 1)), evlh)
|
evlh: LoopHandle<'static, crate::state::State>,
|
||||||
|
theme: cosmic::Theme,
|
||||||
|
) -> SwapIndicator {
|
||||||
|
SwapIndicator::new(SwapIndicatorInternal, Size::from((1, 1)), evlh, theme)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SwapIndicatorInternal;
|
pub struct SwapIndicatorInternal;
|
||||||
|
|
|
||||||
|
|
@ -114,6 +114,7 @@ impl CosmicWindow {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
window: impl Into<CosmicSurface>,
|
window: impl Into<CosmicSurface>,
|
||||||
handle: LoopHandle<'static, crate::state::State>,
|
handle: LoopHandle<'static, crate::state::State>,
|
||||||
|
theme: cosmic::Theme,
|
||||||
) -> CosmicWindow {
|
) -> CosmicWindow {
|
||||||
let window = window.into();
|
let window = window.into();
|
||||||
let width = window.geometry().size.w;
|
let width = window.geometry().size.w;
|
||||||
|
|
@ -129,6 +130,7 @@ impl CosmicWindow {
|
||||||
},
|
},
|
||||||
(width, SSD_HEIGHT),
|
(width, SSD_HEIGHT),
|
||||||
handle,
|
handle,
|
||||||
|
theme,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -213,6 +215,14 @@ impl CosmicWindow {
|
||||||
popup_elements.into_iter().map(C::from).collect(),
|
popup_elements.into_iter().map(C::from).collect(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn set_theme(&self, theme: cosmic::Theme) {
|
||||||
|
self.0.set_theme(theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn force_redraw(&self) {
|
||||||
|
self.0.force_redraw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ use crate::{
|
||||||
utils::prelude::*,
|
utils::prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use cosmic::theme::CosmicTheme;
|
||||||
use smithay::{
|
use smithay::{
|
||||||
backend::renderer::{
|
backend::renderer::{
|
||||||
element::{utils::RescaleRenderElement, AsRenderElements, RenderElement},
|
element::{utils::RescaleRenderElement, AsRenderElements, RenderElement},
|
||||||
|
|
@ -58,7 +59,13 @@ pub struct MoveGrabState {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MoveGrabState {
|
impl MoveGrabState {
|
||||||
pub fn render<I, R>(&self, renderer: &mut R, seat: &Seat<State>, output: &Output) -> Vec<I>
|
pub fn render<I, R>(
|
||||||
|
&self,
|
||||||
|
renderer: &mut R,
|
||||||
|
seat: &Seat<State>,
|
||||||
|
output: &Output,
|
||||||
|
theme: &CosmicTheme,
|
||||||
|
) -> Vec<I>
|
||||||
where
|
where
|
||||||
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
||||||
<R as Renderer>::TextureId: 'static,
|
<R as Renderer>::TextureId: 'static,
|
||||||
|
|
@ -103,6 +110,7 @@ impl MoveGrabState {
|
||||||
+ self.window_offset
|
+ self.window_offset
|
||||||
- scaling_offset;
|
- scaling_offset;
|
||||||
|
|
||||||
|
let active_window_hint = crate::theme::active_window_hint(theme);
|
||||||
let focus_element = if self.indicator_thickness > 0 {
|
let focus_element = if self.indicator_thickness > 0 {
|
||||||
Some(
|
Some(
|
||||||
CosmicMappedRenderElement::from(IndicatorShader::focus_element(
|
CosmicMappedRenderElement::from(IndicatorShader::focus_element(
|
||||||
|
|
@ -121,6 +129,11 @@ impl MoveGrabState {
|
||||||
self.indicator_thickness,
|
self.indicator_thickness,
|
||||||
output_scale.x,
|
output_scale.x,
|
||||||
alpha,
|
alpha,
|
||||||
|
[
|
||||||
|
active_window_hint.red,
|
||||||
|
active_window_hint.green,
|
||||||
|
active_window_hint.blue,
|
||||||
|
],
|
||||||
))
|
))
|
||||||
.into(),
|
.into(),
|
||||||
)
|
)
|
||||||
|
|
@ -277,6 +290,7 @@ impl PointerGrab<State> for MoveGrab {
|
||||||
let element = stack_hover(
|
let element = stack_hover(
|
||||||
state.common.event_loop_handle.clone(),
|
state.common.event_loop_handle.clone(),
|
||||||
geo.size.as_logical(),
|
geo.size.as_logical(),
|
||||||
|
state.common.theme.clone(),
|
||||||
);
|
);
|
||||||
for output in &self.window_outputs {
|
for output in &self.window_outputs {
|
||||||
element.output_enter(
|
element.output_enter(
|
||||||
|
|
|
||||||
|
|
@ -364,6 +364,7 @@ impl FloatingLayout {
|
||||||
&mut self,
|
&mut self,
|
||||||
direction: Direction,
|
direction: Direction,
|
||||||
seat: &Seat<State>,
|
seat: &Seat<State>,
|
||||||
|
theme: cosmic::Theme,
|
||||||
) -> MoveResult {
|
) -> MoveResult {
|
||||||
let Some(target) = seat.get_keyboard().unwrap().current_focus() else {
|
let Some(target) = seat.get_keyboard().unwrap().current_focus() else {
|
||||||
return MoveResult::None
|
return MoveResult::None
|
||||||
|
|
@ -388,7 +389,7 @@ impl FloatingLayout {
|
||||||
match focused.handle_move(direction) {
|
match focused.handle_move(direction) {
|
||||||
StackMoveResult::Handled => return MoveResult::Done,
|
StackMoveResult::Handled => return MoveResult::Done,
|
||||||
StackMoveResult::MoveOut(surface, loop_handle) => {
|
StackMoveResult::MoveOut(surface, loop_handle) => {
|
||||||
let mapped: CosmicMapped = CosmicWindow::new(surface, loop_handle).into();
|
let mapped: CosmicMapped = CosmicWindow::new(surface, loop_handle, theme).into();
|
||||||
let output = seat.active_output();
|
let output = seat.active_output();
|
||||||
let pos = self.space.element_geometry(focused).unwrap().loc
|
let pos = self.space.element_geometry(focused).unwrap().loc
|
||||||
+ match direction {
|
+ match direction {
|
||||||
|
|
@ -464,6 +465,7 @@ impl FloatingLayout {
|
||||||
mut resize_indicator: Option<(ResizeMode, ResizeIndicator)>,
|
mut resize_indicator: Option<(ResizeMode, ResizeIndicator)>,
|
||||||
indicator_thickness: u8,
|
indicator_thickness: u8,
|
||||||
alpha: f32,
|
alpha: f32,
|
||||||
|
theme: &cosmic::theme::CosmicTheme,
|
||||||
) -> (
|
) -> (
|
||||||
Vec<CosmicMappedRenderElement<R>>,
|
Vec<CosmicMappedRenderElement<R>>,
|
||||||
Vec<CosmicMappedRenderElement<R>>,
|
Vec<CosmicMappedRenderElement<R>>,
|
||||||
|
|
@ -521,6 +523,8 @@ impl FloatingLayout {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let active_window_hint = crate::theme::active_window_hint(theme);
|
||||||
|
|
||||||
if indicator_thickness > 0 {
|
if indicator_thickness > 0 {
|
||||||
let element = IndicatorShader::focus_element(
|
let element = IndicatorShader::focus_element(
|
||||||
renderer,
|
renderer,
|
||||||
|
|
@ -529,6 +533,11 @@ impl FloatingLayout {
|
||||||
indicator_thickness,
|
indicator_thickness,
|
||||||
output_scale,
|
output_scale,
|
||||||
alpha,
|
alpha,
|
||||||
|
[
|
||||||
|
active_window_hint.red,
|
||||||
|
active_window_hint.green,
|
||||||
|
active_window_hint.blue,
|
||||||
|
],
|
||||||
);
|
);
|
||||||
window_elements.push(element.into());
|
window_elements.push(element.into());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,8 @@ impl PointerGrab<State> for ResizeForkGrab {
|
||||||
|
|
||||||
if let Some(output) = self.output.upgrade() {
|
if let Some(output) = self.output.upgrade() {
|
||||||
let tiling_layer = &mut data.common.shell.active_space_mut(&output).tiling_layer;
|
let tiling_layer = &mut data.common.shell.active_space_mut(&output).tiling_layer;
|
||||||
|
let gaps = tiling_layer.gaps();
|
||||||
|
|
||||||
let tree = &mut tiling_layer.queue.trees.back_mut().unwrap().0;
|
let tree = &mut tiling_layer.queue.trees.back_mut().unwrap().0;
|
||||||
if tree.get(&self.node).is_ok() {
|
if tree.get(&self.node).is_ok() {
|
||||||
let delta = match self.orientation {
|
let delta = match self.orientation {
|
||||||
|
|
@ -191,7 +193,7 @@ impl PointerGrab<State> for ResizeForkGrab {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.last_loc = event.location;
|
self.last_loc = event.location;
|
||||||
let blocker = TilingLayout::update_positions(&output, tree, tiling_layer.gaps);
|
let blocker = TilingLayout::update_positions(&output, tree, gaps);
|
||||||
tiling_layer.pending_blockers.extend(blocker);
|
tiling_layer.pending_blockers.extend(blocker);
|
||||||
} else {
|
} else {
|
||||||
handle.unset_grab(data, event.serial, event.time);
|
handle.unset_grab(data, event.serial, event.time);
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,7 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::render::{
|
backend::render::{element::AsGlowRenderer, BackdropShader, IndicatorShader, Key, Usage},
|
||||||
element::AsGlowRenderer, BackdropShader, IndicatorShader, Key, Usage, ACTIVE_GROUP_COLOR,
|
|
||||||
GROUP_COLOR,
|
|
||||||
},
|
|
||||||
shell::{
|
shell::{
|
||||||
element::{
|
element::{
|
||||||
resize_indicator::ResizeIndicator,
|
resize_indicator::ResizeIndicator,
|
||||||
|
|
@ -25,6 +22,7 @@ use crate::{
|
||||||
CosmicSurface, Direction, FocusResult, MoveResult, OutputNotMapped, OverviewMode,
|
CosmicSurface, Direction, FocusResult, MoveResult, OutputNotMapped, OverviewMode,
|
||||||
ResizeDirection, ResizeMode, Trigger,
|
ResizeDirection, ResizeMode, Trigger,
|
||||||
},
|
},
|
||||||
|
theme::group_color,
|
||||||
utils::{prelude::*, tween::EaseRectangle},
|
utils::{prelude::*, tween::EaseRectangle},
|
||||||
wayland::{
|
wayland::{
|
||||||
handlers::xdg_shell::popup::get_popup_toplevel,
|
handlers::xdg_shell::popup::get_popup_toplevel,
|
||||||
|
|
@ -116,13 +114,13 @@ impl TreeQueue {
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct TilingLayout {
|
pub struct TilingLayout {
|
||||||
gaps: (i32, i32),
|
|
||||||
output: Output,
|
output: Output,
|
||||||
queue: TreeQueue,
|
queue: TreeQueue,
|
||||||
pending_blockers: Vec<TilingBlocker>,
|
pending_blockers: Vec<TilingBlocker>,
|
||||||
placeholder_id: Id,
|
placeholder_id: Id,
|
||||||
swapping_stack_surface_id: Id,
|
swapping_stack_surface_id: Id,
|
||||||
last_overview_hover: Option<(Option<Instant>, TargetZone)>,
|
last_overview_hover: Option<(Option<Instant>, TargetZone)>,
|
||||||
|
pub theme: cosmic::Theme,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
|
@ -317,9 +315,8 @@ enum FocusedNodeData {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TilingLayout {
|
impl TilingLayout {
|
||||||
pub fn new(gaps: (u8, u8), output: &Output) -> TilingLayout {
|
pub fn new(theme: cosmic::Theme, output: &Output) -> TilingLayout {
|
||||||
TilingLayout {
|
TilingLayout {
|
||||||
gaps: (gaps.0 as i32, gaps.1 as i32),
|
|
||||||
queue: TreeQueue {
|
queue: TreeQueue {
|
||||||
trees: {
|
trees: {
|
||||||
let mut queue = VecDeque::new();
|
let mut queue = VecDeque::new();
|
||||||
|
|
@ -333,10 +330,12 @@ impl TilingLayout {
|
||||||
placeholder_id: Id::new(),
|
placeholder_id: Id::new(),
|
||||||
swapping_stack_surface_id: Id::new(),
|
swapping_stack_surface_id: Id::new(),
|
||||||
last_overview_hover: None,
|
last_overview_hover: None,
|
||||||
|
theme,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_output(&mut self, output: &Output) {
|
pub fn set_output(&mut self, output: &Output) {
|
||||||
|
let gaps = self.gaps();
|
||||||
let mut tree = self.queue.trees.back().unwrap().0.copy_clone();
|
let mut tree = self.queue.trees.back().unwrap().0.copy_clone();
|
||||||
|
|
||||||
for node in tree
|
for node in tree
|
||||||
|
|
@ -355,7 +354,7 @@ impl TilingLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let blocker = TilingLayout::update_positions(output, &mut tree, self.gaps);
|
let blocker = TilingLayout::update_positions(output, &mut tree, gaps);
|
||||||
self.queue.push_tree(tree, None, blocker);
|
self.queue.push_tree(tree, None, blocker);
|
||||||
self.output = output.clone();
|
self.output = output.clone();
|
||||||
}
|
}
|
||||||
|
|
@ -377,9 +376,11 @@ impl TilingLayout {
|
||||||
focus_stack: Option<impl Iterator<Item = &'a CosmicMapped> + 'a>,
|
focus_stack: Option<impl Iterator<Item = &'a CosmicMapped> + 'a>,
|
||||||
direction: Option<Direction>,
|
direction: Option<Direction>,
|
||||||
) {
|
) {
|
||||||
|
let gaps = self.gaps();
|
||||||
|
|
||||||
let mut tree = self.queue.trees.back().unwrap().0.copy_clone();
|
let mut tree = self.queue.trees.back().unwrap().0.copy_clone();
|
||||||
TilingLayout::map_to_tree(&mut tree, window, &self.output, focus_stack, direction);
|
TilingLayout::map_to_tree(&mut tree, window, &self.output, focus_stack, direction);
|
||||||
let blocker = TilingLayout::update_positions(&self.output, &mut tree, self.gaps);
|
let blocker = TilingLayout::update_positions(&self.output, &mut tree, gaps);
|
||||||
self.queue.push_tree(tree, ANIMATION_DURATION, blocker);
|
self.queue.push_tree(tree, ANIMATION_DURATION, blocker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -466,6 +467,7 @@ impl TilingLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn replace_window(&mut self, old: &CosmicMapped, new: &CosmicMapped) {
|
pub fn replace_window(&mut self, old: &CosmicMapped, new: &CosmicMapped) {
|
||||||
|
let gaps = self.gaps();
|
||||||
let Some(old_id) = old.tiling_node_id.lock().unwrap().clone() else { return };
|
let Some(old_id) = old.tiling_node_id.lock().unwrap().clone() else { return };
|
||||||
let mut tree = self.queue.trees.back().unwrap().0.copy_clone();
|
let mut tree = self.queue.trees.back().unwrap().0.copy_clone();
|
||||||
|
|
||||||
|
|
@ -484,7 +486,7 @@ impl TilingLayout {
|
||||||
old.output_leave(&self.output);
|
old.output_leave(&self.output);
|
||||||
new.output_enter(&self.output, new.bbox());
|
new.output_enter(&self.output, new.bbox());
|
||||||
|
|
||||||
let blocker = TilingLayout::update_positions(&self.output, &mut tree, self.gaps);
|
let blocker = TilingLayout::update_positions(&self.output, &mut tree, gaps);
|
||||||
self.queue.push_tree(tree, ANIMATION_DURATION, blocker);
|
self.queue.push_tree(tree, ANIMATION_DURATION, blocker);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -513,7 +515,8 @@ impl TilingLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mapped: CosmicMapped =
|
let mapped: CosmicMapped =
|
||||||
CosmicWindow::new(stack_surface, this_stack.loop_handle()).into();
|
CosmicWindow::new(stack_surface, this_stack.loop_handle(), this.theme.clone())
|
||||||
|
.into();
|
||||||
if this.output != other.output {
|
if this.output != other.output {
|
||||||
mapped.output_leave(&this.output);
|
mapped.output_leave(&this.output);
|
||||||
mapped.output_enter(&other.output, mapped.bbox());
|
mapped.output_enter(&other.output, mapped.bbox());
|
||||||
|
|
@ -635,13 +638,15 @@ impl TilingLayout {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let this_gaps = this.gaps();
|
||||||
|
let other_gaps = other.gaps();
|
||||||
|
|
||||||
let blocker =
|
let blocker =
|
||||||
TilingLayout::update_positions(&this.output, &mut this_tree, this.gaps);
|
TilingLayout::update_positions(&this.output, &mut this_tree, this_gaps);
|
||||||
this.queue.push_tree(this_tree, ANIMATION_DURATION, blocker);
|
this.queue.push_tree(this_tree, ANIMATION_DURATION, blocker);
|
||||||
|
|
||||||
let blocker =
|
let blocker =
|
||||||
TilingLayout::update_positions(&other.output, &mut other_tree, other.gaps);
|
TilingLayout::update_positions(&other.output, &mut other_tree, other_gaps);
|
||||||
other
|
other
|
||||||
.queue
|
.queue
|
||||||
.push_tree(other_tree, ANIMATION_DURATION, blocker);
|
.push_tree(other_tree, ANIMATION_DURATION, blocker);
|
||||||
|
|
@ -900,8 +905,12 @@ impl TilingLayout {
|
||||||
}
|
}
|
||||||
this_stack.remove_window(&this_surface);
|
this_stack.remove_window(&this_surface);
|
||||||
|
|
||||||
let mapped: CosmicMapped =
|
let mapped: CosmicMapped = CosmicWindow::new(
|
||||||
CosmicWindow::new(this_surface.clone(), this_stack.loop_handle()).into();
|
this_surface.clone(),
|
||||||
|
this_stack.loop_handle(),
|
||||||
|
this.theme.clone(),
|
||||||
|
)
|
||||||
|
.into();
|
||||||
mapped.set_tiled(true);
|
mapped.set_tiled(true);
|
||||||
mapped.refresh();
|
mapped.refresh();
|
||||||
if this.output != other_output {
|
if this.output != other_output {
|
||||||
|
|
@ -977,8 +986,12 @@ impl TilingLayout {
|
||||||
}
|
}
|
||||||
other_stack.remove_window(&other_surface);
|
other_stack.remove_window(&other_surface);
|
||||||
|
|
||||||
let mapped: CosmicMapped =
|
let mapped: CosmicMapped = CosmicWindow::new(
|
||||||
CosmicWindow::new(other_surface.clone(), other_stack.loop_handle()).into();
|
other_surface.clone(),
|
||||||
|
other_stack.loop_handle(),
|
||||||
|
this.theme.clone(),
|
||||||
|
)
|
||||||
|
.into();
|
||||||
mapped.set_tiled(true);
|
mapped.set_tiled(true);
|
||||||
mapped.refresh();
|
mapped.refresh();
|
||||||
if this.output != other_output {
|
if this.output != other_output {
|
||||||
|
|
@ -1063,15 +1076,17 @@ impl TilingLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let blocker = TilingLayout::update_positions(&this.output, &mut this_tree, this.gaps);
|
let this_gaps = this.gaps();
|
||||||
|
let blocker = TilingLayout::update_positions(&this.output, &mut this_tree, this_gaps);
|
||||||
this.queue.push_tree(this_tree, ANIMATION_DURATION, blocker);
|
this.queue.push_tree(this_tree, ANIMATION_DURATION, blocker);
|
||||||
|
|
||||||
let has_other_tree = other_tree.is_some();
|
let has_other_tree = other_tree.is_some();
|
||||||
if let Some(mut other_tree) = other_tree {
|
if let Some(mut other_tree) = other_tree {
|
||||||
let (other_queue, gaps) = if let Some(other) = other.as_mut() {
|
let (other_queue, gaps) = if let Some(other) = other.as_mut() {
|
||||||
(&mut other.queue, other.gaps)
|
let other_gaps = other.gaps();
|
||||||
|
(&mut other.queue, other_gaps)
|
||||||
} else {
|
} else {
|
||||||
(&mut this.queue, this.gaps)
|
(&mut this.queue, this_gaps)
|
||||||
};
|
};
|
||||||
let blocker = TilingLayout::update_positions(&other_output, &mut other_tree, gaps);
|
let blocker = TilingLayout::update_positions(&other_output, &mut other_tree, gaps);
|
||||||
other_queue.push_tree(other_tree, ANIMATION_DURATION, blocker);
|
other_queue.push_tree(other_tree, ANIMATION_DURATION, blocker);
|
||||||
|
|
@ -1144,6 +1159,8 @@ impl TilingLayout {
|
||||||
|
|
||||||
fn unmap_window_internal(&mut self, mapped: &CosmicMapped) -> bool {
|
fn unmap_window_internal(&mut self, mapped: &CosmicMapped) -> bool {
|
||||||
let tiling_node_id = mapped.tiling_node_id.lock().unwrap().as_ref().cloned();
|
let tiling_node_id = mapped.tiling_node_id.lock().unwrap().as_ref().cloned();
|
||||||
|
let gaps = self.gaps();
|
||||||
|
|
||||||
if let Some(node_id) = tiling_node_id {
|
if let Some(node_id) = tiling_node_id {
|
||||||
if self
|
if self
|
||||||
.queue
|
.queue
|
||||||
|
|
@ -1159,7 +1176,7 @@ impl TilingLayout {
|
||||||
|
|
||||||
TilingLayout::unmap_internal(&mut tree, &node_id);
|
TilingLayout::unmap_internal(&mut tree, &node_id);
|
||||||
|
|
||||||
let blocker = TilingLayout::update_positions(&self.output, &mut tree, self.gaps);
|
let blocker = TilingLayout::update_positions(&self.output, &mut tree, gaps);
|
||||||
self.queue.push_tree(tree, ANIMATION_DURATION, blocker);
|
self.queue.push_tree(tree, ANIMATION_DURATION, blocker);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -1241,6 +1258,8 @@ impl TilingLayout {
|
||||||
direction: Direction,
|
direction: Direction,
|
||||||
seat: &Seat<State>,
|
seat: &Seat<State>,
|
||||||
) -> MoveResult {
|
) -> MoveResult {
|
||||||
|
let gaps = self.gaps();
|
||||||
|
|
||||||
let mut tree = self.queue.trees.back().unwrap().0.copy_clone();
|
let mut tree = self.queue.trees.back().unwrap().0.copy_clone();
|
||||||
|
|
||||||
let Some(target) = seat.get_keyboard().unwrap().current_focus() else {
|
let Some(target) = seat.get_keyboard().unwrap().current_focus() else {
|
||||||
|
|
@ -1257,7 +1276,8 @@ impl TilingLayout {
|
||||||
match window.handle_move(direction) {
|
match window.handle_move(direction) {
|
||||||
StackMoveResult::Handled => return MoveResult::Done,
|
StackMoveResult::Handled => return MoveResult::Done,
|
||||||
StackMoveResult::MoveOut(surface, loop_handle) => {
|
StackMoveResult::MoveOut(surface, loop_handle) => {
|
||||||
let mapped: CosmicMapped = CosmicWindow::new(surface, loop_handle).into();
|
let mapped: CosmicMapped =
|
||||||
|
CosmicWindow::new(surface, loop_handle, self.theme.clone()).into();
|
||||||
mapped.output_enter(&self.output, mapped.bbox());
|
mapped.output_enter(&self.output, mapped.bbox());
|
||||||
let orientation = match direction {
|
let orientation = match direction {
|
||||||
Direction::Left | Direction::Right => Orientation::Vertical,
|
Direction::Left | Direction::Right => Orientation::Vertical,
|
||||||
|
|
@ -1280,8 +1300,7 @@ impl TilingLayout {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
*mapped.tiling_node_id.lock().unwrap() = Some(new_id);
|
*mapped.tiling_node_id.lock().unwrap() = Some(new_id);
|
||||||
|
|
||||||
let blocker =
|
let blocker = TilingLayout::update_positions(&self.output, &mut tree, gaps);
|
||||||
TilingLayout::update_positions(&self.output, &mut tree, self.gaps);
|
|
||||||
self.queue.push_tree(tree, ANIMATION_DURATION, blocker);
|
self.queue.push_tree(tree, ANIMATION_DURATION, blocker);
|
||||||
return MoveResult::ShiftFocus(mapped.into());
|
return MoveResult::ShiftFocus(mapped.into());
|
||||||
}
|
}
|
||||||
|
|
@ -1357,7 +1376,7 @@ impl TilingLayout {
|
||||||
.data_mut()
|
.data_mut()
|
||||||
.remove_window(og_idx);
|
.remove_window(og_idx);
|
||||||
|
|
||||||
let blocker = TilingLayout::update_positions(&self.output, &mut tree, self.gaps);
|
let blocker = TilingLayout::update_positions(&self.output, &mut tree, gaps);
|
||||||
self.queue.push_tree(tree, ANIMATION_DURATION, blocker);
|
self.queue.push_tree(tree, ANIMATION_DURATION, blocker);
|
||||||
return MoveResult::Done;
|
return MoveResult::Done;
|
||||||
}
|
}
|
||||||
|
|
@ -1383,7 +1402,7 @@ impl TilingLayout {
|
||||||
.data_mut()
|
.data_mut()
|
||||||
.remove_window(og_idx);
|
.remove_window(og_idx);
|
||||||
|
|
||||||
let blocker = TilingLayout::update_positions(&self.output, &mut tree, self.gaps);
|
let blocker = TilingLayout::update_positions(&self.output, &mut tree, gaps);
|
||||||
self.queue.push_tree(tree, ANIMATION_DURATION, blocker);
|
self.queue.push_tree(tree, ANIMATION_DURATION, blocker);
|
||||||
return MoveResult::Done;
|
return MoveResult::Done;
|
||||||
}
|
}
|
||||||
|
|
@ -1539,7 +1558,7 @@ impl TilingLayout {
|
||||||
MoveResult::Done
|
MoveResult::Done
|
||||||
};
|
};
|
||||||
|
|
||||||
let blocker = TilingLayout::update_positions(&self.output, &mut tree, self.gaps);
|
let blocker = TilingLayout::update_positions(&self.output, &mut tree, gaps);
|
||||||
self.queue.push_tree(tree, ANIMATION_DURATION, blocker);
|
self.queue.push_tree(tree, ANIMATION_DURATION, blocker);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -1836,6 +1855,8 @@ impl TilingLayout {
|
||||||
new_orientation: Option<Orientation>,
|
new_orientation: Option<Orientation>,
|
||||||
seat: &Seat<State>,
|
seat: &Seat<State>,
|
||||||
) {
|
) {
|
||||||
|
let gaps = self.gaps();
|
||||||
|
|
||||||
let Some(target) = seat.get_keyboard().unwrap().current_focus() else {
|
let Some(target) = seat.get_keyboard().unwrap().current_focus() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
@ -1871,8 +1892,7 @@ impl TilingLayout {
|
||||||
|
|
||||||
*orientation = new_orientation;
|
*orientation = new_orientation;
|
||||||
|
|
||||||
let blocker =
|
let blocker = TilingLayout::update_positions(&self.output, &mut tree, gaps);
|
||||||
TilingLayout::update_positions(&self.output, &mut tree, self.gaps);
|
|
||||||
self.queue.push_tree(tree, ANIMATION_DURATION, blocker);
|
self.queue.push_tree(tree, ANIMATION_DURATION, blocker);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1880,6 +1900,8 @@ impl TilingLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn toggle_stacking<'a>(&mut self, seat: &Seat<State>, mut focus_stack: FocusStackMut) {
|
pub fn toggle_stacking<'a>(&mut self, seat: &Seat<State>, mut focus_stack: FocusStackMut) {
|
||||||
|
let gaps = self.gaps();
|
||||||
|
|
||||||
let Some(target) = seat.get_keyboard().unwrap().current_focus() else {
|
let Some(target) = seat.get_keyboard().unwrap().current_focus() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
@ -1894,7 +1916,10 @@ impl TilingLayout {
|
||||||
// if it is just a window
|
// if it is just a window
|
||||||
match tree.get_mut(&last_active).unwrap().data_mut() {
|
match tree.get_mut(&last_active).unwrap().data_mut() {
|
||||||
Data::Mapped { mapped, .. } => {
|
Data::Mapped { mapped, .. } => {
|
||||||
mapped.convert_to_stack((&self.output, mapped.bbox()));
|
mapped.convert_to_stack(
|
||||||
|
(&self.output, mapped.bbox()),
|
||||||
|
self.theme.clone(),
|
||||||
|
);
|
||||||
focus_stack.append(&mapped);
|
focus_stack.append(&mapped);
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
|
@ -1907,7 +1932,11 @@ impl TilingLayout {
|
||||||
let handle = match tree.get_mut(&last_active).unwrap().data_mut() {
|
let handle = match tree.get_mut(&last_active).unwrap().data_mut() {
|
||||||
Data::Mapped { mapped, .. } => {
|
Data::Mapped { mapped, .. } => {
|
||||||
let handle = mapped.loop_handle();
|
let handle = mapped.loop_handle();
|
||||||
mapped.convert_to_surface(first, (&self.output, mapped.bbox()));
|
mapped.convert_to_surface(
|
||||||
|
first,
|
||||||
|
(&self.output, mapped.bbox()),
|
||||||
|
self.theme.clone(),
|
||||||
|
);
|
||||||
focus_stack.append(&mapped);
|
focus_stack.append(&mapped);
|
||||||
handle
|
handle
|
||||||
}
|
}
|
||||||
|
|
@ -1918,8 +1947,11 @@ impl TilingLayout {
|
||||||
for other in surfaces {
|
for other in surfaces {
|
||||||
other.try_force_undecorated(false);
|
other.try_force_undecorated(false);
|
||||||
other.set_tiled(false);
|
other.set_tiled(false);
|
||||||
let window =
|
let window = CosmicMapped::from(CosmicWindow::new(
|
||||||
CosmicMapped::from(CosmicWindow::new(other, handle.clone()));
|
other,
|
||||||
|
handle.clone(),
|
||||||
|
self.theme.clone(),
|
||||||
|
));
|
||||||
window.output_enter(&self.output, window.bbox());
|
window.output_enter(&self.output, window.bbox());
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -1960,7 +1992,7 @@ impl TilingLayout {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let handle = handle.unwrap();
|
let handle = handle.unwrap();
|
||||||
let stack = CosmicStack::new(surfaces.into_iter(), handle);
|
let stack = CosmicStack::new(surfaces.into_iter(), handle, self.theme.clone());
|
||||||
|
|
||||||
for child in tree
|
for child in tree
|
||||||
.children_ids(&last_active)
|
.children_ids(&last_active)
|
||||||
|
|
@ -1992,14 +2024,16 @@ impl TilingLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let blocker = TilingLayout::update_positions(&self.output, &mut tree, self.gaps);
|
let blocker = TilingLayout::update_positions(&self.output, &mut tree, gaps);
|
||||||
self.queue.push_tree(tree, ANIMATION_DURATION, blocker);
|
self.queue.push_tree(tree, ANIMATION_DURATION, blocker);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn recalculate(&mut self) {
|
pub fn recalculate(&mut self) {
|
||||||
|
let gaps = self.gaps();
|
||||||
|
|
||||||
let mut tree = self.queue.trees.back().unwrap().0.copy_clone();
|
let mut tree = self.queue.trees.back().unwrap().0.copy_clone();
|
||||||
let blocker = TilingLayout::update_positions(&self.output, &mut tree, self.gaps);
|
let blocker = TilingLayout::update_positions(&self.output, &mut tree, gaps);
|
||||||
self.queue.push_tree(tree, ANIMATION_DURATION, blocker);
|
self.queue.push_tree(tree, ANIMATION_DURATION, blocker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2136,6 +2170,8 @@ impl TilingLayout {
|
||||||
edges: ResizeEdge,
|
edges: ResizeEdge,
|
||||||
amount: i32,
|
amount: i32,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
|
let gaps = self.gaps();
|
||||||
|
|
||||||
let mut tree = self.queue.trees.back().unwrap().0.copy_clone();
|
let mut tree = self.queue.trees.back().unwrap().0.copy_clone();
|
||||||
let Some(root_id) = tree.root_node_id() else { return false };
|
let Some(root_id) = tree.root_node_id() else { return false };
|
||||||
let Some(mut node_id) =
|
let Some(mut node_id) =
|
||||||
|
|
@ -2214,7 +2250,7 @@ impl TilingLayout {
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
let blocker = TilingLayout::update_positions(&self.output, &mut tree, self.gaps);
|
let blocker = TilingLayout::update_positions(&self.output, &mut tree, gaps);
|
||||||
self.queue.push_tree(tree, None, blocker);
|
self.queue.push_tree(tree, None, blocker);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -2234,6 +2270,8 @@ impl TilingLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cleanup_drag(&mut self) {
|
pub fn cleanup_drag(&mut self) {
|
||||||
|
let gaps = self.gaps();
|
||||||
|
|
||||||
let mut tree = self.queue.trees.back().unwrap().0.copy_clone();
|
let mut tree = self.queue.trees.back().unwrap().0.copy_clone();
|
||||||
|
|
||||||
if let Some(root) = tree.root_node_id() {
|
if let Some(root) = tree.root_node_id() {
|
||||||
|
|
@ -2252,12 +2290,14 @@ impl TilingLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let blocker = TilingLayout::update_positions(&self.output, &mut tree, self.gaps);
|
let blocker = TilingLayout::update_positions(&self.output, &mut tree, gaps);
|
||||||
self.queue.push_tree(tree, ANIMATION_DURATION, blocker);
|
self.queue.push_tree(tree, ANIMATION_DURATION, blocker);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn drop_window(&mut self, window: CosmicMapped) -> (CosmicMapped, Point<i32, Local>) {
|
pub fn drop_window(&mut self, window: CosmicMapped) -> (CosmicMapped, Point<i32, Local>) {
|
||||||
|
let gaps = self.gaps();
|
||||||
|
|
||||||
let mut tree = self.queue.trees.back().unwrap().0.copy_clone();
|
let mut tree = self.queue.trees.back().unwrap().0.copy_clone();
|
||||||
|
|
||||||
window.output_enter(&self.output, window.bbox());
|
window.output_enter(&self.output, window.bbox());
|
||||||
|
|
@ -2358,7 +2398,7 @@ impl TilingLayout {
|
||||||
Some(TargetZone::WindowStack(window_id, _)) if tree.get(&window_id).is_ok() => {
|
Some(TargetZone::WindowStack(window_id, _)) if tree.get(&window_id).is_ok() => {
|
||||||
match tree.get_mut(window_id).unwrap().data_mut() {
|
match tree.get_mut(window_id).unwrap().data_mut() {
|
||||||
Data::Mapped { mapped, .. } => {
|
Data::Mapped { mapped, .. } => {
|
||||||
mapped.convert_to_stack((&self.output, mapped.bbox()));
|
mapped.convert_to_stack((&self.output, mapped.bbox()), self.theme.clone());
|
||||||
let Some(stack) = mapped.stack_ref_mut() else {
|
let Some(stack) = mapped.stack_ref_mut() else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
|
|
@ -2399,7 +2439,7 @@ impl TilingLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let blocker = TilingLayout::update_positions(&self.output, &mut tree, self.gaps);
|
let blocker = TilingLayout::update_positions(&self.output, &mut tree, gaps);
|
||||||
self.queue.push_tree(tree, ANIMATION_DURATION, blocker);
|
self.queue.push_tree(tree, ANIMATION_DURATION, blocker);
|
||||||
|
|
||||||
let location = self.element_geometry(&mapped).unwrap().loc;
|
let location = self.element_geometry(&mapped).unwrap().loc;
|
||||||
|
|
@ -2728,9 +2768,9 @@ impl TilingLayout {
|
||||||
location: Point<f64, Local>,
|
location: Point<f64, Local>,
|
||||||
overview: OverviewMode,
|
overview: OverviewMode,
|
||||||
) -> Option<(PointerFocusTarget, Point<i32, Local>)> {
|
) -> Option<(PointerFocusTarget, Point<i32, Local>)> {
|
||||||
|
let gaps = self.gaps();
|
||||||
let last_overview_hover = &mut self.last_overview_hover;
|
let last_overview_hover = &mut self.last_overview_hover;
|
||||||
let placeholder_id = &self.placeholder_id;
|
let placeholder_id = &self.placeholder_id;
|
||||||
let gaps = &self.gaps;
|
|
||||||
let tree = &self.queue.trees.back().unwrap().0;
|
let tree = &self.queue.trees.back().unwrap().0;
|
||||||
let root = tree.root_node_id()?;
|
let root = tree.root_node_id()?;
|
||||||
let location = location.to_i32_round();
|
let location = location.to_i32_round();
|
||||||
|
|
@ -2850,6 +2890,7 @@ impl TilingLayout {
|
||||||
Some(None),
|
Some(None),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
|
self.theme.cosmic(),
|
||||||
)
|
)
|
||||||
.0;
|
.0;
|
||||||
|
|
||||||
|
|
@ -3275,7 +3316,7 @@ impl TilingLayout {
|
||||||
let blocker = TilingLayout::update_positions(
|
let blocker = TilingLayout::update_positions(
|
||||||
&self.output,
|
&self.output,
|
||||||
&mut tree,
|
&mut tree,
|
||||||
*gaps,
|
gaps,
|
||||||
);
|
);
|
||||||
self.queue.push_tree(tree, duration, blocker);
|
self.queue.push_tree(tree, duration, blocker);
|
||||||
}
|
}
|
||||||
|
|
@ -3372,6 +3413,8 @@ impl TilingLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn merge(&mut self, mut other: TilingLayout) {
|
pub fn merge(&mut self, mut other: TilingLayout) {
|
||||||
|
let gaps = self.gaps();
|
||||||
|
|
||||||
let src = other.queue.trees.pop_back().unwrap().0;
|
let src = other.queue.trees.pop_back().unwrap().0;
|
||||||
let mut dst = self.queue.trees.back().unwrap().0.copy_clone();
|
let mut dst = self.queue.trees.back().unwrap().0.copy_clone();
|
||||||
|
|
||||||
|
|
@ -3381,7 +3424,7 @@ impl TilingLayout {
|
||||||
};
|
};
|
||||||
TilingLayout::merge_trees(src, &mut dst, orientation);
|
TilingLayout::merge_trees(src, &mut dst, orientation);
|
||||||
|
|
||||||
let blocker = TilingLayout::update_positions(&self.output, &mut dst, self.gaps);
|
let blocker = TilingLayout::update_positions(&self.output, &mut dst, gaps);
|
||||||
self.queue.push_tree(dst, ANIMATION_DURATION, blocker);
|
self.queue.push_tree(dst, ANIMATION_DURATION, blocker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3432,6 +3475,7 @@ impl TilingLayout {
|
||||||
overview: (OverviewMode, Option<(SwapIndicator, Option<&Tree<Data>>)>),
|
overview: (OverviewMode, Option<(SwapIndicator, Option<&Tree<Data>>)>),
|
||||||
resize_indicator: Option<(ResizeMode, ResizeIndicator)>,
|
resize_indicator: Option<(ResizeMode, ResizeIndicator)>,
|
||||||
indicator_thickness: u8,
|
indicator_thickness: u8,
|
||||||
|
theme: &cosmic::theme::CosmicTheme,
|
||||||
) -> Result<
|
) -> Result<
|
||||||
(
|
(
|
||||||
Vec<CosmicMappedRenderElement<R>>,
|
Vec<CosmicMappedRenderElement<R>>,
|
||||||
|
|
@ -3502,6 +3546,7 @@ impl TilingLayout {
|
||||||
is_mouse_tiling,
|
is_mouse_tiling,
|
||||||
swap_desc.clone(),
|
swap_desc.clone(),
|
||||||
overview.1.as_ref().and_then(|(_, tree)| tree.clone()),
|
overview.1.as_ref().and_then(|(_, tree)| tree.clone()),
|
||||||
|
theme,
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
@ -3539,6 +3584,7 @@ impl TilingLayout {
|
||||||
is_mouse_tiling,
|
is_mouse_tiling,
|
||||||
swap_desc.clone(),
|
swap_desc.clone(),
|
||||||
overview.1.as_ref().and_then(|(_, tree)| tree.clone()),
|
overview.1.as_ref().and_then(|(_, tree)| tree.clone()),
|
||||||
|
theme,
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
@ -3573,6 +3619,7 @@ impl TilingLayout {
|
||||||
swap_desc.clone(),
|
swap_desc.clone(),
|
||||||
&self.swapping_stack_surface_id,
|
&self.swapping_stack_surface_id,
|
||||||
&self.placeholder_id,
|
&self.placeholder_id,
|
||||||
|
theme,
|
||||||
);
|
);
|
||||||
window_elements.extend(w_elements);
|
window_elements.extend(w_elements);
|
||||||
popup_elements.extend(p_elements);
|
popup_elements.extend(p_elements);
|
||||||
|
|
@ -3584,6 +3631,11 @@ impl TilingLayout {
|
||||||
|
|
||||||
Ok((window_elements, popup_elements))
|
Ok((window_elements, popup_elements))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn gaps(&self) -> (i32, i32) {
|
||||||
|
let g = self.theme.cosmic().gaps;
|
||||||
|
(g.0 as i32, g.1 as i32)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const GAP_KEYBOARD: i32 = 8;
|
const GAP_KEYBOARD: i32 = 8;
|
||||||
|
|
@ -3631,6 +3683,7 @@ fn geometries_for_groupview<'a, R>(
|
||||||
mouse_tiling: Option<Option<&TargetZone>>,
|
mouse_tiling: Option<Option<&TargetZone>>,
|
||||||
swap_desc: Option<NodeDesc>,
|
swap_desc: Option<NodeDesc>,
|
||||||
swap_tree: Option<&Tree<Data>>,
|
swap_tree: Option<&Tree<Data>>,
|
||||||
|
theme: &cosmic::theme::CosmicTheme,
|
||||||
) -> (
|
) -> (
|
||||||
HashMap<NodeId, Rectangle<i32, Local>>,
|
HashMap<NodeId, Rectangle<i32, Local>>,
|
||||||
Vec<CosmicMappedRenderElement<R>>,
|
Vec<CosmicMappedRenderElement<R>>,
|
||||||
|
|
@ -3788,6 +3841,8 @@ where
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let group_color = group_color(theme);
|
||||||
|
|
||||||
match data {
|
match data {
|
||||||
Data::Group {
|
Data::Group {
|
||||||
orientation,
|
orientation,
|
||||||
|
|
@ -3825,7 +3880,7 @@ where
|
||||||
if render_active_child { 16 } else { 8 },
|
if render_active_child { 16 } else { 8 },
|
||||||
alpha * if render_potential_group { 0.40 } else { 1.0 },
|
alpha * if render_potential_group { 0.40 } else { 1.0 },
|
||||||
output_scale,
|
output_scale,
|
||||||
GROUP_COLOR,
|
group_color,
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
|
|
@ -3843,7 +3898,7 @@ where
|
||||||
8,
|
8,
|
||||||
alpha * 0.40,
|
alpha * 0.40,
|
||||||
output_scale,
|
output_scale,
|
||||||
GROUP_COLOR,
|
group_color,
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
|
|
@ -3907,7 +3962,7 @@ where
|
||||||
8,
|
8,
|
||||||
alpha * 0.15,
|
alpha * 0.15,
|
||||||
output_scale,
|
output_scale,
|
||||||
GROUP_COLOR,
|
group_color,
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
|
|
@ -3971,7 +4026,7 @@ where
|
||||||
pill_geo,
|
pill_geo,
|
||||||
8.,
|
8.,
|
||||||
alpha * 0.4,
|
alpha * 0.4,
|
||||||
GROUP_COLOR,
|
group_color,
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
|
|
@ -4001,7 +4056,7 @@ where
|
||||||
} else {
|
} else {
|
||||||
0.15
|
0.15
|
||||||
},
|
},
|
||||||
GROUP_COLOR,
|
group_color,
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
|
|
@ -4077,7 +4132,7 @@ where
|
||||||
),
|
),
|
||||||
8.,
|
8.,
|
||||||
alpha * 0.4,
|
alpha * 0.4,
|
||||||
GROUP_COLOR,
|
group_color,
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
|
|
@ -4119,7 +4174,7 @@ where
|
||||||
),
|
),
|
||||||
8.,
|
8.,
|
||||||
alpha * 0.4,
|
alpha * 0.4,
|
||||||
GROUP_COLOR,
|
group_color,
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
|
|
@ -4150,7 +4205,7 @@ where
|
||||||
8,
|
8,
|
||||||
alpha * 0.40,
|
alpha * 0.40,
|
||||||
output_scale,
|
output_scale,
|
||||||
GROUP_COLOR,
|
group_color,
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
|
|
@ -4158,6 +4213,8 @@ where
|
||||||
geo.size -= (gap * 2, gap * 2).into();
|
geo.size -= (gap * 2, gap * 2).into();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let accent = theme.accent.base;
|
||||||
|
|
||||||
if focused
|
if focused
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|focused_id| {
|
.map(|focused_id| {
|
||||||
|
|
@ -4172,9 +4229,9 @@ where
|
||||||
Some(Some(TargetZone::WindowStack(stack_id, _)))
|
Some(Some(TargetZone::WindowStack(stack_id, _)))
|
||||||
if *stack_id == node_id =>
|
if *stack_id == node_id =>
|
||||||
{
|
{
|
||||||
ACTIVE_GROUP_COLOR
|
[accent.red, accent.green, accent.blue]
|
||||||
}
|
}
|
||||||
_ => GROUP_COLOR,
|
_ => group_color,
|
||||||
};
|
};
|
||||||
geo.loc += (WINDOW_BACKDROP_BORDER, WINDOW_BACKDROP_BORDER).into();
|
geo.loc += (WINDOW_BACKDROP_BORDER, WINDOW_BACKDROP_BORDER).into();
|
||||||
geo.size -=
|
geo.size -=
|
||||||
|
|
@ -4189,7 +4246,9 @@ where
|
||||||
* if focused
|
* if focused
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|focused_id| focused_id == &node_id)
|
.map(|focused_id| focused_id == &node_id)
|
||||||
.unwrap_or(color == ACTIVE_GROUP_COLOR)
|
.unwrap_or(
|
||||||
|
color == [accent.red, accent.green, accent.blue],
|
||||||
|
)
|
||||||
{
|
{
|
||||||
0.4
|
0.4
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -4243,7 +4302,7 @@ where
|
||||||
geo,
|
geo,
|
||||||
8.,
|
8.,
|
||||||
alpha * 0.4,
|
alpha * 0.4,
|
||||||
GROUP_COLOR,
|
group_color,
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
|
|
@ -4417,6 +4476,7 @@ fn render_new_tree<R>(
|
||||||
swap_desc: Option<NodeDesc>,
|
swap_desc: Option<NodeDesc>,
|
||||||
swapping_stack_surface_id: &Id,
|
swapping_stack_surface_id: &Id,
|
||||||
placeholder_id: &Id,
|
placeholder_id: &Id,
|
||||||
|
theme: &cosmic::theme::CosmicTheme,
|
||||||
) -> (
|
) -> (
|
||||||
Vec<CosmicMappedRenderElement<R>>,
|
Vec<CosmicMappedRenderElement<R>>,
|
||||||
Vec<CosmicMappedRenderElement<R>>,
|
Vec<CosmicMappedRenderElement<R>>,
|
||||||
|
|
@ -4476,7 +4536,8 @@ where
|
||||||
let (swap_indicator, swap_tree) = overview.1.unzip();
|
let (swap_indicator, swap_tree) = overview.1.unzip();
|
||||||
let swap_tree = swap_tree.flatten().filter(|_| is_active_output);
|
let swap_tree = swap_tree.flatten().filter(|_| is_active_output);
|
||||||
let swap_desc = swap_desc.filter(|_| is_active_output);
|
let swap_desc = swap_desc.filter(|_| is_active_output);
|
||||||
|
let window_hint = crate::theme::active_window_hint(theme);
|
||||||
|
let group_color = group_color(theme);
|
||||||
// render placeholder, if we are swapping to an empty workspace
|
// render placeholder, if we are swapping to an empty workspace
|
||||||
if target_tree.root_node_id().is_none() && swap_desc.is_some() {
|
if target_tree.root_node_id().is_none() && swap_desc.is_some() {
|
||||||
window_elements.push(
|
window_elements.push(
|
||||||
|
|
@ -4486,7 +4547,7 @@ where
|
||||||
focused_geo,
|
focused_geo,
|
||||||
8.,
|
8.,
|
||||||
transition.unwrap_or(1.0) * 0.4,
|
transition.unwrap_or(1.0) * 0.4,
|
||||||
GROUP_COLOR,
|
group_color,
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
|
|
@ -4518,6 +4579,7 @@ where
|
||||||
4,
|
4,
|
||||||
output_scale,
|
output_scale,
|
||||||
transition.unwrap_or(1.0),
|
transition.unwrap_or(1.0),
|
||||||
|
[window_hint.red, window_hint.green, window_hint.blue],
|
||||||
));
|
));
|
||||||
|
|
||||||
let render_loc =
|
let render_loc =
|
||||||
|
|
@ -4679,7 +4741,7 @@ where
|
||||||
geo,
|
geo,
|
||||||
8.,
|
8.,
|
||||||
0.4,
|
0.4,
|
||||||
GROUP_COLOR,
|
group_color,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4706,6 +4768,7 @@ where
|
||||||
},
|
},
|
||||||
output_scale,
|
output_scale,
|
||||||
1.0,
|
1.0,
|
||||||
|
[window_hint.red, window_hint.green, window_hint.blue],
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4825,7 +4888,7 @@ where
|
||||||
geo,
|
geo,
|
||||||
0.0,
|
0.0,
|
||||||
0.3,
|
0.3,
|
||||||
GROUP_COLOR,
|
group_color,
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -163,6 +163,7 @@ pub struct Shell {
|
||||||
pub xdg_shell_state: XdgShellState,
|
pub xdg_shell_state: XdgShellState,
|
||||||
pub workspace_state: WorkspaceState<State>,
|
pub workspace_state: WorkspaceState<State>,
|
||||||
|
|
||||||
|
theme: cosmic::Theme,
|
||||||
overview_mode: OverviewMode,
|
overview_mode: OverviewMode,
|
||||||
swap_indicator: Option<SwapIndicator>,
|
swap_indicator: Option<SwapIndicator>,
|
||||||
resize_mode: ResizeMode,
|
resize_mode: ResizeMode,
|
||||||
|
|
@ -184,8 +185,8 @@ pub struct WorkspaceSet {
|
||||||
group: WorkspaceGroupHandle,
|
group: WorkspaceGroupHandle,
|
||||||
idx: usize,
|
idx: usize,
|
||||||
tiling_enabled: bool,
|
tiling_enabled: bool,
|
||||||
gaps: (u8, u8),
|
|
||||||
output: Output,
|
output: Output,
|
||||||
|
theme: cosmic::Theme,
|
||||||
pub(crate) workspaces: Vec<Workspace>,
|
pub(crate) workspaces: Vec<Workspace>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -201,7 +202,7 @@ fn create_workspace(
|
||||||
group_handle: &WorkspaceGroupHandle,
|
group_handle: &WorkspaceGroupHandle,
|
||||||
active: bool,
|
active: bool,
|
||||||
tiling: bool,
|
tiling: bool,
|
||||||
gaps: (u8, u8),
|
theme: cosmic::Theme,
|
||||||
) -> Workspace {
|
) -> Workspace {
|
||||||
let workspace_handle = state.create_workspace(&group_handle).unwrap();
|
let workspace_handle = state.create_workspace(&group_handle).unwrap();
|
||||||
if active {
|
if active {
|
||||||
|
|
@ -211,7 +212,7 @@ fn create_workspace(
|
||||||
&workspace_handle,
|
&workspace_handle,
|
||||||
[WorkspaceCapabilities::Activate].into_iter(),
|
[WorkspaceCapabilities::Activate].into_iter(),
|
||||||
);
|
);
|
||||||
Workspace::new(workspace_handle, output.clone(), tiling, gaps)
|
Workspace::new(workspace_handle, output.clone(), tiling, theme.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WorkspaceSet {
|
impl WorkspaceSet {
|
||||||
|
|
@ -222,12 +223,18 @@ impl WorkspaceSet {
|
||||||
amount: WorkspaceAmount,
|
amount: WorkspaceAmount,
|
||||||
idx: usize,
|
idx: usize,
|
||||||
tiling_enabled: bool,
|
tiling_enabled: bool,
|
||||||
gaps: (u8, u8),
|
theme: cosmic::Theme,
|
||||||
) -> WorkspaceSet {
|
) -> WorkspaceSet {
|
||||||
let workspaces = match amount {
|
let workspaces = match amount {
|
||||||
WorkspaceAmount::Dynamic => {
|
WorkspaceAmount::Dynamic => {
|
||||||
let workspace =
|
let workspace = create_workspace(
|
||||||
create_workspace(state, output, &group_handle, true, tiling_enabled, gaps);
|
state,
|
||||||
|
output,
|
||||||
|
&group_handle,
|
||||||
|
true,
|
||||||
|
tiling_enabled,
|
||||||
|
theme.clone(),
|
||||||
|
);
|
||||||
workspace_set_idx(state, 1, idx, &workspace.handle);
|
workspace_set_idx(state, 1, idx, &workspace.handle);
|
||||||
state.set_workspace_capabilities(
|
state.set_workspace_capabilities(
|
||||||
&workspace.handle,
|
&workspace.handle,
|
||||||
|
|
@ -243,7 +250,7 @@ impl WorkspaceSet {
|
||||||
&group_handle,
|
&group_handle,
|
||||||
i == 0,
|
i == 0,
|
||||||
tiling_enabled,
|
tiling_enabled,
|
||||||
gaps,
|
theme.clone(),
|
||||||
);
|
);
|
||||||
workspace_set_idx(state, i + 1, idx, &workspace.handle);
|
workspace_set_idx(state, i + 1, idx, &workspace.handle);
|
||||||
state.set_workspace_capabilities(
|
state.set_workspace_capabilities(
|
||||||
|
|
@ -261,7 +268,7 @@ impl WorkspaceSet {
|
||||||
group: group_handle,
|
group: group_handle,
|
||||||
idx,
|
idx,
|
||||||
tiling_enabled,
|
tiling_enabled,
|
||||||
gaps,
|
theme,
|
||||||
workspaces,
|
workspaces,
|
||||||
output: output.clone(),
|
output: output.clone(),
|
||||||
}
|
}
|
||||||
|
|
@ -316,7 +323,7 @@ impl WorkspaceSet {
|
||||||
&self.group,
|
&self.group,
|
||||||
false,
|
false,
|
||||||
self.tiling_enabled,
|
self.tiling_enabled,
|
||||||
self.gaps,
|
self.theme.clone(),
|
||||||
);
|
);
|
||||||
workspace_set_idx(
|
workspace_set_idx(
|
||||||
state,
|
state,
|
||||||
|
|
@ -411,7 +418,7 @@ impl WorkspaceSet {
|
||||||
&self.group,
|
&self.group,
|
||||||
false,
|
false,
|
||||||
self.tiling_enabled,
|
self.tiling_enabled,
|
||||||
self.gaps,
|
self.theme.clone(),
|
||||||
);
|
);
|
||||||
workspace_set_idx(
|
workspace_set_idx(
|
||||||
state,
|
state,
|
||||||
|
|
@ -452,18 +459,18 @@ pub struct Workspaces {
|
||||||
amount: WorkspaceAmount,
|
amount: WorkspaceAmount,
|
||||||
mode: WorkspaceMode,
|
mode: WorkspaceMode,
|
||||||
tiling_enabled: bool,
|
tiling_enabled: bool,
|
||||||
gaps: (u8, u8),
|
theme: cosmic::Theme,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Workspaces {
|
impl Workspaces {
|
||||||
pub fn new(config: &Config) -> Workspaces {
|
pub fn new(config: &Config, theme: cosmic::Theme) -> Workspaces {
|
||||||
Workspaces {
|
Workspaces {
|
||||||
sets: IndexMap::new(),
|
sets: IndexMap::new(),
|
||||||
backup_set: None,
|
backup_set: None,
|
||||||
amount: config.static_conf.workspace_amount,
|
amount: config.static_conf.workspace_amount,
|
||||||
mode: config.static_conf.workspace_mode,
|
mode: config.static_conf.workspace_mode,
|
||||||
tiling_enabled: config.static_conf.tiling_enabled,
|
tiling_enabled: config.static_conf.tiling_enabled,
|
||||||
gaps: config.static_conf.gaps,
|
theme,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -500,7 +507,7 @@ impl Workspaces {
|
||||||
self.amount,
|
self.amount,
|
||||||
self.sets.len(),
|
self.sets.len(),
|
||||||
self.tiling_enabled,
|
self.tiling_enabled,
|
||||||
self.gaps,
|
self.theme.clone(),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
workspace_state.add_group_output(&set.group, &output);
|
workspace_state.add_group_output(&set.group, &output);
|
||||||
|
|
@ -674,7 +681,7 @@ impl Workspaces {
|
||||||
&group,
|
&group,
|
||||||
false,
|
false,
|
||||||
config.static_conf.tiling_enabled,
|
config.static_conf.tiling_enabled,
|
||||||
config.static_conf.gaps,
|
self.theme.clone(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
// Otherwise just update
|
// Otherwise just update
|
||||||
|
|
@ -882,6 +889,24 @@ impl Workspaces {
|
||||||
set.update_tiling_status(seat, tiling)
|
set.update_tiling_status(seat, tiling)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_theme(&mut self, theme: cosmic::Theme) {
|
||||||
|
for (_, s) in &mut self.sets {
|
||||||
|
s.theme = theme.clone();
|
||||||
|
for mut w in &mut s.workspaces {
|
||||||
|
w.tiling_layer.theme = theme.clone();
|
||||||
|
|
||||||
|
w.mapped().for_each(|m| {
|
||||||
|
m.update_theme(theme.clone());
|
||||||
|
m.force_redraw();
|
||||||
|
});
|
||||||
|
|
||||||
|
w.refresh();
|
||||||
|
w.dirty.store(true, Ordering::Relaxed);
|
||||||
|
w.recalculate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct InvalidWorkspaceIndex;
|
pub struct InvalidWorkspaceIndex;
|
||||||
|
|
@ -910,10 +935,11 @@ impl Shell {
|
||||||
//|client| client.get_data::<ClientState>().map_or(false, |s| s.privileged),
|
//|client| client.get_data::<ClientState>().map_or(false, |s| s.privileged),
|
||||||
client_has_security_context,
|
client_has_security_context,
|
||||||
);
|
);
|
||||||
|
let theme = cosmic::theme::system_preference();
|
||||||
|
|
||||||
Shell {
|
Shell {
|
||||||
popups: PopupManager::default(),
|
popups: PopupManager::default(),
|
||||||
workspaces: Workspaces::new(config),
|
workspaces: Workspaces::new(config, theme.clone()),
|
||||||
maximize_mode: MaximizeMode::Floating,
|
maximize_mode: MaximizeMode::Floating,
|
||||||
|
|
||||||
pending_windows: Vec::new(),
|
pending_windows: Vec::new(),
|
||||||
|
|
@ -926,6 +952,7 @@ impl Shell {
|
||||||
xdg_shell_state,
|
xdg_shell_state,
|
||||||
workspace_state,
|
workspace_state,
|
||||||
|
|
||||||
|
theme,
|
||||||
overview_mode: OverviewMode::None,
|
overview_mode: OverviewMode::None,
|
||||||
swap_indicator: None,
|
swap_indicator: None,
|
||||||
resize_mode: ResizeMode::None,
|
resize_mode: ResizeMode::None,
|
||||||
|
|
@ -1158,7 +1185,7 @@ impl Shell {
|
||||||
if let Some(trigger) = enabled {
|
if let Some(trigger) = enabled {
|
||||||
if !matches!(self.overview_mode, OverviewMode::Started(_, _)) {
|
if !matches!(self.overview_mode, OverviewMode::Started(_, _)) {
|
||||||
if matches!(trigger, Trigger::KeyboardSwap(_, _)) {
|
if matches!(trigger, Trigger::KeyboardSwap(_, _)) {
|
||||||
self.swap_indicator = Some(swap_indicator(evlh));
|
self.swap_indicator = Some(swap_indicator(evlh, self.theme.clone()));
|
||||||
}
|
}
|
||||||
self.overview_mode = OverviewMode::Started(trigger, Instant::now());
|
self.overview_mode = OverviewMode::Started(trigger, Instant::now());
|
||||||
}
|
}
|
||||||
|
|
@ -1204,7 +1231,12 @@ impl Shell {
|
||||||
} else {
|
} else {
|
||||||
self.resize_mode = ResizeMode::Started(pattern, Instant::now(), direction);
|
self.resize_mode = ResizeMode::Started(pattern, Instant::now(), direction);
|
||||||
}
|
}
|
||||||
self.resize_indicator = Some(resize_indicator(direction, config, evlh));
|
self.resize_indicator = Some(resize_indicator(
|
||||||
|
direction,
|
||||||
|
config,
|
||||||
|
evlh,
|
||||||
|
self.theme.clone(),
|
||||||
|
));
|
||||||
} else {
|
} else {
|
||||||
if let ResizeMode::Started(_, _, direction) = &self.resize_mode {
|
if let ResizeMode::Started(_, _, direction) = &self.resize_mode {
|
||||||
self.resize_mode = ResizeMode::Ended(Instant::now(), *direction);
|
self.resize_mode = ResizeMode::Ended(Instant::now(), *direction);
|
||||||
|
|
@ -1338,6 +1370,7 @@ impl Shell {
|
||||||
let mapped = CosmicMapped::from(CosmicWindow::new(
|
let mapped = CosmicMapped::from(CosmicWindow::new(
|
||||||
window.clone(),
|
window.clone(),
|
||||||
state.common.event_loop_handle.clone(),
|
state.common.event_loop_handle.clone(),
|
||||||
|
state.common.theme.clone(),
|
||||||
));
|
));
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
{
|
{
|
||||||
|
|
@ -1579,12 +1612,13 @@ impl Shell {
|
||||||
.find(|(w, _)| w.wl_surface().as_ref() == Some(surface))
|
.find(|(w, _)| w.wl_surface().as_ref() == Some(surface))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let button = start_data.button;
|
let button = start_data.button;
|
||||||
|
let active_hint = state.common.theme.cosmic().active_hint as u8;
|
||||||
if let Some(grab) = workspace.move_request(
|
if let Some(grab) = workspace.move_request(
|
||||||
&window,
|
&window,
|
||||||
&seat,
|
&seat,
|
||||||
&output,
|
&output,
|
||||||
start_data,
|
start_data,
|
||||||
state.common.config.static_conf.active_hint,
|
active_hint as u8,
|
||||||
) {
|
) {
|
||||||
let handle = workspace.handle;
|
let handle = workspace.handle;
|
||||||
state
|
state
|
||||||
|
|
@ -1684,6 +1718,12 @@ impl Shell {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn set_theme(&mut self, theme: cosmic::Theme) {
|
||||||
|
self.theme = theme.clone();
|
||||||
|
self.refresh();
|
||||||
|
self.workspaces.set_theme(theme.clone());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn workspace_set_idx<'a>(
|
fn workspace_set_idx<'a>(
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ use crate::{
|
||||||
xwayland::XWaylandState,
|
xwayland::XWaylandState,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use cosmic::theme::CosmicTheme;
|
||||||
use id_tree::Tree;
|
use id_tree::Tree;
|
||||||
use indexmap::IndexSet;
|
use indexmap::IndexSet;
|
||||||
use keyframe::{ease, functions::EaseInOutCubic};
|
use keyframe::{ease, functions::EaseInOutCubic};
|
||||||
|
|
@ -210,9 +211,9 @@ impl Workspace {
|
||||||
handle: WorkspaceHandle,
|
handle: WorkspaceHandle,
|
||||||
output: Output,
|
output: Output,
|
||||||
tiling_enabled: bool,
|
tiling_enabled: bool,
|
||||||
gaps: (u8, u8),
|
theme: cosmic::Theme,
|
||||||
) -> Workspace {
|
) -> Workspace {
|
||||||
let tiling_layer = TilingLayout::new(gaps, &output);
|
let tiling_layer = TilingLayout::new(theme, &output);
|
||||||
let floating_layer = FloatingLayout::new(&output);
|
let floating_layer = FloatingLayout::new(&output);
|
||||||
|
|
||||||
Workspace {
|
Workspace {
|
||||||
|
|
@ -824,7 +825,7 @@ impl Workspace {
|
||||||
MoveResult::MoveFurther(KeyboardFocusTarget::Fullscreen(f.surface.clone()))
|
MoveResult::MoveFurther(KeyboardFocusTarget::Fullscreen(f.surface.clone()))
|
||||||
} else {
|
} else {
|
||||||
self.floating_layer
|
self.floating_layer
|
||||||
.move_current_element(direction, seat)
|
.move_current_element(direction, seat, self.tiling_layer.theme.clone())
|
||||||
.or_else(|| self.tiling_layer.move_current_node(direction, seat))
|
.or_else(|| self.tiling_layer.move_current_node(direction, seat))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -838,6 +839,7 @@ impl Workspace {
|
||||||
overview: (OverviewMode, Option<(SwapIndicator, Option<&Tree<Data>>)>),
|
overview: (OverviewMode, Option<(SwapIndicator, Option<&Tree<Data>>)>),
|
||||||
resize_indicator: Option<(ResizeMode, ResizeIndicator)>,
|
resize_indicator: Option<(ResizeMode, ResizeIndicator)>,
|
||||||
indicator_thickness: u8,
|
indicator_thickness: u8,
|
||||||
|
theme: &CosmicTheme,
|
||||||
) -> Result<
|
) -> Result<
|
||||||
(
|
(
|
||||||
Vec<WorkspaceRenderElement<R>>,
|
Vec<WorkspaceRenderElement<R>>,
|
||||||
|
|
@ -1014,6 +1016,7 @@ impl Workspace {
|
||||||
resize_indicator.clone(),
|
resize_indicator.clone(),
|
||||||
indicator_thickness,
|
indicator_thickness,
|
||||||
alpha,
|
alpha,
|
||||||
|
theme,
|
||||||
);
|
);
|
||||||
popup_elements.extend(p_elements.into_iter().map(WorkspaceRenderElement::from));
|
popup_elements.extend(p_elements.into_iter().map(WorkspaceRenderElement::from));
|
||||||
window_elements.extend(w_elements.into_iter().map(WorkspaceRenderElement::from));
|
window_elements.extend(w_elements.into_iter().map(WorkspaceRenderElement::from));
|
||||||
|
|
@ -1038,6 +1041,7 @@ impl Workspace {
|
||||||
overview,
|
overview,
|
||||||
resize_indicator,
|
resize_indicator,
|
||||||
indicator_thickness,
|
indicator_thickness,
|
||||||
|
theme,
|
||||||
)?;
|
)?;
|
||||||
popup_elements.extend(p_elements.into_iter().map(WorkspaceRenderElement::from));
|
popup_elements.extend(p_elements.into_iter().map(WorkspaceRenderElement::from));
|
||||||
window_elements.extend(w_elements.into_iter().map(WorkspaceRenderElement::from));
|
window_elements.extend(w_elements.into_iter().map(WorkspaceRenderElement::from));
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,8 @@ pub struct Common {
|
||||||
pub clock: Clock<Monotonic>,
|
pub clock: Clock<Monotonic>,
|
||||||
pub should_stop: bool,
|
pub should_stop: bool,
|
||||||
|
|
||||||
|
pub theme: cosmic::Theme,
|
||||||
|
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
pub egui: Egui,
|
pub egui: Egui,
|
||||||
|
|
||||||
|
|
@ -330,6 +332,8 @@ impl State {
|
||||||
clock,
|
clock,
|
||||||
should_stop: false,
|
should_stop: false,
|
||||||
|
|
||||||
|
theme: cosmic::theme::system_preference(),
|
||||||
|
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
egui: Egui {
|
egui: Egui {
|
||||||
active: false,
|
active: false,
|
||||||
|
|
|
||||||
77
src/theme.rs
Normal file
77
src/theme.rs
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
// insert into the event loop, a watcher for the theme & theme mode for changes
|
||||||
|
|
||||||
|
// update a Arc<Mutex<Theme>> in the state on change of the theme and mark all interfaces for a redraw.
|
||||||
|
|
||||||
|
use calloop::LoopHandle;
|
||||||
|
use cosmic::cosmic_theme::{
|
||||||
|
palette::{self, Srgba},
|
||||||
|
Theme, ThemeMode,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::state::State;
|
||||||
|
|
||||||
|
pub(crate) fn clear_color(theme: &Theme<Srgba>) -> [f32; 4] {
|
||||||
|
let neutral_2 = theme.palette.neutral_2;
|
||||||
|
[
|
||||||
|
neutral_2.red,
|
||||||
|
neutral_2.green,
|
||||||
|
neutral_2.blue,
|
||||||
|
neutral_2.alpha,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn group_color(theme: &Theme<Srgba>) -> [f32; 3] {
|
||||||
|
let neutral_8 = theme.palette.neutral_8;
|
||||||
|
[neutral_8.red, neutral_8.green, neutral_8.blue]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn active_window_hint(theme: &Theme<Srgba>) -> palette::Srgba {
|
||||||
|
if let Some(hint) = theme.window_hint {
|
||||||
|
palette::Srgba::from(hint)
|
||||||
|
} else {
|
||||||
|
theme.accent_color()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn watch_theme(handle: LoopHandle<'_, State>) -> Result<(), cosmic_config::Error> {
|
||||||
|
let (ping_tx, ping_rx) = calloop::ping::make_ping().unwrap();
|
||||||
|
let config_mode_helper = ThemeMode::config()?;
|
||||||
|
let config_dark_helper = Theme::<palette::Srgba>::dark_config()?;
|
||||||
|
let config_light_helper = Theme::<palette::Srgba>::light_config()?;
|
||||||
|
|
||||||
|
if let Err(e) = handle.insert_source(ping_rx, move |_, _, state| {
|
||||||
|
let new_theme = cosmic::theme::system_preference();
|
||||||
|
let theme = &mut state.common.theme;
|
||||||
|
|
||||||
|
if theme.theme_type != new_theme.theme_type {
|
||||||
|
*theme = new_theme;
|
||||||
|
state.common.shell.set_theme(theme.clone());
|
||||||
|
state.common.shell.workspaces.spaces().for_each(|s| {
|
||||||
|
s.mapped().for_each(|m| {
|
||||||
|
m.update_theme(theme.clone());
|
||||||
|
m.force_redraw();
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
tracing::error!("{e}");
|
||||||
|
};
|
||||||
|
|
||||||
|
let ping_tx_clone = ping_tx.clone();
|
||||||
|
let theme_watcher_mode = config_mode_helper.watch(move |_, _keys| {
|
||||||
|
ping_tx_clone.ping();
|
||||||
|
})?;
|
||||||
|
let ping_tx_clone = ping_tx.clone();
|
||||||
|
let theme_watcher_light = config_light_helper.watch(move |_, _keys| {
|
||||||
|
ping_tx_clone.ping();
|
||||||
|
})?;
|
||||||
|
let theme_watcher_dark = config_dark_helper.watch(move |_, _keys| {
|
||||||
|
ping_tx.ping();
|
||||||
|
})?;
|
||||||
|
|
||||||
|
std::mem::forget(theme_watcher_dark);
|
||||||
|
std::mem::forget(theme_watcher_light);
|
||||||
|
std::mem::forget(theme_watcher_mode);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
@ -229,6 +229,7 @@ impl<P: Program + Send + 'static> IcedElement<P> {
|
||||||
program: P,
|
program: P,
|
||||||
size: impl Into<Size<i32, Logical>>,
|
size: impl Into<Size<i32, Logical>>,
|
||||||
handle: LoopHandle<'static, crate::state::State>,
|
handle: LoopHandle<'static, crate::state::State>,
|
||||||
|
theme: cosmic::Theme,
|
||||||
) -> IcedElement<P> {
|
) -> IcedElement<P> {
|
||||||
let size = size.into();
|
let size = size.into();
|
||||||
let mut renderer =
|
let mut renderer =
|
||||||
|
|
@ -257,7 +258,7 @@ impl<P: Program + Send + 'static> IcedElement<P> {
|
||||||
pending_update: None,
|
pending_update: None,
|
||||||
size,
|
size,
|
||||||
cursor_pos: None,
|
cursor_pos: None,
|
||||||
theme: Theme::dark(), // TODO
|
theme,
|
||||||
renderer,
|
renderer,
|
||||||
state,
|
state,
|
||||||
debug,
|
debug,
|
||||||
|
|
@ -308,6 +309,11 @@ impl<P: Program + Send + 'static> IcedElement<P> {
|
||||||
self.0.lock().unwrap().update(true);
|
self.0.lock().unwrap().update(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_theme(&self, theme: cosmic::Theme) {
|
||||||
|
let mut guard = self.0.lock().unwrap();
|
||||||
|
guard.theme = theme.clone();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn force_redraw(&self) {
|
pub fn force_redraw(&self) {
|
||||||
let mut internal = self.0.lock().unwrap();
|
let mut internal = self.0.lock().unwrap();
|
||||||
for (_buffer, ref mut old_primitives) in internal.buffers.values_mut() {
|
for (_buffer, ref mut old_primitives) in internal.buffers.values_mut() {
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ use crate::{
|
||||||
backend::render::{
|
backend::render::{
|
||||||
cursor,
|
cursor,
|
||||||
element::{AsGlowRenderer, CosmicElement},
|
element::{AsGlowRenderer, CosmicElement},
|
||||||
render_output, render_workspace, CursorMode, CLEAR_COLOR,
|
render_output, render_workspace, CursorMode,
|
||||||
},
|
},
|
||||||
shell::{CosmicMappedRenderElement, CosmicSurface, WorkspaceRenderElement},
|
shell::{CosmicMappedRenderElement, CosmicSurface, WorkspaceRenderElement},
|
||||||
state::{BackendData, ClientState, Common, State},
|
state::{BackendData, ClientState, Common, State},
|
||||||
|
|
@ -1015,7 +1015,12 @@ pub fn render_window_to_buffer(
|
||||||
renderer.bind(render_buffer).map_err(DTError::Rendering)?;
|
renderer.bind(render_buffer).map_err(DTError::Rendering)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
dt.render_output(renderer, age, &elements, CLEAR_COLOR)
|
dt.render_output(
|
||||||
|
renderer,
|
||||||
|
age,
|
||||||
|
&elements,
|
||||||
|
crate::theme::clear_color(common.theme.cosmic()),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
let node = node_from_params(¶ms, &mut state.backend, None);
|
let node = node_from_params(¶ms, &mut state.backend, None);
|
||||||
|
|
|
||||||
|
|
@ -220,6 +220,7 @@ impl XdgShellHandler for State {
|
||||||
CosmicMapped::from(CosmicWindow::new(
|
CosmicMapped::from(CosmicWindow::new(
|
||||||
surface,
|
surface,
|
||||||
self.common.event_loop_handle.clone(),
|
self.common.event_loop_handle.clone(),
|
||||||
|
self.common.theme.clone(),
|
||||||
)),
|
)),
|
||||||
if workspace.is_tiled(&mapped) {
|
if workspace.is_tiled(&mapped) {
|
||||||
ManagedLayer::Tiling
|
ManagedLayer::Tiling
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue