diff --git a/awesomerc.lua b/awesomerc.lua index d08dc189..d25659ff 100644 --- a/awesomerc.lua +++ b/awesomerc.lua @@ -210,10 +210,18 @@ awful.screen.connect_for_each_screen(function(s) awful.button({ }, 4, function () awful.layout.inc( 1) end), awful.button({ }, 5, function () awful.layout.inc(-1) end))) -- Create a taglist widget - s.mytaglist = awful.widget.taglist(s, awful.widget.taglist.filter.all, taglist_buttons) + s.mytaglist = awful.widget.taglist { + screen = s, + filter = awful.widget.taglist.filter.all, + buttons = taglist_buttons + } -- Create a tasklist widget - s.mytasklist = awful.widget.tasklist(s, awful.widget.tasklist.filter.currenttags, tasklist_buttons) + s.mytasklist = awful.widget.tasklist { + screen = s, + filter = awful.widget.tasklist.filter.currenttags, + buttons = tasklist_buttons + } -- @DOC_WIBAR@ -- Create the wibox diff --git a/lib/awful/widget/common.lua b/lib/awful/widget/common.lua index e9ae6992..7d05f34c 100644 --- a/lib/awful/widget/common.lua +++ b/lib/awful/widget/common.lua @@ -9,7 +9,9 @@ local type = type local ipairs = ipairs local capi = { button = button } local wibox = require("wibox") +local gdebug = require("gears.debug") local dpi = require("beautiful").xresources.apply_dpi +local base = require("wibox.widget.base") --- Common utilities for awful widgets local common = {} @@ -36,6 +38,52 @@ function common.create_buttons(buttons, object) end end +local function default_template() + local ib = wibox.widget.imagebox() + local tb = wibox.widget.textbox() + local bgb = wibox.container.background() + local tbm = wibox.container.margin(tb, dpi(4), dpi(4)) + local ibm = wibox.container.margin(ib, dpi(4)) + local l = wibox.layout.fixed.horizontal() + + -- All of this is added in a fixed widget + l:fill_space(true) + l:add(ibm) + l:add(tbm) + + -- And all of this gets a background + bgb:set_widget(l) + + return { + ib = ib, + tb = tb, + bgb = bgb, + tbm = tbm, + ibm = ibm, + primary = l, + } +end + +local function custom_template(args) + local l = base.make_widget_from_value(args.widget_template) + + -- The template system requires being able to get children elements by ids. + -- This is not optimal, but for now there is no way around it. + assert(l.get_children_by_id,"The given widget template did not result in a".. + "layout with a 'get_children_by_id' method") + + return { + ib = l:get_children_by_id( "icon_role" )[1], + tb = l:get_children_by_id( "text_role" )[1], + bgb = l:get_children_by_id( "background_role" )[1], + tbm = l:get_children_by_id( "text_margin_role" )[1], + ibm = l:get_children_by_id( "icon_margin_role" )[1], + primary = l, + update_callback = l.update_callback, + create_callback = l.create_callback, + } +end + --- Common update method. -- @param w The widget. -- @tab buttons @@ -44,73 +92,69 @@ end -- has to return `text`, `bg`, `bg_image`, `icon`. -- @tab data Current data/cache, indexed by objects. -- @tab objects Objects to be displayed / updated. -function common.list_update(w, buttons, label, data, objects) +-- @tparam[opt={}] table args +function common.list_update(w, buttons, label, data, objects, args) -- update the widgets, creating them if needed w:reset() for i, o in ipairs(objects) do local cache = data[o] - local ib, tb, bgb, tbm, ibm, l - if cache then - ib = cache.ib - tb = cache.tb - bgb = cache.bgb - tbm = cache.tbm - ibm = cache.ibm - else - ib = wibox.widget.imagebox() - tb = wibox.widget.textbox() - bgb = wibox.container.background() - tbm = wibox.container.margin(tb, dpi(4), dpi(4)) - ibm = wibox.container.margin(ib, dpi(4)) - l = wibox.layout.fixed.horizontal() - -- All of this is added in a fixed widget - l:fill_space(true) - l:add(ibm) - l:add(tbm) + if not cache then + cache = (args and args.widget_template) and + custom_template(args) or default_template() - -- And all of this gets a background - bgb:set_widget(l) + cache.primary:buttons(common.create_buttons(buttons, o)) - bgb:buttons(common.create_buttons(buttons, o)) + if cache.create_callback then + cache.create_callback(cache.primary, o, i, objects) + end - data[o] = { - ib = ib, - tb = tb, - bgb = bgb, - tbm = tbm, - ibm = ibm, - } + data[o] = cache + elseif cache.update_callback then + cache.update_callback(cache.primary, o, i, objects) end - local text, bg, bg_image, icon, args = label(o, tb) - args = args or {} + local text, bg, bg_image, icon, item_args = label(o, cache.tb) + item_args = item_args or {} -- The text might be invalid, so use pcall. - if text == nil or text == "" then - tbm:set_margins(0) - else - if not tb:set_markup_silently(text) then - tb:set_markup("<Invalid text>") + if cache.tbm and (text == nil or text == "") then + cache.tbm:set_margins(0) + elseif cache.tb then + if not cache.tb:set_markup_silently(text) then + cache.tb:set_markup("<Invalid text>") end end - bgb:set_bg(bg) - if type(bg_image) == "function" then - -- TODO: Why does this pass nil as an argument? - bg_image = bg_image(tb,o,nil,objects,i) - end - bgb:set_bgimage(bg_image) - if icon then - ib:set_image(icon) - else - ibm:set_margins(0) + + if cache.bgb then + cache.bgb:set_bg(bg) + + --TODO v5 remove this if, it existed only for a removed and + -- undocumented API + if type(bg_image) ~= "function" then + cache.bgb:set_bgimage(bg_image) + else + gdebug.deprecate("If you read this, you used an undocumented API".. + " which has been replaced by the new awful.widget.common ".. + "templating system, please migrate now. This feature is ".. + "already staged for removal", { + deprecated_in = 4 + }) + end + + cache.bgb.shape = item_args.shape + cache.bgb.shape_border_width = item_args.shape_border_width + cache.bgb.shape_border_color = item_args.shape_border_color + end - bgb.shape = args.shape - bgb.shape_border_width = args.shape_border_width - bgb.shape_border_color = args.shape_border_color + if cache.ib and icon then + cache.ib:set_image(icon) + elseif cache.ibm then + cache.ibm:set_margins(0) + end - w:add(bgb) + w:add(cache.primary) end end diff --git a/lib/awful/widget/taglist.lua b/lib/awful/widget/taglist.lua index 623a755f..e2a74415 100644 --- a/lib/awful/widget/taglist.lua +++ b/lib/awful/widget/taglist.lua @@ -1,6 +1,37 @@ --------------------------------------------------------------------------- --- Taglist widget module for awful -- +-- Here is a more advanced example of how to extent the `taglist`. It provides: +-- +-- * mouse "hover" color +-- * an extra index field +-- * a powerline look and feel +-- +--@DOC_wibox_awidget_taglist_indexed_EXAMPLE@ +-- +-- As demonstrated in the example above, there are a few "shortcuts" to avoid +-- re-inventing the wheel. By setting the predefined roles as widget `id`s, +-- `awful.widget.common` will do most of the work to update the values +-- automatically. All of them are optional. The supported roles are: +-- +-- * `icon_role`: A `wibox.widget.imagebox` +-- * `text_role`: A `wibox.widget.textbox` +-- * `background_role`: A `wibox.container.background` +-- * `text_margin_role`: A `wibox.container.margin` +-- * `icon_margin_role`: A `wibox.container.margin` +-- +-- `awful.widget.common` also has 2 callbacks to give more control over the widget: +-- +-- * `create_callback`: Called once after the widget instance is created +-- * `update_callback`: Called everytime the data is refreshed +-- +-- Both callback have the same parameters: +-- +-- * `self`: The widget instance (*widget*). +-- * `t`: The tag (*tag*) +-- * `index`: The widget position in the list (*number*) +-- * `tags`: The list of tag, in order (*table*) +-- -- @author Julien Danjou <julien@danjou.info> -- @copyright 2008-2009 Julien Danjou -- @classmod awful.widget.taglist @@ -22,6 +53,8 @@ local surface = require("gears.surface") local timer = require("gears.timer") local gcolor = require("gears.color") local gstring = require("gears.string") +local gdebug = require("gears.debug") +local base = require("wibox.widget.base") local function get_screen(s) return s and capi.screen[s] @@ -351,7 +384,7 @@ function taglist.taglist_label(t, args) return text, bg_color, bg_image, not taglist_disable_icon and icon or nil, other_args end -local function taglist_update(s, w, buttons, filter, data, style, update_function) +local function taglist_update(s, w, buttons, filter, data, style, update_function, args) local tags = {} for _, t in ipairs(s.tags) do if not tag.getproperty(t, "hide") and filter(t) then @@ -361,73 +394,113 @@ local function taglist_update(s, w, buttons, filter, data, style, update_functio local function label(c) return taglist.taglist_label(c, style) end - update_function(w, buttons, label, data, tags) + update_function(w, buttons, label, data, tags, args) end --- Create a new taglist widget. The last two arguments (update_function --- and base_widget) serve to customize the layout of the taglist (eg. to +-- and layout) serve to customize the layout of the taglist (eg. to -- make it vertical). For that, you will need to copy the -- awful.widget.common.list_update function, make your changes to it --- and pass it as update_function here. Also change the base_widget if the +-- and pass it as update_function here. Also change the layout if the -- default is not what you want. --- @param screen The screen to draw taglist for. --- @param filter Filter function to define what clients will be listed. --- @param buttons A table with buttons binding to set. --- @tparam[opt={}] table style The style overrides default theme. --- @tparam[opt=nil] string|pattern style.fg_focus --- @tparam[opt=nil] string|pattern style.bg_focus --- @tparam[opt=nil] string|pattern style.fg_urgent --- @tparam[opt=nil] string|pattern style.bg_urgent --- @tparam[opt=nil] string|pattern style.bg_occupied --- @tparam[opt=nil] string|pattern style.fg_occupied --- @tparam[opt=nil] string|pattern style.bg_empty --- @tparam[opt=nil] string|pattern style.fg_empty --- @tparam[opt=nil] string|pattern style.bg_volatile --- @tparam[opt=nil] string|pattern style.fg_volatile --- @tparam[opt=nil] string style.squares_sel --- @tparam[opt=nil] string style.squares_unsel --- @tparam[opt=nil] string style.squares_sel_empty --- @tparam[opt=nil] string style.squares_unsel_empty --- @tparam[opt=nil] string style.squares_resize --- @tparam[opt=nil] string style.disable_icon --- @tparam[opt=nil] string style.font --- @tparam[opt=nil] number style.spacing The spacing between tags. --- @param[opt] update_function Function to create a tag widget on each +-- @tparam table args +-- @tparam screen args.screen The screen to draw taglist for. +-- @tparam function[opt=nil] args.filter Filter function to define what clients will be listed. +-- @tparam table args.buttons A table with buttons binding to set. +-- @tparam[opt] function args.update_function Function to create a tag widget on each -- update. See `awful.widget.common`. --- @param[opt] base_widget Optional container widget for tag widgets. Default +-- @tparam[opt] widget args.layout Optional layout widget for tag widgets. Default -- is wibox.layout.fixed.horizontal(). --- @param base_widget.bg_focus The background color for focused client. --- @param base_widget.fg_focus The foreground color for focused client. --- @param base_widget.bg_urgent The background color for urgent clients. --- @param base_widget.fg_urgent The foreground color for urgent clients. --- @param[opt] base_widget.squares_sel A user provided image for selected squares. --- @param[opt] base_widget.squares_unsel A user provided image for unselected squares. --- @param[opt] base_widget.squares_sel_empty A user provided image for selected squares for empty tags. --- @param[opt] base_widget.squares_unsel_empty A user provided image for unselected squares for empty tags. --- @param[opt] base_widget.squares_resize True or false to resize squares. --- @param base_widget.font The font. +-- @tparam[opt] table widget_template A custom widget to be used for each tag +-- @tparam[opt={}] table args.style The style overrides default theme. +-- @tparam[opt=nil] string|pattern args.style.fg_focus +-- @tparam[opt=nil] string|pattern args.style.bg_focus +-- @tparam[opt=nil] string|pattern args.style.fg_urgent +-- @tparam[opt=nil] string|pattern args.style.bg_urgent +-- @tparam[opt=nil] string|pattern args.style.bg_occupied +-- @tparam[opt=nil] string|pattern args.style.fg_occupied +-- @tparam[opt=nil] string|pattern args.style.bg_empty +-- @tparam[opt=nil] string|pattern args.style.fg_empty +-- @tparam[opt=nil] string|pattern args.style.bg_volatile +-- @tparam[opt=nil] string|pattern args.style.fg_volatile +-- @tparam[opt=nil] string args.style.squares_sel +-- @tparam[opt=nil] string args.style.squares_unsel +-- @tparam[opt=nil] string args.style.squares_sel_empty +-- @tparam[opt=nil] string args.style.squares_unsel_empty +-- @tparam[opt=nil] string args.style.squares_resize +-- @tparam[opt=nil] string args.style.disable_icon +-- @tparam[opt=nil] string args.style.font +-- @tparam[opt=nil] number args.style.spacing The spacing between tags. +-- @tparam[opt] string args.style.squares_sel A user provided image for selected squares. +-- @tparam[opt] string args.style.squares_unsel A user provided image for unselected squares. +-- @tparam[opt] string args.style.squares_sel_empty A user provided image for selected squares for empty tags. +-- @tparam[opt] string args.style.squares_unsel_empty A user provided image for unselected squares for empty tags. +-- @tparam[opt] boolean args.style.squares_resize True or false to resize squares. +-- @tparam string|pattern args.style.bg_focus The background color for focused client. +-- @tparam string|pattern args.style.fg_focus The foreground color for focused client. +-- @tparam string|pattern args.style.bg_urgent The background color for urgent clients. +-- @tparam string|pattern args.style.fg_urgent The foreground color for urgent clients. +-- @tparam string args.style.font The font. +-- @param filter **DEPRECATED** use args.filter +-- @param buttons **DEPRECATED** use args.buttons +-- @param style **DEPRECATED** use args.style +-- @param update_function **DEPRECATED** use args.update_function +-- @param base_widget **DEPRECATED** use args.base_widget -- @function awful.taglist -function taglist.new(screen, filter, buttons, style, update_function, base_widget) - screen = get_screen(screen) - local uf = update_function or common.list_update - local w = base_widget or fixed.horizontal() +function taglist.new(args, filter, buttons, style, update_function, base_widget) - if w.set_spacing and (style and style.spacing or beautiful.taglist_spacing) then - w:set_spacing(style and style.spacing or beautiful.taglist_spacing) + local screen = nil + + local argstype = type(args) + + -- Detect the old function signature + if argstype == "number" or argstype == "screen" or + (argstype == "table" and args.index and args == capi.screen[args.index]) then + gdebug.deprecate("The `screen` paramater is deprecated, use `args.screen`.", + {deprecated_in=5}) + + screen = get_screen(args) + args = {} + end + + assert(type(args) == "table") + + for k, v in pairs { filter = filter, + buttons = buttons, + style = style, + update_function = update_function, + layout = base_widget + } do + gdebug.deprecate("The `awful.widget.taglist()` `"..k + .."` paramater is deprecated, use `args."..k.."`.", + {deprecated_in=5}) + args[k] = v + end + + screen = screen or get_screen(args.screen) + + local uf = args.update_function or common.list_update + local w = base.make_widget_from_value(args.layout or fixed.horizontal) + + if w.set_spacing and (args.style and args.style.spacing or beautiful.taglist_spacing) then + w:set_spacing(args.style and args.style.spacing or beautiful.taglist_spacing) end local data = setmetatable({}, { __mode = 'k' }) local queued_update = {} + + function w._do_taglist_update_now() + if screen.valid then + taglist_update(screen, w, args.buttons, args.filter, data, args.style, uf, args) + end + queued_update[screen] = false + end + function w._do_taglist_update() -- Add a delayed callback for the first update. if not queued_update[screen] then - timer.delayed_call(function() - if screen.valid then - taglist_update(screen, w, buttons, filter, data, style, uf) - end - queued_update[screen] = false - end) + timer.delayed_call(w._do_taglist_update_now) queued_update[screen] = true end end diff --git a/lib/awful/widget/tasklist.lua b/lib/awful/widget/tasklist.lua index cfb10425..b8a3cdb5 100644 --- a/lib/awful/widget/tasklist.lua +++ b/lib/awful/widget/tasklist.lua @@ -24,6 +24,50 @@ -- ⬍maximized_vertical -- -- +-- **Customizing the tasklist:** +-- +-- The `tasklist` created by `rc.lua` use the default values for almost +-- everything. However, it is possible to override each aspects to create a +-- very different widget. Here's an example that create a tasklist similar to +-- the default one, but with an explicit layout and some spacing widgets: +-- +--@DOC_wibox_awidget_tasklist_rounded_EXAMPLE@ +-- +-- As demonstrated in the example above, there are a few "shortcuts" to avoid +-- re-inventing the wheel. By setting the predefined roles as widget `id`s, +-- `awful.widget.common` will do most of the work to update the values +-- automatically. All of them are optional. The supported roles are: +-- +-- * `icon_role`: A `wibox.widget.imagebox` +-- * `text_role`: A `wibox.widget.textbox` +-- * `background_role`: A `wibox.container.background` +-- * `text_margin_role`: A `wibox.container.margin` +-- * `icon_margin_role`: A `wibox.container.margin` +-- +-- `awful.widget.common` also has 2 callbacks to give more control over the widget: +-- +-- * `create_callback`: Called once after the widget instance is created +-- * `update_callback`: Called everytime the data is refreshed +-- +-- Both callback have the same parameters: +-- +-- * `self`: The widget instance (*widget*). +-- * `c`: The client (*client*) +-- * `index`: The widget position in the list (*number*) +-- * `clients`: The list of client, in order (*table*) +-- +-- It is also possible to omit some roles and create an icon only tasklist. +-- Notice that this example use the `awful.widget.clienticon` widget instead +-- of an `imagebox`. This allows higher resoluton icons to be loaded. This +-- example reproduces the Windows 10 tasklist look and feel: +-- +--@DOC_wibox_awidget_tasklist_windows10_EXAMPLE@ +-- +-- The tasklist can also be created in an `awful.popup` in case there is no +-- permanent `awful.wibar`: +-- +--@DOC_awful_popup_alttab_EXAMPLE@ +-- -- @author Julien Danjou <julien@danjou.info> -- @copyright 2008-2009 Julien Danjou -- @classmod awful.widget.tasklist @@ -42,6 +86,8 @@ local flex = require("wibox.layout.flex") local timer = require("gears.timer") local gcolor = require("gears.color") local gstring = require("gears.string") +local gdebug = require("gears.debug") +local base = require("wibox.widget.base") local function get_screen(s) return s and screen[s] @@ -244,7 +290,9 @@ local function tasklist_label(c, args, tb) local maximized_horizontal = args.maximized_horizontal or theme.tasklist_maximized_horizontal or '⬌' local maximized_vertical = args.maximized_vertical or theme.tasklist_maximized_vertical or '⬍' - tb:set_align(align) + if tb then + tb:set_align(align) + end if not theme.tasklist_plain_task_name then if c.sticky then name = name .. sticky end @@ -337,7 +385,10 @@ local function tasklist_label(c, args, tb) text = text .. ""..name.."" bg_image = bg_image_normal end - tb:set_font(font) + + if tb then + tb:set_font(font) + end local other_args = { shape = shape, @@ -348,7 +399,7 @@ local function tasklist_label(c, args, tb) return text, bg, bg_image, not tasklist_disable_icon and c.icon or nil, other_args end -local function tasklist_update(s, w, buttons, filter, data, style, update_function) +local function tasklist_update(s, w, buttons, filter, data, style, update_function, args) local clients = {} for _, c in ipairs(capi.client.get()) do if not (c.skip_taskbar or c.hidden @@ -360,77 +411,118 @@ local function tasklist_update(s, w, buttons, filter, data, style, update_functi local function label(c, tb) return tasklist_label(c, style, tb) end - update_function(w, buttons, label, data, clients) + update_function(w, buttons, label, data, clients, args) end ---- Create a new tasklist widget. The last two arguments (update_function --- and base_widget) serve to customize the layout of the tasklist (eg. to +--- Create a new tasklist widget. +-- The last two arguments (update_function +-- and layout) serve to customize the layout of the tasklist (eg. to -- make it vertical). For that, you will need to copy the -- awful.widget.common.list_update function, make your changes to it --- and pass it as update_function here. Also change the base_widget if the +-- and pass it as update_function here. Also change the layout if the -- default is not what you want. --- @param screen The screen to draw tasklist for. --- @param filter Filter function to define what clients will be listed. --- @param buttons A table with buttons binding to set. --- @tparam[opt={}] table style The style overrides default theme. --- @tparam[opt=nil] string|pattern style.fg_normal --- @tparam[opt=nil] string|pattern style.bg_normal --- @tparam[opt=nil] string|pattern style.fg_focus --- @tparam[opt=nil] string|pattern style.bg_focus --- @tparam[opt=nil] string|pattern style.fg_urgent --- @tparam[opt=nil] string|pattern style.bg_urgent --- @tparam[opt=nil] string|pattern style.fg_minimize --- @tparam[opt=nil] string|pattern style.bg_minimize --- @tparam[opt=nil] string style.bg_image_normal --- @tparam[opt=nil] string style.bg_image_focus --- @tparam[opt=nil] string style.bg_image_urgent --- @tparam[opt=nil] string style.bg_image_minimize --- @tparam[opt=nil] boolean style.tasklist_disable_icon --- @tparam[opt=false] boolean style.disable_task_name --- @tparam[opt=nil] string style.font --- @tparam[opt=left] string style.align *left*, *right* or *center* --- @tparam[opt=nil] string style.font_focus --- @tparam[opt=nil] string style.font_minimized --- @tparam[opt=nil] string style.font_urgent --- @tparam[opt=nil] number style.spacing The spacing between tags. --- @tparam[opt=nil] gears.shape style.shape --- @tparam[opt=nil] number style.shape_border_width --- @tparam[opt=nil] string|color style.shape_border_color --- @tparam[opt=nil] gears.shape style.shape_focus --- @tparam[opt=nil] number style.shape_border_width_focus --- @tparam[opt=nil] string|color style.shape_border_color_focus --- @tparam[opt=nil] gears.shape style.shape_minimized --- @tparam[opt=nil] number style.shape_border_width_minimized --- @tparam[opt=nil] string|color style.shape_border_color_minimized --- @tparam[opt=nil] gears.shape style.shape_urgent --- @tparam[opt=nil] number style.shape_border_width_urgent --- @tparam[opt=nil] string|color style.shape_border_color_urgent --- @param[opt] update_function Function to create a tag widget on each +-- +-- @tparam table args +-- @tparam screen args.screen The screen to draw tasklist for. +-- @tparam function args.filter Filter function to define what clients will be listed. +-- @tparam table args.buttons A table with buttons binding to set. +-- @tparam[opt] function args.update_function Function to create a tag widget on each -- update. See `awful.widget.common.list_update`. --- @tparam[opt] table base_widget Container widget for tag widgets. Default +-- @tparam[opt] table args.layout Container widget for tag widgets. Default -- is `wibox.layout.flex.horizontal`. +-- @tparam[opt] table widget_template A custom widget to be used for each client +-- @tparam[opt={}] table args.style The style overrides default theme. +-- @tparam[opt=nil] string|pattern args.style.fg_normal +-- @tparam[opt=nil] string|pattern args.style.bg_normal +-- @tparam[opt=nil] string|pattern args.style.fg_focus +-- @tparam[opt=nil] string|pattern args.style.bg_focus +-- @tparam[opt=nil] string|pattern args.style.fg_urgent +-- @tparam[opt=nil] string|pattern args.style.bg_urgent +-- @tparam[opt=nil] string|pattern args.style.fg_minimize +-- @tparam[opt=nil] string|pattern args.style.bg_minimize +-- @tparam[opt=nil] string args.style.bg_image_normal +-- @tparam[opt=nil] string args.style.bg_image_focus +-- @tparam[opt=nil] string args.style.bg_image_urgent +-- @tparam[opt=nil] string args.style.bg_image_minimize +-- @tparam[opt=nil] boolean args.style.tasklist_disable_icon +-- @tparam[opt=false] boolean args.style.disable_task_name +-- @tparam[opt=nil] string args.style.font +-- @tparam[opt=left] string args.style.align *left*, *right* or *center* +-- @tparam[opt=nil] string args.style.font_focus +-- @tparam[opt=nil] string args.style.font_minimized +-- @tparam[opt=nil] string args.style.font_urgent +-- @tparam[opt=nil] number args.style.spacing The spacing between tags. +-- @tparam[opt=nil] gears.shape args.style.shape +-- @tparam[opt=nil] number args.style.shape_border_width +-- @tparam[opt=nil] string|color args.style.shape_border_color +-- @tparam[opt=nil] gears.shape args.style.shape_focus +-- @tparam[opt=nil] number args.style.shape_border_width_focus +-- @tparam[opt=nil] string|color args.style.shape_border_color_focus +-- @tparam[opt=nil] gears.shape args.style.shape_minimized +-- @tparam[opt=nil] number args.style.shape_border_width_minimized +-- @tparam[opt=nil] string|color args.style.shape_border_color_minimized +-- @tparam[opt=nil] gears.shape args.style.shape_urgent +-- @tparam[opt=nil] number args.style.shape_border_width_urgent +-- @tparam[opt=nil] string|color args.style.shape_border_color_urgent +-- @param filter **DEPRECATED** use args.filter +-- @param buttons **DEPRECATED** use args.buttons +-- @param style **DEPRECATED** use args.style +-- @param update_function **DEPRECATED** use args.update_function +-- @param base_widget **DEPRECATED** use args.base_widget -- @function awful.tasklist -function tasklist.new(screen, filter, buttons, style, update_function, base_widget) - screen = get_screen(screen) - local uf = update_function or common.list_update - local w = base_widget or flex.horizontal() +function tasklist.new(args, filter, buttons, style, update_function, base_widget) + local screen = nil + + local argstype = type(args) + + -- Detect the old function signature + if argstype == "number" or argstype == "screen" or + (argstype == "table" and args.index and args == capi.screen[args.index]) then + gdebug.deprecate("The `screen` paramater is deprecated, use `args.screen`.", + {deprecated_in=5}) + + screen = get_screen(args) + args = {} + end + + assert(type(args) == "table") + + for k, v in pairs { filter = filter, + buttons = buttons, + style = style, + update_function = update_function, + layout = base_widget + } do + gdebug.deprecate("The `awful.widget.tasklist()` `"..k + .."` paramater is deprecated, use `args."..k.."`.", + {deprecated_in=5}) + args[k] = v + end + + screen = screen or get_screen(args.screen) + local uf = args.update_function or common.list_update + local w = base.make_widget_from_value(args.layout or flex.horizontal) local data = setmetatable({}, { __mode = 'k' }) - if w.set_spacing and (style and style.spacing or beautiful.tasklist_spacing) then - w:set_spacing(style and style.spacing or beautiful.tasklist_spacing) + if w.set_spacing and (args.style and args.style.spacing or beautiful.tasklist_spacing) then + w:set_spacing(args.style and args.style.spacing or beautiful.tasklist_spacing) end local queued_update = false + + -- For the tests + function w._do_tasklist_update_now() + queued_update = false + if screen.valid then + tasklist_update(screen, w, args.buttons, args.filter, data, args.style, uf, args) + end + end + function w._do_tasklist_update() -- Add a delayed callback for the first update. if not queued_update then - timer.delayed_call(function() - queued_update = false - if screen.valid then - tasklist_update(screen, w, buttons, filter, data, style, uf) - end - end) + timer.delayed_call(w._do_tasklist_update_now) queued_update = true end end diff --git a/tests/_wibox_helper.lua b/tests/_wibox_helper.lua index 5c7afdc2..d60ad7f8 100644 --- a/tests/_wibox_helper.lua +++ b/tests/_wibox_helper.lua @@ -8,7 +8,10 @@ return { create_wibox = function() -- Widgets that are aligned to the left local left_layout = wibox.layout.fixed.horizontal() left_layout:add(awful.widget.launcher({ image = img, command = "bash" })) - left_layout:add(awful.widget.taglist(1, awful.widget.taglist.filter.all)) + left_layout:add(awful.widget.taglist { + screen = 1, + filter = awful.widget.taglist.filter.all + }) left_layout:add(awful.widget.prompt()) -- Widgets that are aligned to the right @@ -20,7 +23,10 @@ return { create_wibox = function() -- Now bring it all together (with the tasklist in the middle) local layout = wibox.layout.align.horizontal() layout:set_left(left_layout) - layout:set_middle(awful.widget.tasklist(1, awful.widget.tasklist.filter.currenttags)) + layout:set_middle(awful.widget.tasklist { + screen = 1, + filter = awful.widget.tasklist.filter.currenttags + }) layout:set_right(right_layout) -- Create wibox diff --git a/tests/examples/wibox/awidget/taglist/indexed.lua b/tests/examples/wibox/awidget/taglist/indexed.lua new file mode 100644 index 00000000..d4c5daff --- /dev/null +++ b/tests/examples/wibox/awidget/taglist/indexed.lua @@ -0,0 +1,106 @@ +local parent = ... --DOC_NO_USAGE --DOC_HIDE +local awful = { --DOC_HIDE + tag = require("awful.tag"), --DOC_HIDE + layout = require("awful.layout"), --DOC_HIDE + placement = require("awful.placement"), --DOC_HIDE + widget = {taglist = require("awful.widget.taglist")} --DOC_HIDE +} --DOC_HIDE +local gears = { shape = require("gears.shape") } --DOC_HIDE +local wibox = require("wibox") --DOC_HIDE +local beautiful = require("beautiful") --DOC_HIDE + +local s = screen[1] --DOC_HIDE +local taglist_buttons = nil -- To make luacheck shut up --DOC_HIDE + +local tags = awful.tag({ "term", "net", "mail", "chat", "files" }, --DOC_HIDE + s, awful.layout.suit.floating) --DOC_HIDE + +for i=1, 5 do tags[i].selected = false end --DOC_HIDE +tags[2].selected = true --DOC_HIDE + +--DOC_HIDE add some clients to some tags +local c = client.gen_fake {x = 80, y = 55, width=75, height=50} --DOC_HIDE +local c2 = client.gen_fake {x = 80, y = 55, width=75, height=50} --DOC_HIDE +c:tags(tags[4]) --DOC_HIDE +c2:tags(tags[1]) --DOC_HIDE + + s.mytaglist = awful.widget.taglist { + screen = s, + filter = awful.widget.taglist.filter.all, + style = { + shape = gears.shape.powerline + }, + layout = { + spacing = -12, + spacing_widget = { + color = "#dddddd", + shape = gears.shape.powerline, + widget = wibox.widget.separator, + }, + layout = wibox.layout.fixed.horizontal + }, + widget_template = { + { + { + { + { + { + id = "index_role", + widget = wibox.widget.textbox, + }, + margins = 4, + widget = wibox.container.margin, + }, + bg = "#dddddd", + shape = gears.shape.circle, + widget = wibox.container.background, + }, + { + { + id = "icon_role", + widget = wibox.widget.imagebox, + }, + margins = 2, + widget = wibox.container.margin, + }, + { + id = "text_role", + widget = wibox.widget.textbox, + }, + layout = wibox.layout.fixed.horizontal, + }, + left = 18, + right = 18, + widget = wibox.container.margin + }, + id = "background_role", + widget = wibox.container.background, + + -- Add support for hover colors and an index label + create_callback = function(self, c3, index, objects) --luacheck: no unused args + self:get_children_by_id("index_role")[1].markup = " "..index.." " + + self:connect_signal("mouse::enter", function() + if self.bg ~= "#ff0000" then + self.backup = self.bg + self.has_backup = true + end + self.bg = "#ff0000" + end) + + self:connect_signal("mouse::leave", function() + if self.has_backup then self.bg = self.backup end + end) + end, + update_callback = function(self, c3, index, objects) --luacheck: no unused args + self:get_children_by_id("index_role")[1].markup = " "..index.." " + end, + }, + buttons = taglist_buttons + } + +s.mytaglist.forced_width = 400 --DOC_HIDE +s.mytaglist.forced_height = 18 --DOC_HIDE +s.mytaglist._do_taglist_update_now() --DOC_HIDE + +parent:add(wibox.widget.background(s.mytaglist, beautiful.bg_normal)) --DOC_HIDE diff --git a/tests/examples/wibox/awidget/tasklist/rounded.lua b/tests/examples/wibox/awidget/tasklist/rounded.lua new file mode 100644 index 00000000..2ab339ff --- /dev/null +++ b/tests/examples/wibox/awidget/tasklist/rounded.lua @@ -0,0 +1,78 @@ +local parent = ... --DOC_NO_USAGE --DOC_HIDE +local awful = { --DOC_HIDE + tag = require("awful.tag"), --DOC_HIDE + placement = require("awful.placement"), --DOC_HIDE + widget = {tasklist = require("awful.widget.tasklist")} --DOC_HIDE +} --DOC_HIDE +local gears = { shape = require("gears.shape") } --DOC_HIDE +local wibox = require("wibox") --DOC_HIDE +local beautiful = require("beautiful") --DOC_HIDE + +local s = screen[1] --DOC_HIDE +local tasklist_buttons = nil -- To make luacheck shut up --DOC_HIDE + +local t_real = awful.tag.add("Test", {screen=screen[1]}) --DOC_HIDE + +for i=1, 3 do --DOC_HIDE + local c = client.gen_fake {x = 80, y = 55, width=75, height=50} --DOC_HIDE + c:tags{t_real} --DOC_HIDE + c.icon = beautiful.awesome_icon --DOC_HIDE + c.name = " Client "..i.." " --DOC_HIDE +end --DOC_HIDE + + s.mytasklist = awful.widget.tasklist { + screen = s, + filter = awful.widget.tasklist.filter.currenttags, + buttons = tasklist_buttons, + style = { + shape_border_width = 1, + shape_border_color = "#777777", + shape = gears.shape.rounded_bar, + }, + layout = { + spacing = 10, + spacing_widget = { + { + forced_width = 5, + shape = gears.shape.circle, + widget = wibox.widget.separator + }, + valign = "center", + halign = "center", + widget = wibox.container.place, + }, + layout = wibox.layout.flex.horizontal + }, + -- Notice that there is *NO* `wibox.wibox` prefix, it is a template, + -- not a widget instance. + widget_template = { + { + { + { + { + id = "icon_role", + widget = wibox.widget.imagebox, + }, + margins = 2, + widget = wibox.container.margin, + }, + { + id = "text_role", + widget = wibox.widget.textbox, + }, + layout = wibox.layout.fixed.horizontal, + }, + left = 10, + right = 10, + widget = wibox.container.margin + }, + id = "background_role", + widget = wibox.container.background, + }, + } + +s.mytasklist.forced_width = 400 --DOC_HIDE +s.mytasklist.forced_height = 18 --DOC_HIDE +s.mytasklist._do_tasklist_update_now() --DOC_HIDE + +parent:add( s.mytasklist) --DOC_HIDE diff --git a/tests/examples/wibox/awidget/tasklist/windows10.lua b/tests/examples/wibox/awidget/tasklist/windows10.lua new file mode 100644 index 00000000..e51e117d --- /dev/null +++ b/tests/examples/wibox/awidget/tasklist/windows10.lua @@ -0,0 +1,73 @@ +local parent = ... --DOC_NO_USAGE --DOC_HIDE +local awful = { --DOC_HIDE + tag = require("awful.tag"), --DOC_HIDE + placement = require("awful.placement"), --DOC_HIDE + widget = {clienticon =require("awful.widget.clienticon"), --DOC_HIDE + tasklist = require("awful.widget.tasklist")} --DOC_HIDE +} --DOC_HIDE +local wibox = require("wibox") --DOC_HIDE +local beautiful = require("beautiful") --DOC_HIDE + +local s = screen[1] --DOC_HIDE +local tasklist_buttons = nil -- To make luacheck shut up --DOC_HIDE + +local t_real = awful.tag.add("Test", {screen=screen[1]}) --DOC_HIDE + +for i=1, 3 do --DOC_HIDE + local c = client.gen_fake {x = 80, y = 55, width=75, height=50} --DOC_HIDE + c:tags{t_real} --DOC_HIDE + c.icon = beautiful.awesome_icon --DOC_HIDE + c.name = " Client "..i.." " --DOC_HIDE + client.focus = i==2 and c or client.focus --DOC_HIDE +end --DOC_HIDE + + 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 + end, + layout = wibox.layout.align.vertical, + }, + } + +s.mytasklist.forced_width = 400 --DOC_HIDE +s.mytasklist.forced_height = 48 --DOC_HIDE +s.mytasklist._do_tasklist_update_now() --DOC_HIDE + +parent:add( s.mytasklist) --DOC_HIDE diff --git a/tests/test-leaks.lua b/tests/test-leaks.lua index 86c86b13..e7aa1d34 100644 --- a/tests/test-leaks.lua +++ b/tests/test-leaks.lua @@ -73,10 +73,10 @@ prepare_for_collect = emit_refresh collectable(tooltip_now()) prepare_for_collect = emit_refresh -collectable(awful.widget.taglist(1, awful.widget.taglist.filter.all)) +collectable(awful.widget.taglist{screen=1, filter=awful.widget.taglist.filter.all}) prepare_for_collect = emit_refresh -collectable(awful.widget.tasklist(1, awful.widget.tasklist.filter.currenttags)) +collectable(awful.widget.tasklist{screen=1, filter=awful.widget.tasklist.filter.currenttags}) prepare_for_collect = emit_refresh collectable(create_wibox())