1
0
Fork 0
forked from wry/wry

head-management: add connector-info-v1 extension

This commit is contained in:
Julian Orth 2025-07-12 09:29:13 +02:00
parent 51170cbde5
commit e24ea33734
9 changed files with 132 additions and 0 deletions

View file

@ -642,6 +642,8 @@ fn create_dummy_output(state: &Rc<State>) {
name: RcEq(name.clone()),
position: (0, 0),
size: (0, 0),
active: false,
connected: false,
transform: Transform::None,
scale: Default::default(),
wl_output: None,

View file

@ -68,6 +68,8 @@ pub struct HeadState {
pub name: RcEq<String>,
pub wl_output: Option<GlobalName>,
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();
}
}
}
}

View file

@ -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,
}

View file

@ -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;

View file

@ -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<HeadCommon>) -> 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!();

View file

@ -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
{

View file

@ -48,6 +48,8 @@ pub fn handle(state: &Rc<State>, connector: &Rc<dyn Connector>) {
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,

View file

@ -0,0 +1,19 @@
request destroy (destructor) {
}
event connected {
}
event disconnected {
}
event active {
}
event inactive {
}

View file

@ -0,0 +1,7 @@
request destroy (destructor) {
}
event head {
head: id(jay_head_ext_connector_info_v1) (new),
}