1
0
Fork 0
forked from wry/wry

Merge pull request #746 from khyperia/xwayland-disable

config: add XWayland enabled option
This commit is contained in:
mahkoh 2026-02-17 21:34:39 +01:00 committed by GitHub
commit 2a15a9e272
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 85 additions and 10 deletions

View file

@ -1182,6 +1182,10 @@ impl ConfigClient {
self.send(&ClientMessage::SetXScalingMode { mode })
}
pub fn set_x_wayland_enabled(&self, enabled: bool) {
self.send(&ClientMessage::SetXWaylandEnabled { enabled })
}
pub fn set_vrr_mode(&self, connector: Option<Connector>, mode: VrrMode) {
self.send(&ClientMessage::SetVrrMode { connector, mode })
}

View file

@ -831,6 +831,9 @@ pub enum ClientMessage<'a> {
seat: Seat,
mode: FallbackOutputMode,
},
SetXWaylandEnabled {
enabled: bool,
},
}
#[derive(Serialize, Deserialize, Debug)]

View file

@ -2,6 +2,13 @@
use serde::{Deserialize, Serialize};
/// Sets whether Xwayland is enabled
///
/// The default is `true`.
pub fn set_x_wayland_enabled(enabled: bool) {
get!().set_x_wayland_enabled(enabled)
}
/// The scaling mode of X windows.
#[derive(Serialize, Deserialize, Copy, Clone, Debug, Eq, PartialEq, Hash, Default)]
pub struct XScalingMode(pub u32);

View file

