Merge branch 'master' of https://github.com/pop-os/cosmic-session
This commit is contained in:
commit
346a1a6529
10 changed files with 824 additions and 412 deletions
1031
Cargo.lock
generated
1031
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -11,9 +11,11 @@ publish = false
|
||||||
async-signals = "0.4"
|
async-signals = "0.4"
|
||||||
color-eyre = "0.6"
|
color-eyre = "0.6"
|
||||||
futures-util = "0.3"
|
futures-util = "0.3"
|
||||||
launch-pad = { git = "https://github.com/pop-os/launch-pad" }
|
cosmic-dbus-a11y = { git = "https://github.com/pop-os/dbus-settings-bindings" }
|
||||||
|
|
||||||
|
# launch-pad = { git = "https://github.com/pop-os/launch-pad" }
|
||||||
itertools = "0.12"
|
itertools = "0.12"
|
||||||
#launch-pad = { git = "https://github.com/pop-os/launch-pad", branch = "remove-sync-bounds" }
|
launch-pad = { git = "https://github.com/pop-os/launch-pad" }
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
log-panics = { version = "2", features = ["with-backtrace"] }
|
log-panics = { version = "2", features = ["with-backtrace"] }
|
||||||
rustix = "0.38"
|
rustix = "0.38"
|
||||||
|
|
|
||||||
5
Justfile
5
Justfile
|
|
@ -10,6 +10,8 @@ vendor_args := if vendor == '1' { '--frozen --offline' } else { '' }
|
||||||
debug_args := if debug == '1' { '' } else { '--release' }
|
debug_args := if debug == '1' { '' } else { '--release' }
|
||||||
cargo_args := vendor_args + ' ' + debug_args
|
cargo_args := vendor_args + ' ' + debug_args
|
||||||
xdp_cosmic := '/usr/libexec/xdg-desktop-portal-cosmic'
|
xdp_cosmic := '/usr/libexec/xdg-desktop-portal-cosmic'
|
||||||
|
orca := '/usr/bin/orca'
|
||||||
|
cosmic_dconf_profile := '/usr/share/dconf/profile/cosmic'
|
||||||
|
|
||||||
bindir := prefix + '/bin'
|
bindir := prefix + '/bin'
|
||||||
systemddir := prefix + '/lib/systemd/user'
|
systemddir := prefix + '/lib/systemd/user'
|
||||||
|
|
@ -19,7 +21,7 @@ applicationdir := prefix + '/share/applications'
|
||||||
all: _extract_vendor build
|
all: _extract_vendor build
|
||||||
|
|
||||||
build:
|
build:
|
||||||
XDP_COSMIC={{xdp_cosmic}} cargo build {{cargo_args}}
|
XDP_COSMIC={{xdp_cosmic}} ORCA={{orca}} cargo build {{cargo_args}}
|
||||||
|
|
||||||
# Installs files into the system
|
# Installs files into the system
|
||||||
install:
|
install:
|
||||||
|
|
@ -28,6 +30,7 @@ install:
|
||||||
|
|
||||||
# session start script
|
# session start script
|
||||||
install -Dm0755 data/start-cosmic {{bindir}}/start-cosmic
|
install -Dm0755 data/start-cosmic {{bindir}}/start-cosmic
|
||||||
|
sed -i "s|DCONF_PROFILE=cosmic|DCONF_PROFILE={{cosmic_dconf_profile}}|" {{bindir}}/start-cosmic
|
||||||
|
|
||||||
# systemd target
|
# systemd target
|
||||||
install -Dm0644 data/cosmic-session.target {{systemddir}}/cosmic-session.target
|
install -Dm0644 data/cosmic-session.target {{systemddir}}/cosmic-session.target
|
||||||
|
|
|
||||||
2
data/dconf/profile/cosmic
Normal file
2
data/dconf/profile/cosmic
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
user-db:cosmic
|
||||||
|
user-db:user
|
||||||
|
|
@ -30,13 +30,13 @@ fi
|
||||||
|
|
||||||
export XDG_CURRENT_DESKTOP="${XDG_CURRENT_DESKTOP:=COSMIC}"
|
export XDG_CURRENT_DESKTOP="${XDG_CURRENT_DESKTOP:=COSMIC}"
|
||||||
export XDG_SESSION_TYPE="${XDG_SESSION_TYPE:=wayland}"
|
export XDG_SESSION_TYPE="${XDG_SESSION_TYPE:=wayland}"
|
||||||
export XCURSOR_THEME="${XCURSOR_THEME:=Cosmic}"
|
|
||||||
export _JAVA_AWT_WM_NONREPARENTING=1
|
export _JAVA_AWT_WM_NONREPARENTING=1
|
||||||
export GDK_BACKEND=wayland,x11
|
export GDK_BACKEND=wayland,x11
|
||||||
export MOZ_ENABLE_WAYLAND=1
|
export MOZ_ENABLE_WAYLAND=1
|
||||||
export QT_QPA_PLATFORM="wayland;xcb"
|
export QT_QPA_PLATFORM="wayland;xcb"
|
||||||
export QT_AUTO_SCREEN_SCALE_FACTOR=1
|
export QT_AUTO_SCREEN_SCALE_FACTOR=1
|
||||||
export QT_ENABLE_HIGHDPI_SCALING=1
|
export QT_ENABLE_HIGHDPI_SCALING=1
|
||||||
|
export DCONF_PROFILE=cosmic
|
||||||
|
|
||||||
if command -v systemctl >/dev/null; then
|
if command -v systemctl >/dev/null; then
|
||||||
# set environment variables for new units started by user service manager
|
# set environment variables for new units started by user service manager
|
||||||
|
|
|
||||||
1
debian/control
vendored
1
debian/control
vendored
|
|
@ -22,6 +22,7 @@ Depends:
|
||||||
cosmic-files,
|
cosmic-files,
|
||||||
cosmic-greeter,
|
cosmic-greeter,
|
||||||
cosmic-icons,
|
cosmic-icons,
|
||||||
|
cosmic-idle,
|
||||||
cosmic-launcher,
|
cosmic-launcher,
|
||||||
cosmic-notifications,
|
cosmic-notifications,
|
||||||
cosmic-osd,
|
cosmic-osd,
|
||||||
|
|
|
||||||
1
debian/cosmic-session.install
vendored
Normal file
1
debian/cosmic-session.install
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
data/dconf/profile/cosmic /usr/share/dconf/profile/
|
||||||
80
src/a11y.rs
Normal file
80
src/a11y.rs
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
use futures_util::StreamExt;
|
||||||
|
use launch_pad::ProcessManager;
|
||||||
|
use tokio::sync::mpsc;
|
||||||
|
use tracing::Instrument;
|
||||||
|
|
||||||
|
const ORCA: Option<&'static str> = option_env!("ORCA");
|
||||||
|
|
||||||
|
pub async fn start_a11y(
|
||||||
|
env_vars: Vec<(String, String)>,
|
||||||
|
pman: ProcessManager,
|
||||||
|
) -> color_eyre::Result<()> {
|
||||||
|
let (tx, mut rx) = mpsc::unbounded_channel();
|
||||||
|
let mut process_key = None;
|
||||||
|
let conn = zbus::Connection::session().await?;
|
||||||
|
let proxy = cosmic_dbus_a11y::StatusProxy::new(&conn).await?;
|
||||||
|
|
||||||
|
tokio::spawn(async move {
|
||||||
|
let mut watch_changes = proxy.receive_screen_reader_enabled_changed().await;
|
||||||
|
let mut enabled = false;
|
||||||
|
if let Ok(status) = proxy.screen_reader_enabled().await {
|
||||||
|
_ = tx.send(status);
|
||||||
|
|
||||||
|
enabled = status;
|
||||||
|
}
|
||||||
|
while let Some(change) = watch_changes.next().await {
|
||||||
|
let Ok(new_enabled) = change.get().await else {
|
||||||
|
tokio::time::sleep(tokio::time::Duration::from_secs(10)).await;
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
if enabled != new_enabled {
|
||||||
|
_ = tx.send(new_enabled);
|
||||||
|
enabled = new_enabled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
while let Some(enabled) = rx.recv().await {
|
||||||
|
let stdout_span = info_span!(parent: None, "screen-reader");
|
||||||
|
let stderr_span = stdout_span.clone();
|
||||||
|
if enabled && process_key.is_none() {
|
||||||
|
// spawn orca
|
||||||
|
match pman
|
||||||
|
.start(
|
||||||
|
launch_pad::process::Process::new()
|
||||||
|
.with_executable(ORCA.unwrap_or("/usr/bin/orca"))
|
||||||
|
.with_env(env_vars.clone())
|
||||||
|
.with_on_stdout(move |_, _, line| {
|
||||||
|
let stdout_span = stdout_span.clone();
|
||||||
|
async move {
|
||||||
|
info!("{}", line);
|
||||||
|
}
|
||||||
|
.instrument(stdout_span)
|
||||||
|
})
|
||||||
|
.with_on_stderr(move |_, _, line| {
|
||||||
|
let stderr_span = stderr_span.clone();
|
||||||
|
async move {
|
||||||
|
warn!("{}", line);
|
||||||
|
}
|
||||||
|
.instrument(stderr_span)
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(key) => {
|
||||||
|
process_key = Some(key);
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
tracing::error!("Failed to start screen reader {err:?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if !enabled && process_key.is_some() {
|
||||||
|
// kill orca
|
||||||
|
info!("Stopping screen reader");
|
||||||
|
if let Err(err) = pman.stop_process(process_key.take().unwrap()).await {
|
||||||
|
tracing::error!("Failed to stop screen reader. {err:?}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
@ -173,6 +173,8 @@ async fn send_fd(session_tx: &mut OwnedWriteHalf, stream: Vec<UnixStream>) -> Re
|
||||||
|
|
||||||
pub fn run_compositor(
|
pub fn run_compositor(
|
||||||
process_manager: &ProcessManager,
|
process_manager: &ProcessManager,
|
||||||
|
exec: String,
|
||||||
|
args: Vec<String>,
|
||||||
_token: CancellationToken,
|
_token: CancellationToken,
|
||||||
mut socket_rx: mpsc::UnboundedReceiver<Vec<UnixStream>>,
|
mut socket_rx: mpsc::UnboundedReceiver<Vec<UnixStream>>,
|
||||||
env_tx: oneshot::Sender<HashMap<String, String>>,
|
env_tx: oneshot::Sender<HashMap<String, String>>,
|
||||||
|
|
@ -200,7 +202,8 @@ pub fn run_compositor(
|
||||||
process_manager
|
process_manager
|
||||||
.start_process(
|
.start_process(
|
||||||
Process::new()
|
Process::new()
|
||||||
.with_executable("cosmic-comp")
|
.with_executable(exec)
|
||||||
|
.with_args(args)
|
||||||
.with_env([("COSMIC_SESSION_SOCK", comp.as_raw_fd().to_string())])
|
.with_env([("COSMIC_SESSION_SOCK", comp.as_raw_fd().to_string())])
|
||||||
.with_on_exit(move |pman, _, err_code, _will_restart| {
|
.with_on_exit(move |pman, _, err_code, _will_restart| {
|
||||||
let session_dbus_tx = session_dbus_tx.clone();
|
let session_dbus_tx = session_dbus_tx.clone();
|
||||||
|
|
|
||||||
103
src/main.rs
103
src/main.rs
|
|
@ -2,6 +2,7 @@
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate tracing;
|
extern crate tracing;
|
||||||
|
|
||||||
|
mod a11y;
|
||||||
mod comp;
|
mod comp;
|
||||||
mod notifications;
|
mod notifications;
|
||||||
mod process;
|
mod process;
|
||||||
|
|
@ -10,6 +11,7 @@ mod systemd;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
|
env,
|
||||||
os::fd::{AsRawFd, OwnedFd},
|
os::fd::{AsRawFd, OwnedFd},
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
@ -78,9 +80,10 @@ async fn main() -> Result<()> {
|
||||||
let session_tx_clone = session_tx.clone();
|
let session_tx_clone = session_tx.clone();
|
||||||
let _conn = ConnectionBuilder::session()?
|
let _conn = ConnectionBuilder::session()?
|
||||||
.name("com.system76.CosmicSession")?
|
.name("com.system76.CosmicSession")?
|
||||||
.serve_at("/com/system76/CosmicSession", service::SessionService {
|
.serve_at(
|
||||||
session_tx,
|
"/com/system76/CosmicSession",
|
||||||
})?
|
service::SessionService { session_tx },
|
||||||
|
)?
|
||||||
.build()
|
.build()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|
@ -115,6 +118,12 @@ async fn start(
|
||||||
) -> Result<Status> {
|
) -> Result<Status> {
|
||||||
info!("Starting cosmic-session");
|
info!("Starting cosmic-session");
|
||||||
|
|
||||||
|
let mut args = env::args().skip(1);
|
||||||
|
let (executable, args) = (
|
||||||
|
args.next().unwrap_or_else(|| String::from("cosmic-comp")),
|
||||||
|
args.collect::<Vec<_>>(),
|
||||||
|
);
|
||||||
|
|
||||||
let process_manager = ProcessManager::new().await;
|
let process_manager = ProcessManager::new().await;
|
||||||
_ = process_manager.set_max_restarts(usize::MAX).await;
|
_ = process_manager.set_max_restarts(usize::MAX).await;
|
||||||
_ = process_manager
|
_ = process_manager
|
||||||
|
|
@ -127,6 +136,8 @@ async fn start(
|
||||||
let (env_tx, env_rx) = oneshot::channel();
|
let (env_tx, env_rx) = oneshot::channel();
|
||||||
let compositor_handle = comp::run_compositor(
|
let compositor_handle = comp::run_compositor(
|
||||||
&process_manager,
|
&process_manager,
|
||||||
|
executable.clone(),
|
||||||
|
args,
|
||||||
token.child_token(),
|
token.child_token(),
|
||||||
socket_rx,
|
socket_rx,
|
||||||
env_tx,
|
env_tx,
|
||||||
|
|
@ -149,8 +160,37 @@ async fn start(
|
||||||
env_vars.push(("XDG_SESSION_TYPE".to_string(), "wayland".to_string()));
|
env_vars.push(("XDG_SESSION_TYPE".to_string(), "wayland".to_string()));
|
||||||
systemd::set_systemd_environment("XDG_SESSION_TYPE", "wayland").await;
|
systemd::set_systemd_environment("XDG_SESSION_TYPE", "wayland").await;
|
||||||
|
|
||||||
process_manager
|
let stdout_span = info_span!(parent: None, "cosmic-settings-daemon");
|
||||||
.start(Process::new().with_executable("cosmic-settings-daemon"))
|
let stderr_span = stdout_span.clone();
|
||||||
|
let (settings_exit_tx, settings_exit_rx) = oneshot::channel();
|
||||||
|
let settings_exit_tx = Arc::new(std::sync::Mutex::new(Some(settings_exit_tx)));
|
||||||
|
let settings_daemon = process_manager
|
||||||
|
.start(
|
||||||
|
Process::new()
|
||||||
|
.with_executable("cosmic-settings-daemon")
|
||||||
|
.with_on_stdout(move |_, _, line| {
|
||||||
|
let stdout_span = stdout_span.clone();
|
||||||
|
async move {
|
||||||
|
info!("{}", line);
|
||||||
|
}
|
||||||
|
.instrument(stdout_span)
|
||||||
|
})
|
||||||
|
.with_on_stderr(move |_, _, line| {
|
||||||
|
let stderr_span = stderr_span.clone();
|
||||||
|
async move {
|
||||||
|
warn!("{}", line);
|
||||||
|
}
|
||||||
|
.instrument(stderr_span)
|
||||||
|
})
|
||||||
|
.with_on_exit(move |_, _, _, will_restart| {
|
||||||
|
if !will_restart {
|
||||||
|
if let Some(tx) = settings_exit_tx.lock().unwrap().take() {
|
||||||
|
_ = tx.send(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async {}
|
||||||
|
}),
|
||||||
|
)
|
||||||
.await
|
.await
|
||||||
.expect("failed to start settings daemon");
|
.expect("failed to start settings daemon");
|
||||||
|
|
||||||
|
|
@ -165,6 +205,9 @@ async fn start(
|
||||||
systemd::stop_systemd_target();
|
systemd::stop_systemd_target();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// start a11y if configured
|
||||||
|
tokio::spawn(a11y::start_a11y(env_vars.clone(), process_manager.clone()));
|
||||||
|
|
||||||
let (panel_notifications_fd, daemon_notifications_fd) =
|
let (panel_notifications_fd, daemon_notifications_fd) =
|
||||||
notifications::create_socket().expect("Failed to create notification socket");
|
notifications::create_socket().expect("Failed to create notification socket");
|
||||||
|
|
||||||
|
|
@ -302,27 +345,40 @@ async fn start(
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let span = info_span!(parent: None, "xdg-desktop-portal-cosmic");
|
let span = info_span!(parent: None, "cosmic-idle");
|
||||||
let mut sockets = Vec::with_capacity(1);
|
|
||||||
let extra_env = Vec::with_capacity(1);
|
|
||||||
let portal_extras =
|
|
||||||
if let Ok((mut env, fd)) = create_privileged_socket(&mut sockets, &extra_env) {
|
|
||||||
let mut env = env.remove(0);
|
|
||||||
env.0 = "PORTAL_WAYLAND_SOCKET".to_string();
|
|
||||||
vec![(fd, env, sockets.remove(0))]
|
|
||||||
} else {
|
|
||||||
Vec::new()
|
|
||||||
};
|
|
||||||
start_component(
|
start_component(
|
||||||
XDP_COSMIC.unwrap_or("/usr/libexec/xdg-desktop-portal-cosmic"),
|
"cosmic-idle",
|
||||||
span,
|
span,
|
||||||
&process_manager,
|
&process_manager,
|
||||||
&env_vars,
|
&env_vars,
|
||||||
&socket_tx,
|
&socket_tx,
|
||||||
portal_extras,
|
Vec::new(),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
if env::var("XDG_CURRENT_DESKTOP").as_deref() == Ok("COSMIC") {
|
||||||
|
let span = info_span!(parent: None, "xdg-desktop-portal-cosmic");
|
||||||
|
let mut sockets = Vec::with_capacity(1);
|
||||||
|
let extra_env = Vec::with_capacity(1);
|
||||||
|
let portal_extras =
|
||||||
|
if let Ok((mut env, fd)) = create_privileged_socket(&mut sockets, &extra_env) {
|
||||||
|
let mut env = env.remove(0);
|
||||||
|
env.0 = "PORTAL_WAYLAND_SOCKET".to_string();
|
||||||
|
vec![(fd, env, sockets.remove(0))]
|
||||||
|
} else {
|
||||||
|
Vec::new()
|
||||||
|
};
|
||||||
|
start_component(
|
||||||
|
XDP_COSMIC.unwrap_or("/usr/libexec/xdg-desktop-portal-cosmic"),
|
||||||
|
span,
|
||||||
|
&process_manager,
|
||||||
|
&env_vars,
|
||||||
|
&socket_tx,
|
||||||
|
portal_extras,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
|
||||||
let mut signals = Signals::new(vec![libc::SIGTERM, libc::SIGINT]).unwrap();
|
let mut signals = Signals::new(vec![libc::SIGTERM, libc::SIGINT]).unwrap();
|
||||||
let mut status = Status::Exited;
|
let mut status = Status::Exited;
|
||||||
loop {
|
loop {
|
||||||
|
|
@ -357,6 +413,17 @@ async fn start(
|
||||||
}
|
}
|
||||||
compositor_handle.abort();
|
compositor_handle.abort();
|
||||||
token.cancel();
|
token.cancel();
|
||||||
|
if let Err(err) = process_manager.stop_process(settings_daemon).await {
|
||||||
|
tracing::error!("Failed to gracefully stop settings daemon. {err:?}");
|
||||||
|
} else {
|
||||||
|
match tokio::time::timeout(Duration::from_secs(1), settings_exit_rx).await {
|
||||||
|
Ok(Ok(_)) => {}
|
||||||
|
_ => {
|
||||||
|
tracing::error!("Failed to gracefully stop settings daemon.");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
tokio::time::sleep(std::time::Duration::from_secs(2)).await;
|
tokio::time::sleep(std::time::Duration::from_secs(2)).await;
|
||||||
Ok(status)
|
Ok(status)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue