Initial public release of Warp.

Repo-Sync-Origin: warpdotdev/warp-internal@12af1d983b
This commit is contained in:
David Stern
2026-04-28 08:43:33 -05:00
commit 0dbd3d567a
4982 changed files with 1431549 additions and 0 deletions
@@ -0,0 +1,181 @@
//! Provides an application-agnostic D-Bus client for retrieving the
//! desktop environment's appearance settings.
use std::ops::Deref as _;
use std::time::Duration;
use futures::StreamExt as _;
use winit::event_loop::EventLoopProxy;
use zbus::{proxy, zvariant};
use crate::{
platform::SystemTheme,
r#async::{block_on, executor::Background, FutureExt as _},
windowing::winit::app::CustomEvent,
};
const COLOR_SCHEME_SETTINGS_NAMESPACE: &str = "org.freedesktop.appearance";
const COLOR_SCHEME_SETTINGS_KEY: &str = "color-scheme";
/// Values used by the desktop environment to encode the user's
/// system color scheme preference.
#[derive(Debug, Default, serde::Deserialize, serde::Serialize, zbus::zvariant::Type, PartialEq)]
enum SystemColorScheme {
#[default]
NoPreference = 0,
Dark = 1,
Light = 2,
}
impl From<&u32> for SystemColorScheme {
fn from(value: &u32) -> SystemColorScheme {
match value {
0 => SystemColorScheme::NoPreference,
1 => SystemColorScheme::Dark,
2 => SystemColorScheme::Light,
_ => SystemColorScheme::NoPreference,
}
}
}
impl From<&str> for SystemColorScheme {
fn from(value: &str) -> SystemColorScheme {
match value {
"prefer-dark" => SystemColorScheme::Dark,
"prefer-light" => SystemColorScheme::Light,
_ => SystemColorScheme::NoPreference,
}
}
}
impl From<&zvariant::Str<'_>> for SystemColorScheme {
fn from(value: &zvariant::Str) -> SystemColorScheme {
SystemColorScheme::from(value.as_str())
}
}
impl From<&zvariant::Value<'_>> for SystemColorScheme {
fn from(value: &zvariant::Value) -> SystemColorScheme {
match value {
zvariant::Value::U32(u) => SystemColorScheme::from(u),
zvariant::Value::Str(s) => SystemColorScheme::from(s),
zvariant::Value::Value(boxed_v) => match boxed_v.downcast_ref::<u32>() {
Ok(v) => SystemColorScheme::from(&v),
Err(err) => {
log::error!(
"D-Bus inner variant type {:#?}: {:#?} could not be converted to SystemThemePreference: {err:#}",
value.value_signature(),
value
);
SystemColorScheme::NoPreference
}
},
_ => {
log::error!(
"D-Bus outer variant type {:#?}: {:#?} could not be converted to SystemThemePreference",
value.value_signature(),
value
);
SystemColorScheme::NoPreference
}
}
}
}
impl From<&zvariant::OwnedValue> for SystemColorScheme {
fn from(owned_value: &zvariant::OwnedValue) -> SystemColorScheme {
SystemColorScheme::from(owned_value.deref())
}
}
impl From<SystemColorScheme> for SystemTheme {
fn from(os_value: SystemColorScheme) -> SystemTheme {
match os_value {
SystemColorScheme::Dark => SystemTheme::Dark,
SystemColorScheme::Light => SystemTheme::Light,
SystemColorScheme::NoPreference => SystemTheme::default(),
}
}
}
/// A D-Bus client for connecting to the desktop settings.
#[proxy(
interface = "org.freedesktop.portal.Settings",
default_service = "org.freedesktop.portal.Desktop",
default_path = "/org/freedesktop/portal/desktop"
)]
trait DesktopSettings {
fn read(&self, namespace: &str, key: &str) -> zbus::fdo::Result<zvariant::OwnedValue>;
#[zbus(signal)]
fn setting_changed(
&self,
interface_name: &str,
setting_name: &str,
new_setting_value: zvariant::Value<'_>,
) -> zbus::fdo::Result<()>;
}
/// Sets up a background task to listen to desktop settings change events sent
/// over dbus and inject events into the winit EventLoop accordingly.
pub fn watch_desktop_settings_changes(
event_proxy: EventLoopProxy<CustomEvent>,
background: &Background,
) {
background
.spawn(async move {
if let Err(err) = watch_desktop_settings_changes_internal(event_proxy).await {
log::warn!(
"Encountered error while watching for desktop settings change events: {err:#}"
);
}
})
.detach();
}
async fn watch_desktop_settings_changes_internal(
event_proxy: EventLoopProxy<CustomEvent>,
) -> zbus::Result<()> {
let connection = zbus::Connection::session().await?;
let desktop_settings_proxy = DesktopSettingsProxy::new(&connection).await?;
let mut stream = desktop_settings_proxy.receive_setting_changed().await?;
while let Some(msg) = stream.next().await {
let Ok(args) = msg.args() else {
log::warn!("appearance settings signal should have arguments");
continue;
};
// As of now, we are only interested in system color scheme changes.
// In the future, we may check for other types of signals.
if let (&COLOR_SCHEME_SETTINGS_NAMESPACE, &COLOR_SCHEME_SETTINGS_KEY) =
(args.interface_name(), args.setting_name())
{
let _ = event_proxy.send_event(CustomEvent::SystemThemeChanged);
}
}
Ok(())
}
/// Retrieves the system color scheme, blocking for up to 200ms to get the
/// value via dbus.
pub fn get_system_theme() -> Result<SystemTheme, zbus::Error> {
block_on(async {
query_system_theme_from_dbus()
.with_timeout(Duration::from_millis(200))
.await
.unwrap_or_else(|_| {
Err(zbus::Error::from(zbus::fdo::Error::TimedOut(
"Failed to get a response within 200ms".to_owned(),
)))
})
})
}
/// Queries the current D-Bus session bus to get the system color scheme.
async fn query_system_theme_from_dbus() -> Result<SystemTheme, zbus::Error> {
let client_conn = zbus::Connection::session().await?;
let settings_proxy = DesktopSettingsProxy::new(&client_conn).await?;
let owned_val = settings_proxy
.read(COLOR_SCHEME_SETTINGS_NAMESPACE, COLOR_SCHEME_SETTINGS_KEY)
.await?;
Ok(SystemColorScheme::from(&owned_val).into())
}