mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2024-12-26 21:58:10 +01:00
Write half of new Lua API
This commit is contained in:
parent
3b88b3ff11
commit
97f9cf82d6
7 changed files with 605 additions and 34 deletions
8
api/lua_grpc/.luarc.json
Normal file
8
api/lua_grpc/.luarc.json
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://raw.githubusercontent.com/LuaLS/vscode-lua/master/setting/schema.json",
|
||||||
|
"workspace.library": ["./"],
|
||||||
|
"runtime.version": "Lua 5.4",
|
||||||
|
|
||||||
|
"--comment": "Format using Stylua instead",
|
||||||
|
"format.enable": false,
|
||||||
|
}
|
|
@ -1,14 +1,14 @@
|
||||||
local cqueues = require("cqueues")
|
local cqueues = require("cqueues")
|
||||||
|
|
||||||
---@type ClientModule
|
|
||||||
local client = require("pinnacle.grpc.client")
|
local client = require("pinnacle.grpc.client")
|
||||||
|
|
||||||
---@class PinnacleModule
|
---@class PinnacleModule
|
||||||
local pinnacle = {}
|
local pinnacle = {
|
||||||
|
version = "v0alpha1",
|
||||||
|
}
|
||||||
|
|
||||||
---@class Pinnacle
|
---@class Pinnacle
|
||||||
---@field private config_client Client
|
---@field private config_client Client
|
||||||
---@field private loop CqueuesLoop
|
|
||||||
---@field input Input
|
---@field input Input
|
||||||
local Pinnacle = {}
|
local Pinnacle = {}
|
||||||
|
|
||||||
|
@ -25,21 +25,21 @@ end
|
||||||
---@param config_fn fun(pinnacle: Pinnacle)
|
---@param config_fn fun(pinnacle: Pinnacle)
|
||||||
function pinnacle.setup(config_fn)
|
function pinnacle.setup(config_fn)
|
||||||
require("pinnacle.grpc.protobuf").build_protos()
|
require("pinnacle.grpc.protobuf").build_protos()
|
||||||
|
|
||||||
local loop = cqueues.new()
|
local loop = cqueues.new()
|
||||||
---@type Client
|
|
||||||
local config_client = client.new(loop)
|
local config_client = client.new(loop)
|
||||||
|
|
||||||
---@type Pinnacle
|
---@type Pinnacle
|
||||||
local self = {
|
local self = {
|
||||||
config_client = config_client,
|
config_client = config_client,
|
||||||
loop = loop,
|
|
||||||
input = require("pinnacle.input").new(config_client),
|
input = require("pinnacle.input").new(config_client),
|
||||||
}
|
}
|
||||||
setmetatable(self, { __index = Pinnacle })
|
setmetatable(self, { __index = Pinnacle })
|
||||||
|
|
||||||
config_fn(self)
|
config_fn(self)
|
||||||
|
|
||||||
self.loop:loop()
|
loop:loop()
|
||||||
end
|
end
|
||||||
|
|
||||||
return pinnacle
|
return pinnacle
|
||||||
|
|
|
@ -26,20 +26,18 @@ local client = {}
|
||||||
---@field loop CqueuesLoop
|
---@field loop CqueuesLoop
|
||||||
local Client = {}
|
local Client = {}
|
||||||
|
|
||||||
---@return H2Stream stream An http2 stream
|
|
||||||
function Client:new_stream()
|
|
||||||
return self.conn:new_stream()
|
|
||||||
end
|
|
||||||
|
|
||||||
---@class GrpcRequestParams
|
---@class GrpcRequestParams
|
||||||
---@field service string
|
---@field service string
|
||||||
---@field method string
|
---@field method string
|
||||||
---@field request_type string
|
---@field request_type string?
|
||||||
---@field response_type string?
|
---@field response_type string?
|
||||||
---@field data table
|
---@field data table
|
||||||
|
|
||||||
---Send a synchronous unary request to the compositor.
|
---Send a synchronous unary request to the compositor.
|
||||||
---
|
---
|
||||||
|
---If `request_type` is not specified then it will default to
|
||||||
|
---`method` .. "Request".
|
||||||
|
---
|
||||||
---If `response_type` is not specified then it will default to
|
---If `response_type` is not specified then it will default to
|
||||||
---`google.protobuf.Empty`.
|
---`google.protobuf.Empty`.
|
||||||
---@param grpc_request_params GrpcRequestParams
|
---@param grpc_request_params GrpcRequestParams
|
||||||
|
@ -49,7 +47,7 @@ function Client:unary_request(grpc_request_params)
|
||||||
|
|
||||||
local service = grpc_request_params.service
|
local service = grpc_request_params.service
|
||||||
local method = grpc_request_params.method
|
local method = grpc_request_params.method
|
||||||
local request_type = grpc_request_params.request_type
|
local request_type = grpc_request_params.request_type or method .. "Request"
|
||||||
local response_type = grpc_request_params.response_type or "google.protobuf.Empty"
|
local response_type = grpc_request_params.response_type or "google.protobuf.Empty"
|
||||||
local data = grpc_request_params.data
|
local data = grpc_request_params.data
|
||||||
|
|
||||||
|
@ -129,6 +127,7 @@ function client.new(loop)
|
||||||
loop = loop,
|
loop = loop,
|
||||||
}
|
}
|
||||||
setmetatable(self, { __index = Client })
|
setmetatable(self, { __index = Client })
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,38 @@
|
||||||
---@class InputModule
|
---The protobuf absolute path prefix
|
||||||
local input = {}
|
local prefix = "pinnacle.input." .. require("pinnacle").version .. "."
|
||||||
|
local service = prefix .. "InputService"
|
||||||
|
|
||||||
---@class Input
|
---@type table<string, { request_type: string?, response_type: string? }>
|
||||||
---@field private config_client Client
|
---@enum (key) InputServiceMethod
|
||||||
local Input = {}
|
local rpc_types = {
|
||||||
|
SetKeybind = {
|
||||||
|
response_type = "SetKeybindResponse",
|
||||||
|
},
|
||||||
|
SetMousebind = {
|
||||||
|
response_type = "SetMousebindResponse",
|
||||||
|
},
|
||||||
|
SetXkbConfig = {},
|
||||||
|
SetRepeatRate = {},
|
||||||
|
SetLibinputSetting = {},
|
||||||
|
}
|
||||||
|
|
||||||
|
---Build GrpcRequestParams
|
||||||
|
---@param method InputServiceMethod
|
||||||
|
---@param data table
|
||||||
|
---@return GrpcRequestParams
|
||||||
|
local function build_grpc_request_params(method, data)
|
||||||
|
local req_type = rpc_types[method].request_type
|
||||||
|
local resp_type = rpc_types[method].response_type
|
||||||
|
|
||||||
|
---@type GrpcRequestParams
|
||||||
|
return {
|
||||||
|
service = service,
|
||||||
|
method = method,
|
||||||
|
request_type = req_type and prefix .. req_type,
|
||||||
|
response_type = resp_type and prefix .. resp_type,
|
||||||
|
data = data,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
---@enum Modifier
|
---@enum Modifier
|
||||||
local modifier = {
|
local modifier = {
|
||||||
|
@ -13,7 +42,49 @@ local modifier = {
|
||||||
SUPER = 4,
|
SUPER = 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
---@param mods Modifier[]
|
---@enum MouseButton
|
||||||
|
local mouse_button = {
|
||||||
|
--- Left
|
||||||
|
[1] = 0x110,
|
||||||
|
--- Right
|
||||||
|
[2] = 0x111,
|
||||||
|
--- Middle
|
||||||
|
[3] = 0x112,
|
||||||
|
--- Side
|
||||||
|
[4] = 0x113,
|
||||||
|
--- Extra
|
||||||
|
[5] = 0x114,
|
||||||
|
--- Forward
|
||||||
|
[6] = 0x115,
|
||||||
|
--- Back
|
||||||
|
[7] = 0x116,
|
||||||
|
left = 0x110,
|
||||||
|
right = 0x111,
|
||||||
|
middle = 0x112,
|
||||||
|
side = 0x113,
|
||||||
|
extra = 0x114,
|
||||||
|
forward = 0x115,
|
||||||
|
back = 0x116,
|
||||||
|
}
|
||||||
|
|
||||||
|
---@enum MouseEdge
|
||||||
|
local mouse_edge = {
|
||||||
|
PRESS = 1,
|
||||||
|
RELEASE = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
---@class InputModule
|
||||||
|
local input = {}
|
||||||
|
|
||||||
|
---@class Input
|
||||||
|
---@field private config_client Client
|
||||||
|
local Input = {
|
||||||
|
mod = modifier,
|
||||||
|
btn = mouse_button,
|
||||||
|
edge = mouse_edge,
|
||||||
|
}
|
||||||
|
|
||||||
|
---@param mods Modifier[] TODO: accept strings of mods
|
||||||
---@param key integer | string
|
---@param key integer | string
|
||||||
---@param action fun()
|
---@param action fun()
|
||||||
function Input:set_keybind(mods, key, action)
|
function Input:set_keybind(mods, key, action)
|
||||||
|
@ -26,17 +97,63 @@ function Input:set_keybind(mods, key, action)
|
||||||
xkb_name = key
|
xkb_name = key
|
||||||
end
|
end
|
||||||
|
|
||||||
self.config_client:server_streaming_request({
|
self.config_client:server_streaming_request(
|
||||||
service = "pinnacle.input.v0alpha1.InputService",
|
build_grpc_request_params("SetKeybind", {
|
||||||
method = "SetKeybind",
|
|
||||||
request_type = "pinnacle.input.v0alpha1.SetKeybindRequest",
|
|
||||||
data = {
|
|
||||||
modifiers = mods,
|
modifiers = mods,
|
||||||
-- oneof not violated because `key` can't be both an int and string
|
|
||||||
raw_code = raw_code,
|
raw_code = raw_code,
|
||||||
xkb_name = xkb_name,
|
xkb_name = xkb_name,
|
||||||
},
|
}),
|
||||||
}, action)
|
action
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
---Set a mousebind.
|
||||||
|
---
|
||||||
|
---@param mods Modifier[]
|
||||||
|
---@param button MouseButton
|
||||||
|
---@param edge MouseEdge|"press"|"release"
|
||||||
|
---@param action fun()
|
||||||
|
function Input:set_mousebind(mods, button, edge, action)
|
||||||
|
local edge = edge
|
||||||
|
if edge == "press" then
|
||||||
|
edge = mouse_edge.PRESS
|
||||||
|
elseif edge == "release" then
|
||||||
|
edge = mouse_edge.RELEASE
|
||||||
|
end
|
||||||
|
|
||||||
|
self.config_client:server_streaming_request(
|
||||||
|
build_grpc_request_params("SetMousebind", {
|
||||||
|
modifiers = mods,
|
||||||
|
button = button,
|
||||||
|
edge = edge,
|
||||||
|
}),
|
||||||
|
action
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
---@class XkbConfig
|
||||||
|
---@field rules string?
|
||||||
|
---@field model string?
|
||||||
|
---@field layout string?
|
||||||
|
---@field variant string?
|
||||||
|
---@field options string?
|
||||||
|
|
||||||
|
---Set the xkbconfig for your keyboard.
|
||||||
|
---
|
||||||
|
---@param xkb_config XkbConfig
|
||||||
|
function Input:set_xkb_config(xkb_config)
|
||||||
|
self.config_client:unary_request(build_grpc_request_params("SetXkbConfig", xkb_config))
|
||||||
|
end
|
||||||
|
|
||||||
|
---Set the keyboard's repeat rate and delay.
|
||||||
|
---
|
||||||
|
---@param rate integer The time between repeats, in milliseconds
|
||||||
|
---@param delay integer The duration a key needs to be held down before repeating starts, in milliseconds
|
||||||
|
function Input:set_repeat_rate(rate, delay)
|
||||||
|
self.config_client:unary_request(build_grpc_request_params("SetRepeatRate", {
|
||||||
|
rate = rate,
|
||||||
|
delay = delay,
|
||||||
|
}))
|
||||||
end
|
end
|
||||||
|
|
||||||
function input.new(config_client)
|
function input.new(config_client)
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
local cqueues = require("cqueues")
|
|
||||||
|
|
||||||
local loop = {
|
|
||||||
loop = cqueues.new(),
|
|
||||||
}
|
|
||||||
|
|
||||||
return loop
|
|
165
api/lua_grpc/pinnacle/output.lua
Normal file
165
api/lua_grpc/pinnacle/output.lua
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
---The protobuf absolute path prefix
|
||||||
|
local prefix = "pinnacle.output." .. require("pinnacle").version .. "."
|
||||||
|
local service = prefix .. "OutputService"
|
||||||
|
|
||||||
|
---@type table<string, { request_type: string?, response_type: string? }>
|
||||||
|
---@enum (key) OutputServiceMethod
|
||||||
|
local rpc_types = {
|
||||||
|
SetLocation = {},
|
||||||
|
ConnectForAll = {
|
||||||
|
response_type = "ConnectForAllResponse",
|
||||||
|
},
|
||||||
|
Get = {
|
||||||
|
response_type = "GetResponse",
|
||||||
|
},
|
||||||
|
GetProperties = {
|
||||||
|
response_type = "GetPropertiesResponse",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
---Build GrpcRequestParams
|
||||||
|
---@param method OutputServiceMethod
|
||||||
|
---@param data table
|
||||||
|
---@return GrpcRequestParams
|
||||||
|
local function build_grpc_request_params(method, data)
|
||||||
|
local req_type = rpc_types[method].request_type
|
||||||
|
local resp_type = rpc_types[method].response_type
|
||||||
|
|
||||||
|
---@type GrpcRequestParams
|
||||||
|
return {
|
||||||
|
service = service,
|
||||||
|
method = method,
|
||||||
|
request_type = req_type and prefix .. req_type,
|
||||||
|
response_type = resp_type and prefix .. resp_type,
|
||||||
|
data = data,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
---@class OutputHandleModule
|
||||||
|
local output_handle = {}
|
||||||
|
|
||||||
|
---@class OutputHandle
|
||||||
|
---@field private config_client Client
|
||||||
|
---@field name string The unique name of this output
|
||||||
|
local OutputHandle = {}
|
||||||
|
|
||||||
|
---@class OutputModule
|
||||||
|
---@field private handle OutputHandleModule
|
||||||
|
local output = {}
|
||||||
|
output.handle = output_handle
|
||||||
|
|
||||||
|
---@class Output
|
||||||
|
---@field private config_client Client
|
||||||
|
local Output = {}
|
||||||
|
|
||||||
|
---Get all outputs.
|
||||||
|
---
|
||||||
|
---@return OutputHandle[]
|
||||||
|
function Output:get_all()
|
||||||
|
local response = self.config_client:unary_request(build_grpc_request_params("Get", {}))
|
||||||
|
|
||||||
|
---@type OutputHandle[]
|
||||||
|
local handles = {}
|
||||||
|
|
||||||
|
for _, output_name in pairs(response.output_names) do
|
||||||
|
table.insert(handles, output_handle.new(self.config_client, output_name))
|
||||||
|
end
|
||||||
|
|
||||||
|
return handles
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param name string The name of the port the output is connected to
|
||||||
|
---@return OutputHandle | nil
|
||||||
|
function Output:get_by_name(name)
|
||||||
|
local handles = self:get_all()
|
||||||
|
|
||||||
|
for _, handle in pairs(handles) do
|
||||||
|
if handle.name == name then
|
||||||
|
return handle
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
---@return OutputHandle | nil
|
||||||
|
function Output:get_focused()
|
||||||
|
local handles = self:get_all()
|
||||||
|
|
||||||
|
for _, handle in pairs(handles) do
|
||||||
|
if handle:props().focused then
|
||||||
|
return handle
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param callback fun(output: OutputHandle)
|
||||||
|
function Output:connect_for_all(callback)
|
||||||
|
self.config_client:server_streaming_request(build_grpc_request_params("ConnectForAll", {}), function(response)
|
||||||
|
local output_name = response.output_name
|
||||||
|
local handle = output_handle.new(self.config_client, output_name)
|
||||||
|
callback(handle)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param loc { x: integer?, y: integer? }
|
||||||
|
function OutputHandle:set_location(loc)
|
||||||
|
self.config_client:unary_request(build_grpc_request_params("SetLocation", {
|
||||||
|
output_name = self.name,
|
||||||
|
x = loc.x,
|
||||||
|
y = loc.y,
|
||||||
|
}))
|
||||||
|
end
|
||||||
|
|
||||||
|
---@class OutputProperties
|
||||||
|
---@field make string?
|
||||||
|
---@field model string?
|
||||||
|
---@field x integer?
|
||||||
|
---@field y integer?
|
||||||
|
---@field pixel_width integer?
|
||||||
|
---@field pixel_height integer?
|
||||||
|
---@field refresh_rate integer?
|
||||||
|
---@field physical_width integer?
|
||||||
|
---@field physical_height integer?
|
||||||
|
---@field focused boolean?
|
||||||
|
---@field tags TagHandle[]
|
||||||
|
|
||||||
|
---Get all properties of this output.
|
||||||
|
---@return OutputProperties
|
||||||
|
function OutputHandle:props()
|
||||||
|
local response =
|
||||||
|
self.config_client:unary_request(build_grpc_request_params("GetProperties", { output_name = self.name }))
|
||||||
|
|
||||||
|
local handles = require("pinnacle.tag").handle.new_from_table(self.config_client, response.tag_ids)
|
||||||
|
|
||||||
|
response.tags = handles
|
||||||
|
response.tag_ids = nil
|
||||||
|
|
||||||
|
return response
|
||||||
|
end
|
||||||
|
|
||||||
|
---@return Output
|
||||||
|
function output.new(config_client)
|
||||||
|
---@type Output
|
||||||
|
local self = {
|
||||||
|
config_client = config_client,
|
||||||
|
}
|
||||||
|
setmetatable(self, { __index = Output })
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
---Create a new `OutputHandle` from its raw name.
|
||||||
|
---@param output_name string
|
||||||
|
function output_handle.new(config_client, output_name)
|
||||||
|
---@type OutputHandle
|
||||||
|
local self = {
|
||||||
|
config_client = config_client,
|
||||||
|
name = output_name,
|
||||||
|
}
|
||||||
|
setmetatable(self, { __index = OutputHandle })
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
return output
|
289
api/lua_grpc/pinnacle/tag.lua
Normal file
289
api/lua_grpc/pinnacle/tag.lua
Normal file
|
@ -0,0 +1,289 @@
|
||||||
|
---The protobuf absolute path prefix
|
||||||
|
local prefix = "pinnacle.tag." .. require("pinnacle").version .. "."
|
||||||
|
local service = prefix .. "TagService"
|
||||||
|
|
||||||
|
---@type table<string, { request_type: string?, response_type: string? }>
|
||||||
|
---@enum (key) TagServiceMethod
|
||||||
|
local rpc_types = {
|
||||||
|
SetActive = {},
|
||||||
|
SwitchTo = {},
|
||||||
|
Add = {
|
||||||
|
response_type = "AddResponse",
|
||||||
|
},
|
||||||
|
Remove = {},
|
||||||
|
SetLayout = {},
|
||||||
|
Get = {
|
||||||
|
response_type = "GetResponse",
|
||||||
|
},
|
||||||
|
GetProperties = {
|
||||||
|
response_type = "GetPropertiesResponse",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
---Build GrpcRequestParams
|
||||||
|
---@param method TagServiceMethod
|
||||||
|
---@param data table
|
||||||
|
---@return GrpcRequestParams
|
||||||
|
local function build_grpc_request_params(method, data)
|
||||||
|
local req_type = rpc_types[method].request_type
|
||||||
|
local resp_type = rpc_types[method].response_type
|
||||||
|
|
||||||
|
---@type GrpcRequestParams
|
||||||
|
return {
|
||||||
|
service = service,
|
||||||
|
method = method,
|
||||||
|
request_type = req_type and prefix .. req_type,
|
||||||
|
response_type = resp_type and prefix .. resp_type,
|
||||||
|
data = data,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
---@class TagHandleModule
|
||||||
|
local tag_handle = {}
|
||||||
|
|
||||||
|
---@class TagHandle
|
||||||
|
---@field private config_client Client
|
||||||
|
---@field id integer
|
||||||
|
local TagHandle = {}
|
||||||
|
|
||||||
|
---@class TagModule
|
||||||
|
---@field private handle TagHandleModule
|
||||||
|
local tag = {}
|
||||||
|
tag.handle = tag_handle
|
||||||
|
|
||||||
|
---@class Tag
|
||||||
|
---@field private config_client Client
|
||||||
|
local Tag = {}
|
||||||
|
|
||||||
|
---Get all tags across all outputs.
|
||||||
|
---
|
||||||
|
---@return TagHandle[]
|
||||||
|
function Tag:get_all()
|
||||||
|
local response = self.config_client:unary_request(build_grpc_request_params("Get", {}))
|
||||||
|
|
||||||
|
---@type TagHandle[]
|
||||||
|
local handles = {}
|
||||||
|
|
||||||
|
for _, id in pairs(response.tag_ids) do
|
||||||
|
table.insert(handles, tag_handle.new(self.config_client, id))
|
||||||
|
end
|
||||||
|
|
||||||
|
return handles
|
||||||
|
end
|
||||||
|
|
||||||
|
---Add tags with the given names to the specified output.
|
||||||
|
---
|
||||||
|
---Returns handles to the created tags.
|
||||||
|
---
|
||||||
|
---@param output OutputHandle
|
||||||
|
---@param ... string
|
||||||
|
---
|
||||||
|
---@return TagHandle[]
|
||||||
|
---
|
||||||
|
---@overload fun(output: OutputHandle, tag_names: string[])
|
||||||
|
function Tag:add(output, ...)
|
||||||
|
local tag_names = { ... }
|
||||||
|
if type(tag_names[1]) == "table" then
|
||||||
|
tag_names = tag_names[1] --[=[@as string[]]=]
|
||||||
|
end
|
||||||
|
|
||||||
|
local response = self.config_client:unary_request(build_grpc_request_params("Add", {
|
||||||
|
output_name = output.name,
|
||||||
|
tag_names = tag_names,
|
||||||
|
}))
|
||||||
|
|
||||||
|
---@type TagHandle[]
|
||||||
|
local handles = {}
|
||||||
|
|
||||||
|
for _, id in pairs(response.tag_ids) do
|
||||||
|
table.insert(handles, tag_handle.new(self.config_client, id))
|
||||||
|
end
|
||||||
|
|
||||||
|
return handles
|
||||||
|
end
|
||||||
|
|
||||||
|
---Remove the given tags.
|
||||||
|
---
|
||||||
|
---@param tags TagHandle[]
|
||||||
|
function Tag:remove(tags)
|
||||||
|
---@type integer[]
|
||||||
|
local ids = {}
|
||||||
|
|
||||||
|
for _, tg in pairs(tags) do
|
||||||
|
table.insert(ids, tg.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
self.config_client:unary_request(build_grpc_request_params("Remove", { tag_ids = ids }))
|
||||||
|
end
|
||||||
|
|
||||||
|
---@class LayoutCycler
|
||||||
|
---@field next fun(output: OutputHandle)
|
||||||
|
---@field prev fun(output: OutputHandle)
|
||||||
|
|
||||||
|
--- TODO: docs
|
||||||
|
---@param layouts Layout[]
|
||||||
|
---
|
||||||
|
---@return LayoutCycler
|
||||||
|
function Tag:new_layout_cycler(layouts)
|
||||||
|
local indices = {}
|
||||||
|
|
||||||
|
if #layouts == 0 then
|
||||||
|
return {
|
||||||
|
next = function(_) end,
|
||||||
|
prev = function(_) end,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
---@type LayoutCycler
|
||||||
|
return {
|
||||||
|
next = function(output)
|
||||||
|
local tags = output:props().tags
|
||||||
|
|
||||||
|
for _, tg in pairs(tags) do
|
||||||
|
if tg:props().active then
|
||||||
|
local id = tg.id
|
||||||
|
if #layouts == 1 then
|
||||||
|
indices[id] = 1
|
||||||
|
elseif indices[id] == nil then
|
||||||
|
indices[id] = 2
|
||||||
|
else
|
||||||
|
if indices[id] + 1 > #layouts then
|
||||||
|
indices[id] = 1
|
||||||
|
else
|
||||||
|
indices[id] = indices[id] + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
tg:set_layout(layouts[indices[id]])
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
prev = function(output)
|
||||||
|
local tags = output:props().tags
|
||||||
|
|
||||||
|
for _, tg in pairs(tags) do
|
||||||
|
if tg:props().active then
|
||||||
|
local id = tg.id
|
||||||
|
|
||||||
|
if #layouts == 1 then
|
||||||
|
indices[id] = 1
|
||||||
|
elseif indices[id] == nil then
|
||||||
|
indices[id] = #layouts - 1
|
||||||
|
else
|
||||||
|
if indices[id] - 1 < 1 then
|
||||||
|
indices[id] = #layouts
|
||||||
|
else
|
||||||
|
indices[id] = indices[id] - 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
tg:set_layout(layouts[indices[id]])
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
---Remove this tag.
|
||||||
|
function TagHandle:remove()
|
||||||
|
self.config_client:unary_request(build_grpc_request_params("Remove", { tag_ids = { self.id } }))
|
||||||
|
end
|
||||||
|
|
||||||
|
---@enum (key) Layout
|
||||||
|
local _layouts = {
|
||||||
|
master_stack = 1,
|
||||||
|
dwindle = 2,
|
||||||
|
spiral = 3,
|
||||||
|
corner_top_left = 4,
|
||||||
|
corner_top_right = 5,
|
||||||
|
corner_bottom_left = 6,
|
||||||
|
corner_bottom_right = 7,
|
||||||
|
}
|
||||||
|
|
||||||
|
---@param layout Layout
|
||||||
|
function TagHandle:set_layout(layout)
|
||||||
|
local layout = _layouts[layout]
|
||||||
|
|
||||||
|
self.config_client:unary_request(build_grpc_request_params("SetLayout", {
|
||||||
|
tag_id = self.id,
|
||||||
|
layout = layout,
|
||||||
|
}))
|
||||||
|
end
|
||||||
|
|
||||||
|
---Activate this tag and deactivate all other ones on the same output.
|
||||||
|
function TagHandle:switch_to()
|
||||||
|
self.config_client:unary_request(build_grpc_request_params("SwitchTo", { tag_id = self.id }))
|
||||||
|
end
|
||||||
|
|
||||||
|
---Set whether or not this tag is active.
|
||||||
|
---
|
||||||
|
---@param active boolean
|
||||||
|
function TagHandle:set_active(active)
|
||||||
|
self.config_client:unary_request(build_grpc_request_params("SetActive", { tag_id = self.id, set = active }))
|
||||||
|
end
|
||||||
|
|
||||||
|
---Toggle this tag's active state.
|
||||||
|
function TagHandle:toggle_active()
|
||||||
|
self.config_client:unary_request(build_grpc_request_params("SetActive", { tag_id = self.id, toggle = {} }))
|
||||||
|
end
|
||||||
|
|
||||||
|
---@class TagProperties
|
||||||
|
---@field active boolean?
|
||||||
|
---@field name string?
|
||||||
|
---@field output OutputHandle?
|
||||||
|
|
||||||
|
---Get all properties of this tag.
|
||||||
|
---
|
||||||
|
---@return TagProperties
|
||||||
|
function TagHandle:props()
|
||||||
|
local response = self.config_client:unary_request(build_grpc_request_params("GetProperties", { tag_id = self.id }))
|
||||||
|
|
||||||
|
return {
|
||||||
|
active = response.active,
|
||||||
|
name = response.name,
|
||||||
|
output = response.output_name
|
||||||
|
and require("pinnacle.output").handle.new(self.config_client, response.output_name),
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
---@return Tag
|
||||||
|
function tag.new(config_client)
|
||||||
|
---@type Tag
|
||||||
|
local self = {
|
||||||
|
config_client = config_client,
|
||||||
|
}
|
||||||
|
setmetatable(self, { __index = Tag })
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
---Create a new `TagHandle` from an id.
|
||||||
|
---@param config_client Client
|
||||||
|
---@param tag_id integer
|
||||||
|
---@return TagHandle
|
||||||
|
function tag_handle.new(config_client, tag_id)
|
||||||
|
---@type TagHandle
|
||||||
|
local self = {
|
||||||
|
config_client = config_client,
|
||||||
|
id = tag_id,
|
||||||
|
}
|
||||||
|
setmetatable(self, { __index = TagHandle })
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param config_client Client
|
||||||
|
---@param tag_ids integer[]
|
||||||
|
---@return TagHandle[]
|
||||||
|
function tag_handle.new_from_table(config_client, tag_ids)
|
||||||
|
---@type TagHandle[]
|
||||||
|
local handles = {}
|
||||||
|
|
||||||
|
for _, id in pairs(tag_ids) do
|
||||||
|
table.insert(handles, tag_handle.new(config_client, id))
|
||||||
|
end
|
||||||
|
|
||||||
|
return handles
|
||||||
|
end
|
||||||
|
|
||||||
|
return tag
|
Loading…
Reference in a new issue