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 =
|
let cosmic_comp_config =
|
||||||
CosmicCompConfig::get_entry(&config).unwrap_or_else(|(errs, c)| {
|
CosmicCompConfig::get_entry(&config).unwrap_or_else(|(errs, c)| {
|
||||||
for err in errs {
|
if cfg!(debug_assertions) {
|
||||||
error!(?err, "");
|
for err in errs {
|
||||||
|
warn!(?err, "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
c
|
c
|
||||||
});
|
});
|
||||||
|
|
@ -189,6 +191,11 @@ impl Config {
|
||||||
// Listen for updates to the toolkit config
|
// Listen for updates to the toolkit config
|
||||||
if let Ok(tk_config) = cosmic_config::Config::new("com.system76.CosmicTk", 1) {
|
if let Ok(tk_config) = cosmic_config::Config::new("com.system76.CosmicTk", 1) {
|
||||||
fn handle_new_toolkit_config(config: CosmicTk, state: &mut State) {
|
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();
|
let mut workspace_guard = state.common.workspace_state.update();
|
||||||
state.common.shell.write().update_toolkit(
|
state.common.shell.write().update_toolkit(
|
||||||
config,
|
config,
|
||||||
|
|
@ -197,19 +204,32 @@ impl Config {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(config) = CosmicTk::get_entry(&tk_config) {
|
let config = CosmicTk::get_entry(&tk_config).unwrap_or_else(|(errs, c)| {
|
||||||
let _ = loop_handle.insert_idle(move |state| {
|
if cfg!(debug_assertions) {
|
||||||
handle_new_toolkit_config(config, state);
|
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) {
|
match cosmic_config::calloop::ConfigWatchSource::new(&tk_config) {
|
||||||
Ok(source) => {
|
Ok(source) => {
|
||||||
if let Err(err) =
|
if let Err(err) =
|
||||||
loop_handle.insert_source(source, |(config, _keys), (), state| {
|
loop_handle.insert_source(source, |(config, _keys), (), state| {
|
||||||
if let Ok(config) = CosmicTk::get_entry(&config) {
|
let config =
|
||||||
handle_new_toolkit_config(config, state);
|
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");
|
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");
|
let new = get_config::<XwaylandDescaling>(&config, "descale_xwayland");
|
||||||
if new != state.common.config.cosmic_conf.descale_xwayland {
|
if new != state.common.config.cosmic_conf.descale_xwayland {
|
||||||
state.common.config.cosmic_conf.descale_xwayland = new;
|
state.common.config.cosmic_conf.descale_xwayland = new;
|
||||||
state.common.update_xwayland_scale();
|
state.common.update_xwayland_settings();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"xwayland_eavesdropping" => {
|
"xwayland_eavesdropping" => {
|
||||||
|
|
|
||||||
|
|
@ -4711,10 +4711,6 @@ impl Shell {
|
||||||
xdg_activation_state: &XdgActivationState,
|
xdg_activation_state: &XdgActivationState,
|
||||||
workspace_state: &mut WorkspaceUpdateGuard<'_, State>,
|
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();
|
let mut container = cosmic::config::COSMIC_TK.write().unwrap();
|
||||||
if *container != toolkit {
|
if *container != toolkit {
|
||||||
*container = toolkit;
|
*container = toolkit;
|
||||||
|
|
|
||||||
|
|
@ -579,7 +579,7 @@ impl LockedBackend<'_> {
|
||||||
|
|
||||||
loop_handle.insert_idle(move |state| {
|
loop_handle.insert_idle(move |state| {
|
||||||
state.update_inhibitor_locks();
|
state.update_inhibitor_locks();
|
||||||
state.common.update_xwayland_scale();
|
state.common.update_xwayland_settings();
|
||||||
state.common.update_xwayland_primary_output();
|
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::{
|
use crate::{
|
||||||
backend::render::cursor::{Cursor, load_cursor_env, load_cursor_theme},
|
backend::render::cursor::{Cursor, load_cursor_env, load_cursor_theme},
|
||||||
|
|
@ -64,6 +70,39 @@ pub struct XWaylandState {
|
||||||
pub last_modifier_state: Option<ModifiersState>,
|
pub last_modifier_state: Option<ModifiersState>,
|
||||||
pub clipboard_selection_dirty: Option<Vec<String>>,
|
pub clipboard_selection_dirty: Option<Vec<String>>,
|
||||||
pub primary_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 {
|
impl State {
|
||||||
|
|
@ -101,6 +140,9 @@ impl State {
|
||||||
x11_socket,
|
x11_socket,
|
||||||
display_number,
|
display_number,
|
||||||
} => {
|
} => {
|
||||||
|
let (tx, rx) = mpsc::channel();
|
||||||
|
std::thread::spawn(move || xrdb_thread(rx, display_number));
|
||||||
|
|
||||||
data.common.xwayland_state = Some(XWaylandState {
|
data.common.xwayland_state = Some(XWaylandState {
|
||||||
client: client.clone(),
|
client: client.clone(),
|
||||||
xwm: None,
|
xwm: None,
|
||||||
|
|
@ -110,6 +152,7 @@ impl State {
|
||||||
last_modifier_state: None,
|
last_modifier_state: None,
|
||||||
clipboard_selection_dirty: None,
|
clipboard_selection_dirty: None,
|
||||||
primary_selection_dirty: None,
|
primary_selection_dirty: None,
|
||||||
|
xrdb_thread: tx,
|
||||||
});
|
});
|
||||||
|
|
||||||
let wm = match X11Wm::start_wm(
|
let wm = match X11Wm::start_wm(
|
||||||
|
|
@ -130,7 +173,7 @@ impl State {
|
||||||
xwayland_state.reload_cursor(1.);
|
xwayland_state.reload_cursor(1.);
|
||||||
data.notify_ready();
|
data.notify_ready();
|
||||||
|
|
||||||
data.common.update_xwayland_scale();
|
data.common.update_xwayland_settings();
|
||||||
data.common.update_xwayland_primary_output();
|
data.common.update_xwayland_primary_output();
|
||||||
}
|
}
|
||||||
XWaylandEvent::Error => {
|
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 {
|
let new_scale = match self.config.cosmic_conf.descale_xwayland {
|
||||||
XwaylandDescaling::Disabled => 1.,
|
XwaylandDescaling::Disabled => 1.,
|
||||||
XwaylandDescaling::Enabled => {
|
XwaylandDescaling::Enabled => {
|
||||||
|
|
@ -619,10 +662,11 @@ impl Common {
|
||||||
val
|
val
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
let (_, cursor_size) = load_cursor_env();
|
||||||
|
|
||||||
// compare with current scale
|
// 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
|
// backup geometries
|
||||||
let geometries = self
|
let geometries = self
|
||||||
.shell
|
.shell
|
||||||
|
|
@ -632,8 +676,6 @@ impl Common {
|
||||||
.filter_map(|s| s.0.x11_surface().map(|x| (x.clone(), x.geometry())))
|
.filter_map(|s| s.0.x11_surface().map(|x| (x.clone(), x.geometry())))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let (_, cursor_size) = load_cursor_env();
|
|
||||||
|
|
||||||
// update xorg dpi
|
// update xorg dpi
|
||||||
if let Some(xwm) = xwayland.xwm.as_mut() {
|
if let Some(xwm) = xwayland.xwm.as_mut() {
|
||||||
let base = 96. * 1024.;
|
let base = 96. * 1024.;
|
||||||
|
|
@ -644,10 +686,6 @@ impl Common {
|
||||||
if let Err(err) = xwm.set_xsettings(
|
if let Err(err) = xwm.set_xsettings(
|
||||||
[
|
[
|
||||||
("Xft/DPI".into(), (dpi.round() as i32).into()),
|
("Xft/DPI".into(), (dpi.round() as i32).into()),
|
||||||
(
|
|
||||||
"Xcursor/size".into(),
|
|
||||||
((new_scale * cursor_size as f64).round() as i32).into(),
|
|
||||||
),
|
|
||||||
(
|
(
|
||||||
"Gdk/UnscaledDPI".into(),
|
"Gdk/UnscaledDPI".into(),
|
||||||
(unscaled_dpi.round() as i32).into(),
|
(unscaled_dpi.round() as i32).into(),
|
||||||
|
|
@ -667,9 +705,22 @@ impl Common {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// update cursor
|
Some(geometries)
|
||||||
xwayland.reload_cursor(new_scale);
|
} 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
|
// update client scale
|
||||||
xwayland
|
xwayland
|
||||||
.client
|
.client
|
||||||
|
|
@ -1192,7 +1243,7 @@ impl XwmHandler for State {
|
||||||
output_name.as_deref().is_some_and(|o| o == output.name());
|
output_name.as_deref().is_some_and(|o| o == output.name());
|
||||||
}
|
}
|
||||||
self.common.output_configuration_state.update();
|
self.common.output_configuration_state.update();
|
||||||
self.common.update_xwayland_scale();
|
self.common.update_xwayland_settings();
|
||||||
self.common
|
self.common
|
||||||
.config
|
.config
|
||||||
.write_outputs(self.common.output_configuration_state.outputs());
|
.write_outputs(self.common.output_configuration_state.outputs());
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue