mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2025-01-27 19:58:08 +01:00
Merge pull request #122 from pinnacle-comp/spawn_once
Move spawn_once logic into compositor
This commit is contained in:
commit
ddb4b21720
13 changed files with 233 additions and 121 deletions
79
Cargo.lock
generated
79
Cargo.lock
generated
|
@ -183,7 +183,7 @@ dependencies = [
|
||||||
"polling",
|
"polling",
|
||||||
"rustix 0.38.28",
|
"rustix 0.38.28",
|
||||||
"slab",
|
"slab",
|
||||||
"tracing 0.1.37",
|
"tracing",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1458,7 +1458,7 @@ dependencies = [
|
||||||
"sysinfo",
|
"sysinfo",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"toml",
|
"toml",
|
||||||
"tracing 0.2.0",
|
"tracing",
|
||||||
"tracing-appender",
|
"tracing-appender",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
"x11rb 0.13.0",
|
"x11rb 0.13.0",
|
||||||
|
@ -1483,7 +1483,7 @@ dependencies = [
|
||||||
"concurrent-queue",
|
"concurrent-queue",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"rustix 0.38.28",
|
"rustix 0.38.28",
|
||||||
"tracing 0.1.37",
|
"tracing",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1855,7 +1855,7 @@ dependencies = [
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tracing 0.1.37",
|
"tracing",
|
||||||
"udev 0.8.0",
|
"udev 0.8.0",
|
||||||
"wayland-backend",
|
"wayland-backend",
|
||||||
"wayland-egl",
|
"wayland-egl",
|
||||||
|
@ -2079,30 +2079,20 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing"
|
name = "tracing"
|
||||||
version = "0.1.37"
|
version = "0.1.40"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
|
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"pin-project-lite",
|
|
||||||
"tracing-attributes 0.1.24",
|
|
||||||
"tracing-core 0.1.31",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tracing"
|
|
||||||
version = "0.2.0"
|
|
||||||
source = "git+https://github.com/tokio-rs/tracing?rev=84f0a60#84f0a608123a651f268ff76347f81182f487d3b1"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"tracing-attributes 0.2.0",
|
"tracing-attributes",
|
||||||
"tracing-core 0.2.0",
|
"tracing-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-appender"
|
name = "tracing-appender"
|
||||||
version = "0.2.0"
|
version = "0.2.3"
|
||||||
source = "git+https://github.com/tokio-rs/tracing?rev=84f0a60#84f0a608123a651f268ff76347f81182f487d3b1"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
@ -2112,19 +2102,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-attributes"
|
name = "tracing-attributes"
|
||||||
version = "0.1.24"
|
version = "0.1.27"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74"
|
checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.31",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tracing-attributes"
|
|
||||||
version = "0.2.0"
|
|
||||||
source = "git+https://github.com/tokio-rs/tracing?rev=84f0a60#84f0a608123a651f268ff76347f81182f487d3b1"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -2133,35 +2113,30 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-core"
|
name = "tracing-core"
|
||||||
version = "0.1.31"
|
version = "0.1.32"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a"
|
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
|
||||||
dependencies = [
|
|
||||||
"once_cell",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tracing-core"
|
|
||||||
version = "0.2.0"
|
|
||||||
source = "git+https://github.com/tokio-rs/tracing?rev=84f0a60#84f0a608123a651f268ff76347f81182f487d3b1"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
"valuable",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-log"
|
name = "tracing-log"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/tokio-rs/tracing?rev=84f0a60#84f0a608123a651f268ff76347f81182f487d3b1"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"tracing-core 0.2.0",
|
"tracing-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-subscriber"
|
name = "tracing-subscriber"
|
||||||
version = "0.3.0"
|
version = "0.3.18"
|
||||||
source = "git+https://github.com/tokio-rs/tracing?rev=84f0a60#84f0a608123a651f268ff76347f81182f487d3b1"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"matchers",
|
"matchers",
|
||||||
"nu-ansi-term",
|
"nu-ansi-term",
|
||||||
|
@ -2170,8 +2145,8 @@ dependencies = [
|
||||||
"sharded-slab",
|
"sharded-slab",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"thread_local",
|
"thread_local",
|
||||||
"tracing 0.2.0",
|
"tracing",
|
||||||
"tracing-core 0.2.0",
|
"tracing-core",
|
||||||
"tracing-log",
|
"tracing-log",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2216,6 +2191,12 @@ version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "valuable"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "version_check"
|
name = "version_check"
|
||||||
version = "0.9.4"
|
version = "0.9.4"
|
||||||
|
|
|
@ -10,9 +10,9 @@ repository = "https://github.com/pinnacle-comp/pinnacle/"
|
||||||
keywords = ["wayland", "compositor", "smithay", "lua"]
|
keywords = ["wayland", "compositor", "smithay", "lua"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tracing = { git = "https://github.com/tokio-rs/tracing", rev = "84f0a60" }
|
tracing = "0.1.40"
|
||||||
tracing-subscriber = { git = "https://github.com/tokio-rs/tracing", rev = "84f0a60", features = ["env-filter"] }
|
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
||||||
tracing-appender = { git = "https://github.com/tokio-rs/tracing", rev = "84f0a60" }
|
tracing-appender = "0.2.3"
|
||||||
smithay = { git = "https://github.com/Smithay/smithay", rev = "56b6441a14600593d13229b9584058ec19e3e18b", default-features = false, features = ["desktop", "wayland_frontend"] }
|
smithay = { git = "https://github.com/Smithay/smithay", rev = "56b6441a14600593d13229b9584058ec19e3e18b", default-features = false, features = ["desktop", "wayland_frontend"] }
|
||||||
smithay-drm-extras = { git = "https://github.com/Smithay/smithay", rev = "56b6441a14600593d13229b9584058ec19e3e18b", optional = true }
|
smithay-drm-extras = { git = "https://github.com/Smithay/smithay", rev = "56b6441a14600593d13229b9584058ec19e3e18b", optional = true }
|
||||||
thiserror = "1"
|
thiserror = "1"
|
||||||
|
|
|
@ -29,8 +29,8 @@ require("pinnacle").setup(function(pinnacle)
|
||||||
-- Outputs -----------------------------------------------------------------------
|
-- Outputs -----------------------------------------------------------------------
|
||||||
-- You can set your own monitor layout as I have done below for my monitors.
|
-- You can set your own monitor layout as I have done below for my monitors.
|
||||||
--
|
--
|
||||||
-- local lg = output.get_by_name("DP-2") --[[@as Output]]
|
-- local lg = output.get_by_name("DP-2") --[[@as OutputHandle]]
|
||||||
-- local dell = output.get_by_name("DP-3") --[[@as Output]]
|
-- local dell = output.get_by_name("DP-3") --[[@as OutputHandle]]
|
||||||
--
|
--
|
||||||
-- dell:set_loc_left_of(lg, "bottom")
|
-- dell:set_loc_left_of(lg, "bottom")
|
||||||
|
|
||||||
|
@ -42,49 +42,55 @@ require("pinnacle").setup(function(pinnacle)
|
||||||
|
|
||||||
-- Mousebinds --------------------------------------------------------------------
|
-- Mousebinds --------------------------------------------------------------------
|
||||||
|
|
||||||
input.mousebind({"Ctrl"}, buttons.left, "Press",
|
input.mousebind({ "Ctrl" }, buttons.left, "Press", function()
|
||||||
function() window.begin_move(buttons.left) end)
|
window.begin_move(buttons.left)
|
||||||
input.mousebind({"Ctrl"}, buttons.right, "Press",
|
end)
|
||||||
function() window.begin_resize(buttons.right) end)
|
input.mousebind({ "Ctrl" }, buttons.right, "Press", function()
|
||||||
|
window.begin_resize(buttons.right)
|
||||||
|
end)
|
||||||
|
|
||||||
-- Keybinds ----------------------------------------------------------------------
|
-- Keybinds ----------------------------------------------------------------------
|
||||||
|
|
||||||
-- mod_key + Alt + q quits the compositor
|
-- mod_key + Alt + q quits the compositor
|
||||||
input.keybind({mod_key, "Alt"}, keys.q, pinnacle.quit)
|
input.keybind({ mod_key, "Alt" }, keys.q, pinnacle.quit)
|
||||||
|
|
||||||
-- mod_key + Alt + c closes the focused window
|
-- mod_key + Alt + c closes the focused window
|
||||||
input.keybind({mod_key, "Alt"}, keys.c,
|
input.keybind({ mod_key, "Alt" }, keys.c, function()
|
||||||
function() window.get_focused():close() end)
|
window.get_focused():close()
|
||||||
|
end)
|
||||||
|
|
||||||
-- mod_key + return spawns a terminal
|
-- mod_key + return spawns a terminal
|
||||||
input.keybind({mod_key}, keys.Return, function()
|
input.keybind({ mod_key }, keys.Return, function()
|
||||||
process.spawn(terminal, function(stdout, stderr, exit_code, exit_msg)
|
process.spawn(terminal, function(stdout, stderr, exit_code, exit_msg)
|
||||||
-- do something with the output here
|
-- do something with the output here
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- mod_key + Alt + Space toggle floating on the focused window
|
-- mod_key + Alt + Space toggle floating on the focused window
|
||||||
input.keybind({mod_key, "Alt"}, keys.space,
|
input.keybind({ mod_key, "Alt" }, keys.space, function()
|
||||||
function() window.get_focused():toggle_floating() end)
|
window.get_focused():toggle_floating()
|
||||||
|
end)
|
||||||
|
|
||||||
-- mod_key + f toggles fullscreen on the focused window
|
-- mod_key + f toggles fullscreen on the focused window
|
||||||
input.keybind({mod_key}, keys.f,
|
input.keybind({ mod_key }, keys.f, function()
|
||||||
function() window.get_focused():toggle_fullscreen() end)
|
window.get_focused():toggle_fullscreen()
|
||||||
|
end)
|
||||||
|
|
||||||
-- mod_key + m toggles maximized on the focused window
|
-- mod_key + m toggles maximized on the focused window
|
||||||
input.keybind({mod_key}, keys.m,
|
input.keybind({ mod_key }, keys.m, function()
|
||||||
function() window.get_focused():toggle_maximized() end)
|
window.get_focused():toggle_maximized()
|
||||||
|
end)
|
||||||
|
|
||||||
-- Tags ---------------------------------------------------------------------------
|
-- Tags ---------------------------------------------------------------------------
|
||||||
|
|
||||||
local tags = {"1", "2", "3", "4", "5"}
|
local tags = { "1", "2", "3", "4", "5" }
|
||||||
|
|
||||||
output.connect_for_all(function(op)
|
output.connect_for_all(function(op)
|
||||||
-- Add tags 1, 2, 3, 4 and 5 on all monitors, and toggle tag 1 active by default
|
-- Add tags 1, 2, 3, 4 and 5 on all monitors, and toggle tag 1 active by default
|
||||||
|
|
||||||
op:add_tags(tags)
|
op:add_tags(tags)
|
||||||
-- Same as tag.add(op, "1", "2", "3", "4", "5")
|
-- Same as tag.add(op, "1", "2", "3", "4", "5")
|
||||||
tag.toggle({name = "1", output = op})
|
tag.toggle({ name = "1", output = op })
|
||||||
|
|
||||||
-- Window rules
|
-- Window rules
|
||||||
-- Add your own window rules here. Below is an example.
|
-- Add your own window rules here. Below is an example.
|
||||||
|
@ -111,30 +117,35 @@ require("pinnacle").setup(function(pinnacle)
|
||||||
-- Create a layout cycler to cycle your tag layouts. This will store which layout each tag has
|
-- Create a layout cycler to cycle your tag layouts. This will store which layout each tag has
|
||||||
-- and change to the next or previous one in the array when the respective function is called.
|
-- and change to the next or previous one in the array when the respective function is called.
|
||||||
local layout_cycler = tag.layout_cycler({
|
local layout_cycler = tag.layout_cycler({
|
||||||
"MasterStack", "Dwindle", "Spiral", "CornerTopLeft", "CornerTopRight",
|
"MasterStack",
|
||||||
"CornerBottomLeft", "CornerBottomRight"
|
"Dwindle",
|
||||||
|
"Spiral",
|
||||||
|
"CornerTopLeft",
|
||||||
|
"CornerTopRight",
|
||||||
|
"CornerBottomLeft",
|
||||||
|
"CornerBottomRight",
|
||||||
})
|
})
|
||||||
|
|
||||||
input.keybind({mod_key}, keys.space, layout_cycler.next)
|
input.keybind({ mod_key }, keys.space, layout_cycler.next)
|
||||||
input.keybind({mod_key, "Shift"}, keys.space, layout_cycler.prev)
|
input.keybind({ mod_key, "Shift" }, keys.space, layout_cycler.prev)
|
||||||
|
|
||||||
-- Tag manipulation
|
-- Tag manipulation
|
||||||
|
|
||||||
for _, tag_name in pairs(tags) do
|
for _, tag_name in pairs(tags) do
|
||||||
-- mod_key + 1-5 switches tags
|
-- mod_key + 1-5 switches tags
|
||||||
input.keybind({mod_key}, tag_name,
|
input.keybind({ mod_key }, tag_name, function()
|
||||||
function() tag.switch_to(tag_name) end)
|
tag.switch_to(tag_name)
|
||||||
|
end)
|
||||||
-- mod_key + Shift + 1-5 toggles tags
|
-- mod_key + Shift + 1-5 toggles tags
|
||||||
input.keybind({mod_key, "Shift"}, tag_name,
|
input.keybind({ mod_key, "Shift" }, tag_name, function()
|
||||||
function() tag.toggle(tag_name) end)
|
tag.toggle(tag_name)
|
||||||
|
end)
|
||||||
-- mod_key + Alt + 1-5 moves windows to tags
|
-- mod_key + Alt + 1-5 moves windows to tags
|
||||||
input.keybind({mod_key, "Alt"}, tag_name,
|
input.keybind({ mod_key, "Alt" }, tag_name, function()
|
||||||
function()
|
|
||||||
window:get_focused():move_to_tag(tag_name)
|
window:get_focused():move_to_tag(tag_name)
|
||||||
end)
|
end)
|
||||||
-- mod_key + Shift + Alt + 1-5 toggles tags on windows
|
-- mod_key + Shift + Alt + 1-5 toggles tags on windows
|
||||||
input.keybind({mod_key, "Shift", "Alt"}, tag_name,
|
input.keybind({ mod_key, "Shift", "Alt" }, tag_name, function()
|
||||||
function()
|
|
||||||
window.get_focused():toggle_tag(tag_name)
|
window.get_focused():toggle_tag(tag_name)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
---@field WindowResizeGrab { button: integer }?
|
---@field WindowResizeGrab { button: integer }?
|
||||||
--
|
--
|
||||||
---@field Spawn { command: string[], callback_id: integer? }?
|
---@field Spawn { command: string[], callback_id: integer? }?
|
||||||
|
---@field SpawnOnce { command: string[], callback_id: integer? }?
|
||||||
---@field SetEnv { key: string, value: string }?
|
---@field SetEnv { key: string, value: string }?
|
||||||
--Tags
|
--Tags
|
||||||
---@field ToggleTag { tag_id: TagId }?
|
---@field ToggleTag { tag_id: TagId }?
|
||||||
|
|
|
@ -8,17 +8,10 @@
|
||||||
---@class ProcessModule
|
---@class ProcessModule
|
||||||
local process_module = {}
|
local process_module = {}
|
||||||
|
|
||||||
---Spawn a process with an optional callback for its stdout, stderr, and exit information.
|
---@param command string|string[]
|
||||||
---
|
|
||||||
---`callback` has the following parameters:
|
|
||||||
---
|
|
||||||
--- - `stdout` - The process's stdout printed this line.
|
|
||||||
--- - `stderr` - The process's stderr printed this line.
|
|
||||||
--- - `exit_code` - The process exited with this code.
|
|
||||||
--- - `exit_msg` - The process exited with this message.
|
|
||||||
---@param command string|string[] The command as one whole string or a table of each of its arguments
|
|
||||||
---@param callback fun(stdout: string|nil, stderr: string|nil, exit_code: integer|nil, exit_msg: string|nil)? A callback to do something whenever the process's stdout or stderr print a line, or when the process exits.
|
---@param callback fun(stdout: string|nil, stderr: string|nil, exit_code: integer|nil, exit_msg: string|nil)? A callback to do something whenever the process's stdout or stderr print a line, or when the process exits.
|
||||||
function process_module.spawn(command, callback)
|
---@param spawn_once boolean
|
||||||
|
local function spawn_inner(command, callback, spawn_once)
|
||||||
---@type integer|nil
|
---@type integer|nil
|
||||||
local callback_id = nil
|
local callback_id = nil
|
||||||
|
|
||||||
|
@ -40,14 +33,38 @@ function process_module.spawn(command, callback)
|
||||||
command_arr = command
|
command_arr = command
|
||||||
end
|
end
|
||||||
|
|
||||||
SendMsg({
|
if spawn_once then
|
||||||
Spawn = {
|
SendMsg({
|
||||||
command = command_arr,
|
SpawnOnce = {
|
||||||
callback_id = callback_id,
|
command = command_arr,
|
||||||
},
|
callback_id = callback_id,
|
||||||
})
|
},
|
||||||
|
})
|
||||||
|
else
|
||||||
|
SendMsg({
|
||||||
|
Spawn = {
|
||||||
|
command = command_arr,
|
||||||
|
callback_id = callback_id,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---Spawn a process with an optional callback for its stdout, stderr, and exit information.
|
||||||
|
---
|
||||||
|
---`callback` has the following parameters:
|
||||||
|
---
|
||||||
|
--- - `stdout` - The process's stdout printed this line.
|
||||||
|
--- - `stderr` - The process's stderr printed this line.
|
||||||
|
--- - `exit_code` - The process exited with this code.
|
||||||
|
--- - `exit_msg` - The process exited with this message.
|
||||||
|
---@param command string|string[] The command as one whole string or a table of each of its arguments
|
||||||
|
---@param callback fun(stdout: string|nil, stderr: string|nil, exit_code: integer|nil, exit_msg: string|nil)? A callback to do something whenever the process's stdout or stderr print a line, or when the process exits.
|
||||||
|
function process_module.spawn(command, callback)
|
||||||
|
spawn_inner(command, callback, false)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- PERF: callback is stored regardless if cmd was actually spawned
|
||||||
---Spawn a process only if it isn't already running, with an optional callback for its stdout, stderr, and exit information.
|
---Spawn a process only if it isn't already running, with an optional callback for its stdout, stderr, and exit information.
|
||||||
---
|
---
|
||||||
---`callback` has the following parameters:
|
---`callback` has the following parameters:
|
||||||
|
@ -61,19 +78,7 @@ end
|
||||||
---@param command string|string[] The command as one whole string or a table of each of its arguments
|
---@param command string|string[] The command as one whole string or a table of each of its arguments
|
||||||
---@param callback fun(stdout: string|nil, stderr: string|nil, exit_code: integer|nil, exit_msg: string|nil)? A callback to do something whenever the process's stdout or stderr print a line, or when the process exits.
|
---@param callback fun(stdout: string|nil, stderr: string|nil, exit_code: integer|nil, exit_msg: string|nil)? A callback to do something whenever the process's stdout or stderr print a line, or when the process exits.
|
||||||
function process_module.spawn_once(command, callback)
|
function process_module.spawn_once(command, callback)
|
||||||
local proc = ""
|
spawn_inner(command, callback, true)
|
||||||
if type(command) == "string" then
|
|
||||||
proc = command:match("%S+")
|
|
||||||
else
|
|
||||||
proc = command[1]
|
|
||||||
end
|
|
||||||
|
|
||||||
---@type string
|
|
||||||
local procs = io.popen("pgrep -f " .. proc):read("*a")
|
|
||||||
if procs:len() ~= 0 then -- if process exists, return
|
|
||||||
return
|
|
||||||
end
|
|
||||||
process_module.spawn(command, callback)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
---Set an environment variable for Pinnacle. All future processes spawned will have this env set.
|
---Set an environment variable for Pinnacle. All future processes spawned will have this env set.
|
||||||
|
|
|
@ -150,6 +150,12 @@ pub(crate) enum Msg {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
callback_id: Option<CallbackId>,
|
callback_id: Option<CallbackId>,
|
||||||
},
|
},
|
||||||
|
/// Spawn a program with an optional callback only if it isn't running.
|
||||||
|
SpawnOnce {
|
||||||
|
command: Vec<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
callback_id: Option<CallbackId>,
|
||||||
|
},
|
||||||
SetEnv {
|
SetEnv {
|
||||||
key: String,
|
key: String,
|
||||||
value: String,
|
value: String,
|
||||||
|
|
|
@ -19,6 +19,20 @@ pub fn spawn(command: Vec<&str>) -> anyhow::Result<()> {
|
||||||
send_msg(msg)
|
send_msg(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Spawn a process only if it isn't already running.
|
||||||
|
///
|
||||||
|
/// This will use Rust's (more specifically `async_process`'s) `Command` to spawn the provided
|
||||||
|
/// arguments. If you are using any shell syntax like `~`, you may need to spawn a shell
|
||||||
|
/// instead. If so, you may *also* need to correctly escape the input.
|
||||||
|
pub fn spawn_once(command: Vec<&str>) -> anyhow::Result<()> {
|
||||||
|
let msg = Msg::SpawnOnce {
|
||||||
|
command: command.into_iter().map(|s| s.to_string()).collect(),
|
||||||
|
callback_id: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
send_msg(msg)
|
||||||
|
}
|
||||||
|
|
||||||
/// Spawn a process with an optional callback for its stdout, stderr, and exit information.
|
/// Spawn a process with an optional callback for its stdout, stderr, and exit information.
|
||||||
///
|
///
|
||||||
/// `callback` has the following parameters:
|
/// `callback` has the following parameters:
|
||||||
|
@ -60,6 +74,49 @@ where
|
||||||
send_msg(msg)
|
send_msg(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: literally copy pasted from above, but will be rewritten so meh
|
||||||
|
/// Spawn a process with an optional callback for its stdout, stderr, and exit information,
|
||||||
|
/// only if it isn't already running.
|
||||||
|
///
|
||||||
|
/// `callback` has the following parameters:
|
||||||
|
/// - `0`: The process's stdout printed this line.
|
||||||
|
/// - `1`: The process's stderr printed this line.
|
||||||
|
/// - `2`: The process exited with this code.
|
||||||
|
/// - `3`: The process exited with this message.
|
||||||
|
/// - `4`: A `&mut `[`CallbackVec`] for use inside the closure.
|
||||||
|
///
|
||||||
|
/// You must also pass in a mutable reference to a [`CallbackVec`] in order to store your callback.
|
||||||
|
pub fn spawn_once_with_callback<'a, F>(
|
||||||
|
command: Vec<&str>,
|
||||||
|
mut callback: F,
|
||||||
|
callback_vec: &mut CallbackVec<'a>,
|
||||||
|
) -> anyhow::Result<()>
|
||||||
|
where
|
||||||
|
F: FnMut(Option<String>, Option<String>, Option<i32>, Option<String>, &mut CallbackVec) + 'a,
|
||||||
|
{
|
||||||
|
let args_callback = move |args: Option<Args>, callback_vec: &mut CallbackVec<'_>| {
|
||||||
|
if let Some(Args::Spawn {
|
||||||
|
stdout,
|
||||||
|
stderr,
|
||||||
|
exit_code,
|
||||||
|
exit_msg,
|
||||||
|
}) = args
|
||||||
|
{
|
||||||
|
callback(stdout, stderr, exit_code, exit_msg, callback_vec);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let len = callback_vec.callbacks.len();
|
||||||
|
callback_vec.callbacks.push(Box::new(args_callback));
|
||||||
|
|
||||||
|
let msg = Msg::SpawnOnce {
|
||||||
|
command: command.into_iter().map(|s| s.to_string()).collect(),
|
||||||
|
callback_id: Some(CallbackId(len as u32)),
|
||||||
|
};
|
||||||
|
|
||||||
|
send_msg(msg)
|
||||||
|
}
|
||||||
|
|
||||||
/// Set an environment variable for Pinnacle. All future processes spawned will have this env set.
|
/// Set an environment variable for Pinnacle. All future processes spawned will have this env set.
|
||||||
///
|
///
|
||||||
/// Note that this will only set the variable for the compositor, not the running config process.
|
/// Note that this will only set the variable for the compositor, not the running config process.
|
||||||
|
|
16
src/api.rs
16
src/api.rs
|
@ -44,14 +44,12 @@ use std::{
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use self::msg::{Msg, OutgoingMsg};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use calloop::RegistrationToken;
|
use calloop::RegistrationToken;
|
||||||
use smithay::reexports::calloop::{
|
use smithay::reexports::calloop::{
|
||||||
self, channel::Sender, generic::Generic, EventSource, Interest, Mode, PostAction,
|
self, channel::Sender, generic::Generic, EventSource, Interest, Mode, PostAction,
|
||||||
};
|
};
|
||||||
use sysinfo::{ProcessRefreshKind, RefreshKind, SystemExt};
|
|
||||||
|
|
||||||
use self::msg::{Msg, OutgoingMsg};
|
|
||||||
|
|
||||||
pub const SOCKET_NAME: &str = "pinnacle_socket";
|
pub const SOCKET_NAME: &str = "pinnacle_socket";
|
||||||
|
|
||||||
|
@ -100,15 +98,15 @@ pub struct PinnacleSocketSource {
|
||||||
impl PinnacleSocketSource {
|
impl PinnacleSocketSource {
|
||||||
/// Create a loop source that listens for connections to the provided `socket_dir`.
|
/// Create a loop source that listens for connections to the provided `socket_dir`.
|
||||||
/// This will also set PINNACLE_SOCKET for use in API implementations.
|
/// This will also set PINNACLE_SOCKET for use in API implementations.
|
||||||
pub fn new(sender: Sender<Msg>, socket_dir: &Path) -> anyhow::Result<Self> {
|
pub fn new(
|
||||||
|
sender: Sender<Msg>,
|
||||||
|
socket_dir: &Path,
|
||||||
|
multiple_instances: bool,
|
||||||
|
) -> anyhow::Result<Self> {
|
||||||
tracing::debug!("Creating socket source for dir {socket_dir:?}");
|
tracing::debug!("Creating socket source for dir {socket_dir:?}");
|
||||||
|
|
||||||
let system = sysinfo::System::new_with_specifics(
|
|
||||||
RefreshKind::new().with_processes(ProcessRefreshKind::new()),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Test if you are running multiple instances of Pinnacle
|
// Test if you are running multiple instances of Pinnacle
|
||||||
let multiple_instances = system.processes_by_exact_name("pinnacle").count() > 1;
|
// let multiple_instances = system.processes_by_exact_name("pinnacle").count() > 1;
|
||||||
|
|
||||||
// If you are, append a suffix to the socket name
|
// If you are, append a suffix to the socket name
|
||||||
let socket_name = if multiple_instances {
|
let socket_name = if multiple_instances {
|
||||||
|
|
|
@ -9,6 +9,7 @@ use smithay::{
|
||||||
utils::{Point, Rectangle, SERIAL_COUNTER},
|
utils::{Point, Rectangle, SERIAL_COUNTER},
|
||||||
wayland::{compositor, shell::xdg::XdgToplevelSurfaceData},
|
wayland::{compositor, shell::xdg::XdgToplevelSurfaceData},
|
||||||
};
|
};
|
||||||
|
use sysinfo::{PidExt, ProcessExt, ProcessRefreshKind, SystemExt};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
api::msg::{
|
api::msg::{
|
||||||
|
@ -90,6 +91,31 @@ impl State {
|
||||||
} => {
|
} => {
|
||||||
self.handle_spawn(command, callback_id);
|
self.handle_spawn(command, callback_id);
|
||||||
}
|
}
|
||||||
|
Msg::SpawnOnce {
|
||||||
|
command,
|
||||||
|
callback_id,
|
||||||
|
} => {
|
||||||
|
self.system_processes
|
||||||
|
.refresh_processes_specifics(ProcessRefreshKind::new());
|
||||||
|
|
||||||
|
let Some(arg0) = command.first() else {
|
||||||
|
tracing::warn!("No command specified for `SpawnOnce`");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let compositor_pid = std::process::id();
|
||||||
|
let already_running =
|
||||||
|
self.system_processes
|
||||||
|
.processes_by_exact_name(arg0)
|
||||||
|
.any(|proc| {
|
||||||
|
proc.parent()
|
||||||
|
.is_some_and(|parent_pid| parent_pid.as_u32() == compositor_pid)
|
||||||
|
});
|
||||||
|
|
||||||
|
if !already_running {
|
||||||
|
self.handle_spawn(command, callback_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
Msg::SetEnv { key, value } => std::env::set_var(key, value),
|
Msg::SetEnv { key, value } => std::env::set_var(key, value),
|
||||||
|
|
||||||
Msg::SetWindowSize {
|
Msg::SetWindowSize {
|
||||||
|
|
|
@ -125,6 +125,11 @@ pub enum Msg {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
callback_id: Option<CallbackId>,
|
callback_id: Option<CallbackId>,
|
||||||
},
|
},
|
||||||
|
SpawnOnce {
|
||||||
|
command: Vec<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
callback_id: Option<CallbackId>,
|
||||||
|
},
|
||||||
SetEnv {
|
SetEnv {
|
||||||
key: String,
|
key: String,
|
||||||
value: String,
|
value: String,
|
||||||
|
|
|
@ -15,6 +15,7 @@ use smithay::{
|
||||||
input::keyboard::keysyms,
|
input::keyboard::keysyms,
|
||||||
utils::{Logical, Point},
|
utils::{Logical, Point},
|
||||||
};
|
};
|
||||||
|
use sysinfo::{ProcessRefreshKind, SystemExt};
|
||||||
use toml::Table;
|
use toml::Table;
|
||||||
|
|
||||||
use crate::api::msg::{CallbackId, Modifier};
|
use crate::api::msg::{CallbackId, Modifier};
|
||||||
|
@ -236,7 +237,16 @@ impl State {
|
||||||
.unwrap_or(PathBuf::from(DEFAULT_SOCKET_DIR))
|
.unwrap_or(PathBuf::from(DEFAULT_SOCKET_DIR))
|
||||||
};
|
};
|
||||||
|
|
||||||
let socket_source = PinnacleSocketSource::new(tx_channel, &socket_dir)
|
self.system_processes
|
||||||
|
.refresh_processes_specifics(ProcessRefreshKind::new());
|
||||||
|
|
||||||
|
let multiple_instances = self
|
||||||
|
.system_processes
|
||||||
|
.processes_by_exact_name("pinnacle")
|
||||||
|
.count()
|
||||||
|
> 1;
|
||||||
|
|
||||||
|
let socket_source = PinnacleSocketSource::new(tx_channel, &socket_dir, multiple_instances)
|
||||||
.context("Failed to create socket source")?;
|
.context("Failed to create socket source")?;
|
||||||
|
|
||||||
let reload_keybind = metaconfig.reload_keybind;
|
let reload_keybind = metaconfig.reload_keybind;
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use nix::unistd::Uid;
|
use nix::unistd::Uid;
|
||||||
|
use sysinfo::{ProcessRefreshKind, RefreshKind, SystemExt};
|
||||||
use tracing_appender::rolling::Rotation;
|
use tracing_appender::rolling::Rotation;
|
||||||
use tracing_subscriber::{fmt::writer::MakeWriterExt, EnvFilter};
|
use tracing_subscriber::{fmt::writer::MakeWriterExt, EnvFilter};
|
||||||
use xdg::BaseDirectories;
|
use xdg::BaseDirectories;
|
||||||
|
@ -35,6 +36,10 @@ mod window;
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
pub static ref XDG_BASE_DIRS: BaseDirectories =
|
pub static ref XDG_BASE_DIRS: BaseDirectories =
|
||||||
BaseDirectories::with_prefix("pinnacle").expect("couldn't create xdg BaseDirectories");
|
BaseDirectories::with_prefix("pinnacle").expect("couldn't create xdg BaseDirectories");
|
||||||
|
pub static ref SYSTEM_PROCESSES: sysinfo::System =
|
||||||
|
sysinfo::System::new_with_specifics(
|
||||||
|
RefreshKind::new().with_processes(ProcessRefreshKind::new()),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(clap::Args, Debug)]
|
#[derive(clap::Args, Debug)]
|
||||||
|
|
|
@ -41,6 +41,7 @@ use smithay::{
|
||||||
},
|
},
|
||||||
xwayland::{X11Wm, XWayland, XWaylandEvent},
|
xwayland::{X11Wm, XWayland, XWaylandEvent},
|
||||||
};
|
};
|
||||||
|
use sysinfo::{ProcessRefreshKind, RefreshKind, SystemExt};
|
||||||
|
|
||||||
use crate::input::InputState;
|
use crate::input::InputState;
|
||||||
|
|
||||||
|
@ -98,6 +99,8 @@ pub struct State {
|
||||||
pub xwayland: XWayland,
|
pub xwayland: XWayland,
|
||||||
pub xwm: Option<X11Wm>,
|
pub xwm: Option<X11Wm>,
|
||||||
pub xdisplay: Option<u32>,
|
pub xdisplay: Option<u32>,
|
||||||
|
|
||||||
|
pub system_processes: sysinfo::System,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
|
@ -281,6 +284,10 @@ impl State {
|
||||||
xwayland,
|
xwayland,
|
||||||
xwm: None,
|
xwm: None,
|
||||||
xdisplay: None,
|
xdisplay: None,
|
||||||
|
|
||||||
|
system_processes: sysinfo::System::new_with_specifics(
|
||||||
|
RefreshKind::new().with_processes(ProcessRefreshKind::new()),
|
||||||
|
),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue