xwm: Set xcursor variables in Xresources db
This commit is contained in:
parent
612ff2f523
commit
e6a3a3a9c9
4 changed files with 97 additions and 30 deletions
|
|
@ -180,8 +180,10 @@ impl Config {
|
|||
|
||||
let cosmic_comp_config =
|
||||
CosmicCompConfig::get_entry(&config).unwrap_or_else(|(errs, c)| {
|
||||
for err in errs {
|
||||
error!(?err, "");
|
||||
if cfg!(debug_assertions) {
|
||||
for err in errs {
|
||||
warn!(?err, "");
|
||||
}
|
||||
}
|
||||
c
|
||||
});
|
||||
|
|
@ -189,6 +191,11 @@ impl Config {
|
|||
// Listen for updates to the toolkit config
|
||||
if let Ok(tk_config) = cosmic_config::Config::new("com.system76.CosmicTk", 1) {
|
||||
fn handle_new_toolkit_config(config: CosmicTk, state: &mut State) {
|
||||
if cosmic::icon_theme::default() != config.icon_theme {
|
||||
cosmic::icon_theme::set_default(config.icon_theme.clone());
|
||||
state.common.update_xwayland_settings();
|
||||
}
|
||||
|
||||
let mut workspace_guard = state.common.workspace_state.update();
|
||||
state.common.shell.write().update_toolkit(
|
||||
config,
|
||||
|
|
@ -197,19 +204,32 @@ impl Config {
|
|||
);
|
||||
}
|
||||
|
||||
if let Ok(config) = CosmicTk::get_entry(&tk_config) {
|
||||
let _ = loop_handle.insert_idle(move |state| {
|
||||
handle_new_toolkit_config(config, state);
|
||||
});
|
||||
}
|
||||
let config = CosmicTk::get_entry(&tk_config).unwrap_or_else(|(errs, c)| {
|
||||
if cfg!(debug_assertions) {
|
||||
for err in errs {
|
||||
warn!(?err, "");
|
||||
}
|
||||
}
|
||||
c
|
||||
});
|
||||
let _ = loop_handle.insert_idle(move |state| {
|
||||
handle_new_toolkit_config(config, state);
|
||||
});
|
||||
|
||||
match cosmic_config::calloop::ConfigWatchSource::new(&tk_config) {
|
||||
Ok(source) => {
|
||||
if let Err(err) =
|
||||
loop_handle.insert_source(source, |(config, _keys), (), state| {
|
||||
if let Ok(config) = CosmicTk::get_entry(&config) {
|
||||
handle_new_toolkit_config(config, state);
|
||||
}
|
||||
let config =
|
||||
CosmicTk::get_entry(&config).unwrap_or_else(|(errs, c)| {
|
||||
if cfg!(debug_assertions) {
|
||||
for err in errs {
|
||||
warn!(?err, "");
|
||||
}
|
||||
}
|
||||
c
|
||||
});
|
||||
handle_new_toolkit_config(config, state);
|
||||
})
|
||||
{
|
||||
warn!(?err, "Failed to watch com.system76.CosmicTk config");
|
||||
|
|
@ -879,7 +899,7 @@ fn config_changed(config: cosmic_config::Config, keys: Vec<String>, state: &mut
|
|||
let new = get_config::<XwaylandDescaling>(&config, "descale_xwayland");
|
||||
if new != state.common.config.cosmic_conf.descale_xwayland {
|
||||
state.common.config.cosmic_conf.descale_xwayland = new;
|
||||
state.common.update_xwayland_scale();
|
||||
state.common.update_xwayland_settings();
|
||||
}
|
||||
}
|
||||
"xwayland_eavesdropping" => {
|
||||
|
|
|
|||
|
|
@ -4711,10 +4711,6 @@ impl Shell {
|
|||
xdg_activation_state: &XdgActivationState,
|
||||
workspace_state: &mut WorkspaceUpdateGuard<'_, State>,
|
||||
) {
|
||||
if cosmic::icon_theme::default() != toolkit.icon_theme {
|
||||
cosmic::icon_theme::set_default(toolkit.icon_theme.clone());
|
||||
}
|
||||
|
||||
let mut container = cosmic::config::COSMIC_TK.write().unwrap();
|
||||
if *container != toolkit {
|
||||
*container = toolkit;
|
||||
|
|
|
|||
|
|
@ -579,7 +579,7 @@ impl LockedBackend<'_> {
|
|||
|
||||
loop_handle.insert_idle(move |state| {
|
||||
state.update_inhibitor_locks();
|
||||
state.common.update_xwayland_scale();
|
||||
state.common.update_xwayland_settings();
|
||||
state.common.update_xwayland_primary_output();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,10 @@
|
|||
use std::{ffi::OsString, os::unix::io::OwnedFd, process::Stdio};
|
||||
use std::{
|
||||
ffi::OsString,
|
||||
io::Write,
|
||||
os::unix::io::OwnedFd,
|
||||
process::Stdio,
|
||||
sync::mpsc::{self, Receiver, Sender},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
backend::render::cursor::{Cursor, load_cursor_env, load_cursor_theme},
|
||||
|
|
@ -64,6 +70,39 @@ pub struct XWaylandState {
|
|||
pub last_modifier_state: Option<ModifiersState>,
|
||||
pub clipboard_selection_dirty: Option<Vec<String>>,
|
||||
pub primary_selection_dirty: Option<Vec<String>>,
|
||||
pub xrdb_thread: Sender<(String, u32)>,
|
||||
}
|
||||
|
||||
fn xrdb_thread(rx: Receiver<(String, u32)>, display: u32) {
|
||||
while let Ok((cursor_theme, cursor_size)) = rx.recv() {
|
||||
if let Ok(mut child) = std::process::Command::new("xrdb")
|
||||
.arg("-merge")
|
||||
.env("DISPLAY", format!(":{}", display))
|
||||
.stdin(Stdio::piped())
|
||||
.spawn()
|
||||
{
|
||||
let resources = format!(
|
||||
"Xcursor.theme: {}\nXcursor.size: {}\n",
|
||||
cursor_theme, cursor_size,
|
||||
);
|
||||
if let Some(mut stdin) = child.stdin.take() {
|
||||
if let Err(err) = stdin.write_all(resources.as_bytes()) {
|
||||
warn!("Failed to update xresources: {}", err);
|
||||
}
|
||||
}
|
||||
match child.wait() {
|
||||
Ok(code) if code.success() => {}
|
||||
Ok(code) => {
|
||||
warn!("xrdb failed with code: {}", code);
|
||||
}
|
||||
Err(err) => {
|
||||
warn!("Failed to wait for child: {}", err);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
warn!("`xrdb` not found, cannot update Xresources.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl State {
|
||||
|
|
@ -101,6 +140,9 @@ impl State {
|
|||
x11_socket,
|
||||
display_number,
|
||||
} => {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
std::thread::spawn(move || xrdb_thread(rx, display_number));
|
||||
|
||||
data.common.xwayland_state = Some(XWaylandState {
|
||||
client: client.clone(),
|
||||
xwm: None,
|
||||
|
|
@ -110,6 +152,7 @@ impl State {
|
|||
last_modifier_state: None,
|
||||
clipboard_selection_dirty: None,
|
||||
primary_selection_dirty: None,
|
||||
xrdb_thread: tx,
|
||||
});
|
||||
|
||||
let wm = match X11Wm::start_wm(
|
||||
|
|
@ -130,7 +173,7 @@ impl State {
|
|||
xwayland_state.reload_cursor(1.);
|
||||
data.notify_ready();
|
||||
|
||||
data.common.update_xwayland_scale();
|
||||
data.common.update_xwayland_settings();
|
||||
data.common.update_xwayland_primary_output();
|
||||
}
|
||||
XWaylandEvent::Error => {
|
||||
|
|
@ -594,7 +637,7 @@ impl Common {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn update_xwayland_scale(&mut self) {
|
||||
pub fn update_xwayland_settings(&mut self) {
|
||||
let new_scale = match self.config.cosmic_conf.descale_xwayland {
|
||||
XwaylandDescaling::Disabled => 1.,
|
||||
XwaylandDescaling::Enabled => {
|
||||
|
|
@ -619,10 +662,11 @@ impl Common {
|
|||
val
|
||||
}
|
||||
};
|
||||
let (_, cursor_size) = load_cursor_env();
|
||||
|
||||
// compare with current scale
|
||||
if Some(new_scale) != self.xwayland_scale {
|
||||
if let Some(xwayland) = self.xwayland_state.as_mut() {
|
||||
if let Some(xwayland) = self.xwayland_state.as_mut() {
|
||||
let geometries = if Some(new_scale) != self.xwayland_scale {
|
||||
// backup geometries
|
||||
let geometries = self
|
||||
.shell
|
||||
|
|
@ -632,8 +676,6 @@ impl Common {
|
|||
.filter_map(|s| s.0.x11_surface().map(|x| (x.clone(), x.geometry())))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let (_, cursor_size) = load_cursor_env();
|
||||
|
||||
// update xorg dpi
|
||||
if let Some(xwm) = xwayland.xwm.as_mut() {
|
||||
let base = 96. * 1024.;
|
||||
|
|
@ -644,10 +686,6 @@ impl Common {
|
|||
if let Err(err) = xwm.set_xsettings(
|
||||
[
|
||||
("Xft/DPI".into(), (dpi.round() as i32).into()),
|
||||
(
|
||||
"Xcursor/size".into(),
|
||||
((new_scale * cursor_size as f64).round() as i32).into(),
|
||||
),
|
||||
(
|
||||
"Gdk/UnscaledDPI".into(),
|
||||
(unscaled_dpi.round() as i32).into(),
|
||||
|
|
@ -667,9 +705,22 @@ impl Common {
|
|||
}
|
||||
}
|
||||
|
||||
// update cursor
|
||||
xwayland.reload_cursor(new_scale);
|
||||
Some(geometries)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if let Err(_) = xwayland.xrdb_thread.send((
|
||||
cosmic::icon_theme::default(),
|
||||
(new_scale * cursor_size as f64).round() as u32,
|
||||
)) {
|
||||
warn!("xrdb thread died");
|
||||
}
|
||||
|
||||
// update cursor
|
||||
xwayland.reload_cursor(new_scale);
|
||||
|
||||
if let Some(geometries) = geometries {
|
||||
// update client scale
|
||||
xwayland
|
||||
.client
|
||||
|
|
@ -1192,7 +1243,7 @@ impl XwmHandler for State {
|
|||
output_name.as_deref().is_some_and(|o| o == output.name());
|
||||
}
|
||||
self.common.output_configuration_state.update();
|
||||
self.common.update_xwayland_scale();
|
||||
self.common.update_xwayland_settings();
|
||||
self.common
|
||||
.config
|
||||
.write_outputs(self.common.output_configuration_state.outputs());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue