diff --git a/docs/_sidebar.md b/docs/_sidebar.md index 0923141..6ad5d08 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -15,6 +15,7 @@ - Widgets - [Tag Preview](widgets/tag_preview.md) + - [Task Preview](widgets/task_preview.md) - Extra - [Theme Variable Template](theme.md) diff --git a/docs/theme.md b/docs/theme.md index f0f3119..592d771 100644 --- a/docs/theme.md +++ b/docs/theme.md @@ -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_width = 3 -- The border width 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 + ``` diff --git a/docs/widgets/task_preview.md b/docs/widgets/task_preview.md new file mode 100644 index 0000000..1e134b4 --- /dev/null +++ b/docs/widgets/task_preview.md @@ -0,0 +1,109 @@ +## 🔍 Tag Preview + +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). diff --git a/theme-var-template.lua b/theme-var-template.lua index c08bc3e..6b83923 100644 --- a/theme-var-template.lua +++ b/theme-var-template.lua @@ -5,66 +5,73 @@ 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. --]] -- LuaFormatter off - -- window swallowing -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_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 -- flash focus -theme.flash_focus_start_opacity = 0.6 -- the starting opacity -theme.flash_focus_step = 0.01 -- the step of animation +theme.flash_focus_start_opacity = 0.6 -- the starting opacity +theme.flash_focus_step = 0.01 -- the step of animation -- playerctl signal -theme.playerctl_backend = "playerctl_cli" -- backend to use -theme.playerctl_ignore = {} -- list of players to be ignored -theme.playerctl_player = {} -- list of players to be used in priority order -theme.playerctl_update_on_activity = true -- whether to prioritize the most recently active players or not -theme.playerctl_position_update_interval = 1 -- the update interval for fetching the position from playerctl +theme.playerctl_backend = "playerctl_cli" -- backend to use +theme.playerctl_ignore = {} -- list of players to be ignored +theme.playerctl_player = {} -- list of players to be used in priority order +theme.playerctl_update_on_activity = true -- whether to prioritize the most recently active players or not +theme.playerctl_position_update_interval = 1 -- the update interval for fetching the position from playerctl -- 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 -theme.tabbar_ontop = false -theme.tabbar_radius = 0 -- border radius of the tabbar -theme.tabbar_style = "default" -- style of the tabbar ("default", "boxes" or "modern") -theme.tabbar_font = "Sans 11" -- font of the tabbar -theme.tabbar_size = 40 -- size of the tabbar -theme.tabbar_position = "top" -- position of the tabbar -theme.tabbar_bg_normal = "#000000" -- background color of the focused client on the tabbar -theme.tabbar_fg_normal = "#ffffff" -- foreground color of the focused client on the tabbar -theme.tabbar_bg_focus = "#1A2026" -- background color of unfocused clients on the tabbar -theme.tabbar_fg_focus = "#ff0000" -- foreground color of unfocused clients on the tabbar +theme.tabbar_ontop = false +theme.tabbar_radius = 0 -- border radius of the tabbar +theme.tabbar_style = "default" -- style of the tabbar ("default", "boxes" or "modern") +theme.tabbar_font = "Sans 11" -- font of the tabbar +theme.tabbar_size = 40 -- size of the tabbar +theme.tabbar_position = "top" -- position of the tabbar +theme.tabbar_bg_normal = "#000000" -- background color of the focused client on the tabbar +theme.tabbar_fg_normal = "#ffffff" -- foreground color of the focused client on the tabbar +theme.tabbar_bg_focus = "#1A2026" -- background color of unfocused clients on the tabbar +theme.tabbar_fg_focus = "#ff0000" -- foreground color of unfocused clients on the tabbar -- mstab -theme.mstab_bar_ontop = false -- whether you want to allow the bar to be ontop of clients -theme.mstab_dont_resize_slaves = false -- whether the tabbed stack windows should be smaller than the - -- currently focused stack window (set it to true if you use - -- 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 - -- by default it will adjust based on your useless gaps. - -- 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_bar_height = 40 -- height of the tabbar -theme.mstab_tabbar_position = "top" -- position of the tabbar (mstab currently does not support left,right) -theme.mstab_tabbar_style = "default" -- style of the tabbar ("default", "boxes" or "modern") - -- defaults to the tabbar_style so only change if you want a - -- different style for mstab and tabbed +theme.mstab_bar_ontop = false -- whether you want to allow the bar to be ontop of clients +theme.mstab_dont_resize_slaves = false -- whether the tabbed stack windows should be smaller than the +-- currently focused stack window (set it to true if you use +-- 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 +-- by default it will adjust based on your useless gaps. +-- 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_bar_height = 40 -- height of the tabbar +theme.mstab_tabbar_position = "top" -- position of the tabbar (mstab currently does not support left,right) +theme.mstab_tabbar_style = "default" -- style of the tabbar ("default", "boxes" or "modern") +-- defaults to the tabbar_style so only change if you want a +-- different style for mstab and tabbed -- the following variables are currently only for the "modern" tabbar style -theme.tabbar_color_close = "#f9929b" -- chnges the color of the close button -theme.tabbar_color_min = "#fbdf90" -- chnges the color of the minimize button -theme.tabbar_color_float = "#ccaced" -- chnges the color of the float button +theme.tabbar_color_close = "#f9929b" -- chnges the color of the close button +theme.tabbar_color_min = "#fbdf90" -- chnges the color of the minimize button +theme.tabbar_color_float = "#ccaced" -- chnges the color of the float button -- tag preview widget -theme.tag_preview_widget_border_radius = 0 -- Border radius of the widget (With AA) -theme.tag_preview_client_border_radius = 0 -- Border radius of each client in the widget (With AA) -theme.tag_preview_client_opacity = 0.5 -- Opacity of each client -theme.tag_preview_client_bg = "#000000" -- The bg color of each client -theme.tag_preview_client_border_color = "#ffffff" -- The border color of each client -theme.tag_preview_client_border_width = 3 -- The border width of each client -theme.tag_preview_widget_bg = "#000000" -- The bg 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_margin = 0 -- The margin of the widget +theme.tag_preview_widget_border_radius = 0 -- Border radius of the widget (With AA) +theme.tag_preview_client_border_radius = 0 -- Border radius of each client in the widget (With AA) +theme.tag_preview_client_opacity = 0.5 -- Opacity of each client +theme.tag_preview_client_bg = "#000000" -- The bg color of each client +theme.tag_preview_client_border_color = "#ffffff" -- The border color of each client +theme.tag_preview_client_border_width = 3 -- The border width of each client +theme.tag_preview_widget_bg = "#000000" -- The bg 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_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 diff --git a/widget/init.lua b/widget/init.lua index fdfd047..cad993a 100644 --- a/widget/init.lua +++ b/widget/init.lua @@ -1 +1,4 @@ -return {tag_preview = require(... .. ".tag_preview")} +return { + tag_preview = require(... .. ".tag_preview"), + task_preview = require(... .. ".task_preview") +} diff --git a/widget/task_preview.lua b/widget/task_preview.lua new file mode 100644 index 0000000..3b12179 --- /dev/null +++ b/widget/task_preview.lua @@ -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}