diff --git a/jay-config/src/_private/client.rs b/jay-config/src/_private/client.rs index 6915f056..6ad8d154 100644 --- a/jay-config/src/_private/client.rs +++ b/jay-config/src/_private/client.rs @@ -810,6 +810,10 @@ impl Client { self.send(&ClientMessage::SetIdle { timeout }) } + pub fn set_explicit_sync_enabled(&self, enabled: bool) { + self.send(&ClientMessage::SetExplicitSyncEnabled { enabled }) + } + pub fn set_seat(&self, device: InputDevice, seat: Seat) { self.send(&ClientMessage::SetSeat { device, seat }) } diff --git a/jay-config/src/_private/ipc.rs b/jay-config/src/_private/ipc.rs index 07c1f7ed..24854645 100644 --- a/jay-config/src/_private/ipc.rs +++ b/jay-config/src/_private/ipc.rs @@ -428,6 +428,9 @@ pub enum ClientMessage<'a> { workspace: WorkspaceSource, connector: Connector, }, + SetExplicitSyncEnabled { + enabled: bool, + }, } #[derive(Serialize, Deserialize, Debug)] diff --git a/jay-config/src/lib.rs b/jay-config/src/lib.rs index 83543401..4356d23f 100644 --- a/jay-config/src/lib.rs +++ b/jay-config/src/lib.rs @@ -222,3 +222,12 @@ pub fn workspaces() -> Vec { pub fn set_idle(timeout: Option) { get!().set_idle(timeout.unwrap_or_default()) } + +/// Enables or disables explicit sync. +/// +/// Calling this after the compositor has started has no effect. +/// +/// The default is `true`. +pub fn set_explicit_sync_enabled(enabled: bool) { + get!().set_explicit_sync_enabled(enabled); +} diff --git a/src/compositor.rs b/src/compositor.rs index be6ad83d..c435c5b8 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -224,6 +224,7 @@ fn start_compositor2( create_default_seat: Cell::new(true), subsurface_ids: Default::default(), wait_for_sync_obj: Rc::new(WaitForSyncObj::new(&ring, &engine)), + explicit_sync_enabled: Cell::new(true), }); state.tracker.register(ClientId::from_raw(0)); create_dummy_output(&state); diff --git a/src/config/handler.rs b/src/config/handler.rs index f9bbb4f1..8940cfc5 100644 --- a/src/config/handler.rs +++ b/src/config/handler.rs @@ -800,6 +800,10 @@ impl ConfigProxyHandler { self.state.idle.set_timeout(timeout); } + fn handle_set_explicit_sync_enabled(&self, enabled: bool) { + self.state.explicit_sync_enabled.set(enabled); + } + fn handle_connector_connected(&self, connector: Connector) -> Result<(), CphError> { let connector = self.get_connector(connector)?; self.respond(Response::ConnectorConnected { @@ -1725,6 +1729,9 @@ impl ConfigProxyHandler { } => self .handle_move_to_output(workspace, connector) .wrn("move_to_output")?, + ClientMessage::SetExplicitSyncEnabled { enabled } => { + self.handle_set_explicit_sync_enabled(enabled) + } } Ok(()) } diff --git a/src/state.rs b/src/state.rs index d7d6a87a..ff1ad5c9 100644 --- a/src/state.rs +++ b/src/state.rs @@ -172,6 +172,7 @@ pub struct State { pub create_default_seat: Cell, pub subsurface_ids: SubsurfaceIds, pub wait_for_sync_obj: Rc, + pub explicit_sync_enabled: Cell, } // impl Drop for State { @@ -450,7 +451,7 @@ impl State { if !self.render_ctx_ever_initialized.replace(true) { self.add_global(&Rc::new(WlDrmGlobal::new(self.globals.name()))); self.add_global(&Rc::new(ZwpLinuxDmabufV1Global::new(self.globals.name()))); - if ctx.sync_obj_ctx().supports_async_wait() { + if ctx.sync_obj_ctx().supports_async_wait() && self.explicit_sync_enabled.get() { self.add_global(&Rc::new(WpLinuxDrmSyncobjManagerV1Global::new( self.globals.name(), ))); diff --git a/toml-config/src/config.rs b/toml-config/src/config.rs index efdcceef..23e6153e 100644 --- a/toml-config/src/config.rs +++ b/toml-config/src/config.rs @@ -289,6 +289,7 @@ pub struct Config { pub render_device: Option, pub inputs: Vec, pub idle: Option, + pub explicit_sync_enabled: Option, } #[derive(Debug, Error)] diff --git a/toml-config/src/config/parsers/config.rs b/toml-config/src/config/parsers/config.rs index 78da91df..ea70ab81 100644 --- a/toml-config/src/config/parsers/config.rs +++ b/toml-config/src/config/parsers/config.rs @@ -95,6 +95,7 @@ impl Parser for ConfigParser<'_> { _, idle_val, ), + (explicit_sync,), ) = ext.extract(( ( opt(val("keymap")), @@ -120,6 +121,7 @@ impl Parser for ConfigParser<'_> { opt(val("$schema")), opt(val("idle")), ), + (recover(opt(bol("explicit-sync"))),), ))?; let mut keymap = None; if let Some(value) = keymap_val { @@ -271,6 +273,7 @@ impl Parser for ConfigParser<'_> { gfx_api, drm_devices, direct_scanout_enabled: direct_scanout.despan(), + explicit_sync_enabled: explicit_sync.despan(), render_device, inputs, idle, diff --git a/toml-config/src/lib.rs b/toml-config/src/lib.rs index edfd840d..6d107d03 100644 --- a/toml-config/src/lib.rs +++ b/toml-config/src/lib.rs @@ -19,7 +19,8 @@ use { is_reload, keyboard::{Keymap, ModifiedKeySym}, logging::set_log_level, - on_devices_enumerated, on_idle, quit, reload, set_default_workspace_capture, set_idle, + on_devices_enumerated, on_idle, quit, reload, set_default_workspace_capture, + set_explicit_sync_enabled, set_idle, status::{set_i3bar_separator, set_status, set_status_command, unset_status_command}, switch_to_vt, theme::{reset_colors, reset_font, reset_sizes, set_font}, @@ -789,6 +790,9 @@ fn load_config(initial_load: bool, persistent: &Rc) { if let Some(dse) = config.direct_scanout_enabled { set_direct_scanout_enabled(dse); } + if let Some(ese) = config.explicit_sync_enabled { + set_explicit_sync_enabled(ese); + } on_new_drm_device({ let state = state.clone(); move |d| { diff --git a/toml-spec/spec/spec.generated.json b/toml-spec/spec/spec.generated.json index cdf97b93..581b20a6 100644 --- a/toml-spec/spec/spec.generated.json +++ b/toml-spec/spec/spec.generated.json @@ -498,6 +498,10 @@ "type": "boolean", "description": "Configured whether the compositor attempts direct scanout.\n" }, + "explicit-sync": { + "type": "boolean", + "description": "Configures whether the compositor supports explicit sync.\n\nThis cannot be changed after the compositor has started.\n\nThe default is `true`.\n" + }, "render-device": { "description": "Selects the device to use for rendering in a system with multiple GPUs.\n\nThe first device that matches will be used.\n\n- Example:\n\n ```toml\n render-device.name = \"dedicated\"\n\n [[drm-devices]]\n name = \"dedicated\"\n match = { pci-vendor = 0x1002, pci-model = 0x73ff }\n ```\n", "$ref": "#/$defs/DrmDeviceMatch" diff --git a/toml-spec/spec/spec.generated.md b/toml-spec/spec/spec.generated.md index 45c6201e..93646c40 100644 --- a/toml-spec/spec/spec.generated.md +++ b/toml-spec/spec/spec.generated.md @@ -887,6 +887,16 @@ The table has the following fields: The value of this field should be a boolean. +- `explicit-sync` (optional): + + Configures whether the compositor supports explicit sync. + + This cannot be changed after the compositor has started. + + The default is `true`. + + The value of this field should be a boolean. + - `render-device` (optional): Selects the device to use for rendering in a system with multiple GPUs. diff --git a/toml-spec/spec/spec.yaml b/toml-spec/spec/spec.yaml index 458a05d6..2d4a7d43 100644 --- a/toml-spec/spec/spec.yaml +++ b/toml-spec/spec/spec.yaml @@ -1875,6 +1875,15 @@ Config: required: false description: | Configured whether the compositor attempts direct scanout. + explicit-sync: + kind: boolean + required: false + description: | + Configures whether the compositor supports explicit sync. + + This cannot be changed after the compositor has started. + + The default is `true`. render-device: ref: DrmDeviceMatch required: false