api/lua: Make client connection explicit

This commit is contained in:
Ottatop 2024-07-11 15:50:33 -05:00
parent ade04b3833
commit c1936c8a87
14 changed files with 105 additions and 286 deletions

View file

@ -1,6 +1,15 @@
{ {
"$schema": "https://raw.githubusercontent.com/LuaLS/vscode-lua/master/setting/schema.json", "$schema": "https://raw.githubusercontent.com/LuaLS/vscode-lua/master/setting/schema.json",
"workspace.library": ["./", "../../snowcap/api/lua"], "workspace.library": [
"./",
"../../snowcap/api/lua",
"~/.luarocks/share/lua/5.4/grpc_client.lua",
"~/.luarocks/share/lua/5.4/grpc_client",
"~/.luarocks/share/lua/5.3/grpc_client.lua",
"~/.luarocks/share/lua/5.3/grpc_client",
"~/.luarocks/share/lua/5.2/grpc_client.lua",
"~/.luarocks/share/lua/5.2/grpc_client",
],
"runtime.version": "Lua 5.2", "runtime.version": "Lua 5.2",
"--comment": "Format using Stylua instead", "--comment": "Format using Stylua instead",

View file

@ -13,6 +13,7 @@ dependencies = {
"http ~> 0.4", "http ~> 0.4",
"lua-protobuf ~> 0.5", "lua-protobuf ~> 0.5",
"compat53 ~> 0.13", "compat53 ~> 0.13",
"lua-grpc-client >= dev-1",
} }
build = { build = {
type = "builtin", type = "builtin",

View file

@ -2,7 +2,7 @@
-- License, v. 2.0. If a copy of the MPL was not distributed with this -- License, v. 2.0. If a copy of the MPL was not distributed with this
-- file, You can obtain one at https://mozilla.org/MPL/2.0/. -- file, You can obtain one at https://mozilla.org/MPL/2.0/.
local client = require("pinnacle.grpc.client") local client = require("pinnacle.grpc.client").client
local pinnacle_service = require("pinnacle.grpc.defs").pinnacle.v0alpha1.PinnacleService local pinnacle_service = require("pinnacle.grpc.defs").pinnacle.v0alpha1.PinnacleService
---The entry point to configuration. ---The entry point to configuration.
@ -32,12 +32,12 @@ local pinnacle = {
---Quit Pinnacle. ---Quit Pinnacle.
function pinnacle.quit() function pinnacle.quit()
client.unary_request(pinnacle_service.Quit, {}) client():unary_request(pinnacle_service.Quit, {})
end end
---Reload the active config. ---Reload the active config.
function pinnacle.reload_config() function pinnacle.reload_config()
client.unary_request(pinnacle_service.ReloadConfig, {}) client():unary_request(pinnacle_service.ReloadConfig, {})
end end
---Setup a Pinnacle config. ---Setup a Pinnacle config.
@ -59,15 +59,17 @@ function pinnacle.setup(config_fn)
snowcap.init() snowcap.init()
end end
require("pinnacle.grpc.client").connect()
-- Make Snowcap use Pinnacle's cqueues loop -- Make Snowcap use Pinnacle's cqueues loop
require("snowcap.grpc.client").loop = client.loop require("snowcap.grpc.client").client().loop = client().loop
-- This function ensures a config won't run forever if Pinnacle is killed -- This function ensures a config won't run forever if Pinnacle is killed
-- and doesn't kill configs on drop. -- and doesn't kill configs on drop.
client.loop:wrap(function() client().loop:wrap(function()
while true do while true do
require("cqueues").sleep(60) require("cqueues").sleep(60)
local success, err, errno = client.conn:ping(10) local success, err, errno = client().conn:ping(10)
if not success then if not success then
print("Compositor ping failed:", err, errno) print("Compositor ping failed:", err, errno)
os.exit(1) os.exit(1)
@ -77,7 +79,7 @@ function pinnacle.setup(config_fn)
config_fn(pinnacle) config_fn(pinnacle)
local success, err = client.loop:loop() local success, err = client().loop:loop()
if not success then if not success then
print(err) print(err)
end end
@ -104,6 +106,8 @@ function pinnacle.run(run_fn)
snowcap.init() snowcap.init()
end end
require("pinnacle.grpc.client").connect()
run_fn(pinnacle) run_fn(pinnacle)
end end

View file

@ -2,224 +2,19 @@
-- License, v. 2.0. If a copy of the MPL was not distributed with this -- License, v. 2.0. If a copy of the MPL was not distributed with this
-- file, You can obtain one at https://mozilla.org/MPL/2.0/. -- file, You can obtain one at https://mozilla.org/MPL/2.0/.
require("compat53") local client_inner = nil
local socket = require("cqueues.socket")
local headers = require("http.headers")
local h2_connection = require("http.h2_connection")
local protobuf = require("pinnacle.grpc.protobuf")
local pb = require("pb")
---@nodoc
---Create appropriate headers for a gRPC request.
---@param service string The desired service
---@param method string The desired method within the service
local function create_request_headers(service, method)
local req_headers = headers.new()
req_headers:append(":method", "POST")
req_headers:append(":scheme", "http")
req_headers:append(":path", "/" .. service .. "/" .. method)
req_headers:append("te", "trailers")
req_headers:append("content-type", "application/grpc")
return req_headers
end
local function new_conn()
local sock = socket.connect({
path = os.getenv("PINNACLE_GRPC_SOCKET"),
})
sock:connect()
local conn = h2_connection.new(sock, "client")
conn:connect()
return conn
end
---@class CqueuesLoop
---@field loop function
---@field wrap fun(self: self, fn: function)
---@class H2Connection
---@field new_stream function
---@class H2Stream
---@field write_chunk function
---@field shutdown function
---@nodoc
---@class Client
---@field conn H2Connection
---@field loop CqueuesLoop
local client = { local client = {
conn = new_conn(), ---@type fun(): grpc_client.Client
loop = require("cqueues").new(), client = function()
version = "v0alpha1", return client_inner
end,
} }
---@class GrpcRequestParams function client.connect()
---@field service string client_inner = require("grpc_client").new({
---@field method string path = os.getenv("PINNACLE_GRPC_SOCKET"),
---@field request_type string })
---@field response_type string?
---@field data table
---@nodoc
---Send a synchronous unary request to the compositor.
---
---@param grpc_request_args GrpcRequestArgs
---@param data table
---@return table
function client.unary_request(grpc_request_args, data)
local stream = client.conn:new_stream()
local service = grpc_request_args.service
local method = grpc_request_args.method
local request_type = grpc_request_args.request
local response_type = grpc_request_args.response
local body = protobuf.encode(request_type, data)
stream:write_headers(create_request_headers(service, method), false)
stream:write_chunk(body, true)
-- TODO: check response headers for errors
local _ = stream:get_headers()
local response_body = stream:get_next_chunk()
local trailers = stream:get_headers()
if trailers then -- idk if im big dummy or not but there are never any trailers
for name, value, never_index in trailers:each() do
print(name, value, never_index)
end
end
stream:shutdown()
-- Skip the 1-byte compressed flag and the 4-byte message length
---@diagnostic disable-next-line: redefined-local
local response_body = response_body:sub(6)
local response = pb.decode(response_type, response_body)
return response
end
---@nodoc
---Send a async server streaming request to the compositor.
---
---`callback` will be called with every streamed response.
---
---@param grpc_request_args GrpcRequestArgs
---@param data table
---@param callback fun(response: table)
function client.server_streaming_request(grpc_request_args, data, callback)
local stream = client.conn:new_stream()
local service = grpc_request_args.service
local method = grpc_request_args.method
local request_type = grpc_request_args.request
local response_type = grpc_request_args.response
local body = protobuf.encode(request_type, data)
stream:write_headers(create_request_headers(service, method), false)
stream:write_chunk(body, true)
-- TODO: check response headers for errors
local _ = stream:get_headers()
client.loop:wrap(function()
for response_body in stream:each_chunk() do
---@diagnostic disable-next-line: redefined-local
local response_body = response_body
while response_body:len() > 0 do
local msg_len = string.unpack(">I4", response_body:sub(2, 5))
-- Skip the 1-byte compressed flag and the 4-byte message length
local body = response_body:sub(6, 6 + msg_len - 1)
---@diagnostic disable-next-line: redefined-local
local success, obj = pcall(pb.decode, response_type, body)
if not success then
print(obj)
os.exit(1)
end
local response = obj
callback(response)
response_body = response_body:sub(msg_len + 6)
end
end
local trailers = stream:get_headers()
if trailers then
for name, value, never_index in trailers:each() do
print(name, value, never_index)
end
end
end)
end
---@nodoc
---@param grpc_request_args GrpcRequestArgs
---@param callback fun(response: table, stream: H2Stream)
---
---@return H2Stream
function client.bidirectional_streaming_request(grpc_request_args, data, callback)
local stream = client.conn:new_stream()
local service = grpc_request_args.service
local method = grpc_request_args.method
local request_type = grpc_request_args.request
local response_type = grpc_request_args.response
local body = protobuf.encode(request_type, data)
stream:write_headers(create_request_headers(service, method), false)
stream:write_chunk(body, false)
-- TODO: check response headers for errors
local _ = stream:get_headers()
client.loop:wrap(function()
for response_body in stream:each_chunk() do
---@diagnostic disable-next-line: redefined-local
local response_body = response_body
while response_body:len() > 0 do
local msg_len = string.unpack(">I4", response_body:sub(2, 5))
-- Skip the 1-byte compressed flag and the 4-byte message length
local body = response_body:sub(6, 6 + msg_len - 1)
---@diagnostic disable-next-line: redefined-local
local success, obj = pcall(pb.decode, response_type, body)
if not success then
print(obj)
os.exit(1)
end
-- print(require("inspect")(obj))
local response = obj
callback(response, stream)
response_body = response_body:sub(msg_len + 6)
end
end
local trailers = stream:get_headers()
if trailers then
for name, value, never_index in trailers:each() do
print(name, value, never_index)
end
end
end)
return stream
end end
return client return client

View file

@ -2,7 +2,7 @@
-- License, v. 2.0. If a copy of the MPL was not distributed with this -- License, v. 2.0. If a copy of the MPL was not distributed with this
-- file, You can obtain one at https://mozilla.org/MPL/2.0/. -- file, You can obtain one at https://mozilla.org/MPL/2.0/.
local client = require("pinnacle.grpc.client") local client = require("pinnacle.grpc.client").client
local input_service = require("pinnacle.grpc.defs").pinnacle.input.v0alpha1.InputService local input_service = require("pinnacle.grpc.defs").pinnacle.input.v0alpha1.InputService
-- This is an @enum and not an @alias because with an @alias the completion replaces tables with a string, -- This is an @enum and not an @alias because with an @alias the completion replaces tables with a string,
@ -131,7 +131,7 @@ function input.keybind(mods, key, action, keybind_info)
table.insert(mod_values, modifier_values[mod]) table.insert(mod_values, modifier_values[mod])
end end
client.server_streaming_request(input_service.SetKeybind, { client():server_streaming_request(input_service.SetKeybind, {
modifiers = mod_values, modifiers = mod_values,
raw_code = raw_code, raw_code = raw_code,
xkb_name = xkb_name, xkb_name = xkb_name,
@ -165,7 +165,7 @@ function input.mousebind(mods, button, edge, action)
table.insert(mod_values, modifier_values[mod]) table.insert(mod_values, modifier_values[mod])
end end
client.server_streaming_request(input_service.SetMousebind, { client():server_streaming_request(input_service.SetMousebind, {
modifiers = mod_values, modifiers = mod_values,
button = mouse_button_values[button], button = mouse_button_values[button],
edge = edge, edge = edge,
@ -184,7 +184,7 @@ end
---@return KeybindDescription[] ---@return KeybindDescription[]
function input.keybind_descriptions() function input.keybind_descriptions()
---@type pinnacle.input.v0alpha1.KeybindDescriptionsResponse ---@type pinnacle.input.v0alpha1.KeybindDescriptionsResponse
local descs = client.unary_request(input_service.KeybindDescriptions, {}) local descs = client():unary_request(input_service.KeybindDescriptions, {})
local descs = descs.descriptions or {} local descs = descs.descriptions or {}
local ret = {} local ret = {}
@ -233,7 +233,7 @@ end
--- ---
---@param xkb_config XkbConfig The new xkbconfig ---@param xkb_config XkbConfig The new xkbconfig
function input.set_xkb_config(xkb_config) function input.set_xkb_config(xkb_config)
client.unary_request(input_service.SetXkbConfig, xkb_config) client():unary_request(input_service.SetXkbConfig, xkb_config)
end end
---Set the keyboard's repeat rate and delay. ---Set the keyboard's repeat rate and delay.
@ -246,7 +246,7 @@ end
---@param rate integer The time between repeats in milliseconds ---@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 ---@param delay integer The duration a key needs to be held down before repeating starts in milliseconds
function input.set_repeat_rate(rate, delay) function input.set_repeat_rate(rate, delay)
client.unary_request(input_service.SetRepeatRate, { client():unary_request(input_service.SetRepeatRate, {
rate = rate, rate = rate,
delay = delay, delay = delay,
}) })
@ -322,32 +322,32 @@ local tap_button_map_values = {
function input.set_libinput_settings(settings) function input.set_libinput_settings(settings)
for setting, value in pairs(settings) do for setting, value in pairs(settings) do
if setting == "accel_profile" then if setting == "accel_profile" then
client.unary_request( client():unary_request(
input_service.SetLibinputSetting, input_service.SetLibinputSetting,
{ [setting] = accel_profile_values[value] } { [setting] = accel_profile_values[value] }
) )
elseif setting == "calibration_matrix" then elseif setting == "calibration_matrix" then
client.unary_request( client():unary_request(
input_service.SetLibinputSetting, input_service.SetLibinputSetting,
{ [setting] = { matrix = value } } { [setting] = { matrix = value } }
) )
elseif setting == "click_method" then elseif setting == "click_method" then
client.unary_request( client():unary_request(
input_service.SetLibinputSetting, input_service.SetLibinputSetting,
{ [setting] = click_method_values[value] } { [setting] = click_method_values[value] }
) )
elseif setting == "scroll_method" then elseif setting == "scroll_method" then
client.unary_request( client():unary_request(
input_service.SetLibinputSetting, input_service.SetLibinputSetting,
{ [setting] = scroll_method_values[value] } { [setting] = scroll_method_values[value] }
) )
elseif setting == "tap_button_map" then elseif setting == "tap_button_map" then
client.unary_request( client():unary_request(
input_service.SetLibinputSetting, input_service.SetLibinputSetting,
{ [setting] = tap_button_map_values[value] } { [setting] = tap_button_map_values[value] }
) )
else else
client.unary_request(input_service.SetLibinputSetting, { [setting] = value }) client():unary_request(input_service.SetLibinputSetting, { [setting] = value })
end end
end end
end end
@ -359,7 +359,7 @@ end
--- ---
---@param theme string ---@param theme string
function input.set_xcursor_theme(theme) function input.set_xcursor_theme(theme)
client.unary_request(input_service.SetXcursor, { client():unary_request(input_service.SetXcursor, {
theme = theme, theme = theme,
}) })
end end
@ -371,7 +371,7 @@ end
--- ---
---@param size integer ---@param size integer
function input.set_xcursor_size(size) function input.set_xcursor_size(size)
client.unary_request(input_service.SetXcursor, { client():unary_request(input_service.SetXcursor, {
size = size, size = size,
}) })
end end

View file

@ -1,4 +1,8 @@
local client = require("pinnacle.grpc.client") -- This Source Code Form is subject to the terms of the Mozilla Public
-- License, v. 2.0. If a copy of the MPL was not distributed with this
-- file, You can obtain one at https://mozilla.org/MPL/2.0/.
local client = require("pinnacle.grpc.client").client
local protobuf = require("pinnacle.grpc.protobuf") local protobuf = require("pinnacle.grpc.protobuf")
local layout_service = require("pinnacle.grpc.defs").pinnacle.layout.v0alpha1.LayoutService local layout_service = require("pinnacle.grpc.defs").pinnacle.layout.v0alpha1.LayoutService
@ -979,7 +983,7 @@ local layout = {
--- ---
---@param manager LayoutManager ---@param manager LayoutManager
function layout.set_manager(manager) function layout.set_manager(manager)
layout.stream = client.bidirectional_streaming_request(layout_service.Layout, { layout.stream = client():bidirectional_streaming_request(layout_service.Layout, {
layout = {}, layout = {},
}, function(response, stream) }, function(response, stream)
local request_id = response.request_id local request_id = response.request_id

View file

@ -2,7 +2,7 @@
-- License, v. 2.0. If a copy of the MPL was not distributed with this -- License, v. 2.0. If a copy of the MPL was not distributed with this
-- file, You can obtain one at https://mozilla.org/MPL/2.0/. -- file, You can obtain one at https://mozilla.org/MPL/2.0/.
local client = require("pinnacle.grpc.client") local client = require("pinnacle.grpc.client").client
local output_service = require("pinnacle.grpc.defs").pinnacle.output.v0alpha1.OutputService local output_service = require("pinnacle.grpc.defs").pinnacle.output.v0alpha1.OutputService
---@nodoc ---@nodoc
@ -40,7 +40,7 @@ output.handle = output_handle
--- ---
---@return OutputHandle[] ---@return OutputHandle[]
function output.get_all() function output.get_all()
local response = client.unary_request(output_service.Get, {}) local response = client():unary_request(output_service.Get, {})
---@type OutputHandle[] ---@type OutputHandle[]
local handles = {} local handles = {}
@ -690,7 +690,7 @@ end
--- ---
---@see OutputHandle.set_loc_adj_to ---@see OutputHandle.set_loc_adj_to
function OutputHandle:set_location(loc) function OutputHandle:set_location(loc)
client.unary_request(output_service.SetLocation, { client():unary_request(output_service.SetLocation, {
output_name = self.name, output_name = self.name,
x = loc.x, x = loc.x,
y = loc.y, y = loc.y,
@ -827,7 +827,7 @@ end
---@param pixel_height integer ---@param pixel_height integer
---@param refresh_rate_millihz integer? ---@param refresh_rate_millihz integer?
function OutputHandle:set_mode(pixel_width, pixel_height, refresh_rate_millihz) function OutputHandle:set_mode(pixel_width, pixel_height, refresh_rate_millihz)
client.unary_request(output_service.SetMode, { client():unary_request(output_service.SetMode, {
output_name = self.name, output_name = self.name,
pixel_width = pixel_width, pixel_width = pixel_width,
pixel_height = pixel_height, pixel_height = pixel_height,
@ -880,21 +880,21 @@ function OutputHandle:set_modeline(modeline)
vsync_pos = modeline.vsync, vsync_pos = modeline.vsync,
} }
client.unary_request(output_service.SetModeline, request) client():unary_request(output_service.SetModeline, request)
end end
---Set this output's scaling factor. ---Set this output's scaling factor.
--- ---
---@param scale number ---@param scale number
function OutputHandle:set_scale(scale) function OutputHandle:set_scale(scale)
client.unary_request(output_service.SetScale, { output_name = self.name, absolute = scale }) client():unary_request(output_service.SetScale, { output_name = self.name, absolute = scale })
end end
---Increase this output's scaling factor. ---Increase this output's scaling factor.
--- ---
---@param increase_by number ---@param increase_by number
function OutputHandle:increase_scale(increase_by) function OutputHandle:increase_scale(increase_by)
client.unary_request( client():unary_request(
output_service.SetScale, output_service.SetScale,
{ output_name = self.name, relative = increase_by } { output_name = self.name, relative = increase_by }
) )
@ -934,7 +934,7 @@ local transform_code_to_name = {
--- ---
---@param transform Transform ---@param transform Transform
function OutputHandle:set_transform(transform) function OutputHandle:set_transform(transform)
client.unary_request( client():unary_request(
output_service.SetTransform, output_service.SetTransform,
{ output_name = self.name, transform = transform_name_to_code[transform] } { output_name = self.name, transform = transform_name_to_code[transform] }
) )
@ -944,7 +944,10 @@ end
--- ---
---@param powered boolean ---@param powered boolean
function OutputHandle:set_powered(powered) function OutputHandle:set_powered(powered)
client.unary_request(output_service.SetPowered, { output_name = self.name, powered = powered }) client():unary_request(
output_service.SetPowered,
{ output_name = self.name, powered = powered }
)
end end
---@class Mode ---@class Mode
@ -978,7 +981,8 @@ end
---@return OutputProperties ---@return OutputProperties
function OutputHandle:props() function OutputHandle:props()
---@type pinnacle.output.v0alpha1.GetPropertiesResponse ---@type pinnacle.output.v0alpha1.GetPropertiesResponse
local response = client.unary_request(output_service.GetProperties, { output_name = self.name }) local response =
client():unary_request(output_service.GetProperties, { output_name = self.name })
---@diagnostic disable-next-line: invisible ---@diagnostic disable-next-line: invisible
local tag_handles = require("pinnacle.tag").handle.new_from_table(response.tag_ids or {}) local tag_handles = require("pinnacle.tag").handle.new_from_table(response.tag_ids or {})

View file

@ -2,7 +2,7 @@
-- License, v. 2.0. If a copy of the MPL was not distributed with this -- License, v. 2.0. If a copy of the MPL was not distributed with this
-- file, You can obtain one at https://mozilla.org/MPL/2.0/. -- file, You can obtain one at https://mozilla.org/MPL/2.0/.
local client = require("pinnacle.grpc.client") local client = require("pinnacle.grpc.client").client
local process_service = require("pinnacle.grpc.defs").pinnacle.process.v0alpha1.ProcessService local process_service = require("pinnacle.grpc.defs").pinnacle.process.v0alpha1.ProcessService
---Process management. ---Process management.
@ -31,7 +31,7 @@ local function spawn_inner(args, callbacks, once)
end end
end end
client.server_streaming_request(process_service.Spawn, { client():server_streaming_request(process_service.Spawn, {
args = args, args = args,
once = once, once = once,
has_callback = callbacks ~= nil, has_callback = callbacks ~= nil,
@ -106,7 +106,7 @@ end
---@param key string The environment variable key ---@param key string The environment variable key
---@param value string The environment variable value ---@param value string The environment variable value
function process.set_env(key, value) function process.set_env(key, value)
client.unary_request(process_service.SetEnv, { client():unary_request(process_service.SetEnv, {
key = key, key = key,
value = value, value = value,
}) })

View file

@ -2,7 +2,7 @@
-- License, v. 2.0. If a copy of the MPL was not distributed with this -- License, v. 2.0. If a copy of the MPL was not distributed with this
-- file, You can obtain one at https://mozilla.org/MPL/2.0/. -- file, You can obtain one at https://mozilla.org/MPL/2.0/.
local client = require("pinnacle.grpc.client") local client = require("pinnacle.grpc.client").client
local render_service = require("pinnacle.grpc.defs").pinnacle.render.v0alpha1.RenderService local render_service = require("pinnacle.grpc.defs").pinnacle.render.v0alpha1.RenderService
---Rendering management. ---Rendering management.
@ -24,7 +24,7 @@ local filter_name_to_filter_value = {
--- ---
---@param filter ScalingFilter ---@param filter ScalingFilter
function render.set_upscale_filter(filter) function render.set_upscale_filter(filter)
client.unary_request( client():unary_request(
render_service.SetUpscaleFilter, render_service.SetUpscaleFilter,
{ filter = filter_name_to_filter_value[filter] } { filter = filter_name_to_filter_value[filter] }
) )
@ -34,7 +34,7 @@ end
--- ---
---@param filter ScalingFilter ---@param filter ScalingFilter
function render.set_downscale_filter(filter) function render.set_downscale_filter(filter)
client.unary_request( client():unary_request(
render_service.SetDownscaleFilter, render_service.SetDownscaleFilter,
{ filter = filter_name_to_filter_value[filter] } { filter = filter_name_to_filter_value[filter] }
) )

View file

@ -2,7 +2,7 @@
-- License, v. 2.0. If a copy of the MPL was not distributed with this -- License, v. 2.0. If a copy of the MPL was not distributed with this
-- file, You can obtain one at https://mozilla.org/MPL/2.0/. -- file, You can obtain one at https://mozilla.org/MPL/2.0/.
local client = require("pinnacle.grpc.client") local client = require("pinnacle.grpc.client").client
local signal_service = require("pinnacle.grpc.defs").pinnacle.signal.v0alpha1.SignalService local signal_service = require("pinnacle.grpc.defs").pinnacle.signal.v0alpha1.SignalService
local stream_control = { local stream_control = {
@ -250,7 +250,7 @@ end
---@param request SignalServiceMethod ---@param request SignalServiceMethod
---@param callback fun(response: table) ---@param callback fun(response: table)
function signal.connect(request, callback) function signal.connect(request, callback)
local stream = client.bidirectional_streaming_request(signal_service[request], { local stream = client():bidirectional_streaming_request(signal_service[request], {
control = stream_control.READY, control = stream_control.READY,
}, function(response) }, function(response)
callback(response) callback(response)

View file

@ -2,7 +2,7 @@
-- License, v. 2.0. If a copy of the MPL was not distributed with this -- License, v. 2.0. If a copy of the MPL was not distributed with this
-- file, You can obtain one at https://mozilla.org/MPL/2.0/. -- file, You can obtain one at https://mozilla.org/MPL/2.0/.
local client = require("pinnacle.grpc.client") local client = require("pinnacle.grpc.client").client
local tag_service = require("pinnacle.grpc.defs").pinnacle.tag.v0alpha1.TagService local tag_service = require("pinnacle.grpc.defs").pinnacle.tag.v0alpha1.TagService
local set_or_toggle = { local set_or_toggle = {
@ -51,7 +51,7 @@ tag.handle = tag_handle
--- ---
---@return TagHandle[] ---@return TagHandle[]
function tag.get_all() function tag.get_all()
local response = client.unary_request(tag_service.Get, {}) local response = client():unary_request(tag_service.Get, {})
---@type TagHandle[] ---@type TagHandle[]
local handles = {} local handles = {}
@ -136,7 +136,7 @@ function tag.add(output, ...)
tag_names = tag_names[1] --[=[@as string[]]=] tag_names = tag_names[1] --[=[@as string[]]=]
end end
local response = client.unary_request(tag_service.Add, { local response = client():unary_request(tag_service.Add, {
output_name = output.name, output_name = output.name,
tag_names = tag_names, tag_names = tag_names,
}) })
@ -169,7 +169,7 @@ function tag.remove(tags)
table.insert(ids, tg.id) table.insert(ids, tg.id)
end end
client.unary_request(tag_service.Remove, { tag_ids = ids }) client():unary_request(tag_service.Remove, { tag_ids = ids })
end end
---@type table<string, SignalServiceMethod> ---@type table<string, SignalServiceMethod>
@ -245,7 +245,7 @@ end
---Tag.get("3"):switch_to() -- Displays Steam ---Tag.get("3"):switch_to() -- Displays Steam
---``` ---```
function TagHandle:switch_to() function TagHandle:switch_to()
client.unary_request(tag_service.SwitchTo, { tag_id = self.id }) client():unary_request(tag_service.SwitchTo, { tag_id = self.id })
end end
---Set whether or not this tag is active. ---Set whether or not this tag is active.
@ -263,7 +263,7 @@ end
--- ---
---@param active boolean ---@param active boolean
function TagHandle:set_active(active) function TagHandle:set_active(active)
client.unary_request( client():unary_request(
tag_service.SetActive, tag_service.SetActive,
{ tag_id = self.id, set_or_toggle = set_or_toggle[active] } { tag_id = self.id, set_or_toggle = set_or_toggle[active] }
) )
@ -281,7 +281,7 @@ end
---Tag.get("2"):toggle_active() -- Displays nothing ---Tag.get("2"):toggle_active() -- Displays nothing
---``` ---```
function TagHandle:toggle_active() function TagHandle:toggle_active()
client.unary_request( client():unary_request(
tag_service.SetActive, tag_service.SetActive,
{ tag_id = self.id, set_or_toggle = set_or_toggle.TOGGLE } { tag_id = self.id, set_or_toggle = set_or_toggle.TOGGLE }
) )
@ -297,7 +297,7 @@ end
--- ---
---@return TagProperties ---@return TagProperties
function TagHandle:props() function TagHandle:props()
local response = client.unary_request(tag_service.GetProperties, { tag_id = self.id }) local response = client():unary_request(tag_service.GetProperties, { tag_id = self.id })
return { return {
active = response.active, active = response.active,

View file

@ -2,7 +2,7 @@
-- License, v. 2.0. If a copy of the MPL was not distributed with this -- License, v. 2.0. If a copy of the MPL was not distributed with this
-- file, You can obtain one at https://mozilla.org/MPL/2.0/. -- file, You can obtain one at https://mozilla.org/MPL/2.0/.
local client = require("pinnacle.grpc.client") local client = require("pinnacle.grpc.client").client
local window_service = require("pinnacle.grpc.defs").pinnacle.window.v0alpha1.WindowService local window_service = require("pinnacle.grpc.defs").pinnacle.window.v0alpha1.WindowService
local set_or_toggle = { local set_or_toggle = {
@ -50,7 +50,7 @@ window.handle = window_handle
---``` ---```
---@return WindowHandle[] windows Handles to all windows ---@return WindowHandle[] windows Handles to all windows
function window.get_all() function window.get_all()
local response = client.unary_request(window_service.Get, {}) local response = client():unary_request(window_service.Get, {})
local handles = window_handle.new_from_table(response.window_ids or {}) local handles = window_handle.new_from_table(response.window_ids or {})
@ -105,7 +105,7 @@ end
function window.begin_move(button) function window.begin_move(button)
---@diagnostic disable-next-line: redefined-local, invisible ---@diagnostic disable-next-line: redefined-local, invisible
local button = require("pinnacle.input").mouse_button_values[button] local button = require("pinnacle.input").mouse_button_values[button]
client.unary_request(window_service.MoveGrab, { button = button }) client():unary_request(window_service.MoveGrab, { button = button })
end end
---Begin resizing this window using the specified mouse button. ---Begin resizing this window using the specified mouse button.
@ -123,7 +123,7 @@ end
function window.begin_resize(button) function window.begin_resize(button)
---@diagnostic disable-next-line: redefined-local, invisible ---@diagnostic disable-next-line: redefined-local, invisible
local button = require("pinnacle.input").mouse_button_values[button] local button = require("pinnacle.input").mouse_button_values[button]
client.unary_request(window_service.ResizeGrab, { button = button }) client():unary_request(window_service.ResizeGrab, { button = button })
end end
---@class WindowRuleCondition ---@class WindowRuleCondition
@ -328,7 +328,7 @@ function window.add_window_rule(rule)
process_window_rule_cond(rule.cond) process_window_rule_cond(rule.cond)
client.unary_request(window_service.AddWindowRule, { client():unary_request(window_service.AddWindowRule, {
cond = rule.cond, cond = rule.cond,
rule = rule.rule, rule = rule.rule,
}) })
@ -390,7 +390,7 @@ end
---if focused then focused:close() end ---if focused then focused:close() end
---``` ---```
function WindowHandle:close() function WindowHandle:close()
client.unary_request(window_service.Close, { window_id = self.id }) client():unary_request(window_service.Close, { window_id = self.id })
end end
---Set this window's location and/or size. ---Set this window's location and/or size.
@ -420,7 +420,7 @@ end
---``` ---```
---@param geo { x: integer?, y: integer?, width: integer?, height: integer? } The new location and/or size ---@param geo { x: integer?, y: integer?, width: integer?, height: integer? } The new location and/or size
function WindowHandle:set_geometry(geo) function WindowHandle:set_geometry(geo)
client.unary_request(window_service.SetGeometry, { window_id = self.id, geometry = geo }) client():unary_request(window_service.SetGeometry, { window_id = self.id, geometry = geo })
end end
---Set this window to fullscreen or not. ---Set this window to fullscreen or not.
@ -436,7 +436,7 @@ end
--- ---
---@param fullscreen boolean ---@param fullscreen boolean
function WindowHandle:set_fullscreen(fullscreen) function WindowHandle:set_fullscreen(fullscreen)
client.unary_request( client():unary_request(
window_service.SetFullscreen, window_service.SetFullscreen,
{ window_id = self.id, set_or_toggle = set_or_toggle[fullscreen] } { window_id = self.id, set_or_toggle = set_or_toggle[fullscreen] }
) )
@ -452,7 +452,7 @@ end
---end ---end
---``` ---```
function WindowHandle:toggle_fullscreen() function WindowHandle:toggle_fullscreen()
client.unary_request( client():unary_request(
window_service.SetFullscreen, window_service.SetFullscreen,
{ window_id = self.id, set_or_toggle = set_or_toggle.TOGGLE } { window_id = self.id, set_or_toggle = set_or_toggle.TOGGLE }
) )
@ -471,7 +471,7 @@ end
--- ---
---@param maximized boolean ---@param maximized boolean
function WindowHandle:set_maximized(maximized) function WindowHandle:set_maximized(maximized)
client.unary_request( client():unary_request(
window_service.SetMaximized, window_service.SetMaximized,
{ window_id = self.id, set_or_toggle = set_or_toggle[maximized] } { window_id = self.id, set_or_toggle = set_or_toggle[maximized] }
) )
@ -487,7 +487,7 @@ end
---end ---end
---``` ---```
function WindowHandle:toggle_maximized() function WindowHandle:toggle_maximized()
client.unary_request( client():unary_request(
window_service.SetMaximized, window_service.SetMaximized,
{ window_id = self.id, set_or_toggle = set_or_toggle.TOGGLE } { window_id = self.id, set_or_toggle = set_or_toggle.TOGGLE }
) )
@ -506,7 +506,7 @@ end
--- ---
---@param floating boolean ---@param floating boolean
function WindowHandle:set_floating(floating) function WindowHandle:set_floating(floating)
client.unary_request( client():unary_request(
window_service.SetFloating, window_service.SetFloating,
{ window_id = self.id, set_or_toggle = set_or_toggle[floating] } { window_id = self.id, set_or_toggle = set_or_toggle[floating] }
) )
@ -522,7 +522,7 @@ end
---end ---end
---``` ---```
function WindowHandle:toggle_floating() function WindowHandle:toggle_floating()
client.unary_request( client():unary_request(
window_service.SetFloating, window_service.SetFloating,
{ window_id = self.id, set_or_toggle = set_or_toggle.TOGGLE } { window_id = self.id, set_or_toggle = set_or_toggle.TOGGLE }
) )
@ -540,7 +540,7 @@ end
--- ---
---@param focused boolean ---@param focused boolean
function WindowHandle:set_focused(focused) function WindowHandle:set_focused(focused)
client.unary_request( client():unary_request(
window_service.SetFocused, window_service.SetFocused,
{ window_id = self.id, set_or_toggle = set_or_toggle[focused] } { window_id = self.id, set_or_toggle = set_or_toggle[focused] }
) )
@ -556,7 +556,7 @@ end
---end ---end
---``` ---```
function WindowHandle:toggle_focused() function WindowHandle:toggle_focused()
client.unary_request( client():unary_request(
window_service.SetFocused, window_service.SetFocused,
{ window_id = self.id, set_or_toggle = set_or_toggle.TOGGLE } { window_id = self.id, set_or_toggle = set_or_toggle.TOGGLE }
) )
@ -577,7 +577,7 @@ end
--- ---
---@param tag TagHandle The tag to move this window to ---@param tag TagHandle The tag to move this window to
function WindowHandle:move_to_tag(tag) function WindowHandle:move_to_tag(tag)
client.unary_request(window_service.MoveToTag, { window_id = self.id, tag_id = tag.id }) client():unary_request(window_service.MoveToTag, { window_id = self.id, tag_id = tag.id })
end end
---Tag or untag the given tag on this window. ---Tag or untag the given tag on this window.
@ -599,7 +599,7 @@ end
---@param tag TagHandle The tag to set or unset ---@param tag TagHandle The tag to set or unset
---@param set boolean ---@param set boolean
function WindowHandle:set_tag(tag, set) function WindowHandle:set_tag(tag, set)
client.unary_request( client():unary_request(
window_service.SetTag, window_service.SetTag,
{ window_id = self.id, tag_id = tag.id, set_or_toggle = set_or_toggle[set] } { window_id = self.id, tag_id = tag.id, set_or_toggle = set_or_toggle[set] }
) )
@ -624,7 +624,7 @@ end
--- ---
---@param tag TagHandle The tag to toggle ---@param tag TagHandle The tag to toggle
function WindowHandle:toggle_tag(tag) function WindowHandle:toggle_tag(tag)
client.unary_request( client():unary_request(
window_service.SetTag, window_service.SetTag,
{ window_id = self.id, tag_id = tag.id, set_or_toggle = set_or_toggle.TOGGLE } { window_id = self.id, tag_id = tag.id, set_or_toggle = set_or_toggle.TOGGLE }
) )
@ -642,7 +642,7 @@ end
---end ---end
---``` ---```
function WindowHandle:raise() function WindowHandle:raise()
client.unary_request(window_service.Raise, { window_id = self.id }) client():unary_request(window_service.Raise, { window_id = self.id })
end end
---Returns whether or not this window is on an active tag. ---Returns whether or not this window is on an active tag.
@ -685,7 +685,7 @@ end
--- ---
---@return WindowProperties ---@return WindowProperties
function WindowHandle:props() function WindowHandle:props()
local response = client.unary_request(window_service.GetProperties, { window_id = self.id }) local response = client():unary_request(window_service.GetProperties, { window_id = self.id })
response.fullscreen_or_maximized = response.fullscreen_or_maximized =
_fullscreen_or_maximized_keys[response.fullscreen_or_maximized] _fullscreen_or_maximized_keys[response.fullscreen_or_maximized]

View file

@ -38,12 +38,14 @@ install-protos:
install-lua-lib: gen-lua-pb-defs install-lua-lib: gen-lua-pb-defs
#!/usr/bin/env bash #!/usr/bin/env bash
cd "{{rootdir}}/api/lua" cd "{{rootdir}}/api/lua"
luarocks make --local --lua-version "{{lua_version}}" luarocks build --local https://raw.githubusercontent.com/pinnacle-comp/lua-grpc-client/main/lua-grpc-client-dev-1.rockspec
luarocks build --local --lua-version "{{lua_version}}"
# Remove installed configs and the Lua API (requires Luarocks) # Remove installed configs and the Lua API (requires Luarocks)
clean: clean-snowcap clean: clean-snowcap
rm -rf "{{xdg_data_dir}}" rm -rf "{{xdg_data_dir}}"
-luarocks remove --local pinnacle-api -luarocks remove --local pinnacle-api
-luarocks remove --local lua-grpc-client
# [root] Remove installed configs and the Lua API (requires Luarocks) # [root] Remove installed configs and the Lua API (requires Luarocks)
clean-root: clean-root:

@ -1 +1 @@
Subproject commit b217d37fbf88b07c03632a1a86ac568f84b3040c Subproject commit 3783530a00124f1c1ba9ebaccb413a3d3e18ef1b