Add deep copy to copy Lua layouts

This is probably not going to be in the final iteration; I think I might convert all Lua layouts to classes instead of having users deep copy them to change settings
This commit is contained in:
Ottatop 2024-03-16 16:40:47 -05:00
parent 79291d1cd9
commit 17d0760e43
5 changed files with 69 additions and 8 deletions

View file

@ -5,6 +5,7 @@ require("pinnacle").setup(function(Pinnacle)
local Tag = Pinnacle.tag
local Window = Pinnacle.window
local Layout = Pinnacle.layout
local Util = Pinnacle.util
local key = Input.key
@ -88,8 +89,20 @@ require("pinnacle").setup(function(Pinnacle)
-- Layouts --
--------------------
-- TODO: convert layouts into objs, deep_copy doesn't work on fns
local master_stack_right = Util.deep_copy(Layout.builtins.master_stack)
master_stack_right.master_side = "right"
local master_stack_top = Util.deep_copy(Layout.builtins.master_stack)
master_stack_top.master_side = "top"
local master_stack_bottom = Util.deep_copy(Layout.builtins.master_stack)
master_stack_bottom.master_side = "bottom"
local layout_manager = Layout.new_cycling_manager({
Layout.builtins.master_stack,
master_stack_right,
master_stack_top,
master_stack_bottom,
Layout.builtins.dwindle,
Layout.builtins.spiral,
Layout.builtins.corner,

View file

@ -42,29 +42,41 @@ end
---@class LayoutGenerator
---Generate an array of geometries from the given `LayoutArgs`.
---@field layout fun(self: self, args: LayoutArgs): { x: integer, y: integer, width: integer, height: integer }[]
---Gaps between windows.
---
---Generators are free to ignore this, but it is recommended to implement gaps if
---it makes sense for the layout.
---@field gaps integer | { inner: integer, outer: integer }
---A `LayoutGenerator` that has one master area to one side
---and a stack of windows next to it.
---@class Builtin.MasterStack : LayoutGenerator
---@field gaps integer | { inner: integer, outer: integer }
---@field master_factor number
---@field master_side "left"|"right"|"top"|"bottom"
---@field master_count integer
---A `LayoutGenerator` that lays out windows in a shrinking fashion
---towards the bottom right corner.
---@class Builtin.Dwindle : LayoutGenerator
---@field gaps integer | { inner: integer, outer: integer }
---@field split_factors table<integer, number>
---A `LayoutGenerator` that has one main corner window and a
---horizontal and vertical stack flanking it on the other two sides.
---@class Builtin.Corner : LayoutGenerator
---@field gaps integer | { inner: integer, outer: integer }
---@field corner_width_factor number
---@field corner_height_factor number
---@field corner_loc "top_left"|"top_right"|"bottom_left"|"bottom_right"
---A `LayoutGenerator` that lays out windows in a spiral.
---
---This is similar to the dwindle layout but in a spiral instead of
---towards the borrom right corner.
---@class Builtin.Spiral : LayoutGenerator
---@field gaps integer | { inner: integer, outer: integer }
---@field split_factors table<integer, number>
---A `LayoutGenerator` that attempts to layout windows such that
---they are the same size.
---@class Builtin.Fair : LayoutGenerator
---@field gaps integer | { inner: integer, outer: integer }
---@field direction "horizontal"|"vertical"
local builtins = {
@ -401,6 +413,7 @@ function builtins.dwindle:layout(args)
local to_push
---@diagnostic disable-next-line: cast-local-type
to_push, rest = rest:split_at(axis, split_coord, gaps)
if not rest then

View file

@ -77,6 +77,43 @@ function util.batch(requests)
return responses
end
-- Taken from the following stackoverflow answer:
-- https://stackoverflow.com/a/16077650
local function deep_copy_rec(obj, seen)
seen = seen or {}
if obj == nil then
return nil
end
if seen[obj] then
return seen[obj]
end
local no
if type(obj) == "table" then
no = {}
seen[obj] = no
for k, v in next, obj, nil do
no[deep_copy_rec(k, seen)] = deep_copy_rec(v, seen)
end
setmetatable(no, deep_copy_rec(getmetatable(obj), seen))
else -- number, string, boolean, etc
no = obj
end
return no
end
---Create a deep copy of an object.
---
---@generic T
---
---@param obj T The object to deep copy.
---
---@return T deep_copy A deep copy of `obj`
function util.deep_copy(obj)
return deep_copy_rec(obj, nil)
end
-- Geometry stuff
---@class RectangleModule

View file

@ -744,7 +744,7 @@ pub enum CornerLocation {
}
/// A [`LayoutGenerator`] that has one main corner window and a
/// horizontal and vertical stack flanking on the other two sides.
/// horizontal and vertical stack flanking it on the other two sides.
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct CornerLayout {
/// Gaps between windows.

View file

@ -222,8 +222,6 @@ impl State {
}
pub fn apply_layout(&mut self, geometries: Geometries) -> anyhow::Result<()> {
tracing::info!("Applying layout");
let Geometries {
request_id: Some(request_id),
output_name: Some(output_name),