Auto: format source code

This commit is contained in:
github-actions[bot] 2021-08-27 18:01:22 +00:00
parent 489f2a3490
commit 3fc80c7dfd
36 changed files with 1121 additions and 712 deletions

View File

@ -8,10 +8,14 @@ local _client = {}
-- --
-- @param c A client -- @param c A client
function _client.turn_off(c, current_tag) function _client.turn_off(c, current_tag)
if current_tag == nil then current_tag = c.screen.selected_tag end if current_tag == nil then
current_tag = c.screen.selected_tag
end
local ctags = {} local ctags = {}
for k, tag in pairs(c:tags()) do for k, tag in pairs(c:tags()) do
if tag ~= current_tag then table.insert(ctags, tag) end if tag ~= current_tag then
table.insert(ctags, tag)
end
end end
c:tags(ctags) c:tags(ctags)
end end
@ -21,9 +25,11 @@ end
-- @param c A client -- @param c A client
function _client.turn_on(c) function _client.turn_on(c)
local current_tag = c.screen.selected_tag local current_tag = c.screen.selected_tag
ctags = {current_tag} ctags = { current_tag }
for k, tag in pairs(c:tags()) do for k, tag in pairs(c:tags()) do
if tag ~= current_tag then table.insert(ctags, tag) end if tag ~= current_tag then
table.insert(ctags, tag)
end
end end
c:tags(ctags) c:tags(ctags)
c:raise() c:raise()
@ -35,9 +41,15 @@ end
-- @param to_c The client to which to write all properties -- @param to_c The client to which to write all properties
-- @param from_c The client from which to read all properties -- @param from_c The client from which to read all properties
function _client.sync(to_c, from_c) function _client.sync(to_c, from_c)
if not from_c or not to_c then return end if not from_c or not to_c then
if not from_c.valid or not to_c.valid then return end return
if from_c.modal then return end end
if not from_c.valid or not to_c.valid then
return
end
if from_c.modal then
return
end
to_c.floating = from_c.floating to_c.floating = from_c.floating
to_c.maximized = from_c.maximized to_c.maximized = from_c.maximized
to_c.above = from_c.above to_c.above = from_c.above
@ -52,16 +64,21 @@ end
-- @param pid The process ID -- @param pid The process ID
-- @return True if the passed client is a childprocess of the given PID otherwise false -- @return True if the passed client is a childprocess of the given PID otherwise false
function _client.is_child_of(c, pid) function _client.is_child_of(c, pid)
-- io.popen is normally discouraged. Should probably be changed -- io.popen is normally discouraged. Should probably be changed
if not c or not c.valid then return false end if not c or not c.valid then
if tostring(c.pid) == tostring(pid) then return true end return false
local pid_cmd = [[pstree -T -p -a -s ]] .. tostring(c.pid) .. end
[[ | sed '2q;d' | grep -o '[0-9]*$' | tr -d '\n']] if tostring(c.pid) == tostring(pid) then
return true
end
local pid_cmd = [[pstree -T -p -a -s ]]
.. tostring(c.pid)
.. [[ | sed '2q;d' | grep -o '[0-9]*$' | tr -d '\n']]
local handle = io.popen(pid_cmd) local handle = io.popen(pid_cmd)
local parent_pid = handle:read("*a") local parent_pid = handle:read("*a")
handle:close() handle:close()
return tostring(parent_pid) == tostring(pid) or tostring(parent_pid) == return tostring(parent_pid) == tostring(pid)
tostring(c.pid) or tostring(parent_pid) == tostring(c.pid)
end end
--- Finds all clients that satisfy the passed rule --- Finds all clients that satisfy the passed rule
@ -69,7 +86,9 @@ end
-- @param rule The rule to be searched for -- @param rule The rule to be searched for
-- @retrun A list of clients that match the given rule -- @retrun A list of clients that match the given rule
function _client.find(rule) function _client.find(rule)
local function matcher(c) return awful.rules.match(c, rule) end local function matcher(c)
return awful.rules.match(c, rule)
end
local clients = client.get() local clients = client.get()
local findex = gears.table.hasitem(clients, client.focus) or 1 local findex = gears.table.hasitem(clients, client.focus) or 1
local start = gears.math.cycle(#clients, findex + 1) local start = gears.math.cycle(#clients, findex + 1)
@ -82,22 +101,26 @@ function _client.find(rule)
return matches return matches
end end
--- Gets the next client by direction from the focused one --- Gets the next client by direction from the focused one
-- --
-- @param direction it the direction as a string ("up", "down", "left" or "right") -- @param direction it the direction as a string ("up", "down", "left" or "right")
-- @retrun the client in the given direction starting at the currently focused one, nil otherwise -- @retrun the client in the given direction starting at the currently focused one, nil otherwise
function _client.get_by_direction(direction) function _client.get_by_direction(direction)
local sel = client.focus local sel = client.focus
if not sel then return nil end if not sel then
return nil
end
local cltbl = sel.screen:get_clients() local cltbl = sel.screen:get_clients()
local geomtbl = {} local geomtbl = {}
for i, cl in ipairs(cltbl) do for i, cl in ipairs(cltbl) do
geomtbl[i] = cl:geometry() geomtbl[i] = cl:geometry()
end end
local target = gears.geometry.rectangle.get_in_direction(direction, geomtbl, sel:geometry()) local target = gears.geometry.rectangle.get_in_direction(
direction,
geomtbl,
sel:geometry()
)
return cltbl[target] return cltbl[target]
end end
return _client return _client

View File

@ -1,23 +1,18 @@
local _color = {} local _color = {}
--- Try to guess if a color is dark or light. --- Try to guess if a color is dark or light.
-- --
-- @string color The color with hexadecimal HTML format `"#RRGGBB"`. -- @string color The color with hexadecimal HTML format `"#RRGGBB"`.
-- @treturn bool `true` if the color is dark, `false` if it is light. -- @treturn bool `true` if the color is dark, `false` if it is light.
function _color.is_dark(color) function _color.is_dark(color)
-- Try to determine if the color is dark or light -- Try to determine if the color is dark or light
local numeric_value = 0; local numeric_value = 0
for s in color:gmatch("[a-fA-F0-9][a-fA-F0-9]") do for s in color:gmatch("[a-fA-F0-9][a-fA-F0-9]") do
numeric_value = numeric_value + tonumber("0x"..s); numeric_value = numeric_value + tonumber("0x" .. s)
end end
return (numeric_value < 383) return (numeric_value < 383)
end end
--- Lighten a color. --- Lighten a color.
-- --
-- @string color The color to lighten with hexadecimal HTML format `"#RRGGBB"`. -- @string color The color to lighten with hexadecimal HTML format `"#RRGGBB"`.
@ -26,9 +21,9 @@ end
function _color.lighten(color, amount) function _color.lighten(color, amount)
amount = amount or 26 amount = amount or 26
local c = { local c = {
r = tonumber("0x"..color:sub(2,3)), r = tonumber("0x" .. color:sub(2, 3)),
g = tonumber("0x"..color:sub(4,5)), g = tonumber("0x" .. color:sub(4, 5)),
b = tonumber("0x"..color:sub(6,7)), b = tonumber("0x" .. color:sub(6, 7)),
} }
c.r = c.r + amount c.r = c.r + amount
@ -41,7 +36,7 @@ function _color.lighten(color, amount)
c.b = c.b < 0 and 0 or c.b c.b = c.b < 0 and 0 or c.b
c.b = c.b > 255 and 255 or c.b c.b = c.b > 255 and 255 or c.b
return string.format('#%02x%02x%02x', c.r, c.g, c.b) return string.format("#%02x%02x%02x", c.r, c.g, c.b)
end end
--- Darken a color. --- Darken a color.
@ -54,6 +49,4 @@ function _color.darken(color, amount)
return _color.lighten(color, -amount) return _color.lighten(color, -amount)
end end
return _color return _color

View File

@ -13,21 +13,36 @@ function _filesystem.list_directory_files(path, exts, recursive)
local files, valid_exts = {}, {} local files, valid_exts = {}, {}
-- Transforms { "jpg", ... } into { [jpg] = #, ... } -- Transforms { "jpg", ... } into { [jpg] = #, ... }
if exts then for i, j in ipairs(exts) do valid_exts[j:lower()] = i end end if exts then
for i, j in ipairs(exts) do
valid_exts[j:lower()] = i
end
end
-- Build a table of files from the path with the required extensions -- Build a table of files from the path with the required extensions
local file_list = Gio.File.new_for_path(path):enumerate_children("standard::*", 0) local file_list = Gio.File.new_for_path(path):enumerate_children(
"standard::*",
0
)
if file_list then if file_list then
for file in function() return file_list:next_file() end do for file in function()
return file_list:next_file()
end do
local file_type = file:get_file_type() local file_type = file:get_file_type()
if file_type == "REGULAR" then if file_type == "REGULAR" then
local file_name = file:get_display_name() local file_name = file:get_display_name()
if not exts or valid_exts[file_name:lower():match(".+%.(.*)$") or ""] then if
not exts
or valid_exts[file_name:lower():match(".+%.(.*)$") or ""]
then
table.insert(files, file_name) table.insert(files, file_name)
end end
elseif recursive and file_type == "DIRECTORY" then elseif recursive and file_type == "DIRECTORY" then
local file_name = file:get_display_name() local file_name = file:get_display_name()
files = gears.table.join(files, list_directory_files(file_name, exts, recursive)) files = gears.table.join(
files,
list_directory_files(file_name, exts, recursive)
)
end end
end end
end end
@ -35,5 +50,4 @@ function _filesystem.list_directory_files(path, exts, recursive)
return files return files
end end
return _filesystem return _filesystem

View File

@ -3,5 +3,5 @@ return {
color = require(... .. ".color"), color = require(... .. ".color"),
filesystem = require(... .. ".filesystem"), filesystem = require(... .. ".filesystem"),
shape = require(... .. ".shape"), shape = require(... .. ".shape"),
time = require(... .. ".time") time = require(... .. ".time"),
} }

View File

@ -14,10 +14,17 @@ end
function shape.prrect(radius, tl, tr, br, bl) function shape.prrect(radius, tl, tr, br, bl)
return function(cr, width, height) return function(cr, width, height)
gears.shape.partially_rounded_rect(cr, width, height, tl, tr, br, bl, gears.shape.partially_rounded_rect(
radius) cr,
width,
height,
tl,
tr,
br,
bl,
radius
)
end end
end end
return shape return shape

View File

@ -1,8 +1,5 @@
local time = {} local time = {}
--- Parse a time string to seconds (from midnight) --- Parse a time string to seconds (from midnight)
-- --
-- @string time The time (`HH:MM:SS`) -- @string time The time (`HH:MM:SS`)
@ -14,7 +11,6 @@ function time.hhmmss_to_seconds(time)
return (hour_sec + min_sec + get_sec) return (hour_sec + min_sec + get_sec)
end end
--- Get time difference in seconds. --- Get time difference in seconds.
-- --
-- @tparam string base The time to compare from (`HH:MM:SS`). -- @tparam string base The time to compare from (`HH:MM:SS`).
@ -25,5 +21,4 @@ function time.time_diff(base, compare)
return diff return diff
end end
return time return time

View File

@ -1,10 +1,11 @@
--[[ --[[
Bling Bling
Layouts, widgets and utilities for Awesome WM Layouts, widgets and utilities for Awesome WM
--]] return { --]]
return {
layout = require(... .. ".layout"), layout = require(... .. ".layout"),
module = require(... .. ".module"), module = require(... .. ".module"),
helpers = require(... .. ".helpers"), helpers = require(... .. ".helpers"),
signal = require(... .. ".signal"), signal = require(... .. ".signal"),
widget = require(... .. ".widget") widget = require(... .. ".widget"),
} }

View File

@ -16,10 +16,10 @@ function mylayout.arrange(p)
local nslaves = #p.clients - nmaster local nslaves = #p.clients - nmaster
local master_area_width = area.width * mwfact local master_area_width = area.width * mwfact
local slave_area_width = area.width - master_area_width local slave_area_width = area.width - master_area_width
local master_area_x = area.x + 0.5*slave_area_width local master_area_x = area.x + 0.5 * slave_area_width
local number_of_left_sided_slaves =math.floor(nslaves/2) local number_of_left_sided_slaves = math.floor(nslaves / 2)
local number_of_right_sided_slaves = nslaves - number_of_left_sided_slaves local number_of_right_sided_slaves = nslaves - number_of_left_sided_slaves
local left_iterator = 0 local left_iterator = 0
local right_iterator = 0 local right_iterator = 0
@ -30,69 +30,73 @@ function mylayout.arrange(p)
return return
end end
-- Special case: one slave -> relapse into awesomes masterstack tile layout -- Special case: one slave -> relapse into awesomes masterstack tile layout
if nslaves == 1 then if nslaves == 1 then
awful.layout.suit.tile.right.arrange(p) awful.layout.suit.tile.right.arrange(p)
return return
end end
-- Special case: no slaves -> fullscreen master area -- Special case: no slaves -> fullscreen master area
if nslaves < 1 then if nslaves < 1 then
master_area_width = area.width master_area_width = area.width
master_area_x = area.x master_area_x = area.x
end end
-- iterate through masters -- iterate through masters
for idx=1,nmaster do for idx = 1, nmaster do
local c = p.clients[idx] local c = p.clients[idx]
local g local g
g = { g = {
x = master_area_x, x = master_area_x,
y = area.y + (nmaster-idx)*(area.height/nmaster), y = area.y + (nmaster - idx) * (area.height / nmaster),
width = master_area_width, width = master_area_width,
height = area.height/nmaster, height = area.height / nmaster,
} }
p.geometries[c] = g p.geometries[c] = g
end end
-- iterate through slaves -- iterate through slaves
for idx=1,nslaves do -- idx=nmaster+1,#p.clients do for idx = 1, nslaves do -- idx=nmaster+1,#p.clients do
local c = p.clients[idx+nmaster] local c = p.clients[idx + nmaster]
if idx % 2 == 0 then if idx % 2 == 0 then
g = { g = {
x = area.x, x = area.x,
y = area.y + left_iterator * (area.height/number_of_left_sided_slaves), y = area.y
width = slave_area_width/2, + left_iterator
height = area.height/number_of_left_sided_slaves, * (area.height / number_of_left_sided_slaves),
} width = slave_area_width / 2,
left_iterator = left_iterator + 1 height = area.height / number_of_left_sided_slaves,
else }
g = { left_iterator = left_iterator + 1
x = area.x + master_area_width + slave_area_width/2, else
y = area.y + right_iterator * (area.height/number_of_right_sided_slaves), g = {
width = slave_area_width/2, x = area.x + master_area_width + slave_area_width / 2,
height = area.height/number_of_right_sided_slaves, y = area.y
} + right_iterator
right_iterator = right_iterator + 1 * (area.height / number_of_right_sided_slaves),
width = slave_area_width / 2,
end height = area.height / number_of_right_sided_slaves,
p.geometries[c] = g }
right_iterator = right_iterator + 1
end
p.geometries[c] = g
end end
end end
local icon_raw = gears.filesystem.get_configuration_dir() .. tostring(...):match("^.*bling"):gsub("%.", "/") .. "/icons/layouts/centered.png" local icon_raw = gears.filesystem.get_configuration_dir()
.. tostring(...):match("^.*bling"):gsub("%.", "/")
.. "/icons/layouts/centered.png"
local function get_icon() local function get_icon()
if icon_raw ~= nil then if icon_raw ~= nil then
return gcolor.recolor_image(icon_raw, beautiful.fg_normal) return gcolor.recolor_image(icon_raw, beautiful.fg_normal)
else else
return nil return nil
end end
end end
return { return {
layout = mylayout, layout = mylayout,
icon_raw = icon_raw, icon_raw = icon_raw,
get_icon = get_icon, get_icon = get_icon,
} }

View File

@ -25,9 +25,9 @@ function mylayout.arrange(p)
end end
local xoffset = area.width * 0.1 / (client_count - 1) local xoffset = area.width * 0.1 / (client_count - 1)
local yoffset = area.height * 0.1 / (client_count - 1) local yoffset = area.height * 0.1 / (client_count - 1)
for idx=1,client_count do for idx = 1, client_count do
local c = p.clients[idx] local c = p.clients[idx]
local g = { local g = {
x = area.x + (idx - 1) * xoffset, x = area.x + (idx - 1) * xoffset,
@ -39,7 +39,9 @@ function mylayout.arrange(p)
end end
end end
local icon_raw = gears.filesystem.get_configuration_dir() .. tostring(...):match("^.*bling"):gsub("%.", "/") .. "/icons/layouts/deck.png" local icon_raw = gears.filesystem.get_configuration_dir()
.. tostring(...):match("^.*bling"):gsub("%.", "/")
.. "/icons/layouts/deck.png"
local function get_icon() local function get_icon()
if icon_raw ~= nil then if icon_raw ~= nil then

View File

@ -1,84 +1,96 @@
local gears = require("gears") local gears = require("gears")
local gcolor = require("gears.color") local gcolor = require("gears.color")
local beautiful = require("beautiful") local beautiful = require("beautiful")
local math = math local math = math
local screen = screen local screen = screen
local mylayout = {} local mylayout = {}
mylayout.name = "equalarea" mylayout.name = "equalarea"
local function divide(p,g,low,high,cls,mwfact,mcount) local function divide(p, g, low, high, cls, mwfact, mcount)
if low == high then if low == high then
p.geometries[cls[low]] = g p.geometries[cls[low]] = g
else
local masters = math.max(0,math.min(mcount,high)-low+1)
local numblock = high-low + 1
local slaves = numblock - masters
local smalldiv
if numblock > 5 and (numblock % 5) == 0 then
smalldiv = math.floor(numblock/5)
else else
if (numblock % 3) == 0 then local masters = math.max(0, math.min(mcount, high) - low + 1)
smalldiv = math.floor(numblock/3) local numblock = high - low + 1
else local slaves = numblock - masters
smalldiv = math.floor(numblock/2) local smalldiv
end if numblock > 5 and (numblock % 5) == 0 then
smalldiv = math.floor(numblock / 5)
else
if (numblock % 3) == 0 then
smalldiv = math.floor(numblock / 3)
else
smalldiv = math.floor(numblock / 2)
end
end
local bigdiv = numblock - smalldiv
local smallmasters = math.min(masters, smalldiv)
local bigmasters = masters - smallmasters
local smallg = {}
local bigg = {}
smallg.x = g.x
smallg.y = g.y
if g.width > (g.height * 1.3) then
smallg.height = g.height
bigg.height = g.height
bigg.width = math.floor(
g.width
* (bigmasters * (mwfact - 1) + bigdiv)
/ (slaves + mwfact * masters)
)
smallg.width = g.width - bigg.width
bigg.y = g.y
bigg.x = g.x + smallg.width
else
smallg.width = g.width
bigg.width = g.width
bigg.height = math.floor(
g.height
* (bigmasters * (mwfact - 1) + bigdiv)
/ (slaves + mwfact * masters)
)
smallg.height = g.height - bigg.height
bigg.x = g.x
bigg.y = g.y + smallg.height
end
divide(p, smallg, low, high - bigdiv, cls, mwfact, mcount)
divide(p, bigg, low + smalldiv, high, cls, mwfact, mcount)
end end
local bigdiv = numblock - smalldiv return
local smallmasters = math.min(masters,smalldiv)
local bigmasters = masters-smallmasters
local smallg = {}
local bigg = {}
smallg.x = g.x
smallg.y = g.y
if g.width > (g.height*1.3) then
smallg.height = g.height
bigg.height = g.height
bigg.width = math.floor(g.width*(bigmasters*(mwfact-1)+bigdiv)/(slaves+mwfact*masters))
smallg.width = g.width-bigg.width
bigg.y = g.y
bigg.x = g.x + smallg.width
else
smallg.width = g.width
bigg.width = g.width
bigg.height = math.floor(g.height*(bigmasters*(mwfact-1)+bigdiv)/(slaves+mwfact*masters))
smallg.height = g.height-bigg.height
bigg.x = g.x
bigg.y = g.y + smallg.height
end
divide(p,smallg,low,high-bigdiv,cls,mwfact,mcount)
divide(p,bigg,low+smalldiv,high,cls,mwfact,mcount)
end
return
end end
function mylayout.arrange(p) function mylayout.arrange(p)
local t = p.tag or screen[p.screen].selected_tag local t = p.tag or screen[p.screen].selected_tag
local wa = p.workarea local wa = p.workarea
local cls = p.clients local cls = p.clients
if #cls == 0 then return end if #cls == 0 then
local mwfact = t.master_width_factor*2 return
local mcount = t.master_count end
local g = {} local mwfact = t.master_width_factor * 2
g.height = wa.height local mcount = t.master_count
g.width = wa.width local g = {}
g.x = wa.x g.height = wa.height
g.y = wa.y g.width = wa.width
divide(p,g,1,#cls,cls,mwfact,mcount) g.x = wa.x
g.y = wa.y
divide(p, g, 1, #cls, cls, mwfact, mcount)
end end
local icon_raw = gears.filesystem.get_configuration_dir() .. tostring(...):match("^.*bling"):gsub("%.", "/") .. "/icons/layouts/equalarea.png" local icon_raw = gears.filesystem.get_configuration_dir()
.. tostring(...):match("^.*bling"):gsub("%.", "/")
.. "/icons/layouts/equalarea.png"
local function get_icon() local function get_icon()
if icon_raw ~= nil then if icon_raw ~= nil then
return gcolor.recolor_image(icon_raw, beautiful.fg_normal) return gcolor.recolor_image(icon_raw, beautiful.fg_normal)
else else
return nil return nil
end end
end end
return { return {
layout = mylayout, layout = mylayout,
icon_raw = icon_raw, icon_raw = icon_raw,
get_icon = get_icon, get_icon = get_icon,
} }

View File

@ -19,43 +19,47 @@ function mylayout.arrange(p)
local slave_area_height = area.height - master_area_height local slave_area_height = area.height - master_area_height
-- Special case: no slaves -- Special case: no slaves
if nslaves == 0 then if nslaves == 0 then
master_area_height = area.height master_area_height = area.height
slave_area_height = 0 slave_area_height = 0
end end
-- Special case: no masters -- Special case: no masters
if nmaster == 0 then if nmaster == 0 then
master_area_height = 0 master_area_height = 0
slave_area_height = area.height slave_area_height = area.height
end end
-- itearte through masters -- itearte through masters
for idx=1,nmaster do for idx = 1, nmaster do
local c = p.clients[idx] local c = p.clients[idx]
local g = { local g = {
x = area.x + (idx-1)*(area.width/nmaster), x = area.x + (idx - 1) * (area.width / nmaster),
y = area.y, y = area.y,
width = area.width/nmaster, width = area.width / nmaster,
height = master_area_height, height = master_area_height,
} }
p.geometries[c] = g p.geometries[c] = g
end end
-- iterate through slaves -- iterate through slaves
for idx=1,nslaves do for idx = 1, nslaves do
local c = p.clients[idx+nmaster] local c = p.clients[idx + nmaster]
local g = { local g = {
x = area.x, x = area.x,
y = area.y + master_area_height + (idx-1)*(slave_area_height/nslaves), y = area.y
+ master_area_height
+ (idx - 1) * (slave_area_height / nslaves),
width = area.width, width = area.width,
height = slave_area_height/nslaves, height = slave_area_height / nslaves,
} }
p.geometries[c] = g p.geometries[c] = g
end end
end end
local icon_raw = gears.filesystem.get_configuration_dir() .. tostring(...):match("^.*bling"):gsub("%.", "/") .. "/icons/layouts/horizontal.png" local icon_raw = gears.filesystem.get_configuration_dir()
.. tostring(...):match("^.*bling"):gsub("%.", "/")
.. "/icons/layouts/horizontal.png"
local function get_icon() local function get_icon()
if icon_raw ~= nil then if icon_raw ~= nil then

View File

@ -24,7 +24,7 @@ local layout = {
vertical = vertical.layout, vertical = vertical.layout,
horizontal = horizontal.layout, horizontal = horizontal.layout,
equalarea = equalarea.layout, equalarea = equalarea.layout,
deck = deck.layout deck = deck.layout,
} }
return layout return layout

View File

@ -10,33 +10,50 @@ mylayout.name = "mstab"
local tabbar_ontop = beautiful.mstab_bar_ontop or false local tabbar_ontop = beautiful.mstab_bar_ontop or false
local tabbar_padding = beautiful.mstab_bar_padding or "default" local tabbar_padding = beautiful.mstab_bar_padding or "default"
local border_radius = beautiful.mstab_border_radius or local border_radius = beautiful.mstab_border_radius
beautiful.border_radius or 0 or beautiful.border_radius
local tabbar_position = beautiful.mstab_tabbar_position or or 0
beautiful.tabbar_position or "top" local tabbar_position = beautiful.mstab_tabbar_position
or beautiful.tabbar_position
or "top"
local bar_style = beautiful.mstab_tabbar_style or beautiful.tabbar_style or local bar_style = beautiful.mstab_tabbar_style
"default" or beautiful.tabbar_style
local bar = require(tostring(...):match(".*bling") .. ".widget.tabbar." .. or "default"
bar_style) local bar = require(
local tabbar_size = bar.size or beautiful.mstab_bar_height or beautiful.tabbar_size or 40 tostring(...):match(".*bling") .. ".widget.tabbar." .. bar_style
)
local tabbar_size = bar.size
or beautiful.mstab_bar_height
or beautiful.tabbar_size
or 40
local dont_resize_slaves = beautiful.mstab_dont_resize_slaves or false local dont_resize_slaves = beautiful.mstab_dont_resize_slaves or false
-- The top_idx is the idx of the slave clients (excluding all master clients) -- The top_idx is the idx of the slave clients (excluding all master clients)
-- that should be on top of all other slave clients ("the focused slave") -- that should be on top of all other slave clients ("the focused slave")
-- by creating a variable outside of the arrange function, this layout can "remember" that client -- by creating a variable outside of the arrange function, this layout can "remember" that client
-- by creating it as a new property of every tag, this layout can be active on different tags and -- by creating it as a new property of every tag, this layout can be active on different tags and
-- still have different "focused slave clients" -- still have different "focused slave clients"
for idx, tag in ipairs(root.tags()) do tag.top_idx = 1 end for idx, tag in ipairs(root.tags()) do
tag.top_idx = 1
end
-- Haven't found a signal that is emitted when a new tag is added. That should work though -- Haven't found a signal that is emitted when a new tag is added. That should work though
-- since you can't use a layout on a tag that you haven't selected previously -- since you can't use a layout on a tag that you haven't selected previously
tag.connect_signal("property::selected", tag.connect_signal("property::selected", function(t)
function(t) if not t.top_idx then t.top_idx = 1 end end) if not t.top_idx then
t.top_idx = 1
function update_tabbar(clients, t, top_idx, area, master_area_width, end
slave_area_width) end)
function update_tabbar(
clients,
t,
top_idx,
area,
master_area_width,
slave_area_width
)
local s = t.screen local s = t.screen
-- create the list of clients for the tabbar -- create the list of clients for the tabbar
@ -47,42 +64,50 @@ function update_tabbar(clients, t, top_idx, area, master_area_width,
awful.button({}, 1, function() awful.button({}, 1, function()
c:raise() c:raise()
client.focus = c client.focus = c
end), end),
awful.button({}, 2, function() awful.button({}, 2, function()
c:kill() c:kill()
end), end),
awful.button({}, 3, function() awful.button({}, 3, function()
c.minimized = true c.minimized = true
end)) end)
)
local client_box = bar.create(c, (idx == top_idx), buttons) local client_box = bar.create(c, (idx == top_idx), buttons)
clientlist:add(client_box) clientlist:add(client_box)
end end
-- if no tabbar exists, create one -- if no tabbar exists, create one
if not s.tabbar then if not s.tabbar then
s.tabbar = wibox { s.tabbar = wibox({
ontop = tabbar_ontop, ontop = tabbar_ontop,
shape = function(cr, width, height) shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, border_radius) gears.shape.rounded_rect(cr, width, height, border_radius)
end, end,
bg = bar.bg_normal, bg = bar.bg_normal,
visible = true visible = true,
} })
-- Change visibility of the tab bar when layout, selected tag or number of clients (visible, master, slave) changes -- Change visibility of the tab bar when layout, selected tag or number of clients (visible, master, slave) changes
local function adjust_visiblity(t) local function adjust_visiblity(t)
s.tabbar.visible = (#t:clients() - t.master_count > 1) and s.tabbar.visible = (#t:clients() - t.master_count > 1)
(t.layout.name == mylayout.name) and (t.layout.name == mylayout.name)
end end
tag.connect_signal("property::selected", tag.connect_signal("property::selected", function(t)
function(t) adjust_visiblity(t) end) adjust_visiblity(t)
tag.connect_signal("property::layout", end)
function(t, layout) adjust_visiblity(t) end) tag.connect_signal("property::layout", function(t, layout)
tag.connect_signal("tagged", function(t, c) adjust_visiblity(t) end) adjust_visiblity(t)
tag.connect_signal("untagged", function(t, c) adjust_visiblity(t) end) end)
tag.connect_signal("property::master_count", tag.connect_signal("tagged", function(t, c)
function(t) adjust_visiblity(t) end) adjust_visiblity(t)
end)
tag.connect_signal("untagged", function(t, c)
adjust_visiblity(t)
end)
tag.connect_signal("property::master_count", function(t)
adjust_visiblity(t)
end)
client.connect_signal("property::minimized", function(c) client.connect_signal("property::minimized", function(c)
local t = c.first_tag local t = c.first_tag
adjust_visiblity(t) adjust_visiblity(t)
@ -100,21 +125,24 @@ function update_tabbar(clients, t, top_idx, area, master_area_width,
s.tabbar.y = area.y + area.height - tabbar_size - t.gap s.tabbar.y = area.y + area.height - tabbar_size - t.gap
s.tabbar.width = slave_area_width - 2 * t.gap s.tabbar.width = slave_area_width - 2 * t.gap
s.tabbar.height = tabbar_size s.tabbar.height = tabbar_size
elseif tabbar_position == "left" then elseif tabbar_position == "left" then
s.tabbar.x = area.x + master_area_width + t.gap s.tabbar.x = area.x + master_area_width + t.gap
s.tabbar.y = area.y + t.gap s.tabbar.y = area.y + t.gap
s.tabbar.width = tabbar_size s.tabbar.width = tabbar_size
s.tabbar.height = area.height - 2 * t.gap s.tabbar.height = area.height - 2 * t.gap
elseif tabbar_position == "right" then elseif tabbar_position == "right" then
s.tabbar.x = area.x + master_area_width + slave_area_width - tabbar_size - t.gap s.tabbar.x = area.x
+ master_area_width
+ slave_area_width
- tabbar_size
- t.gap
s.tabbar.y = area.y + t.gap s.tabbar.y = area.y + t.gap
s.tabbar.width = tabbar_size s.tabbar.width = tabbar_size
s.tabbar.height = area.height - 2 * t.gap s.tabbar.height = area.height - 2 * t.gap
end end
-- update clientlist -- update clientlist
s.tabbar:setup{layout = wibox.layout.flex.horizontal, clientlist} s.tabbar:setup({ layout = wibox.layout.flex.horizontal, clientlist })
end end
function mylayout.arrange(p) function mylayout.arrange(p)
@ -129,7 +157,9 @@ function mylayout.arrange(p)
local slave_area_width = area.width - master_area_width local slave_area_width = area.width - master_area_width
-- "default" means that it uses standard useless gap size -- "default" means that it uses standard useless gap size
if tabbar_padding == "default" then tabbar_padding = 2 * t.gap end if tabbar_padding == "default" then
tabbar_padding = 2 * t.gap
end
-- Special case: No masters -> full screen slave width -- Special case: No masters -> full screen slave width
if nmaster == 0 then if nmaster == 0 then
@ -140,8 +170,10 @@ function mylayout.arrange(p)
-- Special case: One or zero slaves -> no tabbar (essentially tile right) -- Special case: One or zero slaves -> no tabbar (essentially tile right)
if nslaves <= 1 then if nslaves <= 1 then
-- since update_tabbar isnt called that way we have to hide it manually -- since update_tabbar isnt called that way we have to hide it manually
if s.tabbar then s.tabbar.visible = false end if s.tabbar then
-- otherwise just do tile right s.tabbar.visible = false
end
-- otherwise just do tile right
awful.layout.suit.tile.right.arrange(p) awful.layout.suit.tile.right.arrange(p)
return return
end end
@ -153,25 +185,25 @@ function mylayout.arrange(p)
x = area.x, x = area.x,
y = area.y + (idx - 1) * (area.height / nmaster), y = area.y + (idx - 1) * (area.height / nmaster),
width = master_area_width, width = master_area_width,
height = area.height / nmaster height = area.height / nmaster,
} }
p.geometries[c] = g p.geometries[c] = g
end end
local tabbar_size_change = 0 local tabbar_size_change = 0
local tabbar_width_change = 0 local tabbar_width_change = 0
local tabbar_y_change = 0 local tabbar_y_change = 0
local tabbar_x_change = 0 local tabbar_x_change = 0
if tabbar_position == "top" then if tabbar_position == "top" then
tabbar_size_change = tabbar_size + tabbar_padding tabbar_size_change = tabbar_size + tabbar_padding
tabbar_y_change = tabbar_size + tabbar_padding tabbar_y_change = tabbar_size + tabbar_padding
elseif tabbar_position == "bottom" then elseif tabbar_position == "bottom" then
tabbar_size_change = tabbar_size + tabbar_padding tabbar_size_change = tabbar_size + tabbar_padding
elseif tabbar_position == "left" then elseif tabbar_position == "left" then
tabbar_width_change = tabbar_size + tabbar_padding tabbar_width_change = tabbar_size + tabbar_padding
tabbar_x_change = tabbar_size + tabbar_padding tabbar_x_change = tabbar_size + tabbar_padding
elseif tabbar_position == "right" then elseif tabbar_position == "right" then
tabbar_width_change = tabbar_size + tabbar_padding tabbar_width_change = tabbar_size + tabbar_padding
end end
-- Iterate through slaves -- Iterate through slaves
@ -180,31 +212,39 @@ function mylayout.arrange(p)
for idx = 1, nslaves do for idx = 1, nslaves do
local c = p.clients[idx + nmaster] local c = p.clients[idx + nmaster]
slave_clients[#slave_clients + 1] = c slave_clients[#slave_clients + 1] = c
if c == client.focus then t.top_idx = #slave_clients end if c == client.focus then
t.top_idx = #slave_clients
end
local g = { local g = {
x = area.x + master_area_width + tabbar_x_change, x = area.x + master_area_width + tabbar_x_change,
y = area.y + tabbar_y_change, y = area.y + tabbar_y_change,
width = slave_area_width - tabbar_width_change, width = slave_area_width - tabbar_width_change,
height = area.height - tabbar_size_change height = area.height - tabbar_size_change,
} }
if not dont_resize_slaves and idx ~= t.top_idx then if not dont_resize_slaves and idx ~= t.top_idx then
g = { g = {
x = area.x + master_area_width + slave_area_width / 4, x = area.x + master_area_width + slave_area_width / 4,
y = area.y + tabbar_size + area.height / 4, y = area.y + tabbar_size + area.height / 4,
width = slave_area_width / 2, width = slave_area_width / 2,
height = area.height / 4 - tabbar_size height = area.height / 4 - tabbar_size,
} }
end end
p.geometries[c] = g p.geometries[c] = g
end end
update_tabbar(slave_clients, t, t.top_idx, area, master_area_width, update_tabbar(
slave_area_width) slave_clients,
t,
t.top_idx,
area,
master_area_width,
slave_area_width
)
end end
local icon_raw = gears.filesystem.get_configuration_dir() .. local icon_raw = gears.filesystem.get_configuration_dir()
tostring(...):match("^.*bling"):gsub("%.", "/") .. .. tostring(...):match("^.*bling"):gsub("%.", "/")
"/icons/layouts/mstab.png" .. "/icons/layouts/mstab.png"
local function get_icon() local function get_icon()
if icon_raw ~= nil then if icon_raw ~= nil then
@ -214,4 +254,4 @@ local function get_icon()
end end
end end
return {layout = mylayout, icon_raw = icon_raw, get_icon = get_icon} return { layout = mylayout, icon_raw = icon_raw, get_icon = get_icon }

View File

@ -18,44 +18,48 @@ function mylayout.arrange(p)
local master_area_width = area.width * mwfact local master_area_width = area.width * mwfact
local slave_area_width = area.width - master_area_width local slave_area_width = area.width - master_area_width
-- Special case: no slaves -- Special case: no slaves
if nslaves == 0 then if nslaves == 0 then
master_area_width = area.width master_area_width = area.width
slave_area_width = 0 slave_area_width = 0
end end
-- Special case: no masters -- Special case: no masters
if nmaster == 0 then if nmaster == 0 then
master_area_width = 0 master_area_width = 0
slave_area_width = area.width slave_area_width = area.width
end end
-- iterate through masters -- iterate through masters
for idx=1,nmaster do for idx = 1, nmaster do
local c = p.clients[idx] local c = p.clients[idx]
local g = { local g = {
x = area.x, x = area.x,
y = area.y + (idx-1)*(area.height/nmaster), y = area.y + (idx - 1) * (area.height / nmaster),
width = master_area_width, width = master_area_width,
height = area.height/nmaster, height = area.height / nmaster,
} }
p.geometries[c] = g p.geometries[c] = g
end end
-- itearte through slaves -- itearte through slaves
for idx=1,nslaves do for idx = 1, nslaves do
local c = p.clients[idx+nmaster] local c = p.clients[idx + nmaster]
local g = { local g = {
x = area.x + master_area_width + (idx-1)*(slave_area_width/nslaves), x = area.x
+ master_area_width
+ (idx - 1) * (slave_area_width / nslaves),
y = area.y, y = area.y,
width = slave_area_width/nslaves, width = slave_area_width / nslaves,
height = area.height, height = area.height,
} }
p.geometries[c] = g p.geometries[c] = g
end end
end end
local icon_raw = gears.filesystem.get_configuration_dir() .. tostring(...):match("^.*bling"):gsub("%.", "/") .. "/icons/layouts/vertical.png" local icon_raw = gears.filesystem.get_configuration_dir()
.. tostring(...):match("^.*bling"):gsub("%.", "/")
.. "/icons/layouts/vertical.png"
local function get_icon() local function get_icon()
if icon_raw ~= nil then if icon_raw ~= nil then

View File

@ -8,14 +8,16 @@ local flashfocus = function(c)
if c then if c then
c.opacity = op c.opacity = op
local q = op local q = op
local g = gears.timer { local g = gears.timer({
timeout = stp, timeout = stp,
call_now = false, call_now = false,
autostart = true autostart = true,
} })
g:connect_signal("timeout", function() g:connect_signal("timeout", function()
if not c.valid then return end if not c.valid then
return
end
if q >= 1 then if q >= 1 then
c.opacity = 1 c.opacity = 1
g:stop() g:stop()
@ -27,10 +29,16 @@ local flashfocus = function(c)
end end
-- Bring the focused client to the top -- Bring the focused client to the top
if c then c:raise() end if c then
c:raise()
end
end end
local enable = function() client.connect_signal("focus", flashfocus) end local enable = function()
local disable = function() client.disconnect_signal("focus", flashfocus) end client.connect_signal("focus", flashfocus)
end
local disable = function()
client.disconnect_signal("focus", flashfocus)
end
return {enable = enable, disable = disable, flashfocus = flashfocus} return { enable = enable, disable = disable, flashfocus = flashfocus }

View File

@ -4,5 +4,5 @@ return {
wallpaper = require(... .. ".wallpaper"), wallpaper = require(... .. ".wallpaper"),
flash_focus = require(... .. ".flash_focus"), flash_focus = require(... .. ".flash_focus"),
tabbed = require(... .. ".tabbed"), tabbed = require(... .. ".tabbed"),
scratchpad = require(... .. ".scratchpad") scratchpad = require(... .. ".scratchpad"),
} }

View File

@ -3,7 +3,9 @@ local gears = require("gears")
local naughty = require("naughty") local naughty = require("naughty")
local ruled local ruled
if awesome.version ~= "v4.3" then ruled = require("ruled") end if awesome.version ~= "v4.3" then
ruled = require("ruled")
end
local helpers = require(tostring(...):match(".*bling") .. ".helpers") local helpers = require(tostring(...):match(".*bling") .. ".helpers")
@ -16,12 +18,15 @@ local Scratchpad = { mt = {} }
function Scratchpad:new(args) function Scratchpad:new(args)
args = args or {} args = args or {}
if args.awestore then if args.awestore then
naughty.notify({title = "Bling Error", text = "Awestore is no longer supported! Please take a look at the scratchpad documentation and use rubato for animations instead."}) naughty.notify({
title = "Bling Error",
text = "Awestore is no longer supported! Please take a look at the scratchpad documentation and use rubato for animations instead.",
})
end end
args.rubato = args.rubato or {} args.rubato = args.rubato or {}
args.in_anim = false args.in_anim = false
local ret = gears.object {} local ret = gears.object({})
gears.table.crush(ret, Scratchpad) gears.table.crush(ret, Scratchpad)
gears.table.crush(ret, args) gears.table.crush(ret, args)
return ret return ret
@ -30,13 +35,17 @@ end
--- Find all clients that satisfy the the rule --- Find all clients that satisfy the the rule
-- --
-- @return A list of all clients that satisfy the rule -- @return A list of all clients that satisfy the rule
function Scratchpad:find() return helpers.client.find(self.rule) end function Scratchpad:find()
return helpers.client.find(self.rule)
end
--- Applies the objects scratchpad properties to a given client --- Applies the objects scratchpad properties to a given client
-- --
-- @param c A client to which to apply the properties -- @param c A client to which to apply the properties
function Scratchpad:apply(c) function Scratchpad:apply(c)
if not c or not c.valid then return end if not c or not c.valid then
return
end
c.floating = self.floating c.floating = self.floating
c.sticky = self.sticky c.sticky = self.sticky
c.fullscreen = false c.fullscreen = false
@ -45,7 +54,7 @@ function Scratchpad:apply(c)
x = self.geometry.x + awful.screen.focused().geometry.x, x = self.geometry.x + awful.screen.focused().geometry.x,
y = self.geometry.y + awful.screen.focused().geometry.y, y = self.geometry.y + awful.screen.focused().geometry.y,
width = self.geometry.width, width = self.geometry.width,
height = self.geometry.height height = self.geometry.height,
}) })
if self.autoclose then if self.autoclose then
c:connect_signal("unfocus", function(c1) c:connect_signal("unfocus", function(c1)
@ -67,19 +76,27 @@ function Scratchpad:turn_on()
if axis == "x" and anim.pos == self.geometry.x then if axis == "x" and anim.pos == self.geometry.x then
anim.pos = anim:initial() anim.pos = anim:initial()
else else
if anim.pos == self.geometry.y then anim.pos = anim:initial() end if anim.pos == self.geometry.y then
anim.pos = anim:initial()
end
end end
anim:subscribe(function(pos) anim:subscribe(function(pos)
if c and c.valid then if c and c.valid then
if axis == "x" then c.x = pos if axis == "x" then
else c.y = pos end c.x = pos
else
c.y = pos
end
end end
self.in_anim = true self.in_anim = true
end) end)
if axis == "x" then anim:set(self.geometry.x) if axis == "x" then
else anim:set(self.geometry.y) end anim:set(self.geometry.x)
else
anim:set(self.geometry.y)
end
anim.ended:subscribe(function() anim.ended:subscribe(function()
self.in_anim = false self.in_anim = false
@ -100,12 +117,18 @@ function Scratchpad:turn_on()
end end
if c and not self.in_anim then if c and not self.in_anim then
-- if a client was found, turn it on -- if a client was found, turn it on
if self.reapply then self:apply(c) end if self.reapply then
self:apply(c)
end
-- c.sticky was set to false in turn_off so it has to be reapplied anyway -- c.sticky was set to false in turn_off so it has to be reapplied anyway
c.sticky = self.sticky c.sticky = self.sticky
if anim_x then animate(c, anim_x, "x") end if anim_x then
if anim_y then animate(c, anim_y, "y") end animate(c, anim_x, "x")
end
if anim_y then
animate(c, anim_y, "y")
end
helpers.client.turn_on(c) helpers.client.turn_on(c)
self:emit_signal("turn_on", c) self:emit_signal("turn_on", c)
@ -117,49 +140,64 @@ function Scratchpad:turn_on()
-- apply the properties only once (until the next closing) -- apply the properties only once (until the next closing)
local pid = awful.spawn.with_shell(self.command) local pid = awful.spawn.with_shell(self.command)
if awesome.version ~= "v4.3" then if awesome.version ~= "v4.3" then
ruled.client.append_rule ruled.client.append_rule({
{
id = "scratchpad", id = "scratchpad",
rule = self.rule, rule = self.rule,
properties = properties = {
{
-- If a scratchpad is opened it should spawn at the current tag -- If a scratchpad is opened it should spawn at the current tag
-- the same way it will behave if the client was already open -- the same way it will behave if the client was already open
tag = awful.screen.focused().selected_tag, tag = awful.screen.focused().selected_tag,
switch_to_tags = false, switch_to_tags = false,
-- Hide the client until the gemoetry rules are applied -- Hide the client until the gemoetry rules are applied
hidden = true, hidden = true,
minimized = true minimized = true,
}, },
callback = function(c) callback = function(c)
-- For a reason I can't quite get the gemotery rules will fail to apply unless we use this timer -- For a reason I can't quite get the gemotery rules will fail to apply unless we use this timer
gears.timer{timeout = 0.15, autostart = true, single_shot = true, callback = function() gears.timer({
self:apply(c) timeout = 0.15,
c.hidden = false autostart = true,
c.minimized = false single_shot = true,
-- Some clients fail to gain focus callback = function()
c:activate{} self:apply(c)
c.hidden = false
c.minimized = false
-- Some clients fail to gain focus
c:activate({})
if anim_x then animate(c, anim_x, "x") end if anim_x then
if anim_y then animate(c, anim_y, "y") end animate(c, anim_x, "x")
end
if anim_y then
animate(c, anim_y, "y")
end
self:emit_signal("inital_apply", c) self:emit_signal("inital_apply", c)
-- Discord spawns 2 windows, so keep the rule until the 2nd window shows -- Discord spawns 2 windows, so keep the rule until the 2nd window shows
if c.name ~= "Discord Updater" then ruled.client.remove_rule("scratchpad") end if c.name ~= "Discord Updater" then
-- In a case Discord is killed before the second window spawns ruled.client.remove_rule("scratchpad")
c:connect_signal("request::unmanage", function() ruled.client.remove_rule("scratchpad") end) end
end} -- In a case Discord is killed before the second window spawns
end c:connect_signal("request::unmanage", function()
} ruled.client.remove_rule("scratchpad")
end)
end,
})
end,
})
else else
local function inital_apply(c1) local function inital_apply(c1)
if helpers.client.is_child_of(c1, pid) then if helpers.client.is_child_of(c1, pid) then
self:apply(c1) self:apply(c1)
if anim_x then animate(c1, anim_x, "x") end if anim_x then
if anim_y then animate(c1, anim_y, "y") end animate(c1, anim_x, "x")
end
if anim_y then
animate(c1, anim_y, "y")
end
self:emit_signal("inital_apply", c1) self:emit_signal("inital_apply", c1)
client.disconnect_signal("manage", inital_apply) client.disconnect_signal("manage", inital_apply)
end end
end end
client.connect_signal("manage", inital_apply) client.connect_signal("manage", inital_apply)
@ -177,13 +215,19 @@ function Scratchpad:turn_off()
-- Can't animate non floating clients -- Can't animate non floating clients
c.floating = true c.floating = true
if axis == "x" then anim.pos = c.x if axis == "x" then
else anim.pos = c.y end anim.pos = c.x
else
anim.pos = c.y
end
anim:subscribe(function(pos) anim:subscribe(function(pos)
if c and c.valid then if c and c.valid then
if axis == "x" then c.x = pos if axis == "x" then
else c.y = pos end c.x = pos
else
c.y = pos
end
end end
self.in_anim = true self.in_anim = true
@ -195,15 +239,23 @@ function Scratchpad:turn_off()
-- Switch to tag 2 -- Switch to tag 2
-- The client will remain on tag 1 -- The client will remain on tag 1
-- The client will be removed from tag 2 -- The client will be removed from tag 2
if c.screen.selected_tag ~= current_tag_on_toggled_scratchpad then if
c.screen.selected_tag ~= current_tag_on_toggled_scratchpad
then
self.in_anim = false self.in_anim = false
anim:abort() anim:abort()
anim:reset() anim:reset()
anim:unsubscribe() anim:unsubscribe()
anim.ended:unsubscribe() anim.ended:unsubscribe()
if axis == "x" then anim.pos = self.geometry.x if axis == "x" then
else anim.pos = self.geometry.y end anim.pos = self.geometry.x
helpers.client.turn_off(c, current_tag_on_toggled_scratchpad) else
anim.pos = self.geometry.y
end
helpers.client.turn_off(
c,
current_tag_on_toggled_scratchpad
)
self:apply(c) self:apply(c)
self:emit_signal("turn_off", c) self:emit_signal("turn_off", c)
end end
@ -233,8 +285,12 @@ function Scratchpad:turn_off()
local anim_x = self.rubato.x local anim_x = self.rubato.x
local anim_y = self.rubato.y local anim_y = self.rubato.y
if anim_x then animate(anim_x, self.geometry.x, "x") end if anim_x then
if anim_y then animate(anim_y, self.geometry.y, "y") end animate(anim_x, self.geometry.x, "x")
end
if anim_y then
animate(anim_y, self.geometry.y, "y")
end
if not anim_x and not anim_y then if not anim_x and not anim_y then
helpers.client.turn_off(c) helpers.client.turn_off(c)
@ -260,8 +316,8 @@ function Scratchpad:toggle()
end end
end end
else else
is_turn_off = client.focus and is_turn_off = client.focus
awful.rules.match(client.focus, self.rule) and awful.rules.match(client.focus, self.rule)
end end
if is_turn_off then if is_turn_off then

View File

@ -17,24 +17,33 @@ local beautiful = require("beautiful")
local helpers = require(tostring(...):match(".*bling") .. ".helpers") local helpers = require(tostring(...):match(".*bling") .. ".helpers")
local bar_style = beautiful.tabbar_style or "default" local bar_style = beautiful.tabbar_style or "default"
local bar = require(tostring(...):match(".*bling") .. ".widget.tabbar." .. local bar = require(
bar_style) tostring(...):match(".*bling") .. ".widget.tabbar." .. bar_style
)
tabbed = {} tabbed = {}
-- used to change focused tab relative to the currently focused one -- used to change focused tab relative to the currently focused one
tabbed.iter = function(idx) tabbed.iter = function(idx)
if not idx then idx = 1 end if not idx then
if not client.focus or not client.focus.bling_tabbed then return end idx = 1
end
if not client.focus or not client.focus.bling_tabbed then
return
end
local tabobj = client.focus.bling_tabbed local tabobj = client.focus.bling_tabbed
local new_idx = (tabobj.focused_idx + idx) % #tabobj.clients local new_idx = (tabobj.focused_idx + idx) % #tabobj.clients
if new_idx == 0 then new_idx = #tabobj.clients end if new_idx == 0 then
new_idx = #tabobj.clients
end
tabbed.switch_to(tabobj, new_idx) tabbed.switch_to(tabobj, new_idx)
end end
-- removes a given client from its tab object -- removes a given client from its tab object
tabbed.remove = function(c) tabbed.remove = function(c)
if not c or not c.bling_tabbed then return end if not c or not c.bling_tabbed then
return
end
local tabobj = c.bling_tabbed local tabobj = c.bling_tabbed
table.remove(tabobj.clients, tabobj.focused_idx) table.remove(tabobj.clients, tabobj.focused_idx)
if not beautiful.tabbar_disable then if not beautiful.tabbar_disable then
@ -47,7 +56,9 @@ end
-- removes the currently focused client from the tab object -- removes the currently focused client from the tab object
tabbed.pop = function() tabbed.pop = function()
if not client.focus or not client.focus.bling_tabbed then return end if not client.focus or not client.focus.bling_tabbed then
return
end
tabbed.remove(client.focus) tabbed.remove(client.focus)
end end
@ -60,7 +71,7 @@ tabbed.add = function(c, tabobj)
tabobj.clients[#tabobj.clients + 1] = c tabobj.clients[#tabobj.clients + 1] = c
tabobj.focused_idx = #tabobj.clients tabobj.focused_idx = #tabobj.clients
-- calls update even though switch_to calls update again -- calls update even though switch_to calls update again
-- but the new client needs to have the tabobj property -- but the new client needs to have the tabobj property
-- before a clean switch can happen -- before a clean switch can happen
tabbed.update(tabobj) tabbed.update(tabobj)
awesome.emit_signal("bling::tabbed::client_added", tabobj, c) awesome.emit_signal("bling::tabbed::client_added", tabobj, c)
@ -69,11 +80,14 @@ end
-- use xwininfo to select one client and make it tab in the currently focused tab -- use xwininfo to select one client and make it tab in the currently focused tab
tabbed.pick = function() tabbed.pick = function()
if not client.focus then return end if not client.focus then
return
end
-- this function uses xwininfo to grab a client window id which is then -- this function uses xwininfo to grab a client window id which is then
-- compared to all other clients window ids -- compared to all other clients window ids
local xwininfo_cmd = [[ xwininfo | grep 'xwininfo: Window id:' | cut -d " " -f 4 ]] local xwininfo_cmd =
[[ xwininfo | grep 'xwininfo: Window id:' | cut -d " " -f 4 ]]
awful.spawn.easy_async_with_shell(xwininfo_cmd, function(output) awful.spawn.easy_async_with_shell(xwininfo_cmd, function(output)
for _, c in ipairs(client.get()) do for _, c in ipairs(client.get()) do
if tonumber(c.window) == tonumber(output) then if tonumber(c.window) == tonumber(output) then
@ -95,20 +109,30 @@ tabbed.pick = function()
end end
-- select a client by direction and make it tab in the currently focused tab -- select a client by direction and make it tab in the currently focused tab
tabbed.pick_by_direction = function(direction) tabbed.pick_by_direction = function(direction)
local sel = client.focus local sel = client.focus
if not sel then return end if not sel then
if not sel.bling_tabbed then tabbed.init(sel) end return
end
if not sel.bling_tabbed then
tabbed.init(sel)
end
local c = helpers.client.get_by_direction(direction) local c = helpers.client.get_by_direction(direction)
if not c then return end if not c then
return
end
tabbed.add(c, sel.bling_tabbed) tabbed.add(c, sel.bling_tabbed)
end end
-- use dmenu to select a client and make it tab in the currently focused tab -- use dmenu to select a client and make it tab in the currently focused tab
tabbed.pick_with_dmenu = function(dmenu_command) tabbed.pick_with_dmenu = function(dmenu_command)
if not client.focus then return end if not client.focus then
return
end
if not dmenu_command then dmenu_command = "rofi -dmenu -i" end if not dmenu_command then
dmenu_command = "rofi -dmenu -i"
end
-- get all clients from the current tag -- get all clients from the current tag
-- ignores the case where multiple tags are selected -- ignores the case where multiple tags are selected
@ -121,17 +145,28 @@ tabbed.pick_with_dmenu = function(dmenu_command)
if #list_clients ~= 1 then if #list_clients ~= 1 then
list_clients_string = list_clients_string .. "\\n" list_clients_string = list_clients_string .. "\\n"
end end
list_clients_string = list_clients_string .. tostring(c.window) .. " " .. c.name list_clients_string = list_clients_string
.. tostring(c.window)
.. " "
.. c.name
end end
end end
if #list_clients == 0 then return end if #list_clients == 0 then
return
end
-- calls the actual dmenu -- calls the actual dmenu
local xprop_cmd = [[ echo -e "]] .. list_clients_string .. [[" | ]] .. dmenu_command .. [[ | awk '{ print $1 }' ]] local xprop_cmd = [[ echo -e "]]
.. list_clients_string
.. [[" | ]]
.. dmenu_command
.. [[ | awk '{ print $1 }' ]]
awful.spawn.easy_async_with_shell(xprop_cmd, function(output) awful.spawn.easy_async_with_shell(xprop_cmd, function(output)
for _, c in ipairs(list_clients) do for _, c in ipairs(list_clients) do
if tonumber(c.window) == tonumber(output) then if tonumber(c.window) == tonumber(output) then
if not client.focus.bling_tabbed then tabbed.init(client.focus) end if not client.focus.bling_tabbed then
tabbed.init(client.focus)
end
local tabobj = client.focus.bling_tabbed local tabobj = client.focus.bling_tabbed
tabbed.add(c, tabobj) tabbed.add(c, tabobj)
end end
@ -148,13 +183,15 @@ tabbed.update = function(tabobj)
c.bling_tabbed = tabobj c.bling_tabbed = tabobj
helpers.client.sync(c, currently_focused_c) helpers.client.sync(c, currently_focused_c)
-- the following handles killing a client while the client is tabbed -- the following handles killing a client while the client is tabbed
c:connect_signal("unmanage", function(c) tabbed.remove(c) end) c:connect_signal("unmanage", function(c)
tabbed.remove(c)
end)
end end
end end
-- Maybe remove if I'm the only one using it? -- Maybe remove if I'm the only one using it?
awesome.emit_signal("bling::tabbed::update", tabobj) awesome.emit_signal("bling::tabbed::update", tabobj)
if not beautiful.tabbar_disable then if not beautiful.tabbar_disable then
tabbed.update_tabbar(tabobj) tabbed.update_tabbar(tabobj)
end end
end end
@ -183,10 +220,9 @@ tabbed.update_tabbar = function(tabobj)
local flexlist = bar.layout() local flexlist = bar.layout()
-- itearte over all tabbed clients to create the widget tabbed list -- itearte over all tabbed clients to create the widget tabbed list
for idx, c in ipairs(tabobj.clients) do for idx, c in ipairs(tabobj.clients) do
local buttons = gears.table.join( local buttons = gears.table.join(awful.button({}, 1, function()
awful.button({}, 1, function() tabbed.switch_to(tabobj, idx)
tabbed.switch_to(tabobj, idx) end))
end))
wid_temp = bar.create(c, (idx == tabobj.focused_idx), buttons) wid_temp = bar.create(c, (idx == tabobj.focused_idx), buttons)
flexlist:add(wid_temp) flexlist:add(wid_temp)
end end
@ -195,15 +231,15 @@ tabbed.update_tabbar = function(tabobj)
local titlebar = awful.titlebar(c, { local titlebar = awful.titlebar(c, {
bg = bar.bg_normal, bg = bar.bg_normal,
size = bar.size, size = bar.size,
position = bar.position position = bar.position,
}) })
titlebar:setup{layout = wibox.layout.flex.horizontal, flexlist} titlebar:setup({ layout = wibox.layout.flex.horizontal, flexlist })
end end
end end
tabbed.init = function(c) tabbed.init = function(c)
local tabobj = {} local tabobj = {}
tabobj.clients = {c} tabobj.clients = { c }
tabobj.focused_idx = 1 tabobj.focused_idx = 1
tabbed.update(tabobj) tabbed.update(tabobj)
end end

View File

@ -16,7 +16,6 @@ local cairo = require("lgi").cairo
local gears = require("gears") local gears = require("gears")
function create_tiled_wallpaper(str, s, args_table) function create_tiled_wallpaper(str, s, args_table)
-- user input -- user input
args_table = args_table or {} args_table = args_table or {}
local fg = args_table.fg or "#ff0000" local fg = args_table.fg or "#ff0000"
@ -27,7 +26,7 @@ function create_tiled_wallpaper(str, s, args_table)
local font_size = tonumber(args_table.font_size) or 16 local font_size = tonumber(args_table.font_size) or 16
local zickzack_bool = args_table.zickzack or false local zickzack_bool = args_table.zickzack or false
local padding = args_table.padding or 100 local padding = args_table.padding or 100
-- create cairo image wallpaper -- create cairo image wallpaper
local img = cairo.ImageSurface(cairo.Format.RGB24, padding, padding) local img = cairo.ImageSurface(cairo.Format.RGB24, padding, padding)
cr = cairo.Context(img) cr = cairo.Context(img)
@ -40,19 +39,18 @@ function create_tiled_wallpaper(str, s, args_table)
cr:set_font_size(font_size) cr:set_font_size(font_size)
cr:select_font_face(font) cr:select_font_face(font)
if zickzack_bool then if zickzack_bool then
cr:set_source(gears.color(fg)) cr:set_source(gears.color(fg))
cr:move_to(padding/2 + font_size, padding/2 + font_size) cr:move_to(padding / 2 + font_size, padding / 2 + font_size)
cr:show_text(str) cr:show_text(str)
end end
cr:set_source(gears.color(fg)) cr:set_source(gears.color(fg))
cr:move_to(font_size, font_size) cr:move_to(font_size, font_size)
cr:show_text(str) cr:show_text(str)
-- tile cairo image -- tile cairo image
gears.wallpaper.tiled(img, s, {x=offset_x, y=offset_y}) gears.wallpaper.tiled(img, s, { x = offset_x, y = offset_y })
end end
return create_tiled_wallpaper return create_tiled_wallpaper

View File

@ -23,7 +23,6 @@
-- --
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
local awful = require("awful") local awful = require("awful")
local beautiful = require("beautiful") local beautiful = require("beautiful")
local gears = require("gears") local gears = require("gears")
@ -50,23 +49,47 @@ local setters = {}
-- @int[opt=1] args.scale See `gears.wallpaper`. -- @int[opt=1] args.scale See `gears.wallpaper`.
function apply(wallpaper_object, args) function apply(wallpaper_object, args)
args.background = args.background or beautiful.bg_normal or "black" args.background = args.background or beautiful.bg_normal or "black"
args.ignore_aspect = args.ignore_aspect or false -- false = keep aspect ratio args.ignore_aspect = args.ignore_aspect or false -- false = keep aspect ratio
args.offset = args.offset or {x = 0, y = 0} args.offset = args.offset or { x = 0, y = 0 }
args.scale = args.scale or 1 args.scale = args.scale or 1
local positions = { local positions = {
["centered"] = function() gears.wallpaper.centered(wallpaper_object, args.screen, args.background, args.scale) end, ["centered"] = function()
["tiled"] = function() gears.wallpaper.tiled(wallpaper_object, args.screen, args.offset) end, gears.wallpaper.centered(
["maximized"] = function() gears.wallpaper.maximized(wallpaper_object, args.screen, args.ignore_aspect, args.offset) end, wallpaper_object,
["fit"] = function() gears.wallpaper.fit(wallpaper_object, args.screen, args.background) end, args.screen,
args.background,
args.scale
)
end,
["tiled"] = function()
gears.wallpaper.tiled(wallpaper_object, args.screen, args.offset)
end,
["maximized"] = function()
gears.wallpaper.maximized(
wallpaper_object,
args.screen,
args.ignore_aspect,
args.offset
)
end,
["fit"] = function()
gears.wallpaper.fit(wallpaper_object, args.screen, args.background)
end,
} }
if type(wallpaper_object) == "string" and gears.filesystem.file_readable(wallpaper_object) then if
type(wallpaper_object) == "string"
and gears.filesystem.file_readable(wallpaper_object)
then
-- path of an image file, we use a position function -- path of an image file, we use a position function
local p = args.position or "centered" local p = args.position or "centered"
positions[p]() positions[p]()
elseif type(wallpaper_object) == "function" then elseif type(wallpaper_object) == "function" then
-- function -- function
wallpaper_object(args) wallpaper_object(args)
elseif (not gears.color.ensure_pango_color(wallpaper_object, nil)) and args.position then elseif
(not gears.color.ensure_pango_color(wallpaper_object, nil))
and args.position
then
-- if the user sets a position function, wallpaper_object should be a cairo surface -- if the user sets a position function, wallpaper_object should be a cairo surface
positions[args.position]() positions[args.position]()
else else
@ -92,15 +115,13 @@ end
-- @treturn table A list of `wallpaper_objects` (what `apply` can read). -- @treturn table A list of `wallpaper_objects` (what `apply` can read).
-- @see apply -- @see apply
function prepare_list(args) function prepare_list(args)
args.image_formats = args.image_formats or {"jpg", "jpeg", "png", "bmp"} args.image_formats = args.image_formats or { "jpg", "jpeg", "png", "bmp" }
args.recursive = args.recursive or true args.recursive = args.recursive or true
local wallpapers = (args.wallpaper local wallpapers = (args.wallpaper or beautiful.wallpaper_path or "black")
or beautiful.wallpaper_path
or "black")
local res = {} local res = {}
if type(wallpapers) ~= "table" then if type(wallpapers) ~= "table" then
wallpapers = {wallpapers} wallpapers = { wallpapers }
end end
for _, w in ipairs(wallpapers) do for _, w in ipairs(wallpapers) do
-- w is either: -- w is either:
@ -109,7 +130,11 @@ function prepare_list(args)
-- - a cairo surface or a cairo pattern -- - a cairo surface or a cairo pattern
-- - a function for setting the wallpaper -- - a function for setting the wallpaper
if type(w) == "string" and gears.filesystem.dir_readable(w) then if type(w) == "string" and gears.filesystem.dir_readable(w) then
local file_list = helpers.filesystem.list_directory_files(w, args.image_formats, args.recursive) local file_list = helpers.filesystem.list_directory_files(
w,
args.image_formats,
args.recursive
)
for _, f in ipairs(file_list) do for _, f in ipairs(file_list) do
res[#res + 1] = w .. "/" .. f res[#res + 1] = w .. "/" .. f
end end
@ -142,7 +167,6 @@ function setters.random(args)
apply(wallpapers[math.random(#wallpapers)], args) apply(wallpapers[math.random(#wallpapers)], args)
end end
local simple_schedule_object = nil local simple_schedule_object = nil
--- A schedule setter. --- A schedule setter.
-- --
@ -158,22 +182,31 @@ local simple_schedule_object = nil
-- @tparam[opt=`setters.simple`] function args.wallpaper_set_function The set_function used by default -- @tparam[opt=`setters.simple`] function args.wallpaper_set_function The set_function used by default
function setters.simple_schedule(args) function setters.simple_schedule(args)
local function update_wallpaper() local function update_wallpaper()
local fake_args = gears.table.join(args, {wallpaper = args.wallpaper[simple_schedule_object.closest_lower_time]}) local fake_args = gears.table.join(
args,
{
wallpaper = args.wallpaper[simple_schedule_object.closest_lower_time],
}
)
simple_schedule_object.schedule_set_function(fake_args) simple_schedule_object.schedule_set_function(fake_args)
end end
if not simple_schedule_object then if not simple_schedule_object then
simple_schedule_object = {} simple_schedule_object = {}
-- initialize the schedule object, so we don't do it for every call -- initialize the schedule object, so we don't do it for every call
simple_schedule_object.schedule_set_function = args.schedule_set_function or setters.simple simple_schedule_object.schedule_set_function = args.schedule_set_function
or setters.simple
-- we get the sorted time keys -- we get the sorted time keys
simple_schedule_object.times = {} simple_schedule_object.times = {}
for k in pairs(args.wallpaper) do table.insert(simple_schedule_object.times, k) end for k in pairs(args.wallpaper) do
table.insert(simple_schedule_object.times, k)
end
table.sort(simple_schedule_object.times) table.sort(simple_schedule_object.times)
-- now we get the closest time which is below current time (the current applicable period) -- now we get the closest time which is below current time (the current applicable period)
local function update_timer() local function update_timer()
local current_time = os.date("%H:%M:%S") local current_time = os.date("%H:%M:%S")
local next_time = simple_schedule_object.times[1] local next_time = simple_schedule_object.times[1]
simple_schedule_object.closest_lower_time = simple_schedule_object.times[#(simple_schedule_object.times)] simple_schedule_object.closest_lower_time =
simple_schedule_object.times[#simple_schedule_object.times]
for _, k in ipairs(simple_schedule_object.times) do for _, k in ipairs(simple_schedule_object.times) do
if k > current_time then if k > current_time then
next_time = k next_time = k
@ -181,17 +214,21 @@ function setters.simple_schedule(args)
end end
simple_schedule_object.closest_lower_time = k simple_schedule_object.closest_lower_time = k
end end
simple_schedule_object.timer.timeout = helpers.time.time_diff(next_time, current_time) simple_schedule_object.timer.timeout = helpers.time.time_diff(
next_time,
current_time
)
if simple_schedule_object.timer.timeout < 0 then if simple_schedule_object.timer.timeout < 0 then
-- the next_time is the day after, so we add 24 hours to the timer -- the next_time is the day after, so we add 24 hours to the timer
simple_schedule_object.timer.timeout = simple_schedule_object.timer.timeout + 86400 simple_schedule_object.timer.timeout = simple_schedule_object.timer.timeout
+ 86400
end end
simple_schedule_object.timer:again() simple_schedule_object.timer:again()
update_wallpaper() update_wallpaper()
end end
simple_schedule_object.timer = gears.timer { simple_schedule_object.timer = gears.timer({
callback = update_timer, callback = update_timer,
} })
update_timer() update_timer()
else else
-- if called again (usually when the change_timer is set), we just change the wallpaper depending on current parameters -- if called again (usually when the change_timer is set), we just change the wallpaper depending on current parameters
@ -199,10 +236,6 @@ function setters.simple_schedule(args)
end end
end end
--- Set the AWESOME wallpaper. --- Set the AWESOME wallpaper.
-- --
-- @tparam table args The argument table containing the argument below. -- @tparam table args The argument table containing the argument below.
@ -214,31 +247,43 @@ end
-- --
-- see beautiful.theme_assets.wallpaper -- see beautiful.theme_assets.wallpaper
function setters.awesome_wallpaper(args) function setters.awesome_wallpaper(args)
local colors = {bg = beautiful.bg_normal, fg = beautiful.fg_normal, alt_fg = beautiful.bg_focus } local colors = {
bg = beautiful.bg_normal,
fg = beautiful.fg_normal,
alt_fg = beautiful.bg_focus,
}
colors.bg = helpers.color.is_dark(beautiful.bg_normal) colors.bg = helpers.color.is_dark(beautiful.bg_normal)
and helpers.color.lighten(colors.bg) and helpers.color.lighten(colors.bg)
or helpers.color.darken(colors.bg) or helpers.color.darken(colors.bg)
if (type(args.colors) == "table") then if type(args.colors) == "table" then
colors.bg = args.colors.bg or colors.bg colors.bg = args.colors.bg or colors.bg
colors.fg = args.colors.fg or colors.fg colors.fg = args.colors.fg or colors.fg
colors.alt_fg = args.colors.alt_fg or colors.alt_fg colors.alt_fg = args.colors.alt_fg or colors.alt_fg
end end
-- Generate wallpaper: -- Generate wallpaper:
if not args.screen then if not args.screen then
for s in screen do for s in screen do
gears.wallpaper.set( gears.wallpaper.set(
beautiful.theme_assets.wallpaper(colors.bg, colors.fg, colors.alt_fg, s) beautiful.theme_assets.wallpaper(
colors.bg,
colors.fg,
colors.alt_fg,
s
)
) )
end end
else else
gears.wallpaper.set( gears.wallpaper.set(
beautiful.theme_assets.wallpaper(colors.bg, colors.fg, colors.alt_fg, args.screen) beautiful.theme_assets.wallpaper(
colors.bg,
colors.fg,
colors.alt_fg,
args.screen
)
) )
end end
end end
--- Setup a wallpaper. --- Setup a wallpaper.
-- --
-- @tparam table args Parameters for the wallpaper. It may also contain all parameters your `args.set_function` needs -- @tparam table args Parameters for the wallpaper. It may also contain all parameters your `args.set_function` needs
@ -265,30 +310,30 @@ end
-- @see setters.simple -- @see setters.simple
function setup(args) function setup(args)
local config = args or {} local config = args or {}
config.set_function = config.set_function or (config.wallpaper and setters.simple or setters.awesome_wallpaper) config.set_function = config.set_function
or (config.wallpaper and setters.simple or setters.awesome_wallpaper)
local function set_wallpaper(s) local function set_wallpaper(s)
config.screen = s or config.screen config.screen = s or config.screen
config.set_function(config) config.set_function(config)
end end
if config.change_timer and config.change_timer > 0 then if config.change_timer and config.change_timer > 0 then
gears.timer { gears.timer({
timeout = config.change_timer, timeout = config.change_timer,
call_now = false, call_now = false,
autostart = true, autostart = true,
callback = function() set_wallpaper() end callback = function()
} set_wallpaper()
end,
})
end end
if awesome.version == "v4.3" then if awesome.version == "v4.3" then
awful.screen.connect_for_each_screen(set_wallpaper) awful.screen.connect_for_each_screen(set_wallpaper)
else else
screen.connect_signal("request::wallpaper", set_wallpaper) screen.connect_signal("request::wallpaper", set_wallpaper)
end end
end end
return { return {
setup = setup, setup = setup,
setters = setters, setters = setters,

View File

@ -5,15 +5,16 @@ local beautiful = require("beautiful")
local helpers = require(tostring(...):match(".*bling") .. ".helpers") local helpers = require(tostring(...):match(".*bling") .. ".helpers")
-- It might actually swallow too much, that's why there is a filter option by classname -- It might actually swallow too much, that's why there is a filter option by classname
-- without the don't-swallow-list it would also swallow for example -- without the don't-swallow-list it would also swallow for example
-- file pickers or new firefox windows spawned by an already existing one -- file pickers or new firefox windows spawned by an already existing one
local window_swallowing_activated = false local window_swallowing_activated = false
-- you might want to add or remove applications here -- you might want to add or remove applications here
local dont_swallow_classname_list = beautiful.dont_swallow_classname_list or {"firefox", "Gimp", "Google-chrome"} local dont_swallow_classname_list = beautiful.dont_swallow_classname_list
local activate_dont_swallow_filter = beautiful.dont_swallow_filter_activated or true or { "firefox", "Gimp", "Google-chrome" }
local activate_dont_swallow_filter = beautiful.dont_swallow_filter_activated
or true
-- checks if client classname matches with any entry of the dont-swallow-list -- checks if client classname matches with any entry of the dont-swallow-list
local function check_if_swallow(c) local function check_if_swallow(c)
@ -31,16 +32,24 @@ end
-- the function that will be connected to / disconnected from the spawn client signal -- the function that will be connected to / disconnected from the spawn client signal
local function manage_clientspawn(c) local function manage_clientspawn(c)
-- get the last focused window to check if it is a parent window -- get the last focused window to check if it is a parent window
local parent_client=awful.client.focus.history.get(c.screen, 1) local parent_client = awful.client.focus.history.get(c.screen, 1)
if not parent_client then return end if not parent_client then
return
end
-- io.popen is normally discouraged. Should probably be changed -- io.popen is normally discouraged. Should probably be changed
local handle = io.popen([[pstree -T -p -a -s ]] .. tostring(c.pid) .. [[ | sed '2q;d' | grep -o '[0-9]*$' | tr -d '\n']]) local handle = io.popen(
[[pstree -T -p -a -s ]]
.. tostring(c.pid)
.. [[ | sed '2q;d' | grep -o '[0-9]*$' | tr -d '\n']]
)
local parent_pid = handle:read("*a") local parent_pid = handle:read("*a")
handle:close() handle:close()
if (tostring(parent_pid) == tostring(parent_client.pid)) and check_if_swallow(c) then if
(tostring(parent_pid) == tostring(parent_client.pid))
and check_if_swallow(c)
then
c:connect_signal("unmanage", function() c:connect_signal("unmanage", function()
helpers.client.turn_on(parent_client) helpers.client.turn_on(parent_client)
helpers.client.sync(parent_client, c) helpers.client.sync(parent_client, c)
@ -48,7 +57,6 @@ local function manage_clientspawn(c)
helpers.client.sync(c, parent_client) helpers.client.sync(c, parent_client)
helpers.client.turn_off(parent_client) helpers.client.turn_off(parent_client)
end end
end end
@ -58,12 +66,12 @@ end
local function start() local function start()
client.connect_signal("manage", manage_clientspawn) client.connect_signal("manage", manage_clientspawn)
window_swallowing_activated = true window_swallowing_activated = true
end end
local function stop() local function stop()
client.disconnect_signal("manage", manage_clientspawn) client.disconnect_signal("manage", manage_clientspawn)
window_swallowing_activated = false window_swallowing_activated = false
end end
local function toggle() local function toggle()
if window_swallowing_activated then if window_swallowing_activated then
@ -76,6 +84,5 @@ end
return { return {
start = start, start = start,
stop = stop, stop = stop,
toggle = toggle toggle = toggle,
} }

View File

@ -1 +1 @@
return {playerctl = require(... .. ".playerctl")} return { playerctl = require(... .. ".playerctl") }

View File

@ -4,7 +4,7 @@ local beautiful = require("beautiful")
local backend_config = beautiful.playerctl_backend or "playerctl_cli" local backend_config = beautiful.playerctl_backend or "playerctl_cli"
local backends = { local backends = {
playerctl_cli = require(... .. ".playerctl_cli"), playerctl_cli = require(... .. ".playerctl_cli"),
playerctl_lib = require(... .. ".playerctl_lib") playerctl_lib = require(... .. ".playerctl_lib"),
} }
local function enable_wrapper(args) local function enable_wrapper(args)
@ -16,4 +16,4 @@ local function disable_wrapper()
backends[backend_config].disable() backends[backend_config].disable()
end end
return {enable = enable_wrapper, disable = disable_wrapper} return { enable = enable_wrapper, disable = disable_wrapper }

View File

@ -21,7 +21,11 @@ local function emit_player_status()
-- Follow status -- Follow status
awful.spawn.easy_async({ awful.spawn.easy_async({
"pkill", "--full", "--uid", os.getenv("USER"), "^playerctl status" "pkill",
"--full",
"--uid",
os.getenv("USER"),
"^playerctl status",
}, function() }, function()
awful.spawn.with_line_callback(status_cmd, { awful.spawn.with_line_callback(status_cmd, {
stdout = function(line) stdout = function(line)
@ -32,7 +36,7 @@ local function emit_player_status()
playing = false playing = false
end end
awesome.emit_signal("bling::playerctl::status", playing) awesome.emit_signal("bling::playerctl::status", playing)
end end,
}) })
collectgarbage("collect") collectgarbage("collect")
end) end)
@ -75,8 +79,11 @@ echo "$tmp_cover_path"
local interval_sec = tonumber(interval) -- in seconds local interval_sec = tonumber(interval) -- in seconds
if length_sec and interval_sec then if length_sec and interval_sec then
if interval_sec >= 0 and length_sec > 0 then if interval_sec >= 0 and length_sec > 0 then
awesome.emit_signal("bling::playerctl::position", awesome.emit_signal(
interval_sec, length_sec / 1000000) "bling::playerctl::position",
interval_sec,
length_sec / 1000000
)
end end
end end
end) end)
@ -85,28 +92,35 @@ echo "$tmp_cover_path"
-- Follow title -- Follow title
awful.spawn.easy_async({ awful.spawn.easy_async({
"pkill", "--full", "--uid", os.getenv("USER"), "^playerctl metadata" "pkill",
"--full",
"--uid",
os.getenv("USER"),
"^playerctl metadata",
}, function() }, function()
awful.spawn.with_line_callback(song_follow_cmd, { awful.spawn.with_line_callback(song_follow_cmd, {
stdout = function(line) stdout = function(line)
local album_path = "" local album_path = ""
awful.spawn.easy_async_with_shell(art_script, function(out) awful.spawn.easy_async_with_shell(art_script, function(out)
-- Get album path -- Get album path
album_path = out:gsub('%\n', '') album_path = out:gsub("%\n", "")
-- Get title and artist -- Get title and artist
local artist = line:match('artist_(.*)title_') local artist = line:match("artist_(.*)title_")
local title = line:match('title_(.*)') local title = line:match("title_(.*)")
-- If the title is nil or empty then the players stopped -- If the title is nil or empty then the players stopped
if title and title ~= "" then if title and title ~= "" then
awesome.emit_signal( awesome.emit_signal(
"bling::playerctl::title_artist_album", title, "bling::playerctl::title_artist_album",
artist, album_path) title,
artist,
album_path
)
else else
awesome.emit_signal("bling::playerctl::no_players") awesome.emit_signal("bling::playerctl::no_players")
end end
end) end)
collectgarbage("collect") collectgarbage("collect")
end end,
}) })
collectgarbage("collect") collectgarbage("collect")
end) end)
@ -123,11 +137,15 @@ local enable = function(args)
end end
local disable = function() local disable = function()
awful.spawn.with_shell("pkill --full --uid " .. os.getenv("USER") .. awful.spawn.with_shell(
" '^playerctl status -F'") "pkill --full --uid " .. os.getenv("USER") .. " '^playerctl status -F'"
)
awful.spawn.with_shell("pkill --full --uid " .. os.getenv("USER") .. awful.spawn.with_shell(
" '^playerctl metadata --format'") "pkill --full --uid "
.. os.getenv("USER")
.. " '^playerctl metadata --format'"
)
end end
return {enable = enable, disable = disable} return { enable = enable, disable = disable }

View File

@ -39,10 +39,12 @@ local function position_cb()
local position = player:get_position() / 1000000 local position = player:get_position() / 1000000
local length = (player.metadata.value["mpris:length"] or 0) / 1000000 local length = (player.metadata.value["mpris:length"] or 0) / 1000000
if position ~= last_position or length ~= last_length then if position ~= last_position or length ~= last_length then
awesome.emit_signal("bling::playerctl::position", awesome.emit_signal(
position, "bling::playerctl::position",
length, position,
player.player_name) length,
player.player_name
)
last_position = position last_position = position
last_length = length last_length = length
end end
@ -50,7 +52,8 @@ local function position_cb()
end end
local function get_album_art(url) local function get_album_art(url)
return awful.util.shell .. [[ -c ' return awful.util.shell
.. [[ -c '
tmp_dir="$XDG_CACHE_HOME/awesome/" tmp_dir="$XDG_CACHE_HOME/awesome/"
@ -64,7 +67,9 @@ if [ ! -d "$tmp_dir" ]; then
mkdir -p $tmp_dir mkdir -p $tmp_dir
fi fi
curl -s ']] .. url .. [[' --output $tmp_cover_path curl -s ']]
.. url
.. [[' --output $tmp_cover_path
echo "$tmp_cover_path" echo "$tmp_cover_path"
']] ']]
@ -96,10 +101,15 @@ local function metadata_cb(player, metadata)
if player == manager.players[1] then if player == manager.players[1] then
-- Callback can be called even though values we care about haven't -- Callback can be called even though values we care about haven't
-- changed, so check to see if they have -- changed, so check to see if they have
if player ~= last_player or title ~= last_title or if
artist ~= last_artist or artUrl ~= last_artUrl player ~= last_player
or title ~= last_title
or artist ~= last_artist
or artUrl ~= last_artUrl
then then
if (title == "" and artist == "" and artUrl == "") then return end if title == "" and artist == "" and artUrl == "" then
return
end
if metadata_timer ~= nil then if metadata_timer ~= nil then
if metadata_timer.started then if metadata_timer.started then
@ -107,7 +117,7 @@ local function metadata_cb(player, metadata)
end end
end end
metadata_timer = gears.timer { metadata_timer = gears.timer({
timeout = 0.3, timeout = 0.3,
autostart = true, autostart = true,
single_shot = true, single_shot = true,
@ -122,7 +132,7 @@ local function metadata_cb(player, metadata)
line, line,
player.player_name player.player_name
) )
end end,
}) })
else else
awesome.emit_signal( awesome.emit_signal(
@ -133,8 +143,8 @@ local function metadata_cb(player, metadata)
player.player_name player.player_name
) )
end end
end end,
} })
-- Re-sync with position timer when track changes -- Re-sync with position timer when track changes
position_timer:again() position_timer:again()
@ -155,9 +165,17 @@ local function playback_status_cb(player, status)
if player == manager.players[1] then if player == manager.players[1] then
if status == "PLAYING" then if status == "PLAYING" then
awesome.emit_signal("bling::playerctl::status", true, player.player_name) awesome.emit_signal(
"bling::playerctl::status",
true,
player.player_name
)
else else
awesome.emit_signal("bling::playerctl::status", false, player.player_name) awesome.emit_signal(
"bling::playerctl::status",
false,
player.player_name
)
end end
end end
end end
@ -243,10 +261,10 @@ local function start_manager()
end end
-- Timer to update track position at specified interval -- Timer to update track position at specified interval
position_timer = gears.timer { position_timer = gears.timer({
timeout = interval, timeout = interval,
callback = position_cb callback = position_cb,
} })
-- Manage existing players on startup -- Manage existing players on startup
for _, name in ipairs(manager.player_names) do for _, name in ipairs(manager.player_names) do
@ -295,9 +313,10 @@ local function playerctl_enable(args)
-- Grab settings from beautiful variables if not set explicitly -- Grab settings from beautiful variables if not set explicitly
args.ignore = args.ignore or beautiful.playerctl_ignore args.ignore = args.ignore or beautiful.playerctl_ignore
args.player = args.player or beautiful.playerctl_player args.player = args.player or beautiful.playerctl_player
args.update_on_activity = args.update_on_activity or args.update_on_activity = args.update_on_activity
beautiful.playerctl_update_on_activity or beautiful.playerctl_update_on_activity
args.interval = args.interval or beautiful.playerctl_position_update_interval args.interval = args.interval
or beautiful.playerctl_position_update_interval
parse_args(args) parse_args(args)
-- Grab playerctl library -- Grab playerctl library
@ -328,4 +347,4 @@ local function playerctl_disable()
last_artUrl = "" last_artUrl = ""
end end
return {enable = playerctl_enable, disable = playerctl_disable} return { enable = playerctl_enable, disable = playerctl_disable }

View File

@ -4,10 +4,11 @@ This file has all theme variables of the bling module.
Every variable has a small comment on what it does. Every variable has a small comment on what it does.
You might just want to copy that whole part into your theme.lua and start adjusting from there. You might just want to copy that whole part into your theme.lua and start adjusting from there.
--]] -- LuaFormatter off --]]
-- LuaFormatter off
-- window swallowing -- window swallowing
theme.dont_swallow_classname_list = {"firefox", "Gimp"} -- list of class names that should not be swallowed theme.dont_swallow_classname_list = { "firefox", "Gimp" } -- list of class names that should not be swallowed
theme.dont_swallow_filter_activated = true -- whether the filter above should be active theme.dont_swallow_filter_activated = true -- whether the filter above should be active
-- flash focus -- flash focus
theme.flash_focus_start_opacity = 0.6 -- the starting opacity theme.flash_focus_start_opacity = 0.6 -- the starting opacity
@ -21,7 +22,7 @@ theme.playerctl_update_on_activity = true -- whether to prioritize the most rece
theme.playerctl_position_update_interval = 1 -- the update interval for fetching the position from playerctl theme.playerctl_position_update_interval = 1 -- the update interval for fetching the position from playerctl
-- tabbed -- tabbed
theme.tabbed_spawn_in_tab = false -- whether a new client should spawn into the focused tabbing container theme.tabbed_spawn_in_tab = false -- whether a new client should spawn into the focused tabbing container
-- tabbar general -- tabbar general
theme.tabbar_disable = false -- disable the tab bar entirely theme.tabbar_disable = false -- disable the tab bar entirely
@ -42,7 +43,7 @@ theme.mstab_dont_resize_slaves = false -- whether the tabbed stack windows shoul
-- currently focused stack window (set it to true if you use -- currently focused stack window (set it to true if you use
-- transparent terminals. False if you use shadows on solid ones -- transparent terminals. False if you use shadows on solid ones
theme.mstab_bar_padding = "default" -- how much padding there should be between clients and your tabbar theme.mstab_bar_padding = "default" -- how much padding there should be between clients and your tabbar
-- by default it will adjust based on your useless gaps. -- by default it will adjust based on your useless gaps.
-- If you want a custom value. Set it to the number of pixels (int) -- If you want a custom value. Set it to the number of pixels (int)
theme.mstab_border_radius = 0 -- border radius of the tabbar theme.mstab_border_radius = 0 -- border radius of the tabbar
theme.mstab_bar_height = 40 -- height of the tabbar theme.mstab_bar_height = 40 -- height of the tabbar
@ -51,7 +52,7 @@ theme.mstab_tabbar_style = "default" -- style of the tabbar ("default", "boxes"
-- defaults to the tabbar_style so only change if you want a -- defaults to the tabbar_style so only change if you want a
-- different style for mstab and tabbed -- different style for mstab and tabbed
-- the following variables are currently only for the "modern" tabbar style -- the following variables are currently only for the "modern" tabbar style
theme.tabbar_color_close = "#f9929b" -- changes the color of the close button theme.tabbar_color_close = "#f9929b" -- changes the color of the close button
theme.tabbar_color_min = "#fbdf90" -- changes the color of the minimize button theme.tabbar_color_min = "#fbdf90" -- changes the color of the minimize button
theme.tabbar_color_float = "#ccaced" -- changes the color of the float button theme.tabbar_color_float = "#ccaced" -- changes the color of the float button

View File

@ -1,5 +1,5 @@
return { return {
tag_preview = require(... .. ".tag_preview"), tag_preview = require(... .. ".tag_preview"),
task_preview = require(... .. ".task_preview"), task_preview = require(... .. ".task_preview"),
tabbed_misc = require(... .. ".tabbed_misc") tabbed_misc = require(... .. ".tabbed_misc"),
} }

View File

@ -6,16 +6,16 @@ local beautiful = require("beautiful")
local bg_normal = beautiful.tabbar_bg_normal or beautiful.bg_normal or "#ffffff" local bg_normal = beautiful.tabbar_bg_normal or beautiful.bg_normal or "#ffffff"
local fg_normal = beautiful.tabbar_fg_normal or beautiful.fg_normal or "#000000" local fg_normal = beautiful.tabbar_fg_normal or beautiful.fg_normal or "#000000"
local bg_focus = beautiful.tabbar_bg_focus or beautiful.bg_focus or "#000000" local bg_focus = beautiful.tabbar_bg_focus or beautiful.bg_focus or "#000000"
local fg_focus = beautiful.tabbar_fg_focus or beautiful.fg_focus or "#ffffff" local fg_focus = beautiful.tabbar_fg_focus or beautiful.fg_focus or "#ffffff"
local font = beautiful.tabbar_font or beautiful.font or "Hack 15" local font = beautiful.tabbar_font or beautiful.font or "Hack 15"
local size = beautiful.tabbar_size or 40 local size = beautiful.tabbar_size or 40
local position = beautiful.tabbar_position or "bottom" local position = beautiful.tabbar_position or "bottom"
local function create(c, focused_bool, buttons) local function create(c, focused_bool, buttons)
local bg_temp = bg_normal local bg_temp = bg_normal
local fg_temp = fg_normal local fg_temp = fg_normal
if focused_bool then if focused_bool then
bg_temp = bg_focus bg_temp = bg_focus
fg_temp = fg_focus fg_temp = fg_focus
end end
@ -25,21 +25,21 @@ local function create(c, focused_bool, buttons)
awful.widget.clienticon(c), awful.widget.clienticon(c),
left = 10, left = 10,
right = 10, right = 10,
bottom= 10, bottom = 10,
top= 10, top = 10,
widget = wibox.container.margin() widget = wibox.container.margin(),
}, },
widget = wibox.container.place() widget = wibox.container.place(),
}, },
buttons = buttons, buttons = buttons,
bg = bg_temp, bg = bg_temp,
widget = wibox.container.background() widget = wibox.container.background(),
}) })
return wid_temp return wid_temp
end end
local layout = wibox.layout.fixed.horizontal local layout = wibox.layout.fixed.horizontal
if position == "left" or position == "right" then if position == "left" or position == "right" then
layout = wibox.layout.fixed.vertical layout = wibox.layout.fixed.vertical
end end
@ -49,6 +49,5 @@ return {
position = position, position = position,
size = size, size = size,
bg_normal = bg_normal, bg_normal = bg_normal,
bg_focus = bg_normal bg_focus = bg_normal,
} }

View File

@ -5,10 +5,10 @@ local beautiful = require("beautiful")
local bg_normal = beautiful.tabbar_bg_normal or beautiful.bg_normal or "#ffffff" local bg_normal = beautiful.tabbar_bg_normal or beautiful.bg_normal or "#ffffff"
local fg_normal = beautiful.tabbar_fg_normal or beautiful.fg_normal or "#000000" local fg_normal = beautiful.tabbar_fg_normal or beautiful.fg_normal or "#000000"
local bg_focus = beautiful.tabbar_bg_focus or beautiful.bg_focus or "#000000" local bg_focus = beautiful.tabbar_bg_focus or beautiful.bg_focus or "#000000"
local fg_focus = beautiful.tabbar_fg_focus or beautiful.fg_focus or "#ffffff" local fg_focus = beautiful.tabbar_fg_focus or beautiful.fg_focus or "#ffffff"
local font = beautiful.tabbar_font or beautiful.font or "Hack 15" local font = beautiful.tabbar_font or beautiful.font or "Hack 15"
local size = beautiful.tabbar_size or 20 local size = beautiful.tabbar_size or 20
local position = beautiful.tabbar_position or "top" local position = beautiful.tabbar_position or "top"
local function create(c, focused_bool, buttons) local function create(c, focused_bool, buttons)
@ -16,7 +16,7 @@ local function create(c, focused_bool, buttons)
local title_temp = c.name or c.class or "-" local title_temp = c.name or c.class or "-"
local bg_temp = bg_normal local bg_temp = bg_normal
local fg_temp = fg_normal local fg_temp = fg_normal
if focused_bool then if focused_bool then
bg_temp = bg_focus bg_temp = bg_focus
fg_temp = fg_focus fg_temp = fg_focus
end end
@ -24,20 +24,27 @@ local function create(c, focused_bool, buttons)
text_temp.align = "center" text_temp.align = "center"
text_temp.valign = "center" text_temp.valign = "center"
text_temp.font = font text_temp.font = font
text_temp.markup = "<span foreground='" .. fg_temp .. "'>" .. title_temp.. "</span>" text_temp.markup = "<span foreground='"
.. fg_temp
.. "'>"
.. title_temp
.. "</span>"
c:connect_signal("property::name", function(_) c:connect_signal("property::name", function(_)
local title_temp = c.name or c.class or "-" local title_temp = c.name or c.class or "-"
text_temp.markup = "<span foreground='" .. fg_temp .. "'>" .. title_temp.. "</span>" text_temp.markup = "<span foreground='"
.. fg_temp
.. "'>"
.. title_temp
.. "</span>"
end) end)
local wid_temp = wibox.widget({ local wid_temp = wibox.widget({
text_temp, text_temp,
buttons = buttons, buttons = buttons,
bg = bg_temp, bg = bg_temp,
widget = wibox.container.background() widget = wibox.container.background(),
}) })
return wid_temp return wid_temp
end end
return { return {
layout = wibox.layout.flex.horizontal, layout = wibox.layout.flex.horizontal,
@ -45,5 +52,5 @@ return {
position = position, position = position,
size = size, size = size,
bg_normal = bg_normal, bg_normal = bg_normal,
bg_focus = bg_focus bg_focus = bg_focus,
} }

View File

@ -12,33 +12,36 @@ local bg_focus = beautiful.tabbar_bg_focus or beautiful.bg_focus or "#000000"
local fg_focus = beautiful.tabbar_fg_focus or beautiful.fg_focus or "#ffffff" local fg_focus = beautiful.tabbar_fg_focus or beautiful.fg_focus or "#ffffff"
local font = beautiful.tabbar_font or beautiful.font or "Hack 15" local font = beautiful.tabbar_font or beautiful.font or "Hack 15"
local size = beautiful.tabbar_size or dpi(40) local size = beautiful.tabbar_size or dpi(40)
local border_radius = local border_radius = beautiful.mstab_border_radius
beautiful.mstab_border_radius or beautiful.border_radius or 6 or beautiful.border_radius
or 6
local position = beautiful.tabbar_position or "top" local position = beautiful.tabbar_position or "top"
local close_color = beautiful.tabbar_color_close or beautiful.xcolor1 or local close_color = beautiful.tabbar_color_close
"#f9929b" or beautiful.xcolor1
or "#f9929b"
local min_color = beautiful.tabbar_color_min or beautiful.xcolor3 or "#fbdf90" local min_color = beautiful.tabbar_color_min or beautiful.xcolor3 or "#fbdf90"
local float_color = beautiful.tabbar_color_float or beautiful.xcolor5 or local float_color = beautiful.tabbar_color_float
"#ccaced" or beautiful.xcolor5
or "#ccaced"
-- Helper to create buttons -- Helper to create buttons
local function create_title_button(c, color_focus, color_unfocus) local function create_title_button(c, color_focus, color_unfocus)
local tb_color = wibox.widget { local tb_color = wibox.widget({
wibox.widget.textbox(), wibox.widget.textbox(),
forced_width = dpi(8), forced_width = dpi(8),
forced_height = dpi(8), forced_height = dpi(8),
bg = color_focus, bg = color_focus,
shape = gears.shape.circle, shape = gears.shape.circle,
widget = wibox.container.background widget = wibox.container.background,
} })
local tb = wibox.widget { local tb = wibox.widget({
tb_color, tb_color,
width = dpi(25), width = dpi(25),
height = dpi(25), height = dpi(25),
strategy = "min", strategy = "min",
layout = wibox.layout.constraint layout = wibox.layout.constraint,
} })
local function update() local function update()
if client.focus == c then if client.focus == c then
@ -51,10 +54,13 @@ local function create_title_button(c, color_focus, color_unfocus)
c:connect_signal("focus", update) c:connect_signal("focus", update)
c:connect_signal("unfocus", update) c:connect_signal("unfocus", update)
tb:connect_signal("mouse::enter", tb:connect_signal("mouse::enter", function()
function() tb_color.bg = color_focus .. "70" end) tb_color.bg = color_focus .. "70"
end)
tb:connect_signal("mouse::leave", function() tb_color.bg = color_focus end) tb:connect_signal("mouse::leave", function()
tb_color.bg = color_focus
end)
tb.visible = true tb.visible = true
return tb return tb
@ -73,58 +79,69 @@ local function create(c, focused_bool, buttons)
text_temp.align = "center" text_temp.align = "center"
text_temp.valign = "center" text_temp.valign = "center"
text_temp.font = font text_temp.font = font
text_temp.markup = "<span foreground='" .. fg_temp .. "'>" .. title_temp .. text_temp.markup = "<span foreground='"
"</span>" .. fg_temp
.. "'>"
.. title_temp
.. "</span>"
c:connect_signal("property::name", function(_) c:connect_signal("property::name", function(_)
local title_temp = c.name or c.class or "-" local title_temp = c.name or c.class or "-"
text_temp.markup = text_temp.markup = "<span foreground='"
"<span foreground='" .. fg_temp .. "'>" .. title_temp .. "</span>" .. fg_temp
.. "'>"
.. title_temp
.. "</span>"
end) end)
local tab_content = wibox.widget { local tab_content = wibox.widget({
{ {
awful.widget.clienticon(c), awful.widget.clienticon(c),
top = dpi(6), top = dpi(6),
left = dpi(15), left = dpi(15),
bottom = dpi(6), bottom = dpi(6),
widget = wibox.container.margin widget = wibox.container.margin,
}, },
text_temp, text_temp,
nill, nill,
expand = "none", expand = "none",
layout = wibox.layout.align.horizontal layout = wibox.layout.align.horizontal,
} })
local close = create_title_button(c, close_color, bg_normal) local close = create_title_button(c, close_color, bg_normal)
close:connect_signal("button::press", function() c:kill() end) close:connect_signal("button::press", function()
c:kill()
end)
local floating = create_title_button(c, float_color, bg_normal) local floating = create_title_button(c, float_color, bg_normal)
floating:connect_signal("button::press", floating:connect_signal("button::press", function()
function() c.floating = not c.floating end) c.floating = not c.floating
end)
local min = create_title_button(c, min_color, bg_normal) local min = create_title_button(c, min_color, bg_normal)
min:connect_signal("button::press", function() c.minimized = true end) min:connect_signal("button::press", function()
c.minimized = true
end)
if focused_bool then if focused_bool then
tab_content = wibox.widget { tab_content = wibox.widget({
{ {
awful.widget.clienticon(c), awful.widget.clienticon(c),
top = dpi(10), top = dpi(10),
left = dpi(15), left = dpi(15),
bottom = dpi(10), bottom = dpi(10),
widget = wibox.container.margin widget = wibox.container.margin,
}, },
text_temp, text_temp,
{ {
{min, floating, close, layout = wibox.layout.fixed.horizontal}, { min, floating, close, layout = wibox.layout.fixed.horizontal },
top = dpi(10), top = dpi(10),
right = dpi(10), right = dpi(10),
bottom = dpi(10), bottom = dpi(10),
widget = wibox.container.margin widget = wibox.container.margin,
}, },
expand = "none", expand = "none",
layout = wibox.layout.align.horizontal layout = wibox.layout.align.horizontal,
} })
end end
local main_content = nil local main_content = nil
@ -132,39 +149,69 @@ local function create(c, focused_bool, buttons)
local right_shape = nil local right_shape = nil
if position == "top" then if position == "top" then
main_content = wibox.widget { main_content = wibox.widget({
{ {
tab_content, tab_content,
bg = bg_temp, bg = bg_temp,
shape = helpers.shape.prrect(border_radius, true, true, false, shape = helpers.shape.prrect(
false), border_radius,
widget = wibox.container.background true,
true,
false,
false
),
widget = wibox.container.background,
}, },
top = dpi(8), top = dpi(8),
widget = wibox.container.margin widget = wibox.container.margin,
} })
left_shape = helpers.shape.prrect(border_radius, false, false, true, left_shape = helpers.shape.prrect(
false) border_radius,
right_shape = helpers.shape.prrect(border_radius, false, false, false, false,
true) false,
true,
false
)
right_shape = helpers.shape.prrect(
border_radius,
false,
false,
false,
true
)
else else
main_content = wibox.widget { main_content = wibox.widget({
{ {
tab_content, tab_content,
bg = bg_temp, bg = bg_temp,
shape = helpers.shape.prrect(border_radius, false, false, true, shape = helpers.shape.prrect(
true), border_radius,
widget = wibox.container.background false,
false,
true,
true
),
widget = wibox.container.background,
}, },
bottom = dpi(8), bottom = dpi(8),
widget = wibox.container.margin widget = wibox.container.margin,
} })
left_shape = helpers.shape.prrect(border_radius, false, true, false, left_shape = helpers.shape.prrect(
false) border_radius,
right_shape = helpers.shape.prrect(border_radius, true, false, false, false,
false) true,
false,
false
)
right_shape = helpers.shape.prrect(
border_radius,
true,
false,
false,
false
)
end end
local wid_temp = wibox.widget({ local wid_temp = wibox.widget({
@ -175,16 +222,16 @@ local function create(c, focused_bool, buttons)
wibox.widget.textbox(), wibox.widget.textbox(),
bg = bg_normal, bg = bg_normal,
shape = left_shape, shape = left_shape,
widget = wibox.container.background widget = wibox.container.background,
}, },
bg = bg_temp, bg = bg_temp,
shape = gears.rectangle, shape = gears.rectangle,
widget = wibox.container.background widget = wibox.container.background,
}, },
width = border_radius + (border_radius / 2), width = border_radius + (border_radius / 2),
height = size, height = size,
strategy = "exact", strategy = "exact",
layout = wibox.layout.constraint layout = wibox.layout.constraint,
}, },
main_content, main_content,
{ {
@ -193,19 +240,19 @@ local function create(c, focused_bool, buttons)
wibox.widget.textbox(), wibox.widget.textbox(),
bg = bg_normal, bg = bg_normal,
shape = right_shape, shape = right_shape,
widget = wibox.container.background widget = wibox.container.background,
}, },
bg = bg_temp, bg = bg_temp,
shape = gears.rectangle, shape = gears.rectangle,
widget = wibox.container.background widget = wibox.container.background,
}, },
width = border_radius + (border_radius / 2), width = border_radius + (border_radius / 2),
height = size, height = size,
strategy = "exact", strategy = "exact",
layout = wibox.layout.constraint layout = wibox.layout.constraint,
}, },
layout = wibox.layout.align.horizontal layout = wibox.layout.align.horizontal,
}) })
return wid_temp return wid_temp
end end
@ -216,5 +263,5 @@ return {
position = position, position = position,
size = size, size = size,
bg_normal = bg_normal, bg_normal = bg_normal,
bg_focus = bg_focus bg_focus = bg_focus,
} }

View File

@ -6,11 +6,11 @@ local beautiful = require("beautiful")
local bg_normal = beautiful.tabbar_bg_normal or beautiful.bg_normal or "#ffffff" local bg_normal = beautiful.tabbar_bg_normal or beautiful.bg_normal or "#ffffff"
local fg_normal = beautiful.tabbar_fg_normal or beautiful.fg_normal or "#000000" local fg_normal = beautiful.tabbar_fg_normal or beautiful.fg_normal or "#000000"
local bg_focus = beautiful.tabbar_bg_focus or beautiful.bg_focus or "#000000" local bg_focus = beautiful.tabbar_bg_focus or beautiful.bg_focus or "#000000"
local fg_focus = beautiful.tabbar_fg_focus or beautiful.fg_focus or "#ffffff" local fg_focus = beautiful.tabbar_fg_focus or beautiful.fg_focus or "#ffffff"
local font = beautiful.tabbar_font or beautiful.font or "Hack 15" local font = beautiful.tabbar_font or beautiful.font or "Hack 15"
local size = beautiful.tabbar_size or 20 local size = beautiful.tabbar_size or 20
local position = beautiful.tabbar_position or "top" local position = beautiful.tabbar_position or "top"
local function create(c, focused_bool, buttons) local function create(c, focused_bool, buttons)
local bg_temp = focused_bool and bg_focus or bg_normal local bg_temp = focused_bool and bg_focus or bg_normal
@ -19,40 +19,55 @@ local function create(c, focused_bool, buttons)
local wid_temp = wibox.widget({ local wid_temp = wibox.widget({
{ {
{ -- Left { -- Left
wibox.widget.base.make_widget(awful.titlebar.widget.iconwidget(c)), wibox.widget.base.make_widget(
awful.titlebar.widget.iconwidget(c)
),
buttons = buttons, buttons = buttons,
layout = wibox.layout.fixed.horizontal, layout = wibox.layout.fixed.horizontal,
}, },
{ -- Title { -- Title
wibox.widget.base.make_widget(awful.titlebar.widget.titlewidget(c)), wibox.widget.base.make_widget(
awful.titlebar.widget.titlewidget(c)
),
buttons = buttons, buttons = buttons,
widget = wibox.container.place, widget = wibox.container.place,
}, },
{ -- Right { -- Right
focused_bool and wibox.widget.base.make_widget(awful.titlebar.widget.floatingbutton(c)) or nil, focused_bool and wibox.widget.base.make_widget(
focused_bool and wibox.widget.base.make_widget(awful.titlebar.widget.stickybutton(c)) or nil, awful.titlebar.widget.floatingbutton(c)
focused_bool and wibox.widget.base.make_widget(awful.titlebar.widget.ontopbutton(c)) or nil, ) or nil,
focused_bool and wibox.widget.base.make_widget(awful.titlebar.widget.maximizedbutton(c)) or nil, focused_bool and wibox.widget.base.make_widget(
focused_bool and wibox.widget.base.make_widget(awful.titlebar.widget.minimizebutton(c)) or nil, awful.titlebar.widget.stickybutton(c)
focused_bool and wibox.widget.base.make_widget(awful.titlebar.widget.closebutton(c)) or nil, ) or nil,
focused_bool and wibox.widget.base.make_widget(
awful.titlebar.widget.ontopbutton(c)
) or nil,
focused_bool and wibox.widget.base.make_widget(
awful.titlebar.widget.maximizedbutton(c)
) or nil,
focused_bool and wibox.widget.base.make_widget(
awful.titlebar.widget.minimizebutton(c)
) or nil,
focused_bool and wibox.widget.base.make_widget(
awful.titlebar.widget.closebutton(c)
) or nil,
layout = wibox.layout.fixed.horizontal, layout = wibox.layout.fixed.horizontal,
}, },
layout = wibox.layout.align.horizontal, layout = wibox.layout.align.horizontal,
}, },
bg = bg_temp, bg = bg_temp,
fg = fg_temp, fg = fg_temp,
widget = wibox.container.background, widget = wibox.container.background,
}) })
return wid_temp return wid_temp
end end
return { return {
layout = wibox.layout.flex.horizontal, layout = wibox.layout.flex.horizontal,
create = create, create = create,
position = position, position = position,
size = size, size = size,
bg_normal = bg_normal, bg_normal = bg_normal,
bg_focus = bg_focus, bg_focus = bg_focus,
} }

View File

@ -1,7 +1,7 @@
local wibox = require('wibox') local wibox = require("wibox")
local awful = require('awful') local awful = require("awful")
local gears = require('gears') local gears = require("gears")
local beautiful = require('beautiful') local beautiful = require("beautiful")
local dpi = require("beautiful.xresources").apply_dpi local dpi = require("beautiful.xresources").apply_dpi
local function tabobj_support(self, c, index, clients) local function tabobj_support(self, c, index, clients)
@ -10,11 +10,10 @@ local function tabobj_support(self, c, index, clients)
return return
end end
local group = c.bling_tabbed local group = c.bling_tabbed
-- Single item tabbed group's dont get special rendering -- Single item tabbed group's dont get special rendering
if #group.clients > 1 then if #group.clients > 1 then
local wrapper = wibox.widget({ local wrapper = wibox.widget({
{ {
-- This is so dumb... but it works so meh -- This is so dumb... but it works so meh
@ -29,24 +28,27 @@ local function tabobj_support(self, c, index, clients)
spacing = dpi(2), spacing = dpi(2),
layout = wibox.layout.fixed.vertical, layout = wibox.layout.fixed.vertical,
}, },
id = 'click_role', id = "click_role",
widget = wibox.container.margin, widget = wibox.container.margin,
margins = dpi(5) margins = dpi(5),
}) })
for idx, c in ipairs(group.clients) do for idx, c in ipairs(group.clients) do
if c and c.icon then if c and c.icon then
-- TODO: Don't do this in a -1iq way -- TODO: Don't do this in a -1iq way
if idx <= 2 then if idx <= 2 then
wrapper:get_children_by_id("row1")[1]:add(awful.widget.clienticon(c)) wrapper
:get_children_by_id("row1")[1]
:add(awful.widget.clienticon(c))
else else
wrapper:get_children_by_id("row2")[1]:add(awful.widget.clienticon(c)) wrapper
:get_children_by_id("row2")[1]
:add(awful.widget.clienticon(c))
end end
end end
end end
self.widget = wrapper self.widget = wrapper
end end
end end

View File

@ -1,4 +1,9 @@
return { return {
titlebar_indicator = require(tostring(...):match(".*bling") .. ".widget.tabbed_misc.titlebar_indicator"), titlebar_indicator = require(
custom_tasklist = require(tostring(...):match(".*bling") .. ".widget.tabbed_misc.custom_tasklist") tostring(...):match(".*bling")
.. ".widget.tabbed_misc.titlebar_indicator"
),
custom_tasklist = require(
tostring(...):match(".*bling") .. ".widget.tabbed_misc.custom_tasklist"
),
} }

View File

@ -1,9 +1,11 @@
local wibox = require('wibox') local wibox = require("wibox")
local awful = require('awful') local awful = require("awful")
local gears = require('gears') local gears = require("gears")
local beautiful = require('beautiful') local beautiful = require("beautiful")
local dpi = require("beautiful.xresources").apply_dpi local dpi = require("beautiful.xresources").apply_dpi
local tabbed_module = require(tostring(...):match(".*bling") .. ".module.tabbed") local tabbed_module = require(
tostring(...):match(".*bling") .. ".module.tabbed"
)
-- Just check if a table contains a value. -- Just check if a table contains a value.
local function tbl_contains(tbl, item) local function tbl_contains(tbl, item)
@ -17,7 +19,6 @@ end
-- Needs to be run, every time a new titlbear is created -- Needs to be run, every time a new titlbear is created
return function(c, opts) return function(c, opts)
-- Args & Fallback -- Widget templates are in their original loactions -- Args & Fallback -- Widget templates are in their original loactions
opts = gears.table.crush({ opts = gears.table.crush({
layout_spacing = dpi(4), layout_spacing = dpi(4),
@ -25,8 +26,13 @@ return function(c, opts)
icon_margin = dpi(4), icon_margin = dpi(4),
bg_color_focus = "#ff0000", bg_color_focus = "#ff0000",
bg_color = "#00000000", bg_color = "#00000000",
icon_shape = function(cr,w,h) gears.shape.rounded_rect(cr,w,h,0) end icon_shape = function(cr, w, h)
}, gears.table.join(opts, beautiful.bling_tabbed_misc_titlebar_indicator)) gears.shape.rounded_rect(cr, w, h, 0)
end,
}, gears.table.join(
opts,
beautiful.bling_tabbed_misc_titlebar_indicator
))
-- Container to store icons -- Container to store icons
local tabbed_icons = wibox.widget({ local tabbed_icons = wibox.widget({
@ -34,25 +40,30 @@ return function(c, opts)
spacing = opts.layout_spacing, spacing = opts.layout_spacing,
}) })
awesome.connect_signal("bling::tabbed::client_removed", function(_, removed_c) awesome.connect_signal(
-- Remove from list "bling::tabbed::client_removed",
for idx, icon in ipairs(tabbed_icons.children) do function(_, removed_c)
if icon:get_children_by_id("icon_role")[1].client == removed_c then -- Remove from list
tabbed_icons:remove(idx) for idx, icon in ipairs(tabbed_icons.children) do
if
icon:get_children_by_id("icon_role")[1].client == removed_c
then
tabbed_icons:remove(idx)
end
end
-- Empty list
if removed_c == c then
tabbed_icons:reset()
end end
end end
)
-- Empty list
if removed_c == c then
tabbed_icons:reset()
end
end)
local function recreate(group) local function recreate(group)
if tbl_contains(group.clients, c) then if tbl_contains(group.clients, c) then
tabbed_icons:reset() tabbed_icons:reset()
local focused = group.clients[group.focused_idx] local focused = group.clients[group.focused_idx]
-- Autohide? -- Autohide?
if #group.clients == 1 then if #group.clients == 1 then
return return
@ -63,7 +74,7 @@ return function(c, opts)
{ {
{ {
{ {
id = 'icon_role', id = "icon_role",
forced_width = opts.icon_size, forced_width = opts.icon_size,
forced_height = opts.icon_size, forced_height = opts.icon_size,
widget = awful.widget.clienticon, widget = awful.widget.clienticon,
@ -71,9 +82,10 @@ return function(c, opts)
margins = opts.icon_margin, margins = opts.icon_margin,
widget = wibox.container.margin, widget = wibox.container.margin,
}, },
bg = (client == focused) and (opts.bg_color_focus) or (opts.bg_color), bg = (client == focused) and opts.bg_color_focus
or opts.bg_color,
shape = opts.icon_shape, shape = opts.icon_shape,
id = 'click_role', id = "click_role",
widget = wibox.container.background, widget = wibox.container.background,
}, },
halign = "center", halign = "center",
@ -90,7 +102,7 @@ return function(c, opts)
for _, w in ipairs(widget:get_children_by_id("click_role")) do for _, w in ipairs(widget:get_children_by_id("click_role")) do
w:add_button(awful.button({}, 1, function() w:add_button(awful.button({}, 1, function()
tabbed_module.switch_to(group,idx) tabbed_module.switch_to(group, idx)
end)) end))
end end
@ -101,7 +113,6 @@ return function(c, opts)
awesome.connect_signal("bling::tabbed::client_added", recreate) awesome.connect_signal("bling::tabbed::client_added", recreate)
awesome.connect_signal("bling::tabbed::changed_focus", recreate) awesome.connect_signal("bling::tabbed::changed_focus", recreate)
return tabbed_icons return tabbed_icons
end end

View File

@ -3,7 +3,7 @@
-- bling::tag_preview::update -- first line is the signal -- bling::tag_preview::update -- first line is the signal
-- t (tag) -- indented lines are function parameters -- t (tag) -- indented lines are function parameters
-- bling::tag_preview::visibility -- bling::tag_preview::visibility
-- s (screen) -- s (screen)
-- v (boolean) -- v (boolean)
-- --
local awful = require("awful") local awful = require("awful")
@ -14,26 +14,35 @@ local beautiful = require("beautiful")
local dpi = beautiful.xresources.apply_dpi local dpi = beautiful.xresources.apply_dpi
local cairo = require("lgi").cairo local cairo = require("lgi").cairo
local function draw_widget(t, tag_preview_image, scale, screen_radius, local function draw_widget(
client_radius, client_opacity, client_bg, t,
client_border_color, client_border_width, widget_bg, tag_preview_image,
widget_border_color, widget_border_width, geo, margin) scale,
screen_radius,
client_radius,
client_opacity,
client_bg,
client_border_color,
client_border_width,
widget_bg,
widget_border_color,
widget_border_width,
geo,
margin
)
local client_list = wibox.layout.manual() local client_list = wibox.layout.manual()
client_list.forced_height = geo.height client_list.forced_height = geo.height
client_list.forced_width = geo.width client_list.forced_width = geo.width
local tag_screen = t.screen local tag_screen = t.screen
for i, c in ipairs(t:clients()) do for i, c in ipairs(t:clients()) do
if not c.hidden and not c.minimized then if not c.hidden and not c.minimized then
local img_box = wibox.widget({
local img_box = wibox.widget {
image = gears.surface.load(c.icon), image = gears.surface.load(c.icon),
resize = true, resize = true,
forced_height = 100 * scale, forced_height = 100 * scale,
forced_width = 100 * scale, forced_width = 100 * scale,
widget = wibox.widget.imagebox widget = wibox.widget.imagebox,
} })
if tag_preview_image then if tag_preview_image then
if c.prev_content or t.selected then if c.prev_content or t.selected then
@ -45,25 +54,28 @@ local function draw_widget(t, tag_preview_image, scale, screen_radius,
end end
local cr = cairo.Context(content) local cr = cairo.Context(content)
local x, y, w, h = cr:clip_extents() local x, y, w, h = cr:clip_extents()
local img = cairo.ImageSurface.create(cairo.Format.ARGB32, local img = cairo.ImageSurface.create(
w - x, h - y) cairo.Format.ARGB32,
w - x,
h - y
)
cr = cairo.Context(img) cr = cairo.Context(img)
cr:set_source_surface(content, 0, 0) cr:set_source_surface(content, 0, 0)
cr.operator = cairo.Operator.SOURCE cr.operator = cairo.Operator.SOURCE
cr:paint() cr:paint()
img_box = wibox.widget { img_box = wibox.widget({
image = gears.surface.load(img), image = gears.surface.load(img),
resize = true, resize = true,
opacity = client_opacity, opacity = client_opacity,
forced_height = math.floor(c.height * scale), forced_height = math.floor(c.height * scale),
forced_width = math.floor(c.width * scale), forced_width = math.floor(c.width * scale),
widget = wibox.widget.imagebox widget = wibox.widget.imagebox,
} })
end end
end end
local client_box = wibox.widget { local client_box = wibox.widget({
{ {
nil, nil,
{ {
@ -71,11 +83,11 @@ local function draw_widget(t, tag_preview_image, scale, screen_radius,
img_box, img_box,
nil, nil,
expand = "outside", expand = "outside",
layout = wibox.layout.align.horizontal layout = wibox.layout.align.horizontal,
}, },
nil, nil,
expand = "outside", expand = "outside",
widget = wibox.layout.align.vertical widget = wibox.layout.align.vertical,
}, },
forced_height = math.floor(c.height * scale), forced_height = math.floor(c.height * scale),
forced_width = math.floor(c.width * scale), forced_width = math.floor(c.width * scale),
@ -83,12 +95,12 @@ local function draw_widget(t, tag_preview_image, scale, screen_radius,
shape_border_color = client_border_color, shape_border_color = client_border_color,
shape_border_width = client_border_width, shape_border_width = client_border_width,
shape = helpers.shape.rrect(client_radius), shape = helpers.shape.rrect(client_radius),
widget = wibox.container.background widget = wibox.container.background,
} })
client_box.point = { client_box.point = {
x = math.floor((c.x - geo.x) * scale), x = math.floor((c.x - geo.x) * scale),
y = math.floor((c.y - geo.y) * scale) y = math.floor((c.y - geo.y) * scale),
} }
client_list:add(client_box) client_list:add(client_box)
@ -103,22 +115,20 @@ local function draw_widget(t, tag_preview_image, scale, screen_radius,
client_list, client_list,
forced_height = geo.height, forced_height = geo.height,
forced_width = geo.width, forced_width = geo.width,
widget = wibox.container.place widget = wibox.container.place,
}, },
layout = wibox.layout.align.horizontal layout = wibox.layout.align.horizontal,
}, },
layout = wibox.layout.align.vertical layout = wibox.layout.align.vertical,
}, },
margins = margin, margins = margin,
widget = wibox.container.margin widget = wibox.container.margin,
}, },
bg = widget_bg, bg = widget_bg,
shape_border_width = widget_border_width, shape_border_width = widget_border_width,
shape_border_color = widget_border_color, shape_border_color = widget_border_color,
shape = helpers.shape.rrect(screen_radius), shape = helpers.shape.rrect(screen_radius),
widget = wibox.container.background widget = wibox.container.background,
} }
end end
@ -138,15 +148,15 @@ local enable = function(opts)
local client_radius = beautiful.tag_preview_client_border_radius or dpi(0) local client_radius = beautiful.tag_preview_client_border_radius or dpi(0)
local client_opacity = beautiful.tag_preview_client_opacity or 0.5 local client_opacity = beautiful.tag_preview_client_opacity or 0.5
local client_bg = beautiful.tag_preview_client_bg or "#000000" local client_bg = beautiful.tag_preview_client_bg or "#000000"
local client_border_color = beautiful.tag_preview_client_border_color or local client_border_color = beautiful.tag_preview_client_border_color
"#ffffff" or "#ffffff"
local client_border_width = beautiful.tag_preview_client_border_width or local client_border_width = beautiful.tag_preview_client_border_width
dpi(3) or dpi(3)
local widget_bg = beautiful.tag_preview_widget_bg or "#000000" local widget_bg = beautiful.tag_preview_widget_bg or "#000000"
local widget_border_color = beautiful.tag_preview_widget_border_color or local widget_border_color = beautiful.tag_preview_widget_border_color
"#ffffff" or "#ffffff"
local widget_border_width = beautiful.tag_preview_widget_border_width or local widget_border_width = beautiful.tag_preview_widget_border_width
dpi(3) or dpi(3)
local tag_preview_box = awful.popup({ local tag_preview_box = awful.popup({
type = "dropdown_menu", type = "dropdown_menu",
@ -155,7 +165,7 @@ local enable = function(opts)
placement = placement_fn, placement = placement_fn,
widget = wibox.container.background, widget = wibox.container.background,
input_passthrough = true, input_passthrough = true,
bg = "#00000000" bg = "#00000000",
}) })
tag.connect_signal("property::selected", function(t) tag.connect_signal("property::selected", function(t)
@ -165,20 +175,31 @@ local enable = function(opts)
end) end)
awesome.connect_signal("bling::tag_preview::update", function(t) awesome.connect_signal("bling::tag_preview::update", function(t)
local geo = t.screen:get_bounding_geometry{ local geo = t.screen:get_bounding_geometry({
honor_padding = padding, honor_padding = padding,
honor_workarea = work_area honor_workarea = work_area,
} })
tag_preview_box.maximum_width = scale * geo.width + margin * 2 tag_preview_box.maximum_width = scale * geo.width + margin * 2
tag_preview_box.maximum_height = scale * geo.height + margin * 2 tag_preview_box.maximum_height = scale * geo.height + margin * 2
tag_preview_box:setup(draw_widget(t, tag_preview_image, scale, tag_preview_box:setup(
screen_radius, client_radius, draw_widget(
client_opacity, client_bg, t,
client_border_color, tag_preview_image,
client_border_width, widget_bg, scale,
widget_border_color, screen_radius,
widget_border_width, geo, margin)) client_radius,
client_opacity,
client_bg,
client_border_color,
client_border_width,
widget_bg,
widget_border_color,
widget_border_width,
geo,
margin
)
)
end) end)
awesome.connect_signal("bling::tag_preview::visibility", function(s, v) awesome.connect_signal("bling::tag_preview::visibility", function(s, v)
@ -191,4 +212,4 @@ local enable = function(opts)
end) end)
end end
return {enable = enable} return { enable = enable }

View File

@ -14,11 +14,22 @@ local dpi = beautiful.xresources.apply_dpi
local cairo = require("lgi").cairo local cairo = require("lgi").cairo
-- TODO: rename structure to something better? -- TODO: rename structure to something better?
local function draw_widget(c, widget_template, screen_radius, widget_bg, local function draw_widget(
widget_border_color, widget_border_width, margin, c,
widget_width, widget_height) widget_template,
screen_radius,
if not pcall(function() return type(c.content) end) then return end widget_bg,
widget_border_color,
widget_border_width,
margin,
widget_width,
widget_height
)
if not pcall(function()
return type(c.content)
end) then
return
end
local content = gears.surface(c.content) local content = gears.surface(c.content)
local cr = cairo.Context(content) local cr = cairo.Context(content)
local x, y, w, h = cr:clip_extents() local x, y, w, h = cr:clip_extents()
@ -28,61 +39,61 @@ local function draw_widget(c, widget_template, screen_radius, widget_bg,
cr.operator = cairo.Operator.SOURCE cr.operator = cairo.Operator.SOURCE
cr:paint() cr:paint()
local widget = wibox.widget { local widget = wibox.widget({
(widget_template or { (widget_template or {
{ {
{ {
{ {
{ {
id = 'icon_role', id = "icon_role",
resize = true, resize = true,
forced_height = dpi(20), forced_height = dpi(20),
forced_width = dpi(20), forced_width = dpi(20),
widget = wibox.widget.imagebox widget = wibox.widget.imagebox,
}, },
{ {
{ {
id = 'name_role', id = "name_role",
align = "center", align = "center",
widget = wibox.widget.textbox widget = wibox.widget.textbox,
}, },
left = dpi(4), left = dpi(4),
right = dpi(4), right = dpi(4),
widget = wibox.container.margin widget = wibox.container.margin,
}, },
layout = wibox.layout.align.horizontal layout = wibox.layout.align.horizontal,
}, },
{ {
{ {
{ {
id = 'image_role', id = "image_role",
resize = true, resize = true,
clip_shape = helpers.shape.rrect(screen_radius), clip_shape = helpers.shape.rrect(screen_radius),
widget = wibox.widget.imagebox widget = wibox.widget.imagebox,
}, },
valign = "center", valign = "center",
halign = "center", halign = "center",
widget = wibox.container.place widget = wibox.container.place,
}, },
top = margin * 0.25, top = margin * 0.25,
widget = wibox.container.margin widget = wibox.container.margin,
}, },
fill_space = true, fill_space = true,
layout = wibox.layout.fixed.vertical layout = wibox.layout.fixed.vertical,
}, },
margins = margin, margins = margin,
widget = wibox.container.margin widget = wibox.container.margin,
}, },
bg = widget_bg, bg = widget_bg,
shape_border_width = widget_border_width, shape_border_width = widget_border_width,
shape_border_color = widget_border_color, shape_border_color = widget_border_color,
shape = helpers.shape.rrect(screen_radius), shape = helpers.shape.rrect(screen_radius),
widget = wibox.container.background widget = wibox.container.background,
}), }),
width = widget_width, width = widget_width,
height = widget_height, height = widget_height,
widget = wibox.container.constraint widget = wibox.container.constraint,
} })
-- TODO: have something like a create callback here? -- TODO: have something like a create callback here?
@ -102,7 +113,6 @@ local function draw_widget(c, widget_template, screen_radius, widget_bg,
end end
local enable = function(opts) local enable = function(opts)
local opts = opts or {} local opts = opts or {}
local widget_x = opts.x or dpi(20) local widget_x = opts.x or dpi(20)
@ -114,30 +124,35 @@ local enable = function(opts)
local margin = beautiful.task_preview_widget_margin or dpi(0) local margin = beautiful.task_preview_widget_margin or dpi(0)
local screen_radius = beautiful.task_preview_widget_border_radius or dpi(0) local screen_radius = beautiful.task_preview_widget_border_radius or dpi(0)
local widget_bg = beautiful.task_preview_widget_bg or "#000000" local widget_bg = beautiful.task_preview_widget_bg or "#000000"
local widget_border_color = beautiful.task_preview_widget_border_color or local widget_border_color = beautiful.task_preview_widget_border_color
"#ffffff" or "#ffffff"
local widget_border_width = beautiful.task_preview_widget_border_width or local widget_border_width = beautiful.task_preview_widget_border_width
dpi(3) or dpi(3)
local task_preview_box = awful.popup( local task_preview_box = awful.popup({
{ type = "dropdown_menu",
type = "dropdown_menu", visible = false,
visible = false, ontop = true,
ontop = true, placement = placement_fn,
placement = placement_fn, widget = wibox.container.background, -- A dummy widget to make awful.popup not scream
widget = wibox.container.background, -- A dummy widget to make awful.popup not scream input_passthrough = true,
input_passthrough = true, bg = "#00000000",
bg = "#00000000" })
})
awesome.connect_signal("bling::task_preview::visibility", function(s, v, c) awesome.connect_signal("bling::task_preview::visibility", function(s, v, c)
if v then if v then
-- Update task preview contents -- Update task preview contents
task_preview_box.widget = draw_widget(c, opts.structure, task_preview_box.widget = draw_widget(
screen_radius, widget_bg, c,
widget_border_color, opts.structure,
widget_border_width, margin, screen_radius,
widget_width, widget_height) widget_bg,
widget_border_color,
widget_border_width,
margin,
widget_width,
widget_height
)
end end
if not placement_fn then if not placement_fn then
@ -149,4 +164,4 @@ local enable = function(opts)
end) end)
end end
return {enable = enable} return { enable = enable }