2022-07-04 15:27:08 +02:00
|
|
|
use smithay::{
|
2024-04-29 19:00:39 +02:00
|
|
|
output::{Output, WeakOutput},
|
2024-04-05 13:53:35 +02:00
|
|
|
utils::{Rectangle, Transform},
|
2022-07-04 15:27:08 +02:00
|
|
|
};
|
|
|
|
|
|
2023-10-25 19:24:51 +02:00
|
|
|
pub use super::geometry::*;
|
2024-04-05 13:53:35 +02:00
|
|
|
pub use crate::shell::{SeatExt, Shell, Workspace};
|
2022-08-31 13:01:23 +02:00
|
|
|
pub use crate::state::{Common, State};
|
2022-07-05 18:46:38 +02:00
|
|
|
pub use crate::wayland::handlers::xdg_shell::popup::update_reactive_popups;
|
2022-07-04 15:27:08 +02:00
|
|
|
|
2024-04-29 19:00:39 +02:00
|
|
|
use std::sync::{
|
|
|
|
|
atomic::{AtomicBool, Ordering},
|
|
|
|
|
Mutex,
|
|
|
|
|
};
|
2024-04-29 15:40:29 +02:00
|
|
|
|
2022-07-04 15:27:08 +02:00
|
|
|
pub trait OutputExt {
|
2023-10-25 19:24:51 +02:00
|
|
|
fn geometry(&self) -> Rectangle<i32, Global>;
|
2024-04-29 15:40:29 +02:00
|
|
|
fn adaptive_sync(&self) -> bool;
|
|
|
|
|
fn set_adaptive_sync(&self, vrr: bool);
|
2024-04-29 19:00:39 +02:00
|
|
|
fn mirroring(&self) -> Option<Output>;
|
|
|
|
|
fn set_mirroring(&self, output: Option<Output>);
|
2022-07-04 15:27:08 +02:00
|
|
|
}
|
|
|
|
|
|
2024-04-29 15:40:29 +02:00
|
|
|
struct Vrr(AtomicBool);
|
|
|
|
|
|
2024-04-29 19:00:39 +02:00
|
|
|
struct Mirroring(Mutex<Option<WeakOutput>>);
|
|
|
|
|
|
2022-07-04 15:27:08 +02:00
|
|
|
impl OutputExt for Output {
|
2023-10-25 19:24:51 +02:00
|
|
|
fn geometry(&self) -> Rectangle<i32, Global> {
|
2022-07-04 16:00:29 +02:00
|
|
|
Rectangle::from_loc_and_size(self.current_location(), {
|
|
|
|
|
Transform::from(self.current_transform())
|
|
|
|
|
.transform_size(
|
|
|
|
|
self.current_mode()
|
|
|
|
|
.map(|m| m.size)
|
|
|
|
|
.unwrap_or_else(|| (0, 0).into()),
|
|
|
|
|
)
|
|
|
|
|
.to_f64()
|
|
|
|
|
.to_logical(self.current_scale().fractional_scale())
|
|
|
|
|
.to_i32_round()
|
|
|
|
|
})
|
2023-10-25 19:24:51 +02:00
|
|
|
.as_global()
|
2022-07-04 15:27:08 +02:00
|
|
|
}
|
2024-04-29 15:40:29 +02:00
|
|
|
|
|
|
|
|
fn adaptive_sync(&self) -> bool {
|
|
|
|
|
self.user_data()
|
|
|
|
|
.get::<Vrr>()
|
|
|
|
|
.map(|vrr| vrr.0.load(Ordering::SeqCst))
|
|
|
|
|
.unwrap_or(false)
|
|
|
|
|
}
|
|
|
|
|
fn set_adaptive_sync(&self, vrr: bool) {
|
|
|
|
|
let user_data = self.user_data();
|
|
|
|
|
user_data.insert_if_missing_threadsafe(|| Vrr(AtomicBool::new(false)));
|
|
|
|
|
user_data
|
|
|
|
|
.get::<Vrr>()
|
|
|
|
|
.unwrap()
|
|
|
|
|
.0
|
|
|
|
|
.store(vrr, Ordering::SeqCst);
|
|
|
|
|
}
|
2024-04-29 19:00:39 +02:00
|
|
|
|
|
|
|
|
fn mirroring(&self) -> Option<Output> {
|
|
|
|
|
self.user_data().get::<Mirroring>().and_then(|mirroring| {
|
|
|
|
|
mirroring
|
|
|
|
|
.0
|
|
|
|
|
.lock()
|
|
|
|
|
.unwrap()
|
|
|
|
|
.clone()
|
|
|
|
|
.and_then(|o| o.upgrade())
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
fn set_mirroring(&self, output: Option<Output>) {
|
|
|
|
|
let user_data = self.user_data();
|
|
|
|
|
user_data.insert_if_missing_threadsafe(|| Mirroring(Mutex::new(None)));
|
|
|
|
|
*user_data.get::<Mirroring>().unwrap().0.lock().unwrap() =
|
|
|
|
|
output.map(|output| output.downgrade());
|
|
|
|
|
}
|
2022-07-04 15:27:08 +02:00
|
|
|
}
|