diff --git a/src/wayland/handlers/output_configuration.rs b/src/wayland/handlers/output_configuration.rs index 1f0ad7bb..d97d2009 100644 --- a/src/wayland/handlers/output_configuration.rs +++ b/src/wayland/handlers/output_configuration.rs @@ -6,6 +6,7 @@ use tracing::{error, warn}; use crate::{ config::{OutputConfig, OutputState}, state::State, + utils::prelude::OutputExt, wayland::protocols::output_configuration::{ delegate_output_configuration, ModeConfiguration, OutputConfiguration, OutputConfigurationHandler, OutputConfigurationState, @@ -25,6 +26,17 @@ impl OutputConfigurationHandler for State { fn apply_configuration(&mut self, conf: Vec<(Output, OutputConfiguration)>) -> bool { self.output_configuration(false, conf) } + + fn request_xwayland_primary(&mut self, primary_output: Option) { + for output in self.common.output_configuration_state.outputs() { + output.config_mut().xwayland_primary = + primary_output.as_ref().is_some_and(|o| *o == output); + } + self.common.update_xwayland_primary_output(); + self.common + .config + .write_outputs(self.common.output_configuration_state.outputs()); + } } impl State { diff --git a/src/wayland/protocols/output_configuration/handlers/cosmic.rs b/src/wayland/protocols/output_configuration/handlers/cosmic.rs index b0b768df..88f667f4 100644 --- a/src/wayland/protocols/output_configuration/handlers/cosmic.rs +++ b/src/wayland/protocols/output_configuration/handlers/cosmic.rs @@ -21,7 +21,7 @@ use cosmic_protocols::output_management::v1::server::{ zcosmic_output_manager_v1::{self, ZcosmicOutputManagerV1}, }; -use crate::wayland::protocols::output_configuration::*; +use crate::{config::OutputState as EnabledState, wayland::protocols::output_configuration::*}; impl GlobalDispatch for OutputConfigurationState @@ -109,6 +109,25 @@ where } => { data_init.init(extended, config_head.downgrade()); } + zcosmic_output_manager_v1::Request::SetXwaylandPrimary { head } => { + let Some(head) = head else { + state.request_xwayland_primary(None); + return; + }; + + let inner = state.output_configuration_state(); + if let Some(head_data) = inner.instances.iter_mut().find_map(|instance| { + instance + .heads + .iter() + .find(|instance| instance.extension_obj.as_ref() == Some(&head)) + }) { + let output = head_data.output.clone(); + if output.config().enabled == EnabledState::Enabled { + state.request_xwayland_primary(Some(output)); + } + } + } _ => {} } } diff --git a/src/wayland/protocols/output_configuration/mod.rs b/src/wayland/protocols/output_configuration/mod.rs index 9cffb102..0165ed38 100644 --- a/src/wayland/protocols/output_configuration/mod.rs +++ b/src/wayland/protocols/output_configuration/mod.rs @@ -58,6 +58,8 @@ pub trait OutputConfigurationHandler: Sized { fn test_configuration(&mut self, conf: Vec<(Output, OutputConfiguration)>) -> bool; fn apply_configuration(&mut self, conf: Vec<(Output, OutputConfiguration)>) -> bool; + + fn request_xwayland_primary(&mut self, output: Option); } pub struct OutputMngrGlobalData { @@ -189,7 +191,7 @@ where ); let extension_global = dh.create_global::( - 2, + 3, OutputMngrGlobalData { filter: Box::new(client_filter), }, @@ -505,6 +507,14 @@ where instance.obj.model(physical.model); } } + + if let Some(extension_obj) = instance.extension_obj.as_ref() { + if inner.enabled + && extension_obj.version() >= zcosmic_output_head_v1::EVT_XWAYLAND_PRIMARY_SINCE + { + extension_obj.xwayland_primary(output.config().xwayland_primary as u32); + } + } } fn remove_global_with_timer( diff --git a/src/xwayland.rs b/src/xwayland.rs index 10c28faa..8835fdf5 100644 --- a/src/xwayland.rs +++ b/src/xwayland.rs @@ -652,9 +652,12 @@ impl Common { if let Some(xwm) = xstate.xwm.as_mut() { if let Err(err) = xwm.set_randr_primary_output(xwayland_primary_output.as_ref()) { warn!("Failed to set xwayland primary output: {}", err); + return; }; } } + + self.output_configuration_state.update(); } }