diff --git a/README.md b/README.md index 6f3655c..58b9aa7 100644 --- a/README.md +++ b/README.md @@ -37,14 +37,17 @@ We now have tabs for tiled clients :) - [ ] Better keybindings (possibly emacs style, or vim style): an xcape key can be used to to initiate awm layer and enter can exit from it. - [X] Clickable tabs -- [ ] Add align to left or right for floating windows: this will allow the user to see either side of the layout +- [X] On focus of tiled clients, allow realigning visible floating windows to sides via shortcuts. +- [X] Add align to left or right for floating windows: this will allow the user to see either side of the layout. - [X] Override cyclefocus for tabbed regions or bind alt-tab? - [ ] Merge Backham and Mouser (focus should stay client under mouse - sometimes?) -- [ ] Update tabs on tag change +- [X] Update tabs on tag change via signal - [ ] Add binding for relocating the entire region - [ ] Deck spread (send focused client to a direction without moving focus) - [ ] Client pull (pull a client from a direction onto the current deck) - [ ] Visual teleport (overlay with region numbers to choose from, possibly on all monitors, kind of like vimium) +- [ ] Add tabbing for floating clients: drag and drop seems not so easy, using rofi could be fine too but it is another step. Focus and mark could work better. Execute the shourtcut and choose the window to be tabbed with mouse or possibly via keyboard. +- [ ] Allow detaching from floating tabs. Can be a right click to the tab. - [x] Allow expanding regions horizontally and vertically - [x] Auto resize all clients in the region when expanded - [x] Avoid machi's auto expansion on config reload diff --git a/init.lua b/init.lua index 707e23a..95e0367 100644 --- a/init.lua +++ b/init.lua @@ -20,6 +20,8 @@ local teleport_client = machina.teleport_client local get_client_info = machina.get_client_info local focus_by_index = machina.focus_by_index local focus_by_number = machina.focus_by_number +local set_region = machina.set_region +local align_floats = machina.align_floats ---------------------------------------------------------- key bindings -- ; @@ -39,6 +41,10 @@ local bindings = { -- awful.key({modkey}, "Tab", focus_by_index("backward")), -- awful.key({modkey, "Shift"}, "Tab", focus_by_index("forward")), + + awful.key({modkey}, ";", align_floats("right")), + awful.key({modkey, "Shift"}, ";", align_floats("left")), + --▨ floating alignment awful.key({modkey}, "x", function () c = client.focus or nil @@ -63,7 +69,6 @@ local bindings = { awful.key({modkey, "Control"}, "]", my_shifter("forward", "swap")), --▨ swap - awful.key({modkey}, ";", function() log(get_client_info(client.focus).active_region) end ), awful.key({modkey}, "'", shuffle("forward")), --▨ shuffle diff --git a/methods.lua b/methods.lua index 7eb123f..d66ef92 100644 --- a/methods.lua +++ b/methods.lua @@ -26,6 +26,8 @@ function update_global_clients(c) global_client_table[c.window] = c end +----------------------------------------------------- reset_client_meta -- ; + local function reset_client_meta(c) c.maximized = false c.maximized_horizontal = false @@ -34,12 +36,122 @@ local function reset_client_meta(c) return c end +--------------------------------------------------- reset_all_clients() -- ; + 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 + +---------------------------------------------------------- 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 -- ; + +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) + local cs = get_visible_floating_clients(s) + + if space_around.right < 300 and space_around.left < 300 then + return + end + + 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 + + p:emit_signal("request::activate") + --|bring float up + + awful.placement.no_offscreen(p) + --|ensure everything is visible + + ::next:: + end + + client.focus = c + --|keep focus at the originating client + end +end +--|this will spread out visible floating to the left or +--|right, can refactor most of this later. + ------------------------------------------------------------- go_edge() -- ; local function go_edge(direction, regions, current_box) @@ -518,7 +630,7 @@ local function expand_horizontal(direction) geom = geoms.p1080() end - if fixedchoice then + if fixedchoice and not c.floating then c.direction = "center" c.maximized_horizontal = true geom = fixedchoice() @@ -1108,13 +1220,18 @@ end --[8] ----------------------------------------------------; local function floating_signal(c) + 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. + if c.floating then if c.region then - gears.timer.delayed_call(function(active_region) + gears.timer.delayed_call(function(active_region,c) clear_tabbar(c) draw_tabbar(c.region) c.region = nil - end, active_region) + end, active_region,c) end end --|window became floating @@ -1222,7 +1339,9 @@ module = { get_client_info = get_client_info, teleport_client = teleport_client, focus_by_index = focus_by_index, - focus_by_number = focus_by_number + focus_by_number = focus_by_number, + set_region = set_region, + align_floats = align_floats, } return module