summaryrefslogtreecommitdiff
path: root/awesome/lib/awful
diff options
context:
space:
mode:
authorache <ache@ache.one>2017-04-25 02:24:15 +0000
committerache <ache@ache.one>2017-04-25 02:24:15 +0000
commit9a8809f5d7fb61db02f5fbd90edd927d61006455 (patch)
treea023e3f37460df5f25e6dc97f8f8465e81433874 /awesome/lib/awful
parentChange theme colors (diff)
Big clean up of the config directory
Diffstat (limited to 'awesome/lib/awful')
-rw-r--r--awesome/lib/awful/autofocus.lua64
-rw-r--r--awesome/lib/awful/button.lua61
-rw-r--r--awesome/lib/awful/client.lua1238
-rw-r--r--awesome/lib/awful/client/focus.lua215
-rw-r--r--awesome/lib/awful/client/shape.lua93
-rw-r--r--awesome/lib/awful/client/urgent.lua88
-rw-r--r--awesome/lib/awful/completion.lua201
-rw-r--r--awesome/lib/awful/dbus.lua19
-rw-r--r--awesome/lib/awful/ewmh.lua295
-rw-r--r--awesome/lib/awful/hotkeys_popup/init.lua17
-rw-r--r--awesome/lib/awful/hotkeys_popup/keys/init.lua15
-rw-r--r--awesome/lib/awful/hotkeys_popup/keys/vim.lua173
-rw-r--r--awesome/lib/awful/hotkeys_popup/widget.lua482
-rw-r--r--awesome/lib/awful/init.lua64
-rw-r--r--awesome/lib/awful/key.lua136
-rw-r--r--awesome/lib/awful/keygrabber.lua96
-rw-r--r--awesome/lib/awful/layout/init.lua323
-rw-r--r--awesome/lib/awful/layout/suit/corner.lua204
-rw-r--r--awesome/lib/awful/layout/suit/fair.lua108
-rw-r--r--awesome/lib/awful/layout/suit/floating.lua112
-rw-r--r--awesome/lib/awful/layout/suit/init.lua19
-rw-r--r--awesome/lib/awful/layout/suit/magnifier.lua147
-rw-r--r--awesome/lib/awful/layout/suit/max.lua61
-rw-r--r--awesome/lib/awful/layout/suit/spiral.lua89
-rw-r--r--awesome/lib/awful/layout/suit/tile.lua348
-rw-r--r--awesome/lib/awful/menu.lua723
-rw-r--r--awesome/lib/awful/mouse/drag_to_tag.lua58
-rw-r--r--awesome/lib/awful/mouse/init.lua437
-rw-r--r--awesome/lib/awful/mouse/resize.lua229
-rw-r--r--awesome/lib/awful/mouse/snap.lua266
-rw-r--r--awesome/lib/awful/placement.lua1694
-rw-r--r--awesome/lib/awful/prompt.lua777
-rw-r--r--awesome/lib/awful/remote.lua47
-rw-r--r--awesome/lib/awful/rules.lua545
-rw-r--r--awesome/lib/awful/screen.lua477
-rw-r--r--awesome/lib/awful/spawn.lua421
-rw-r--r--awesome/lib/awful/startup_notification.lua53
-rw-r--r--awesome/lib/awful/tag.lua1505
-rw-r--r--awesome/lib/awful/titlebar.lua509
-rw-r--r--awesome/lib/awful/tooltip.lua616
-rw-r--r--awesome/lib/awful/util.lua588
-rw-r--r--awesome/lib/awful/wibar.lua603
-rw-r--r--awesome/lib/awful/wibox.lua12
-rw-r--r--awesome/lib/awful/widget/button.lua263
-rw-r--r--awesome/lib/awful/widget/common.lua119
-rw-r--r--awesome/lib/awful/widget/graph.lua16
-rw-r--r--awesome/lib/awful/widget/init.lua24
-rw-r--r--awesome/lib/awful/widget/keyboardlayout.lua308
-rw-r--r--awesome/lib/awful/widget/launcher.lua41
-rw-r--r--awesome/lib/awful/widget/layoutbox.lua73
-rw-r--r--awesome/lib/awful/widget/progressbar.lua16
-rw-r--r--awesome/lib/awful/widget/prompt.lua64
-rw-r--r--awesome/lib/awful/widget/taglist.lua452
-rw-r--r--awesome/lib/awful/widget/tasklist.lua573
-rw-r--r--awesome/lib/awful/widget/textclock.lua16
-rw-r--r--awesome/lib/awful/widget/watch.lua91
56 files changed, 0 insertions, 16284 deletions
diff --git a/awesome/lib/awful/autofocus.lua b/awesome/lib/awful/autofocus.lua
deleted file mode 100644
index 5fcd220..0000000
--- a/awesome/lib/awful/autofocus.lua
+++ /dev/null
@@ -1,64 +0,0 @@
----------------------------------------------------------------------------
---- Autofocus functions.
---
--- When loaded, this module makes sure that there's always a client that will
--- have focus on events such as tag switching, client unmanaging, etc.
---
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2009 Julien Danjou
--- @module awful.autofocus
----------------------------------------------------------------------------
-
-local client = client
-local aclient = require("awful.client")
-local timer = require("gears.timer")
-
---- Give focus when clients appear/disappear.
---
--- @param obj An object that should have a .screen property.
-local function check_focus(obj)
- if not obj.screen.valid then return end
- -- When no visible client has the focus...
- if not client.focus or not client.focus:isvisible() then
- local c = aclient.focus.history.get(screen[obj.screen], 0, aclient.focus.filter)
- if c then
- c:emit_signal("request::activate", "autofocus.check_focus",
- {raise=false})
- end
- end
-end
-
---- Check client focus (delayed).
--- @param obj An object that should have a .screen property.
-local function check_focus_delayed(obj)
- timer.delayed_call(check_focus, {screen = obj.screen})
-end
-
---- Give focus on tag selection change.
---
--- @param tag A tag object
-local function check_focus_tag(t)
- local s = t.screen
- if (not s) or (not s.valid) then return end
- s = screen[s]
- check_focus({ screen = s })
- if client.focus and screen[client.focus.screen] ~= s then
- local c = aclient.focus.history.get(s, 0, aclient.focus.filter)
- if c then
- c:emit_signal("request::activate", "autofocus.check_focus_tag",
- {raise=false})
- end
- end
-end
-
-tag.connect_signal("property::selected", function (t)
- timer.delayed_call(check_focus_tag, t)
-end)
-client.connect_signal("unmanage", check_focus_delayed)
-client.connect_signal("tagged", check_focus_delayed)
-client.connect_signal("untagged", check_focus_delayed)
-client.connect_signal("property::hidden", check_focus_delayed)
-client.connect_signal("property::minimized", check_focus_delayed)
-client.connect_signal("property::sticky", check_focus_delayed)
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/button.lua b/awesome/lib/awful/button.lua
deleted file mode 100644
index b50664d..0000000
--- a/awesome/lib/awful/button.lua
+++ /dev/null
@@ -1,61 +0,0 @@
----------------------------------------------------------------------------
---- Create easily new buttons objects ignoring certain modifiers.
---
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2009 Julien Danjou
--- @classmod awful.button
----------------------------------------------------------------------------
-
--- Grab environment we need
-local setmetatable = setmetatable
-local ipairs = ipairs
-local capi = { button = button }
-local util = require("awful.util")
-
-local button = { mt = {} }
-
---- Modifiers to ignore.
---
--- By default this is initialized as `{ "Lock", "Mod2" }`
--- so the `Caps Lock` or `Num Lock` modifier are not taking into account by awesome
--- when pressing keys.
---
--- @table ignore_modifiers
-local ignore_modifiers = { "Lock", "Mod2" }
-
---- Create a new button to use as binding.
---
--- This function is useful to create several buttons from one, because it will use
--- the ignore_modifier variable to create more button with or without the ignored
--- modifiers activated.
---
--- For example if you want to ignore CapsLock in your buttonbinding (which is
--- ignored by default by this function), creating button binding with this function
--- will return 2 button objects: one with CapsLock on, and the other one with
--- CapsLock off.
---
--- @see button
--- @treturn table A table with one or several button objects.
-function button.new(mod, _button, press, release)
- local ret = {}
- local subsets = util.subsets(ignore_modifiers)
- for _, set in ipairs(subsets) do
- ret[#ret + 1] = capi.button({ modifiers = util.table.join(mod, set),
- button = _button })
- if press then
- ret[#ret]:connect_signal("press", function(_, ...) press(...) end)
- end
- if release then
- ret[#ret]:connect_signal("release", function (_, ...) release(...) end)
- end
- end
- return ret
-end
-
-function button.mt:__call(...)
- return button.new(...)
-end
-
-return setmetatable(button, button.mt)
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/client.lua b/awesome/lib/awful/client.lua
deleted file mode 100644
index 809c055..0000000
--- a/awesome/lib/awful/client.lua
+++ /dev/null
@@ -1,1238 +0,0 @@
----------------------------------------------------------------------------
---- Useful client manipulation functions.
---
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2008 Julien Danjou
--- @module client
----------------------------------------------------------------------------
-
--- Grab environment we need
-local util = require("awful.util")
-local spawn = require("awful.spawn")
-local object = require("gears.object")
-local grect = require("gears.geometry").rectangle
-local pairs = pairs
-local type = type
-local ipairs = ipairs
-local table = table
-local math = math
-local setmetatable = setmetatable
-local capi =
-{
- client = client,
- mouse = mouse,
- screen = screen,
- awesome = awesome,
-}
-
-local function get_screen(s)
- return s and capi.screen[s]
-end
-
--- We use a metatable to prevent circular dependency loops.
-local screen
-do
- screen = setmetatable({}, {
- __index = function(_, k)
- screen = require("awful.screen")
- return screen[k]
- end,
- __newindex = error -- Just to be sure in case anything ever does this
- })
-end
-local client = {object={}}
-
--- Private data
-client.data = {}
-client.data.marked = {}
-client.data.persistent_properties_registered = {} -- keys are names of persistent properties, value always true
-
--- Functions
-client.urgent = require("awful.client.urgent")
-client.swap = {}
-client.floating = {}
-client.dockable = {}
-client.property = {}
-client.shape = require("awful.client.shape")
-client.focus = require("awful.client.focus")
-
---- Jump to the given client.
--- Takes care of focussing the screen, the right tag, etc.
---
--- @deprecated awful.client.jumpto
--- @see client.jump_to
--- @client c the client to jump to
--- @tparam bool|function merge If true then merge tags (select the client's
--- first tag additionally) when the client is not visible.
--- If it is a function, it will be called with the client and its first
--- tag as arguments.
-function client.jumpto(c, merge)
- util.deprecate("Use c:jump_to(merge) instead of awful.client.jumpto")
- client.object.jump_to(c, merge)
-end
-
---- Jump to the given client.
--- Takes care of focussing the screen, the right tag, etc.
---
--- @function client.jump_to
--- @tparam bool|function merge If true then merge tags (select the client's
--- first tag additionally) when the client is not visible.
--- If it is a function, it will be called with the client and its first
--- tag as arguments.
-function client.object.jump_to(self, merge)
- local s = get_screen(screen.focused())
- -- focus the screen
- if s ~= get_screen(self.screen) then
- screen.focus(self.screen)
- end
-
- self.minimized = false
-
- -- Try to make client visible, this also covers e.g. sticky.
- if not self:isvisible() then
- local t = self.first_tag
- if merge then
- if type(merge) == "function" then
- merge(self, t)
- elseif t then
- t.selected = true
- end
- elseif t then
- t:view_only()
- end
- end
-
- self:emit_signal("request::activate", "client.jumpto", {raise=true})
-end
-
---- Get visible clients from a screen.
---
--- @deprecated awful.client.visible
--- @see screen.clients
--- @tparam[opt] integer|screen s The screen, or nil for all screens.
--- @tparam[opt=false] boolean stacked Use stacking order? (top to bottom)
--- @treturn table A table with all visible clients.
-function client.visible(s, stacked)
- local cls = capi.client.get(s, stacked)
- local vcls = {}
- for _, c in pairs(cls) do
- if c:isvisible() then
- table.insert(vcls, c)
- end
- end
- return vcls
-end
-
---- Get visible and tiled clients
---
--- @deprecated awful.client.tiled
--- @see screen.tiled_clients
--- @tparam integer|screen s The screen, or nil for all screens.
--- @tparam[opt=false] boolean stacked Use stacking order? (top to bottom)
--- @treturn table A table with all visible and tiled clients.
-function client.tiled(s, stacked)
- local clients = client.visible(s, stacked)
- local tclients = {}
- -- Remove floating clients
- for _, c in pairs(clients) do
- if not client.object.get_floating(c)
- and not c.fullscreen
- and not c.maximized_vertical
- and not c.maximized_horizontal then
- table.insert(tclients, c)
- end
- end
- return tclients
-end
-
---- Get a client by its relative index to another client.
--- If no client is passed, the focused client will be used.
---
--- @function awful.client.next
--- @tparam int i The index. Use 1 to get the next, -1 to get the previous.
--- @client[opt] sel The client.
--- @tparam[opt=false] boolean stacked Use stacking order? (top to bottom)
--- @return A client, or nil if no client is available.
---
--- @usage -- focus the next window in the index
--- awful.client.next(1)
--- -- focus the previous
--- awful.client.next(-1)
-function client.next(i, sel, stacked)
- -- Get currently focused client
- sel = sel or capi.client.focus
- if sel then
- -- Get all visible clients
- local cls = client.visible(sel.screen, stacked)
- local fcls = {}
- -- Remove all non-normal clients
- for _, c in ipairs(cls) do
- if client.focus.filter(c) or c == sel then
- table.insert(fcls, c)
- end
- end
- cls = fcls
- -- Loop upon each client
- for idx, c in ipairs(cls) do
- if c == sel then
- -- Cycle
- return cls[util.cycle(#cls, idx + i)]
- end
- end
- end
-end
-
---- Swap a client with another client in the given direction.
--- @function awful.client.swap.bydirection
--- @tparam string dir The direction, can be either "up", "down", "left" or "right".
--- @client[opt=focused] c The client.
--- @tparam[opt=false] boolean stacked Use stacking order? (top to bottom)
-function client.swap.bydirection(dir, c, stacked)
- local sel = c or capi.client.focus
- if sel then
- local cltbl = client.visible(sel.screen, stacked)
- local geomtbl = {}
- for i,cl in ipairs(cltbl) do
- geomtbl[i] = cl:geometry()
- end
- local target = grect.get_in_direction(dir, geomtbl, sel:geometry())
-
- -- If we found a client to swap with, then go for it
- if target then
- cltbl[target]:swap(sel)
- end
- end
-end
-
---- Swap a client with another client in the given direction. Swaps across screens.
--- @function awful.client.swap.global_bydirection
--- @param dir The direction, can be either "up", "down", "left" or "right".
--- @client[opt] sel The client.
-function client.swap.global_bydirection(dir, sel)
- sel = sel or capi.client.focus
- local scr = get_screen(sel and sel.screen or screen.focused())
-
- if sel then
- -- move focus
- client.focus.global_bydirection(dir, sel)
- local c = capi.client.focus
-
- -- swapping inside a screen
- if get_screen(sel.screen) == get_screen(c.screen) and sel ~= c then
- c:swap(sel)
-
- -- swapping to an empty screen
- elseif get_screen(sel.screen) ~= get_screen(c.screen) and sel == c then
- sel:move_to_screen(screen.focused())
-
- -- swapping to a nonempty screen
- elseif get_screen(sel.screen) ~= get_screen(c.screen) and sel ~= c then
- sel:move_to_screen(c.screen)
- c:move_to_screen(scr)
- end
-
- screen.focus(sel.screen)
- sel:emit_signal("request::activate", "client.swap.global_bydirection",
- {raise=false})
- end
-end
-
---- Swap a client by its relative index.
--- @function awful.client.swap.byidx
--- @param i The index.
--- @client[opt] c The client, otherwise focused one is used.
-function client.swap.byidx(i, c)
- local sel = c or capi.client.focus
- local target = client.next(i, sel)
- if target then
- target:swap(sel)
- end
-end
-
---- Cycle clients.
---
--- @function awful.client.cycle
--- @param clockwise True to cycle clients clockwise.
--- @param[opt] s The screen where to cycle clients.
--- @tparam[opt=false] boolean stacked Use stacking order? (top to bottom)
-function client.cycle(clockwise, s, stacked)
- s = s or screen.focused()
- local cls = client.visible(s, stacked)
- -- We can't rotate without at least 2 clients, buddy.
- if #cls >= 2 then
- local c = table.remove(cls, 1)
- if clockwise then
- for i = #cls, 1, -1 do
- c:swap(cls[i])
- end
- else
- for _, rc in pairs(cls) do
- c:swap(rc)
- end
- end
- end
-end
-
---- Get the master window.
---
--- @legacylayout awful.client.getmaster
--- @screen_or_idx[opt=awful.screen.focused()] s The screen.
--- @return The master window.
-function client.getmaster(s)
- s = s or screen.focused()
- return client.visible(s)[1]
-end
-
---- Set the client as master: put it at the beginning of other windows.
---
--- @legacylayout awful.client.setmaster
--- @client c The window to set as master.
-function client.setmaster(c)
- local cls = util.table.reverse(capi.client.get(c.screen))
- for _, v in pairs(cls) do
- c:swap(v)
- end
-end
-
---- Set the client as slave: put it at the end of other windows.
--- @legacylayout awful.client.setslave
--- @client c The window to set as slave.
-function client.setslave(c)
- local cls = capi.client.get(c.screen)
- for _, v in pairs(cls) do
- c:swap(v)
- end
-end
-
---- Move/resize a client relative to current coordinates.
--- @deprecated awful.client.moveresize
--- @param x The relative x coordinate.
--- @param y The relative y coordinate.
--- @param w The relative width.
--- @param h The relative height.
--- @client[opt] c The client, otherwise focused one is used.
--- @see client.relative_move
-function client.moveresize(x, y, w, h, c)
- util.deprecate("Use c:relative_move(x, y, w, h) instead of awful.client.moveresize")
- client.object.relative_move(c or capi.client.focus, x, y, w, h)
-end
-
---- Move/resize a client relative to current coordinates.
--- @function client.relative_move
--- @see geometry
--- @tparam[opt=c.x] number x The relative x coordinate.
--- @tparam[opt=c.y] number y The relative y coordinate.
--- @tparam[opt=c.width] number w The relative width.
--- @tparam[opt=c.height] number h The relative height.
-function client.object.relative_move(self, x, y, w, h)
- local geometry = self:geometry()
- geometry['x'] = geometry['x'] + x
- geometry['y'] = geometry['y'] + y
- geometry['width'] = geometry['width'] + w
- geometry['height'] = geometry['height'] + h
- self:geometry(geometry)
-end
-
---- Move a client to a tag.
--- @deprecated awful.client.movetotag
--- @param target The tag to move the client to.
--- @client[opt] c The client to move, otherwise the focused one is used.
--- @see client.move_to_tag
-function client.movetotag(target, c)
- util.deprecate("Use c:move_to_tag(target) instead of awful.client.movetotag")
- client.object.move_to_tag(c or capi.client.focus, target)
-end
-
---- Move a client to a tag.
--- @function client.move_to_tag
--- @tparam tag target The tag to move the client to.
-function client.object.move_to_tag(self, target)
- local s = target.screen
- if self and s then
- if self == capi.client.focus then
- self:emit_signal("request::activate", "client.movetotag", {raise=true})
- end
- -- Set client on the same screen as the tag.
- self.screen = s
- self:tags({ target })
- end
-end
-
---- Toggle a tag on a client.
--- @deprecated awful.client.toggletag
--- @param target The tag to toggle.
--- @client[opt] c The client to toggle, otherwise the focused one is used.
--- @see client.toggle_tag
-function client.toggletag(target, c)
- util.deprecate("Use c:toggle_tag(target) instead of awful.client.toggletag")
- client.object.toggle_tag(c or capi.client.focus, target)
-end
-
---- Toggle a tag on a client.
--- @function client.toggle_tag
--- @tparam tag target The tag to move the client to.
-function client.object.toggle_tag(self, target)
- -- Check that tag and client screen are identical
- if self and get_screen(self.screen) == get_screen(target.screen) then
- local tags = self:tags()
- local index = nil;
- for i, v in ipairs(tags) do
- if v == target then
- index = i
- break
- end
- end
- if index then
- -- If it's the only tag for the window, stop.
- if #tags == 1 then return end
- tags[index] = nil
- else
- tags[#tags + 1] = target
- end
- self:tags(tags)
- end
-end
-
---- Move a client to a screen. Default is next screen, cycling.
--- @deprecated awful.client.movetoscreen
--- @client c The client to move.
--- @param s The screen, default to current + 1.
--- @see screen
--- @see client.move_to_screen
-function client.movetoscreen(c, s)
- util.deprecate("Use c:move_to_screen(s) instead of awful.client.movetoscreen")
- client.object.move_to_screen(c or capi.client.focus, s)
-end
-
---- Move a client to a screen. Default is next screen, cycling.
--- @function client.move_to_screen
--- @tparam[opt=c.screen.index+1] screen s The screen, default to current + 1.
--- @see screen
--- @see request::activate
-function client.object.move_to_screen(self, s)
- if self then
- local sc = capi.screen.count()
- if not s then
- s = self.screen.index + 1
- end
- if type(s) == "number" then
- if s > sc then s = 1 elseif s < 1 then s = sc end
- end
- s = get_screen(s)
- if get_screen(self.screen) ~= s then
- local sel_is_focused = self == capi.client.focus
- self.screen = s
- screen.focus(s)
-
- if sel_is_focused then
- self:emit_signal("request::activate", "client.movetoscreen",
- {raise=true})
- end
- end
- end
-end
-
---- Tag a client with the set of current tags.
--- @function client.to_selected_tags
--- @see screen.selected_tags
-function client.object.to_selected_tags(self)
- local tags = {}
-
- for _, t in ipairs(self:tags()) do
- if get_screen(t.screen) == get_screen(self.screen) then
- table.insert(tags, t)
- end
- end
-
- if self.screen then
- if #tags == 0 then
- tags = self.screen.selected_tags
- end
-
- if #tags == 0 then
- tags = self.screen.tags
- end
- end
-
- if #tags ~= 0 then
- self:tags(tags)
- end
-end
-
---- If a client is marked or not.
---
--- **Signal:**
---
--- * *marked* (for legacy reasons, use `property::marked`)
--- * *unmarked* (for legacy reasons, use `property::marked`)
--- * *property::marked*
---
--- @property marked
--- @param boolean
-
---- The border color when the client is focused.
---
--- @beautiful beautiful.border_marked
--- @param string
---
-
-function client.object.set_marked(self, value)
- local is_marked = self.marked
-
- if value == false and is_marked then
- for k, v in pairs(client.data.marked) do
- if self == v then
- table.remove(client.data.marked, k)
- end
- end
- self:emit_signal("unmarked")
- elseif not is_marked and value then
- self:emit_signal("marked")
- table.insert(client.data.marked, self)
- end
-
- client.property.set(self, "marked", value)
-end
-
-function client.object.get_marked(self)
- return client.property.get(self, "marked")
-end
-
---- Mark a client, and then call 'marked' hook.
--- @deprecated awful.client.mark
--- @client c The client to mark, the focused one if not specified.
-function client.mark(c)
- util.deprecate("Use c.marked = true instead of awful.client.mark")
- client.object.set_marked(c or capi.client.focus, true)
-end
-
---- Unmark a client and then call 'unmarked' hook.
--- @deprecated awful.client.unmark
--- @client c The client to unmark, or the focused one if not specified.
-function client.unmark(c)
- util.deprecate("Use c.marked = false instead of awful.client.unmark")
- client.object.set_marked(c or capi.client.focus, false)
-end
-
---- Check if a client is marked.
--- @deprecated awful.client.ismarked
--- @client c The client to check, or the focused one otherwise.
-function client.ismarked(c)
- util.deprecate("Use c.marked instead of awful.client.ismarked")
- return client.object.get_marked(c or capi.client.focus)
-end
-
---- Toggle a client as marked.
--- @deprecated awful.client.togglemarked
--- @client c The client to toggle mark.
-function client.togglemarked(c)
- util.deprecate("Use c.marked = not c.marked instead of awful.client.togglemarked")
- c = c or capi.client.focus
- if c then
- c.marked = not c.marked
- end
-end
-
---- Return the marked clients and empty the marked table.
--- @function awful.client.getmarked
--- @return A table with all marked clients.
-function client.getmarked()
- local copy = util.table.clone(client.data.marked, false)
-
- for _, v in pairs(copy) do
- client.property.set(v, "marked", false)
- v:emit_signal("unmarked")
- end
-
- client.data.marked = {}
-
- return copy
-end
-
---- Set a client floating state, overriding auto-detection.
--- Floating client are not handled by tiling layouts.
--- @deprecated awful.client.floating.set
--- @client c A client.
--- @param s True or false.
-function client.floating.set(c, s)
- util.deprecate("Use c.floating = true instead of awful.client.floating.set")
- client.object.set_floating(c, s)
-end
-
--- Set a client floating state, overriding auto-detection.
--- Floating client are not handled by tiling layouts.
--- @client c A client.
--- @param s True or false.
-function client.object.set_floating(c, s)
- c = c or capi.client.focus
- if c and client.property.get(c, "floating") ~= s then
- client.property.set(c, "floating", s)
- local scr = c.screen
- if s == true then
- c:geometry(client.property.get(c, "floating_geometry"))
- end
- c.screen = scr
- end
-end
-
-local function store_floating_geometry(c)
- if client.object.get_floating(c) then
- client.property.set(c, "floating_geometry", c:geometry())
- end
-end
-
--- Store the initial client geometry.
-capi.client.connect_signal("new", function(cl)
- local function store_init_geometry(c)
- client.property.set(c, "floating_geometry", c:geometry())
- c:disconnect_signal("property::border_width", store_init_geometry)
- end
- cl:connect_signal("property::border_width", store_init_geometry)
-end)
-
-capi.client.connect_signal("property::geometry", store_floating_geometry)
-
---- Return if a client has a fixed size or not.
--- This function is deprecated, use `c.is_fixed`
--- @client c The client.
--- @deprecated awful.client.isfixed
--- @see is_fixed
--- @see size_hints_honor
-function client.isfixed(c)
- util.deprecate("Use c.is_fixed instead of awful.client.isfixed")
- c = c or capi.client.focus
- return client.object.is_fixed(c)
-end
-
---- Return if a client has a fixed size or not.
---
--- **Signal:**
---
--- * *property::is_fixed*
---
--- This property is read only.
--- @property is_fixed
--- @param boolean The floating state
--- @see size_hints
--- @see size_hints_honor
-
-function client.object.is_fixed(c)
- if not c then return end
- local h = c.size_hints
- if h.min_width and h.max_width
- and h.max_height and h.min_height
- and h.min_width > 0 and h.max_width > 0
- and h.max_height > 0 and h.min_height > 0
- and h.min_width == h.max_width
- and h.min_height == h.max_height then
- return true
- end
- return false
-end
-
---- Get a client floating state.
--- @client c A client.
--- @see floating
--- @deprecated awful.client.floating.get
--- @return True or false. Note that some windows might be floating even if you
--- did not set them manually. For example, windows with a type different than
--- normal.
-function client.floating.get(c)
- util.deprecate("Use c.floating instead of awful.client.floating.get")
- return client.object.get_floating(c)
-end
-
---- The client floating state.
--- If the client is part of the tiled layout or free floating.
---
--- Note that some windows might be floating even if you
--- did not set them manually. For example, windows with a type different than
--- normal.
---
--- **Signal:**
---
--- * *property::floating*
---
--- @property floating
--- @param boolean The floating state
-
-function client.object.get_floating(c)
- c = c or capi.client.focus
- if c then
- local value = client.property.get(c, "floating")
- if value ~= nil then
- return value
- end
- if c.type ~= "normal"
- or c.fullscreen
- or c.maximized_vertical
- or c.maximized_horizontal
- or client.object.is_fixed(c) then
- return true
- end
- return false
- end
-end
-
---- Toggle the floating state of a client between 'auto' and 'true'.
--- Use `c.floating = not c.floating`
--- @deprecated awful.client.floating.toggle
--- @client c A client.
--- @see floating
-function client.floating.toggle(c)
- c = c or capi.client.focus
- -- If it has been set to floating
- client.object.set_floating(c, not client.object.get_floating(c))
-end
-
--- Remove the floating information on a client.
--- @client c The client.
-function client.floating.delete(c)
- client.object.set_floating(c, nil)
-end
-
---- The x coordinates.
---
--- **Signal:**
---
--- * *property::x*
---
--- @property x
--- @param integer
-
---- The y coordinates.
---
--- **Signal:**
---
--- * *property::y*
---
--- @property y
--- @param integer
-
---- The width of the wibox.
---
--- **Signal:**
---
--- * *property::width*
---
--- @property width
--- @param width
-
---- The height of the wibox.
---
--- **Signal:**
---
--- * *property::height*
---
--- @property height
--- @param height
-
--- Add the geometry helpers to match the wibox API
-for _, v in ipairs {"x", "y", "width", "height"} do
- client.object["get_"..v] = function(c)
- return c:geometry()[v]
- end
-
- client.object["set_"..v] = function(c, value)
- return c:geometry({[v] = value})
- end
-end
-
-
---- Restore (=unminimize) a random client.
--- @function awful.client.restore
--- @param s The screen to use.
--- @return The restored client if some client was restored, otherwise nil.
-function client.restore(s)
- s = s or screen.focused()
- local cls = capi.client.get(s)
- local tags = s.selected_tags
- for _, c in pairs(cls) do
- local ctags = c:tags()
- if c.minimized then
- for _, t in ipairs(tags) do
- if util.table.hasitem(ctags, t) then
- c.minimized = false
- return c
- end
- end
- end
- end
- return nil
-end
-
---- Normalize a set of numbers to 1
--- @param set the set of numbers to normalize
--- @param num the number of numbers to normalize
-local function normalize(set, num)
- num = num or #set
- local total = 0
- if num then
- for i = 1,num do
- total = total + set[i]
- end
- for i = 1,num do
- set[i] = set[i] / total
- end
- else
- for _,v in ipairs(set) do
- total = total + v
- end
-
- for i,v in ipairs(set) do
- set[i] = v / total
- end
- end
-end
-
---- Calculate a client's column number, index in that column, and
--- number of visible clients in this column.
---
--- @legacylayout awful.client.idx
--- @client c the client
--- @return col the column number
--- @return idx index of the client in the column
--- @return num the number of visible clients in the column
-function client.idx(c)
- c = c or capi.client.focus
- if not c then return end
-
- -- Only check the tiled clients, the others un irrelevant
- local clients = client.tiled(c.screen)
- local idx = nil
- for k, cl in ipairs(clients) do
- if cl == c then
- idx = k
- break
- end
- end
-
- local t = c.screen.selected_tag
- local nmaster = t.master_count
-
- -- This will happen for floating or maximized clients
- if not idx then return nil end
-
- if idx <= nmaster then
- return {idx = idx, col=0, num=nmaster}
- end
- local nother = #clients - nmaster
- idx = idx - nmaster
-
- -- rather than regenerate the column number we can calculate it
- -- based on the how the tiling algorithm places clients we calculate
- -- the column, we could easily use the for loop in the program but we can
- -- calculate it.
- local ncol = t.column_count
- -- minimum number of clients per column
- local percol = math.floor(nother / ncol)
- -- number of columns with an extra client
- local overcol = math.fmod(nother, ncol)
- -- number of columns filled with [percol] clients
- local regcol = ncol - overcol
-
- local col = math.floor( (idx - 1) / percol) + 1
- if col > regcol then
- -- col = math.floor( (idx - (percol*regcol) - 1) / (percol + 1) ) + regcol + 1
- -- simplified
- col = math.floor( (idx + regcol + percol) / (percol+1) )
- -- calculate the index in the column
- idx = idx - percol*regcol - (col - regcol - 1) * (percol+1)
- percol = percol+1
- else
- idx = idx - percol*(col-1)
- end
-
- return {idx = idx, col=col, num=percol}
-end
-
-
---- Set the window factor of a client
---
--- @legacylayout awful.client.setwfact
--- @param wfact the window factor value
--- @client c the client
-function client.setwfact(wfact, c)
- -- get the currently selected window
- c = c or capi.client.focus
- if not c or not c:isvisible() then return end
-
- local w = client.idx(c)
-
- if not w then return end
-
- local t = c.screen.selected_tag
-
- -- n is the number of windows currently visible for which we have to be concerned with the properties
- local data = t.windowfact or {}
- local colfact = data[w.col]
-
- local need_normalize = colfact ~= nil
-
- if not need_normalize then
- colfact = {}
- end
-
- colfact[w.idx] = wfact
-
- if not need_normalize then
- t:emit_signal("property::windowfact")
- return
- end
-
- local rest = 1-wfact
-
- -- calculate the current denominator
- local total = 0
- for i = 1,w.num do
- if i ~= w.idx then
- total = total + colfact[i]
- end
- end
-
- -- normalize the windows
- for i = 1,w.num do
- if i ~= w.idx then
- colfact[i] = (colfact[i] * rest) / total
- end
- end
-
- t:emit_signal("property::windowfact")
-end
-
---- Change window factor of a client.
---
--- @legacylayout awful.client.incwfact
--- @tparam number add Amount to increase/decrease the client's window factor.
--- Should be between `-current_window_factor` and something close to
--- infinite. The normalisation then ensures that the sum of all factors is 1.
--- @client c the client
-function client.incwfact(add, c)
- c = c or capi.client.focus
- if not c then return end
-
- local t = c.screen.selected_tag
- local w = client.idx(c)
- local data = t.windowfact or {}
- local colfact = data[w.col] or {}
- local curr = colfact[w.idx] or 1
- colfact[w.idx] = curr + add
-
- -- keep our ratios normalized
- normalize(colfact, w.num)
-
- t:emit_signal("property::windowfact")
-end
-
---- Get a client dockable state.
---
--- @client c A client.
--- @return True or false. Note that some windows might be dockable even if you
--- did not set them manually. For example, windows with a type "utility",
--- "toolbar" or "dock"
--- @deprecated awful.client.dockable.get
-function client.dockable.get(c)
- util.deprecate("Use c.dockable instead of awful.client.dockable.get")
- return client.object.get_dockable(c)
-end
-
---- If the client is dockable.
--- A dockable client is an application confined to the edge of the screen. The
--- space it occupy is substracted from the `screen.workarea`.
---
--- **Signal:**
---
--- * *property::dockable*
---
--- @property dockable
--- @param boolean The dockable state
-
-function client.object.get_dockable(c)
- local value = client.property.get(c, "dockable")
-
- -- Some sane defaults
- if value == nil then
- if (c.type == "utility" or c.type == "toolbar" or c.type == "dock") then
- value = true
- else
- value = false
- end
- end
-
- return value
-end
-
---- Set a client dockable state, overriding auto-detection.
--- With this enabled you can dock windows by moving them from the center
--- to the edge of the workarea.
---
--- @client c A client.
--- @param value True or false.
--- @deprecated awful.client.dockable.set
-function client.dockable.set(c, value)
- util.deprecate("Use c.dockable = value instead of awful.client.dockable.set")
- client.property.set(c, "dockable", value)
-end
-
---- Get a client property.
---
--- This method is deprecated. It is now possible to use `c.value` directly.
---
--- @client c The client.
--- @param prop The property name.
--- @return The property.
--- @deprecated awful.client.property.get
-function client.property.get(c, prop)
- if not c.data._persistent_properties_loaded then
- c.data._persistent_properties_loaded = true
- for p in pairs(client.data.persistent_properties_registered) do
- local value = c:get_xproperty("awful.client.property." .. p)
- if value ~= nil then
- client.property.set(c, p, value)
- end
- end
- end
- if c.data.awful_client_properties then
- return c.data.awful_client_properties[prop]
- end
-end
-
---- Set a client property.
---
--- This method is deprecated. It is now possible to use `c.value = value`
--- directly.
---
--- @client c The client.
--- @param prop The property name.
--- @param value The value.
--- @deprecated awful.client.property.set
-function client.property.set(c, prop, value)
- if not c.data.awful_client_properties then
- c.data.awful_client_properties = {}
- end
- if c.data.awful_client_properties[prop] ~= value then
- if client.data.persistent_properties_registered[prop] then
- c:set_xproperty("awful.client.property." .. prop, value)
- end
- c.data.awful_client_properties[prop] = value
- c:emit_signal("property::" .. prop)
- end
-end
-
---- Set a client property to be persistent across restarts (via X properties).
---
--- @function awful.client.property.persist
--- @param prop The property name.
--- @param kind The type (used for register_xproperty).
--- One of "string", "number" or "boolean".
-function client.property.persist(prop, kind)
- local xprop = "awful.client.property." .. prop
- capi.awesome.register_xproperty(xprop, kind)
- client.data.persistent_properties_registered[prop] = true
-
- -- Make already-set properties persistent
- for c in pairs(capi.client.get()) do
- if c.data.awful_client_properties and c.data.awful_client_properties[prop] ~= nil then
- c:set_xproperty(xprop, c.data.awful_client_properties[prop])
- end
- end
-end
-
----
--- Returns an iterator to cycle through, starting from the client in focus or
--- the given index, all clients that match a given criteria.
---
--- @param filter a function that returns true to indicate a positive match
--- @param start what index to start iterating from. Defaults to using the
--- index of the currently focused client.
--- @param s which screen to use. nil means all screens.
---
--- @function awful.client.iterate
--- @usage -- un-minimize all urxvt instances
--- local urxvt = function (c)
--- return awful.rules.match(c, {class = "URxvt"})
--- end
---
--- for c in awful.client.iterate(urxvt) do
--- c.minimized = false
--- end
-function client.iterate(filter, start, s)
- local clients = capi.client.get(s)
- local focused = capi.client.focus
- start = start or util.table.hasitem(clients, focused)
- return util.table.iterate(clients, filter, start)
-end
-
---- Switch to a client matching the given condition if running, else spawn it.
--- If multiple clients match the given condition then the next one is
--- focussed.
---
--- @param cmd the command to execute
--- @param matcher a function that returns true to indicate a matching client
--- @tparam bool|function merge If true then merge tags (select the client's
--- first tag additionally) when the client is not visible.
--- If it is a function, it will be called with the client as argument.
---
--- @function awful.client.run_or_raise
--- @usage -- run or raise urxvt (perhaps, with tabs) on modkey + semicolon
--- awful.key({ modkey, }, 'semicolon', function ()
--- local matcher = function (c)
--- return awful.rules.match(c, {class = 'URxvt'})
--- end
--- awful.client.run_or_raise('urxvt', matcher)
--- end);
-function client.run_or_raise(cmd, matcher, merge)
- local clients = capi.client.get()
- local findex = util.table.hasitem(clients, capi.client.focus) or 1
- local start = util.cycle(#clients, findex + 1)
-
- local c = client.iterate(matcher, start)()
- if c then
- c:jump_to(merge)
- else
- -- client not found, spawn it
- spawn(cmd)
- end
-end
-
---- Get a matching transient_for client (if any).
--- @deprecated awful.client.get_transient_for_matching
--- @see client.get_transient_for_matching
--- @client c The client.
--- @tparam function matcher A function that should return true, if
--- a matching parent client is found.
--- @treturn client.client|nil The matching parent client or nil.
-function client.get_transient_for_matching(c, matcher)
- util.deprecate("Use c:get_transient_for_matching(matcher) instead of"..
- "awful.client.get_transient_for_matching")
-
- return client.object.get_transient_for_matching(c, matcher)
-end
-
---- Get a matching transient_for client (if any).
--- @function client.get_transient_for_matching
--- @tparam function matcher A function that should return true, if
--- a matching parent client is found.
--- @treturn client.client|nil The matching parent client or nil.
-function client.object.get_transient_for_matching(self, matcher)
- local tc = self.transient_for
- while tc do
- if matcher(tc) then
- return tc
- end
- tc = tc.transient_for
- end
- return nil
-end
-
---- Is a client transient for another one?
--- @deprecated awful.client.is_transient_for
--- @see client.is_transient_for
--- @client c The child client (having transient_for).
--- @client c2 The parent client to check.
--- @treturn client.client|nil The parent client or nil.
-function client.is_transient_for(c, c2)
- util.deprecate("Use c:is_transient_for(c2) instead of"..
- "awful.client.is_transient_for")
- return client.object.is_transient_for(c, c2)
-end
-
---- Is a client transient for another one?
--- @function client.is_transient_for
--- @client c2 The parent client to check.
--- @treturn client.client|nil The parent client or nil.
-function client.object.is_transient_for(self, c2)
- local tc = self
- while tc.transient_for do
- if tc.transient_for == c2 then
- return tc
- end
- tc = tc.transient_for
- end
- return nil
-end
-
--- Register standards signals
-
---- The last geometry when client was floating.
--- @signal property::floating_geometry
-
---- Emited when a client need to get a titlebar.
--- @signal request::titlebars
--- @tparam[opt=nil] string content The context (like "rules")
--- @tparam[opt=nil] table hints Some hints.
-
---- The client marked signal (deprecated).
--- @signal .marked
-
---- The client unmarked signal (deprecated).
--- @signal unmarked
-
--- Add clients during startup to focus history.
--- This used to happen through ewmh.activate, but that only handles visible
--- clients now.
-capi.client.connect_signal("manage", function (c)
- if awesome.startup then
- client.focus.history.add(c)
- end
-end)
-capi.client.connect_signal("unmanage", client.focus.history.delete)
-
-capi.client.connect_signal("unmanage", client.floating.delete)
-
--- Connect to "focus" signal, and allow to disable tracking.
-do
- local disabled_count = 1
- --- Disable history tracking.
- --
- -- See `awful.client.focus.history.enable_tracking` to enable it again.
- -- @treturn int The internal value of `disabled_count` (calls to this
- -- function without calling `awful.client.focus.history.enable_tracking`).
- -- @function awful.client.focus.history.disable_tracking
- function client.focus.history.disable_tracking()
- disabled_count = disabled_count + 1
- if disabled_count == 1 then
- capi.client.disconnect_signal("focus", client.focus.history.add)
- end
- return disabled_count
- end
-
- --- Enable history tracking.
- --
- -- This is the default, but can be disabled
- -- through `awful.client.focus.history.disable_tracking`.
- -- @treturn boolean True if history tracking has been enabled.
- -- @function awful.client.focus.history.enable_tracking
- function client.focus.history.enable_tracking()
- assert(disabled_count > 0)
- disabled_count = disabled_count - 1
- if disabled_count == 0 then
- capi.client.connect_signal("focus", client.focus.history.add)
- end
- return disabled_count == 0
- end
-
- --- Is history tracking enabled?
- -- @treturn bool True if history tracking is enabled.
- -- @treturn int The number of times that tracking has been disabled.
- -- @function awful.client.focus.history.is_enabled
- function client.focus.history.is_enabled()
- return disabled_count == 0, disabled_count
- end
-end
-client.focus.history.enable_tracking()
-
--- Register persistent properties
-client.property.persist("floating", "boolean")
-
--- Extend the luaobject
-object.properties(capi.client, {
- getter_class = client.object,
- setter_class = client.object,
- getter_fallback = client.property.get,
- setter_fallback = client.property.set,
-})
-
-return client
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/client/focus.lua b/awesome/lib/awful/client/focus.lua
deleted file mode 100644
index a8b04f2..0000000
--- a/awesome/lib/awful/client/focus.lua
+++ /dev/null
@@ -1,215 +0,0 @@
----------------------------------------------------------------------------
---- Keep track of the focused clients.
---
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2008 Julien Danjou
--- @submodule client
----------------------------------------------------------------------------
-local grect = require("gears.geometry").rectangle
-
-local capi =
-{
- screen = screen,
- client = client,
-}
-
--- We use a metatable to prevent circular dependency loops.
-local screen
-do
- screen = setmetatable({}, {
- __index = function(_, k)
- screen = require("awful.screen")
- return screen[k]
- end,
- __newindex = error -- Just to be sure in case anything ever does this
- })
-end
-
-local client
-do
- client = setmetatable({}, {
- __index = function(_, k)
- client = require("awful.client")
- return client[k]
- end,
- __newindex = error -- Just to be sure in case anything ever does this
- })
-end
-
-local focus = {history = {list = {}}}
-
-local function get_screen(s)
- return s and capi.screen[s]
-end
-
---- Remove a client from the focus history
---
--- @client c The client that must be removed.
--- @function awful.client.focus.history.delete
-function focus.history.delete(c)
- for k, v in ipairs(focus.history.list) do
- if v == c then
- table.remove(focus.history.list, k)
- break
- end
- end
-end
-
---- Focus a client by its relative index.
---
--- @function awful.client.focus.byidx
--- @param i The index.
--- @client[opt] c The client.
-function focus.byidx(i, c)
- local target = client.next(i, c)
- if target then
- target:emit_signal("request::activate", "client.focus.byidx",
- {raise=true})
- end
-end
-
---- Filter out window that we do not want handled by focus.
--- This usually means that desktop, dock and splash windows are
--- not registered and cannot get focus.
---
--- @client c A client.
--- @return The same client if it's ok, nil otherwise.
--- @function awful.client.focus.filter
-function focus.filter(c)
- if c.type == "desktop"
- or c.type == "dock"
- or c.type == "splash"
- or not c.focusable then
- return nil
- end
- return c
-end
-
---- Update client focus history.
---
--- @client c The client that has been focused.
--- @function awful.client.focus.history.add
-function focus.history.add(c)
- -- Remove the client if its in stack
- focus.history.delete(c)
- -- Record the client has latest focused
- table.insert(focus.history.list, 1, c)
-end
-
---- Get the latest focused client for a screen in history.
---
--- @tparam int|screen s The screen to look for.
--- @tparam int idx The index: 0 will return first candidate,
--- 1 will return second, etc.
--- @tparam function filter An optional filter. If no client is found in the
--- first iteration, `awful.client.focus.filter` is used by default to get any
--- client.
--- @treturn client.object A client.
--- @function awful.client.focus.history.get
-function focus.history.get(s, idx, filter)
- s = get_screen(s)
- -- When this counter is equal to idx, we return the client
- local counter = 0
- local vc = client.visible(s, true)
- for _, c in ipairs(focus.history.list) do
- if get_screen(c.screen) == s then
- if not filter or filter(c) then
- for _, vcc in ipairs(vc) do
- if vcc == c then
- if counter == idx then
- return c
- end
- -- We found one, increment the counter only.
- counter = counter + 1
- break
- end
- end
- end
- end
- end
- -- Argh nobody found in history, give the first one visible if there is one
- -- that passes the filter.
- filter = filter or focus.filter
- if counter == 0 then
- for _, v in ipairs(vc) do
- if filter(v) then
- return v
- end
- end
- end
-end
-
---- Focus the previous client in history.
--- @function awful.client.focus.history.previous
-function focus.history.previous()
- local sel = capi.client.focus
- local s = sel and sel.screen or screen.focused()
- local c = focus.history.get(s, 1)
- if c then
- c:emit_signal("request::activate", "client.focus.history.previous",
- {raise=false})
- end
-end
-
---- Focus a client by the given direction.
---
--- @tparam string dir The direction, can be either
--- `"up"`, `"down"`, `"left"` or `"right"`.
--- @client[opt] c The client.
--- @tparam[opt=false] boolean stacked Use stacking order? (top to bottom)
--- @function awful.client.focus.bydirection
-function focus.bydirection(dir, c, stacked)
- local sel = c or capi.client.focus
- if sel then
- local cltbl = client.visible(sel.screen, stacked)
- local geomtbl = {}
- for i,cl in ipairs(cltbl) do
- geomtbl[i] = cl:geometry()
- end
-
- local target = grect.get_in_direction(dir, geomtbl, sel:geometry())
-
- -- If we found a client to focus, then do it.
- if target then
- cltbl[target]:emit_signal("request::activate",
- "client.focus.bydirection", {raise=false})
- end
- end
-end
-
---- Focus a client by the given direction. Moves across screens.
---
--- @param dir The direction, can be either "up", "down", "left" or "right".
--- @client[opt] c The client.
--- @tparam[opt=false] boolean stacked Use stacking order? (top to bottom)
--- @function awful.client.focus.global_bydirection
-function focus.global_bydirection(dir, c, stacked)
- local sel = c or capi.client.focus
- local scr = get_screen(sel and sel.screen or screen.focused())
-
- -- change focus inside the screen
- focus.bydirection(dir, sel)
-
- -- if focus not changed, we must change screen
- if sel == capi.client.focus then
- screen.focus_bydirection(dir, scr)
- if scr ~= get_screen(screen.focused()) then
- local cltbl = client.visible(screen.focused(), stacked)
- local geomtbl = {}
- for i,cl in ipairs(cltbl) do
- geomtbl[i] = cl:geometry()
- end
- local target = grect.get_in_direction(dir, geomtbl, scr.geometry)
-
- if target then
- cltbl[target]:emit_signal("request::activate",
- "client.focus.global_bydirection",
- {raise=false})
- end
- end
- end
-end
-
-return focus
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/client/shape.lua b/awesome/lib/awful/client/shape.lua
deleted file mode 100644
index e51d873..0000000
--- a/awesome/lib/awful/client/shape.lua
+++ /dev/null
@@ -1,93 +0,0 @@
----------------------------------------------------------------------------
---- Handle client shapes.
---
--- @author Uli Schlachter &lt;psychon@znc.in&gt;
--- @copyright 2014 Uli Schlachter
--- @submodule client
----------------------------------------------------------------------------
-
--- Grab environment we need
-local surface = require("gears.surface")
-local cairo = require("lgi").cairo
-local capi =
-{
- client = client,
-}
-
-local shape = {}
-shape.update = {}
-
---- Get one of a client's shapes and transform it to include window decorations.
--- @function awful.shape.get_transformed
--- @client c The client whose shape should be retrieved
--- @tparam string shape_name Either "bounding" or "clip"
-function shape.get_transformed(c, shape_name)
- local border = shape_name == "bounding" and c.border_width or 0
- local shape_img = surface.load_silently(c["client_shape_" .. shape_name], false)
- if not shape_img then return end
-
- -- Get information about various sizes on the client
- local geom = c:geometry()
- local _, t = c:titlebar_top()
- local _, b = c:titlebar_bottom()
- local _, l = c:titlebar_left()
- local _, r = c:titlebar_right()
-
- -- Figure out the size of the shape that we need
- local img_width = geom.width + 2*border
- local img_height = geom.height + 2*border
- local result = cairo.ImageSurface(cairo.Format.A1, img_width, img_height)
- local cr = cairo.Context(result)
-
- -- Fill everything (this paints the titlebars and border)
- cr:paint()
-
- -- Draw the client's shape in the middle
- cr:set_operator(cairo.Operator.SOURCE)
- cr:set_source_surface(shape_img, border + l, border + t)
- cr:rectangle(border + l, border + t, geom.width - l - r, geom.height - t - b)
- cr:fill()
-
- return result
-end
-
---- Update a client's bounding shape from the shape the client set itself.
--- @function awful.shape.update.bounding
--- @client c The client to act on
-function shape.update.bounding(c)
- local res = shape.get_transformed(c, "bounding")
- c.shape_bounding = res and res._native
- -- Free memory
- if res then
- res:finish()
- end
-end
-
---- Update a client's clip shape from the shape the client set itself.
--- @function awful.shape.update.clip
--- @client c The client to act on
-function shape.update.clip(c)
- local res = shape.get_transformed(c, "clip")
- c.shape_clip = res and res._native
- -- Free memory
- if res then
- res:finish()
- end
-end
-
---- Update all of a client's shapes from the shapes the client set itself.
--- @function awful.shape.update.all
--- @client c The client to act on
-function shape.update.all(c)
- shape.update.bounding(c)
- shape.update.clip(c)
-end
-
-capi.client.connect_signal("property::shape_client_bounding", shape.update.bounding)
-capi.client.connect_signal("property::shape_client_clip", shape.update.clip)
-capi.client.connect_signal("property::width", shape.update.all)
-capi.client.connect_signal("property::height", shape.update.all)
-
-return shape
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/client/urgent.lua b/awesome/lib/awful/client/urgent.lua
deleted file mode 100644
index 22f6a6d..0000000
--- a/awesome/lib/awful/client/urgent.lua
+++ /dev/null
@@ -1,88 +0,0 @@
----------------------------------------------------------------------------
---- Keep track of the urgent clients.
---
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2008 Julien Danjou
--- @submodule client
----------------------------------------------------------------------------
-
-local urgent = {}
-
-local capi =
-{
- client = client,
-}
-
-local client
-do
- client = setmetatable({}, {
- __index = function(_, k)
- client = require("awful.client")
- return client[k]
- end,
- __newindex = error -- Just to be sure in case anything ever does this
- })
-end
-
-local data = setmetatable({}, { __mode = 'k' })
-
---- Get the first client that got the urgent hint.
---
--- @function awful.urgent.get
--- @treturn client.object The first urgent client.
-function urgent.get()
- if #data > 0 then
- return data[1]
- else
- -- fallback behaviour: iterate through clients and get the first urgent
- local clients = capi.client.get()
- for _, cl in pairs(clients) do
- if cl.urgent then
- return cl
- end
- end
- end
-end
-
---- Jump to the client that received the urgent hint first.
---
--- @function awful.urgent.jumpto
--- @tparam bool|function merge If true then merge tags (select the client's
--- first tag additionally) when the client is not visible.
--- If it is a function, it will be called with the client as argument.
-function urgent.jumpto(merge)
- local c = client.urgent.get()
- if c then
- c:jump_to(merge)
- end
-end
-
---- Adds client to urgent stack.
---
--- @function awful.urgent.add
--- @client c The client object.
--- @param prop The property which is updated.
-function urgent.add(c, prop)
- if type(c) == "client" and prop == "urgent" and c.urgent then
- table.insert(data, c)
- end
-end
-
---- Remove client from urgent stack.
---
--- @function awful.urgent.delete
--- @client c The client object.
-function urgent.delete(c)
- for k, cl in ipairs(data) do
- if c == cl then
- table.remove(data, k)
- break
- end
- end
-end
-
-capi.client.connect_signal("property::urgent", urgent.add)
-capi.client.connect_signal("focus", urgent.delete)
-capi.client.connect_signal("unmanage", urgent.delete)
-
-return urgent
diff --git a/awesome/lib/awful/completion.lua b/awesome/lib/awful/completion.lua
deleted file mode 100644
index 3462ed1..0000000
--- a/awesome/lib/awful/completion.lua
+++ /dev/null
@@ -1,201 +0,0 @@
----------------------------------------------------------------------------
---- Completion module.
---
--- This module store a set of function using shell to complete commands name.
---
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @author Sébastien Gross &lt;seb-awesome@chezwam.org&gt;
--- @copyright 2008 Julien Danjou, Sébastien Gross
--- @module awful.completion
----------------------------------------------------------------------------
-
--- Grab environment we need
-local io = io
-local os = os
-local table = table
-local math = math
-local print = print
-local pairs = pairs
-local string = string
-
-local completion = {}
-
--- mapping of command/completion function
-local bashcomp_funcs = {}
-local bashcomp_src = "/etc/bash_completion"
-
---- Enable programmable bash completion in awful.completion.bash at the price of
--- a slight overhead.
--- @param src The bash completion source file, /etc/bash_completion by default.
-function completion.bashcomp_load(src)
- if src then bashcomp_src = src end
- local c, err = io.popen("/usr/bin/env bash -c 'source " .. bashcomp_src .. "; complete -p'")
- if c then
- while true do
- local line = c:read("*line")
- if not line then break end
- -- if a bash function is used for completion, register it
- if line:match(".* -F .*") then
- bashcomp_funcs[line:gsub(".* (%S+)$","%1")] = line:gsub(".*-F +(%S+) .*$", "%1")
- end
- end
- c:close()
- else
- print(err)
- end
-end
-
-local function bash_escape(str)
- str = str:gsub(" ", "\\ ")
- str = str:gsub("%[", "\\[")
- str = str:gsub("%]", "\\]")
- str = str:gsub("%(", "\\(")
- str = str:gsub("%)", "\\)")
- return str
-end
-
---- Use shell completion system to complete command and filename.
--- @param command The command line.
--- @param cur_pos The cursor position.
--- @param ncomp The element number to complete.
--- @param shell The shell to use for completion (bash (default) or zsh).
--- @return The new command, the new cursor position, the table of all matches.
-function completion.shell(command, cur_pos, ncomp, shell)
- local wstart = 1
- local wend = 1
- local words = {}
- local cword_index = 0
- local cword_start = 0
- local cword_end = 0
- local i = 1
- local comptype = "file"
-
- -- do nothing if we are on a letter, i.e. not at len + 1 or on a space
- if cur_pos ~= #command + 1 and command:sub(cur_pos, cur_pos) ~= " " then
- return command, cur_pos
- elseif #command == 0 then
- return command, cur_pos
- end
-
- while wend <= #command do
- wend = command:find(" ", wstart)
- if not wend then wend = #command + 1 end
- table.insert(words, command:sub(wstart, wend - 1))
- if cur_pos >= wstart and cur_pos <= wend + 1 then
- cword_start = wstart
- cword_end = wend
- cword_index = i
- end
- wstart = wend + 1
- i = i + 1
- end
-
- if cword_index == 1 and not string.find(words[cword_index], "/") then
- comptype = "command"
- end
-
- local shell_cmd
- if shell == "zsh" or (not shell and os.getenv("SHELL"):match("zsh$")) then
- if comptype == "file" then
- -- NOTE: ${~:-"..."} turns on GLOB_SUBST, useful for expansion of
- -- "~/" ($HOME). ${:-"foo"} is the string "foo" as var.
- shell_cmd = "/usr/bin/env zsh -c 'local -a res; res=( ${~:-"
- .. string.format('%q', words[cword_index]) .. "}* ); "
- .. "print -ln -- ${res[@]}'"
- else
- -- check commands, aliases, builtins, functions and reswords
- shell_cmd = "/usr/bin/env zsh -c 'local -a res; "..
- "res=( "..
- "\"${(k)commands[@]}\" \"${(k)aliases[@]}\" \"${(k)builtins[@]}\" \"${(k)functions[@]}\" \"${(k)reswords[@]}\" "..
- "${PWD}/*(:t)"..
- "); "..
- "print -ln -- ${(M)res[@]:#" .. string.format('%q', words[cword_index]) .. "*}'"
- end
- else
- if bashcomp_funcs[words[1]] then
- -- fairly complex command with inline bash script to get the possible completions
- shell_cmd = "/usr/bin/env bash -c 'source " .. bashcomp_src .. "; " ..
- "__print_completions() { for ((i=0;i<${#COMPREPLY[*]};i++)); do echo ${COMPREPLY[i]}; done }; " ..
- "COMP_WORDS=(" .. command .."); COMP_LINE=\"" .. command .. "\"; " ..
- "COMP_COUNT=" .. cur_pos .. "; COMP_CWORD=" .. cword_index-1 .. "; " ..
- bashcomp_funcs[words[1]] .. "; __print_completions'"
- else
- shell_cmd = "/usr/bin/env bash -c 'compgen -A " .. comptype .. " "
- .. string.format('%q', words[cword_index]) .. "'"
- end
- end
- local c, err = io.popen(shell_cmd .. " | sort -u")
- local output = {}
- if c then
- while true do
- local line = c:read("*line")
- if not line then break end
- if os.execute("test -d " .. string.format('%q', line)) == 0 then
- line = line .. "/"
- end
- table.insert(output, bash_escape(line))
- end
-
- c:close()
- else
- print(err)
- end
-
- -- no completion, return
- if #output == 0 then
- return command, cur_pos
- end
-
- -- cycle
- while ncomp > #output do
- ncomp = ncomp - #output
- end
-
- local str = command:sub(1, cword_start - 1) .. output[ncomp] .. command:sub(cword_end)
- cur_pos = cword_end + #output[ncomp] + 1
-
- return str, cur_pos, output
-end
-
---- Run a generic completion.
--- For this function to run properly the awful.completion.keyword table should
--- be fed up with all keywords. The completion is run against these keywords.
--- @param text The current text the user had typed yet.
--- @param cur_pos The current cursor position.
--- @param ncomp The number of yet requested completion using current text.
--- @param keywords The keywords table uised for completion.
--- @return The new match, the new cursor position, the table of all matches.
-function completion.generic(text, cur_pos, ncomp, keywords) -- luacheck: no unused args
- -- The keywords table may be empty
- if #keywords == 0 then
- return text, #text + 1
- end
-
- -- if no text had been typed yet, then we could start cycling around all
- -- keywords with out filtering and move the cursor at the end of keyword
- if text == nil or #text == 0 then
- ncomp = math.fmod(ncomp - 1, #keywords) + 1
- return keywords[ncomp], #keywords[ncomp] + 2
- end
-
- -- Filter out only keywords starting with text
- local matches = {}
- for _, x in pairs(keywords) do
- if x:sub(1, #text) == text then
- table.insert(matches, x)
- end
- end
-
- -- if there are no matches just leave out with the current text and position
- if #matches == 0 then
- return text, #text + 1, matches
- end
-
- -- cycle around all matches
- ncomp = math.fmod(ncomp - 1, #matches) + 1
- return matches[ncomp], #matches[ncomp] + 1, matches
-end
-
-return completion
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/dbus.lua b/awesome/lib/awful/dbus.lua
deleted file mode 100644
index 8660dce..0000000
--- a/awesome/lib/awful/dbus.lua
+++ /dev/null
@@ -1,19 +0,0 @@
----------------------------------------------------------------------------
---- D-Bus module for awful.
---
--- This module simply request the org.awesomewm.awful name on the D-Bus
--- for futur usage by other awful modules.
---
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2009 Julien Danjou
--- @module awful.dbus
----------------------------------------------------------------------------
-
--- Grab environment we need
-local dbus = dbus
-
-if dbus then
- dbus.request_name("session", "org.awesomewm.awful")
-end
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/ewmh.lua b/awesome/lib/awful/ewmh.lua
deleted file mode 100644
index eb72a16..0000000
--- a/awesome/lib/awful/ewmh.lua
+++ /dev/null
@@ -1,295 +0,0 @@
----------------------------------------------------------------------------
---- Implements EWMH requests handling.
---
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2009 Julien Danjou
--- @module awful.ewmh
----------------------------------------------------------------------------
-
-local client = client
-local screen = screen
-local ipairs = ipairs
-local util = require("awful.util")
-local aclient = require("awful.client")
-local aplace = require("awful.placement")
-local asuit = require("awful.layout.suit")
-
-local ewmh = {
- generic_activate_filters = {},
- contextual_activate_filters = {},
-}
-
---- The list of all registered generic request::activate (focus stealing)
--- filters. If a filter is added to only one context, it will be in
--- `ewmh.contextual_activate_filters`["context_name"].
--- @table[opt={}] generic_activate_filters
--- @see ewmh.activate
--- @see ewmh.add_activate_filter
--- @see ewmh.remove_activate_filter
-
---- The list of all registered contextual request::activate (focus stealing)
--- filters. If a filter is added to only one context, it will be in
--- `ewmh.generic_activate_filters`.
--- @table[opt={}] contextual_activate_filters
--- @see ewmh.activate
--- @see ewmh.add_activate_filter
--- @see ewmh.remove_activate_filter
-
---- Update a client's settings when its geometry changes, skipping signals
--- resulting from calls within.
-local geometry_change_lock = false
-local function geometry_change(window)
- if geometry_change_lock then return end
- geometry_change_lock = true
-
- -- Fix up the geometry in case this window needs to cover the whole screen.
- local bw = window.border_width or 0
- local g = window.screen.workarea
- if window.maximized_vertical then
- window:geometry { height = g.height - 2*bw, y = g.y }
- end
- if window.maximized_horizontal then
- window:geometry { width = g.width - 2*bw, x = g.x }
- end
- if window.fullscreen then
- window.border_width = 0
- window:geometry(window.screen.geometry)
- end
-
- geometry_change_lock = false
-end
-
---- Activate a window.
---
--- This sets the focus only if the client is visible.
---
--- It is the default signal handler for `request::activate` on a `client`.
---
--- @signalhandler awful.ewmh.activate
--- @client c A client to use
--- @tparam string context The context where this signal was used.
--- @tparam[opt] table hints A table with additional hints:
--- @tparam[opt=false] boolean hints.raise should the client be raised?
-function ewmh.activate(c, context, hints) -- luacheck: no unused args
- hints = hints or {}
-
- if c.focusable == false and not hints.force then return end
-
- local found, ret = false
-
- -- Execute the filters until something handle the request
- for _, tab in ipairs {
- ewmh.contextual_activate_filters[context] or {},
- ewmh.generic_activate_filters
- } do
- for i=#tab, 1, -1 do
- ret = tab[i](c, context, hints)
- if ret ~= nil then found=true; break end
- end
-
- if found then break end
- end
-
- if ret ~= false and c:isvisible() then
- client.focus = c
- elseif ret == false and not hints.force then
- return
- end
-
- if hints and hints.raise then
- c:raise()
- if not awesome.startup and not c:isvisible() then
- c.urgent = true
- end
- end
-end
-
---- Add an activate (focus stealing) filter function.
---
--- The callback takes the following parameters:
---
--- * **c** (*client*) The client requesting the activation
--- * **context** (*string*) The activation context.
--- * **hints** (*table*) Some additional hints (depending on the context)
---
--- If the callback returns `true`, the client will be activated unless the `force`
--- hint is set. If the callback returns `false`, the activation request is
--- cancelled. If the callback returns `nil`, the previous callback will be
--- executed. This will continue until either a callback handles the request or
--- when it runs out of callbacks. In that case, the request will be granted if
--- the client is visible.
---
--- For example, to block Firefox from stealing the focus, use:
---
--- awful.ewmh.add_activate_filter(function(c, "ewmh")
--- if c.class == "Firefox" then return false end
--- end)
---
--- @tparam function f The callback
--- @tparam[opt] string context The `request::activate` context
--- @see generic_activate_filters
--- @see contextual_activate_filters
--- @see remove_activate_filter
-function ewmh.add_activate_filter(f, context)
- if not context then
- table.insert(ewmh.generic_activate_filters, f)
- else
- ewmh.contextual_activate_filters[context] =
- ewmh.contextual_activate_filters[context] or {}
-
- table.insert(ewmh.contextual_activate_filters[context], f)
- end
-end
-
---- Remove an activate (focus stealing) filter function.
--- This is an helper to avoid dealing with `ewmh.add_activate_filter` directly.
--- @tparam function f The callback
--- @tparam[opt] string context The `request::activate` context
--- @treturn boolean If the callback existed
--- @see generic_activate_filters
--- @see contextual_activate_filters
--- @see add_activate_filter
-function ewmh.remove_activate_filter(f, context)
- local tab = context and (ewmh.contextual_activate_filters[context] or {})
- or ewmh.generic_activate_filters
-
- for k, v in ipairs(tab) do
- if v == f then
- table.remove(tab, k)
-
- -- In case the callback is there multiple time.
- ewmh.remove_activate_filter(f, context)
-
- return true
- end
- end
-
- return false
-end
-
--- Get tags that are on the same screen as the client. This should _almost_
--- always return the same content as c:tags().
-local function get_valid_tags(c, s)
- local tags, new_tags = c:tags(), {}
-
- for _, t in ipairs(tags) do
- if s == t.screen then
- table.insert(new_tags, t)
- end
- end
-
- return new_tags
-end
-
---- Tag a window with its requested tag.
---
--- It is the default signal handler for `request::tag` on a `client`.
---
--- @signalhandler awful.ewmh.tag
--- @client c A client to tag
--- @tparam[opt] tag|boolean t A tag to use. If true, then the client is made sticky.
--- @tparam[opt={}] table hints Extra information
-function ewmh.tag(c, t, hints) --luacheck: no unused
- -- There is nothing to do
- if not t and #get_valid_tags(c, c.screen) > 0 then return end
-
- if not t then
- if c.transient_for then
- c.screen = c.transient_for.screen
- if not c.sticky then
- c:tags(c.transient_for:tags())
- end
- else
- c:to_selected_tags()
- end
- elseif type(t) == "boolean" and t then
- c.sticky = true
- else
- c.screen = t.screen
- c:tags({ t })
- end
-end
-
---- Handle client urgent request
--- @signalhandler awful.ewmh.urgent
--- @client c A client
--- @tparam boolean urgent If the client should be urgent
-function ewmh.urgent(c, urgent)
- if c ~= client.focus and not aclient.property.get(c,"ignore_urgent") then
- c.urgent = urgent
- end
-end
-
--- Map the state to the action name
-local context_mapper = {
- maximized_vertical = "maximize_vertically",
- maximized_horizontal = "maximize_horizontally",
- fullscreen = "maximize"
-}
-
---- Move and resize the client.
---
--- This is the default geometry request handler.
---
--- @signalhandler awful.ewmh.geometry
--- @tparam client c The client
--- @tparam string context The context
--- @tparam[opt={}] table hints The hints to pass to the handler
-function ewmh.geometry(c, context, hints)
- local layout = c.screen.selected_tag and c.screen.selected_tag.layout or nil
-
- -- Setting the geometry wont work unless the client is floating.
- if (not c.floating) and (not layout == asuit.floating) then
- return
- end
-
- context = context or ""
-
- local original_context = context
-
- -- Now, map it to something useful
- context = context_mapper[context] or context
-
- local props = util.table.clone(hints or {}, false)
- props.store_geometry = props.store_geometry==nil and true or props.store_geometry
-
- -- If it is a known placement function, then apply it, otherwise let
- -- other potential handler resize the client (like in-layout resize or
- -- floating client resize)
- if aplace[context] then
-
- -- Check if it correspond to a boolean property
- local state = c[original_context]
-
- -- If the property is boolean and it correspond to the undo operation,
- -- restore the stored geometry.
- if state == false then
- aplace.restore(c,{context=context})
- return
- end
-
- local honor_default = original_context ~= "fullscreen"
-
- if props.honor_workarea == nil then
- props.honor_workarea = honor_default
- end
-
- aplace[context](c, props)
- end
-end
-
-client.connect_signal("request::activate", ewmh.activate)
-client.connect_signal("request::tag", ewmh.tag)
-client.connect_signal("request::urgent", ewmh.urgent)
-client.connect_signal("request::geometry", ewmh.geometry)
-client.connect_signal("property::border_width", geometry_change)
-client.connect_signal("property::geometry", geometry_change)
-screen.connect_signal("property::workarea", function(s)
- for _, c in pairs(client.get(s)) do
- geometry_change(c)
- end
-end)
-
-return ewmh
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/hotkeys_popup/init.lua b/awesome/lib/awful/hotkeys_popup/init.lua
deleted file mode 100644
index cb8c8be..0000000
--- a/awesome/lib/awful/hotkeys_popup/init.lua
+++ /dev/null
@@ -1,17 +0,0 @@
----------------------------------------------------------------------------
---- Popup widget which shows current hotkeys and their descriptions.
---
--- @author Yauheni Kirylau &lt;yawghen@gmail.com&gt;
--- @copyright 2014-2015 Yauheni Kirylau
--- @module awful.hotkeys_popup
----------------------------------------------------------------------------
-
-
-local hotkeys_popup = {
- widget = require("awful.hotkeys_popup.widget"),
- keys = require("awful.hotkeys_popup.keys")
-}
-hotkeys_popup.show_help = hotkeys_popup.widget.show_help
-return hotkeys_popup
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/hotkeys_popup/keys/init.lua b/awesome/lib/awful/hotkeys_popup/keys/init.lua
deleted file mode 100644
index cbcbb62..0000000
--- a/awesome/lib/awful/hotkeys_popup/keys/init.lua
+++ /dev/null
@@ -1,15 +0,0 @@
----------------------------------------------------------------------------
---- Additional hotkeys for awful.hotkeys_widget
---
--- @author Yauheni Kirylau &lt;yawghen@gmail.com&gt;
--- @copyright 2014-2015 Yauheni Kirylau
--- @module awful.hotkeys_popup.keys
----------------------------------------------------------------------------
-
-
-local keys = {
- vim = require("awful.hotkeys_popup.keys.vim")
-}
-return keys
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/hotkeys_popup/keys/vim.lua b/awesome/lib/awful/hotkeys_popup/keys/vim.lua
deleted file mode 100644
index 69d21e9..0000000
--- a/awesome/lib/awful/hotkeys_popup/keys/vim.lua
+++ /dev/null
@@ -1,173 +0,0 @@
----------------------------------------------------------------------------
---- VIM hotkeys for awful.hotkeys_widget
---
--- @author Yauheni Kirylau &lt;yawghen@gmail.com&gt;
--- @copyright 2014-2015 Yauheni Kirylau
--- @module awful.hotkeys_popup.keys.vim
----------------------------------------------------------------------------
-
-local hotkeys_popup = require("awful.hotkeys_popup.widget")
-
-local vim_rule_any = {name={"vim", "VIM"}}
-for group_name, group_data in pairs({
- ["VIM: motion"] = { color="#009F00", rule_any=vim_rule_any },
- ["VIM: command"] = { color="#aFaF00", rule_any=vim_rule_any },
- ["VIM: command (insert)"] = { color="#cF4F40", rule_any=vim_rule_any },
- ["VIM: operator"] = { color="#aF6F00", rule_any=vim_rule_any },
- ["VIM: find"] = { color="#65cF9F", rule_any=vim_rule_any },
- ["VIM: scroll"] = { color="#659FdF", rule_any=vim_rule_any },
-}) do
- hotkeys_popup.group_rules[group_name] = group_data
-end
-
-
-local vim_keys = {
-
- ["VIM: motion"] = {{
- modifiers = {},
- keys = {
- ['`']="goto mark",
- ['0']='"hard" BOL',
- ['-']="prev line",
- w="next word",
- e="end word",
- ['[']=". misc",
- [']']=". misc",
- ["'"]=". goto mk. BOL",
- b="prev word",
- ["|"]='BOL/goto col',
- ["$"]='EOL',
- ["%"]='goto matching bracket',
- ["^"]='"soft" BOL',
- ["("]='sentence begin',
- [")"]='sentence end',
- ["_"]='"soft" BOL down',
- ["+"]='next line',
- W='next WORD',
- E='end WORD',
- ['{']="paragraph begin",
- ['}']="paragraph end",
- G='EOF/goto line',
- H='move cursor to screen top',
- M='move cursor to screen middle',
- L='move cursor to screen bottom',
- B='prev WORD',
- }
- }, {
- modifiers = {"Ctrl"},
- keys = {
- u="half page up",
- d="half page down",
- b="page up",
- f="page down",
- o="prev mark",
- }
- }},
-
- ["VIM: operator"] = {{
- modifiers = {},
- keys = {
- ['=']="auto format",
- y="yank",
- d="delete",
- c="change",
- ["!"]='external filter',
- ['&lt;']='unindent',
- ['&gt;']='indent',
- }
- }},
-
- ["VIM: command"] = {{
- modifiers = {},
- keys = {
- ['~']="toggle case",
- q=". record macro",
- r=". replace char",
- u="undo",
- p="paste after",
- gg="go to the top of file",
- gf="open file under cursor",
- x="delete char",
- v="visual mode",
- m=". set mark",
- ['.']="repeat command",
- ["@"]='. play macro',
- ["&amp;"]='repeat :s',
- Q='ex mode',
- Y='yank line',
- U='undo line',
- P='paste before cursor',
- D='delete to EOL',
- J='join lines',
- K='help',
- [':']='ex cmd line',
- ['"']='. register spec',
- ZZ='quit and save',
- ZQ='quit discarding changes',
- X='back-delete',
- V='visual lines selection',
- }
- }, {
- modifiers = {"Ctrl"},
- keys = {
- w=". window operations",
- r="redo",
- ["["]="normal mode",
- a="increase number",
- x="decrease number",
- g="file/cursor info",
- z="suspend",
- c="cancel/normal mode",
- v="visual block selection",
- }
- }},
-
- ["VIM: command (insert)"] = {{
- modifiers = {},
- keys = {
- i="insert mode",
- o="open below",
- a="append",
- s="subst char",
- R='replace mode',
- I='insert at BOL',
- O='open above',
- A='append at EOL',
- S='subst line',
- C='change to EOL',
- }
- }},
-
- ["VIM: find"] = {{
- modifiers = {},
- keys = {
- [';']="repeat t/T/f/F",
- [',']="reverse t/T/f/F",
- ['/']=". find",
- ['?']='. reverse find',
- n="next search match",
- N='prev search match',
- f=". find char",
- F='. reverse find char',
- t=". 'till char",
- T=". reverse 'till char",
- ["*"]='find word under cursor',
- ["#"]='reverse find under cursor',
- }
- }},
-
- ["VIM: scroll"] = {{
- modifiers = {},
- keys = {
- e="scroll line up",
- y="scroll line down",
- zt="scroll cursor to the top",
- zz="scroll cursor to the center",
- zb="scroll cursor to the bottom",
- }
- }},
-}
-
-hotkeys_popup.add_hotkeys(vim_keys)
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/hotkeys_popup/widget.lua b/awesome/lib/awful/hotkeys_popup/widget.lua
deleted file mode 100644
index 62a2231..0000000
--- a/awesome/lib/awful/hotkeys_popup/widget.lua
+++ /dev/null
@@ -1,482 +0,0 @@
----------------------------------------------------------------------------
---- Popup widget which shows current hotkeys and their descriptions.
---
--- @author Yauheni Kirylau &lt;yawghen@gmail.com&gt;
--- @copyright 2014-2015 Yauheni Kirylau
--- @module awful.hotkeys_popup.widget
----------------------------------------------------------------------------
-
-local capi = {
- screen = screen,
- client = client,
- keygrabber = keygrabber,
-}
-local awful = require("awful")
-local wibox = require("wibox")
-local beautiful = require("beautiful")
-local dpi = beautiful.xresources.apply_dpi
-local compute_textbox_width = require("menubar").utils.compute_textbox_width
-
-
--- Stripped copy of this module https://github.com/copycat-killer/lain/blob/master/util/markup.lua:
-local markup = {}
--- Set the font.
-function markup.font(font, text)
- return '<span font="' .. tostring(font) .. '">' .. tostring(text) ..'</span>'
-end
--- Set the foreground.
-function markup.fg(color, text)
- return '<span foreground="' .. tostring(color) .. '">' .. tostring(text) .. '</span>'
-end
--- Set the background.
-function markup.bg(color, text)
- return '<span background="' .. tostring(color) .. '">' .. tostring(text) .. '</span>'
-end
-
-local widget_module = {
- group_rules = {},
-}
-
---- Don't show hotkeys without descriptions.
-widget_module.hide_without_description = true
-
---- Merge hotkey records into one if they have the same modifiers and
--- description.
-widget_module.merge_duplicates = true
-
-
-function widget_module.new()
-local widget = {
- hide_without_description = widget_module.hide_without_description,
- merge_duplicates = widget_module.merge_duplicates,
- group_rules = awful.util.table.clone(widget_module.group_rules),
- title_font = "Monospace Bold 9",
- description_font = "Monospace 8",
- width = dpi(1200),
- height = dpi(800),
- border_width = beautiful.border_width or dpi(2),
- modifiers_color = beautiful.bg_minimize or "#555555",
- group_margin = dpi(6),
- additional_hotkeys = {},
- labels = {
- Mod4="Super",
- Mod1="Alt",
- Escape="Esc",
- Insert="Ins",
- Delete="Del",
- Backspace="BackSpc",
- Return="Enter",
- Next="PgDn",
- Prior="PgUp",
- ['#108']="Alt Gr",
- Left='←',
- Up='↑',
- Right='→',
- Down='↓',
- ['#67']="F1",
- ['#68']="F2",
- ['#69']="F3",
- ['#70']="F4",
- ['#71']="F5",
- ['#72']="F6",
- ['#73']="F7",
- ['#74']="F8",
- ['#75']="F9",
- ['#76']="F10",
- ['#95']="F11",
- ['#96']="F12",
- ['#10']="1",
- ['#11']="2",
- ['#12']="3",
- ['#13']="4",
- ['#14']="5",
- ['#15']="6",
- ['#16']="7",
- ['#17']="8",
- ['#18']="9",
- ['#19']="0",
- ['#20']="-",
- ['#21']="=",
- Control="Ctrl"
- },
-}
-
-local cached_wiboxes = {}
-local cached_awful_keys = nil
-local colors_counter = {}
-local colors = beautiful.xresources.get_current_theme()
-local group_list = {}
-
-
-local function get_next_color(id)
- id = id or "default"
- if colors_counter[id] then
- colors_counter[id] = math.fmod(colors_counter[id] + 1, 15) + 1
- else
- colors_counter[id] = 1
- end
- return colors["color"..tostring(colors_counter[id], 15)]
-end
-
-
-local function join_plus_sort(modifiers)
- if #modifiers<1 then return "none" end
- table.sort(modifiers)
- return table.concat(modifiers, '+')
-end
-
-
-local function add_hotkey(key, data, target)
- if widget.hide_without_description and not data.description then return end
-
- local readable_mods = {}
- for _, mod in ipairs(data.mod) do
- table.insert(readable_mods, widget.labels[mod] or mod)
- end
- local joined_mods = join_plus_sort(readable_mods)
-
- local group = data.group or "none"
- group_list[group] = true
- if not target[group] then target[group] = {} end
- local new_key = {
- key = (widget.labels[key] or key),
- mod = joined_mods,
- description = data.description
- }
- local index = data.description or "none" -- or use its hash?
- if not target[group][index] then
- target[group][index] = new_key
- else
- if widget.merge_duplicates and joined_mods == target[group][index].mod then
- target[group][index].key = target[group][index].key .. "/" .. new_key.key
- else
- while target[group][index] do
- index = index .. " "
- end
- target[group][index] = new_key
- end
- end
-end
-
-
-local function sort_hotkeys(target)
- -- @TODO: add sort by 12345qwertyasdf etc
- for group, _ in pairs(group_list) do
- if target[group] then
- local sorted_table = {}
- for _, key in pairs(target[group]) do
- table.insert(sorted_table, key)
- end
- table.sort(
- sorted_table,
- function(a,b) return (a.mod or '')..a.key<(b.mod or '')..b.key end
- )
- target[group] = sorted_table
- end
- end
-end
-
-
-local function import_awful_keys()
- if cached_awful_keys then
- return
- end
- cached_awful_keys = {}
- for _, data in pairs(awful.key.hotkeys) do
- add_hotkey(data.key, data, cached_awful_keys)
- end
- sort_hotkeys(cached_awful_keys)
-end
-
-
-local function group_label(group, color)
- local textbox = wibox.widget.textbox(
- markup.font(widget.title_font,
- markup.bg(
- color or (widget.group_rules[group] and
- widget.group_rules[group].color or get_next_color("group_title")
- ),
- markup.fg(beautiful.bg_normal or "#000000", " "..group.." ")
- )
- )
- )
- local margin = wibox.container.margin()
- margin:set_widget(textbox)
- margin:set_top(widget.group_margin)
- return margin
-end
-
-local function get_screen(s)
- return s and capi.screen[s]
-end
-
-local function create_wibox(s, available_groups)
- s = get_screen(s)
-
- local wa = s.workarea
- local height = (widget.height < wa.height) and widget.height or
- (wa.height - widget.border_width * 2)
- local width = (widget.width < wa.width) and widget.width or
- (wa.width - widget.border_width * 2)
-
- -- arrange hotkey groups into columns
- local line_height = beautiful.get_font_height(widget.title_font)
- local group_label_height = line_height + widget.group_margin
- -- -1 for possible pagination:
- local max_height_px = height - group_label_height
- local column_layouts = {}
- for _, group in ipairs(available_groups) do
- local keys = cached_awful_keys[group] or widget.additional_hotkeys[group]
- local joined_descriptions = ""
- for i, key in ipairs(keys) do
- joined_descriptions = joined_descriptions .. key.description .. (i~=#keys and "\n" or "")
- end
- -- +1 for group label:
- local items_height = awful.util.linecount(joined_descriptions) * line_height + group_label_height
- local current_column
- local available_height_px = max_height_px
- local add_new_column = true
- for i, column in ipairs(column_layouts) do
- if ((column.height_px + items_height) < max_height_px) or
- (i == #column_layouts and column.height_px < max_height_px / 2)
- then
- current_column = column
- add_new_column = false
- available_height_px = max_height_px - current_column.height_px
- break
- end
- end
- local overlap_leftovers
- if items_height > available_height_px then
- local new_keys = {}
- overlap_leftovers = {}
- -- +1 for group title and +1 for possible hyphen (v):
- local available_height_items = (available_height_px - group_label_height*2) / line_height
- for i=1,#keys do
- table.insert(((i<available_height_items) and new_keys or overlap_leftovers), keys[i])
- end
- keys = new_keys
- table.insert(keys, {key=markup.fg(widget.modifiers_color, "▽"), description=""})
- end
- if not current_column then
- current_column = {layout=wibox.layout.fixed.vertical()}
- end
- current_column.layout:add(group_label(group))
-
- local function insert_keys(_keys, _add_new_column)
- local max_label_width = 0
- local max_label_content = ""
- local joined_labels = ""
- for i, key in ipairs(_keys) do
- local length = string.len(key.key or '') + string.len(key.description or '')
- local modifiers = key.mod
- if not modifiers or modifiers == "none" then
- modifiers = ""
- else
- length = length + string.len(modifiers) + 1 -- +1 for "+" character
- modifiers = markup.fg(widget.modifiers_color, modifiers.."+")
- end
- local rendered_hotkey = markup.font(widget.title_font,
- modifiers .. (key.key or "") .. " "
- ) .. markup.font(widget.description_font,
- key.description or ""
- )
- if length > max_label_width then
- max_label_width = length
- max_label_content = rendered_hotkey
- end
- joined_labels = joined_labels .. rendered_hotkey .. (i~=#_keys and "\n" or "")
- end
- current_column.layout:add(wibox.widget.textbox(joined_labels))
- local max_width = compute_textbox_width(wibox.widget.textbox(max_label_content), s) +
- widget.group_margin
- if not current_column.max_width or max_width > current_column.max_width then
- current_column.max_width = max_width
- end
- -- +1 for group label:
- current_column.height_px = (current_column.height_px or 0) +
- awful.util.linecount(joined_labels)*line_height + group_label_height
- if _add_new_column then
- table.insert(column_layouts, current_column)
- end
- end
-
- insert_keys(keys, add_new_column)
- if overlap_leftovers then
- current_column = {layout=wibox.layout.fixed.vertical()}
- insert_keys(overlap_leftovers, true)
- end
- end
-
- -- arrange columns into pages
- local available_width_px = width
- local pages = {}
- local columns = wibox.layout.fixed.horizontal()
- for _, item in ipairs(column_layouts) do
- if item.max_width > available_width_px then
- columns.widgets[#columns.widgets]['widget']:add(
- group_label("PgDn - Next Page", beautiful.fg_normal)
- )
- table.insert(pages, columns)
- columns = wibox.layout.fixed.horizontal()
- available_width_px = width - item.max_width
- local old_widgets = item.layout.widgets
- item.layout.widgets = {group_label("PgUp - Prev Page", beautiful.fg_normal)}
- awful.util.table.merge(item.layout.widgets, old_widgets)
- else
- available_width_px = available_width_px - item.max_width
- end
- local column_margin = wibox.container.margin()
- column_margin:set_widget(item.layout)
- column_margin:set_left(widget.group_margin)
- columns:add(column_margin)
- end
- table.insert(pages, columns)
-
- local mywibox = wibox({
- ontop = true,
- opacity = beautiful.notification_opacity or 1,
- border_width = widget.border_width,
- border_color = beautiful.fg_normal,
- })
- mywibox:geometry({
- x = wa.x + math.floor((wa.width - width - widget.border_width*2) / 2),
- y = wa.y + math.floor((wa.height - height - widget.border_width*2) / 2),
- width = width,
- height = height,
- })
- mywibox:set_widget(pages[1])
- mywibox:buttons(awful.util.table.join(
- awful.button({ }, 1, function () mywibox.visible=false end),
- awful.button({ }, 3, function () mywibox.visible=false end)
- ))
-
- local widget_obj = {}
- widget_obj.current_page = 1
- widget_obj.wibox = mywibox
- function widget_obj:page_next()
- if self.current_page == #pages then return end
- self.current_page = self.current_page + 1
- self.wibox:set_widget(pages[self.current_page])
- end
- function widget_obj:page_prev()
- if self.current_page == 1 then return end
- self.current_page = self.current_page - 1
- self.wibox:set_widget(pages[self.current_page])
- end
- function widget_obj:show()
- self.wibox.visible = true
- end
- function widget_obj:hide()
- self.wibox.visible = false
- end
-
- return widget_obj
-end
-
-
---- Show popup with hotkeys help.
--- @tparam[opt] client c Client.
--- @tparam[opt] screen s Screen.
-function widget.show_help(c, s)
- import_awful_keys()
- c = c or capi.client.focus
- s = s or (c and c.screen or awful.screen.focused())
-
- local available_groups = {}
- for group, _ in pairs(group_list) do
- local need_match
- for group_name, data in pairs(widget.group_rules) do
- if group_name==group and (
- data.rule or data.rule_any or data.except or data.except_any
- ) then
- if not c or not awful.rules.matches(c, {
- rule=data.rule,
- rule_any=data.rule_any,
- except=data.except,
- except_any=data.except_any
- }) then
- need_match = true
- break
- end
- end
- end
- if not need_match then table.insert(available_groups, group) end
- end
-
- local joined_groups = join_plus_sort(available_groups)
- if not cached_wiboxes[s] then
- cached_wiboxes[s] = {}
- end
- if not cached_wiboxes[s][joined_groups] then
- cached_wiboxes[s][joined_groups] = create_wibox(s, available_groups)
- end
- local help_wibox = cached_wiboxes[s][joined_groups]
- help_wibox:show()
-
- return capi.keygrabber.run(function(_, key, event)
- if event == "release" then return end
- if key then
- if key == "Next" then
- help_wibox:page_next()
- elseif key == "Prior" then
- help_wibox:page_prev()
- else
- capi.keygrabber.stop()
- help_wibox:hide()
- end
- end
- end)
-end
-
-
---- Add hotkey descriptions for third-party applications.
--- @tparam table hotkeys Table with bindings,
--- see `awful.hotkeys_popup.key.vim` as an example.
-function widget.add_hotkeys(hotkeys)
- for group, bindings in pairs(hotkeys) do
- for _, binding in ipairs(bindings) do
- local modifiers = binding.modifiers
- local keys = binding.keys
- for key, description in pairs(keys) do
- add_hotkey(key, {
- mod=modifiers,
- description=description,
- group=group},
- widget.additional_hotkeys
- )
- end
- end
- end
- sort_hotkeys(widget.additional_hotkeys)
-end
-
-
-return widget
-end
-
-local function get_default_widget()
- if not widget_module.default_widget then
- widget_module.default_widget = widget_module.new()
- end
- return widget_module.default_widget
-end
-
---- Show popup with hotkeys help (default widget instance will be used).
--- @tparam[opt] client c Client.
--- @tparam[opt] screen s Screen.
-function widget_module.show_help(...)
- return get_default_widget().show_help(...)
-end
-
---- Add hotkey descriptions for third-party applications
--- (default widget instance will be used).
--- @tparam table hotkeys Table with bindings,
--- see `awful.hotkeys_popup.key.vim` as an example.
-function widget_module.add_hotkeys(...)
- return get_default_widget().add_hotkeys(...)
-end
-
-return widget_module
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/init.lua b/awesome/lib/awful/init.lua
deleted file mode 100644
index 840897e..0000000
--- a/awesome/lib/awful/init.lua
+++ /dev/null
@@ -1,64 +0,0 @@
----------------------------------------------------------------------------
---- AWesome Functions very UsefuL
---
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2008 Julien Danjou
--- @module awful
----------------------------------------------------------------------------
-
--- TODO: This is a hack for backwards-compatibility with 3.5, remove!
-local util = require("awful.util")
-local gtimer = require("gears.timer")
-function timer(...) -- luacheck: ignore
- util.deprecate("gears.timer")
- return gtimer(...)
-end
-
---TODO: This is a hack for backwards-compatibility with 3.5, remove!
--- Set awful.util.spawn* and awful.util.pread.
-local spawn = require("awful.spawn")
-
-util.spawn = function(...)
- util.deprecate("awful.spawn")
- return spawn.spawn(...)
-end
-
-util.spawn_with_shell = function(...)
- util.deprecate("awful.spawn.with_shell")
- return spawn.with_shell(...)
-end
-
-util.pread = function()
- util.deprecate("Use io.popen() directly or look at awful.spawn.easy_async() "
- .. "for an asynchronous alternative")
- return ""
-end
-
-return
-{
- client = require("awful.client");
- completion = require("awful.completion");
- layout = require("awful.layout");
- placement = require("awful.placement");
- prompt = require("awful.prompt");
- screen = require("awful.screen");
- tag = require("awful.tag");
- util = require("awful.util");
- widget = require("awful.widget");
- keygrabber = require("awful.keygrabber");
- menu = require("awful.menu");
- mouse = require("awful.mouse");
- remote = require("awful.remote");
- key = require("awful.key");
- button = require("awful.button");
- wibar = require("awful.wibar");
- wibox = require("awful.wibox");
- startup_notification = require("awful.startup_notification");
- tooltip = require("awful.tooltip");
- ewmh = require("awful.ewmh");
- titlebar = require("awful.titlebar");
- rules = require("awful.rules");
- spawn = spawn;
-}
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/key.lua b/awesome/lib/awful/key.lua
deleted file mode 100644
index c3ce359..0000000
--- a/awesome/lib/awful/key.lua
+++ /dev/null
@@ -1,136 +0,0 @@
----------------------------------------------------------------------------
---- Create easily new key objects ignoring certain modifiers.
---
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2009 Julien Danjou
--- @module awful.key
----------------------------------------------------------------------------
-
--- Grab environment we need
-local setmetatable = setmetatable
-local ipairs = ipairs
-local capi = { key = key, root = root }
-local util = require("awful.util")
-
-
-
-local key = { mt = {}, hotkeys = {} }
-
-
---- Modifiers to ignore.
--- By default this is initialized as { "Lock", "Mod2" }
--- so the Caps Lock or Num Lock modifier are not taking into account by awesome
--- when pressing keys.
--- @name awful.key.ignore_modifiers
--- @class table
-key.ignore_modifiers = { "Lock", "Mod2" }
-
---- Convert the modifiers into pc105 key names
-local conversion = {
- mod4 = "Super_L",
- control = "Control_L",
- shift = "Shift_L",
- mod1 = "Alt_L",
-}
-
---- Execute a key combination.
--- If an awesome keybinding is assigned to the combination, it should be
--- executed.
--- @see root.fake_input
--- @tparam table mod A modified table. Valid modifiers are: Any, Mod1,
--- Mod2, Mod3, Mod4, Mod5, Shift, Lock and Control.
--- @tparam string k The key
-function key.execute(mod, k)
- for _, v in ipairs(mod) do
- local m = conversion[v:lower()]
- if m then
- root.fake_input("key_press", m)
- end
- end
-
- root.fake_input("key_press" , k)
- root.fake_input("key_release", k)
-
- for _, v in ipairs(mod) do
- local m = conversion[v:lower()]
- if m then
- root.fake_input("key_release", m)
- end
- end
-end
-
---- Create a new key to use as binding.
--- This function is useful to create several keys from one, because it will use
--- the ignore_modifier variable to create several keys with and without the
--- ignored modifiers activated.
--- For example if you want to ignore CapsLock in your keybinding (which is
--- ignored by default by this function), creating a key binding with this
--- function will return 2 key objects: one with CapsLock on, and another one
--- with CapsLock off.
--- @see key.key
--- @tparam table mod A list of modifier keys. Valid modifiers are: Any, Mod1,
--- Mod2, Mod3, Mod4, Mod5, Shift, Lock and Control.
--- @tparam string _key The key to trigger an event.
--- @tparam function press Callback for when the key is pressed.
--- @tparam[opt] function release Callback for when the key is released.
--- @tparam table data User data for key,
--- for example {description="select next tag", group="tag"}.
--- @treturn table A table with one or several key objects.
-function key.new(mod, _key, press, release, data)
- if type(release)=='table' then
- data=release
- release=nil
- end
- local ret = {}
- local subsets = util.subsets(key.ignore_modifiers)
- for _, set in ipairs(subsets) do
- ret[#ret + 1] = capi.key({ modifiers = util.table.join(mod, set),
- key = _key })
- if press then
- ret[#ret]:connect_signal("press", function(_, ...) press(...) end)
- end
- if release then
- ret[#ret]:connect_signal("release", function(_, ...) release(...) end)
- end
- end
-
- -- append custom userdata (like description) to a hotkey
- data = data or {}
- data.mod = mod
- data.key = _key
- table.insert(key.hotkeys, data)
- data.execute = function(_) key.execute(mod, _key) end
-
- return ret
-end
-
---- Compare a key object with modifiers and key.
--- @param _key The key object.
--- @param pressed_mod The modifiers to compare with.
--- @param pressed_key The key to compare with.
-function key.match(_key, pressed_mod, pressed_key)
- -- First, compare key.
- if pressed_key ~= _key.key then return false end
- -- Then, compare mod
- local mod = _key.modifiers
- -- For each modifier of the key object, check that the modifier has been
- -- pressed.
- for _, m in ipairs(mod) do
- -- Has it been pressed?
- if not util.table.hasitem(pressed_mod, m) then
- -- No, so this is failure!
- return false
- end
- end
- -- If the number of pressed modifier is ~=, it is probably >, so this is not
- -- the same, return false.
- return #pressed_mod == #mod
-end
-
-function key.mt:__call(...)
- return key.new(...)
-end
-
-return setmetatable(key, key.mt)
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/keygrabber.lua b/awesome/lib/awful/keygrabber.lua
deleted file mode 100644
index 4351f5b..0000000
--- a/awesome/lib/awful/keygrabber.lua
+++ /dev/null
@@ -1,96 +0,0 @@
----------------------------------------------------------------------------
---- Keygrabber Stack
---
--- @author dodo
--- @copyright 2012 dodo
--- @module awful.keygrabber
----------------------------------------------------------------------------
-
-local ipairs = ipairs
-local table = table
-local capi = {
- keygrabber = keygrabber }
-
-local keygrabber = {}
-
--- Private data
-local grabbers = {}
-local keygrabbing = false
-
-
-local function grabber(mod, key, event)
- for _, keygrabber_function in ipairs(grabbers) do
- -- continue if the grabber explicitly returns false
- if keygrabber_function(mod, key, event) ~= false then
- break
- end
- end
-end
-
---- Stop grabbing the keyboard for the provided callback.
--- When no callback is given, the last grabber gets removed (last one added to
--- the stack).
--- @param g The key grabber that must be removed.
-function keygrabber.stop(g)
- for i, v in ipairs(grabbers) do
- if v == g then
- table.remove(grabbers, i)
- break
- end
- end
- -- Stop the global key grabber if the last grabber disappears from stack.
- if #grabbers == 0 then
- keygrabbing = false
- capi.keygrabber.stop()
- end
-end
-
----
--- Grab keyboard input and read pressed keys, calling the least callback
--- function from the stack at each keypress, until the stack is empty.
---
--- Calling run with the same callback again will bring the callback
--- to the top of the stack.
---
--- The callback function receives three arguments:
---
--- * a table containing modifiers keys
--- * a string with the pressed key
--- * a string with either "press" or "release" to indicate the event type
---
--- A callback can return `false` to pass the events to the next
--- keygrabber in the stack.
--- @param g The key grabber callback that will get the key events until it will be deleted or a new grabber is added.
--- @return the given callback `g`.
--- @usage
--- -- The following function can be bound to a key, and be used to resize a
--- -- client using the keyboard.
---
--- function resize(c)
--- local grabber = awful.keygrabber.run(function(mod, key, event)
--- if event == "release" then return end
---
--- if key == 'Up' then awful.client.moveresize(0, 0, 0, 5, c)
--- elseif key == 'Down' then awful.client.moveresize(0, 0, 0, -5, c)
--- elseif key == 'Right' then awful.client.moveresize(0, 0, 5, 0, c)
--- elseif key == 'Left' then awful.client.moveresize(0, 0, -5, 0, c)
--- else awful.keygrabber.stop(grabber)
--- end
--- end)
--- end
-function keygrabber.run(g)
- -- Remove the grabber if it is in the stack.
- keygrabber.stop(g)
- -- Record the grabber that has been added most recently.
- table.insert(grabbers, 1, g)
- -- Start the keygrabber if it is not running already.
- if not keygrabbing then
- keygrabbing = true
- capi.keygrabber.run(grabber)
- end
- return g
-end
-
-return keygrabber
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/layout/init.lua b/awesome/lib/awful/layout/init.lua
deleted file mode 100644
index dfce562..0000000
--- a/awesome/lib/awful/layout/init.lua
+++ /dev/null
@@ -1,323 +0,0 @@
----------------------------------------------------------------------------
---- Layout module for awful
---
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2008 Julien Danjou
--- @module awful.layout
----------------------------------------------------------------------------
-
--- Grab environment we need
-local ipairs = ipairs
-local type = type
-local util = require("awful.util")
-local capi = {
- screen = screen,
- mouse = mouse,
- awesome = awesome,
- client = client,
- tag = tag
-}
-local tag = require("awful.tag")
-local client = require("awful.client")
-local ascreen = require("awful.screen")
-local timer = require("gears.timer")
-
-local function get_screen(s)
- return s and capi.screen[s]
-end
-
-local layout = {}
-
-layout.suit = require("awful.layout.suit")
-
-layout.layouts = {
- layout.suit.floating,
- layout.suit.tile,
- layout.suit.tile.left,
- layout.suit.tile.bottom,
- layout.suit.tile.top,
- layout.suit.fair,
- layout.suit.fair.horizontal,
- layout.suit.spiral,
- layout.suit.spiral.dwindle,
- layout.suit.max,
- layout.suit.max.fullscreen,
- layout.suit.magnifier,
- layout.suit.corner.nw,
- layout.suit.corner.ne,
- layout.suit.corner.sw,
- layout.suit.corner.se,
-}
-
---- The default list of layouts.
---
--- The default value is:
---
--- awful.layout.suit.floating,
--- awful.layout.suit.tile,
--- awful.layout.suit.tile.left,
--- awful.layout.suit.tile.bottom,
--- awful.layout.suit.tile.top,
--- awful.layout.suit.fair,
--- awful.layout.suit.fair.horizontal,
--- awful.layout.suit.spiral,
--- awful.layout.suit.spiral.dwindle,
--- awful.layout.suit.max,
--- awful.layout.suit.max.fullscreen,
--- awful.layout.suit.magnifier,
--- awful.layout.suit.corner.nw,
--- awful.layout.suit.corner.ne,
--- awful.layout.suit.corner.sw,
--- awful.layout.suit.corner.se,
---
--- @field layout.layouts
-
-
--- This is a special lock used by the arrange function.
--- This avoids recurring call by emitted signals.
-local arrange_lock = false
--- Delay one arrange call per screen.
-local delayed_arrange = {}
-
---- Get the current layout.
--- @param screen The screen.
--- @return The layout function.
-function layout.get(screen)
- screen = screen or capi.mouse.screen
- local t = get_screen(screen).selected_tag
- return tag.getproperty(t, "layout") or layout.suit.floating
-end
-
---- Change the layout of the current tag.
--- @param i Relative index.
--- @param s The screen.
--- @param[opt] layouts A table of layouts.
-function layout.inc(i, s, layouts)
- if type(i) == "table" then
- -- Older versions of this function had arguments (layouts, i, s), but
- -- this was changed so that 'layouts' can be an optional parameter
- layouts, i, s = i, s, layouts
- end
- s = get_screen(s or ascreen.focused())
- local t = s.selected_tag
- layouts = layouts or layout.layouts
- if t then
- local curlayout = layout.get(s)
- local curindex
- for k, v in ipairs(layouts) do
- if v == curlayout or curlayout._type == v then
- curindex = k
- break
- end
- end
- if not curindex then
- -- Safety net: handle cases where another reference of the layout
- -- might be given (e.g. when (accidentally) cloning it).
- for k, v in ipairs(layouts) do
- if v.name == curlayout.name then
- curindex = k
- break
- end
- end
- end
- if curindex then
- local newindex = util.cycle(#layouts, curindex + i)
- layout.set(layouts[newindex], t)
- end
- end
-end
-
---- Set the layout function of the current tag.
--- @param _layout Layout name.
--- @tparam[opt=mouse.screen.selected_tag] tag t The tag to modify.
-function layout.set(_layout, t)
- t = t or capi.mouse.screen.selected_tag
- t.layout = _layout
-end
-
---- Get the layout parameters used for the screen
---
--- This should give the same result as "arrange", but without the "geometries"
--- parameter, as this is computed during arranging.
---
--- If `t` is given, `screen` is ignored, if none are given, the mouse screen is
--- used.
---
--- @tparam[opt] tag t The tag to query
--- @param[opt] screen The screen
--- @treturn table A table with the workarea (x, y, width, height), the screen
--- geometry (x, y, width, height), the clients, the screen and sometime, a
--- "geometries" table with client as keys and geometry as value
-function layout.parameters(t, screen)
- screen = get_screen(screen)
- t = t or screen.selected_tag
-
- screen = get_screen(t and t.screen or 1)
-
- local p = {}
-
- local clients = client.tiled(screen)
- local gap_single_client = true
-
- if(t and t.gap_single_client ~= nil) then
- gap_single_client = t.gap_single_client
- end
-
- local min_clients = gap_single_client and 1 or 2
- local useless_gap = t and (#clients >= min_clients and t.gap or 0) or 0
-
- p.workarea = screen:get_bounding_geometry {
- honor_padding = true,
- honor_workarea = true,
- margins = useless_gap,
- }
-
- p.geometry = screen.geometry
- p.clients = clients
- p.screen = screen.index
- p.padding = screen.padding
- p.useless_gap = useless_gap
-
- return p
-end
-
---- Arrange a screen using its current layout.
--- @param screen The screen to arrange.
-function layout.arrange(screen)
- screen = get_screen(screen)
- if not screen or delayed_arrange[screen] then return end
- delayed_arrange[screen] = true
-
- timer.delayed_call(function()
- if not screen.valid then
- -- Screen was removed
- delayed_arrange[screen] = nil
- return
- end
- if arrange_lock then return end
- arrange_lock = true
-
- local p = layout.parameters(nil, screen)
-
- local useless_gap = p.useless_gap
-
- p.geometries = setmetatable({}, {__mode = "k"})
- layout.get(screen).arrange(p)
- for c, g in pairs(p.geometries) do
- g.width = math.max(1, g.width - c.border_width * 2 - useless_gap * 2)
- g.height = math.max(1, g.height - c.border_width * 2 - useless_gap * 2)
- g.x = g.x + useless_gap
- g.y = g.y + useless_gap
- c:geometry(g)
- end
- arrange_lock = false
- delayed_arrange[screen] = nil
-
- screen:emit_signal("arrange")
- end)
-end
-
---- Get the current layout name.
--- @param _layout The layout.
--- @return The layout name.
-function layout.getname(_layout)
- _layout = _layout or layout.get()
- return _layout.name
-end
-
-local function arrange_prop_nf(obj)
- if not client.object.get_floating(obj) then
- layout.arrange(obj.screen)
- end
-end
-
-local function arrange_prop(obj) layout.arrange(obj.screen) end
-
-capi.client.connect_signal("property::size_hints_honor", arrange_prop_nf)
-capi.client.connect_signal("property::struts", arrange_prop)
-capi.client.connect_signal("property::minimized", arrange_prop_nf)
-capi.client.connect_signal("property::sticky", arrange_prop_nf)
-capi.client.connect_signal("property::fullscreen", arrange_prop_nf)
-capi.client.connect_signal("property::maximized_horizontal", arrange_prop_nf)
-capi.client.connect_signal("property::maximized_vertical", arrange_prop_nf)
-capi.client.connect_signal("property::border_width", arrange_prop_nf)
-capi.client.connect_signal("property::hidden", arrange_prop_nf)
-capi.client.connect_signal("property::floating", arrange_prop)
-capi.client.connect_signal("property::geometry", arrange_prop_nf)
-capi.client.connect_signal("property::screen", function(c, old_screen)
- if old_screen then
- layout.arrange(old_screen)
- end
- layout.arrange(c.screen)
-end)
-
-local function arrange_tag(t)
- layout.arrange(t.screen)
-end
-
-capi.tag.connect_signal("property::master_width_factor", arrange_tag)
-capi.tag.connect_signal("property::master_count", arrange_tag)
-capi.tag.connect_signal("property::column_count", arrange_tag)
-capi.tag.connect_signal("property::layout", arrange_tag)
-capi.tag.connect_signal("property::windowfact", arrange_tag)
-capi.tag.connect_signal("property::selected", arrange_tag)
-capi.tag.connect_signal("property::activated", arrange_tag)
-capi.tag.connect_signal("property::useless_gap", arrange_tag)
-capi.tag.connect_signal("property::master_fill_policy", arrange_tag)
-capi.tag.connect_signal("tagged", arrange_tag)
-
-capi.screen.connect_signal("property::workarea", layout.arrange)
-capi.screen.connect_signal("padding", layout.arrange)
-
-capi.client.connect_signal("raised", function(c) layout.arrange(c.screen) end)
-capi.client.connect_signal("lowered", function(c) layout.arrange(c.screen) end)
-capi.client.connect_signal("list", function()
- for screen in capi.screen do
- layout.arrange(screen)
- end
- end)
-
---- Default handler for `request::geometry` signals for tiled clients with
--- the "mouse.move" context.
--- @tparam client c The client
--- @tparam string context The context
--- @tparam table hints Additional hints
-function layout.move_handler(c, context, hints) --luacheck: no unused args
- -- Quit if it isn't a mouse.move on a tiled layout, that's handled elsewhere
- if c.floating then return end
- if context ~= "mouse.move" then return end
-
- if capi.mouse.screen ~= c.screen then
- c.screen = capi.mouse.screen
- end
-
- local l = c.screen.selected_tag and c.screen.selected_tag.layout or nil
- if l == layout.suit.floating then return end
-
- local c_u_m = capi.mouse.current_client
- if c_u_m and not c_u_m.floating then
- if c_u_m ~= c then
- c:swap(c_u_m)
- end
- end
-end
-
-capi.client.connect_signal("request::geometry", layout.move_handler)
-
--- When a screen is moved, make (floating) clients follow it
-capi.screen.connect_signal("property::geometry", function(s, old_geom)
- local geom = s.geometry
- local xshift = geom.x - old_geom.x
- local yshift = geom.y - old_geom.y
- for _, c in ipairs(capi.client.get(s)) do
- local cgeom = c:geometry()
- c:geometry({
- x = cgeom.x + xshift,
- y = cgeom.y + yshift
- })
- end
-end)
-
-return layout
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/layout/suit/corner.lua b/awesome/lib/awful/layout/suit/corner.lua
deleted file mode 100644
index 4b746c9..0000000
--- a/awesome/lib/awful/layout/suit/corner.lua
+++ /dev/null
@@ -1,204 +0,0 @@
----------------------------------------------------------------------------
--- Corner layout.
--- Display master client in a corner of the screen, and slaves in one
--- column and one row around the master.
--- See Pull Request for example : https://github.com/awesomeWM/awesome/pull/251
--- @module awful.layout
--- @author Alexis Brenon &lt;brenon.alexis+awesomewm@gmail.com&gt;
--- @copyright 2015 Alexis Brenon
-
--- Grab environment we need
-local ipairs = ipairs
-local math = math
-local capi = {screen = screen}
-
---- The cornernw layout layoutbox icon.
--- @beautiful beautiful.layout_cornernw
--- @param surface
--- @see gears.surface
-
---- The cornerne layout layoutbox icon.
--- @beautiful beautiful.layout_cornerne
--- @param surface
--- @see gears.surface
-
---- The cornersw layout layoutbox icon.
--- @beautiful beautiful.layout_cornersw
--- @param surface
--- @see gears.surface
-
---- The cornerse layout layoutbox icon.
--- @beautiful beautiful.layout_cornerse
--- @param surface
--- @see gears.surface
-
--- Actually arrange clients of p.clients for corner layout
--- @param p Mandatory table containing required informations for layouts
--- (clients to arrange, workarea geometry, etc.)
--- @param orientation String indicating in which corner is the master window.
--- Available values are : NE, NW, SW, SE
-local function do_corner(p, orientation)
- local t = p.tag or capi.screen[p.screen].selected_tag
- local wa = p.workarea
- local cls = p.clients
-
- if #cls == 0 then return end
-
- local master = {}
- local column = {}
- local row = {}
- -- Use the nmaster field of the tag in a cheaty way
- local row_privileged = ((cls[1].screen.selected_tag.master_count % 2) == 0)
-
- local master_factor = cls[1].screen.selected_tag.master_width_factor
- master.width = master_factor * wa.width
- master.height = master_factor * wa.height
-
- local number_privileged_win = math.ceil((#cls - 1)/2)
- local number_unprivileged_win = (#cls - 1) - number_privileged_win
-
- -- Define some obvious parameters
- column.width = wa.width - master.width
- column.x_increment = 0
- row.height = wa.height - master.height
- row.y_increment = 0
-
- -- Place master at the right place and move row and column accordingly
- column.y = wa.y
- row.x = wa.x
- if orientation:match('N.') then
- master.y = wa.y
- row.y = master.y + master.height
- elseif orientation:match('S.') then
- master.y = wa.y + wa.height - master.height
- row.y = wa.y
- end
- if orientation:match('.W') then
- master.x = wa.x
- column.x = master.x + master.width
- elseif orientation:match('.E') then
- master.x = wa.x + wa.width - master.width
- column.x = wa.x
- end
- -- At this point, master is in a corner
- -- but row and column are overlayed in the opposite corner...
-
- -- Reduce the unprivileged slaves to remove overlay
- -- and define actual width and height
- if row_privileged then
- row.width = wa.width
- row.number_win = number_privileged_win
- column.y = master.y
- column.height = master.height
- column.number_win = number_unprivileged_win
- else
- column.height = wa.height
- column.number_win = number_privileged_win
- row.x = master.x
- row.width = master.width
- row.number_win = number_unprivileged_win
- end
-
- column.win_height = column.height/column.number_win
- column.win_width = column.width
- column.y_increment = column.win_height
- column.win_idx = 0
-
- row.win_width = row.width/row.number_win
- row.win_height = row.height
- row.x_increment = row.win_width
- row.win_idx = 0
-
- -- Extend master if there is only a few windows and "expand" policy is set
- if #cls < 3 then
- if row_privileged then
- master.x = wa.x
- master.width = wa.width
- else
- master.y = wa.y
- master.height = wa.height
- end
- if #cls < 2 then
- if t.master_fill_policy == "expand" then
- master = wa
- else
- master.x = master.x + (wa.width - master.width)/2
- master.y = master.y + (wa.height - master.height)/2
- end
- end
- end
-
- for i, c in ipairs(cls) do
- local g
- -- Handle master window
- if i == 1 then
- g = {
- x = master.x,
- y = master.y,
- width = master.width,
- height = master.height
- }
- -- handle column windows
- elseif i % 2 == 0 then
- g = {
- x = column.x + column.win_idx * column.x_increment,
- y = column.y + column.win_idx * column.y_increment,
- width = column.win_width,
- height = column.win_height
- }
- column.win_idx = column.win_idx + 1
- else
- g = {
- x = row.x + row.win_idx * row.x_increment,
- y = row.y + row.win_idx * row.y_increment,
- width = row.win_width,
- height = row.win_height
- }
- row.win_idx = row.win_idx + 1
- end
- p.geometries[c] = g
- end
-end
-
-local corner = {}
-corner.row_privileged = false
-
---- Corner layout.
--- Display master client in a corner of the screen, and slaves in one
--- column and one row around the master.
--- @clientlayout awful.layout.suit.corner.nw
-corner.nw = {
- name = "cornernw",
- arrange = function (p) return do_corner(p, "NW") end
- }
-
---- Corner layout.
--- Display master client in a corner of the screen, and slaves in one
--- column and one row around the master.
--- @clientlayout awful.layout.suit.corner.ne
-corner.ne = {
- name = "cornerne",
- arrange = function (p) return do_corner(p, "NE") end
- }
-
---- Corner layout.
--- Display master client in a corner of the screen, and slaves in one
--- column and one row around the master.
--- @clientlayout awful.layout.suit.corner.sw
-corner.sw = {
- name = "cornersw",
- arrange = function (p) return do_corner(p, "SW") end
- }
-
---- Corner layout.
--- Display master client in a corner of the screen, and slaves in one
--- column and one row around the master.
--- @clientlayout awful.layout.suit.corner.se
-corner.se = {
- name = "cornerse",
- arrange = function (p) return do_corner(p, "SE") end
- }
-
-return corner
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/layout/suit/fair.lua b/awesome/lib/awful/layout/suit/fair.lua
deleted file mode 100644
index 161b6ed..0000000
--- a/awesome/lib/awful/layout/suit/fair.lua
+++ /dev/null
@@ -1,108 +0,0 @@
----------------------------------------------------------------------------
---- Fair layouts module for awful.
---
--- @author Josh Komoroske
--- @copyright 2012 Josh Komoroske
--- @module awful.layout
----------------------------------------------------------------------------
-
--- Grab environment we need
-local ipairs = ipairs
-local math = math
-
---- The fairh layout layoutbox icon.
--- @beautiful beautiful.layout_fairh
--- @param surface
--- @see gears.surface
-
---- The fairv layout layoutbox icon.
--- @beautiful beautiful.layout_fairv
--- @param surface
--- @see gears.surface
-
-local fair = {}
-
-local function do_fair(p, orientation)
- local wa = p.workarea
- local cls = p.clients
-
- -- Swap workarea dimensions, if our orientation is "east"
- if orientation == 'east' then
- wa.width, wa.height = wa.height, wa.width
- wa.x, wa.y = wa.y, wa.x
- end
-
- if #cls > 0 then
- local rows, cols
- if #cls == 2 then
- rows, cols = 1, 2
- else
- rows = math.ceil(math.sqrt(#cls))
- cols = math.ceil(#cls / rows)
- end
-
- for k, c in ipairs(cls) do
- k = k - 1
- local g = {}
-
- local row, col
- row = k % rows
- col = math.floor(k / rows)
-
- local lrows, lcols
- if k >= rows * cols - rows then
- lrows = #cls - (rows * cols - rows)
- lcols = cols
- else
- lrows = rows
- lcols = cols
- end
-
- if row == lrows - 1 then
- g.height = wa.height - math.ceil(wa.height / lrows) * row
- g.y = wa.height - g.height
- else
- g.height = math.ceil(wa.height / lrows)
- g.y = g.height * row
- end
-
- if col == lcols - 1 then
- g.width = wa.width - math.ceil(wa.width / lcols) * col
- g.x = wa.width - g.width
- else
- g.width = math.ceil(wa.width / lcols)
- g.x = g.width * col
- end
-
- g.y = g.y + wa.y
- g.x = g.x + wa.x
-
- -- Swap window dimensions, if our orientation is "east"
- if orientation == 'east' then
- g.width, g.height = g.height, g.width
- g.x, g.y = g.y, g.x
- end
-
- p.geometries[c] = g
- end
- end
-end
-
---- Horizontal fair layout.
--- @param screen The screen to arrange.
-fair.horizontal = {}
-fair.horizontal.name = "fairh"
-function fair.horizontal.arrange(p)
- return do_fair(p, "east")
-end
-
---- Vertical fair layout.
--- @param screen The screen to arrange.
-fair.name = "fairv"
-function fair.arrange(p)
- return do_fair(p, "south")
-end
-
-return fair
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/layout/suit/floating.lua b/awesome/lib/awful/layout/suit/floating.lua
deleted file mode 100644
index b769435..0000000
--- a/awesome/lib/awful/layout/suit/floating.lua
+++ /dev/null
@@ -1,112 +0,0 @@
----------------------------------------------------------------------------
---- Dummy function for floating layout
---
--- @author Gregor Best
--- @copyright 2008 Gregor Best
--- @module awful.layout
----------------------------------------------------------------------------
-
--- Grab environment we need
-local ipairs = ipairs
-local capi =
-{
- mouse = mouse,
- mousegrabber = mousegrabber
-}
-
---- The floating layout layoutbox icon.
--- @beautiful beautiful.layout_floating
--- @param surface
--- @see gears.surface
-
-local floating = {}
-
---- Jump mouse cursor to the client's corner when resizing it.
-floating.resize_jump_to_corner = true
-
-function floating.mouse_resize_handler(c, corner, x, y)
- local g = c:geometry()
-
- -- Do not allow maximized clients to be resized by mouse
- local fixed_x = c.maximized_horizontal
- local fixed_y = c.maximized_vertical
-
- local prev_coords = {}
- local coordinates_delta = {x=0,y=0}
- if floating.resize_jump_to_corner then
- -- Warp mouse pointer
- capi.mouse.coords({ x = x, y = y })
- else
- local corner_x, corner_y = x, y
- local mouse_coords = capi.mouse.coords()
- x = mouse_coords.x
- y = mouse_coords.y
- coordinates_delta = {x=corner_x-x,y=corner_y-y}
- end
-
- capi.mousegrabber.run(function (_mouse)
- if not c.valid then return false end
-
- _mouse.x = _mouse.x + coordinates_delta.x
- _mouse.y = _mouse.y + coordinates_delta.y
- for _, v in ipairs(_mouse.buttons) do
- if v then
- local ng
- prev_coords = { x =_mouse.x, y = _mouse.y }
- if corner == "bottom_right" then
- ng = { width = _mouse.x - g.x,
- height = _mouse.y - g.y }
- elseif corner == "bottom_left" then
- ng = { x = _mouse.x,
- width = (g.x + g.width) - _mouse.x,
- height = _mouse.y - g.y }
- elseif corner == "top_left" then
- ng = { x = _mouse.x,
- width = (g.x + g.width) - _mouse.x,
- y = _mouse.y,
- height = (g.y + g.height) - _mouse.y }
- else
- ng = { width = _mouse.x - g.x,
- y = _mouse.y,
- height = (g.y + g.height) - _mouse.y }
- end
- if ng.width <= 0 then ng.width = nil end
- if ng.height <= 0 then ng.height = nil end
- if fixed_x then ng.width = g.width ng.x = g.x end
- if fixed_y then ng.height = g.height ng.y = g.y end
- c:geometry(ng)
- -- Get real geometry that has been applied
- -- in case we honor size hints
- -- XXX: This should be rewritten when size
- -- hints are available from Lua.
- local rg = c:geometry()
-
- if corner == "bottom_right" then
- ng = {}
- elseif corner == "bottom_left" then
- ng = { x = (g.x + g.width) - rg.width }
- elseif corner == "top_left" then
- ng = { x = (g.x + g.width) - rg.width,
- y = (g.y + g.height) - rg.height }
- else
- ng = { y = (g.y + g.height) - rg.height }
- end
- c:geometry({ x = ng.x, y = ng.y })
- return true
- end
- end
- return prev_coords.x == _mouse.x and prev_coords.y == _mouse.y
- end, corner .. "_corner")
-end
-
-function floating.arrange()
-end
-
---- The floating layout.
--- @clientlayout awful.layout.suit.
-
-floating.name = "floating"
-
-return floating
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/layout/suit/init.lua b/awesome/lib/awful/layout/suit/init.lua
deleted file mode 100644
index 57a49fa..0000000
--- a/awesome/lib/awful/layout/suit/init.lua
+++ /dev/null
@@ -1,19 +0,0 @@
----------------------------------------------------------------------------
---- Suits for awful
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2008 Julien Danjou
--- @module awful.layout
----------------------------------------------------------------------------
-
-return
-{
- corner = require("awful.layout.suit.corner");
- max = require("awful.layout.suit.max");
- tile = require("awful.layout.suit.tile");
- fair = require("awful.layout.suit.fair");
- floating = require("awful.layout.suit.floating");
- magnifier = require("awful.layout.suit.magnifier");
- spiral = require("awful.layout.suit.spiral");
-}
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/layout/suit/magnifier.lua b/awesome/lib/awful/layout/suit/magnifier.lua
deleted file mode 100644
index f30d7ee..0000000
--- a/awesome/lib/awful/layout/suit/magnifier.lua
+++ /dev/null
@@ -1,147 +0,0 @@
----------------------------------------------------------------------------
---- Magnifier layout module for awful
---
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2008 Julien Danjou
--- @module awful.layout
----------------------------------------------------------------------------
-
--- Grab environment we need
-local ipairs = ipairs
-local math = math
-local capi =
-{
- client = client,
- screen = screen,
- mouse = mouse,
- mousegrabber = mousegrabber
-}
-
---- The magnifier layout layoutbox icon.
--- @beautiful beautiful.layout_magnifier
--- @param surface
--- @see gears.surface
-
-local magnifier = {}
-
-function magnifier.mouse_resize_handler(c, corner, x, y)
- capi.mouse.coords({ x = x, y = y })
-
- local wa = c.screen.workarea
- local center_x = wa.x + wa.width / 2
- local center_y = wa.y + wa.height / 2
- local maxdist_pow = (wa.width^2 + wa.height^2) / 4
-
- local prev_coords = {}
- capi.mousegrabber.run(function (_mouse)
- if not c.valid then return false end
-
- for _, v in ipairs(_mouse.buttons) do
- if v then
- prev_coords = { x =_mouse.x, y = _mouse.y }
- local dx = center_x - _mouse.x
- local dy = center_y - _mouse.y
- local dist = dx^2 + dy^2
-
- -- New master width factor
- local mwfact = dist / maxdist_pow
- c.screen.selected_tag.master_width_factor
- = math.min(math.max(0.01, mwfact), 0.99)
- return true
- end
- end
- return prev_coords.x == _mouse.x and prev_coords.y == _mouse.y
- end, corner .. "_corner")
-end
-
-function magnifier.arrange(p)
- -- Fullscreen?
- local area = p.workarea
- local cls = p.clients
- local focus = p.focus or capi.client.focus
- local t = p.tag or capi.screen[p.screen].selected_tag
- local mwfact = t.master_width_factor
- local fidx
-
- -- Check that the focused window is on the right screen
- if focus and focus.screen ~= p.screen then focus = nil end
-
- -- If no window is focused or focused window is not tiled, take the first tiled one.
- if (not focus or focus.floating) and #cls > 0 then
- focus = cls[1]
- fidx = 1
- end
-
- -- Abort if no clients are present
- if not focus then return end
-
- local geometry = {}
- if #cls > 1 then
- geometry.width = area.width * math.sqrt(mwfact)
- geometry.height = area.height * math.sqrt(mwfact)
- geometry.x = area.x + (area.width - geometry.width) / 2
- geometry.y = area.y + (area.height - geometry.height) /2
- else
- geometry.x = area.x
- geometry.y = area.y
- geometry.width = area.width
- geometry.height = area.height
- end
-
- local g = {
- x = geometry.x,
- y = geometry.y,
- width = geometry.width,
- height = geometry.height
- }
- p.geometries[focus] = g
-
- if #cls > 1 then
- geometry.x = area.x
- geometry.y = area.y
- geometry.height = area.height / (#cls - 1)
- geometry.width = area.width
-
- -- We don't know the focus window index. Try to find it.
- if not fidx then
- for k, c in ipairs(cls) do
- if c == focus then
- fidx = k
- break
- end
- end
- end
-
- -- First move clients that are before focused client.
- for k = fidx + 1, #cls do
- p.geometries[cls[k]] = {
- x = geometry.x,
- y = geometry.y,
- width = geometry.width,
- height = geometry.height
- }
- geometry.y = geometry.y + geometry.height
- end
-
- -- Then move clients that are after focused client.
- -- So the next focused window will be the one at the top of the screen.
- for k = 1, fidx - 1 do
- p.geometries[cls[k]] = {
- x = geometry.x,
- y = geometry.y,
- width = geometry.width,
- height = geometry.height
- }
- geometry.y = geometry.y + geometry.height
- end
- end
-end
-
---- The magnifier layout.
--- @clientlayout awful.layout.suit.magnifier
-
-magnifier.name = "magnifier"
-
-return magnifier
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/layout/suit/max.lua b/awesome/lib/awful/layout/suit/max.lua
deleted file mode 100644
index 2cd1812..0000000
--- a/awesome/lib/awful/layout/suit/max.lua
+++ /dev/null
@@ -1,61 +0,0 @@
----------------------------------------------------------------------------
---- Maximized and fullscreen layouts module for awful
---
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2008 Julien Danjou
--- @module awful.layout
----------------------------------------------------------------------------
-
--- Grab environment we need
-local pairs = pairs
-
-local max = {}
-
---- The max layout layoutbox icon.
--- @beautiful beautiful.layout_max
--- @param surface
--- @see gears.surface
-
---- The fullscreen layout layoutbox icon.
--- @beautiful beautiful.layout_fullscreen
--- @param surface
--- @see gears.surface
-
-local function fmax(p, fs)
- -- Fullscreen?
- local area
- if fs then
- area = p.geometry
- else
- area = p.workarea
- end
-
- for _, c in pairs(p.clients) do
- local g = {
- x = area.x,
- y = area.y,
- width = area.width,
- height = area.height
- }
- p.geometries[c] = g
- end
-end
-
---- Maximized layout.
--- @clientlayout awful.layout.suit.max.name
-max.name = "max"
-function max.arrange(p)
- return fmax(p, false)
-end
-
---- Fullscreen layout.
--- @clientlayout awful.layout.suit.max.fullscreen
-max.fullscreen = {}
-max.fullscreen.name = "fullscreen"
-function max.fullscreen.arrange(p)
- return fmax(p, true)
-end
-
-return max
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/layout/suit/spiral.lua b/awesome/lib/awful/layout/suit/spiral.lua
deleted file mode 100644
index 0a7eb9b..0000000
--- a/awesome/lib/awful/layout/suit/spiral.lua
+++ /dev/null
@@ -1,89 +0,0 @@
----------------------------------------------------------------------------
---- Dwindle and spiral layouts
---
--- @author Uli Schlachter &lt;psychon@znc.in&gt;
--- @copyright 2009 Uli Schlachter
--- @copyright 2008 Julien Danjou
---
--- @module awful.layout
----------------------------------------------------------------------------
-
--- Grab environment we need
-local ipairs = ipairs
-local math = math
-
---- The spiral layout layoutbox icon.
--- @beautiful beautiful.layout_spiral
--- @param surface
--- @see gears.surface
-
---- The dwindle layout layoutbox icon.
--- @beautiful beautiful.layout_dwindle
--- @param surface
--- @see gears.surface
-
-local spiral = {}
-
-local function do_spiral(p, _spiral)
- local wa = p.workarea
- local cls = p.clients
- local n = #cls
- local old_width, old_height = wa.width, 2 * wa.height
-
- for k, c in ipairs(cls) do
- if k % 2 == 0 then
- wa.width, old_width = math.ceil(old_width / 2), wa.width
- if k ~= n then
- wa.height, old_height = math.floor(wa.height / 2), wa.height
- end
- else
- wa.height, old_height = math.ceil(old_height / 2), wa.height
- if k ~= n then
- wa.width, old_width = math.floor(wa.width / 2), wa.width
- end
- end
-
- if k % 4 == 0 and _spiral then
- wa.x = wa.x - wa.width
- elseif k % 2 == 0 then
- wa.x = wa.x + old_width
- elseif k % 4 == 3 and k < n and _spiral then
- wa.x = wa.x + math.ceil(old_width / 2)
- end
-
- if k % 4 == 1 and k ~= 1 and _spiral then
- wa.y = wa.y - wa.height
- elseif k % 2 == 1 and k ~= 1 then
- wa.y = wa.y + old_height
- elseif k % 4 == 0 and k < n and _spiral then
- wa.y = wa.y + math.ceil(old_height / 2)
- end
-
- local g = {
- x = wa.x,
- y = wa.y,
- width = wa.width,
- height = wa.height
- }
- p.geometries[c] = g
- end
-end
-
---- Dwindle layout.
--- @clientlayout awful.layout.suit.spiral.dwindle
-spiral.dwindle = {}
-spiral.dwindle.name = "dwindle"
-function spiral.dwindle.arrange(p)
- return do_spiral(p, false)
-end
-
---- Spiral layout.
--- @clientlayout awful.layout.suit.spiral.name
-spiral.name = "spiral"
-function spiral.arrange(p)
- return do_spiral(p, true)
-end
-
-return spiral
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/layout/suit/tile.lua b/awesome/lib/awful/layout/suit/tile.lua
deleted file mode 100644
index 9fa263c..0000000
--- a/awesome/lib/awful/layout/suit/tile.lua
+++ /dev/null
@@ -1,348 +0,0 @@
----------------------------------------------------------------------------
---- Tiled layouts module for awful
---
--- @author Donald Ephraim Curtis &lt;dcurtis@cs.uiowa.edu&gt;
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2009 Donald Ephraim Curtis
--- @copyright 2008 Julien Danjou
--- @module awful.layout
----------------------------------------------------------------------------
-
--- Grab environment we need
-local tag = require("awful.tag")
-local client = require("awful.client")
-local ipairs = ipairs
-local math = math
-local capi =
-{
- mouse = mouse,
- screen = screen,
- mousegrabber = mousegrabber
-}
-
-local tile = {}
-
---- The tile layout layoutbox icon.
--- @beautiful beautiful.layout_tile
--- @param surface
--- @see gears.surface
-
---- The tile top layout layoutbox icon.
--- @beautiful beautiful.layout_tiletop
--- @param surface
--- @see gears.surface
-
---- The tile bottom layout layoutbox icon.
--- @beautiful beautiful.layout_tilebottom
--- @param surface
--- @see gears.surface
-
---- The tile left layout layoutbox icon.
--- @beautiful beautiful.layout_tileleft
--- @param surface
--- @see gears.surface
-
---- Jump mouse cursor to the client's corner when resizing it.
-tile.resize_jump_to_corner = true
-
-local function mouse_resize_handler(c, _, _, _, orientation)
- orientation = orientation or "tile"
- local wa = c.screen.workarea
- local mwfact = c.screen.selected_tag.master_width_factor
- local cursor
- local g = c:geometry()
- local offset = 0
- local corner_coords
- local coordinates_delta = {x=0,y=0}
-
- if orientation == "tile" then
- cursor = "cross"
- if g.height+15 > wa.height then
- offset = g.height * .5
- cursor = "sb_h_double_arrow"
- elseif not (g.y+g.height+15 > wa.y+wa.height) then
- offset = g.height
- end
- corner_coords = { x = wa.x + wa.width * mwfact, y = g.y + offset }
- elseif orientation == "left" then
- cursor = "cross"
- if g.height+15 >= wa.height then
- offset = g.height * .5
- cursor = "sb_h_double_arrow"
- elseif not (g.y+g.height+15 > wa.y+wa.height) then
- offset = g.height
- end
- corner_coords = { x = wa.x + wa.width * (1 - mwfact), y = g.y + offset }
- elseif orientation == "bottom" then
- cursor = "cross"
- if g.width+15 >= wa.width then
- offset = g.width * .5
- cursor = "sb_v_double_arrow"
- elseif not (g.x+g.width+15 > wa.x+wa.width) then
- offset = g.width
- end
- corner_coords = { y = wa.y + wa.height * mwfact, x = g.x + offset}
- else
- cursor = "cross"
- if g.width+15 >= wa.width then
- offset = g.width * .5
- cursor = "sb_v_double_arrow"
- elseif not (g.x+g.width+15 > wa.x+wa.width) then
- offset = g.width
- end
- corner_coords = { y = wa.y + wa.height * (1 - mwfact), x= g.x + offset }
- end
- if tile.resize_jump_to_corner then
- capi.mouse.coords(corner_coords)
- else
- local mouse_coords = capi.mouse.coords()
- coordinates_delta = {
- x = corner_coords.x - mouse_coords.x,
- y = corner_coords.y - mouse_coords.y,
- }
- end
-
- local prev_coords = {}
- capi.mousegrabber.run(function (_mouse)
- if not c.valid then return false end
-
- _mouse.x = _mouse.x + coordinates_delta.x
- _mouse.y = _mouse.y + coordinates_delta.y
- for _, v in ipairs(_mouse.buttons) do
- if v then
- prev_coords = { x =_mouse.x, y = _mouse.y }
- local fact_x = (_mouse.x - wa.x) / wa.width
- local fact_y = (_mouse.y - wa.y) / wa.height
- local new_mwfact
-
- local geom = c:geometry()
-
- -- we have to make sure we're not on the last visible client where we have to use different settings.
- local wfact
- local wfact_x, wfact_y
- if (geom.y+geom.height+15) > (wa.y+wa.height) then
- wfact_y = (geom.y + geom.height - _mouse.y) / wa.height
- else
- wfact_y = (_mouse.y - geom.y) / wa.height
- end
-
- if (geom.x+geom.width+15) > (wa.x+wa.width) then
- wfact_x = (geom.x + geom.width - _mouse.x) / wa.width
- else
- wfact_x = (_mouse.x - geom.x) / wa.width
- end
-
-
- if orientation == "tile" then
- new_mwfact = fact_x
- wfact = wfact_y
- elseif orientation == "left" then
- new_mwfact = 1 - fact_x
- wfact = wfact_y
- elseif orientation == "bottom" then
- new_mwfact = fact_y
- wfact = wfact_x
- else
- new_mwfact = 1 - fact_y
- wfact = wfact_x
- end
-
- c.screen.selected_tag.master_width_factor
- = math.min(math.max(new_mwfact, 0.01), 0.99)
- client.setwfact(math.min(math.max(wfact,0.01), 0.99), c)
- return true
- end
- end
- return prev_coords.x == _mouse.x and prev_coords.y == _mouse.y
- end, cursor)
-end
-
-local function tile_group(gs, cls, wa, orientation, fact, group)
- -- get our orientation right
- local height = "height"
- local width = "width"
- local x = "x"
- local y = "y"
- if orientation == "top" or orientation == "bottom" then
- height = "width"
- width = "height"
- x = "y"
- y = "x"
- end
-
- -- make this more generic (not just width)
- local available = wa[width] - (group.coord - wa[x])
-
- -- find our total values
- local total_fact = 0
- local min_fact = 1
- local size = group.size
- for c = group.first,group.last do
- -- determine the width/height based on the size_hint
- local i = c - group.first +1
- local size_hints = cls[c].size_hints
- local size_hint = size_hints["min_"..width] or size_hints["base_"..width] or 0
- size = math.max(size_hint, size)
-
- -- calculate the height
- if not fact[i] then
- fact[i] = min_fact
- else
- min_fact = math.min(fact[i],min_fact)
- end
- total_fact = total_fact + fact[i]
- end
- size = math.max(1, math.min(size, available))
-
- local coord = wa[y]
- local used_size = 0
- local unused = wa[height]
- for c = group.first,group.last do
- local geom = {}
- local hints = {}
- local i = c - group.first +1
- geom[width] = size
- geom[height] = math.max(1, math.floor(unused * fact[i] / total_fact))
- geom[x] = group.coord
- geom[y] = coord
- gs[cls[c]] = geom
- hints.width, hints.height = cls[c]:apply_size_hints(geom.width, geom.height)
- coord = coord + hints[height]
- unused = unused - hints[height]
- total_fact = total_fact - fact[i]
- used_size = math.max(used_size, hints[width])
- end
-
- return used_size
-end
-
-local function do_tile(param, orientation)
- local t = param.tag or capi.screen[param.screen].selected_tag
- orientation = orientation or "right"
-
- -- This handles all different orientations.
- local width = "width"
- local x = "x"
- if orientation == "top" or orientation == "bottom" then
- width = "height"
- x = "y"
- end
-
- local gs = param.geometries
- local cls = param.clients
- local nmaster = math.min(t.master_count, #cls)
- local nother = math.max(#cls - nmaster,0)
-
- local mwfact = t.master_width_factor
- local wa = param.workarea
- local ncol = t.column_count
-
- local data = tag.getdata(t).windowfact
-
- if not data then
- data = {}
- tag.getdata(t).windowfact = data
- end
-
- local coord = wa[x]
- local place_master = true
- if orientation == "left" or orientation == "top" then
- -- if we are on the left or top we need to render the other windows first
- place_master = false
- end
-
- local grow_master = t.master_fill_policy == "expand"
- -- this was easier than writing functions because there is a lot of data we need
- for _ = 1,2 do
- if place_master and nmaster > 0 then
- local size = wa[width]
- if nother > 0 or not grow_master then
- size = math.min(wa[width] * mwfact, wa[width] - (coord - wa[x]))
- end
- if nother == 0 and not grow_master then
- coord = coord + (wa[width] - size)/2
- end
- if not data[0] then
- data[0] = {}
- end
- coord = coord + tile_group(gs, cls, wa, orientation, data[0], {first=1, last=nmaster, coord = coord, size = size})
- end
-
- if not place_master and nother > 0 then
- local last = nmaster
-
- -- we have to modify the work area size to consider left and top views
- local wasize = wa[width]
- if nmaster > 0 and (orientation == "left" or orientation == "top") then
- wasize = wa[width] - wa[width]*mwfact
- end
- for i = 1,ncol do
- -- Try to get equal width among remaining columns
- local size = math.min( (wasize - (coord - wa[x])) / (ncol - i + 1) )
- local first = last + 1
- last = last + math.floor((#cls - last)/(ncol - i + 1))
- -- tile the column and update our current x coordinate
- if not data[i] then
- data[i] = {}
- end
- coord = coord + tile_group(gs, cls, wa, orientation, data[i], { first = first, last = last, coord = coord, size = size })
- end
- end
- place_master = not place_master
- end
-
-end
-
---- The main tile algo, on the right.
--- @param screen The screen number to tile.
--- @clientlayout awful.layout.suit.tile.top
-tile.right = {}
-tile.right.name = "tile"
-tile.right.arrange = do_tile
-function tile.right.mouse_resize_handler(c, corner, x, y)
- return mouse_resize_handler(c, corner, x, y)
-end
-
---- The main tile algo, on the left.
--- @param screen The screen number to tile.
--- @clientlayout awful.layout.suit.tile.left
-tile.left = {}
-tile.left.name = "tileleft"
-function tile.left.arrange(p)
- return do_tile(p, "left")
-end
-function tile.left.mouse_resize_handler(c, corner, x, y)
- return mouse_resize_handler(c, corner, x, y, "left")
-end
-
---- The main tile algo, on the bottom.
--- @param screen The screen number to tile.
--- @clientlayout awful.layout.suit.tile.bottom
-tile.bottom = {}
-tile.bottom.name = "tilebottom"
-function tile.bottom.arrange(p)
- return do_tile(p, "bottom")
-end
-function tile.bottom.mouse_resize_handler(c, corner, x, y)
- return mouse_resize_handler(c, corner, x, y, "bottom")
-end
-
---- The main tile algo, on the top.
--- @param screen The screen number to tile.
--- @clientlayout awful.layout.suit.tile.top
-tile.top = {}
-tile.top.name = "tiletop"
-function tile.top.arrange(p)
- return do_tile(p, "top")
-end
-function tile.top.mouse_resize_handler(c, corner, x, y)
- return mouse_resize_handler(c, corner, x, y, "top")
-end
-
-tile.arrange = tile.right.arrange
-tile.mouse_resize_handler = tile.right.mouse_resize_handler
-tile.name = tile.right.name
-
-return tile
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/menu.lua b/awesome/lib/awful/menu.lua
deleted file mode 100644
index dcbc5fa..0000000
--- a/awesome/lib/awful/menu.lua
+++ /dev/null
@@ -1,723 +0,0 @@
---------------------------------------------------------------------------------
---- A menu for awful
---
--- @author Damien Leone &lt;damien.leone@gmail.com&gt;
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @author dodo
--- @copyright 2008, 2011 Damien Leone, Julien Danjou, dodo
--- @module awful.menu
---------------------------------------------------------------------------------
-
-local wibox = require("wibox")
-local button = require("awful.button")
-local util = require("awful.util")
-local spawn = require("awful.spawn")
-local tags = require("awful.tag")
-local keygrabber = require("awful.keygrabber")
-local client_iterate = require("awful.client").iterate
-local beautiful = require("beautiful")
-local dpi = require("beautiful").xresources.apply_dpi
-local object = require("gears.object")
-local surface = require("gears.surface")
-local protected_call = require("gears.protected_call")
-local cairo = require("lgi").cairo
-local setmetatable = setmetatable
-local tonumber = tonumber
-local string = string
-local ipairs = ipairs
-local pairs = pairs
-local print = print
-local table = table
-local type = type
-local math = math
-local capi = {
- screen = screen,
- mouse = mouse,
- client = client }
-local screen = require("awful.screen")
-
-
-local menu = { mt = {} }
-
-
-local table_update = function (t, set)
- for k, v in pairs(set) do
- t[k] = v
- end
- return t
-end
-
---- The icon used for sub-menus.
--- @beautiful beautiful.menu_submenu_icon
-
---- The item height.
--- @beautiful beautiful.menu_height
--- @tparam[opt=16] number menu_height
-
---- The default menu width.
--- @beautiful beautiful.menu_width
--- @tparam[opt=100] number menu_width
-
---- The menu item border color.
--- @beautiful beautiful.menu_border_color
--- @tparam[opt=0] number menu_border_color
-
---- The menu item border width.
--- @beautiful beautiful.menu_border_width
--- @tparam[opt=0] number menu_border_width
-
---- The default focused item foreground (text) color.
--- @beautiful beautiful.menu_fg_focus
--- @param color
--- @see gears.color
-
---- The default focused item background color.
--- @beautiful beautiful.menu_bg_focus
--- @param color
--- @see gears.color
-
---- The default foreground (text) color.
--- @beautiful beautiful.menu_fg_normal
--- @param color
--- @see gears.color
-
---- The default background color.
--- @beautiful beautiful.menu_bg_normal
--- @param color
--- @see gears.color
-
---- The default sub-menu indicator if no menu_submenu_icon is provided.
--- @beautiful beautiful.menu_submenu
--- @tparam[opt="▶"] string menu_submenu The sub-menu text.
--- @see beautiful.menu_submenu_icon
-
---- Key bindings for menu navigation.
--- Keys are: up, down, exec, enter, back, close. Value are table with a list of valid
--- keys for the action, i.e. menu_keys.up = { "j", "k" } will bind 'j' and 'k'
--- key to up action. This is common to all created menu.
--- @class table
--- @name menu_keys
-menu.menu_keys = { up = { "Up", "k" },
- down = { "Down", "j" },
- back = { "Left", "h" },
- exec = { "Return" },
- enter = { "Right", "l" },
- close = { "Escape" } }
-
-
-local function load_theme(a, b)
- a = a or {}
- b = b or {}
- local ret = {}
- local fallback = beautiful.get()
- if a.reset then b = fallback end
- if a == "reset" then a = fallback end
- ret.border = a.border_color or b.menu_border_color or b.border_normal or
- fallback.menu_border_color or fallback.border_normal
- ret.border_width= a.border_width or b.menu_border_width or b.border_width or
- fallback.menu_border_width or fallback.border_width or 0
- ret.fg_focus = a.fg_focus or b.menu_fg_focus or b.fg_focus or
- fallback.menu_fg_focus or fallback.fg_focus
- ret.bg_focus = a.bg_focus or b.menu_bg_focus or b.bg_focus or
- fallback.menu_bg_focus or fallback.bg_focus
- ret.fg_normal = a.fg_normal or b.menu_fg_normal or b.fg_normal or
- fallback.menu_fg_normal or fallback.fg_normal
- ret.bg_normal = a.bg_normal or b.menu_bg_normal or b.bg_normal or
- fallback.menu_bg_normal or fallback.bg_normal
- ret.submenu_icon= a.submenu_icon or b.menu_submenu_icon or b.submenu_icon or
- fallback.menu_submenu_icon or fallback.submenu_icon
- ret.submenu = a.submenu or b.menu_submenu or b.submenu or
- fallback.menu_submenu or fallback.submenu or "▶"
- ret.height = a.height or b.menu_height or b.height or
- fallback.menu_height or 16
- ret.width = a.width or b.menu_width or b.width or
- fallback.menu_width or 100
- ret.font = a.font or b.font or fallback.font
- for _, prop in ipairs({"width", "height", "menu_width"}) do
- if type(ret[prop]) ~= "number" then ret[prop] = tonumber(ret[prop]) end
- end
- return ret
-end
-
-
-local function item_position(_menu, child)
- local a, b = "height", "width"
- local dir = _menu.layout.dir or "y"
- if dir == "x" then a, b = b, a end
-
- local in_dir, other = 0, _menu[b]
- local num = util.table.hasitem(_menu.child, child)
- if num then
- for i = 0, num - 1 do
- local item = _menu.items[i]
- if item then
- other = math.max(other, item[b])
- in_dir = in_dir + item[a]
- end
- end
- end
- local w, h = other, in_dir
- if dir == "x" then w, h = h, w end
- return w, h
-end
-
-
-local function set_coords(_menu, s, m_coords)
- local s_geometry = s.workarea
- local screen_w = s_geometry.x + s_geometry.width
- local screen_h = s_geometry.y + s_geometry.height
-
- _menu.width = _menu.wibox.width
- _menu.height = _menu.wibox.height
-
- _menu.x = _menu.wibox.x
- _menu.y = _menu.wibox.y
-
- if _menu.parent then
- local w, h = item_position(_menu.parent, _menu)
- w = w + _menu.parent.theme.border_width
-
- _menu.y = _menu.parent.y + h + _menu.height > screen_h and
- screen_h - _menu.height or _menu.parent.y + h
- _menu.x = _menu.parent.x + w + _menu.width > screen_w and
- _menu.parent.x - _menu.width or _menu.parent.x + w
- else
- if m_coords == nil then
- m_coords = capi.mouse.coords()
- m_coords.x = m_coords.x + 1
- m_coords.y = m_coords.y + 1
- end
- _menu.y = m_coords.y < s_geometry.y and s_geometry.y or m_coords.y
- _menu.x = m_coords.x < s_geometry.x and s_geometry.x or m_coords.x
-
- _menu.y = _menu.y + _menu.height > screen_h and
- screen_h - _menu.height or _menu.y
- _menu.x = _menu.x + _menu.width > screen_w and
- screen_w - _menu.width or _menu.x
- end
-
- _menu.wibox.x = _menu.x
- _menu.wibox.y = _menu.y
-end
-
-
-local function set_size(_menu)
- local in_dir, other, a, b = 0, 0, "height", "width"
- local dir = _menu.layout.dir or "y"
- if dir == "x" then a, b = b, a end
- for _, item in ipairs(_menu.items) do
- other = math.max(other, item[b])
- in_dir = in_dir + item[a]
- end
- _menu[a], _menu[b] = in_dir, other
- if in_dir > 0 and other > 0 then
- _menu.wibox[a] = in_dir
- _menu.wibox[b] = other
- return true
- end
- return false
-end
-
-
-local function check_access_key(_menu, key)
- for i, item in ipairs(_menu.items) do
- if item.akey == key then
- _menu:item_enter(i)
- _menu:exec(i, { exec = true })
- return
- end
- end
- if _menu.parent then
- check_access_key(_menu.parent, key)
- end
-end
-
-
-local function grabber(_menu, _, key, event)
- if event ~= "press" then return end
-
- local sel = _menu.sel or 0
- if util.table.hasitem(menu.menu_keys.up, key) then
- local sel_new = sel-1 < 1 and #_menu.items or sel-1
- _menu:item_enter(sel_new)
- elseif util.table.hasitem(menu.menu_keys.down, key) then
- local sel_new = sel+1 > #_menu.items and 1 or sel+1
- _menu:item_enter(sel_new)
- elseif sel > 0 and util.table.hasitem(menu.menu_keys.enter, key) then
- _menu:exec(sel)
- elseif sel > 0 and util.table.hasitem(menu.menu_keys.exec, key) then
- _menu:exec(sel, { exec = true })
- elseif util.table.hasitem(menu.menu_keys.back, key) then
- _menu:hide()
- elseif util.table.hasitem(menu.menu_keys.close, key) then
- menu.get_root(_menu):hide()
- else
- check_access_key(_menu, key)
- end
-end
-
-
-function menu:exec(num, opts)
- opts = opts or {}
- local item = self.items[num]
- if not item then return end
- local cmd = item.cmd
- if type(cmd) == "table" then
- local action = cmd.cmd
- if #cmd == 0 then
- if opts.exec and action and type(action) == "function" then
- action()
- end
- return
- end
- if not self.child[num] then
- self.child[num] = menu.new(cmd, self)
- end
- local can_invoke_action = opts.exec and
- action and type(action) == "function" and
- (not opts.mouse or (opts.mouse and (self.auto_expand or
- (self.active_child == self.child[num] and
- self.active_child.wibox.visible))))
- if can_invoke_action then
- local visible = action(self.child[num], item)
- if not visible then
- menu.get_root(self):hide()
- return
- else
- self.child[num]:update()
- end
- end
- if self.active_child and self.active_child ~= self.child[num] then
- self.active_child:hide()
- end
- self.active_child = self.child[num]
- if not self.active_child.wibox.visible then
- self.active_child:show()
- end
- elseif type(cmd) == "string" then
- menu.get_root(self):hide()
- spawn(cmd)
- elseif type(cmd) == "function" then
- local visible, action = cmd(item, self)
- if not visible then
- menu.get_root(self):hide()
- else
- self:update()
- if self.items[num] then
- self:item_enter(num, opts)
- end
- end
- if action and type(action) == "function" then
- action()
- end
- end
-end
-
-function menu:item_enter(num, opts)
- opts = opts or {}
- local item = self.items[num]
- if num == nil or self.sel == num or not item then
- return
- elseif self.sel then
- self:item_leave(self.sel)
- end
- --print("sel", num, menu.sel, item.theme.bg_focus)
- item._background:set_fg(item.theme.fg_focus)
- item._background:set_bg(item.theme.bg_focus)
- self.sel = num
-
- if self.auto_expand and opts.hover then
- if self.active_child then
- self.active_child:hide()
- self.active_child = nil
- end
-
- if type(item.cmd) == "table" then
- self:exec(num, opts)
- end
- end
-end
-
-
-function menu:item_leave(num)
- --print("leave", num)
- local item = self.items[num]
- if item then
- item._background:set_fg(item.theme.fg_normal)
- item._background:set_bg(item.theme.bg_normal)
- end
-end
-
-
---- Show a menu.
--- @param args The arguments
--- @param args.coords Menu position defaulting to mouse.coords()
-function menu:show(args)
- args = args or {}
- local coords = args.coords or nil
- local s = capi.screen[screen.focused()]
-
- if not set_size(self) then return end
- set_coords(self, s, coords)
-
- keygrabber.run(self._keygrabber)
- self.wibox.visible = true
-end
-
---- Hide a menu popup.
-function menu:hide()
- -- Remove items from screen
- for i = 1, #self.items do
- self:item_leave(i)
- end
- if self.active_child then
- self.active_child:hide()
- self.active_child = nil
- end
- self.sel = nil
-
- keygrabber.stop(self._keygrabber)
- self.wibox.visible = false
-end
-
---- Toggle menu visibility.
--- @param args The arguments
--- @param args.coords Menu position {x,y}
-function menu:toggle(args)
- if self.wibox.visible then
- self:hide()
- else
- self:show(args)
- end
-end
-
---- Update menu content
-function menu:update()
- if self.wibox.visible then
- self:show({ coords = { x = self.x, y = self.y } })
- end
-end
-
-
---- Get the elder parent so for example when you kill
--- it, it will destroy the whole family.
-function menu:get_root()
- return self.parent and menu.get_root(self.parent) or self
-end
-
---- Add a new menu entry.
--- args.* params needed for the menu entry constructor.
--- @param args The item params
--- @param args.new (Default: awful.menu.entry) The menu entry constructor.
--- @param[opt] args.theme The menu entry theme.
--- @param[opt] index The index where the new entry will inserted.
-function menu:add(args, index)
- if not args then return end
- local theme = load_theme(args.theme or {}, self.theme)
- args.theme = theme
- args.new = args.new or menu.entry
- local item = protected_call(args.new, self, args)
- if (not item) or (not item.widget) then
- print("Error while checking menu entry: no property widget found.")
- return
- end
- item.parent = self
- item.theme = item.theme or theme
- item.width = item.width or theme.width
- item.height = item.height or theme.height
- wibox.widget.base.check_widget(item.widget)
- item._background = wibox.container.background()
- item._background:set_widget(item.widget)
- item._background:set_fg(item.theme.fg_normal)
- item._background:set_bg(item.theme.bg_normal)
-
-
- -- Create bindings
- item._background:buttons(util.table.join(
- button({}, 3, function () self:hide() end),
- button({}, 1, function ()
- local num = util.table.hasitem(self.items, item)
- self:item_enter(num, { mouse = true })
- self:exec(num, { exec = true, mouse = true })
- end )))
-
-
- item._mouse = function ()
- local num = util.table.hasitem(self.items, item)
- self:item_enter(num, { hover = true, moue = true })
- end
- item.widget:connect_signal("mouse::enter", item._mouse)
-
- if index then
- self.layout:reset()
- table.insert(self.items, index, item)
- for _, i in ipairs(self.items) do
- self.layout:add(i._background)
- end
- else
- table.insert(self.items, item)
- self.layout:add(item._background)
- end
- if self.wibox then
- set_size(self)
- end
- return item
-end
-
---- Delete menu entry at given position
--- @param num The position in the table of the menu entry to be deleted; can be also the menu entry itself
-function menu:delete(num)
- if type(num) == "table" then
- num = util.table.hasitem(self.items, num)
- end
- local item = self.items[num]
- if not item then return end
- item.widget:disconnect_signal("mouse::enter", item._mouse)
- item.widget:set_visible(false)
- table.remove(self.items, num)
- if self.sel == num then
- self:item_leave(self.sel)
- self.sel = nil
- end
- self.layout:reset()
- for _, i in ipairs(self.items) do
- self.layout:add(i._background)
- end
- if self.child[num] then
- self.child[num]:hide()
- if self.active_child == self.child[num] then
- self.active_child = nil
- end
- table.remove(self.child, num)
- end
- if self.wibox then
- set_size(self)
- end
-end
-
---------------------------------------------------------------------------------
-
---- Build a popup menu with running clients and show it.
--- @tparam[opt] table args Menu table, see `new()` for more information.
--- @tparam[opt] table item_args Table that will be merged into each item, see
--- `new()` for more information.
--- @tparam[opt] func filter A function taking a client as an argument and
--- returning `true` or `false` to indicate whether the client should be
--- included in the menu.
--- @return The menu.
-function menu.clients(args, item_args, filter)
- local cls_t = {}
- for c in client_iterate(filter or function() return true end) do
- cls_t[#cls_t + 1] = {
- c.name or "",
- function ()
- if not c:isvisible() then
- tags.viewmore(c:tags(), c.screen)
- end
- c:emit_signal("request::activate", "menu.clients", {raise=true})
- end,
- c.icon }
- if item_args then
- if type(item_args) == "function" then
- util.table.merge(cls_t[#cls_t], item_args(c))
- else
- util.table.merge(cls_t[#cls_t], item_args)
- end
- end
- end
- args = args or {}
- args.items = args.items or {}
- util.table.merge(args.items, cls_t)
-
- local m = menu.new(args)
- m:show(args)
- return m
-end
-
---------------------------------------------------------------------------------
-
---- Default awful.menu.entry constructor
--- @param parent The parent menu (TODO: This is apparently unused)
--- @param args the item params
--- @return table with 'widget', 'cmd', 'akey' and all the properties the user wants to change
-function menu.entry(parent, args) -- luacheck: no unused args
- args = args or {}
- args.text = args[1] or args.text or ""
- args.cmd = args[2] or args.cmd
- args.icon = args[3] or args.icon
- local ret = {}
- -- Create the item label widget
- local label = wibox.widget.textbox()
- local key = ''
- label:set_font(args.theme.font)
- label:set_markup(string.gsub(
- util.escape(args.text), "&amp;(%w)",
- function (l)
- key = string.lower(l)
- return "<u>" .. l .. "</u>"
- end, 1))
- -- Set icon if needed
- local icon, iconbox
- local margin = wibox.container.margin()
- margin:set_widget(label)
- if args.icon then
- icon = surface.load(args.icon)
- end
- if icon then
- local iw = icon:get_width()
- local ih = icon:get_height()
- if iw > args.theme.width or ih > args.theme.height then
- local w, h
- if ((args.theme.height / ih) * iw) > args.theme.width then
- w, h = args.theme.height, (args.theme.height / iw) * ih
- else
- w, h = (args.theme.height / ih) * iw, args.theme.height
- end
- -- We need to scale the image to size w x h
- local img = cairo.ImageSurface(cairo.Format.ARGB32, w, h)
- local cr = cairo.Context(img)
- cr:scale(w / iw, h / ih)
- cr:set_source_surface(icon, 0, 0)
- cr:paint()
- icon = img
- end
- iconbox = wibox.widget.imagebox()
- if iconbox:set_image(icon) then
- margin:set_left(dpi(2))
- else
- iconbox = nil
- end
- end
- if not iconbox then
- margin:set_left(args.theme.height + dpi(2))
- end
- -- Create the submenu icon widget
- local submenu
- if type(args.cmd) == "table" then
- if args.theme.submenu_icon then
- submenu = wibox.widget.imagebox()
- submenu:set_image(args.theme.submenu_icon)
- else
- submenu = wibox.widget.textbox()
- submenu:set_font(args.theme.font)
- submenu:set_text(args.theme.submenu)
- end
- end
- -- Add widgets to the wibox
- local left = wibox.layout.fixed.horizontal()
- if iconbox then
- left:add(iconbox)
- end
- -- This contains the label
- left:add(margin)
-
- local layout = wibox.layout.align.horizontal()
- layout:set_left(left)
- if submenu then
- layout:set_right(submenu)
- end
-
- return table_update(ret, {
- label = label,
- sep = submenu,
- icon = iconbox,
- widget = layout,
- cmd = args.cmd,
- akey = key,
- })
-end
-
---------------------------------------------------------------------------------
-
---- Create a menu popup.
--- @param args Table containing the menu informations.
---
--- * Key items: Table containing the displayed items. Each element is a table by default (when element 'new' is awful.menu.entry) containing: item name, triggered action, submenu table or function, item icon (optional).
--- * Keys theme.[fg|bg]_[focus|normal], theme.border_color, theme.border_width, theme.submenu_icon, theme.height and theme.width override the default display for your menu and/or of your menu entry, each of them are optional.
--- * Key auto_expand controls the submenu auto expand behaviour by setting it to true (default) or false.
---
--- @param parent Specify the parent menu if we want to open a submenu, this value should never be set by the user.
--- @usage -- The following function builds and shows a menu of clients that match
--- -- a particular rule.
--- -- Bound to a key, it can be used to select from dozens of terminals open on
--- -- several tags.
--- -- When using @{rules.match_any} instead of @{rules.match},
--- -- a menu of clients with different classes could be build.
---
--- function terminal_menu ()
--- terms = {}
--- for i, c in pairs(client.get()) do
--- if awful.rules.match(c, {class = "URxvt"}) then
--- terms[i] =
--- {c.name,
--- function()
--- c.first_tag:view_only()
--- client.focus = c
--- end,
--- c.icon
--- }
--- end
--- end
--- awful.menu(terms):show()
--- end
-function menu.new(args, parent)
- args = args or {}
- args.layout = args.layout or wibox.layout.flex.vertical
- local _menu = table_update(object(), {
- item_enter = menu.item_enter,
- item_leave = menu.item_leave,
- get_root = menu.get_root,
- delete = menu.delete,
- update = menu.update,
- toggle = menu.toggle,
- hide = menu.hide,
- show = menu.show,
- exec = menu.exec,
- add = menu.add,
- child = {},
- items = {},
- parent = parent,
- layout = args.layout(),
- theme = load_theme(args.theme or {}, parent and parent.theme) })
-
- if parent then
- _menu.auto_expand = parent.auto_expand
- elseif args.auto_expand ~= nil then
- _menu.auto_expand = args.auto_expand
- else
- _menu.auto_expand = true
- end
-
- -- Create items
- for _, v in ipairs(args) do _menu:add(v) end
- if args.items then
- for _, v in pairs(args.items) do _menu:add(v) end
- end
-
- _menu._keygrabber = function (...)
- grabber(_menu, ...)
- end
-
- _menu.wibox = wibox({
- ontop = true,
- fg = _menu.theme.fg_normal,
- bg = _menu.theme.bg_normal,
- border_color = _menu.theme.border,
- border_width = _menu.theme.border_width,
- type = "popup_menu" })
- _menu.wibox.visible = false
- _menu.wibox:set_widget(_menu.layout)
- set_size(_menu)
-
- _menu.x = _menu.wibox.x
- _menu.y = _menu.wibox.y
- return _menu
-end
-
-function menu.mt:__call(...)
- return menu.new(...)
-end
-
-return setmetatable(menu, menu.mt)
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/mouse/drag_to_tag.lua b/awesome/lib/awful/mouse/drag_to_tag.lua
deleted file mode 100644
index 141456b..0000000
--- a/awesome/lib/awful/mouse/drag_to_tag.lua
+++ /dev/null
@@ -1,58 +0,0 @@
----------------------------------------------------------------------------
---- When the the mouse reach the end of the screen, then switch tag instead
--- of screens.
---
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2008 Julien Danjou
--- @submodule mouse
----------------------------------------------------------------------------
-
-local capi = {screen = screen, mouse = mouse}
-local util = require("awful.util")
-local tag = require("awful.tag")
-local resize = require("awful.mouse.resize")
-
-local module = {}
-
-function module.drag_to_tag(c)
- if (not c) or (not c.valid) then return end
-
- local coords = capi.mouse.coords()
-
- local dir = nil
-
- local wa = c.screen.workarea
-
- if coords.x >= wa.x + wa.width - 1 then
- capi.mouse.coords({ x = wa.x + 2 }, true)
- dir = "right"
- elseif coords.x <= wa.x + 1 then
- capi.mouse.coords({ x = wa.x + wa.width - 2 }, true)
- dir = "left"
- end
-
- local tags = c.screen.tags
- local t = c.screen.selected_tag
- local idx = t.index
-
- if dir then
-
- if dir == "right" then
- local newtag = tags[util.cycle(#tags, idx + 1)]
- c:move_to_tag(newtag)
- tag.viewnext()
- elseif dir == "left" then
- local newtag = tags[util.cycle(#tags, idx - 1)]
- c:move_to_tag(newtag)
- tag.viewprev()
- end
- end
-end
-
-resize.add_move_callback(function(c, _, _)
- if module.enabled then
- module.drag_to_tag(c)
- end
-end, "mouse.move")
-
-return setmetatable(module, {__call = function(_, ...) return module.drag_to_tag(...) end})
diff --git a/awesome/lib/awful/mouse/init.lua b/awesome/lib/awful/mouse/init.lua
deleted file mode 100644
index 03f7e89..0000000
--- a/awesome/lib/awful/mouse/init.lua
+++ /dev/null
@@ -1,437 +0,0 @@
----------------------------------------------------------------------------
---- Mouse module for awful
---
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2008 Julien Danjou
--- @module mouse
----------------------------------------------------------------------------
-
--- Grab environment we need
-local layout = require("awful.layout")
-local aplace = require("awful.placement")
-local util = require("awful.util")
-local type = type
-local ipairs = ipairs
-local capi =
-{
- root = root,
- mouse = mouse,
- screen = screen,
- client = client,
- mousegrabber = mousegrabber,
-}
-
-local mouse = {
- resize = require("awful.mouse.resize"),
- snap = require("awful.mouse.snap"),
- drag_to_tag = require("awful.mouse.drag_to_tag")
-}
-
-mouse.object = {}
-mouse.client = {}
-mouse.wibox = {}
-
---- The default snap distance.
--- @tfield integer awful.mouse.snap.default_distance
--- @tparam[opt=8] integer default_distance
--- @see awful.mouse.snap
-
---- Enable screen edges snapping.
--- @tfield[opt=true] boolean awful.mouse.snap.edge_enabled
-
---- Enable client to client snapping.
--- @tfield[opt=true] boolean awful.mouse.snap.client_enabled
-
---- Enable changing tag when a client is dragged to the edge of the screen.
--- @tfield[opt=false] integer awful.mouse.drag_to_tag.enabled
-
---- The snap outline background color.
--- @beautiful beautiful.snap_bg
--- @tparam color|string|gradient|pattern color
-
---- The snap outline width.
--- @beautiful beautiful.snap_border_width
--- @param integer
-
---- The snap outline shape.
--- @beautiful beautiful.snap_shape
--- @tparam function shape A `gears.shape` compatible function
-
---- Get the client object under the pointer.
--- @deprecated awful.mouse.client_under_pointer
--- @return The client object under the pointer, if one can be found.
--- @see current_client
-function mouse.client_under_pointer()
- util.deprecate("Use mouse.current_client instead of awful.mouse.client_under_pointer()")
-
- return mouse.object.get_current_client()
-end
-
---- Move a client.
--- @function awful.mouse.client.move
--- @param c The client to move, or the focused one if nil.
--- @param snap The pixel to snap clients.
--- @param finished_cb Deprecated, do not use
-function mouse.client.move(c, snap, finished_cb) --luacheck: no unused args
- if finished_cb then
- util.deprecate("The mouse.client.move `finished_cb` argument is no longer"..
- " used, please use awful.mouse.resize.add_leave_callback(f, 'mouse.move')")
- end
-
- c = c or capi.client.focus
-
- if not c
- or c.fullscreen
- or c.type == "desktop"
- or c.type == "splash"
- or c.type == "dock" then
- return
- end
-
- -- Compute the offset
- local coords = capi.mouse.coords()
- local geo = aplace.centered(capi.mouse,{parent=c, pretend=true})
-
- local offset = {
- x = geo.x - coords.x,
- y = geo.y - coords.y,
- }
-
- mouse.resize(c, "mouse.move", {
- placement = aplace.under_mouse,
- offset = offset,
- snap = snap
- })
-end
-
-mouse.client.dragtotag = { }
-
---- Move a client to a tag by dragging it onto the left / right side of the screen.
--- @deprecated awful.mouse.client.dragtotag.border
--- @param c The client to move
-function mouse.client.dragtotag.border(c)
- util.deprecate("Use awful.mouse.snap.drag_to_tag_enabled = true instead "..
- "of awful.mouse.client.dragtotag.border(c). It will now be enabled.")
-
- -- Enable drag to border
- mouse.snap.drag_to_tag_enabled = true
-
- return mouse.client.move(c)
-end
-
---- Move the wibox under the cursor.
--- @function awful.mouse.wibox.move
---@tparam wibox w The wibox to move, or none to use that under the pointer
-function mouse.wibox.move(w)
- w = w or mouse.wibox_under_pointer()
- if not w then return end
-
- if not w
- or w.type == "desktop"
- or w.type == "splash"
- or w.type == "dock" then
- return
- end
-
- -- Compute the offset
- local coords = capi.mouse.coords()
- local geo = aplace.centered(capi.mouse,{parent=w, pretend=true})
-
- local offset = {
- x = geo.x - coords.x,
- y = geo.y - coords.y,
- }
-
- mouse.resize(w, "mouse.move", {
- placement = aplace.under_mouse,
- offset = offset
- })
-end
-
---- Get a client corner coordinates.
--- @deprecated awful.mouse.client.corner
--- @tparam[opt=client.focus] client c The client to get corner from, focused one by default.
--- @tparam string corner The corner to use: auto, top_left, top_right, bottom_left,
--- bottom_right, left, right, top bottom. Default is auto, and auto find the
--- nearest corner.
--- @treturn string The corner name
--- @treturn number x The horizontal position
--- @treturn number y The vertical position
-function mouse.client.corner(c, corner)
- util.deprecate(
- "Use awful.placement.closest_corner(mouse) or awful.placement[corner](mouse)"..
- " instead of awful.mouse.client.corner"
- )
-
- c = c or capi.client.focus
- if not c then return end
-
- local ngeo = nil
-
- if (not corner) or corner == "auto" then
- ngeo, corner = aplace.closest_corner(mouse, {parent = c})
- elseif corner and aplace[corner] then
- ngeo = aplace[corner](mouse, {parent = c})
- end
-
- return corner, ngeo and ngeo.x or nil, ngeo and ngeo.y or nil
-end
-
---- Resize a client.
--- @function awful.mouse.client.resize
--- @param c The client to resize, or the focused one by default.
--- @tparam string corner The corner to grab on resize. Auto detected by default.
--- @tparam[opt={}] table args A set of `awful.placement` arguments
--- @treturn string The corner (or side) name
-function mouse.client.resize(c, corner, args)
- c = c or capi.client.focus
-
- if not c then return end
-
- if c.fullscreen
- or c.type == "desktop"
- or c.type == "splash"
- or c.type == "dock" then
- return
- end
-
- -- Set some default arguments
- local new_args = setmetatable(
- {
- include_sides = (not args) or args.include_sides ~= false
- },
- {
- __index = args or {}
- }
- )
-
- -- Move the mouse to the corner
- if corner and aplace[corner] then
- aplace[corner](capi.mouse, {parent=c})
- else
- local _
- _, corner = aplace.closest_corner(capi.mouse, {
- parent = c,
- include_sides = new_args.include_sides ~= false,
- })
- end
-
- new_args.corner = corner
-
- mouse.resize(c, "mouse.resize", new_args)
-
- return corner
-end
-
---- Default handler for `request::geometry` signals with "mouse.resize" context.
--- @signalhandler awful.mouse.resize_handler
--- @tparam client c The client
--- @tparam string context The context
--- @tparam[opt={}] table hints The hints to pass to the handler
-function mouse.resize_handler(c, context, hints)
- if hints and context and context:find("mouse.*") then
- -- This handler only handle the floating clients. If the client is tiled,
- -- then it let the layouts handle it.
- local t = c.screen.selected_tag
- local lay = t and t.layout or nil
-
- if (lay and lay == layout.suit.floating) or c.floating then
- c:geometry {
- x = hints.x,
- y = hints.y,
- width = hints.width,
- height = hints.height,
- }
- elseif lay and lay.resize_handler then
- lay.resize_handler(c, context, hints)
- end
- end
-end
-
--- Older layouts implement their own mousegrabber.
--- @tparam client c The client
--- @tparam table args Additional arguments
--- @treturn boolean This return false when the resize need to be aborted
-mouse.resize.add_enter_callback(function(c, args) --luacheck: no unused args
- if c.floating then return end
-
- local l = c.screen.selected_tag and c.screen.selected_tag.layout or nil
- if l == layout.suit.floating then return end
-
- if l ~= layout.suit.floating and l.mouse_resize_handler then
- capi.mousegrabber.stop()
-
- local geo, corner = aplace.closest_corner(capi.mouse, {parent=c})
-
- l.mouse_resize_handler(c, corner, geo.x, geo.y)
-
- return false
- end
-end, "mouse.resize")
-
---- Get the client currently under the mouse cursor.
--- @property current_client
--- @tparam client|nil The client
-
-function mouse.object.get_current_client()
- local obj = capi.mouse.object_under_pointer()
- if type(obj) == "client" then
- return obj
- end
-end
-
---- Get the wibox currently under the mouse cursor.
--- @property current_wibox
--- @tparam wibox|nil The wibox
-
-function mouse.object.get_current_wibox()
- local obj = capi.mouse.object_under_pointer()
- if type(obj) == "drawin" and obj.get_wibox then
- return obj:get_wibox()
- end
-end
-
---- Get the widgets currently under the mouse cursor.
---
--- @property current_widgets
--- @tparam nil|table list The widget list
--- @treturn table The list of widgets.The first element is the biggest
--- container while the last is the topmost widget. The table contains *x*, *y*,
--- *width*, *height* and *widget*.
--- @see wibox.find_widgets
-
-function mouse.object.get_current_widgets()
- local w = mouse.object.get_current_wibox()
- if w then
- local geo, coords = w:geometry(), capi.mouse:coords()
-
- local list = w:find_widgets(coords.x - geo.x, coords.y - geo.y)
-
- local ret = {}
-
- for k, v in ipairs(list) do
- ret[k] = v.widget
- end
-
- return ret, list
- end
-end
-
---- Get the topmost widget currently under the mouse cursor.
--- @property current_widget
--- @tparam widget|nil widget The widget
--- @treturn ?widget The widget
--- @see wibox.find_widgets
--- @see current_widget_geometry
-
-function mouse.object.get_current_widget()
- local wdgs, geos = mouse.object.get_current_widgets()
-
- if wdgs then
- return wdgs[#wdgs], geos[#geos]
- end
-end
-
---- Get the current widget geometry.
--- @property current_widget_geometry
--- @tparam ?table The geometry.
--- @see current_widget
-
-function mouse.object.get_current_widget_geometry()
- local _, ret = mouse.object.get_current_widget()
-
- return ret
-end
-
---- Get the current widget geometries.
--- @property current_widget_geometries
--- @tparam ?table A list of geometry tables.
--- @see current_widgets
-
-function mouse.object.get_current_widget_geometries()
- local _, ret = mouse.object.get_current_widgets()
-
- return ret
-end
-
---- True if the left mouse button is pressed.
--- @property is_left_mouse_button_pressed
--- @param boolean
-
---- True if the right mouse button is pressed.
--- @property is_right_mouse_button_pressed
--- @param boolean
-
---- True if the middle mouse button is pressed.
--- @property is_middle_mouse_button_pressed
--- @param boolean
-
-for _, b in ipairs {"left", "right", "middle"} do
- mouse.object["is_".. b .."_mouse_button_pressed"] = function()
- return capi.mouse.coords().buttons[1]
- end
-end
-
-capi.client.connect_signal("request::geometry", mouse.resize_handler)
-
--- Set the cursor at startup
-capi.root.cursor("left_ptr")
-
--- Implement the custom property handler
-local props = {}
-
-capi.mouse.set_newindex_miss_handler(function(_,key,value)
- if mouse.object["set_"..key] then
- mouse.object["set_"..key](value)
- elseif not mouse.object["get_"..key] then
- props[key] = value
- else
- -- If there is a getter, but no setter, then the property is read-only
- error("Cannot set '" .. tostring(key) .. " because it is read-only")
- end
-end)
-
-capi.mouse.set_index_miss_handler(function(_,key)
- if mouse.object["get_"..key] then
- return mouse.object["get_"..key]()
- else
- return props[key]
- end
-end)
-
---- Get or set the mouse coords.
---
---
---
---![Usage example](../images/AUTOGEN_awful_mouse_coords.svg)
---
---**Usage example output**:
---
--- 235
---
---
--- @usage
--- -- Get the position
---print(mouse.coords().x)
--- -- Change the position
---mouse.coords {
--- x = 185,
--- y = 10
---}
---
--- @tparam[opt=nil] table coords_table None or a table with x and y keys as mouse
--- coordinates.
--- @tparam[opt=nil] integer coords_table.x The mouse horizontal position
--- @tparam[opt=nil] integer coords_table.y The mouse vertical position
--- @tparam[opt=false] boolean silent Disable mouse::enter or mouse::leave events that
--- could be triggered by the pointer when moving.
--- @treturn integer table.x The horizontal position
--- @treturn integer table.y The vertical position
--- @treturn table table.buttons Table containing the status of buttons, e.g. field [1] is true
--- when button 1 is pressed.
--- @function mouse.coords
-
-
-return mouse
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/mouse/resize.lua b/awesome/lib/awful/mouse/resize.lua
deleted file mode 100644
index edd278d..0000000
--- a/awesome/lib/awful/mouse/resize.lua
+++ /dev/null
@@ -1,229 +0,0 @@
----------------------------------------------------------------------------
---- An extandable mouse resizing handler.
---
--- This module offer a resizing and moving mechanism for drawable such as
--- clients and wiboxes.
---
--- @author Emmanuel Lepage Vallee &lt;elv1313@gmail.com&gt;
--- @copyright 2016 Emmanuel Lepage Vallee
--- @submodule mouse
----------------------------------------------------------------------------
-
-local aplace = require("awful.placement")
-local capi = {mousegrabber = mousegrabber}
-local beautiful = require("beautiful")
-
-local module = {}
-
-local mode = "live"
-local req = "request::geometry"
-local callbacks = {enter={}, move={}, leave={}}
-
-local cursors = {
- ["mouse.move" ] = "fleur",
- ["mouse.resize" ] = "cross",
- ["mouse.resize_left" ] = "sb_h_double_arrow",
- ["mouse.resize_right" ] = "sb_h_double_arrow",
- ["mouse.resize_top" ] = "sb_v_double_arrow",
- ["mouse.resize_bottom" ] = "sb_v_double_arrow",
- ["mouse.resize_top_left" ] = "top_left_corner",
- ["mouse.resize_top_right" ] = "top_right_corner",
- ["mouse.resize_bottom_left" ] = "bottom_left_corner",
- ["mouse.resize_bottom_right"] = "bottom_right_corner",
-}
-
---- The resize cursor name.
--- @beautiful beautiful.cursor_mouse_resize
--- @tparam[opt=cross] string cursor
-
---- The move cursor name.
--- @beautiful beautiful.cursor_mouse_move
--- @tparam[opt=fleur] string cursor
-
---- Set the resize mode.
--- The available modes are:
---
--- * **live**: Resize the layout everytime the mouse move
--- * **after**: Resize the layout only when the mouse is released
---
--- Some clients, such as XTerm, may lose information if resized too often.
---
--- @function awful.mouse.resize.set_mode
--- @tparam string m The mode
-function module.set_mode(m)
- assert(m == "live" or m == "after")
- mode = m
-end
-
---- Add an initialization callback.
--- This callback will be executed before the mouse grabbing starts.
--- @function awful.mouse.resize.add_enter_callback
--- @tparam function cb The callback (or nil)
--- @tparam[default=other] string context The callback context
-function module.add_enter_callback(cb, context)
- context = context or "other"
- callbacks.enter[context] = callbacks.enter[context] or {}
- table.insert(callbacks.enter[context], cb)
-end
-
---- Add a "move" callback.
--- This callback is executed in "after" mode (see `set_mode`) instead of
--- applying the operation.
--- @function awful.mouse.resize.add_move_callback
--- @tparam function cb The callback (or nil)
--- @tparam[default=other] string context The callback context
-function module.add_move_callback(cb, context)
- context = context or "other"
- callbacks.move[context] = callbacks.move[context] or {}
- table.insert(callbacks.move[context], cb)
-end
-
---- Add a "leave" callback
--- This callback is executed just before the `mousegrabber` stop
--- @function awful.mouse.resize.add_leave_callback
--- @tparam function cb The callback (or nil)
--- @tparam[default=other] string context The callback context
-function module.add_leave_callback(cb, context)
- context = context or "other"
- callbacks.leave[context] = callbacks.leave[context] or {}
- table.insert(callbacks.leave[context], cb)
-end
-
--- Resize, the drawable.
---
--- Valid `args` are:
---
--- * *enter_callback*: A function called before the `mousegrabber` start
--- * *move_callback*: A function called when the mouse move
--- * *leave_callback*: A function called before the `mousegrabber` is released
--- * *mode*: The resize mode
---
--- @function awful.mouse.resize
--- @tparam client client A client
--- @tparam[default=mouse.resize] string context The resizing context
--- @tparam[opt={}] table args A set of `awful.placement` arguments
-
-local function handler(_, client, context, args) --luacheck: no unused_args
- args = args or {}
- context = context or "mouse.resize"
-
- local placement = args.placement
-
- if type(placement) == "string" and aplace[placement] then
- placement = aplace[placement]
- end
-
- -- Extend the table with the default arguments
- args = setmetatable(
- {
- placement = placement or aplace.resize_to_mouse,
- mode = args.mode or mode,
- pretend = true,
- },
- {__index = args or {}}
- )
-
- local geo
-
- for _, cb in ipairs(callbacks.enter[context] or {}) do
- geo = cb(client, args)
-
- if geo == false then
- return false
- end
- end
-
- if args.enter_callback then
- geo = args.enter_callback(client, args)
-
- if geo == false then
- return false
- end
- end
-
- geo = nil
-
- -- Select the cursor
- local tcontext = context:gsub('[.]', '_')
- local corner = args.corner and ("_".. args.corner) or ""
-
- local cursor = beautiful["cursor_"..tcontext]
- or cursors[context..corner]
- or cursors[context]
- or "fleur"
-
- -- Execute the placement function and use request::geometry
- capi.mousegrabber.run(function (_mouse)
- if not client.valid then return end
-
- -- Resize everytime the mouse move (default behavior)
- if args.mode == "live" then
- -- Get the new geometry
- geo = setmetatable(args.placement(client, args),{__index=args})
- end
-
- -- Execute the move callbacks. This can be used to add features such as
- -- snap or adding fancy graphical effects.
- for _, cb in ipairs(callbacks.move[context] or {}) do
- -- If something is returned, assume it is a modified geometry
- geo = cb(client, geo, args) or geo
-
- if geo == false then
- return false
- end
- end
-
- if args.move_callback then
- geo = args.move_callback(client, geo, args)
-
- if geo == false then
- return false
- end
- end
-
- -- In case it was modified
- setmetatable(geo,{__index=args})
-
- if args.mode == "live" then
- -- Ask the resizing handler to resize the client
- client:emit_signal( req, context, geo)
- end
-
- -- Quit when the button is released
- for _,v in pairs(_mouse.buttons) do
- if v then return true end
- end
-
- -- Only resize after the mouse is released, this avoid losing content
- -- in resize sensitive apps such as XTerm or allow external modules
- -- to implement custom resizing.
- if args.mode == "after" then
- -- Get the new geometry
- geo = args.placement(client, args)
-
- -- Ask the resizing handler to resize the client
- client:emit_signal( req, context, geo)
- end
-
- geo = nil
-
- for _, cb in ipairs(callbacks.leave[context] or {}) do
- geo = cb(client, geo, args)
- end
-
- if args.leave_callback then
- geo = args.leave_callback(client, geo, args)
- end
-
- if not geo then return false end
-
- -- In case it was modified
- setmetatable(geo,{__index=args})
-
- client:emit_signal( req, context, geo)
-
- return false
- end, cursor)
-end
-
-return setmetatable(module, {__call=handler})
diff --git a/awesome/lib/awful/mouse/snap.lua b/awesome/lib/awful/mouse/snap.lua
deleted file mode 100644
index 048a679..0000000
--- a/awesome/lib/awful/mouse/snap.lua
+++ /dev/null
@@ -1,266 +0,0 @@
----------------------------------------------------------------------------
---- Mouse snapping related functions
---
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2008 Julien Danjou
--- @submodule mouse
----------------------------------------------------------------------------
-
-local aclient = require("awful.client")
-local resize = require("awful.mouse.resize")
-local aplace = require("awful.placement")
-local wibox = require("wibox")
-local beautiful = require("beautiful")
-local color = require("gears.color")
-local shape = require("gears.shape")
-local cairo = require("lgi").cairo
-
-local capi = {
- root = root,
- mouse = mouse,
- screen = screen,
- client = client,
- mousegrabber = mousegrabber,
-}
-
-local module = {
- default_distance = 8
-}
-
-local placeholder_w = nil
-
-local function show_placeholder(geo)
- if not geo then
- if placeholder_w then
- placeholder_w.visible = false
- end
- return
- end
-
- placeholder_w = placeholder_w or wibox {
- ontop = true,
- bg = color(beautiful.snap_bg or beautiful.bg_urgent or "#ff0000"),
- }
-
- placeholder_w:geometry(geo)
-
- local img = cairo.ImageSurface(cairo.Format.A1, geo.width, geo.height)
- local cr = cairo.Context(img)
-
- cr:set_operator(cairo.Operator.CLEAR)
- cr:set_source_rgba(0,0,0,1)
- cr:paint()
- cr:set_operator(cairo.Operator.SOURCE)
- cr:set_source_rgba(1,1,1,1)
-
- local line_width = beautiful.snap_border_width or 5
- cr:set_line_width(beautiful.xresources.apply_dpi(line_width))
-
- local f = beautiful.snap_shape or function()
- cr:translate(line_width,line_width)
- shape.rounded_rect(cr,geo.width-2*line_width,geo.height-2*line_width, 10)
- end
-
- f(cr, geo.width, geo.height)
-
- cr:stroke()
-
- placeholder_w.shape_bounding = img._native
-
- placeholder_w.visible = true
-end
-
-local function build_placement(snap, axis)
- return aplace.scale
- + aplace[snap]
- + (
- axis and aplace["maximize_"..axis] or nil
- )
-end
-
-local function detect_screen_edges(c, snap)
- local coords = capi.mouse.coords()
-
- local sg = c.screen.geometry
-
- local v, h = nil
-
- if math.abs(coords.x) <= snap + sg.x and coords.x >= sg.x then
- h = "left"
- elseif math.abs((sg.x + sg.width) - coords.x) <= snap then
- h = "right"
- end
-
- if math.abs(coords.y) <= snap + sg.y and coords.y >= sg.y then
- v = "top"
- elseif math.abs((sg.y + sg.height) - coords.y) <= snap then
- v = "bottom"
- end
-
- return v, h
-end
-
-local current_snap, current_axis = nil
-
-local function detect_areasnap(c, distance)
- local old_snap = current_snap
- local v, h = detect_screen_edges(c, distance)
-
- if v and h then
- current_snap = v.."_"..h
- else
- current_snap = v or h or nil
- end
-
- if old_snap == current_snap then return end
-
- current_axis = ((v and not h) and "horizontally")
- or ((h and not v) and "vertically")
- or nil
-
- -- Show the expected geometry outline
- show_placeholder(
- current_snap and build_placement(current_snap, current_axis)(c, {
- to_percent = 0.5,
- honor_workarea = true,
- pretend = true
- }) or nil
- )
-
-end
-
-local function apply_areasnap(c, args)
- if not current_snap then return end
-
- -- Remove the move offset
- args.offset = {}
-
- placeholder_w.visible = false
-
- return build_placement(current_snap, current_axis)(c,{
- to_percent = 0.5,
- honor_workarea = true,
- })
-end
-
-local function snap_outside(g, sg, snap)
- if g.x < snap + sg.x + sg.width and g.x > sg.x + sg.width then
- g.x = sg.x + sg.width
- elseif g.x + g.width < sg.x and g.x + g.width > sg.x - snap then
- g.x = sg.x - g.width
- end
- if g.y < snap + sg.y + sg.height and g.y > sg.y + sg.height then
- g.y = sg.y + sg.height
- elseif g.y + g.height < sg.y and g.y + g.height > sg.y - snap then
- g.y = sg.y - g.height
- end
- return g
-end
-
-local function snap_inside(g, sg, snap)
- local edgev = 'none'
- local edgeh = 'none'
- if math.abs(g.x) < snap + sg.x and g.x > sg.x then
- edgev = 'left'
- g.x = sg.x
- elseif math.abs((sg.x + sg.width) - (g.x + g.width)) < snap then
- edgev = 'right'
- g.x = sg.x + sg.width - g.width
- end
- if math.abs(g.y) < snap + sg.y and g.y > sg.y then
- edgeh = 'top'
- g.y = sg.y
- elseif math.abs((sg.y + sg.height) - (g.y + g.height)) < snap then
- edgeh = 'bottom'
- g.y = sg.y + sg.height - g.height
- end
-
- -- What is the dominant dimension?
- if g.width > g.height then
- return g, edgeh
- else
- return g, edgev
- end
-end
-
---- Snap a client to the closest client or screen edge.
--- @function awful.mouse.snap
--- @param c The client to snap.
--- @param snap The pixel to snap clients.
--- @param x The client x coordinate.
--- @param y The client y coordinate.
--- @param fixed_x True if the client isn't allowed to move in the x direction.
--- @param fixed_y True if the client isn't allowed to move in the y direction.
-function module.snap(c, snap, x, y, fixed_x, fixed_y)
- snap = snap or module.default_distance
- c = c or capi.client.focus
- local cur_geom = c:geometry()
- local geom = c:geometry()
- geom.width = geom.width + (2 * c.border_width)
- geom.height = geom.height + (2 * c.border_width)
- local edge
- geom.x = x or geom.x
- geom.y = y or geom.y
-
- geom, edge = snap_inside(geom, c.screen.geometry, snap)
- geom = snap_inside(geom, c.screen.workarea, snap)
-
- -- Allow certain windows to snap to the edge of the workarea.
- -- Only allow docking to workarea for consistency/to avoid problems.
- if c.dockable then
- local struts = c:struts()
- struts['left'] = 0
- struts['right'] = 0
- struts['top'] = 0
- struts['bottom'] = 0
- if edge ~= "none" and c.floating then
- if edge == "left" or edge == "right" then
- struts[edge] = cur_geom.width
- elseif edge == "top" or edge == "bottom" then
- struts[edge] = cur_geom.height
- end
- end
- c:struts(struts)
- end
-
- for _, snapper in ipairs(aclient.visible(c.screen)) do
- if snapper ~= c then
- local snapper_geom = snapper:geometry()
- snapper_geom.width = snapper_geom.width + (2 * snapper.border_width)
- snapper_geom.height = snapper_geom.height + (2 * snapper.border_width)
- geom = snap_outside(geom, snapper_geom, snap)
- end
- end
-
- geom.width = geom.width - (2 * c.border_width)
- geom.height = geom.height - (2 * c.border_width)
-
- -- It's easiest to undo changes afterwards if they're not allowed
- if fixed_x then geom.x = cur_geom.x end
- if fixed_y then geom.y = cur_geom.y end
-
- return geom
-end
-
--- Enable edge snapping
-resize.add_move_callback(function(c, geo, args)
- -- Screen edge snapping (areosnap)
- if (module.edge_enabled ~= false)
- and args and (args.snap == nil or args.snap) then
- detect_areasnap(c, 16)
- end
-
- -- Snapping between clients
- if (module.client_enabled ~= false)
- and args and (args.snap == nil or args.snap) then
- return module.snap(c, args.snap, geo.x, geo.y)
- end
-end, "mouse.move")
-
--- Apply the aerosnap
-resize.add_leave_callback(function(c, _, args)
- if module.edge_enabled == false then return end
- return apply_areasnap(c, args)
-end, "mouse.move")
-
-return setmetatable(module, {__call = function(_, ...) return module.snap(...) end})
diff --git a/awesome/lib/awful/placement.lua b/awesome/lib/awful/placement.lua
deleted file mode 100644
index d288f49..0000000
--- a/awesome/lib/awful/placement.lua
+++ /dev/null
@@ -1,1694 +0,0 @@
----------------------------------------------------------------------------
---- Algorithms used to place various drawables.
---
--- The functions provided by this module all follow the same arguments
--- conventions. This allow:
---
--- * To use them in various other module as
--- [visitor objects](https://en.wikipedia.org/wiki/Visitor_pattern)
--- * Turn each function into an API with various common customization parameters.
--- * Re-use the same functions for the `mouse`, `client`s, `screen`s and `wibox`es
---
---
--- <h3>Compositing</h3>
---
--- It is possible to compose placement function using the `+` or `*` operator:
---
---
---
---![Usage example](../images/AUTOGEN_awful_placement_compose.svg)
---
---
--- -- 'right' will be replaced by 'left'
--- local f = (awful.placement.right + awful.placement.left)
--- f(client.focus)
---
---
---
---![Usage example](../images/AUTOGEN_awful_placement_compose2.svg)
---
---
--- -- Simulate Windows 7 'edge snap' (also called aero snap) feature
--- local axis = 'vertically'
--- local f = awful.placement.scale
--- + awful.placement.left
--- + (axis and awful.placement['maximize_'..axis] or nil)
--- local geo = f(client.focus, {honor_workarea=true, to_percent = 0.5})
---
--- <h3>Common arguments</h3>
---
--- **pretend** (*boolean*):
---
--- Do not apply the new geometry. This is useful if only the return values is
--- necessary.
---
--- **honor_workarea** (*boolean*):
---
--- Take workarea into account when placing the drawable (default: false)
---
--- **honor_padding** (*boolean*):
---
--- Take the screen padding into account (see `screen.padding`)
---
--- **tag** (*tag*):
---
--- Use a tag geometry
---
--- **margins** (*number* or *table*):
---
--- A table with left, right, top, bottom keys or a number
---
--- **parent** (client, wibox, mouse or screen):
---
--- A parent drawable to use a base geometry
---
--- **bounding_rect** (table):
---
--- A bounding rectangle
---
--- **attach** (*boolean*):
---
--- When the parent geometry (like the screen) changes, re-apply the placement
--- function. This will add a `detach_callback` function to the drawable. Call
--- this to detach the function. This will be called automatically when a new
--- attached function is set.
---
--- **offset** (*table or number*):
---
--- The offset(s) to apply to the new geometry.
---
--- **store_geometry** (*boolean*):
---
--- Keep a single history of each type of placement. It can be restored using
--- `awful.placement.restore` by setting the right `context` argument.
---
--- When either the parent or the screen geometry change, call the placement
--- function again.
---
--- **update_workarea** (*boolean*):
---
--- If *attach* is true, also update the screen workarea.
---
--- @author Emmanuel Lepage Vallee &lt;elv1313@gmail.com&gt;
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2008 Julien Danjou, Emmanuel Lepage Vallee 2016
--- @module awful.placement
----------------------------------------------------------------------------
-
--- Grab environment we need
-local ipairs = ipairs
-local pairs = pairs
-local math = math
-local table = table
-local capi =
-{
- screen = screen,
- mouse = mouse,
- client = client
-}
-local client = require("awful.client")
-local layout = require("awful.layout")
-local a_screen = require("awful.screen")
-local grect = require("gears.geometry").rectangle
-local util = require("awful.util")
-local cairo = require( "lgi" ).cairo
-local unpack = unpack or table.unpack -- luacheck: globals unpack (compatibility with Lua 5.1)
-
-local function get_screen(s)
- return s and capi.screen[s]
-end
-
-local wrap_client = nil
-local placement
-
--- Store function -> keys
-local reverse_align_map = {}
-
--- Forward declarations
-local area_common
-local wibox_update_strut
-local attach
-
---- Allow multiple placement functions to be daisy chained.
--- This also allow the functions to be aware they are being chained and act
--- upon the previous nodes results to avoid unnecessary processing or deduce
--- extra paramaters/arguments.
-local function compose(...)
- local queue = {}
-
- local nodes = {...}
-
- -- Allow placement.foo + (var == 42 and placement.bar)
- if not nodes[2] then
- return nodes[1]
- end
-
- -- nodes[1] == self, nodes[2] == other
- for _, w in ipairs(nodes) do
- -- Build an execution queue
- if w.context and w.context == "compose" then
- for _, elem in ipairs(w.queue or {}) do
- table.insert(queue, elem)
- end
- else
- table.insert(queue, w)
- end
- end
-
- local ret
- ret = wrap_client(function(d, args, ...)
- local rets = {}
- local last_geo = nil
-
- -- As some functions may have to take into account results from
- -- previously execued ones, add the `composition_results` hint.
- args = setmetatable({composition_results=rets}, {__index=args})
-
- -- Only apply the geometry once, not once per chain node, to do this,
- -- Force the "pretend" argument and restore the original value for
- -- the last node.
- local attach_real = args.attach
- args.pretend = true
- args.attach = false
- args.offset = {}
-
- for k, f in ipairs(queue) do
- if k == #queue then
- -- Let them fallback to the parent table
- args.pretend = nil
- args.offset = nil
- end
-
- local r = {f(d, args, ...)}
- last_geo = r[1] or last_geo
- args.override_geometry = last_geo
-
- -- Keep the return value, store one per context
- if f.context then
- -- When 2 composition queue are executed, merge the return values
- if f.context == "compose" then
- for k2,v in pairs(r) do
- rets[k2] = v
- end
- else
- rets[f.context] = r
- end
- end
- end
-
- if attach_real then
- args.attach = true
- attach(d, ret, args)
- end
-
- return last_geo, rets
- end, "compose")
-
- ret.queue = queue
-
- return ret
-end
-
-wrap_client = function(f, context)
- return setmetatable(
- {
- is_placement= true,
- context = context,
- },
- {
- __call = function(_,...) return f(...) end,
- __add = compose, -- Composition is usually defined as +
- __mul = compose -- Make sense if you think of the functions as matrices
- }
- )
-end
-
-local placement_private = {}
-
--- The module is a proxy in front of the "real" functions.
--- This allow syntax like:
---
--- (awful.placement.no_overlap + awful.placement.no_offscreen)(c)
---
-placement = setmetatable({}, {
- __index = placement_private,
- __newindex = function(_, k, f)
- placement_private[k] = wrap_client(f, k)
- end
-})
-
--- 3x3 matrix of the valid sides and corners
-local corners3x3 = {{"top_left" , "top" , "top_right" },
- {"left" , nil , "right" },
- {"bottom_left", "bottom" , "bottom_right"}}
-
--- 2x2 matrix of the valid sides and corners
-local corners2x2 = {{"top_left" , "top_right" },
- {"bottom_left", "bottom_right"}}
-
--- Compute the new `x` and `y`.
--- The workarea position need to be applied by the caller
-local align_map = {
- top_left = function(_ , _ , _ , _ ) return {x=0 , y=0 } end,
- top_right = function(sw, _ , dw, _ ) return {x=sw-dw , y=0 } end,
- bottom_left = function(_ , sh, _ , dh) return {x=0 , y=sh-dh } end,
- bottom_right = function(sw, sh, dw, dh) return {x=sw-dw , y=sh-dh } end,
- left = function(_ , sh, _ , dh) return {x=0 , y=sh/2-dh/2} end,
- right = function(sw, sh, dw, dh) return {x=sw-dw , y=sh/2-dh/2} end,
- top = function(sw, _ , dw, _ ) return {x=sw/2-dw/2, y=0 } end,
- bottom = function(sw, sh, dw, dh) return {x=sw/2-dw/2, y=sh-dh } end,
- centered = function(sw, sh, dw, dh) return {x=sw/2-dw/2, y=sh/2-dh/2} end,
- center_vertical = function(_ , sh, _ , dh) return {x= nil , y=sh-dh } end,
- center_horizontal = function(sw, _ , dw, _ ) return {x=sw/2-dw/2, y= nil } end,
-}
-
--- Some parameters to correctly compute the final size
-local resize_to_point_map = {
- -- Corners
- top_left = {p1= nil , p2={1,1}, x_only=false, y_only=false, align="bottom_right"},
- top_right = {p1={0,1} , p2= nil , x_only=false, y_only=false, align="bottom_left" },
- bottom_left = {p1= nil , p2={1,0}, x_only=false, y_only=false, align="top_right" },
- bottom_right = {p1={0,0} , p2= nil , x_only=false, y_only=false, align="top_left" },
-
- -- Sides
- left = {p1= nil , p2={1,1}, x_only=true , y_only=false, align="top_right" },
- right = {p1={0,0} , p2= nil , x_only=true , y_only=false, align="top_left" },
- top = {p1= nil , p2={1,1}, x_only=false, y_only=true , align="bottom_left" },
- bottom = {p1={0,0} , p2= nil , x_only=false, y_only=true , align="top_left" },
-}
-
--- Outer position matrix
--- 1=best case, 2=fallback
-local outer_positions = {
- left1 = function(r, w, _) return {x=r.x-w , y=r.y }, "down" end,
- left2 = function(r, w, h) return {x=r.x-w , y=r.y-h+r.height }, "up" end,
- right1 = function(r, _, _) return {x=r.x , y=r.y }, "down" end,
- right2 = function(r, _, h) return {x=r.x , y=r.y-h+r.height }, "up" end,
- top1 = function(r, _, h) return {x=r.x , y=r.y-h }, "right" end,
- top2 = function(r, w, h) return {x=r.x-w+r.width, y=r.y-h }, "left" end,
- bottom1 = function(r, _, _) return {x=r.x , y=r.y }, "right" end,
- bottom2 = function(r, w, _) return {x=r.x-w+r.width, y=r.y }, "left" end,
-}
-
---- Add a context to the arguments.
--- This function extend the argument table. The context is used by some
--- internal helper methods. If there already is a context, it has priority and
--- is kept.
-local function add_context(args, context)
- return setmetatable({context = (args or {}).context or context }, {__index=args})
-end
-
-local data = setmetatable({}, { __mode = 'k' })
-
---- Store a drawable geometry (per context) in a weak table.
--- @param d The drawin
--- @tparam string reqtype The context.
-local function store_geometry(d, reqtype)
- if not data[d] then data[d] = {} end
- if not data[d][reqtype] then data[d][reqtype] = {} end
- data[d][reqtype] = d:geometry()
- data[d][reqtype].screen = d.screen
- data[d][reqtype].border_width = d.border_width
-end
-
---- Get the margins and offset
--- @tparam table args The arguments
--- @treturn table The margins
--- @treturn table The offsets
-local function get_decoration(args)
- local offset = args.offset
-
- -- Offset are "blind" values added to the output
- offset = type(offset) == "number" and {
- x = offset,
- y = offset,
- width = offset,
- height = offset,
- } or args.offset or {}
-
- -- Margins are distances on each side to substract from the area`
- local m = type(args.margins) == "table" and args.margins or {
- left = args.margins or 0 , right = args.margins or 0,
- top = args.margins or 0 , bottom = args.margins or 0
- }
-
- return m, offset
-end
-
---- Apply some modifications before applying the new geometry.
--- @tparam table new_geo The new geometry
--- @tparam table args The common arguments
--- @tparam boolean force Always ajust the geometry, even in pretent mode. This
--- should only be used when returning the final geometry as it would otherwise
--- mess the pipeline.
--- @treturn table|nil The new geometry
-local function fix_new_geometry(new_geo, args, force)
- if (args.pretend and not force) or not new_geo then return nil end
-
- local m, offset = get_decoration(args)
-
- return {
- x = new_geo.x and (new_geo.x + (offset.x or 0) + (m.left or 0) ),
- y = new_geo.y and (new_geo.y + (offset.y or 0) + (m.top or 0) ),
- width = new_geo.width and math.max(
- 1, (new_geo.width + (offset.width or 0) - (m.left or 0) - (m.right or 0) )
- ),
- height = new_geo.height and math.max(
- 1, (new_geo.height + (offset.height or 0) - (m.top or 0) - (m.bottom or 0) )
- ),
- }
-end
-
--- Get the area covered by a drawin.
--- @param d The drawin
--- @tparam[opt=nil] table new_geo A new geometry
--- @tparam[opt=false] boolean ignore_border_width Ignore the border
--- @tparam table args the method arguments
--- @treturn The drawin's area.
-area_common = function(d, new_geo, ignore_border_width, args)
- -- The C side expect no arguments, nil isn't valid
- local geometry = new_geo and d:geometry(new_geo) or d:geometry()
- local border = ignore_border_width and 0 or d.border_width or 0
-
- -- When using the placement composition along with the "pretend"
- -- option, it is necessary to keep a "virtual" geometry.
- if args and args.override_geometry then
- geometry = util.table.clone(args.override_geometry)
- end
-
- geometry.width = geometry.width + 2 * border
- geometry.height = geometry.height + 2 * border
- return geometry
-end
-
---- Get (and optionally set) an object geometry.
--- Some elements, such as `mouse` and `screen` don't have a `:geometry()`
--- methods.
--- @param obj An object
--- @tparam table args the method arguments
--- @tparam[opt=nil] table new_geo A new geometry to replace the existing one
--- @tparam[opt=false] boolean ignore_border_width Ignore the border
--- @treturn table A table with *x*, *y*, *width* and *height*.
-local function geometry_common(obj, args, new_geo, ignore_border_width)
- -- Store the current geometry in a singleton-memento
- if args.store_geometry and new_geo and args.context then
- store_geometry(obj, args.context)
- end
-
- -- It's a mouse
- if obj.coords then
- local coords = fix_new_geometry(new_geo, args)
- and obj.coords(new_geo) or obj.coords()
- return {x=coords.x, y=coords.y, width=0, height=0}
- elseif obj.geometry then
- local geo = obj.geometry
-
- -- It is either a drawable or something that implement its API
- if type(geo) == "function" then
- local dgeo = area_common(
- obj, fix_new_geometry(new_geo, args), ignore_border_width, args
- )
-
- -- Apply the margins
- if args.margins then
- local delta = get_decoration(args)
-
- return {
- x = dgeo.x - (delta.left or 0),
- y = dgeo.y - (delta.top or 0),
- width = dgeo.width + (delta.left or 0) + (delta.right or 0),
- height = dgeo.height + (delta.top or 0) + (delta.bottom or 0),
- }
- end
-
- return dgeo
- end
-
- -- It is a screen, it doesn't support setting new sizes.
- return obj:get_bounding_geometry(args)
- else
- assert(false, "Invalid object")
- end
-end
-
---- Get the parent geometry from the standardized arguments API shared by all
--- `awful.placement` methods.
--- @param obj A screen or a drawable
--- @tparam table args the method arguments
--- @treturn table A table with *x*, *y*, *width* and *height*.
-local function get_parent_geometry(obj, args)
- -- Didable override_geometry, context and other to avoid mutating the state
- -- or using the wrong geo.
-
- if args.bounding_rect then
- return args.bounding_rect
- elseif args.parent then
- return geometry_common(args.parent, {})
- elseif obj.screen then
- return geometry_common(obj.screen, {
- honor_padding = args.honor_padding,
- honor_workarea = args.honor_workarea
- })
- else
- return geometry_common(capi.screen[capi.mouse.screen], args)
- end
-end
-
---- Move a point into an area.
--- This doesn't change the *width* and *height* values, allowing the target
--- area to be smaller than the source one.
--- @tparam table source The (larger) geometry to move `target` into
--- @tparam table target The area to move into `source`
--- @treturn table A table with *x* and *y* keys
-local function move_into_geometry(source, target)
- local ret = {x = target.x, y = target.y}
-
- -- Horizontally
- if ret.x < source.x then
- ret.x = source.x
- elseif ret.x > source.x + source.width then
- ret.x = source.x + source.width - 1
- end
-
- -- Vertically
- if ret.y < source.y then
- ret.y = source.y
- elseif ret.y > source.y + source.height then
- ret.y = source.y + source.height - 1
- end
-
- return ret
-end
-
--- Update the workarea
-wibox_update_strut = function(d, position, args)
- -- If the drawable isn't visible, remove the struts
- if not d.visible then
- d:struts { left = 0, right = 0, bottom = 0, top = 0 }
- return
- end
-
- -- Detect horizontal or vertical drawables
- local geo = area_common(d)
- local vertical = geo.width < geo.height
-
- -- Look into the `position` string to find the relevants sides to crop from
- -- the workarea
- local struts = { left = 0, right = 0, bottom = 0, top = 0 }
-
- local m = get_decoration(args)
-
- if vertical then
- for _, v in ipairs {"right", "left"} do
- if (not position) or position:match(v) then
- struts[v] = geo.width + m[v]
- end
- end
- else
- for _, v in ipairs {"top", "bottom"} do
- if (not position) or position:match(v) then
- struts[v] = geo.height + m[v]
- end
- end
- end
-
- -- Update the workarea
- d:struts(struts)
-end
-
--- Pin a drawable to a placement function.
--- Automatically update the position when the size change.
--- All other arguments will be passed to the `position` function (if any)
--- @tparam[opt=client.focus] drawable d A drawable (like `client`, `mouse`
--- or `wibox`)
--- @param position_f A position name (see `align`) or a position function
--- @tparam[opt={}] table args Other arguments
-attach = function(d, position_f, args)
- args = args or {}
-
- if args.pretend then return end
-
- if not args.attach then return end
-
- -- Avoid a connection loop
- args = setmetatable({attach=false}, {__index=args})
-
- d = d or capi.client.focus
- if not d then return end
-
- if type(position_f) == "string" then
- position_f = placement[position_f]
- end
-
- if not position_f then return end
-
- -- If there is multiple attached function, there is an high risk of infinite
- -- loop. While some combinaisons are harmless, other are very hard to debug.
- --
- -- Use the placement composition to build explicit multi step attached
- -- placement functions.
- if d.detach_callback then
- d.detach_callback()
- d.detach_callback = nil
- end
-
- local function tracker()
- position_f(d, args)
- end
-
- d:connect_signal("property::width" , tracker)
- d:connect_signal("property::height" , tracker)
- d:connect_signal("property::border_width", tracker)
-
- local function tracker_struts()
- --TODO this is too fragile and doesn't work with all methods.
- wibox_update_strut(d, d.position or reverse_align_map[position_f], args)
- end
-
- local parent = args.parent or d.screen
-
- if args.update_workarea then
- d:connect_signal("property::geometry" , tracker_struts)
- d:connect_signal("property::visible" , tracker_struts)
- capi.client.connect_signal("property::struts", tracker_struts)
-
- tracker_struts()
- elseif parent == d.screen then
- if args.honor_workarea then
- parent:connect_signal("property::workarea", tracker)
- end
-
- if args.honor_padding then
- parent:connect_signal("property::padding", tracker)
- end
- end
-
- -- If there is a parent drawable, screen, also track it.
- -- Note that tracking the mouse is not supported
- if parent and parent.connect_signal then
- parent:connect_signal("property::geometry" , tracker)
- end
-
- -- Create a way to detach a placement function
- function d.detach_callback()
- d:disconnect_signal("property::width" , tracker)
- d:disconnect_signal("property::height" , tracker)
- d:disconnect_signal("property::border_width", tracker)
- if parent then
- parent:disconnect_signal("property::geometry" , tracker)
-
- if parent == d.screen then
- if args.honor_workarea then
- parent:disconnect_signal("property::workarea", tracker)
- end
-
- if args.honor_padding then
- parent:disconnect_signal("property::padding", tracker)
- end
- end
- end
-
- if args.update_workarea then
- d:disconnect_signal("property::geometry" , tracker_struts)
- d:disconnect_signal("property::visible" , tracker_struts)
- capi.client.disconnect_signal("property::struts", tracker_struts)
- end
- end
-end
-
--- Convert 2 points into a rectangle
-local function rect_from_points(p1x, p1y, p2x, p2y)
- return {
- x = p1x,
- y = p1y,
- width = p2x - p1x,
- height = p2y - p1y,
- }
-end
-
--- Convert a rectangle and matrix info into a point
-local function rect_to_point(rect, corner_i, corner_j)
- return {
- x = rect.x + corner_i * math.floor(rect.width ),
- y = rect.y + corner_j * math.floor(rect.height),
- }
-end
-
--- Create a pair of rectangles used to set the relative areas.
--- v=vertical, h=horizontal
-local function get_cross_sections(abs_geo, mode)
- if not mode or mode == "cursor" then
- -- A 1px cross section centered around the mouse position
- local coords = capi.mouse.coords()
- return {
- h = {
- x = abs_geo.drawable_geo.x ,
- y = coords.y ,
- width = abs_geo.drawable_geo.width ,
- height = 1 ,
- },
- v = {
- x = coords.x ,
- y = abs_geo.drawable_geo.y ,
- width = 1 ,
- height = abs_geo.drawable_geo.height,
- }
- }
- elseif mode == "geometry" then
- -- The widget geometry extended to reach the end of the drawable
-
- return {
- h = {
- x = abs_geo.drawable_geo.x ,
- y = abs_geo.y ,
- width = abs_geo.drawable_geo.width ,
- height = abs_geo.height ,
- },
- v = {
- x = abs_geo.x ,
- y = abs_geo.drawable_geo.y ,
- width = abs_geo.width ,
- height = abs_geo.drawable_geo.height,
- }
- }
- elseif mode == "cursor_inside" then
- -- A 1x1 rectangle centered around the mouse position
-
- local coords = capi.mouse.coords()
- coords.width,coords.height = 1,1
- return {h=coords, v=coords}
- elseif mode == "geometry_inside" then
- -- The widget absolute geometry, unchanged
-
- return {h=abs_geo, v=abs_geo}
- end
-end
-
--- When a rectangle is embedded into a bigger one, get the regions around
--- the outline of the bigger rectangle closest to the smaller one (on each side)
-local function get_relative_regions(geo, mode, is_absolute)
-
- -- Use the mouse position and the wibox/client under it
- if not geo then
- local draw = capi.mouse.current_wibox
- geo = draw and draw:geometry() or capi.mouse.coords()
- geo.drawable = draw
- elseif is_absolute then
- -- Some signals are a bit inconsistent in their arguments convention.
- -- This little hack tries to mitigate the issue.
-
- geo.drawable = geo -- is a wibox or client, geometry and object are one
- -- and the same.
- elseif (not geo.drawable) and geo.x and geo.width then
- local coords = capi.mouse.coords()
-
- -- Check if the mouse is in the rect
- if coords.x > geo.x and coords.x < geo.x+geo.width and
- coords.y > geo.y and coords.y < geo.y+geo.height then
- geo.drawable = capi.mouse.current_wibox
- end
-
- -- Maybe there is a client
- if (not geo.drawable) and capi.mouse.current_client then
- geo.drawable = capi.mouse.current_client
- end
- end
-
- -- Get the drawable geometry
- local dpos = geo.drawable and (
- geo.drawable.drawable and
- geo.drawable.drawable:geometry()
- or geo.drawable:geometry()
- ) or {x=0, y=0}
-
- -- Compute the absolute widget geometry
- local abs_widget_geo = is_absolute and geo or {
- x = dpos.x + geo.x ,
- y = dpos.y + geo.y ,
- width = geo.width ,
- height = geo.height ,
- drawable = geo.drawable ,
- }
-
- abs_widget_geo.drawable_geo = geo.drawable and dpos or geo
-
- -- Get the point for comparison.
- local center_point = mode:match("cursor") and capi.mouse.coords() or {
- x = abs_widget_geo.x + abs_widget_geo.width / 2,
- y = abs_widget_geo.y + abs_widget_geo.height / 2,
- }
-
- -- Get widget regions for both axis
- local cs = get_cross_sections(abs_widget_geo, mode)
-
- -- Get the 4 closest points from `center_point` around the wibox
- local regions = {
- left = {x = cs.h.x , y = cs.h.y },
- right = {x = cs.h.x+cs.h.width, y = cs.h.y },
- top = {x = cs.v.x , y = cs.v.y },
- bottom = {x = cs.v.x , y = cs.v.y+cs.v.height},
- }
-
- -- Assume the section is part of a single screen until someone complains.
- -- It is much faster to compute and getting it wrong probably has no side
- -- effects.
- local s = geo.drawable and geo.drawable.screen or a_screen.getbycoord(
- center_point.x,
- center_point.y
- )
-
- -- Compute the distance (dp) between the `center_point` and the sides.
- -- This is only relevant for "cursor" and "cursor_inside" modes.
- for _, v in pairs(regions) do
- local dx, dy = v.x - center_point.x, v.y - center_point.y
-
- v.distance = math.sqrt(dx*dx + dy*dy)
- v.width = cs.v.width
- v.height = cs.h.height
- v.screen = capi.screen[s]
- end
-
- return regions
-end
-
--- Check if the proposed geometry fits the screen
-local function fit_in_bounding(obj, geo, args)
- local sgeo = get_parent_geometry(obj, args)
- local region = cairo.Region.create_rectangle(cairo.RectangleInt(sgeo))
-
- region:intersect(cairo.Region.create_rectangle(
- cairo.RectangleInt(geo)
- ))
-
- local geo2 = region:get_rectangle(0)
-
- -- If the geometry is the same then it fits, otherwise it will be cropped.
- return geo2.width == geo.width and geo2.height == geo.height
-end
-
---- Move a drawable to the closest corner of the parent geometry (such as the
--- screen).
---
--- Valid arguments include the common ones and:
---
--- * **include_sides**: Also include the left, right, top and bottom positions
---
---
---
---![Usage example](../images/AUTOGEN_awful_placement_closest_mouse.svg)
---
---**Usage example output**:
---
--- Closest corner: top_left
---
---
--- @usage
--- -- Move the mouse to the closest corner of the focused client
---awful.placement.closest_corner(mouse, {include_sides=true, parent=c})
--- -- It is possible to emulate the mouse API to get the closest corner of
--- -- random area
---local _, corner = awful.placement.closest_corner(
--- {coords=function() return {x = 100, y=100} end},
--- {include_sides = true, bounding_rect = {x=0, y=0, width=200, height=200}}
---)
---print('Closest corner:', corner)
--- @tparam[opt=client.focus] drawable d A drawable (like `client`, `mouse`
--- or `wibox`)
--- @tparam[opt={}] table args The arguments
--- @treturn table The new geometry
--- @treturn string The corner name
-function placement.closest_corner(d, args)
- args = add_context(args, "closest_corner")
- d = d or capi.client.focus
-
- local sgeo = get_parent_geometry(d, args)
- local dgeo = geometry_common(d, args)
-
- local pos = move_into_geometry(sgeo, dgeo)
-
- local corner_i, corner_j, n
-
- -- Use the product of 3 to get the closest point in a NxN matrix
- local function f(_n, mat)
- n = _n
- -- The +1 is required to avoid a rounding error when
- -- pos.x == sgeo.x+sgeo.width
- corner_i = -math.ceil( ( (sgeo.x - pos.x) * n) / (sgeo.width + 1))
- corner_j = -math.ceil( ( (sgeo.y - pos.y) * n) / (sgeo.height + 1))
- return mat[corner_j + 1][corner_i + 1]
- end
-
- -- Turn the area into a grid and snap to the cloest point. This size of the
- -- grid will increase the accuracy. A 2x2 matrix only include the corners,
- -- at 3x3, this include the sides too technically, a random size would work,
- -- but without corner names.
- local grid_size = args.include_sides and 3 or 2
-
- -- If the point is in the center, use the closest corner
- local corner = grid_size == 3 and f(3, corners3x3) or f(2, corners2x2)
-
- -- Transpose the corner back to the original size
- local new_args = setmetatable({position = corner}, {__index=args})
- local ngeo = placement_private.align(d, new_args)
-
- return fix_new_geometry(ngeo, args, true), corner
-end
-
---- Place the client so no part of it will be outside the screen (workarea).
---
---
---![Usage example](../images/AUTOGEN_awful_placement_no_offscreen.svg)
---
---**Usage example output**:
---
--- Before: x=-30, y=-30, width=100, height=100
--- After: x=10, y=10, width=100, height=100
---
---
--- @usage
---awful.placement.no_offscreen(c)--, {honor_workarea=true, margins=40})
--- @client c The client.
--- @tparam[opt=client's screen] integer screen The screen.
--- @treturn table The new client geometry.
-function placement.no_offscreen(c, screen)
- --HACK necessary for composition to work. The API will be changed soon
- if type(screen) == "table" then
- screen = nil
- end
-
- c = c or capi.client.focus
- local geometry = area_common(c)
- screen = get_screen(screen or c.screen or a_screen.getbycoord(geometry.x, geometry.y))
- local screen_geometry = screen.workarea
-
- if geometry.x + geometry.width > screen_geometry.x + screen_geometry.width then
- geometry.x = screen_geometry.x + screen_geometry.width - geometry.width
- end
- if geometry.x < screen_geometry.x then
- geometry.x = screen_geometry.x
- end
-
- if geometry.y + geometry.height > screen_geometry.y + screen_geometry.height then
- geometry.y = screen_geometry.y + screen_geometry.height - geometry.height
- end
- if geometry.y < screen_geometry.y then
- geometry.y = screen_geometry.y
- end
-
- return c:geometry {
- x = geometry.x,
- y = geometry.y
- }
-end
-
---- Place the client where there's place available with minimum overlap.
---
---
---![Usage example](../images/AUTOGEN_awful_placement_no_overlap.svg)
---
--- @usage
---awful.placement.no_overlap(client.focus)
---local x,y = screen[4].geometry.x, screen[4].geometry.y
--- @param c The client.
--- @treturn table The new geometry
-function placement.no_overlap(c)
- c = c or capi.client.focus
- local geometry = area_common(c)
- local screen = get_screen(c.screen or a_screen.getbycoord(geometry.x, geometry.y))
- local cls = client.visible(screen)
- local curlay = layout.get()
- local areas = { screen.workarea }
- for _, cl in pairs(cls) do
- if cl ~= c and cl.type ~= "desktop" and (cl.floating or curlay == layout.suit.floating) then
- areas = grect.area_remove(areas, area_common(cl))
- end
- end
-
- -- Look for available space
- local found = false
- local new = { x = geometry.x, y = geometry.y, width = 0, height = 0 }
- for _, r in ipairs(areas) do
- if r.width >= geometry.width
- and r.height >= geometry.height
- and r.width * r.height > new.width * new.height then
- found = true
- new = r
- -- Check if the client's current position is available
- -- and prefer that one (why move it around pointlessly?)
- if geometry.x >= r.x
- and geometry.y >= r.y
- and geometry.x + geometry.width <= r.x + r.width
- and geometry.y + geometry.height <= r.y + r.height then
- new.x = geometry.x
- new.y = geometry.y
- end
- end
- end
-
- -- We did not find an area with enough space for our size:
- -- just take the biggest available one and go in.
- -- This makes sure to have the whole screen's area in case it has been
- -- removed.
- if not found then
- if #areas == 0 then
- areas = { screen.workarea }
- end
- for _, r in ipairs(areas) do
- if r.width * r.height > new.width * new.height then
- new = r
- end
- end
- end
-
- -- Restore height and width
- new.width = geometry.width
- new.height = geometry.height
-
- return c:geometry({ x = new.x, y = new.y })
-end
-
---- Place the client under the mouse.
---
---
---![Usage example](../images/AUTOGEN_awful_placement_under_mouse.svg)
---
--- @usage
---awful.placement.under_mouse(client.focus)
--- @tparam drawable d A drawable (like `client`, `mouse` or `wibox`)
--- @tparam[opt={}] table args Other arguments
--- @treturn table The new geometry
-function placement.under_mouse(d, args)
- args = add_context(args, "under_mouse")
- d = d or capi.client.focus
-
- local m_coords = capi.mouse.coords()
-
- local ngeo = geometry_common(d, args)
- ngeo.x = math.floor(m_coords.x - ngeo.width / 2)
- ngeo.y = math.floor(m_coords.y - ngeo.height / 2)
-
- local bw = d.border_width or 0
- ngeo.width = ngeo.width - 2*bw
- ngeo.height = ngeo.height - 2*bw
-
- geometry_common(d, args, ngeo)
-
- return fix_new_geometry(ngeo, args, true)
-end
-
---- Place the client next to the mouse.
---
--- It will place `c` next to the mouse pointer, trying the following positions
--- in this order: right, left, above and below.
---
---
---![Usage example](../images/AUTOGEN_awful_placement_next_to_mouse.svg)
---
--- @usage
---awful.placement.next_to_mouse(client.focus)
--- @tparam drawable d A drawable (like `client`, `mouse` or `wibox`)
--- @tparam[opt={}] table args Other arguments
--- @treturn table The new geometry
-function placement.next_to_mouse(d, args)
- if type(args) == "number" then
- util.deprecate(
- "awful.placement.next_to_mouse offset argument is deprecated"..
- " use awful.placement.next_to_mouse(c, {offset={x=...}})"
- )
- args = nil
- end
-
- local old_args = args or {}
-
- args = add_context(args, "next_to_mouse")
- d = d or capi.client.focus
-
- local sgeo = get_parent_geometry(d, args)
-
- args.pretend = true
- args.parent = capi.mouse
-
- local ngeo = placement.left(d, args)
-
- if ngeo.x + ngeo.width > sgeo.x+sgeo.width then
- ngeo = placement.right(d, args)
- else
- -- It is _next_ to mouse, not under_mouse
- ngeo.x = ngeo.x+1
- end
-
- args.pretend = old_args.pretend
-
- geometry_common(d, args, ngeo)
-
- attach(d, placement.next_to_mouse, old_args)
-
- return fix_new_geometry(ngeo, args, true)
-end
-
---- Resize the drawable to the cursor.
---
--- Valid args:
---
--- * *axis*: The axis (vertical or horizontal). If none is
--- specified, then the drawable will be resized on both axis.
---
---
---
---![Usage example](../images/AUTOGEN_awful_placement_resize_to_mouse.svg)
---
--- @tparam drawable d A drawable (like `client`, `mouse` or `wibox`)
--- @tparam[opt={}] table args Other arguments
--- @treturn table The new geometry
-function placement.resize_to_mouse(d, args)
- d = d or capi.client.focus
- args = add_context(args, "resize_to_mouse")
-
- local coords = capi.mouse.coords()
- local ngeo = geometry_common(d, args)
- local h_only = args.axis == "horizontal"
- local v_only = args.axis == "vertical"
-
- -- To support both growing and shrinking the drawable, it is necessary
- -- to decide to use either "north or south" and "east or west" directions.
- -- Otherwise, the result will always be 1x1
- local _, closest_corner = placement.closest_corner(capi.mouse, {
- parent = d,
- pretend = true,
- include_sides = args.include_sides or false,
- })
-
- -- Given "include_sides" wasn't set, it will always return a name
- -- with the 2 axis. If only one axis is needed, adjust the result
- if h_only then
- closest_corner = closest_corner:match("left") or closest_corner:match("right")
- elseif v_only then
- closest_corner = closest_corner:match("top") or closest_corner:match("bottom")
- end
-
- -- Use p0 (mouse), p1 and p2 to create a rectangle
- local pts = resize_to_point_map[closest_corner]
- local p1 = pts.p1 and rect_to_point(ngeo, pts.p1[1], pts.p1[2]) or coords
- local p2 = pts.p2 and rect_to_point(ngeo, pts.p2[1], pts.p2[2]) or coords
-
- -- Create top_left and bottom_right points, convert to rectangle
- ngeo = rect_from_points(
- pts.y_only and ngeo.x or math.min(p1.x, p2.x),
- pts.x_only and ngeo.y or math.min(p1.y, p2.y),
- pts.y_only and ngeo.x + ngeo.width or math.max(p2.x, p1.x),
- pts.x_only and ngeo.y + ngeo.height or math.max(p2.y, p1.y)
- )
-
- local bw = d.border_width or 0
-
- for _, a in ipairs {"width", "height"} do
- ngeo[a] = ngeo[a] - 2*bw
- end
-
- -- Now, correct the geometry by the given size_hints offset
- if d.apply_size_hints then
- local w, h = d:apply_size_hints(
- ngeo.width,
- ngeo.height
- )
- local offset = align_map[pts.align](w, h, ngeo.width, ngeo.height)
- ngeo.x = ngeo.x - offset.x
- ngeo.y = ngeo.y - offset.y
- end
-
- geometry_common(d, args, ngeo)
-
- return fix_new_geometry(ngeo, args, true)
-end
-
---- Move the drawable (client or wibox) `d` to a screen position or side.
---
--- Supported args.positions are:
---
--- * top_left
--- * top_right
--- * bottom_left
--- * bottom_right
--- * left
--- * right
--- * top
--- * bottom
--- * centered
--- * center_vertical
--- * center_horizontal
---
---
---
---![Usage example](../images/AUTOGEN_awful_placement_align.svg)
---
--- @tparam drawable d A drawable (like `client`, `mouse` or `wibox`)
--- @tparam[opt={}] table args Other arguments
--- @treturn table The new geometry
-function placement.align(d, args)
- args = add_context(args, "align")
- d = d or capi.client.focus
-
- if not d or not args.position then return end
-
- local sgeo = get_parent_geometry(d, args)
- local dgeo = geometry_common(d, args)
- local bw = d.border_width or 0
-
- local pos = align_map[args.position](
- sgeo.width ,
- sgeo.height,
- dgeo.width ,
- dgeo.height
- )
-
- local ngeo = {
- x = (pos.x and math.ceil(sgeo.x + pos.x) or dgeo.x) ,
- y = (pos.y and math.ceil(sgeo.y + pos.y) or dgeo.y) ,
- width = math.ceil(dgeo.width ) - 2*bw,
- height = math.ceil(dgeo.height ) - 2*bw,
- }
-
- geometry_common(d, args, ngeo)
-
- attach(d, placement[args.position], args)
-
- return fix_new_geometry(ngeo, args, true)
-end
-
--- Add the alias functions
-for k in pairs(align_map) do
- placement[k] = function(d, args)
- args = add_context(args, k)
- args.position = k
- return placement_private.align(d, args)
- end
- reverse_align_map[placement[k]] = k
-end
-
--- Add the documentation for align alias
-
----
--- Align a client to the top left of the parent area.
---
---![Usage example](../images/AUTOGEN_awful_placement_top_left.svg)
--- @tparam drawable d A drawable (like `client`, `mouse` or `wibox`)
--- @tparam[opt={}] table args Other arguments')
--- @treturn table The new geometry
--- @name top_left
--- @class function
---
--- @usage
---awful.placement.top_left(client.focus)
-
----
--- Align a client to the top right of the parent area.
---
---![Usage example](../images/AUTOGEN_awful_placement_top_right.svg)
--- @tparam drawable d A drawable (like `client`, `mouse` or `wibox`)
--- @tparam[opt={}] table args Other arguments')
--- @treturn table The new geometry
--- @name top_right
--- @class function
---
--- @usage
---awful.placement.top_right(client.focus)
-
----
--- Align a client to the bottom left of the parent area.
---
---![Usage example](../images/AUTOGEN_awful_placement_bottom_left.svg)
--- @tparam drawable d A drawable (like `client`, `mouse` or `wibox`)
--- @tparam[opt={}] table args Other arguments')
--- @treturn table The new geometry
--- @name bottom_left
--- @class function
---
--- @usage
---awful.placement.bottom_left(client.focus)
-
----
--- Align a client to the bottom right of the parent area.
---
---![Usage example](../images/AUTOGEN_awful_placement_bottom_right.svg)
--- @tparam drawable d A drawable (like `client`, `mouse` or `wibox`)
--- @tparam[opt={}] table args Other arguments')
--- @treturn table The new geometry
--- @name bottom_right
--- @class function
---
--- @usage
---awful.placement.bottom_right(client.focus)
-
----
--- Align a client to the left of the parent area.
---
---![Usage example](../images/AUTOGEN_awful_placement_left.svg)
--- @tparam drawable d A drawable (like `client`, `mouse` or `wibox`)
--- @tparam[opt={}] table args Other arguments')
--- @treturn table The new geometry
--- @name left
--- @class function
---
--- @usage
---awful.placement.left(client.focus)
-
----
--- Align a client to the right of the parent area.
---
---![Usage example](../images/AUTOGEN_awful_placement_right.svg)
--- @tparam drawable d A drawable (like `client`, `mouse` or `wibox`)
--- @tparam[opt={}] table args Other arguments')
--- @treturn table The new geometry
--- @name right
--- @class function
---
--- @usage
---awful.placement.right(client.focus)
-
----
--- Align a client to the top of the parent area.
---
---![Usage example](../images/AUTOGEN_awful_placement_top.svg)
--- @tparam drawable d A drawable (like `client`, `mouse` or `wibox`)
--- @tparam[opt={}] table args Other arguments')
--- @treturn table The new geometry
--- @name top
--- @class function
---
--- @usage
---awful.placement.top(client.focus)
---assert(c.x == screen[1].geometry.width/2-40/2-c.border_width)
-
----
--- Align a client to the bottom of the parent area.
---
---![Usage example](../images/AUTOGEN_awful_placement_bottom.svg)
--- @tparam drawable d A drawable (like `client`, `mouse` or `wibox`)
--- @tparam[opt={}] table args Other arguments')
--- @treturn table The new geometry
--- @name bottom
--- @class function
---
--- @usage
---awful.placement.bottom(client.focus)
-
----
--- Align a client to the center of the parent area.
---
---![Usage example](../images/AUTOGEN_awful_placement_centered.svg)
--- @tparam drawable d A drawable (like `client`, `mouse` or `wibox`)
--- @tparam[opt={}] table args Other arguments')
--- @treturn table The new geometry
--- @name centered
--- @class function
---
--- @usage
---awful.placement.centered(client.focus)
-
----
--- Align a client to the vertical center of the parent area.
---
---![Usage example](../images/AUTOGEN_awful_placement_center_vertical.svg)
--- @tparam drawable d A drawable (like `client`, `mouse` or `wibox`)
--- @tparam[opt={}] table args Other arguments')
--- @name center_vertical
--- @class function
---
--- @usage
---awful.placement.center_vertical(client.focus)
-
----
--- Align a client to the horizontal center left of the parent area.
---
---![Usage example](../images/AUTOGEN_awful_placement_center_horizontal.svg)
--- @tparam drawable d A drawable (like `client`, `mouse` or `wibox`)
--- @tparam[opt={}] table args Other arguments')
--- @treturn table The new geometry
--- @name center_horizontal
--- @class function
---
--- @usage
---awful.placement.center_horizontal(client.focus)
-
---- Stretch a drawable in a specific direction.
--- Valid args:
---
--- * **direction**: The stretch direction (*left*, *right*, *up*, *down*) or
--- a table with multiple directions.
---
---
---
---![Usage example](../images/AUTOGEN_awful_placement_stretch.svg)
---
--- @tparam[opt=client.focus] drawable d A drawable (like `client` or `wibox`)
--- @tparam[opt={}] table args The arguments
--- @treturn table The new geometry
-function placement.stretch(d, args)
- args = add_context(args, "stretch")
-
- d = d or capi.client.focus
- if not d or not args.direction then return end
-
- -- In case there is multiple directions, call `stretch` for each of them
- if type(args.direction) == "table" then
- for _, dir in ipairs(args.direction) do
- args.direction = dir
- placement_private.stretch(dir, args)
- end
- return
- end
-
- local sgeo = get_parent_geometry(d, args)
- local dgeo = geometry_common(d, args)
- local ngeo = geometry_common(d, args, nil, true)
- local bw = d.border_width or 0
-
- if args.direction == "left" then
- ngeo.x = sgeo.x
- ngeo.width = dgeo.width + (dgeo.x - ngeo.x)
- elseif args.direction == "right" then
- ngeo.width = sgeo.width - ngeo.x - 2*bw
- elseif args.direction == "up" then
- ngeo.y = sgeo.y
- ngeo.height = dgeo.height + (dgeo.y - ngeo.y)
- elseif args.direction == "down" then
- ngeo.height = sgeo.height - dgeo.y - 2*bw
- else
- assert(false)
- end
-
- -- Avoid negative sizes if args.parent isn't compatible
- ngeo.width = math.max(args.minimim_width or 1, ngeo.width )
- ngeo.height = math.max(args.minimim_height or 1, ngeo.height)
-
- geometry_common(d, args, ngeo)
-
- attach(d, placement["stretch_"..args.direction], args)
-
- return fix_new_geometry(ngeo, args, true)
-end
-
--- Add the alias functions
-for _,v in ipairs {"left", "right", "up", "down"} do
- placement["stretch_"..v] = function(d, args)
- args = add_context(args, "stretch_"..v)
- args.direction = v
- return placement_private.stretch(d, args)
- end
-end
-
----
--- Stretch the drawable to the left of the parent area.
---
---![Usage example](../images/AUTOGEN_awful_placement_stretch_left.svg)
--- @tparam drawable d A drawable (like `client` or `wibox`)
--- @tparam[opt={}] table args Other arguments
--- @treturn table The new geometry
--- @name stretch_left
--- @class function
---
--- @usage
---placement.stretch_left(client.focus)
-
----
--- Stretch the drawable to the right of the parent area.
---
---![Usage example](../images/AUTOGEN_awful_placement_stretch_right.svg)
--- @tparam drawable d A drawable (like `client` or `wibox`)
--- @tparam[opt={}] table args Other arguments
--- @treturn table The new geometry
--- @name stretch_right
--- @class function
---
--- @usage
---placement.stretch_right(client.focus)
-
----
--- Stretch the drawable to the top of the parent area.
---
---![Usage example](../images/AUTOGEN_awful_placement_stretch_up.svg)
--- @tparam drawable d A drawable (like `client` or `wibox`)
--- @tparam[opt={}] table args Other arguments
--- @treturn table The new geometry
--- @name stretch_up
--- @class function
---
--- @usage
---placement.stretch_up(client.focus)
-
----
--- Stretch the drawable to the bottom of the parent area.
---
---![Usage example](../images/AUTOGEN_awful_placement_stretch_down.svg)
--- @tparam drawable d A drawable (like `client` or `wibox`)
--- @tparam[opt={}] table args Other arguments
--- @treturn table The new geometry
--- @name stretch_down
--- @class function
---
--- @usage
---placement.stretch_down(client.focus)
-
---- Maximize a drawable horizontally, vertically or both.
--- Valid args:
---
--- * *axis*:The axis (vertical or horizontal). If none is
--- specified, then the drawable will be maximized on both axis.
---
---
---
---![Usage example](../images/AUTOGEN_awful_placement_maximize.svg)
---
--- @tparam[opt=client.focus] drawable d A drawable (like `client` or `wibox`)
--- @tparam[opt={}] table args The arguments
--- @treturn table The new geometry
-function placement.maximize(d, args)
- args = add_context(args, "maximize")
- d = d or capi.client.focus
-
- if not d then return end
-
- local sgeo = get_parent_geometry(d, args)
- local ngeo = geometry_common(d, args, nil, true)
- local bw = d.border_width or 0
-
- if (not args.axis) or args.axis :match "vertical" then
- ngeo.y = sgeo.y
- ngeo.height = sgeo.height - 2*bw
- end
-
- if (not args.axis) or args.axis :match "horizontal" then
- ngeo.x = sgeo.x
- ngeo.width = sgeo.width - 2*bw
- end
-
- geometry_common(d, args, ngeo)
-
- attach(d, placement.maximize, args)
-
- return fix_new_geometry(ngeo, args, true)
-end
-
--- Add the alias functions
-for _, v in ipairs {"vertically", "horizontally"} do
- placement["maximize_"..v] = function(d2, args)
- args = add_context(args, "maximize_"..v)
- args.axis = v
- return placement_private.maximize(d2, args)
- end
-end
-
----
--- Vetically maximize the drawable in the parent area.
---
---![Usage example](../images/AUTOGEN_awful_placement_maximize_vertically.svg)
--- @tparam drawable d A drawable (like `client` or `wibox`)
--- @tparam[opt={}] table args Other arguments')
--- @name maximize_vertically
--- @class function
---
--- @usage
---placement.maximize_vertically(c)
-
----
--- Horizontally maximize the drawable in the parent area.
---
---![Usage example](../images/AUTOGEN_awful_placement_maximize_horizontally.svg)
--- @tparam drawable d A drawable (like `client` or `wibox`)
--- @tparam[opt={}] table args Other arguments')
--- @name maximize_horizontally
--- @class function
---
--- @usage
---placement.maximize_horizontally(c)
-
---- Scale the drawable by either a relative or absolute percent.
---
--- Valid args:
---
--- **to_percent** : A number between 0 and 1. It represent a percent related to
--- the parent geometry.
--- **by_percent** : A number between 0 and 1. It represent a percent related to
--- the current size.
--- **direction**: Nothing or "left", "right", "up", "down".
---
--- @tparam[opt=client.focus] drawable d A drawable (like `client` or `wibox`)
--- @tparam[opt={}] table args The arguments
--- @treturn table The new geometry
-function placement.scale(d, args)
- args = add_context(args, "scale_to_percent")
- d = d or capi.client.focus
-
- local to_percent = args.to_percent
- local by_percent = args.by_percent
-
- local percent = to_percent or by_percent
-
- local direction = args.direction
-
- local sgeo = get_parent_geometry(d, args)
- local ngeo = geometry_common(d, args, nil)
-
- local old_area = {width = ngeo.width, height = ngeo.height}
-
- if (not direction) or direction == "left" or direction == "right" then
- ngeo.width = (to_percent and sgeo or ngeo).width*percent
-
- if direction == "left" then
- ngeo.x = ngeo.x - (ngeo.width - old_area.width)
- end
- end
-
- if (not direction) or direction == "up" or direction == "down" then
- ngeo.height = (to_percent and sgeo or ngeo).height*percent
-
- if direction == "up" then
- ngeo.y = ngeo.y - (ngeo.height - old_area.height)
- end
- end
-
- local bw = d.border_width or 0
- ngeo.width = ngeo.width - 2*bw
- ngeo.height = ngeo.height - 2*bw
-
- geometry_common(d, args, ngeo)
-
- attach(d, placement.maximize, args)
-
- return fix_new_geometry(ngeo, args, true)
-end
-
---- Move a drawable to a relative position next to another one.
---
--- The `args.preferred_positions` look like this:
---
--- {"top", "right", "left", "bottom"}
---
--- In that case, if there is room on the top of the geomtry, then it will have
--- priority, followed by all the others, in order.
---
--- @tparam drawable d A wibox or client
--- @tparam table args
--- @tparam string args.mode The mode
--- @tparam string args.preferred_positions The preferred positions (in order)
--- @tparam string args.geometry A geometry inside the other drawable
--- @treturn table The new geometry
--- @treturn string The choosen position
--- @treturn string The choosen direction
-function placement.next_to(d, args)
- args = add_context(args, "next_to")
- d = d or capi.client.focus
-
- local preferred_positions = {}
-
- if #(args.preferred_positions or {}) then
- for k, v in ipairs(args.preferred_positions) do
- preferred_positions[v] = k
- end
- end
-
- local dgeo = geometry_common(d, args)
- local pref_idx, pref_name = 99, nil
- local mode,wgeo = args.mode
-
- if args.geometry then
- mode = "geometry"
- wgeo = args.geometry
- else
- local pos = capi.mouse.current_widget_geometry
-
- if pos then
- wgeo, mode = pos, "cursor"
- elseif capi.mouse.current_client then
- wgeo, mode = capi.mouse.current_client:geometry(), "cursor"
- end
- end
-
- if not wgeo then return end
-
- -- See get_relative_regions comments
- local is_absolute = wgeo.ontop ~= nil
-
- local regions = get_relative_regions(wgeo, mode, is_absolute)
-
- -- Check each possible slot around the drawable (8 total), see what fits
- -- and order them by preferred_positions
- local does_fit = {}
- for k,v in pairs(regions) do
- local geo, dir = outer_positions[k.."1"](v, dgeo.width, dgeo.height)
- geo.width, geo.height = dgeo.width, dgeo.height
- local fit = fit_in_bounding(v.screen, geo, args)
-
- -- Try the other compatible geometry
- if not fit then
- geo, dir = outer_positions[k.."2"](v, dgeo.width, dgeo.height)
- geo.width, geo.height = dgeo.width, dgeo.height
- fit = fit_in_bounding(v.screen, geo, args)
- end
-
- does_fit[k] = fit and {geo, dir} or nil
-
- if fit and preferred_positions[k] and preferred_positions[k] < pref_idx then
- pref_idx = preferred_positions[k]
- pref_name = k
- end
-
- -- No need to continue
- if fit and preferred_positions[k] == 1 then break end
- end
-
- local pos_name = pref_name or next(does_fit)
- local ngeo, dir = unpack(does_fit[pos_name] or {}) --FIXME why does this happen
-
- geometry_common(d, args, ngeo)
-
- attach(d, placement.next_to, args)
-
- return fix_new_geometry(ngeo, args, true), pos_name, dir
-end
-
---- Restore the geometry.
--- @tparam[opt=client.focus] drawable d A drawable (like `client` or `wibox`)
--- @tparam[opt={}] table args The arguments
--- @treturn boolean If the geometry was restored
-function placement.restore(d, args)
- if not args or not args.context then return false end
- d = d or capi.client.focus
-
- if not data[d] then return false end
-
- local memento = data[d][args.context]
-
- if not memento then return false end
-
- memento.screen = nil --TODO use it
-
- d.border_width = memento.border_width
-
- d:geometry(memento)
- return true
-end
-
-return placement
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/prompt.lua b/awesome/lib/awful/prompt.lua
deleted file mode 100644
index 9a86475..0000000
--- a/awesome/lib/awful/prompt.lua
+++ /dev/null
@@ -1,777 +0,0 @@
----------------------------------------------------------------------------
---- Prompt module for awful.
---
--- By default, `rc.lua` will create one `awful.widget.prompt` per screen called
--- `mypromptbox`. It is used for both the command execution (`mod4+r`) and
--- Lua prompt (`mod4+x`). It can be re-used for random inputs using:
---
--- -- Create a shortcut function
--- local function echo_test()
--- awful.prompt.run {
--- prompt = "Echo: ",
--- textbox = mouse.screen.mypromptbox.widget,
--- exe_callback = function(input)
--- if not input or #input == 0 then return end
--- naughty.notify{ text = "The input was: "..input }
--- end
--- }
--- end
---
--- -- Then **IN THE globalkeys TABLE** add a new shortcut
--- awful.key({ modkey }, "e", echo_test,
--- {description = "Echo a string", group = "custom"}),
---
--- Note that this assumes an `rc.lua` file based on the default one. The way
--- to access the screen prompt may vary.
---
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2008 Julien Danjou
--- @module awful.prompt
----------------------------------------------------------------------------
-
--- Grab environment we need
-local assert = assert
-local io = io
-local table = table
-local math = math
-local ipairs = ipairs
-local pcall = pcall
-local capi =
-{
- selection = selection
-}
-local unpack = unpack or table.unpack -- luacheck: globals unpack (compatibility with Lua 5.1)
-local keygrabber = require("awful.keygrabber")
-local util = require("awful.util")
-local beautiful = require("beautiful")
-local akey = require("awful.key")
-
-local prompt = {}
-
---- Private data
-local data = {}
-data.history = {}
-
-local search_term = nil
-local function itera (inc,a, i)
- i = i + inc
- local v = a[i]
- if v then return i,v end
-end
-
---- Load history file in history table
--- @param id The data.history identifier which is the path to the filename.
--- @param[opt] max The maximum number of entries in file.
-local function history_check_load(id, max)
- if id and id ~= "" and not data.history[id] then
- data.history[id] = { max = 50, table = {} }
-
- if max then
- data.history[id].max = max
- end
-
- local f = io.open(id, "r")
- if not f then return end
-
- -- Read history file
- for line in f:lines() do
- if util.table.hasitem(data.history[id].table, line) == nil then
- table.insert(data.history[id].table, line)
- if #data.history[id].table >= data.history[id].max then
- break
- end
- end
- end
- f:close()
- end
-end
-
-local function is_word_char(c)
- if string.find("[{[(,.:;_-+=@/ ]", c) then
- return false
- else
- return true
- end
-end
-
-local function cword_start(s, pos)
- local i = pos
- if i > 1 then
- i = i - 1
- end
- while i >= 1 and not is_word_char(s:sub(i, i)) do
- i = i - 1
- end
- while i >= 1 and is_word_char(s:sub(i, i)) do
- i = i - 1
- end
- if i <= #s then
- i = i + 1
- end
- return i
-end
-
-local function cword_end(s, pos)
- local i = pos
- while i <= #s and not is_word_char(s:sub(i, i)) do
- i = i + 1
- end
- while i <= #s and is_word_char(s:sub(i, i)) do
- i = i + 1
- end
- return i
-end
-
---- Save history table in history file
--- @param id The data.history identifier
-local function history_save(id)
- if data.history[id] then
- local f = io.open(id, "w")
- if not f then
- local i = 0
- for d in id:gmatch(".-/") do
- i = i + #d
- end
- util.mkdir(id:sub(1, i - 1))
- f = assert(io.open(id, "w"))
- end
- for i = 1, math.min(#data.history[id].table, data.history[id].max) do
- f:write(data.history[id].table[i] .. "\n")
- end
- f:close()
- end
-end
-
---- Return the number of items in history table regarding the id
--- @param id The data.history identifier
--- @return the number of items in history table, -1 if history is disabled
-local function history_items(id)
- if data.history[id] then
- return #data.history[id].table
- else
- return -1
- end
-end
-
---- Add an entry to the history file
--- @param id The data.history identifier
--- @param command The command to add
-local function history_add(id, command)
- if data.history[id] and command ~= "" then
- local index = util.table.hasitem(data.history[id].table, command)
- if index == nil then
- table.insert(data.history[id].table, command)
-
- -- Do not exceed our max_cmd
- if #data.history[id].table > data.history[id].max then
- table.remove(data.history[id].table, 1)
- end
-
- history_save(id)
- else
- -- Bump this command to the end of history
- table.remove(data.history[id].table, index)
- table.insert(data.history[id].table, command)
- history_save(id)
- end
- end
-end
-
-
---- Draw the prompt text with a cursor.
--- @tparam table args The table of arguments.
--- @field text The text.
--- @field font The font.
--- @field prompt The text prefix.
--- @field text_color The text color.
--- @field cursor_color The cursor color.
--- @field cursor_pos The cursor position.
--- @field cursor_ul The cursor underline style.
--- @field selectall If true cursor is rendered on the entire text.
-local function prompt_text_with_cursor(args)
- local char, spacer, text_start, text_end, ret
- local text = args.text or ""
- local _prompt = args.prompt or ""
- local underline = args.cursor_ul or "none"
-
- if args.selectall then
- if #text == 0 then char = " " else char = util.escape(text) end
- spacer = " "
- text_start = ""
- text_end = ""
- elseif #text < args.cursor_pos then
- char = " "
- spacer = ""
- text_start = util.escape(text)
- text_end = ""
- else
- char = util.escape(text:sub(args.cursor_pos, args.cursor_pos))
- spacer = " "
- text_start = util.escape(text:sub(1, args.cursor_pos - 1))
- text_end = util.escape(text:sub(args.cursor_pos + 1))
- end
-
- local cursor_color = util.ensure_pango_color(args.cursor_color)
- local text_color = util.ensure_pango_color(args.text_color)
-
- ret = _prompt .. text_start .. "<span background=\"" .. cursor_color ..
- "\" foreground=\"" .. text_color .. "\" underline=\"" .. underline ..
- "\">" .. char .. "</span>" .. text_end .. spacer
- return ret
-end
-
---- Run a prompt in a box.
---
--- The following readline keyboard shortcuts are implemented as expected:
--- <kbd>CTRL+A</kbd>, <kbd>CTRL+B</kbd>, <kbd>CTRL+C</kbd>, <kbd>CTRL+D</kbd>,
--- <kbd>CTRL+E</kbd>, <kbd>CTRL+J</kbd>, <kbd>CTRL+M</kbd>, <kbd>CTRL+F</kbd>,
--- <kbd>CTRL+H</kbd>, <kbd>CTRL+K</kbd>, <kbd>CTRL+U</kbd>, <kbd>CTRL+W</kbd>,
--- <kbd>CTRL+BACKSPACE</kbd>, <kbd>SHIFT+INSERT</kbd>, <kbd>HOME</kbd>,
--- <kbd>END</kbd> and arrow keys.
---
--- The following shortcuts implement additional history manipulation commands
--- where the search term is defined as the substring of the command from first
--- character to cursor position.
---
--- * <kbd>CTRL+R</kbd>: reverse history search, matches any history entry
--- containing search term.
--- * <kbd>CTRL+S</kbd>: forward history search, matches any history entry
--- containing search term.
--- * <kbd>CTRL+UP</kbd>: ZSH up line or search, matches any history entry
--- starting with search term.
--- * <kbd>CTRL+DOWN</kbd>: ZSH down line or search, matches any history
--- entry starting with search term.
--- * <kbd>CTRL+DELETE</kbd>: delete the currently visible history entry from
--- history file. This does not delete new commands or history entries under
--- user editing.
---
--- @tparam[opt={}] table args A table with optional arguments
--- @tparam[opt] gears.color args.fg_cursor
--- @tparam[opt] gears.color args.bg_cursor
--- @tparam[opt] gears.color args.ul_cursor
--- @tparam[opt] widget args.prompt
--- @tparam[opt] string args.text
--- @tparam[opt] boolean args.selectall
--- @tparam[opt] string args.font
--- @tparam[opt] boolean args.autoexec
--- @tparam widget args.textbox The textbox to use for the prompt.
--- @tparam function args.exe_callback The callback function to call with command as argument
--- when finished.
--- @tparam function args.completion_callback The callback function to call to get completion.
--- @tparam[opt] string args.history_path File path where the history should be
--- saved, set nil to disable history
--- @tparam[opt] function args.history_max Set the maximum entries in history
--- file, 50 by default
--- @tparam[opt] function args.done_callback The callback function to always call
--- without arguments, regardless of whether the prompt was cancelled.
--- @tparam[opt] function args.changed_callback The callback function to call
--- with command as argument when a command was changed.
--- @tparam[opt] function args.keypressed_callback The callback function to call
--- with mod table, key and command as arguments when a key was pressed.
--- @tparam[opt] function args.keyreleased_callback The callback function to call
--- with mod table, key and command as arguments when a key was pressed.
--- @tparam[opt] table args.hooks The "hooks" argument uses a syntax similar to
--- `awful.key`. It will call a function for the matching modifiers + key.
--- It receives the command (widget text/input) as an argument.
--- If the callback returns a command, this will be passed to the
--- `exe_callback`, otherwise nothing gets executed by default, and the hook
--- needs to handle it.
--- hooks = {
--- -- Apply startup notification properties with Shift-Return.
--- {{"Shift" }, "Return", function(command)
--- awful.screen.focused().mypromptbox:spawn_and_handle_error(
--- command, {floating=true})
--- end},
--- -- Override default behavior of "Return": launch commands prefixed
--- -- with ":" in a terminal.
--- {{}, "Return", function(command)
--- if command:sub(1,1) == ":" then
--- return terminal .. ' -e ' .. command:sub(2)
--- end
--- return command
--- end}
--- }
--- @param textbox The textbox to use for the prompt. [**DEPRECATED**]
--- @param exe_callback The callback function to call with command as argument
--- when finished. [**DEPRECATED**]
--- @param completion_callback The callback function to call to get completion.
--- [**DEPRECATED**]
--- @param[opt] history_path File path where the history should be
--- saved, set nil to disable history [**DEPRECATED**]
--- @param[opt] history_max Set the maximum entries in history
--- file, 50 by default [**DEPRECATED**]
--- @param[opt] done_callback The callback function to always call
--- without arguments, regardless of whether the prompt was cancelled.
--- [**DEPRECATED**]
--- @param[opt] changed_callback The callback function to call
--- with command as argument when a command was changed. [**DEPRECATED**]
--- @param[opt] keypressed_callback The callback function to call
--- with mod table, key and command as arguments when a key was pressed.
--- [**DEPRECATED**]
--- @see gears.color
-function prompt.run(args, textbox, exe_callback, completion_callback,
- history_path, history_max, done_callback,
- changed_callback, keypressed_callback)
- local grabber
- local theme = beautiful.get()
- if not args then args = {} end
- local command = args.text or ""
- local command_before_comp
- local cur_pos_before_comp
- local prettyprompt = args.prompt or ""
- local inv_col = args.fg_cursor or theme.fg_focus or "black"
- local cur_col = args.bg_cursor or theme.bg_focus or "white"
- local cur_ul = args.ul_cursor
- local text = args.text or ""
- local font = args.font or theme.font
- local selectall = args.selectall
- local hooks = {}
-
- -- A function with 9 parameters deserve to die
- if textbox then
- util.deprecate("Use args.textbox instead of the textbox parameter")
- end
- if exe_callback then
- util.deprecate(
- "Use args.exe_callback instead of the exe_callback parameter"
- )
- end
- if completion_callback then
- util.deprecate(
- "Use args.completion_callback instead of the completion_callback parameter"
- )
- end
- if history_path then
- util.deprecate(
- "Use args.history_path instead of the history_path parameter"
- )
- end
- if history_max then
- util.deprecate(
- "Use args.history_max instead of the history_max parameter"
- )
- end
- if done_callback then
- util.deprecate(
- "Use args.done_callback instead of the done_callback parameter"
- )
- end
- if changed_callback then
- util.deprecate(
- "Use args.changed_callback instead of the changed_callback parameter"
- )
- end
- if keypressed_callback then
- util.deprecate(
- "Use args.keypressed_callback instead of the keypressed_callback parameter"
- )
- end
-
- -- This function has already an absurd number of parameters, allow them
- -- to be set using the args to avoid a "nil, nil, nil, nil, foo" scenario
- keypressed_callback = keypressed_callback or args.keypressed_callback
- changed_callback = changed_callback or args.changed_callback
- done_callback = done_callback or args.done_callback
- history_max = history_max or args.history_max
- history_path = history_path or args.history_path
- completion_callback = completion_callback or args.completion_callback
- exe_callback = exe_callback or args.exe_callback
- textbox = textbox or args.textbox
-
- search_term=nil
-
- history_check_load(history_path, history_max)
- local history_index = history_items(history_path) + 1
- -- The cursor position
- local cur_pos = (selectall and 1) or text:wlen() + 1
- -- The completion element to use on completion request.
- local ncomp = 1
- if not textbox then
- return
- end
-
- -- Build the hook map
- for _,v in ipairs(args.hooks or {}) do
- if #v == 3 then
- local _,key,callback = unpack(v)
- if type(callback) == "function" then
- hooks[key] = hooks[key] or {}
- hooks[key][#hooks[key]+1] = v
- else
- assert("The hook's 3rd parameter has to be a function.")
- end
- else
- assert("The hook has to have 3 parameters.")
- end
- end
-
- textbox:set_font(font)
- textbox:set_markup(prompt_text_with_cursor{
- text = text, text_color = inv_col, cursor_color = cur_col,
- cursor_pos = cur_pos, cursor_ul = cur_ul, selectall = selectall,
- prompt = prettyprompt })
-
- local function exec(cb, command_to_history)
- textbox:set_markup("")
- history_add(history_path, command_to_history)
- keygrabber.stop(grabber)
- if cb then cb(command) end
- if done_callback then done_callback() end
- end
-
- -- Update textbox
- local function update()
- textbox:set_font(font)
- textbox:set_markup(prompt_text_with_cursor{
- text = command, text_color = inv_col, cursor_color = cur_col,
- cursor_pos = cur_pos, cursor_ul = cur_ul, selectall = selectall,
- prompt = prettyprompt })
- end
-
- grabber = keygrabber.run(
- function (modifiers, key, event)
- -- Convert index array to hash table
- local mod = {}
- for _, v in ipairs(modifiers) do mod[v] = true end
-
- if event ~= "press" then
- if args.keyreleased_callback then
- args.keyreleased_callback(mod, key, command)
- end
-
- return
- end
-
- -- Call the user specified callback. If it returns true as
- -- the first result then return from the function. Treat the
- -- second and third results as a new command and new prompt
- -- to be set (if provided)
- if keypressed_callback then
- local user_catched, new_command, new_prompt =
- keypressed_callback(mod, key, command)
- if new_command or new_prompt then
- if new_command then
- command = new_command
- end
- if new_prompt then
- prettyprompt = new_prompt
- end
- update()
- end
- if user_catched then
- if changed_callback then
- changed_callback(command)
- end
- return
- end
- end
-
- local filtered_modifiers = {}
-
- -- User defined cases
- if hooks[key] then
- -- Remove caps and num lock
- for _, m in ipairs(modifiers) do
- if not util.table.hasitem(akey.ignore_modifiers, m) then
- table.insert(filtered_modifiers, m)
- end
- end
-
- for _,v in ipairs(hooks[key]) do
- if #filtered_modifiers == #v[1] then
- local match = true
- for _,v2 in ipairs(v[1]) do
- match = match and mod[v2]
- end
- if match then
- local cb
- local ret = v[3](command)
- local original_command = command
- if ret then
- command = ret
- cb = exe_callback
- else
- -- No callback.
- cb = function() end
- end
- exec(cb, original_command)
- return
- end
- end
- end
- end
-
- -- Get out cases
- if (mod.Control and (key == "c" or key == "g"))
- or (not mod.Control and key == "Escape") then
- keygrabber.stop(grabber)
- textbox:set_markup("")
- history_save(history_path)
- if done_callback then done_callback() end
- return false
- elseif (mod.Control and (key == "j" or key == "m"))
- or (not mod.Control and key == "Return")
- or (not mod.Control and key == "KP_Enter") then
- exec(exe_callback, command)
- -- We already unregistered ourselves so we don't want to return
- -- true, otherwise we may unregister someone else.
- return
- end
-
- -- Control cases
- if mod.Control then
- selectall = nil
- if key == "a" then
- cur_pos = 1
- elseif key == "b" then
- if cur_pos > 1 then
- cur_pos = cur_pos - 1
- end
- elseif key == "d" then
- if cur_pos <= #command then
- command = command:sub(1, cur_pos - 1) .. command:sub(cur_pos + 1)
- end
- elseif key == "p" then
- if history_index > 1 then
- history_index = history_index - 1
-
- command = data.history[history_path].table[history_index]
- cur_pos = #command + 2
- end
- elseif key == "n" then
- if history_index < history_items(history_path) then
- history_index = history_index + 1
-
- command = data.history[history_path].table[history_index]
- cur_pos = #command + 2
- elseif history_index == history_items(history_path) then
- history_index = history_index + 1
-
- command = ""
- cur_pos = 1
- end
- elseif key == "e" then
- cur_pos = #command + 1
- elseif key == "r" then
- search_term = search_term or command:sub(1, cur_pos - 1)
- for i,v in (function(a,i) return itera(-1,a,i) end), data.history[history_path].table, history_index do
- if v:find(search_term,1,true) ~= nil then
- command=v
- history_index=i
- cur_pos=#command+1
- break
- end
- end
- elseif key == "s" then
- search_term = search_term or command:sub(1, cur_pos - 1)
- for i,v in (function(a,i) return itera(1,a,i) end), data.history[history_path].table, history_index do
- if v:find(search_term,1,true) ~= nil then
- command=v
- history_index=i
- cur_pos=#command+1
- break
- end
- end
- elseif key == "f" then
- if cur_pos <= #command then
- cur_pos = cur_pos + 1
- end
- elseif key == "h" then
- if cur_pos > 1 then
- command = command:sub(1, cur_pos - 2) .. command:sub(cur_pos)
- cur_pos = cur_pos - 1
- end
- elseif key == "k" then
- command = command:sub(1, cur_pos - 1)
- elseif key == "u" then
- command = command:sub(cur_pos, #command)
- cur_pos = 1
- elseif key == "Up" then
- search_term = command:sub(1, cur_pos - 1) or ""
- for i,v in (function(a,i) return itera(-1,a,i) end), data.history[history_path].table, history_index do
- if v:find(search_term,1,true) == 1 then
- command=v
- history_index=i
- break
- end
- end
- elseif key == "Down" then
- search_term = command:sub(1, cur_pos - 1) or ""
- for i,v in (function(a,i) return itera(1,a,i) end), data.history[history_path].table, history_index do
- if v:find(search_term,1,true) == 1 then
- command=v
- history_index=i
- break
- end
- end
- elseif key == "w" or key == "BackSpace" then
- local wstart = 1
- local wend = 1
- local cword_start_pos = 1
- local cword_end_pos = 1
- while wend < cur_pos do
- wend = command:find("[{[(,.:;_-+=@/ ]", wstart)
- if not wend then wend = #command + 1 end
- if cur_pos >= wstart and cur_pos <= wend + 1 then
- cword_start_pos = wstart
- cword_end_pos = cur_pos - 1
- break
- end
- wstart = wend + 1
- end
- command = command:sub(1, cword_start_pos - 1) .. command:sub(cword_end_pos + 1)
- cur_pos = cword_start_pos
- elseif key == "Delete" then
- -- delete from history only if:
- -- we are not dealing with a new command
- -- the user has not edited an existing entry
- if command == data.history[history_path].table[history_index] then
- table.remove(data.history[history_path].table, history_index)
- if history_index <= history_items(history_path) then
- command = data.history[history_path].table[history_index]
- cur_pos = #command + 2
- elseif history_index > 1 then
- history_index = history_index - 1
-
- command = data.history[history_path].table[history_index]
- cur_pos = #command + 2
- else
- command = ""
- cur_pos = 1
- end
- end
- end
- elseif mod.Mod1 or mod.Mod3 then
- if key == "b" then
- cur_pos = cword_start(command, cur_pos)
- elseif key == "f" then
- cur_pos = cword_end(command, cur_pos)
- elseif key == "d" then
- command = command:sub(1, cur_pos - 1) .. command:sub(cword_end(command, cur_pos))
- elseif key == "BackSpace" then
- local wstart = cword_start(command, cur_pos)
- command = command:sub(1, wstart - 1) .. command:sub(cur_pos)
- cur_pos = wstart
- end
- else
- if completion_callback then
- if key == "Tab" or key == "ISO_Left_Tab" then
- if key == "ISO_Left_Tab" then
- if ncomp == 1 then return end
- if ncomp == 2 then
- command = command_before_comp
- textbox:set_font(font)
- textbox:set_markup(prompt_text_with_cursor{
- text = command_before_comp, text_color = inv_col, cursor_color = cur_col,
- cursor_pos = cur_pos, cursor_ul = cur_ul, selectall = selectall,
- prompt = prettyprompt })
- return
- end
-
- ncomp = ncomp - 2
- elseif ncomp == 1 then
- command_before_comp = command
- cur_pos_before_comp = cur_pos
- end
- local matches
- command, cur_pos, matches = completion_callback(command_before_comp, cur_pos_before_comp, ncomp)
- ncomp = ncomp + 1
- key = ""
- -- execute if only one match found and autoexec flag set
- if matches and #matches == 1 and args.autoexec then
- exec(exe_callback)
- return
- end
- else
- ncomp = 1
- end
- end
-
- -- Typin cases
- if mod.Shift and key == "Insert" then
- local selection = capi.selection()
- if selection then
- -- Remove \n
- local n = selection:find("\n")
- if n then
- selection = selection:sub(1, n - 1)
- end
- command = command:sub(1, cur_pos - 1) .. selection .. command:sub(cur_pos)
- cur_pos = cur_pos + #selection
- end
- elseif key == "Home" then
- cur_pos = 1
- elseif key == "End" then
- cur_pos = #command + 1
- elseif key == "BackSpace" then
- if cur_pos > 1 then
- command = command:sub(1, cur_pos - 2) .. command:sub(cur_pos)
- cur_pos = cur_pos - 1
- end
- elseif key == "Delete" then
- command = command:sub(1, cur_pos - 1) .. command:sub(cur_pos + 1)
- elseif key == "Left" then
- cur_pos = cur_pos - 1
- elseif key == "Right" then
- cur_pos = cur_pos + 1
- elseif key == "Up" then
- if history_index > 1 then
- history_index = history_index - 1
-
- command = data.history[history_path].table[history_index]
- cur_pos = #command + 2
- end
- elseif key == "Down" then
- if history_index < history_items(history_path) then
- history_index = history_index + 1
-
- command = data.history[history_path].table[history_index]
- cur_pos = #command + 2
- elseif history_index == history_items(history_path) then
- history_index = history_index + 1
-
- command = ""
- cur_pos = 1
- end
- else
- -- wlen() is UTF-8 aware but #key is not,
- -- so check that we have one UTF-8 char but advance the cursor of # position
- if key:wlen() == 1 then
- if selectall then command = "" end
- command = command:sub(1, cur_pos - 1) .. key .. command:sub(cur_pos)
- cur_pos = cur_pos + #key
- end
- end
- if cur_pos < 1 then
- cur_pos = 1
- elseif cur_pos > #command + 1 then
- cur_pos = #command + 1
- end
- selectall = nil
- end
-
- local success = pcall(update)
- while not success do
- -- TODO UGLY HACK TODO
- -- Setting the text failed. Most likely reason is that the user
- -- entered a multibyte character and pressed backspace which only
- -- removed the last byte. Let's remove another byte.
- if cur_pos <= 1 then
- -- No text left?!
- break
- end
-
- command = command:sub(1, cur_pos - 2) .. command:sub(cur_pos)
- cur_pos = cur_pos - 1
- success = pcall(update)
- end
-
- if changed_callback then
- changed_callback(command)
- end
- end)
-end
-
-return prompt
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/remote.lua b/awesome/lib/awful/remote.lua
deleted file mode 100644
index 7967f2f..0000000
--- a/awesome/lib/awful/remote.lua
+++ /dev/null
@@ -1,47 +0,0 @@
----------------------------------------------------------------------------
---- Remote control module allowing usage of awesome-client.
---
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2009 Julien Danjou
--- @module awful.remote
----------------------------------------------------------------------------
-
--- Grab environment we need
-require("awful.dbus")
-local load = loadstring or load -- luacheck: globals loadstring (compatibility with Lua 5.1)
-local tostring = tostring
-local ipairs = ipairs
-local table = table
-local unpack = unpack or table.unpack -- luacheck: globals unpack (compatibility with Lua 5.1)
-local dbus = dbus
-local type = type
-
-if dbus then
- dbus.connect_signal("org.awesomewm.awful.Remote", function(data, code)
- if data.member == "Eval" then
- local f, e = load(code)
- if f then
- local results = { f() }
- local retvals = {}
- for _, v in ipairs(results) do
- local t = type(v)
- if t == "boolean" then
- table.insert(retvals, "b")
- table.insert(retvals, v)
- elseif t == "number" then
- table.insert(retvals, "d")
- table.insert(retvals, v)
- else
- table.insert(retvals, "s")
- table.insert(retvals, tostring(v))
- end
- end
- return unpack(retvals)
- elseif e then
- return "s", e
- end
- end
- end)
-end
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/rules.lua b/awesome/lib/awful/rules.lua
deleted file mode 100644
index dc44e00..0000000
--- a/awesome/lib/awful/rules.lua
+++ /dev/null
@@ -1,545 +0,0 @@
----------------------------------------------------------------------------
---- Apply rules to clients at startup.
---
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2009 Julien Danjou
--- @module awful.rules
----------------------------------------------------------------------------
-
--- Grab environment we need
-local client = client
-local awesome = awesome
-local screen = screen
-local table = table
-local type = type
-local ipairs = ipairs
-local pairs = pairs
-local atag = require("awful.tag")
-local util = require("awful.util")
-local a_place = require("awful.placement")
-local protected_call = require("gears.protected_call")
-
-local rules = {}
-
---[[--
-This is the global rules table.
-
-You should fill this table with your rule and properties to apply.
-For example, if you want to set xterm maximized at startup, you can add:
-
- { rule = { class = "xterm" },
- properties = { maximized_vertical = true, maximized_horizontal = true } }
-
-If you want to set mplayer floating at startup, you can add:
-
- { rule = { name = "MPlayer" },
- properties = { floating = true } }
-
-If you want to put Firefox on a specific tag at startup, you can add:
-
- { rule = { instance = "firefox" },
- properties = { tag = mytagobject } }
-
-Alternatively, you can specify the tag by name:
-
- { rule = { instance = "firefox" },
- properties = { tag = "3" } }
-
-If you want to put Thunderbird on a specific screen at startup, use:
-
- { rule = { instance = "Thunderbird" },
- properties = { screen = 1 } }
-
-Assuming that your X11 server supports the RandR extension, you can also specify
-the screen by name:
-
- { rule = { instance = "Thunderbird" },
- properties = { screen = "VGA1" } }
-
-If you want to put Emacs on a specific tag at startup, and immediately switch
-to that tag you can add:
-
- { rule = { class = "Emacs" },
- properties = { tag = mytagobject, switchtotag = true } }
-
-If you want to apply a custom callback to execute when a rule matched,
-for example to pause playing music from mpd when you start dosbox, you
-can add:
-
- { rule = { class = "dosbox" },
- callback = function(c)
- awful.spawn('mpc pause')
- end }
-
-Note that all "rule" entries need to match. If any of the entry does not
-match, the rule won't be applied.
-
-If a client matches multiple rules, they are applied in the order they are
-put in this global rules table. If the value of a rule is a string, then the
-match function is used to determine if the client matches the rule.
-
-If the value of a property is a function, that function gets called and
-function's return value is used for the property.
-
-To match multiple clients to a rule one need to use slightly different
-syntax:
-
- { rule_any = { class = { "MPlayer", "Nitrogen" }, instance = { "xterm" } },
- properties = { floating = true } }
-
-To match multiple clients with an exception one can couple `rules.except` or
-`rules.except_any` with the rules:
-
- { rule = { class = "Firefox" },
- except = { instance = "Navigator" },
- properties = {floating = true},
- },
-
- { rule_any = { class = { "Pidgin", "Xchat" } },
- except_any = { role = { "conversation" } },
- properties = { tag = "1" }
- }
-
- { rule = {},
- except_any = { class = { "Firefox", "Vim" } },
- properties = { floating = true }
- }
-]]--
-rules.rules = {}
-
---- Check if a client matches a rule.
--- @client c The client.
--- @tab rule The rule to check.
--- @treturn bool True if it matches, false otherwise.
-function rules.match(c, rule)
- if not rule then return false end
- for field, value in pairs(rule) do
- if c[field] then
- if type(c[field]) == "string" then
- if not c[field]:match(value) and c[field] ~= value then
- return false
- end
- elseif c[field] ~= value then
- return false
- end
- else
- return false
- end
- end
- return true
-end
-
---- Check if a client matches any part of a rule.
--- @client c The client.
--- @tab rule The rule to check.
--- @treturn bool True if at least one rule is matched, false otherwise.
-function rules.match_any(c, rule)
- if not rule then return false end
- for field, values in pairs(rule) do
- if c[field] then
- for _, value in ipairs(values) do
- if c[field] == value then
- return true
- elseif type(c[field]) == "string" and c[field]:match(value) then
- return true
- end
- end
- end
- end
- return false
-end
-
---- Does a given rule entry match a client?
--- @client c The client.
--- @tab entry Rule entry (with keys `rule`, `rule_any`, `except` and/or
--- `except_any`).
--- @treturn bool
-function rules.matches(c, entry)
- return (rules.match(c, entry.rule) or rules.match_any(c, entry.rule_any)) and
- (not rules.match(c, entry.except) and not rules.match_any(c, entry.except_any))
-end
-
---- Get list of matching rules for a client.
--- @client c The client.
--- @tab _rules The rules to check. List with "rule", "rule_any", "except" and
--- "except_any" keys.
--- @treturn table The list of matched rules.
-function rules.matching_rules(c, _rules)
- local result = {}
- for _, entry in ipairs(_rules) do
- if (rules.matches(c, entry)) then
- table.insert(result, entry)
- end
- end
- return result
-end
-
---- Check if a client matches a given set of rules.
--- @client c The client.
--- @tab _rules The rules to check. List of tables with `rule`, `rule_any`,
--- `except` and `except_any` keys.
--- @treturn bool True if at least one rule is matched, false otherwise.
-function rules.matches_list(c, _rules)
- for _, entry in ipairs(_rules) do
- if (rules.matches(c, entry)) then
- return true
- end
- end
- return false
-end
-
---- Apply awful.rules.rules to a client.
--- @client c The client.
-function rules.apply(c)
-
- local props = {}
- local callbacks = {}
-
- for _, entry in ipairs(rules.matching_rules(c, rules.rules)) do
- if entry.properties then
- for property, value in pairs(entry.properties) do
- props[property] = value
- end
- end
- if entry.callback then
- table.insert(callbacks, entry.callback)
- end
- end
-
- rules.execute(c, props, callbacks)
-end
-
-local function add_to_tag(c, t)
- if not t then return end
-
- local tags = c:tags()
- table.insert(tags, t)
- c:tags(tags)
-end
-
---- Extra rules properties.
---
--- These properties are used in the rules only and are not sent to the client
--- afterward.
---
--- To add a new properties, just do:
---
--- function awful.rules.extra_properties.my_new_property(c, value, props)
--- -- do something
--- end
---
--- By default, the table has the following functions:
---
--- * geometry
--- * switchtotag
---
--- @tfield table awful.rules.extra_properties
-rules.extra_properties = {}
-
---- Extra high priority properties.
---
--- Some properties, such as anything related to tags, geometry or focus, will
--- cause a race condition if set in the main property section. This is why
--- they have a section for them.
---
--- To add a new properties, just do:
---
--- function awful.rules.high_priority_properties.my_new_property(c, value, props)
--- -- do something
--- end
---
--- By default, the table has the following functions:
---
--- * tag
--- * new_tag
---
--- @tfield table awful.rules.high_priority_properties
-rules.high_priority_properties = {}
-
---- Delayed properties.
--- Properties applied after all other categories.
--- @tfield table awful.rules.delayed_properties
-rules.delayed_properties = {}
-
-local force_ignore = {
- titlebars_enabled=true, focus=true, screen=true, x=true,
- y=true, width=true, height=true, geometry=true,placement=true,
- border_width=true,floating=true,size_hints_honor=true
-}
-
-function rules.high_priority_properties.tag(c, value, props)
- if value then
- if type(value) == "string" then
- value = atag.find_by_name(c.screen, value)
- end
-
- -- In case the tag has been forced to another screen, move the client
- if c.screen ~= value.screen then
- c.screen = value.screen
- props.screen = value.screen -- In case another rule query it
- end
-
- c:tags{ value }
- end
-end
-
-function rules.delayed_properties.switchtotag(c, value)
- if not value then return end
-
- local selected_tags = {}
-
- for _,v in ipairs(c.screen.selected_tags) do
- selected_tags[v] = true
- end
-
- local tags = c:tags()
-
- for _, t in ipairs(tags) do
- t.selected = true
- selected_tags[t] = nil
- end
-
- for t in pairs(selected_tags) do
- t.selected = false
- end
-end
-
-function rules.extra_properties.geometry(c, _, props)
- local cur_geo = c:geometry()
-
- local new_geo = type(props.geometry) == "function"
- and props.geometry(c, props) or props.geometry or {}
-
- for _, v in ipairs {"x", "y", "width", "height"} do
- new_geo[v] = type(props[v]) == "function" and props[v](c, props)
- or props[v] or new_geo[v] or cur_geo[v]
- end
-
- c:geometry(new_geo) --TODO use request::geometry
-end
-
---- Create a new tag based on a rule.
--- @tparam client c The client
--- @tparam boolean|function|string value The value.
--- @tparam table props The properties.
--- @treturn tag The new tag
-function rules.high_priority_properties.new_tag(c, value, props)
- local ty = type(value)
- local t = nil
-
- if ty == "boolean" then
- -- Create a new tag named after the client class
- t = atag.add(c.class or "N/A", {screen=c.screen, volatile=true})
- elseif ty == "string" then
- -- Create a tag named after "value"
- t = atag.add(value, {screen=c.screen, volatile=true})
- elseif ty == "table" then
- -- Assume a table of tags properties. Set the right screen, but
- -- avoid editing the original table
- local values = value.screen and value or util.table.clone(value)
- values.screen = values.screen or c.screen
-
- t = atag.add(value.name or c.class or "N/A", values)
-
- -- In case the tag has been forced to another screen, move the client
- c.screen = t.screen
- props.screen = t.screen -- In case another rule query it
- else
- assert(false)
- end
-
- add_to_tag(c, t)
-
- return t
-end
-
-function rules.extra_properties.placement(c, value)
- -- Avoid problems
- if awesome.startup and
- (c.size_hints.user_position or c.size_hints.program_position) then
- return
- end
-
- local ty = type(value)
-
- local args = {
- honor_workarea = true,
- honor_padding = true
- }
-
- if ty == "function" or (ty == "table" and
- getmetatable(value) and getmetatable(value).__call
- ) then
- value(c, args)
- elseif ty == "string" and a_place[value] then
- a_place[value](c, args)
- end
-end
-
-function rules.extra_properties.tags(c, value, props)
- local current = c:tags()
-
- local tags, s = {}, nil
-
- for _, t in ipairs(value) do
- if type(t) == "string" then
- t = atag.find_by_name(c.screen, t)
- end
-
- if t and ((not s) or t.screen == s) then
- table.insert(tags, t)
- s = s or t.screen
- end
- end
-
- if s and s ~= c.screen then
- c.screen = s
- props.screen = s -- In case another rule query it
- end
-
- if #current == 0 or (value[1] and value[1].screen ~= current[1].screen) then
- c:tags(tags)
- else
- c:tags(util.table.merge(current, tags))
- end
-end
-
---- Apply properties and callbacks to a client.
--- @client c The client.
--- @tab props Properties to apply.
--- @tab[opt] callbacks Callbacks to apply.
-function rules.execute(c, props, callbacks)
- -- This has to be done first, as it will impact geometry related props.
- if props.titlebars_enabled then
- c:emit_signal("request::titlebars", "rules", {properties=props})
- end
-
- -- Border width will also cause geometry related properties to fail
- if props.border_width then
- c.border_width = type(props.border_width) == "function" and
- props.border_width(c, props) or props.border_width
- end
-
- -- Size hints will be re-applied when setting width/height unless it is
- -- disabled first
- if props.size_hints_honor ~= nil then
- c.size_hints_honor = type(props.size_hints_honor) == "function" and props.size_hints_honor(c,props)
- or props.size_hints_honor
- end
-
- -- Geometry will only work if floating is true, otherwise the "saved"
- -- geometry will be restored.
- if props.floating ~= nil then
- c.floating = type(props.floating) == "function" and props.floating(c,props)
- or props.floating
- end
-
- -- Before requesting a tag, make sure the screen is right
- if props.screen then
- c.screen = type(props.screen) == "function" and screen[props.screen(c,props)]
- or screen[props.screen]
- end
-
- -- Some properties need to be handled first. For example, many properties
- -- depend that the client is tagged, this isn't yet the case.
- for prop, handler in pairs(rules.high_priority_properties) do
- local value = props[prop]
-
- if value ~= nil then
- if type(value) == "function" then
- value = value(c, props)
- end
-
- handler(c, value, props)
- end
-
- end
-
- -- By default, rc.lua use no_overlap+no_offscreen placement. This has to
- -- be executed before x/y/width/height/geometry as it would otherwise
- -- always override the user specified position with the default rule.
- if props.placement then
- -- It may be a function, so this one doesn't execute it like others
- rules.extra_properties.placement(c, props.placement, props)
- end
-
- -- Make sure the tag is selected before the main rules are called.
- -- Otherwise properties like "urgent" or "focus" may fail because they
- -- will be overiden by various callbacks.
- -- Previously, this was done in a second client.manage callback, but caused
- -- a race condition where the order the require() would change the output.
- c:emit_signal("request::tag", nil, {reason="rules"})
-
- -- By default, rc.lua use no_overlap+no_offscreen placement. This has to
- -- be executed before x/y/width/height/geometry as it would otherwise
- -- always override the user specified position with the default rule.
- if props.placement then
- -- It may be a function, so this one doesn't execute it like others
- rules.extra_properties.placement(c, props.placement, props)
- end
-
- -- Now that the tags and screen are set, handle the geometry
- if props.height or props.width or props.x or props.y or props.geometry then
- rules.extra_properties.geometry(c, nil, props)
- end
-
- -- As most race conditions should now have been avoided, apply the remaining
- -- properties.
- for property, value in pairs(props) do
- if property ~= "focus" and type(value) == "function" then
- value = value(c, props)
- end
-
- local ignore = rules.high_priority_properties[property] or
- rules.delayed_properties[property] or force_ignore[property]
-
- if not ignore then
- if rules.extra_properties[property] then
- rules.extra_properties[property](c, value, props)
- elseif type(c[property]) == "function" then
- c[property](c, value)
- else
- c[property] = value
- end
- end
- end
-
- -- Apply all callbacks.
- if callbacks then
- for _, callback in pairs(callbacks) do
- protected_call(callback, c)
- end
- end
-
- -- Apply the delayed properties
- for prop, handler in pairs(rules.delayed_properties) do
- if not force_ignore[prop] then
- local value = props[prop]
-
- if value ~= nil then
- if type(value) == "function" then
- value = value(c, props)
- end
-
- handler(c, value, props)
- end
- end
- end
-
- -- Do this at last so we do not erase things done by the focus signal.
- if props.focus and (type(props.focus) ~= "function" or props.focus(c)) then
- c:emit_signal('request::activate', "rules", {raise=true})
- end
-end
-
-function rules.completed_with_payload_callback(c, props, callbacks)
- rules.execute(c, props, callbacks)
-end
-
-client.connect_signal("spawn::completed_with_payload", rules.completed_with_payload_callback)
-
-client.connect_signal("manage", rules.apply)
-
-return rules
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/screen.lua b/awesome/lib/awful/screen.lua
deleted file mode 100644
index e36e622..0000000
--- a/awesome/lib/awful/screen.lua
+++ /dev/null
@@ -1,477 +0,0 @@
----------------------------------------------------------------------------
---- Screen module for awful
---
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2008 Julien Danjou
--- @module screen
----------------------------------------------------------------------------
-
--- Grab environment we need
-local capi =
-{
- mouse = mouse,
- screen = screen,
- client = client,
- awesome = awesome,
-}
-local util = require("awful.util")
-local object = require("gears.object")
-local grect = require("gears.geometry").rectangle
-
-local function get_screen(s)
- return s and capi.screen[s]
-end
-
--- we use require("awful.client") inside functions to prevent circular dependencies.
-local client
-
-local screen = {object={}}
-
-local data = {}
-data.padding = {}
-
---- Take an input geometry and substract/add a delta.
--- @tparam table geo A geometry (width, height, x, y) table.
--- @tparam table delta A delta table (top, bottom, x, y).
--- @treturn table A geometry (width, height, x, y) table.
-local function apply_geometry_ajustments(geo, delta)
- return {
- x = geo.x + (delta.left or 0),
- y = geo.y + (delta.top or 0),
- width = geo.width - (delta.left or 0) - (delta.right or 0),
- height = geo.height - (delta.top or 0) - (delta.bottom or 0),
- }
-end
-
---- Get the square distance between a `screen` and a point.
--- @deprecated awful.screen.getdistance_sq
--- @param s Screen
--- @param x X coordinate of point
--- @param y Y coordinate of point
--- @return The squared distance of the screen to the provided point.
--- @see screen.get_square_distance
-function screen.getdistance_sq(s, x, y)
- util.deprecate("Use s:get_square_distance(x, y) instead of awful.screen.getdistance_sq")
- return screen.object.get_square_distance(s, x, y)
-end
-
---- Get the square distance between a `screen` and a point.
--- @function screen.get_square_distance
--- @tparam number x X coordinate of point
--- @tparam number y Y coordinate of point
--- @treturn number The squared distance of the screen to the provided point.
-function screen.object.get_square_distance(self, x, y)
- return grect.get_square_distance(get_screen(self).geometry, x, y)
-end
-
---- Return the screen index corresponding to the given (pixel) coordinates.
---
--- The number returned can be used as an index into the global
--- `screen` table/object.
--- @function awful.screen.getbycoord
--- @tparam number x The x coordinate
--- @tparam number y The y coordinate
--- @treturn ?number The screen index
-function screen.getbycoord(x, y)
- local s, sgeos = capi.screen.primary, {}
- for scr in capi.screen do
- sgeos[scr] = scr.geometry
- end
- s = grect.get_closest_by_coord(sgeos, x, y) or s
- return s and s.index
-end
-
---- Move the focus to a screen.
---
--- This moves the mouse pointer to the last known position on the new screen,
--- or keeps its position relative to the current focused screen.
--- @function awful.screen.focus
--- @screen _screen Screen number (defaults / falls back to mouse.screen).
-function screen.focus(_screen)
- client = client or require("awful.client")
- if type(_screen) == "number" and _screen > capi.screen.count() then _screen = screen.focused() end
- _screen = get_screen(_screen)
-
- -- screen and pos for current screen
- local s = get_screen(capi.mouse.screen)
- local pos
-
- if not _screen.mouse_per_screen then
- -- This is the first time we enter this screen,
- -- keep relative mouse position on the new screen.
- pos = capi.mouse.coords()
- local relx = (pos.x - s.geometry.x) / s.geometry.width
- local rely = (pos.y - s.geometry.y) / s.geometry.height
-
- pos.x = _screen.geometry.x + relx * _screen.geometry.width
- pos.y = _screen.geometry.y + rely * _screen.geometry.height
- else
- -- restore mouse position
- pos = _screen.mouse_per_screen
- end
-
- -- save pointer position of current screen
- s.mouse_per_screen = capi.mouse.coords()
-
- -- move cursor without triggering signals mouse::enter and mouse::leave
- capi.mouse.coords(pos, true)
-
- local c = client.focus.history.get(_screen, 0)
- if c then
- c:emit_signal("request::activate", "screen.focus", {raise=false})
- end
-end
-
---- Move the focus to a screen in a specific direction.
---
--- This moves the mouse pointer to the last known position on the new screen,
--- or keeps its position relative to the current focused screen.
--- @function awful.screen.focus_bydirection
--- @param dir The direction, can be either "up", "down", "left" or "right".
--- @param _screen Screen.
-function screen.focus_bydirection(dir, _screen)
- local sel = get_screen(_screen or screen.focused())
- if sel then
- local geomtbl = {}
- for s in capi.screen do
- geomtbl[s] = s.geometry
- end
- local target = grect.get_in_direction(dir, geomtbl, sel.geometry)
- if target then
- return screen.focus(target)
- end
- end
-end
-
---- Move the focus to a screen relative to the current one,
---
--- This moves the mouse pointer to the last known position on the new screen,
--- or keeps its position relative to the current focused screen.
---
--- @function awful.screen.focus_relative
--- @tparam int offset Value to add to the current focused screen index. 1 to
--- focus the next one, -1 to focus the previous one.
-function screen.focus_relative(offset)
- return screen.focus(util.cycle(capi.screen.count(),
- screen.focused().index + offset))
-end
-
---- Get or set the screen padding.
---
--- @deprecated awful.screen.padding
--- @param _screen The screen object to change the padding on
--- @param[opt=nil] padding The padding, a table with 'top', 'left', 'right' and/or
--- 'bottom' or a number value to apply set the same padding on all sides. Can be
--- nil if you only want to retrieve padding
--- @treturn table A table with left, right, top and bottom number values.
--- @see padding
-function screen.padding(_screen, padding)
- util.deprecate("Use _screen.padding = value instead of awful.screen.padding")
- if padding then
- screen.object.set_padding(_screen, padding)
- end
- return screen.object.get_padding(_screen)
-end
-
---- The screen padding.
---
--- This adds a "buffer" section on each side of the screen.
---
--- **Signal:**
---
--- * *property::padding*
---
--- @property padding
--- @param table
--- @tfield integer table.left The padding on the left.
--- @tfield integer table.right The padding on the right.
--- @tfield integer table.top The padding on the top.
--- @tfield integer table.bottom The padding on the bottom.
-
-function screen.object.get_padding(self)
- local p = data.padding[self] or {}
- -- Create a copy to avoid accidental mutation and nil values.
- return {
- left = p.left or 0,
- right = p.right or 0,
- top = p.top or 0,
- bottom = p.bottom or 0,
- }
-end
-
-function screen.object.set_padding(self, padding)
- if type(padding) == "number" then
- padding = {
- left = padding,
- right = padding,
- top = padding,
- bottom = padding,
- }
- end
-
- self = get_screen(self)
- if padding then
- data.padding[self] = padding
- self:emit_signal("padding")
- end
-end
-
---- Get the preferred screen in the context of a client.
---
--- This is exactly the same as `awful.screen.focused` except that it avoids
--- clients being moved when Awesome is restarted.
--- This is used in the default `rc.lua` to ensure clients get assigned to the
--- focused screen by default.
--- @tparam client c A client.
--- @treturn screen The preferred screen.
-function screen.preferred(c)
- return capi.awesome.startup and c.screen or screen.focused()
-end
-
---- The defaults arguments for `awful.screen.focused`.
--- @tfield[opt=nil] table awful.screen.default_focused_args
-
---- Get the focused screen.
---
--- It is possible to set `awful.screen.default_focused_args` to override the
--- default settings.
---
--- @function awful.screen.focused
--- @tparam[opt] table args
--- @tparam[opt=false] boolean args.client Use the client screen instead of the
--- mouse screen.
--- @tparam[opt=true] boolean args.mouse Use the mouse screen
--- @treturn ?screen The focused screen object, or `nil` in case no screen is
--- present currently.
-function screen.focused(args)
- args = args or screen.default_focused_args or {}
- return get_screen(
- args.client and capi.client.focus and capi.client.focus.screen or capi.mouse.screen
- )
-end
-
---- Get a placement bounding geometry.
---
--- This method computes the different variants of the "usable" screen geometry.
---
--- @function screen.get_bounding_geometry
--- @tparam[opt={}] table args The arguments
--- @tparam[opt=false] boolean args.honor_padding Whether to honor the screen's padding.
--- @tparam[opt=false] boolean args.honor_workarea Whether to honor the screen's workarea.
--- @tparam[opt] int|table args.margins Apply some margins on the output.
--- This can either be a number or a table with *left*, *right*, *top*
--- and *bottom* keys.
--- @tag[opt] args.tag Use this tag's screen.
--- @tparam[opt] drawable args.parent A parent drawable to use as base geometry.
--- @tab[opt] args.bounding_rect A bounding rectangle. This parameter is
--- incompatible with `honor_workarea`.
--- @treturn table A table with *x*, *y*, *width* and *height*.
--- @usage local geo = screen:get_bounding_geometry {
--- honor_padding = true,
--- honor_workarea = true,
--- margins = {
--- left = 20,
--- },
--- }
-function screen.object.get_bounding_geometry(self, args)
- args = args or {}
-
- -- If the tag has a geometry, assume it is right
- if args.tag then
- self = args.tag.screen
- end
-
- self = get_screen(self or capi.mouse.screen)
-
- local geo = args.bounding_rect or (args.parent and args.parent:geometry()) or
- self[args.honor_workarea and "workarea" or "geometry"]
-
- if (not args.parent) and (not args.bounding_rect) and args.honor_padding then
- local padding = self.padding
- geo = apply_geometry_ajustments(geo, padding)
- end
-
- if args.margins then
- geo = apply_geometry_ajustments(geo,
- type(args.margins) == "table" and args.margins or {
- left = args.margins, right = args.margins,
- top = args.margins, bottom = args.margins,
- }
- )
- end
- return geo
-end
-
---- Get the list of visible clients for the screen.
---
--- Minimized and unmanaged clients are not included in this list as they are
--- technically not on the screen.
---
--- The clients on tags that are currently not visible are not part of this list.
---
--- @property clients
--- @param table The clients list, ordered from top to bottom.
--- @see all_clients
--- @see hidden_clients
--- @see client.get
-
-function screen.object.get_clients(s)
- local cls = capi.client.get(s, true)
- local vcls = {}
- for _, c in pairs(cls) do
- if c:isvisible() then
- table.insert(vcls, c)
- end
- end
- return vcls
-end
-
---- Get the list of clients assigned to the screen but not currently visible.
---
--- This includes minimized clients and clients on hidden tags.
---
--- @property hidden_clients
--- @param table The clients list, ordered from top to bottom.
--- @see clients
--- @see all_clients
--- @see client.get
-
-function screen.object.get_hidden_clients(s)
- local cls = capi.client.get(s, true)
- local vcls = {}
- for _, c in pairs(cls) do
- if not c:isvisible() then
- table.insert(vcls, c)
- end
- end
- return vcls
-end
-
---- Get all clients assigned to the screen.
---
--- @property all_clients
--- @param table The clients list, ordered from top to bottom.
--- @see clients
--- @see hidden_clients
--- @see client.get
-
-function screen.object.get_all_clients(s)
- return capi.client.get(s, true)
-end
-
---- Get the list of tiled clients for the screen.
---
--- Same as `clients`, but excluding:
---
--- * fullscreen clients
--- * maximized clients
--- * floating clients
---
--- @property tiled_clients
--- @param table The clients list, ordered from top to bottom.
-
-function screen.object.get_tiled_clients(s)
- local clients = s.clients
- local tclients = {}
- -- Remove floating clients
- for _, c in pairs(clients) do
- if not c.floating
- and not c.fullscreen
- and not c.maximized_vertical
- and not c.maximized_horizontal then
- table.insert(tclients, c)
- end
- end
- return tclients
-end
-
---- Call a function for each existing and created-in-the-future screen.
---
--- @function awful.screen.connect_for_each_screen
--- @tparam function func The function to call.
--- @screen func.screen The screen.
-function screen.connect_for_each_screen(func)
- for s in capi.screen do
- func(s)
- end
- capi.screen.connect_signal("added", func)
-end
-
---- Undo the effect of connect_for_each_screen.
--- @function awful.screen.disconnect_for_each_screen
--- @tparam function func The function that should no longer be called.
-function screen.disconnect_for_each_screen(func)
- capi.screen.disconnect_signal("added", func)
-end
-
---- A list of all tags on the screen.
---
--- This property is read only, use `tag.screen`, `awful.tag.add`,
--- `awful.tag.new` or `t:delete()` to alter this list.
---
--- @property tags
--- @param table
--- @treturn table A table with all available tags.
-
-function screen.object.get_tags(s, unordered)
- local tags = {}
-
- for _, t in ipairs(root.tags()) do
- if get_screen(t.screen) == s then
- table.insert(tags, t)
- end
- end
-
- -- Avoid infinite loop and save some time.
- if not unordered then
- table.sort(tags, function(a, b)
- return (a.index or math.huge) < (b.index or math.huge)
- end)
- end
- return tags
-end
-
---- A list of all selected tags on the screen.
--- @property selected_tags
--- @param table
--- @treturn table A table with all selected tags.
--- @see tag.selected
--- @see client.to_selected_tags
-
-function screen.object.get_selected_tags(s)
- local tags = screen.object.get_tags(s, true)
-
- local vtags = {}
- for _, t in pairs(tags) do
- if t.selected then
- vtags[#vtags + 1] = t
- end
- end
- return vtags
-end
-
---- The first selected tag.
--- @property selected_tag
--- @param table
--- @treturn ?tag The first selected tag or nil.
--- @see tag.selected
--- @see selected_tags
-
-function screen.object.get_selected_tag(s)
- return screen.object.get_selected_tags(s)[1]
-end
-
-
---- When the tag history changed.
--- @signal tag::history::update
-
--- Extend the luaobject
-object.properties(capi.screen, {
- getter_class = screen.object,
- setter_class = screen.object,
- auto_emit = true,
-})
-
-return screen
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/spawn.lua b/awesome/lib/awful/spawn.lua
deleted file mode 100644
index bcfb68d..0000000
--- a/awesome/lib/awful/spawn.lua
+++ /dev/null
@@ -1,421 +0,0 @@
----------------------------------------------------------------------------
---- Spawning of programs.
---
--- This module provides methods to start programs and supports startup
--- notifications, which allows for callbacks and applying properties to the
--- program after it has been launched. This requires currently that the
--- applicaton supports them.
---
--- **Rules of thumb when a shell is needed**:
---
--- * A shell is required when the commands contain `&&`, `;`, `||`, `&` or
--- any other unix shell language syntax
--- * When shell variables are defined as part of the command
--- * When the command is a shell alias
---
--- Note that a shell is **not** a terminal emulator. A terminal emulator is
--- something like XTerm, Gnome-terminal or Konsole. A shell is something like
--- `bash`, `zsh`, `busybox sh` or `Debian ash`.
---
--- If you wish to open a process in a terminal window, check that your terminal
--- emulator supports the common `-e` option. If it does, then something like
--- this should work:
---
--- awful.spawn(terminal.." -e my_command")
---
--- Note that some terminals, such as rxvt-unicode (urxvt) support full commands
--- using quotes, while other terminal emulators require to use quoting.
---
--- **Understanding clients versus PID versus commands versus class**:
---
--- A *process* has a *PID* (process identifier). It can have 0, 1 or many
--- *window*s.
---
--- A *command* if what is used to start *process*(es). It has no direct relation
--- with *process*, *client* or *window*. When a command is executed, it will
--- usually start a *process* which keeps running until it exits. This however is
--- not always the case as some applications use scripts as command and others
--- use various single-instance mechanisms (usually client/server) and merge
--- with an existing process.
---
--- A *client* corresponds to a *window*. It is owned by a process. It can have
--- both a parent and one or many children. A *client* has a *class*, an
--- *instance*, a *role*, and a *type*. See `client.class`, `client.instance`,
--- `client.role` and `client.type` for more information about these properties.
---
--- **The startup notification protocol**:
---
--- The startup notification protocol is an optional specification implemented
--- by X11 applications to bridge the chain of knowledge between the moment a
--- program is launched to the moment its window (client) is shown. It can be
--- found [on the FreeDesktop.org website](https://www.freedesktop.org/wiki/Specifications/startup-notification-spec/).
---
--- Awesome has support for the various events that are part of the protocol, but
--- the most useful is the identifier, usually identified by its `SNID` acronym in
--- the documentation. It isn't usually necessary to even know it exists, as it
--- is all done automatically. However, if more control is required, the
--- identifier can be specified by an environment variable called
--- `DESKTOP_STARTUP_ID`. For example, let us consider execution of the following
--- command:
---
--- DESKTOP_STARTUP_ID="something_TIME$(date '+%s')" my_command
---
--- This should (if the program correctly implements the protocol) result in
--- `c.startup_id` to at least match `something`.
--- This identifier can then be used in `awful.rules` to configure the client.
---
--- Awesome can automatically set the `DESKTOP_STARTUP_ID` variable. This is used
--- by `awful.spawn` to specify additional rules for the startup. For example:
---
--- awful.spawn("urxvt -e maxima -name CALCULATOR", {
--- floating = true,
--- tag = mouse.screen.selected_tag,
--- placement = awful.placement.bottom_right,
--- })
---
--- This can also be used from the command line:
---
--- awesome-client 'awful=require("awful");
--- awful.spawn("urxvt -e maxima -name CALCULATOR", {
--- floating = true,
--- tag = mouse.screen.selected_tag,
--- placement = awful.placement.bottom_right,
--- })'
---
--- **Getting a command's output**:
---
--- First, do **not** use `io.popen` **ever**. It is synchronous. Synchronous
--- functions **block everything** until they are done. All visual applications
--- lock (as Awesome no longer responds), you will probably lose some keyboard
--- and mouse events and will have higher latency when playing games. This is
--- also true when reading files synchronously, but this is another topic.
---
--- Awesome provides a few ways to get output from commands. One is to use the
--- `Gio` libraries directly. This is usually very complicated, but gives a lot
--- of control on the command execution.
---
--- This modules provides `with_line_callback` and `easy_async` for convenience.
--- First, lets add this bash command to `rc.lua`:
---
--- local noisy = [[bash -c '
--- for I in $(seq 1 5); do
--- date
--- echo err >&2
--- sleep 2
--- done
--- ']]
---
--- It prints a bunch of junk on the standard output (*stdout*) and error
--- (*stderr*) streams. This command would block Awesome for 10 seconds if it
--- were executed synchronously, but will not block it at all using the
--- asynchronous functions.
---
--- `with_line_callback` will execute the callbacks every time a new line is
--- printed by the command:
---
--- awful.spawn.with_line_callback(noisy, {
--- stdout = function(line)
--- naughty.notify { text = "LINE:"..line }
--- end,
--- stderr = function(line)
--- naughty.notify { text = "ERR:"..line}
--- end,
--- })
---
--- If only the full output is needed, then `easy_async` is the right choice:
---
--- awful.spawn.easy_async(noisy, function(stdout, stderr, reason, exit_code)
--- naughty.notify { text = stdout }
--- end)
---
--- **Default applications**:
---
--- If the intent is to open a file/document, then it is recommended to use the
--- following standard command. The default application will be selected
--- according to the [Shared MIME-info Database](https://specifications.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-latest.html)
--- specification. The `xdg-utils` package provided by most distributions
--- includes the `xdg-open` command:
---
--- awful.spawn({"xdg-open", "/path/to/file"})
---
--- Awesome **does not** manage, modify or otherwise influence the database
--- for default applications. For information about how to do this, consult the
--- [ARCH Linux Wiki](https://wiki.archlinux.org/index.php/default_applications).
---
--- If you wish to change how the default applications behave, then consult the
--- [Desktop Entry](https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html)
--- specification.
---
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @author Emmanuel Lepage Vallee &lt;elv1313@gmail.com&gt;
--- @copyright 2008 Julien Danjou
--- @copyright 2014 Emmanuel Lepage Vallee
--- @module awful.spawn
----------------------------------------------------------------------------
-
-local capi =
-{
- awesome = awesome,
- mouse = mouse,
- client = client,
-}
-local lgi = require("lgi")
-local Gio = lgi.Gio
-local GLib = lgi.GLib
-local util = require("awful.util")
-local protected_call = require("gears.protected_call")
-
-local spawn = {}
-
-
-local end_of_file
-do
- -- API changes, bug fixes and lots of fun. Figure out how a EOF is signalled.
- local input
- if not pcall(function()
- -- No idea when this API changed, but some versions expect a string,
- -- others a table with some special(?) entries
- input = Gio.DataInputStream.new(Gio.MemoryInputStream.new_from_data(""))
- end) then
- input = Gio.DataInputStream.new(Gio.MemoryInputStream.new_from_data({}))
- end
- local line, length = input:read_line()
- if not line then
- -- Fixed in 2016: NULL on the C side is transformed to nil in Lua
- end_of_file = function(arg)
- return not arg
- end
- elseif tostring(line) == "" and #line ~= length then
- -- "Historic" behaviour for end-of-file:
- -- - NULL is turned into an empty string
- -- - The length variable is not initialized
- -- It's highly unlikely that the uninitialized variable has value zero.
- -- Use this hack to detect EOF.
- end_of_file = function(arg1, arg2)
- return #arg1 ~= arg2
- end
- else
- assert(tostring(line) == "", "Cannot determine how to detect EOF")
- -- The above uninitialized variable was fixed and thus length is
- -- always 0 when line is NULL in C. We cannot tell apart an empty line and
- -- EOF in this case.
- require("gears.debug").print_warning("Cannot reliably detect EOF on an "
- .. "GIOInputStream with this LGI version")
- end_of_file = function(arg)
- return tostring(arg) == ""
- end
- end
-end
-
-spawn.snid_buffer = {}
-
-function spawn.on_snid_callback(c)
- local entry = spawn.snid_buffer[c.startup_id]
- if entry then
- local props = entry[1]
- local callback = entry[2]
- c:emit_signal("spawn::completed_with_payload", props, callback)
- spawn.snid_buffer[c.startup_id] = nil
- end
-end
-
-function spawn.on_snid_cancel(id)
- if spawn.snid_buffer[id] then
- spawn.snid_buffer[id] = nil
- end
-end
-
---- Spawn a program, and optionally apply properties and/or run a callback.
---
--- Applying properties or running a callback requires the program/client to
--- support startup notifications.
---
--- See `awful.rules.execute` for more details about the format of `sn_rules`.
---
--- @tparam string|table cmd The command.
--- @tparam[opt=true] table|boolean sn_rules A table of properties to be applied
--- after startup; `false` to disable startup notifications.
--- @tparam[opt] function callback A callback function to be run after startup.
--- @treturn[1] integer The forked PID.
--- @treturn[1] ?string The startup notification ID, if `sn` is not false, or
--- a `callback` is provided.
--- @treturn[2] string Error message.
-function spawn.spawn(cmd, sn_rules, callback)
- if cmd and cmd ~= "" then
- local enable_sn = (sn_rules ~= false or callback)
- enable_sn = not not enable_sn -- Force into a boolean.
- local pid, snid = capi.awesome.spawn(cmd, enable_sn)
- -- The snid will be nil in case of failure
- if snid then
- sn_rules = type(sn_rules) ~= "boolean" and sn_rules or {}
- spawn.snid_buffer[snid] = { sn_rules, { callback } }
- end
- return pid, snid
- end
- -- For consistency
- return "Error: No command to execute"
-end
-
---- Spawn a program using the shell.
--- This calls `cmd` with `$SHELL -c` (via `awful.util.shell`).
--- @tparam string cmd The command.
-function spawn.with_shell(cmd)
- if cmd and cmd ~= "" then
- cmd = { util.shell, "-c", cmd }
- return capi.awesome.spawn(cmd, false)
- end
-end
-
---- Spawn a program and asynchronously capture its output line by line.
--- @tparam string|table cmd The command.
--- @tab callbacks Table containing callbacks that should be invoked on
--- various conditions.
--- @tparam[opt] function callbacks.stdout Function that is called with each
--- line of output on stdout, e.g. `stdout(line)`.
--- @tparam[opt] function callbacks.stderr Function that is called with each
--- line of output on stderr, e.g. `stderr(line)`.
--- @tparam[opt] function callbacks.output_done Function to call when no more
--- output is produced.
--- @tparam[opt] function callbacks.exit Function to call when the spawned
--- process exits. This function gets the exit reason and code as its
--- arguments.
--- The reason can be "exit" or "signal".
--- For "exit", the second argument is the exit code.
--- For "signal", the second argument is the signal causing process
--- termination.
--- @treturn[1] Integer the PID of the forked process.
--- @treturn[2] string Error message.
-function spawn.with_line_callback(cmd, callbacks)
- local stdout_callback, stderr_callback, done_callback, exit_callback =
- callbacks.stdout, callbacks.stderr, callbacks.output_done, callbacks.exit
- local have_stdout, have_stderr = stdout_callback ~= nil, stderr_callback ~= nil
- local pid, _, stdin, stdout, stderr = capi.awesome.spawn(cmd,
- false, false, have_stdout, have_stderr, exit_callback)
- if type(pid) == "string" then
- -- Error
- return pid
- end
-
- local done_before = false
- local function step_done()
- if have_stdout and have_stderr and not done_before then
- done_before = true
- return
- end
- if done_callback then
- done_callback()
- end
- end
- if have_stdout then
- spawn.read_lines(Gio.UnixInputStream.new(stdout, true),
- stdout_callback, step_done, true)
- end
- if have_stderr then
- spawn.read_lines(Gio.UnixInputStream.new(stderr, true),
- stderr_callback, step_done, true)
- end
- assert(stdin == nil)
- return pid
-end
-
---- Asynchronously spawn a program and capture its output.
--- (wraps `spawn.with_line_callback`).
--- @tparam string|table cmd The command.
--- @tab callback Function with the following arguments
--- @tparam string callback.stdout Output on stdout.
--- @tparam string callback.stderr Output on stderr.
--- @tparam string callback.exitreason Exit Reason.
--- The reason can be "exit" or "signal".
--- @tparam integer callback.exitcode Exit code.
--- For "exit" reason it's the exit code.
--- For "signal" reason — the signal causing process termination.
--- @treturn[1] Integer the PID of the forked process.
--- @treturn[2] string Error message.
--- @see spawn.with_line_callback
-function spawn.easy_async(cmd, callback)
- local stdout = ''
- local stderr = ''
- local exitcode, exitreason
- local function parse_stdout(str)
- stdout = stdout .. str .. "\n"
- end
- local function parse_stderr(str)
- stderr = stderr .. str .. "\n"
- end
- local function done_callback()
- return callback(stdout, stderr, exitreason, exitcode)
- end
- local exit_callback_fired = false
- local output_done_callback_fired = false
- local function exit_callback(reason, code)
- exitcode = code
- exitreason = reason
- exit_callback_fired = true
- if output_done_callback_fired then
- return done_callback()
- end
- end
- local function output_done_callback()
- output_done_callback_fired = true
- if exit_callback_fired then
- return done_callback()
- end
- end
- return spawn.with_line_callback(
- cmd, {
- stdout=parse_stdout,
- stderr=parse_stderr,
- exit=exit_callback,
- output_done=output_done_callback
- })
-end
-
---- Read lines from a Gio input stream
--- @tparam Gio.InputStream input_stream The input stream to read from.
--- @tparam function line_callback Function that is called with each line
--- read, e.g. `line_callback(line_from_stream)`.
--- @tparam[opt] function done_callback Function that is called when the
--- operation finishes (e.g. due to end of file).
--- @tparam[opt=false] boolean close Should the stream be closed after end-of-file?
-function spawn.read_lines(input_stream, line_callback, done_callback, close)
- local stream = Gio.DataInputStream.new(input_stream)
- local function done()
- if close then
- stream:close()
- end
- if done_callback then
- protected_call(done_callback)
- end
- end
- local start_read, finish_read
- start_read = function()
- stream:read_line_async(GLib.PRIORITY_DEFAULT, nil, finish_read)
- end
- finish_read = function(obj, res)
- local line, length = obj:read_line_finish(res)
- if type(length) ~= "number" then
- -- Error
- print("Error in awful.spawn.read_lines:", tostring(length))
- done()
- elseif end_of_file(line, length) then
- -- End of file
- done()
- else
- -- Read a line
- -- This needs tostring() for older lgi versions which returned
- -- "GLib.Bytes" instead of Lua strings (I guess)
- protected_call(line_callback, tostring(line))
-
- -- Read the next line
- start_read()
- end
- end
- start_read()
-end
-
-capi.awesome.connect_signal("spawn::canceled" , spawn.on_snid_cancel )
-capi.awesome.connect_signal("spawn::timeout" , spawn.on_snid_cancel )
-capi.client.connect_signal ("manage" , spawn.on_snid_callback )
-
-return setmetatable(spawn, { __call = function(_, ...) return spawn.spawn(...) end })
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/startup_notification.lua b/awesome/lib/awful/startup_notification.lua
deleted file mode 100644
index 5f1c123..0000000
--- a/awesome/lib/awful/startup_notification.lua
+++ /dev/null
@@ -1,53 +0,0 @@
----------------------------------------------------------------------------
---- Startup notification module for awful
---
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2009 Julien Danjou
--- @module awful.startup_notification
----------------------------------------------------------------------------
-
--- Grab environment we need
-local ipairs = ipairs
-local table = table
-local capi =
-{
- awesome = awesome,
- root = root
-}
-
-local app_starting = {}
-
-local cursor_waiting = "watch"
-
-local function update_cursor()
- if #app_starting > 0 then
- capi.root.cursor(cursor_waiting)
- else
- capi.root.cursor("left_ptr")
- end
-end
-
-local function unregister_event(event_id)
- for k, v in ipairs(app_starting) do
- if v == event_id then
- table.remove(app_starting, k)
- update_cursor()
- break
- end
- end
-end
-
-local function register_event(event_id)
- table.insert(app_starting, event_id)
- update_cursor()
-end
-
-local function unregister_hook(event) unregister_event(event.id) end
-local function register_hook(event) register_event(event.id) end
-
-capi.awesome.connect_signal("spawn::initiated", register_hook)
-capi.awesome.connect_signal("spawn::canceled", unregister_hook)
-capi.awesome.connect_signal("spawn::completed", unregister_hook)
-capi.awesome.connect_signal("spawn::timeout", unregister_hook)
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/tag.lua b/awesome/lib/awful/tag.lua
deleted file mode 100644
index dbf3a60..0000000
--- a/awesome/lib/awful/tag.lua
+++ /dev/null
@@ -1,1505 +0,0 @@
----------------------------------------------------------------------------
---- Useful functions for tag manipulation.
---
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2008 Julien Danjou
--- @module tag
----------------------------------------------------------------------------
-
--- Grab environment we need
-local util = require("awful.util")
-local ascreen = require("awful.screen")
-local beautiful = require("beautiful")
-local object = require("gears.object")
-local timer = require("gears.timer")
-local pairs = pairs
-local ipairs = ipairs
-local table = table
-local setmetatable = setmetatable
-local capi =
-{
- tag = tag,
- screen = screen,
- mouse = mouse,
- client = client,
- root = root
-}
-
-local function get_screen(s)
- return s and capi.screen[s]
-end
-
-local tag = {object = {}, mt = {} }
-
--- Private data
-local data = {}
-data.history = {}
-
--- History functions
-tag.history = {}
-tag.history.limit = 20
-
--- Default values
-local defaults = {}
-
--- The gap between clients (in points).
-defaults.gap = 0
-
--- The default gap_count.
-defaults.gap_single_client = true
-
--- The default master fill policy.
-defaults.master_fill_policy = "expand"
-
--- The default master width factor.
-defaults.master_width_factor = 0.5
-
--- The default master count.
-defaults.master_count = 1
-
--- The default column count.
-defaults.column_count = 1
-
--- screen.tags depend on index, it cannot be used by awful.tag
-local function raw_tags(scr)
- local tmp_tags = {}
- for _, t in ipairs(root.tags()) do
- if get_screen(t.screen) == scr then
- table.insert(tmp_tags, t)
- end
- end
-
- return tmp_tags
-end
-
---- The number of elements kept in the history.
--- @tfield integer awful.tag.history.limit
--- @tparam[opt=20] integer limit
-
---- The tag index.
---
--- The index is the position as shown in the `awful.widget.taglist`.
---
--- **Signal:**
---
--- * *property::index*
---
--- @property index
--- @param integer
--- @treturn number The tag index.
-
-function tag.object.set_index(self, idx)
- local scr = get_screen(tag.getproperty(self, "screen"))
-
- -- screen.tags cannot be used as it depend on index
- local tmp_tags = raw_tags(scr)
-
- -- sort the tags by index
- table.sort(tmp_tags, function(a, b)
- local ia, ib = tag.getproperty(a, "index"), tag.getproperty(b, "index")
- return (ia or math.huge) < (ib or math.huge)
- end)
-
- if (not idx) or (idx < 1) or (idx > #tmp_tags) then
- return
- end
-
- local rm_index = nil
-
- for i, t in ipairs(tmp_tags) do
- if t == self then
- table.remove(tmp_tags, i)
- rm_index = i
- break
- end
- end
-
- table.insert(tmp_tags, idx, self)
- for i = idx < rm_index and idx or rm_index, #tmp_tags do
- local tmp_tag = tmp_tags[i]
- tag.object.set_screen(tmp_tag, scr)
- tag.setproperty(tmp_tag, "index", i)
- end
-end
-
-function tag.object.get_index(query_tag)
-
- local idx = tag.getproperty(query_tag, "index")
-
- if idx then return idx end
-
- -- Get an unordered list of tags
- local tags = raw_tags(query_tag.screen)
-
- -- Too bad, lets compute it
- for i, t in ipairs(tags) do
- if t == query_tag then
- tag.setproperty(t, "index", i)
- return i
- end
- end
-end
-
---- Move a tag to an absolute position in the screen[]:tags() table.
--- @deprecated awful.tag.move
--- @param new_index Integer absolute position in the table to insert.
--- @param target_tag The tag that should be moved. If null, the currently
--- selected tag is used.
--- @see index
-function tag.move(new_index, target_tag)
- util.deprecate("Use t.index = new_index instead of awful.tag.move")
-
- target_tag = target_tag or ascreen.focused().selected_tag
- tag.object.set_index(target_tag, new_index)
-end
-
---- Swap 2 tags
--- @function tag.swap
--- @param tag2 The second tag
--- @see client.swap
-function tag.object.swap(self, tag2)
- local idx1, idx2 = tag.object.get_index(self), tag.object.get_index(tag2)
- local scr2, scr1 = tag.getproperty(tag2, "screen"), tag.getproperty(self, "screen")
-
- -- If they are on the same screen, avoid recomputing the whole table
- -- for nothing.
- if scr1 == scr2 then
- tag.setproperty(self, "index", idx2)
- tag.setproperty(tag2, "index", idx1)
- else
- tag.object.set_screen(tag2, scr1)
- tag.object.set_index (tag2, idx1)
- tag.object.set_screen(self, scr2)
- tag.object.set_index (self, idx2)
- end
-end
-
---- Swap 2 tags
--- @deprecated awful.tag.swap
--- @see tag.swap
--- @param tag1 The first tag
--- @param tag2 The second tag
-function tag.swap(tag1, tag2)
- util.deprecate("Use t:swap(tag2) instead of awful.tag.swap")
-
- tag.object.swap(tag1, tag2)
-end
-
---- Add a tag.
---
--- This function allow to create tags from a set of properties:
---
--- local t = awful.tag.add("my new tag", {
--- screen = screen.primary,
--- layout = awful.layout.suit.max,
--- })
---
--- @function awful.tag.add
--- @param name The tag name, a string
--- @param props The tags inital properties, a table
--- @return The created tag
--- @see tag.delete
-function tag.add(name, props)
- local properties = props or {}
-
- -- Be sure to set the screen before the tag is activated to avoid function
- -- connected to property::activated to be called without a valid tag.
- -- set properties cannot be used as this has to be set before the first
- -- signal is sent
- properties.screen = get_screen(properties.screen or ascreen.focused())
- -- Index is also required
- properties.index = properties.index or #raw_tags(properties.screen)+1
-
- local newtag = capi.tag{ name = name }
-
- -- Start with a fresh property table to avoid collisions with unsupported data
- newtag.data.awful_tag_properties = {screen=properties.screen, index=properties.index}
-
- newtag.activated = true
-
- for k, v in pairs(properties) do
- -- `rawget` doesn't work on userdata, `:clients()` is the only relevant
- -- entry.
- if k == "clients" or tag.object[k] then
- newtag[k](newtag, v)
- else
- newtag[k] = v
- end
- end
-
- return newtag
-end
-
---- Create a set of tags and attach it to a screen.
--- @function awful.tag.new
--- @param names The tag name, in a table
--- @param screen The tag screen, or 1 if not set.
--- @param layout The layout or layout table to set for this tags by default.
--- @return A table with all created tags.
-function tag.new(names, screen, layout)
- screen = get_screen(screen or 1)
- local tags = {}
- for id, name in ipairs(names) do
- table.insert(tags, id, tag.add(name, {screen = screen,
- layout = (layout and layout[id]) or
- layout}))
- -- Select the first tag.
- if id == 1 then
- tags[id].selected = true
- end
- end
-
- return tags
-end
-
---- Find a suitable fallback tag.
--- @function awful.tag.find_fallback
--- @param screen The screen to look for a tag on. [awful.screen.focused()]
--- @param invalids A table of tags we consider unacceptable. [selectedlist(scr)]
-function tag.find_fallback(screen, invalids)
- local scr = screen or ascreen.focused()
- local t = invalids or scr.selected_tags
-
- for _, v in pairs(scr.tags) do
- if not util.table.hasitem(t, v) then return v end
- end
-end
-
---- Delete a tag.
---
--- To delete the current tag:
---
--- mouse.screen.selected_tag:delete()
---
--- @function tag.delete
--- @see awful.tag.add
--- @see awful.tag.find_fallback
--- @tparam[opt=awful.tag.find_fallback()] tag fallback_tag Tag to assign
--- stickied tags to.
--- @tparam[opt=false] boolean force Move even non-sticky clients to the fallback
--- tag.
--- @return Returns true if the tag is successfully deleted.
--- If there are no clients exclusively on this tag then delete it. Any
--- stickied clients are assigned to the optional 'fallback_tag'.
--- If after deleting the tag there is no selected tag, try and restore from
--- history or select the first tag on the screen.
-function tag.object.delete(self, fallback_tag, force)
- -- abort if the taf isn't currently activated
- if not self.activated then return false end
-
- local target_scr = get_screen(tag.getproperty(self, "screen"))
- local tags = target_scr.tags
- local idx = tag.object.get_index(self)
- local ntags = #tags
-
- -- We can't use the target tag as a fallback.
- if fallback_tag == self then return false end
-
- -- No fallback_tag provided, try and get one.
- if fallback_tag == nil then
- fallback_tag = tag.find_fallback(target_scr, {self})
- end
-
- -- Abort if we would have un-tagged clients.
- local clients = self:clients()
- if #clients > 0 and fallback_tag == nil then return false end
-
- -- Move the clients we can off of this tag.
- for _, c in pairs(clients) do
- local nb_tags = #c:tags()
-
- -- If a client has only this tag, or stickied clients with
- -- nowhere to go, abort.
- if (not c.sticky and nb_tags == 1 and not force) then
- return
- -- If a client has multiple tags, then do not move it to fallback
- elseif nb_tags < 2 then
- c:tags({fallback_tag})
- end
- end
-
- -- delete the tag
- self.data.awful_tag_properties.screen = nil
- self.activated = false
-
- -- Update all indexes
- for i=idx+1, #tags do
- tag.setproperty(tags[i], "index", i-1)
- end
-
- -- If no tags are visible (and we did not delete the lasttag), try and
- -- view one. The > 1 is because ntags is no longer synchronized with the
- -- current count.
- if target_scr.selected_tag == nil and ntags > 1 then
- tag.history.restore(target_scr, 1)
- if target_scr.selected_tag == nil then
- local other_tag = tags[tags[1] == self and 2 or 1]
- if other_tag then
- other_tag.selected = true
- end
- end
- end
-
- return true
-end
-
---- Delete a tag.
--- @deprecated awful.tag.delete
--- @see tag.delete
--- @param target_tag Optional tag object to delete. [selected()]
--- @param fallback_tag Tag to assign stickied tags to. [~selected()]
--- @return Returns true if the tag is successfully deleted, nil otherwise.
--- If there are no clients exclusively on this tag then delete it. Any
--- stickied clients are assigned to the optional 'fallback_tag'.
--- If after deleting the tag there is no selected tag, try and restore from
--- history or select the first tag on the screen.
-function tag.delete(target_tag, fallback_tag)
- util.deprecate("Use t:delete(fallback_tag) instead of awful.tag.delete")
-
- return tag.object.delete(target_tag, fallback_tag)
-end
-
---- Update the tag history.
--- @function awful.tag.history.update
--- @param obj Screen object.
-function tag.history.update(obj)
- local s = get_screen(obj)
- local curtags = s.selected_tags
- -- create history table
- if not data.history[s] then
- data.history[s] = {}
- else
- if data.history[s].current then
- -- Check that the list is not identical
- local identical = #data.history[s].current == #curtags
- if identical then
- for idx, _tag in ipairs(data.history[s].current) do
- if curtags[idx] ~= _tag then
- identical = false
- break
- end
- end
- end
-
- -- Do not update history the table are identical
- if identical then return end
- end
-
- -- Limit history
- if #data.history[s] >= tag.history.limit then
- for i = tag.history.limit, #data.history[s] do
- data.history[s][i] = nil
- end
- end
- end
-
- -- store previously selected tags in the history table
- table.insert(data.history[s], 1, data.history[s].current)
- data.history[s].previous = data.history[s][1]
- -- store currently selected tags
- data.history[s].current = setmetatable(curtags, { __mode = 'v' })
-end
-
---- Revert tag history.
--- @function awful.tag.history.restore
--- @param screen The screen.
--- @param idx Index in history. Defaults to "previous" which is a special index
--- toggling between last two selected sets of tags. Number (eg 1) will go back
--- to the given index in history.
-function tag.history.restore(screen, idx)
- local s = get_screen(screen or ascreen.focused())
- local i = idx or "previous"
- local sel = s.selected_tags
- -- do nothing if history empty
- if not data.history[s] or not data.history[s][i] then return end
- -- if all tags been deleted, try next entry
- if #data.history[s][i] == 0 then
- if i == "previous" then i = 0 end
- tag.history.restore(s, i + 1)
- return
- end
- -- deselect all tags
- tag.viewnone(s)
- -- select tags from the history entry
- for _, t in ipairs(data.history[s][i]) do
- if t.activated and t.screen then
- t.selected = true
- end
- end
- -- update currently selected tags table
- data.history[s].current = data.history[s][i]
- -- store previously selected tags
- data.history[s].previous = setmetatable(sel, { __mode = 'v' })
- -- remove the reverted history entry
- if i ~= "previous" then table.remove(data.history[s], i) end
-
- s:emit_signal("tag::history::update")
-end
-
---- Get a list of all tags on a screen
--- @deprecated awful.tag.gettags
--- @tparam screen s Screen
--- @return A table with all available tags
--- @see screen.tags
-function tag.gettags(s)
- util.deprecate("Use s.tags instead of awful.tag.gettags")
-
- s = get_screen(s)
-
- return s and s.tags or {}
-end
-
---- Find a tag by name
--- @tparam[opt] screen s The screen of the tag
--- @tparam string name The name of the tag
--- @return The tag found, or `nil`
-function tag.find_by_name(s, name)
- local tags = s and s.tags or root.tags()
- for _, t in ipairs(tags) do
- if name == t.name then
- return t
- end
- end
-end
-
---- The tag screen.
---
--- **Signal:**
---
--- * *property::screen*
---
--- @property screen
--- @param screen
--- @see screen
-
-function tag.object.set_screen(t, s)
-
- s = get_screen(s or ascreen.focused())
- local sel = tag.selected
- local old_screen = get_screen(tag.getproperty(t, "screen"))
-
- if s == old_screen then return end
-
- -- Keeping the old index make very little sense when changing screen
- tag.setproperty(t, "index", nil)
-
- -- Change the screen
- tag.setproperty(t, "screen", s)
- tag.setproperty(t, "index", #s:get_tags(true))
-
- -- Make sure the client's screen matches its tags
- for _,c in ipairs(t:clients()) do
- c.screen = s --Move all clients
- c:tags({t})
- end
-
- -- Update all indexes
- for i,t2 in ipairs(old_screen.tags) do
- tag.setproperty(t2, "index", i)
- end
-
- -- Restore the old screen history if the tag was selected
- if sel then
- tag.history.restore(old_screen, 1)
- end
-end
-
---- Set a tag's screen
--- @deprecated awful.tag.setscreen
--- @see screen
--- @param s Screen
--- @param t tag object
-function tag.setscreen(s, t)
- -- For API consistency, the arguments have been swapped for Awesome 3.6
- -- this method is already deprecated, so be silent and swap the args
- if type(t) == "number" then
- s, t = t, s
- end
-
- util.deprecate("Use t.screen = s instead of awful.tag.setscreen(t, s)")
-
- tag.object.set_screen(t, s)
-end
-
---- Get a tag's screen
--- @deprecated awful.tag.getscreen
--- @see screen
--- @param[opt] t tag object
--- @return Screen number
-function tag.getscreen(t)
- util.deprecate("Use t.screen instead of awful.tag.getscreen(t)")
-
- -- A new getter is not required
-
- t = t or ascreen.focused().selected_tag
- local prop = tag.getproperty(t, "screen")
- return prop and prop.index
-end
-
---- Return a table with all visible tags
--- @deprecated awful.tag.selectedlist
--- @param s Screen.
--- @return A table with all selected tags.
--- @see screen.selected_tags
-function tag.selectedlist(s)
- util.deprecate("Use s.selected_tags instead of awful.tag.selectedlist")
-
- s = get_screen(s or ascreen.focused())
-
- return s.selected_tags
-end
-
---- Return only the first visible tag.
--- @deprecated awful.tag.selected
--- @param s Screen.
--- @see screen.selected_tag
-function tag.selected(s)
- util.deprecate("Use s.selected_tag instead of awful.tag.selected")
-
- s = get_screen(s or ascreen.focused())
-
- return s.selected_tag
-end
-
---- The default master width factor
---
--- @beautiful beautiful.master_width_factor
--- @param number (default: 0.5)
--- @see master_width_factor
--- @see gap
-
---- The tag master width factor.
---
--- The master width factor is one of the 5 main properties used to configure
--- the `layout`. Each layout interpret (or ignore) this property differenly.
---
--- See the layout suit documentation for information about how the master width
--- factor is used.
---
--- **Signal:**
---
--- * *property::mwfact* (deprecated)
--- * *property::master_width_factor*
---
--- @property master_width_factor
--- @param number Between 0 and 1
--- @see master_count
--- @see column_count
--- @see master_fill_policy
--- @see gap
-
-function tag.object.set_master_width_factor(t, mwfact)
- if mwfact >= 0 and mwfact <= 1 then
- tag.setproperty(t, "mwfact", mwfact)
- tag.setproperty(t, "master_width_factor", mwfact)
- end
-end
-
-function tag.object.get_master_width_factor(t)
- return tag.getproperty(t, "master_width_factor")
- or beautiful.master_width_factor
- or defaults.master_width_factor
-end
-
---- Set master width factor.
--- @deprecated awful.tag.setmwfact
--- @see master_fill_policy
--- @see master_width_factor
--- @param mwfact Master width factor.
--- @param t The tag to modify, if null tag.selected() is used.
-function tag.setmwfact(mwfact, t)
- util.deprecate("Use t.master_width_factor = mwfact instead of awful.tag.setmwfact")
-
- tag.object.get_master_width_factor(t or ascreen.focused().selected_tag, mwfact)
-end
-
---- Increase master width factor.
--- @function awful.tag.incmwfact
--- @see master_width_factor
--- @param add Value to add to master width factor.
--- @param t The tag to modify, if null tag.selected() is used.
-function tag.incmwfact(add, t)
- t = t or t or ascreen.focused().selected_tag
- tag.object.set_master_width_factor(t, tag.object.get_master_width_factor(t) + add)
-end
-
---- Get master width factor.
--- @deprecated awful.tag.getmwfact
--- @see master_width_factor
--- @see master_fill_policy
--- @param[opt] t The tag.
-function tag.getmwfact(t)
- util.deprecate("Use t.master_width_factor instead of awful.tag.getmwfact")
-
- return tag.object.get_master_width_factor(t or ascreen.focused().selected_tag)
-end
-
---- An ordered list of layouts.
--- `awful.tag.layout` Is usually defined in `rc.lua`. It store the list of
--- layouts used when selecting the previous and next layouts. This is the
--- default:
---
--- -- Table of layouts to cover with awful.layout.inc, order matters.
--- awful.layout.layouts = {
--- awful.layout.suit.floating,
--- awful.layout.suit.tile,
--- awful.layout.suit.tile.left,
--- awful.layout.suit.tile.bottom,
--- awful.layout.suit.tile.top,
--- awful.layout.suit.fair,
--- awful.layout.suit.fair.horizontal,
--- awful.layout.suit.spiral,
--- awful.layout.suit.spiral.dwindle,
--- awful.layout.suit.max,
--- awful.layout.suit.max.fullscreen,
--- awful.layout.suit.magnifier,
--- awful.layout.suit.corner.nw,
--- -- awful.layout.suit.corner.ne,
--- -- awful.layout.suit.corner.sw,
--- -- awful.layout.suit.corner.se,
--- }
---
--- @field awful.tag.layouts
-
---- The tag client layout.
---
--- This property hold the layout. A layout can be either stateless or stateful.
--- Stateless layouts are used by default by Awesome. They tile clients without
--- any other overhead. They take an ordered list of clients and place them on
--- the screen. Stateful layouts create an object instance for each tags and
--- can store variables and metadata. Because of this, they are able to change
--- over time and be serialized (saved).
---
--- Both types of layouts have valid usage scenarios.
---
--- **Stateless layouts:**
---
--- These layouts are stored in `awful.layout.suit`. They expose a table with 2
--- fields:
---
--- * **name** (*string*): The layout name. This should be unique.
--- * **arrange** (*function*): The function called when the clients need to be
--- placed. The only parameter is a table or arguments returned by
--- `awful.layout.parameters`
---
--- **Stateful layouts:**
---
--- The stateful layouts API is the same as stateless, but they are a function
--- returining a layout instead of a layout itself. They also should have an
--- `is_dynamic = true` property. If they don't, `awful.tag` will create a new
--- instance everytime the layout is set. If they do, the instance will be
--- cached and re-used.
---
--- **Signal:**
---
--- * *property::layout*
---
--- @property layout
--- @see awful.tag.layouts
--- @tparam layout|function layout A layout table or a constructor function
--- @return The layout
-
-function tag.object.set_layout(t, layout)
- -- Check if the signature match a stateful layout
- if type(layout) == "function" or (
- type(layout) == "table"
- and getmetatable(layout)
- and getmetatable(layout).__call
- ) then
- if not t.dynamic_layout_cache then
- t.dynamic_layout_cache = {}
- end
-
- local instance = t.dynamic_layout_cache[layout] or layout(t)
-
- -- Always make sure the layout is notified it is enabled
- if tag.getproperty(t, "screen").selected_tag == t and instance.wake_up then
- instance:wake_up()
- end
-
- -- Avoid creating the same layout twice, use layout:reset() to reset
- if instance.is_dynamic then
- t.dynamic_layout_cache[layout] = instance
- end
-
- layout = instance
- end
-
- tag.setproperty(t, "layout", layout)
-
- return layout
-end
-
---- Set layout.
--- @deprecated awful.tag.setlayout
--- @see layout
--- @param layout a layout table or a constructor function
--- @param t The tag to modify
--- @return The layout
-function tag.setlayout(layout, t)
- util.deprecate("Use t.layout = layout instead of awful.tag.setlayout")
-
- return tag.object.set_layout(t, layout)
-end
-
---- Define if the tag must be deleted when the last client is untagged.
---
--- This is useful to create "throw-away" tags for operation like 50/50
--- side-by-side views.
---
--- local t = awful.tag.add("Temporary", {
--- screen = client.focus.screen,
--- volatile = true,
--- clients = {
--- client.focus,
--- awful.client.focus.history.get(client.focus.screen, 1)
--- }
--- }
---
--- **Signal:**
---
--- * *property::volatile*
---
--- @property volatile
--- @param boolean
-
--- Volatile accessors are implicit
-
---- Set if the tag must be deleted when the last client is untagged
--- @deprecated awful.tag.setvolatile
--- @see volatile
--- @tparam boolean volatile If the tag must be deleted when the last client is untagged
--- @param t The tag to modify, if null tag.selected() is used.
-function tag.setvolatile(volatile, t)
- util.deprecate("Use t.volatile = volatile instead of awful.tag.setvolatile")
-
- tag.setproperty(t, "volatile", volatile)
-end
-
---- Get if the tag must be deleted when the last client closes
--- @deprecated awful.tag.getvolatile
--- @see volatile
--- @param t The tag to modify, if null tag.selected() is used.
--- @treturn boolean If the tag will be deleted when the last client is untagged
-function tag.getvolatile(t)
- util.deprecate("Use t.volatile instead of awful.tag.getvolatile")
-
- return tag.getproperty(t, "volatile") or false
-end
-
---- The default gap.
---
--- @beautiful beautiful.useless_gap
--- @param number (default: 0)
--- @see gap
--- @see gap_single_client
-
---- The gap (spacing, also called `useless_gap`) between clients.
---
--- This property allow to waste space on the screen in the name of style,
--- unicorns and readability.
---
--- **Signal:**
---
--- * *property::useless_gap*
---
--- @property gap
--- @param number The value has to be greater than zero.
--- @see gap_single_client
-
-function tag.object.set_gap(t, useless_gap)
- if useless_gap >= 0 then
- tag.setproperty(t, "useless_gap", useless_gap)
- end
-end
-
-function tag.object.get_gap(t)
- return tag.getproperty(t, "useless_gap")
- or beautiful.useless_gap
- or defaults.gap
-end
-
---- Set the spacing between clients
--- @deprecated awful.tag.setgap
--- @see gap
--- @param useless_gap The spacing between clients
--- @param t The tag to modify, if null tag.selected() is used.
-function tag.setgap(useless_gap, t)
- util.deprecate("Use t.gap = useless_gap instead of awful.tag.setgap")
-
- tag.object.set_gap(t or ascreen.focused().selected_tag, useless_gap)
-end
-
---- Increase the spacing between clients
--- @function awful.tag.incgap
--- @see gap
--- @param add Value to add to the spacing between clients
--- @param t The tag to modify, if null tag.selected() is used.
-function tag.incgap(add, t)
- t = t or t or ascreen.focused().selected_tag
- tag.object.set_gap(t, tag.object.get_gap(t) + add)
-end
-
---- Enable gaps for a single client.
---
--- @beautiful beautiful.gap_single_client
--- @param boolean (default: true)
--- @see gap
--- @see gap_single_client
-
---- Enable gaps for a single client.
---
--- **Signal:**
---
--- * *property::gap\_single\_client*
---
--- @property gap_single_client
--- @param boolean Enable gaps for a single client
-
-function tag.object.set_gap_single_client(t, gap_single_client)
- tag.setproperty(t, "gap_single_client", gap_single_client == true)
-end
-
-function tag.object.get_gap_single_client(t)
- local val = tag.getproperty(t, "gap_single_client")
- if val ~= nil then
- return val
- end
- val = beautiful.gap_single_client
- if val ~= nil then
- return val
- end
- return defaults.gap_single_client
-end
-
---- Get the spacing between clients.
--- @deprecated awful.tag.getgap
--- @see gap
--- @tparam[opt=tag.selected()] tag t The tag.
--- @tparam[opt] int numclients Number of (tiled) clients. Passing this will
--- return 0 for a single client. You can override this function to change
--- this behavior.
-function tag.getgap(t, numclients)
- util.deprecate("Use t.gap instead of awful.tag.getgap")
-
- if numclients == 1 then
- return 0
- end
-
- return tag.object.get_gap(t or ascreen.focused().selected_tag)
-end
-
---- The default fill policy.
---
--- ** Possible values**:
---
--- * *expand*: Take all the space
--- * *master_width_factor*: Only take the ratio defined by the
--- `master_width_factor`
---
--- @beautiful beautiful.master_fill_policy
--- @param string (default: "expand")
--- @see master_fill_policy
-
---- Set size fill policy for the master client(s).
---
--- ** Possible values**:
---
--- * *expand*: Take all the space
--- * *master_width_factor*: Only take the ratio defined by the
--- `master_width_factor`
---
--- **Signal:**
---
--- * *property::master_fill_policy*
---
--- @property master_fill_policy
--- @param string "expand" or "master_width_factor"
-
-function tag.object.get_master_fill_policy(t)
- return tag.getproperty(t, "master_fill_policy")
- or beautiful.master_fill_policy
- or defaults.master_fill_policy
-end
-
---- Set size fill policy for the master client(s)
--- @deprecated awful.tag.setmfpol
--- @see master_fill_policy
--- @tparam string policy Can be set to
--- "expand" (fill all the available workarea) or
--- "master_width_factor" (fill only an area inside the master width factor)
--- @tparam[opt=tag.selected()] tag t The tag to modify
-function tag.setmfpol(policy, t)
- util.deprecate("Use t.master_fill_policy = policy instead of awful.tag.setmfpol")
-
- t = t or ascreen.focused().selected_tag
- tag.setproperty(t, "master_fill_policy", policy)
-end
-
---- Toggle size fill policy for the master client(s)
--- between "expand" and "master_width_factor".
--- @function awful.tag.togglemfpol
--- @see master_fill_policy
--- @tparam tag t The tag to modify, if null tag.selected() is used.
-function tag.togglemfpol(t)
- t = t or ascreen.focused().selected_tag
-
- if tag.getmfpol(t) == "expand" then
- tag.setproperty(t, "master_fill_policy", "master_width_factor")
- else
- tag.setproperty(t, "master_fill_policy", "expand")
- end
-end
-
---- Get size fill policy for the master client(s)
--- @deprecated awful.tag.getmfpol
--- @see master_fill_policy
--- @tparam[opt=tag.selected()] tag t The tag
--- @treturn string Possible values are
--- "expand" (fill all the available workarea, default one) or
--- "master_width_factor" (fill only an area inside the master width factor)
-function tag.getmfpol(t)
- util.deprecate("Use t.master_fill_policy instead of awful.tag.getmfpol")
-
- t = t or ascreen.focused().selected_tag
- return tag.getproperty(t, "master_fill_policy")
- or beautiful.master_fill_policy
- or defaults.master_fill_policy
-end
-
---- The default number of master windows.
---
--- @beautiful beautiful.master_count
--- @param integer (default: 1)
--- @see master_count
-
---- Set the number of master windows.
---
--- **Signal:**
---
--- * *property::nmaster* (deprecated)
--- * *property::master_count* (deprecated)
---
--- @property master_count
--- @param integer nmaster Only positive values are accepted
-
-function tag.object.set_master_count(t, nmaster)
- if nmaster >= 0 then
- tag.setproperty(t, "nmaster", nmaster)
- tag.setproperty(t, "master_count", nmaster)
- end
-end
-
-function tag.object.get_master_count(t)
- return tag.getproperty(t, "master_count")
- or beautiful.master_count
- or defaults.master_count
-end
-
----
--- @deprecated awful.tag.setnmaster
--- @see master_count
--- @param nmaster The number of master windows.
--- @param[opt] t The tag.
-function tag.setnmaster(nmaster, t)
- util.deprecate("Use t.master_count = nmaster instead of awful.tag.setnmaster")
-
- tag.object.set_master_count(t or ascreen.focused().selected_tag, nmaster)
-end
-
---- Get the number of master windows.
--- @deprecated awful.tag.getnmaster
--- @see master_count
--- @param[opt] t The tag.
-function tag.getnmaster(t)
- util.deprecate("Use t.master_count instead of awful.tag.setnmaster")
-
- t = t or ascreen.focused().selected_tag
- return tag.getproperty(t, "master_count") or 1
-end
-
---- Increase the number of master windows.
--- @function awful.tag.incnmaster
--- @see master_count
--- @param add Value to add to number of master windows.
--- @param[opt] t The tag to modify, if null tag.selected() is used.
--- @tparam[opt=false] boolean sensible Limit nmaster based on the number of
--- visible tiled windows?
-function tag.incnmaster(add, t, sensible)
- t = t or ascreen.focused().selected_tag
-
- if sensible then
- local screen = get_screen(tag.getproperty(t, "screen"))
- local ntiled = #screen.tiled_clients
-
- local nmaster = tag.object.get_master_count(t)
- if nmaster > ntiled then
- nmaster = ntiled
- end
-
- local newnmaster = nmaster + add
- if newnmaster > ntiled then
- newnmaster = ntiled
- end
- tag.object.set_master_count(t, newnmaster)
- else
- tag.object.set_master_count(t, tag.object.get_master_count(t) + add)
- end
-end
-
---- Set the tag icon.
---
--- **Signal:**
---
--- * *property::icon*
---
--- @property icon
--- @tparam path|surface icon The icon
-
--- accessors are implicit.
-
---- Set the tag icon
--- @deprecated awful.tag.seticon
--- @see icon
--- @param icon the icon to set, either path or image object
--- @param _tag the tag
-function tag.seticon(icon, _tag)
- util.deprecate("Use t.icon = icon instead of awful.tag.seticon")
-
- _tag = _tag or ascreen.focused().selected_tag
- tag.setproperty(_tag, "icon", icon)
-end
-
---- Get the tag icon
--- @deprecated awful.tag.geticon
--- @see icon
--- @param _tag the tag
-function tag.geticon(_tag)
- util.deprecate("Use t.icon instead of awful.tag.geticon")
-
- _tag = _tag or ascreen.focused().selected_tag
- return tag.getproperty(_tag, "icon")
-end
-
---- The default number of columns.
---
--- @beautiful beautiful.column_count
--- @param integer (default: 1)
--- @see column_count
-
---- Set the number of columns.
---
--- **Signal:**
---
--- * *property::ncol* (deprecated)
--- * *property::column_count*
---
--- @property column_count
--- @tparam integer ncol Has to be greater than 1
-
-function tag.object.set_column_count(t, ncol)
- if ncol >= 1 then
- tag.setproperty(t, "ncol", ncol)
- tag.setproperty(t, "column_count", ncol)
- end
-end
-
-function tag.object.get_column_count(t)
- return tag.getproperty(t, "column_count")
- or beautiful.column_count
- or defaults.column_count
-end
-
---- Set number of column windows.
--- @deprecated awful.tag.setncol
--- @see column_count
--- @param ncol The number of column.
--- @param t The tag to modify, if null tag.selected() is used.
-function tag.setncol(ncol, t)
- util.deprecate("Use t.column_count = new_index instead of awful.tag.setncol")
-
- t = t or ascreen.focused().selected_tag
- if ncol >= 1 then
- tag.setproperty(t, "ncol", ncol)
- tag.setproperty(t, "column_count", ncol)
- end
-end
-
---- Get number of column windows.
--- @deprecated awful.tag.getncol
--- @see column_count
--- @param[opt] t The tag.
-function tag.getncol(t)
- util.deprecate("Use t.column_count instead of awful.tag.getncol")
-
- t = t or ascreen.focused().selected_tag
- return tag.getproperty(t, "column_count") or 1
-end
-
---- Increase number of column windows.
--- @function awful.tag.incncol
--- @param add Value to add to number of column windows.
--- @param[opt] t The tag to modify, if null tag.selected() is used.
--- @tparam[opt=false] boolean sensible Limit column_count based on the number
--- of visible tiled windows?
-function tag.incncol(add, t, sensible)
- t = t or ascreen.focused().selected_tag
-
- if sensible then
- local screen = get_screen(tag.getproperty(t, "screen"))
- local ntiled = #screen.tiled_clients
- local nmaster = tag.object.get_master_count(t)
- local nsecondary = ntiled - nmaster
-
- local ncol = tag.object.get_column_count(t)
- if ncol > nsecondary then
- ncol = nsecondary
- end
-
- local newncol = ncol + add
- if newncol > nsecondary then
- newncol = nsecondary
- end
-
- tag.object.set_column_count(t, newncol)
- else
- tag.object.set_column_count(t, tag.object.get_column_count(t) + add)
- end
-end
-
---- View no tag.
--- @function awful.tag.viewnone
--- @tparam[opt] int|screen screen The screen.
-function tag.viewnone(screen)
- screen = screen or ascreen.focused()
- local tags = screen.tags
- for _, t in pairs(tags) do
- t.selected = false
- end
-end
-
---- View a tag by its taglist index.
---
--- This is equivalent to `screen.tags[i]:view_only()`
--- @function awful.tag.viewidx
--- @see screen.tags
--- @param i The **relative** index to see.
--- @param[opt] screen The screen.
-function tag.viewidx(i, screen)
- screen = get_screen(screen or ascreen.focused())
- local tags = screen.tags
- local showntags = {}
- for _, t in ipairs(tags) do
- if not tag.getproperty(t, "hide") then
- table.insert(showntags, t)
- end
- end
- local sel = screen.selected_tag
- tag.viewnone(screen)
- for k, t in ipairs(showntags) do
- if t == sel then
- showntags[util.cycle(#showntags, k + i)].selected = true
- end
- end
- screen:emit_signal("tag::history::update")
-end
-
---- Get a tag's index in the gettags() table.
--- @deprecated awful.tag.getidx
--- @see index
--- @param query_tag The tag object to find. [selected()]
--- @return The index of the tag, nil if the tag is not found.
-function tag.getidx(query_tag)
- util.deprecate("Use t.index instead of awful.tag.getidx")
-
- return tag.object.get_index(query_tag or ascreen.focused().selected_tag)
-end
-
---- View next tag. This is the same as tag.viewidx(1).
--- @function awful.tag.viewnext
--- @param screen The screen.
-function tag.viewnext(screen)
- return tag.viewidx(1, screen)
-end
-
---- View previous tag. This is the same a tag.viewidx(-1).
--- @function awful.tag.viewprev
--- @param screen The screen.
-function tag.viewprev(screen)
- return tag.viewidx(-1, screen)
-end
-
---- View only a tag.
--- @function tag.view_only
--- @see selected
-function tag.object.view_only(self)
- local tags = self.screen.tags
- -- First, untag everyone except the viewed tag.
- for _, _tag in pairs(tags) do
- if _tag ~= self then
- _tag.selected = false
- end
- end
- -- Then, set this one to selected.
- -- We need to do that in 2 operations so we avoid flickering and several tag
- -- selected at the same time.
- self.selected = true
- capi.screen[self.screen]:emit_signal("tag::history::update")
-end
-
---- View only a tag.
--- @deprecated awful.tag.viewonly
--- @see tag.view_only
--- @param t The tag object.
-function tag.viewonly(t)
- util.deprecate("Use t:view_only() instead of awful.tag.viewonly")
-
- tag.object.view_only(t)
-end
-
---- View only a set of tags.
--- @function awful.tag.viewmore
--- @param tags A table with tags to view only.
--- @param[opt] screen The screen of the tags.
-function tag.viewmore(tags, screen)
- screen = get_screen(screen or ascreen.focused())
- local screen_tags = screen.tags
- for _, _tag in ipairs(screen_tags) do
- if not util.table.hasitem(tags, _tag) then
- _tag.selected = false
- end
- end
- for _, _tag in ipairs(tags) do
- _tag.selected = true
- end
- screen:emit_signal("tag::history::update")
-end
-
---- Toggle selection of a tag
--- @function awful.tag.viewtoggle
--- @see selected
--- @tparam tag t Tag to be toggled
-function tag.viewtoggle(t)
- t.selected = not t.selected
- capi.screen[tag.getproperty(t, "screen")]:emit_signal("tag::history::update")
-end
-
---- Get tag data table.
---
--- Do not use.
---
--- @deprecated awful.tag.getdata
--- @tparam tag _tag The tag.
--- @return The data table.
-function tag.getdata(_tag)
- return _tag.data.awful_tag_properties
-end
-
---- Get a tag property.
---
--- Use `_tag.prop` directly.
---
--- @deprecated awful.tag.getproperty
--- @tparam tag _tag The tag.
--- @tparam string prop The property name.
--- @return The property.
-function tag.getproperty(_tag, prop)
- if not _tag then return end -- FIXME: Turn this into an error?
- if _tag.data.awful_tag_properties then
- return _tag.data.awful_tag_properties[prop]
- end
-end
-
---- Set a tag property.
--- This properties are internal to awful. Some are used to draw taglist, or to
--- handle layout, etc.
---
--- Use `_tag.prop = value`
---
--- @deprecated awful.tag.setproperty
--- @param _tag The tag.
--- @param prop The property name.
--- @param value The value.
-function tag.setproperty(_tag, prop, value)
- if not _tag.data.awful_tag_properties then
- _tag.data.awful_tag_properties = {}
- end
-
- if _tag.data.awful_tag_properties[prop] ~= value then
- _tag.data.awful_tag_properties[prop] = value
- _tag:emit_signal("property::" .. prop)
- end
-end
-
---- Tag a client with the set of current tags.
--- @deprecated awful.tag.withcurrent
--- @param c The client to tag.
-function tag.withcurrent(c)
- util.deprecate("Use c:to_selected_tags() instead of awful.tag.selectedlist")
-
- -- It can't use c:to_selected_tags() because awful.tag is loaded before
- -- awful.client
-
- local tags = {}
- for _, t in ipairs(c:tags()) do
- if get_screen(tag.getproperty(t, "screen")) == get_screen(c.screen) then
- table.insert(tags, t)
- end
- end
- if #tags == 0 then
- tags = c.screen.selected_tags
- end
- if #tags == 0 then
- tags = c.screen.tags
- end
- if #tags ~= 0 then
- c:tags(tags)
- end
-end
-
-local function attached_connect_signal_screen(screen, sig, func)
- screen = get_screen(screen)
- capi.tag.connect_signal(sig, function(_tag)
- if get_screen(tag.getproperty(_tag, "screen")) == screen then
- func(_tag)
- end
- end)
-end
-
---- Add a signal to all attached tags and all tags that will be attached in the
--- future. When a tag is detached from the screen, its signal is removed.
---
--- @function awful.tag.attached_connect_signal
--- @screen The screen concerned, or all if nil.
--- @tparam[opt] string Signal
--- @tparam[opt] function Callback
-function tag.attached_connect_signal(screen, ...)
- if screen then
- attached_connect_signal_screen(screen, ...)
- else
- capi.tag.connect_signal(...)
- end
-end
-
--- Register standard signals.
-capi.client.connect_signal("property::screen", function(c)
- -- First, the delayed timer is necessary to avoid a race condition with
- -- awful.rules. It is also messing up the tags before the user have a chance
- -- to set them manually.
- timer.delayed_call(function()
- local tags, new_tags = c:tags(), {}
-
- for _, t in ipairs(tags) do
- if t.screen == c.screen then
- table.insert(new_tags, t)
- end
- end
-
- if #new_tags == 0 then
- c:emit_signal("request::tag", nil, {reason="screen"})
- elseif #new_tags < #tags then
- c:tags(new_tags)
- end
- end)
-end)
-
--- Keep track of the number of urgent clients.
-local function update_urgent(t, modif)
- local count = tag.getproperty(t, "urgent_count") or 0
- count = (count + modif) >= 0 and (count + modif) or 0
- tag.setproperty(t, "urgent" , count > 0)
- tag.setproperty(t, "urgent_count", count )
-end
-
--- Update the urgent counter when a client is tagged.
-local function client_tagged(c, t)
- if c.urgent then
- update_urgent(t, 1)
- end
-end
-
--- Update the urgent counter when a client is untagged.
-local function client_untagged(c, t)
- if c.urgent then
- update_urgent(t, -1)
- end
-
- if #t:clients() == 0 and tag.getproperty(t, "volatile") then
- tag.object.delete(t)
- end
-end
-
--- Count the urgent clients.
-local function urgent_callback(c)
- for _,t in ipairs(c:tags()) do
- update_urgent(t, c.urgent and 1 or -1)
- end
-end
-
-capi.client.connect_signal("property::urgent", urgent_callback)
-capi.client.connect_signal("untagged", client_untagged)
-capi.client.connect_signal("tagged", client_tagged)
-capi.tag.connect_signal("request::select", tag.object.view_only)
-
---- True when a tagged client is urgent
--- @signal property::urgent
--- @see client.urgent
-
---- The number of urgent tagged clients
--- @signal property::urgent_count
--- @see client.urgent
-
-capi.screen.connect_signal("tag::history::update", tag.history.update)
-
-capi.screen.connect_signal("removed", function(s)
- -- First give other code a chance to move the tag to another screen
- for _, t in pairs(s.tags) do
- t:emit_signal("request::screen")
- end
- -- Everything that's left: Tell everyone that these tags go away (other code
- -- could e.g. save clients)
- for _, t in pairs(s.tags) do
- t:emit_signal("removal-pending")
- end
- -- Give other code yet another change to save clients
- for _, c in pairs(capi.client.get(s)) do
- c:emit_signal("request::tag", nil, { reason = "screen-removed" })
- end
- -- Then force all clients left to go somewhere random
- local fallback = nil
- for other_screen in capi.screen do
- if #other_screen.tags > 0 then
- fallback = other_screen.tags[1]
- break
- end
- end
- for _, t in pairs(s.tags) do
- t:delete(fallback, true)
- end
- -- If any tag survived until now, forcefully get rid of it
- for _, t in pairs(s.tags) do
- t.activated = false
-
- if t.data.awful_tag_properties then
- t.data.awful_tag_properties.screen = nil
- end
- end
-end)
-
-function tag.mt:__call(...)
- return tag.new(...)
-end
-
--- Extend the luaobject
--- `awful.tag.setproperty` currently handle calling the setter method itself
--- while `awful.tag.getproperty`.
-object.properties(capi.tag, {
- getter_class = tag.object,
- setter_class = tag.object,
- getter_fallback = tag.getproperty,
- setter_fallback = tag.setproperty,
-})
-
-return setmetatable(tag, tag.mt)
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/titlebar.lua b/awesome/lib/awful/titlebar.lua
deleted file mode 100644
index c055349..0000000
--- a/awesome/lib/awful/titlebar.lua
+++ /dev/null
@@ -1,509 +0,0 @@
----------------------------------------------------------------------------
---- Titlebars for awful.
---
--- @author Uli Schlachter
--- @copyright 2012 Uli Schlachter
--- @module awful.titlebar
----------------------------------------------------------------------------
-
-local error = error
-local type = type
-local util = require("awful.util")
-local abutton = require("awful.button")
-local aclient = require("awful.client")
-local atooltip = require("awful.tooltip")
-local beautiful = require("beautiful")
-local drawable = require("wibox.drawable")
-local imagebox = require("wibox.widget.imagebox")
-local textbox = require("wibox.widget.textbox")
-local base = require("wibox.widget.base")
-local capi = {
- client = client
-}
-local titlebar = {
- widget = {}
-}
-
---- The titlebar foreground (text) color.
--- @beautiful beautiful.titlebar_fg_normal
--- @param color
--- @see gears.color
-
---- The titlebar background color.
--- @beautiful beautiful.titlebar_bg_normal
--- @param color
--- @see gears.color
-
---- The titlebar background image image.
--- @beautiful beautiful.titlebar_bgimage_normal
--- @param surface
--- @see gears.surface
-
---- The titlebar foreground (text) color.
--- @beautiful beautiful.titlebar_fg
--- @param color
--- @see gears.color
-
---- The titlebar background color.
--- @beautiful beautiful.titlebar_bg
--- @param color
--- @see gears.color
-
---- The titlebar background image image.
--- @beautiful beautiful.titlebar_bgimage
--- @param surface
--- @see gears.surface
-
---- The focused titlebar foreground (text) color.
--- @beautiful beautiful.titlebar_fg_focus
--- @param color
--- @see gears.color
-
---- The focused titlebar background color.
--- @beautiful beautiful.titlebar_bg_focus
--- @param color
--- @see gears.color
-
---- The focused titlebar background image image.
--- @beautiful beautiful.titlebar_bgimage_focus
--- @param surface
--- @see gears.surface
-
---- floating_button_normal.
--- @beautiful beautiful.titlebar_floating_button_normal
--- @param surface
--- @see gears.surface
-
---- maximized_button_normal.
--- @beautiful beautiful.titlebar_maximized_button_normal
--- @param surface
--- @see gears.surface
-
---- minimize_button_normal
--- @beautiful beautiful.titlebar_minimize_button_normal
--- @param surface
--- @see gears.surface
-
---- close_button_normal.
--- @beautiful beautiful.titlebar_close_button_normal
--- @param surface
--- @see gears.surface
-
---- ontop_button_normal.
--- @beautiful beautiful.titlebar_ontop_button_normal
--- @param surface
--- @see gears.surface
-
---- sticky_button_normal.
--- @beautiful beautiful.titlebar_sticky_button_normal
--- @param surface
--- @see gears.surface
-
---- floating_button_focus.
--- @beautiful beautiful.titlebar_floating_button_focus
--- @param surface
--- @see gears.surface
-
---- maximized_button_focus.
--- @beautiful beautiful.titlebar_maximized_button_focus
--- @param surface
--- @see gears.surface
-
---- minimize_button_focus.
--- @beautiful beautiful.titlebar_minimize_button_focus
--- @param surface
--- @see gears.surface
-
---- close_button_focus.
--- @beautiful beautiful.titlebar_close_button_focus
--- @param surface
--- @see gears.surface
-
---- ontop_button_focus.
--- @beautiful beautiful.titlebar_ontop_button_focus
--- @param surface
--- @see gears.surface
-
---- sticky_button_focus.
--- @beautiful beautiful.titlebar_sticky_button_focus
--- @param surface
--- @see gears.surface
-
---- floating_button_normal_active.
--- @beautiful beautiful.titlebar_floating_button_normal_active
--- @param surface
--- @see gears.surface
-
---- maximized_button_normal_active.
--- @beautiful beautiful.titlebar_maximized_button_normal_active
--- @param surface
--- @see gears.surface
-
---- ontop_button_normal_active.
--- @beautiful beautiful.titlebar_ontop_button_normal_active
--- @param surface
--- @see gears.surface
-
---- sticky_button_normal_active.
--- @beautiful beautiful.titlebar_sticky_button_normal_active
--- @param surface
--- @see gears.surface
-
---- floating_button_focus_active.
--- @beautiful beautiful.titlebar_floating_button_focus_active
--- @param surface
--- @see gears.surface
-
---- maximized_button_focus_active.
--- @beautiful beautiful.titlebar_maximized_button_focus_active
--- @param surface
--- @see gears.surface
-
---- ontop_button_focus_active.
--- @beautiful beautiful.titlebar_ontop_button_focus_active
--- @param surface
--- @see gears.surface
-
---- sticky_button_focus_active.
--- @beautiful beautiful.titlebar_sticky_button_focus_active
--- @param surface
--- @see gears.surface
-
---- floating_button_normal_inactive.
--- @beautiful beautiful.titlebar_floating_button_normal_inactive
--- @param surface
--- @see gears.surface
-
---- maximized_button_normal_inactive.
--- @beautiful beautiful.titlebar_maximized_button_normal_inactive
--- @param surface
--- @see gears.surface
-
---- ontop_button_normal_inactive.
--- @beautiful beautiful.titlebar_ontop_button_normal_inactive
--- @param surface
--- @see gears.surface
-
---- sticky_button_normal_inactive.
--- @beautiful beautiful.titlebar_sticky_button_normal_inactive
--- @param surface
--- @see gears.surface
-
---- floating_button_focus_inactive.
--- @beautiful beautiful.titlebar_floating_button_focus_inactive
--- @param surface
--- @see gears.surface
-
---- maximized_button_focus_inactive.
--- @beautiful beautiful.titlebar_maximized_button_focus_inactive
--- @param surface
--- @see gears.surface
-
---- ontop_button_focus_inactive.
--- @beautiful beautiful.titlebar_ontop_button_focus_inactive
--- @param surface
--- @see gears.surface
-
---- sticky_button_focus_inactive.
--- @beautiful beautiful.titlebar_sticky_button_focus_inactive
--- @param surface
--- @see gears.surface
-
---- Set a declarative widget hierarchy description.
--- See [The declarative layout system](../documentation/03-declarative-layout.md.html)
--- @param args An array containing the widgets disposition
--- @name setup
--- @class function
-
---- Show tooltips when hover on titlebar buttons (defaults to 'true')
-titlebar.enable_tooltip = true
-
-local all_titlebars = setmetatable({}, { __mode = 'k' })
-
--- Get a color for a titlebar, this tests many values from the array and the theme
-local function get_color(name, c, args)
- local suffix = "_normal"
- if capi.client.focus == c then
- suffix = "_focus"
- end
- local function get(array)
- return array["titlebar_"..name..suffix] or array["titlebar_"..name] or array[name..suffix] or array[name]
- end
- return get(args) or get(beautiful)
-end
-
-local function get_titlebar_function(c, position)
- if position == "left" then
- return c.titlebar_left
- elseif position == "right" then
- return c.titlebar_right
- elseif position == "top" then
- return c.titlebar_top
- elseif position == "bottom" then
- return c.titlebar_bottom
- else
- error("Invalid titlebar position '" .. position .. "'")
- end
-end
-
---- Get a client's titlebar
--- @class function
--- @tparam client c The client for which a titlebar is wanted.
--- @tparam[opt={}] table args A table with extra arguments for the titlebar.
--- @tparam[opt=font.height*1.5] number args.size The height of the titlebar.
--- @tparam[opt=top] string args.position" values are `top`,
--- `left`, `right` and `bottom`.
--- @tparam[opt=top] string args.bg_normal
--- @tparam[opt=top] string args.bg_focus
--- @tparam[opt=top] string args.bgimage_normal
--- @tparam[opt=top] string args.bgimage_focus
--- @tparam[opt=top] string args.fg_normal
--- @tparam[opt=top] string args.fg_focus
--- @tparam[opt=top] string args.font
--- @name titlebar
-local function new(c, args)
- args = args or {}
- local position = args.position or "top"
- local size = args.size or util.round(beautiful.get_font_height(args.font) * 1.5)
- local d = get_titlebar_function(c, position)(c, size)
-
- -- Make sure that there is never more than one titlebar for any given client
- local bars = all_titlebars[c]
- if not bars then
- bars = {}
- all_titlebars[c] = bars
- end
-
- local ret
- if not bars[position] then
- local context = {
- client = c,
- position = position
- }
- ret = drawable(d, context, "awful.titlebar")
- ret:_inform_visible(true)
- local function update_colors()
- local args_ = bars[position].args
- ret:set_bg(get_color("bg", c, args_))
- ret:set_fg(get_color("fg", c, args_))
- ret:set_bgimage(get_color("bgimage", c, args_))
- end
-
- bars[position] = {
- args = args,
- drawable = ret,
- update_colors = update_colors
- }
-
- -- Update the colors when focus changes
- c:connect_signal("focus", update_colors)
- c:connect_signal("unfocus", update_colors)
-
- -- Inform the drawable when it becomes invisible
- c:connect_signal("unmanage", function() ret:_inform_visible(false) end)
- else
- bars[position].args = args
- ret = bars[position].drawable
- end
-
- -- Make sure the titlebar has the right colors applied
- bars[position].update_colors()
-
- -- Handle declarative/recursive widget container
- ret.setup = base.widget.setup
-
- return ret
-end
-
---- Show a client's titlebar.
--- @param c The client whose titlebar is modified
--- @param[opt] position The position of the titlebar. Must be one of "left",
--- "right", "top", "bottom". Default is "top".
-function titlebar.show(c, position)
- position = position or "top"
- local bars = all_titlebars[c]
- local data = bars and bars[position]
- local args = data and data.args
- new(c, args)
-end
-
---- Hide a client's titlebar.
--- @param c The client whose titlebar is modified
--- @param[opt] position The position of the titlebar. Must be one of "left",
--- "right", "top", "bottom". Default is "top".
-function titlebar.hide(c, position)
- position = position or "top"
- get_titlebar_function(c, position)(c, 0)
-end
-
---- Toggle a client's titlebar, hiding it if it is visible, otherwise showing it.
--- @param c The client whose titlebar is modified
--- @param[opt] position The position of the titlebar. Must be one of "left",
--- "right", "top", "bottom". Default is "top".
-function titlebar.toggle(c, position)
- position = position or "top"
- local _, size = get_titlebar_function(c, position)(c)
- if size == 0 then
- titlebar.show(c, position)
- else
- titlebar.hide(c, position)
- end
-end
-
---- Create a new titlewidget. A title widget displays the name of a client.
--- Please note that this returns a textbox and all of textbox' API is available.
--- This way, you can e.g. modify the font that is used.
--- @param c The client for which a titlewidget should be created.
--- @return The title widget.
-function titlebar.widget.titlewidget(c)
- local ret = textbox()
- local function update()
- ret:set_text(c.name or "<unknown>")
- end
- c:connect_signal("property::name", update)
- update()
-
- return ret
-end
-
---- Create a new icon widget. An icon widget displays the icon of a client.
--- Please note that this returns an imagebox and all of the imagebox' API is
--- available. This way, you can e.g. disallow resizes.
--- @param c The client for which an icon widget should be created.
--- @return The icon widget.
-function titlebar.widget.iconwidget(c)
- local ret = imagebox()
- local function update()
- ret:set_image(c.icon)
- end
- c:connect_signal("property::icon", update)
- update()
-
- return ret
-end
-
---- Create a new button widget. A button widget displays an image and reacts to
--- mouse clicks. Please note that the caller has to make sure that this widget
--- gets redrawn when needed by calling the returned widget's update() function.
--- The selector function should return a value describing a state. If the value
--- is a boolean, either "active" or "inactive" are used. The actual image is
--- then found in the theme as "titlebar_[name]_button_[normal/focus]_[state]".
--- If that value does not exist, the focused state is ignored for the next try.
--- @param c The client for which a button is created.
--- @tparam string name Name of the button, used for accessing the theme and
--- in the tooltip.
--- @param selector A function that selects the image that should be displayed.
--- @param action Function that is called when the button is clicked.
--- @return The widget
-function titlebar.widget.button(c, name, selector, action)
- local ret = imagebox()
-
- if titlebar.enable_tooltip then
- ret._private.tooltip = atooltip({ objects = {ret}, delay_show = 1 })
- ret._private.tooltip:set_text(name)
- end
-
- local function update()
- local img = selector(c)
- if type(img) ~= "nil" then
- -- Convert booleans automatically
- if type(img) == "boolean" then
- if img then
- img = "active"
- else
- img = "inactive"
- end
- end
- local prefix = "normal"
- if capi.client.focus == c then
- prefix = "focus"
- end
- if img ~= "" then
- prefix = prefix .. "_"
- end
- -- First try with a prefix based on the client's focus state,
- -- then try again without that prefix if nothing was found,
- -- and finally, try a fallback for compatibility with Awesome 3.5 themes
- local theme = beautiful["titlebar_" .. name .. "_button_" .. prefix .. img]
- or beautiful["titlebar_" .. name .. "_button_" .. img]
- or beautiful["titlebar_" .. name .. "_button_" .. prefix .. "_inactive"]
- if theme then
- img = theme
- end
- end
- ret:set_image(img)
- end
- if action then
- ret:buttons(abutton({ }, 1, nil, function() action(c, selector(c)) end))
- end
-
- ret.update = update
- update()
-
- -- We do magic based on whether a client is focused above, so we need to
- -- connect to the corresponding signal here.
- c:connect_signal("focus", update)
- c:connect_signal("unfocus", update)
-
- return ret
-end
-
---- Create a new float button for a client.
--- @param c The client for which the button is wanted.
-function titlebar.widget.floatingbutton(c)
- local widget = titlebar.widget.button(c, "floating", aclient.object.get_floating, aclient.floating.toggle)
- c:connect_signal("property::floating", widget.update)
- return widget
-end
-
---- Create a new maximize button for a client.
--- @param c The client for which the button is wanted.
-function titlebar.widget.maximizedbutton(c)
- local widget = titlebar.widget.button(c, "maximized", function(cl)
- return cl.maximized_horizontal or cl.maximized_vertical
- end, function(cl, state)
- cl.maximized_horizontal = not state
- cl.maximized_vertical = not state
- end)
- c:connect_signal("property::maximized_vertical", widget.update)
- c:connect_signal("property::maximized_horizontal", widget.update)
- return widget
-end
-
---- Create a new minimize button for a client.
--- @param c The client for which the button is wanted.
-function titlebar.widget.minimizebutton(c)
- local widget = titlebar.widget.button(c, "minimize", function() return "" end, function(cl) cl.minimized = not cl.minimized end)
- c:connect_signal("property::minimized", widget.update)
- return widget
-end
-
---- Create a new closing button for a client.
--- @param c The client for which the button is wanted.
-function titlebar.widget.closebutton(c)
- return titlebar.widget.button(c, "close", function() return "" end, function(cl) cl:kill() end)
-end
-
---- Create a new ontop button for a client.
--- @param c The client for which the button is wanted.
-function titlebar.widget.ontopbutton(c)
- local widget = titlebar.widget.button(c, "ontop", function(cl) return cl.ontop end, function(cl, state) cl.ontop = not state end)
- c:connect_signal("property::ontop", widget.update)
- return widget
-end
-
---- Create a new sticky button for a client.
--- @param c The client for which the button is wanted.
-function titlebar.widget.stickybutton(c)
- local widget = titlebar.widget.button(c, "sticky", function(cl) return cl.sticky end, function(cl, state) cl.sticky = not state end)
- c:connect_signal("property::sticky", widget.update)
- return widget
-end
-
-client.connect_signal("unmanage", function(c)
- all_titlebars[c] = nil
-end)
-
-return setmetatable(titlebar, { __call = function(_, ...) return new(...) end})
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/tooltip.lua b/awesome/lib/awful/tooltip.lua
deleted file mode 100644
index cd151c4..0000000
--- a/awesome/lib/awful/tooltip.lua
+++ /dev/null
@@ -1,616 +0,0 @@
--------------------------------------------------------------------------
---- Tooltip module for awesome objects.
---
--- A tooltip is a small hint displayed when the mouse cursor
--- hovers a specific item.
--- In awesome, a tooltip can be linked with almost any
--- object having a `:connect_signal()` method and receiving
--- `mouse::enter` and `mouse::leave` signals.
---
--- How to create a tooltip?
--- ---
---
--- myclock = wibox.widget.textclock({}, "%T", 1)
--- myclock_t = awful.tooltip({
--- objects = { myclock },
--- timer_function = function()
--- return os.date("Today is %A %B %d %Y\nThe time is %T")
--- end,
--- })
---
--- How to add the same tooltip to multiple objects?
--- ---
---
--- myclock_t:add_to_object(obj1)
--- myclock_t:add_to_object(obj2)
---
--- Now the same tooltip is attached to `myclock`, `obj1`, `obj2`.
---
--- How to remove a tooltip from several objects?
--- ---
---
--- myclock_t:remove_from_object(obj1)
--- myclock_t:remove_from_object(obj2)
---
--- Now the same tooltip is only attached to `myclock`.
---
--- @author Sébastien Gross &lt;seb•ɱɩɲʋʃ•awesome•ɑƬ•chezwam•ɖɵʈ•org&gt;
--- @copyright 2009 Sébastien Gross
--- @classmod awful.tooltip
--------------------------------------------------------------------------
-
-local mouse = mouse
-local timer = require("gears.timer")
-local util = require("awful.util")
-local object = require("gears.object")
-local color = require("gears.color")
-local wibox = require("wibox")
-local a_placement = require("awful.placement")
-local abutton = require("awful.button")
-local shape = require("gears.shape")
-local beautiful = require("beautiful")
-local textbox = require("wibox.widget.textbox")
-local dpi = require("beautiful").xresources.apply_dpi
-local cairo = require("lgi").cairo
-local setmetatable = setmetatable
-local unpack = unpack or table.unpack -- luacheck: globals unpack (compatibility with Lua 5.1)
-local ipairs = ipairs
-local capi = {mouse=mouse, awesome=awesome}
-
-local tooltip = { mt = {} }
-
--- The mouse point is 1x1, so anything aligned based on it as parent
--- geometry will go out of bound. To get the desired placement, it is
--- necessary to swap left with right and top with bottom
-local align_convert = {
- top_left = "bottom_right",
- left = "right",
- bottom_left = "top_right",
- right = "left",
- top_right = "bottom_left",
- bottom_right = "top_left",
- top = "bottom",
- bottom = "top",
-}
-
--- If the wibox is under the cursor, it will trigger a mouse::leave
-local offset = {
- top_left = {x = 0, y = 0 },
- left = {x = 0, y = 0 },
- bottom_left = {x = 0, y = 0 },
- right = {x = 1, y = 0 },
- top_right = {x = 0, y = 0 },
- bottom_right = {x = 1, y = 1 },
- top = {x = 0, y = 0 },
- bottom = {x = 0, y = 1 },
-}
-
---- The tooltip border color.
--- @beautiful beautiful.tooltip_border_color
-
---- The tooltip background color.
--- @beautiful beautiful.tooltip_bg
-
---- The tooltip foregound (text) color.
--- @beautiful beautiful.tooltip_fg
-
---- The tooltip font.
--- @beautiful beautiful.tooltip_font
-
---- The tooltip border width.
--- @beautiful beautiful.tooltip_border_width
-
---- The tooltip opacity.
--- @beautiful beautiful.tooltip_opacity
-
---- The default tooltip shape.
--- By default, all tooltips are rectangles, however, by setting this variables,
--- they can default to rounded rectangle or stretched octogons.
--- @beautiful beautiful.tooltip_shape
--- @tparam[opt=gears.shape.rectangle] function shape A `gears.shape` compatible function
--- @see shape
--- @see gears.shape
-
-local function apply_shape(self)
- local s = self._private.shape
-
- local wb = self.wibox
-
- if not s then
- -- Clear the shape
- if wb.shape_bounding then
- wb.shape_bounding = nil
- wb:set_bgimage(nil)
- end
-
- return
- end
-
- local w, h = wb.width, wb.height
-
- -- First, create a A1 mask for the shape bounding itself
- local img = cairo.ImageSurface(cairo.Format.A1, w, h)
- local cr = cairo.Context(img)
-
- cr:set_source_rgba(1,1,1,1)
-
- s(cr, w, h, unpack(self._private.shape_args or {}))
- cr:fill()
- wb.shape_bounding = img._native
-
- -- The wibox background uses ARGB32 border so tooltip anti-aliasing works
- -- when an external compositor is used. This will look better than
- -- the capi.drawin's own border support.
- img = cairo.ImageSurface(cairo.Format.ARGB32, w, h)
- cr = cairo.Context(img)
-
- -- Draw the border (multiply by 2, then mask the inner part to save a path)
- local bw = (self._private.border_width
- or beautiful.tooltip_border_width
- or beautiful.border_width or 0) * 2
-
- -- Fix anti-aliasing
- if bw > 2 and awesome.composite_manager_running then
- bw = bw - 1
- end
-
- local bc = self._private.border_color
- or beautiful.tooltip_border_color
- or beautiful.border_normal
- or "#ffcb60"
-
- cr:translate(bw, bw)
- s(cr, w-2*bw, h-2*bw, unpack(self._private.shape_args or {}))
- cr:set_line_width(bw)
- cr:set_source(color(bc))
- cr:stroke_preserve()
- cr:clip()
-
- local bg = self._private.bg
- or beautiful.tooltip_bg
- or beautiful.bg_focus or "#ffcb60"
-
- cr:set_source(color(bg))
- cr:paint()
-
- wb:set_bgimage(img)
-end
-
-local function apply_mouse_mode(self)
- local w = self:get_wibox()
- local align = self._private.align
- local real_placement = align_convert[align]
-
- a_placement[real_placement](w, {
- parent = capi.mouse,
- offset = offset[align]
- })
-end
-
-local function apply_outside_mode(self)
- local w = self:get_wibox()
-
- local _, position = a_placement.next_to(w, {
- geometry = self._private.widget_geometry,
- preferred_positions = self.preferred_positions,
- honor_workarea = true,
- })
-
- if position ~= self.current_position then
- -- Re-apply the shape.
- apply_shape(self)
- end
-
- self.current_position = position
-end
-
--- Place the tooltip under the mouse.
---
--- @tparam tooltip self A tooltip object.
-local function set_geometry(self)
- -- calculate width / height
- local n_w, n_h = self.textbox:get_preferred_size(mouse.screen)
- n_w = n_w + self.marginbox.left + self.marginbox.right
- n_h = n_h + self.marginbox.top + self.marginbox.bottom
-
- local w = self:get_wibox()
- w:geometry({ width = n_w, height = n_h })
-
- if self._private.shape then
- apply_shape(self)
- end
-
- local mode = self.mode
-
- if mode == "outside" and self._private.widget_geometry then
- apply_outside_mode(self)
- else
- apply_mouse_mode(self)
- end
-
- a_placement.no_offscreen(w)
-end
-
--- Show a tooltip.
---
--- @tparam tooltip self The tooltip to show.
-local function show(self)
- -- do nothing if the tooltip is already shown
- if self._private.visible then return end
- if self.timer then
- if not self.timer.started then
- self:timer_function()
- self.timer:start()
- end
- end
- set_geometry(self)
- self.wibox.visible = true
- self._private.visible = true
- self:emit_signal("property::visible")
-end
-
--- Hide a tooltip.
---
--- @tparam tooltip self The tooltip to hide.
-local function hide(self)
- -- do nothing if the tooltip is already hidden
- if not self._private.visible then return end
- if self.timer then
- if self.timer.started then
- self.timer:stop()
- end
- end
- self.wibox.visible = false
- self._private.visible = false
- self:emit_signal("property::visible")
-end
-
---- The wibox.
--- @property wibox
--- @param `wibox`
-
-function tooltip:get_wibox()
- if self._private.wibox then
- return self._private.wibox
- end
-
- local wb = wibox(self.wibox_properties)
- wb:set_widget(self.marginbox)
-
- -- Close the tooltip when clicking it. This gets done on release, to not
- -- emit the release event on an underlying object, e.g. the titlebar icon.
- wb:buttons(abutton({}, 1, nil, self.hide))
-
- self._private.wibox = wb
-
- return wb
-end
-
---- Is the tooltip visible?
--- @property visible
--- @param boolean
-
-function tooltip:get_visible()
- return self._private.visible
-end
-
-function tooltip:set_visible(value)
- if self._private.visible == value then return end
-
- if value then
- show(self)
- else
- hide(self)
- end
-end
-
---- The horizontal alignment.
---
--- The following values are valid:
---
--- * top_left
--- * left
--- * bottom_left
--- * right
--- * top_right
--- * bottom_right
--- * bottom
--- * top
---
--- @property align
--- @see beautiful.tooltip_align
-
---- The default tooltip alignment.
--- @beautiful beautiful.tooltip_align
--- @param string
--- @see align
-
-function tooltip:get_align()
- return self._private.align
-end
-
-function tooltip:set_align(value)
- if not align_convert[value] then
- return
- end
-
- self._private.align = value
-
- set_geometry(self)
- self:emit_signal("property::align")
-end
-
---- The shape of the tooltip window.
--- If the shape require some parameters, use `set_shape`.
--- @property shape
--- @see gears.shape
--- @see set_shape
--- @see beautiful.tooltip_shape
-
---- Set the tooltip shape.
--- All other arguments will be passed to the shape function.
--- @tparam gears.shape s The shape
--- @see shape
--- @see gears.shape
-function tooltip:set_shape(s, ...)
- self._private.shape = s
- self._private.shape_args = {...}
- apply_shape(self)
-end
-
---- Set the tooltip positioning mode.
--- This affects how the tooltip is placed. By default, the tooltip is `align`ed
--- close to the mouse cursor. It is also possible to place the tooltip relative
--- to the widget geometry.
---
--- Valid modes are:
---
--- * "mouse": Next to the mouse cursor
--- * "outside": Outside of the widget
---
--- @property mode
--- @param string
-
-function tooltip:set_mode(mode)
- self._private.mode = mode
-
- set_geometry(self)
- self:emit_signal("property::mode")
-end
-
-function tooltip:get_mode()
- return self._private.mode or "mouse"
-end
-
---- The preferred positions when in `outside` mode.
---
--- If the tooltip fits on multiple sides of the drawable, then this defines the
--- priority
---
--- The default is:
---
--- {"top", "right", "left", "bottom"}
---
--- @property preferred_positions
--- @tparam table preferred_positions The position, ordered by priorities
-
-function tooltip:get_preferred_positions()
- return self._private.preferred_positions or
- {"top", "right", "left", "bottom"}
-end
-
-function tooltip:set_preferred_positions(value)
- self._private.preferred_positions = value
-
- set_geometry(self)
-end
-
---- Change displayed text.
---
--- @property text
--- @tparam tooltip self The tooltip object.
--- @tparam string text New tooltip text, passed to
--- `wibox.widget.textbox.set_text`.
-
-function tooltip:set_text(text)
- self.textbox:set_text(text)
- if self._private.visible then
- set_geometry(self)
- end
-end
-
---- Change displayed markup.
---
--- @property markup
--- @tparam tooltip self The tooltip object.
--- @tparam string text New tooltip markup, passed to
--- `wibox.widget.textbox.set_markup`.
-
-function tooltip:set_markup(text)
- self.textbox:set_markup(text)
- if self._private.visible then
- set_geometry(self)
- end
-end
-
---- Change the tooltip's update interval.
---
--- @property timeout
--- @tparam tooltip self A tooltip object.
--- @tparam number timeout The timeout value.
-
-function tooltip:set_timeout(timeout)
- if self.timer then
- self.timer.timeout = timeout
- end
-end
-
---- Add tooltip to an object.
---
--- @tparam tooltip self The tooltip.
--- @tparam gears.object obj An object with `mouse::enter` and
--- `mouse::leave` signals.
--- @function add_to_object
-function tooltip:add_to_object(obj)
- if not obj then return end
-
- obj:connect_signal("mouse::enter", self.show)
- obj:connect_signal("mouse::leave", self.hide)
-end
-
---- Remove tooltip from an object.
---
--- @tparam tooltip self The tooltip.
--- @tparam gears.object obj An object with `mouse::enter` and
--- `mouse::leave` signals.
--- @function remove_from_object
-function tooltip:remove_from_object(obj)
- obj:disconnect_signal("mouse::enter", self.show)
- obj:disconnect_signal("mouse::leave", self.hide)
-end
-
--- Tooltip can be applied to both widgets, wibox and client, their geometry
--- works differently.
-local function get_parent_geometry(arg1, arg2)
- if type(arg2) == "table" and arg2.width then
- return arg2
- elseif type(arg1) == "table" and arg1.width then
- return arg1
- end
-end
-
---- Create a new tooltip and link it to a widget.
--- Tooltips emit `property::visible` when their visibility changes.
--- @tparam table args Arguments for tooltip creation.
--- @tparam function args.timer_function A function to dynamically set the
--- tooltip text. Its return value will be passed to
--- `wibox.widget.textbox.set_markup`.
--- @tparam[opt=1] number args.timeout The timeout value for
--- `timer_function`.
--- @tparam[opt] table args.objects A list of objects linked to the tooltip.
--- @tparam[opt] number args.delay_show Delay showing the tooltip by this many
--- seconds.
--- @tparam[opt=apply_dpi(5)] integer args.margin_leftright The left/right margin for the text.
--- @tparam[opt=apply_dpi(3)] integer args.margin_topbottom The top/bottom margin for the text.
--- @tparam[opt=nil] gears.shape args.shape The shape
--- @treturn awful.tooltip The created tooltip.
--- @see add_to_object
--- @see timeout
--- @see text
--- @see markup
--- @function awful.tooltip
-function tooltip.new(args)
- local self = object {
- enable_properties = true,
- }
-
- rawset(self,"_private", {})
-
- self._private.visible = false
- self._private.align = args.align or beautiful.tooltip_align or "right"
- self._private.shape = args.shape or beautiful.tooltip_shape
- or shape.rectangle
-
- -- private data
- if args.delay_show then
- local delay_timeout
-
- delay_timeout = timer { timeout = args.delay_show }
- delay_timeout:connect_signal("timeout", function ()
- show(self)
- delay_timeout:stop()
- end)
-
- function self.show(other, geo)
- -- Auto detect clients and wiboxes
- if other.drawable or other.pid then
- geo = other:geometry()
- end
-
- -- Cache the geometry in case it is needed later
- self._private.widget_geometry = get_parent_geometry(other, geo)
-
- if not delay_timeout.started then
- delay_timeout:start()
- end
- end
- function self.hide()
- if delay_timeout.started then
- delay_timeout:stop()
- end
- hide(self)
- end
- else
- function self.show(other, geo)
- -- Auto detect clients and wiboxes
- if other.drawable or other.pid then
- geo = other:geometry()
- end
-
- -- Cache the geometry in case it is needed later
- self._private.widget_geometry = get_parent_geometry(other, geo)
-
- show(self)
- end
- function self.hide()
- hide(self)
- end
- end
-
- -- export functions
- util.table.crush(self, tooltip, true)
-
- -- setup the timer action only if needed
- if args.timer_function then
- self.timer = timer { timeout = args.timeout and args.timeout or 1 }
- self.timer_function = function()
- self:set_markup(args.timer_function())
- end
- self.timer:connect_signal("timeout", self.timer_function)
- end
-
- local fg = beautiful.tooltip_fg or beautiful.fg_focus or "#000000"
- local font = beautiful.tooltip_font or beautiful.font
-
- -- Set default properties
- self.wibox_properties = {
- visible = false,
- ontop = true,
- border_width = 0,
- fg = fg,
- bg = color.transparent,
- opacity = beautiful.tooltip_opacity or 1,
- }
-
- self.textbox = textbox()
- self.textbox:set_font(font)
-
- -- Add margin.
- local m_lr = args.margin_leftright or dpi(5)
- local m_tb = args.margin_topbottom or dpi(3)
- self.marginbox = wibox.container.margin(self.textbox, m_lr, m_lr, m_tb, m_tb)
-
- -- Add tooltip to objects
- if args.objects then
- for _, obj in ipairs(args.objects) do
- self:add_to_object(obj)
- end
- end
-
- -- Apply the properties
- for k, v in pairs(args) do
- if tooltip["set_"..k] then
- self[k] = v
- end
- end
-
- return self
-end
-
-function tooltip.mt:__call(...)
- return tooltip.new(...)
-end
-
-return setmetatable(tooltip, tooltip.mt)
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/util.lua b/awesome/lib/awful/util.lua
deleted file mode 100644
index 8dcb955..0000000
--- a/awesome/lib/awful/util.lua
+++ /dev/null
@@ -1,588 +0,0 @@
----------------------------------------------------------------------------
---- Utility module for awful
---
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2008 Julien Danjou
--- @module awful.util
----------------------------------------------------------------------------
-
--- Grab environment we need
-local os = os
-local assert = assert
-local load = loadstring or load -- luacheck: globals loadstring (compatibility with Lua 5.1)
-local loadfile = loadfile
-local debug = debug
-local pairs = pairs
-local ipairs = ipairs
-local type = type
-local rtable = table
-local string = string
-local lgi = require("lgi")
-local grect = require("gears.geometry").rectangle
-local Gio = require("lgi").Gio
-local Pango = lgi.Pango
-local capi =
-{
- awesome = awesome,
- mouse = mouse
-}
-local gears_debug = require("gears.debug")
-local floor = math.floor
-
-local util = {}
-util.table = {}
-
---- The default shell used when spawing processes.
-util.shell = os.getenv("SHELL") or "/bin/sh"
-
-local displayed_deprecations = {}
---- Display a deprecation notice, but only once per traceback.
--- @param[opt] see The message to a new method / function to use.
--- @tparam table args Extra arguments
--- @tparam boolean args.raw Print the message as-is without the automatic context
-function util.deprecate(see, args)
- args = args or {}
- local tb = debug.traceback()
- if displayed_deprecations[tb] then
- return
- end
- displayed_deprecations[tb] = true
-
- -- Get function name/desc from caller.
- local info = debug.getinfo(2, "n")
- local funcname = info.name or "?"
- local msg = "awful: function " .. funcname .. " is deprecated"
- if see then
- if args.raw then
- msg = see
- elseif string.sub(see, 1, 3) == 'Use' then
- msg = msg .. ". " .. see
- else
- msg = msg .. ", see " .. see
- end
- end
- gears_debug.print_warning(msg .. ".\n" .. tb)
-end
-
---- Create a class proxy with deprecation messages.
--- This is useful when a class has moved somewhere else.
--- @tparam table fallback The new class
--- @tparam string old_name The old class name
--- @tparam string new_name The new class name
--- @treturn table A proxy class.
-function util.deprecate_class(fallback, old_name, new_name)
- local message = old_name.." has been renamed to "..new_name
-
- local function call(_,...)
- util.deprecate(message)
-
- return fallback(...)
- end
-
- local function index(_, k)
- util.deprecate(message)
-
- return fallback[k]
- end
-
- local function newindex(_, k, v)
- util.deprecate(message, {raw = true})
-
- fallback[k] = v
- end
-
- return setmetatable({}, {__call = call, __index = index, __newindex = newindex})
-end
-
---- Get a valid color for Pango markup
--- @param color The color.
--- @tparam string fallback The color to return if the first is invalid. (default: black)
--- @treturn string color if it is valid, else fallback.
-function util.ensure_pango_color(color, fallback)
- color = tostring(color)
- return Pango.Color.parse(Pango.Color(), color) and color or fallback or "black"
-end
-
---- Make i cycle.
--- @param t A length. Must be greater than zero.
--- @param i An absolute index to fit into #t.
--- @return An integer in (1, t) or nil if t is less than or equal to zero.
-function util.cycle(t, i)
- if t < 1 then return end
- i = i % t
- if i == 0 then
- i = t
- end
- return i
-end
-
---- Create a directory
--- @param dir The directory.
--- @return mkdir return code
-function util.mkdir(dir)
- return os.execute("mkdir -p " .. dir)
-end
-
---- Eval Lua code.
--- @return The return value of Lua code.
-function util.eval(s)
- return assert(load(s))()
-end
-
-local xml_entity_names = { ["'"] = "&apos;", ["\""] = "&quot;", ["<"] = "&lt;", [">"] = "&gt;", ["&"] = "&amp;" };
---- Escape a string from XML char.
--- Useful to set raw text in textbox.
--- @param text Text to escape.
--- @return Escape text.
-function util.escape(text)
- return text and text:gsub("['&<>\"]", xml_entity_names) or nil
-end
-
-local xml_entity_chars = { lt = "<", gt = ">", nbsp = " ", quot = "\"", apos = "'", ndash = "-", mdash = "-", amp = "&" };
---- Unescape a string from entities.
--- @param text Text to unescape.
--- @return Unescaped text.
-function util.unescape(text)
- return text and text:gsub("&(%a+);", xml_entity_chars) or nil
-end
-
---- Check if a file is a Lua valid file.
--- This is done by loading the content and compiling it with loadfile().
--- @param path The file path.
--- @return A function if everything is alright, a string with the error
--- otherwise.
-function util.checkfile(path)
- local f, e = loadfile(path)
- -- Return function if function, otherwise return error.
- if f then return f end
- return e
-end
-
---- Try to restart awesome.
--- It checks if the configuration file is valid, and then restart if it's ok.
--- If it's not ok, the error will be returned.
--- @return Never return if awesome restart, or return a string error.
-function util.restart()
- local c = util.checkfile(capi.awesome.conffile)
-
- if type(c) ~= "function" then
- return c
- end
-
- capi.awesome.restart()
-end
-
---- Get the config home according to the XDG basedir specification.
--- @return the config home (XDG_CONFIG_HOME) with a slash at the end.
-function util.get_xdg_config_home()
- return (os.getenv("XDG_CONFIG_HOME") or os.getenv("HOME") .. "/.config") .. "/"
-end
-
---- Get the cache home according to the XDG basedir specification.
--- @return the cache home (XDG_CACHE_HOME) with a slash at the end.
-function util.get_xdg_cache_home()
- return (os.getenv("XDG_CACHE_HOME") or os.getenv("HOME") .. "/.cache") .. "/"
-end
-
---- Get the path to the user's config dir.
--- This is the directory containing the configuration file ("rc.lua").
--- @return A string with the requested path with a slash at the end.
-function util.get_configuration_dir()
- return capi.awesome.conffile:match(".*/") or "./"
-end
-
---- Get the path to a directory that should be used for caching data.
--- @return A string with the requested path with a slash at the end.
-function util.get_cache_dir()
- return util.get_xdg_cache_home() .. "awesome/"
-end
-
---- Get the path to the directory where themes are installed.
--- @return A string with the requested path with a slash at the end.
-function util.get_themes_dir()
- return "/usr/share/awesome/themes" .. "/"
-end
-
---- Get the path to the directory where our icons are installed.
--- @return A string with the requested path with a slash at the end.
-function util.get_awesome_icon_dir()
- return "/usr/share/awesome/icons" .. "/"
-end
-
---- Get the user's config or cache dir.
--- It first checks XDG_CONFIG_HOME / XDG_CACHE_HOME, but then goes with the
--- default paths.
--- @param d The directory to get (either "config" or "cache").
--- @return A string containing the requested path.
-function util.getdir(d)
- if d == "config" then
- -- No idea why this is what is returned, I recommend everyone to use
- -- get_configuration_dir() instead
- return util.get_xdg_config_home() .. "awesome/"
- elseif d == "cache" then
- return util.get_cache_dir()
- end
-end
-
---- Search for an icon and return the full path.
--- It searches for the icon path under the given directories with respect to the
--- given extensions for the icon filename.
--- @param iconname The name of the icon to search for.
--- @param exts Table of image extensions allowed, otherwise { 'png', gif' }
--- @param dirs Table of dirs to search, otherwise { '/usr/share/pixmaps/' }
--- @tparam[opt] string size The size. If this is specified, subdirectories `x`
--- of the dirs are searched first.
-function util.geticonpath(iconname, exts, dirs, size)
- exts = exts or { 'png', 'gif' }
- dirs = dirs or { '/usr/share/pixmaps/', '/usr/share/icons/hicolor/' }
- local icontypes = { 'apps', 'actions', 'categories', 'emblems',
- 'mimetypes', 'status', 'devices', 'extras', 'places', 'stock' }
- for _, d in pairs(dirs) do
- local icon
- for _, e in pairs(exts) do
- icon = d .. iconname .. '.' .. e
- if util.file_readable(icon) then
- return icon
- end
- if size then
- for _, t in pairs(icontypes) do
- icon = string.format("%s%ux%u/%s/%s.%s", d, size, size, t, iconname, e)
- if util.file_readable(icon) then
- return icon
- end
- end
- end
- end
- end
-end
-
---- Check if a file exists, is not readable and not a directory.
--- @param filename The file path.
--- @return True if file exists and is readable.
-function util.file_readable(filename)
- local gfile = Gio.File.new_for_path(filename)
- local gfileinfo = gfile:query_info("standard::type,access::can-read",
- Gio.FileQueryInfoFlags.NONE)
- return gfileinfo and gfileinfo:get_file_type() ~= "DIRECTORY" and
- gfileinfo:get_attribute_boolean("access::can-read")
-end
-
---- Check if a path exists, is readable and is a directory.
--- @tparam string path The directory path.
--- @treturn boolean True if dir exists and is readable.
-function util.dir_readable(path)
- local gfile = Gio.File.new_for_path(path)
- local gfileinfo = gfile:query_info("standard::type,access::can-read",
- Gio.FileQueryInfoFlags.NONE)
- return gfileinfo and gfileinfo:get_file_type() == "DIRECTORY" and
- gfileinfo:get_attribute_boolean("access::can-read")
-end
-
---- Check if a path is a directory.
--- @tparam string path
--- @treturn bool True if path exists and is a directory.
-function util.is_dir(path)
- return Gio.File.new_for_path(path):query_file_type({}) == "DIRECTORY"
-end
-
-local function subset_mask_apply(mask, set)
- local ret = {}
- for i = 1, #set do
- if mask[i] then
- rtable.insert(ret, set[i])
- end
- end
- return ret
-end
-
-local function subset_next(mask)
- local i = 1
- while i <= #mask and mask[i] do
- mask[i] = false
- i = i + 1
- end
-
- if i <= #mask then
- mask[i] = 1
- return true
- end
- return false
-end
-
---- Return all subsets of a specific set.
--- This function, giving a set, will return all subset it.
--- For example, if we consider a set with value { 10, 15, 34 },
--- it will return a table containing 2^n set:
--- { }, { 10 }, { 15 }, { 34 }, { 10, 15 }, { 10, 34 }, etc.
--- @param set A set.
--- @return A table with all subset.
-function util.subsets(set)
- local mask = {}
- local ret = {}
- for i = 1, #set do mask[i] = false end
-
- -- Insert the empty one
- rtable.insert(ret, {})
-
- while subset_next(mask) do
- rtable.insert(ret, subset_mask_apply(mask, set))
- end
- return ret
-end
-
---- Get the nearest rectangle in the given direction. Every rectangle is specified as a table
--- with 'x', 'y', 'width', 'height' keys, the same as client or screen geometries.
--- @deprecated awful.util.get_rectangle_in_direction
--- @param dir The direction, can be either "up", "down", "left" or "right".
--- @param recttbl A table of rectangle specifications.
--- @param cur The current rectangle.
--- @return The index for the rectangle in recttbl closer to cur in the given direction. nil if none found.
--- @see gears.geometry
-function util.get_rectangle_in_direction(dir, recttbl, cur)
- util.deprecate("gears.geometry.rectangle.get_in_direction")
-
- return grect.get_in_direction(dir, recttbl, cur)
-end
-
---- Join all tables given as parameters.
--- This will iterate all tables and insert all their keys into a new table.
--- @param args A list of tables to join
--- @return A new table containing all keys from the arguments.
-function util.table.join(...)
- local ret = {}
- for _, t in pairs({...}) do
- if t then
- for k, v in pairs(t) do
- if type(k) == "number" then
- rtable.insert(ret, v)
- else
- ret[k] = v
- end
- end
- end
- end
- return ret
-end
-
---- Override elements in the first table by the one in the second.
---
--- Note that this method doesn't copy entries found in `__index`.
--- @tparam table t the table to be overriden
--- @tparam table set the table used to override members of `t`
--- @tparam[opt=false] boolean raw Use rawset (avoid the metatable)
--- @treturn table t (for convenience)
-function util.table.crush(t, set, raw)
- if raw then
- for k, v in pairs(set) do
- rawset(t, k, v)
- end
- else
- for k, v in pairs(set) do
- t[k] = v
- end
- end
-
- return t
-end
-
---- Pack all elements with an integer key into a new table
--- While both lua and luajit implement __len over sparse
--- table, the standard define it as an implementation
--- detail.
---
--- This function remove any non numeric keys from the value set
---
--- @tparam table t A potentially sparse table
--- @treturn table A packed table with all numeric keys
-function util.table.from_sparse(t)
- local keys= {}
- for k in pairs(t) do
- if type(k) == "number" then
- keys[#keys+1] = k
- end
- end
-
- table.sort(keys)
-
- local ret = {}
- for _,v in ipairs(keys) do
- ret[#ret+1] = t[v]
- end
-
- return ret
-end
-
---- Check if a table has an item and return its key.
--- @param t The table.
--- @param item The item to look for in values of the table.
--- @return The key were the item is found, or nil if not found.
-function util.table.hasitem(t, item)
- for k, v in pairs(t) do
- if v == item then
- return k
- end
- end
-end
-
---- Split a string into multiple lines
--- @param text String to wrap.
--- @param width Maximum length of each line. Default: 72.
--- @param indent Number of spaces added before each wrapped line. Default: 0.
--- @return The string with lines wrapped to width.
-function util.linewrap(text, width, indent)
- text = text or ""
- width = width or 72
- indent = indent or 0
-
- local pos = 1
- return text:gsub("(%s+)()(%S+)()",
- function(_, st, word, fi)
- if fi - pos > width then
- pos = st
- return "\n" .. string.rep(" ", indent) .. word
- end
- end)
-end
-
---- Count number of lines in a string
--- @tparam string text Input string.
--- @treturn int Number of lines.
-function util.linecount(text)
- return select(2, text:gsub('\n', '\n')) + 1
-end
-
---- Get a sorted table with all integer keys from a table
--- @param t the table for which the keys to get
--- @return A table with keys
-function util.table.keys(t)
- local keys = { }
- for k, _ in pairs(t) do
- rtable.insert(keys, k)
- end
- rtable.sort(keys, function (a, b)
- return type(a) == type(b) and a < b or false
- end)
- return keys
-end
-
---- Filter a tables keys for certain content types
--- @param t The table to retrieve the keys for
--- @param ... the types to look for
--- @return A filtered table with keys
-function util.table.keys_filter(t, ...)
- local keys = util.table.keys(t)
- local keys_filtered = { }
- for _, k in pairs(keys) do
- for _, et in pairs({...}) do
- if type(t[k]) == et then
- rtable.insert(keys_filtered, k)
- break
- end
- end
- end
- return keys_filtered
-end
-
---- Reverse a table
--- @param t the table to reverse
--- @return the reversed table
-function util.table.reverse(t)
- local tr = { }
- -- reverse all elements with integer keys
- for _, v in ipairs(t) do
- rtable.insert(tr, 1, v)
- end
- -- add the remaining elements
- for k, v in pairs(t) do
- if type(k) ~= "number" then
- tr[k] = v
- end
- end
- return tr
-end
-
---- Clone a table
--- @param t the table to clone
--- @param deep Create a deep clone? (default: true)
--- @return a clone of t
-function util.table.clone(t, deep)
- deep = deep == nil and true or deep
- local c = { }
- for k, v in pairs(t) do
- if deep and type(v) == "table" then
- c[k] = util.table.clone(v)
- else
- c[k] = v
- end
- end
- return c
-end
-
----
--- Returns an iterator to cycle through, starting from the first element or the
--- given index, all elements of a table that match a given criteria.
---
--- @param t the table to iterate
--- @param filter a function that returns true to indicate a positive match
--- @param start what index to start iterating from. Default is 1 (=> start of
--- the table)
-function util.table.iterate(t, filter, start)
- local count = 0
- local index = start or 1
- local length = #t
-
- return function ()
- while count < length do
- local item = t[index]
- index = util.cycle(#t, index + 1)
- count = count + 1
- if filter(item) then return item end
- end
- end
-end
-
-
---- Merge items from the one table to another one
--- @tparam table t the container table
--- @tparam table set the mixin table
--- @treturn table Return `t` for convenience
-function util.table.merge(t, set)
- for _, v in ipairs(set) do
- table.insert(t, v)
- end
- return t
-end
-
-
--- Escape all special pattern-matching characters so that lua interprets them
--- literally instead of as a character class.
--- Source: http://stackoverflow.com/a/20778724/15690
-function util.quote_pattern(s)
- -- All special characters escaped in a string: %%, %^, %$, ...
- local patternchars = '['..("%^$().[]*+-?"):gsub("(.)", "%%%1")..']'
- return string.gsub(s, patternchars, "%%%1")
-end
-
--- Generate a pattern matching expression that ignores case.
--- @param s Original pattern matching expression.
-function util.query_to_pattern(q)
- local s = util.quote_pattern(q)
- -- Poor man's case-insensitive character matching.
- s = string.gsub(s, "%a",
- function (c)
- return string.format("[%s%s]", string.lower(c),
- string.upper(c))
- end)
- return s
-end
-
---- Round a number to an integer.
--- @tparam number x
--- @treturn integer
-function util.round(x)
- return floor(x + 0.5)
-end
-
-return util
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/wibar.lua b/awesome/lib/awful/wibar.lua
deleted file mode 100644
index bbe7289..0000000
--- a/awesome/lib/awful/wibar.lua
+++ /dev/null
@@ -1,603 +0,0 @@
----------------------------------------------------------------------------
---- Wibox module for awful.
--- This module allows you to easily create wibox and attach them to the edge of
--- a screen.
---
--- @author Emmanuel Lepage Vallee &lt;elv1313@gmail.com&gt;
--- @copyright 2016 Emmanuel Lepage Vallee
--- @classmod awful.wibar
----------------------------------------------------------------------------
-
--- Grab environment we need
-local capi =
-{
- screen = screen,
- client = client
-}
-local setmetatable = setmetatable
-local tostring = tostring
-local ipairs = ipairs
-local error = error
-local wibox = require("wibox")
-local beautiful = require("beautiful")
-local util = require("awful.util")
-local placement = require("awful.placement")
-
-local function get_screen(s)
- return s and capi.screen[s]
-end
-
-local awfulwibar = { mt = {} }
-
---- Array of table with wiboxes inside.
--- It's an array so it is ordered.
-local wiboxes = setmetatable({}, {__mode = "v"})
-
--- Compute the margin on one side
-local function get_margin(w, position, auto_stop)
- local h_or_w = (position == "top" or position == "bottom") and "height" or "width"
- local ret = 0
-
- for _, v in ipairs(wiboxes) do
- -- Ignore the wibars placed after this one
- if auto_stop and v == w then break end
-
- if v.position == position and v.screen == w.screen and v.visible then
- ret = ret + v[h_or_w]
- end
- end
-
- return ret
-end
-
--- `honor_workarea` cannot be used as it does modify the workarea itself.
--- a manual padding has to be generated.
-local function get_margins(w)
- local position = w.position
- assert(position)
-
- local margins = {left=0, right=0, top=0, bottom=0}
-
- margins[position] = get_margin(w, position, true)
-
- -- Avoid overlapping wibars
- if position == "left" or position == "right" then
- margins.top = get_margin(w, "top" )
- margins.bottom = get_margin(w, "bottom")
- end
-
- return margins
-end
-
--- Create the placement function
-local function gen_placement(position, stretch)
- local maximize = (position == "right" or position == "left") and
- "maximize_vertically" or "maximize_horizontally"
-
- return placement[position] + (stretch and placement[maximize] or nil)
-end
-
--- Attach the placement function.
-local function attach(wb, align)
- gen_placement(align, wb._stretch)(wb, {
- attach = true,
- update_workarea = true,
- margins = get_margins(wb)
- })
-end
-
--- Re-attach all wibars on a given wibar screen
-local function reattach(wb)
- local s = wb.screen
- for _, w in ipairs(wiboxes) do
- if w ~= wb and w.screen == s then
- if w.detach_callback then
- w.detach_callback()
- w.detach_callback = nil
- end
- attach(w, w.position)
- end
- end
-end
-
---- The wibox position.
--- @property position
--- @param string Either "left", right", "top" or "bottom"
-
-local function get_position(wb)
- return wb._position or "top"
-end
-
-local function set_position(wb, position)
- -- Detach first to avoid any uneeded callbacks
- if wb.detach_callback then
- wb.detach_callback()
-
- -- Avoid disconnecting twice, this produces a lot of warnings
- wb.detach_callback = nil
- end
-
- -- Move the wibar to the end of the list to avoid messing up the others in
- -- case there is stacked wibars on one side.
- if wb._position then
- for k, w in ipairs(wiboxes) do
- if w == wb then
- table.remove(wiboxes, k)
- end
- end
- table.insert(wiboxes, wb)
- end
-
- -- In case the position changed, it may be necessary to reset the size
- if (wb._position == "left" or wb._position == "right")
- and (position == "top" or position == "bottom") then
- wb.height = math.ceil(beautiful.get_font_height(wb.font) * 1.5)
- elseif (wb._position == "top" or wb._position == "bottom")
- and (position == "left" or position == "right") then
- wb.width = math.ceil(beautiful.get_font_height(wb.font) * 1.5)
- end
-
- -- Changing the position will also cause the other margins to be invalidated.
- -- For example, adding a wibar to the top will change the margins of any left
- -- or right wibars. To solve, this, they need to be re-attached.
- reattach(wb)
-
- -- Set the new position
- wb._position = position
-
- -- Attach to the new position
- attach(wb, position)
-end
-
---- Stretch the wibar.
---
--- @property stretch
--- @param[opt=true] boolean
-
-local function get_stretch(w)
- return w._stretch
-end
-
-local function set_stretch(w, value)
- w._stretch = value
-
- attach(w, w.position)
-end
-
---- Remove a wibar.
--- @function remove
-local function remove(self)
- self.visible = false
-
- if self.detach_callback then
- self.detach_callback()
- self.detach_callback = nil
- end
-
- for k, w in ipairs(wiboxes) do
- if w == self then
- table.remove(wiboxes, k)
- end
- end
-
- self._screen = nil
-end
-
---- Get a wibox position if it has been set, or return top.
--- @param wb The wibox
--- @deprecated awful.wibar.get_position
--- @return The wibox position.
-function awfulwibar.get_position(wb)
- util.deprecate("Use wb:get_position() instead of awful.wibar.get_position")
- return get_position(wb)
-end
-
---- Put a wibox on a screen at this position.
--- @param wb The wibox to attach.
--- @param position The position: top, bottom left or right.
--- @param screen This argument is deprecated, use wb.screen directly.
--- @deprecated awful.wibar.set_position
-function awfulwibar.set_position(wb, position, screen) --luacheck: no unused args
- util.deprecate("Use wb:set_position(position) instead of awful.wibar.set_position")
-
- set_position(wb, position)
-end
-
---- Attach a wibox to a screen.
---
--- This function has been moved to the `awful.placement` module. Calling this
--- no longer does anything.
---
--- @param wb The wibox to attach.
--- @param position The position of the wibox: top, bottom, left or right.
--- @param screen The screen to attach to
--- @see awful.placement
--- @deprecated awful.wibar.attach
-function awfulwibar.attach(wb, position, screen) --luacheck: no unused args
- util.deprecate("awful.wibar.attach is deprecated, use the 'attach' property"..
- " of awful.placement. This method doesn't do anything anymore"
- )
-end
-
---- Align a wibox.
---
--- Supported alignment are:
---
--- * top_left
--- * top_right
--- * bottom_left
--- * bottom_right
--- * left
--- * right
--- * top
--- * bottom
--- * centered
--- * center_vertical
--- * center_horizontal
---
--- @param wb The wibox.
--- @param align The alignment
--- @param screen This argument is deprecated. It is not used. Use wb.screen
--- directly.
--- @deprecated awful.wibar.align
--- @see awful.placement.align
-function awfulwibar.align(wb, align, screen) --luacheck: no unused args
- if align == "center" then
- util.deprecate("awful.wibar.align(wb, 'center' is deprecated, use 'centered'")
- align = "centered"
- end
-
- if screen then
- util.deprecate("awful.wibar.align 'screen' argument is deprecated")
- end
-
- if placement[align] then
- return placement[align](wb)
- end
-end
-
---- Stretch a wibox so it takes all screen width or height.
---
--- **This function has been removed.**
---
--- @deprecated awful.wibox.stretch
--- @see awful.placement
--- @see awful.wibar.stretch
-
---- Create a new wibox and attach it to a screen edge.
--- You can add also position key with value top, bottom, left or right.
--- You can also use width or height in % and set align to center, right or left.
--- You can also set the screen key with a screen number to attach the wibox.
--- If not specified, the primary screen is assumed.
--- @see wibox
--- @tparam[opt=nil] table arg
--- @tparam string arg.position The position.
--- @tparam string arg.stretch If the wibar need to be stretched to fill the screen.
--- @tparam integer arg.border_width Border width.
--- @tparam string arg.border_color Border color.
--- @tparam boolean arg.ontop On top of other windows.
--- @tparam string arg.cursor The mouse cursor.
--- @tparam boolean arg.visible Visibility.
--- @tparam number arg.opacity The opacity of the wibox, between 0 and 1.
--- @tparam string arg.type The window type (desktop, normal, dock, …).
--- @tparam integer arg.x The x coordinates.
--- @tparam integer arg.y The y coordinates.
--- @tparam integer arg.width The width of the wibox.
--- @tparam integer arg.height The height of the wibox.
--- @tparam screen arg.screen The wibox screen.
--- @tparam wibox.widget arg.widget The widget that the wibox displays.
--- @param arg.shape_bounding The wibox’s bounding shape as a (native) cairo surface.
--- @param arg.shape_clip The wibox’s clip shape as a (native) cairo surface.
--- @tparam color arg.bg The background of the wibox.
--- @tparam surface arg.bgimage The background image of the drawable.
--- @tparam color arg.fg The foreground (text) of the wibox.
--- @return The new wibar
--- @function awful.wibar
-function awfulwibar.new(arg)
- arg = arg or {}
- local position = arg.position or "top"
- local has_to_stretch = true
- local screen = get_screen(arg.screen or 1)
-
- arg.type = arg.type or "dock"
-
- if position ~= "top" and position ~="bottom"
- and position ~= "left" and position ~= "right" then
- error("Invalid position in awful.wibar(), you may only use"
- .. " 'top', 'bottom', 'left' and 'right'")
- end
-
- -- Set default size
- if position == "left" or position == "right" then
- arg.width = arg.width or math.ceil(beautiful.get_font_height(arg.font) * 1.5)
- if arg.height then
- has_to_stretch = false
- if arg.screen then
- local hp = tostring(arg.height):match("(%d+)%%")
- if hp then
- arg.height = math.ceil(screen.geometry.height * hp / 100)
- end
- end
- end
- else
- arg.height = arg.height or math.ceil(beautiful.get_font_height(arg.font) * 1.5)
- if arg.width then
- has_to_stretch = false
- if arg.screen then
- local wp = tostring(arg.width):match("(%d+)%%")
- if wp then
- arg.width = math.ceil(screen.geometry.width * wp / 100)
- end
- end
- end
- end
-
- arg.screen = nil
-
- local w = wibox(arg)
-
- w.screen = screen
- w._screen = screen --HACK When a screen is removed, then getbycoords wont work
- w._stretch = arg.stretch == nil and has_to_stretch or arg.stretch
-
- w.get_position = get_position
- w.set_position = set_position
-
- w.get_stretch = get_stretch
- w.set_stretch = set_stretch
- w.remove = remove
-
- if arg.visible == nil then w.visible = true end
-
- w:set_position(position)
-
- table.insert(wiboxes, w)
-
- w:connect_signal("property::visible", function() reattach(w) end)
-
- return w
-end
-
-capi.screen.connect_signal("removed", function(s)
- for _, wibar in ipairs(wiboxes) do
- if wibar._screen == s then
- wibar:remove()
- end
- end
-end)
-
-function awfulwibar.mt:__call(...)
- return awfulwibar.new(...)
-end
-
---Imported documentation
-
---- Border width.
---
--- **Signal:**
---
--- * *property::border_width*
---
--- @property border_width
--- @param integer
-
---- Border color.
---
--- Please note that this property only support string based 24 bit or 32 bit
--- colors:
---
--- Red Blue
--- _| _|
--- #FF00FF
--- T‾
--- Green
---
---
--- Red Blue
--- _| _|
--- #FF00FF00
--- T‾ ‾T
--- Green Alpha
---
--- **Signal:**
---
--- * *property::border_color*
---
--- @property border_color
--- @param string
-
---- On top of other windows.
---
--- **Signal:**
---
--- * *property::ontop*
---
--- @property ontop
--- @param boolean
-
---- The mouse cursor.
---
--- **Signal:**
---
--- * *property::cursor*
---
--- @property cursor
--- @param string
--- @see mouse
-
---- Visibility.
---
--- **Signal:**
---
--- * *property::visible*
---
--- @property visible
--- @param boolean
-
---- The opacity of the wibox, between 0 and 1.
---
--- **Signal:**
---
--- * *property::opacity*
---
--- @property opacity
--- @tparam number opacity (between 0 and 1)
-
---- The window type (desktop, normal, dock, ...).
---
--- **Signal:**
---
--- * *property::type*
---
--- @property type
--- @param string
--- @see client.type
-
---- The x coordinates.
---
--- **Signal:**
---
--- * *property::x*
---
--- @property x
--- @param integer
-
---- The y coordinates.
---
--- **Signal:**
---
--- * *property::y*
---
--- @property y
--- @param integer
-
---- The width of the wibox.
---
--- **Signal:**
---
--- * *property::width*
---
--- @property width
--- @param width
-
---- The height of the wibox.
---
--- **Signal:**
---
--- * *property::height*
---
--- @property height
--- @param height
-
---- The wibox screen.
---
--- @property screen
--- @param screen
-
---- The wibox's `drawable`.
---
--- **Signal:**
---
--- * *property::drawable*
---
--- @property drawable
--- @tparam drawable drawable
-
---- The widget that the `wibox` displays.
--- @property widget
--- @param widget
-
---- The X window id.
---
--- **Signal:**
---
--- * *property::window*
---
--- @property window
--- @param string
--- @see client.window
-
---- The wibox's bounding shape as a (native) cairo surface.
---
--- **Signal:**
---
--- * *property::shape_bounding*
---
--- @property shape_bounding
--- @param surface._native
-
---- The wibox's clip shape as a (native) cairo surface.
---
--- **Signal:**
---
--- * *property::shape_clip*
---
--- @property shape_clip
--- @param surface._native
-
---- Get or set mouse buttons bindings to a wibox.
---
--- @param buttons_table A table of buttons objects, or nothing.
--- @function buttons
-
---- Get or set wibox geometry. That's the same as accessing or setting the x,
--- y, width or height properties of a wibox.
---
--- @param A table with coordinates to modify.
--- @return A table with wibox coordinates and geometry.
--- @function geometry
-
---- Get or set wibox struts.
---
--- @param strut A table with new strut, or nothing
--- @return The wibox strut in a table.
--- @function struts
--- @see client.struts
-
---- The default background color.
--- @beautiful beautiful.bg_normal
--- @see bg
-
---- The default foreground (text) color.
--- @beautiful beautiful.fg_normal
--- @see fg
-
---- Set a declarative widget hierarchy description.
--- See [The declarative layout system](../documentation/03-declarative-layout.md.html)
--- @param args An array containing the widgets disposition
--- @name setup
--- @class function
-
---- The background of the wibox.
--- @param c The background to use. This must either be a cairo pattern object,
--- nil or a string that gears.color() understands.
--- @property bg
--- @see gears.color
-
---- The background image of the drawable.
--- If `image` is a function, it will be called with `(context, cr, width, height)`
--- as arguments. Any other arguments passed to this method will be appended.
--- @param image A background image or a function
--- @property bgimage
--- @see gears.surface
-
---- The foreground (text) of the wibox.
--- @param c The foreground to use. This must either be a cairo pattern object,
--- nil or a string that gears.color() understands.
--- @property fg
--- @see gears.color
-
---- Find a widget by a point.
--- The wibox must have drawn itself at least once for this to work.
--- @tparam number x X coordinate of the point
--- @tparam number y Y coordinate of the point
--- @treturn table A sorted table of widgets positions. The first element is the biggest
--- container while the last is the topmost widget. The table contains *x*, *y*,
--- *width*, *height* and *widget*.
--- @name find_widgets
--- @class function
-
-
-return setmetatable(awfulwibar, awfulwibar.mt)
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/wibox.lua b/awesome/lib/awful/wibox.lua
deleted file mode 100644
index e8c7c7f..0000000
--- a/awesome/lib/awful/wibox.lua
+++ /dev/null
@@ -1,12 +0,0 @@
----------------------------------------------------------------------------
---- This module is deprecated and has been renamed `awful.wibar`
---
--- @author Emmanuel Lepage Vallee &lt;elv1313@gmail.com&gt;
--- @copyright 2016 Emmanuel Lepage Vallee
--- @module awful.wibox
----------------------------------------------------------------------------
-local util = require("awful.util")
-
-return util.deprecate_class(require("awful.wibar"), "awful.wibox", "awful.wibar")
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/widget/button.lua b/awesome/lib/awful/widget/button.lua
deleted file mode 100644
index 388f9dd..0000000
--- a/awesome/lib/awful/widget/button.lua
+++ /dev/null
@@ -1,263 +0,0 @@
----------------------------------------------------------------------------
--- A simple button widget.
--- @usage local button = awful.widget.button()
--- button:buttons(awful.util.table.join(
--- button:buttons(),
--- awful.button({}, 1, nil, function ()
--- print("Mouse was clicked")
--- end)
--- ))
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2008-2009 Julien Danjou
--- @classmod awful.widget.button
----------------------------------------------------------------------------
-
-local setmetatable = setmetatable
-local abutton = require("awful.button")
-local imagebox = require("wibox.widget.imagebox")
-local widget = require("wibox.widget.base")
-local surface = require("gears.surface")
-local cairo = require("lgi").cairo
-
-local button = { mt = {} }
-
---- Create a button widget. When clicked, the image is deplaced to make it like
--- a real button.
---
--- @param args Widget arguments. "image" is the image to display.
--- @return A textbox widget configured as a button.
-function button.new(args)
- if not args or not args.image then
- return widget.empty_widget()
- end
-
- local w = imagebox()
- local orig_set_image = w.set_image
- local img_release
- local img_press
-
- function w:set_image(image)
- img_release = surface.load(image)
- img_press = img_release:create_similar(cairo.Content.COLOR_ALPHA, img_release.width, img_release.height)
- local cr = cairo.Context(img_press)
- cr:set_source_surface(img_release, 2, 2)
- cr:paint()
- orig_set_image(self, img_release)
- end
- w:set_image(args.image)
- w:buttons(abutton({}, 1, function () orig_set_image(w, img_press) end, function () orig_set_image(w, img_release) end))
-
- w:connect_signal("mouse::leave", function(self) orig_set_image(self, img_release) end)
-
- return w
-end
-
-function button.mt:__call(...)
- return button.new(...)
-end
-
---Imported documentation
-
-
---- Get a widex index.
--- @param widget The widget to look for
--- @param[opt] recursive Also check sub-widgets
--- @param[opt] ... Aditional widgets to add at the end of the \"path\"
--- @return The index
--- @return The parent layout
--- @return The path between \"self\" and \"widget\"
--- @function index
-
---- Get all direct and indirect children widgets.
--- This will scan all containers recursively to find widgets
--- Warning: This method it prone to stack overflow id the widget, or any of its
--- children, contain (directly or indirectly) itself.
--- @treturn table The children
--- @function get_all_children
-
---- Set a declarative widget hierarchy description.
--- See [The declarative layout system](../documentation/03-declarative-layout.md.html)
--- @param args An array containing the widgets disposition
--- @function setup
-
---- Force a widget height.
--- @property forced_height
--- @tparam number|nil height The height (`nil` for automatic)
-
---- Force a widget width.
--- @property forced_width
--- @tparam number|nil width The width (`nil` for automatic)
-
---- The widget opacity (transparency).
--- @property opacity
--- @tparam[opt=1] number opacity The opacity (between 0 and 1)
-
---- The widget visibility.
--- @property visible
--- @param boolean
-
---- Set/get a widget's buttons.
--- @param _buttons The table of buttons that should bind to the widget.
--- @function buttons
-
---- Emit a signal and ensure all parent widgets in the hierarchies also
--- forward the signal. This is useful to track signals when there is a dynamic
--- set of containers and layouts wrapping the widget.
--- @tparam string signal_name
--- @param ... Other arguments
--- @function emit_signal_recursive
-
---- When the layout (size) change.
--- This signal is emitted when the previous results of `:layout()` and `:fit()`
--- are no longer valid. Unless this signal is emitted, `:layout()` and `:fit()`
--- must return the same result when called with the same arguments.
--- @signal widget::layout_changed
--- @see widget::redraw_needed
-
---- When the widget content changed.
--- This signal is emitted when the content of the widget changes. The widget will
--- be redrawn, it is not re-layouted. Put differently, it is assumed that
--- `:layout()` and `:fit()` would still return the same results as before.
--- @signal widget::redraw_needed
--- @see widget::layout_changed
-
---- When a mouse button is pressed over the widget.
--- @signal button::press
--- @tparam number lx The horizontal position relative to the (0,0) position in
--- the widget.
--- @tparam number ly The vertical position relative to the (0,0) position in the
--- widget.
--- @tparam number button The button number.
--- @tparam table mods The modifiers (mod4, mod1 (alt), Control, Shift)
--- @tparam table find_widgets_result The entry from the result of
--- @{wibox.drawable:find_widgets} for the position that the mouse hit.
--- @tparam wibox.drawable find_widgets_result.drawable The drawable containing
--- the widget.
--- @tparam widget find_widgets_result.widget The widget being displayed.
--- @tparam wibox.hierarchy find_widgets_result.hierarchy The hierarchy
--- managing the widget's geometry.
--- @tparam number find_widgets_result.x An approximation of the X position that
--- the widget is visible at on the surface.
--- @tparam number find_widgets_result.y An approximation of the Y position that
--- the widget is visible at on the surface.
--- @tparam number find_widgets_result.width An approximation of the width that
--- the widget is visible at on the surface.
--- @tparam number find_widgets_result.height An approximation of the height that
--- the widget is visible at on the surface.
--- @tparam number find_widgets_result.widget_width The exact width of the widget
--- in its local coordinate system.
--- @tparam number find_widgets_result.widget_height The exact height of the widget
--- in its local coordinate system.
--- @see mouse
-
---- When a mouse button is released over the widget.
--- @signal button::release
--- @tparam number lx The horizontal position relative to the (0,0) position in
--- the widget.
--- @tparam number ly The vertical position relative to the (0,0) position in the
--- widget.
--- @tparam number button The button number.
--- @tparam table mods The modifiers (mod4, mod1 (alt), Control, Shift)
--- @tparam table find_widgets_result The entry from the result of
--- @{wibox.drawable:find_widgets} for the position that the mouse hit.
--- @tparam wibox.drawable find_widgets_result.drawable The drawable containing
--- the widget.
--- @tparam widget find_widgets_result.widget The widget being displayed.
--- @tparam wibox.hierarchy find_widgets_result.hierarchy The hierarchy
--- managing the widget's geometry.
--- @tparam number find_widgets_result.x An approximation of the X position that
--- the widget is visible at on the surface.
--- @tparam number find_widgets_result.y An approximation of the Y position that
--- the widget is visible at on the surface.
--- @tparam number find_widgets_result.width An approximation of the width that
--- the widget is visible at on the surface.
--- @tparam number find_widgets_result.height An approximation of the height that
--- the widget is visible at on the surface.
--- @tparam number find_widgets_result.widget_width The exact width of the widget
--- in its local coordinate system.
--- @tparam number find_widgets_result.widget_height The exact height of the widget
--- in its local coordinate system.
--- @see mouse
-
---- When the mouse enter a widget.
--- @signal mouse::enter
--- @tparam table find_widgets_result The entry from the result of
--- @{wibox.drawable:find_widgets} for the position that the mouse hit.
--- @tparam wibox.drawable find_widgets_result.drawable The drawable containing
--- the widget.
--- @tparam widget find_widgets_result.widget The widget being displayed.
--- @tparam wibox.hierarchy find_widgets_result.hierarchy The hierarchy
--- managing the widget's geometry.
--- @tparam number find_widgets_result.x An approximation of the X position that
--- the widget is visible at on the surface.
--- @tparam number find_widgets_result.y An approximation of the Y position that
--- the widget is visible at on the surface.
--- @tparam number find_widgets_result.width An approximation of the width that
--- the widget is visible at on the surface.
--- @tparam number find_widgets_result.height An approximation of the height that
--- the widget is visible at on the surface.
--- @tparam number find_widgets_result.widget_width The exact width of the widget
--- in its local coordinate system.
--- @tparam number find_widgets_result.widget_height The exact height of the widget
--- in its local coordinate system.
--- @see mouse
-
---- When the mouse leave a widget.
--- @signal mouse::leave
--- @tparam table find_widgets_result The entry from the result of
--- @{wibox.drawable:find_widgets} for the position that the mouse hit.
--- @tparam wibox.drawable find_widgets_result.drawable The drawable containing
--- the widget.
--- @tparam widget find_widgets_result.widget The widget being displayed.
--- @tparam wibox.hierarchy find_widgets_result.hierarchy The hierarchy
--- managing the widget's geometry.
--- @tparam number find_widgets_result.x An approximation of the X position that
--- the widget is visible at on the surface.
--- @tparam number find_widgets_result.y An approximation of the Y position that
--- the widget is visible at on the surface.
--- @tparam number find_widgets_result.width An approximation of the width that
--- the widget is visible at on the surface.
--- @tparam number find_widgets_result.height An approximation of the height that
--- the widget is visible at on the surface.
--- @tparam number find_widgets_result.widget_width The exact width of the widget
--- in its local coordinate system.
--- @tparam number find_widgets_result.widget_height The exact height of the widget
--- in its local coordinate system.
--- @see mouse
-
-
---Imported documentation
-
-
---- Disconnect to a signal.
--- @tparam string name The name of the signal
--- @tparam function func The callback that should be disconnected
--- @function disconnect_signal
-
---- Emit a signal.
---
--- @tparam string name The name of the signal
--- @param ... Extra arguments for the callback functions. Each connected
--- function receives the object as first argument and then any extra arguments
--- that are given to emit_signal()
--- @function emit_signal
-
---- Connect to a signal.
--- @tparam string name The name of the signal
--- @tparam function func The callback to call when the signal is emitted
--- @function connect_signal
-
---- Connect to a signal weakly. This allows the callback function to be garbage
--- collected and automatically disconnects the signal when that happens.
---
--- **Warning:**
--- Only use this function if you really, really, really know what you
--- are doing.
--- @tparam string name The name of the signal
--- @tparam function func The callback to call when the signal is emitted
--- @function weak_connect_signal
-
-
-return setmetatable(button, button.mt)
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/widget/common.lua b/awesome/lib/awful/widget/common.lua
deleted file mode 100644
index e9ae699..0000000
--- a/awesome/lib/awful/widget/common.lua
+++ /dev/null
@@ -1,119 +0,0 @@
----------------------------------------------------------------------------
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2008-2009 Julien Danjou
--- @classmod awful.widget.common
----------------------------------------------------------------------------
-
--- Grab environment we need
-local type = type
-local ipairs = ipairs
-local capi = { button = button }
-local wibox = require("wibox")
-local dpi = require("beautiful").xresources.apply_dpi
-
---- Common utilities for awful widgets
-local common = {}
-
---- Common method to create buttons.
--- @tab buttons
--- @param object
--- @treturn table
-function common.create_buttons(buttons, object)
- if buttons then
- local btns = {}
- for _, b in ipairs(buttons) do
- -- Create a proxy button object: it will receive the real
- -- press and release events, and will propagate them to the
- -- button object the user provided, but with the object as
- -- argument.
- local btn = capi.button { modifiers = b.modifiers, button = b.button }
- btn:connect_signal("press", function () b:emit_signal("press", object) end)
- btn:connect_signal("release", function () b:emit_signal("release", object) end)
- btns[#btns + 1] = btn
- end
-
- return btns
- end
-end
-
---- Common update method.
--- @param w The widget.
--- @tab buttons
--- @func label Function to generate label parameters from an object.
--- The function gets passed an object from `objects`, and
--- has to return `text`, `bg`, `bg_image`, `icon`.
--- @tab data Current data/cache, indexed by objects.
--- @tab objects Objects to be displayed / updated.
-function common.list_update(w, buttons, label, data, objects)
- -- update the widgets, creating them if needed
- w:reset()
- for i, o in ipairs(objects) do
- local cache = data[o]
- local ib, tb, bgb, tbm, ibm, l
- if cache then
- ib = cache.ib
- tb = cache.tb
- bgb = cache.bgb
- tbm = cache.tbm
- ibm = cache.ibm
- else
- ib = wibox.widget.imagebox()
- tb = wibox.widget.textbox()
- bgb = wibox.container.background()
- tbm = wibox.container.margin(tb, dpi(4), dpi(4))
- ibm = wibox.container.margin(ib, dpi(4))
- l = wibox.layout.fixed.horizontal()
-
- -- All of this is added in a fixed widget
- l:fill_space(true)
- l:add(ibm)
- l:add(tbm)
-
- -- And all of this gets a background
- bgb:set_widget(l)
-
- bgb:buttons(common.create_buttons(buttons, o))
-
- data[o] = {
- ib = ib,
- tb = tb,
- bgb = bgb,
- tbm = tbm,
- ibm = ibm,
- }
- end
-
- local text, bg, bg_image, icon, args = label(o, tb)
- args = args or {}
-
- -- The text might be invalid, so use pcall.
- if text == nil or text == "" then
- tbm:set_margins(0)
- else
- if not tb:set_markup_silently(text) then
- tb:set_markup("<i>&lt;Invalid text&gt;</i>")
- end
- end
- bgb:set_bg(bg)
- if type(bg_image) == "function" then
- -- TODO: Why does this pass nil as an argument?
- bg_image = bg_image(tb,o,nil,objects,i)
- end
- bgb:set_bgimage(bg_image)
- if icon then
- ib:set_image(icon)
- else
- ibm:set_margins(0)
- end
-
- bgb.shape = args.shape
- bgb.shape_border_width = args.shape_border_width
- bgb.shape_border_color = args.shape_border_color
-
- w:add(bgb)
- end
-end
-
-return common
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/widget/graph.lua b/awesome/lib/awful/widget/graph.lua
deleted file mode 100644
index e231463..0000000
--- a/awesome/lib/awful/widget/graph.lua
+++ /dev/null
@@ -1,16 +0,0 @@
----------------------------------------------------------------------------
---- This module has been moved to `wibox.widget.graph`
---
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2009 Julien Danjou
--- @classmod awful.widget.graph
----------------------------------------------------------------------------
-local util = require("awful.util")
-
-return util.deprecate_class(
- require("wibox.widget.graph"),
- "awful.widget.graph",
- "wibox.widget.graph"
-)
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/widget/init.lua b/awesome/lib/awful/widget/init.lua
deleted file mode 100644
index 02400a1..0000000
--- a/awesome/lib/awful/widget/init.lua
+++ /dev/null
@@ -1,24 +0,0 @@
----------------------------------------------------------------------------
---- Widget module for awful
---
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2008-2009 Julien Danjou
--- @classmod awful.widget
----------------------------------------------------------------------------
-
-return
-{
- taglist = require("awful.widget.taglist");
- tasklist = require("awful.widget.tasklist");
- button = require("awful.widget.button");
- launcher = require("awful.widget.launcher");
- prompt = require("awful.widget.prompt");
- progressbar = require("awful.widget.progressbar");
- graph = require("awful.widget.graph");
- layoutbox = require("awful.widget.layoutbox");
- textclock = require("awful.widget.textclock");
- keyboardlayout = require("awful.widget.keyboardlayout");
- watch = require("awful.widget.watch");
-}
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/widget/keyboardlayout.lua b/awesome/lib/awful/widget/keyboardlayout.lua
deleted file mode 100644
index 4f79a81..0000000
--- a/awesome/lib/awful/widget/keyboardlayout.lua
+++ /dev/null
@@ -1,308 +0,0 @@
----------------------------------------------------------------------------
--- @author Aleksey Fedotov &lt;lexa@cfotr.com&gt;
--- @copyright 2015 Aleksey Fedotov
--- @classmod wibox.widget.keyboardlayout
----------------------------------------------------------------------------
-
-local capi = {awesome = awesome}
-local setmetatable = setmetatable
-local textbox = require("wibox.widget.textbox")
-local button = require("awful.button")
-local util = require("awful.util")
-local widget_base = require("wibox.widget.base")
-local gdebug = require("gears.debug")
-
---- Keyboard Layout widget.
--- awful.widget.keyboardlayout
-local keyboardlayout = { mt = {} }
-
--- As to the country-code-like symbols below, refer to the names of XKB's
--- data files in /.../xkb/symbols/*.
-keyboardlayout.xkeyboard_country_code = {
- ["ad"] = true, -- Andorra
- ["af"] = true, -- Afganistan
- ["al"] = true, -- Albania
- ["am"] = true, -- Armenia
- ["ara"] = true, -- Arabic
- ["at"] = true, -- Austria
- ["az"] = true, -- Azerbaijan
- ["ba"] = true, -- Bosnia and Herzegovina
- ["bd"] = true, -- Bangladesh
- ["be"] = true, -- Belgium
- ["bg"] = true, -- Bulgaria
- ["br"] = true, -- Brazil
- ["bt"] = true, -- Bhutan
- ["bw"] = true, -- Botswana
- ["by"] = true, -- Belarus
- ["ca"] = true, -- Canada
- ["cd"] = true, -- Congo
- ["ch"] = true, -- Switzerland
- ["cm"] = true, -- Cameroon
- ["cn"] = true, -- China
- ["cz"] = true, -- Czechia
- ["de"] = true, -- Germany
- ["dk"] = true, -- Denmark
- ["ee"] = true, -- Estonia
- ["epo"] = true, -- Esperanto
- ["es"] = true, -- Spain
- ["et"] = true, -- Ethiopia
- ["fi"] = true, -- Finland
- ["fo"] = true, -- Faroe Islands
- ["fr"] = true, -- France
- ["gb"] = true, -- United Kingdom
- ["ge"] = true, -- Georgia
- ["gh"] = true, -- Ghana
- ["gn"] = true, -- Guinea
- ["gr"] = true, -- Greece
- ["hr"] = true, -- Croatia
- ["hu"] = true, -- Hungary
- ["ie"] = true, -- Ireland
- ["il"] = true, -- Israel
- ["in"] = true, -- India
- ["iq"] = true, -- Iraq
- ["ir"] = true, -- Iran
- ["is"] = true, -- Iceland
- ["it"] = true, -- Italy
- ["jp"] = true, -- Japan
- ["ke"] = true, -- Kenya
- ["kg"] = true, -- Kyrgyzstan
- ["kh"] = true, -- Cambodia
- ["kr"] = true, -- Korea
- ["kz"] = true, -- Kazakhstan
- ["la"] = true, -- Laos
- ["latam"] = true, -- Latin America
- ["latin"] = true, -- Latin
- ["lk"] = true, -- Sri Lanka
- ["lt"] = true, -- Lithuania
- ["lv"] = true, -- Latvia
- ["ma"] = true, -- Morocco
- ["mao"] = true, -- Maori
- ["me"] = true, -- Montenegro
- ["mk"] = true, -- Macedonia
- ["ml"] = true, -- Mali
- ["mm"] = true, -- Myanmar
- ["mn"] = true, -- Mongolia
- ["mt"] = true, -- Malta
- ["mv"] = true, -- Maldives
- ["ng"] = true, -- Nigeria
- ["nl"] = true, -- Netherlands
- ["no"] = true, -- Norway
- ["np"] = true, -- Nepal
- ["ph"] = true, -- Philippines
- ["pk"] = true, -- Pakistan
- ["pl"] = true, -- Poland
- ["pt"] = true, -- Portugal
- ["ro"] = true, -- Romania
- ["rs"] = true, -- Serbia
- ["ru"] = true, -- Russia
- ["se"] = true, -- Sweden
- ["si"] = true, -- Slovenia
- ["sk"] = true, -- Slovakia
- ["sn"] = true, -- Senegal
- ["sy"] = true, -- Syria
- ["th"] = true, -- Thailand
- ["tj"] = true, -- Tajikistan
- ["tm"] = true, -- Turkmenistan
- ["tr"] = true, -- Turkey
- ["tw"] = true, -- Taiwan
- ["tz"] = true, -- Tanzania
- ["ua"] = true, -- Ukraine
- ["us"] = true, -- USA
- ["uz"] = true, -- Uzbekistan
- ["vn"] = true, -- Vietnam
- ["za"] = true, -- South Africa
-}
-
--- Callback for updating current layout.
-local function update_status (self)
- self._current = awesome.xkb_get_layout_group();
- local text = ""
- if (#self._layout > 0) then
- text = (" " .. self._layout[self._current] .. " ")
- end
- self.widget:set_text(text)
-end
-
---- Auxiliary function for the local function update_layout().
--- Create an array whose element is a table consisting of the four fields:
--- vendor, file, section and group_idx, which all correspond to the
--- xkb_symbols pattern "vendor/file(section):group_idx".
--- @tparam string group_names The string awesome.xkb_get_group_names() returns.
--- @treturn table An array of tables whose keys are vendor, file, section, and group_idx.
-function keyboardlayout.get_groups_from_group_names(group_names)
- if group_names == nil then
- return nil
- end
-
- -- Pattern elements to be captured.
- local word_pat = "([%w_]+)"
- local sec_pat = "(%b())"
- local idx_pat = ":(%d)"
- -- Pairs of a pattern and its callback. In callbacks, set 'group_idx' to 1
- -- and return it if there's no specification on 'group_idx' in the given
- -- pattern.
- local pattern_and_callback_pairs = {
- -- vendor/file(section):group_idx
- ["^" .. word_pat .. "/" .. word_pat .. sec_pat .. idx_pat .. "$"]
- = function(token, pattern)
- local vendor, file, section, group_idx = string.match(token, pattern)
- return vendor, file, section, group_idx
- end,
- -- vendor/file(section)
- ["^" .. word_pat .. "/" .. word_pat .. sec_pat .. "$"]
- = function(token, pattern)
- local vendor, file, section = string.match(token, pattern)
- return vendor, file, section, 1
- end,
- -- vendor/file:group_idx
- ["^" .. word_pat .. "/" .. word_pat .. idx_pat .. "$"]
- = function(token, pattern)
- local vendor, file, group_idx = string.match(token, pattern)
- return vendor, file, nil, group_idx
- end,
- -- vendor/file
- ["^" .. word_pat .. "/" .. word_pat .. "$"]
- = function(token, pattern)
- local vendor, file = string.match(token, pattern)
- return vendor, file, nil, 1
- end,
- -- file(section):group_idx
- ["^" .. word_pat .. sec_pat .. idx_pat .. "$"]
- = function(token, pattern)
- local file, section, group_idx = string.match(token, pattern)
- return nil, file, section, group_idx
- end,
- -- file(section)
- ["^" .. word_pat .. sec_pat .. "$"]
- = function(token, pattern)
- local file, section = string.match(token, pattern)
- return nil, file, section, 1
- end,
- -- file:group_idx
- ["^" .. word_pat .. idx_pat .. "$"]
- = function(token, pattern)
- local file, group_idx = string.match(token, pattern)
- return nil, file, nil, group_idx
- end,
- -- file
- ["^" .. word_pat .. "$"]
- = function(token, pattern)
- local file = string.match(token, pattern)
- return nil, file, nil, 1
- end
- }
-
- -- Split 'group_names' into 'tokens'. The separator is "+".
- local tokens = {}
- string.gsub(group_names, "[^+]+", function(match)
- table.insert(tokens, match)
- end)
-
- -- For each token in 'tokens', check if it matches one of the patterns in
- -- the array 'pattern_and_callback_pairs', where the patterns are used as
- -- key. If a match is found, extract captured strings using the
- -- corresponding callback function. Check if those extracted is country
- -- specific part of a layout. If so, add it to 'layout_groups'; otherwise,
- -- ignore it.
- local layout_groups = {}
- for i = 1, #tokens do
- for pattern, callback in pairs(pattern_and_callback_pairs) do
- local vendor, file, section, group_idx = callback(tokens[i], pattern)
- if file then
- if not keyboardlayout.xkeyboard_country_code[file] then
- break
- end
-
- if section then
- section = string.gsub(section, "%(([%w-_]+)%)", "%1")
- end
-
- table.insert(layout_groups, { vendor = vendor,
- file = file,
- section = section,
- group_idx = tonumber(group_idx) })
- break
- end
- end
- end
-
- return layout_groups
-end
-
--- Callback for updating list of layouts
-local function update_layout(self)
- self._layout = {};
- local layouts = keyboardlayout.get_groups_from_group_names(awesome.xkb_get_group_names())
- if layouts == nil or layouts[1] == nil then
- gdebug.print_error("Failed to get list of keyboard groups")
- return
- end
- if #layouts == 1 then
- layouts[1].group_idx = 0
- end
- for _, v in ipairs(layouts) do
- local layout_name = self.layout_name(v)
- -- Please note that numbers of groups reported by xkb_get_group_names
- -- is greater by one than the real group number.
- self._layout[v.group_idx - 1] = layout_name
- end
- update_status(self)
-end
-
---- Create a keyboard layout widget. It shows current keyboard layout name in a textbox.
--- @return A keyboard layout widget.
-function keyboardlayout.new()
- local widget = textbox()
- local self = widget_base.make_widget(widget)
-
- self.widget = widget
-
- self.layout_name = function(v)
- local name = v.file
- if v.section ~= nil then
- name = name .. "(" .. v.section .. ")"
- end
- return name
- end
-
- self.next_layout = function()
- self.set_layout((self._current + 1) % (#self._layout + 1))
- end
-
- self.set_layout = function(group_number)
- if (0 > group_number) or (group_number > #self._layout) then
- error("Invalid group number: " .. group_number ..
- "expected number from 0 to " .. #self._layout)
- return;
- end
- awesome.xkb_set_layout_group(group_number);
- end
-
- update_layout(self);
-
- -- callback for processing layout changes
- capi.awesome.connect_signal("xkb::map_changed",
- function () update_layout(self) end)
- capi.awesome.connect_signal("xkb::group_changed",
- function () update_status(self) end);
-
- -- Mouse bindings
- self:buttons(
- util.table.join(button({ }, 1, self.next_layout))
- )
-
- return self
-end
-
-local _instance = nil;
-
-function keyboardlayout.mt:__call(...)
- if _instance == nil then
- _instance = keyboardlayout.new(...)
- end
- return _instance
-end
-
-return setmetatable(keyboardlayout, keyboardlayout.mt)
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/widget/launcher.lua b/awesome/lib/awful/widget/launcher.lua
deleted file mode 100644
index a944908..0000000
--- a/awesome/lib/awful/widget/launcher.lua
+++ /dev/null
@@ -1,41 +0,0 @@
----------------------------------------------------------------------------
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2008-2009 Julien Danjou
--- @classmod awful.widget.launcher
----------------------------------------------------------------------------
-
-local setmetatable = setmetatable
-local util = require("awful.util")
-local spawn = require("awful.spawn")
-local wbutton = require("awful.widget.button")
-local button = require("awful.button")
-
-local launcher = { mt = {} }
-
---- Create a button widget which will launch a command.
--- @param args Standard widget table arguments, plus image for the image path
--- and command for the command to run on click, or either menu to create menu.
--- @return A launcher widget.
-function launcher.new(args)
- if not args.command and not args.menu then return end
- local w = wbutton(args)
- if not w then return end
-
- local b
- if args.command then
- b = util.table.join(w:buttons(), button({}, 1, nil, function () spawn(args.command) end))
- elseif args.menu then
- b = util.table.join(w:buttons(), button({}, 1, nil, function () args.menu:toggle() end))
- end
-
- w:buttons(b)
- return w
-end
-
-function launcher.mt:__call(...)
- return launcher.new(...)
-end
-
-return setmetatable(launcher, launcher.mt)
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/widget/layoutbox.lua b/awesome/lib/awful/widget/layoutbox.lua
deleted file mode 100644
index c5f8ed3..0000000
--- a/awesome/lib/awful/widget/layoutbox.lua
+++ /dev/null
@@ -1,73 +0,0 @@
----------------------------------------------------------------------------
---- Layoutbox widget.
---
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2009 Julien Danjou
--- @classmod awful.widget.layoutbox
----------------------------------------------------------------------------
-
-local setmetatable = setmetatable
-local capi = { screen = screen, tag = tag }
-local layout = require("awful.layout")
-local tooltip = require("awful.tooltip")
-local beautiful = require("beautiful")
-local imagebox = require("wibox.widget.imagebox")
-
-local function get_screen(s)
- return s and capi.screen[s]
-end
-
-local layoutbox = { mt = {} }
-
-local boxes = nil
-
-local function update(w, screen)
- screen = get_screen(screen)
- local name = layout.getname(layout.get(screen))
- w._layoutbox_tooltip:set_text(name or "[no name]")
- w:set_image(name and beautiful["layout_" .. name])
-end
-
-local function update_from_tag(t)
- local screen = get_screen(t.screen)
- local w = boxes[screen]
- if w then
- update(w, screen)
- end
-end
-
---- Create a layoutbox widget. It draws a picture with the current layout
--- symbol of the current tag.
--- @param screen The screen number that the layout will be represented for.
--- @return An imagebox widget configured as a layoutbox.
-function layoutbox.new(screen)
- screen = get_screen(screen or 1)
-
- -- Do we already have the update callbacks registered?
- if boxes == nil then
- boxes = setmetatable({}, { __mode = "kv" })
- capi.tag.connect_signal("property::selected", update_from_tag)
- capi.tag.connect_signal("property::layout", update_from_tag)
- layoutbox.boxes = boxes
- end
-
- -- Do we already have a layoutbox for this screen?
- local w = boxes[screen]
- if not w then
- w = imagebox()
- w._layoutbox_tooltip = tooltip {objects = {w}, delay_show = 1}
-
- update(w, screen)
- boxes[screen] = w
- end
-
- return w
-end
-
-function layoutbox.mt:__call(...)
- return layoutbox.new(...)
-end
-
-return setmetatable(layoutbox, layoutbox.mt)
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/widget/progressbar.lua b/awesome/lib/awful/widget/progressbar.lua
deleted file mode 100644
index 11147f4..0000000
--- a/awesome/lib/awful/widget/progressbar.lua
+++ /dev/null
@@ -1,16 +0,0 @@
----------------------------------------------------------------------------
---- This module has been moved to `wibox.widget.progressbar`
---
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2009 Julien Danjou
--- @classmod awful.widget.progressbar
----------------------------------------------------------------------------
-local util = require("awful.util")
-
-return util.deprecate_class(
- require("wibox.widget.progressbar"),
- "awful.widget.progressbar",
- "wibox.widget.progressbar"
-)
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/widget/prompt.lua b/awesome/lib/awful/widget/prompt.lua
deleted file mode 100644
index ff9d904..0000000
--- a/awesome/lib/awful/widget/prompt.lua
+++ /dev/null
@@ -1,64 +0,0 @@
----------------------------------------------------------------------------
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2009 Julien Danjou
--- @classmod awful.widget.prompt
----------------------------------------------------------------------------
-
-local setmetatable = setmetatable
-
-local completion = require("awful.completion")
-local util = require("awful.util")
-local spawn = require("awful.spawn")
-local prompt = require("awful.prompt")
-local widget_base = require("wibox.widget.base")
-local textbox = require("wibox.widget.textbox")
-local type = type
-
-local widgetprompt = { mt = {} }
-
---- Run method for promptbox.
---
--- @param promptbox The promptbox to run.
-local function run(promptbox)
- return prompt.run {
- prompt = promptbox.prompt,
- textbox = promptbox.widget,
- completion_callback = completion.shell,
- history_path = util.get_cache_dir() .. "/history",
- exe_callback = function (...)
- promptbox:spawn_and_handle_error(...)
- end,
- }
-end
-
-local function spawn_and_handle_error(self, ...)
- local result = spawn(...)
- if type(result) == "string" then
- self.widget:set_text(result)
- end
-end
-
---- Create a prompt widget which will launch a command.
---
--- @param args Arguments table. "prompt" is the prompt to use.
--- @return A launcher widget.
-function widgetprompt.new(args)
- args = args or {}
- local widget = textbox()
- local promptbox = widget_base.make_widget(widget)
-
- promptbox.widget = widget
- promptbox.widget:set_ellipsize("start")
- promptbox.run = run
- promptbox.spawn_and_handle_error = spawn_and_handle_error
- promptbox.prompt = args.prompt or "Run: "
- return promptbox
-end
-
-function widgetprompt.mt:__call(...)
- return widgetprompt.new(...)
-end
-
-return setmetatable(widgetprompt, widgetprompt.mt)
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/widget/taglist.lua b/awesome/lib/awful/widget/taglist.lua
deleted file mode 100644
index d8cf475..0000000
--- a/awesome/lib/awful/widget/taglist.lua
+++ /dev/null
@@ -1,452 +0,0 @@
----------------------------------------------------------------------------
---- Taglist widget module for awful
---
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2008-2009 Julien Danjou
--- @classmod awful.widget.taglist
----------------------------------------------------------------------------
-
--- Grab environment we need
-local capi = { screen = screen,
- awesome = awesome,
- client = client }
-local setmetatable = setmetatable
-local pairs = pairs
-local ipairs = ipairs
-local table = table
-local common = require("awful.widget.common")
-local util = require("awful.util")
-local tag = require("awful.tag")
-local beautiful = require("beautiful")
-local fixed = require("wibox.layout.fixed")
-local surface = require("gears.surface")
-local timer = require("gears.timer")
-
-local function get_screen(s)
- return s and capi.screen[s]
-end
-
-local taglist = { mt = {} }
-taglist.filter = {}
-
---- The tag list main foreground (text) color.
--- @beautiful beautiful.taglist_fg_focus
--- @param[opt=fg_focus] color
--- @see gears.color
-
---- The tag list main background color.
--- @beautiful beautiful.taglist_bg_focus
--- @param[opt=bg_focus] color
--- @see gears.color
-
---- The tag list urgent elements foreground (text) color.
--- @beautiful beautiful.taglist_fg_urgent
--- @param[opt=fg_urgent] color
--- @see gears.color
-
---- The tag list urgent elements background color.
--- @beautiful beautiful.taglist_bg_urgent
--- @param[opt=bg_urgent] color
--- @see gears.color
-
---- The tag list occupied elements background color.
--- @beautiful beautiful.taglist_bg_occupied
--- @param color
--- @see gears.color
-
---- The tag list occupied elements foreground (text) color.
--- @beautiful beautiful.taglist_fg_occupied
--- @param color
--- @see gears.color
-
---- The tag list empty elements background color.
--- @beautiful beautiful.taglist_bg_empty
--- @param color
--- @see gears.color
-
---- The tag list empty elements foreground (text) color.
--- @beautiful beautiful.taglist_fg_empty
--- @param color
--- @see gears.color
-
---- The selected elements background image.
--- @beautiful beautiful.taglist_squares_sel
--- @param surface
--- @see gears.surface
-
---- The unselected elements background image.
--- @beautiful beautiful.taglist_squares_unsel
--- @param surface
--- @see gears.surface
-
---- The selected empty elements background image.
--- @beautiful beautiful.taglist_squares_sel_empty
--- @param surface
--- @see gears.surface
-
---- The unselected empty elements background image.
--- @beautiful beautiful.taglist_squares_unsel_empty
--- @param surface
--- @see gears.surface
-
---- If the background images can be resized.
--- @beautiful beautiful.taglist_squares_resize
--- @param boolean
-
---- Do not display the tag icons, even if they are set.
--- @beautiful beautiful.taglist_disable_icon
--- @param boolean
-
---- The taglist font.
--- @beautiful beautiful.taglist_font
--- @param string
-
---- The main shape used for the elements.
--- This will be the fallback for state specific shapes.
--- To get a shape for the whole taglist, use `wibox.container.background`.
--- @beautiful beautiful.taglist_shape
--- @param[opt=rectangle] gears.shape
--- @see gears.shape
--- @see beautiful.taglist_shape_empty
--- @see beautiful.taglist_shape_focus
--- @see beautiful.taglist_shape_urgent
-
---- The shape elements border width.
--- @beautiful beautiful.taglist_shape_border_width
--- @param[opt=0] number
--- @see wibox.container.background
-
---- The elements shape border color.
--- @beautiful beautiful.taglist_shape_border_color
--- @param color
--- @see gears.color
-
---- The shape used for the empty elements.
--- @beautiful beautiful.taglist_shape_empty
--- @param[opt=rectangle] gears.shape
--- @see gears.shape
-
---- The shape used for the empty elements border width.
--- @beautiful beautiful.taglist_shape_border_width_empty
--- @param[opt=0] number
--- @see wibox.container.background
-
---- The empty elements shape border color.
--- @beautiful beautiful.taglist_shape_border_color_empty
--- @param color
--- @see gears.color
-
---- The shape used for the selected elements.
--- @beautiful beautiful.taglist_shape_focus
--- @param[opt=rectangle] gears.shape
--- @see gears.shape
-
---- The shape used for the selected elements border width.
--- @beautiful beautiful.taglist_shape_border_width_focus
--- @param[opt=0] number
--- @see wibox.container.background
-
---- The selected elements shape border color.
--- @beautiful beautiful.taglist_shape_border_color_focus
--- @param color
--- @see gears.color
-
---- The shape used for the urgent elements.
--- @beautiful beautiful.taglist_shape_urgent
--- @param[opt=rectangle] gears.shape
--- @see gears.shape
-
---- The shape used for the urgent elements border width.
--- @beautiful beautiful.taglist_shape_border_width_urgent
--- @param[opt=0] number
--- @see wibox.container.background
-
---- The urgents elements shape border color.
--- @beautiful beautiful.taglist_shape_border_color_urgent
--- @param color
--- @see gears.color
-
-local instances = nil
-
-function taglist.taglist_label(t, args)
- if not args then args = {} end
- local theme = beautiful.get()
- local fg_focus = args.fg_focus or theme.taglist_fg_focus or theme.fg_focus
- local bg_focus = args.bg_focus or theme.taglist_bg_focus or theme.bg_focus
- local fg_urgent = args.fg_urgent or theme.taglist_fg_urgent or theme.fg_urgent
- local bg_urgent = args.bg_urgent or theme.taglist_bg_urgent or theme.bg_urgent
- local bg_occupied = args.bg_occupied or theme.taglist_bg_occupied
- local fg_occupied = args.fg_occupied or theme.taglist_fg_occupied
- local bg_empty = args.bg_empty or theme.taglist_bg_empty
- local fg_empty = args.fg_empty or theme.taglist_fg_empty
- local taglist_squares_sel = args.squares_sel or theme.taglist_squares_sel
- local taglist_squares_unsel = args.squares_unsel or theme.taglist_squares_unsel
- local taglist_squares_sel_empty = args.squares_sel_empty or theme.taglist_squares_sel_empty
- local taglist_squares_unsel_empty = args.squares_unsel_empty or theme.taglist_squares_unsel_empty
- local taglist_squares_resize = theme.taglist_squares_resize or args.squares_resize or "true"
- local taglist_disable_icon = args.taglist_disable_icon or theme.taglist_disable_icon or false
- local font = args.font or theme.taglist_font or theme.font or ""
- local text = nil
- local sel = capi.client.focus
- local bg_color = nil
- local fg_color = nil
- local bg_image
- local icon
- local shape = args.shape or theme.taglist_shape
- local shape_border_width = args.shape_border_width or theme.taglist_shape_border_width
- local shape_border_color = args.shape_border_color or theme.taglist_shape_border_color
- -- TODO: Re-implement bg_resize
- local bg_resize = false -- luacheck: ignore
- local is_selected = false
- local cls = t:clients()
-
- if sel and taglist_squares_sel then
- -- Check that the selected client is tagged with 't'.
- local seltags = sel:tags()
- for _, v in ipairs(seltags) do
- if v == t then
- bg_image = taglist_squares_sel
- bg_resize = taglist_squares_resize == "true"
- is_selected = true
- break
- end
- end
- end
- if #cls == 0 and t.selected and taglist_squares_sel_empty then
- bg_image = taglist_squares_sel_empty
- bg_resize = taglist_squares_resize == "true"
- elseif not is_selected then
- if #cls > 0 then
- if taglist_squares_unsel then
- bg_image = taglist_squares_unsel
- bg_resize = taglist_squares_resize == "true"
- end
- if bg_occupied then bg_color = bg_occupied end
- if fg_occupied then fg_color = fg_occupied end
- else
- if taglist_squares_unsel_empty then
- bg_image = taglist_squares_unsel_empty
- bg_resize = taglist_squares_resize == "true"
- end
- if bg_empty then bg_color = bg_empty end
- if fg_empty then fg_color = fg_empty end
-
- if args.shape_empty or theme.taglist_shape_empty then
- shape = args.shape_empty or theme.taglist_shape_empty
- end
-
- if args.shape_border_width_empty or theme.taglist_shape_border_width_empty then
- shape_border_width = args.shape_border_width_empty or theme.taglist_shape_border_width_empty
- end
-
- if args.shape_border_color_empty or theme.taglist_shape_border_color_empty then
- shape_border_color = args.shape_border_color_empty or theme.taglist_shape_border_color_empty
- end
- end
- end
- if t.selected then
- bg_color = bg_focus
- fg_color = fg_focus
-
- if args.shape_focus or theme.taglist_shape_focus then
- shape = args.shape_focus or theme.taglist_shape_focus
- end
-
- if args.shape_border_width_focus or theme.taglist_shape_border_width_focus then
- shape = args.shape_border_width_focus or theme.taglist_shape_border_width_focus
- end
-
- if args.shape_border_color_focus or theme.taglist_shape_border_color_focus then
- shape = args.shape_border_color_focus or theme.taglist_shape_border_color_focus
- end
-
- elseif tag.getproperty(t, "urgent") then
- if bg_urgent then bg_color = bg_urgent end
- if fg_urgent then fg_color = fg_urgent end
-
- if args.shape_urgent or theme.taglist_shape_urgent then
- shape = args.shape_urgent or theme.taglist_shape_urgent
- end
-
- if args.shape_border_width_urgent or theme.taglist_shape_border_width_urgent then
- shape_border_width = args.shape_border_width_urgent or theme.taglist_shape_border_width_urgent
- end
-
- if args.shape_border_color_urgent or theme.taglist_shape_border_color_urgent then
- shape_border_color = args.shape_border_color_urgent or theme.taglist_shape_border_color_urgent
- end
- end
-
- if not tag.getproperty(t, "icon_only") then
- text = "<span font_desc='"..font.."'>"
- if fg_color then
- text = text .. "<span color='" .. util.ensure_pango_color(fg_color) ..
- "'>" .. (util.escape(t.name) or "") .. "</span>"
- else
- text = text .. (util.escape(t.name) or "")
- end
- text = text .. "</span>"
- end
- if not taglist_disable_icon then
- if t.icon then
- icon = surface.load(t.icon)
- end
- end
-
- local other_args = {
- shape = shape,
- shape_border_width = shape_border_width,
- shape_border_color = shape_border_color,
- }
-
- return text, bg_color, bg_image, not taglist_disable_icon and icon or nil, other_args
-end
-
-local function taglist_update(s, w, buttons, filter, data, style, update_function)
- local tags = {}
- for _, t in ipairs(s.tags) do
- if not tag.getproperty(t, "hide") and filter(t) then
- table.insert(tags, t)
- end
- end
-
- local function label(c) return taglist.taglist_label(c, style) end
-
- update_function(w, buttons, label, data, tags)
-end
-
---- Create a new taglist widget. The last two arguments (update_function
--- and base_widget) serve to customize the layout of the taglist (eg. to
--- make it vertical). For that, you will need to copy the
--- awful.widget.common.list_update function, make your changes to it
--- and pass it as update_function here. Also change the base_widget if the
--- default is not what you want.
--- @param screen The screen to draw taglist for.
--- @param filter Filter function to define what clients will be listed.
--- @param buttons A table with buttons binding to set.
--- @tparam[opt={}] table style The style overrides default theme.
--- @tparam[opt=nil] string|pattern style.fg_focus
--- @tparam[opt=nil] string|pattern style.bg_focus
--- @tparam[opt=nil] string|pattern style.fg_urgent
--- @tparam[opt=nil] string|pattern style.bg_urgent
--- @tparam[opt=nil] string|pattern style.bg_occupied
--- @tparam[opt=nil] string|pattern style.fg_occupied
--- @tparam[opt=nil] string|pattern style.bg_empty
--- @tparam[opt=nil] string|pattern style.fg_empty
--- @tparam[opt=nil] string style.taglist_squares_sel
--- @tparam[opt=nil] string style.taglist_squares_unsel
--- @tparam[opt=nil] string style.taglist_squares_sel_empty
--- @tparam[opt=nil] string style.taglist_squares_unsel_empty
--- @tparam[opt=nil] string style.taglist_squares_resize
--- @tparam[opt=nil] string style.taglist_disable_icon
--- @tparam[opt=nil] string style.font
--- @tparam[opt=nil] number style.spacing The spacing between tags.
--- @param[opt] update_function Function to create a tag widget on each
--- update. See `awful.widget.common`.
--- @param[opt] base_widget Optional container widget for tag widgets. Default
--- is wibox.layout.fixed.horizontal().
--- @param base_widget.bg_focus The background color for focused client.
--- @param base_widget.fg_focus The foreground color for focused client.
--- @param base_widget.bg_urgent The background color for urgent clients.
--- @param base_widget.fg_urgent The foreground color for urgent clients.
--- @param[opt] base_widget.squares_sel A user provided image for selected squares.
--- @param[opt] base_widget.squares_unsel A user provided image for unselected squares.
--- @param[opt] base_widget.squares_sel_empty A user provided image for selected squares for empty tags.
--- @param[opt] base_widget.squares_unsel_empty A user provided image for unselected squares for empty tags.
--- @param[opt] base_widget.squares_resize True or false to resize squares.
--- @param base_widget.font The font.
--- @function awful.taglist
-function taglist.new(screen, filter, buttons, style, update_function, base_widget)
- screen = get_screen(screen)
- local uf = update_function or common.list_update
- local w = base_widget or fixed.horizontal()
-
- if w.set_spacing and (style and style.spacing or beautiful.taglist_spacing) then
- w:set_spacing(style and style.spacing or beautiful.taglist_spacing)
- end
-
- local data = setmetatable({}, { __mode = 'k' })
-
- local queued_update = {}
- function w._do_taglist_update()
- -- Add a delayed callback for the first update.
- if not queued_update[screen] then
- timer.delayed_call(function()
- if screen.valid then
- taglist_update(screen, w, buttons, filter, data, style, uf)
- end
- queued_update[screen] = false
- end)
- queued_update[screen] = true
- end
- end
- if instances == nil then
- instances = setmetatable({}, { __mode = "k" })
- local function u(s)
- local i = instances[get_screen(s)]
- if i then
- for _, tlist in pairs(i) do
- tlist._do_taglist_update()
- end
- end
- end
- local uc = function (c) return u(c.screen) end
- local ut = function (t) return u(t.screen) end
- capi.client.connect_signal("focus", uc)
- capi.client.connect_signal("unfocus", uc)
- tag.attached_connect_signal(nil, "property::selected", ut)
- tag.attached_connect_signal(nil, "property::icon", ut)
- tag.attached_connect_signal(nil, "property::hide", ut)
- tag.attached_connect_signal(nil, "property::name", ut)
- tag.attached_connect_signal(nil, "property::activated", ut)
- tag.attached_connect_signal(nil, "property::screen", ut)
- tag.attached_connect_signal(nil, "property::index", ut)
- tag.attached_connect_signal(nil, "property::urgent", ut)
- capi.client.connect_signal("property::screen", function(c, old_screen)
- u(c.screen)
- u(old_screen)
- end)
- capi.client.connect_signal("tagged", uc)
- capi.client.connect_signal("untagged", uc)
- capi.client.connect_signal("unmanage", uc)
- capi.screen.connect_signal("removed", function(s)
- instances[get_screen(s)] = nil
- end)
- end
- w._do_taglist_update()
- local list = instances[screen]
- if not list then
- list = setmetatable({}, { __mode = "v" })
- instances[screen] = list
- end
- table.insert(list, w)
- return w
-end
-
---- Filtering function to include all nonempty tags on the screen.
--- @param t The tag.
--- @return true if t is not empty, else false
-function taglist.filter.noempty(t)
- return #t:clients() > 0 or t.selected
-end
-
---- Filtering function to include selected tags on the screen.
--- @param t The tag.
--- @return true if t is not empty, else false
-function taglist.filter.selected(t)
- return t.selected
-end
-
---- Filtering function to include all tags on the screen.
--- @return true
-function taglist.filter.all()
- return true
-end
-
-function taglist.mt:__call(...)
- return taglist.new(...)
-end
-
-return setmetatable(taglist, taglist.mt)
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/widget/tasklist.lua b/awesome/lib/awful/widget/tasklist.lua
deleted file mode 100644
index d5580c1..0000000
--- a/awesome/lib/awful/widget/tasklist.lua
+++ /dev/null
@@ -1,573 +0,0 @@
----------------------------------------------------------------------------
---- Tasklist widget module for awful.
---
--- <a name="status_icons"></a>
--- **Status icons:**
---
--- By default, the tasklist prepends some symbols in front of the client name.
--- This is used to notify that the client has some specific properties that are
--- currently enabled. This can be disabled using
--- `beautiful.tasklist_plain_task_name`=true in the theme.
---
--- <table class='widget_list' border=1>
--- <tr style='font-weight: bold;'>
--- <th align='center'>Icon</th>
--- <th align='center'>Client property</th>
--- </tr>
--- <tr><td>▪</td><td><a href="./client.html#client.sticky">sticky</a></td></tr>
--- <tr><td>⌃</td><td><a href="./client.html#client.ontop">ontop</a></td></tr>
--- <tr><td>▴</td><td><a href="./client.html#client.above">above</a></td></tr>
--- <tr><td>▾</td><td><a href="./client.html#client.below">below</a></td></tr>
--- <tr><td>✈</td><td><a href="./client.html#client.floating">floating</a></td></tr>
--- <tr><td>+</td><td><a href="./client.html#client.maximized">maximized</a></td></tr>
--- <tr><td>⬌</td><td><a href="./client.html#client.maximized_horizontal">maximized_horizontal</a></td></tr>
--- <tr><td>⬍</td><td><a href="./client.html#client.maximized_vertical">maximized_vertical</a></td></tr>
--- </table>
---
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2008-2009 Julien Danjou
--- @classmod awful.widget.tasklist
----------------------------------------------------------------------------
-
--- Grab environment we need
-local capi = { screen = screen,
- client = client }
-local ipairs = ipairs
-local setmetatable = setmetatable
-local table = table
-local common = require("awful.widget.common")
-local beautiful = require("beautiful")
-local util = require("awful.util")
-local tag = require("awful.tag")
-local flex = require("wibox.layout.flex")
-local timer = require("gears.timer")
-
-local function get_screen(s)
- return s and screen[s]
-end
-
-local tasklist = { mt = {} }
-
-local instances
-
---- The default foreground (text) color.
--- @beautiful beautiful.tasklist_fg_normal
--- @tparam[opt=nil] string|pattern fg_normal
--- @see gears.color
-
---- The default background color.
--- @beautiful beautiful.tasklist_bg_normal
--- @tparam[opt=nil] string|pattern bg_normal
--- @see gears.color
-
---- The focused client foreground (text) color.
--- @beautiful beautiful.tasklist_fg_focus
--- @tparam[opt=nil] string|pattern fg_focus
--- @see gears.color
-
---- The focused client background color.
--- @beautiful beautiful.tasklist_bg_focus
--- @tparam[opt=nil] string|pattern bg_focus
--- @see gears.color
-
---- The urgent clients foreground (text) color.
--- @beautiful beautiful.tasklist_fg_urgent
--- @tparam[opt=nil] string|pattern fg_urgent
--- @see gears.color
-
---- The urgent clients background color.
--- @beautiful beautiful.tasklist_bg_urgent
--- @tparam[opt=nil] string|pattern bg_urgent
--- @see gears.color
-
---- The minimized clients foreground (text) color.
--- @beautiful beautiful.tasklist_fg_minimize
--- @tparam[opt=nil] string|pattern fg_minimize
--- @see gears.color
-
---- The minimized clients background color.
--- @beautiful beautiful.tasklist_bg_minimize
--- @tparam[opt=nil] string|pattern bg_minimize
--- @see gears.color
-
---- The elements default background image.
--- @beautiful beautiful.tasklist_bg_image_normal
--- @tparam[opt=nil] string bg_image_normal
-
---- The focused client background image.
--- @beautiful beautiful.tasklist_bg_image_focus
--- @tparam[opt=nil] string bg_image_focus
-
---- The urgent clients background image.
--- @beautiful beautiful.tasklist_bg_image_urgent
--- @tparam[opt=nil] string bg_image_urgent
-
---- The minimized clients background image.
--- @beautiful beautiful.tasklist_bg_image_minimize
--- @tparam[opt=nil] string bg_image_minimize
-
---- Disable the tasklist client icons.
--- @beautiful beautiful.tasklist_tasklist_disable_icon
--- @tparam[opt=false] boolean tasklist_disable_icon
-
---- Disable the extra tasklist client property notification icons.
---
--- See the <a href="status_icons">Status icons</a> section for more details.
---
--- @beautiful beautiful.tasklist_plain_task_name
--- @tparam[opt=false] boolean tasklist_plain_task_name
-
---- The tasklist font.
--- @beautiful beautiful.tasklist_font
--- @tparam[opt=nil] string font
-
---- The focused client alignment.
--- @beautiful beautiful.tasklist_align
--- @tparam[opt=left] string align *left*, *right* or *center*
-
---- The focused client title alignment.
--- @beautiful beautiful.tasklist_font_focus
--- @tparam[opt=nil] string font_focus
-
---- The minimized clients font.
--- @beautiful beautiful.tasklist_font_minimized
--- @tparam[opt=nil] string font_minimized
-
---- The urgent clients font.
--- @beautiful beautiful.tasklist_font_urgent
--- @tparam[opt=nil] string font_urgent
-
---- The space between the tasklist elements.
--- @beautiful beautiful.tasklist_spacing
--- @tparam[opt=0] number spacing The spacing between tags.
-
---- The default tasklist elements shape.
--- @beautiful beautiful.tasklist_shape
--- @tparam[opt=nil] gears.shape shape
-
---- The default tasklist elements border width.
--- @beautiful beautiful.tasklist_shape_border_width
--- @tparam[opt=0] number shape_border_width
-
---- The default tasklist elements border color.
--- @beautiful beautiful.tasklist_shape_border_color
--- @tparam[opt=nil] string|color shape_border_color
--- @see gears.color
-
---- The focused client shape.
--- @beautiful beautiful.tasklist_shape_focus
--- @tparam[opt=nil] gears.shape shape_focus
-
---- The focused client border width.
--- @beautiful beautiful.tasklist_shape_border_width_focus
--- @tparam[opt=0] number shape_border_width_focus
-
---- The focused client border color.
--- @beautiful beautiful.tasklist_shape_border_color_focus
--- @tparam[opt=nil] string|color shape_border_color_focus
--- @see gears.color
-
---- The minimized clients shape.
--- @beautiful beautiful.tasklist_shape_minimized
--- @tparam[opt=nil] gears.shape shape_minimized
-
---- The minimized clients border width.
--- @beautiful beautiful.tasklist_shape_border_width_minimized
--- @tparam[opt=0] number shape_border_width_minimized
-
---- The minimized clients border color.
--- @beautiful beautiful.tasklist_shape_border_color_minimized
--- @tparam[opt=nil] string|color shape_border_color_minimized
--- @see gears.color
-
---- The urgent clients shape.
--- @beautiful beautiful.tasklist_shape_urgent
--- @tparam[opt=nil] gears.shape shape_urgent
-
---- The urgent clients border width.
--- @beautiful beautiful.tasklist_shape_border_width_urgent
--- @tparam[opt=0] number shape_border_width_urgent
-
---- The urgent clients border color.
--- @beautiful beautiful.tasklist_shape_border_color_urgent
--- @tparam[opt=nil] string|color shape_border_color_urgent
--- @see gears.color
-
--- Public structures
-tasklist.filter = {}
-
-local function tasklist_label(c, args, tb)
- if not args then args = {} end
- local theme = beautiful.get()
- local align = args.align or theme.tasklist_align or "left"
- local fg_normal = util.ensure_pango_color(args.fg_normal or theme.tasklist_fg_normal or theme.fg_normal, "white")
- local bg_normal = args.bg_normal or theme.tasklist_bg_normal or theme.bg_normal or "#000000"
- local fg_focus = util.ensure_pango_color(args.fg_focus or theme.tasklist_fg_focus or theme.fg_focus, fg_normal)
- local bg_focus = args.bg_focus or theme.tasklist_bg_focus or theme.bg_focus or bg_normal
- local fg_urgent = util.ensure_pango_color(args.fg_urgent or theme.tasklist_fg_urgent or theme.fg_urgent, fg_normal)
- local bg_urgent = args.bg_urgent or theme.tasklist_bg_urgent or theme.bg_urgent or bg_normal
- local fg_minimize = util.ensure_pango_color(args.fg_minimize or theme.tasklist_fg_minimize or theme.fg_minimize, fg_normal)
- local bg_minimize = args.bg_minimize or theme.tasklist_bg_minimize or theme.bg_minimize or bg_normal
- local bg_image_normal = args.bg_image_normal or theme.bg_image_normal
- local bg_image_focus = args.bg_image_focus or theme.bg_image_focus
- local bg_image_urgent = args.bg_image_urgent or theme.bg_image_urgent
- local bg_image_minimize = args.bg_image_minimize or theme.bg_image_minimize
- local tasklist_disable_icon = args.tasklist_disable_icon or theme.tasklist_disable_icon or false
- local font = args.font or theme.tasklist_font or theme.font or ""
- local font_focus = args.font_focus or theme.tasklist_font_focus or theme.font_focus or font or ""
- local font_minimized = args.font_minimized or theme.tasklist_font_minimized or theme.font_minimized or font or ""
- local font_urgent = args.font_urgent or theme.tasklist_font_urgent or theme.font_urgent or font or ""
- local text = ""
- local name = ""
- local bg
- local bg_image
- local shape = args.shape or theme.tasklist_shape
- local shape_border_width = args.shape_border_width or theme.tasklist_shape_border_width
- local shape_border_color = args.shape_border_color or theme.tasklist_shape_border_color
-
- -- symbol to use to indicate certain client properties
- local sticky = args.sticky or theme.tasklist_sticky or "▪"
- local ontop = args.ontop or theme.tasklist_ontop or '⌃'
- local above = args.above or theme.tasklist_above or '▴'
- local below = args.below or theme.tasklist_below or '▾'
- local floating = args.floating or theme.tasklist_floating or '✈'
- local maximized = args.maximized or theme.tasklist_maximized or '<b>+</b>'
- local maximized_horizontal = args.maximized_horizontal or theme.tasklist_maximized_horizontal or '⬌'
- local maximized_vertical = args.maximized_vertical or theme.tasklist_maximized_vertical or '⬍'
-
- tb:set_align(align)
-
- if not theme.tasklist_plain_task_name then
- if c.sticky then name = name .. sticky end
-
- if c.ontop then name = name .. ontop
- elseif c.above then name = name .. above
- elseif c.below then name = name .. below end
-
- if c.maximized then
- name = name .. maximized
- else
- if c.maximized_horizontal then name = name .. maximized_horizontal end
- if c.maximized_vertical then name = name .. maximized_vertical end
- if c.floating then name = name .. floating end
- end
- end
-
- if c.minimized then
- name = name .. (util.escape(c.icon_name) or util.escape(c.name) or util.escape("<untitled>"))
- else
- name = name .. (util.escape(c.name) or util.escape("<untitled>"))
- end
-
- local focused = capi.client.focus == c
- -- Handle transient_for: the first parent that does not skip the taskbar
- -- is considered to be focused, if the real client has skip_taskbar.
- if not focused and capi.client.focus and capi.client.focus.skip_taskbar
- and capi.client.focus:get_transient_for_matching(function(cl)
- return not cl.skip_taskbar
- end) == c then
- focused = true
- end
-
- if focused then
- bg = bg_focus
- text = text .. "<span color='"..fg_focus.."'>"..name.."</span>"
- bg_image = bg_image_focus
- font = font_focus
-
- if args.shape_focus or theme.tasklist_shape_focus then
- shape = args.shape_focus or theme.tasklist_shape_focus
- end
-
- if args.shape_border_width_focus or theme.tasklist_shape_border_width_focus then
- shape_border_width = args.shape_border_width_focus or theme.tasklist_shape_border_width_focus
- end
-
- if args.shape_border_color_focus or theme.tasklist_shape_border_color_focus then
- shape_border_color = args.shape_border_color_focus or theme.tasklist_shape_border_color_focus
- end
- elseif c.urgent then
- bg = bg_urgent
- text = text .. "<span color='"..fg_urgent.."'>"..name.."</span>"
- bg_image = bg_image_urgent
- font = font_urgent
-
- if args.shape_urgent or theme.tasklist_shape_urgent then
- shape = args.shape_urgent or theme.tasklist_shape_urgent
- end
-
- if args.shape_border_width_urgent or theme.tasklist_shape_border_width_urgent then
- shape_border_width = args.shape_border_width_urgent or theme.tasklist_shape_border_width_urgent
- end
-
- if args.shape_border_color_urgent or theme.tasklist_shape_border_color_urgent then
- shape_border_color = args.shape_border_color_urgent or theme.tasklist_shape_border_color_urgent
- end
- elseif c.minimized then
- bg = bg_minimize
- text = text .. "<span color='"..fg_minimize.."'>"..name.."</span>"
- bg_image = bg_image_minimize
- font = font_minimized
-
- if args.shape_minimized or theme.tasklist_shape_minimized then
- shape = args.shape_minimized or theme.tasklist_shape_minimized
- end
-
- if args.shape_border_width_minimized or theme.tasklist_shape_border_width_minimized then
- shape_border_width = args.shape_border_width_minimized or theme.tasklist_shape_border_width_minimized
- end
-
- if args.shape_border_color_minimized or theme.tasklist_shape_border_color_minimized then
- shape_border_color = args.shape_border_color_minimized or theme.tasklist_shape_border_color_minimized
- end
- else
- bg = bg_normal
- text = text .. "<span color='"..fg_normal.."'>"..name.."</span>"
- bg_image = bg_image_normal
- end
- tb:set_font(font)
-
- local other_args = {
- shape = shape,
- shape_border_width = shape_border_width,
- shape_border_color = shape_border_color,
- }
-
- return text, bg, bg_image, not tasklist_disable_icon and c.icon or nil, other_args
-end
-
-local function tasklist_update(s, w, buttons, filter, data, style, update_function)
- local clients = {}
- for _, c in ipairs(capi.client.get()) do
- if not (c.skip_taskbar or c.hidden
- or c.type == "splash" or c.type == "dock" or c.type == "desktop")
- and filter(c, s) then
- table.insert(clients, c)
- end
- end
-
- local function label(c, tb) return tasklist_label(c, style, tb) end
-
- update_function(w, buttons, label, data, clients)
-end
-
---- Create a new tasklist widget. The last two arguments (update_function
--- and base_widget) serve to customize the layout of the tasklist (eg. to
--- make it vertical). For that, you will need to copy the
--- awful.widget.common.list_update function, make your changes to it
--- and pass it as update_function here. Also change the base_widget if the
--- default is not what you want.
--- @param screen The screen to draw tasklist for.
--- @param filter Filter function to define what clients will be listed.
--- @param buttons A table with buttons binding to set.
--- @tparam[opt={}] table style The style overrides default theme.
--- @tparam[opt=nil] string|pattern style.fg_normal
--- @tparam[opt=nil] string|pattern style.bg_normal
--- @tparam[opt=nil] string|pattern style.fg_focus
--- @tparam[opt=nil] string|pattern style.bg_focus
--- @tparam[opt=nil] string|pattern style.fg_urgent
--- @tparam[opt=nil] string|pattern style.bg_urgent
--- @tparam[opt=nil] string|pattern style.fg_minimize
--- @tparam[opt=nil] string|pattern style.bg_minimize
--- @tparam[opt=nil] string style.bg_image_normal
--- @tparam[opt=nil] string style.bg_image_focus
--- @tparam[opt=nil] string style.bg_image_urgent
--- @tparam[opt=nil] string style.bg_image_minimize
--- @tparam[opt=nil] boolean style.tasklist_disable_icon
--- @tparam[opt=nil] string style.font
--- @tparam[opt=left] string style.align *left*, *right* or *center*
--- @tparam[opt=nil] string style.font_focus
--- @tparam[opt=nil] string style.font_minimized
--- @tparam[opt=nil] string style.font_urgent
--- @tparam[opt=nil] number style.spacing The spacing between tags.
--- @tparam[opt=nil] gears.shape style.shape
--- @tparam[opt=nil] number style.shape_border_width
--- @tparam[opt=nil] string|color style.shape_border_color
--- @tparam[opt=nil] gears.shape style.shape_focus
--- @tparam[opt=nil] number style.shape_border_width_focus
--- @tparam[opt=nil] string|color style.shape_border_color_focus
--- @tparam[opt=nil] gears.shape style.shape_minimized
--- @tparam[opt=nil] number style.shape_border_width_minimized
--- @tparam[opt=nil] string|color style.shape_border_color_minimized
--- @tparam[opt=nil] gears.shape style.shape_urgent
--- @tparam[opt=nil] number style.shape_border_width_urgent
--- @tparam[opt=nil] string|color style.shape_border_color_urgent
--- @param[opt] update_function Function to create a tag widget on each
--- update. See `awful.widget.common.list_update`.
--- @tparam[opt] table base_widget Container widget for tag widgets. Default
--- is `wibox.layout.flex.horizontal`.
--- @function awful.tasklist
-function tasklist.new(screen, filter, buttons, style, update_function, base_widget)
- screen = get_screen(screen)
- local uf = update_function or common.list_update
- local w = base_widget or flex.horizontal()
-
- local data = setmetatable({}, { __mode = 'k' })
-
- if w.set_spacing and (style and style.spacing or beautiful.taglist_spacing) then
- w:set_spacing(style and style.spacing or beautiful.taglist_spacing)
- end
-
- local queued_update = false
- function w._do_tasklist_update()
- -- Add a delayed callback for the first update.
- if not queued_update then
- timer.delayed_call(function()
- queued_update = false
- if screen.valid then
- tasklist_update(screen, w, buttons, filter, data, style, uf)
- end
- end)
- queued_update = true
- end
- end
- function w._unmanage(c)
- data[c] = nil
- end
- if instances == nil then
- instances = setmetatable({}, { __mode = "k" })
- local function us(s)
- local i = instances[get_screen(s)]
- if i then
- for _, tlist in pairs(i) do
- tlist._do_tasklist_update()
- end
- end
- end
- local function u()
- for s in pairs(instances) do
- if s.valid then
- us(s)
- end
- end
- end
-
- tag.attached_connect_signal(nil, "property::selected", u)
- tag.attached_connect_signal(nil, "property::activated", u)
- capi.client.connect_signal("property::urgent", u)
- capi.client.connect_signal("property::sticky", u)
- capi.client.connect_signal("property::ontop", u)
- capi.client.connect_signal("property::above", u)
- capi.client.connect_signal("property::below", u)
- capi.client.connect_signal("property::floating", u)
- capi.client.connect_signal("property::maximized_horizontal", u)
- capi.client.connect_signal("property::maximized_vertical", u)
- capi.client.connect_signal("property::minimized", u)
- capi.client.connect_signal("property::name", u)
- capi.client.connect_signal("property::icon_name", u)
- capi.client.connect_signal("property::icon", u)
- capi.client.connect_signal("property::skip_taskbar", u)
- capi.client.connect_signal("property::screen", function(c, old_screen)
- us(c.screen)
- us(old_screen)
- end)
- capi.client.connect_signal("property::hidden", u)
- capi.client.connect_signal("tagged", u)
- capi.client.connect_signal("untagged", u)
- capi.client.connect_signal("unmanage", function(c)
- u(c)
- for _, i in pairs(instances) do
- for _, tlist in pairs(i) do
- tlist._unmanage(c)
- end
- end
- end)
- capi.client.connect_signal("list", u)
- capi.client.connect_signal("focus", u)
- capi.client.connect_signal("unfocus", u)
- capi.screen.connect_signal("removed", function(s)
- instances[get_screen(s)] = nil
- end)
- end
- w._do_tasklist_update()
- local list = instances[screen]
- if not list then
- list = setmetatable({}, { __mode = "v" })
- instances[screen] = list
- end
- table.insert(list, w)
- return w
-end
-
---- Filtering function to include all clients.
--- @return true
-function tasklist.filter.allscreen()
- return true
-end
-
---- Filtering function to include the clients from all tags on the screen.
--- @param c The client.
--- @param screen The screen we are drawing on.
--- @return true if c is on screen, false otherwise
-function tasklist.filter.alltags(c, screen)
- -- Only print client on the same screen as this widget
- return get_screen(c.screen) == get_screen(screen)
-end
-
---- Filtering function to include only the clients from currently selected tags.
--- @param c The client.
--- @param screen The screen we are drawing on.
--- @return true if c is in a selected tag on screen, false otherwise
-function tasklist.filter.currenttags(c, screen)
- screen = get_screen(screen)
- -- Only print client on the same screen as this widget
- if get_screen(c.screen) ~= screen then return false end
- -- Include sticky client too
- if c.sticky then return true end
- local tags = screen.tags
- for _, t in ipairs(tags) do
- if t.selected then
- local ctags = c:tags()
- for _, v in ipairs(ctags) do
- if v == t then
- return true
- end
- end
- end
- end
- return false
-end
-
---- Filtering function to include only the minimized clients from currently selected tags.
--- @param c The client.
--- @param screen The screen we are drawing on.
--- @return true if c is in a selected tag on screen and is minimized, false otherwise
-function tasklist.filter.minimizedcurrenttags(c, screen)
- screen = get_screen(screen)
- -- Only print client on the same screen as this widget
- if get_screen(c.screen) ~= screen then return false end
- -- Check client is minimized
- if not c.minimized then return false end
- -- Include sticky client
- if c.sticky then return true end
- local tags = screen.tags
- for _, t in ipairs(tags) do
- -- Select only minimized clients
- if t.selected then
- local ctags = c:tags()
- for _, v in ipairs(ctags) do
- if v == t then
- return true
- end
- end
- end
- end
- return false
-end
-
---- Filtering function to include only the currently focused client.
--- @param c The client.
--- @param screen The screen we are drawing on.
--- @return true if c is focused on screen, false otherwise
-function tasklist.filter.focused(c, screen)
- -- Only print client on the same screen as this widget
- return get_screen(c.screen) == get_screen(screen) and capi.client.focus == c
-end
-
-function tasklist.mt:__call(...)
- return tasklist.new(...)
-end
-
-return setmetatable(tasklist, tasklist.mt)
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/widget/textclock.lua b/awesome/lib/awful/widget/textclock.lua
deleted file mode 100644
index 002aa0e..0000000
--- a/awesome/lib/awful/widget/textclock.lua
+++ /dev/null
@@ -1,16 +0,0 @@
----------------------------------------------------------------------------
--- This widget has moved to `wibox.widget.textclock`
---
--- @author Julien Danjou &lt;julien@danjou.info&gt;
--- @copyright 2008-2009 Julien Danjou
--- @classmod awful.widget.textclock
----------------------------------------------------------------------------
-local util = require("awful.util")
-
-return util.deprecate_class(
- require("wibox.widget.textclock"),
- "awful.widget.textclock",
- "wibox.widget.textclock"
-)
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/awesome/lib/awful/widget/watch.lua b/awesome/lib/awful/widget/watch.lua
deleted file mode 100644
index bc4c9af..0000000
--- a/awesome/lib/awful/widget/watch.lua
+++ /dev/null
@@ -1,91 +0,0 @@
----------------------------------------------------------------------------
---- Watch widget.
--- Here is an example of simple temperature widget which will update each 15
--- seconds implemented in two different ways.
--- The first, simpler one, will just display the return command output
--- (so output is stripped by shell commands).
--- In the other example `sensors` returns to the widget its full output
--- and it's trimmed in the widget callback function:
---
--- 211 mytextclock,
--- 212 wibox.widget.textbox(' | '),
--- 213 -- one way to do that:
--- 214 awful.widget.watch('bash -c "sensors | grep temp1"', 15),
--- 215 -- another way:
--- 216 awful.widget.watch('sensors', 15, function(widget, stdout)
--- 217 for line in stdout:gmatch("[^\r\n]+") do
--- 218 if line:match("temp1") then
--- 219 widget:set_text(line)
--- 220 return
--- 221 end
--- 222 end
--- 223 end),
--- 224 s.mylayoutbox,
---
--- ![Example screenshot](../images/awful_widget_watch.png)
---
--- @author Benjamin Petrenko
--- @author Yauheni Kirylau
--- @copyright 2015, 2016 Benjamin Petrenko, Yauheni Kirylau
--- @classmod awful.widget.watch
----------------------------------------------------------------------------
-
-local setmetatable = setmetatable
-local textbox = require("wibox.widget.textbox")
-local timer = require("gears.timer")
-local spawn = require("awful.spawn")
-
-local watch = { mt = {} }
-
---- Create a textbox that shows the output of a command
--- and updates it at a given time interval.
---
--- @tparam string|table command The command.
---
--- @tparam[opt=5] integer timeout The time interval at which the textbox
--- will be updated.
---
--- @tparam[opt] function callback The function that will be called after
--- the command output will be received. it is shown in the textbox.
--- Defaults to:
--- function(widget, stdout, stderr, exitreason, exitcode)
--- widget:set_text(stdout)
--- end
--- @param callback.widget Base widget instance.
--- @tparam string callback.stdout Output on stdout.
--- @tparam string callback.stderr Output on stderr.
--- @tparam string callback.exitreason Exit Reason.
--- The reason can be "exit" or "signal".
--- @tparam integer callback.exitcode Exit code.
--- For "exit" reason it's the exit code.
--- For "signal" reason — the signal causing process termination.
---
--- @param[opt=wibox.widget.textbox()] base_widget Base widget.
---
--- @return The widget used by this watch
-function watch.new(command, timeout, callback, base_widget)
- timeout = timeout or 5
- base_widget = base_widget or textbox()
- callback = callback or function(widget, stdout, stderr, exitreason, exitcode) -- luacheck: no unused args
- widget:set_text(stdout)
- end
- local t = timer { timeout = timeout }
- t:connect_signal("timeout", function()
- t:stop()
- spawn.easy_async(command, function(stdout, stderr, exitreason, exitcode)
- callback(base_widget, stdout, stderr, exitreason, exitcode)
- t:again()
- end)
- end)
- t:start()
- t:emit_signal("timeout")
- return base_widget
-end
-
-function watch.mt.__call(_, ...)
- return watch.new(...)
-end
-
-return setmetatable(watch, watch.mt)
-
--- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80