mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2024-12-25 09:59:21 +01:00
154 lines
4.7 KiB
Lua
154 lines
4.7 KiB
Lua
-- 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 log = require("pinnacle.log")
|
|
local client = require("pinnacle.grpc.client").client
|
|
local pinnacle_service = require("pinnacle.grpc.defs").pinnacle.v0alpha1.PinnacleService
|
|
|
|
---The entry point to configuration.
|
|
---
|
|
---This module contains the `setup` function, which is how you'll access all the ways to configure Pinnacle.
|
|
---@class Pinnacle
|
|
local pinnacle = {
|
|
---@type Input
|
|
input = require("pinnacle.input"),
|
|
---@type Tag
|
|
tag = require("pinnacle.tag"),
|
|
---@type Output
|
|
output = require("pinnacle.output"),
|
|
---@type Window
|
|
window = require("pinnacle.window"),
|
|
---@type Process
|
|
process = require("pinnacle.process"),
|
|
---@type Util
|
|
util = require("pinnacle.util"),
|
|
---@type Layout
|
|
layout = require("pinnacle.layout"),
|
|
---@type Render
|
|
render = require("pinnacle.render"),
|
|
---@type pinnacle.Snowcap
|
|
snowcap = nil,
|
|
}
|
|
|
|
---Quit Pinnacle.
|
|
function pinnacle.quit()
|
|
local _, err = client:unary_request(pinnacle_service.Quit, {})
|
|
|
|
if err then
|
|
log:error(err)
|
|
end
|
|
end
|
|
|
|
---Reload the active config.
|
|
function pinnacle.reload_config()
|
|
local _, err = client:unary_request(pinnacle_service.ReloadConfig, {})
|
|
|
|
if err then
|
|
log:error(err)
|
|
end
|
|
end
|
|
|
|
---Gets the currently running backend.
|
|
---
|
|
---@return "tty" | "window" `"tty"` if Pinnacle is running in a tty, or `"window"` if it's running in a nested window
|
|
function pinnacle.backend()
|
|
local response, err = client:unary_request(pinnacle_service.Backend, {})
|
|
|
|
if err then
|
|
log:error(err)
|
|
-- TODO: possibly panic here; a nil index error will be thrown after this anyway
|
|
end
|
|
|
|
---@cast response pinnacle.v0alpha1.BackendResponse
|
|
|
|
local defs = require("pinnacle.grpc.defs")
|
|
|
|
if response.backend == defs.pinnacle.v0alpha1.Backend.BACKEND_WINDOW then
|
|
return "window"
|
|
else
|
|
return "tty"
|
|
end
|
|
end
|
|
|
|
---Initializes the protobuf backend and connects to Pinnacle's gRPC socket.
|
|
---
|
|
---If the Snowcap Lua API is installed and Snowcap is running, this will also setup Snowcap and
|
|
---connect to its socket as well.
|
|
function pinnacle.init()
|
|
require("pinnacle.grpc.protobuf").build_protos()
|
|
|
|
require("pinnacle.grpc.client").connect()
|
|
|
|
local success, snowcap = pcall(require, "snowcap")
|
|
if success then
|
|
if pcall(snowcap.init) then
|
|
pinnacle.snowcap = require("pinnacle.snowcap")
|
|
|
|
-- Make Snowcap use Pinnacle's cqueues loop
|
|
require("snowcap.grpc.client").client.loop = client.loop
|
|
end
|
|
end
|
|
end
|
|
|
|
---Setup a Pinnacle config.
|
|
---
|
|
---You must pass in a function that takes in the `Pinnacle` table. This table is how you'll access the other config modules.
|
|
---
|
|
---You can also `require` the other modules. Just be sure not to call any of their functions outside this
|
|
---setup function.
|
|
---
|
|
---If you want to run a function with the config without blocking at the end, see `Pinnacle.run`.
|
|
---
|
|
---@param config_fn fun(pinnacle: Pinnacle)
|
|
---
|
|
---@see Pinnacle.run
|
|
function pinnacle.setup(config_fn)
|
|
pinnacle.init()
|
|
|
|
-- This function ensures a config won't run forever if Pinnacle is killed
|
|
-- and doesn't kill configs on drop.
|
|
client.loop:wrap(function()
|
|
while true do
|
|
require("cqueues").sleep(60)
|
|
local success, err, errno = client.conn:ping(10)
|
|
if not success then
|
|
error(
|
|
"compositor ping failed: err = "
|
|
.. tostring(err)
|
|
.. ", errno = "
|
|
.. tostring(errno)
|
|
)
|
|
end
|
|
end
|
|
end)
|
|
|
|
config_fn(pinnacle)
|
|
|
|
local success, err = client.loop:loop()
|
|
if not success then
|
|
error("loop errored: " .. tostring(err))
|
|
end
|
|
end
|
|
|
|
---Run a function with the Pinnacle API.
|
|
---
|
|
---If you are writing a config, use `Pinnacle.setup` instead.
|
|
---
|
|
---Like `Pinnacle.setup`, this function takes in a function that takes in the `Pinnacle` table.
|
|
---This allows you to run anything that `setup` can run.
|
|
---
|
|
---*Unlike* `setup`, this will **not** listen to the compositor for incoming key presses, signals, and the like.
|
|
---This means that this function will not block and can be used to integrate with external applications
|
|
---like taskbars and widget systems like eww, but it will not allow you to set usable keybinds or
|
|
---call signal callbacks. This is useful for things like querying compositor information for outputs and
|
|
---windows.
|
|
---
|
|
---@param run_fn fun(pinnacle: Pinnacle)
|
|
function pinnacle.run(run_fn)
|
|
pinnacle.init()
|
|
|
|
run_fn(pinnacle)
|
|
end
|
|
|
|
return pinnacle
|