init
This commit is contained in:
commit
d2743fe41d
22 changed files with 2290 additions and 0 deletions
85
lib/tree/init.lua
Normal file
85
lib/tree/init.lua
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
-- This source code form is subject to the terms of the MPL-v2 https://mozilla.org/MPL/2.0/ --
|
||||
--* .name Manages the tree structure that holds all monitors, containers, windows, and tags
|
||||
local X = require("x")
|
||||
local EWMH = require("ewmh")
|
||||
local Conf = require("conf")
|
||||
local Tree = {
|
||||
windows = {},
|
||||
monitors = {},
|
||||
focusedWindow = nil,
|
||||
focusedMonitor = nil,
|
||||
-- tags = {},
|
||||
}
|
||||
|
||||
-- local Tag = require("tree.tag")
|
||||
local Window = require("tree.window")
|
||||
|
||||
function Tree.newWindow(ev)
|
||||
local win = Window.new(ev.id)
|
||||
if EWMH.shouldManage(win) then
|
||||
Tree.windows[win.id] = win
|
||||
win.managed = true
|
||||
if EWMH.shouldTile(win) then
|
||||
table.insert(Tree.focusedMonitor.stack, win)
|
||||
win.monitor = Tree.focusedMonitor
|
||||
-- Tree.focusedMonitor:updateTiling()
|
||||
else
|
||||
win:float()
|
||||
end
|
||||
win:show()
|
||||
else
|
||||
win.managed = false
|
||||
win:show()
|
||||
return
|
||||
end
|
||||
return win
|
||||
end
|
||||
|
||||
----* table tag Tree.newTag(any id, [table preset]) Creates a new tag that can then be added to tables. New tags are also initialised automatically with *Window*:*addTag*()
|
||||
--function Tree.newTag(id, tbl)
|
||||
-- if Tree.tags[id] then return Tree.tags[id] end
|
||||
-- local tag = Tag.new(tbl)
|
||||
-- tag.id = id
|
||||
-- Tree.tags[id] = tag
|
||||
-- return tag
|
||||
--end
|
||||
--* Tree.init() Sets up the tree
|
||||
function Tree.init()
|
||||
Window.init()
|
||||
for m,monitor in pairs(X.getMonitors()) do
|
||||
Tree.monitors[m] = monitor
|
||||
monitor.number = m
|
||||
monitor.stack = {}
|
||||
monitor.dockMargins = { top = 0, bottom = 0, left = 0, right = 0 }
|
||||
monitor.margins = { top = 5, bottom = 5, left = 5, right = 5 }
|
||||
function monitor:updateTiling()
|
||||
if self.tiler then
|
||||
self.tiler:tile(self.stack, self)
|
||||
end
|
||||
end
|
||||
function monitor:setMargins(m)
|
||||
print("привет", inspect(m))
|
||||
self.margins.top = m.top + self.dockMargins.top
|
||||
self.margins.bottom = m.bottom + self.dockMargins.bottom
|
||||
self.margins.right = m.right + self.dockMargins.right
|
||||
self.margins.left = m.left + self.dockMargins.left
|
||||
end
|
||||
if Conf.eventHandlers.newMonitor then
|
||||
Conf.eventHandlers.newMonitor(monitor)
|
||||
end
|
||||
end
|
||||
Tree.focusedMonitor = Tree.monitors[1]
|
||||
-- Tree.newTag("focused")
|
||||
end
|
||||
-- function Tree.updateDirty()
|
||||
-- if Tree.dirtyGeometry then
|
||||
-- for w,win in pairs(Tree.windows) do
|
||||
-- if win.dirtyGeometry then
|
||||
-- win:applyGeometry()
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
|
||||
return Tree
|
||||
|
||||
56
lib/tree/tag.lua
Normal file
56
lib/tree/tag.lua
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
---- TAG --
|
||||
--local Tag = {}
|
||||
--Tag.__index = Tag
|
||||
--function Tag.new(tag)
|
||||
-- tag = tag or {}
|
||||
-- tag.windows = {}
|
||||
-- return setmetatable(tag, Tag)
|
||||
--end
|
||||
----* Tag:setBorderColour(int colour) Sets the tag's window's border colour. **colour** is in the form of 0xRRGGBB
|
||||
--function Tag:setBorderColour(col)
|
||||
-- self.borderColour = col
|
||||
-- for w,win in pairs(self.windows) do win:updateTag(self) end
|
||||
--end
|
||||
--function Tag:setBorderWidth(width)
|
||||
-- self.borderWidth = width
|
||||
-- for w,win in pairs(self.windows) do win:updateTag(self) end
|
||||
--end
|
||||
--function Tag:setMargin(top, right, bottom, left)
|
||||
-- if type(top) == "table" then
|
||||
-- self.margin = top
|
||||
-- else
|
||||
-- self.margin = {top = top, right = right, bottom = bottom, left = left}
|
||||
-- end
|
||||
-- for w,win in pairs(self.windows) do win:updateTag(self) end
|
||||
--end
|
||||
----* Tag:set(table props) Sets a table worth of properties
|
||||
--function Tag:set(tbl)
|
||||
-- for prop,value in pairs(tbl) do
|
||||
-- if prop == "borderColour" then
|
||||
-- self:setBorderColour(value)
|
||||
-- elseif prop == "borderWidth" then
|
||||
-- self:setBorderWidth(value)
|
||||
-- elseif prop == "visible" then
|
||||
-- if value then self:show() else self:hide() end
|
||||
-- elseif prop == "margin" then
|
||||
-- self:setMargin(value)
|
||||
-- end
|
||||
-- end
|
||||
--end
|
||||
----* Tag:show() Unhides windows from the screen
|
||||
--function Tag:show()
|
||||
-- self.visible = true
|
||||
-- for w,win in pairs(self.windows) do
|
||||
-- win:updateTag(self)
|
||||
-- end
|
||||
--end
|
||||
----* Tag:hide() Hides windows from the screen
|
||||
--function Tag:hide()
|
||||
-- self.visible = false
|
||||
-- for w,win in pairs(self.windows) do
|
||||
-- win:updateTag(self)
|
||||
-- end
|
||||
--end
|
||||
|
||||
--return Tag
|
||||
|
||||
91
lib/tree/tilers.lua
Normal file
91
lib/tree/tilers.lua
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
local Tilers = {}
|
||||
local inspect = require("inspect")
|
||||
|
||||
local dirs = {
|
||||
left = function(m, w, h, stack, r, gap)
|
||||
local masterBase = {
|
||||
w = w * r - gap/2,
|
||||
h = h,
|
||||
x = m.left,
|
||||
y = m.top
|
||||
}
|
||||
local childBase = {
|
||||
w = (w * (1-r)) - gap/2,
|
||||
h = (masterBase.h / (#stack-1)) - gap + gap / (#stack-1),
|
||||
x = masterBase.x + masterBase.w + gap,
|
||||
y = m.top
|
||||
}
|
||||
local childOffset = {
|
||||
x = 0, y = childBase.h + gap
|
||||
}
|
||||
return masterBase, childBase, childOffset
|
||||
end,
|
||||
top = function(m, w, h, stack, r, gap)
|
||||
local masterBase = {
|
||||
w = w,
|
||||
h = h * r - gap,
|
||||
x = m.left,
|
||||
y = m.top
|
||||
}
|
||||
local childBase = {
|
||||
w = (masterBase.w / (#stack-1)) - gap + gap / (#stack-1),
|
||||
h = (h * (1-r)) - gap,
|
||||
x = m.left,
|
||||
y = masterBase.y + masterBase.h + gap,
|
||||
}
|
||||
local childOffset = {
|
||||
x = childBase.w + gap, y = 0
|
||||
}
|
||||
return masterBase, childBase, childOffset
|
||||
end
|
||||
}
|
||||
dirs.right = function(...)
|
||||
local masterBase, childBase, childOffset = dirs.left(...)
|
||||
masterBase.x, childBase.x = childBase.x, masterBase.x
|
||||
masterBase.w, childBase.w = childBase.w, masterBase.w
|
||||
return masterBase, childBase, childOffset
|
||||
end
|
||||
dirs.bottom = function(...)
|
||||
local masterBase, childBase, childOffset = dirs.top(...)
|
||||
masterBase.y, childBase.y = childBase.y, masterBase.y
|
||||
masterBase.h, childBase.h = childBase.h, masterBase.h
|
||||
return masterBase, childBase, childOffset
|
||||
end
|
||||
|
||||
local function makeTiler(getOff)
|
||||
return {
|
||||
r = 0.5,
|
||||
tile = function(self, stack, monitor)
|
||||
local m = monitor.margins
|
||||
local w = monitor.width - m.left - m.right
|
||||
local h = monitor.height - m.top - m.bottom
|
||||
if #stack == 1 then
|
||||
stack[1]:setGeometry(m.left, m.top, w, h)
|
||||
elseif #stack >= 2 then
|
||||
local masterBase, childBase, childOffset = getOff(m, w, h, stack, self.r, self.gap)
|
||||
stack[1]:setGeometry(masterBase.x, masterBase.y, masterBase.w, masterBase.h)
|
||||
for i=2,#stack do
|
||||
stack[i]:setGeometry(childBase.x, childBase.y, childBase.w, childBase.h)
|
||||
childBase.x = childBase.x + childOffset.x
|
||||
childBase.y = childBase.y + childOffset.y
|
||||
end
|
||||
end
|
||||
end,
|
||||
setGap = function(self, gap)
|
||||
assert(type(gap) == "number")
|
||||
self.gap = gap
|
||||
end,
|
||||
gap = 0
|
||||
}
|
||||
end
|
||||
|
||||
Tilers = {
|
||||
masterTop = makeTiler(dirs.top),
|
||||
masterLeft = makeTiler(dirs.left),
|
||||
masterRight = makeTiler(dirs.right),
|
||||
masterBottom = makeTiler(dirs.bottom),
|
||||
}
|
||||
|
||||
return Tilers
|
||||
|
||||
|
||||
122
lib/tree/window.lua
Normal file
122
lib/tree/window.lua
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
local Tree
|
||||
local X = require("x")
|
||||
local Util = require("util")
|
||||
local Async = require("async")
|
||||
local Tag = require("tree.tag")
|
||||
|
||||
local function round(n)
|
||||
return math.floor(n+0.5)
|
||||
end
|
||||
|
||||
local Window = {
|
||||
x = 0, y = 0,
|
||||
w = 0, h = 0,
|
||||
bx = 0, by = 0,
|
||||
bw = 0, bh = 0,
|
||||
margin = {top = 0, right = 0, bottom = 0, left = 0},
|
||||
borderWidth = 0
|
||||
}
|
||||
Window.__index = Window
|
||||
function Window.new(id)
|
||||
local window = {
|
||||
id = id,
|
||||
monitor = Tree.focusedMonitor,
|
||||
-- tags = {
|
||||
-- main = Tag.new()
|
||||
-- }
|
||||
}
|
||||
setmetatable(window, Window)
|
||||
return window
|
||||
end
|
||||
function Window:getClass()
|
||||
if self.class == nil then
|
||||
local c1, c2 = X.getProperty(self.id, X.getAtoms("WM_CLASS"), 0, X.AnyPropertyType)
|
||||
if c1 then
|
||||
self.class = {c1, c2}
|
||||
else
|
||||
self.class = false
|
||||
end
|
||||
end
|
||||
return self.class
|
||||
end
|
||||
function Window:getName()
|
||||
self.name = X.getProperty(self.id, X.getAtoms("_NET_WM_NAME"), 0, X.getAtoms("UTF8_STRING"))
|
||||
if not self.name then
|
||||
self.name = X.getProperty(self.id, X.getAtoms("WM_NAME"), 0, X.AnyPropertyType)
|
||||
end
|
||||
return self.name
|
||||
end
|
||||
function Window:float()
|
||||
end
|
||||
function Window:setGeometry(x, y, w, h)
|
||||
if self.x ~= x or self.y ~= y or self.width ~= w or self.h ~= h then
|
||||
self.x, self.y, self.width, self.height = x, y, w, h
|
||||
self:applyGeometry()
|
||||
end
|
||||
-- self.monitor.dirtyGeometry = true
|
||||
-- self.dirtyGeometry = true
|
||||
-- Tree.dirtyGeometry = true
|
||||
-- self.dirtyGeometry = true
|
||||
-- print("set")
|
||||
-- Async.idle(function()
|
||||
-- if self.dirtyGeometry then
|
||||
-- self:applyGeometry()
|
||||
-- end
|
||||
-- print("ran")
|
||||
-- self.dirtyGeometry = false
|
||||
-- end)
|
||||
end
|
||||
function Window:applyGeometry()
|
||||
X.setWindowGeometry(self.id, self.x, self.y, self.width, self.height)
|
||||
end
|
||||
function Window:show()
|
||||
self.visible = true
|
||||
X.mapWindow(self.id)
|
||||
Tree.focusedMonitor:updateTiling()
|
||||
end
|
||||
function Window:hide()
|
||||
self.visible = false
|
||||
X.unmapWindow(self.id)
|
||||
Tree.focusedMonitor:updateTiling()
|
||||
end
|
||||
--* Window:focus() Moves keyboard focus to window, appends it to the focus history (**Tree**.**focusHistory**), and adds the "focused" tag
|
||||
function Window:unmanage()
|
||||
local i = self:getIndex()
|
||||
table.remove(self.monitor.stack, i)
|
||||
if self.focused then
|
||||
Tree.focusedWindow = nil
|
||||
self.focused = nil
|
||||
end
|
||||
Tree.windows[self.id] = nil
|
||||
Tree.focusedMonitor:updateTiling()
|
||||
end
|
||||
function Window:getIndex()
|
||||
return Util.indexOf(self.monitor.stack, self)
|
||||
end
|
||||
function Window:getNext(d)
|
||||
d = d or 1
|
||||
local stack = Tree.focusedMonitor.stack
|
||||
local w = self:getIndex()
|
||||
local i = (((w-1) + d) % #stack) + 1
|
||||
return stack[i]
|
||||
end
|
||||
function Window:focus()
|
||||
self.focused = true
|
||||
if Tree.focusedWindow then
|
||||
Tree.focusedWindow.focused = false
|
||||
end
|
||||
Tree.focusedWindow = self
|
||||
Tree.focusedContainer = self.parent
|
||||
Tree.focusedMonitor.focusedContainer = self.parent
|
||||
X.setInputFocus(self.id)
|
||||
end
|
||||
function Window:getStackIndex()
|
||||
return Util.indexOf(self, self.monitor.stack)
|
||||
end
|
||||
|
||||
function Window.init()
|
||||
Tree = require("tree")
|
||||
end
|
||||
|
||||
return Window
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue