I did something, Idk.
This commit is contained in:
parent
49e7c07657
commit
0a40308f90
|
@ -1,87 +1,127 @@
|
|||
--
|
||||
-- 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 cairo = require("lgi").cairo
|
||||
local awful = require("awful")
|
||||
local wibox = require("wibox")
|
||||
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 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 tag_preview = {mt = {}}
|
||||
|
||||
local function _get_widget_geometry(_hierarchy, widget)
|
||||
local width, height = _hierarchy:get_size()
|
||||
if _hierarchy:get_widget() == widget then
|
||||
-- Get the extents of this widget in the device space
|
||||
local x, y, w, h = gmatrix.transform_rectangle(
|
||||
_hierarchy:get_matrix_to_device(), 0, 0, width,
|
||||
height)
|
||||
return {x = x, y = y, width = w, height = h, hierarchy = _hierarchy}
|
||||
end
|
||||
|
||||
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 function 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
|
||||
)
|
||||
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
|
||||
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 ({
|
||||
local img_box = wibox.widget {
|
||||
resize = true,
|
||||
forced_height = 100 * scale,
|
||||
forced_width = 100 * scale,
|
||||
widget = wibox.widget.imagebox,
|
||||
})
|
||||
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 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
|
||||
-- If fails to set image, fallback to a awesome icon
|
||||
|
||||
if tag_preview_image then
|
||||
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
|
||||
local content
|
||||
local content = nil
|
||||
if t.selected then
|
||||
content = gears.surface(c.content)
|
||||
content = gsurface(c.content)
|
||||
else
|
||||
content = gears.surface(c.prev_content)
|
||||
content = gsurface(c.prev_content)
|
||||
end
|
||||
local cr = cairo.Context(content)
|
||||
local x, y, w, h = cr:clip_extents()
|
||||
local img = cairo.ImageSurface.create(
|
||||
cairo.Format.ARGB32,
|
||||
w - x,
|
||||
h - y
|
||||
)
|
||||
local 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()
|
||||
|
||||
img_box = wibox.widget({
|
||||
image = gears.surface.load(img),
|
||||
image = gsurface.load(img),
|
||||
resize = true,
|
||||
opacity = client_opacity,
|
||||
forced_height = math.floor(c.height * scale),
|
||||
forced_width = math.floor(c.width * scale),
|
||||
widget = wibox.widget.imagebox,
|
||||
opacity = args.client_opacity,
|
||||
forced_height = c.height * args.scale,
|
||||
forced_width = c.width * args.scale,
|
||||
widget = wibox.widget.imagebox
|
||||
})
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
local c_bg = args.client_bg
|
||||
|
||||
if c == capi.client.focus then
|
||||
c_bg = beautiful.xcolor4
|
||||
end
|
||||
|
||||
local client_box = wibox.widget({
|
||||
{
|
||||
nil,
|
||||
|
@ -90,157 +130,143 @@ local function draw_widget(
|
|||
img_box,
|
||||
nil,
|
||||
expand = "outside",
|
||||
layout = wibox.layout.align.horizontal,
|
||||
layout = wibox.layout.align.horizontal
|
||||
},
|
||||
nil,
|
||||
expand = "outside",
|
||||
widget = wibox.layout.align.vertical,
|
||||
widget = wibox.layout.align.vertical
|
||||
},
|
||||
forced_height = math.floor(c.height * scale),
|
||||
forced_width = math.floor(c.width * scale),
|
||||
bg = client_bg,
|
||||
shape_border_color = client_border_color,
|
||||
shape_border_width = client_border_width,
|
||||
shape = helpers.shape.rrect(client_radius),
|
||||
widget = wibox.container.background,
|
||||
forced_height = math.floor(c.height * args.scale),
|
||||
forced_width = math.floor(c.width * args.scale),
|
||||
bg = c_bg,
|
||||
shape_border_color = args.client_border_color,
|
||||
shape_border_width = args.client_border_width,
|
||||
shape = helpers.shape.rrect(args.client_border_radius),
|
||||
widget = wibox.container.background
|
||||
})
|
||||
|
||||
client_box.point = {
|
||||
x = math.floor((c.x - geo.x) * scale),
|
||||
y = math.floor((c.y - geo.y) * scale),
|
||||
x = math.floor((c.x - geo.x) * args.scale),
|
||||
y = math.floor((c.y - geo.y) * args.scale)
|
||||
}
|
||||
|
||||
client_list:add(client_box)
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
return wibox.widget {
|
||||
local w = wibox.widget {
|
||||
{
|
||||
background_image,
|
||||
args.background_image,
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
client_list,
|
||||
forced_height = geo.height,
|
||||
forced_width = geo.width,
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
layout = wibox.layout.align.vertical,
|
||||
client_list,
|
||||
forced_height = geo.height,
|
||||
forced_width = geo.width,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
margins = margin,
|
||||
widget = wibox.container.margin,
|
||||
margins = args.tag_margin,
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
layout = wibox.layout.stack
|
||||
},
|
||||
bg = widget_bg,
|
||||
shape_border_width = widget_border_width,
|
||||
shape_border_color = widget_border_color,
|
||||
shape = helpers.shape.rrect(screen_radius),
|
||||
widget = wibox.container.background,
|
||||
bg = args.tag_bg,
|
||||
shape_border_color = args.tag_border_color,
|
||||
shape_border_width = args.tag_border_width,
|
||||
shape = helpers.shape.rrect(args.tag_border_radius),
|
||||
widget = wibox.container.background
|
||||
}
|
||||
|
||||
self._private.widget.widget = w
|
||||
end
|
||||
|
||||
local enable = function(opts)
|
||||
local opts = opts or {}
|
||||
local function new(args)
|
||||
args = args or {}
|
||||
|
||||
local tag_preview_image = opts.show_client_content or false
|
||||
local widget_x = opts.x or dpi(20)
|
||||
local widget_y = opts.y or dpi(20)
|
||||
local scale = opts.scale or 0.2
|
||||
local work_area = opts.honor_workarea or false
|
||||
local padding = opts.honor_padding or false
|
||||
local placement_fn = opts.placement_fn or nil
|
||||
local background_image = opts.background_widget or nil
|
||||
args.type = args.type or "dropdown_menu"
|
||||
args.coords = args.coords or nil
|
||||
args.placement = args.placement or nil
|
||||
args.wibox = args.wibox
|
||||
args.widget = args.widget
|
||||
args.offset = args.offset or {}
|
||||
args.padding = args.padding
|
||||
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 screen_radius = beautiful.tag_preview_widget_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_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 ret = gobject {}
|
||||
ret._private = {}
|
||||
|
||||
local tag_preview_box = awful.popup({
|
||||
type = "dropdown_menu",
|
||||
gtable.crush(ret, tag_preview)
|
||||
gtable.crush(ret, args)
|
||||
|
||||
ret._private.widget = awful.popup({
|
||||
type = ret.type,
|
||||
visible = false,
|
||||
ontop = true,
|
||||
placement = placement_fn,
|
||||
widget = wibox.container.background,
|
||||
input_passthrough = true,
|
||||
placement = ret.placement,
|
||||
input_passthrough = ret.input_passthrough,
|
||||
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
|
||||
-- which can cause the c.content to not show the correct image
|
||||
gears.timer
|
||||
{
|
||||
gtimer {
|
||||
timeout = 0.1,
|
||||
call_now = false,
|
||||
call_now = false,
|
||||
autostart = true,
|
||||
single_shot = true,
|
||||
callback = function()
|
||||
if t.selected == true then
|
||||
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)
|
||||
|
||||
awesome.connect_signal("bling::tag_preview::update", function(t)
|
||||
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
|
||||
|
||||
if v == false then
|
||||
tag_preview_box.widget = nil
|
||||
collectgarbage("collect")
|
||||
end
|
||||
|
||||
tag_preview_box.visible = v
|
||||
end)
|
||||
return ret
|
||||
end
|
||||
|
||||
return {enable = enable, draw_widget = draw_widget}
|
||||
function tag_preview:get_widget() return self._private.widget.widget end
|
||||
|
||||
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")
|
||||
end
|
||||
|
||||
function tag_preview:toggle(t)
|
||||
if self._private.widget.visible == true then
|
||||
self:hide()
|
||||
else
|
||||
self:show(t)
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
if not pcall(function() return type(c.content) end) then return end
|
||||
|
||||
local content = nil
|
||||
if c.active then
|
||||
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 shoot = awful.screenshot {client = c}
|
||||
shoot:refresh()
|
||||
local ib = shoot.content_widget
|
||||
ib.resize = true
|
||||
|
||||
local widget = wibox.widget {
|
||||
(self.widget_template or {
|
||||
|
@ -104,12 +89,7 @@ function task_preview:show(c, args)
|
|||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
id = "image_role",
|
||||
resize = true,
|
||||
clip_shape = self.image_shape,
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
id = "image_container_role",
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.container.place
|
||||
|
@ -136,8 +116,8 @@ function task_preview:show(c, args)
|
|||
|
||||
-- TODO: have something like a create callback here?
|
||||
|
||||
for _, w in ipairs(widget:get_children_by_id("image_role")) do
|
||||
w.image = img -- TODO: copy it with gsurface.xxx or something
|
||||
for _, w in ipairs(widget:get_children_by_id("image_container_role")) do
|
||||
w.widget = ib -- TODO: copy it with gsurface.xxx or something
|
||||
end
|
||||
|
||||
for _, w in ipairs(widget:get_children_by_id("name_role")) do
|
||||
|
|
Loading…
Reference in New Issue