xwayland: Add descaling option
This commit is contained in:
parent
c9220a7acc
commit
971c28db38
5 changed files with 98 additions and 2 deletions
|
|
@ -23,6 +23,8 @@ pub struct CosmicCompConfig {
|
|||
pub autotile_behavior: TileBehavior,
|
||||
/// Active hint enabled
|
||||
pub active_hint: bool,
|
||||
/// Let X11 applications scale themselves
|
||||
pub descale_xwayland: bool,
|
||||
}
|
||||
|
||||
impl Default for CosmicCompConfig {
|
||||
|
|
@ -48,6 +50,7 @@ impl Default for CosmicCompConfig {
|
|||
autotile: Default::default(),
|
||||
autotile_behavior: Default::default(),
|
||||
active_hint: true,
|
||||
descale_xwayland: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -651,6 +651,13 @@ fn config_changed(config: cosmic_config::Config, keys: Vec<String>, state: &mut
|
|||
state.common.update_config();
|
||||
}
|
||||
}
|
||||
"descale_xwayland" => {
|
||||
let new = get_config::<bool>(&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();
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3422,6 +3422,18 @@ impl Shell {
|
|||
|
||||
output_presentation_feedback
|
||||
}
|
||||
|
||||
pub fn mapped(&self) -> impl Iterator<Item = &CosmicMapped> {
|
||||
self.workspaces.iter().flat_map(|(_, set)| {
|
||||
set.sticky_layer
|
||||
.mapped()
|
||||
.chain(set.minimized_windows.iter().map(|m| &m.window))
|
||||
.chain(set.workspaces.iter().flat_map(|w| {
|
||||
w.mapped()
|
||||
.chain(w.minimized_windows.iter().map(|m| &m.window))
|
||||
}))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn workspace_set_idx(
|
||||
|
|
|
|||
|
|
@ -223,6 +223,7 @@ pub struct Common {
|
|||
pub xdg_activation_state: XdgActivationState,
|
||||
pub xdg_foreign_state: XdgForeignState,
|
||||
pub workspace_state: WorkspaceState<State>,
|
||||
pub xwayland_scale: Option<i32>,
|
||||
pub xwayland_state: Option<XWaylandState>,
|
||||
pub xwayland_shell_state: XWaylandShellState,
|
||||
}
|
||||
|
|
@ -354,6 +355,8 @@ impl BackendData {
|
|||
self.schedule_render(&output);
|
||||
}
|
||||
|
||||
loop_handle.insert_idle(|state| state.common.update_xwayland_scale());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -615,6 +618,7 @@ impl State {
|
|||
xdg_activation_state,
|
||||
xdg_foreign_state,
|
||||
workspace_state,
|
||||
xwayland_scale: None,
|
||||
xwayland_state: None,
|
||||
xwayland_shell_state,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use crate::{
|
|||
use smithay::{
|
||||
backend::drm::DrmNode,
|
||||
desktop::space::SpaceElement,
|
||||
reexports::x11rb::protocol::xproto::Window as X11Window,
|
||||
reexports::{wayland_server::Client, x11rb::protocol::xproto::Window as X11Window},
|
||||
utils::{Logical, Point, Rectangle, Size, SERIAL_COUNTER},
|
||||
wayland::{
|
||||
selection::{
|
||||
|
|
@ -33,13 +33,14 @@ use smithay::{
|
|||
},
|
||||
xwayland::{
|
||||
xwm::{Reorder, X11Relatable, XwmId},
|
||||
X11Surface, X11Wm, XWayland, XWaylandEvent, XwmHandler,
|
||||
X11Surface, X11Wm, XWayland, XWaylandClientData, XWaylandEvent, XwmHandler,
|
||||
},
|
||||
};
|
||||
use tracing::{error, trace, warn};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct XWaylandState {
|
||||
pub client: Client,
|
||||
pub xwm: Option<X11Wm>,
|
||||
pub display: u32,
|
||||
}
|
||||
|
|
@ -80,6 +81,7 @@ impl State {
|
|||
display_number,
|
||||
} => {
|
||||
data.common.xwayland_state = Some(XWaylandState {
|
||||
client: client.clone(),
|
||||
xwm: None,
|
||||
display: display_number,
|
||||
});
|
||||
|
|
@ -114,6 +116,8 @@ impl State {
|
|||
let xwayland_state = data.common.xwayland_state.as_mut().unwrap();
|
||||
xwayland_state.xwm = Some(wm);
|
||||
data.notify_ready();
|
||||
|
||||
data.common.update_xwayland_scale();
|
||||
}
|
||||
XWaylandEvent::Error => {
|
||||
if let Some(mut xwayland_state) = data.common.xwayland_state.take() {
|
||||
|
|
@ -242,6 +246,72 @@ impl Common {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_xwayland_scale(&mut self) {
|
||||
let new_scale = if self.config.cosmic_conf.descale_xwayland {
|
||||
let shell = self.shell.read().unwrap();
|
||||
shell
|
||||
.outputs()
|
||||
.map(|o| o.current_scale().integer_scale())
|
||||
.max()
|
||||
.unwrap_or(1) as i32
|
||||
} else {
|
||||
1
|
||||
};
|
||||
|
||||
// compare with current scale
|
||||
if Some(new_scale) != self.xwayland_scale {
|
||||
if let Some(xwayland) = self.xwayland_state.as_mut() {
|
||||
// backup geometries
|
||||
let geometries = self
|
||||
.shell
|
||||
.read()
|
||||
.unwrap()
|
||||
.mapped()
|
||||
.flat_map(|m| m.windows().map(|(s, _)| s))
|
||||
.filter_map(|s| s.0.x11_surface().map(|x| (x.clone(), x.geometry())))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// update xorg dpi
|
||||
if let Some(xwm) = xwayland.xwm.as_mut() {
|
||||
let dpi = new_scale.abs() * 96 * 1024;
|
||||
if let Err(err) = xwm.set_xsettings(
|
||||
[
|
||||
("Xft/DPI".into(), dpi.into()),
|
||||
("Gdk/UnscaledDPI".into(), (dpi / new_scale).into()),
|
||||
("Gdk/WindowScalingFactor".into(), new_scale.into()),
|
||||
]
|
||||
.into_iter(),
|
||||
) {
|
||||
warn!(wm_id = ?xwm.id(), ?err, "Failed to update XSETTINGS.");
|
||||
}
|
||||
}
|
||||
|
||||
// update client scale
|
||||
xwayland
|
||||
.client
|
||||
.get_data::<XWaylandClientData>()
|
||||
.unwrap()
|
||||
.compositor_state
|
||||
.set_client_scale(new_scale as u32);
|
||||
|
||||
// update wl/xdg_outputs
|
||||
for output in self.shell.read().unwrap().outputs() {
|
||||
output.change_current_state(None, None, None, None);
|
||||
}
|
||||
|
||||
// update geometries
|
||||
for (surface, geometry) in geometries.iter() {
|
||||
if let Err(err) = surface.configure(*geometry) {
|
||||
warn!(?err, surface = ?surface.window_id(), "Failed to update geometry after scale change");
|
||||
}
|
||||
}
|
||||
self.update_x11_stacking_order();
|
||||
|
||||
self.xwayland_scale = Some(new_scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl XwmHandler for State {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue