I did something, Idk.
This commit is contained in:
parent
49e7c07657
commit
0a40308f90
|
@ -1,87 +1,127 @@
|
||||||
--
|
local cairo = require("lgi").cairo
|
||||||
-- Provides:
|
|
||||||
-- bling::tag_preview::update -- first line is the signal
|
|
||||||
-- t (tag) -- indented lines are function parameters
|
|
||||||
-- bling::tag_preview::visibility
|
|
||||||
-- s (screen)
|
|
||||||
-- v (boolean)
|
|
||||||
--
|
|
||||||
local awful = require("awful")
|
local awful = require("awful")
|
||||||
local wibox = require("wibox")
|
local wibox = require("wibox")
|
||||||
local helpers = require(tostring(...):match(".*bling") .. ".helpers")
|
local helpers = require(tostring(...):match(".*bling") .. ".helpers")
|
||||||
local gears = require("gears")
|
local gobject = require("gears.object")
|
||||||
|
local gtable = require("gears.table")
|
||||||
|
local gtimer = require("gears.timer")
|
||||||
|
local gmatrix = require("gears.matrix")
|
||||||
|
local gsurface = require("gears.surface")
|
||||||
local beautiful = require("beautiful")
|
local beautiful = require("beautiful")
|
||||||
local dpi = beautiful.xresources.apply_dpi
|
local dpi = beautiful.xresources.apply_dpi
|
||||||
local cairo = require("lgi").cairo
|
local collectgarbage = collectgarbage
|
||||||
|
local ipairs = ipairs
|
||||||
|
local pcall = pcall
|
||||||
|
local capi = {client = client, tag = tag}
|
||||||
|
|
||||||
local function draw_widget(
|
local tag_preview = {mt = {}}
|
||||||
t,
|
|
||||||
tag_preview_image,
|
|
||||||
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,
|
|
||||||
background_image
|
|
||||||
)
|
|
||||||
local client_list = wibox.layout.manual()
|
|
||||||
client_list.forced_height = geo.height
|
|
||||||
client_list.forced_width = geo.width
|
|
||||||
local tag_screen = t.screen
|
|
||||||
for i, c in ipairs(t:clients()) do
|
|
||||||
if not c.hidden and not c.minimized then
|
|
||||||
|
|
||||||
|
local function _get_widget_geometry(_hierarchy, widget)
|
||||||
local img_box = wibox.widget ({
|
local width, height = _hierarchy:get_size()
|
||||||
resize = true,
|
if _hierarchy:get_widget() == widget then
|
||||||
forced_height = 100 * scale,
|
-- Get the extents of this widget in the device space
|
||||||
forced_width = 100 * scale,
|
local x, y, w, h = gmatrix.transform_rectangle(
|
||||||
widget = wibox.widget.imagebox,
|
_hierarchy:get_matrix_to_device(), 0, 0, width,
|
||||||
})
|
height)
|
||||||
|
return {x = x, y = y, width = w, height = h, hierarchy = _hierarchy}
|
||||||
-- If fails to set image, fallback to a awesome icon
|
|
||||||
if not pcall(function() img_box.image = gears.surface.load(c.icon) end) then
|
|
||||||
img_box.image = beautiful.theme_assets.awesome_icon (24, "#222222", "#fafafa")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if tag_preview_image then
|
for _, child in ipairs(_hierarchy:get_children()) do
|
||||||
|
local ret = _get_widget_geometry(child, widget)
|
||||||
|
if ret then return ret end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_widget_geometry(wibox, widget)
|
||||||
|
return _get_widget_geometry(wibox._drawable._widget_hierarchy, widget)
|
||||||
|
end
|
||||||
|
|
||||||
|
function tag_preview:update(t)
|
||||||
|
local args = self
|
||||||
|
|
||||||
|
if not args.coords and args.wibox and args.widget then
|
||||||
|
args.coords = get_widget_geometry(args.wibox, args.widget)
|
||||||
|
if args.offset.x ~= nil then
|
||||||
|
args.coords.x = args.coords.x + args.offset.x
|
||||||
|
end
|
||||||
|
if args.offset.y ~= nil then
|
||||||
|
args.coords.y = args.coords.y + args.offset.y
|
||||||
|
end
|
||||||
|
|
||||||
|
self._private.widget.x = args.coords.x
|
||||||
|
self._private.widget.y = args.coords.y
|
||||||
|
end
|
||||||
|
|
||||||
|
local geo = t.screen:get_bounding_geometry({
|
||||||
|
honor_padding = args.padding,
|
||||||
|
honor_workarea = args.work_area
|
||||||
|
})
|
||||||
|
|
||||||
|
self._private.widget.maximum_width =
|
||||||
|
args.scale * geo.width + args.margin * 2
|
||||||
|
self._private.widget.maximum_height =
|
||||||
|
args.scale * geo.height + args.margin * 2
|
||||||
|
|
||||||
|
local client_list = wibox.layout.manual()
|
||||||
|
client_list.forced_height = geo.height
|
||||||
|
client_list.forced_width = geo.widget
|
||||||
|
|
||||||
|
for _, c in ipairs(t:clients()) do
|
||||||
|
if not c.hidden and not c.minimized then
|
||||||
|
local img_box = wibox.widget {
|
||||||
|
resize = true,
|
||||||
|
forced_height = 100 * args.scale,
|
||||||
|
forced_width = 100 * args.scale,
|
||||||
|
widget = wibox.widget.imagebox
|
||||||
|
}
|
||||||
|
|
||||||
|
-- If fails to set image, fallback to a awesome icon
|
||||||
|
|
||||||
|
if args.client_icon then
|
||||||
|
if not pcall(function()
|
||||||
|
img_box.image = gsurface.load(c.icon)
|
||||||
|
end) then
|
||||||
|
img_box.image = beautiful.theme_assets.awesome_icon(24,
|
||||||
|
"#222222",
|
||||||
|
"#fafafa")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if args.tag_preview_image then
|
||||||
if c.prev_content or t.selected then
|
if c.prev_content or t.selected then
|
||||||
local content
|
local content = nil
|
||||||
if t.selected then
|
if t.selected then
|
||||||
content = gears.surface(c.content)
|
content = gsurface(c.content)
|
||||||
else
|
else
|
||||||
content = gears.surface(c.prev_content)
|
content = gsurface(c.prev_content)
|
||||||
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(
|
local img = cairo.ImageSurface.create(cairo.Format.ARGB32,
|
||||||
cairo.Format.ARGB32,
|
w - x, h - y)
|
||||||
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 = gsurface.load(img),
|
||||||
resize = true,
|
resize = true,
|
||||||
opacity = client_opacity,
|
opacity = args.client_opacity,
|
||||||
forced_height = math.floor(c.height * scale),
|
forced_height = c.height * args.scale,
|
||||||
forced_width = math.floor(c.width * scale),
|
forced_width = c.width * args.scale,
|
||||||
widget = wibox.widget.imagebox,
|
widget = wibox.widget.imagebox
|
||||||
})
|
})
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local c_bg = args.client_bg
|
||||||
|
|
||||||
|
if c == capi.client.focus then
|
||||||
|
c_bg = beautiful.xcolor4
|
||||||
|
end
|
||||||
|
|
||||||
local client_box = wibox.widget({
|
local client_box = wibox.widget({
|
||||||
{
|
{
|
||||||
nil,
|
nil,
|
||||||
|
@ -90,101 +130,105 @@ local function draw_widget(
|
||||||
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 * args.scale),
|
||||||
forced_width = math.floor(c.width * scale),
|
forced_width = math.floor(c.width * args.scale),
|
||||||
bg = client_bg,
|
bg = c_bg,
|
||||||
shape_border_color = client_border_color,
|
shape_border_color = args.client_border_color,
|
||||||
shape_border_width = client_border_width,
|
shape_border_width = args.client_border_width,
|
||||||
shape = helpers.shape.rrect(client_radius),
|
shape = helpers.shape.rrect(args.client_border_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) * args.scale),
|
||||||
y = math.floor((c.y - geo.y) * scale),
|
y = math.floor((c.y - geo.y) * args.scale)
|
||||||
}
|
}
|
||||||
|
|
||||||
client_list:add(client_box)
|
client_list:add(client_box)
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return wibox.widget {
|
local w = wibox.widget {
|
||||||
{
|
|
||||||
background_image,
|
|
||||||
{
|
|
||||||
{
|
{
|
||||||
|
args.background_image,
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
client_list,
|
client_list,
|
||||||
forced_height = geo.height,
|
forced_height = geo.height,
|
||||||
forced_width = geo.width,
|
forced_width = geo.width,
|
||||||
widget = wibox.container.place,
|
valign = "center",
|
||||||
|
halign = "center",
|
||||||
|
widget = wibox.container.place
|
||||||
},
|
},
|
||||||
layout = wibox.layout.align.horizontal,
|
margins = args.tag_margin,
|
||||||
},
|
widget = wibox.container.margin
|
||||||
layout = wibox.layout.align.vertical,
|
|
||||||
},
|
|
||||||
margins = margin,
|
|
||||||
widget = wibox.container.margin,
|
|
||||||
},
|
},
|
||||||
layout = wibox.layout.stack
|
layout = wibox.layout.stack
|
||||||
},
|
},
|
||||||
bg = widget_bg,
|
bg = args.tag_bg,
|
||||||
shape_border_width = widget_border_width,
|
shape_border_color = args.tag_border_color,
|
||||||
shape_border_color = widget_border_color,
|
shape_border_width = args.tag_border_width,
|
||||||
shape = helpers.shape.rrect(screen_radius),
|
shape = helpers.shape.rrect(args.tag_border_radius),
|
||||||
widget = wibox.container.background,
|
widget = wibox.container.background
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self._private.widget.widget = w
|
||||||
end
|
end
|
||||||
|
|
||||||
local enable = function(opts)
|
local function new(args)
|
||||||
local opts = opts or {}
|
args = args or {}
|
||||||
|
|
||||||
local tag_preview_image = opts.show_client_content or false
|
args.type = args.type or "dropdown_menu"
|
||||||
local widget_x = opts.x or dpi(20)
|
args.coords = args.coords or nil
|
||||||
local widget_y = opts.y or dpi(20)
|
args.placement = args.placement or nil
|
||||||
local scale = opts.scale or 0.2
|
args.wibox = args.wibox
|
||||||
local work_area = opts.honor_workarea or false
|
args.widget = args.widget
|
||||||
local padding = opts.honor_padding or false
|
args.offset = args.offset or {}
|
||||||
local placement_fn = opts.placement_fn or nil
|
args.padding = args.padding
|
||||||
local background_image = opts.background_widget or nil
|
args.work_area = args.work_area
|
||||||
|
args.scale = args.scale or 0.2
|
||||||
|
args.margin = args.margin or dpi(0)
|
||||||
|
args.client_icon = args.client_icon
|
||||||
|
args.client_opacity = args.client_opacity or 0
|
||||||
|
args.client_bg = args.client_bg or "#000000"
|
||||||
|
args.client_border_color = args.client_border_color or "#ffffff"
|
||||||
|
args.client_border_width = args.client_border_width or dpi(1)
|
||||||
|
args.client_border_radius = args.client_border_radius or dpi(0)
|
||||||
|
args.tag_margin = args.tag_margin or dpi(0)
|
||||||
|
args.tag_bg = args.tag_bg or "#000000"
|
||||||
|
args.tag_border_color = args.tag_border_color or "#ffffff"
|
||||||
|
args.tag_border_width = args.tag_border_width or dpi(0)
|
||||||
|
args.tag_border_radius = args.tag_border_radius or dpi(0)
|
||||||
|
args.background_image = args.background_image or nil
|
||||||
|
args.tag_preview_image = args.tag_preview_image
|
||||||
|
|
||||||
local margin = beautiful.tag_preview_widget_margin or dpi(0)
|
local ret = gobject {}
|
||||||
local screen_radius = beautiful.tag_preview_widget_border_radius or dpi(0)
|
ret._private = {}
|
||||||
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_bg = beautiful.tag_preview_client_bg or "#000000"
|
|
||||||
local client_border_color = beautiful.tag_preview_client_border_color
|
|
||||||
or "#ffffff"
|
|
||||||
local client_border_width = beautiful.tag_preview_client_border_width
|
|
||||||
or dpi(3)
|
|
||||||
local widget_bg = beautiful.tag_preview_widget_bg or "#000000"
|
|
||||||
local widget_border_color = beautiful.tag_preview_widget_border_color
|
|
||||||
or "#ffffff"
|
|
||||||
local widget_border_width = beautiful.tag_preview_widget_border_width
|
|
||||||
or dpi(3)
|
|
||||||
|
|
||||||
local tag_preview_box = awful.popup({
|
gtable.crush(ret, tag_preview)
|
||||||
type = "dropdown_menu",
|
gtable.crush(ret, args)
|
||||||
|
|
||||||
|
ret._private.widget = awful.popup({
|
||||||
|
type = ret.type,
|
||||||
visible = false,
|
visible = false,
|
||||||
ontop = true,
|
ontop = true,
|
||||||
placement = placement_fn,
|
placement = ret.placement,
|
||||||
widget = wibox.container.background,
|
input_passthrough = ret.input_passthrough,
|
||||||
input_passthrough = true,
|
|
||||||
bg = "#00000000",
|
bg = "#00000000",
|
||||||
|
widget = wibox.container.background -- A dummy widget to make awful.popup not scream
|
||||||
})
|
})
|
||||||
|
|
||||||
tag.connect_signal("property::selected", function(t)
|
capi.tag.connect_signal("property::selected", function(t)
|
||||||
-- Awesome switches up tags on startup really fast it seems, probably depends on what rules you have set
|
-- Awesome switches up tags on startup really fast it seems, probably depends on what rules you have set
|
||||||
-- which can cause the c.content to not show the correct image
|
-- which can cause the c.content to not show the correct image
|
||||||
gears.timer
|
gtimer {
|
||||||
{
|
|
||||||
timeout = 0.1,
|
timeout = 0.1,
|
||||||
call_now = false,
|
call_now = false,
|
||||||
autostart = true,
|
autostart = true,
|
||||||
|
@ -192,55 +236,37 @@ local enable = function(opts)
|
||||||
callback = function()
|
callback = function()
|
||||||
if t.selected == true then
|
if t.selected == true then
|
||||||
for _, c in ipairs(t:clients()) do
|
for _, c in ipairs(t:clients()) do
|
||||||
c.prev_content = gears.surface.duplicate_surface(c.content)
|
c.prev_content = gsurface.duplicate_surface(c.content)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
awesome.connect_signal("bling::tag_preview::update", function(t)
|
return ret
|
||||||
local geo = t.screen:get_bounding_geometry({
|
|
||||||
honor_padding = padding,
|
|
||||||
honor_workarea = work_area,
|
|
||||||
})
|
|
||||||
|
|
||||||
tag_preview_box.maximum_width = scale * geo.width + margin * 2
|
|
||||||
tag_preview_box.maximum_height = scale * geo.height + margin * 2
|
|
||||||
|
|
||||||
|
|
||||||
tag_preview_box.widget = draw_widget(
|
|
||||||
t,
|
|
||||||
tag_preview_image,
|
|
||||||
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,
|
|
||||||
background_image
|
|
||||||
)
|
|
||||||
end)
|
|
||||||
|
|
||||||
awesome.connect_signal("bling::tag_preview::visibility", function(s, v)
|
|
||||||
if not placement_fn then
|
|
||||||
tag_preview_box.x = s.geometry.x + widget_x
|
|
||||||
tag_preview_box.y = s.geometry.y + widget_y
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if v == false then
|
function tag_preview:get_widget() return self._private.widget.widget end
|
||||||
tag_preview_box.widget = nil
|
|
||||||
|
function tag_preview:show(t)
|
||||||
|
self:update(t)
|
||||||
|
self._private.widget.visible = true
|
||||||
|
end
|
||||||
|
|
||||||
|
function tag_preview:hide()
|
||||||
|
self._private.widget.visible = false
|
||||||
|
self._private.widget.widget = nil
|
||||||
collectgarbage("collect")
|
collectgarbage("collect")
|
||||||
end
|
end
|
||||||
|
|
||||||
tag_preview_box.visible = v
|
function tag_preview:toggle(t)
|
||||||
end)
|
if self._private.widget.visible == true then
|
||||||
|
self:hide()
|
||||||
|
else
|
||||||
|
self:show(t)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return {enable = enable, draw_widget = draw_widget}
|
function tag_preview.mt:__call(...) return new(...) end
|
||||||
|
|
||||||
|
return setmetatable(tag_preview, tag_preview.mt)
|
||||||
|
|
|
@ -58,25 +58,10 @@ function task_preview:show(c, args)
|
||||||
self._private.widget.y = args.coords.y
|
self._private.widget.y = args.coords.y
|
||||||
end
|
end
|
||||||
|
|
||||||
if not pcall(function() return type(c.content) end) then return end
|
local shoot = awful.screenshot {client = c}
|
||||||
|
shoot:refresh()
|
||||||
local content = nil
|
local ib = shoot.content_widget
|
||||||
if c.active then
|
ib.resize = true
|
||||||
content = gsurface(c.content)
|
|
||||||
elseif c.prev_content then
|
|
||||||
content = gsurface(c.prev_content)
|
|
||||||
end
|
|
||||||
|
|
||||||
local img = nil
|
|
||||||
if content ~= nil then
|
|
||||||
local cr = cairo.Context(content)
|
|
||||||
local x, y, w, h = cr:clip_extents()
|
|
||||||
img = cairo.ImageSurface.create(cairo.Format.ARGB32, w - x, h - y)
|
|
||||||
cr = cairo.Context(img)
|
|
||||||
cr:set_source_surface(content, 0, 0)
|
|
||||||
cr.operator = cairo.Operator.SOURCE
|
|
||||||
cr:paint()
|
|
||||||
end
|
|
||||||
|
|
||||||
local widget = wibox.widget {
|
local widget = wibox.widget {
|
||||||
(self.widget_template or {
|
(self.widget_template or {
|
||||||
|
@ -104,12 +89,7 @@ function task_preview:show(c, args)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
{
|
id = "image_container_role",
|
||||||
id = "image_role",
|
|
||||||
resize = true,
|
|
||||||
clip_shape = self.image_shape,
|
|
||||||
widget = wibox.widget.imagebox
|
|
||||||
},
|
|
||||||
valign = "center",
|
valign = "center",
|
||||||
halign = "center",
|
halign = "center",
|
||||||
widget = wibox.container.place
|
widget = wibox.container.place
|
||||||
|
@ -136,8 +116,8 @@ function task_preview:show(c, args)
|
||||||
|
|
||||||
-- TODO: have something like a create callback here?
|
-- TODO: have something like a create callback here?
|
||||||
|
|
||||||
for _, w in ipairs(widget:get_children_by_id("image_role")) do
|
for _, w in ipairs(widget:get_children_by_id("image_container_role")) do
|
||||||
w.image = img -- TODO: copy it with gsurface.xxx or something
|
w.widget = ib -- TODO: copy it with gsurface.xxx or something
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, w in ipairs(widget:get_children_by_id("name_role")) do
|
for _, w in ipairs(widget:get_children_by_id("name_role")) do
|
||||||
|
|
Loading…
Reference in New Issue