feat(displays): listen to display change events with cosmic-randr
This commit is contained in:
parent
e756291b09
commit
554824aedf
4 changed files with 187 additions and 40 deletions
115
Cargo.lock
generated
115
Cargo.lock
generated
|
|
@ -300,6 +300,15 @@ dependencies = [
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-event"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4172595da7ffb68640606be5723e35a353555f2829e9209437627a003725bbdb"
|
||||||
|
dependencies = [
|
||||||
|
"loom",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-executor"
|
name = "async-executor"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
|
|
@ -1199,7 +1208,7 @@ name = "cosmic-client-toolkit"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/pop-os/cosmic-protocols?rev=e4e6f8c#e4e6f8ca4d7c239c02a8cdfd48a74cb0969425eb"
|
source = "git+https://github.com/pop-os/cosmic-protocols?rev=e4e6f8c#e4e6f8ca4d7c239c02a8cdfd48a74cb0969425eb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cosmic-protocols",
|
"cosmic-protocols 0.1.0 (git+https://github.com/pop-os/cosmic-protocols?rev=e4e6f8c)",
|
||||||
"libc",
|
"libc",
|
||||||
"smithay-client-toolkit",
|
"smithay-client-toolkit",
|
||||||
"wayland-client",
|
"wayland-client",
|
||||||
|
|
@ -1273,10 +1282,40 @@ dependencies = [
|
||||||
"wayland-server",
|
"wayland-server",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cosmic-protocols"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://github.com/pop-os/cosmic-protocols.git#1316f9e1148ec65351471d8a046ffc82171b066e"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.5.0",
|
||||||
|
"wayland-backend",
|
||||||
|
"wayland-client",
|
||||||
|
"wayland-protocols",
|
||||||
|
"wayland-protocols-wlr",
|
||||||
|
"wayland-scanner",
|
||||||
|
"wayland-server",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cosmic-randr"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://github.com/pop-os/cosmic-randr#8ad117e7c57848f113fbc87986e91209f2262b5a"
|
||||||
|
dependencies = [
|
||||||
|
"cosmic-protocols 0.1.0 (git+https://github.com/pop-os/cosmic-protocols.git)",
|
||||||
|
"futures-lite 2.3.0",
|
||||||
|
"indexmap",
|
||||||
|
"tachyonix",
|
||||||
|
"thiserror",
|
||||||
|
"tokio",
|
||||||
|
"tracing",
|
||||||
|
"wayland-client",
|
||||||
|
"wayland-protocols-wlr",
|
||||||
|
]
|
||||||
|
|
||||||
[[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#12fa7ce503c832cb9565b59ff722b15b7bab3f31"
|
source = "git+https://github.com/pop-os/cosmic-randr#8ad117e7c57848f113fbc87986e91209f2262b5a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"kdl",
|
"kdl",
|
||||||
"slotmap",
|
"slotmap",
|
||||||
|
|
@ -1297,6 +1336,7 @@ dependencies = [
|
||||||
"cosmic-bg-config",
|
"cosmic-bg-config",
|
||||||
"cosmic-comp-config",
|
"cosmic-comp-config",
|
||||||
"cosmic-panel-config",
|
"cosmic-panel-config",
|
||||||
|
"cosmic-randr",
|
||||||
"cosmic-randr-shell",
|
"cosmic-randr-shell",
|
||||||
"cosmic-settings-page",
|
"cosmic-settings-page",
|
||||||
"cosmic-settings-system",
|
"cosmic-settings-system",
|
||||||
|
|
@ -1326,6 +1366,7 @@ dependencies = [
|
||||||
"slotmap",
|
"slotmap",
|
||||||
"static_init",
|
"static_init",
|
||||||
"sunrise",
|
"sunrise",
|
||||||
|
"tachyonix",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
|
|
@ -1622,6 +1663,16 @@ dependencies = [
|
||||||
"syn 2.0.61",
|
"syn 2.0.61",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "diatomic-waker"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "28025fb55a9d815acf7b0877555f437254f373036eec6ed265116c7a5c0825e9"
|
||||||
|
dependencies = [
|
||||||
|
"loom",
|
||||||
|
"waker-fn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "digest"
|
name = "digest"
|
||||||
version = "0.10.7"
|
version = "0.10.7"
|
||||||
|
|
@ -3571,6 +3622,19 @@ version = "0.4.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
|
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "loom"
|
||||||
|
version = "0.5.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"generator",
|
||||||
|
"scoped-tls",
|
||||||
|
"tracing",
|
||||||
|
"tracing-subscriber",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "loop9"
|
name = "loop9"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
|
|
@ -3650,6 +3714,15 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "matchers"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
|
||||||
|
dependencies = [
|
||||||
|
"regex-automata 0.1.10",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "maybe-rayon"
|
name = "maybe-rayon"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
|
|
@ -4637,8 +4710,17 @@ checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
"regex-automata",
|
"regex-automata 0.4.6",
|
||||||
"regex-syntax",
|
"regex-syntax 0.8.3",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-automata"
|
||||||
|
version = "0.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
|
||||||
|
dependencies = [
|
||||||
|
"regex-syntax 0.6.29",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -4649,9 +4731,15 @@ checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
"regex-syntax",
|
"regex-syntax 0.8.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.6.29"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.8.3"
|
version = "0.8.3"
|
||||||
|
|
@ -5397,6 +5485,19 @@ dependencies = [
|
||||||
"version-compare",
|
"version-compare",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tachyonix"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "64e0bf82be3359dbefbfea621d6365db00e1d7846561daad2ea74cc4cb4c9604"
|
||||||
|
dependencies = [
|
||||||
|
"async-event",
|
||||||
|
"crossbeam-utils",
|
||||||
|
"diatomic-waker",
|
||||||
|
"futures-core",
|
||||||
|
"loom",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "taffy"
|
name = "taffy"
|
||||||
version = "0.3.11"
|
version = "0.3.11"
|
||||||
|
|
@ -5723,10 +5824,14 @@ version = "0.3.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
|
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"matchers",
|
||||||
"nu-ansi-term",
|
"nu-ansi-term",
|
||||||
|
"once_cell",
|
||||||
|
"regex",
|
||||||
"sharded-slab",
|
"sharded-slab",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"thread_local",
|
"thread_local",
|
||||||
|
"tracing",
|
||||||
"tracing-core",
|
"tracing-core",
|
||||||
"tracing-log",
|
"tracing-log",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ rust-version = "1.71.0"
|
||||||
sunrise_sunset = "1.0.1"
|
sunrise_sunset = "1.0.1"
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
|
cosmic-randr = { git = "https://github.com/pop-os/cosmic-randr" }
|
||||||
tokio = { version = "1.37.0", features = ["macros"] }
|
tokio = { version = "1.37.0", features = ["macros"] }
|
||||||
|
|
||||||
[workspace.dependencies.libcosmic]
|
[workspace.dependencies.libcosmic]
|
||||||
|
|
|
||||||
|
|
@ -6,51 +6,52 @@ license = "GPL-3.0"
|
||||||
rust-version = "1.65.0"
|
rust-version = "1.65.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tokio.workspace = true
|
anyhow = "1.0"
|
||||||
|
ashpd = { version = "0.7", default-features = false }
|
||||||
async-channel = "2.1.1"
|
async-channel = "2.1.1"
|
||||||
|
chrono = "0.4.37"
|
||||||
|
clap = { version = "4.4.18", features = ["derive"] }
|
||||||
color-eyre = "0.6.2"
|
color-eyre = "0.6.2"
|
||||||
cosmic-bg-config = { workspace = true }
|
cosmic-bg-config.workspace = true
|
||||||
cosmic-randr-shell = { workspace = true }
|
cosmic-comp-config.workspace = true
|
||||||
cosmic-settings-wallpaper = { path = "../pages/wallpapers" }
|
cosmic-panel-config.workspace = true
|
||||||
|
cosmic-randr-shell.workspace = true
|
||||||
|
cosmic-randr.workspace = true
|
||||||
cosmic-settings-page = { path = "../page" }
|
cosmic-settings-page = { path = "../page" }
|
||||||
cosmic-settings-system = { path = "../pages/system" }
|
cosmic-settings-system = { path = "../pages/system" }
|
||||||
cosmic-settings-time = { path = "../pages/time" }
|
cosmic-settings-time = { path = "../pages/time" }
|
||||||
|
cosmic-settings-wallpaper = { path = "../pages/wallpapers" }
|
||||||
derivative = "2.2.0"
|
derivative = "2.2.0"
|
||||||
derive_setters = "0.1.6"
|
derive_setters = "0.1.6"
|
||||||
dirs = "5.0.1"
|
dirs = "5.0.1"
|
||||||
generator = "=0.7.5"
|
|
||||||
i18n-embed-fl = "0.7.0"
|
|
||||||
itertools = "0.12.0"
|
|
||||||
libcosmic = { workspace = true }
|
|
||||||
once_cell = "1.19.0"
|
|
||||||
regex = "1.10.3"
|
|
||||||
rust-embed = "8.2.0"
|
|
||||||
slotmap = "1.0.7"
|
|
||||||
downcast-rs = "1.2.0"
|
downcast-rs = "1.2.0"
|
||||||
cosmic-comp-config = { workspace = true }
|
|
||||||
# TODO: migrate this dependency to the pages/desktop crate.
|
|
||||||
cosmic-panel-config = { workspace = true }
|
|
||||||
chrono = "0.4.37"
|
|
||||||
sunrise = "1.0.1"
|
|
||||||
tracing = "0.1.40"
|
|
||||||
tracing-subscriber = "0.3.18"
|
|
||||||
url = "2.5.0"
|
|
||||||
freedesktop-desktop-entry = "0.5.0"
|
freedesktop-desktop-entry = "0.5.0"
|
||||||
notify = "6.1.1"
|
|
||||||
anyhow = "1.0"
|
|
||||||
image = "0.25"
|
|
||||||
serde = { version = "1.0.196", features = ["derive"] }
|
|
||||||
ashpd = { version = "0.7", default-features = false }
|
|
||||||
ron = "0.8"
|
|
||||||
static_init = "1.0.3"
|
|
||||||
clap = { version = "4.4.18", features = ["derive"] }
|
|
||||||
itoa = "1.0.10"
|
|
||||||
futures = { package = "futures-lite", version = "2.2.0" }
|
futures = { package = "futures-lite", version = "2.2.0" }
|
||||||
xkb-data = "0.1.0"
|
generator = "=0.7.5"
|
||||||
udev = "0.8.0"
|
|
||||||
hostname-validator = "1.1.1"
|
hostname-validator = "1.1.1"
|
||||||
hostname1-zbus = "0.1.0"
|
hostname1-zbus = "0.1.0"
|
||||||
|
i18n-embed-fl = "0.7.0"
|
||||||
|
image = "0.25"
|
||||||
|
itertools = "0.12.0"
|
||||||
|
itoa = "1.0.10"
|
||||||
|
libcosmic.workspace = true
|
||||||
|
notify = "6.1.1"
|
||||||
|
once_cell = "1.19.0"
|
||||||
|
regex = "1.10.3"
|
||||||
|
ron = "0.8"
|
||||||
|
rust-embed = "8.2.0"
|
||||||
|
serde = { version = "1.0.196", features = ["derive"] }
|
||||||
|
slotmap = "1.0.7"
|
||||||
|
static_init = "1.0.3"
|
||||||
|
sunrise = "1.0.1"
|
||||||
|
tokio.workspace = true
|
||||||
|
tracing = "0.1.40"
|
||||||
|
tracing-subscriber = "0.3.18"
|
||||||
|
udev = "0.8.0"
|
||||||
|
url = "2.5.0"
|
||||||
|
xkb-data = "0.1.0"
|
||||||
zbus = { version = "3.15.2", features = ["tokio"] }
|
zbus = { version = "3.15.2", features = ["tokio"] }
|
||||||
|
tachyonix = "0.2.1"
|
||||||
|
|
||||||
[dependencies.i18n-embed]
|
[dependencies.i18n-embed]
|
||||||
version = "0.14.1"
|
version = "0.14.1"
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,8 @@ pub enum Message {
|
||||||
Orientation(Transform),
|
Orientation(Transform),
|
||||||
/// Status of an applied display change.
|
/// Status of an applied display change.
|
||||||
RandrResult(Arc<std::io::Result<ExitStatus>>),
|
RandrResult(Arc<std::io::Result<ExitStatus>>),
|
||||||
|
/// Request to reload the page.
|
||||||
|
Refresh,
|
||||||
/// Set the refresh rate of a display.
|
/// Set the refresh rate of a display.
|
||||||
RefreshRate(usize),
|
RefreshRate(usize),
|
||||||
/// Set the resolution of a display.
|
/// Set the resolution of a display.
|
||||||
|
|
@ -118,6 +120,7 @@ pub struct Page {
|
||||||
list: List,
|
list: List,
|
||||||
display_tabs: segmented_button::SingleSelectModel,
|
display_tabs: segmented_button::SingleSelectModel,
|
||||||
active_display: OutputKey,
|
active_display: OutputKey,
|
||||||
|
background_service: Option<tokio::task::JoinHandle<()>>,
|
||||||
config: Config,
|
config: Config,
|
||||||
cache: ViewCache,
|
cache: ViewCache,
|
||||||
context: Option<ContextDrawer>,
|
context: Option<ContextDrawer>,
|
||||||
|
|
@ -130,6 +133,7 @@ impl Default for Page {
|
||||||
list: List::default(),
|
list: List::default(),
|
||||||
display_tabs: segmented_button::SingleSelectModel::default(),
|
display_tabs: segmented_button::SingleSelectModel::default(),
|
||||||
active_display: OutputKey::default(),
|
active_display: OutputKey::default(),
|
||||||
|
background_service: None,
|
||||||
config: Config::default(),
|
config: Config::default(),
|
||||||
cache: ViewCache::default(),
|
cache: ViewCache::default(),
|
||||||
context: None,
|
context: None,
|
||||||
|
|
@ -224,9 +228,43 @@ impl page::Page<crate::pages::Message> for Page {
|
||||||
_page: page::Entity,
|
_page: page::Entity,
|
||||||
sender: tokio::sync::mpsc::Sender<crate::pages::Message>,
|
sender: tokio::sync::mpsc::Sender<crate::pages::Message>,
|
||||||
) -> Command<crate::pages::Message> {
|
) -> Command<crate::pages::Message> {
|
||||||
|
if let Some(task) = self.background_service.take() {
|
||||||
|
task.abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spawns a background service to monitor for display state changes.
|
||||||
|
// This must be spawned onto its own thread because `*mut wayland_sys::client::wl_display` is not Send-able.
|
||||||
|
let runtime = tokio::runtime::Handle::current();
|
||||||
|
self.background_service = Some(tokio::task::spawn_blocking(move || {
|
||||||
|
runtime.block_on(async move {
|
||||||
|
let (tx, mut rx) = tachyonix::channel(5);
|
||||||
|
let Ok((mut context, mut event_queue)) = cosmic_randr::connect(tx) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
while context.dispatch(&mut event_queue).await.is_ok() {
|
||||||
|
while let Ok(message) = rx.try_recv() {
|
||||||
|
if let cosmic_randr::Message::ManagerDone = message {
|
||||||
|
let _ = sender
|
||||||
|
.send(pages::Message::Displays(Message::Refresh))
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
command::future(on_enter())
|
command::future(on_enter())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_leave(&mut self) -> Command<crate::pages::Message> {
|
||||||
|
if let Some(task) = self.background_service.take() {
|
||||||
|
task.abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
Command::none()
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "test")]
|
#[cfg(feature = "test")]
|
||||||
fn on_enter(
|
fn on_enter(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|
@ -295,10 +333,6 @@ impl Page {
|
||||||
if let Some(Err(why)) = Arc::into_inner(result) {
|
if let Some(Err(why)) = Arc::into_inner(result) {
|
||||||
tracing::error!(?why, "cosmic-randr error");
|
tracing::error!(?why, "cosmic-randr error");
|
||||||
}
|
}
|
||||||
|
|
||||||
return cosmic::command::future(async {
|
|
||||||
crate::Message::PageMessage(on_enter().await)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Message::Display(display) => self.set_display(display),
|
Message::Display(display) => self.set_display(display),
|
||||||
|
|
@ -344,6 +378,12 @@ impl Page {
|
||||||
|
|
||||||
Message::Position(display, x, y) => return self.set_position(display, x, y),
|
Message::Position(display, x, y) => return self.set_position(display, x, y),
|
||||||
|
|
||||||
|
Message::Refresh => {
|
||||||
|
return cosmic::command::future(async move {
|
||||||
|
crate::Message::PageMessage(on_enter().await)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Message::RefreshRate(rate) => return self.set_refresh_rate(rate),
|
Message::RefreshRate(rate) => return self.set_refresh_rate(rate),
|
||||||
|
|
||||||
Message::Resolution(option) => return self.set_resolution(option),
|
Message::Resolution(option) => return self.set_resolution(option),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue