diff --git a/src/compositor.rs b/src/compositor.rs index 8ef2f6f9..7967ed46 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -642,6 +642,8 @@ fn create_dummy_output(state: &Rc) { name: RcEq(name.clone()), position: (0, 0), size: (0, 0), + active: false, + connected: false, transform: Transform::None, scale: Default::default(), wl_output: None, diff --git a/src/ifs/head_management.rs b/src/ifs/head_management.rs index a1e470fa..162d8e42 100644 --- a/src/ifs/head_management.rs +++ b/src/ifs/head_management.rs @@ -68,6 +68,8 @@ pub struct HeadState { pub name: RcEq, pub wl_output: Option, pub connector_enabled: bool, + pub active: bool, + pub connected: bool, pub in_compositor_space: bool, pub position: (i32, i32), pub size: (i32, i32), @@ -201,6 +203,7 @@ impl HeadManagers { pub fn handle_output_connected(&self, output: &OutputData) { let state = &mut *self.state.borrow_mut(); + state.connected = true; state.monitor_info = Some(RcEq(output.monitor_info.clone())); state.update_in_compositor_space(output.node.as_ref().map(|n| n.global.name)); if let Some(n) = &output.node { @@ -211,6 +214,10 @@ impl HeadManagers { } for head in self.managers.lock().values() { skip_in_transaction!(head); + if let Some(ext) = &head.ext.connector_info_v1 { + ext.send_connected(state); + head.session.schedule_done(); + } if let Some(ext) = &head.ext.compositor_space_info_v1 { ext.send_inside_outside(state); head.session.schedule_done(); @@ -224,6 +231,7 @@ impl HeadManagers { pub fn handle_output_disconnected(&self) { let state = &mut *self.state.borrow_mut(); + state.connected = false; state.monitor_info = None; state.update_in_compositor_space(None); for head in self.managers.lock().values() { @@ -232,6 +240,10 @@ impl HeadManagers { ext.send_inside_outside(state); head.session.schedule_done(); } + if let Some(ext) = &head.ext.connector_info_v1 { + ext.send_connected(state); + head.session.schedule_done(); + } if let Some(ext) = &head.ext.core_info_v1 { ext.send_wl_output(state); head.session.schedule_done(); @@ -292,4 +304,16 @@ impl HeadManagers { } } } + + pub fn handle_active_change(&self, active: bool) { + let state = &mut *self.state.borrow_mut(); + state.active = active; + for head in self.managers.lock().values() { + skip_in_transaction!(head); + if let Some(ext) = &head.ext.connector_info_v1 { + ext.send_active(state); + head.session.schedule_done(); + } + } + } } diff --git a/src/ifs/head_management/head_management_macros.rs b/src/ifs/head_management/head_management_macros.rs index 52d6c99a..db079acf 100644 --- a/src/ifs/head_management/head_management_macros.rs +++ b/src/ifs/head_management/head_management_macros.rs @@ -394,4 +394,5 @@ declare_extensions! { compositor_space_transformer_v1: CompositorSpaceTransformerV1, compositor_space_scaler_v1: CompositorSpaceScalerV1, compositor_space_enabler_v1: CompositorSpaceEnablerV1, + connector_info_v1: ConnectorInfoV1, } diff --git a/src/ifs/head_management/jay_head_ext.rs b/src/ifs/head_management/jay_head_ext.rs index 2d5dda28..29d69415 100644 --- a/src/ifs/head_management/jay_head_ext.rs +++ b/src/ifs/head_management/jay_head_ext.rs @@ -3,4 +3,5 @@ pub(super) mod jay_head_ext_compositor_space_info_v1; pub(super) mod jay_head_ext_compositor_space_positioner_v1; pub(super) mod jay_head_ext_compositor_space_scaler_v1; pub(super) mod jay_head_ext_compositor_space_transformer_v1; +pub(super) mod jay_head_ext_connector_info_v1; pub(super) mod jay_head_ext_core_info_v1; diff --git a/src/ifs/head_management/jay_head_ext/jay_head_ext_connector_info_v1.rs b/src/ifs/head_management/jay_head_ext/jay_head_ext_connector_info_v1.rs new file mode 100644 index 00000000..5cb8da3f --- /dev/null +++ b/src/ifs/head_management/jay_head_ext/jay_head_ext_connector_info_v1.rs @@ -0,0 +1,73 @@ +use { + crate::{ + backend::CONCAP_CONNECTOR, + ifs::head_management::{HeadCommon, HeadState}, + state::ConnectorData, + wire::{ + jay_head_ext_connector_info_v1::{ + Active, Connected, Disconnected, Inactive, JayHeadExtConnectorInfoV1RequestHandler, + }, + jay_head_manager_ext_connector_info_v1::JayHeadManagerExtConnectorInfoV1RequestHandler, + }, + }, + std::rc::Rc, +}; + +impl_connector_info_v1! { + version = 1, + filter = filter, + after_announce = after_announce, + after_transaction = after_transaction, +} + +impl MgrName { + fn filter(&self, connector: &ConnectorData, _common: &Rc) -> bool { + connector.connector.caps().contains(CONCAP_CONNECTOR) + } +} + +impl HeadName { + fn after_announce(&self, shared: &HeadState) { + self.send_connected(shared); + self.send_active(shared); + } + + fn after_transaction(&self, shared: &HeadState, tran: &HeadState) { + if shared.connected != tran.connected { + self.send_connected(shared); + } + if shared.active != tran.active { + self.send_active(shared); + } + } + + pub(in super::super) fn send_connected(&self, state: &HeadState) { + if state.connected { + self.client.event(Connected { self_id: self.id }); + } else { + self.client.event(Disconnected { self_id: self.id }); + } + } + + pub(in super::super) fn send_active(&self, state: &HeadState) { + if state.active { + self.client.event(Active { self_id: self.id }); + } else { + self.client.event(Inactive { self_id: self.id }); + } + } +} + +impl JayHeadManagerExtConnectorInfoV1RequestHandler for MgrName { + type Error = ErrorName; + + mgr_common_req!(); +} + +impl JayHeadExtConnectorInfoV1RequestHandler for HeadName { + type Error = ErrorName; + + head_common_req!(); +} + +error!(); diff --git a/src/state.rs b/src/state.rs index f708ef92..1e79ca79 100644 --- a/src/state.rs +++ b/src/state.rs @@ -446,6 +446,9 @@ impl ConnectorData { if old.enabled != s.enabled { self.head_managers.handle_enabled_change(s.enabled); } + if old.active != s.active { + self.head_managers.handle_active_change(s.active); + } if let Some(output) = state.outputs.get(&self.connector.id()) && let Some(node) = &output.node { diff --git a/src/tasks/connector.rs b/src/tasks/connector.rs index 49e07403..b453da99 100644 --- a/src/tasks/connector.rs +++ b/src/tasks/connector.rs @@ -48,6 +48,8 @@ pub fn handle(state: &Rc, connector: &Rc) { name: RcEq(name.clone()), position: (0, 0), size: (0, 0), + active: backend_state.active, + connected: false, transform: Transform::None, scale: Default::default(), wl_output: None, diff --git a/wire/jay_head_ext_connector_info_v1.txt b/wire/jay_head_ext_connector_info_v1.txt new file mode 100644 index 00000000..d17f1af1 --- /dev/null +++ b/wire/jay_head_ext_connector_info_v1.txt @@ -0,0 +1,19 @@ +request destroy (destructor) { + +} + +event connected { + +} + +event disconnected { + +} + +event active { + +} + +event inactive { + +} diff --git a/wire/jay_head_manager_ext_connector_info_v1.txt b/wire/jay_head_manager_ext_connector_info_v1.txt new file mode 100644 index 00000000..ef85fc1a --- /dev/null +++ b/wire/jay_head_manager_ext_connector_info_v1.txt @@ -0,0 +1,7 @@ +request destroy (destructor) { + +} + +event head { + head: id(jay_head_ext_connector_info_v1) (new), +}