@ -269,6 +269,7 @@ fn start_compositor2(
run_args,
xwayland: XWaylandState {
enabled: Cell::new(true),
running: Cell::new(false),
pidfd: Default::default(),
handler: Default::default(),
queue: Default::default(),

View file

@ -979,6 +979,11 @@ impl ConfigProxyHandler {
Ok(())
}
fn handle_set_x_wayland_enabled(&self, enabled: bool) -> Result<(), CphError> {
self.state.set_xwayland_enabled(enabled);
Ok(())
}
fn handle_set_ui_drag_enabled(&self, enabled: bool) {
self.state.ui_drag_enabled.set(enabled);
}
@ -3369,6 +3374,9 @@ impl ConfigProxyHandler {
ClientMessage::SetFallbackOutputMode { seat, mode } => self
.handle_set_fallback_output_mode(seat, mode)
.wrn("set_fallback_output_mode")?,
ClientMessage::SetXWaylandEnabled { enabled } => self
.handle_set_x_wayland_enabled(enabled)
.wrn("set_x_wayland_enabled")?,
}
Ok(())
}

View file

@ -313,6 +313,7 @@ pub struct ScreenlockState {
pub struct XWaylandState {
pub enabled: Cell<bool>,
pub running: Cell<bool>,
pub pidfd: CloneCell<Option<Rc<OwnedFd>>>,
pub handler: RefCell<Option<SpawnedFuture<()>>>,
pub queue: Rc<AsyncQueue<XWaylandEvent>>,
@ -968,6 +969,24 @@ impl State {
}
}
pub fn stop_xwayland(&self) {
if self.xwayland.running.get() {
return;
}
self.xwayland.handler.take();
}
pub fn set_xwayland_enabled(self: &Rc<Self>, enabled: bool) {
if self.xwayland.enabled.replace(enabled) == enabled {
return;
}
if enabled {
self.start_xwayland();
} else {
self.stop_xwayland();
}
}
pub fn next_serial(&self, client: Option<&Client>) -> u64 {
let serial = self.serial.fetch_add(1);
if let Some(client) = client {

View file

@ -110,6 +110,7 @@ pub async fn manage(state: Rc<State>) {
}
let display = format!(":{}", xsocket.id);
forker.setenv(DISPLAY.as_bytes(), display.as_bytes());
let _unsetenv = on_drop(|| forker.unsetenv(DISPLAY.as_bytes()));
log::info!("Allocated display :{} for Xwayland", xsocket.id);
log::info!("Waiting for connection attempt");
if state.backend.get().import_environment() {
@ -120,12 +121,17 @@ pub async fn manage(state: Rc<State>) {
return;
}
log::info!("Starting Xwayland");
state.xwayland.running.set(true);
if let Err(e) = run(&state, &forker, socket).await {
log::error!("Xwayland failed: {}", ErrorFmt(e));
} else {
log::warn!("Xwayland exited unexpectedly");
}
forker.unsetenv(DISPLAY.as_bytes());
state.xwayland.running.set(false);
if !state.xwayland.enabled.get() {
state.stop_xwayland();
return;
}
}
}

View file

@ -463,6 +463,7 @@ pub struct SimpleIm {
#[derive(Debug, Clone)]
pub struct Xwayland {
pub enabled: Option<bool>,
pub scaling_mode: Option<XScalingMode>,
}

View file

@ -3,11 +3,11 @@ use {
config::{
Xwayland,
context::Context,
extractor::{Extractor, ExtractorError, opt, val},
extractor::{Extractor, ExtractorError, bol, opt, recover, val},
parser::{DataType, ParseResult, Parser, UnexpectedDataType},
},
toml::{
toml_span::{Span, Spanned, SpannedExt},
toml_span::{DespanExt, Span, Spanned, SpannedExt},
toml_value::Value,
},
},
@ -37,7 +37,8 @@ impl Parser for XwaylandParser<'_> {
table: &IndexMap<Spanned<String>, Spanned<Value>>,
) -> ParseResult<Self> {
let mut ext = Extractor::new(self.0, span, table);
let scaling_mode = ext.extract(opt(val("scaling-mode")))?;
let (enabled, scaling_mode) =
ext.extract((recover(opt(bol("enabled"))), opt(val("scaling-mode"))))?;
let scaling_mode = scaling_mode.and_then(|m| match m.parse(&mut XScalingModeParser) {
Ok(m) => Some(m),
Err(e) => {
@ -45,7 +46,10 @@ impl Parser for XwaylandParser<'_> {
None
}
});
Ok(Xwayland { scaling_mode })
Ok(Xwayland {
enabled: enabled.despan(),
scaling_mode,
})
}
}

View file

@ -56,7 +56,7 @@ use {
},
window::Window,
workspace::set_workspace_display_order,
xwayland::set_x_scaling_mode,
xwayland::{set_x_scaling_mode, set_x_wayland_enabled},
},
run_on_drop::on_drop,
std::{
@ -1578,10 +1578,13 @@ fn load_config(initial_load: bool, auto_reload: bool, persistent: &Rc<Persistent
if let Some(threshold) = config.ui_drag.threshold {
set_ui_drag_threshold(threshold);
}
if let Some(xwayland) = config.xwayland
&& let Some(mode) = xwayland.scaling_mode
{
set_x_scaling_mode(mode);
if let Some(xwayland) = config.xwayland {
if let Some(enabled) = xwayland.enabled {
set_x_wayland_enabled(enabled);
}
if let Some(mode) = xwayland.scaling_mode {
set_x_scaling_mode(mode);
}
}
if let Some(cm) = config.color_management
&& let Some(enabled) = cm.enabled

View file

@ -2349,6 +2349,10 @@
"description": "Describes Xwayland settings.\n\n- Example:\n\n ```toml\n xwayland = { scaling-mode = \"downscaled\" }\n ```\n",
"type": "object",
"properties": {
"enabled": {
"type": "boolean",
"description": "Enables or disables XWayland.\n\nThe default is `true`.\n"
},
"scaling-mode": {
"description": "The scaling mode of X windows.",
"$ref": "#/$defs/XScalingMode"

View file

@ -5319,6 +5319,14 @@ Values of this type should be tables.
The table has the following fields:
- `enabled` (optional):
Enables or disables XWayland.
The default is `true`.
The value of this field should be a boolean.
- `scaling-mode` (optional):
The scaling mode of X windows.

View file

@ -3428,6 +3428,13 @@ Xwayland:
xwayland = { scaling-mode = "downscaled" }
```
fields:
enabled:
kind: boolean
required: false
description: |
Enables or disables XWayland.
The default is `true`.
scaling-mode:
ref: XScalingMode
required: false