mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2024-12-26 21:58:10 +01:00
Re-add lost API functionality, fix msg ordering
This commit is contained in:
parent
3ddd57c63f
commit
fb63e7ada3
8 changed files with 444 additions and 253 deletions
|
@ -31,7 +31,7 @@
|
||||||
|
|
||||||
--------------------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
---@class _Request
|
---@class __Request
|
||||||
--Windows
|
--Windows
|
||||||
---@field GetWindowProps { window_id: WindowId }
|
---@field GetWindowProps { window_id: WindowId }
|
||||||
--Outputs
|
--Outputs
|
||||||
|
@ -39,11 +39,12 @@
|
||||||
--Tags
|
--Tags
|
||||||
---@field GetTagProps { tag_id: TagId }
|
---@field GetTagProps { tag_id: TagId }
|
||||||
|
|
||||||
---@alias Request _Request | "GetWindows" | "GetOutputs" | "GetTags"
|
---@alias _Request __Request | "GetWindows" | "GetOutputs" | "GetTags"
|
||||||
|
---@alias Request { request_id: integer, request: _Request }
|
||||||
|
|
||||||
---@class IncomingMsg
|
---@class IncomingMsg
|
||||||
---@field CallCallback { callback_id: integer, args: Args }
|
---@field CallCallback { callback_id: integer, args: Args? }
|
||||||
---@field RequestResponse { response: RequestResponse }
|
---@field RequestResponse { request_id: integer, response: RequestResponse }
|
||||||
|
|
||||||
---@class Args
|
---@class Args
|
||||||
---@field Spawn { stdout: string?, stderr: string?, exit_code: integer?, exit_msg: string? }
|
---@field Spawn { stdout: string?, stderr: string?, exit_code: integer?, exit_msg: string? }
|
||||||
|
@ -51,6 +52,7 @@
|
||||||
|
|
||||||
---@alias WindowId integer
|
---@alias WindowId integer
|
||||||
---@alias TagId integer
|
---@alias TagId integer
|
||||||
|
---@alias RequestId integer
|
||||||
---@alias OutputName string
|
---@alias OutputName string
|
||||||
|
|
||||||
---@class RequestResponse
|
---@class RequestResponse
|
||||||
|
|
|
@ -4,67 +4,64 @@
|
||||||
--
|
--
|
||||||
-- SPDX-License-Identifier: MPL-2.0
|
-- SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
|
---@class OutputGlobal
|
||||||
|
local output_global = {}
|
||||||
|
|
||||||
---@class Output A display.
|
---@class Output A display.
|
||||||
---@field private _name string The name of this output (or rather, of its connector).
|
---@field private _name string The name of this output (or rather, of its connector).
|
||||||
local op = {}
|
local output = {}
|
||||||
|
|
||||||
---Get this output's name. This is something like "eDP-1" or "HDMI-A-0".
|
---Get this output's name. This is something like "eDP-1" or "HDMI-A-0".
|
||||||
---@return string
|
---@return string
|
||||||
function op:name()
|
function output:name()
|
||||||
return self._name
|
return self._name
|
||||||
end
|
end
|
||||||
|
|
||||||
---Get all tags on this output. See `tag.get_on_output`.
|
---Get all tags on this output. See `tag.get_on_output`.
|
||||||
---@return Tag[]
|
---@return Tag[]
|
||||||
function op:tags()
|
function output:tags()
|
||||||
return require("tag").get_on_output(self)
|
return require("tag").get_on_output(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
---Add tags to this output. See `tag.add`.
|
---Add tags to this output. See `tag.add`.
|
||||||
---@param ... string The names of the tags you want to add.
|
---@param ... string The names of the tags you want to add.
|
||||||
---@overload fun(self: self, tag_names: string[])
|
---@overload fun(self: self, tag_names: string[])
|
||||||
function op:add_tags(...)
|
function output:add_tags(...)
|
||||||
require("tag").add(self, ...)
|
require("tag").add(self, ...)
|
||||||
end
|
end
|
||||||
|
|
||||||
---Get this output's make.
|
---Get this output's make.
|
||||||
---@return string|nil
|
---@return string|nil
|
||||||
function op:make()
|
function output:make()
|
||||||
SendRequest({
|
local response = ReadMsg(SendRequest({
|
||||||
GetOutputProps = {
|
GetOutputProps = {
|
||||||
output_name = self._name,
|
output_name = self._name,
|
||||||
},
|
},
|
||||||
})
|
}))
|
||||||
|
|
||||||
local response = ReadMsg()
|
|
||||||
local props = response.RequestResponse.response.OutputProps
|
local props = response.RequestResponse.response.OutputProps
|
||||||
return props.make
|
return props.make
|
||||||
end
|
end
|
||||||
|
|
||||||
---Get this output's model.
|
---Get this output's model.
|
||||||
---@return string|nil
|
---@return string|nil
|
||||||
function op:model()
|
function output:model()
|
||||||
SendRequest({
|
local response = ReadMsg(SendRequest({
|
||||||
GetOutputProps = {
|
GetOutputProps = {
|
||||||
output_name = self._name,
|
output_name = self._name,
|
||||||
},
|
},
|
||||||
})
|
}))
|
||||||
|
|
||||||
local response = ReadMsg()
|
|
||||||
local props = response.RequestResponse.response.OutputProps
|
local props = response.RequestResponse.response.OutputProps
|
||||||
return props.model
|
return props.model
|
||||||
end
|
end
|
||||||
|
|
||||||
---Get this output's location in the global space.
|
---Get this output's location in the global space.
|
||||||
---@return { x: integer, y: integer }|nil
|
---@return { x: integer, y: integer }|nil
|
||||||
function op:loc()
|
function output:loc()
|
||||||
SendRequest({
|
local response = ReadMsg(SendRequest({
|
||||||
GetOutputProps = {
|
GetOutputProps = {
|
||||||
output_name = self._name,
|
output_name = self._name,
|
||||||
},
|
},
|
||||||
})
|
}))
|
||||||
|
|
||||||
local response = ReadMsg()
|
|
||||||
local props = response.RequestResponse.response.OutputProps
|
local props = response.RequestResponse.response.OutputProps
|
||||||
if props.loc == nil then
|
if props.loc == nil then
|
||||||
return nil
|
return nil
|
||||||
|
@ -75,14 +72,12 @@ end
|
||||||
|
|
||||||
---Get this output's resolution in pixels.
|
---Get this output's resolution in pixels.
|
||||||
---@return { w: integer, h: integer }|nil
|
---@return { w: integer, h: integer }|nil
|
||||||
function op:res()
|
function output:res()
|
||||||
SendRequest({
|
local response = ReadMsg(SendRequest({
|
||||||
GetOutputProps = {
|
GetOutputProps = {
|
||||||
output_name = self._name,
|
output_name = self._name,
|
||||||
},
|
},
|
||||||
})
|
}))
|
||||||
|
|
||||||
local response = ReadMsg()
|
|
||||||
local props = response.RequestResponse.response.OutputProps
|
local props = response.RequestResponse.response.OutputProps
|
||||||
if props.res == nil then
|
if props.res == nil then
|
||||||
return nil
|
return nil
|
||||||
|
@ -94,28 +89,24 @@ end
|
||||||
---Get this output's refresh rate in millihertz.
|
---Get this output's refresh rate in millihertz.
|
||||||
---For example, 60Hz will be returned as 60000.
|
---For example, 60Hz will be returned as 60000.
|
||||||
---@return integer|nil
|
---@return integer|nil
|
||||||
function op:refresh_rate()
|
function output:refresh_rate()
|
||||||
SendRequest({
|
local response = ReadMsg(SendRequest({
|
||||||
GetOutputProps = {
|
GetOutputProps = {
|
||||||
output_name = self._name,
|
output_name = self._name,
|
||||||
},
|
},
|
||||||
})
|
}))
|
||||||
|
|
||||||
local response = ReadMsg()
|
|
||||||
local props = response.RequestResponse.response.OutputProps
|
local props = response.RequestResponse.response.OutputProps
|
||||||
return props.refresh_rate
|
return props.refresh_rate
|
||||||
end
|
end
|
||||||
|
|
||||||
---Get this output's physical size in millimeters.
|
---Get this output's physical size in millimeters.
|
||||||
---@return { w: integer, h: integer }|nil
|
---@return { w: integer, h: integer }|nil
|
||||||
function op:physical_size()
|
function output:physical_size()
|
||||||
SendRequest({
|
local response = ReadMsg(SendRequest({
|
||||||
GetOutputProps = {
|
GetOutputProps = {
|
||||||
output_name = self._name,
|
output_name = self._name,
|
||||||
},
|
},
|
||||||
})
|
}))
|
||||||
|
|
||||||
local response = ReadMsg()
|
|
||||||
local props = response.RequestResponse.response.OutputProps
|
local props = response.RequestResponse.response.OutputProps
|
||||||
if props.physical_size == nil then
|
if props.physical_size == nil then
|
||||||
return nil
|
return nil
|
||||||
|
@ -126,14 +117,12 @@ end
|
||||||
|
|
||||||
---Get whether or not this output is focused. This is currently defined as having the cursor on it.
|
---Get whether or not this output is focused. This is currently defined as having the cursor on it.
|
||||||
---@return boolean|nil
|
---@return boolean|nil
|
||||||
function op:focused()
|
function output:focused()
|
||||||
SendRequest({
|
local response = ReadMsg(SendRequest({
|
||||||
GetOutputProps = {
|
GetOutputProps = {
|
||||||
output_name = self._name,
|
output_name = self._name,
|
||||||
},
|
},
|
||||||
})
|
}))
|
||||||
|
|
||||||
local response = ReadMsg()
|
|
||||||
local props = response.RequestResponse.response.OutputProps
|
local props = response.RequestResponse.response.OutputProps
|
||||||
return props.focused
|
return props.focused
|
||||||
end
|
end
|
||||||
|
@ -145,7 +134,7 @@ local function new_output(output_name)
|
||||||
---@type Output
|
---@type Output
|
||||||
local o = { _name = output_name }
|
local o = { _name = output_name }
|
||||||
-- Copy functions over
|
-- Copy functions over
|
||||||
for k, v in pairs(op) do
|
for k, v in pairs(output) do
|
||||||
o[k] = v
|
o[k] = v
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -154,9 +143,6 @@ end
|
||||||
|
|
||||||
------------------------------------------------------
|
------------------------------------------------------
|
||||||
|
|
||||||
---@class OutputGlobal
|
|
||||||
local output = {}
|
|
||||||
|
|
||||||
---Get an output by its name.
|
---Get an output by its name.
|
||||||
---
|
---
|
||||||
---"Name" in this sense does not mean its model or manufacturer;
|
---"Name" in this sense does not mean its model or manufacturer;
|
||||||
|
@ -170,9 +156,8 @@ local output = {}
|
||||||
---```
|
---```
|
||||||
---@param name string The name of the output.
|
---@param name string The name of the output.
|
||||||
---@return Output|nil output The output, or nil if none have the provided name.
|
---@return Output|nil output The output, or nil if none have the provided name.
|
||||||
function output.get_by_name(name)
|
function output_global.get_by_name(name)
|
||||||
SendRequest("GetOutputs")
|
local response = ReadMsg(SendRequest("GetOutputs"))
|
||||||
local response = ReadMsg()
|
|
||||||
local output_names = response.RequestResponse.response.Outputs.output_names
|
local output_names = response.RequestResponse.response.Outputs.output_names
|
||||||
|
|
||||||
for _, output_name in pairs(output_names) do
|
for _, output_name in pairs(output_names) do
|
||||||
|
@ -190,9 +175,8 @@ end
|
||||||
---This is something like "DELL E2416H" or whatever gibberish monitor manufacturers call their displays.
|
---This is something like "DELL E2416H" or whatever gibberish monitor manufacturers call their displays.
|
||||||
---@param model string The model of the output(s).
|
---@param model string The model of the output(s).
|
||||||
---@return Output[] outputs All outputs with this model.
|
---@return Output[] outputs All outputs with this model.
|
||||||
function output.get_by_model(model)
|
function output_global.get_by_model(model)
|
||||||
SendRequest("GetOutputs")
|
local response = ReadMsg(SendRequest("GetOutputs"))
|
||||||
local response = ReadMsg()
|
|
||||||
local output_names = response.RequestResponse.response.Outputs.output_names
|
local output_names = response.RequestResponse.response.Outputs.output_names
|
||||||
|
|
||||||
---@type Output[]
|
---@type Output[]
|
||||||
|
@ -212,10 +196,8 @@ end
|
||||||
---@param width integer The width of the outputs, in pixels.
|
---@param width integer The width of the outputs, in pixels.
|
||||||
---@param height integer The height of the outputs, in pixels.
|
---@param height integer The height of the outputs, in pixels.
|
||||||
---@return Output[] outputs All outputs with this resolution.
|
---@return Output[] outputs All outputs with this resolution.
|
||||||
function output.get_by_res(width, height)
|
function output_global.get_by_res(width, height)
|
||||||
SendRequest("GetOutputs")
|
local response = ReadMsg(SendRequest("GetOutputs"))
|
||||||
|
|
||||||
local response = ReadMsg()
|
|
||||||
|
|
||||||
local output_names = response.RequestResponse.response.Outputs.output_names
|
local output_names = response.RequestResponse.response.Outputs.output_names
|
||||||
|
|
||||||
|
@ -251,9 +233,8 @@ end
|
||||||
---local tags = output.get_focused():tags() -- will NOT warn for nil
|
---local tags = output.get_focused():tags() -- will NOT warn for nil
|
||||||
---```
|
---```
|
||||||
---@return Output|nil output The output, or nil if none are focused.
|
---@return Output|nil output The output, or nil if none are focused.
|
||||||
function output.get_focused()
|
function output_global.get_focused()
|
||||||
SendRequest("GetOutputs")
|
local response = ReadMsg(SendRequest("GetOutputs"))
|
||||||
local response = ReadMsg()
|
|
||||||
local output_names = response.RequestResponse.response.Outputs.output_names
|
local output_names = response.RequestResponse.response.Outputs.output_names
|
||||||
|
|
||||||
for _, output_name in pairs(output_names) do
|
for _, output_name in pairs(output_names) do
|
||||||
|
@ -274,7 +255,7 @@ end
|
||||||
---Please note: this function will be run *after* Pinnacle processes your entire config.
|
---Please note: this function will be run *after* Pinnacle processes your entire config.
|
||||||
---For example, if you define tags in `func` but toggle them directly after `connect_for_all`, nothing will happen as the tags haven't been added yet.
|
---For example, if you define tags in `func` but toggle them directly after `connect_for_all`, nothing will happen as the tags haven't been added yet.
|
||||||
---@param func fun(output: Output) The function that will be run.
|
---@param func fun(output: Output) The function that will be run.
|
||||||
function output.connect_for_all(func)
|
function output_global.connect_for_all(func)
|
||||||
---@param args Args
|
---@param args Args
|
||||||
table.insert(CallbackTable, function(args)
|
table.insert(CallbackTable, function(args)
|
||||||
local args = args.ConnectForAllOutputs
|
local args = args.ConnectForAllOutputs
|
||||||
|
@ -290,14 +271,12 @@ end
|
||||||
---Get the output the specified tag is on.
|
---Get the output the specified tag is on.
|
||||||
---@param tag Tag
|
---@param tag Tag
|
||||||
---@return Output|nil
|
---@return Output|nil
|
||||||
function output.get_for_tag(tag)
|
function output_global.get_for_tag(tag)
|
||||||
SendRequest({
|
local response = ReadMsg(SendRequest({
|
||||||
GetTagProps = {
|
GetTagProps = {
|
||||||
tag_id = tag:id(),
|
tag_id = tag:id(),
|
||||||
},
|
},
|
||||||
})
|
}))
|
||||||
|
|
||||||
local response = ReadMsg()
|
|
||||||
local output_name = response.RequestResponse.response.TagProps.output_name
|
local output_name = response.RequestResponse.response.TagProps.output_name
|
||||||
|
|
||||||
if output_name == nil then
|
if output_name == nil then
|
||||||
|
@ -307,4 +286,4 @@ function output.get_for_tag(tag)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return output
|
return output_global
|
||||||
|
|
|
@ -9,6 +9,33 @@ local msgpack = require("msgpack")
|
||||||
|
|
||||||
local SOCKET_PATH = "/tmp/pinnacle_socket"
|
local SOCKET_PATH = "/tmp/pinnacle_socket"
|
||||||
|
|
||||||
|
--[[ rPrint(struct, [limit], [indent]) Recursively print arbitrary data.
|
||||||
|
Set limit (default 100) to stanch infinite loops.
|
||||||
|
Indents tables as [KEY] VALUE, nested tables as [KEY] [KEY]...[KEY] VALUE
|
||||||
|
Set indent ("") to prefix each line: Mytable [KEY] [KEY]...[KEY] VALUE
|
||||||
|
--]]
|
||||||
|
function RPrint(s, l, i) -- recursive Print (structure, limit, indent)
|
||||||
|
l = l or 100
|
||||||
|
i = i or "" -- default item limit, indent string
|
||||||
|
if l < 1 then
|
||||||
|
print("ERROR: Item limit reached.")
|
||||||
|
return l - 1
|
||||||
|
end
|
||||||
|
local ts = type(s)
|
||||||
|
if ts ~= "table" then
|
||||||
|
print(i, ts, s)
|
||||||
|
return l - 1
|
||||||
|
end
|
||||||
|
print(i, ts) -- print "table"
|
||||||
|
for k, v in pairs(s) do -- print "[KEY] VALUE"
|
||||||
|
l = RPrint(v, l, i .. "\t[" .. tostring(k) .. "]")
|
||||||
|
if l < 0 then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return l
|
||||||
|
end
|
||||||
|
|
||||||
---Read the specified number of bytes.
|
---Read the specified number of bytes.
|
||||||
---@param socket_fd integer The socket file descriptor
|
---@param socket_fd integer The socket file descriptor
|
||||||
---@param count integer The amount of bytes to read
|
---@param count integer The amount of bytes to read
|
||||||
|
@ -85,6 +112,7 @@ function pinnacle.setup(config_func)
|
||||||
---This is an internal global function used to send serialized messages to the Pinnacle server.
|
---This is an internal global function used to send serialized messages to the Pinnacle server.
|
||||||
---@param data Msg
|
---@param data Msg
|
||||||
function SendMsg(data)
|
function SendMsg(data)
|
||||||
|
-- RPrint(data)
|
||||||
local encoded = msgpack.encode(data)
|
local encoded = msgpack.encode(data)
|
||||||
assert(encoded)
|
assert(encoded)
|
||||||
-- print(encoded)
|
-- print(encoded)
|
||||||
|
@ -93,54 +121,98 @@ function pinnacle.setup(config_func)
|
||||||
socket.send(socket_fd, encoded)
|
socket.send(socket_fd, encoded)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local request_id = 0
|
||||||
|
---Get the next request id.
|
||||||
|
---@return integer
|
||||||
|
local function next_request_id()
|
||||||
|
local ret = request_id
|
||||||
|
request_id = request_id + 1
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
---@type table<integer, IncomingMsg>
|
||||||
|
local unread_req_msgs = {}
|
||||||
|
---@type table<integer, IncomingMsg>
|
||||||
|
local unread_cb_msgs = {}
|
||||||
|
|
||||||
---This is an internal global function used to send requests to the Pinnacle server for information.
|
---This is an internal global function used to send requests to the Pinnacle server for information.
|
||||||
---@param data Request
|
---@param data _Request
|
||||||
|
---@return RequestId
|
||||||
function SendRequest(data)
|
function SendRequest(data)
|
||||||
|
local req_id = next_request_id()
|
||||||
SendMsg({
|
SendMsg({
|
||||||
Request = data,
|
Request = {
|
||||||
|
request_id = req_id,
|
||||||
|
request = data,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
return req_id
|
||||||
end
|
end
|
||||||
|
|
||||||
---This is an internal global function used to read messages sent from the server.
|
---This is an internal global function used to read messages sent from the server.
|
||||||
---These are used to call user-defined functions and provide requested information.
|
---These are used to call user-defined functions and provide requested information.
|
||||||
function ReadMsg()
|
---@return IncomingMsg
|
||||||
local msg_len_bytes, err_msg, err_num = read_exact(socket_fd, 4)
|
---@param req_id integer? A request id if you're looking for that specific message.
|
||||||
assert(msg_len_bytes)
|
function ReadMsg(req_id)
|
||||||
|
while true do
|
||||||
|
if req_id then
|
||||||
|
if unread_req_msgs[req_id] then
|
||||||
|
local msg = unread_req_msgs[req_id]
|
||||||
|
unread_req_msgs[req_id] = nil -- INFO: is this a reference?
|
||||||
|
return msg
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- TODO: break here if error in read_exact
|
local msg_len_bytes, err_msg, err_num = read_exact(socket_fd, 4)
|
||||||
|
assert(msg_len_bytes)
|
||||||
|
|
||||||
---@type integer
|
-- TODO: break here if error in read_exact
|
||||||
local msg_len = string.unpack("=I4", msg_len_bytes)
|
|
||||||
-- print(msg_len)
|
|
||||||
|
|
||||||
local msg_bytes, err_msg2, err_num2 = read_exact(socket_fd, msg_len)
|
---@type integer
|
||||||
assert(msg_bytes)
|
local msg_len = string.unpack("=I4", msg_len_bytes)
|
||||||
-- print(msg_bytes)
|
-- print(msg_len)
|
||||||
|
|
||||||
---@type IncomingMsg
|
local msg_bytes, err_msg2, err_num2 = read_exact(socket_fd, msg_len)
|
||||||
local tb = msgpack.decode(msg_bytes)
|
assert(msg_bytes)
|
||||||
-- print(msg_bytes)
|
-- print(msg_bytes)
|
||||||
|
|
||||||
return tb
|
---@type IncomingMsg
|
||||||
|
local inc_msg = msgpack.decode(msg_bytes)
|
||||||
|
-- print(msg_bytes)
|
||||||
|
|
||||||
|
if req_id then
|
||||||
|
if inc_msg.CallCallback then
|
||||||
|
unread_cb_msgs[inc_msg.CallCallback.callback_id] = inc_msg
|
||||||
|
elseif inc_msg.RequestResponse.request_id ~= req_id then
|
||||||
|
unread_req_msgs[inc_msg.RequestResponse.request_id] = inc_msg
|
||||||
|
else
|
||||||
|
return inc_msg
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return inc_msg
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
config_func(pinnacle)
|
config_func(pinnacle)
|
||||||
|
|
||||||
while true do
|
while true do
|
||||||
local tb = ReadMsg()
|
for cb_id, inc_msg in pairs(unread_cb_msgs) do
|
||||||
|
CallbackTable[inc_msg.CallCallback.callback_id](inc_msg.CallCallback.args)
|
||||||
if tb.CallCallback and tb.CallCallback.callback_id then
|
unread_cb_msgs[cb_id] = nil -- INFO: does this shift the table and frick everything up?
|
||||||
if tb.CallCallback.args then -- TODO: can just inline
|
|
||||||
CallbackTable[tb.CallCallback.callback_id](tb.CallCallback.args)
|
|
||||||
else
|
|
||||||
CallbackTable[tb.CallCallback.callback_id](nil)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- if tb.RequestResponse then
|
local inc_msg = ReadMsg()
|
||||||
-- local req_id = tb.RequestResponse.request_id
|
|
||||||
-- Requests[req_id] = tb.RequestResponse.response
|
assert(inc_msg.CallCallback) -- INFO: is this gucci or no
|
||||||
-- end
|
|
||||||
|
if inc_msg.CallCallback and inc_msg.CallCallback.callback_id then
|
||||||
|
if inc_msg.CallCallback.args then -- TODO: can just inline
|
||||||
|
CallbackTable[inc_msg.CallCallback.callback_id](inc_msg.CallCallback.args)
|
||||||
|
else
|
||||||
|
CallbackTable[inc_msg.CallCallback.callback_id](nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
206
api/lua/tag.lua
206
api/lua/tag.lua
|
@ -4,7 +4,8 @@
|
||||||
--
|
--
|
||||||
-- SPDX-License-Identifier: MPL-2.0
|
-- SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
local tag = {}
|
---@class TagGlobal
|
||||||
|
local tag_global = {}
|
||||||
|
|
||||||
---@alias Layout
|
---@alias Layout
|
||||||
---| "MasterStack" # One master window on the left with all other windows stacked to the right.
|
---| "MasterStack" # One master window on the left with all other windows stacked to the right.
|
||||||
|
@ -17,7 +18,7 @@ local tag = {}
|
||||||
|
|
||||||
---@class Tag
|
---@class Tag
|
||||||
---@field private _id integer The internal id of this tag.
|
---@field private _id integer The internal id of this tag.
|
||||||
local tg = {}
|
local tag = {}
|
||||||
|
|
||||||
---@param tag_id integer
|
---@param tag_id integer
|
||||||
---@return Tag
|
---@return Tag
|
||||||
|
@ -25,67 +26,66 @@ local function new_tag(tag_id)
|
||||||
---@type Tag
|
---@type Tag
|
||||||
local t = { _id = tag_id }
|
local t = { _id = tag_id }
|
||||||
-- Copy functions over
|
-- Copy functions over
|
||||||
for k, v in pairs(tg) do
|
for k, v in pairs(tag) do
|
||||||
t[k] = v
|
t[k] = v
|
||||||
end
|
end
|
||||||
|
|
||||||
return t
|
return t
|
||||||
end
|
end
|
||||||
|
|
||||||
---Switch to this tag.
|
|
||||||
function tg:switch_to()
|
|
||||||
tag.switch_to(self)
|
|
||||||
end
|
|
||||||
|
|
||||||
---Toggle this tag.
|
|
||||||
function tg:toggle()
|
|
||||||
tag.toggle(self)
|
|
||||||
end
|
|
||||||
|
|
||||||
---Get this tag's internal id.
|
---Get this tag's internal id.
|
||||||
---@return integer
|
---@return integer
|
||||||
function tg:id()
|
function tag:id()
|
||||||
return self._id
|
return self._id
|
||||||
end
|
end
|
||||||
|
|
||||||
---Get this tag's active status.
|
---Get this tag's active status.
|
||||||
---@return boolean|nil active `true` if the tag is active, `false` if not, and `nil` if the tag doesn't exist.
|
---@return boolean|nil active `true` if the tag is active, `false` if not, and `nil` if the tag doesn't exist.
|
||||||
function tg:active()
|
function tag:active()
|
||||||
SendRequest({
|
local response = ReadMsg(SendRequest({
|
||||||
GetTagProps = {
|
GetTagProps = {
|
||||||
tag_id = self._id,
|
tag_id = self._id,
|
||||||
},
|
},
|
||||||
})
|
}))
|
||||||
|
|
||||||
local response = ReadMsg()
|
|
||||||
local active = response.RequestResponse.response.TagProps.active
|
local active = response.RequestResponse.response.TagProps.active
|
||||||
return active
|
return active
|
||||||
end
|
end
|
||||||
|
|
||||||
---Get this tag's name.
|
---Get this tag's name.
|
||||||
---@return string|nil name The name of this tag, or nil if it doesn't exist.
|
---@return string|nil name The name of this tag, or nil if it doesn't exist.
|
||||||
function tg:name()
|
function tag:name()
|
||||||
SendRequest({
|
local response = ReadMsg(SendRequest({
|
||||||
GetTagProps = {
|
GetTagProps = {
|
||||||
tag_id = self._id,
|
tag_id = self._id,
|
||||||
},
|
},
|
||||||
})
|
}))
|
||||||
|
|
||||||
local response = ReadMsg()
|
|
||||||
local name = response.RequestResponse.response.TagProps.name
|
local name = response.RequestResponse.response.TagProps.name
|
||||||
return name
|
return name
|
||||||
end
|
end
|
||||||
|
|
||||||
---Get this tag's output.
|
---Get this tag's output.
|
||||||
---@return Output|nil output The output this tag is on, or nil if the tag doesn't exist.
|
---@return Output|nil output The output this tag is on, or nil if the tag doesn't exist.
|
||||||
function tg:output()
|
function tag:output()
|
||||||
return require("output").get_for_tag(self)
|
return require("output").get_for_tag(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---Switch to this tag.
|
||||||
|
function tag:switch_to()
|
||||||
|
tag_global.switch_to(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
---Toggle this tag.
|
||||||
|
function tag:toggle()
|
||||||
|
tag_global.toggle(self)
|
||||||
|
end
|
||||||
|
|
||||||
---Set this tag's layout.
|
---Set this tag's layout.
|
||||||
---@param layout Layout
|
---@param layout Layout
|
||||||
function tg:set_layout(layout)
|
function tag:set_layout(layout)
|
||||||
tag.set_layout(self, layout)
|
local name = self:name()
|
||||||
|
if name ~= nil then
|
||||||
|
tag_global.set_layout(name, layout)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-----------------------------------------------------------
|
-----------------------------------------------------------
|
||||||
|
@ -110,7 +110,7 @@ end
|
||||||
---@param output Output The output you want these tags to be added to.
|
---@param output Output The output you want these tags to be added to.
|
||||||
---@param ... string The names of the new tags you want to add.
|
---@param ... string The names of the new tags you want to add.
|
||||||
---@overload fun(output: Output, tag_names: string[])
|
---@overload fun(output: Output, tag_names: string[])
|
||||||
function tag.add(output, ...)
|
function tag_global.add(output, ...)
|
||||||
local varargs = { ... }
|
local varargs = { ... }
|
||||||
if type(varargs[1]) == "string" then
|
if type(varargs[1]) == "string" then
|
||||||
local tag_names = varargs
|
local tag_names = varargs
|
||||||
|
@ -145,17 +145,43 @@ end
|
||||||
---tag.toggle("2", op)
|
---tag.toggle("2", op)
|
||||||
----- will cause windows on both tags 1 and 2 to be displayed at the same time.
|
----- will cause windows on both tags 1 and 2 to be displayed at the same time.
|
||||||
---```
|
---```
|
||||||
---@param t Tag
|
---@param name string The name of the tag.
|
||||||
function tag.toggle(t)
|
---@param output Output? The output.
|
||||||
SendMsg({
|
---@overload fun(t: Tag)
|
||||||
ToggleTag = {
|
function tag_global.toggle(name, output)
|
||||||
tag_id = t:id(),
|
if type(name) == "table" then
|
||||||
},
|
SendMsg({
|
||||||
})
|
ToggleTag = {
|
||||||
|
tag_id = name--[[@as Tag]]:id(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local output = output or require("output").get_focused()
|
||||||
|
|
||||||
|
if output == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
print("before tag_global.get_by_name")
|
||||||
|
local tags = tag_global.get_by_name(name)
|
||||||
|
print("after tag_global.get_by_name")
|
||||||
|
for _, t in pairs(tags) do
|
||||||
|
if t:output() and t:output():name() == output:name() then
|
||||||
|
SendMsg({
|
||||||
|
ToggleTag = {
|
||||||
|
tag_id = t:id(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
---Switch to a tag on the specified output, deactivating any other active tags on it.
|
---Switch to a tag on the specified output, deactivating any other active tags on it.
|
||||||
---If `output` is not specified, this uses the currently focused output instead.
|
---If `output` is not specified, this uses the currently focused output instead.
|
||||||
|
---Alternatively, provide a tag object instead of a name and output.
|
||||||
---
|
---
|
||||||
---This is used to replicate what a traditional workspace is on some other Wayland compositors.
|
---This is used to replicate what a traditional workspace is on some other Wayland compositors.
|
||||||
---
|
---
|
||||||
|
@ -164,25 +190,73 @@ end
|
||||||
---```lua
|
---```lua
|
||||||
---tag.switch_to("3") -- Switches to and displays *only* windows on tag 3
|
---tag.switch_to("3") -- Switches to and displays *only* windows on tag 3
|
||||||
---```
|
---```
|
||||||
---@param t Tag
|
---@param name string The name of the tag.
|
||||||
function tag.switch_to(t)
|
---@param output Output? The output.
|
||||||
SendMsg({
|
---@overload fun(t: Tag)
|
||||||
SwitchToTag = {
|
function tag_global.switch_to(name, output)
|
||||||
tag_id = t:id(),
|
if type(name) == "table" then
|
||||||
},
|
SendMsg({
|
||||||
})
|
SwitchToTag = {
|
||||||
|
tag_id = name--[[@as Tag]]:id(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local output = output or require("output").get_focused()
|
||||||
|
|
||||||
|
if output == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local tags = tag_global.get_by_name(name)
|
||||||
|
for _, t in pairs(tags) do
|
||||||
|
if t:output() and t:output():name() == output:name() then
|
||||||
|
SendMsg({
|
||||||
|
SwitchToTag = {
|
||||||
|
tag_id = t:id(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
---Set a layout for the specified tag.
|
---Set a layout for the tag on the specified output. If no output is provided, set it for the tag on the currently focused one.
|
||||||
---@param t Tag
|
---Alternatively, provide a tag object instead of a name and output.
|
||||||
---@param layout Layout
|
---@param name string The name of the tag.
|
||||||
function tag.set_layout(t, layout)
|
---@param layout Layout The layout.
|
||||||
SendMsg({
|
---@param output Output? The output.
|
||||||
SetLayout = {
|
---@overload fun(t: Tag, layout: Layout)
|
||||||
tag_id = t:id(),
|
function tag_global.set_layout(name, layout, output)
|
||||||
layout = layout,
|
if type(name) == "table" then
|
||||||
},
|
SendMsg({
|
||||||
})
|
SetLayout = {
|
||||||
|
tag_id = name--[[@as Tag]]:id(),
|
||||||
|
layout = layout,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local output = output or require("output").get_focused()
|
||||||
|
|
||||||
|
if output == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local tags = tag_global.get_by_name(name)
|
||||||
|
for _, t in pairs(tags) do
|
||||||
|
if t:output() and t:output():name() == output:name() then
|
||||||
|
SendMsg({
|
||||||
|
SetLayout = {
|
||||||
|
tag_id = t:id(),
|
||||||
|
layout = layout,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
---Get all tags on the specified output.
|
---Get all tags on the specified output.
|
||||||
|
@ -195,14 +269,12 @@ end
|
||||||
---```
|
---```
|
||||||
---@param output Output
|
---@param output Output
|
||||||
---@return Tag[]
|
---@return Tag[]
|
||||||
function tag.get_on_output(output)
|
function tag_global.get_on_output(output)
|
||||||
SendRequest({
|
local response = ReadMsg(SendRequest({
|
||||||
GetOutputProps = {
|
GetOutputProps = {
|
||||||
output_name = output:name(),
|
output_name = output:name(),
|
||||||
},
|
},
|
||||||
})
|
}))
|
||||||
|
|
||||||
local response = ReadMsg()
|
|
||||||
|
|
||||||
local tag_ids = response.RequestResponse.response.OutputProps.tag_ids
|
local tag_ids = response.RequestResponse.response.OutputProps.tag_ids
|
||||||
|
|
||||||
|
@ -223,18 +295,13 @@ end
|
||||||
---Get all tags with this name across all outputs.
|
---Get all tags with this name across all outputs.
|
||||||
---@param name string The name of the tags you want.
|
---@param name string The name of the tags you want.
|
||||||
---@return Tag[]
|
---@return Tag[]
|
||||||
function tag.get_by_name(name)
|
function tag_global.get_by_name(name)
|
||||||
SendRequest("GetTags")
|
local t_s = tag_global.get_all()
|
||||||
|
|
||||||
local response = ReadMsg()
|
|
||||||
|
|
||||||
local tag_ids = response.RequestResponse.response.Tags.tag_ids
|
|
||||||
|
|
||||||
---@type Tag[]
|
---@type Tag[]
|
||||||
local tags = {}
|
local tags = {}
|
||||||
|
|
||||||
for _, tag_id in pairs(tag_ids) do
|
for _, t in pairs(t_s) do
|
||||||
local t = new_tag(tag_id)
|
|
||||||
if t:name() == name then
|
if t:name() == name then
|
||||||
table.insert(tags, t)
|
table.insert(tags, t)
|
||||||
end
|
end
|
||||||
|
@ -245,10 +312,9 @@ end
|
||||||
|
|
||||||
---Get all tags across all ouptuts.
|
---Get all tags across all ouptuts.
|
||||||
---@return Tag[]
|
---@return Tag[]
|
||||||
function tag.get_all()
|
function tag_global.get_all()
|
||||||
SendRequest("GetTags")
|
local response = ReadMsg(SendRequest("GetTags"))
|
||||||
|
RPrint(response)
|
||||||
local response = ReadMsg()
|
|
||||||
|
|
||||||
local tag_ids = response.RequestResponse.response.Tags.tag_ids
|
local tag_ids = response.RequestResponse.response.Tags.tag_ids
|
||||||
|
|
||||||
|
@ -262,4 +328,4 @@ function tag.get_all()
|
||||||
return tags
|
return tags
|
||||||
end
|
end
|
||||||
|
|
||||||
return tag
|
return tag_global
|
||||||
|
|
|
@ -4,19 +4,24 @@
|
||||||
--
|
--
|
||||||
-- SPDX-License-Identifier: MPL-2.0
|
-- SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
---@class Window
|
---@class WindowGlobal
|
||||||
---@field private id integer The internal id of this window
|
local window_global = {}
|
||||||
local win = {}
|
|
||||||
|
|
||||||
---@param props Window
|
---@class Window
|
||||||
|
---@field private _id integer The internal id of this window
|
||||||
|
local window = {}
|
||||||
|
|
||||||
|
---@param window_id WindowId
|
||||||
---@return Window
|
---@return Window
|
||||||
local function new_window(props)
|
local function new_window(window_id)
|
||||||
|
---@type Window
|
||||||
|
local w = { _id = window_id }
|
||||||
-- Copy functions over
|
-- Copy functions over
|
||||||
for k, v in pairs(win) do
|
for k, v in pairs(window) do
|
||||||
props[k] = v
|
w[k] = v
|
||||||
end
|
end
|
||||||
|
|
||||||
return props
|
return w
|
||||||
end
|
end
|
||||||
|
|
||||||
---Set a window's size.
|
---Set a window's size.
|
||||||
|
@ -28,10 +33,10 @@ end
|
||||||
---window.get_focused():set_size({}) -- do absolutely nothing useful
|
---window.get_focused():set_size({}) -- do absolutely nothing useful
|
||||||
---```
|
---```
|
||||||
---@param size { w: integer?, h: integer? }
|
---@param size { w: integer?, h: integer? }
|
||||||
function win:set_size(size)
|
function window:set_size(size)
|
||||||
SendMsg({
|
SendMsg({
|
||||||
SetWindowSize = {
|
SetWindowSize = {
|
||||||
window_id = self.id,
|
window_id = self._id,
|
||||||
width = size.w,
|
width = size.w,
|
||||||
height = size.h,
|
height = size.h,
|
||||||
},
|
},
|
||||||
|
@ -46,14 +51,11 @@ end
|
||||||
---window.get_focused():move_to_tag("5")
|
---window.get_focused():move_to_tag("5")
|
||||||
----- ...will make the window only appear on tag 5.
|
----- ...will make the window only appear on tag 5.
|
||||||
---```
|
---```
|
||||||
---@param t Tag
|
---@param name string
|
||||||
function win:move_to_tag(t)
|
---@param output Output?
|
||||||
SendMsg({
|
---@overload fun(self: self, t: Tag)
|
||||||
MoveWindowToTag = {
|
function window:move_to_tag(name, output)
|
||||||
window_id = self.id,
|
window_global.move_to_tag(self, name, output)
|
||||||
tag_id = t:id(),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
end
|
end
|
||||||
|
|
||||||
---Toggle the specified tag for this window.
|
---Toggle the specified tag for this window.
|
||||||
|
@ -66,14 +68,11 @@ end
|
||||||
---window.get_focused():toggle_tag("2")
|
---window.get_focused():toggle_tag("2")
|
||||||
----- ...will also make the window appear on tag 2.
|
----- ...will also make the window appear on tag 2.
|
||||||
---```
|
---```
|
||||||
---@param t Tag
|
---@param name string
|
||||||
function win:toggle_tag(t)
|
---@param output Output?
|
||||||
SendMsg({
|
---@overload fun(self: self, t: Tag)
|
||||||
ToggleTagOnWindow = {
|
function window:toggle_tag(name, output)
|
||||||
window_id = self.id,
|
window_global.toggle_tag(self, name, output)
|
||||||
tag_id = t:id(),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
end
|
end
|
||||||
|
|
||||||
---Close this window.
|
---Close this window.
|
||||||
|
@ -85,10 +84,10 @@ end
|
||||||
---```lua
|
---```lua
|
||||||
---window.get_focused():close() -- close the currently focused window
|
---window.get_focused():close() -- close the currently focused window
|
||||||
---```
|
---```
|
||||||
function win:close()
|
function window:close()
|
||||||
SendMsg({
|
SendMsg({
|
||||||
CloseWindow = {
|
CloseWindow = {
|
||||||
window_id = self.id,
|
window_id = self._id,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
@ -99,10 +98,10 @@ end
|
||||||
---```lua
|
---```lua
|
||||||
---window.get_focused():toggle_floating() -- toggles the focused window between tiled and floating
|
---window.get_focused():toggle_floating() -- toggles the focused window between tiled and floating
|
||||||
---```
|
---```
|
||||||
function win:toggle_floating()
|
function window:toggle_floating()
|
||||||
SendMsg({
|
SendMsg({
|
||||||
ToggleFloating = {
|
ToggleFloating = {
|
||||||
window_id = self.id,
|
window_id = self._id,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
@ -116,14 +115,12 @@ end
|
||||||
----- ...should have size equal to `{ w = 3840, h = 2160 }`.
|
----- ...should have size equal to `{ w = 3840, h = 2160 }`.
|
||||||
---```
|
---```
|
||||||
---@return { w: integer, h: integer }|nil size The size of the window, or nil if it doesn't exist.
|
---@return { w: integer, h: integer }|nil size The size of the window, or nil if it doesn't exist.
|
||||||
function win:size()
|
function window:size()
|
||||||
SendRequest({
|
local response = ReadMsg(SendRequest({
|
||||||
GetWindowProps = {
|
GetWindowProps = {
|
||||||
window_id = self.id,
|
window_id = self._id,
|
||||||
},
|
},
|
||||||
})
|
}))
|
||||||
|
|
||||||
local response = ReadMsg()
|
|
||||||
local size = response.RequestResponse.response.WindowProps.size
|
local size = response.RequestResponse.response.WindowProps.size
|
||||||
if size == nil then
|
if size == nil then
|
||||||
return nil
|
return nil
|
||||||
|
@ -149,14 +146,12 @@ end
|
||||||
----- ...should have loc equal to `{ x = 1920, y = 0 }`.
|
----- ...should have loc equal to `{ x = 1920, y = 0 }`.
|
||||||
---```
|
---```
|
||||||
---@return { x: integer, y: integer }|nil loc The location of the window, or nil if it's not on-screen or alive.
|
---@return { x: integer, y: integer }|nil loc The location of the window, or nil if it's not on-screen or alive.
|
||||||
function win:loc()
|
function window:loc()
|
||||||
SendRequest({
|
local response = ReadMsg(SendRequest({
|
||||||
GetWindowProps = {
|
GetWindowProps = {
|
||||||
window_id = self.id,
|
window_id = self._id,
|
||||||
},
|
},
|
||||||
})
|
}))
|
||||||
|
|
||||||
local response = ReadMsg()
|
|
||||||
local loc = response.RequestResponse.response.WindowProps.loc
|
local loc = response.RequestResponse.response.WindowProps.loc
|
||||||
if loc == nil then
|
if loc == nil then
|
||||||
return nil
|
return nil
|
||||||
|
@ -177,14 +172,12 @@ end
|
||||||
----- ...should print "Alacritty".
|
----- ...should print "Alacritty".
|
||||||
---```
|
---```
|
||||||
---@return string|nil class This window's class, or nil if it doesn't exist.
|
---@return string|nil class This window's class, or nil if it doesn't exist.
|
||||||
function win:class()
|
function window:class()
|
||||||
SendRequest({
|
local response = ReadMsg(SendRequest({
|
||||||
GetWindowProps = {
|
GetWindowProps = {
|
||||||
window_id = self.id,
|
window_id = self._id,
|
||||||
},
|
},
|
||||||
})
|
}))
|
||||||
|
|
||||||
local response = ReadMsg()
|
|
||||||
local class = response.RequestResponse.response.WindowProps.class
|
local class = response.RequestResponse.response.WindowProps.class
|
||||||
return class
|
return class
|
||||||
end
|
end
|
||||||
|
@ -198,14 +191,12 @@ end
|
||||||
----- ...should print the directory Alacritty is in or what it's running (what's in its title bar).
|
----- ...should print the directory Alacritty is in or what it's running (what's in its title bar).
|
||||||
---```
|
---```
|
||||||
---@return string|nil title This window's title, or nil if it doesn't exist.
|
---@return string|nil title This window's title, or nil if it doesn't exist.
|
||||||
function win:title()
|
function window:title()
|
||||||
SendRequest({
|
local response = ReadMsg(SendRequest({
|
||||||
GetWindowProps = {
|
GetWindowProps = {
|
||||||
window_id = self.id,
|
window_id = self._id,
|
||||||
},
|
},
|
||||||
})
|
}))
|
||||||
|
|
||||||
local response = ReadMsg()
|
|
||||||
local title = response.RequestResponse.response.WindowProps.title
|
local title = response.RequestResponse.response.WindowProps.title
|
||||||
return title
|
return title
|
||||||
end
|
end
|
||||||
|
@ -219,14 +210,12 @@ end
|
||||||
----- ...should print `true`.
|
----- ...should print `true`.
|
||||||
---```
|
---```
|
||||||
---@return boolean|nil floating `true` if it's floating, `false` if it's tiled, or nil if it doesn't exist.
|
---@return boolean|nil floating `true` if it's floating, `false` if it's tiled, or nil if it doesn't exist.
|
||||||
function win:floating()
|
function window:floating()
|
||||||
SendRequest({
|
local response = ReadMsg(SendRequest({
|
||||||
GetWindowProps = {
|
GetWindowProps = {
|
||||||
window_id = self.id,
|
window_id = self._id,
|
||||||
},
|
},
|
||||||
})
|
}))
|
||||||
|
|
||||||
local response = ReadMsg()
|
|
||||||
local floating = response.RequestResponse.response.WindowProps.floating
|
local floating = response.RequestResponse.response.WindowProps.floating
|
||||||
return floating
|
return floating
|
||||||
end
|
end
|
||||||
|
@ -238,28 +227,28 @@ end
|
||||||
---print(window.get_focused():focused()) -- should print `true`.
|
---print(window.get_focused():focused()) -- should print `true`.
|
||||||
---```
|
---```
|
||||||
---@return boolean|nil floating `true` if it's floating, `false` if it's tiled, or nil if it doesn't exist.
|
---@return boolean|nil floating `true` if it's floating, `false` if it's tiled, or nil if it doesn't exist.
|
||||||
function win:focused()
|
function window:focused()
|
||||||
SendRequest({
|
local response = ReadMsg(SendRequest({
|
||||||
GetWindowProps = {
|
GetWindowProps = {
|
||||||
window_id = self.id,
|
window_id = self._id,
|
||||||
},
|
},
|
||||||
})
|
}))
|
||||||
|
|
||||||
local response = ReadMsg()
|
|
||||||
local focused = response.RequestResponse.response.WindowProps.focused
|
local focused = response.RequestResponse.response.WindowProps.focused
|
||||||
return focused
|
return focused
|
||||||
end
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
---@return WindowId
|
||||||
|
function window:id()
|
||||||
|
return self._id
|
||||||
|
end
|
||||||
|
|
||||||
---@class WindowGlobal
|
-------------------------------------------------------------------
|
||||||
local window = {}
|
|
||||||
|
|
||||||
---Get all windows with the specified class (usually the name of the application).
|
---Get all windows with the specified class (usually the name of the application).
|
||||||
---@param class string The class. For example, Alacritty's class is "Alacritty".
|
---@param class string The class. For example, Alacritty's class is "Alacritty".
|
||||||
---@return Window[]
|
---@return Window[]
|
||||||
function window.get_by_class(class)
|
function window_global.get_by_class(class)
|
||||||
local windows = window.get_all()
|
local windows = window_global.get_all()
|
||||||
|
|
||||||
---@type Window[]
|
---@type Window[]
|
||||||
local windows_ret = {}
|
local windows_ret = {}
|
||||||
|
@ -275,8 +264,8 @@ end
|
||||||
---Get all windows with the specified title.
|
---Get all windows with the specified title.
|
||||||
---@param title string The title.
|
---@param title string The title.
|
||||||
---@return Window[]
|
---@return Window[]
|
||||||
function window.get_by_title(title)
|
function window_global.get_by_title(title)
|
||||||
local windows = window.get_all()
|
local windows = window_global.get_all()
|
||||||
|
|
||||||
---@type Window[]
|
---@type Window[]
|
||||||
local windows_ret = {}
|
local windows_ret = {}
|
||||||
|
@ -291,8 +280,8 @@ end
|
||||||
|
|
||||||
---Get the currently focused window.
|
---Get the currently focused window.
|
||||||
---@return Window|nil
|
---@return Window|nil
|
||||||
function window.get_focused()
|
function window_global.get_focused()
|
||||||
local windows = window.get_all()
|
local windows = window_global.get_all()
|
||||||
|
|
||||||
for _, w in pairs(windows) do
|
for _, w in pairs(windows) do
|
||||||
if w:focused() then
|
if w:focused() then
|
||||||
|
@ -305,16 +294,85 @@ end
|
||||||
|
|
||||||
---Get all windows.
|
---Get all windows.
|
||||||
---@return Window[]
|
---@return Window[]
|
||||||
function window.get_all()
|
function window_global.get_all()
|
||||||
SendRequest("GetWindows")
|
local window_ids = ReadMsg(SendRequest("GetWindows")).RequestResponse.response.Windows.window_ids
|
||||||
|
|
||||||
local window_ids = ReadMsg().RequestResponse.response.Windows.window_ids
|
|
||||||
---@type Window[]
|
---@type Window[]
|
||||||
local windows = {}
|
local windows = {}
|
||||||
for _, window_id in pairs(window_ids) do
|
for _, window_id in pairs(window_ids) do
|
||||||
table.insert(windows, new_window({ id = window_id }))
|
table.insert(windows, new_window(window_id))
|
||||||
end
|
end
|
||||||
return windows
|
return windows
|
||||||
end
|
end
|
||||||
|
|
||||||
return window
|
---comment
|
||||||
|
---@param w Window
|
||||||
|
---@param name string
|
||||||
|
---@param output Output?
|
||||||
|
function window_global.toggle_tag(w, name, output)
|
||||||
|
if type(name) == "table" then
|
||||||
|
SendMsg({
|
||||||
|
ToggleTagOnWindow = {
|
||||||
|
window_id = w:id(),
|
||||||
|
tag_id = name--[[@as Tag]]:id(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local output = output or require("output").get_focused()
|
||||||
|
|
||||||
|
if output == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local tags = require("tag").get_by_name(name)
|
||||||
|
for _, t in pairs(tags) do
|
||||||
|
if t:output() and t:output():name() == output:name() then
|
||||||
|
SendMsg({
|
||||||
|
ToggleTagOnWindow = {
|
||||||
|
window_id = w:id(),
|
||||||
|
tag_id = t:id(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---comment
|
||||||
|
---@param w Window
|
||||||
|
---@param name string
|
||||||
|
---@param output Output?
|
||||||
|
---@overload fun(w: Window, t: Tag)
|
||||||
|
function window_global.move_to_tag(w, name, output)
|
||||||
|
if type(name) == "table" then
|
||||||
|
SendMsg({
|
||||||
|
MoveWindowToTag = {
|
||||||
|
window_id = w:id(),
|
||||||
|
tag_id = name--[[@as Tag]]:id(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local output = output or require("output").get_focused()
|
||||||
|
|
||||||
|
if output == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local tags = require("tag").get_by_name(name)
|
||||||
|
for _, t in pairs(tags) do
|
||||||
|
if t:output() and t:output():name() == output:name() then
|
||||||
|
SendMsg({
|
||||||
|
MoveWindowToTag = {
|
||||||
|
window_id = w:id(),
|
||||||
|
tag_id = t:id(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return window_global
|
||||||
|
|
|
@ -112,7 +112,7 @@ pub fn send_to_client(
|
||||||
stream: &mut UnixStream,
|
stream: &mut UnixStream,
|
||||||
msg: &OutgoingMsg,
|
msg: &OutgoingMsg,
|
||||||
) -> Result<(), rmp_serde::encode::Error> {
|
) -> Result<(), rmp_serde::encode::Error> {
|
||||||
// tracing::debug!("Sending {msg:?}");
|
tracing::debug!("Sending {msg:?}");
|
||||||
let msg = rmp_serde::to_vec_named(msg)?;
|
let msg = rmp_serde::to_vec_named(msg)?;
|
||||||
let msg_len = msg.len() as u32;
|
let msg_len = msg.len() as u32;
|
||||||
let bytes = msg_len.to_ne_bytes();
|
let bytes = msg_len.to_ne_bytes();
|
||||||
|
|
|
@ -85,11 +85,14 @@ pub enum Msg {
|
||||||
/// Quit the compositor.
|
/// Quit the compositor.
|
||||||
Quit,
|
Quit,
|
||||||
|
|
||||||
Request(Request),
|
Request {
|
||||||
|
request_id: RequestId,
|
||||||
|
request: Request,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
||||||
pub struct RequestId(pub u32);
|
pub struct RequestId(u32);
|
||||||
|
|
||||||
#[allow(clippy::enum_variant_names)]
|
#[allow(clippy::enum_variant_names)]
|
||||||
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
||||||
|
@ -158,6 +161,7 @@ pub enum OutgoingMsg {
|
||||||
args: Option<Args>,
|
args: Option<Args>,
|
||||||
},
|
},
|
||||||
RequestResponse {
|
RequestResponse {
|
||||||
|
request_id: RequestId,
|
||||||
response: RequestResponse,
|
response: RequestResponse,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
18
src/state.rs
18
src/state.rs
|
@ -16,7 +16,7 @@ use std::{
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
api::{
|
api::{
|
||||||
msg::{Args, CallbackId, Msg, OutgoingMsg, Request, RequestResponse},
|
msg::{Args, CallbackId, Msg, OutgoingMsg, Request, RequestId, RequestResponse},
|
||||||
PinnacleSocketSource,
|
PinnacleSocketSource,
|
||||||
},
|
},
|
||||||
focus::FocusState,
|
focus::FocusState,
|
||||||
|
@ -259,13 +259,16 @@ impl<B: Backend> State<B> {
|
||||||
self.loop_signal.stop();
|
self.loop_signal.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
Msg::Request(request) => {
|
Msg::Request {
|
||||||
self.handle_request(request);
|
request_id,
|
||||||
|
request,
|
||||||
|
} => {
|
||||||
|
self.handle_request(request_id, request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_request(&mut self, request: Request) {
|
fn handle_request(&mut self, request_id: RequestId, request: Request) {
|
||||||
let stream = self
|
let stream = self
|
||||||
.api_state
|
.api_state
|
||||||
.stream
|
.stream
|
||||||
|
@ -284,6 +287,7 @@ impl<B: Backend> State<B> {
|
||||||
crate::api::send_to_client(
|
crate::api::send_to_client(
|
||||||
&mut stream,
|
&mut stream,
|
||||||
&OutgoingMsg::RequestResponse {
|
&OutgoingMsg::RequestResponse {
|
||||||
|
request_id,
|
||||||
response: RequestResponse::Windows { window_ids },
|
response: RequestResponse::Windows { window_ids },
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -320,6 +324,7 @@ impl<B: Backend> State<B> {
|
||||||
crate::api::send_to_client(
|
crate::api::send_to_client(
|
||||||
&mut stream,
|
&mut stream,
|
||||||
&OutgoingMsg::RequestResponse {
|
&OutgoingMsg::RequestResponse {
|
||||||
|
request_id,
|
||||||
response: RequestResponse::WindowProps {
|
response: RequestResponse::WindowProps {
|
||||||
size,
|
size,
|
||||||
loc,
|
loc,
|
||||||
|
@ -341,6 +346,7 @@ impl<B: Backend> State<B> {
|
||||||
crate::api::send_to_client(
|
crate::api::send_to_client(
|
||||||
&mut stream,
|
&mut stream,
|
||||||
&OutgoingMsg::RequestResponse {
|
&OutgoingMsg::RequestResponse {
|
||||||
|
request_id,
|
||||||
response: RequestResponse::Outputs { output_names },
|
response: RequestResponse::Outputs { output_names },
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -385,6 +391,7 @@ impl<B: Backend> State<B> {
|
||||||
crate::api::send_to_client(
|
crate::api::send_to_client(
|
||||||
&mut stream,
|
&mut stream,
|
||||||
&OutgoingMsg::RequestResponse {
|
&OutgoingMsg::RequestResponse {
|
||||||
|
request_id,
|
||||||
response: RequestResponse::OutputProps {
|
response: RequestResponse::OutputProps {
|
||||||
make,
|
make,
|
||||||
model,
|
model,
|
||||||
|
@ -406,9 +413,11 @@ impl<B: Backend> State<B> {
|
||||||
.flat_map(|op| op.with_state(|state| state.tags.clone()))
|
.flat_map(|op| op.with_state(|state| state.tags.clone()))
|
||||||
.map(|tag| tag.id())
|
.map(|tag| tag.id())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
tracing::debug!("GetTags: {:?}", tag_ids);
|
||||||
crate::api::send_to_client(
|
crate::api::send_to_client(
|
||||||
&mut stream,
|
&mut stream,
|
||||||
&OutgoingMsg::RequestResponse {
|
&OutgoingMsg::RequestResponse {
|
||||||
|
request_id,
|
||||||
response: RequestResponse::Tags { tag_ids },
|
response: RequestResponse::Tags { tag_ids },
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -425,6 +434,7 @@ impl<B: Backend> State<B> {
|
||||||
crate::api::send_to_client(
|
crate::api::send_to_client(
|
||||||
&mut stream,
|
&mut stream,
|
||||||
&OutgoingMsg::RequestResponse {
|
&OutgoingMsg::RequestResponse {
|
||||||
|
request_id,
|
||||||
response: RequestResponse::TagProps {
|
response: RequestResponse::TagProps {
|
||||||
active,
|
active,
|
||||||
name,
|
name,
|
||||||
|
|
Loading…
Reference in a new issue