mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2025-01-13 08:01:05 +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",
|
||||
"rustix 0.38.28",
|
||||
"slab",
|
||||
"tracing 0.1.37",
|
||||
"tracing",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
|
@ -1458,7 +1458,7 @@ dependencies = [
|
|||
"sysinfo",
|
||||
"thiserror",
|
||||
"toml",
|
||||
"tracing 0.2.0",
|
||||
"tracing",
|
||||
"tracing-appender",
|
||||
"tracing-subscriber",
|
||||
"x11rb 0.13.0",
|
||||
|
@ -1483,7 +1483,7 @@ dependencies = [
|
|||
"concurrent-queue",
|
||||
"pin-project-lite",
|
||||
"rustix 0.38.28",
|
||||
"tracing 0.1.37",
|
||||
"tracing",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
|
@ -1855,7 +1855,7 @@ dependencies = [
|
|||
"smallvec",
|
||||
"tempfile",
|
||||
"thiserror",
|
||||
"tracing 0.1.37",
|
||||
"tracing",
|
||||
"udev 0.8.0",
|
||||
"wayland-backend",
|
||||
"wayland-egl",
|
||||
|
@ -2079,30 +2079,20 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.37"
|
||||
version = "0.1.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
|
||||
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"
|
||||
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
|
||||
dependencies = [
|
||||
"pin-project-lite",
|
||||
"tracing-attributes 0.2.0",
|
||||
"tracing-core 0.2.0",
|
||||
"tracing-attributes",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-appender"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/tokio-rs/tracing?rev=84f0a60#84f0a608123a651f268ff76347f81182f487d3b1"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"thiserror",
|
||||
|
@ -2112,19 +2102,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tracing-attributes"
|
||||
version = "0.1.24"
|
||||
version = "0.1.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74"
|
||||
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"
|
||||
checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -2133,35 +2113,30 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.31"
|
||||
version = "0.1.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/tokio-rs/tracing?rev=84f0a60#84f0a608123a651f268ff76347f81182f487d3b1"
|
||||
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"valuable",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-log"
|
||||
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 = [
|
||||
"log",
|
||||
"once_cell",
|
||||
"tracing-core 0.2.0",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-subscriber"
|
||||
version = "0.3.0"
|
||||
source = "git+https://github.com/tokio-rs/tracing?rev=84f0a60#84f0a608123a651f268ff76347f81182f487d3b1"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
|
||||
dependencies = [
|
||||
"matchers",
|
||||
"nu-ansi-term",
|
||||
|
@ -2170,8 +2145,8 @@ dependencies = [
|
|||
"sharded-slab",
|
||||
"smallvec",
|
||||
"thread_local",
|
||||
"tracing 0.2.0",
|
||||
"tracing-core 0.2.0",
|
||||
"tracing",
|
||||
"tracing-core",
|
||||
"tracing-log",
|
||||
]
|
||||
|
||||
|
@ -2216,6 +2191,12 @@ version = "0.2.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||
|
||||
[[package]]
|
||||
name = "valuable"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
|
|
|
@ -10,9 +10,9 @@ repository = "https://github.com/pinnacle-comp/pinnacle/"
|
|||
keywords = ["wayland", "compositor", "smithay", "lua"]
|
||||
|
||||
[dependencies]
|
||||
tracing = { git = "https://github.com/tokio-rs/tracing", rev = "84f0a60" }
|
||||
tracing-subscriber = { git = "https://github.com/tokio-rs/tracing", rev = "84f0a60", features = ["env-filter"] }
|
||||
tracing-appender = { git = "https://github.com/tokio-rs/tracing", rev = "84f0a60" }
|
||||
tracing = "0.1.40"
|
||||
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
||||
tracing-appender = "0.2.3"
|
||||
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 }
|
||||
thiserror = "1"
|
||||
|
|
|
@ -29,8 +29,8 @@ require("pinnacle").setup(function(pinnacle)
|
|||
-- Outputs -----------------------------------------------------------------------
|
||||
-- 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 dell = output.get_by_name("DP-3") --[[@as Output]]
|
||||
-- local lg = output.get_by_name("DP-2") --[[@as OutputHandle]]
|
||||
-- local dell = output.get_by_name("DP-3") --[[@as OutputHandle]]
|
||||
--
|
||||
-- dell:set_loc_left_of(lg, "bottom")
|
||||
|
||||
|
@ -42,49 +42,55 @@ require("pinnacle").setup(function(pinnacle)
|
|||
|
||||
-- Mousebinds --------------------------------------------------------------------
|
||||
|
||||
input.mousebind({"Ctrl"}, buttons.left, "Press",
|
||||
function() window.begin_move(buttons.left) end)
|
||||
input.mousebind({"Ctrl"}, buttons.right, "Press",
|
||||
function() window.begin_resize(buttons.right) end)
|
||||
input.mousebind({ "Ctrl" }, buttons.left, "Press", function()
|
||||
window.begin_move(buttons.left)
|
||||
end)
|
||||
input.mousebind({ "Ctrl" }, buttons.right, "Press", function()
|
||||
window.begin_resize(buttons.right)
|
||||
end)
|
||||
|
||||
-- Keybinds ----------------------------------------------------------------------
|
||||
|
||||
-- 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
|
||||
input.keybind({mod_key, "Alt"}, keys.c,
|
||||
function() window.get_focused():close() end)
|
||||
input.keybind({ mod_key, "Alt" }, keys.c, function()
|
||||
window.get_focused():close()
|
||||
end)
|
||||
|
||||
-- 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)
|
||||
-- do something with the output here
|
||||
end)
|
||||
end)
|
||||
|
||||
-- mod_key + Alt + Space toggle floating on the focused window
|
||||
input.keybind({mod_key, "Alt"}, keys.space,
|
||||
function() window.get_focused():toggle_floating() end)
|
||||
input.keybind({ mod_key, "Alt" }, keys.space, function()
|
||||
window.get_focused():toggle_floating()
|
||||
end)
|
||||
|
||||
-- mod_key + f toggles fullscreen on the focused window
|
||||
input.keybind({mod_key}, keys.f,
|
||||
function() window.get_focused():toggle_fullscreen() end)
|
||||
input.keybind({ mod_key }, keys.f, function()
|
||||
window.get_focused():toggle_fullscreen()
|
||||
end)
|
||||
|
||||
-- mod_key + m toggles maximized on the focused window
|
||||
input.keybind({mod_key}, keys.m,
|
||||
function() window.get_focused():toggle_maximized() end)
|
||||
input.keybind({ mod_key }, keys.m, function()
|
||||
window.get_focused():toggle_maximized()
|
||||
end)
|
||||
|
||||
-- Tags ---------------------------------------------------------------------------
|
||||
|
||||
local tags = {"1", "2", "3", "4", "5"}
|
||||
local tags = { "1", "2", "3", "4", "5" }
|
||||
|
||||
output.connect_for_all(function(op)
|
||||
-- Add tags 1, 2, 3, 4 and 5 on all monitors, and toggle tag 1 active by default
|
||||
|
||||
op:add_tags(tags)
|
||||
-- Same as tag.add(op, "1", "2", "3", "4", "5")
|
||||
tag.toggle({name = "1", output = op})
|
||||
tag.toggle({ name = "1", output = op })
|
||||
|
||||
-- Window rules
|
||||
-- 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
|
||||
-- and change to the next or previous one in the array when the respective function is called.
|
||||
local layout_cycler = tag.layout_cycler({
|
||||
"MasterStack", "Dwindle", "Spiral", "CornerTopLeft", "CornerTopRight",
|
||||
"CornerBottomLeft", "CornerBottomRight"
|
||||
"MasterStack",
|
||||
"Dwindle",
|
||||
"Spiral",
|
||||
"CornerTopLeft",
|
||||
"CornerTopRight",
|
||||
"CornerBottomLeft",
|
||||
"CornerBottomRight",
|
||||
})
|
||||
|
||||
input.keybind({mod_key}, keys.space, layout_cycler.next)
|
||||
input.keybind({mod_key, "Shift"}, keys.space, layout_cycler.prev)
|
||||
input.keybind({ mod_key }, keys.space, layout_cycler.next)
|
||||
input.keybind({ mod_key, "Shift" }, keys.space, layout_cycler.prev)
|
||||
|
||||
-- Tag manipulation
|
||||
|
||||
for _, tag_name in pairs(tags) do
|
||||
-- mod_key + 1-5 switches tags
|
||||
input.keybind({mod_key}, tag_name,
|
||||
function() tag.switch_to(tag_name) end)
|
||||
input.keybind({ mod_key }, tag_name, function()
|
||||
tag.switch_to(tag_name)
|
||||
end)
|
||||
-- mod_key + Shift + 1-5 toggles tags
|
||||
input.keybind({mod_key, "Shift"}, tag_name,
|
||||
function() tag.toggle(tag_name) end)
|
||||
input.keybind({ mod_key, "Shift" }, tag_name, function()
|
||||
tag.toggle(tag_name)
|
||||
end)
|
||||
-- mod_key + Alt + 1-5 moves windows to tags
|
||||
input.keybind({mod_key, "Alt"}, tag_name,
|
||||
function()
|
||||
input.keybind({ mod_key, "Alt" }, tag_name, function()
|
||||
window:get_focused():move_to_tag(tag_name)
|
||||
end)
|
||||
-- mod_key + Shift + Alt + 1-5 toggles tags on windows
|
||||
input.keybind({mod_key, "Shift", "Alt"}, tag_name,
|
||||
function()
|
||||
input.keybind({ mod_key, "Shift", "Alt" }, tag_name, function()
|
||||
window.get_focused():toggle_tag(tag_name)
|
||||
end)
|
||||
end
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
---@field WindowResizeGrab { button: integer }?
|
||||
--
|
||||
---@field Spawn { command: string[], callback_id: integer? }?
|
||||
---@field SpawnOnce { command: string[], callback_id: integer? }?
|
||||
---@field SetEnv { key: string, value: string }?
|
||||
--Tags
|
||||
---@field ToggleTag { tag_id: TagId }?
|
||||
|
|
|
@ -8,17 +8,10 @@
|
|||
---@class ProcessModule
|
||||
local process_module = {}
|
||||
|
||||
---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 command string|string[]
|
||||
---@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
|
||||
local callback_id = nil
|
||||
|
||||
|
@ -40,14 +33,38 @@ function process_module.spawn(command, callback)
|
|||
command_arr = command
|
||||
end
|
||||
|
||||
SendMsg({
|
||||
Spawn = {
|
||||
command = command_arr,
|
||||
callback_id = callback_id,
|
||||
},
|
||||
})
|
||||
if spawn_once then
|
||||
SendMsg({
|
||||
SpawnOnce = {
|
||||
command = command_arr,
|
||||
callback_id = callback_id,
|
||||
},
|
||||
})
|
||||
else
|
||||
SendMsg({
|
||||
Spawn = {
|
||||
command = command_arr,
|
||||
callback_id = callback_id,
|
||||
},
|
||||
})
|
||||
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.
|
||||
---
|
||||
---`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 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)
|
||||
local proc = ""
|
||||
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)
|
||||
spawn_inner(command, callback, true)
|
||||
end
|
||||
|
||||
---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)]
|
||||
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 {
|
||||
key: String,
|
||||
value: String,
|
||||
|
|
|
@ -19,6 +19,20 @@ pub fn spawn(command: Vec<&str>) -> anyhow::Result<()> {
|
|||
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.
|
||||
///
|
||||
/// `callback` has the following parameters:
|
||||
|
@ -60,6 +74,49 @@ where
|
|||
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.
|
||||
///
|
||||
/// 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},
|
||||
};
|
||||
|
||||
use self::msg::{Msg, OutgoingMsg};
|
||||
use anyhow::Context;
|
||||
use calloop::RegistrationToken;
|
||||
use smithay::reexports::calloop::{
|
||||
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";
|
||||
|
||||
|
@ -100,15 +98,15 @@ pub struct PinnacleSocketSource {
|
|||
impl PinnacleSocketSource {
|
||||
/// Create a loop source that listens for connections to the provided `socket_dir`.
|
||||
/// 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:?}");
|
||||
|
||||
let system = sysinfo::System::new_with_specifics(
|
||||
RefreshKind::new().with_processes(ProcessRefreshKind::new()),
|
||||
);
|
||||
|
||||
// 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
|
||||
let socket_name = if multiple_instances {
|
||||
|
|
|
@ -9,6 +9,7 @@ use smithay::{
|
|||
utils::{Point, Rectangle, SERIAL_COUNTER},
|
||||
wayland::{compositor, shell::xdg::XdgToplevelSurfaceData},
|
||||
};
|
||||
use sysinfo::{PidExt, ProcessExt, ProcessRefreshKind, SystemExt};
|
||||
|
||||
use crate::{
|
||||
api::msg::{
|
||||
|
@ -90,6 +91,31 @@ impl State {
|
|||
} => {
|
||||
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::SetWindowSize {
|
||||
|
|
|
@ -125,6 +125,11 @@ pub enum Msg {
|
|||
#[serde(default)]
|
||||
callback_id: Option<CallbackId>,
|
||||
},
|
||||
SpawnOnce {
|
||||
command: Vec<String>,
|
||||
#[serde(default)]
|
||||
callback_id: Option<CallbackId>,
|
||||
},
|
||||
SetEnv {
|
||||
key: String,
|
||||
value: String,
|
||||
|
|
|
@ -15,6 +15,7 @@ use smithay::{
|
|||
input::keyboard::keysyms,
|
||||
utils::{Logical, Point},
|
||||
};
|
||||
use sysinfo::{ProcessRefreshKind, SystemExt};
|
||||
use toml::Table;
|
||||
|
||||
use crate::api::msg::{CallbackId, Modifier};
|
||||
|
@ -236,7 +237,16 @@ impl State {
|
|||
.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")?;
|
||||
|
||||
let reload_keybind = metaconfig.reload_keybind;
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
use clap::Parser;
|
||||
use nix::unistd::Uid;
|
||||
use sysinfo::{ProcessRefreshKind, RefreshKind, SystemExt};
|
||||
use tracing_appender::rolling::Rotation;
|
||||
use tracing_subscriber::{fmt::writer::MakeWriterExt, EnvFilter};
|
||||
use xdg::BaseDirectories;
|
||||
|
@ -35,6 +36,10 @@ mod window;
|
|||
lazy_static::lazy_static! {
|
||||
pub static ref XDG_BASE_DIRS: 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)]
|
||||
|
|
|
@ -41,6 +41,7 @@ use smithay::{
|
|||
},
|
||||
xwayland::{X11Wm, XWayland, XWaylandEvent},
|
||||
};
|
||||
use sysinfo::{ProcessRefreshKind, RefreshKind, SystemExt};
|
||||
|
||||
use crate::input::InputState;
|
||||
|
||||
|
@ -98,6 +99,8 @@ pub struct State {
|
|||
pub xwayland: XWayland,
|
||||
pub xwm: Option<X11Wm>,
|
||||
pub xdisplay: Option<u32>,
|
||||
|
||||
pub system_processes: sysinfo::System,
|
||||
}
|
||||
|
||||
impl State {
|
||||
|
@ -281,6 +284,10 @@ impl State {
|
|||
xwayland,
|
||||
xwm: None,
|
||||
xdisplay: None,
|
||||
|
||||
system_processes: sysinfo::System::new_with_specifics(
|
||||
RefreshKind::new().with_processes(ProcessRefreshKind::new()),
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue