Impl Layout.request_layout

This commit is contained in:
Ottatop 2024-03-14 19:42:08 -05:00
parent e1f2706428
commit e86f242330
4 changed files with 57 additions and 10 deletions

View file

@ -109,6 +109,7 @@ require("pinnacle").setup(function(Pinnacle)
end
if tag then
layout_manager:cycle_layout_forward(tag)
Layout.request_layout(focused_op)
end
end
end)
@ -127,6 +128,7 @@ require("pinnacle").setup(function(Pinnacle)
end
if tag then
layout_manager:cycle_layout_backward(tag)
Layout.request_layout(focused_op)
end
end
end)

View file

@ -391,13 +391,18 @@ function builtins.dwindle:layout(args)
end
---@class Layout
---@field private stream H2Stream?
local layout = {
builtins = builtins,
}
---Set the layout manager for this config.
---
---It will manage layout requests from the compositor.
---
---@param manager LayoutManager
function layout.set_manager(manager)
client.bidirectional_streaming_request(
layout.stream = client.bidirectional_streaming_request(
build_grpc_request_params("Layout", {
layout = {},
}),
@ -437,20 +442,39 @@ function layout.set_manager(manager)
)
end
---Request a layout on the given output, or the focused output if nil.
---
---If no `LayoutManager` was set, this will do nothing.
---
---@param output? OutputHandle
function layout.request_layout(output)
if not layout.stream then
return
end
local body = protobuf.encode(".pinnacle.layout.v0alpha1.LayoutRequest", {
layout = {
output_name = output and output.name,
},
})
layout.stream:write_chunk(body, false)
end
---An object that manages layouts.
---@class LayoutManager
---@field layouts LayoutGenerator[]
---Get the active layout generator.
---@field get_active fun(self: self, args: LayoutArgs): LayoutGenerator
---A `LayoutManager` that keeps track of layouts per tag and provides
---methods to cycle between them.
---@class CyclingLayoutManager : LayoutManager
---@field index integer
local CyclingLayoutManager = {
---@type table<integer, integer>
tag_indices = {},
}
---@field tag_indices table<integer, integer>
local CyclingLayoutManager = {}
---@param args LayoutArgs
---
---@return LayoutGenerator
function CyclingLayoutManager:get_active(args)
local first_tag = args.tags[1]
@ -472,6 +496,7 @@ function CyclingLayoutManager:get_active(args)
end
---Cycle the layout for the given tag forward.
---
---@param tag TagHandle
function CyclingLayoutManager:cycle_layout_forward(tag)
if not self.tag_indices[tag.id] then
@ -486,6 +511,7 @@ function CyclingLayoutManager:cycle_layout_forward(tag)
end
---Cycle the layout for the given tag backward.
---
---@param tag TagHandle
function CyclingLayoutManager:cycle_layout_backward(tag)
if not self.tag_indices[tag.id] then
@ -499,14 +525,18 @@ function CyclingLayoutManager:cycle_layout_backward(tag)
end
end
---Create a new cycling layout manager.
---
---@param layouts LayoutGenerator[]
---
---@return CyclingLayoutManager
---
---@see CyclingLayoutManager
function layout.new_cycling_manager(layouts)
---@type CyclingLayoutManager
local self = {
index = 1,
layouts = layouts,
tag_indices = {},
}
setmetatable(self, { __index = CyclingLayoutManager })

View file

@ -23,7 +23,14 @@ message LayoutRequest {
repeated .pinnacle.v0alpha1.Geometry geometries = 3;
}
// An explicit layout request.
message ExplicitLayout {}
message ExplicitLayout {
// NULLABLE
//
// Layout this output.
//
// If it is null, the focused output will be used.
optional string output_name = 1;
}
oneof body {
Geometries geometries = 1;

View file

@ -4,6 +4,8 @@ use pinnacle_api_defs::pinnacle::layout::v0alpha1::{
};
use tonic::{Request, Response, Status, Streaming};
use crate::output::OutputName;
use super::{run_bidirectional_streaming, ResponseStream, StateFnSender};
pub struct LayoutService {
@ -39,8 +41,14 @@ impl layout_service_server::LayoutService for LayoutService {
tracing::error!("{err}")
}
}
layout_request::Body::Layout(ExplicitLayout {}) => {
// TODO: state.layout_request(output, windows)
layout_request::Body::Layout(ExplicitLayout { output_name }) => {
if let Some(output) = output_name
.map(OutputName)
.and_then(|name| name.output(state))
.or_else(|| state.focused_output().cloned())
{
state.request_layout(&output);
}
}
}
}