Add set mode

This commit is contained in:
Ottatop 2024-03-22 18:58:31 -05:00
parent 2fd98301e6
commit 6adb560e81
4 changed files with 70 additions and 6 deletions

View file

@ -362,6 +362,33 @@ function OutputHandle:set_loc_adj_to(other, alignment)
self:set_location({ x = x, y = y })
end
---Set this output's mode.
---
---If `refresh_rate_millihz` is provided, Pinnacle will attempt to use the mode with that refresh rate.
---If it isn't, Pinnacle will attempt to use the mode with the highest refresh rate that matches the
---given size.
---
---The refresh rate is in millihertz. For example, to choose a mode with a refresh rate of 60Hz, use 60000.
---
---If this output doesn't support the given mode, it will be ignored.
---
---### Example
---```lua
---Output.get_focused():set_mode(2560, 1440, 144000)
---```
---
---@param pixel_width integer
---@param pixel_height integer
---@param refresh_rate_millihz integer?
function OutputHandle:set_mode(pixel_width, pixel_height, refresh_rate_millihz)
client.unary_request(build_grpc_request_params("SetMode", {
output_name = self.name,
pixel_width = pixel_width,
pixel_height = pixel_height,
refresh_rate_millihz = refresh_rate_millihz,
}))
end
---@class Mode
---@field pixel_width integer
---@field pixel_height integer

View file

@ -18,7 +18,10 @@ message SetLocationRequest {
message SetModeRequest {
optional string output_name = 1;
optional Mode mode = 2;
optional uint32 pixel_width = 2;
optional uint32 pixel_height = 3;
// NULLABLE
optional uint32 refresh_rate_millihz = 4;
}
message GetRequest {}

View file

@ -12,7 +12,7 @@
use futures::FutureExt;
use pinnacle_api_defs::pinnacle::output::{
self,
v0alpha1::{output_service_client::OutputServiceClient, SetLocationRequest},
v0alpha1::{output_service_client::OutputServiceClient, SetLocationRequest, SetModeRequest},
};
use tonic::transport::Channel;
@ -358,6 +358,38 @@ impl OutputHandle {
attempt_set_loc();
}
/// Set this output's mode.
///
/// If `refresh_rate_millihertz` is provided, Pinnacle will attempt to use the mode with that
/// refresh rate. If it is not, Pinnacle will attempt to use the mode with the
/// highest refresh rate that matches the given size.
///
/// The refresh rate should be given in millihertz. For example, if you want a refresh rate of
/// 60Hz, use 60000.
///
/// If this output doesn't support the given mode, it will be ignored.
///
/// # Examples
///
/// ```
/// output.get_focused()?.set_mode(2560, 1440, 144000);
/// ```
pub fn set_mode(
&self,
pixel_width: u32,
pixel_height: u32,
refresh_rate_millihertz: impl Into<Option<u32>>,
) {
let mut client = self.output_client.clone();
block_on_tokio(client.set_mode(SetModeRequest {
output_name: Some(self.name.clone()),
pixel_width: Some(pixel_width),
pixel_height: Some(pixel_height),
refresh_rate_millihz: refresh_rate_millihertz.into(),
}))
.unwrap();
}
/// Get all properties of this output.
///
/// # Examples

View file

@ -955,16 +955,18 @@ impl output_service_server::OutputService for OutputService {
run_unary_no_response(&self.sender, |state| {
let Some(output) = request
.output_name
.clone()
.map(OutputName)
.and_then(|name| name.output(state))
else {
return;
};
let mode = request.mode.and_then(|mode| {
// poor man's try v2
let mode = Some(request).and_then(|request| {
Some(smithay::output::Mode {
size: (mode.pixel_width? as i32, mode.pixel_height? as i32).into(),
refresh: mode.refresh_rate_millihz? as i32,
size: (request.pixel_width? as i32, request.pixel_height? as i32).into(),
refresh: request.refresh_rate_millihz? as i32,
})
});
@ -1029,7 +1031,7 @@ impl output_service_server::OutputService for OutputService {
.map(from_smithay_mode)
.collect::<Vec<_>>()
})
.unwrap_or(Vec::new());
.unwrap_or_default();
let model = output
.as_ref()