From 7456184ca8e673842e8560b1d8f46dd82067c64e Mon Sep 17 00:00:00 2001 From: Gokul Swami Date: Sun, 4 Apr 2021 00:49:41 -0700 Subject: [PATCH] Add tag preview widget --- init.lua | 3 +- widget/init.lua | 1 + widget/tag_preview.lua | 180 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 widget/init.lua create mode 100644 widget/tag_preview.lua diff --git a/init.lua b/init.lua index 0ac3478..b04983e 100644 --- a/init.lua +++ b/init.lua @@ -5,5 +5,6 @@ layout = require(... .. ".layout"), module = require(... .. ".module"), helpers = require(... .. ".helpers"), - signal = require(... .. ".signal") + signal = require(... .. ".signal"), + widget = require(... .. ".widget") } diff --git a/widget/init.lua b/widget/init.lua new file mode 100644 index 0000000..fdfd047 --- /dev/null +++ b/widget/init.lua @@ -0,0 +1 @@ +return {tag_preview = require(... .. ".tag_preview")} diff --git a/widget/tag_preview.lua b/widget/tag_preview.lua new file mode 100644 index 0000000..ffe1cca --- /dev/null +++ b/widget/tag_preview.lua @@ -0,0 +1,180 @@ +local awful = require("awful") +local wibox = require("wibox") +local helpers = require(tostring(...):match(".*bling") .. ".helpers") +local gears = require("gears") +local beautiful = require("beautiful") +local dpi = beautiful.xresources.apply_dpi +local cairo = require("lgi").cairo + +local function draw_widget(tag_preview_box, tag, tag_preview_image, scale, + prev_screen_width, prev_screen_height, screen_radius, + client_radius, client_opacity, client_bg, + client_border_color, client_border_width, widget_bg, + widget_border_color, widget_border_width) + + local client_list = wibox.layout.manual() + client_list.forced_height = prev_screen_height + client_list.forced_width = prev_screen_width + for i, c in ipairs(tag:clients()) do + + local img_box = wibox.widget { + image = gears.surface.load(c.icon), + resize = true, + forced_height = 100 * scale, + forced_width = 100 * scale, + widget = wibox.widget.imagebox + } + + if tag_preview_image then + if c.prev_content or tag.selected then + local content + if tag.selected then + content = gears.surface(c.content) + else + content = gears.surface(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) + 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), + resize = true, + opacity = client_opacity, + forced_height = math.floor(c.height * scale), + forced_width = math.floor(c.width * scale), + widget = wibox.widget.imagebox + } + end + end + + local client_box = wibox.widget { + { + nil, + { + nil, + img_box, + nil, + expand = "outside", + layout = wibox.layout.align.horizontal + }, + nil, + expand = "outside", + widget = wibox.layout.align.vertical + }, + forced_height = math.floor(c.height * scale), + forced_width = math.floor(c.width * scale), + bg = client_bg, + border_color = client_border_color, + border_width = client_border_width, + shape = helpers.shape.rrect(client_radius), + widget = wibox.container.background + } + + client_box.point = { + x = math.floor(c.x * scale), + y = math.floor(c.y * scale) + } + + --[[ + local pos_layout = wibox.widget { + client_box, + forced_height = prev_screen_height, + forced_width = prev_screen_width, + layout = wibox.layout.manual + } + --]] + + client_list:add(client_box) + + end + + tag_preview_box:setup{ + { + { + { + client_list, + forced_height = prev_screen_height, + forced_width = prev_screen_width, + bg = widget_bg, + widget = wibox.container.background + }, + layout = wibox.layout.align.horizontal + }, + layout = wibox.layout.align.vertical + }, + bg = widget_bg, + border_width = widget_border_width, + border_color = widget_border_color, + shape = helpers.shape.rrect(screen_radius), + widget = wibox.container.background + } +end + +local enable = function(opts) + local tag_preview_image = false + local widget_x = dpi(20) + local widget_y = dpi(20) + 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 scale = 0.2 + + if opts then + tag_preview_image = opts.show_client_content or tag_preview_image + widget_x = opts.x or widget_x + widget_y = opts.y or widget_y + scale = opts.scale or scale + end + + local prev_screen_width = math.floor(screen_width * scale) + local prev_screen_height = math.floor(screen_height * scale) + + local tag_preview_box = wibox({ + visible = false, + ontop = true, + width = prev_screen_width, + height = prev_screen_height, + input_passthrough = true, + bg = beautiful.xbackground .. "00", + x = widget_x, + y = widget_y + }) + + tag.connect_signal("property::selected", function(t) + for _, c in ipairs(t:clients()) do + c.prev_content = gears.surface.duplicate_surface(c.content) + end + end) + + awesome.connect_signal("bling::tag_preview::update", function(tag) + draw_widget(tag_preview_box, tag, tag_preview_image, scale, + prev_screen_width, prev_screen_height, screen_radius, + client_radius, client_opacity, client_bg, + client_border_color, client_border_width, widget_bg, + widget_border_color, widget_border_width) + end) + + awesome.connect_signal("bling::tag_preview::visiblity", function(s, v) + tag_preview_box.screen = s + tag_preview_box.visible = v + end) +end + +return {enable = enable}