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
|
|
@ -6,51 +6,52 @@ license = "GPL-3.0"
|
|||
rust-version = "1.65.0"
|
||||
|
||||
[dependencies]
|
||||
tokio.workspace = true
|
||||
anyhow = "1.0"
|
||||
ashpd = { version = "0.7", default-features = false }
|
||||
async-channel = "2.1.1"
|
||||
chrono = "0.4.37"
|
||||
clap = { version = "4.4.18", features = ["derive"] }
|
||||
color-eyre = "0.6.2"
|
||||
cosmic-bg-config = { workspace = true }
|
||||
cosmic-randr-shell = { workspace = true }
|
||||
cosmic-settings-wallpaper = { path = "../pages/wallpapers" }
|
||||
cosmic-bg-config.workspace = true
|
||||
cosmic-comp-config.workspace = true
|
||||
cosmic-panel-config.workspace = true
|
||||
cosmic-randr-shell.workspace = true
|
||||
cosmic-randr.workspace = true
|
||||
cosmic-settings-page = { path = "../page" }
|
||||
cosmic-settings-system = { path = "../pages/system" }
|
||||
cosmic-settings-time = { path = "../pages/time" }
|
||||
cosmic-settings-wallpaper = { path = "../pages/wallpapers" }
|
||||
derivative = "2.2.0"
|
||||
derive_setters = "0.1.6"
|
||||
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"
|
||||
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"
|
||||
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" }
|
||||
xkb-data = "0.1.0"
|
||||
udev = "0.8.0"
|
||||
generator = "=0.7.5"
|
||||
hostname-validator = "1.1.1"
|
||||
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"] }
|
||||
tachyonix = "0.2.1"
|
||||
|
||||
[dependencies.i18n-embed]
|
||||
version = "0.14.1"
|
||||
|
|
|
|||
|
|
@ -80,6 +80,8 @@ pub enum Message {
|
|||
Orientation(Transform),
|
||||
/// Status of an applied display change.
|
||||
RandrResult(Arc<std::io::Result<ExitStatus>>),
|
||||
/// Request to reload the page.
|
||||
Refresh,
|
||||
/// Set the refresh rate of a display.
|
||||
RefreshRate(usize),
|
||||
/// Set the resolution of a display.
|
||||
|
|
@ -118,6 +120,7 @@ pub struct Page {
|
|||
list: List,
|
||||
display_tabs: segmented_button::SingleSelectModel,
|
||||
active_display: OutputKey,
|
||||
background_service: Option<tokio::task::JoinHandle<()>>,
|
||||
config: Config,
|
||||
cache: ViewCache,
|
||||
context: Option<ContextDrawer>,
|
||||
|
|
@ -130,6 +133,7 @@ impl Default for Page {
|
|||
list: List::default(),
|
||||
display_tabs: segmented_button::SingleSelectModel::default(),
|
||||
active_display: OutputKey::default(),
|
||||
background_service: None,
|
||||
config: Config::default(),
|
||||
cache: ViewCache::default(),
|
||||
context: None,
|
||||
|
|
@ -224,9 +228,43 @@ impl page::Page<crate::pages::Message> for Page {
|
|||
_page: page::Entity,
|
||||
sender: tokio::sync::mpsc::Sender<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())
|
||||
}
|
||||
|
||||
fn on_leave(&mut self) -> Command<crate::pages::Message> {
|
||||
if let Some(task) = self.background_service.take() {
|
||||
task.abort();
|
||||
}
|
||||
|
||||
Command::none()
|
||||
}
|
||||
|
||||
#[cfg(feature = "test")]
|
||||
fn on_enter(
|
||||
&mut self,
|
||||
|
|
@ -295,10 +333,6 @@ impl Page {
|
|||
if let Some(Err(why)) = Arc::into_inner(result) {
|
||||
tracing::error!(?why, "cosmic-randr error");
|
||||
}
|
||||
|
||||
return cosmic::command::future(async {
|
||||
crate::Message::PageMessage(on_enter().await)
|
||||
});
|
||||
}
|
||||
|
||||
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::Refresh => {
|
||||
return cosmic::command::future(async move {
|
||||
crate::Message::PageMessage(on_enter().await)
|
||||
});
|
||||
}
|
||||
|
||||
Message::RefreshRate(rate) => return self.set_refresh_rate(rate),
|
||||
|
||||
Message::Resolution(option) => return self.set_resolution(option),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue