mirror of
https://github.com/MezzalunaWM/master.mez.git
synced 2026-03-07 20:19:53 -05:00
basic tiling
This commit is contained in:
parent
69945499a4
commit
6d95f33446
3 changed files with 175 additions and 34 deletions
15
README.md
15
README.md
|
|
@ -3,3 +3,18 @@
|
|||
master.mez is meant to be part of the default config of any [Mezzaluna](https://github.com/MezzalunaWM/Mezzaluna) install. It provides basic window management in the master and stack style, simmilar to default dwm. As of right now, since Mezzaluna is in early development, this plugin does a little more than just managing windows. To be fair though, this is more for seeing how a plugin might work and seeing what would be required of plugin developers, and what they have the freedom to customize.
|
||||
|
||||
There is **NO WAY** to officially install this right now sooooooo, maybe just copy or simlink files where they need to go. Sorry lol.
|
||||
|
||||
## Configuration
|
||||
|
||||
How configuration works exactly is still up for debate as of now. Peronally I don't think that things like binds for spawning windows are necessary for a window manager plugin, so those are left for the user to still define. But here is what configuring master.mez would hopefully look like.
|
||||
|
||||
Also don't know if constructs like workspaces or tags should really be the responsibility of the window manager plugin either, but those will stay for now.
|
||||
|
||||
```lua
|
||||
local master = requre("master")
|
||||
|
||||
master.setup({
|
||||
master_ratio = 0.5,
|
||||
tag_count = 5
|
||||
})
|
||||
```
|
||||
|
|
|
|||
|
|
@ -3,18 +3,6 @@
|
|||
|
||||
local M = {}
|
||||
|
||||
local spawn_terminal = function()
|
||||
mez.api.spawn("wmenu-run")
|
||||
end
|
||||
|
||||
local spawn_run_launcher = function()
|
||||
mez.api.spawn("wmneu-run")
|
||||
end
|
||||
|
||||
local spawn_background = function()
|
||||
mez.api.spawn("swaybg -i ~/Images/wallpapers/void/gruv_void.png")
|
||||
end
|
||||
|
||||
local close_focused = function ()
|
||||
mez.view.close(0)
|
||||
end
|
||||
|
|
@ -23,6 +11,4 @@ local close_compositor = function ()
|
|||
mez.api.exit()
|
||||
end
|
||||
|
||||
local
|
||||
|
||||
return M
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
---@field default_config MasterConfig
|
||||
---@field config MasterConfig
|
||||
---@field state MasterState
|
||||
---@field builtins MasterBuiltins
|
||||
---@field builtins Builtins
|
||||
local M = {};
|
||||
|
||||
M.builtins = require("master.builtins")
|
||||
|
|
@ -12,35 +12,175 @@ M.builtins = require("master.builtins")
|
|||
---@class MasterConfig
|
||||
---@field master_ratio number
|
||||
---@field tag_count number
|
||||
---@field focus_on_spawn boolean
|
||||
---@field refocus_on_kill boolean
|
||||
---@field screen_gap number
|
||||
---@field tile_gap number
|
||||
local default_config = {
|
||||
master_ratio = 0.5,
|
||||
tag_count = 5,
|
||||
applications = {
|
||||
terminal = "alacritty",
|
||||
browser = "zen"
|
||||
},
|
||||
binds = {
|
||||
spawn_terminal = { lhs = { mod = "alt", key = "Return" }, rhs = M.builtins.spawn_terminal },
|
||||
spawn_run_launcher = { lhs = { mod = "alt", key = "p" }, rhs = M.builtins.spawn_run_launcher },
|
||||
close_focused = { lhs = { mods = "alt|shift", key = "C", rhs = M.builtins.close_focused },
|
||||
}
|
||||
master_ratio = 0.5,
|
||||
tag_count = 5,
|
||||
focus_on_spawn = true,
|
||||
refocus_on_kill = true,
|
||||
screen_gap = 10,
|
||||
tile_gap = 10
|
||||
}
|
||||
|
||||
---@class Tag
|
||||
---@field floating number[]
|
||||
---@class MasterTag
|
||||
---@field master number | nil
|
||||
---@field stack number[]
|
||||
---@field floating number[]
|
||||
|
||||
---@param config MasterConfig
|
||||
---@return MasterState
|
||||
local create_state = function(config)
|
||||
---@type MasterTag[]
|
||||
local tags = {}
|
||||
|
||||
for i = 1,config.tag_count do
|
||||
tags[i] = {
|
||||
master = nil,
|
||||
floating = {},
|
||||
stack = {}
|
||||
}
|
||||
end
|
||||
|
||||
return {
|
||||
tag_id = 0,
|
||||
tags = tags
|
||||
}
|
||||
end
|
||||
|
||||
---@class MasterState
|
||||
---@field tag_id number
|
||||
---@field tags Tag[]
|
||||
M.state = {
|
||||
tag_id = 1,
|
||||
tags = {}
|
||||
}
|
||||
---@field tags MasterTag[]
|
||||
---@field master_ratio number
|
||||
|
||||
---@param config MasterConfig
|
||||
M.setup = function(config)
|
||||
--- Here we need to validate the config
|
||||
--- DON'T FORGET TO VALIDATE THE CONFIG
|
||||
|
||||
M.state = create_state(config)
|
||||
|
||||
---@param tag_id number
|
||||
local tile_tag = function(tag_id)
|
||||
local tag = M.state.tags[tag_id]
|
||||
|
||||
local res = mez.output.get_resolution(0)
|
||||
|
||||
if #tag.stack == 0 then
|
||||
mez.view.set_position(tag.master, config.screen_gap, config.screen_gap)
|
||||
mez.view.set_size(
|
||||
tag.master,
|
||||
res.width - config.screen_gap * 2,
|
||||
res.height - config.screen_gap * 2)
|
||||
else
|
||||
mez.view.set_position(tag.master, config.screen_gap, config.screen_gap)
|
||||
mez.view.set_size(
|
||||
tag.master,
|
||||
res.width * M.state.master_ratio - config.screen_gap - config.tile_gap,
|
||||
res.height - config.screen_gap * 2)
|
||||
|
||||
local stack_x = (res.width * (1 - M.state.master_ratio)) - config.tile_gap - config.screen_gap
|
||||
local stack_width = res.width * (1 - M.state.master_ratio) - config.tile_gap - config.screen_gap
|
||||
|
||||
for i, view_id in ipairs(tag.stack) do
|
||||
mez.view.set_position(view_id,
|
||||
stack_x,
|
||||
(res.height / #tag.stack + config.tile_gap) * (i - 1) + config.screen_gap)
|
||||
|
||||
mez.view.set_size(view_id,
|
||||
stack_width,
|
||||
res.height / #tag.stack - config.screen_gap * 2 - config.tile_gap * (#tag.stack - 1))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
mez.hook.add("ViewMapPre", {
|
||||
callback = function(view_id)
|
||||
local curr_tag = M.state.tags[M.state.tag_id]
|
||||
|
||||
if curr_tag.master == nil then
|
||||
curr_tag.master = view_id
|
||||
else
|
||||
table.insert(curr_tag.stack, #curr_tag.stack + 1, view_id)
|
||||
end
|
||||
|
||||
if config.focus_on_spawn then mez.view.set_focused(view_id) end
|
||||
|
||||
tile_tag(M.state.tag_id)
|
||||
end
|
||||
})
|
||||
|
||||
mez.hook.add("ViewUnmapPost", {
|
||||
callback = function(view_id)
|
||||
---@type number | nil
|
||||
local tag_idx = nil
|
||||
|
||||
---@type "master" | "stacking" | "floating" | nil
|
||||
local type = nil
|
||||
|
||||
---@type number | nil
|
||||
local view_idx = nil
|
||||
|
||||
for i, curr_tag in ipairs[M.state.tags] do
|
||||
local t = M.state.tags[i]
|
||||
|
||||
--- If view is the master
|
||||
if view_id == curr_tag.master then
|
||||
tag_idx = i
|
||||
type = "master"
|
||||
break
|
||||
end
|
||||
|
||||
--- If view is floating
|
||||
for j, curr_view in ipairs(t.floating) do
|
||||
if curr_view == view_id then
|
||||
tag_idx = i
|
||||
type = "floating"
|
||||
view_idx = j
|
||||
break;
|
||||
end
|
||||
end
|
||||
|
||||
--- If view is stacking
|
||||
for j, curr_view in ipairs(t.stack) do
|
||||
if curr_view == view_id then
|
||||
tag_idx = i
|
||||
type = "stacking"
|
||||
view_idx = j
|
||||
break;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local tag = M.state.tags[tag_idx]
|
||||
|
||||
--- Now remove the view and retile if needed
|
||||
if type == "floating" then
|
||||
table.remove(tag.floating, view_idx)
|
||||
elseif type == "master" then
|
||||
tag.master = table.remove(tag.stack, 1)
|
||||
tile_tag(tag_idx)
|
||||
|
||||
if config.refocus_on_kill then
|
||||
mez.view.set_focused(tag.master)
|
||||
end
|
||||
elseif type == "stacking" then
|
||||
local is_last = #tag.stack == view_idx
|
||||
table.remove(tag.stack, view_idx)
|
||||
tile_tag(tag_idx)
|
||||
|
||||
if config.refocus_on_kill then
|
||||
if #tag.stack == 0 then
|
||||
mez.view.set_focus(tag.master)
|
||||
else
|
||||
mez.view.set_focused(is_last and view_idx - 1 or view_idx)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
})
|
||||
end
|
||||
|
||||
return M
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue