Add most of the output stuff

This commit is contained in:
Ottatop 2023-10-19 18:18:34 -05:00
parent 2c3fb2dbd7
commit c62d090f9f
2 changed files with 117 additions and 0 deletions

View file

@ -1,5 +1,6 @@
mod input;
mod msg;
mod output;
mod process;
mod window;
@ -7,6 +8,7 @@ use input::Input;
pub use input::MouseButton;
pub use msg::Modifier;
pub use msg::MouseEdge;
use output::Output;
use window::Window;
pub use xkbcommon::xkb::keysyms;
pub use xkbcommon::xkb::Keysym;
@ -46,6 +48,7 @@ pub fn setup(config_func: impl FnOnce(Pinnacle)) -> anyhow::Result<()> {
process: Process,
input: Input,
window: Window,
output: Output,
};
config_func(pinnacle);
@ -170,4 +173,5 @@ pub struct Pinnacle {
pub process: Process,
pub window: Window,
pub input: Input,
pub output: Output,
}

113
api/rust/src/output.rs Normal file
View file

@ -0,0 +1,113 @@
use crate::{
msg::{OutputName, Request, RequestResponse},
request,
};
/// Output management.
pub struct Output;
impl Output {
/// Get an [`OutputHandle`] by its name.
///
/// `name` is the name of the port the output is plugged in to.
/// This is something like `HDMI-1` or `eDP-0`.
pub fn get_by_name(&self, name: &str) -> Option<OutputHandle> {
let RequestResponse::Outputs { output_names } = request(Request::GetOutputs) else {
unreachable!()
};
output_names
.into_iter()
.find(|s| s == name)
.map(|s| OutputHandle(OutputName(s)))
}
/// Get a handle to all connected outputs.
pub fn get_all(&self) -> impl Iterator<Item = OutputHandle> {
let RequestResponse::Outputs { output_names } = request(Request::GetOutputs) else {
unreachable!()
};
output_names
.into_iter()
.map(|name| OutputHandle(OutputName(name)))
}
/// Get the currently focused output.
///
/// This is currently defined as the one with the cursor on it.
pub fn get_focused(&self) -> Option<OutputHandle> {
let RequestResponse::Outputs { output_names } = request(Request::GetOutputs) else {
unreachable!()
};
output_names
.into_iter()
.map(|s| OutputHandle(OutputName(s)))
.find(|op| op.properties().focused == Some(true))
}
}
/// An output handle.
///
/// This is a handle to one of your monitors.
/// It serves to make it easier to deal with them, defining methods for getting properties and
/// helpers for things like positioning multiple monitors.
pub struct OutputHandle(OutputName);
/// Properties of an output.
pub struct OutputProperties {
/// The make.
make: Option<String>,
/// The model.
///
/// This is something like `27GL850` or whatever gibberish monitor manufacturers name their
/// displays.
model: Option<String>,
/// The location of the output in the global space.
loc: Option<(i32, i32)>,
/// The resolution of the output in pixels, where `res.0` is the width and `res.1` is the
/// height.
res: Option<(i32, i32)>,
/// The refresh rate of the output in millihertz.
///
/// For example, 60Hz is returned as 60000.
refresh_rate: Option<i32>,
/// The physical size of the output in millimeters.
physical_size: Option<(i32, i32)>,
/// Whether or not the output is focused.
focused: Option<bool>,
// TODO: tags
}
impl OutputHandle {
// TODO: Make OutputProperties an option, make non null fields not options
/// Get all properties of this output.
pub fn properties(&self) -> OutputProperties {
let RequestResponse::OutputProps {
make,
model,
loc,
res,
refresh_rate,
physical_size,
focused,
tag_ids,
} = request(Request::GetOutputProps {
output_name: self.0 .0.clone(),
})
else {
unreachable!()
};
OutputProperties {
make,
model,
loc,
res,
refresh_rate,
physical_size,
focused,
}
}
}