1--------------------------------------------------------------------------- 2--- Tasklist widget module for awful. 3-- 4-- <a name="status_icons"></a> 5-- **Status icons:** 6-- 7-- By default, the tasklist prepends some symbols in front of the client name. 8-- This is used to notify that the client has some specific properties that are 9-- currently enabled. This can be disabled using 10-- `beautiful.tasklist_plain_task_name`=true in the theme. 11-- 12-- <table class='widget_list' border=1> 13-- <tr style='font-weight: bold;'> 14-- <th align='center'>Icon</th> 15-- <th align='center'>Client property</th> 16-- </tr> 17-- <tr><td>▪</td><td><a href="./client.html#client.sticky">sticky</a></td></tr> 18-- <tr><td>⌃</td><td><a href="./client.html#client.ontop">ontop</a></td></tr> 19-- <tr><td>▴</td><td><a href="./client.html#client.above">above</a></td></tr> 20-- <tr><td>▾</td><td><a href="./client.html#client.below">below</a></td></tr> 21-- <tr><td>✈</td><td><a href="./client.html#client.floating">floating</a></td></tr> 22-- <tr><td>+</td><td><a href="./client.html#client.maximized">maximized</a></td></tr> 23-- <tr><td>⬌</td><td><a href="./client.html#client.maximized_horizontal">maximized_horizontal</a></td></tr> 24-- <tr><td>⬍</td><td><a href="./client.html#client.maximized_vertical">maximized_vertical</a></td></tr> 25-- </table> 26-- 27-- **Customizing the tasklist:** 28-- 29-- The `tasklist` created by `rc.lua` use the default values for almost 30-- everything. However, it is possible to override each aspects to create a 31-- very different widget. Here's an example that create a tasklist similar to 32-- the default one, but with an explicit layout and some spacing widgets: 33-- 34--@DOC_wibox_awidget_tasklist_rounded_EXAMPLE@ 35-- 36-- As demonstrated in the example above, there are a few "shortcuts" to avoid 37-- re-inventing the wheel. By setting the predefined roles as widget `id`s, 38-- `awful.widget.common` will do most of the work to update the values 39-- automatically. All of them are optional. The supported roles are: 40-- 41-- * `icon_role`: A `wibox.widget.imagebox` 42-- * `text_role`: A `wibox.widget.textbox` 43-- * `background_role`: A `wibox.container.background` 44-- * `text_margin_role`: A `wibox.container.margin` 45-- * `icon_margin_role`: A `wibox.container.margin` 46-- 47-- `awful.widget.common` also has 2 callbacks to give more control over the widget: 48-- 49-- * `create_callback`: Called once after the widget instance is created 50-- * `update_callback`: Called everytime the data is refreshed 51-- 52-- Both callback have the same parameters: 53-- 54-- * `self`: The widget instance (*widget*). 55-- * `c`: The client (*client*) 56-- * `index`: The widget position in the list (*number*) 57-- * `clients`: The list of client, in order (*table*) 58-- 59-- It is also possible to omit some roles and create an icon only tasklist. 60-- Notice that this example use the `awful.widget.clienticon` widget instead 61-- of an `imagebox`. This allows higher resoluton icons to be loaded. This 62-- example reproduces the Windows 10 tasklist look and feel: 63-- 64--@DOC_wibox_awidget_tasklist_windows10_EXAMPLE@ 65-- 66-- The tasklist can also be created in an `awful.popup` in case there is no 67-- permanent `awful.wibar`: 68-- 69--@DOC_awful_popup_alttab_EXAMPLE@ 70-- 71-- @author Julien Danjou <julien@danjou.info> 72-- @copyright 2008-2009 Julien Danjou 73-- @classmod awful.widget.tasklist 74--------------------------------------------------------------------------- 75 76-- Grab environment we need 77local capi = { screen = screen, 78 client = client } 79local ipairs = ipairs 80local setmetatable = setmetatable 81local table = table 82local common = require("awful.widget.common") 83local beautiful = require("beautiful") 84local tag = require("awful.tag") 85local flex = require("wibox.layout.flex") 86local timer = require("gears.timer") 87local gcolor = require("gears.color") 88local gstring = require("gears.string") 89local gdebug = require("gears.debug") 90local base = require("wibox.widget.base") 91 92local function get_screen(s) 93 return s and screen[s] 94end 95 96local tasklist = { mt = {} } 97 98local instances 99 100--- The default foreground (text) color. 101-- @beautiful beautiful.tasklist_fg_normal 102-- @tparam[opt=nil] string|pattern fg_normal 103-- @see gears.color 104 105--- The default background color. 106-- @beautiful beautiful.tasklist_bg_normal 107-- @tparam[opt=nil] string|pattern bg_normal 108-- @see gears.color 109 110--- The focused client foreground (text) color. 111-- @beautiful beautiful.tasklist_fg_focus 112-- @tparam[opt=nil] string|pattern fg_focus 113-- @see gears.color 114 115--- The focused client background color. 116-- @beautiful beautiful.tasklist_bg_focus 117-- @tparam[opt=nil] string|pattern bg_focus 118-- @see gears.color 119 120--- The urgent clients foreground (text) color. 121-- @beautiful beautiful.tasklist_fg_urgent 122-- @tparam[opt=nil] string|pattern fg_urgent 123-- @see gears.color 124 125--- The urgent clients background color. 126-- @beautiful beautiful.tasklist_bg_urgent 127-- @tparam[opt=nil] string|pattern bg_urgent 128-- @see gears.color 129 130--- The minimized clients foreground (text) color. 131-- @beautiful beautiful.tasklist_fg_minimize 132-- @tparam[opt=nil] string|pattern fg_minimize 133-- @see gears.color 134 135--- The minimized clients background color. 136-- @beautiful beautiful.tasklist_bg_minimize 137-- @tparam[opt=nil] string|pattern bg_minimize 138-- @see gears.color 139 140--- The elements default background image. 141-- @beautiful beautiful.tasklist_bg_image_normal 142-- @tparam[opt=nil] string bg_image_normal 143 144--- The focused client background image. 145-- @beautiful beautiful.tasklist_bg_image_focus 146-- @tparam[opt=nil] string bg_image_focus 147 148--- The urgent clients background image. 149-- @beautiful beautiful.tasklist_bg_image_urgent 150-- @tparam[opt=nil] string bg_image_urgent 151 152--- The minimized clients background image. 153-- @beautiful beautiful.tasklist_bg_image_minimize 154-- @tparam[opt=nil] string bg_image_minimize 155 156--- Disable the tasklist client icons. 157-- @beautiful beautiful.tasklist_disable_icon 158-- @tparam[opt=false] boolean tasklist_disable_icon 159 160--- Disable the tasklist client titles. 161-- @beautiful beautiful.tasklist_disable_task_name 162-- @tparam[opt=false] boolean tasklist_disable_task_name 163 164--- Disable the extra tasklist client property notification icons. 165-- 166-- See the <a href="status_icons">Status icons</a> section for more details. 167-- 168-- @beautiful beautiful.tasklist_plain_task_name 169-- @tparam[opt=false] boolean tasklist_plain_task_name 170 171--- The tasklist font. 172-- @beautiful beautiful.tasklist_font 173-- @tparam[opt=nil] string font 174 175--- The focused client alignment. 176-- @beautiful beautiful.tasklist_align 177-- @tparam[opt=left] string align *left*, *right* or *center* 178 179--- The focused client title alignment. 180-- @beautiful beautiful.tasklist_font_focus 181-- @tparam[opt=nil] string font_focus 182 183--- The minimized clients font. 184-- @beautiful beautiful.tasklist_font_minimized 185-- @tparam[opt=nil] string font_minimized 186 187--- The urgent clients font. 188-- @beautiful beautiful.tasklist_font_urgent 189-- @tparam[opt=nil] string font_urgent 190 191--- The space between the tasklist elements. 192-- @beautiful beautiful.tasklist_spacing 193-- @tparam[opt=0] number spacing The spacing between tasks. 194 195--- The default tasklist elements shape. 196-- @beautiful beautiful.tasklist_shape 197-- @tparam[opt=nil] gears.shape shape 198 199--- The default tasklist elements border width. 200-- @beautiful beautiful.tasklist_shape_border_width 201-- @tparam[opt=0] number shape_border_width 202 203--- The default tasklist elements border color. 204-- @beautiful beautiful.tasklist_shape_border_color 205-- @tparam[opt=nil] string|color shape_border_color 206-- @see gears.color 207 208--- The focused client shape. 209-- @beautiful beautiful.tasklist_shape_focus 210-- @tparam[opt=nil] gears.shape shape_focus 211 212--- The focused client border width. 213-- @beautiful beautiful.tasklist_shape_border_width_focus 214-- @tparam[opt=0] number shape_border_width_focus 215 216--- The focused client border color. 217-- @beautiful beautiful.tasklist_shape_border_color_focus 218-- @tparam[opt=nil] string|color shape_border_color_focus 219-- @see gears.color 220 221--- The minimized clients shape. 222-- @beautiful beautiful.tasklist_shape_minimized 223-- @tparam[opt=nil] gears.shape shape_minimized 224 225--- The minimized clients border width. 226-- @beautiful beautiful.tasklist_shape_border_width_minimized 227-- @tparam[opt=0] number shape_border_width_minimized 228 229--- The minimized clients border color. 230-- @beautiful beautiful.tasklist_shape_border_color_minimized 231-- @tparam[opt=nil] string|color shape_border_color_minimized 232-- @see gears.color 233 234--- The urgent clients shape. 235-- @beautiful beautiful.tasklist_shape_urgent 236-- @tparam[opt=nil] gears.shape shape_urgent 237 238--- The urgent clients border width. 239-- @beautiful beautiful.tasklist_shape_border_width_urgent 240-- @tparam[opt=0] number shape_border_width_urgent 241 242--- The urgent clients border color. 243-- @beautiful beautiful.tasklist_shape_border_color_urgent 244-- @tparam[opt=nil] string|color shape_border_color_urgent 245-- @see gears.color 246 247-- Public structures 248tasklist.filter, tasklist.source = {}, {} 249 250local function tasklist_label(c, args, tb) 251 if not args then args = {} end 252 local theme = beautiful.get() 253 local align = args.align or theme.tasklist_align or "left" 254 local fg_normal = gcolor.ensure_pango_color(args.fg_normal or theme.tasklist_fg_normal or theme.fg_normal, "white") 255 local bg_normal = args.bg_normal or theme.tasklist_bg_normal or theme.bg_normal or "#000000" 256 local fg_focus = gcolor.ensure_pango_color(args.fg_focus or theme.tasklist_fg_focus or theme.fg_focus, fg_normal) 257 local bg_focus = args.bg_focus or theme.tasklist_bg_focus or theme.bg_focus or bg_normal 258 local fg_urgent = gcolor.ensure_pango_color(args.fg_urgent or theme.tasklist_fg_urgent or theme.fg_urgent, 259 fg_normal) 260 local bg_urgent = args.bg_urgent or theme.tasklist_bg_urgent or theme.bg_urgent or bg_normal 261 local fg_minimize = gcolor.ensure_pango_color(args.fg_minimize or theme.tasklist_fg_minimize or theme.fg_minimize, 262 fg_normal) 263 local bg_minimize = args.bg_minimize or theme.tasklist_bg_minimize or theme.bg_minimize or bg_normal 264 -- FIXME v5, remove the fallback theme.bg_image_* variables, see GH#1403 265 local bg_image_normal = args.bg_image_normal or theme.tasklist_bg_image_normal or theme.bg_image_normal 266 local bg_image_focus = args.bg_image_focus or theme.tasklist_bg_image_focus or theme.bg_image_focus 267 local bg_image_urgent = args.bg_image_urgent or theme.tasklist_bg_image_urgent or theme.bg_image_urgent 268 local bg_image_minimize = args.bg_image_minimize or theme.tasklist_bg_image_minimize or theme.bg_image_minimize 269 local tasklist_disable_icon = args.tasklist_disable_icon or theme.tasklist_disable_icon or false 270 local disable_task_name = args.disable_task_name or theme.tasklist_disable_task_name or false 271 local font = args.font or theme.tasklist_font or theme.font or "" 272 local font_focus = args.font_focus or theme.tasklist_font_focus or theme.font_focus or font or "" 273 local font_minimized = args.font_minimized or theme.tasklist_font_minimized or theme.font_minimized or font or "" 274 local font_urgent = args.font_urgent or theme.tasklist_font_urgent or theme.font_urgent or font or "" 275 local text = "" 276 local name = "" 277 local bg 278 local bg_image 279 local shape = args.shape or theme.tasklist_shape 280 local shape_border_width = args.shape_border_width or theme.tasklist_shape_border_width 281 local shape_border_color = args.shape_border_color or theme.tasklist_shape_border_color 282 283 -- symbol to use to indicate certain client properties 284 local sticky = args.sticky or theme.tasklist_sticky or "▪" 285 local ontop = args.ontop or theme.tasklist_ontop or '⌃' 286 local above = args.above or theme.tasklist_above or '▴' 287 local below = args.below or theme.tasklist_below or '▾' 288 local floating = args.floating or theme.tasklist_floating or '✈' 289 local maximized = args.maximized or theme.tasklist_maximized or '<b>+</b>' 290 local maximized_horizontal = args.maximized_horizontal or theme.tasklist_maximized_horizontal or '⬌' 291 local maximized_vertical = args.maximized_vertical or theme.tasklist_maximized_vertical or '⬍' 292 293 if tb then 294 tb:set_align(align) 295 end 296 297 if not theme.tasklist_plain_task_name then 298 if c.sticky then name = name .. sticky end 299 300 if c.ontop then name = name .. ontop 301 elseif c.above then name = name .. above 302 elseif c.below then name = name .. below end 303 304 if c.maximized then 305 name = name .. maximized 306 else 307 if c.maximized_horizontal then name = name .. maximized_horizontal end 308 if c.maximized_vertical then name = name .. maximized_vertical end 309 if c.floating then name = name .. floating end 310 end 311 end 312 313 if not disable_task_name then 314 if c.minimized then 315 name = name .. (gstring.xml_escape(c.icon_name) or gstring.xml_escape(c.name) or 316 gstring.xml_escape("<untitled>")) 317 else 318 name = name .. (gstring.xml_escape(c.name) or gstring.xml_escape("<untitled>")) 319 end 320 end 321 322 local focused = capi.client.focus == c 323 -- Handle transient_for: the first parent that does not skip the taskbar 324 -- is considered to be focused, if the real client has skip_taskbar. 325 if not focused and capi.client.focus and capi.client.focus.skip_taskbar 326 and capi.client.focus:get_transient_for_matching(function(cl) 327 return not cl.skip_taskbar 328 end) == c then 329 focused = true 330 end 331 332 if focused then 333 bg = bg_focus 334 text = text .. "<span color='"..fg_focus.."'>"..name.."</span>" 335 bg_image = bg_image_focus 336 font = font_focus 337 338 if args.shape_focus or theme.tasklist_shape_focus then 339 shape = args.shape_focus or theme.tasklist_shape_focus 340 end 341 342 if args.shape_border_width_focus or theme.tasklist_shape_border_width_focus then 343 shape_border_width = args.shape_border_width_focus or theme.tasklist_shape_border_width_focus 344 end 345 346 if args.shape_border_color_focus or theme.tasklist_shape_border_color_focus then 347 shape_border_color = args.shape_border_color_focus or theme.tasklist_shape_border_color_focus 348 end 349 elseif c.urgent then 350 bg = bg_urgent 351 text = text .. "<span color='"..fg_urgent.."'>"..name.."</span>" 352 bg_image = bg_image_urgent 353 font = font_urgent 354 355 if args.shape_urgent or theme.tasklist_shape_urgent then 356 shape = args.shape_urgent or theme.tasklist_shape_urgent 357 end 358 359 if args.shape_border_width_urgent or theme.tasklist_shape_border_width_urgent then 360 shape_border_width = args.shape_border_width_urgent or theme.tasklist_shape_border_width_urgent 361 end 362 363 if args.shape_border_color_urgent or theme.tasklist_shape_border_color_urgent then 364 shape_border_color = args.shape_border_color_urgent or theme.tasklist_shape_border_color_urgent 365 end 366 elseif c.minimized then 367 bg = bg_minimize 368 text = text .. "<span color='"..fg_minimize.."'>"..name.."</span>" 369 bg_image = bg_image_minimize 370 font = font_minimized 371 372 if args.shape_minimized or theme.tasklist_shape_minimized then 373 shape = args.shape_minimized or theme.tasklist_shape_minimized 374 end 375 376 if args.shape_border_width_minimized or theme.tasklist_shape_border_width_minimized then 377 shape_border_width = args.shape_border_width_minimized or theme.tasklist_shape_border_width_minimized 378 end 379 380 if args.shape_border_color_minimized or theme.tasklist_shape_border_color_minimized then 381 shape_border_color = args.shape_border_color_minimized or theme.tasklist_shape_border_color_minimized 382 end 383 else 384 bg = bg_normal 385 text = text .. "<span color='"..fg_normal.."'>"..name.."</span>" 386 bg_image = bg_image_normal 387 end 388 389 if tb then 390 tb:set_font(font) 391 end 392 393 local other_args = { 394 shape = shape, 395 shape_border_width = shape_border_width, 396 shape_border_color = shape_border_color, 397 } 398 399 return text, bg, bg_image, not tasklist_disable_icon and c.icon or nil, other_args 400end 401 402local function tasklist_update(s, w, buttons, filter, data, style, update_function, args) 403 local clients = {} 404 405 local source = args and args.source or tasklist.source.all_clients or nil 406 local list = source and source(s, args) or capi.client.get() 407 408 for _, c in ipairs(list) do 409 if not (c.skip_taskbar or c.hidden 410 or c.type == "splash" or c.type == "dock" or c.type == "desktop") 411 and filter(c, s) then 412 table.insert(clients, c) 413 end 414 end 415 416 local function label(c, tb) return tasklist_label(c, style, tb) end 417 418 update_function(w, buttons, label, data, clients, args) 419end 420 421--- Create a new tasklist widget. 422-- The last two arguments (update_function 423-- and layout) serve to customize the layout of the tasklist (eg. to 424-- make it vertical). For that, you will need to copy the 425-- awful.widget.common.list_update function, make your changes to it 426-- and pass it as update_function here. Also change the layout if the 427-- default is not what you want. 428-- 429-- @tparam table args 430-- @tparam screen args.screen The screen to draw tasklist for. 431-- @tparam function args.filter Filter function to define what clients will be listed. 432-- @tparam table args.buttons A table with buttons binding to set. 433-- @tparam[opt] function args.update_function Function to create a tag widget on each 434-- update. See `awful.widget.common.list_update`. 435-- @tparam[opt] table args.layout Container widget for tag widgets. Default 436-- is `wibox.layout.flex.horizontal`. 437-- @tparam[opt=awful.tasklist.source.all_clients] function args.source The 438-- function used to generate the list of client. 439-- @tparam[opt] table args.widget_template A custom widget to be used for each client 440-- @tparam[opt={}] table args.style The style overrides default theme. 441-- @tparam[opt=nil] string|pattern args.style.fg_normal 442-- @tparam[opt=nil] string|pattern args.style.bg_normal 443-- @tparam[opt=nil] string|pattern args.style.fg_focus 444-- @tparam[opt=nil] string|pattern args.style.bg_focus 445-- @tparam[opt=nil] string|pattern args.style.fg_urgent 446-- @tparam[opt=nil] string|pattern args.style.bg_urgent 447-- @tparam[opt=nil] string|pattern args.style.fg_minimize 448-- @tparam[opt=nil] string|pattern args.style.bg_minimize 449-- @tparam[opt=nil] string args.style.bg_image_normal 450-- @tparam[opt=nil] string args.style.bg_image_focus 451-- @tparam[opt=nil] string args.style.bg_image_urgent 452-- @tparam[opt=nil] string args.style.bg_image_minimize 453-- @tparam[opt=nil] boolean args.style.tasklist_disable_icon 454-- @tparam[opt=false] boolean args.style.disable_task_name 455-- @tparam[opt=nil] string args.style.font 456-- @tparam[opt=left] string args.style.align *left*, *right* or *center* 457-- @tparam[opt=nil] string args.style.font_focus 458-- @tparam[opt=nil] string args.style.font_minimized 459-- @tparam[opt=nil] string args.style.font_urgent 460-- @tparam[opt=nil] number args.style.spacing The spacing between tags. 461-- @tparam[opt=nil] gears.shape args.style.shape 462-- @tparam[opt=nil] number args.style.shape_border_width 463-- @tparam[opt=nil] string|color args.style.shape_border_color 464-- @tparam[opt=nil] gears.shape args.style.shape_focus 465-- @tparam[opt=nil] number args.style.shape_border_width_focus 466-- @tparam[opt=nil] string|color args.style.shape_border_color_focus 467-- @tparam[opt=nil] gears.shape args.style.shape_minimized 468-- @tparam[opt=nil] number args.style.shape_border_width_minimized 469-- @tparam[opt=nil] string|color args.style.shape_border_color_minimized 470-- @tparam[opt=nil] gears.shape args.style.shape_urgent 471-- @tparam[opt=nil] number args.style.shape_border_width_urgent 472-- @tparam[opt=nil] string|color args.style.shape_border_color_urgent 473-- @param filter **DEPRECATED** use args.filter 474-- @param buttons **DEPRECATED** use args.buttons 475-- @param style **DEPRECATED** use args.style 476-- @param update_function **DEPRECATED** use args.update_function 477-- @param base_widget **DEPRECATED** use args.base_widget 478-- @function awful.tasklist 479function tasklist.new(args, filter, buttons, style, update_function, base_widget) 480 local screen = nil 481 482 local argstype = type(args) 483 484 -- Detect the old function signature 485 if argstype == "number" or argstype == "screen" or 486 (argstype == "table" and args.index and args == capi.screen[args.index]) then 487 gdebug.deprecate("The `screen` paramater is deprecated, use `args.screen`.", 488 {deprecated_in=5}) 489 490 screen = get_screen(args) 491 args = {} 492 end 493 494 assert(type(args) == "table") 495 496 for k, v in pairs { filter = filter, 497 buttons = buttons, 498 style = style, 499 update_function = update_function, 500 layout = base_widget 501 } do 502 gdebug.deprecate("The `awful.widget.tasklist()` `"..k 503 .."` paramater is deprecated, use `args."..k.."`.", 504 {deprecated_in=5}) 505 args[k] = v 506 end 507 508 screen = screen or get_screen(args.screen) 509 local uf = args.update_function or common.list_update 510 local w = base.make_widget_from_value(args.layout or flex.horizontal) 511 512 local data = setmetatable({}, { __mode = 'k' }) 513 514 local spacing = args.style and args.style.spacing or args.layout and args.layout.spacing 515 or beautiful.tasklist_spacing 516 if w.set_spacing and spacing then 517 w:set_spacing(spacing) 518 end 519 520 local queued_update = false 521 522 -- For the tests 523 function w._do_tasklist_update_now() 524 queued_update = false 525 if screen.valid then 526 tasklist_update(screen, w, args.buttons, args.filter, data, args.style, uf, args) 527 end 528 end 529 530 function w._do_tasklist_update() 531 -- Add a delayed callback for the first update. 532 if not queued_update then 533 timer.delayed_call(w._do_tasklist_update_now) 534 queued_update = true 535 end 536 end 537 function w._unmanage(c) 538 data[c] = nil 539 end 540 if instances == nil then 541 instances = setmetatable({}, { __mode = "k" }) 542 local function us(s) 543 local i = instances[get_screen(s)] 544 if i then 545 for _, tlist in pairs(i) do 546 tlist._do_tasklist_update() 547 end 548 end 549 end 550 local function u() 551 for s in pairs(instances) do 552 if s.valid then 553 us(s) 554 end 555 end 556 end 557 558 tag.attached_connect_signal(nil, "property::selected", u) 559 tag.attached_connect_signal(nil, "property::activated", u) 560 capi.client.connect_signal("property::urgent", u) 561 capi.client.connect_signal("property::sticky", u) 562 capi.client.connect_signal("property::ontop", u) 563 capi.client.connect_signal("property::above", u) 564 capi.client.connect_signal("property::below", u) 565 capi.client.connect_signal("property::floating", u) 566 capi.client.connect_signal("property::maximized_horizontal", u) 567 capi.client.connect_signal("property::maximized_vertical", u) 568 capi.client.connect_signal("property::maximized", u) 569 capi.client.connect_signal("property::minimized", u) 570 capi.client.connect_signal("property::name", u) 571 capi.client.connect_signal("property::icon_name", u) 572 capi.client.connect_signal("property::icon", u) 573 capi.client.connect_signal("property::skip_taskbar", u) 574 capi.client.connect_signal("property::screen", function(c, old_screen) 575 us(c.screen) 576 us(old_screen) 577 end) 578 capi.client.connect_signal("property::hidden", u) 579 capi.client.connect_signal("tagged", u) 580 capi.client.connect_signal("untagged", u) 581 capi.client.connect_signal("unmanage", function(c) 582 u(c) 583 for _, i in pairs(instances) do 584 for _, tlist in pairs(i) do 585 tlist._unmanage(c) 586 end 587 end 588 end) 589 capi.client.connect_signal("list", u) 590 capi.client.connect_signal("focus", u) 591 capi.client.connect_signal("unfocus", u) 592 capi.screen.connect_signal("removed", function(s) 593 instances[get_screen(s)] = nil 594 end) 595 end 596 w._do_tasklist_update() 597 local list = instances[screen] 598 if not list then 599 list = setmetatable({}, { __mode = "v" }) 600 instances[screen] = list 601 end 602 table.insert(list, w) 603 return w 604end 605 606--- Filtering function to include all clients. 607-- @return true 608-- @filterfunction awful.tasklist.filter.allscreen 609function tasklist.filter.allscreen() 610 return true 611end 612 613--- Filtering function to include the clients from all tags on the screen. 614-- @param c The client. 615-- @param screen The screen we are drawing on. 616-- @return true if c is on screen, false otherwise 617-- @filterfunction awful.tasklist.filter.alltags 618function tasklist.filter.alltags(c, screen) 619 -- Only print client on the same screen as this widget 620 return get_screen(c.screen) == get_screen(screen) 621end 622 623--- Filtering function to include only the clients from currently selected tags. 624-- @param c The client. 625-- @param screen The screen we are drawing on. 626-- @return true if c is in a selected tag on screen, false otherwise 627-- @filterfunction awful.tasklist.filter.currenttags 628function tasklist.filter.currenttags(c, screen) 629 screen = get_screen(screen) 630 -- Only print client on the same screen as this widget 631 if get_screen(c.screen) ~= screen then return false end 632 -- Include sticky client too 633 if c.sticky then return true end 634 local tags = screen.tags 635 for _, t in ipairs(tags) do 636 if t.selected then 637 local ctags = c:tags() 638 for _, v in ipairs(ctags) do 639 if v == t then 640 return true 641 end 642 end 643 end 644 end 645 return false 646end 647 648--- Filtering function to include only the minimized clients from currently selected tags. 649-- @param c The client. 650-- @param screen The screen we are drawing on. 651-- @return true if c is in a selected tag on screen and is minimized, false otherwise 652-- @filterfunction awful.tasklist.filter.minimizedcurrenttags 653function tasklist.filter.minimizedcurrenttags(c, screen) 654 screen = get_screen(screen) 655 -- Only print client on the same screen as this widget 656 if get_screen(c.screen) ~= screen then return false end 657 -- Check client is minimized 658 if not c.minimized then return false end 659 -- Include sticky client 660 if c.sticky then return true end 661 local tags = screen.tags 662 for _, t in ipairs(tags) do 663 -- Select only minimized clients 664 if t.selected then 665 local ctags = c:tags() 666 for _, v in ipairs(ctags) do 667 if v == t then 668 return true 669 end 670 end 671 end 672 end 673 return false 674end 675 676--- Filtering function to include only the currently focused client. 677-- @param c The client. 678-- @param screen The screen we are drawing on. 679-- @return true if c is focused on screen, false otherwise 680-- @filterfunction awful.tasklist.filter.focused 681function tasklist.filter.focused(c, screen) 682 -- Only print client on the same screen as this widget 683 return get_screen(c.screen) == get_screen(screen) and capi.client.focus == c 684end 685 686--- Get all the clients in an undefined order. 687-- 688-- This is the default source. 689-- 690-- @sourcefunction awful.tasklist.source.all_clients 691function tasklist.source.all_clients() 692 return capi.client.get() 693end 694 695function tasklist.mt:__call(...) 696 return tasklist.new(...) 697end 698 699return setmetatable(tasklist, tasklist.mt) 700 701-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 702