mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2024-12-25 09:59:21 +01:00
Merge pull request #256 from pinnacle-comp/snowcap-lua
Some checks failed
CI (Pinnacle) / Build (push) Waiting to run
CI (Pinnacle) / Run tests (push) Waiting to run
CI (Pinnacle) / Check formatting (push) Waiting to run
CI (Pinnacle) / Clippy check (push) Waiting to run
Build Lua Docs / Build Lua docs (push) Has been cancelled
Build Rust Docs / Build docs (push) Has been cancelled
Some checks failed
CI (Pinnacle) / Build (push) Waiting to run
CI (Pinnacle) / Run tests (push) Waiting to run
CI (Pinnacle) / Check formatting (push) Waiting to run
CI (Pinnacle) / Clippy check (push) Waiting to run
Build Lua Docs / Build Lua docs (push) Has been cancelled
Build Rust Docs / Build docs (push) Has been cancelled
Preliminary Snowcap integration (Lua)
This commit is contained in:
commit
aada66ce70
15 changed files with 812 additions and 36 deletions
26
README.md
26
README.md
|
@ -35,14 +35,10 @@ Pinnacle is a Wayland compositor built in Rust using [Smithay](https://github.co
|
||||||
It's my attempt at creating something like [AwesomeWM](https://github.com/awesomeWM/awesome)
|
It's my attempt at creating something like [AwesomeWM](https://github.com/awesomeWM/awesome)
|
||||||
for Wayland.
|
for Wayland.
|
||||||
|
|
||||||
### What is Snowcap?
|
Pinnacle comes integrated with [Snowcap](https://github.com/pinnacle-comp/snowcap), a
|
||||||
You will see references to Snowcap throughout this README. [Snowcap](https://github.com/pinnacle-comp/snowcap) is the
|
very, *very* WIP widget system. Currently it's only being used for the builtin quit prompt and keybind overlay.
|
||||||
very, *very* WIP widget system for Pinnacle. Currently it's only being used for the builtin quit prompt and keybind overlay.
|
|
||||||
In the future, Snowcap will be used for everything Awesome uses its widget system for: a taskbar, system tray, etc.
|
In the future, Snowcap will be used for everything Awesome uses its widget system for: a taskbar, system tray, etc.
|
||||||
|
|
||||||
> [!NOTE]
|
|
||||||
> Only the Rust API has implemented Snowcap integration currently. Lua support soon™️
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
- Tag system
|
- Tag system
|
||||||
- Customizable layouts, including most of the ones from Awesome
|
- Customizable layouts, including most of the ones from Awesome
|
||||||
|
@ -170,16 +166,20 @@ the Lua or Rust default configs standalone, run one of the following in the crat
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
# For a Lua configuration
|
# For a Lua configuration
|
||||||
just install run -- -c "./api/lua/examples/default"
|
just install run -- -c ./api/lua/examples/default
|
||||||
|
|
||||||
# For a Rust configuration
|
# For a Rust configuration
|
||||||
cargo run -- -c "./api/rust/examples/default_config"
|
cargo run -- -c ./api/rust/examples/default_config
|
||||||
```
|
```
|
||||||
|
|
||||||
When running the default Rust config standalone without compiled Snowcap integration,
|
When running without compiled Snowcap integration,
|
||||||
run the one in the following directory:
|
use the following directories instead:
|
||||||
```sh
|
```sh
|
||||||
cargo run -- -c "./api/rust/examples/default_config_no_snowcap"
|
# Lua
|
||||||
|
just install run -- -c ./api/lua/examples/default_no_snowcap
|
||||||
|
|
||||||
|
# Rust
|
||||||
|
cargo run -- -c ./api/rust/examples/default_config_no_snowcap
|
||||||
```
|
```
|
||||||
|
|
||||||
## Custom configuration
|
## Custom configuration
|
||||||
|
@ -200,6 +200,8 @@ It will then generate a config at that directory. If Lua is chosen and there are
|
||||||
files in the directory, the generator will prompt to rename them to a backup before continuing.
|
files in the directory, the generator will prompt to rename them to a backup before continuing.
|
||||||
If Rust is chosen, the directory must be manually emptied to continue.
|
If Rust is chosen, the directory must be manually emptied to continue.
|
||||||
|
|
||||||
|
Note that this currently copies default configs *with* Snowcap integration.
|
||||||
|
|
||||||
Run `cargo run -- config gen --help` for information on the command.
|
Run `cargo run -- config gen --help` for information on the command.
|
||||||
|
|
||||||
## More on configuration
|
## More on configuration
|
||||||
|
@ -252,6 +254,8 @@ Rust: https://pinnacle-comp.github.io/rust-reference/main.</b>
|
||||||
> Documentation for other branches can be reached by replacing `main` with the branch you want.
|
> Documentation for other branches can be reached by replacing `main` with the branch you want.
|
||||||
|
|
||||||
# Controls
|
# Controls
|
||||||
|
> Yes, ctrl is a bad mod key I know, this will be changed to Awesome keybinds soon
|
||||||
|
|
||||||
The following are the default controls in the [`default_config`](api/rust/examples/default_config/main.rs).
|
The following are the default controls in the [`default_config`](api/rust/examples/default_config/main.rs).
|
||||||
| Binding | Action |
|
| Binding | Action |
|
||||||
|----------------------------------------------|------------------------------------|
|
|----------------------------------------------|------------------------------------|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/LuaLS/vscode-lua/master/setting/schema.json",
|
"$schema": "https://raw.githubusercontent.com/LuaLS/vscode-lua/master/setting/schema.json",
|
||||||
"workspace.library": ["./"],
|
"workspace.library": ["./", "../../snowcap/api/lua"],
|
||||||
"runtime.version": "Lua 5.2",
|
"runtime.version": "Lua 5.2",
|
||||||
|
|
||||||
"--comment": "Format using Stylua instead",
|
"--comment": "Format using Stylua instead",
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/LuaLS/vscode-lua/master/setting/schema.json",
|
"$schema": "https://raw.githubusercontent.com/LuaLS/vscode-lua/master/setting/schema.json",
|
||||||
"workspace.library": ["~/.luarocks/share/lua/5.4/pinnacle.lua", "~/.luarocks/share/lua/5.4/pinnacle"],
|
"workspace.library": [
|
||||||
|
"~/.luarocks/share/lua/5.4/pinnacle.lua",
|
||||||
|
"~/.luarocks/share/lua/5.4/pinnacle",
|
||||||
|
"~/.luarocks/share/lua/5.4/snowcap.lua",
|
||||||
|
"~/.luarocks/share/lua/5.4/snowcap"
|
||||||
|
],
|
||||||
"runtime.version": "Lua 5.4",
|
"runtime.version": "Lua 5.4",
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ require("pinnacle").setup(function(Pinnacle)
|
||||||
local Window = Pinnacle.window
|
local Window = Pinnacle.window
|
||||||
local Layout = Pinnacle.layout
|
local Layout = Pinnacle.layout
|
||||||
local Util = Pinnacle.util
|
local Util = Pinnacle.util
|
||||||
|
local Snowcap = Pinnacle.snowcap
|
||||||
|
|
||||||
local key = Input.key
|
local key = Input.key
|
||||||
|
|
||||||
|
@ -15,6 +16,13 @@ require("pinnacle").setup(function(Pinnacle)
|
||||||
|
|
||||||
local terminal = "alacritty"
|
local terminal = "alacritty"
|
||||||
|
|
||||||
|
Input.keybind({ mod_key }, "s", function()
|
||||||
|
Snowcap.integration.keybind_overlay():show()
|
||||||
|
end, {
|
||||||
|
group = "Compositor",
|
||||||
|
description = "Show the keybind overlay",
|
||||||
|
})
|
||||||
|
|
||||||
--------------------
|
--------------------
|
||||||
-- Mousebinds --
|
-- Mousebinds --
|
||||||
--------------------
|
--------------------
|
||||||
|
@ -33,7 +41,7 @@ require("pinnacle").setup(function(Pinnacle)
|
||||||
|
|
||||||
-- mod_key + alt + q = Quit Pinnacle
|
-- mod_key + alt + q = Quit Pinnacle
|
||||||
Input.keybind({ mod_key, "alt" }, "q", function()
|
Input.keybind({ mod_key, "alt" }, "q", function()
|
||||||
Pinnacle.quit()
|
Snowcap.integration.quit_prompt():show()
|
||||||
end, {
|
end, {
|
||||||
group = "Compositor",
|
group = "Compositor",
|
||||||
description = "Quit Pinnacle",
|
description = "Quit Pinnacle",
|
||||||
|
|
10
api/lua/examples/default_no_snowcap/.luarc.json
Normal file
10
api/lua/examples/default_no_snowcap/.luarc.json
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://raw.githubusercontent.com/LuaLS/vscode-lua/master/setting/schema.json",
|
||||||
|
"workspace.library": [
|
||||||
|
"~/.luarocks/share/lua/5.4/pinnacle.lua",
|
||||||
|
"~/.luarocks/share/lua/5.4/pinnacle",
|
||||||
|
"~/.luarocks/share/lua/5.4/snowcap.lua",
|
||||||
|
"~/.luarocks/share/lua/5.4/snowcap"
|
||||||
|
],
|
||||||
|
"runtime.version": "Lua 5.4",
|
||||||
|
}
|
314
api/lua/examples/default_no_snowcap/default_config.lua
Normal file
314
api/lua/examples/default_no_snowcap/default_config.lua
Normal file
|
@ -0,0 +1,314 @@
|
||||||
|
-- neovim users be like
|
||||||
|
require("pinnacle").setup(function(Pinnacle)
|
||||||
|
local Input = Pinnacle.input
|
||||||
|
local Process = Pinnacle.process
|
||||||
|
local Output = Pinnacle.output
|
||||||
|
local Tag = Pinnacle.tag
|
||||||
|
local Window = Pinnacle.window
|
||||||
|
local Layout = Pinnacle.layout
|
||||||
|
local Util = Pinnacle.util
|
||||||
|
|
||||||
|
local key = Input.key
|
||||||
|
|
||||||
|
---@type Modifier
|
||||||
|
local mod_key = "ctrl"
|
||||||
|
|
||||||
|
local terminal = "alacritty"
|
||||||
|
|
||||||
|
--------------------
|
||||||
|
-- Mousebinds --
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Input.mousebind({ mod_key }, "btn_left", "press", function()
|
||||||
|
Window.begin_move("btn_left")
|
||||||
|
end)
|
||||||
|
|
||||||
|
Input.mousebind({ mod_key }, "btn_right", "press", function()
|
||||||
|
Window.begin_resize("btn_right")
|
||||||
|
end)
|
||||||
|
|
||||||
|
--------------------
|
||||||
|
-- Keybinds --
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
-- mod_key + alt + q = Quit Pinnacle
|
||||||
|
Input.keybind({ mod_key, "alt" }, "q", function()
|
||||||
|
Pinnacle.quit()
|
||||||
|
end, {
|
||||||
|
group = "Compositor",
|
||||||
|
description = "Quit Pinnacle",
|
||||||
|
})
|
||||||
|
|
||||||
|
-- mod_key + alt + r = Reload config
|
||||||
|
Input.keybind({ mod_key, "alt" }, "r", function()
|
||||||
|
Pinnacle.reload_config()
|
||||||
|
end, {
|
||||||
|
group = "Compositor",
|
||||||
|
description = "Reload the config",
|
||||||
|
})
|
||||||
|
|
||||||
|
-- mod_key + alt + c = Close window
|
||||||
|
Input.keybind({ mod_key, "alt" }, "c", function()
|
||||||
|
local focused = Window.get_focused()
|
||||||
|
if focused then
|
||||||
|
focused:close()
|
||||||
|
end
|
||||||
|
end, {
|
||||||
|
group = "Window",
|
||||||
|
description = "Close the focused window",
|
||||||
|
})
|
||||||
|
|
||||||
|
-- mod_key + alt + Return = Spawn `terminal`
|
||||||
|
Input.keybind({ mod_key }, key.Return, function()
|
||||||
|
Process.spawn(terminal)
|
||||||
|
end, {
|
||||||
|
group = "Process",
|
||||||
|
description = "Spawn `alacritty`",
|
||||||
|
})
|
||||||
|
|
||||||
|
-- mod_key + alt + space = Toggle floating
|
||||||
|
Input.keybind({ mod_key, "alt" }, key.space, function()
|
||||||
|
local focused = Window.get_focused()
|
||||||
|
if focused then
|
||||||
|
focused:toggle_floating()
|
||||||
|
focused:raise()
|
||||||
|
end
|
||||||
|
end, {
|
||||||
|
group = "Window",
|
||||||
|
description = "Toggle floating on the focused window",
|
||||||
|
})
|
||||||
|
|
||||||
|
-- mod_key + f = Toggle fullscreen
|
||||||
|
Input.keybind({ mod_key }, "f", function()
|
||||||
|
local focused = Window.get_focused()
|
||||||
|
if focused then
|
||||||
|
focused:toggle_fullscreen()
|
||||||
|
focused:raise()
|
||||||
|
end
|
||||||
|
end, {
|
||||||
|
group = "Window",
|
||||||
|
description = "Toggle fullscreen on the focused window",
|
||||||
|
})
|
||||||
|
|
||||||
|
-- mod_key + m = Toggle maximized
|
||||||
|
Input.keybind({ mod_key }, "m", function()
|
||||||
|
local focused = Window.get_focused()
|
||||||
|
if focused then
|
||||||
|
focused:toggle_maximized()
|
||||||
|
focused:raise()
|
||||||
|
end
|
||||||
|
end, {
|
||||||
|
group = "Window",
|
||||||
|
description = "Toggle maximized on the focused window",
|
||||||
|
})
|
||||||
|
|
||||||
|
----------------------
|
||||||
|
-- Tags and Outputs --
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
local tag_names = { "1", "2", "3", "4", "5" }
|
||||||
|
|
||||||
|
-- Setup outputs.
|
||||||
|
--
|
||||||
|
-- `Output.setup` allows you to declare things like mode, scale, and tags for outputs.
|
||||||
|
-- Here we give all outputs tags 1 through 5.
|
||||||
|
Output.setup({
|
||||||
|
-- "*" matches all outputs
|
||||||
|
["*"] = { tags = tag_names },
|
||||||
|
})
|
||||||
|
|
||||||
|
-- If you want to declare output locations as well, you can use `Output.setup_locs`.
|
||||||
|
-- This will additionally allow you to recalculate output locations on signals like
|
||||||
|
-- output connect, disconnect, and resize.
|
||||||
|
--
|
||||||
|
-- Read the admittedly scuffed docs for more.
|
||||||
|
|
||||||
|
-- Tag keybinds
|
||||||
|
for _, tag_name in ipairs(tag_names) do
|
||||||
|
-- nil-safety: tags are guaranteed to be on the outputs due to connect_for_all above
|
||||||
|
|
||||||
|
-- mod_key + 1-5 = Switch to tags 1-5
|
||||||
|
Input.keybind({ mod_key }, tag_name, function()
|
||||||
|
Tag.get(tag_name):switch_to()
|
||||||
|
end, {
|
||||||
|
group = "Tag",
|
||||||
|
description = "Switch to tag " .. tag_name,
|
||||||
|
})
|
||||||
|
|
||||||
|
-- mod_key + shift + 1-5 = Toggle tags 1-5
|
||||||
|
Input.keybind({ mod_key, "shift" }, tag_name, function()
|
||||||
|
Tag.get(tag_name):toggle_active()
|
||||||
|
end, {
|
||||||
|
group = "Tag",
|
||||||
|
description = "Toggle tag " .. tag_name,
|
||||||
|
})
|
||||||
|
|
||||||
|
-- mod_key + alt + 1-5 = Move window to tags 1-5
|
||||||
|
Input.keybind({ mod_key, "alt" }, tag_name, function()
|
||||||
|
local focused = Window.get_focused()
|
||||||
|
if focused then
|
||||||
|
focused:move_to_tag(Tag.get(tag_name) --[[@as TagHandle]])
|
||||||
|
end
|
||||||
|
end, {
|
||||||
|
group = "Tag",
|
||||||
|
description = "Move the focused window to tag " .. tag_name,
|
||||||
|
})
|
||||||
|
|
||||||
|
-- mod_key + shift + alt + 1-5 = Toggle tags 1-5 on window
|
||||||
|
Input.keybind({ mod_key, "shift", "alt" }, tag_name, function()
|
||||||
|
local focused = Window.get_focused()
|
||||||
|
if focused then
|
||||||
|
focused:toggle_tag(Tag.get(tag_name) --[[@as TagHandle]])
|
||||||
|
end
|
||||||
|
end, {
|
||||||
|
group = "Tag",
|
||||||
|
description = "Toggle tag " .. tag_name .. " on the focused window",
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
--------------------
|
||||||
|
-- Layouts --
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
-- Pinnacle does not manage layouts compositor-side.
|
||||||
|
-- Instead, it delegates computation of layouts to your config,
|
||||||
|
-- which provides an interface to calculate the size and location of
|
||||||
|
-- windows that the compositor will use to position windows.
|
||||||
|
--
|
||||||
|
-- If you're familiar with River's layout generators, you'll understand the system here
|
||||||
|
-- a bit better.
|
||||||
|
--
|
||||||
|
-- The Lua API provides two layout system abstractions:
|
||||||
|
-- 1. Layout managers, and
|
||||||
|
-- 2. Layout generators.
|
||||||
|
--
|
||||||
|
-- ### Layout Managers ###
|
||||||
|
-- A layout manager is a table that contains a `get_active` function
|
||||||
|
-- that returns some layout generator.
|
||||||
|
-- A manager is meant to keep track of and choose various layout generators
|
||||||
|
-- across your usage of the compositor.
|
||||||
|
--
|
||||||
|
-- ### Layout generators ###
|
||||||
|
-- A layout generator is a table that holds some state as well as
|
||||||
|
-- the `layout` function, which takes in layout arguments and computes
|
||||||
|
-- an array of geometries that will determine the size and position
|
||||||
|
-- of windows being laid out.
|
||||||
|
--
|
||||||
|
-- There is one built-in layout manager and five built-in layout generators,
|
||||||
|
-- as shown below.
|
||||||
|
--
|
||||||
|
-- Additionally, this system is designed to be user-extensible;
|
||||||
|
-- you are free to create your own layout managers and generators for
|
||||||
|
-- maximum customizability! Docs for doing so are in the works, so sit tight.
|
||||||
|
|
||||||
|
-- Create a cycling layout manager. This provides methods to cycle
|
||||||
|
-- between the given layout generators below.
|
||||||
|
local layout_manager = Layout.new_cycling_manager({
|
||||||
|
-- `Layout.builtins` contains functions that create various layout generators.
|
||||||
|
-- Each of these has settings that can be overridden by passing in a table with
|
||||||
|
-- overriding options.
|
||||||
|
Layout.builtins.master_stack(),
|
||||||
|
Layout.builtins.master_stack({ master_side = "right" }),
|
||||||
|
Layout.builtins.master_stack({ master_side = "top" }),
|
||||||
|
Layout.builtins.master_stack({ master_side = "bottom" }),
|
||||||
|
Layout.builtins.dwindle(),
|
||||||
|
Layout.builtins.spiral(),
|
||||||
|
Layout.builtins.corner(),
|
||||||
|
Layout.builtins.corner({ corner_loc = "top_right" }),
|
||||||
|
Layout.builtins.corner({ corner_loc = "bottom_left" }),
|
||||||
|
Layout.builtins.corner({ corner_loc = "bottom_right" }),
|
||||||
|
Layout.builtins.fair(),
|
||||||
|
Layout.builtins.fair({ direction = "horizontal" }),
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Set the cycling layout manager as the layout manager that will be used.
|
||||||
|
-- This then allows you to call `Layout.request_layout` to manually layout windows.
|
||||||
|
Layout.set_manager(layout_manager)
|
||||||
|
|
||||||
|
-- mod_key + space = Cycle forward one layout on the focused output
|
||||||
|
--
|
||||||
|
-- Yes, this is a bit verbose for my liking.
|
||||||
|
-- You need to cycle the layout on the first active tag
|
||||||
|
-- because that is the one that decides which layout is used.
|
||||||
|
Input.keybind({ mod_key }, key.space, function()
|
||||||
|
local focused_op = Output.get_focused()
|
||||||
|
if focused_op then
|
||||||
|
local tags = focused_op:tags() or {}
|
||||||
|
local tag = nil
|
||||||
|
|
||||||
|
---@type (fun(): (boolean|nil))[]
|
||||||
|
local tag_actives = {}
|
||||||
|
for i, t in ipairs(tags) do
|
||||||
|
tag_actives[i] = function()
|
||||||
|
return t:active()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- We are batching API calls here for better performance
|
||||||
|
tag_actives = Util.batch(tag_actives)
|
||||||
|
|
||||||
|
for i, active in ipairs(tag_actives) do
|
||||||
|
if active then
|
||||||
|
tag = tags[i]
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if tag then
|
||||||
|
layout_manager:cycle_layout_forward(tag)
|
||||||
|
Layout.request_layout(focused_op)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end, {
|
||||||
|
group = "Layout",
|
||||||
|
description = "Cycle the layout forward on the first active tag",
|
||||||
|
})
|
||||||
|
|
||||||
|
-- mod_key + shift + space = Cycle backward one layout on the focused output
|
||||||
|
Input.keybind({ mod_key, "shift" }, key.space, function()
|
||||||
|
local focused_op = Output.get_focused()
|
||||||
|
if focused_op then
|
||||||
|
local tags = focused_op:tags() or {}
|
||||||
|
local tag = nil
|
||||||
|
|
||||||
|
---@type (fun(): (boolean|nil))[]
|
||||||
|
local tag_actives = {}
|
||||||
|
for i, t in ipairs(tags) do
|
||||||
|
tag_actives[i] = function()
|
||||||
|
return t:active()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
tag_actives = Util.batch(tag_actives)
|
||||||
|
|
||||||
|
for i, active in ipairs(tag_actives) do
|
||||||
|
if active then
|
||||||
|
tag = tags[i]
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if tag then
|
||||||
|
layout_manager:cycle_layout_backward(tag)
|
||||||
|
Layout.request_layout(focused_op)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end, {
|
||||||
|
group = "Layout",
|
||||||
|
description = "Cycle the layout backward on the first active tag",
|
||||||
|
})
|
||||||
|
|
||||||
|
Input.set_libinput_settings({
|
||||||
|
tap = true,
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Enable sloppy focus
|
||||||
|
Window.connect_signal({
|
||||||
|
pointer_enter = function(window)
|
||||||
|
window:set_focused(true)
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Spawning should happen after you add tags, as Pinnacle currently doesn't render windows without tags.
|
||||||
|
Process.spawn_once(terminal)
|
||||||
|
end)
|
46
api/lua/examples/default_no_snowcap/metaconfig.toml
Normal file
46
api/lua/examples/default_no_snowcap/metaconfig.toml
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
# This metaconfig.toml file dictates what config Pinnacle will run.
|
||||||
|
#
|
||||||
|
# When running Pinnacle, the compositor will look in the following directories for a metaconfig.toml file,
|
||||||
|
# in order from top to bottom:
|
||||||
|
# $PINNACLE_CONFIG_DIR
|
||||||
|
# $XDG_CONFIG_HOME/pinnacle/
|
||||||
|
# ~/.config/pinnacle/
|
||||||
|
#
|
||||||
|
# When Pinnacle finds a metaconfig.toml file, it will execute the command provided to `command`.
|
||||||
|
# To use a Rust config, this should be changed to something like ["cargo", "run"].
|
||||||
|
#
|
||||||
|
# Because configuration is done using an external process, if it ever crashes, you lose all of your keybinds.
|
||||||
|
# The compositor will load the default config if that happens, but in the event that you don't have
|
||||||
|
# the necessary dependencies for it to run, you may get softlocked.
|
||||||
|
# In order prevent you from getting stuck in the compositor, you must define keybinds to reload your config
|
||||||
|
# and kill Pinnacle.
|
||||||
|
#
|
||||||
|
# More details on each setting can be found below.
|
||||||
|
|
||||||
|
# The command Pinnacle will run on startup and when you reload your config.
|
||||||
|
# Paths are relative to the directory the metaconfig.toml file is in.
|
||||||
|
# This must be an array.
|
||||||
|
command = ["lua", "default_config.lua"]
|
||||||
|
|
||||||
|
### Keybinds ###
|
||||||
|
# Each keybind takes in a table with two fields: `modifiers` and `key`.
|
||||||
|
# - `modifiers` can be one of "Ctrl", "Alt", "Shift", or "Super".
|
||||||
|
# - `key` can be a string of any lowercase letter, number,
|
||||||
|
# "numN" where N is a number for numpad keys, or "esc"/"escape".
|
||||||
|
# Support for any xkbcommon key is planned for a future update.
|
||||||
|
|
||||||
|
# The keybind that will reload your config.
|
||||||
|
reload_keybind = { modifiers = ["Ctrl", "Alt"], key = "r" }
|
||||||
|
# The keybind that will kill Pinnacle.
|
||||||
|
kill_keybind = { modifiers = ["Ctrl", "Alt", "Shift"], key = "escape" }
|
||||||
|
|
||||||
|
### Socket directory ###
|
||||||
|
# Pinnacle will open a Unix socket at `$XDG_RUNTIME_DIR` by default, falling back to `/tmp` if it doesn't exist.
|
||||||
|
# If you want/need to change this, use the `socket_dir` setting set to the directory of your choosing.
|
||||||
|
#
|
||||||
|
# socket_dir = "/your/dir/here/"
|
||||||
|
|
||||||
|
### Environment Variables ###
|
||||||
|
# If you need to spawn your config with any environment variables, list them here.
|
||||||
|
[envs]
|
||||||
|
# key = "value"
|
|
@ -31,5 +31,6 @@ build = {
|
||||||
["pinnacle.signal"] = "pinnacle/signal.lua",
|
["pinnacle.signal"] = "pinnacle/signal.lua",
|
||||||
["pinnacle.layout"] = "pinnacle/layout.lua",
|
["pinnacle.layout"] = "pinnacle/layout.lua",
|
||||||
["pinnacle.render"] = "pinnacle/render.lua",
|
["pinnacle.render"] = "pinnacle/render.lua",
|
||||||
|
["pinnacle.snowcap"] = "pinnacle/snowcap.lua",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,8 @@ local pinnacle = {
|
||||||
layout = require("pinnacle.layout"),
|
layout = require("pinnacle.layout"),
|
||||||
---@type Render
|
---@type Render
|
||||||
render = require("pinnacle.render"),
|
render = require("pinnacle.render"),
|
||||||
|
---@type pinnacle.Snowcap
|
||||||
|
snowcap = require("pinnacle.snowcap"),
|
||||||
}
|
}
|
||||||
|
|
||||||
---Quit Pinnacle.
|
---Quit Pinnacle.
|
||||||
|
@ -52,6 +54,13 @@ end
|
||||||
---@see Pinnacle.run
|
---@see Pinnacle.run
|
||||||
function pinnacle.setup(config_fn)
|
function pinnacle.setup(config_fn)
|
||||||
require("pinnacle.grpc.protobuf").build_protos()
|
require("pinnacle.grpc.protobuf").build_protos()
|
||||||
|
local success, snowcap = pcall(require, "snowcap")
|
||||||
|
if success then
|
||||||
|
snowcap.init()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Make Snowcap use Pinnacle's cqueues loop
|
||||||
|
require("snowcap.grpc.client").loop = client.loop
|
||||||
|
|
||||||
-- This function ensures a config won't run forever if Pinnacle is killed
|
-- This function ensures a config won't run forever if Pinnacle is killed
|
||||||
-- and doesn't kill configs on drop.
|
-- and doesn't kill configs on drop.
|
||||||
|
@ -90,6 +99,10 @@ end
|
||||||
---@param run_fn fun(pinnacle: Pinnacle)
|
---@param run_fn fun(pinnacle: Pinnacle)
|
||||||
function pinnacle.run(run_fn)
|
function pinnacle.run(run_fn)
|
||||||
require("pinnacle.grpc.protobuf").build_protos()
|
require("pinnacle.grpc.protobuf").build_protos()
|
||||||
|
local success, snowcap = pcall(require, "snowcap")
|
||||||
|
if success then
|
||||||
|
snowcap.init()
|
||||||
|
end
|
||||||
|
|
||||||
run_fn(pinnacle)
|
run_fn(pinnacle)
|
||||||
end
|
end
|
||||||
|
|
|
@ -190,7 +190,20 @@ function input.keybind_descriptions()
|
||||||
local ret = {}
|
local ret = {}
|
||||||
|
|
||||||
for _, desc in ipairs(descs) do
|
for _, desc in ipairs(descs) do
|
||||||
desc.modifiers = desc.modifiers or {}
|
local mods = {}
|
||||||
|
for _, mod in ipairs(desc.modifiers or {}) do
|
||||||
|
if mod == modifier_values.shift then
|
||||||
|
table.insert(mods, "shift")
|
||||||
|
elseif mod == modifier_values.ctrl then
|
||||||
|
table.insert(mods, "ctrl")
|
||||||
|
elseif mod == modifier_values.alt then
|
||||||
|
table.insert(mods, "alt")
|
||||||
|
elseif mod == modifier_values.super then
|
||||||
|
table.insert(mods, "super")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
desc.modifiers = mods
|
||||||
table.insert(ret, desc)
|
table.insert(ret, desc)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
349
api/lua/pinnacle/snowcap.lua
Normal file
349
api/lua/pinnacle/snowcap.lua
Normal file
|
@ -0,0 +1,349 @@
|
||||||
|
local integration = {}
|
||||||
|
|
||||||
|
---The Snowcap widget system, integrated into Pinnacle.
|
||||||
|
---@class pinnacle.Snowcap
|
||||||
|
local snowcap = {
|
||||||
|
layer = require("snowcap.layer"),
|
||||||
|
widget = require("snowcap.widget"),
|
||||||
|
input = {
|
||||||
|
key = require("snowcap.input.keys"),
|
||||||
|
},
|
||||||
|
integration = integration,
|
||||||
|
}
|
||||||
|
|
||||||
|
---@class pinnacle.snowcap.integration.QuitPrompt
|
||||||
|
---@field border_radius number
|
||||||
|
---@field border_thickness number
|
||||||
|
---@field background_color snowcap.Color
|
||||||
|
---@field border_color snowcap.Color
|
||||||
|
---@field font snowcap.Font
|
||||||
|
---@field width integer
|
||||||
|
---@field height integer
|
||||||
|
local QuitPrompt = {}
|
||||||
|
|
||||||
|
---@class pinnacle.snowcap.integration.KeybindOverlay
|
||||||
|
---@field border_radius number
|
||||||
|
---@field border_thickness number
|
||||||
|
---@field background_color snowcap.Color
|
||||||
|
---@field border_color snowcap.Color
|
||||||
|
---@field font snowcap.Font
|
||||||
|
---@field width integer
|
||||||
|
---@field height integer
|
||||||
|
local KeybindOverlay = {}
|
||||||
|
|
||||||
|
---Show this quit prompt.
|
||||||
|
function QuitPrompt:show()
|
||||||
|
local Widget = require("snowcap.widget")
|
||||||
|
local Layer = require("snowcap.layer")
|
||||||
|
|
||||||
|
local quit_font = require("pinnacle.util").deep_copy(self.font)
|
||||||
|
quit_font.weight = Widget.font.weight.BOLD
|
||||||
|
|
||||||
|
local prompt = Widget.container({
|
||||||
|
width = Widget.length.Fill,
|
||||||
|
height = Widget.length.Fill,
|
||||||
|
valign = Widget.alignment.CENTER,
|
||||||
|
halign = Widget.alignment.CENTER,
|
||||||
|
border_radius = self.border_radius,
|
||||||
|
border_thickness = self.border_thickness,
|
||||||
|
border_color = self.border_color,
|
||||||
|
background_color = self.background_color,
|
||||||
|
child = Widget.column({
|
||||||
|
children = {
|
||||||
|
Widget.text({
|
||||||
|
text = "Quit Pinnacle?",
|
||||||
|
font = quit_font,
|
||||||
|
size = 20.0,
|
||||||
|
}),
|
||||||
|
Widget.text({ text = "", size = 8.0 }),
|
||||||
|
Widget.text({
|
||||||
|
text = "Press ENTER to confirm, or\nany other key to close this",
|
||||||
|
font = self.font,
|
||||||
|
size = 14.0,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
|
||||||
|
local prompt = Layer.new_widget({
|
||||||
|
widget = prompt,
|
||||||
|
width = self.width,
|
||||||
|
height = self.height,
|
||||||
|
anchor = nil,
|
||||||
|
keyboard_interactivity = Layer.keyboard_interactivity.EXCLUSIVE,
|
||||||
|
exclusive_zone = "respect",
|
||||||
|
layer = Layer.zlayer.OVERLAY,
|
||||||
|
})
|
||||||
|
|
||||||
|
prompt:on_key_press(function(_, key)
|
||||||
|
if key == require("snowcap.input.keys").Return then
|
||||||
|
require("pinnacle").quit()
|
||||||
|
else
|
||||||
|
prompt:close()
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
---Show this keybind overlay.
|
||||||
|
function KeybindOverlay:show()
|
||||||
|
local descriptions = require("pinnacle.input").keybind_descriptions()
|
||||||
|
|
||||||
|
---@param mods Modifier[]
|
||||||
|
---@param xkb_name string
|
||||||
|
---@return string
|
||||||
|
local function keybind_to_string(mods, xkb_name)
|
||||||
|
local repr = {}
|
||||||
|
for _, mod in ipairs(mods) do
|
||||||
|
if mod == "super" then
|
||||||
|
table.insert(repr, "Super")
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for _, mod in ipairs(mods) do
|
||||||
|
if mod == "ctrl" then
|
||||||
|
table.insert(repr, "Ctrl")
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for _, mod in ipairs(mods) do
|
||||||
|
if mod == "alt" then
|
||||||
|
table.insert(repr, "Alt")
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for _, mod in ipairs(mods) do
|
||||||
|
if mod == "shift" then
|
||||||
|
table.insert(repr, "Shift")
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
table.insert(repr, xkb_name)
|
||||||
|
|
||||||
|
return table.concat(repr, " + ")
|
||||||
|
end
|
||||||
|
|
||||||
|
---@type { group: string?, data: { keybind: string, descs: string[] }[] }[]
|
||||||
|
local groups = {}
|
||||||
|
|
||||||
|
for _, desc in ipairs(descriptions) do
|
||||||
|
local repr = keybind_to_string(desc.modifiers, desc.xkb_name)
|
||||||
|
|
||||||
|
for _, group in ipairs(groups) do
|
||||||
|
if group.group == desc.group then
|
||||||
|
for _, keybind in ipairs(group.data) do
|
||||||
|
if keybind.keybind == repr then
|
||||||
|
if desc.description then
|
||||||
|
table.insert(keybind.descs, desc.description)
|
||||||
|
end
|
||||||
|
goto continue
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(group.data, { keybind = repr, descs = { desc.description } })
|
||||||
|
goto continue
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(
|
||||||
|
groups,
|
||||||
|
{ group = desc.group, data = { { keybind = repr, descs = { desc.description } } } }
|
||||||
|
)
|
||||||
|
|
||||||
|
::continue::
|
||||||
|
end
|
||||||
|
|
||||||
|
-- List keybinds without a group last
|
||||||
|
|
||||||
|
local pos = nil
|
||||||
|
for i, group in ipairs(groups) do
|
||||||
|
if not group.group then
|
||||||
|
pos = i
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if pos then
|
||||||
|
local other = table.remove(groups, pos)
|
||||||
|
table.insert(groups, other)
|
||||||
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
|
||||||
|
---@type snowcap.WidgetDef[]
|
||||||
|
local sections = {}
|
||||||
|
|
||||||
|
local Widget = require("snowcap.widget")
|
||||||
|
|
||||||
|
local bold_font = require("pinnacle.util").deep_copy(self.font)
|
||||||
|
bold_font.weight = Widget.font.weight.BOLD
|
||||||
|
|
||||||
|
for _, group in ipairs(groups) do
|
||||||
|
local group_name = group.group or "Other"
|
||||||
|
|
||||||
|
table.insert(sections, Widget.text({ text = group_name, font = bold_font, size = 19.0 }))
|
||||||
|
|
||||||
|
for _, keybind in ipairs(group.data) do
|
||||||
|
local repr = keybind.keybind
|
||||||
|
local descs = keybind.descs
|
||||||
|
|
||||||
|
if #descs == 0 then
|
||||||
|
table.insert(sections, Widget.text({ text = repr, font = self.font }))
|
||||||
|
elseif #descs == 1 then
|
||||||
|
table.insert(
|
||||||
|
sections,
|
||||||
|
Widget.row({
|
||||||
|
children = {
|
||||||
|
Widget.text({
|
||||||
|
text = repr,
|
||||||
|
width = Widget.length.FillPortion(1),
|
||||||
|
font = self.font,
|
||||||
|
}),
|
||||||
|
Widget.text({
|
||||||
|
text = descs[1],
|
||||||
|
width = Widget.length.FillPortion(2),
|
||||||
|
font = self.font,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
)
|
||||||
|
else
|
||||||
|
local children = {}
|
||||||
|
|
||||||
|
table.insert(
|
||||||
|
children,
|
||||||
|
Widget.text({
|
||||||
|
text = repr .. ":",
|
||||||
|
font = self.font,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
for _, desc in descs do
|
||||||
|
table.insert(
|
||||||
|
children,
|
||||||
|
Widget.text({
|
||||||
|
text = "\t" .. desc,
|
||||||
|
font = self.font,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(
|
||||||
|
sections,
|
||||||
|
Widget.column({
|
||||||
|
children = children,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(sections, Widget.text({ text = "", size = 8.0 }))
|
||||||
|
end
|
||||||
|
|
||||||
|
local scrollable = Widget.scrollable({
|
||||||
|
child = Widget.column({
|
||||||
|
children = sections,
|
||||||
|
}),
|
||||||
|
width = Widget.length.Fill,
|
||||||
|
height = Widget.length.Fill,
|
||||||
|
})
|
||||||
|
|
||||||
|
local overlay = Widget.container({
|
||||||
|
child = Widget.column({
|
||||||
|
children = {
|
||||||
|
Widget.text({
|
||||||
|
text = "Keybinds",
|
||||||
|
font = bold_font,
|
||||||
|
size = 24.0,
|
||||||
|
width = Widget.length.Fill,
|
||||||
|
}),
|
||||||
|
Widget.text({
|
||||||
|
text = "",
|
||||||
|
size = 8.0,
|
||||||
|
}),
|
||||||
|
scrollable,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
width = Widget.length.Fill,
|
||||||
|
height = Widget.length.Fill,
|
||||||
|
padding = {
|
||||||
|
top = 16.0,
|
||||||
|
left = 16.0,
|
||||||
|
bottom = 16.0,
|
||||||
|
right = 16.0,
|
||||||
|
},
|
||||||
|
valign = Widget.alignment.CENTER,
|
||||||
|
halign = Widget.alignment.CENTER,
|
||||||
|
border_radius = self.border_radius,
|
||||||
|
border_color = self.border_color,
|
||||||
|
border_thickness = self.border_thickness,
|
||||||
|
background_color = self.background_color,
|
||||||
|
})
|
||||||
|
|
||||||
|
local Layer = require("snowcap.layer")
|
||||||
|
|
||||||
|
local overlay = Layer.new_widget({
|
||||||
|
widget = overlay,
|
||||||
|
width = self.width,
|
||||||
|
height = self.height,
|
||||||
|
anchor = nil,
|
||||||
|
keyboard_interactivity = Layer.keyboard_interactivity.EXCLUSIVE,
|
||||||
|
exclusive_zone = "respect",
|
||||||
|
layer = Layer.zlayer.OVERLAY,
|
||||||
|
})
|
||||||
|
|
||||||
|
overlay:on_key_press(function(_, _)
|
||||||
|
overlay:close()
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
---Creates the default quit prompt.
|
||||||
|
---
|
||||||
|
---Some of its characteristics can be changed by altering its fields.
|
||||||
|
---@return pinnacle.snowcap.integration.QuitPrompt
|
||||||
|
function integration.quit_prompt()
|
||||||
|
local Widget = require("snowcap.widget")
|
||||||
|
|
||||||
|
---@type pinnacle.snowcap.integration.QuitPrompt
|
||||||
|
local prompt = {
|
||||||
|
border_radius = 12.0,
|
||||||
|
border_thickness = 6.0,
|
||||||
|
background_color = Widget.color.from_rgba(0.15, 0.03, 0.1, 0.65),
|
||||||
|
border_color = Widget.color.from_rgba(0.8, 0.2, 0.4),
|
||||||
|
font = {
|
||||||
|
family = Widget.font.family.Name("Ubuntu"),
|
||||||
|
},
|
||||||
|
width = 220,
|
||||||
|
height = 120,
|
||||||
|
}
|
||||||
|
|
||||||
|
setmetatable(prompt, { __index = QuitPrompt })
|
||||||
|
|
||||||
|
return prompt
|
||||||
|
end
|
||||||
|
|
||||||
|
---Creates the default keybind overlay.
|
||||||
|
---
|
||||||
|
---Some of its characteristics can be changed by altering its fields.
|
||||||
|
---@return pinnacle.snowcap.integration.KeybindOverlay
|
||||||
|
function integration.keybind_overlay()
|
||||||
|
local Widget = require("snowcap.widget")
|
||||||
|
|
||||||
|
---@type pinnacle.snowcap.integration.KeybindOverlay
|
||||||
|
local prompt = {
|
||||||
|
border_radius = 12.0,
|
||||||
|
border_thickness = 6.0,
|
||||||
|
background_color = Widget.color.from_rgba(0.15, 0.15, 0.225, 0.8),
|
||||||
|
border_color = Widget.color.from_rgba(0.4, 0.4, 0.7),
|
||||||
|
font = {
|
||||||
|
family = Widget.font.family.Name("Ubuntu"),
|
||||||
|
},
|
||||||
|
width = 700,
|
||||||
|
height = 500,
|
||||||
|
}
|
||||||
|
|
||||||
|
setmetatable(prompt, { __index = KeybindOverlay })
|
||||||
|
|
||||||
|
return prompt
|
||||||
|
end
|
||||||
|
|
||||||
|
return snowcap
|
|
@ -166,22 +166,23 @@ impl KeybindOverlay {
|
||||||
|
|
||||||
impl std::fmt::Display for KeybindRepr {
|
impl std::fmt::Display for KeybindRepr {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
let bind = self
|
let mut parts = Vec::new();
|
||||||
.mods
|
if self.mods.contains(&Mod::Super) {
|
||||||
.iter()
|
parts.push("Super");
|
||||||
.map(|m| {
|
}
|
||||||
// TODO: strum name or something
|
if self.mods.contains(&Mod::Ctrl) {
|
||||||
match m {
|
parts.push("Ctrl");
|
||||||
Mod::Shift => "Shift",
|
}
|
||||||
Mod::Ctrl => "Ctrl",
|
if self.mods.contains(&Mod::Alt) {
|
||||||
Mod::Alt => "Alt",
|
parts.push("Alt");
|
||||||
Mod::Super => "Super",
|
}
|
||||||
}
|
if self.mods.contains(&Mod::Shift) {
|
||||||
.to_string()
|
parts.push("Shift");
|
||||||
})
|
}
|
||||||
.chain([self.name.clone()])
|
|
||||||
.collect::<Vec<_>>()
|
parts.push(self.name.as_str());
|
||||||
.join(" + ");
|
|
||||||
|
let bind = parts.join(" + ");
|
||||||
write!(f, "{bind}")
|
write!(f, "{bind}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
16
justfile
16
justfile
|
@ -11,7 +11,7 @@ list:
|
||||||
@just --list --unsorted
|
@just --list --unsorted
|
||||||
|
|
||||||
# Install the configs, protobuf definitions, and the Lua library (requires Luarocks)
|
# Install the configs, protobuf definitions, and the Lua library (requires Luarocks)
|
||||||
install: install-configs install-protos install-lua-lib
|
install: install-configs install-protos install-lua-lib install-snowcap
|
||||||
|
|
||||||
# Install the default Lua and Rust configs
|
# Install the default Lua and Rust configs
|
||||||
install-configs:
|
install-configs:
|
||||||
|
@ -41,7 +41,7 @@ install-lua-lib:
|
||||||
luarocks make --local --lua-version "{{lua_version}}"
|
luarocks make --local --lua-version "{{lua_version}}"
|
||||||
|
|
||||||
# Remove installed configs and the Lua API (requires Luarocks)
|
# Remove installed configs and the Lua API (requires Luarocks)
|
||||||
clean:
|
clean: clean-snowcap
|
||||||
rm -rf "{{xdg_data_dir}}"
|
rm -rf "{{xdg_data_dir}}"
|
||||||
-luarocks remove --local pinnacle-api
|
-luarocks remove --local pinnacle-api
|
||||||
|
|
||||||
|
@ -119,3 +119,15 @@ wlcs *args: compile-wlcs
|
||||||
set -euxo pipefail
|
set -euxo pipefail
|
||||||
cargo build -p wlcs_pinnacle
|
cargo build -p wlcs_pinnacle
|
||||||
RUST_BACKTRACE=1 ./wlcs/wlcs target/debug/libwlcs_pinnacle.so {{args}}
|
RUST_BACKTRACE=1 ./wlcs/wlcs target/debug/libwlcs_pinnacle.so {{args}}
|
||||||
|
|
||||||
|
install-snowcap:
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euxo pipefail
|
||||||
|
cd "{{rootdir}}/snowcap"
|
||||||
|
just install
|
||||||
|
|
||||||
|
clean-snowcap:
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euxo pipefail
|
||||||
|
cd "{{rootdir}}/snowcap"
|
||||||
|
just clean
|
||||||
|
|
2
snowcap
2
snowcap
|
@ -1 +1 @@
|
||||||
Subproject commit 3e79a16e1065f07001b08fabdc763bb274cac394
|
Subproject commit e901659a86ec41c6903f8c913da711e1b8d95a56
|
|
@ -46,7 +46,7 @@ async fn main() -> anyhow::Result<()> {
|
||||||
let env_filter = EnvFilter::try_from_default_env();
|
let env_filter = EnvFilter::try_from_default_env();
|
||||||
|
|
||||||
let file_log_env_filter =
|
let file_log_env_filter =
|
||||||
EnvFilter::new("debug,h2=warn,hyper=warn,smithay::xwayland::xwm=warn,wgpu_hal=warn,naga=warn,wgpu_core=warn,cosmic_text=warn,iced_wgpu=warn,sctk=warn");
|
EnvFilter::new("debug,h2=warn,hyper=warn,smithay::xwayland::xwm=warn,wgpu_hal=warn,naga=warn,wgpu_core=warn,cosmic_text=warn,iced_wgpu=warn,sctk=error");
|
||||||
|
|
||||||
let file_log_layer = tracing_subscriber::fmt::layer()
|
let file_log_layer = tracing_subscriber::fmt::layer()
|
||||||
.compact()
|
.compact()
|
||||||
|
@ -55,7 +55,7 @@ async fn main() -> anyhow::Result<()> {
|
||||||
.with_filter(file_log_env_filter);
|
.with_filter(file_log_env_filter);
|
||||||
|
|
||||||
let stdout_env_filter =
|
let stdout_env_filter =
|
||||||
env_filter.unwrap_or_else(|_| EnvFilter::new("warn,pinnacle=info,snowcap=info"));
|
env_filter.unwrap_or_else(|_| EnvFilter::new("warn,pinnacle=info,snowcap=info,sctk=error"));
|
||||||
let stdout_layer = tracing_subscriber::fmt::layer()
|
let stdout_layer = tracing_subscriber::fmt::layer()
|
||||||
.compact()
|
.compact()
|
||||||
.with_writer(std::io::stdout)
|
.with_writer(std::io::stdout)
|
||||||
|
|
Loading…
Reference in a new issue