2024-01-11 23:22:18 +00:00
|
|
|
use super::{Client, Environment, Event};
|
2025-05-18 15:17:09 +01:00
|
|
|
use crate::channels::AsyncSenderExt;
|
2023-04-29 22:08:02 +01:00
|
|
|
use smithay_client_toolkit::output::{OutputHandler, OutputInfo, OutputState};
|
2024-01-07 23:50:10 +00:00
|
|
|
use tokio::sync::broadcast;
|
|
|
|
use tracing::{debug, error};
|
|
|
|
use wayland_client::protocol::wl_output::WlOutput;
|
2023-04-29 22:08:02 +01:00
|
|
|
use wayland_client::{Connection, QueueHandle};
|
|
|
|
|
2024-01-07 23:50:10 +00:00
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub struct OutputEvent {
|
2024-01-11 23:22:18 +00:00
|
|
|
pub output: OutputInfo,
|
|
|
|
pub event_type: OutputEventType,
|
2024-01-07 23:50:10 +00:00
|
|
|
}
|
|
|
|
|
2024-08-14 20:37:04 +01:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
2024-01-07 23:50:10 +00:00
|
|
|
pub enum OutputEventType {
|
|
|
|
New,
|
|
|
|
Update,
|
|
|
|
Destroyed,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Client {
|
|
|
|
/// Gets the information for all outputs.
|
2024-01-11 23:22:18 +00:00
|
|
|
#[cfg(feature = "ipc")]
|
2024-01-07 23:50:10 +00:00
|
|
|
pub fn output_info_all(&self) -> Vec<OutputInfo> {
|
2024-01-11 23:22:18 +00:00
|
|
|
use super::{Request, Response};
|
2024-01-07 23:50:10 +00:00
|
|
|
match self.send_request(Request::OutputInfoAll) {
|
|
|
|
Response::OutputInfoAll(info) => info,
|
|
|
|
_ => unreachable!(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Subscribes to events from outputs.
|
|
|
|
pub fn subscribe_outputs(&self) -> broadcast::Receiver<OutputEvent> {
|
|
|
|
self.output_channel.0.subscribe()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-29 22:08:02 +01:00
|
|
|
impl Environment {
|
2024-01-11 23:22:18 +00:00
|
|
|
#[cfg(feature = "ipc")]
|
2024-01-07 23:50:10 +00:00
|
|
|
pub fn output_info_all(&mut self) -> Vec<OutputInfo> {
|
2023-04-29 22:08:02 +01:00
|
|
|
self.output_state
|
|
|
|
.outputs()
|
|
|
|
.filter_map(|output| self.output_state.info(&output))
|
|
|
|
.collect()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// In order to use OutputDelegate, we must implement this trait to indicate when something has happened to an
|
|
|
|
// output and to provide an instance of the output state to the delegate when dispatching events.
|
|
|
|
impl OutputHandler for Environment {
|
|
|
|
// First we need to provide a way to access the delegate.
|
|
|
|
//
|
|
|
|
// This is needed because delegate implementations for handling events use the application data type in
|
|
|
|
// their function signatures. This allows the implementation to access an instance of the type.
|
|
|
|
fn output_state(&mut self) -> &mut OutputState {
|
|
|
|
&mut self.output_state
|
|
|
|
}
|
|
|
|
|
|
|
|
// Then there exist these functions that indicate the lifecycle of an output.
|
|
|
|
// These will be called as appropriate by the delegate implementation.
|
|
|
|
|
2024-01-07 23:50:10 +00:00
|
|
|
fn new_output(&mut self, _conn: &Connection, _qh: &QueueHandle<Self>, output: WlOutput) {
|
2023-04-29 22:08:02 +01:00
|
|
|
debug!("Handler received new output");
|
2024-01-07 23:50:10 +00:00
|
|
|
if let Some(info) = self.output_state.info(&output) {
|
2025-05-18 15:17:09 +01:00
|
|
|
self.event_tx.send_spawn(Event::Output(OutputEvent {
|
|
|
|
output: info,
|
|
|
|
event_type: OutputEventType::New,
|
|
|
|
}));
|
2024-01-07 23:50:10 +00:00
|
|
|
} else {
|
|
|
|
error!("Output is missing information!");
|
|
|
|
}
|
2023-04-29 22:08:02 +01:00
|
|
|
}
|
|
|
|
|
2024-01-07 23:50:10 +00:00
|
|
|
fn update_output(&mut self, _conn: &Connection, _qh: &QueueHandle<Self>, output: WlOutput) {
|
|
|
|
debug!("Handle received output update");
|
|
|
|
if let Some(info) = self.output_state.info(&output) {
|
2025-05-18 15:17:09 +01:00
|
|
|
self.event_tx.send_spawn(Event::Output(OutputEvent {
|
|
|
|
output: info,
|
|
|
|
event_type: OutputEventType::Update,
|
|
|
|
}));
|
2024-01-07 23:50:10 +00:00
|
|
|
} else {
|
|
|
|
error!("Output is missing information!");
|
|
|
|
}
|
2023-04-29 22:08:02 +01:00
|
|
|
}
|
|
|
|
|
2024-01-07 23:50:10 +00:00
|
|
|
fn output_destroyed(&mut self, _conn: &Connection, _qh: &QueueHandle<Self>, output: WlOutput) {
|
2023-04-29 22:08:02 +01:00
|
|
|
debug!("Handle received output destruction");
|
2024-01-07 23:50:10 +00:00
|
|
|
if let Some(info) = self.output_state.info(&output) {
|
2025-05-18 15:17:09 +01:00
|
|
|
self.event_tx.send_spawn(Event::Output(OutputEvent {
|
|
|
|
output: info,
|
|
|
|
event_type: OutputEventType::Destroyed,
|
|
|
|
}));
|
2024-01-07 23:50:10 +00:00
|
|
|
} else {
|
|
|
|
error!("Output is missing information!");
|
|
|
|
}
|
2023-04-29 22:08:02 +01:00
|
|
|
}
|
|
|
|
}
|