|
- --[[
-
- Lain
- Layouts, widgets and utilities for Awesome WM
-
- Utilities section
-
- Licensed under GNU General Public License v2
- * (c) 2013, Luca CPZ
- * (c) 2010-2012, Peter Hofmann
-
- --]]
-
- local awful = require("awful")
- local sqrt = math.sqrt
- local pairs = pairs
- local client = client
- local tonumber = tonumber
- local wrequire = require("lain.helpers").wrequire
- local setmetatable = setmetatable
-
- -- Lain utilities submodule
- -- lain.util
- local util = { _NAME = "lain.util" }
-
- -- Like awful.menu.clients, but only show clients of currently selected tags
- function util.menu_clients_current_tags(menu, args)
- -- List of currently selected tags.
- local cls_tags = awful.screen.focused().selected_tags
-
- if cls_tags == nil then return nil end
-
- -- Final list of menu items.
- local cls_t = {}
-
- -- For each selected tag get all clients of that tag and add them to
- -- the menu. A click on a menu item will raise that client.
- for i = 1,#cls_tags do
- local t = cls_tags[i]
- local cls = t:clients()
-
- for _, c in pairs(cls) do
- cls_t[#cls_t + 1] = { awful.util.escape(c.name) or "",
- function ()
- c.minimized = false
- client.focus = c
- c:raise()
- end,
- c.icon }
- end
- end
-
- -- No clients? Then quit.
- if #cls_t <= 0 then return nil end
-
- -- menu may contain some predefined values, otherwise start with a
- -- fresh menu.
- if not menu then menu = {} end
-
- -- Set the list of items and show the menu.
- menu.items = cls_t
- local m = awful.menu(menu)
- m:show(args)
-
- return m
- end
-
- -- Magnify a client: set it to "float" and resize it.
- function util.magnify_client(c, width_f, height_f)
- if c and not c.floating then
- util.magnified_client = c
- util.mc(c, width_f, height_f)
- else
- util.magnified_client = nil
- c.floating = false
- end
- end
-
- -- https://github.com/lcpz/lain/issues/195
- function util.mc(c, width_f, height_f)
- c = c or util.magnified_client
- if not c then return end
-
- c.floating = true
- local s = awful.screen.focused()
- local mg = s.workarea
- local g = {}
- local mwfact = width_f or s.selected_tag.master_width_factor or 0.5
- g.width = sqrt(mwfact) * mg.width
- g.height = sqrt(height_f or mwfact) * mg.height
- g.x = mg.x + (mg.width - g.width) / 2
- g.y = mg.y + (mg.height - g.height) / 2
-
- if c then c:geometry(g) end -- if c is still a valid object
- end
-
- -- Non-empty tag browsing
- -- direction in {-1, 1} <-> {previous, next} non-empty tag
- function util.tag_view_nonempty(direction,sc)
- direction = direction or 1
- local s = sc or awful.screen.focused()
- local tags = s.tags
- local sel = s.selected_tag
-
- local i = sel.index
- repeat
- i = i + direction
-
- -- Wrap around when we reach one of the bounds
- if i > #tags then
- i = i - #tags
- end
- if i < 1 then
- i = i + #tags
- end
-
- local t = tags[i]
-
- -- Stop when we get back to where we started
- if t == sel then
- break
- end
-
- -- If it's The One, view it.
- if #t:clients() > 0 then
- t:view_only()
- return
- end
- until false
- end
-
- -- {{{ Dynamic tagging
-
- -- Add a new tag
- function util.add_tag(layout)
- awful.prompt.run {
- prompt = "New tag name: ",
- textbox = awful.screen.focused().mypromptbox.widget,
- exe_callback = function(name)
- if not name or #name == 0 then return end
- awful.tag.add(name, { screen = awful.screen.focused(), layout = layout or awful.layout.suit.tile }):view_only()
- end
- }
- end
-
- -- Rename current tag
- function util.rename_tag()
- awful.prompt.run {
- prompt = "Rename tag: ",
- textbox = awful.screen.focused().mypromptbox.widget,
- exe_callback = function(new_name)
- if not new_name or #new_name == 0 then return end
- local t = awful.screen.focused().selected_tag
- if t then
- t.name = new_name
- end
- end
- }
- end
-
- -- Move current tag
- -- pos in {-1, 1} <-> {previous, next} tag position
- function util.move_tag(pos)
- local tag = awful.screen.focused().selected_tag
- if tonumber(pos) <= -1 then
- awful.tag.move(tag.index - 1, tag)
- else
- awful.tag.move(tag.index + 1, tag)
- end
- end
-
- -- Delete current tag
- -- Any rule set on the tag shall be broken
- function util.delete_tag()
- local t = awful.screen.focused().selected_tag
- if not t then return end
- t:delete()
- end
-
- -- }}}
-
- -- On the fly useless gaps change
- function util.useless_gaps_resize(thatmuch, s, t)
- local scr = s or awful.screen.focused()
- local tag = t or scr.selected_tag
- tag.gap = tag.gap + tonumber(thatmuch)
- awful.layout.arrange(scr)
- end
-
- return setmetatable(util, { __index = wrequire })
|