mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2025-01-18 22:26:12 +01:00
Add scale setting to API, fix fractional scaling
This commit is contained in:
parent
8d3bbf28f8
commit
dfc7a1351e
5 changed files with 88 additions and 11 deletions
|
@ -31,6 +31,13 @@ require("pinnacle").setup(function(Pinnacle)
|
|||
-- Keybinds --
|
||||
--------------------
|
||||
|
||||
Input.keybind({ mod_key }, "=", function()
|
||||
Output.get_focused():increase_scale(0.25)
|
||||
end)
|
||||
Input.keybind({ mod_key }, "-", function()
|
||||
Output.get_focused():decrease_scale(0.25)
|
||||
end)
|
||||
|
||||
-- mod_key + alt + q = Quit Pinnacle
|
||||
Input.keybind({ mod_key, "alt" }, "q", function()
|
||||
Pinnacle.quit()
|
||||
|
|
|
@ -13,6 +13,7 @@ local service = prefix .. "OutputService"
|
|||
local rpc_types = {
|
||||
SetLocation = {},
|
||||
SetMode = {},
|
||||
SetScale = {},
|
||||
ConnectForAll = {
|
||||
response_type = "ConnectForAllResponse",
|
||||
},
|
||||
|
@ -389,6 +390,27 @@ function OutputHandle:set_mode(pixel_width, pixel_height, refresh_rate_millihz)
|
|||
}))
|
||||
end
|
||||
|
||||
---Set this output's scaling factor.
|
||||
---
|
||||
---@param scale number
|
||||
function OutputHandle:set_scale(scale)
|
||||
client.unary_request(build_grpc_request_params("SetScale", { output_name = self.name, absolute = scale }))
|
||||
end
|
||||
|
||||
---Increase this output's scaling factor.
|
||||
---
|
||||
---@param increase_by number
|
||||
function OutputHandle:increase_scale(increase_by)
|
||||
client.unary_request(build_grpc_request_params("SetScale", { output_name = self.name, relative = increase_by }))
|
||||
end
|
||||
|
||||
---Decrease this output's scaling factor.
|
||||
---
|
||||
---@param decrease_by number
|
||||
function OutputHandle:decrease_scale(decrease_by)
|
||||
client.unary_request(build_grpc_request_params("SetScale", { output_name = self.name, relative = -decrease_by }))
|
||||
end
|
||||
|
||||
---@class Mode
|
||||
---@field pixel_width integer
|
||||
---@field pixel_height integer
|
||||
|
|
|
@ -24,6 +24,14 @@ message SetModeRequest {
|
|||
optional uint32 refresh_rate_millihz = 4;
|
||||
}
|
||||
|
||||
message SetScaleRequest {
|
||||
optional string output_name = 1;
|
||||
oneof absolute_or_relative {
|
||||
float absolute = 2;
|
||||
float relative = 3;
|
||||
}
|
||||
}
|
||||
|
||||
message GetRequest {}
|
||||
message GetResponse {
|
||||
repeated string output_names = 1;
|
||||
|
@ -62,6 +70,7 @@ message GetPropertiesResponse {
|
|||
service OutputService {
|
||||
rpc SetLocation(SetLocationRequest) returns (google.protobuf.Empty);
|
||||
rpc SetMode(SetModeRequest) returns (google.protobuf.Empty);
|
||||
rpc SetScale(SetScaleRequest) returns (google.protobuf.Empty);
|
||||
rpc Get(GetRequest) returns (GetResponse);
|
||||
rpc GetProperties(GetPropertiesRequest) returns (GetPropertiesResponse);
|
||||
}
|
||||
|
|
40
src/api.rs
40
src/api.rs
|
@ -14,7 +14,10 @@ use pinnacle_api_defs::pinnacle::{
|
|||
},
|
||||
output::{
|
||||
self,
|
||||
v0alpha1::{output_service_server, SetLocationRequest, SetModeRequest},
|
||||
v0alpha1::{
|
||||
output_service_server, set_scale_request::AbsoluteOrRelative, SetLocationRequest,
|
||||
SetModeRequest, SetScaleRequest,
|
||||
},
|
||||
},
|
||||
process::v0alpha1::{process_service_server, SetEnvRequest, SpawnRequest, SpawnResponse},
|
||||
tag::{
|
||||
|
@ -27,7 +30,9 @@ use pinnacle_api_defs::pinnacle::{
|
|||
v0alpha1::{pinnacle_service_server, PingRequest, PingResponse, QuitRequest, SetOrToggle},
|
||||
};
|
||||
use smithay::{
|
||||
desktop::layer_map_for_output,
|
||||
input::keyboard::XkbConfig,
|
||||
output::Scale,
|
||||
reexports::{calloop, input as libinput},
|
||||
};
|
||||
use sysinfo::ProcessRefreshKind;
|
||||
|
@ -977,6 +982,39 @@ impl output_service_server::OutputService for OutputService {
|
|||
.await
|
||||
}
|
||||
|
||||
async fn set_scale(&self, request: Request<SetScaleRequest>) -> Result<Response<()>, Status> {
|
||||
let SetScaleRequest {
|
||||
output_name: Some(output_name),
|
||||
absolute_or_relative: Some(absolute_or_relative),
|
||||
} = request.into_inner()
|
||||
else {
|
||||
return Err(Status::invalid_argument(
|
||||
"output_name or absolute_or_relative were null",
|
||||
));
|
||||
};
|
||||
|
||||
run_unary_no_response(&self.sender, move |state| {
|
||||
let Some(output) = OutputName(output_name).output(state) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let mut current_scale = output.current_scale().fractional_scale();
|
||||
|
||||
match absolute_or_relative {
|
||||
AbsoluteOrRelative::Absolute(abs) => current_scale = abs as f64,
|
||||
AbsoluteOrRelative::Relative(rel) => current_scale += rel as f64,
|
||||
}
|
||||
|
||||
current_scale = f64::max(current_scale, 0.25);
|
||||
|
||||
output.change_current_state(None, None, Some(Scale::Fractional(current_scale)), None);
|
||||
layer_map_for_output(&output).arrange();
|
||||
state.request_layout(&output);
|
||||
state.schedule_render(&output);
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
async fn get(
|
||||
&self,
|
||||
_request: Request<output::v0alpha1::GetRequest>,
|
||||
|
|
|
@ -106,12 +106,9 @@ where
|
|||
.map(|geo| (surface, geo.loc))
|
||||
})
|
||||
.map(|(surface, loc)| {
|
||||
let render_elements = surface.render_elements::<WaylandSurfaceRenderElement<R>>(
|
||||
renderer,
|
||||
loc.to_physical((scale.x.round() as i32, scale.y.round() as i32)),
|
||||
scale,
|
||||
1.0,
|
||||
);
|
||||
let loc = loc.to_physical_precise_round(scale);
|
||||
let render_elements = surface
|
||||
.render_elements::<WaylandSurfaceRenderElement<R>>(renderer, loc, scale, 1.0);
|
||||
(surface.layer(), render_elements)
|
||||
});
|
||||
|
||||
|
@ -150,8 +147,12 @@ where
|
|||
.filter(|win| win.is_on_active_tag())
|
||||
.map(|win| {
|
||||
// subtract win.geometry().loc to align decorations correctly
|
||||
let loc = (space.element_location(win).unwrap_or((0, 0).into()) - win.geometry().loc - output.current_location())
|
||||
.to_physical((scale.x.round() as i32, scale.x.round() as i32));
|
||||
let loc = (
|
||||
space.element_location(win) .unwrap_or((0, 0).into())
|
||||
- win.geometry().loc
|
||||
- output.current_location()
|
||||
)
|
||||
.to_physical_precise_round(scale);
|
||||
|
||||
let elem_geo = space.element_geometry(win).map(|mut geo| {
|
||||
geo.loc -= output.current_location();
|
||||
|
@ -166,7 +167,7 @@ where
|
|||
match rect {
|
||||
Some(rect) => {
|
||||
elems.into_iter().filter_map(|elem| {
|
||||
CropRenderElement::from_element(elem, scale, rect.to_physical_precise_down(scale))
|
||||
CropRenderElement::from_element(elem, scale, rect.to_physical_precise_round(scale))
|
||||
}).map(TransformRenderElement::from).map(OutputRenderElements::from).collect::<Vec<_>>()
|
||||
},
|
||||
None => elems.into_iter().map(OutputRenderElements::from).collect(),
|
||||
|
@ -243,7 +244,7 @@ where
|
|||
};
|
||||
|
||||
let cursor_pos = pointer_location - output_geometry.loc.to_f64() - cursor_hotspot.to_f64();
|
||||
let cursor_pos_scaled = cursor_pos.to_physical(scale).to_i32_round();
|
||||
let cursor_pos_scaled = cursor_pos.to_physical_precise_round(scale);
|
||||
|
||||
// set cursor
|
||||
if let Some(pointer_image) = pointer_image {
|
||||
|
|
Loading…
Reference in a new issue