mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2024-12-27 21:58:18 +01:00
Streamline API naming
This commit is contained in:
parent
ffa847bf36
commit
b2521f949c
10 changed files with 169 additions and 263 deletions
|
@ -31,7 +31,15 @@ require("pinnacle").setup(function(pinnacle)
|
||||||
|
|
||||||
input.keybind({ mod_key, "Alt" }, keys.q, pinnacle.quit)
|
input.keybind({ mod_key, "Alt" }, keys.q, pinnacle.quit)
|
||||||
|
|
||||||
input.keybind({ mod_key, "Alt" }, keys.c, window.close_window)
|
input.keybind({ mod_key, "Alt" }, keys.c, function()
|
||||||
|
-- The commented out line may crash the config process if you have no windows open.
|
||||||
|
-- There is no nil warning here due to limitations in Lua LS type checking, so check for nil as shown below.
|
||||||
|
-- window.get_focused():close()
|
||||||
|
local win = window.get_focused()
|
||||||
|
if win ~= nil then
|
||||||
|
win:close()
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
input.keybind({ mod_key, "Alt" }, keys.space, window.toggle_floating)
|
input.keybind({ mod_key, "Alt" }, keys.space, window.toggle_floating)
|
||||||
|
|
||||||
|
@ -72,7 +80,7 @@ require("pinnacle").setup(function(pinnacle)
|
||||||
local indices = {}
|
local indices = {}
|
||||||
|
|
||||||
-- Layout cycling
|
-- Layout cycling
|
||||||
-- Yes, this is very complicated and yes, I'll cook up a way to make it less complicated.
|
-- Yes, this is overly complicated and yes, I'll cook up a way to make it less so.
|
||||||
input.keybind({ mod_key }, keys.space, function()
|
input.keybind({ mod_key }, keys.space, function()
|
||||||
local tags = output.get_focused():tags()
|
local tags = output.get_focused():tags()
|
||||||
for _, tg in pairs(tags) do
|
for _, tg in pairs(tags) do
|
||||||
|
|
|
@ -10,7 +10,7 @@ local input = {
|
||||||
|
|
||||||
---Set a keybind. If called with an already existing keybind, it gets replaced.
|
---Set a keybind. If called with an already existing keybind, it gets replaced.
|
||||||
---
|
---
|
||||||
---# Example
|
---### Example
|
||||||
---
|
---
|
||||||
---```lua
|
---```lua
|
||||||
----- The following sets Super + Return to open Alacritty
|
----- The following sets Super + Return to open Alacritty
|
||||||
|
|
|
@ -10,9 +10,9 @@
|
||||||
---@field SetKeybind { key: Keys, modifiers: Modifier[], callback_id: integer }
|
---@field SetKeybind { key: Keys, modifiers: Modifier[], callback_id: integer }
|
||||||
---@field SetMousebind { button: integer }
|
---@field SetMousebind { button: integer }
|
||||||
--Windows
|
--Windows
|
||||||
---@field CloseWindow { client_id: integer? }
|
---@field CloseWindow { window_id: integer }
|
||||||
---@field ToggleFloating { client_id: integer? }
|
---@field ToggleFloating { window_id: integer }
|
||||||
---@field SetWindowSize { window_id: integer, size: { w: integer, h: integer } }
|
---@field SetWindowSize { window_id: integer, size: integer[] }
|
||||||
---@field MoveWindowToTag { window_id: integer, tag_id: string }
|
---@field MoveWindowToTag { window_id: integer, tag_id: string }
|
||||||
---@field ToggleTagOnWindow { window_id: integer, tag_id: string }
|
---@field ToggleTagOnWindow { window_id: integer, tag_id: string }
|
||||||
--
|
--
|
||||||
|
@ -21,8 +21,8 @@
|
||||||
--Tags
|
--Tags
|
||||||
---@field ToggleTag { output_name: string, tag_name: string }
|
---@field ToggleTag { output_name: string, tag_name: string }
|
||||||
---@field SwitchToTag { output_name: string, tag_name: string }
|
---@field SwitchToTag { output_name: string, tag_name: string }
|
||||||
---@field AddTags { output_name: string, tags: string[] }
|
---@field AddTags { output_name: string, tag_names: string[] }
|
||||||
---@field RemoveTags { output_name: string, tags: string[] }
|
---@field RemoveTags { output_name: string, tag_names: string[] }
|
||||||
---@field SetLayout { output_name: string, tag_name: string, layout: Layout }
|
---@field SetLayout { output_name: string, tag_name: string, layout: Layout }
|
||||||
--Outputs
|
--Outputs
|
||||||
---@field ConnectForAllOutputs { callback_id: integer }
|
---@field ConnectForAllOutputs { callback_id: integer }
|
||||||
|
@ -36,12 +36,12 @@
|
||||||
---@field GetWindowByAppId { app_id: string }
|
---@field GetWindowByAppId { app_id: string }
|
||||||
---@field GetWindowByTitle { title: string }
|
---@field GetWindowByTitle { title: string }
|
||||||
--Outputs
|
--Outputs
|
||||||
---@field GetOutputByName { name: string }
|
---@field GetOutputByName { output_name: OutputName }
|
||||||
---@field GetOutputsByModel { model: string }
|
---@field GetOutputsByModel { model: string }
|
||||||
---@field GetOutputsByRes { res: integer[] }
|
---@field GetOutputsByRes { res: integer[] }
|
||||||
---@field GetTagsByOutput { output: string }
|
---@field GetTagsByOutput { output_name: string }
|
||||||
---@field GetTagActive { tag_id: integer }
|
---@field GetTagActive { tag_id: TagId }
|
||||||
---@field GetTagName { tag_id: integer }
|
---@field GetTagName { tag_id: TagId }
|
||||||
|
|
||||||
---@alias Request _Request | "GetWindowByFocus" | "GetAllWindows" | "GetOutputByFocus"
|
---@alias Request _Request | "GetWindowByFocus" | "GetAllWindows" | "GetOutputByFocus"
|
||||||
|
|
||||||
|
@ -53,21 +53,14 @@
|
||||||
---@field Spawn { stdout: string?, stderr: string?, exit_code: integer?, exit_msg: string? }
|
---@field Spawn { stdout: string?, stderr: string?, exit_code: integer?, exit_msg: string? }
|
||||||
---@field ConnectForAllOutputs { output_name: string }
|
---@field ConnectForAllOutputs { output_name: string }
|
||||||
|
|
||||||
|
---@alias WindowId integer
|
||||||
|
---@alias TagId integer
|
||||||
|
---@alias OutputName string
|
||||||
|
|
||||||
---@class RequestResponse
|
---@class RequestResponse
|
||||||
---@field Window { window: WindowProperties }
|
---@field Window { window_id: WindowId|nil }
|
||||||
---@field GetAllWindows { windows: WindowProperties[] }
|
---@field Windows { window_ids: WindowId[] }
|
||||||
---@field Outputs { names: string[] }
|
---@field Outputs { output_names: OutputName[] }
|
||||||
---@field Tags { tags: TagProperties[] }
|
---@field Tags { tag_ids: TagId[] }
|
||||||
---@field TagActive { active: boolean }
|
---@field TagActive { active: boolean }
|
||||||
---@field TagName { name: string }
|
---@field TagName { name: string }
|
||||||
|
|
||||||
---@class WindowProperties
|
|
||||||
---@field id integer
|
|
||||||
---@field app_id string?
|
|
||||||
---@field title string?
|
|
||||||
---@field size integer[] A two element int array, \[1\] = w, \[2\] = h
|
|
||||||
---@field location integer[] A two element int array, \[1\] = x, \[2\] = y
|
|
||||||
---@field floating boolean
|
|
||||||
|
|
||||||
---@class TagProperties
|
|
||||||
---@field id integer
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ local output = {}
|
||||||
---rather, "name" is the name of the connector the output is connected to.
|
---rather, "name" is the name of the connector the output is connected to.
|
||||||
---This should be something like "HDMI-A-0", "eDP-1", or similar.
|
---This should be something like "HDMI-A-0", "eDP-1", or similar.
|
||||||
---
|
---
|
||||||
---# Examples
|
---### Example
|
||||||
---```lua
|
---```lua
|
||||||
---local monitor = output.get_by_name("DP-1")
|
---local monitor = output.get_by_name("DP-1")
|
||||||
---print(monitor.name) -- should print `DP-1`
|
---print(monitor.name) -- should print `DP-1`
|
||||||
|
@ -58,16 +58,16 @@ local output = {}
|
||||||
function output.get_by_name(name)
|
function output.get_by_name(name)
|
||||||
SendRequest({
|
SendRequest({
|
||||||
GetOutputByName = {
|
GetOutputByName = {
|
||||||
name = name,
|
output_name = name,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
local response = ReadMsg()
|
local response = ReadMsg()
|
||||||
|
|
||||||
local names = response.RequestResponse.response.Outputs.names
|
local output_names = response.RequestResponse.response.Outputs.output_names
|
||||||
|
|
||||||
if names[1] ~= nil then
|
if output_names[1] ~= nil then
|
||||||
return new_output({ name = names[1] })
|
return new_output({ name = output_names[1] })
|
||||||
else
|
else
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
@ -88,11 +88,11 @@ function output.get_by_model(model)
|
||||||
|
|
||||||
local response = ReadMsg()
|
local response = ReadMsg()
|
||||||
|
|
||||||
local names = response.RequestResponse.response.Outputs.names
|
local output_names = response.RequestResponse.response.Outputs.output_names
|
||||||
|
|
||||||
---@type Output
|
---@type Output
|
||||||
local outputs = {}
|
local outputs = {}
|
||||||
for _, v in pairs(names) do
|
for _, v in pairs(output_names) do
|
||||||
table.insert(outputs, new_output({ name = v }))
|
table.insert(outputs, new_output({ name = v }))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -113,12 +113,12 @@ function output.get_by_res(width, height)
|
||||||
|
|
||||||
local response = ReadMsg()
|
local response = ReadMsg()
|
||||||
|
|
||||||
local names = response.RequestResponse.response.Outputs.names
|
local output_names = response.RequestResponse.response.Outputs.output_names
|
||||||
|
|
||||||
---@type Output
|
---@type Output
|
||||||
local outputs = {}
|
local outputs = {}
|
||||||
for _, v in pairs(names) do
|
for _, output_name in pairs(output_names) do
|
||||||
table.insert(outputs, new_output({ name = v }))
|
table.insert(outputs, new_output({ name = output_name }))
|
||||||
end
|
end
|
||||||
|
|
||||||
return outputs
|
return outputs
|
||||||
|
@ -145,16 +145,14 @@ end
|
||||||
---```
|
---```
|
||||||
---@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.get_focused()
|
||||||
SendMsg({
|
SendRequest("GetOutputByFocus")
|
||||||
Request = "GetOutputByFocus",
|
|
||||||
})
|
|
||||||
|
|
||||||
local response = ReadMsg()
|
local response = ReadMsg()
|
||||||
|
|
||||||
local names = response.RequestResponse.response.Outputs.names
|
local output_names = response.RequestResponse.response.Outputs.output_names
|
||||||
|
|
||||||
if names[1] ~= nil then
|
if output_names[1] ~= nil then
|
||||||
return new_output({ name = names[1] })
|
return new_output({ name = output_names[1] })
|
||||||
else
|
else
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
|
@ -68,7 +68,7 @@ end
|
||||||
---
|
---
|
||||||
---If you need to add the names as a table, use `tag.add_table` instead.
|
---If you need to add the names as a table, use `tag.add_table` instead.
|
||||||
---
|
---
|
||||||
---# Example
|
---### Example
|
||||||
---
|
---
|
||||||
---```lua
|
---```lua
|
||||||
---local output = output.get_by_name("DP-1")
|
---local output = output.get_by_name("DP-1")
|
||||||
|
@ -79,20 +79,20 @@ 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.
|
||||||
function tag.add(output, ...)
|
function tag.add(output, ...)
|
||||||
local tags = table.pack(...)
|
local tag_names = table.pack(...)
|
||||||
tags["n"] = nil
|
tag_names["n"] = nil -- remove the length to make it a true array for serializing
|
||||||
|
|
||||||
SendMsg({
|
SendMsg({
|
||||||
AddTags = {
|
AddTags = {
|
||||||
output_name = output.name,
|
output_name = output.name,
|
||||||
tags = tags,
|
tag_names = tag_names,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
---Like `tag.add`, but with a table of strings instead.
|
---Like `tag.add`, but with a table of strings instead.
|
||||||
---
|
---
|
||||||
---# Example
|
---### Example
|
||||||
---
|
---
|
||||||
---```lua
|
---```lua
|
||||||
---local tags = { "Terminal", "Browser", "Mail", "Gaming", "Potato" }
|
---local tags = { "Terminal", "Browser", "Mail", "Gaming", "Potato" }
|
||||||
|
@ -107,14 +107,14 @@ function tag.add_table(output, names)
|
||||||
SendMsg({
|
SendMsg({
|
||||||
AddTags = {
|
AddTags = {
|
||||||
output_name = output.name,
|
output_name = output.name,
|
||||||
tags = names,
|
tag_names = names,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
---Toggle a tag on the specified output. If `output` isn't specified, toggle it on the currently focused output instead.
|
---Toggle a tag on the specified output. If `output` isn't specified, toggle it on the currently focused output instead.
|
||||||
---
|
---
|
||||||
---# Example
|
---### Example
|
||||||
---
|
---
|
||||||
---```lua
|
---```lua
|
||||||
----- Assuming all tags are toggled off...
|
----- Assuming all tags are toggled off...
|
||||||
|
@ -151,7 +151,7 @@ end
|
||||||
---
|
---
|
||||||
---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.
|
||||||
---
|
---
|
||||||
---# Example
|
---### Example
|
||||||
---
|
---
|
||||||
---```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
|
||||||
|
@ -219,19 +219,19 @@ end
|
||||||
function tag.get_on_output(output)
|
function tag.get_on_output(output)
|
||||||
SendRequest({
|
SendRequest({
|
||||||
GetTagsByOutput = {
|
GetTagsByOutput = {
|
||||||
output = output.name,
|
output_name = output.name,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
local response = ReadMsg()
|
local response = ReadMsg()
|
||||||
|
|
||||||
local tag_props = response.RequestResponse.response.Tags.tags
|
local tag_ids = response.RequestResponse.response.Tags.tag_ids
|
||||||
|
|
||||||
---@type Tag[]
|
---@type Tag[]
|
||||||
local tags = {}
|
local tags = {}
|
||||||
|
|
||||||
for _, prop in pairs(tag_props) do
|
for _, tag_id in pairs(tag_ids) do
|
||||||
table.insert(tags, new_tag({ id = prop.id }))
|
table.insert(tags, new_tag({ id = tag_id }))
|
||||||
end
|
end
|
||||||
|
|
||||||
return tags
|
return tags
|
||||||
|
|
|
@ -61,6 +61,24 @@ function win:toggle_tag(name)
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---Close this window.
|
||||||
|
function win:close()
|
||||||
|
SendMsg({
|
||||||
|
CloseWindow = {
|
||||||
|
window_id = self.id,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
---Toggle this window's floating status.
|
||||||
|
function win:toggle_floating()
|
||||||
|
SendMsg({
|
||||||
|
ToggleFloating = {
|
||||||
|
window_id = self.id,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
---Get a window's size.
|
---Get a window's size.
|
||||||
---@return { w: integer, h: integer }
|
---@return { w: integer, h: integer }
|
||||||
function win:get_size()
|
function win:get_size()
|
||||||
|
@ -71,31 +89,11 @@ end
|
||||||
|
|
||||||
local window = {}
|
local window = {}
|
||||||
|
|
||||||
---Close a window.
|
|
||||||
---@param client_id integer? The id of the window you want closed, or nil to close the currently focused window, if any.
|
|
||||||
function window.close_window(client_id)
|
|
||||||
SendMsg({
|
|
||||||
CloseWindow = {
|
|
||||||
client_id = client_id,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
---Toggle a window's floating status.
|
|
||||||
---@param client_id integer? The id of the window you want to toggle, or nil to toggle the currently focused window, if any.
|
|
||||||
function window.toggle_floating(client_id)
|
|
||||||
SendMsg({
|
|
||||||
ToggleFloating = {
|
|
||||||
client_id = client_id,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
---TODO: This function is not implemented yet.
|
---TODO: This function is not implemented yet.
|
||||||
---
|
---
|
||||||
---Get a window by its app id (aka its X11 class).
|
---Get a window by its app id (aka its X11 class).
|
||||||
---@param app_id string The window's app id. For example, Alacritty's app id is "Alacritty".
|
---@param app_id string The window's app id. For example, Alacritty's app id is "Alacritty".
|
||||||
---@return Window window -- TODO: nil
|
---@return Window|nil
|
||||||
function window.get_by_app_id(app_id)
|
function window.get_by_app_id(app_id)
|
||||||
SendRequest({
|
SendRequest({
|
||||||
GetWindowByAppId = {
|
GetWindowByAppId = {
|
||||||
|
@ -105,22 +103,15 @@ function window.get_by_app_id(app_id)
|
||||||
|
|
||||||
local response = ReadMsg()
|
local response = ReadMsg()
|
||||||
|
|
||||||
local props = response.RequestResponse.response.Window.window
|
local window_id = response.RequestResponse.response.Window.window_id
|
||||||
|
|
||||||
|
if window_id == nil then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
---@type Window
|
---@type Window
|
||||||
local wind = {
|
local wind = {
|
||||||
id = props.id,
|
id = window_id,
|
||||||
app_id = props.app_id or "",
|
|
||||||
title = props.title or "",
|
|
||||||
size = {
|
|
||||||
w = props.size[1],
|
|
||||||
h = props.size[2],
|
|
||||||
},
|
|
||||||
location = {
|
|
||||||
x = props.location[1],
|
|
||||||
y = props.location[2],
|
|
||||||
},
|
|
||||||
floating = props.floating,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new_window(wind)
|
return new_window(wind)
|
||||||
|
@ -130,7 +121,7 @@ end
|
||||||
---
|
---
|
||||||
---Get a window by its title.
|
---Get a window by its title.
|
||||||
---@param title string The window's title.
|
---@param title string The window's title.
|
||||||
---@return Window
|
---@return Window|nil
|
||||||
function window.get_by_title(title)
|
function window.get_by_title(title)
|
||||||
SendRequest({
|
SendRequest({
|
||||||
GetWindowByTitle = {
|
GetWindowByTitle = {
|
||||||
|
@ -140,50 +131,36 @@ function window.get_by_title(title)
|
||||||
|
|
||||||
local response = ReadMsg()
|
local response = ReadMsg()
|
||||||
|
|
||||||
local props = response.RequestResponse.response.Window.window
|
local window_id = response.RequestResponse.response.Window.window_id
|
||||||
|
|
||||||
|
if window_id == nil then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
---@type Window
|
---@type Window
|
||||||
local wind = {
|
local wind = {
|
||||||
id = props.id,
|
id = window_id,
|
||||||
app_id = props.app_id or "",
|
|
||||||
title = props.title or "",
|
|
||||||
size = {
|
|
||||||
w = props.size[1],
|
|
||||||
h = props.size[2],
|
|
||||||
},
|
|
||||||
location = {
|
|
||||||
x = props.location[1],
|
|
||||||
y = props.location[2],
|
|
||||||
},
|
|
||||||
floating = props.floating,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new_window(wind)
|
return new_window(wind)
|
||||||
end
|
end
|
||||||
|
|
||||||
---Get the currently focused window.
|
---Get the currently focused window.
|
||||||
---@return Window
|
---@return Window|nil
|
||||||
function window.get_focused()
|
function window.get_focused()
|
||||||
SendRequest("GetWindowByFocus")
|
SendRequest("GetWindowByFocus")
|
||||||
|
|
||||||
local response = ReadMsg()
|
local response = ReadMsg()
|
||||||
|
|
||||||
local props = response.RequestResponse.response.Window.window
|
local window_id = response.RequestResponse.response.Window.window_id
|
||||||
|
|
||||||
|
if window_id == nil then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
---@type Window
|
---@type Window
|
||||||
local wind = {
|
local wind = {
|
||||||
id = props.id,
|
id = window_id,
|
||||||
app_id = props.app_id or "",
|
|
||||||
title = props.title or "",
|
|
||||||
size = {
|
|
||||||
w = props.size[1],
|
|
||||||
h = props.size[2],
|
|
||||||
},
|
|
||||||
location = {
|
|
||||||
x = props.location[1],
|
|
||||||
y = props.location[2],
|
|
||||||
},
|
|
||||||
floating = props.floating,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new_window(wind)
|
return new_window(wind)
|
||||||
|
@ -194,26 +171,11 @@ end
|
||||||
function window.get_all()
|
function window.get_all()
|
||||||
SendRequest("GetAllWindows")
|
SendRequest("GetAllWindows")
|
||||||
|
|
||||||
-- INFO: these read synchronously so this should always work IF the server works correctly
|
local window_ids = ReadMsg().RequestResponse.response.Windows.window_ids
|
||||||
|
|
||||||
local window_props = ReadMsg().RequestResponse.response.GetAllWindows.windows
|
|
||||||
---@type Window[]
|
---@type Window[]
|
||||||
local windows = {}
|
local windows = {}
|
||||||
for i, v in ipairs(window_props) do
|
for i, window_id in ipairs(window_ids) do
|
||||||
windows[i] = {
|
windows[i] = new_window({ id = window_id })
|
||||||
id = v.id,
|
|
||||||
app_id = v.app_id or "",
|
|
||||||
title = v.title or "",
|
|
||||||
size = {
|
|
||||||
w = v.size[1],
|
|
||||||
h = v.size[2],
|
|
||||||
},
|
|
||||||
location = {
|
|
||||||
x = v.location[1],
|
|
||||||
y = v.location[2],
|
|
||||||
},
|
|
||||||
floating = v.floating,
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
return windows
|
return windows
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,11 +7,7 @@
|
||||||
// The MessagePack format for these is a one-element map where the element's key is the enum name and its
|
// The MessagePack format for these is a one-element map where the element's key is the enum name and its
|
||||||
// value is a map of the enum's values
|
// value is a map of the enum's values
|
||||||
|
|
||||||
use crate::{
|
use crate::{layout::Layout, tag::TagId, window::window_state::WindowId};
|
||||||
layout::Layout,
|
|
||||||
tag::{TagId, TagProperties},
|
|
||||||
window::{window_state::WindowId, WindowProperties},
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, Copy)]
|
#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, Copy)]
|
||||||
pub struct CallbackId(pub u32);
|
pub struct CallbackId(pub u32);
|
||||||
|
@ -30,12 +26,10 @@ pub enum Msg {
|
||||||
|
|
||||||
// Window management
|
// Window management
|
||||||
CloseWindow {
|
CloseWindow {
|
||||||
#[serde(default)]
|
window_id: WindowId,
|
||||||
client_id: Option<u32>,
|
|
||||||
},
|
},
|
||||||
ToggleFloating {
|
ToggleFloating {
|
||||||
#[serde(default)]
|
window_id: WindowId,
|
||||||
client_id: Option<u32>,
|
|
||||||
},
|
},
|
||||||
SetWindowSize {
|
SetWindowSize {
|
||||||
window_id: WindowId,
|
window_id: WindowId,
|
||||||
|
@ -62,12 +56,12 @@ pub enum Msg {
|
||||||
AddTags {
|
AddTags {
|
||||||
/// The name of the output you want these tags on.
|
/// The name of the output you want these tags on.
|
||||||
output_name: String,
|
output_name: String,
|
||||||
tags: Vec<String>,
|
tag_names: Vec<String>,
|
||||||
},
|
},
|
||||||
RemoveTags {
|
RemoveTags {
|
||||||
/// The name of the output you want these tags removed from.
|
/// The name of the output you want these tags removed from.
|
||||||
output_name: String,
|
output_name: String,
|
||||||
tags: Vec<String>,
|
tag_names: Vec<String>,
|
||||||
},
|
},
|
||||||
SetLayout {
|
SetLayout {
|
||||||
output_name: String,
|
output_name: String,
|
||||||
|
@ -106,11 +100,11 @@ pub enum Request {
|
||||||
GetWindowByTitle { title: String },
|
GetWindowByTitle { title: String },
|
||||||
GetWindowByFocus,
|
GetWindowByFocus,
|
||||||
GetAllWindows,
|
GetAllWindows,
|
||||||
GetOutputByName { name: String },
|
GetOutputByName { output_name: String },
|
||||||
GetOutputsByModel { model: String },
|
GetOutputsByModel { model: String },
|
||||||
GetOutputsByRes { res: (u32, u32) },
|
GetOutputsByRes { res: (u32, u32) },
|
||||||
GetOutputByFocus,
|
GetOutputByFocus,
|
||||||
GetTagsByOutput { output: String },
|
GetTagsByOutput { output_name: String },
|
||||||
GetTagActive { tag_id: TagId },
|
GetTagActive { tag_id: TagId },
|
||||||
GetTagName { tag_id: TagId },
|
GetTagName { tag_id: TagId },
|
||||||
}
|
}
|
||||||
|
@ -139,6 +133,7 @@ impl<T: IntoIterator<Item = Modifier>> From<T> for ModifierMask {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModifierMask {
|
impl ModifierMask {
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn values(self) -> Vec<Modifier> {
|
pub fn values(self) -> Vec<Modifier> {
|
||||||
let mut res = Vec::<Modifier>::new();
|
let mut res = Vec::<Modifier>::new();
|
||||||
if self.0 & Modifier::Shift as u8 == Modifier::Shift as u8 {
|
if self.0 & Modifier::Shift as u8 == Modifier::Shift as u8 {
|
||||||
|
@ -190,10 +185,10 @@ pub enum Args {
|
||||||
|
|
||||||
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
||||||
pub enum RequestResponse {
|
pub enum RequestResponse {
|
||||||
Window { window: WindowProperties },
|
Window { window_id: Option<WindowId> },
|
||||||
GetAllWindows { windows: Vec<WindowProperties> },
|
Windows { window_ids: Vec<WindowId> },
|
||||||
Outputs { names: Vec<String> },
|
Outputs { output_names: Vec<String> },
|
||||||
Tags { tags: Vec<TagProperties> },
|
Tags { tag_ids: Vec<TagId> },
|
||||||
TagActive { active: bool },
|
TagActive { active: bool },
|
||||||
TagName { name: String },
|
TagName { name: String },
|
||||||
}
|
}
|
||||||
|
|
153
src/state.rs
153
src/state.rs
|
@ -21,8 +21,8 @@ use crate::{
|
||||||
},
|
},
|
||||||
focus::FocusState,
|
focus::FocusState,
|
||||||
grab::resize_grab::ResizeSurfaceState,
|
grab::resize_grab::ResizeSurfaceState,
|
||||||
tag::{Tag, TagProperties},
|
tag::Tag,
|
||||||
window::{window_state::WindowResizeState, WindowProperties},
|
window::window_state::WindowResizeState,
|
||||||
};
|
};
|
||||||
use calloop::futures::Scheduler;
|
use calloop::futures::Scheduler;
|
||||||
use futures_lite::AsyncBufReadExt;
|
use futures_lite::AsyncBufReadExt;
|
||||||
|
@ -55,7 +55,7 @@ use smithay::{
|
||||||
dmabuf::DmabufFeedback,
|
dmabuf::DmabufFeedback,
|
||||||
fractional_scale::FractionalScaleManagerState,
|
fractional_scale::FractionalScaleManagerState,
|
||||||
output::OutputManagerState,
|
output::OutputManagerState,
|
||||||
shell::xdg::{XdgShellState, XdgToplevelSurfaceData},
|
shell::xdg::XdgShellState,
|
||||||
shm::ShmState,
|
shm::ShmState,
|
||||||
socket::ListeningSocketSource,
|
socket::ListeningSocketSource,
|
||||||
viewporter::ViewporterState,
|
viewporter::ViewporterState,
|
||||||
|
@ -117,17 +117,22 @@ impl<B: Backend> State<B> {
|
||||||
.keybinds
|
.keybinds
|
||||||
.insert((modifiers.into(), key), callback_id);
|
.insert((modifiers.into(), key), callback_id);
|
||||||
}
|
}
|
||||||
Msg::SetMousebind { button } => todo!(),
|
Msg::SetMousebind { button: _ } => todo!(),
|
||||||
Msg::CloseWindow { client_id } => {
|
Msg::CloseWindow { window_id } => {
|
||||||
// TODO: client_id
|
if let Some(window) = self
|
||||||
tracing::info!("CloseWindow {:?}", client_id);
|
.windows
|
||||||
if let Some(window) = self.focus_state.current_focus() {
|
.iter()
|
||||||
|
.find(|win| win.with_state(|state| state.id == window_id))
|
||||||
|
{
|
||||||
window.toplevel().send_close();
|
window.toplevel().send_close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Msg::ToggleFloating { client_id } => {
|
Msg::ToggleFloating { window_id } => {
|
||||||
// TODO: add client_ids
|
if let Some(window) = self
|
||||||
if let Some(window) = self.focus_state.current_focus() {
|
.windows
|
||||||
|
.iter()
|
||||||
|
.find(|win| win.with_state(|state| state.id == window_id)).cloned()
|
||||||
|
{
|
||||||
crate::window::toggle_floating(self, &window);
|
crate::window::toggle_floating(self, &window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -247,7 +252,7 @@ impl<B: Backend> State<B> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: add output
|
// TODO: add output
|
||||||
Msg::AddTags { output_name, tags } => {
|
Msg::AddTags { output_name, tag_names } => {
|
||||||
if let Some(output) = self
|
if let Some(output) = self
|
||||||
.space
|
.space
|
||||||
.outputs()
|
.outputs()
|
||||||
|
@ -256,19 +261,19 @@ impl<B: Backend> State<B> {
|
||||||
output.with_state(|state| {
|
output.with_state(|state| {
|
||||||
state
|
state
|
||||||
.tags
|
.tags
|
||||||
.extend(tags.iter().cloned().map(Tag::new));
|
.extend(tag_names.iter().cloned().map(Tag::new));
|
||||||
tracing::debug!("tags added, are now {:?}", state.tags);
|
tracing::debug!("tags added, are now {:?}", state.tags);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Msg::RemoveTags { output_name, tags } => {
|
Msg::RemoveTags { output_name, tag_names } => {
|
||||||
if let Some(output) = self
|
if let Some(output) = self
|
||||||
.space
|
.space
|
||||||
.outputs()
|
.outputs()
|
||||||
.find(|output| output.name() == output_name)
|
.find(|output| output.name() == output_name)
|
||||||
{
|
{
|
||||||
output.with_state(|state| {
|
output.with_state(|state| {
|
||||||
state.tags.retain(|tag| !tags.contains(&tag.name()));
|
state.tags.retain(|tag| !tag_names.contains(&tag.name()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -319,70 +324,38 @@ impl<B: Backend> State<B> {
|
||||||
.expect("Stream doesn't exist");
|
.expect("Stream doesn't exist");
|
||||||
let mut stream = stream.lock().expect("Couldn't lock stream");
|
let mut stream = stream.lock().expect("Couldn't lock stream");
|
||||||
match request {
|
match request {
|
||||||
Request::GetWindowByAppId { app_id } => todo!(),
|
Request::GetWindowByAppId { app_id: _ } => todo!(),
|
||||||
Request::GetWindowByTitle { title } => todo!(),
|
Request::GetWindowByTitle { title: _ } => todo!(),
|
||||||
Request::GetWindowByFocus => {
|
Request::GetWindowByFocus => {
|
||||||
let Some(current_focus) = self.focus_state.current_focus() else { return; };
|
match self.focus_state.current_focus() {
|
||||||
let (app_id, title) =
|
Some(current_focus) => {
|
||||||
compositor::with_states(current_focus.toplevel().wl_surface(), |states| {
|
let window_id =
|
||||||
let lock = states
|
current_focus.with_state(|state| state.id);
|
||||||
.data_map
|
crate::api::send_to_client(
|
||||||
.get::<XdgToplevelSurfaceData>()
|
&mut stream,
|
||||||
.expect("XdgToplevelSurfaceData doesn't exist")
|
&OutgoingMsg::RequestResponse {
|
||||||
.lock()
|
response: RequestResponse::Window { window_id: Some(window_id) },
|
||||||
.expect("Couldn't lock XdgToplevelSurfaceData");
|
},
|
||||||
(lock.app_id.clone(), lock.title.clone())
|
)
|
||||||
});
|
.expect("Send to client failed");
|
||||||
let (window_id, floating) =
|
|
||||||
current_focus.with_state(|state| (state.id, state.floating.is_floating()));
|
|
||||||
// TODO: unwrap
|
|
||||||
let location = self.space.element_location(¤t_focus).unwrap();
|
|
||||||
let props = WindowProperties {
|
|
||||||
id: window_id,
|
|
||||||
app_id,
|
|
||||||
title,
|
|
||||||
size: current_focus.geometry().size.into(),
|
|
||||||
location: location.into(),
|
|
||||||
floating,
|
|
||||||
};
|
|
||||||
crate::api::send_to_client(
|
|
||||||
&mut stream,
|
|
||||||
&OutgoingMsg::RequestResponse {
|
|
||||||
response: RequestResponse::Window { window: props },
|
|
||||||
},
|
},
|
||||||
)
|
None => {
|
||||||
.expect("Send to client failed");
|
crate::api::send_to_client(
|
||||||
|
&mut stream,
|
||||||
|
&OutgoingMsg::RequestResponse {
|
||||||
|
response: RequestResponse::Window { window_id: None },
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.expect("Send to client failed");
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Request::GetAllWindows => {
|
Request::GetAllWindows => {
|
||||||
let window_props = self
|
let window_ids = self
|
||||||
.space
|
.windows
|
||||||
.elements()
|
.iter()
|
||||||
.map(|win| {
|
.map(|win| {
|
||||||
let (app_id, title) =
|
win.with_state(|state| state.id)
|
||||||
compositor::with_states(win.toplevel().wl_surface(), |states| {
|
|
||||||
let lock = states
|
|
||||||
.data_map
|
|
||||||
.get::<XdgToplevelSurfaceData>()
|
|
||||||
.expect("XdgToplevelSurfaceData doesn't exist")
|
|
||||||
.lock()
|
|
||||||
.expect("Couldn't lock XdgToplevelSurfaceData");
|
|
||||||
(lock.app_id.clone(), lock.title.clone())
|
|
||||||
});
|
|
||||||
let (window_id, floating) =
|
|
||||||
win.with_state(|state| (state.id, state.floating.is_floating()));
|
|
||||||
// TODO: unwrap
|
|
||||||
let location = self
|
|
||||||
.space
|
|
||||||
.element_location(win)
|
|
||||||
.expect("Window location doesn't exist");
|
|
||||||
WindowProperties {
|
|
||||||
id: window_id,
|
|
||||||
app_id,
|
|
||||||
title,
|
|
||||||
size: win.geometry().size.into(),
|
|
||||||
location: location.into(),
|
|
||||||
floating,
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
@ -390,25 +363,25 @@ impl<B: Backend> State<B> {
|
||||||
crate::api::send_to_client(
|
crate::api::send_to_client(
|
||||||
&mut stream,
|
&mut stream,
|
||||||
&OutgoingMsg::RequestResponse {
|
&OutgoingMsg::RequestResponse {
|
||||||
response: RequestResponse::GetAllWindows {
|
response: RequestResponse::Windows {
|
||||||
windows: window_props,
|
window_ids,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.expect("Couldn't send to client");
|
.expect("Couldn't send to client");
|
||||||
}
|
}
|
||||||
Request::GetOutputByName { name } => {
|
Request::GetOutputByName { output_name } => {
|
||||||
// TODO: name better
|
// TODO: name better
|
||||||
let names = self
|
let names = self
|
||||||
.space
|
.space
|
||||||
.outputs()
|
.outputs()
|
||||||
.find(|output| output.name() == name)
|
.find(|output| output.name() == output_name)
|
||||||
.map(|output| output.name());
|
.map(|output| output.name());
|
||||||
crate::api::send_to_client(
|
crate::api::send_to_client(
|
||||||
&mut stream,
|
&mut stream,
|
||||||
&OutgoingMsg::RequestResponse {
|
&OutgoingMsg::RequestResponse {
|
||||||
response: RequestResponse::Outputs {
|
response: RequestResponse::Outputs {
|
||||||
names: if let Some(name) = names {
|
output_names: if let Some(name) = names {
|
||||||
vec![name]
|
vec![name]
|
||||||
} else {
|
} else {
|
||||||
vec![]
|
vec![]
|
||||||
|
@ -428,7 +401,7 @@ impl<B: Backend> State<B> {
|
||||||
crate::api::send_to_client(
|
crate::api::send_to_client(
|
||||||
&mut stream,
|
&mut stream,
|
||||||
&OutgoingMsg::RequestResponse {
|
&OutgoingMsg::RequestResponse {
|
||||||
response: RequestResponse::Outputs { names },
|
response: RequestResponse::Outputs { output_names: names },
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -452,7 +425,7 @@ impl<B: Backend> State<B> {
|
||||||
crate::api::send_to_client(
|
crate::api::send_to_client(
|
||||||
&mut stream,
|
&mut stream,
|
||||||
&OutgoingMsg::RequestResponse {
|
&OutgoingMsg::RequestResponse {
|
||||||
response: RequestResponse::Outputs { names },
|
response: RequestResponse::Outputs { output_names: names },
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -468,27 +441,27 @@ impl<B: Backend> State<B> {
|
||||||
crate::api::send_to_client(
|
crate::api::send_to_client(
|
||||||
&mut stream,
|
&mut stream,
|
||||||
&OutgoingMsg::RequestResponse {
|
&OutgoingMsg::RequestResponse {
|
||||||
response: RequestResponse::Outputs { names },
|
response: RequestResponse::Outputs { output_names: names },
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
Request::GetTagsByOutput { output } => {
|
Request::GetTagsByOutput { output_name } => {
|
||||||
let output = self
|
let output = self
|
||||||
.space
|
.space
|
||||||
.outputs()
|
.outputs()
|
||||||
.find(|op| op.name() == output);
|
.find(|op| op.name() == output_name);
|
||||||
if let Some(output) = output {
|
if let Some(output) = output {
|
||||||
let tag_props = output.with_state(|state| {
|
let tag_ids = output.with_state(|state| {
|
||||||
state.tags
|
state.tags
|
||||||
.iter()
|
.iter()
|
||||||
.map(|tag| TagProperties { id: tag.id() })
|
.map(|tag| tag.id())
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
});
|
});
|
||||||
crate::api::send_to_client(
|
crate::api::send_to_client(
|
||||||
&mut stream,
|
&mut stream,
|
||||||
&OutgoingMsg::RequestResponse {
|
&OutgoingMsg::RequestResponse {
|
||||||
response: RequestResponse::Tags { tags: tag_props }
|
response: RequestResponse::Tags { tag_ids }
|
||||||
}).unwrap();
|
}).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -747,15 +720,9 @@ pub fn schedule_on_commit<F, B: Backend>(data: &mut CalloopData<B>, windows: Vec
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut CalloopData<B>) + 'static,
|
F: FnOnce(&mut CalloopData<B>) + 'static,
|
||||||
{
|
{
|
||||||
// tracing::debug!("scheduling on_commit");
|
|
||||||
// tracing::debug!("win len is {}", windows.len());
|
|
||||||
for window in windows.iter() {
|
for window in windows.iter() {
|
||||||
window.with_state(|state| {
|
|
||||||
// tracing::debug!("win state is {:?}", state.resize_state);
|
|
||||||
});
|
|
||||||
if window.with_state(|state| !matches!(state.resize_state, WindowResizeState::Idle))
|
if window.with_state(|state| !matches!(state.resize_state, WindowResizeState::Idle))
|
||||||
{
|
{
|
||||||
// tracing::debug!("some windows not idle");
|
|
||||||
data.state.loop_handle.insert_idle(|data| {
|
data.state.loop_handle.insert_idle(|data| {
|
||||||
schedule_on_commit(data, windows, on_commit);
|
schedule_on_commit(data, windows, on_commit);
|
||||||
});
|
});
|
||||||
|
|
|
@ -90,11 +90,6 @@ impl Tag {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
|
||||||
pub struct TagProperties {
|
|
||||||
pub id: TagId,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<B: Backend> State<B> {
|
impl<B: Backend> State<B> {
|
||||||
pub fn output_for_tag(&self, tag: &Tag) -> Option<Output> {
|
pub fn output_for_tag(&self, tag: &Tag) -> Option<Output> {
|
||||||
self.space
|
self.space
|
||||||
|
|
|
@ -23,7 +23,7 @@ use crate::{
|
||||||
state::{State, WithState},
|
state::{State, WithState},
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::window_state::{Float, WindowId};
|
use self::window_state::Float;
|
||||||
|
|
||||||
pub mod window_state;
|
pub mod window_state;
|
||||||
|
|
||||||
|
@ -116,18 +116,6 @@ pub fn toggle_floating<B: Backend>(state: &mut State<B>, window: &Window) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
|
||||||
pub struct WindowProperties {
|
|
||||||
pub id: WindowId,
|
|
||||||
pub app_id: Option<String>,
|
|
||||||
pub title: Option<String>,
|
|
||||||
/// Width and height
|
|
||||||
pub size: (i32, i32),
|
|
||||||
/// x and y
|
|
||||||
pub location: (i32, i32),
|
|
||||||
pub floating: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct WindowBlocker;
|
pub struct WindowBlocker;
|
||||||
pub static BLOCKER_COUNTER: AtomicU32 = AtomicU32::new(0);
|
pub static BLOCKER_COUNTER: AtomicU32 = AtomicU32::new(0);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue