pinnacle/api/lua/examples/default/default_config.lua

323 lines
10 KiB
Lua
Raw Normal View History

2024-03-17 02:40:39 +01:00
-- 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
2024-06-17 23:27:02 +02:00
local Snowcap = Pinnacle.snowcap
local key = Input.key
---@type Modifier
local mod_key = "ctrl"
local terminal = "alacritty"
2024-06-17 23:27:02 +02:00
Input.keybind({ mod_key }, "s", function()
Snowcap.integration.keybind_overlay():show()
end, {
group = "Compositor",
description = "Show the keybind overlay",
})
2024-01-16 06:37:17 +01:00
--------------------
-- Mousebinds --
--------------------
2024-02-08 04:39:56 +01:00
Input.mousebind({ mod_key }, "btn_left", "press", function()
Window.begin_move("btn_left")
end)
2024-02-08 04:39:56 +01:00
Input.mousebind({ mod_key }, "btn_right", "press", function()
Window.begin_resize("btn_right")
end)
2024-01-16 06:37:17 +01:00
--------------------
-- Keybinds --
--------------------
2024-01-16 06:37:17 +01:00
-- mod_key + alt + q = Quit Pinnacle
2024-02-08 04:39:56 +01:00
Input.keybind({ mod_key, "alt" }, "q", function()
2024-06-17 23:27:02 +02:00
Snowcap.integration.quit_prompt():show()
2024-06-15 21:06:23 +02:00
end, {
group = "Compositor",
description = "Quit Pinnacle",
})
2024-04-18 23:39:30 +02:00
-- mod_key + alt + r = Reload config
Input.keybind({ mod_key, "alt" }, "r", function()
Pinnacle.reload_config()
2024-06-15 21:06:23 +02:00
end, {
group = "Compositor",
description = "Reload the config",
})
2024-04-18 23:39:30 +02:00
2024-01-16 06:37:17 +01:00
-- mod_key + alt + c = Close window
2024-02-08 04:39:56 +01:00
Input.keybind({ mod_key, "alt" }, "c", function()
local focused = Window.get_focused()
if focused then
focused:close()
end
2024-06-15 21:06:23 +02:00
end, {
group = "Window",
description = "Close the focused window",
})
2024-01-16 06:37:17 +01:00
-- mod_key + alt + Return = Spawn `terminal`
2024-02-08 04:39:56 +01:00
Input.keybind({ mod_key }, key.Return, function()
Process.spawn(terminal)
2024-06-15 21:06:23 +02:00
end, {
group = "Process",
description = "Spawn `alacritty`",
})
2024-01-16 06:37:17 +01:00
-- mod_key + alt + space = Toggle floating
2024-02-08 04:39:56 +01:00
Input.keybind({ mod_key, "alt" }, key.space, function()
local focused = Window.get_focused()
if focused then
focused:toggle_floating()
2024-03-22 00:39:27 +01:00
focused:raise()
end
2024-06-15 21:06:23 +02:00
end, {
group = "Window",
description = "Toggle floating on the focused window",
})
2024-01-16 06:37:17 +01:00
-- mod_key + f = Toggle fullscreen
2024-02-08 04:39:56 +01:00
Input.keybind({ mod_key }, "f", function()
local focused = Window.get_focused()
if focused then
focused:toggle_fullscreen()
2024-03-22 00:39:27 +01:00
focused:raise()
end
2024-06-15 21:06:23 +02:00
end, {
group = "Window",
description = "Toggle fullscreen on the focused window",
})
2024-01-16 06:37:17 +01:00
-- mod_key + m = Toggle maximized
2024-02-08 04:39:56 +01:00
Input.keybind({ mod_key }, "m", function()
local focused = Window.get_focused()
if focused then
focused:toggle_maximized()
2024-03-22 00:39:27 +01:00
focused:raise()
end
2024-06-15 21:06:23 +02:00
end, {
group = "Window",
description = "Toggle maximized on the focused window",
})
2024-04-17 02:25:59 +02:00
----------------------
-- Tags and Outputs --
----------------------
2024-01-16 06:37:17 +01:00
local tag_names = { "1", "2", "3", "4", "5" }
2024-04-17 02:25:59 +02:00
-- 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({
2024-04-18 04:25:55 +02:00
-- "*" matches all outputs
["*"] = { tags = tag_names },
})
2024-04-17 02:25:59 +02:00
-- 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.
2024-03-17 02:40:39 +01:00
-- 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()
2024-06-15 21:06:23 +02:00
end, {
group = "Tag",
description = "Switch to tag " .. tag_name,
})
2024-03-17 02:40:39 +01:00
-- mod_key + shift + 1-5 = Toggle tags 1-5
Input.keybind({ mod_key, "shift" }, tag_name, function()
Tag.get(tag_name):toggle_active()
2024-06-15 21:06:23 +02:00
end, {
group = "Tag",
description = "Toggle tag " .. tag_name,
})
2024-03-17 02:40:39 +01:00
-- 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
2024-06-15 21:06:23 +02:00
end, {
group = "Tag",
description = "Move the focused window to tag " .. tag_name,
})
2024-03-17 02:40:39 +01:00
-- 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
2024-06-15 21:06:23 +02:00
end, {
group = "Tag",
description = "Toggle tag " .. tag_name .. " on the focused window",
})
2024-03-17 02:40:39 +01:00
end
--------------------
-- Layouts --
--------------------
2024-03-17 02:40:39 +01:00
-- 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({
2024-03-17 02:40:39 +01:00
-- `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.
2024-03-17 01:58:38 +01:00
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" }),
})
2024-03-17 02:40:39 +01:00
-- 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
2024-03-17 02:40:39 +01:00
--
-- 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
2024-03-17 02:40:39 +01:00
local tags = focused_op:tags() or {}
local tag = nil
2024-03-17 02:40:39 +01:00
---@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
2024-03-17 02:40:39 +01:00
if tag then
layout_manager:cycle_layout_forward(tag)
2024-03-15 01:42:08 +01:00
Layout.request_layout(focused_op)
end
end
2024-06-15 21:06:23 +02:00
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
2024-03-17 02:40:39 +01:00
local tags = focused_op:tags() or {}
local tag = nil
2024-03-17 02:40:39 +01:00
---@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
2024-03-17 02:40:39 +01:00
if tag then
layout_manager:cycle_layout_backward(tag)
2024-03-15 01:42:08 +01:00
Layout.request_layout(focused_op)
end
end
2024-06-15 21:06:23 +02:00
end, {
group = "Layout",
description = "Cycle the layout backward on the first active tag",
})
2024-04-18 23:39:30 +02:00
Input.set_libinput_settings({
tap = true,
})
-- Enable sloppy focus
Window.connect_signal({
pointer_enter = function(window)
window:set_focused(true)
end,
})
2024-03-17 02:40:39 +01:00
-- Spawning should happen after you add tags, as Pinnacle currently doesn't render windows without tags.
Process.spawn_once(terminal)
end)