1 -----------------------------------------------
2 -- awful: AWesome Function very UsefuL --
3 -- Common useful awesome functions --
5 -- © 2008 Julien Danjou <julien@danjou.info> --
6 -----------------------------------------------
8 -- We usually are required as 'awful'
9 -- But that can be changed.
10 local P
= {} -- package
11 if _REQUIREDNAME
== nil then
17 -- Grab environment we need
20 local loadstring
= loadstring
24 local awesome
= awesome
29 local titlebar
= titlebar
34 local keygrabber
= keygrabber
49 P
.tag.history
.data
= {}
50 P
.tag.history
.data
.past
= {}
51 P
.tag.history
.data
.current
= {}
55 P
.widget
.taglist
.label
= {}
56 P
.widget
.tasklist
= {}
57 P
.widget
.tasklist
.label
= {}
59 --- Create a new userhook (for external libs).
60 -- @param name Hook name.
61 local function userhook_create(name
)
63 P
.hooks
[name
] = function (f
)
64 table.insert(P
.myhooks
[name
], { callback
= f
})
68 --- Call a created userhook (for external libs).
69 -- @param name Hook name.
70 local function userhook_call(name
, args
)
71 for i
, o
in pairs(P
.myhooks
[name
]) do
72 P
.myhooks
[name
][i
]['callback'](unpack(args
))
78 -- @param i An absolute index to fit into #t.
79 -- @return The object at new index.
80 local function cycle(t
, i
)
81 while i
> t
do i
= i
- t
end
82 while i
< 1 do i
= i
+ t
end
86 --- Get a client by its relative index to the focused window.
87 -- @usage Set i to 1 to get next, -1 to get previous.
88 -- @param i The index.
89 -- @param c Optional client.
90 -- @return A client, or nil if no client is available.
91 function P
.client
.next(i
, c
)
92 -- Get currently focused client
93 local sel
= c
or client
.focus_get()
95 -- Get all visible clients
96 local cls
= client
.visible_get(sel
.screen
)
97 -- Loop upon each client
98 for idx
, c
in ipairs(cls
) do
101 return cls
[cycle(#cls
, idx
+i
)]
107 --- Focus a client by its relative index.
108 -- @param i The index.
109 -- @param c Optional client.
110 function P
.client
.focus(i
, c
)
111 local target
= P
.client
.next(i
, c
)
117 --- Swap a client by its relative index.
118 -- @param i The index.
119 -- @param c Optional client, otherwise focused one is used.
120 function P
.client
.swap(i
, c
)
121 local sel
= c
or client
.focus_get()
122 local target
= P
.client
.next(i
, sel
)
128 --- Get the master window
129 -- @param screen Optional screen number, otherwise screen mouse is used.
130 -- @return The master window.
131 function P
.client
.master(screen
)
132 local s
= screen
or mouse
.screen
133 return client
.visible_get(s
)[1]
136 --- Move/resize a client relative to current coordinates.
137 -- @param x The relative x coordinate.
138 -- @param y The relative y coordinate.
139 -- @param w The relative width.
140 -- @param h The relative height.
141 -- @param c The optional client, otherwise focused one is used.
142 function P
.client
.moveresize(x
, y
, w
, h
, c
)
143 local sel
= c
or client
.focus_get()
144 local coords
= sel
.coords
145 coords
['x'] = coords
['x'] + x
146 coords
['y'] = coords
['y'] + y
147 coords
['width'] = coords
['width'] + w
148 coords
['height'] = coords
['height'] + h
152 --- Maximize a client to use the full workspace area.
153 -- @param c A client, or the focused one if nil.
154 function P
.client
.maximize(c
)
155 local sel
= c
or client
.focus_get()
158 local ws
= screen
.workspace_get(sel
.screen
)
159 ws
.width
= ws
.width
- 2 * sel
.border_width
160 ws
.height
= ws
.height
- 2 * sel
.border_width
165 --- Give the focus to a screen, and move pointer.
166 -- @param Screen number.
167 function P
.screen
.focus(i
)
168 local sel
= client
.focus_get()
175 s
= cycle(screen
.count(), s
+ i
)
177 -- Move the mouse on the screen
178 mouse
.coords
= screen
.coords_get(s
)
181 --- Compare 2 tables of tags.
182 -- @param a The first table.
183 -- @param b The second table of tags.
184 -- @return True if the tables are identical, false otherwise.
185 local function tag_compare_select(a
, b
)
186 if not a
or not b
then
189 -- Quick size comparison
193 for ka
, va
in pairs(a
) do
194 if b
[ka
] ~= va
.selected
then
198 for kb
, vb
in pairs(b
) do
199 if a
[kb
].selected
~= vb
then
206 --- Update the tag history.
207 -- @param screen The screen number.
208 function P
.tag.history
.update(screen
)
209 local curtags
= tag.geti(screen
)
210 if not tag_compare_select(curtags
, P
.tag.history
.data
.current
[screen
]) then
211 P
.tag.history
.data
.past
[screen
] = P
.tag.history
.data
.current
[screen
]
212 P
.tag.history
.data
.current
[screen
] = {}
213 for k
, v
in ipairs(curtags
) do
214 P
.tag.history
.data
.current
[screen
][k
] = v
.selected
219 -- Revert tag history.
220 -- @param screen The screen number.
221 function P
.tag.history
.restore(screen
)
222 local s
= screen
or mouse
.screen
223 local tags
= tag.geti(s
)
224 for k
, t
in pairs(tags
) do
225 t
.selected
= P
.tag.history
.data
.past
[s
][k
]
229 --- Return a table with all visible tags
230 -- @param s Screen number.
231 -- @return A table with all selected tags.
232 function P
.tag.selectedlist(s
)
233 local screen
= s
or mouse
.screen
234 local tags
= tag.geti(screen
)
236 for i
, t
in pairs(tags
) do
238 vtags
[#vtags
+ 1] = t
244 --- Return only the first visible tag.
245 -- @param s Screen number.
246 function P
.tag.selected(s
)
247 return P
.tag.selectedlist(s
)[1]
250 --- Set master width factor.
251 -- @param mwfact Master width factor.
252 function P
.tag.setmwfact(mwfact
)
253 local t
= P
.tag.selected()
259 --- Increase master width factor.
260 -- @param add Value to add to master width factor.
261 function P
.tag.incmwfact(add
)
262 local t
= P
.tag.selected()
264 t
.mwfact
= t
.mwfact
+ add
268 --- Set the number of master windows.
269 -- @param nmaster The number of master windows.
270 function P
.tag.setnmaster(nmaster
)
271 local t
= P
.tag.selected()
277 --- Increase the number of master windows.
278 -- @param add Value to add to number of master windows.
279 function P
.tag.incnmaster(add
)
280 local t
= P
.tag.selected()
282 t
.nmaster
= t
.nmaster
+ add
286 --- Set number of column windows.
287 -- @param ncol The number of column.
288 function P
.tag.setncol(ncol
)
289 local t
= P
.tag.selected()
295 --- Increase number of column windows.
296 -- @param add Value to add to number of column windows.
297 function P
.tag.incncol(add
)
298 local t
= P
.tag.selected()
300 t
.ncol
= t
.ncol
+ add
305 -- @param Optional screen number.
306 function P
.tag.viewnone(screen
)
307 local tags
= tag.get(screen
or mouse
.screen
)
308 for i
, t
in pairs(tags
) do
313 --- View a tag by its index.
314 -- @param i The relative index to see.
315 -- @param screen Optional screen number.
316 function P
.tag.viewidx(i
, screen
)
317 local tags
= tag.geti(screen
or mouse
.screen
)
318 local sel
= P
.tag.selected()
320 for k
, t
in ipairs(tags
) do
322 tags
[cycle(#tags
, k
+ i
)].selected
= true
327 --- View next tag. This is the same as tag.viewidx(1).
328 function P
.tag.viewnext()
329 return P
.tag.viewidx(1)
332 --- View previous tag. This is the same a tag.viewidx(-1).
333 function P
.tag.viewprev()
334 return P
.tag.viewidx(-1)
338 -- @param t The tag object.
339 function P
.tag.viewonly(t
)
344 --- View only a set of tags.
345 -- @param tags A table with tags to view only.
346 -- @param screen Optional screen number of the tags.
347 function P
.tag.viewmore(tags
, screen
)
348 P
.tag.viewnone(screen
)
349 for i
, t
in pairs(tags
) do
354 --- Move a client to a tag.
355 -- @param target The tag to move the client to.
356 -- @para c Optional client to move, otherwise the focused one is used.
357 function P
.client
.movetotag(target
, c
)
358 local sel
= c
or client
.focus_get();
359 -- Check that tag and client screen are identical
360 if sel
.screen
~= target
.screen
then return end
361 local tags
= tag.get(sel
.screen
)
362 for k
, t
in pairs(tags
) do
365 sel
:tag(target
, true)
368 --- Toggle a tag on a client.
369 -- @param target The tag to toggle.
370 -- @param c Optional client to toggle, otherwise the focused one is used.
371 function P
.client
.toggletag(target
, c
)
372 local sel
= c
or client
.focus_get();
373 -- Check that tag and client screen are identical
374 if sel
.screen
~= target
.screen
then return end
377 -- Count how many tags has the client
378 -- an only toggle tag if the client has at least one tag other than target
379 for k
, v
in pairs(tag.get(sel
.screen
)) do
380 if target
~= v
and sel
:istagged(v
) then
386 sel
:tag(target
, not sel
:istagged(target
))
391 --- Toggle the floating status of a client.
392 -- @param c Optional client, the focused on if not set.
393 function P
.client
.togglefloating(c
)
394 local sel
= c
or client
.focus_get();
396 sel
.floating
= not sel
.floating
400 --- Move a client to a screen. Default is next screen, cycling.
401 -- @param c The client to move.
402 -- @param s The screen number, default to current + 1.
403 function P
.client
.movetoscreen(c
, s
)
404 local sel
= c
or client
.focus_get();
406 local sc
= screen
.count()
410 if s
> sc
then s
= 1 elseif s
< 1 then s
= sc
end
412 mouse
.coords
= screen
.coords_get(s
)
417 --- Get the current layout name.
418 -- @param screen The screen number.
419 function P
.layout
.get(screen
)
420 local t
= P
.tag.selected(screen
)
426 -- Just set an awful mark to a client to move it later.
427 local awfulmarked
= {}
428 userhook_create('marked')
429 userhook_create('unmarked')
431 --- Mark a client, and then call 'marked' hook.
432 -- @param c The client to mark, the focused one if not specified.
433 -- @return True if the client has been marked. False if the client was already marked.
434 function P
.client
.mark (c
)
435 local cl
= c
or client
.focus_get()
437 for k
, v
in pairs(awfulmarked
) do
443 table.insert(awfulmarked
, cl
)
446 userhook_call('marked', {cl
})
451 --- Unmark a client and then call 'unmarked' hook.
452 -- @param c The client to unmark, or the focused one if not specified.
453 -- @return True if the client has been unmarked. False if the client was not marked.
454 function P
.client
.unmark(c
)
455 local cl
= c
or client
.focus_get()
457 for k
, v
in pairs(awfulmarked
) do
459 table.remove(awfulmarked
, k
)
460 userhook_call('unmarked', {cl
})
468 --- Check if a client is marked.
469 -- @param c The client to check, or the focused one otherwise.
470 function P
.client
.ismarked(c
)
471 local cl
= c
or client
.focus_get()
473 for k
, v
in pairs(awfulmarked
) do
482 --- Toggle a client as marked.
483 -- @param c The client to toggle mark.
484 function P
.client
.togglemarked(c
)
485 local cl
= c
or client
.focus_get()
487 if not P
.client
.mark(c
) then
492 --- Return the marked clients and empty the marked table.
493 -- @return A table with all marked clients.
494 function P
.client
.getmarked()
495 for k
, v
in pairs(awfulmarked
) do
496 userhook_call('unmarked', {v
})
504 --- Change the layout of the current tag.
505 -- @param layouts A table of layouts.
506 -- @param i Relative index.
507 function P
.layout
.inc(layouts
, i
)
508 local t
= P
.tag.selected()
509 local number_of_layouts
= 0
510 local rev_layouts
= {}
511 for i
, v
in ipairs(layouts
) do
513 number_of_layouts
= number_of_layouts
+ 1
516 local cur_layout
= layout
.get()
517 local new_layout_index
= (rev_layouts
[cur_layout
] + i
) % number_of_layouts
518 if new_layout_index
== 0 then
519 new_layout_index
= number_of_layouts
521 t
.layout
= layouts
[new_layout_index
]
525 --- Set the layout of the current tag by name.
526 -- @param layout Layout name.
527 function P
.layout
.set(layout
)
528 local t
= P
.tag.selected()
534 P
.hooks
['userhook_create'] = userhook_create
535 P
.hooks
['userhook_call'] = userhook_call
537 for name
, hook
in pairs(hooks
) do
538 if name
~= 'timer' then
539 P
.hooks
[name
] = function (f
)
541 if P
.myhooks
[name
] == nil then
543 hooks
[name
](function (...)
545 for i
, o
in pairs(P
.myhooks
[name
]) do
546 P
.myhooks
[name
][i
]['callback'](...)
552 table.insert(P
.myhooks
[name
], {callback
= f
})
555 P
.hooks
[name
] = function (time
, f
, runnow
)
557 if P
.myhooks
[name
] == nil then
559 hooks
[name
](1, function (...)
561 for i
,o
in pairs(P
.myhooks
[name
]) do
562 if P
.myhooks
[name
][i
]['counter'] >= P
.myhooks
[name
][i
]['timer'] then
563 P
.myhooks
[name
][i
]['counter'] = 1
564 P
.myhooks
[name
][i
]['callback'](...)
566 P
.myhooks
[name
][i
]['counter'] = P
.myhooks
[name
][i
]['counter']+1
574 table.insert(P
.myhooks
[name
], {callback
= f
, timer
= time
, counter
= time
})
576 table.insert(P
.myhooks
[name
], {callback
= f
, timer
= time
, counter
= 0})
583 -- @param cmd The command.
584 -- @return The os.execute() return value.
585 function P
.spawn(cmd
)
586 return os
.execute(cmd
.. "&")
590 -- @return The return value of Lua code.
592 return assert(loadstring("return " .. s
))()
595 --- Use bash completion system to complete command and filename.
596 -- @param command The command line.
597 -- @param cur_pos The cursor position.
598 -- @paran ncomp The element number to complete.
599 -- @return The new commande and the new cursor position.
600 function P
.completion
.bash(command
, cur_pos
, ncomp
)
604 local cword_index
= 0
605 local cword_start
= 0
608 local comptype
= "file"
610 -- do nothing if we are on a letter, i.e. not at len + 1 or on a space
611 if cur_pos
~= #command
+ 1 and command
:sub(cur_pos
, cur_pos
) ~= " " then
612 return command
, cur_pos
613 elseif #command
== 0 then
614 return command
, cur_pos
617 while wend
<= #command
do
618 wend
= command
:find(" ", wstart
)
619 if not wend
then wend
= #command
+ 1 end
620 table.insert(words
, command
:sub(wstart
, wend
- 1))
621 if cur_pos
>= wstart
and cur_pos
<= wend
+ 1 then
630 if cword_index
== 1 then
634 local c
= io
.popen("/usr/bin/env bash -c 'compgen -A " .. comptype
.. " " .. words
[cword_index
] .. "'")
638 local line
= c
:read("*line")
639 if not line
then break end
640 table.insert(output
, line
)
645 -- no completion, return
647 return command
, cur_pos
651 while ncomp
> #output
do
652 ncomp
= ncomp
- #output
655 local str
= command
:sub(1, cword_start
- 1) .. output
[ncomp
] .. command
:sub(cword_end
)
656 cur_pos
= cword_end
+ #output
[ncomp
] + 1
661 --- Draw the prompt text with a cursor.
662 -- @param text The text.
663 -- @param text_color The text color.
664 -- @param cursor_color The cursor color.
665 -- @param cursor_pos The cursor position.
666 local function prompt_text_with_cursor(text
, text_color
, cursor_color
, cursor_pos
)
668 if not text
then text
= "" end
669 if #text
< cursor_pos
then
672 char
= escape(text
:sub(cursor_pos
, cursor_pos
))
674 local text_start
= escape(text
:sub(1, cursor_pos
- 1))
675 local text_end
= escape(text
:sub(cursor_pos
+ 1))
676 return text_start
.. "<span background=\"" .. cursor_color
.. "\" foreground=\"" .. text_color
.. "\">" .. char
.. "</span>" .. text_end
679 --- Run a prompt in a box.
680 -- @param args A table with optional arguments: cursor_fg, cursor_bg, prompt.
681 -- @param textbox The textbox to use for the prompt.
682 -- @param exe_callback The callback function to call with command as argument when finished.
683 -- @param completion_callback The callback function to call to get completion.
684 function P
.prompt(args
, textbox
, exe_callback
, completion_callback
)
685 if not args
then return end
687 local command_before_comp
688 local cur_pos_before_comp
689 local prompt
= args
.prompt
or ""
690 local inv_col
= args
.cursor_fg
or "black"
691 local cur_col
= args
.cursor_bg
or "white"
692 -- The cursor position
694 -- The completion element to use on completion request.
696 if not textbox
or not exe_callback
then
699 textbox
.text
= prompt
.. prompt_text_with_cursor(text
, inv_col
, cur_col
, cur_pos
)
702 local has_ctrl
= false
704 -- Compute modifiers keys
705 for k
, v
in ipairs(mod) do
706 if v
== "Control" then has_ctrl
= true end
716 if key
== "Return" then
718 exe_callback(command
)
720 elseif key
== "Escape" then
730 elseif key
== "e" then
731 cur_pos
= #command
+ 1
732 elseif key
== "w" then
735 local cword_start
= 1
737 while wend
< cur_pos
do
738 wend
= command
:find(" ", wstart
)
739 if not wend
then wend
= #command
+ 1 end
740 if cur_pos
>= wstart
and cur_pos
<= wend
+ 1 then
742 cword_end
= cur_pos
- 1
747 command
= command
:sub(1, cword_start
- 1) .. command
:sub(cword_end
+ 1)
748 cur_pos
= cword_start
751 if completion_callback
then
753 if key
:byte() == 9 then
755 command_before_comp
= command
756 cur_pos_before_comp
= cur_pos
758 command
, cur_pos
= completion_callback(command_before_comp
, cur_pos_before_comp
, ncomp
)
767 if key
== "Home" then
769 elseif key
== "End" then
770 cur_pos
= #command
+ 1
771 elseif key
== "BackSpace" then
773 command
= command
:sub(1, cur_pos
- 2) .. command
:sub(cur_pos
)
774 cur_pos
= cur_pos
- 1
777 elseif key
:byte() == 127 then
778 command
= command
:sub(1, cur_pos
- 1) .. command
:sub(cur_pos
+ 1)
779 elseif key
== "Left" then
780 cur_pos
= cur_pos
- 1
781 elseif key
== "Right" then
782 cur_pos
= cur_pos
+ 1
784 -- len() is UTF-8 aware but #key is not,
785 -- so check that we have one UTF-8 char but advance the cursor of # position
786 if key
:len() == 1 then
787 command
= command
:sub(1, cur_pos
- 1) .. key
.. command
:sub(cur_pos
)
788 cur_pos
= cur_pos
+ #key
793 elseif cur_pos
> #command
+ 1 then
794 cur_pos
= #command
+ 1
799 textbox
.text
= prompt
.. prompt_text_with_cursor(command
, inv_col
, cur_col
, cur_pos
)
805 --- Escape a string from XML char.
806 -- Useful to set raw text in textbox.
807 -- @param text Text to escape.
808 -- @return Escape text.
809 function P
.escape(text
)
810 text
= text
:gsub("&", "&")
811 text
= text
:gsub("<", "<")
812 text
= text
:gsub(">", ">")
813 text
= text
:gsub("'", "'")
814 text
= text
:gsub("\"", """)
818 --- Unescape a string from entities.
819 -- @param text Text to unescape.
820 -- @return Unescaped text.
821 function P
.unescape(text
)
822 text
= text
:gsub("&", "&")
823 text
= text
:gsub("<", "<")
824 text
= text
:gsub(">", ">")
825 text
= text
:gsub("'", "'")
826 text
= text
:gsub(""", "\"")
830 --- Return labels for a taglist widget with all tag from screen.
831 -- It returns the tag name and set a special
832 -- foreground and background color for selected tags.
834 -- @param bg_focus The background color for selected tag.
835 -- @param fg_focus The foreground color for selected tag.
836 -- @return A string to print.
837 function P
.widget
.taglist
.label
.all(t
, bg_focus
, fg_focus
)
839 local background
= ""
840 local sel
= client
.focus_get()
841 if sel
and sel
:istagged(t
) then
842 background
= "resize=\"true\" image=\"@AWESOME_ICON_PATH@/taglist/squarefw.png\""
844 for k
, c
in pairs(client
.get()) do
845 if c
:istagged(t
) then
846 background
= "resize=\"true\" image=\"@AWESOME_ICON_PATH@/taglist/squarew.png\""
852 text
= "<bg "..background
.." color='"..bg_focus
.."'/> <span color='"..fg_focus
.."'>"..P
.escape(t
.name
).."</span> "
854 text
= " <bg "..background
.." />"..P
.escape(t
.name
).." "
859 local function widget_tasklist_label_common(c
, bg_focus
, fg_focus
)
862 text
= "<bg image=\"@AWESOME_ICON_PATH@/tasklist/floatingw.png\" align=\"right\"/>"
864 if client
.focus_get() == c
then
865 text
= text
.. " <bg color='"..bg_focus
.."'/><span color='"..fg_focus
.."'>"..P
.escape(c
.name
).."</span> "
867 text
= text
.. " "..P
.escape(c
.name
).." "
872 --- Return labels for a tasklist widget with clients from all tags and screen.
873 -- It returns the client name and set a special
874 -- foreground and background color for focused client.
875 -- It also puts a special icon for floating windows.
876 -- @param c The client.
877 -- @param screen The screen we are drawing on.
878 -- @param bg_focus The background color for focused client.
879 -- @param fg_focus The foreground color for focused client.
880 -- @return A string to pring.
881 function P
.widget
.tasklist
.label
.allscreen(c
, screen
, bg_focus
, fg_focus
)
882 return widget_tasklist_label_common(c
, bg_focus
, fg_focus
)
885 --- Return labels for a tasklist widget with clients from all tags.
886 -- It returns the client name and set a special
887 -- foreground and background color for focused client.
888 -- It also puts a special icon for floating windows.
889 -- @param c The client.
890 -- @param screen The screen we are drawing on.
891 -- @param bg_focus The background color for focused client.
892 -- @param fg_focus The foreground color for focused client.
893 -- @return A string to pring.
894 function P
.widget
.tasklist
.label
.alltags(c
, screen
, bg_focus
, fg_focus
)
895 -- Only print client on the same screen as this widget
896 if c
.screen
~= screen
then return end
897 return widget_tasklist_label_common(c
, bg_focus
, fg_focus
)
900 --- Return labels for a tasklist widget with clients from currently selected tags.
901 -- It returns the client name and set a special
902 -- foreground and background color for focused client.
903 -- It also puts a special icon for floating windows.
904 -- @param c The client.
905 -- @param screen The screen we are drawing on.
906 -- @param bg_focus The background color for focused client.
907 -- @param fg_focus The foreground color for focused client.
908 -- @return A string to pring.
909 function P
.widget
.tasklist
.label
.currenttags(c
, screen
, bg_focus
, fg_focus
)
910 -- Only print client on the same screen as this widget
911 if c
.screen
~= screen
then return end
912 for k
, t
in pairs(tag.get(screen
)) do
913 if t
.selected
and c
:istagged(t
) then
914 return widget_tasklist_label_common(c
, bg_focus
, fg_focus
)
919 --- Create a standard titlebar.
920 -- @param args Arguments.
921 -- fg: the foreground color,
922 -- bg: the background color.
923 -- @return A brand new titlebar.
924 function P
.titlebar
.new(args
)
926 if args
.fg
then targs
.fg
= args
.fg
end
927 if args
.bg
then targs
.bg
= args
.bg
end
928 local tb
= titlebar(targs
)
929 tb
:widget_add(widget({ type = "appicon", name
= "appicon", align
= "left" }))
930 local title
= widget({ type = "textbox", name
= "title", align
= "flex" })
931 title
:mouse_add(mouse({ args
.modkey
}, 1, function (t
) t
:client_get():mouse_move() end))
932 title
:mouse_add(mouse({ args
.modkey
}, 3, function (t
) t
:client_get():mouse_resize() end))
934 local close_button
= widget({ type = "textbox", name
= "close", align
= "right" })
935 close_button
:mouse_add(mouse({ }, 1, function (t
) t
:client_get():kill() end))
936 tb
:widget_add(close_button
)
940 --- Update a titlebar. This should be called in some hooks.
941 -- @param c The client to update.
942 -- @param bg The background color for normal client.
943 -- @param fg The foreground color for normal client.
944 -- @param bg_focus The background color for focused client.
945 -- @param fg_focus The foreground color for focused client.
946 function P
.titlebar
.update(c
, bg
, fg
, bg_focus
, fg_focus
)
948 local widgets
= c
.titlebar
:widget_get()
949 if widgets
.title
then
950 widgets
.title
.text
= " " .. P
.escape(c
.name
)
952 if client
.focus_get() == c
then
953 c
.titlebar
.bg
= bg_focus
954 c
.titlebar
.fg
= fg_focus
955 if widgets
.close
then
956 widgets
.close
.text
= "<bg image=\"@AWESOME_ICON_PATH@/titlebar/closer.png\" resize=\"true\"/>"
961 if widgets
.close
then
962 widgets
.close
.text
= "<bg image=\"@AWESOME_ICON_PATH@/titlebar/close.png\" resize=\"true\"/>"