diff --git a/api/lua/examples/default/default_config.lua b/api/lua/examples/default/default_config.lua index 9a8b63a..28427d8 100644 --- a/api/lua/examples/default/default_config.lua +++ b/api/lua/examples/default/default_config.lua @@ -16,12 +16,12 @@ require("pinnacle").setup(function(Pinnacle) -- Mousebinds -- -------------------- - Input:mousebind({ mod_key }, "btn_left", "press", function() - Window:begin_move("btn_left") + Input.mousebind({ mod_key }, "btn_left", "press", function() + Window.begin_move("btn_left") end) - Input:mousebind({ mod_key }, "btn_right", "press", function() - Window:begin_resize("btn_right") + Input.mousebind({ mod_key }, "btn_right", "press", function() + Window.begin_resize("btn_right") end) -------------------- @@ -29,42 +29,42 @@ require("pinnacle").setup(function(Pinnacle) -------------------- -- mod_key + alt + q = Quit Pinnacle - Input:keybind({ mod_key, "alt" }, "q", function() - Pinnacle:quit() + Input.keybind({ mod_key, "alt" }, "q", function() + Pinnacle.quit() end) -- mod_key + alt + c = Close window - Input:keybind({ mod_key, "alt" }, "c", function() - local focused = Window:get_focused() + Input.keybind({ mod_key, "alt" }, "c", function() + local focused = Window.get_focused() if focused then focused:close() end end) -- mod_key + alt + Return = Spawn `terminal` - Input:keybind({ mod_key }, key.Return, function() - Process:spawn(terminal) + Input.keybind({ mod_key }, key.Return, function() + Process.spawn(terminal) end) -- mod_key + alt + space = Toggle floating - Input:keybind({ mod_key, "alt" }, key.space, function() - local focused = Window:get_focused() + Input.keybind({ mod_key, "alt" }, key.space, function() + local focused = Window.get_focused() if focused then focused:toggle_floating() end end) -- mod_key + f = Toggle fullscreen - Input:keybind({ mod_key }, "f", function() - local focused = Window:get_focused() + Input.keybind({ mod_key }, "f", function() + local focused = Window.get_focused() if focused then focused:toggle_fullscreen() end end) -- mod_key + m = Toggle maximized - Input:keybind({ mod_key }, "m", function() - local focused = Window:get_focused() + Input.keybind({ mod_key }, "m", function() + local focused = Window.get_focused() if focused then focused:toggle_maximized() end @@ -78,16 +78,16 @@ require("pinnacle").setup(function(Pinnacle) -- `connect_for_all` is useful for performing setup on every monitor you have. -- Here, we add tags with names 1-5 and set tag 1 as active. - Output:connect_for_all(function(op) - local tags = Tag:add(op, tag_names) + Output.connect_for_all(function(op) + local tags = Tag.add(op, tag_names) tags[1]:set_active(true) end) -- Spawning must happen after you add tags, as Pinnacle currently doesn't render windows without tags. - Process:spawn_once(terminal) + Process.spawn_once(terminal) -- Create a layout cycler to cycle layouts on an output. - local layout_cycler = Tag:new_layout_cycler({ + local layout_cycler = Tag.new_layout_cycler({ "master_stack", "dwindle", "spiral", @@ -98,16 +98,16 @@ require("pinnacle").setup(function(Pinnacle) }) -- mod_key + space = Cycle forward one layout on the focused output - Input:keybind({ mod_key }, key.space, function() - local focused_op = Output:get_focused() + Input.keybind({ mod_key }, key.space, function() + local focused_op = Output.get_focused() if focused_op then layout_cycler.next(focused_op) end end) -- mod_key + shift + space = Cycle backward one layout on the focused output - Input:keybind({ mod_key, "shift" }, key.space, function() - local focused_op = Output:get_focused() + Input.keybind({ mod_key, "shift" }, key.space, function() + local focused_op = Output.get_focused() if focused_op then layout_cycler.prev(focused_op) end @@ -117,28 +117,28 @@ require("pinnacle").setup(function(Pinnacle) -- nil-safety: tags are guaranteed to be on the outputs due to connect_for_all above -- mod_key + 1-5 = Switch to tags 1-5 - Input:keybind({ mod_key }, tag_name, function() - Tag:get(tag_name):switch_to() + Input.keybind({ mod_key }, tag_name, function() + Tag.get(tag_name):switch_to() end) -- mod_key + shift + 1-5 = Toggle tags 1-5 - Input:keybind({ mod_key, "shift" }, tag_name, function() - Tag:get(tag_name):toggle_active() + Input.keybind({ mod_key, "shift" }, tag_name, function() + Tag.get(tag_name):toggle_active() end) -- mod_key + alt + 1-5 = Move window to tags 1-5 - Input:keybind({ mod_key, "alt" }, tag_name, function() - local focused = Window:get_focused() + Input.keybind({ mod_key, "alt" }, tag_name, function() + local focused = Window.get_focused() if focused then - focused:move_to_tag(Tag:get(tag_name) --[[@as TagHandle]]) + focused:move_to_tag(Tag.get(tag_name) --[[@as TagHandle]]) end end) -- mod_key + shift + alt + 1-5 = Toggle tags 1-5 on window - Input:keybind({ mod_key, "shift", "alt" }, tag_name, function() - local focused = Window:get_focused() + Input.keybind({ mod_key, "shift", "alt" }, tag_name, function() + local focused = Window.get_focused() if focused then - focused:toggle_tag(Tag:get(tag_name) --[[@as TagHandle]]) + focused:toggle_tag(Tag.get(tag_name) --[[@as TagHandle]]) end end) end diff --git a/api/lua/pinnacle.lua b/api/lua/pinnacle.lua index 6f74b46..249bcd4 100644 --- a/api/lua/pinnacle.lua +++ b/api/lua/pinnacle.lua @@ -2,34 +2,28 @@ -- 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 cqueues = require("cqueues") - local client = require("pinnacle.grpc.client") ---The entry point to configuration. --- ---This module contains one function: `setup`, which is how you'll access all the ways to configure Pinnacle. ----@class PinnacleModule +---@class Pinnacle local pinnacle = { - version = "v0alpha1", + ---@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"), } ----The Pinnacle module. ---- ----This module holds all the other configuration modules (Window, Input, etc.), and allows you to ----quit the compositor using the `quit` method. ----@class Pinnacle ----@field private config_client Client ----@field input Input ----@field output Output ----@field process Process ----@field tag Tag ----@field window Window -local Pinnacle = {} - ---Quit Pinnacle. -function Pinnacle:quit() - self.config_client:unary_request({ +function pinnacle.quit() + client.unary_request({ service = "pinnacle.v0alpha1.PinnacleService", method = "Quit", request_type = "pinnacle.v0alpha1.QuitRequest", @@ -39,36 +33,18 @@ end ---Setup Pinnacle. --- ----You must pass in a function that takes in the `Pinnacle` module object. The module is how you'll access the other config modules. +---You must pass in a function that takes in the `Pinnacle` table. This table is how you'll access the other config modules. --- ----Note: All the config modules are object instantiations, and their methods require you to use the colon operator ----instead of the dot operator to call them. ---- ----If you want to do a multi-file config, you should have other files return a function taking in necessary modules. ----Or you could cheat and stick the modules into globals :TrollFace: +---You can also `require` the other modules. Just be sure not to call any of their functions outside this +---setup function. --- ---@param config_fn fun(pinnacle: Pinnacle) function pinnacle.setup(config_fn) require("pinnacle.grpc.protobuf").build_protos() - local loop = cqueues.new() + config_fn(pinnacle) - local config_client = client.new(loop) - - ---@type Pinnacle - local self = { - config_client = config_client, - input = require("pinnacle.input").new(config_client), - process = require("pinnacle.process").new(config_client), - window = require("pinnacle.window").new(config_client), - output = require("pinnacle.output").new(config_client), - tag = require("pinnacle.tag").new(config_client), - } - setmetatable(self, { __index = Pinnacle }) - - config_fn(self) - - loop:loop() + client.loop:loop() end return pinnacle diff --git a/api/lua/pinnacle/grpc/client.lua b/api/lua/pinnacle/grpc/client.lua index 96d7465..7f45105 100644 --- a/api/lua/pinnacle/grpc/client.lua +++ b/api/lua/pinnacle/grpc/client.lua @@ -22,15 +22,27 @@ local function create_request_headers(service, method) return req_headers end ----@nodoc ----@class ClientModule -local client = {} +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 ---@nodoc ---@class Client ---@field conn H2Connection ---@field loop CqueuesLoop -local Client = {} +local client = { + conn = new_conn(), + loop = require("cqueues").new(), + version = "v0alpha1", +} ---@class GrpcRequestParams ---@field service string @@ -49,8 +61,8 @@ local Client = {} ---`google.protobuf.Empty`. ---@param grpc_request_params GrpcRequestParams ---@return table -function Client:unary_request(grpc_request_params) - local stream = self.conn:new_stream() +function client.unary_request(grpc_request_params) + local stream = client.conn:new_stream() local service = grpc_request_params.service local method = grpc_request_params.method @@ -98,8 +110,8 @@ end ---`google.protobuf.Empty`. ---@param grpc_request_params GrpcRequestParams ---@param callback fun(response: table) -function Client:server_streaming_request(grpc_request_params, callback) - local stream = self.conn:new_stream() +function client.server_streaming_request(grpc_request_params, callback) + local stream = client.conn:new_stream() local service = grpc_request_params.service local method = grpc_request_params.method @@ -126,7 +138,7 @@ function Client:server_streaming_request(grpc_request_params, callback) local response_headers = stream:get_headers() -- TODO: check headers for errors - self.loop:wrap(function() + client.loop:wrap(function() for response_body in stream:each_chunk() do -- Skip the 1-byte compressed flag and the 4-byte message length local response_body = response_body:sub(6) @@ -150,25 +162,4 @@ function Client:server_streaming_request(grpc_request_params, callback) end) end ----@nodoc ----@return Client -function client.new(loop) - local sock = socket.connect({ - path = os.getenv("PINNACLE_GRPC_SOCKET"), - }) - sock:connect() - - local conn = h2_connection.new(sock, "client") - conn:connect() - - ---@type Client - local self = { - conn = conn, - loop = loop, - } - setmetatable(self, { __index = Client }) - - return self -end - return client diff --git a/api/lua/pinnacle/input.lua b/api/lua/pinnacle/input.lua index ad06fba..c30db6d 100644 --- a/api/lua/pinnacle/input.lua +++ b/api/lua/pinnacle/input.lua @@ -2,8 +2,10 @@ -- 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") + ---The protobuf absolute path prefix -local prefix = "pinnacle.input." .. require("pinnacle").version .. "." +local prefix = "pinnacle.input." .. client.version .. "." local service = prefix .. "InputService" ---@type table @@ -97,20 +99,15 @@ local mouse_edge_values = { ---| "press" Trigger on mouse button press ---| "release" Trigger on mouse button release ----@nodoc ----@class InputModule ----@field private btn table -local input = {} -input.btn = mouse_button_values - ---Input management. --- ---This module provides utilities to set key- and mousebinds as well as change keyboard settings. ---@class Input ----@field private config_client Client -local Input = { +---@field private btn table +local input = { key = require("pinnacle.input.keys"), } +input.btn = mouse_button_values ---Set a keybind. If called with an already existing keybind, it gets replaced. --- @@ -127,29 +124,29 @@ local Input = { ---Usually, it's best to use the non-modified key to prevent confusion and unintended behavior. --- ---```lua ----Input:keybind({ "shift" }, "a", function() end) -- This is preferred ----Input:keybind({ "shift" }, "A", function() end) -- over this +---Input.keybind({ "shift" }, "a", function() end) -- This is preferred +---Input.keybind({ "shift" }, "A", function() end) -- over this --- --- -- This keybind will only work with capslock on. ----Input:keybind({}, "A", function() end) +---Input.keybind({}, "A", function() end) --- --- -- This keybind won't work at all because to get `@` you need to hold shift, --- -- which this keybind doesn't accept. ----Input:keybind({ "ctrl" }, "@", function() end) +---Input.keybind({ "ctrl" }, "@", function() end) ---``` --- ---### Example ---```lua --- -- Set `super + Return` to open Alacritty ----Input:keybind({ "super" }, Input.key.Return, function() ---- Process:spawn("alacritty") +---Input.keybind({ "super" }, Input.key.Return, function() +--- Process.spawn("alacritty") ---end) ---``` --- ---@param mods Modifier[] The modifiers that need to be held down for the bind to trigger ---@param key Key | string The key used to trigger the bind ---@param action fun() The function to run when the bind is triggered -function Input:keybind(mods, key, action) +function input.keybind(mods, key, action) local raw_code = nil local xkb_name = nil @@ -164,7 +161,7 @@ function Input:keybind(mods, key, action) table.insert(mod_values, modifier_values[mod]) end - self.config_client:server_streaming_request( + client.server_streaming_request( build_grpc_request_params("SetKeybind", { modifiers = mod_values, raw_code = raw_code, @@ -181,8 +178,8 @@ end ---### Example ---```lua --- -- Set `super + left mouse button` to move a window on press ----Input:mousebind({ "super" }, "btn_left", "press", function() ---- Window:begin_move("btn_left") +---Input.mousebind({ "super" }, "btn_left", "press", function() +--- Window.begin_move("btn_left") ---end) ---``` --- @@ -190,7 +187,7 @@ end ---@param button MouseButton The mouse button used to trigger the bind ---@param edge MouseEdge "press" or "release" to trigger on button press or release ---@param action fun() The function to run when the bind is triggered -function Input:mousebind(mods, button, edge, action) +function input.mousebind(mods, button, edge, action) local edge = mouse_edge_values[edge] local mod_values = {} @@ -198,7 +195,7 @@ function Input:mousebind(mods, button, edge, action) table.insert(mod_values, modifier_values[mod]) end - self.config_client:server_streaming_request( + client.server_streaming_request( build_grpc_request_params("SetMousebind", { modifiers = mod_values, button = mouse_button_values[button], @@ -223,28 +220,28 @@ end --- ---### Example ---```lua ----Input:set_xkb_config({ +---Input.set_xkb_config({ --- layout = "us,fr,ge", --- options = "ctrl:swapcaps,caps:shift" ---}) ---``` --- ---@param xkb_config XkbConfig The new xkbconfig -function Input:set_xkb_config(xkb_config) - self.config_client:unary_request(build_grpc_request_params("SetXkbConfig", xkb_config)) +function input.set_xkb_config(xkb_config) + client.unary_request(build_grpc_request_params("SetXkbConfig", xkb_config)) end ---Set the keyboard's repeat rate and delay. --- ---### Example ---```lua ----Input:set_repeat_rate(100, 1000) -- Key must be held down for 1 second, then repeats 10 times per second. +---Input.set_repeat_rate(100, 1000) -- Key must be held down for 1 second, then repeats 10 times per second. ---``` --- ---@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", { +function input.set_repeat_rate(rate, delay) + client.unary_request(build_grpc_request_params("SetRepeatRate", { rate = rate, delay = delay, })) @@ -308,42 +305,39 @@ local tap_button_map_values = { --- ---This includes settings for pointer devices, like acceleration profiles, natural scroll, and more. --- +---### Example +---```lua +---Input.set_libinput_settings({ +--- accel_profile = "flat", +--- natural_scroll = true, +---}) +---``` +--- ---@param settings LibinputSettings -function Input:set_libinput_settings(settings) +function input.set_libinput_settings(settings) for setting, value in pairs(settings) do if setting == "accel_profile" then - self.config_client:unary_request( + client.unary_request( build_grpc_request_params("SetLibinputSetting", { [setting] = accel_profile_values[value] }) ) elseif setting == "calibration_matrix" then - self.config_client:unary_request( - build_grpc_request_params("SetLibinputSetting", { [setting] = { matrix = value } }) - ) + client.unary_request(build_grpc_request_params("SetLibinputSetting", { [setting] = { matrix = value } })) elseif setting == "click_method" then - self.config_client:unary_request( + client.unary_request( build_grpc_request_params("SetLibinputSetting", { [setting] = click_method_values[value] }) ) elseif setting == "scroll_method" then - self.config_client:unary_request( + client.unary_request( build_grpc_request_params("SetLibinputSetting", { [setting] = scroll_method_values[value] }) ) elseif setting == "tap_button_map" then - self.config_client:unary_request( + client.unary_request( build_grpc_request_params("SetLibinputSetting", { [setting] = tap_button_map_values[value] }) ) else - self.config_client:unary_request(build_grpc_request_params("SetLibinputSetting", { [setting] = value })) + client.unary_request(build_grpc_request_params("SetLibinputSetting", { [setting] = value })) end end end -function input.new(config_client) - ---@type Input - local self = { - config_client = config_client, - } - setmetatable(self, { __index = Input }) - return self -end - return input diff --git a/api/lua/pinnacle/output.lua b/api/lua/pinnacle/output.lua index 30c8411..48d26c1 100644 --- a/api/lua/pinnacle/output.lua +++ b/api/lua/pinnacle/output.lua @@ -2,8 +2,10 @@ -- 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") + ---The protobuf absolute path prefix -local prefix = "pinnacle.output." .. require("pinnacle").version .. "." +local prefix = "pinnacle.output." .. client.version .. "." local service = prefix .. "OutputService" ---@type table @@ -52,41 +54,35 @@ local output_handle = {} ---This can be retrieved through the various `get` functions in the `Output` module. ---@classmod ---@class OutputHandle ----@field private config_client Client ---@field name string The unique name of this output local OutputHandle = {} ----@nodoc ----@class OutputModule ----@field private handle OutputHandleModule -local output = {} -output.handle = output_handle - ---Output management. --- ---An output is what you would call a monitor. It presents windows, your cursor, and other UI elements. --- ---Outputs are uniquely identified by their name, a.k.a. the name of the connector they're plugged in to. ---@class Output ----@field private config_client Client -local Output = {} +---@field private handle OutputHandleModule +local output = {} +output.handle = output_handle ---Get all outputs. --- ---### Example ---```lua ----local outputs = Output:get_all() +---local outputs = Output.get_all() ---``` --- ---@return OutputHandle[] -function Output:get_all() - local response = self.config_client:unary_request(build_grpc_request_params("Get", {})) +function output.get_all() + local response = client.unary_request(build_grpc_request_params("Get", {})) ---@type OutputHandle[] local handles = {} for _, output_name in ipairs(response.output_names or {}) do - table.insert(handles, output_handle.new(self.config_client, output_name)) + table.insert(handles, output_handle.new(output_name)) end return handles @@ -96,13 +92,13 @@ end --- ---### Example ---```lua ----local output = Output:get_by_name("eDP-1") +---local output = Output.get_by_name("eDP-1") ---``` --- ---@param name string The name of the connector the output is connected to ---@return OutputHandle | nil -function Output:get_by_name(name) - local handles = self:get_all() +function output.get_by_name(name) + local handles = output.get_all() for _, handle in ipairs(handles) do if handle.name == name then @@ -119,12 +115,12 @@ end --- ---### Example ---```lua ----local output = Output:get_focused() +---local output = Output.get_focused() ---``` --- ---@return OutputHandle | nil -function Output:get_focused() - local handles = self:get_all() +function output.get_focused() + local handles = output.get_all() for _, handle in ipairs(handles) do if handle:props().focused then @@ -148,22 +144,22 @@ end ---### Example ---```lua --- -- Add tags "1" through "5" to all outputs ----Output:connect_for_all(function(output) ---- local tags = Tag:add(output, "1", "2", "3", "4", "5") +---Output.connect_for_all(function(output) +--- local tags = Tag.add(output, "1", "2", "3", "4", "5") --- tags[1]:toggle_active() ---end) ---``` --- ---@param callback fun(output: OutputHandle) -function Output:connect_for_all(callback) - local handles = self:get_all() +function output.connect_for_all(callback) + local handles = output.get_all() for _, handle in ipairs(handles) do callback(handle) end - self.config_client:server_streaming_request(build_grpc_request_params("ConnectForAll", {}), function(response) + 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) + local handle = output_handle.new(output_name) callback(handle) end) end @@ -188,8 +184,8 @@ end --- -- │ 2560x │ --- -- │ 1440 │ --- -- └───────┘ ----Output:get_by_name("DP-1"):set_location({ x = 0, y = 0 }) ----Output:get_by_name("HDMI-1"):set_location({ x = 1920, y = -360 }) +---Output.get_by_name("DP-1"):set_location({ x = 0, y = 0 }) +---Output.get_by_name("HDMI-1"):set_location({ x = 1920, y = -360 }) --- -- Results in: --- -- ┌───────┐ --- -- ┌─────┤ │ @@ -202,7 +198,7 @@ end --- ---@see OutputHandle.set_loc_adj_to function OutputHandle:set_location(loc) - self.config_client:unary_request(build_grpc_request_params("SetLocation", { + client.unary_request(build_grpc_request_params("SetLocation", { output_name = self.name, x = loc.x, y = loc.y, @@ -239,7 +235,7 @@ end --- -- │ 2560x │ --- -- │ 1440 │ --- -- └───────┘ ----Output:get_by_name("DP-1"):set_loc_adj_to(Output:get_by_name("HDMI-1"), "bottom_align_right") +---Output.get_by_name("DP-1"):set_loc_adj_to(Output:get_by_name("HDMI-1"), "bottom_align_right") --- -- Results in: --- -- ┌───────┐ --- -- │ │ @@ -328,10 +324,9 @@ end --- ---@return OutputProperties function OutputHandle:props() - local response = - self.config_client:unary_request(build_grpc_request_params("GetProperties", { output_name = self.name })) + local response = 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 or {}) + local handles = require("pinnacle.tag").handle.new_from_table(response.tag_ids or {}) response.tags = handles response.tag_ids = nil @@ -446,24 +441,12 @@ function OutputHandle:tags() return self:props().tags end ----@nodoc ----@return Output -function output.new(config_client) - ---@type Output - local self = { - config_client = config_client, - } - setmetatable(self, { __index = Output }) - return self -end - ---@nodoc ---Create a new `OutputHandle` from its raw name. ---@param output_name string -function output_handle.new(config_client, output_name) +function output_handle.new(output_name) ---@type OutputHandle local self = { - config_client = config_client, name = output_name, } setmetatable(self, { __index = OutputHandle }) diff --git a/api/lua/pinnacle/process.lua b/api/lua/pinnacle/process.lua index 3a0c9f7..c22f76e 100644 --- a/api/lua/pinnacle/process.lua +++ b/api/lua/pinnacle/process.lua @@ -2,8 +2,10 @@ -- 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") + ---The protobuf absolute path prefix -local prefix = "pinnacle.process." .. require("pinnacle").version .. "." +local prefix = "pinnacle.process." .. client.version .. "." local service = prefix .. "ProcessService" ---@type table @@ -33,22 +35,16 @@ local function build_grpc_request_params(method, data) } end ----@nodoc ----@class ProcessModule -local process = {} - ---Process management. --- ---This module provides utilities to spawn processes and capture their output. ---@class Process ----@field private config_client Client -local Process = {} +local process = {} ----@param config_client Client ---@param args string[] ---@param callbacks { stdout: fun(line: string)?, stderr: fun(line: string)?, exit: fun(code: integer, msg: string)? }? ---@param once boolean -local function spawn_inner(config_client, args, callbacks, once) +local function spawn_inner(args, callbacks, once) local callback = function() end if callbacks then @@ -65,7 +61,7 @@ local function spawn_inner(config_client, args, callbacks, once) end end - config_client:server_streaming_request( + client.server_streaming_request( build_grpc_request_params("Spawn", { args = args, once = once, @@ -88,47 +84,65 @@ end ---Note 2: If you spawn a window before tags are added it will spawn without any tags and ---won't be displayed in the compositor. TODO: Do what awesome does and display on all tags instead --- +---### Example +---```lua +---Process.spawn("alacritty") +--- +--- -- With a table of arguments +---Process.spawn({ "bash", "-c", "echo hello" }) +--- +--- -- With callbacks +---Process.spawn("alacritty", { +--- stdout = function(line) +--- print(line) +--- end, +--- -- You can ignore callbacks you don't need +--- exit = function(code, msg) +--- print("exited with code", code) +--- print("exited with msg", msg) +--- end, +---}) +---``` +--- ---@param args string | string[] The program arguments; a string instead of an array should be for only 1 argument ---@param callbacks { stdout: fun(line: string)?, stderr: fun(line: string)?, exit: fun(code: integer, msg: string)? }? Callbacks that will be run whenever the program outputs to stdout, stderr, or exits. -function Process:spawn(args, callbacks) +function process.spawn(args, callbacks) if type(args) == "string" then args = { args } end - spawn_inner(self.config_client, args, callbacks, false) + spawn_inner(args, callbacks, false) end ----Like `Process:spawn` but will only spawn the program if it isn't already running. +---Like `Process.spawn` but will only spawn the program if it isn't already running. --- ---@param args string | string[] ---@param callbacks { stdout: fun(line: string)?, stderr: fun(line: string)?, exit: fun(code: integer, msg: string)? }? --- ---@see Process.spawn -function Process:spawn_once(args, callbacks) +function process.spawn_once(args, callbacks) if type(args) == "string" then args = { args } end - spawn_inner(self.config_client, args, callbacks, true) + spawn_inner(args, callbacks, true) end ---Set an environment variable for the compositor. ---This will cause any future spawned processes to have this environment variable. --- +---### Example +---```lua +---Process.set_env("ENV_NAME", "the value") +---``` +--- ---@param key string The environment variable key ---@param value string The environment variable value -function Process:set_env(key, value) - self.config_client:unary_request(build_grpc_request_params("SetEnv", { +function process.set_env(key, value) + client.unary_request(build_grpc_request_params("SetEnv", { key = key, value = value, })) end -function process.new(config_client) - ---@type Process - local self = { config_client = config_client } - setmetatable(self, { __index = Process }) - return self -end - return process diff --git a/api/lua/pinnacle/tag.lua b/api/lua/pinnacle/tag.lua index b2de63e..0aac85a 100644 --- a/api/lua/pinnacle/tag.lua +++ b/api/lua/pinnacle/tag.lua @@ -2,8 +2,10 @@ -- 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") + ---The protobuf absolute path prefix -local prefix = "pinnacle.tag." .. require("pinnacle").version .. "." +local prefix = "pinnacle.tag." .. client.version .. "." local service = prefix .. "TagService" ---@type table @@ -53,16 +55,9 @@ local tag_handle = {} ---This can be retrieved through the various `get` functions in the `Tag` module. ---@classmod ---@class TagHandle ----@field private config_client Client ---@field id integer local TagHandle = {} ----@nodoc ----@class TagModule ----@field private handle TagHandleModule -local tag = {} -tag.handle = tag_handle - ---Tag management. --- ---This module provides utilities for creating and manipulating tags. @@ -79,20 +74,21 @@ tag.handle = tag_handle --- ---If you need to get tags beyond the first with the same name, use the `get` method and find what you need. ---@class Tag ----@field private config_client Client -local Tag = {} +---@field private handle TagHandleModule +local tag = {} +tag.handle = tag_handle ---Get all tags across all outputs. --- ---@return TagHandle[] -function Tag:get_all() - local response = self.config_client:unary_request(build_grpc_request_params("Get", {})) +function tag.get_all() + local response = client.unary_request(build_grpc_request_params("Get", {})) ---@type TagHandle[] local handles = {} for _, id in ipairs(response.tag_ids or {}) do - table.insert(handles, tag_handle.new(self.config_client, id)) + table.insert(handles, tag_handle.new(id)) end return handles @@ -107,24 +103,24 @@ end ---### Example ---```lua --- -- Get tags on the focused output ----local tag = Tag:get("Tag") +---local tag = Tag.get("Tag") --- --- -- Get tags on a specific output ----local tag_on_hdmi1 = Tag:get("Tag", Output:get_by_name("HDMI-1")) +---local tag_on_hdmi1 = Tag.get("Tag", Output:get_by_name("HDMI-1")) ---``` --- ---@param name string ---@param output OutputHandle? --- ---@return TagHandle | nil -function Tag:get(name, output) - output = output or require("pinnacle.output").new(self.config_client):get_focused() +function tag.get(name, output) + output = output or require("pinnacle.output").get_focused() if not output then return end - local handles = self:get_all() + local handles = tag.get_all() for _, handle in ipairs(handles) do local props = handle:props() @@ -142,11 +138,11 @@ end --- ---### Example ---```lua ----local tags = Tag:add(Output:get_by_name("HDMI-1"), "1", "2", "Buckle", "Shoe") +---local tags = Tag.add(Output.get_by_name("HDMI-1"), "1", "2", "Buckle", "Shoe") --- --- -- With a table ---local tag_names = { "1", "2", "Buckle", "Shoe" } ----local tags = Tag:add(Output:get_by_name("HDMI-1"), tag_names) +---local tags = Tag.add(Output.get_by_name("HDMI-1"), tag_names) ---``` --- ---@param output OutputHandle @@ -154,14 +150,14 @@ end --- ---@return TagHandle[] tags Handles to the created tags --- ----@overload fun(self: self, output: OutputHandle, tag_names: string[]) -function Tag:add(output, ...) +---@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", { + local response = client.unary_request(build_grpc_request_params("Add", { output_name = output.name, tag_names = tag_names, })) @@ -170,7 +166,7 @@ function Tag:add(output, ...) local handles = {} for _, id in ipairs(response.tag_ids) do - table.insert(handles, tag_handle.new(self.config_client, id)) + table.insert(handles, tag_handle.new(id)) end return handles @@ -180,13 +176,13 @@ end --- ---### Example ---```lua ----local tags = Tag:add(Output:get_by_name("HDMI-1"), "1", "2", "Buckle", "Shoe") +---local tags = Tag.add(Output.get_by_name("HDMI-1"), "1", "2", "Buckle", "Shoe") --- ----Tag:remove(tags) -- "HDMI-1" no longer has those tags +---Tag.remove(tags) -- "HDMI-1" no longer has those tags ---``` --- ---@param tags TagHandle[] -function Tag:remove(tags) +function tag.remove(tags) ---@type integer[] local ids = {} @@ -194,7 +190,7 @@ function Tag:remove(tags) table.insert(ids, tg.id) end - self.config_client:unary_request(build_grpc_request_params("Remove", { tag_ids = ids })) + client.unary_request(build_grpc_request_params("Remove", { tag_ids = ids })) end ---@class LayoutCycler @@ -222,7 +218,7 @@ end --- "corner_top_right". ---} -- Only cycle between these four layouts --- ----local layout_cycler = Tag:new_layout_cycler() +---local layout_cycler = Tag.new_layout_cycler() --- --- -- Assume the focused output starts with the "master_stack" layout ---layout_cycler.next() -- Layout is now "dwindle" @@ -232,14 +228,14 @@ end ---layout_cycler.next() -- Layout is now "corner_top_right" --- --- -- Cycling on another output ----layout_cycler.next(Output:get_by_name("eDP-1")) ----layout_cycler.prev(Output:get_by_name("HDMI-1")) +---layout_cycler.next(Output.get_by_name("eDP-1")) +---layout_cycler.prev(Output.get_by_name("HDMI-1")) ---``` --- ---@param layouts Layout[] --- ---@return LayoutCycler -function Tag:new_layout_cycler(layouts) +function tag.new_layout_cycler(layouts) local indices = {} if #layouts == 0 then @@ -252,7 +248,7 @@ function Tag:new_layout_cycler(layouts) ---@type LayoutCycler return { next = function(output) - local output = output or require("pinnacle.output").new(self.config_client):get_focused() + local output = output or require("pinnacle.output").get_focused() if not output then return end @@ -280,7 +276,7 @@ function Tag:new_layout_cycler(layouts) end end, prev = function(output) - local output = output or require("pinnacle.output").new(self.config_client):get_focused() + local output = output or require("pinnacle.output").get_focused() if not output then return end @@ -315,14 +311,14 @@ end --- ---### Example ---```lua ----local tags = Tag:add(Output:get_by_name("HDMI-1"), "1", "2", "Buckle", "Shoe") +---local tags = Tag.add(Output.get_by_name("HDMI-1"), "1", "2", "Buckle", "Shoe") --- ---tags[2]:remove() ---tags[4]:remove() --- -- "HDMI-1" now only has tags "1" and "Buckle" ---``` function TagHandle:remove() - self.config_client:unary_request(build_grpc_request_params("Remove", { tag_ids = { self.id } })) + client.unary_request(build_grpc_request_params("Remove", { tag_ids = { self.id } })) end local _layouts = { @@ -350,14 +346,14 @@ local _layouts = { ---### Example ---```lua --- -- Assume the focused output has tag "Tag" ----Tag:get("Tag"):set_layout("dwindle") +---Tag.get("Tag"):set_layout("dwindle") ---``` --- ---@param layout Layout function TagHandle:set_layout(layout) local layout = _layouts[layout] - self.config_client:unary_request(build_grpc_request_params("SetLayout", { + client.unary_request(build_grpc_request_params("SetLayout", { tag_id = self.id, layout = layout, })) @@ -371,11 +367,11 @@ end --- -- - "1": Alacritty --- -- - "2": Firefox, Discord --- -- - "3": Steam ----Tag:get("2"):switch_to() -- Displays Firefox and Discord ----Tag:get("3"):switch_to() -- Displays Steam +---Tag.get("2"):switch_to() -- Displays Firefox and Discord +---Tag.get("3"):switch_to() -- Displays Steam ---``` function TagHandle:switch_to() - self.config_client:unary_request(build_grpc_request_params("SwitchTo", { tag_id = self.id })) + client.unary_request(build_grpc_request_params("SwitchTo", { tag_id = self.id })) end ---Set whether or not this tag is active. @@ -386,14 +382,14 @@ end --- -- - "1": Alacritty --- -- - "2": Firefox, Discord --- -- - "3": Steam ----Tag:get("2"):set_active(true) -- Displays Firefox and Discord ----Tag:get("3"):set_active(true) -- Displays Firefox, Discord, and Steam ----Tag:get("2"):set_active(false) -- Displays Steam +---Tag.get("2"):set_active(true) -- Displays Firefox and Discord +---Tag.get("3"):set_active(true) -- Displays Firefox, Discord, and Steam +---Tag.get("2"):set_active(false) -- Displays Steam ---``` --- ---@param active boolean function TagHandle:set_active(active) - self.config_client:unary_request(build_grpc_request_params("SetActive", { tag_id = self.id, set = active })) + client.unary_request(build_grpc_request_params("SetActive", { tag_id = self.id, set = active })) end ---Toggle this tag's active state. @@ -404,11 +400,11 @@ end --- -- - "1": Alacritty --- -- - "2": Firefox, Discord --- -- - "3": Steam ----Tag:get("2"):toggle_active() -- Displays Firefox and Discord ----Tag:get("2"):toggle_active() -- Displays nothing +---Tag.get("2"):toggle_active() -- Displays Firefox and Discord +---Tag.get("2"):toggle_active() -- Displays nothing ---``` function TagHandle:toggle_active() - self.config_client:unary_request(build_grpc_request_params("SetActive", { tag_id = self.id, toggle = {} })) + client.unary_request(build_grpc_request_params("SetActive", { tag_id = self.id, toggle = {} })) end ---@class TagProperties @@ -420,13 +416,12 @@ end --- ---@return TagProperties function TagHandle:props() - local response = self.config_client:unary_request(build_grpc_request_params("GetProperties", { tag_id = self.id })) + local response = 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), + output = response.output_name and require("pinnacle.output").handle.new(response.output_name), } end @@ -457,26 +452,13 @@ function TagHandle:output() return self:props().output end ----@nodoc ----@return Tag -function tag.new(config_client) - ---@type Tag - local self = { - config_client = config_client, - } - setmetatable(self, { __index = Tag }) - return self -end - ---@nodoc ---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) +function tag_handle.new(tag_id) ---@type TagHandle local self = { - config_client = config_client, id = tag_id, } setmetatable(self, { __index = TagHandle }) @@ -484,15 +466,14 @@ function tag_handle.new(config_client, tag_id) end ---@nodoc ----@param config_client Client ---@param tag_ids integer[] ---@return TagHandle[] -function tag_handle.new_from_table(config_client, tag_ids) +function tag_handle.new_from_table(tag_ids) ---@type TagHandle[] local handles = {} for _, id in ipairs(tag_ids) do - table.insert(handles, tag_handle.new(config_client, id)) + table.insert(handles, tag_handle.new(id)) end return handles diff --git a/api/lua/pinnacle/window.lua b/api/lua/pinnacle/window.lua index 38a1176..4cfa23c 100644 --- a/api/lua/pinnacle/window.lua +++ b/api/lua/pinnacle/window.lua @@ -2,8 +2,10 @@ -- 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") + ---The protobuf absolute path prefix -local prefix = "pinnacle.window." .. require("pinnacle").version .. "." +local prefix = "pinnacle.window." .. client.version .. "." local service = prefix .. "WindowService" ---@type table @@ -59,38 +61,30 @@ local window_handle = {} ---You can retrieve window handles through the various `get` functions in the `Window` module. ---@classmod ---@class WindowHandle ----@field private config_client Client ---@field id integer local WindowHandle = {} ----@nodoc ----@class WindowModule ----@field private handle WindowHandleModule -local window = {} -window.handle = window_handle - ---Window management. --- ---This module helps you deal with setting windows to fullscreen and maximized, setting their size, ---moving them between tags, and various other actions. ---@class Window ----@field private config_client Client -local Window = {} +local window = {} ---Get all windows. --- ---### Example ---```lua ----local windows = Window:get_all() +---local windows = Window.get_all() ---for _, window in ipairs(windows) do --- print(window:props().class) ---end ---``` ---@return WindowHandle[] windows Handles to all windows -function Window:get_all() - local response = self.config_client:unary_request(build_grpc_request_params("Get", {})) +function window.get_all() + local response = client.unary_request(build_grpc_request_params("Get", {})) - local handles = window_handle.new_from_table(self.config_client, response.window_ids or {}) + local handles = window_handle.new_from_table(response.window_ids or {}) return handles end @@ -99,14 +93,14 @@ end --- ---### Example ---```lua ----local focused = Window:get_focused() +---local focused = Window.get_focused() ---if focused then --- print(focused:props().class) ---end ---``` ---@return WindowHandle | nil window A handle to the currently focused window -function Window:get_focused() - local handles = self:get_all() +function window.get_focused() + local handles = window.get_all() for _, handle in ipairs(handles) do if handle:props().focused then @@ -124,14 +118,14 @@ end --- ---### Example ---```lua ----Input:mousebind({ "super" }, "btn_left", function() ---- Window:begin_move("btn_left") +---Input.mousebind({ "super" }, "btn_left", function() +--- Window.begin_move("btn_left") ---end) ---``` ---@param button MouseButton The button that will initiate the move -function Window:begin_move(button) +function window.begin_move(button) local button = require("pinnacle.input").btn[button] - self.config_client:unary_request(build_grpc_request_params("MoveGrab", { button = button })) + client.unary_request(build_grpc_request_params("MoveGrab", { button = button })) end ---Begin resizing this window using the specified mouse button. @@ -141,14 +135,14 @@ end --- ---### Example ---```lua ----Input:mousebind({ "super" }, "btn_right", function() ---- Window:begin_resize("btn_right") +---Input.mousebind({ "super" }, "btn_right", function() +--- Window.begin_resize("btn_right") ---end) ---``` ---@param button MouseButton The button that will initiate the resize -function Window:begin_resize(button) +function window.begin_resize(button) local button = require("pinnacle.input").btn[button] - self.config_client:unary_request(build_grpc_request_params("ResizeGrab", { button = button })) + client.unary_request(build_grpc_request_params("ResizeGrab", { button = button })) end ---@class WindowRuleCondition @@ -204,7 +198,7 @@ local _fullscreen_or_maximized_keys = { ---### Examples ---```lua --- -- A simple window rule. This one will cause Firefox to open on tag "Browser". ----Window:add_window_rule({ +---Window.add_window_rule({ --- cond = { classes = { "firefox" } }, --- rule = { tags = { "Browser" } }, ---}) @@ -212,7 +206,7 @@ local _fullscreen_or_maximized_keys = { --- -- To apply rules when *all* provided conditions are true, use `all`. --- -- `all` takes an array of conditions and checks if all are true. --- -- The following will open Steam fullscreen only if it opens on tag "5". ----Window:add_window_rule({ +---Window.add_window_rule({ --- cond = { --- all = { --- { @@ -226,7 +220,7 @@ local _fullscreen_or_maximized_keys = { --- --- -- The outermost block of a `cond` is implicitly an `all` block. --- -- Thus, the above can be shortened to: ----Window:add_window_rule({ +---Window.add_window_rule({ --- cond = { --- class = "steam", --- tag = Tag:get("5"), @@ -236,7 +230,7 @@ local _fullscreen_or_maximized_keys = { --- --- -- `any` also exists to allow at least one provided condition to match. --- -- The following will open either xterm or Alacritty floating. ----Window:add_window_rule({ +---Window.add_window_rule({ --- cond = { --- any = { { classes = { "xterm", "Alacritty" } } } --- }, @@ -246,7 +240,7 @@ local _fullscreen_or_maximized_keys = { --- -- You can arbitrarily nest `any` and `all` to achieve desired logic. --- -- The following will open Discord, Thunderbird, or Firefox floating if they --- -- open on either *all* of tags "A", "B", and "C" or both tags "1" and "2". ----Window:add_window_rule({ +---Window.add_window_rule({ --- cond = { --- all = { -- This `all` block is needed because the outermost block cannot be an array. --- { any = { @@ -270,7 +264,7 @@ local _fullscreen_or_maximized_keys = { ---``` --- ---@param rule { cond: WindowRuleCondition, rule: WindowRule } The condition and rule -function Window:add_window_rule(rule) +function window.add_window_rule(rule) if rule.cond.tags then local ids = {} for _, tg in ipairs(rule.cond.tags) do @@ -295,7 +289,7 @@ function Window:add_window_rule(rule) rule.rule.fullscreen_or_maximized = _fullscreen_or_maximized[rule.rule.fullscreen_or_maximized] end - self.config_client:unary_request(build_grpc_request_params("AddWindowRule", { + client.unary_request(build_grpc_request_params("AddWindowRule", { cond = rule.cond, rule = rule.rule, })) @@ -305,11 +299,11 @@ end --- ---### Example ---```lua ----local focused = Window:get_focused() +---local focused = Window.get_focused() ---if focused then focused:close() end ---``` function WindowHandle:close() - self.config_client:unary_request(build_grpc_request_params("Close", { window_id = self.id })) + client.unary_request(build_grpc_request_params("Close", { window_id = self.id })) end ---Set this window's location and/or size. @@ -328,7 +322,7 @@ end --- ---### Example ---```lua ----local focused = Window:get_focused() +---local focused = Window.get_focused() ---if focused then --- focused:set_floating(true) -- `set_geometry` only applies to floating geometry. --- @@ -339,14 +333,14 @@ end ---``` ---@param geo { x: integer?, y: integer, width: integer?, height: integer? } The new location and/or size function WindowHandle:set_geometry(geo) - self.config_client:unary_request(build_grpc_request_params("SetGeometry", { window_id = self.id, geometry = geo })) + client.unary_request(build_grpc_request_params("SetGeometry", { window_id = self.id, geometry = geo })) end ---Set this window to fullscreen or not. --- ---### Example ---```lua ----local focused = Window:get_focused() +---local focused = Window.get_focused() ---if focused then --- focused:set_fullscreen(true) --- focused:set_fullscreen(false) @@ -355,29 +349,27 @@ end --- ---@param fullscreen boolean function WindowHandle:set_fullscreen(fullscreen) - self.config_client:unary_request( - build_grpc_request_params("SetFullscreen", { window_id = self.id, set = fullscreen }) - ) + client.unary_request(build_grpc_request_params("SetFullscreen", { window_id = self.id, set = fullscreen })) end ---Toggle this window to and from fullscreen. --- ---### Example ---```lua ----local focused = Window:get_focused() +---local focused = Window.get_focused() ---if focused then --- focused:toggle_fullscreen() ---end ---``` function WindowHandle:toggle_fullscreen() - self.config_client:unary_request(build_grpc_request_params("SetFullscreen", { window_id = self.id, toggle = {} })) + client.unary_request(build_grpc_request_params("SetFullscreen", { window_id = self.id, toggle = {} })) end ---Set this window to maximized or not. --- ---### Example ---```lua ----local focused = Window:get_focused() +---local focused = Window.get_focused() ---if focused then --- focused:set_maximized(true) --- focused:set_maximized(false) @@ -386,29 +378,27 @@ end --- ---@param maximized boolean function WindowHandle:set_maximized(maximized) - self.config_client:unary_request( - build_grpc_request_params("SetMaximized", { window_id = self.id, set = maximized }) - ) + client.unary_request(build_grpc_request_params("SetMaximized", { window_id = self.id, set = maximized })) end ---Toggle this window to and from maximized. --- ---### Example ---```lua ----local focused = Window:get_focused() +---local focused = Window.get_focused() ---if focused then --- focused:toggle_maximized() ---end ---``` function WindowHandle:toggle_maximized() - self.config_client:unary_request(build_grpc_request_params("SetMaximized", { window_id = self.id, toggle = {} })) + client.unary_request(build_grpc_request_params("SetMaximized", { window_id = self.id, toggle = {} })) end ---Set this window to floating or not. --- ---### Example ---```lua ----local focused = Window:get_focused() +---local focused = Window.get_focused() ---if focused then --- focused:set_floating(true) --- focused:set_floating(false) @@ -417,20 +407,20 @@ end --- ---@param floating boolean function WindowHandle:set_floating(floating) - self.config_client:unary_request(build_grpc_request_params("SetFloating", { window_id = self.id, set = floating })) + client.unary_request(build_grpc_request_params("SetFloating", { window_id = self.id, set = floating })) end ---Toggle this window to and from floating. --- ---### Example ---```lua ----local focused = Window:get_focused() +---local focused = Window.get_focused() ---if focused then --- focused:toggle_floating() ---end ---``` function WindowHandle:toggle_floating() - self.config_client:unary_request(build_grpc_request_params("SetFloating", { window_id = self.id, toggle = {} })) + client.unary_request(build_grpc_request_params("SetFloating", { window_id = self.id, toggle = {} })) end ---Move this window to the specified tag. @@ -440,15 +430,15 @@ end ---### Example ---```lua --- -- Assume the focused output has the tag "Tag" ----local focused = Window:get_focused() +---local focused = Window.get_focused() ---if focused then ---- focused:move_to_tag(Tag:get("Tag")) +--- focused:move_to_tag(Tag.get("Tag")) ---end ---``` --- ---@param tag TagHandle The tag to move this window to function WindowHandle:move_to_tag(tag) - self.config_client:unary_request(build_grpc_request_params("MoveToTag", { window_id = self.id, tag_id = tag.id })) + client.unary_request(build_grpc_request_params("MoveToTag", { window_id = self.id, tag_id = tag.id })) end ---Tag or untag the given tag on this window. @@ -456,9 +446,9 @@ end ---### Example ---```lua --- -- Assume the focused output has the tag "Tag" ----local focused = Window:get_focused() +---local focused = Window.get_focused() ---if focused then ---- local tag = Tag:get("Tag") +--- local tag = Tag.get("Tag") --- --- focused:set_tag(tag, true) --- -- `focused` now has tag "Tag" @@ -470,9 +460,7 @@ end ---@param tag TagHandle The tag to set or unset ---@param set boolean function WindowHandle:set_tag(tag, set) - self.config_client:unary_request( - build_grpc_request_params("SetTag", { window_id = self.id, tag_id = tag.id, set = set }) - ) + client.unary_request(build_grpc_request_params("SetTag", { window_id = self.id, tag_id = tag.id, set = set })) end ---Toggle the given tag on this window. @@ -480,9 +468,9 @@ end ---### Example ---```lua --- -- Assume the focused output has the tag "Tag" ----local focused = Window:get_focused() +---local focused = Window.get_focused() ---if focused then ---- local tag = Tag:get("Tag") +--- local tag = Tag.get("Tag") --- focused:set_tag(tag, false) --- --- focused:toggle_tag(tag) @@ -494,9 +482,7 @@ end --- ---@param tag TagHandle The tag to toggle function WindowHandle:toggle_tag(tag) - self.config_client:unary_request( - build_grpc_request_params("SetTag", { window_id = self.id, tag_id = tag.id, toggle = {} }) - ) + client.unary_request(build_grpc_request_params("SetTag", { window_id = self.id, tag_id = tag.id, toggle = {} })) end ---@class WindowProperties @@ -512,13 +498,11 @@ end --- ---@return WindowProperties function WindowHandle:props() - local response = - self.config_client:unary_request(build_grpc_request_params("GetProperties", { window_id = self.id })) + local response = client.unary_request(build_grpc_request_params("GetProperties", { window_id = self.id })) response.fullscreen_or_maximized = _fullscreen_or_maximized_keys[response.fullscreen_or_maximized] - response.tags = response.tag_ids - and require("pinnacle.tag").handle.new_from_table(self.config_client, response.tag_ids) + response.tags = response.tag_ids and require("pinnacle.tag").handle.new_from_table(response.tag_ids) response.tag_ids = nil return response @@ -587,27 +571,13 @@ function WindowHandle:tags() return self:props().tags end ----@nodoc ----@param config_client Client ----@return Window -function window.new(config_client) - ---@type Window - local self = { - config_client = config_client, - } - setmetatable(self, { __index = Window }) - return self -end - ---@nodoc ---Create a new `WindowHandle` from an id. ----@param config_client Client ---@param window_id integer ---@return WindowHandle -function window_handle.new(config_client, window_id) +function window_handle.new(window_id) ---@type WindowHandle local self = { - config_client = config_client, id = window_id, } setmetatable(self, { __index = WindowHandle }) @@ -615,16 +585,15 @@ function window_handle.new(config_client, window_id) end ---@nodoc ----@param config_client Client ---@param window_ids integer[] --- ---@return WindowHandle[] -function window_handle.new_from_table(config_client, window_ids) +function window_handle.new_from_table(window_ids) ---@type WindowHandle[] local handles = {} for _, id in ipairs(window_ids) do - table.insert(handles, window_handle.new(config_client, id)) + table.insert(handles, window_handle.new(id)) end return handles