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,
|
pub autotile_behavior: TileBehavior,
|
||||||
/// Active hint enabled
|
/// Active hint enabled
|
||||||
pub active_hint: bool,
|
pub active_hint: bool,
|
||||||
|
/// Let X11 applications scale themselves
|
||||||
|
pub descale_xwayland: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for CosmicCompConfig {
|
impl Default for CosmicCompConfig {
|
||||||
|
|
@ -48,6 +50,7 @@ impl Default for CosmicCompConfig {
|
||||||
autotile: Default::default(),
|
autotile: Default::default(),
|
||||||
autotile_behavior: Default::default(),
|
autotile_behavior: Default::default(),
|
||||||
active_hint: true,
|
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();
|
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
|
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(
|
fn workspace_set_idx(
|
||||||
|
|
|
||||||
|
|
@ -223,6 +223,7 @@ pub struct Common {
|
||||||
pub xdg_activation_state: XdgActivationState,
|
pub xdg_activation_state: XdgActivationState,
|
||||||
pub xdg_foreign_state: XdgForeignState,
|
pub xdg_foreign_state: XdgForeignState,
|
||||||
pub workspace_state: WorkspaceState<State>,
|
pub workspace_state: WorkspaceState<State>,
|
||||||
|
pub xwayland_scale: Option<i32>,
|
||||||
pub xwayland_state: Option<XWaylandState>,
|
pub xwayland_state: Option<XWaylandState>,
|
||||||
pub xwayland_shell_state: XWaylandShellState,
|
pub xwayland_shell_state: XWaylandShellState,
|
||||||
}
|
}
|
||||||
|
|
@ -354,6 +355,8 @@ impl BackendData {
|
||||||
self.schedule_render(&output);
|
self.schedule_render(&output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loop_handle.insert_idle(|state| state.common.update_xwayland_scale());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -615,6 +618,7 @@ impl State {
|
||||||
xdg_activation_state,
|
xdg_activation_state,
|
||||||
xdg_foreign_state,
|
xdg_foreign_state,
|
||||||
workspace_state,
|
workspace_state,
|
||||||
|
xwayland_scale: None,
|
||||||
xwayland_state: None,
|
xwayland_state: None,
|
||||||
xwayland_shell_state,
|
xwayland_shell_state,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ use crate::{
|
||||||
use smithay::{
|
use smithay::{
|
||||||
backend::drm::DrmNode,
|
backend::drm::DrmNode,
|
||||||
desktop::space::SpaceElement,
|
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},
|
utils::{Logical, Point, Rectangle, Size, SERIAL_COUNTER},
|
||||||
wayland::{
|
wayland::{
|
||||||
selection::{
|
selection::{
|
||||||
|
|
@ -33,13 +33,14 @@ use smithay::{
|
||||||
},
|
},
|
||||||
xwayland::{
|
xwayland::{
|
||||||
xwm::{Reorder, X11Relatable, XwmId},
|
xwm::{Reorder, X11Relatable, XwmId},
|
||||||
X11Surface, X11Wm, XWayland, XWaylandEvent, XwmHandler,
|
X11Surface, X11Wm, XWayland, XWaylandClientData, XWaylandEvent, XwmHandler,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use tracing::{error, trace, warn};
|
use tracing::{error, trace, warn};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct XWaylandState {
|
pub struct XWaylandState {
|
||||||
|
pub client: Client,
|
||||||
pub xwm: Option<X11Wm>,
|
pub xwm: Option<X11Wm>,
|
||||||
pub display: u32,
|
pub display: u32,
|
||||||
}
|
}
|
||||||
|
|
@ -80,6 +81,7 @@ impl State {
|
||||||
display_number,
|
display_number,
|
||||||
} => {
|
} => {
|
||||||
data.common.xwayland_state = Some(XWaylandState {
|
data.common.xwayland_state = Some(XWaylandState {
|
||||||
|
client: client.clone(),
|
||||||
xwm: None,
|
xwm: None,
|
||||||
display: display_number,
|
display: display_number,
|
||||||
});
|
});
|
||||||
|
|
@ -114,6 +116,8 @@ impl State {
|
||||||
let xwayland_state = data.common.xwayland_state.as_mut().unwrap();
|
let xwayland_state = data.common.xwayland_state.as_mut().unwrap();
|
||||||
xwayland_state.xwm = Some(wm);
|
xwayland_state.xwm = Some(wm);
|
||||||
data.notify_ready();
|
data.notify_ready();
|
||||||
|
|
||||||
|
data.common.update_xwayland_scale();
|
||||||
}
|
}
|
||||||
XWaylandEvent::Error => {
|
XWaylandEvent::Error => {
|
||||||
if let Some(mut xwayland_state) = data.common.xwayland_state.take() {
|
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 {
|
impl XwmHandler for State {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue