mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2025-01-13 08:01:05 +01:00
Impl Layout.request_layout
This commit is contained in:
parent
e1f2706428
commit
e86f242330
4 changed files with 57 additions and 10 deletions
|
@ -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)
|
||||
|
|
|
@ -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 })
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue