1
0
Fork 0
forked from wry/wry

head-management: add vrr-state-v1 extension

This commit is contained in:
Julian Orth 2025-07-13 13:20:42 +02:00
parent b76aade265
commit aaef75f9f3
9 changed files with 108 additions and 0 deletions

View file

@ -653,6 +653,7 @@ fn create_dummy_output(state: &Rc<State>) {
monitor_info: None, monitor_info: None,
inherent_non_desktop: false, inherent_non_desktop: false,
override_non_desktop: None, override_non_desktop: None,
vrr: false,
}; };
let connector_data = Rc::new(ConnectorData { let connector_data = Rc::new(ConnectorData {
id, id,

View file

@ -79,6 +79,7 @@ pub struct HeadState {
pub monitor_info: Option<RcEq<MonitorInfo>>, pub monitor_info: Option<RcEq<MonitorInfo>>,
pub inherent_non_desktop: bool, pub inherent_non_desktop: bool,
pub override_non_desktop: Option<bool>, pub override_non_desktop: Option<bool>,
pub vrr: bool,
} }
impl HeadState { impl HeadState {
@ -249,6 +250,10 @@ impl HeadManagers {
ext.send_state(state); ext.send_state(state);
head.session.schedule_done(); head.session.schedule_done();
} }
if let Some(ext) = &head.ext.vrr_state_v1 {
ext.send_state(state);
head.session.schedule_done();
}
} }
} }
@ -275,6 +280,10 @@ impl HeadManagers {
ext.send_info(state); ext.send_info(state);
head.session.schedule_done(); head.session.schedule_done();
} }
if let Some(ext) = &head.ext.vrr_state_v1 {
ext.send_state(state);
head.session.schedule_done();
}
} }
} }
@ -359,4 +368,16 @@ impl HeadManagers {
} }
} }
} }
pub fn handle_vrr_change(&self, vrr: bool) {
let state = &mut *self.state.borrow_mut();
state.vrr = vrr;
for head in self.managers.lock().values() {
skip_in_transaction!(head);
if let Some(ext) = &head.ext.vrr_state_v1 {
ext.send_state(state);
head.session.schedule_done();
}
}
}
} }

View file

@ -399,4 +399,5 @@ declare_extensions! {
mode_setter_v1: ModeSetterV1, mode_setter_v1: ModeSetterV1,
physical_display_info_v1: PhysicalDisplayInfoV1, physical_display_info_v1: PhysicalDisplayInfoV1,
non_desktop_info_v1: NonDesktopInfoV1, non_desktop_info_v1: NonDesktopInfoV1,
vrr_state_v1: VrrStateV1,
} }

View file

@ -9,3 +9,4 @@ pub(super) mod jay_head_ext_mode_info_v1;
pub(super) mod jay_head_ext_mode_setter_v1; pub(super) mod jay_head_ext_mode_setter_v1;
pub(super) mod jay_head_ext_non_desktop_info_v1; pub(super) mod jay_head_ext_non_desktop_info_v1;
pub(super) mod jay_head_ext_physical_display_info_v1; pub(super) mod jay_head_ext_physical_display_info_v1;
pub(super) mod jay_head_ext_vrr_state_v1;

View file

@ -0,0 +1,58 @@
use {
crate::{
ifs::head_management::HeadState,
wire::{
jay_head_ext_vrr_state_v1::{
Capable, Enabled, JayHeadExtVrrStateV1RequestHandler, Reset,
},
jay_head_manager_ext_vrr_state_v1::JayHeadManagerExtVrrStateV1RequestHandler,
},
},
std::rc::Rc,
};
impl_vrr_state_v1! {
version = 1,
after_announce = after_announce,
after_transaction = after_transaction,
}
impl HeadName {
fn after_announce(&self, shared: &HeadState) {
self.send_state(shared);
}
fn after_transaction(&self, shared: &HeadState, tran: &HeadState) {
let shared_capable = shared.monitor_info.as_ref().map(|m| m.vrr_capable);
let tran_capable = tran.monitor_info.as_ref().map(|m| m.vrr_capable);
if (shared.vrr, shared_capable) != (tran.vrr, tran_capable) {
self.send_state(shared);
}
}
pub(in super::super) fn send_state(&self, state: &HeadState) {
self.client.event(Reset { self_id: self.id });
if let Some(mi) = &state.monitor_info
&& mi.vrr_capable
{
self.client.event(Capable { self_id: self.id });
}
if state.vrr {
self.client.event(Enabled { self_id: self.id });
}
}
}
impl JayHeadManagerExtVrrStateV1RequestHandler for MgrName {
type Error = ErrorName;
mgr_common_req!();
}
impl JayHeadExtVrrStateV1RequestHandler for HeadName {
type Error = ErrorName;
head_common_req!();
}
error!();

View file

@ -453,6 +453,9 @@ impl ConnectorData {
self.head_managers self.head_managers
.handle_non_desktop_override_changed(s.non_desktop_override); .handle_non_desktop_override_changed(s.non_desktop_override);
} }
if old.vrr != s.vrr {
self.head_managers.handle_vrr_change(s.vrr);
}
if let Some(output) = state.outputs.get(&self.connector.id()) if let Some(output) = state.outputs.get(&self.connector.id())
&& let Some(node) = &output.node && let Some(node) = &output.node
{ {

View file

@ -59,6 +59,7 @@ pub fn handle(state: &Rc<State>, connector: &Rc<dyn Connector>) {
monitor_info: None, monitor_info: None,
inherent_non_desktop: false, inherent_non_desktop: false,
override_non_desktop: backend_state.non_desktop_override, override_non_desktop: backend_state.non_desktop_override,
vrr: backend_state.vrr,
}; };
let data = Rc::new(ConnectorData { let data = Rc::new(ConnectorData {
id, id,

View file

@ -0,0 +1,15 @@
request destroy (destructor) {
}
event reset {
}
event capable {
}
event enabled {
}

View file

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