awesomewm-machina/methods.lua

1534 lines
44 KiB
Lua
Raw Permalink Normal View History

2021-06-28 13:27:03 +02:00
2021-07-03 23:50:31 +02:00
--------------------------------------------------------- dependencies -- ;
2021-06-27 07:48:46 +02:00
2021-07-11 22:34:28 +02:00
local naughty = require('naughty')
local gears = require("gears")
local awful = require("awful")
local beautiful = require('beautiful')
local grect = gears.geometry.rectangle
2021-07-03 23:50:31 +02:00
local tabs = require("machina.tabs")
local geoms = require("machina.geoms")
local helpers = require("machina.helpers")
2021-06-28 07:58:41 +02:00
2021-07-03 23:50:31 +02:00
local get_client_ix = helpers.get_client_ix
local getlowest = helpers.getlowest
local compare = helpers.compare
local tablelength = helpers.tablelength
local set_contains = helpers.set_contains
local clear_tabbar = helpers.clear_tabbar
2021-06-27 07:48:46 +02:00
2021-07-03 23:50:31 +02:00
---------------------------------------------------------------- locals -- ;
2021-06-27 07:48:46 +02:00
2021-07-03 23:50:31 +02:00
local global_client_table = {}
2021-07-05 08:50:14 +02:00
local global_widget_table = {}
2021-06-28 07:58:41 +02:00
2021-07-10 02:49:27 +02:00
function double_click_event_handler(double_click_event)
if double_click_timer then
double_click_timer:stop()
double_click_timer = nil
double_click_event()
return
end
beautiful.layout_machi = machi.get_icon()
double_click_timer = gears.timer.start_new(0.20, function()
double_click_timer = nil
return false
end)
end
2021-07-03 23:50:31 +02:00
function get_global_clients()
return global_client_table
2021-06-28 07:58:41 +02:00
end
2021-07-03 23:50:31 +02:00
function update_global_clients(c)
global_client_table[c.window] = c
2021-06-28 07:58:41 +02:00
end
2021-07-10 02:27:14 +02:00
----------------------------------------------------- reset_client_meta -- ;
2021-07-06 20:41:24 +02:00
local function reset_client_meta(c)
c.maximized = false
c.maximized_horizontal = false
c.maximized_vertical = false
c.direction = nil
return c
end
2021-07-10 02:27:14 +02:00
--------------------------------------------------- reset_all_clients() -- ;
2021-07-08 09:08:40 +02:00
local function reset_all_clients(s)
local s = s or awful.screen.focused()
for i,c in pairs(s.clients) do
reset_client_meta(c)
end
end
2021-07-10 02:27:14 +02:00
---------------------------------------------------------- set_region() -- ;
local function set_region(region, c)
local c = c or client.focus or nil
if c then
c.region = region end
end
------------------------------------------ get_visible_floating_clients -- ;
2021-07-11 22:34:28 +02:00
local function get_all_floating_clients(s)
local s = s or awful.screen.focused(s)
local les_visibles = {}
for i,p in pairs(s.all_clients) do
if p.floating then
les_visibles[#les_visibles+1] = p
end
end
return les_visibles
end
2021-07-10 02:27:14 +02:00
local function get_visible_floating_clients(s)
local s = s or awful.screen.focused(s)
local les_visibles = {}
for i,p in pairs(s.all_clients) do
if p.floating and (p.always_on or p.bypass) and p:isvisible() then
les_visibles[#les_visibles+1] = p
end
end
return les_visibles
end
---------------------------------------------------- get_space_around() -- ;
local function get_space_around(c)
if not c then return nil end
local c = c or nil
local s = awful.screen.focused()
local space_around = {
left=c.x,
right=s.workarea.width - (c.x + c.width),
top=s.workarea.height - (c.y),
bottom=s.workarea.height - (c.y + c.height),
}
return space_around
end
-------------------------------------------------------- align_floats() -- ;
local function align_floats(direction)
return function (c)
local s = s or awful.screen.focused()
local c = client.focus or nil
local direction = direction or "right"
local space_around = get_space_around(c)
2021-07-11 22:34:28 +02:00
local cs = get_all_floating_clients(s)
if not c then return end
--|flow control
2021-07-10 02:27:14 +02:00
2021-07-11 22:34:28 +02:00
if space_around.right < 300
and space_around.left < 300 then
2021-07-10 02:27:14 +02:00
return
2021-07-11 22:34:28 +02:00
end --|flow control
2021-07-10 02:27:14 +02:00
for i,p in pairs(cs) do
if p.window == c.window then goto next end
--|if c itself if it is actually floating
if space_around.right < 300 and direction == "right" then
direction = "left"
end
if space_around.left < 300 and direction == "left" then
direction = "right"
end --|flow control, nothing to do
if direction == "right" then
if (p.width) > space_around.right then
p.width = space_around.right
end
--|resize if necessary
p:geometry({x=c.x+c.width, y=c.y})
--|place x on the right
end
if direction == "left" then
if p.width > space_around.left then
p.width = space_around.left
end
--|resize if necessary
p:geometry({x=space_around.left - p.width, y=c.y})
--|place x on the left
end
if direction == "left" then direction = "right" end
if direction == "right" then direction = "left" end
2021-07-11 22:34:28 +02:00
p.hidden = false
p:raise()
-- p:emit_signal("request::activate")
2021-07-10 02:27:14 +02:00
--|bring float up
2021-07-11 22:34:28 +02:00
2021-07-10 02:27:14 +02:00
awful.placement.no_offscreen(p)
--|ensure everything is visible
::next::
end
client.focus = c
--|keep focus at the originating client
end
end
2021-07-11 22:34:28 +02:00
--|this will spread out floating clients to the left or
--|right of the focused client, can refactor most of this later.
--|perhaps it is better to limit this to visible floats only.
--|perhaps it would be better to keep the position and geometry
--|of the floats prior to aligning them, so that they can appear
--|where they used to be later.
2021-07-10 02:27:14 +02:00
2021-07-03 23:50:31 +02:00
------------------------------------------------------------- go_edge() -- ;
2021-06-28 07:58:41 +02:00
2021-07-03 23:50:31 +02:00
local function go_edge(direction, regions, current_box)
test_box = true
edge_pos = nil
2021-06-28 07:58:41 +02:00
2021-07-03 23:50:31 +02:00
while test_box do
test_box = grect.get_in_direction(direction, regions, current_box)
2021-06-27 08:57:56 +02:00
2021-07-03 23:50:31 +02:00
if test_box then
current_box = regions[test_box]
edge_pos = test_box
2021-06-28 07:58:41 +02:00
end
end
2021-07-03 23:50:31 +02:00
return edge_pos
end --|
--|figures out the beginning of each row on the layout.
2021-06-27 07:48:46 +02:00
2021-06-28 13:27:03 +02:00
----------------------------------------------------------- always_on() -- ;
local function toggle_always_on()
always_on = nil or client.focus.always_on
client.focus.always_on = not always_on
end
2021-06-28 07:58:41 +02:00
--------------------------------------------------------- screen_info() -- ;
2021-07-05 08:26:24 +02:00
local function screen_info(s)
local s = s or awful.screen.focused()
local focused_screen = s or nil
local workarea = s.workarea or nil
local selected_tag = s.selected_tag or nil
local layout = awful.layout.get(s) or nil
2021-06-27 07:48:46 +02:00
local focused_client = client.focus or nil
2021-07-03 23:50:31 +02:00
return focused_screen,
workarea,
selected_tag,
layout,
focused_client
2021-06-27 07:48:46 +02:00
end
2021-07-11 22:34:28 +02:00
---------------------------------------------------------- get_region() -- ;
2021-06-27 07:48:46 +02:00
2021-07-07 21:52:05 +02:00
local function get_region(region_ix, s)
local s = s or awful.screen.focused()
local focused_screen,
workarea,
selected_tag,
layout,
focused_client = screen_info(s)
local machi_fn = nil
local machi_data = nil
local machi_regions = nil
if layout.machi_get_regions then
machi_fn = layout.machi_get_regions
machi_data = machi_fn(workarea, selected_tag)
machi_regions = machi_data
end --|version 1
if layout.machi_get_instance_data then
machi_fn = layout.machi_get_instance_data
machi_geom = layout.machi_set_geometry
machi_data = {machi_fn(screen[focused_screen], selected_tag)}
machi_regions = machi_data[3]
for i=#machi_regions,1,-1 do
if machi_regions[i].habitable == false then
table.remove(machi_regions, i)
end
end --|remove unhabitable regions
table.sort(
machi_regions,
function (a1, a2)
return a1.id > a2.id
end
) --|v2 returns unordered region list and needs sorting.
end --|version 2/NG
return machi_regions[region_ix]
end
2021-07-11 22:34:28 +02:00
--------------------------------------------------------- get_regions() -- ;
2021-07-07 21:52:05 +02:00
2021-07-05 08:26:24 +02:00
local function get_regions(s)
local s = s or awful.screen.focused()
2021-06-27 07:48:46 +02:00
local focused_screen,
workarea,
selected_tag,
layout,
2021-07-05 08:26:24 +02:00
focused_client = screen_info(s)
2021-06-27 07:48:46 +02:00
local machi_fn = nil
local machi_data = nil
local machi_regions = nil
if layout.machi_get_regions then
machi_fn = layout.machi_get_regions
machi_data = machi_fn(workarea, selected_tag)
machi_regions = machi_data
2021-06-28 03:50:16 +02:00
end --|version 1
2021-06-27 07:48:46 +02:00
if layout.machi_get_instance_data then
machi_fn = layout.machi_get_instance_data
2021-07-05 02:44:09 +02:00
machi_geom = layout.machi_set_geometry
2021-07-03 23:50:31 +02:00
machi_data = {machi_fn(screen[focused_screen], selected_tag)}
2021-06-27 07:48:46 +02:00
machi_regions = machi_data[3]
for i=#machi_regions,1,-1 do
2021-07-03 23:50:31 +02:00
if machi_regions[i].habitable == false then
table.remove(machi_regions, i)
end
2021-06-28 03:50:16 +02:00
end --|remove unhabitable regions
2021-06-27 07:48:46 +02:00
table.sort(
machi_regions,
function (a1, a2)
2021-07-03 23:50:31 +02:00
return a1.id > a2.id
2021-06-27 07:48:46 +02:00
end
2021-07-03 23:50:31 +02:00
) --|v2 returns unordered region list and needs sorting.
2021-06-28 03:50:16 +02:00
end --|version 2/NG
2021-06-27 07:48:46 +02:00
return machi_regions, machi_fn
end
2021-07-03 23:50:31 +02:00
------------------------------------------------------- get_client_info -- ;
2021-06-27 07:48:46 +02:00
2021-07-03 23:50:31 +02:00
local function get_client_info(c)
2021-07-06 00:54:27 +02:00
local c = c or client.focus or nil
local s = s or c.screen or nil
local source_client = c
2021-06-27 07:48:46 +02:00
local active_region = nil
local outofboundary = nil
local proximity = {}
2021-07-03 23:50:31 +02:00
if not source_client then return {} end
2021-06-28 03:50:16 +02:00
--|flow control
2021-06-27 07:48:46 +02:00
2021-07-03 23:50:31 +02:00
if source_client.x < 0 or source_client.y < 0
2021-06-27 07:48:46 +02:00
then outofboundary = true
end --| negative coordinates always mean out of boundary
2021-07-06 00:54:27 +02:00
local regions = get_regions(s)
--|get regions on the screen
if not regions then return {} end
--|flow control
2021-07-03 23:50:31 +02:00
2021-06-27 07:48:46 +02:00
for i, a in ipairs(regions) do
2021-07-03 23:50:31 +02:00
local px = a.x - source_client.x
local py = a.y - source_client.y
2021-06-27 07:48:46 +02:00
if px == 0 then px = 1 end
if py == 0 then py = 1 end
proximity[i] = {
index = i,
v = math.abs(px * py)
2021-06-28 03:50:16 +02:00
} --│keep track of proximity in case nothing matches in
--│this block.
2021-06-27 07:48:46 +02:00
2021-06-28 03:50:16 +02:00
end --│figures out focused client's region under normal
--│circumstances.
2021-06-27 07:48:46 +02:00
if not active_region then
table.sort(proximity, compare) --| sort to get the smallest area
active_region = proximity[1].index --| first item should be the right choice
2021-07-03 23:50:31 +02:00
if source_client.floating then
if regions[active_region].width - source_client.width ~= 0
or regions[active_region].height - source_client.height ~= 0
2021-06-27 07:48:46 +02:00
then
outofboundary = true
end
2021-06-28 03:50:16 +02:00
end --|when client is not the same size as the located
--|region, we should still consider this as out of
--|boundary
end --|user is probably executing get_active_regions on a
--|floating window.
2021-06-27 07:48:46 +02:00
if not active_region then
active_region = 1
2021-06-28 03:50:16 +02:00
end --|at this point, we are out of options, set the index
--|to one and hope for the best.
2021-06-27 07:48:46 +02:00
2021-07-03 23:50:31 +02:00
-- refactor
if active_region and source_client.width > regions[active_region].width then
outofboundary = true
end --|machi sometimes could auto expand the client, consider
--|that as out of boundary.
if active_region and source_client.height > regions[active_region].height then
outofboundary = true
end --|machi sometimes could auto expand the client, consider
--|that as out of boundary.
-- refactor
2021-07-06 17:20:47 +02:00
active_region_geom = {
width=regions[active_region].width-regions[active_region].width/2,
height=regions[active_region].height-regions[active_region].height/2
}
2021-07-03 23:50:31 +02:00
2021-06-27 07:48:46 +02:00
return {
active_region = active_region,
2021-07-06 17:20:47 +02:00
active_region_geom = active_region_geom,
2021-06-27 07:48:46 +02:00
regions = regions,
2021-07-06 23:01:00 +02:00
outofboundary = outofboundary,
tags = c:tags()
2021-06-27 07:48:46 +02:00
}
end
2021-07-03 23:50:31 +02:00
2021-07-06 17:20:47 +02:00
------------------------------------------------------------- move_to() -- ;
local function move_to(location)
return function()
2021-07-06 20:41:24 +02:00
local c = client.focus or nil
if not c then return end
--▨ flow control
local c = reset_client_meta(client.focus)
local ci = get_client_info(c)
2021-07-06 17:20:47 +02:00
local useless_gap = nil
local regions = get_regions()
local edges = {x={},y={}}
2021-07-06 20:41:24 +02:00
2021-07-06 17:20:47 +02:00
local is = {
2021-07-06 20:41:24 +02:00
region=ci.active_region,
region_geom=ci.active_region_geom
2021-07-06 17:20:47 +02:00
}
for i,region in ipairs(regions) do
edges.x[region.x] = region.x + region.width
edges.y[region.y] = region.y + region.height
end
useless_gap = getlowest(edges.x)
2021-07-08 09:08:40 +02:00
if client.focus.floating then
client.focus:geometry(geoms[location](useless_gap))
end
2021-07-06 17:20:47 +02:00
if not client.focus.floating then
2021-07-06 20:41:24 +02:00
2021-07-08 09:08:40 +02:00
-- todo: set actual destination region geometry
-- this is not okay and buggy
-- or at least set it up to use directional shifting
-- to match left, right, center
local tobe_geom = geoms[location](useless_gap)
tobe_geom.width = 300
tobe_geom.height = 600
2021-07-06 20:41:24 +02:00
2021-07-06 17:20:47 +02:00
local tobe = {
2021-07-08 09:08:40 +02:00
region=get_client_info(client.focus).active_region,
2021-07-06 17:20:47 +02:00
}
2021-07-08 09:08:40 +02:00
client.focus:geometry(tobe_geom)
resize_region_to_index(is.region, is.region_geom, true)
2021-07-06 17:20:47 +02:00
draw_tabbar(is.region)
2021-07-06 20:16:13 +02:00
gears.timer.delayed_call(function ()
client.focus.region = tobe.region
draw_tabbar(tobe.region)
end)
2021-07-06 17:20:47 +02:00
end --| redraw tabs and update meta
return
end
end
2021-07-03 23:50:31 +02:00
----------------------------------------- focus_by_direction(direction) -- ;
local function focus_by_direction(direction)
return function()
if not client.focus then return false end
awful.client.focus.global_bydirection(direction, nil,true)
client.focus:raise()
end
end
2021-06-27 07:48:46 +02:00
2021-07-06 17:20:47 +02:00
----------------------------------------------- get_clients_in_region() -- ;
2021-06-27 07:48:46 +02:00
2021-07-07 21:52:05 +02:00
local function get_punched_clients(region_ix, s)
local s = s or awful.screen.focused()
local active_region = region_ix or nil
local region = get_region(region_ix, s)
local region_clients = {}
if #region_clients == 0 then
for i, w in ipairs(s.clients) do
2021-07-08 09:08:40 +02:00
if not w.floating then
if w.region == region_ix then
2021-07-07 21:52:05 +02:00
region_clients[#region_clients + 1] = w
end
end
end --|try to get clients based on simple coordinates
end
return region_clients
end --|try to get clients in a region using three different
--|algorithms.
2021-07-06 17:20:47 +02:00
local function get_clients_in_region(region_ix, c, s)
local c = c or client.focus or nil
2021-07-07 18:59:15 +02:00
local s = s or c.screen or awful.screen.focused()
2021-07-05 02:44:09 +02:00
local source_client = c or client.focus or nil
2021-07-06 00:54:27 +02:00
local source_screen = s or (source_client and source_client.screen)
2021-07-05 08:26:24 +02:00
local active_region = region_ix or nil
2021-07-06 00:54:27 +02:00
local regions = get_regions(s)
2021-07-05 08:26:24 +02:00
local region_clients = {}
2021-07-05 02:44:09 +02:00
if not active_region then
for i, a in ipairs(regions) do
if a.x <= source_client.x and source_client.x < a.x + a.width and
a.y <= source_client.y and source_client.y < a.y + a.height
then
active_region = i
end
end
2021-07-06 17:20:47 +02:00
end --|if no region index was provided, find the
--|region of the focused_client.
2021-07-05 02:44:09 +02:00
2021-07-07 05:02:58 +02:00
2021-07-06 17:20:47 +02:00
if not active_region then
return
2021-07-05 02:44:09 +02:00
end
2021-07-06 17:20:47 +02:00
if #region_clients == 0 then
for i, w in ipairs(s.clients) do
if not (w.floating) then
2021-07-07 18:59:15 +02:00
if (
math.abs(regions[active_region].x - w.x) <= 5 and
math.abs(regions[active_region].y - w.y) <= 5
)
2021-07-08 09:08:40 +02:00
-- or
-- (
-- regions[active_region].x ~= w.x and
-- w.region == region_ix
-- ) --|handle resizing left expanded regions
2021-07-06 17:20:47 +02:00
then
region_clients[#region_clients + 1] = w
w.region = region_ix
--|this basically will fix any inconsistency
--|along the way.
end
end
end --|try to get clients based on simple coordinates
end
2021-06-27 07:48:46 +02:00
2021-07-07 05:02:58 +02:00
-- if #region_clients == 0 then
-- for i, cc in pairs(s.clients) do
-- if cc.region == active_region
-- and regions[active_region].x == cc.x
-- and regions[active_region].y == cc.y
-- then
-- region_clients[#region_clients + 1] = cc
-- end
-- end
-- end --| this logic compares c.region to global client index.
-- --| if we somehow fail to update c.region somewhere
-- --| shuffle shortcuts won't work with this one.
-- if #region_clients == 0 then
-- for _, cc in ipairs(s.clients) do
-- if not (cc.floating) then
-- if regions[active_region].x <= cc.x + cc.width + cc.border_width * 2
-- and cc.x <= (regions[active_region].x + regions[active_region].width)
-- and regions[active_region].y <= (cc.y + cc.height + cc.border_width * 2)
-- and cc.y <= (regions[active_region].y + regions[active_region].height)
-- then
-- region_clients[#region_clients + 1] = cc
-- end
-- end
-- end
-- end --|this logic works with coordinates more throughly but
-- --|it also causes issues with overflowing
-- --|(expanded) clients.
2021-06-27 07:48:46 +02:00
2021-07-06 17:20:47 +02:00
return region_clients
end --|try to get clients in a region using three different
--|algorithms.
2021-06-27 07:48:46 +02:00
----------------------------------------------------- expand_horizontal -- ;
local function expand_horizontal(direction)
return function ()
2021-06-27 11:59:19 +02:00
local c = client.focus
local geom = nil
2021-06-27 07:48:46 +02:00
if c.maximized_horizontal then
c.maximized_horizontal = false
2021-06-28 03:23:53 +02:00
end --|reset toggle maximized state
2021-06-27 07:48:46 +02:00
if c.direction == direction then
c.direction = nil
2021-07-03 23:50:31 +02:00
c.maximized_horizontal = false
c.maximized_vertical = false
2021-07-06 17:20:47 +02:00
if not c.floating then
2021-07-08 09:18:32 +02:00
resize_region_to_index(c.region, true, true)
2021-07-11 22:56:17 +02:00
draw_tabbar(c.region)
2021-07-11 22:34:28 +02:00
gears.timer.weak_start_new(0.1,function ()
2021-07-11 22:38:55 +02:00
client_under_mouse = mouse.current_client
if client_under_mouse then
client.focus = mouse.current_client
end
2021-07-11 22:34:28 +02:00
end) --|when toggling leave the focus
--|to the client under the pointer
2021-07-06 17:20:47 +02:00
end
2021-06-27 07:48:46 +02:00
return
2021-07-11 22:34:28 +02:00
end --|reset toggle when sending the same
--|shortcut consequitively.
2021-06-27 07:48:46 +02:00
2021-07-03 23:50:31 +02:00
local stuff = get_client_info()
2021-06-27 07:48:46 +02:00
local target = grect.get_in_direction(direction, stuff.regions, client.focus:geometry())
2021-06-27 08:57:56 +02:00
if not target and direction ~= "center" then return end -- flow control
2021-06-27 07:48:46 +02:00
2021-06-28 03:23:53 +02:00
--▨▨▨
2021-06-27 07:48:46 +02:00
if direction == "right" then
tobe = {
x=c.x,
2021-07-05 02:44:09 +02:00
width=math.abs(stuff.regions[target].x + stuff.regions[target].width - c.x - 4),
2021-06-28 03:23:53 +02:00
height=c.height,
y=c.y
2021-06-27 07:48:46 +02:00
}
2021-07-05 02:44:09 +02:00
2021-06-27 07:48:46 +02:00
c.direction = direction
c.maximized_horizontal = true
c.maximixed_vertical = false
2021-06-28 03:23:53 +02:00
2021-07-11 22:34:28 +02:00
gears.timer.delayed_call(function (c)
2021-07-05 02:44:09 +02:00
c:geometry(tobe)
2021-07-06 17:20:47 +02:00
resize_region_to_client(c, {horizontal=true,vertical=false,direction=direction})
2021-07-05 02:44:09 +02:00
end,c)
2021-06-27 07:48:46 +02:00
return
end
2021-06-28 03:23:53 +02:00
--▨▨▨
2021-06-27 07:48:46 +02:00
if direction == "left" then
tobe = {
x=stuff.regions[target].x,
2021-06-28 03:23:53 +02:00
width=c.x + c.width - stuff.regions[target].x,
height=c.height,
y=c.y
2021-06-27 07:48:46 +02:00
}
2021-07-07 05:02:58 +02:00
2021-06-27 07:48:46 +02:00
c.direction = direction
c.maximized_horizontal = true
c.maximixed_vertical = false
2021-06-28 03:23:53 +02:00
2021-07-05 02:44:09 +02:00
gears.timer.delayed_call(function (c)
2021-07-07 05:02:58 +02:00
c:geometry(tobe)
2021-07-06 17:20:47 +02:00
resize_region_to_client(c, {horizontal=true,vertical=false,direction=direction})
2021-07-05 02:44:09 +02:00
end,c)
2021-06-27 07:48:46 +02:00
return
end
2021-06-28 03:23:53 +02:00
--▨▨▨
2021-06-27 07:48:46 +02:00
if direction == "center" then
2021-06-27 08:57:56 +02:00
c.maximized = false
2021-06-27 07:48:46 +02:00
c.maximixed_vertical = false
2021-07-03 23:50:31 +02:00
fixedchoice = geoms.clients[c.class] or nil
2021-06-27 08:57:56 +02:00
if c.floating then
2021-07-03 23:50:31 +02:00
c.maximized_horizontal = false
2021-06-27 11:59:19 +02:00
geom = geoms.crt43()
2021-06-27 08:57:56 +02:00
end
if not c.floating then
c.direction = "center"
c.maximized_horizontal = true
2021-06-27 11:59:19 +02:00
geom = geoms.p1080()
2021-06-27 08:57:56 +02:00
end
2021-07-03 23:50:31 +02:00
2021-07-10 02:27:14 +02:00
if fixedchoice and not c.floating then
2021-07-03 23:50:31 +02:00
c.direction = "center"
2021-07-05 02:44:09 +02:00
c.maximized_horizontal = true
2021-07-03 23:50:31 +02:00
geom = fixedchoice()
end
2021-07-05 02:44:09 +02:00
c:geometry(geom)
awful.placement.centered(c)
2021-07-11 22:34:28 +02:00
client.focus = nil
--|allow micky to move the mouse
2021-07-05 02:44:09 +02:00
gears.timer.delayed_call(function (c)
2021-07-11 22:34:28 +02:00
client.focus = c
--|allow micky to move the mouse
2021-07-05 02:44:09 +02:00
c:raise()
client.emit_signal("tabbar_draw", c.region)
2021-07-03 23:50:31 +02:00
clear_tabbar(c)
2021-07-05 02:44:09 +02:00
end,c) --|give it time in case maximize_horizontal is
2021-06-28 03:23:53 +02:00
--|adjusted before centering
2021-06-27 07:48:46 +02:00
return
end
end
end
2021-06-28 03:23:53 +02:00
--|c.direction is used to create a fake toggling effect.
--|tiled clients require an internal maximized property to
--|be set, otherwise they won't budge.
2021-06-27 07:48:46 +02:00
----------------------------------------------------- expand_vertical() -- ;
local function expand_vertical()
local c = client.focus
local going = "down"
if c.maximized_vertical then
2021-07-07 21:52:05 +02:00
2021-07-07 19:05:10 +02:00
if not c.floating then
-- draw_tabbar(c.region)
2021-07-07 21:52:05 +02:00
resize_region_to_index(c.region, true, true)
2021-07-07 19:05:10 +02:00
end
2021-06-27 07:48:46 +02:00
return
2021-07-07 19:05:10 +02:00
end --|reset toggle when sending same shortcut
--|consequitively
2021-06-27 07:48:46 +02:00
2021-07-03 23:50:31 +02:00
local stuff = get_client_info()
2021-06-27 07:48:46 +02:00
local target = grect.get_in_direction("down", stuff.regions, client.focus:geometry())
if target and stuff.regions[target].x ~= c.x then
return
2021-06-28 03:23:53 +02:00
end --|flow control
--|ensure we are operating in the same X axis,
--|vertical directions jump around
2021-06-27 07:48:46 +02:00
if not target then
going = "up"
target = grect.get_in_direction("up", stuff.regions, client.focus:geometry())
2021-06-28 03:23:53 +02:00
end --|flow control
--|try reverse direction
2021-06-27 07:48:46 +02:00
if not target then return end
2021-06-28 03:23:53 +02:00
--|flow control
2021-06-27 07:48:46 +02:00
if going == "down" then
tobe = {
y=c.y,
2021-06-28 03:50:16 +02:00
x=c.x,
width=c.width,
2021-06-27 07:48:46 +02:00
height=stuff.regions[target].y + stuff.regions[target].height - c.y
}
end
if going == "up" then
tobe = {
2021-06-28 03:50:16 +02:00
x=c.x,
width=c.width,
2021-06-27 07:48:46 +02:00
y=stuff.regions[target].y,
height= c.height + c.y - stuff.regions[target].y
}
end
c.maximized_vertical = true
2021-06-28 03:50:16 +02:00
gears.timer.delayed_call(function ()
2021-07-07 21:52:05 +02:00
client.focus:raise()
2021-07-05 02:44:09 +02:00
client.focus:geometry(tobe)
2021-07-07 19:05:10 +02:00
resize_region_to_client(c, {horizontal=false,vertical=true,direction=direction})
2021-06-28 03:50:16 +02:00
end)
2021-06-27 07:48:46 +02:00
return
end
2021-07-03 23:50:31 +02:00
------------------------------------------------------------- shuffle() -- ;
2021-06-27 07:48:46 +02:00
2021-07-03 23:50:31 +02:00
local function shuffle(direction)
return function()
2021-07-07 05:02:58 +02:00
if not client.focus then return end
--▨ flow control
2021-07-07 21:52:05 +02:00
local tablist = get_piled_clients(client.focus.region)
2021-07-03 23:50:31 +02:00
--|this is the ordered list
2021-06-27 07:48:46 +02:00
2021-07-03 23:50:31 +02:00
if not #tablist then return end
--▨ flow control
2021-06-27 07:48:46 +02:00
2021-07-03 23:50:31 +02:00
focused_client_ix = get_client_ix(client.focus.window, tablist)
--|find the index position of the focused client
2021-06-27 07:48:46 +02:00
2021-07-03 23:50:31 +02:00
if not focused_client_ix then return end
--▨ flow control
2021-06-27 07:48:46 +02:00
2021-07-03 23:50:31 +02:00
prev_ix = focused_client_ix - 1
next_ix = focused_client_ix + 1
--|calculate target indexes
2021-06-27 07:48:46 +02:00
2021-07-03 23:50:31 +02:00
if next_ix > #tablist then next_ix = 1 end
if prev_ix < 1 then prev_ix = #tablist end
--|check for validity of the index
2021-06-27 07:48:46 +02:00
if direction == "backward" then
2021-07-03 23:50:31 +02:00
tablist[prev_ix]:emit_signal("request::activate", "mouse_enter",{raise = true})
2021-06-27 07:48:46 +02:00
return
end
if direction == "forward" then
2021-07-03 23:50:31 +02:00
tablist[next_ix]:emit_signal("request::activate", "mouse_enter",{raise = true})
2021-06-27 07:48:46 +02:00
return
end
end
end
2021-07-03 23:50:31 +02:00
---------------------------------------------------------- get_swapee() -- ;
local function get_swapee(target_region_ix)
local regions = get_regions()
--| all regions
local cltbl = awful.client.visible(client.focus.screen, true)
--| all visible clients on all regions
--| but we don't know which regions they are at
local swap_map = {}
for a,region in ipairs(regions) do
for i,c in ipairs(cltbl) do
if c.x == region.x and c.y == region.y then
swap_map[a] = i
break --|avoid stacked regions
end
end
end --|iterate over regions, and match the client objects in
--|each region.
local swapee = cltbl[swap_map[target_region_ix]]
return swapee
end
--[[
returns the client object at a specific region. we can
also use signals to keep track of this but we are trying
to avoid exessive use of signals.
--]]
---------------------------------------------------------- my_shifter() -- ;
2021-07-08 09:08:40 +02:00
local function focus_by_number(region_ix,s)
return function()
local s = s or awful.screen.focused()
local regions = get_regions(s)
local target_region_ix
local target_region
local swapee = get_swapee(region_ix)
--|visible client at the target region
swapee:emit_signal("request::activate", "mouse_enter",{raise = true})
end
end
local function focus_by_index(direction)
return function()
if direction == "left" then direction = "backward" end
if direction == "right" then direction = "forward" end
local c = client.focus
local stuff = get_client_info()
local client_region_ix = stuff.active_region
local source_region
local target_region_ix
local target_region
c = reset_client_meta(c)
--|clean artifacts in case client was expanded.
if direction == "backward" then
if (client_region_ix + 1) > #stuff.regions then
target_region_ix = 1
else
target_region_ix = client_region_ix+1
end
end --|go next region by index,
--|if not reset to first
if direction == "forward" then
if (client_region_ix - 1) < 1 then
target_region_ix = #stuff.regions
else
target_region_ix = client_region_ix - 1
end
end --|go previous region by index,
--|if not reset to last
local swapee = get_swapee(target_region_ix)
--|visible client at the target region
swapee:emit_signal("request::activate", "mouse_enter",{raise = true})
end
end
2021-07-03 23:50:31 +02:00
local function my_shifter(direction, swap)
2021-06-27 07:48:46 +02:00
return function()
2021-07-03 23:50:31 +02:00
if direction == "left" then direction = "backward" end
if direction == "right" then direction = "forward" end
2021-06-27 07:48:46 +02:00
2021-07-03 23:50:31 +02:00
local c = client.focus
local stuff = get_client_info()
local client_region_ix = stuff.active_region
local source_region
local target_region_ix
local target_region
2021-07-05 02:44:09 +02:00
c = reset_client_meta(c)
--|clean artifacts in case client was expanded.
2021-07-03 23:50:31 +02:00
if direction == "backward" then
if (client_region_ix + 1) > #stuff.regions then
target_region_ix = 1
2021-06-27 07:48:46 +02:00
else
2021-07-03 23:50:31 +02:00
target_region_ix = client_region_ix+1
end
end --|go next region by index,
--|if not reset to first
2021-06-27 07:48:46 +02:00
if direction == "forward" then
2021-07-03 23:50:31 +02:00
if (client_region_ix - 1) < 1 then
target_region_ix = #stuff.regions
else
target_region_ix = client_region_ix - 1
end
end --|go previous region by index,
--|if not reset to last
if stuff.outofboundary then
target_region_ix = client_region_ix
end --|ignore previous when out of boundary
--|probably floating or expanded client
--|push inside the boundary instead
source_region = stuff.regions[client_region_ix]
target_region = stuff.regions[target_region_ix]
--|target regions geometry
local swapee = get_swapee(target_region_ix)
--|visible client at the target region
c:geometry(target_region)
--|relocate client
2021-07-05 02:44:09 +02:00
c.region = target_region_ix
--|update client property
2021-07-03 23:50:31 +02:00
if not swap then c:raise() end
--|raise
if swap and swapee then
swapee:geometry(source_region)
swapee:emit_signal("request::activate", "mouse_enter",{raise = true})
end --|perform swap
draw_tabbar(target_region_ix)
2021-07-06 17:20:47 +02:00
resize_region_to_index(target_region_ix, target_region, true)
2021-07-03 23:50:31 +02:00
--|update tabs in target region
2021-06-27 07:48:46 +02:00
2021-07-03 23:50:31 +02:00
draw_tabbar(client_region_ix)
2021-07-06 17:20:47 +02:00
resize_region_to_index(client_region_ix, source_region, true)
2021-07-03 23:50:31 +02:00
--|update tabs in source region
end
end
2021-06-27 07:48:46 +02:00
2021-07-03 23:50:31 +02:00
---------------------------------------------------- shift_by_direction -- ;
local function shift_by_direction(direction, swap)
return function ()
local c = client.focus
local stuff = get_client_info()
local target_region_ix = nil
local client_region_ix = stuff.active_region
if stuff.outofboundary == true then
return my_shifter(direction)()
end --|my_shifter handles this situation better.
local candidate = {
up = grect.get_in_direction("up", stuff.regions, client.focus:geometry()),
down = grect.get_in_direction("down", stuff.regions, client.focus:geometry()),
left = grect.get_in_direction("left", stuff.regions, client.focus:geometry()),
right = grect.get_in_direction("right", stuff.regions, client.focus:geometry())
2021-07-06 17:20:47 +02:00
}
2021-07-03 23:50:31 +02:00
target_region_ix = candidate[direction]
--|try to get a candidate region if possible
if not target_region_ix then
if direction == "right" then try = "left" end
if direction == "left" then try = "right" end
if direction == "down" then try = "up" end
if direction == "up" then try = "down" end
target_region_ix = go_edge(try, stuff.regions, client.focus:geometry())
end --|go the beginning or the end if there is no
--|candidate
source_region = stuff.regions[client_region_ix]
target_region = stuff.regions[target_region_ix]
local swapee = get_swapee(target_region_ix)
--|visible client at the target region
c:geometry(target_region)
--|relocate client
2021-07-05 02:44:09 +02:00
c.region = target_region_ix
--|update client property
2021-07-03 23:50:31 +02:00
if not swap then c:raise() end
--|raise
if swap and swapee then
swapee:geometry(source_region)
swapee:emit_signal("request::activate", "mouse_enter",{raise = true})
2021-07-06 17:20:47 +02:00
swapee.region = client_region_ix
end --|perform swap, update meta
2021-07-03 23:50:31 +02:00
draw_tabbar(target_region_ix)
2021-07-06 17:20:47 +02:00
resize_region_to_index(target_region_ix, target_region, true)
2021-07-03 23:50:31 +02:00
--|update tabs in target region
2021-06-27 07:48:46 +02:00
2021-07-03 23:50:31 +02:00
draw_tabbar(client_region_ix)
2021-07-06 17:20:47 +02:00
resize_region_to_index(client_region_ix, source_region, true)
2021-07-03 23:50:31 +02:00
--|update tabs in source region
end
end
----------------------------------------------------- get_tiled_clients -- ;
2021-07-07 21:52:05 +02:00
function get_piled_clients(region_ix, s)
local s = s or client.focus.screen or awful.screen.focused()
local tablist = get_punched_clients(region_ix, s)
local all_clients = get_global_clients()
local tiled_clients = {}
local myorder = {}
local window_ix = {}
for i,t in ipairs(tablist) do
window_ix[t.window] = true
end
local po = 1
for i,c in pairs(all_clients) do
if not c.floating and window_ix[c.window] then
tiled_clients[po] = c
po = po + 1
end
end
return tiled_clients
end --[23]
2021-07-05 08:26:24 +02:00
function get_tiled_clients(region_ix, s)
2021-07-06 17:20:47 +02:00
local s = s or client.focus.screen or awful.screen.focused()
local tablist = get_clients_in_region(region_ix, c, s)
2021-07-03 23:50:31 +02:00
local all_clients = get_global_clients()
local tiled_clients = {}
local myorder = {}
local window_ix = {}
for i,t in ipairs(tablist) do
window_ix[t.window] = true
end
local po = 1
for i,c in pairs(all_clients) do
if not c.floating and window_ix[c.window] then
tiled_clients[po] = c
po = po + 1
2021-06-27 07:48:46 +02:00
end
2021-07-03 23:50:31 +02:00
end
2021-06-27 07:48:46 +02:00
2021-07-03 23:50:31 +02:00
return tiled_clients
2021-07-06 17:20:47 +02:00
end --[23]
2021-06-27 07:48:46 +02:00
2021-07-03 23:50:31 +02:00
-------------------------------------------------------- draw_tabbar() -- ;
2021-07-05 08:26:24 +02:00
function draw_tabbar(region_ix, s)
local s = s or awful.screen.focused()
2021-07-03 23:50:31 +02:00
local flexlist = tabs.layout()
2021-07-05 08:26:24 +02:00
local tablist = get_tiled_clients(region_ix, s)
2021-07-08 09:08:40 +02:00
2021-07-03 23:50:31 +02:00
if tablelength(tablist) == 0 then
return
end --|this should only fire on an empty region
if tablelength(tablist) == 1 then
clear_tabbar(tablist[1])
return
end --|reset tabbar titlebar when only
--|one client is in the region.
2021-07-05 08:26:24 +02:00
for cl_ix, cl in ipairs(tablist) do
2021-07-03 23:50:31 +02:00
local flexlist = tabs.layout()
2021-07-05 08:50:14 +02:00
global_widget_table[cl.window] = {}
2021-07-03 23:50:31 +02:00
for cc_ix, cc in ipairs(tablist) do
2021-07-07 05:02:58 +02:00
local buttons = gears.table.join(
awful.button({}, 1, function(_)
2021-07-10 02:49:27 +02:00
double_click_event_handler(function()
cc.floating = not cc.floating
end)
2021-07-07 05:02:58 +02:00
gears.timer.delayed_call(function(p)
client.emit_signal("riseup", p)
end, cc)
end),
awful.button({}, 3, function(_)
cc:kill()
end))
2021-07-05 08:50:14 +02:00
global_widget_table[cl.window][cc_ix] = tabs.create(cc, (cc == cl), buttons, cl_ix)
flexlist:add(global_widget_table[cl.window][cc_ix])
2021-07-05 02:44:09 +02:00
flexlist.max_widget_size = 120
2021-07-03 23:50:31 +02:00
end
2021-07-05 08:26:24 +02:00
local titlebar = awful.titlebar(cl, {
2021-07-03 23:50:31 +02:00
bg = tabs.bg_normal,
size = tabs.size,
position = tabs.position,
})
titlebar:setup{layout = wibox.layout.flex.horizontal, flexlist}
2021-07-05 08:26:24 +02:00
awful.titlebar(cl, {size=8, position = "top"})
awful.titlebar(cl, {size=0, position = "left"})
awful.titlebar(cl, {size=0, position = "right"})
2021-07-03 23:50:31 +02:00
end
end
2021-07-06 17:20:47 +02:00
------------------------------------------------------ resize_region_to -- ;
-- todo: can merge these later, this will have side effects
-- when using multipler monitors.
function resize_region_to_client(c, reset)
2021-07-07 18:59:15 +02:00
local c = c or client.focus or nil
2021-07-06 17:20:47 +02:00
if c.floating then return end
--|we don't wan't interference
local tablist = get_tiled_clients(c.region)
2021-07-07 05:02:58 +02:00
2021-07-06 17:20:47 +02:00
for i, w in ipairs(tablist) do
if reset == true then
reset_client_meta(w)
else
w.maximized_horizontal = reset.horizontal
w.maximized_vertical = reset.vertical
w.direction = reset.direction
end
2021-07-07 20:26:28 +02:00
2021-07-06 17:20:47 +02:00
w:geometry(c:geometry())
end
end
function resize_region_to_index(region_ix, geom, reset)
2021-07-07 21:52:05 +02:00
local tablist = get_punched_clients(region_ix)
local region_info = get_region(region_ix)
2021-07-05 02:44:09 +02:00
for c_ix, c in ipairs(tablist) do
if reset == true then
reset_client_meta(c)
else
c.maximized_horizontal = reset.horizontal
c.maximized_vertical = reset.vertical
c.direction = reset.direction
end
2021-07-07 21:52:05 +02:00
c:geometry(region_info)
2021-07-05 02:44:09 +02:00
end
end
2021-07-03 23:50:31 +02:00
2021-07-06 17:20:47 +02:00
----------------------------------------------------- teleport_client() -- ;
2021-07-06 00:54:27 +02:00
local function teleport_client(c,s)
local c = c or client.focus
local s = s or c.screen or awful.screen.focused()
2021-07-05 06:34:14 +02:00
2021-07-06 00:54:27 +02:00
if not c then return true end
--|flow control
2021-07-05 06:34:14 +02:00
local is = {
2021-07-06 00:54:27 +02:00
region=c.region or get_client_info(c).active_region,
geom=c:geometry(),
screen=c.screen
} --|parameters before teleport
2021-07-05 06:34:14 +02:00
2021-07-06 00:54:27 +02:00
if not c.floating then
c:geometry({width=300, height=300})
end --|to avoid machi's auto expansion (lu,rd) of tiled
--|clients, resize them temporarily. they will be auto
--|expanded to the region anyway.
2021-07-05 06:34:14 +02:00
2021-07-06 00:54:27 +02:00
c:move_to_screen()
--|teleport
2021-07-05 06:34:14 +02:00
2021-07-06 00:54:27 +02:00
gears.timer.delayed_call(function (c)
local tobe = {
region=get_client_info(c).active_region,
}
c.region = tobe.region
2021-07-06 17:20:47 +02:00
draw_tabbar(c.region, c.screen)
draw_tabbar(is.region, is.screen)
2021-07-06 00:54:27 +02:00
c:emit_signal("request::activate", "mouse_enter",{raise = true})
end,c)
2021-07-05 06:34:14 +02:00
end
2021-07-03 23:50:31 +02:00
------------------------------------------------------ signal helpers -- ;
local function manage_signal(c)
2021-07-22 15:04:22 +02:00
-- reset_all_clients(s)
2021-07-08 09:08:40 +02:00
--|reset hack, we shouldn't need this in the second write
--|up.
2021-07-07 05:02:58 +02:00
if c.data.awful_client_properties then
local ci = get_client_info(c)
--|client info
2021-07-06 17:20:47 +02:00
2021-07-07 05:02:58 +02:00
global_client_table[c.window] = c
--|add window.id to client index
if ci.active_region and not c.floating then
gears.timer.delayed_call(function(cinfo, p)
if p.data.awful_client_properties then --[20]
p.region = cinfo.region
draw_tabbar(cinfo.active_region, p.screen)
p:geometry(cinfo.active_region_geom)
end
end, ci, c)
end --|in case new client appears tiled
--|we must update the regions tabbars.
2021-07-22 07:52:31 +02:00
if c.transient_for then
c:move_to_screen(c.transient_for.screen)
c:move_to_tag(awful.screen.focused().selected_tag)
client.focus = c
end --|when clients have a preset screen index with the rules,
--|transient windows always open in that screen even if we
--|moved it to the other one. this takes care of that.
2021-07-07 05:02:58 +02:00
end
2021-07-06 17:20:47 +02:00
end --[6]
----------------------------------------------------;
2021-07-03 23:50:31 +02:00
local function unmanage_signal(c)
if c then
global_client_table[c.window] = nil
2021-07-05 08:50:14 +02:00
--|remove window.id from client index
global_widget_table[c.window] = nil
--|remove window.id from widget index
2021-07-03 23:50:31 +02:00
if not c.floating then
2021-07-06 17:20:47 +02:00
local ci = get_client_info(c)
if ci.active_region then
draw_tabbar(ci.active_region, c.screen)
end
2021-07-03 23:50:31 +02:00
end
end
2021-07-06 17:20:47 +02:00
end --[7]
----------------------------------------------------;
2021-06-28 03:50:16 +02:00
2021-07-03 23:50:31 +02:00
local function selected_tag_signal(t)
2021-07-06 00:54:27 +02:00
gears.timer.delayed_call(function(t)
local regions = get_regions(t.screen)
2021-07-03 23:50:31 +02:00
if regions and #regions then
for i, region in ipairs(regions) do
2021-07-06 00:54:27 +02:00
draw_tabbar(i, t.screen)
2021-07-03 23:50:31 +02:00
end
end
2021-07-06 00:54:27 +02:00
end,t)
2021-07-06 17:20:47 +02:00
end --[8]
----------------------------------------------------;
2021-07-03 23:50:31 +02:00
local function floating_signal(c)
2021-07-10 02:27:14 +02:00
if not global_client_table[c.window] then return end
--|possibly to optimize config reload
--|floating signal kicks in before manage
--|this should bypass weird things happening during reload if any.
2021-07-03 23:50:31 +02:00
if c.floating then
if c.region then
2021-07-10 02:27:14 +02:00
gears.timer.delayed_call(function(active_region,c)
2021-07-03 23:53:36 +02:00
clear_tabbar(c)
draw_tabbar(c.region)
2021-07-06 17:20:47 +02:00
c.region = nil
2021-07-10 02:27:14 +02:00
end, active_region,c)
2021-07-03 23:50:31 +02:00
end
end --|window became floating
if not c.floating then
2021-07-06 17:20:47 +02:00
local ci = get_client_info(c)
if ci.active_region then
c.region = ci.active_region
2021-07-03 23:50:31 +02:00
gears.timer.delayed_call(function(active_region)
2021-07-06 17:20:47 +02:00
draw_tabbar(active_region)
end, ci.active_region)
2021-07-03 23:50:31 +02:00
end
end --|window became tiled
2021-07-06 17:20:47 +02:00
end --[9]
----------------------------------------------------;
local function focus_signal(c)
if global_widget_table[c.window] then
for i, p in pairs(global_widget_table[c.window]) do
if p.focused then
local widget = global_widget_table[c.window][i]:get_children_by_id(c.window)[1]
widget.bg = "#43417a"
end
end
end
2021-07-03 23:50:31 +02:00
end
2021-07-06 17:20:47 +02:00
----------------------------------------------------;
2021-07-05 02:44:09 +02:00
2021-07-06 17:20:47 +02:00
local function unfocus_signal(c)
if global_widget_table[c.window] then
for i, p in pairs(global_widget_table[c.window]) do
if p.focused then
p.bg = "#292929"
break
end
end
end
end
----------------------------------------------------;
2021-07-03 23:50:31 +02:00
2021-07-06 17:20:47 +02:00
local function minimized_signal(c)
2021-07-03 23:50:31 +02:00
if c.minimized then unmanage_signal(c) end
if not c.minimized then manage_signal(c) end
2021-07-06 17:20:47 +02:00
end --[[ manage minimized and not minimized ]]
2021-07-03 23:50:31 +02:00
2021-07-06 17:20:47 +02:00
----------------------------------------------------;
2021-07-03 23:50:31 +02:00
2021-07-06 17:20:47 +02:00
local function name_signal(c)
if widget_ix[c.window] then
for i, p in pairs(widget_ix[c.window]) do
if p.focused then
widget = widget_ix[c.window][i]:get_children_by_id(c.window)[1]
widget.widget.markup = c.name
end
end
end
end -- todo: need to update the other clients in the region here as well
-- this may not even be worth it as the client names kind of pollute the
-- tabs a lot making it harder to distinguish what is what.
-- client.connect_signal("property::name", name_signal)
2021-07-05 02:44:09 +02:00
2021-07-08 09:08:40 +02:00
----------------------------------------------------;
2021-07-05 04:11:56 +02:00
2021-07-06 22:15:56 +02:00
local function riseup_signal(c)
client.focus = c; c:raise()
-- c:emit_signal("request::activate", "mouse_enter",{raise = true})
end
2021-07-06 23:01:00 +02:00
2021-07-08 09:08:40 +02:00
----------------------------------------------------;
2021-07-11 22:34:28 +02:00
-- awful.titlebar.widget.connect_signal("mouse::enter", function()
-- log('here')
-- end)
2021-07-06 23:01:00 +02:00
2021-07-06 17:20:47 +02:00
--------------------------------------------------------------- signals -- ;
2021-07-03 23:50:31 +02:00
2021-07-06 22:15:56 +02:00
client.connect_signal("riseup", riseup_signal)
2021-07-06 17:20:47 +02:00
client.connect_signal("focus", focus_signal)
client.connect_signal("unfocus", unfocus_signal)
client.connect_signal("property::minimized", minimized_signal)
client.connect_signal("property::floating", floating_signal)
client.connect_signal("tabbar_draw", draw_tabbar)
client.connect_signal("unmanage", unmanage_signal)
2021-07-03 23:50:31 +02:00
client.connect_signal("manage", manage_signal)
tag.connect_signal("property::selected", selected_tag_signal)
2021-07-11 22:34:28 +02:00
-- client.connect_signal("mouse::enter", function ()
-- log(mouse.current_widget)
-- end)
2021-06-27 07:48:46 +02:00
--------------------------------------------------------------- exports -- ;
module = {
focus_by_direction = focus_by_direction,
2021-07-03 23:50:31 +02:00
get_active_regions = get_client_info,
2021-06-27 07:48:46 +02:00
shift_by_direction = shift_by_direction,
expand_horizontal = expand_horizontal,
shuffle = shuffle,
2021-07-03 23:50:31 +02:00
old_shuffle = old_shuffle,
2021-06-27 07:48:46 +02:00
my_shifter = my_shifter,
2021-06-28 07:58:41 +02:00
expand_vertical = expand_vertical,
2021-06-28 13:27:03 +02:00
move_to = move_to,
2021-07-03 23:50:31 +02:00
get_regions = get_regions,
toggle_always_on = toggle_always_on,
draw_tabbar = draw_tabbar,
get_global_clients = get_global_clients,
update_global_clients = update_global_clients,
get_client_info = get_client_info,
2021-07-05 06:34:14 +02:00
teleport_client = teleport_client,
2021-07-08 09:08:40 +02:00
focus_by_index = focus_by_index,
2021-07-10 02:27:14 +02:00
focus_by_number = focus_by_number,
set_region = set_region,
align_floats = align_floats,
2021-06-27 07:48:46 +02:00
}
return module
2021-07-06 17:20:47 +02:00
--[[ ------------------------------------------------- NOTES ]
2021-07-08 23:46:29 +02:00
[99] order of signals, manage_signal executes the last,
not the first.
2021-07-08 09:08:40 +02:00
[0] todo: rewrite the whole thing, but plan ahead this
time.
- get regions from machi, this will give us indexes
- manage signal will mark the global index and punch
the region_id to the client.
- it will then draw tabs to the region
region_expansions:
- regions can be expanded using the maximixed trick.
- it will change the geometry of all the clients in
that region.
- redrawing the tabbar is not necessary.
- when toggling, region geometry will also change.
functions needed:
- get_region(region_id, screen)
- get_regions(screen)
- get_clients_in_region(region_id, screen): this would
need to return the ordered list of all the clients
in the region from the global client list.
there are multiple strategies that can be used:
c.region_id:
this wil flap during reload
geometric comparison: we can compare all client
geometry to regions geometry. but it will fail for
expanded/overflowing clients.
- draw_tabbar(region, screen): it will draw tabbars
for all the clients in the region.
- expand_region(direction, region, screen): it will
expand all the clients in the region. same shortcut
will reset the expansions. expansions will happen
in multiple directions, and "center".
MPV: it appears client flashing could also be an issue.
MPV for instance starts large briefly and causes an
update in the wrong region. We need a region.id lookup
only it seems. We should also consider reading awm rules
for a region id for placement.
2021-07-06 17:20:47 +02:00
[4] machi's own region expansion has issues on
awesome-reload. if we were to expand a region, and then
do reload, machi-layout would insist to keep the expanded
layout in its own accord.
[5] to avoid this, we temporarily set the non floating
clients region geometry.
[4] when the clients become float, we restore this
geometry. Do note, there is something awkward here, it
appears no matter what all clients start as float then
get tiled, so there is a flaw in this logic.
[9] when windows switch between float and tiled we must
perform necessary maintenance on the destination and
source regions. a delayed call was necessary when clients
become tiled to give awm enough time to draw the widgets
properly. (*)this floating signal acts weird during
configuration reloads.
[8] property::selected gets called the last, by the time
we are here, we already have the global_client_list to
draw tabbars. This may appear redundant here, but it's
good to have this fire up in case the user switches
tags.
[7] when removing a tiled client we must update the
tabbars of others. floating clients do not require any
cleanup.
[6] global_client_table is the milestone the tabbars rely
on. whenever a new client appears we must add to it, and
when a client is killed we must make sure it is
removed.
[23] global_client_index stores the ordered list of all
clients available and it is used as a blueprint to keep
the order of our tablist intact, without this, tabbars
would go out of order when user focuses via shortcuts
(run_or_raise).
2021-07-07 05:02:58 +02:00
[20] cudatext had an awkward issue, I suppose it's the way
it's rendering its window causing it to register multiple
times and it would make client.lua throw an invalid
object error at line 1195. So, it's handled now.
2021-07-06 17:20:47 +02:00
--]]