Task Preview Widget (#72)

* Started on task_preview widget

* Finish task_preview widget

Finalized the code for the task_preview widget. Options and theme
variables should be allowed now.

* Changes according to review

* Improved opts
* Fixed vars to be backwards compat

* Update docs
This commit is contained in:
gokul 2021-07-14 15:17:46 -07:00 committed by GitHub
parent 921d386b47
commit a77fdbc1be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 297 additions and 48 deletions

View File

@ -15,6 +15,7 @@
- Widgets - Widgets
- [Tag Preview](widgets/tag_preview.md) - [Tag Preview](widgets/tag_preview.md)
- [Task Preview](widgets/task_preview.md)
- Extra - Extra
- [Theme Variable Template](theme.md) - [Theme Variable Template](theme.md)

View File

@ -67,4 +67,12 @@ theme.tag_preview_widget_bg = "#000000" -- The bg color of the widge
theme.tag_preview_widget_border_color = "#ffffff" -- The border color of the widget theme.tag_preview_widget_border_color = "#ffffff" -- The border color of the widget
theme.tag_preview_widget_border_width = 3 -- The border width of the widget theme.tag_preview_widget_border_width = 3 -- The border width of the widget
theme.tag_preview_widget_margin = 0 -- The margin of the widget theme.tag_preview_widget_margin = 0 -- The margin of the widget
-- task preview widget
theme.task_preview_widget_border_radius = 0 -- Border radius of the widget (With AA)
theme.task_preview_widget_bg = "#000000" -- The bg color of the widget
theme.task_preview_widget_border_color = "#ffffff" -- The border color of the widget
theme.task_preview_widget_border_width = 3 -- The border width of the widget
theme.task_preview_widget_margin = 0 -- The margin of the widget
``` ```

View File

@ -0,0 +1,109 @@
## 🔍 Tag Preview <!-- {docsify-ignore} -->
This is a popup widget that will show a preview of the specified client. It is supposed to mimic the small popup that Windows has when hovering over the application icon.
![](https://user-images.githubusercontent.com/33443763/124705653-d7b98b80-deaa-11eb-8091-42bbe62365be.png)
*image by [javacafe](https://github.com/JavaCafe01)*
### Usage
To enable:
```lua
bling.widget.tag_preview.enable {
x = 20, -- The x-coord of the popup
y = 20, -- The y-coord of the popup
height = 200, -- The height of the popup
width = 200, -- The width of the popup
placement_fn = function(c) -- Place the widget using awful.placement (this overrides x & y)
awful.placement.bottom(c, {
margins = {
bottom = 30
}
})
end
}
```
Here are the signals available:
```lua
-- bling::task_preview::visibility -- first line is the signal
-- s (screen) -- indented lines are function parameters
-- v (boolean)
-- c (client)
```
By default, the widget is not visible. You must implement when it will update and when it will show.
### Example Implementation
We can trigger the widget to show the specific client when hovering over it in the tasklist. The code shown below is the example icon only tasklist from the [AwesomeWM docs](https://awesomewm.org/doc/api/classes/awful.widget.tasklist.html). Basically, we are going to toggle the widget through the tasklist's `create_callback`. (The bling addons are commented)
```lua
s.mytasklist = awful.widget.tasklist {
screen = s,
filter = awful.widget.tasklist.filter.currenttags,
buttons = tasklist_buttons,
layout = {
spacing_widget = {
{
forced_width = 5,
forced_height = 24,
thickness = 1,
color = '#777777',
widget = wibox.widget.separator
},
valign = 'center',
halign = 'center',
widget = wibox.container.place,
},
spacing = 1,
layout = wibox.layout.fixed.horizontal
},
-- Notice that there is *NO* wibox.wibox prefix, it is a template,
-- not a widget instance.
widget_template = {
{
wibox.widget.base.make_widget(),
forced_height = 5,
id = 'background_role',
widget = wibox.container.background,
},
{
{
id = 'clienticon',
widget = awful.widget.clienticon,
},
margins = 5,
widget = wibox.container.margin
},
nil,
create_callback = function(self, c, index, objects) --luacheck: no unused args
self:get_children_by_id('clienticon')[1].client = c
-- BLING: Toggle the popup on hover and disable it off hover
self:connect_signal('mouse::enter', function()
awesome.emit_signal("bling::task_preview::visibility", s,
true, c)
end)
self:connect_signal('mouse::leave', function()
awesome.emit_signal("bling::task_preview::visibility", s,
false, c)
end)
end,
layout = wibox.layout.align.vertical,
},
}
```
### Theme Variables
```lua
theme.task_preview_widget_border_radius = 0 -- Border radius of the widget (With AA)
theme.task_preview_widget_bg = "#000000" -- The bg color of the widget
theme.task_preview_widget_border_color = "#ffffff" -- The border color of the widget
theme.task_preview_widget_border_width = 3 -- The border width of the widget
theme.task_preview_widget_margin = 0 -- The margin of the widget
```
NOTE: I recommend to only use the widget border radius theme variable when not using shadows with a compositor, as anti-aliased rounding with the outer widgets made with AwesomeWM rely on the actual bg being transparent. If you want rounding with shadows on the widget, use a compositor like [jonaburg's fork](https://github.com/jonaburg/picom).

View File

@ -5,7 +5,6 @@ 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
@ -67,4 +66,12 @@ theme.tag_preview_widget_bg = "#000000" -- The bg color of the widge
theme.tag_preview_widget_border_color = "#ffffff" -- The border color of the widget theme.tag_preview_widget_border_color = "#ffffff" -- The border color of the widget
theme.tag_preview_widget_border_width = 3 -- The border width of the widget theme.tag_preview_widget_border_width = 3 -- The border width of the widget
theme.tag_preview_widget_margin = 0 -- The margin of the widget theme.tag_preview_widget_margin = 0 -- The margin of the widget
-- task preview widget
theme.task_preview_widget_border_radius = 0 -- Border radius of the widget (With AA)
theme.task_preview_widget_bg = "#000000" -- The bg color of the widget
theme.task_preview_widget_border_color = "#ffffff" -- The border color of the widget
theme.task_preview_widget_border_width = 3 -- The border width of the widget
theme.task_preview_widget_margin = 0 -- The margin of the widget
-- LuaFormatter on -- LuaFormatter on

View File

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

121
widget/task_preview.lua Normal file
View File

@ -0,0 +1,121 @@
--
-- Provides:
-- bling::task_preview::visibility
-- s (screen)
-- v (boolean)
-- c (client)
--
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(c, task_preview_box, screen_radius, widget_bg,
widget_border_color, widget_border_width, margin)
local content = gears.surface(c.content)
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()
task_preview_box:setup{
{
{
{
{
image = gears.surface.load(c.icon),
resize = true,
forced_height = dpi(20),
forced_width = dpi(20),
widget = wibox.widget.imagebox
},
{
{
markup = c.name,
align = "center",
widget = wibox.widget.textbox
},
left = dpi(4),
right = dpi(4),
widget = wibox.container.margin
},
layout = wibox.layout.align.horizontal
},
{
{
{
image = gears.surface.load(img),
resize = true,
widget = wibox.widget.imagebox
},
valign = "center",
halign = "center",
widget = wibox.container.place
},
top = margin * 0.25,
widget = wibox.container.margin
},
fill_space = true,
layout = wibox.layout.fixed.vertical
},
margins = margin,
widget = wibox.container.margin
},
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
}
end
local enable = function(opts)
local opts = opts or {}
local widget_x = opts.x or dpi(20)
local widget_y = opts.y or dpi(20)
local widget_height = opts.height or dpi(200)
local widget_width = opts.width or dpi(200)
local placement_fn = opts.placement_fn or nil
local margin = beautiful.task_preview_widget_margin 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_border_color = beautiful.task_preview_widget_border_color or
"#ffffff"
local widget_border_width = beautiful.task_preview_widget_border_width or
dpi(3)
local task_preview_box = wibox({
type = "dropdown_menu",
visible = false,
ontop = true,
input_passthrough = true,
width = widget_width,
height = widget_height,
bg = "#00000000"
})
awesome.connect_signal("bling::task_preview::visibility", function(s, v, c)
draw_widget(c, task_preview_box, screen_radius, widget_bg,
widget_border_color, widget_border_width, margin)
if placement_fn then
placement_fn(task_preview_box)
else
task_preview_box.x = s.geometry.x + widget_x
task_preview_box.y = s.geometry.y + widget_y
end
task_preview_box.visible = v
end)
end
return {enable = enable}