improv(appearance): use context drawer for all color pick options
This commit is contained in:
parent
82b96d1951
commit
71cfd2d2f0
13 changed files with 193 additions and 381 deletions
60
Cargo.lock
generated
60
Cargo.lock
generated
|
|
@ -743,9 +743,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.89"
|
||||
version = "1.0.90"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0ba8f7aaa012f30d5b2861462f6708eccd49c3c39863fe083a308035f63d723"
|
||||
checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5"
|
||||
|
||||
[[package]]
|
||||
name = "cfb"
|
||||
|
|
@ -1086,7 +1086,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cosmic-config"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#801c502c36c4c7d3b6cfa7f41f34f2c093877030"
|
||||
source = "git+https://github.com/pop-os/libcosmic#422d9126342d94aa8a8a04be0bd76036fdbcf01c"
|
||||
dependencies = [
|
||||
"atomicwrites",
|
||||
"calloop",
|
||||
|
|
@ -1104,7 +1104,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cosmic-config-derive"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#801c502c36c4c7d3b6cfa7f41f34f2c093877030"
|
||||
source = "git+https://github.com/pop-os/libcosmic#422d9126342d94aa8a8a04be0bd76036fdbcf01c"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
|
|
@ -1273,7 +1273,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cosmic-theme"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#801c502c36c4c7d3b6cfa7f41f34f2c093877030"
|
||||
source = "git+https://github.com/pop-os/libcosmic#422d9126342d94aa8a8a04be0bd76036fdbcf01c"
|
||||
dependencies = [
|
||||
"almost",
|
||||
"cosmic-config",
|
||||
|
|
@ -2559,7 +2559,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced"
|
||||
version = "0.12.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#801c502c36c4c7d3b6cfa7f41f34f2c093877030"
|
||||
source = "git+https://github.com/pop-os/libcosmic#422d9126342d94aa8a8a04be0bd76036fdbcf01c"
|
||||
dependencies = [
|
||||
"iced_accessibility",
|
||||
"iced_core",
|
||||
|
|
@ -2574,7 +2574,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_accessibility"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#801c502c36c4c7d3b6cfa7f41f34f2c093877030"
|
||||
source = "git+https://github.com/pop-os/libcosmic#422d9126342d94aa8a8a04be0bd76036fdbcf01c"
|
||||
dependencies = [
|
||||
"accesskit",
|
||||
"accesskit_unix",
|
||||
|
|
@ -2583,7 +2583,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_core"
|
||||
version = "0.12.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#801c502c36c4c7d3b6cfa7f41f34f2c093877030"
|
||||
source = "git+https://github.com/pop-os/libcosmic#422d9126342d94aa8a8a04be0bd76036fdbcf01c"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"iced_accessibility",
|
||||
|
|
@ -2602,7 +2602,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_futures"
|
||||
version = "0.12.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#801c502c36c4c7d3b6cfa7f41f34f2c093877030"
|
||||
source = "git+https://github.com/pop-os/libcosmic#422d9126342d94aa8a8a04be0bd76036fdbcf01c"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"iced_core",
|
||||
|
|
@ -2615,7 +2615,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_graphics"
|
||||
version = "0.12.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#801c502c36c4c7d3b6cfa7f41f34f2c093877030"
|
||||
source = "git+https://github.com/pop-os/libcosmic#422d9126342d94aa8a8a04be0bd76036fdbcf01c"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bytemuck",
|
||||
|
|
@ -2639,7 +2639,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_renderer"
|
||||
version = "0.12.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#801c502c36c4c7d3b6cfa7f41f34f2c093877030"
|
||||
source = "git+https://github.com/pop-os/libcosmic#422d9126342d94aa8a8a04be0bd76036fdbcf01c"
|
||||
dependencies = [
|
||||
"iced_graphics",
|
||||
"iced_tiny_skia",
|
||||
|
|
@ -2651,7 +2651,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_runtime"
|
||||
version = "0.12.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#801c502c36c4c7d3b6cfa7f41f34f2c093877030"
|
||||
source = "git+https://github.com/pop-os/libcosmic#422d9126342d94aa8a8a04be0bd76036fdbcf01c"
|
||||
dependencies = [
|
||||
"iced_accessibility",
|
||||
"iced_core",
|
||||
|
|
@ -2663,7 +2663,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_sctk"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#801c502c36c4c7d3b6cfa7f41f34f2c093877030"
|
||||
source = "git+https://github.com/pop-os/libcosmic#422d9126342d94aa8a8a04be0bd76036fdbcf01c"
|
||||
dependencies = [
|
||||
"enum-repr",
|
||||
"float-cmp",
|
||||
|
|
@ -2689,7 +2689,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_style"
|
||||
version = "0.12.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#801c502c36c4c7d3b6cfa7f41f34f2c093877030"
|
||||
source = "git+https://github.com/pop-os/libcosmic#422d9126342d94aa8a8a04be0bd76036fdbcf01c"
|
||||
dependencies = [
|
||||
"iced_core",
|
||||
"once_cell",
|
||||
|
|
@ -2699,7 +2699,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_tiny_skia"
|
||||
version = "0.12.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#801c502c36c4c7d3b6cfa7f41f34f2c093877030"
|
||||
source = "git+https://github.com/pop-os/libcosmic#422d9126342d94aa8a8a04be0bd76036fdbcf01c"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"cosmic-text",
|
||||
|
|
@ -2716,7 +2716,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_wgpu"
|
||||
version = "0.12.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#801c502c36c4c7d3b6cfa7f41f34f2c093877030"
|
||||
source = "git+https://github.com/pop-os/libcosmic#422d9126342d94aa8a8a04be0bd76036fdbcf01c"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bytemuck",
|
||||
|
|
@ -2735,7 +2735,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_widget"
|
||||
version = "0.12.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#801c502c36c4c7d3b6cfa7f41f34f2c093877030"
|
||||
source = "git+https://github.com/pop-os/libcosmic#422d9126342d94aa8a8a04be0bd76036fdbcf01c"
|
||||
dependencies = [
|
||||
"iced_renderer",
|
||||
"iced_runtime",
|
||||
|
|
@ -3132,7 +3132,7 @@ checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
|||
[[package]]
|
||||
name = "libcosmic"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#801c502c36c4c7d3b6cfa7f41f34f2c093877030"
|
||||
source = "git+https://github.com/pop-os/libcosmic#422d9126342d94aa8a8a04be0bd76036fdbcf01c"
|
||||
dependencies = [
|
||||
"apply",
|
||||
"ashpd 0.7.0",
|
||||
|
|
@ -4934,9 +4934,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "sysinfo"
|
||||
version = "0.30.6"
|
||||
version = "0.30.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6746919caf9f2a85bff759535664c060109f21975c5ac2e8652e60102bd4d196"
|
||||
checksum = "0c385888ef380a852a16209afc8cfad22795dd8873d69c9a14d2e2088f118d18"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"core-foundation-sys",
|
||||
|
|
@ -6237,9 +6237,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zbus"
|
||||
version = "3.15.1"
|
||||
version = "3.15.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5acecd3f8422f198b1a2f954bcc812fe89f3fa4281646f3da1da7925db80085d"
|
||||
checksum = "675d170b632a6ad49804c8cf2105d7c31eddd3312555cffd4b740e08e97c25e6"
|
||||
dependencies = [
|
||||
"async-broadcast",
|
||||
"async-executor",
|
||||
|
|
@ -6279,9 +6279,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zbus_macros"
|
||||
version = "3.15.1"
|
||||
version = "3.15.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2207eb71efebda17221a579ca78b45c4c5f116f074eb745c3a172e688ccf89f5"
|
||||
checksum = "7131497b0f887e8061b430c530240063d33bf9455fa34438f388a245da69e0a5"
|
||||
dependencies = [
|
||||
"proc-macro-crate 1.3.1",
|
||||
"proc-macro2",
|
||||
|
|
@ -6393,9 +6393,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zvariant"
|
||||
version = "3.15.1"
|
||||
version = "3.15.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c5b4fcf3660d30fc33ae5cd97e2017b23a96e85afd7a1dd014534cd0bf34ba67"
|
||||
checksum = "4eef2be88ba09b358d3b58aca6e41cd853631d44787f319a1383ca83424fb2db"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"enumflags2",
|
||||
|
|
@ -6408,9 +6408,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zvariant_derive"
|
||||
version = "3.15.1"
|
||||
version = "3.15.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0277758a8a0afc0e573e80ed5bfd9d9c2b48bd3108ffe09384f9f738c83f4a55"
|
||||
checksum = "37c24dc0bed72f5f90d1f8bb5b07228cbf63b3c6e9f82d82559d4bae666e7ed9"
|
||||
dependencies = [
|
||||
"proc-macro-crate 1.3.1",
|
||||
"proc-macro2",
|
||||
|
|
@ -6421,9 +6421,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zvariant_utils"
|
||||
version = "1.1.0"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00bedb16a193cc12451873fee2a1bc6550225acece0e36f333e68326c73c8172"
|
||||
checksum = "7234f0d811589db492d16893e3f21e8e2fd282e6d01b0cddee310322062cc200"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::config::Config;
|
||||
use crate::pages::desktop::appearance::COLOR_PICKER_DIALOG_ID;
|
||||
use crate::pages::desktop::{
|
||||
self, appearance,
|
||||
dock::{self, applets::ADD_DOCK_APPLET_DIALOGUE_ID},
|
||||
|
|
@ -166,10 +165,6 @@ impl cosmic::Application for SettingsApp {
|
|||
Message::PageMessage(crate::pages::Message::DockApplet(dock::applets::Message(
|
||||
applets_inner::Message::ClosedAppletDialog,
|
||||
)))
|
||||
} else if id == *COLOR_PICKER_DIALOG_ID {
|
||||
Message::PageMessage(crate::pages::Message::Appearance(
|
||||
appearance::Message::CloseRequested,
|
||||
))
|
||||
} else {
|
||||
return None;
|
||||
};
|
||||
|
|
@ -463,12 +458,6 @@ impl cosmic::Application for SettingsApp {
|
|||
return page.add_applet_view(crate::pages::Message::PanelApplet);
|
||||
}
|
||||
|
||||
if let Some(Some(page)) = (id == *appearance::COLOR_PICKER_DIALOG_ID)
|
||||
.then(|| self.pages.page::<appearance::Page>())
|
||||
{
|
||||
return page.color_picker_view();
|
||||
}
|
||||
|
||||
if let Some(Some(page)) =
|
||||
(id == *ADD_DOCK_APPLET_DIALOGUE_ID).then(|| self.pages.page::<dock::applets::Page>())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright 2023 System76 <info@system76.com>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::sync::Arc;
|
||||
|
||||
use apply::Apply;
|
||||
|
|
@ -8,53 +9,52 @@ use ashpd::desktop::file_chooser::{FileFilter, SelectedFiles};
|
|||
use cosmic::cosmic_config::{Config, ConfigSet, CosmicConfigEntry};
|
||||
use cosmic::cosmic_theme::palette::{FromColor, Hsv, Srgb, Srgba};
|
||||
use cosmic::cosmic_theme::{CornerRadii, Theme, ThemeBuilder, ThemeMode};
|
||||
use cosmic::iced::wayland::actions::window::SctkWindowSettings;
|
||||
use cosmic::iced::window;
|
||||
use cosmic::iced_core::{alignment, layout, Color, Length};
|
||||
use cosmic::iced_sctk::commands::window::{close_window, get_window};
|
||||
use cosmic::iced_core::{alignment, Color, Length};
|
||||
use cosmic::iced_widget::scrollable;
|
||||
use cosmic::prelude::CollectionWidget;
|
||||
use cosmic::widget::icon::{from_name, icon};
|
||||
use cosmic::widget::{
|
||||
button, color_picker::ColorPickerUpdate, container, header_bar, horizontal_space, row,
|
||||
settings, spin_button, text, ColorPickerModel,
|
||||
button, color_picker::ColorPickerUpdate, container, horizontal_space, row, settings,
|
||||
spin_button, text, ColorPickerModel,
|
||||
};
|
||||
use cosmic::{command, Command, Element};
|
||||
use cosmic_settings_page::Section;
|
||||
use cosmic_settings_page::{self as page, section};
|
||||
use cosmic_settings_wallpaper as wallpaper;
|
||||
use once_cell::sync::Lazy;
|
||||
use ron::ser::PrettyConfig;
|
||||
use slotmap::SlotMap;
|
||||
use tracing::warn;
|
||||
|
||||
use crate::app;
|
||||
|
||||
use super::wallpaper::widgets::color_image;
|
||||
|
||||
pub static COLOR_PICKER_DIALOG_ID: Lazy<window::Id> = Lazy::new(window::Id::unique);
|
||||
|
||||
crate::cache_dynamic_lazy! {
|
||||
static HEX: String = fl!("hex");
|
||||
static RGB: String = fl!("rgb");
|
||||
static RESET_TO_DEFAULT: String = fl!("reset-to-default");
|
||||
}
|
||||
|
||||
enum NamedColorPicker {
|
||||
CustomAccent,
|
||||
ApplicationBackground,
|
||||
InterfaceText,
|
||||
ControlComponent,
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
enum ContextView {
|
||||
AccentWindowHint,
|
||||
ApplicationBackground,
|
||||
ContainerBackground,
|
||||
ControlComponent,
|
||||
CustomAccent,
|
||||
InterfaceText,
|
||||
}
|
||||
|
||||
// TODO integrate with settings backend
|
||||
pub struct Page {
|
||||
can_reset: bool,
|
||||
theme_builder_needs_update: bool,
|
||||
context_view: Option<ContextView>,
|
||||
custom_accent: ColorPickerModel,
|
||||
accent_window_hint: ColorPickerModel,
|
||||
application_background: ColorPickerModel,
|
||||
container_background: ColorPickerModel,
|
||||
interface_text: ColorPickerModel,
|
||||
control_component: ColorPickerModel,
|
||||
active_dialog: Option<NamedColorPicker>,
|
||||
roundness: Roundness,
|
||||
no_custom_window_hint: bool,
|
||||
|
||||
|
|
@ -119,6 +119,8 @@ impl From<(Option<Config>, ThemeMode, Option<Config>, ThemeBuilder)> for Page {
|
|||
} else {
|
||||
theme_builder == ThemeBuilder::light()
|
||||
},
|
||||
theme_builder_needs_update: false,
|
||||
context_view: None,
|
||||
roundness: theme_builder.corner_radii.into(),
|
||||
custom_accent: ColorPickerModel::new(
|
||||
&*HEX,
|
||||
|
|
@ -157,7 +159,6 @@ impl From<(Option<Config>, ThemeMode, Option<Config>, ThemeBuilder)> for Page {
|
|||
theme_builder.window_hint.map(Color::from),
|
||||
),
|
||||
no_custom_window_hint: theme_builder.accent.is_some(),
|
||||
active_dialog: None,
|
||||
theme_mode_config,
|
||||
theme_builder_config,
|
||||
theme_mode,
|
||||
|
|
@ -206,7 +207,6 @@ impl From<(Option<Config>, ThemeMode)> for Page {
|
|||
pub enum Message {
|
||||
Entered,
|
||||
DarkMode(bool),
|
||||
DragColorPicker,
|
||||
Autoswitch(bool),
|
||||
Frosted(bool),
|
||||
WindowHintSize(spin_button::Message),
|
||||
|
|
@ -218,7 +218,6 @@ pub enum Message {
|
|||
CustomAccent(ColorPickerUpdate),
|
||||
InterfaceText(ColorPickerUpdate),
|
||||
ControlComponent(ColorPickerUpdate),
|
||||
CloseRequested,
|
||||
Roundness(Roundness),
|
||||
StartImport,
|
||||
StartExport,
|
||||
|
|
@ -284,9 +283,38 @@ impl From<CornerRadii> for Roundness {
|
|||
}
|
||||
|
||||
impl Page {
|
||||
fn color_picker_context_view(
|
||||
&self,
|
||||
description: Option<Cow<'static, str>>,
|
||||
reset: Cow<'static, str>,
|
||||
on_update: fn(ColorPickerUpdate) -> Message,
|
||||
model: impl Fn(&Self) -> &ColorPickerModel,
|
||||
) -> Element<'_, crate::pages::Message> {
|
||||
cosmic::widget::column()
|
||||
.push_maybe(description.map(|description| text(description).width(Length::Fill)))
|
||||
.push(
|
||||
model(self)
|
||||
.builder(on_update)
|
||||
.width(Length::Fixed(248.0))
|
||||
.height(Length::Fixed(158.0))
|
||||
.reset_label(reset)
|
||||
.build(
|
||||
fl!("recent-colors"),
|
||||
fl!("copy-to-clipboard"),
|
||||
fl!("copied-to-clipboard"),
|
||||
),
|
||||
)
|
||||
.padding(self.theme_builder.spacing.space_l)
|
||||
.align_items(cosmic::iced_core::Alignment::Center)
|
||||
.spacing(self.theme_builder.spacing.space_m)
|
||||
.width(Length::Fill)
|
||||
.apply(Element::from)
|
||||
.map(crate::pages::Message::Appearance)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub fn update(&mut self, message: Message) -> Command<app::Message> {
|
||||
let mut theme_builder_needs_update = false;
|
||||
self.theme_builder_needs_update = false;
|
||||
|
||||
let mut ret = match message {
|
||||
Message::DarkMode(enabled) => {
|
||||
|
|
@ -315,48 +343,20 @@ impl Page {
|
|||
Command::none()
|
||||
}
|
||||
Message::AccentWindowHint(u) => {
|
||||
let cmd = match &u {
|
||||
ColorPickerUpdate::AppliedColor | ColorPickerUpdate::Reset => {
|
||||
// close the color picker dialog
|
||||
// apply changes
|
||||
theme_builder_needs_update = true;
|
||||
self.active_dialog = None;
|
||||
close_window::<app::Message>(*COLOR_PICKER_DIALOG_ID)
|
||||
}
|
||||
// TODO apply changes
|
||||
ColorPickerUpdate::ActionFinished => {
|
||||
theme_builder_needs_update = true;
|
||||
_ = self
|
||||
.accent_window_hint
|
||||
.update::<app::Message>(ColorPickerUpdate::AppliedColor);
|
||||
Command::none()
|
||||
}
|
||||
ColorPickerUpdate::Cancel => {
|
||||
// close the color picker dialog
|
||||
self.active_dialog = None;
|
||||
close_window(*COLOR_PICKER_DIALOG_ID)
|
||||
}
|
||||
ColorPickerUpdate::ToggleColorPicker => {
|
||||
let prev = self
|
||||
.active_dialog
|
||||
.replace(NamedColorPicker::AccentWindowHint);
|
||||
if prev.is_none() {
|
||||
get_window(color_picker_window_settings())
|
||||
} else {
|
||||
Command::none()
|
||||
}
|
||||
}
|
||||
_ => Command::none(),
|
||||
};
|
||||
let cmd = self.update_color_picker(
|
||||
&u,
|
||||
ContextView::AccentWindowHint,
|
||||
fl!("window-hint-accent").into(),
|
||||
);
|
||||
Command::batch(vec![cmd, self.accent_window_hint.update::<app::Message>(u)])
|
||||
}
|
||||
Message::Frosted(enabled) => {
|
||||
theme_builder_needs_update = true;
|
||||
self.theme_builder_needs_update = true;
|
||||
self.theme_builder.is_frosted = enabled;
|
||||
Command::none()
|
||||
}
|
||||
Message::WindowHintSize(msg) => {
|
||||
theme_builder_needs_update = true;
|
||||
self.theme_builder_needs_update = true;
|
||||
self.theme_builder.active_hint = match msg {
|
||||
spin_button::Message::Increment => {
|
||||
self.theme_builder.active_hint.saturating_add(1)
|
||||
|
|
@ -368,7 +368,7 @@ impl Page {
|
|||
Command::none()
|
||||
}
|
||||
Message::GapSize(msg) => {
|
||||
theme_builder_needs_update = true;
|
||||
self.theme_builder_needs_update = true;
|
||||
self.theme_builder.gaps.1 = match msg {
|
||||
spin_button::Message::Increment => self.theme_builder.gaps.1.saturating_add(1),
|
||||
spin_button::Message::Decrement => self.theme_builder.gaps.1.saturating_sub(1),
|
||||
|
|
@ -376,215 +376,62 @@ impl Page {
|
|||
Command::none()
|
||||
}
|
||||
Message::ApplicationBackground(u) => {
|
||||
let cmd = match &u {
|
||||
ColorPickerUpdate::AppliedColor | ColorPickerUpdate::Reset => {
|
||||
// close the color picker dialog
|
||||
// apply changes
|
||||
theme_builder_needs_update = true;
|
||||
self.active_dialog = None;
|
||||
close_window::<app::Message>(*COLOR_PICKER_DIALOG_ID)
|
||||
}
|
||||
// TODO apply changes
|
||||
ColorPickerUpdate::ActionFinished => {
|
||||
theme_builder_needs_update = true;
|
||||
_ = self
|
||||
.application_background
|
||||
.update::<app::Message>(ColorPickerUpdate::AppliedColor);
|
||||
Command::none()
|
||||
}
|
||||
ColorPickerUpdate::Cancel => {
|
||||
// close the color picker dialog
|
||||
self.active_dialog = None;
|
||||
close_window(*COLOR_PICKER_DIALOG_ID)
|
||||
}
|
||||
ColorPickerUpdate::ToggleColorPicker => {
|
||||
let prev = self
|
||||
.active_dialog
|
||||
.replace(NamedColorPicker::ApplicationBackground);
|
||||
if prev.is_none() {
|
||||
get_window(color_picker_window_settings())
|
||||
} else {
|
||||
Command::none()
|
||||
}
|
||||
}
|
||||
_ => Command::none(),
|
||||
};
|
||||
let cmd = self.update_color_picker(
|
||||
&u,
|
||||
ContextView::ApplicationBackground,
|
||||
fl!("app-background").into(),
|
||||
);
|
||||
|
||||
Command::batch(vec![
|
||||
cmd,
|
||||
self.application_background.update::<app::Message>(u),
|
||||
])
|
||||
}
|
||||
Message::ContainerBackground(u) => {
|
||||
let cmd = match &u {
|
||||
ColorPickerUpdate::AppliedColor | ColorPickerUpdate::Reset => {
|
||||
theme_builder_needs_update = true;
|
||||
Command::perform(async {}, |()| crate::app::Message::CloseContextDrawer)
|
||||
}
|
||||
ColorPickerUpdate::ActionFinished => {
|
||||
theme_builder_needs_update = true;
|
||||
_ = self
|
||||
.container_background
|
||||
.update::<app::Message>(ColorPickerUpdate::AppliedColor);
|
||||
Command::none()
|
||||
}
|
||||
ColorPickerUpdate::Cancel => {
|
||||
Command::perform(async {}, |()| crate::app::Message::CloseContextDrawer)
|
||||
}
|
||||
ColorPickerUpdate::ToggleColorPicker => Command::perform(async {}, |()| {
|
||||
crate::app::Message::OpenContextDrawer(fl!("container-background").into())
|
||||
}),
|
||||
_ => Command::none(),
|
||||
};
|
||||
let cmd = self.update_color_picker(
|
||||
&u,
|
||||
ContextView::ContainerBackground,
|
||||
fl!("container-background").into(),
|
||||
);
|
||||
|
||||
Command::batch(vec![
|
||||
cmd,
|
||||
self.container_background.update::<app::Message>(u),
|
||||
])
|
||||
}
|
||||
Message::CustomAccent(u) => {
|
||||
let cmd = match &u {
|
||||
ColorPickerUpdate::AppliedColor | ColorPickerUpdate::Reset => {
|
||||
// close the color picker dialog
|
||||
// apply changes
|
||||
theme_builder_needs_update = true;
|
||||
self.active_dialog = None;
|
||||
close_window::<app::Message>(*COLOR_PICKER_DIALOG_ID)
|
||||
}
|
||||
// TODO apply changes
|
||||
ColorPickerUpdate::ActionFinished => {
|
||||
theme_builder_needs_update = true;
|
||||
_ = self
|
||||
.custom_accent
|
||||
.update::<app::Message>(ColorPickerUpdate::AppliedColor);
|
||||
Command::none()
|
||||
}
|
||||
ColorPickerUpdate::Cancel => {
|
||||
// close the color picker dialog
|
||||
self.active_dialog = None;
|
||||
close_window(*COLOR_PICKER_DIALOG_ID)
|
||||
}
|
||||
ColorPickerUpdate::ToggleColorPicker => {
|
||||
let prev = self.active_dialog.replace(NamedColorPicker::CustomAccent);
|
||||
if prev.is_none() {
|
||||
get_window(color_picker_window_settings())
|
||||
} else {
|
||||
Command::none()
|
||||
}
|
||||
}
|
||||
_ => Command::none(),
|
||||
};
|
||||
let cmd = self.update_color_picker(
|
||||
&u,
|
||||
ContextView::CustomAccent,
|
||||
fl!("accent-color").into(),
|
||||
);
|
||||
|
||||
let cmd2 = self.custom_accent.update::<app::Message>(u);
|
||||
|
||||
self.theme_builder.accent = self.custom_accent.get_applied_color().map(Srgb::from);
|
||||
Command::batch(vec![cmd, cmd2])
|
||||
}
|
||||
Message::InterfaceText(u) => {
|
||||
let cmd = match &u {
|
||||
ColorPickerUpdate::AppliedColor | ColorPickerUpdate::Reset => {
|
||||
// close the color picker dialog
|
||||
// apply changes
|
||||
theme_builder_needs_update = true;
|
||||
self.active_dialog = None;
|
||||
close_window::<app::Message>(*COLOR_PICKER_DIALOG_ID)
|
||||
}
|
||||
// TODO apply changes
|
||||
ColorPickerUpdate::ActionFinished => {
|
||||
theme_builder_needs_update = true;
|
||||
_ = self
|
||||
.interface_text
|
||||
.update::<app::Message>(ColorPickerUpdate::AppliedColor);
|
||||
Command::none()
|
||||
}
|
||||
ColorPickerUpdate::Cancel => {
|
||||
// close the color picker dialog
|
||||
self.active_dialog = None;
|
||||
close_window(*COLOR_PICKER_DIALOG_ID)
|
||||
}
|
||||
ColorPickerUpdate::ToggleColorPicker => {
|
||||
let prev = self.active_dialog.replace(NamedColorPicker::InterfaceText);
|
||||
if prev.is_none() {
|
||||
get_window(color_picker_window_settings())
|
||||
} else {
|
||||
Command::none()
|
||||
}
|
||||
}
|
||||
_ => Command::none(),
|
||||
};
|
||||
let cmd = self.update_color_picker(
|
||||
&u,
|
||||
ContextView::InterfaceText,
|
||||
fl!("text-tint").into(),
|
||||
);
|
||||
|
||||
Command::batch(vec![cmd, self.interface_text.update::<app::Message>(u)])
|
||||
}
|
||||
Message::ControlComponent(u) => {
|
||||
let cmd = match &u {
|
||||
ColorPickerUpdate::AppliedColor | ColorPickerUpdate::Reset => {
|
||||
// close the color picker dialog
|
||||
// apply changes
|
||||
theme_builder_needs_update = true;
|
||||
self.active_dialog = None;
|
||||
close_window::<app::Message>(*COLOR_PICKER_DIALOG_ID)
|
||||
}
|
||||
// TODO apply changes
|
||||
ColorPickerUpdate::ActionFinished => {
|
||||
theme_builder_needs_update = true;
|
||||
_ = self
|
||||
.control_component
|
||||
.update::<app::Message>(ColorPickerUpdate::AppliedColor);
|
||||
Command::none()
|
||||
}
|
||||
ColorPickerUpdate::Cancel => {
|
||||
// close the color picker dialog
|
||||
self.active_dialog = None;
|
||||
close_window(*COLOR_PICKER_DIALOG_ID)
|
||||
}
|
||||
ColorPickerUpdate::ToggleColorPicker => {
|
||||
let prev = self
|
||||
.active_dialog
|
||||
.replace(NamedColorPicker::ControlComponent);
|
||||
if prev.is_none() {
|
||||
get_window(color_picker_window_settings())
|
||||
} else {
|
||||
Command::none()
|
||||
}
|
||||
}
|
||||
_ => Command::none(),
|
||||
};
|
||||
let cmd = self.update_color_picker(
|
||||
&u,
|
||||
ContextView::ControlComponent,
|
||||
fl!("control-tint").into(),
|
||||
);
|
||||
Command::batch(vec![cmd, self.control_component.update::<app::Message>(u)])
|
||||
}
|
||||
Message::CloseRequested => {
|
||||
match self.active_dialog.take() {
|
||||
Some(NamedColorPicker::ApplicationBackground) => {
|
||||
_ = self
|
||||
.application_background
|
||||
.update::<app::Message>(ColorPickerUpdate::Cancel);
|
||||
}
|
||||
Some(NamedColorPicker::ControlComponent) => {
|
||||
_ = self
|
||||
.control_component
|
||||
.update::<app::Message>(ColorPickerUpdate::Cancel);
|
||||
}
|
||||
Some(NamedColorPicker::CustomAccent) => {
|
||||
_ = self
|
||||
.custom_accent
|
||||
.update::<app::Message>(ColorPickerUpdate::Cancel);
|
||||
}
|
||||
Some(NamedColorPicker::InterfaceText) => {
|
||||
_ = self
|
||||
.interface_text
|
||||
.update::<app::Message>(ColorPickerUpdate::AppliedColor);
|
||||
}
|
||||
Some(NamedColorPicker::AccentWindowHint) => {
|
||||
_ = self
|
||||
.accent_window_hint
|
||||
.update::<app::Message>(ColorPickerUpdate::AppliedColor);
|
||||
}
|
||||
None => {
|
||||
theme_builder_needs_update = false;
|
||||
warn!("Unknown appearance dialog closed.");
|
||||
}
|
||||
};
|
||||
Command::none()
|
||||
}
|
||||
Message::Roundness(r) => {
|
||||
self.roundness = r;
|
||||
self.theme_builder.corner_radii = self.roundness.into();
|
||||
theme_builder_needs_update = true;
|
||||
self.theme_builder_needs_update = true;
|
||||
Command::none()
|
||||
}
|
||||
Message::Entered => {
|
||||
|
|
@ -604,7 +451,7 @@ impl Page {
|
|||
}),
|
||||
Message::PaletteAccent(c) => {
|
||||
self.theme_builder.accent = Some(c.into());
|
||||
theme_builder_needs_update = true;
|
||||
self.theme_builder_needs_update = true;
|
||||
Command::none()
|
||||
}
|
||||
Message::Reset => {
|
||||
|
|
@ -780,7 +627,7 @@ impl Page {
|
|||
}
|
||||
Message::UseDefaultWindowHint(v) => {
|
||||
self.no_custom_window_hint = v;
|
||||
theme_builder_needs_update = true;
|
||||
self.theme_builder_needs_update = true;
|
||||
let theme = if self.theme_mode.is_dark {
|
||||
Theme::dark_default()
|
||||
} else {
|
||||
|
|
@ -814,12 +661,9 @@ impl Page {
|
|||
};
|
||||
Command::none()
|
||||
}
|
||||
Message::DragColorPicker => {
|
||||
cosmic::iced_sctk::commands::window::start_drag_window(*COLOR_PICKER_DIALOG_ID)
|
||||
}
|
||||
};
|
||||
|
||||
if theme_builder_needs_update {
|
||||
if self.theme_builder_needs_update {
|
||||
let Some(config) = self.theme_builder_config.as_ref() else {
|
||||
return ret;
|
||||
};
|
||||
|
|
@ -875,49 +719,34 @@ impl Page {
|
|||
ret
|
||||
}
|
||||
|
||||
pub fn color_picker_view(&self) -> Element<crate::app::Message> {
|
||||
let (picker, msg): (_, fn(ColorPickerUpdate) -> Message) = match self.active_dialog {
|
||||
Some(NamedColorPicker::ApplicationBackground) => {
|
||||
(&self.application_background, Message::ApplicationBackground)
|
||||
fn update_color_picker(
|
||||
&mut self,
|
||||
message: &ColorPickerUpdate,
|
||||
context_view: ContextView,
|
||||
context_title: Cow<'static, str>,
|
||||
) -> Command<app::Message> {
|
||||
match message {
|
||||
ColorPickerUpdate::AppliedColor | ColorPickerUpdate::Reset => {
|
||||
self.theme_builder_needs_update = true;
|
||||
cosmic::command::message(crate::app::Message::CloseContextDrawer)
|
||||
}
|
||||
Some(NamedColorPicker::ControlComponent) => {
|
||||
(&self.control_component, Message::ControlComponent)
|
||||
|
||||
ColorPickerUpdate::ActionFinished => {
|
||||
self.theme_builder_needs_update = true;
|
||||
Command::none()
|
||||
}
|
||||
Some(NamedColorPicker::CustomAccent) => (&self.custom_accent, Message::CustomAccent),
|
||||
Some(NamedColorPicker::InterfaceText) => (&self.interface_text, Message::InterfaceText),
|
||||
Some(NamedColorPicker::AccentWindowHint) => {
|
||||
(&self.accent_window_hint, Message::AccentWindowHint)
|
||||
|
||||
ColorPickerUpdate::Cancel => {
|
||||
cosmic::command::message(crate::app::Message::CloseContextDrawer)
|
||||
}
|
||||
None => return text("OOPS!").into(),
|
||||
};
|
||||
cosmic::iced::widget::column![
|
||||
header_bar()
|
||||
.title(fl!("color-picker"))
|
||||
.on_close(msg(ColorPickerUpdate::AppliedColor))
|
||||
.on_drag(Message::DragColorPicker),
|
||||
container(
|
||||
picker
|
||||
.builder(msg)
|
||||
.width(Length::Fixed(254.0))
|
||||
.height(Length::Fixed(174.0))
|
||||
.reset_label(fl!("reset-to-default"))
|
||||
.build(
|
||||
fl!("recent-colors"),
|
||||
fl!("copy-to-clipboard"),
|
||||
fl!("copied-to-clipboard"),
|
||||
)
|
||||
)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill)
|
||||
.align_x(cosmic::iced_core::alignment::Horizontal::Center)
|
||||
.style(cosmic::theme::style::Container::Background)
|
||||
]
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill)
|
||||
.align_items(cosmic::iced_core::Alignment::Center)
|
||||
.apply(Element::from)
|
||||
.map(crate::pages::Message::Appearance)
|
||||
.map(crate::app::Message::PageMessage)
|
||||
|
||||
ColorPickerUpdate::ToggleColorPicker => {
|
||||
self.context_view = Some(context_view);
|
||||
cosmic::command::message(crate::app::Message::OpenContextDrawer(context_title))
|
||||
}
|
||||
|
||||
_ => Command::none(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -964,36 +793,59 @@ impl page::Page<crate::pages::Message> for Page {
|
|||
}
|
||||
|
||||
fn reload(&mut self, _: page::Entity) -> Command<crate::pages::Message> {
|
||||
command::future(async move { crate::pages::Message::Appearance(Message::Entered) })
|
||||
command::message(crate::pages::Message::Appearance(Message::Entered))
|
||||
}
|
||||
|
||||
fn on_leave(&mut self) -> Command<crate::pages::Message> {
|
||||
Command::perform(async {}, |()| {
|
||||
crate::pages::Message::Appearance(Message::Left)
|
||||
})
|
||||
command::message(crate::pages::Message::Appearance(Message::Left))
|
||||
}
|
||||
|
||||
fn context_drawer(&self) -> Option<Element<'_, crate::pages::Message>> {
|
||||
Some(
|
||||
cosmic::iced::widget::column![
|
||||
text(fl!("container-background", "desc-detail")).width(Length::Fill),
|
||||
self.container_background
|
||||
.builder(Message::ContainerBackground)
|
||||
.width(Length::Fixed(248.0))
|
||||
.height(Length::Fixed(158.0))
|
||||
.reset_label(fl!("container-background", "reset"))
|
||||
.build(
|
||||
fl!("recent-colors"),
|
||||
fl!("copy-to-clipboard"),
|
||||
fl!("copied-to-clipboard"),
|
||||
)
|
||||
]
|
||||
.padding(self.theme_builder.spacing.space_l)
|
||||
.align_items(cosmic::iced_core::Alignment::Center)
|
||||
.spacing(self.theme_builder.spacing.space_m)
|
||||
.apply(Element::from)
|
||||
.map(crate::pages::Message::Appearance),
|
||||
)
|
||||
let view = match self.context_view? {
|
||||
ContextView::AccentWindowHint => self.color_picker_context_view(
|
||||
None,
|
||||
RESET_TO_DEFAULT.as_str().into(),
|
||||
Message::AccentWindowHint,
|
||||
|this| &this.accent_window_hint,
|
||||
),
|
||||
|
||||
ContextView::ApplicationBackground => self.color_picker_context_view(
|
||||
None,
|
||||
RESET_TO_DEFAULT.as_str().into(),
|
||||
Message::ApplicationBackground,
|
||||
|this| &this.application_background,
|
||||
),
|
||||
|
||||
ContextView::ContainerBackground => self.color_picker_context_view(
|
||||
Some(fl!("container-background", "desc-detail").into()),
|
||||
fl!("container-background", "reset").into(),
|
||||
Message::ContainerBackground,
|
||||
|this| &this.container_background,
|
||||
),
|
||||
|
||||
ContextView::ControlComponent => self.color_picker_context_view(
|
||||
None,
|
||||
RESET_TO_DEFAULT.as_str().into(),
|
||||
Message::ControlComponent,
|
||||
|this| &this.control_component,
|
||||
),
|
||||
|
||||
ContextView::CustomAccent => self.color_picker_context_view(
|
||||
None,
|
||||
RESET_TO_DEFAULT.as_str().into(),
|
||||
Message::CustomAccent,
|
||||
|this| &this.custom_accent,
|
||||
),
|
||||
|
||||
ContextView::InterfaceText => self.color_picker_context_view(
|
||||
None,
|
||||
RESET_TO_DEFAULT.as_str().into(),
|
||||
Message::InterfaceText,
|
||||
|this| &this.interface_text,
|
||||
),
|
||||
};
|
||||
|
||||
Some(view)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1382,7 +1234,7 @@ pub fn window_management() -> Section<crate::pages::Message> {
|
|||
#[allow(clippy::too_many_lines)]
|
||||
pub fn reset_button() -> Section<crate::pages::Message> {
|
||||
Section::default()
|
||||
.descriptions(vec![fl!("reset-default").into()])
|
||||
.descriptions(vec![fl!("reset-to-default").into()])
|
||||
.view::<Page>(|_binder, page, section| {
|
||||
let spacing = &page.theme_builder.spacing;
|
||||
let descriptions = §ion.descriptions;
|
||||
|
|
@ -1399,26 +1251,6 @@ pub fn reset_button() -> Section<crate::pages::Message> {
|
|||
}
|
||||
impl page::AutoBind<crate::pages::Message> for Page {}
|
||||
|
||||
fn color_picker_window_settings() -> SctkWindowSettings {
|
||||
SctkWindowSettings {
|
||||
window_id: *COLOR_PICKER_DIALOG_ID,
|
||||
app_id: Some("com.system76.CosmicSettings".to_string()),
|
||||
title: Some(fl!("color-picker")),
|
||||
parent: Some(window::Id::MAIN),
|
||||
autosize: false,
|
||||
size_limits: layout::Limits::NONE
|
||||
.min_width(300.0)
|
||||
.max_width(800.0)
|
||||
.min_height(520.0)
|
||||
.max_height(1080.0),
|
||||
size: (300, 520),
|
||||
resizable: Some(8.0),
|
||||
client_decorations: true,
|
||||
transparent: true,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// A button for selecting a color or gradient.
|
||||
pub fn color_button<'a, Message: 'a + Clone>(
|
||||
on_press: Option<Message>,
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ import = Import
|
|||
light = Light
|
||||
mode-and-colors = Mode and Colors
|
||||
recent-colors = Recent colors
|
||||
reset-default = Reset to default
|
||||
reset-to-default = Reset to default
|
||||
rgb = RGB
|
||||
window-hint-accent = Active window hint color
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ import = Importer
|
|||
light = Clair
|
||||
mode-and-colors = Mode et Couleur
|
||||
recent-colors = Couleurs récentes
|
||||
reset-default = Réinitialiser
|
||||
reset-to-default = Réinitialiser
|
||||
rgb = RVB
|
||||
window-hint-accent = Couleur de l'indice de la fenêtre active Active window hint color
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ import = Importa
|
|||
light = Chiaro
|
||||
mode-and-colors = Modalità e colori
|
||||
recent-colors = Colori recenti
|
||||
reset-default = Ripristina predefinito
|
||||
reset-to-default = Ripristina predefinito
|
||||
rgb = RGB
|
||||
window-hint-accent = Colore d'accento per la finestra attiva
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ import = Import
|
|||
light = Jasny
|
||||
mode-and-colors = Tryb i Kolor
|
||||
recent-colors = Ostatnie kolory
|
||||
reset-default = Resetuj do ustawień domyślnych
|
||||
reset-to-default = Resetuj do ustawień domyślnych
|
||||
rgb = RGB
|
||||
window-hint-accent = Kolor wyróżnienia aktywnego okna
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ import = Importar
|
|||
light = Claro
|
||||
mode-and-colors = Modo e cores
|
||||
recent-colors = Cores recentes
|
||||
reset-default = Repor a predefinição
|
||||
reset-to-default = Repor a predefinição
|
||||
rgb = RGB
|
||||
window-hint-accent = Cor da sugestão da janela ativa
|
||||
|
|
|
|||
|
|
@ -56,7 +56,6 @@ style = Стиль
|
|||
frosted = Эффект матового стекла на интерфейсе системы
|
||||
.desc = Размытие фона для верхней панели, дока, апплетов, панели запуска и библиотеки приложений.
|
||||
|
||||
reset-default = Вернуть по умолчанию
|
||||
# interface density left out for now
|
||||
|
||||
window-management = Управление окнами
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ import = Увези
|
|||
light = Светло
|
||||
mode-and-colors = Режим и боје
|
||||
recent-colors = Недавне боје
|
||||
reset-default = Врати на подразумевано
|
||||
reset-to-default = Врати на подразумевано
|
||||
rgb = RGB
|
||||
window-hint-accent = Боја наговештаја активног прозора
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ import = Uvezi
|
|||
light = Svetlo
|
||||
mode-and-colors = Režim i boje
|
||||
recent-colors = Nedavne boje
|
||||
reset-default = Vrati na podrazumevano
|
||||
reset-to-default = Vrati na podrazumevano
|
||||
rgb = RGB
|
||||
window-hint-accent = Boja nagoveštaja aktivnog prozora
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ import = Importera
|
|||
light = Ljust
|
||||
mode-and-colors = Läge och färger
|
||||
recent-colors = Senaste färger
|
||||
reset-default = Återställ till standard
|
||||
reset-to-default = Återställ till standard
|
||||
rgb = RGB
|
||||
window-hint-accent = Aktivt fönsterhinting färg
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ style = 風格
|
|||
.square = 正角
|
||||
frosted = 系統介面呈現磨砂玻璃的透明效果
|
||||
.desc = 將磨砂玻璃的透明效果套用至面板、容器、Dock、啟動器及程式庫
|
||||
reset-default = 重設至預設值
|
||||
|
||||
# interface density left out for now
|
||||
|
||||
window-management = 視窗管理
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue