refactor: use randr kdl command

cleanup

chore: update deps

fix: typo
This commit is contained in:
Ashley Wulber 2025-08-20 18:06:41 -04:00 committed by Ashley Wulber
parent f3f7d5cfb6
commit 0e2141ac6c
5 changed files with 125 additions and 313 deletions

76
Cargo.lock generated
View file

@ -1100,9 +1100,10 @@ dependencies = [
[[package]] [[package]]
name = "cosmic-comp-config" name = "cosmic-comp-config"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/cosmic-comp?branch=refactor-config#f59af1685b38b8cc339e542ffab3b3cf82ac00b6" source = "git+https://github.com/pop-os/cosmic-comp?branch=refactor-config#2c1106b41f62d57f90fb5976684f890f2751272d"
dependencies = [ dependencies = [
"cosmic-config", "cosmic-config",
"cosmic-randr-shell",
"input", "input",
"ron 0.9.0", "ron 0.9.0",
"serde", "serde",
@ -1112,7 +1113,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#6e7a6343981df7d86f7ab01fe102d0b69d8e3bed" source = "git+https://github.com/pop-os/libcosmic#29f38f83a38b550ae0de2b130fde9f2c36341fab"
dependencies = [ dependencies = [
"atomicwrites", "atomicwrites",
"calloop 0.14.3", "calloop 0.14.3",
@ -1135,7 +1136,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#6e7a6343981df7d86f7ab01fe102d0b69d8e3bed" source = "git+https://github.com/pop-os/libcosmic#29f38f83a38b550ae0de2b130fde9f2c36341fab"
dependencies = [ dependencies = [
"quote", "quote",
"syn 2.0.106", "syn 2.0.106",
@ -1171,7 +1172,7 @@ dependencies = [
"dirs 5.0.1", "dirs 5.0.1",
"ini_core", "ini_core",
"memmap2 0.9.7", "memmap2 0.9.7",
"thiserror 2.0.15", "thiserror 2.0.16",
"tracing", "tracing",
"xdg 2.5.2", "xdg 2.5.2",
] ]
@ -1206,6 +1207,7 @@ dependencies = [
"i18n-embed-fl", "i18n-embed-fl",
"icu", "icu",
"itoa", "itoa",
"kdl",
"libcosmic", "libcosmic",
"log", "log",
"logind-zbus", "logind-zbus",
@ -1243,8 +1245,10 @@ dependencies = [
"cosmic-bg-config", "cosmic-bg-config",
"cosmic-comp-config", "cosmic-comp-config",
"cosmic-config", "cosmic-config",
"cosmic-randr-shell",
"cosmic-theme", "cosmic-theme",
"env_logger", "env_logger",
"kdl",
"libc", "libc",
"log", "log",
"nix 0.29.0", "nix 0.29.0",
@ -1273,11 +1277,11 @@ dependencies = [
[[package]] [[package]]
name = "cosmic-randr-shell" name = "cosmic-randr-shell"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/cosmic-randr#f2cf6dfe9af22c005018b1aa952347dcc1d80b1c" source = "git+https://github.com/pop-os/cosmic-randr?branch=kdl-command#4b2dcdc840774f919e94abdf4088d658c7bd1ebf"
dependencies = [ dependencies = [
"kdl", "kdl",
"slotmap", "slotmap",
"thiserror 2.0.15", "thiserror 2.0.16",
"tokio", "tokio",
] ]
@ -1290,7 +1294,7 @@ dependencies = [
"ron 0.9.0", "ron 0.9.0",
"serde", "serde",
"serde_with", "serde_with",
"thiserror 2.0.15", "thiserror 2.0.16",
"tracing", "tracing",
"xkbcommon", "xkbcommon",
] ]
@ -1330,7 +1334,7 @@ dependencies = [
"num-derive", "num-derive",
"num-traits", "num-traits",
"smithay-client-toolkit", "smithay-client-toolkit",
"thiserror 2.0.15", "thiserror 2.0.16",
"tokio", "tokio",
"tokio-stream", "tokio-stream",
"tracing", "tracing",
@ -1362,7 +1366,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#6e7a6343981df7d86f7ab01fe102d0b69d8e3bed" source = "git+https://github.com/pop-os/libcosmic#29f38f83a38b550ae0de2b130fde9f2c36341fab"
dependencies = [ dependencies = [
"almost", "almost",
"cosmic-config", "cosmic-config",
@ -1373,7 +1377,7 @@ dependencies = [
"ron 0.9.0", "ron 0.9.0",
"serde", "serde",
"serde_json", "serde_json",
"thiserror 2.0.15", "thiserror 2.0.16",
] ]
[[package]] [[package]]
@ -2125,7 +2129,7 @@ dependencies = [
"gettext-rs", "gettext-rs",
"log", "log",
"memchr", "memchr",
"thiserror 2.0.15", "thiserror 2.0.16",
"unicase", "unicase",
"xdg 2.5.2", "xdg 2.5.2",
] ]
@ -2663,7 +2667,7 @@ dependencies = [
[[package]] [[package]]
name = "iced" name = "iced"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#6e7a6343981df7d86f7ab01fe102d0b69d8e3bed" source = "git+https://github.com/pop-os/libcosmic#29f38f83a38b550ae0de2b130fde9f2c36341fab"
dependencies = [ dependencies = [
"dnd", "dnd",
"iced_accessibility", "iced_accessibility",
@ -2681,7 +2685,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_accessibility" name = "iced_accessibility"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#6e7a6343981df7d86f7ab01fe102d0b69d8e3bed" source = "git+https://github.com/pop-os/libcosmic#29f38f83a38b550ae0de2b130fde9f2c36341fab"
dependencies = [ dependencies = [
"accesskit", "accesskit",
"accesskit_winit", "accesskit_winit",
@ -2690,7 +2694,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_core" name = "iced_core"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#6e7a6343981df7d86f7ab01fe102d0b69d8e3bed" source = "git+https://github.com/pop-os/libcosmic#29f38f83a38b550ae0de2b130fde9f2c36341fab"
dependencies = [ dependencies = [
"bitflags 2.9.2", "bitflags 2.9.2",
"bytes", "bytes",
@ -2715,7 +2719,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_futures" name = "iced_futures"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#6e7a6343981df7d86f7ab01fe102d0b69d8e3bed" source = "git+https://github.com/pop-os/libcosmic#29f38f83a38b550ae0de2b130fde9f2c36341fab"
dependencies = [ dependencies = [
"futures", "futures",
"iced_core", "iced_core",
@ -2741,7 +2745,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_graphics" name = "iced_graphics"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#6e7a6343981df7d86f7ab01fe102d0b69d8e3bed" source = "git+https://github.com/pop-os/libcosmic#29f38f83a38b550ae0de2b130fde9f2c36341fab"
dependencies = [ dependencies = [
"bitflags 2.9.2", "bitflags 2.9.2",
"bytemuck", "bytemuck",
@ -2763,7 +2767,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_renderer" name = "iced_renderer"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#6e7a6343981df7d86f7ab01fe102d0b69d8e3bed" source = "git+https://github.com/pop-os/libcosmic#29f38f83a38b550ae0de2b130fde9f2c36341fab"
dependencies = [ dependencies = [
"iced_graphics", "iced_graphics",
"iced_tiny_skia", "iced_tiny_skia",
@ -2775,7 +2779,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_runtime" name = "iced_runtime"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#6e7a6343981df7d86f7ab01fe102d0b69d8e3bed" source = "git+https://github.com/pop-os/libcosmic#29f38f83a38b550ae0de2b130fde9f2c36341fab"
dependencies = [ dependencies = [
"bytes", "bytes",
"cosmic-client-toolkit", "cosmic-client-toolkit",
@ -2791,7 +2795,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_tiny_skia" name = "iced_tiny_skia"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#6e7a6343981df7d86f7ab01fe102d0b69d8e3bed" source = "git+https://github.com/pop-os/libcosmic#29f38f83a38b550ae0de2b130fde9f2c36341fab"
dependencies = [ dependencies = [
"bytemuck", "bytemuck",
"cosmic-text", "cosmic-text",
@ -2807,7 +2811,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_wgpu" name = "iced_wgpu"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#6e7a6343981df7d86f7ab01fe102d0b69d8e3bed" source = "git+https://github.com/pop-os/libcosmic#29f38f83a38b550ae0de2b130fde9f2c36341fab"
dependencies = [ dependencies = [
"as-raw-xcb-connection", "as-raw-xcb-connection",
"bitflags 2.9.2", "bitflags 2.9.2",
@ -2838,7 +2842,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_widget" name = "iced_widget"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#6e7a6343981df7d86f7ab01fe102d0b69d8e3bed" source = "git+https://github.com/pop-os/libcosmic#29f38f83a38b550ae0de2b130fde9f2c36341fab"
dependencies = [ dependencies = [
"cosmic-client-toolkit", "cosmic-client-toolkit",
"dnd", "dnd",
@ -2858,7 +2862,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_winit" name = "iced_winit"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#6e7a6343981df7d86f7ab01fe102d0b69d8e3bed" source = "git+https://github.com/pop-os/libcosmic#29f38f83a38b550ae0de2b130fde9f2c36341fab"
dependencies = [ dependencies = [
"cosmic-client-toolkit", "cosmic-client-toolkit",
"dnd", "dnd",
@ -3733,7 +3737,7 @@ checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543"
[[package]] [[package]]
name = "libcosmic" name = "libcosmic"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#6e7a6343981df7d86f7ab01fe102d0b69d8e3bed" source = "git+https://github.com/pop-os/libcosmic#29f38f83a38b550ae0de2b130fde9f2c36341fab"
dependencies = [ dependencies = [
"apply", "apply",
"ashpd", "ashpd",
@ -3770,7 +3774,7 @@ dependencies = [
"shlex", "shlex",
"slotmap", "slotmap",
"taffy", "taffy",
"thiserror 2.0.15", "thiserror 2.0.16",
"tokio", "tokio",
"tracing", "tracing",
"unicode-segmentation", "unicode-segmentation",
@ -5314,7 +5318,7 @@ checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac"
dependencies = [ dependencies = [
"getrandom 0.2.16", "getrandom 0.2.16",
"libredox", "libredox",
"thiserror 2.0.15", "thiserror 2.0.16",
] ]
[[package]] [[package]]
@ -6122,15 +6126,15 @@ checksum = "83176759e9416cf81ee66cb6508dbfe9c96f20b8b56265a39917551c23c70964"
[[package]] [[package]]
name = "tempfile" name = "tempfile"
version = "3.20.0" version = "3.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" checksum = "15b61f8f20e3a6f7e0649d825294eaf317edce30f82cf6026e7e4cb9222a7d1e"
dependencies = [ dependencies = [
"fastrand 2.3.0", "fastrand 2.3.0",
"getrandom 0.3.3", "getrandom 0.3.3",
"once_cell", "once_cell",
"rustix 1.0.8", "rustix 1.0.8",
"windows-sys 0.59.0", "windows-sys 0.60.2",
] ]
[[package]] [[package]]
@ -6153,11 +6157,11 @@ dependencies = [
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "2.0.15" version = "2.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80d76d3f064b981389ecb4b6b7f45a0bf9fdac1d5b9204c7bd6714fecc302850" checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0"
dependencies = [ dependencies = [
"thiserror-impl 2.0.15", "thiserror-impl 2.0.16",
] ]
[[package]] [[package]]
@ -6173,9 +6177,9 @@ dependencies = [
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "2.0.15" version = "2.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44d29feb33e986b6ea906bd9c3559a856983f92371b3eaa5e83782a351623de0" checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -7080,11 +7084,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]] [[package]]
name = "winapi-util" name = "winapi-util"
version = "0.1.9" version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" checksum = "0978bf7171b3d90bac376700cb56d606feb40f251a475a5d6634613564460b22"
dependencies = [ dependencies = [
"windows-sys 0.59.0", "windows-sys 0.60.2",
] ]
[[package]] [[package]]

View file

@ -77,9 +77,11 @@ i18n-embed-fl = "0.7"
rust-embed = "8" rust-embed = "8"
futures-util = "0.3.30" futures-util = "0.3.30"
timedate-zbus = { git = "https://github.com/pop-os/dbus-settings-bindings" } timedate-zbus = { git = "https://github.com/pop-os/dbus-settings-bindings" }
cosmic-randr-shell = { git = "https://github.com/pop-os/cosmic-randr", default-features = false }
tachyonix = "0.3.1" tachyonix = "0.3.1"
itoa = "1.0.15" itoa = "1.0.15"
cosmic-randr-shell = { workspace = true }
kdl.workspace = true
[dependencies.greetd_ipc] [dependencies.greetd_ipc]
version = "0.10.3" version = "0.10.3"
@ -120,6 +122,9 @@ ron = "0.10.1"
serde = "1" serde = "1"
tokio = "1.39.1" tokio = "1.39.1"
zbus = "5" zbus = "5"
kdl = "6"
cosmic-randr-shell = { git = "https://github.com/pop-os/cosmic-randr", default-features = false, branch = "kdl-command" }
# cosmic-randr-shell = { path = "../cosmic-randr/shell", default-features = false }
[workspace.dependencies.cosmic-applets-config] [workspace.dependencies.cosmic-applets-config]
git = "https://github.com/pop-os/cosmic-applets" git = "https://github.com/pop-os/cosmic-applets"
@ -134,7 +139,7 @@ git = "https://github.com/pop-os/cosmic-comp"
branch = "refactor-config" branch = "refactor-config"
# path = "../cosmic-comp/cosmic-comp-config" # path = "../cosmic-comp/cosmic-comp-config"
default-features = false default-features = false
features = ["output"] features = ["output", "randr"]
[workspace.dependencies.cosmic-greeter-config] [workspace.dependencies.cosmic-greeter-config]
path = "cosmic-greeter-config" path = "cosmic-greeter-config"

View file

@ -19,6 +19,9 @@ pwd.workspace = true
ron.workspace = true ron.workspace = true
serde.workspace = true serde.workspace = true
zbus.workspace = true zbus.workspace = true
cosmic-randr-shell.workspace = true
kdl.workspace = true
#TODO: reduce features #TODO: reduce features
tokio = { workspace = true, features = ["full"] } tokio = { workspace = true, features = ["full"] }
xdg = "3.0.0" xdg = "3.0.0"

View file

@ -1,5 +1,6 @@
use cosmic_comp_config::output::{self, OutputsConfig}; use cosmic_comp_config::output::randr;
use cosmic_config::CosmicConfigEntry; use cosmic_config::CosmicConfigEntry;
use kdl::KdlDocument;
use std::{ use std::{
collections::BTreeMap, collections::BTreeMap,
fs, fs,
@ -24,7 +25,7 @@ pub struct UserData {
pub xkb_config_opt: Option<XkbConfig>, pub xkb_config_opt: Option<XkbConfig>,
pub time_applet_config: TimeAppletConfig, pub time_applet_config: TimeAppletConfig,
pub accessibility_zoom: ZoomConfig, pub accessibility_zoom: ZoomConfig,
pub outputs: Option<OutputsConfig>, pub kdl_output_lists: Vec<String>,
} }
impl UserData { impl UserData {
@ -178,10 +179,17 @@ impl UserData {
}; };
let xdg = xdg::BaseDirectories::new(); let xdg = xdg::BaseDirectories::new();
self.outputs = xdg.get_state_home().map(|mut s| { self.kdl_output_lists = xdg
s.push("cosmic-comp/outputs.ron"); .get_state_home()
output::load_outputs(Some(&s)) .map(|mut s| {
}); s.push("cosmic-comp/outputs.ron");
let lists = randr::load_outputs(Some(&s));
lists
.into_iter()
.map(|l| KdlDocument::from(l).to_string())
.collect()
})
.unwrap_or_default();
match cosmic_config::Config::new("com.system76.CosmicAppletTime", TimeAppletConfig::VERSION) match cosmic_config::Config::new("com.system76.CosmicAppletTime", TimeAppletConfig::VERSION)
{ {

View file

@ -17,7 +17,7 @@ use cosmic::{
iced::{ iced::{
self, Background, Border, Length, Subscription, alignment, self, Background, Border, Length, Subscription, alignment,
event::wayland::OutputEvent, event::wayland::OutputEvent,
futures::{self, SinkExt}, futures::SinkExt,
platform_specific::{ platform_specific::{
runtime::wayland::layer_surface::{IcedMargin, IcedOutput, SctkLayerSurfaceSettings}, runtime::wayland::layer_surface::{IcedMargin, IcedOutput, SctkLayerSurfaceSettings},
shell::wayland::commands::layer_surface::{ shell::wayland::commands::layer_surface::{
@ -32,16 +32,15 @@ use cosmic::{
cosmic_theme::{self, CosmicPalette}, cosmic_theme::{self, CosmicPalette},
surface, surface,
}; };
use cosmic_comp_config::output::{OutputConfig, OutputInfo, OutputState};
use cosmic_greeter_config::Config as CosmicGreeterConfig; use cosmic_greeter_config::Config as CosmicGreeterConfig;
use cosmic_greeter_daemon::UserData; use cosmic_greeter_daemon::UserData;
use cosmic_randr_shell::{ use cosmic_randr_shell::{AdaptiveSyncState, KdlParseWithError, List, OutputKey, Transform};
AdaptiveSyncAvailability, AdaptiveSyncState, List, Output, OutputKey, Transform,
};
use cosmic_settings_subscriptions::cosmic_a11y_manager::{ use cosmic_settings_subscriptions::cosmic_a11y_manager::{
AccessibilityEvent, AccessibilityRequest, AccessibilityEvent, AccessibilityRequest,
}; };
use greetd_ipc::Request; use greetd_ipc::Request;
use kdl::KdlDocument;
use std::process::Stdio;
use std::sync::LazyLock; use std::sync::LazyLock;
use std::{ use std::{
collections::{HashMap, hash_map}, collections::{HashMap, hash_map},
@ -437,257 +436,34 @@ struct Accessibility {
impl App { impl App {
/// Applies a display configuration via `cosmic-randr`. /// Applies a display configuration via `cosmic-randr`.
fn exec_randr(&self, output: Output, user_config: OutputConfig) -> Task<Message> { fn exec_randr(&self, user_config: cosmic_randr_shell::List) -> Task<Message> {
let Some(current_mode) = output.current else { let mut task = tokio::process::Command::new("cosmic-randr");
log::warn!("Current output mode missing..."); task.arg("kdl");
return Task::none();
};
let Some(current_mode) = self
.randr_list
.as_ref()
.and_then(|l| l.modes.get(current_mode))
else {
log::warn!("Mode key does not exist...");
return Task::none();
};
let Some(list) = self.randr_list.as_ref() else {
return Task::none();
};
let mut tasks = Vec::new(); cosmic::task::future::<(), ()>(async move {
let name = &*output.name; task.stdin(Stdio::piped());
let Ok(mut p) = task.spawn() else {
return;
};
// Mirror let kdl_doc = kdl::KdlDocument::from(user_config).to_string();
let cur_state = if output.enabled { use tokio::io::AsyncWriteExt;
output
.mirroring if let Some(mut stdin) = p.stdin.take() {
.map(|n| OutputState::Mirroring(n)) if let Err(err) = stdin.write_all(kdl_doc.as_bytes()).await {
.unwrap_or(OutputState::Enabled) log::error!("Failed to write KDL to stdin: {err:?}");
} else {
OutputState::Disabled
};
// Enable/Disable or Mirror
if user_config.enabled != cur_state {
match user_config.enabled {
OutputState::Enabled => {
let mut task = tokio::process::Command::new("cosmic-randr");
task.arg("enable").arg(name);
tasks.push(
cosmic::task::future::<(), ()>(async move {
log::debug!("executing {task:?}");
let status = task.status().await;
if let Err(err) = status {
log::error!("Randr error: {err:?}");
}
})
.discard(),
);
} }
OutputState::Disabled => { if let Err(err) = stdin.flush().await {
let mut task = tokio::process::Command::new("cosmic-randr"); log::error!("Failed to flush stdin: {err:?}");
task.arg("disable").arg(name);
tasks.push(
cosmic::task::future::<(), ()>(async move {
log::debug!("executing {task:?}");
let status = task.status().await;
if let Err(err) = status {
log::error!("Randr error: {err:?}");
}
})
.discard(),
);
}
OutputState::Mirroring(ref mirror_name) => {
let mut task = tokio::process::Command::new("cosmic-randr");
task.arg("mirror").arg(&output.name).arg(mirror_name);
tasks.push(
cosmic::task::future::<(), ()>(async move {
log::debug!("executing {task:?}");
let status = task.status().await;
if let Err(err) = status {
log::error!("Randr error: {err:?}");
}
})
.discard(),
);
} }
} }
} log::debug!("executing {task:?}");
let status = p.wait().await;
// Position if let Err(err) = status {
if (user_config.position.0 as i32, user_config.position.1 as i32) != output.position { log::error!("Randr error: {err:?}");
let (x, y) = user_config.position;
let mut task = tokio::process::Command::new("cosmic-randr");
task.arg("mode")
.arg("--pos-x")
.arg(itoa::Buffer::new().format(x))
.arg("--pos-y")
.arg(itoa::Buffer::new().format(y))
.arg(name)
.arg(itoa::Buffer::new().format(current_mode.size.0))
.arg(itoa::Buffer::new().format(current_mode.size.1));
tasks.push(
cosmic::task::future::<(), ()>(async move {
log::debug!("executing {task:?}");
let status = task.status().await;
if let Err(err) = status {
log::error!("Randr error: {err:?}");
}
})
.discard(),
);
}
// RefreshRate
if user_config.mode.1 != Some(current_mode.refresh_rate) {
let rate = current_mode.refresh_rate;
let mut task = tokio::process::Command::new("cosmic-randr");
task.arg("mode")
.arg("--refresh")
.arg(format!("{}.{:03}", rate / 1000, rate % 1000))
.arg(name)
.arg(itoa::Buffer::new().format(current_mode.size.0))
.arg(itoa::Buffer::new().format(current_mode.size.1));
tasks.push(
cosmic::task::future::<(), ()>(async move {
log::debug!("executing {task:?}");
let status = task.status().await;
if let Err(err) = status {
log::error!("Randr error: {err:?}");
}
})
.discard(),
);
}
let configured_vrr = match user_config.vrr {
cosmic_comp_config::output::AdaptiveSync::Enabled => {
cosmic_randr_shell::AdaptiveSyncState::Auto
} }
cosmic_comp_config::output::AdaptiveSync::Disabled => { })
cosmic_randr_shell::AdaptiveSyncState::Disabled .discard()
}
cosmic_comp_config::output::AdaptiveSync::Force => {
cosmic_randr_shell::AdaptiveSyncState::Always
}
};
// VariableRefreshRate
if Some(configured_vrr) != output.adaptive_sync {
let mode = configured_vrr;
let mut task = tokio::process::Command::new("cosmic-randr");
task.arg("mode")
.arg("--adaptive-sync")
.arg(format!("{}", mode))
.arg(name)
.arg(itoa::Buffer::new().format(current_mode.size.0))
.arg(itoa::Buffer::new().format(current_mode.size.1));
tasks.push(
cosmic::task::future::<(), ()>(async move {
log::debug!("executing {task:?}");
let status = task.status().await;
if let Err(err) = status {
log::error!("Randr error: {err:?}");
}
})
.discard(),
);
}
// Resolution
if (user_config.mode.0.0 as u32, user_config.mode.0.1 as u32) != current_mode.size {
let (width, height) = user_config.mode.0;
let mut task = tokio::process::Command::new("cosmic-randr");
task.arg("mode")
.arg(name)
.arg(itoa::Buffer::new().format(width))
.arg(itoa::Buffer::new().format(height));
tasks.push(
cosmic::task::future::<(), ()>(async move {
log::debug!("executing {task:?}");
let status = task.status().await;
if let Err(err) = status {
log::error!("Randr error: {err:?}");
}
})
.discard(),
);
}
// Scale
if user_config.scale != user_config.scale {
let scale = user_config.scale;
let rate = current_mode.refresh_rate;
let mut task = tokio::process::Command::new("cosmic-randr");
task.arg("mode")
.arg("--scale")
.arg(format!("{:02}", scale / 100.))
.arg("--refresh")
.arg(format!("{}.{:03}", rate / 1000, rate % 1000))
.arg(name)
.arg(itoa::Buffer::new().format(current_mode.size.0))
.arg(itoa::Buffer::new().format(current_mode.size.1));
tasks.push(
cosmic::task::future::<(), ()>(async move {
log::debug!("executing {task:?}");
let status = task.status().await;
if let Err(err) = status {
log::error!("Randr error: {err:?}");
}
})
.discard(),
);
}
// Transform
let configured_transform = match user_config.transform {
cosmic_comp_config::output::TransformDef::Normal => {
cosmic_randr_shell::Transform::Normal
}
cosmic_comp_config::output::TransformDef::_90 => {
cosmic_randr_shell::Transform::Rotate90
}
cosmic_comp_config::output::TransformDef::_180 => {
cosmic_randr_shell::Transform::Rotate180
}
cosmic_comp_config::output::TransformDef::_270 => {
cosmic_randr_shell::Transform::Rotate270
}
cosmic_comp_config::output::TransformDef::Flipped => {
cosmic_randr_shell::Transform::Flipped
}
cosmic_comp_config::output::TransformDef::Flipped90 => {
cosmic_randr_shell::Transform::Flipped90
}
cosmic_comp_config::output::TransformDef::Flipped180 => {
cosmic_randr_shell::Transform::Flipped180
}
cosmic_comp_config::output::TransformDef::Flipped270 => {
cosmic_randr_shell::Transform::Flipped270
}
};
if Some(configured_transform) != output.transform {
let transform = configured_transform;
let mut task = tokio::process::Command::new("cosmic-randr");
task.arg("mode")
.arg("--transform")
.arg(&*format!("{transform}"))
.arg(name)
.arg(itoa::Buffer::new().format(current_mode.size.0))
.arg(itoa::Buffer::new().format(current_mode.size.1));
tasks.push(
cosmic::task::future::<(), ()>(async move {
log::debug!("executing {task:?}");
let status = task.status().await;
if let Err(err) = status {
log::error!("Randr error: {err:?}");
}
})
.discard(),
);
}
Task::batch(tasks)
} }
fn menu(&self, id: SurfaceId) -> Element<Message> { fn menu(&self, id: SurfaceId) -> Element<Message> {
@ -1870,43 +1646,59 @@ impl cosmic::Application for App {
let mut tasks = Vec::new(); let mut tasks = Vec::new();
self.randr_list = Some(outputs.clone()); self.randr_list = Some(outputs.clone());
let mut output_pairs: Vec<(Output, OutputInfo, OutputConfig)> = Vec::new(); let mut list: Option<List> = None;
let Some(cur_user_output_state) = self let Some(cur_user_output_state) = self
.selected_username .selected_username
.data_idx .data_idx
.and_then(|i| self.flags.user_datas.get(i)) .and_then(|i| self.flags.user_datas.get(i))
.and_then(|user_data| user_data.outputs.as_ref()) .map(|user_data| &user_data.kdl_output_lists)
else { else {
return Task::none(); return Task::none();
}; };
'outer: for (i, (configured_info, output_configs)) in 'outer: for configured_list in cur_user_output_state
cur_user_output_state.config.iter().enumerate() .iter()
.filter_map(|s| match KdlDocument::parse(s) {
Ok(doc) => Some(doc),
Err(err) => {
log::warn!("Invalid output KDL {err:?}");
None
}
})
.map(|kdl| match List::try_from(kdl) {
Ok(list) => list,
Err(KdlParseWithError { list, errors }) => {
for err in errors {
log::warn!("KDL output error: {err:?}");
}
list
}
})
{ {
if configured_info.len() != outputs.outputs.len() { if configured_list.outputs.len() != outputs.outputs.len() {
continue; continue;
} }
let mut matching_outputs = Vec::new();
for o in outputs.outputs.values() { for o in outputs.outputs.values() {
if let Some(pos) = configured_info.iter().position(|configured| { if configured_list.outputs.values().all(|configured| {
configured.connector == o.name configured.name != o.name
&& configured.make == o.make.clone().unwrap_or_default() || configured.make != o.make
&& configured.model == o.model || configured.model != o.model
}) { }) {
matching_outputs.push((
o.clone(),
configured_info[pos].clone(),
output_configs[pos].clone(),
));
} else {
continue 'outer; continue 'outer;
} }
} }
output_pairs = matching_outputs; if list
.as_ref()
.is_none_or(|old| old.outputs.len() < configured_list.outputs.len())
{
list = Some(configured_list);
}
} }
for (randr_o, _info, user_config) in output_pairs { if let Some(list) = list {
tasks.push(self.exec_randr(randr_o, user_config)) tasks.push(self.exec_randr(list))
} else {
log::warn!("Failed to apply user display config");
} }
return Task::batch(tasks); return Task::batch(tasks);