1 ---------------------------------------------------------------------------
2 -- @author Julien Danjou <julien@danjou.info>
3 -- @copyright 2008 Julien Danjou
4 -- @release @AWESOME_VERSION@
5 ---------------------------------------------------------------------------
7 -- Grab environment we need
8 local util
= require("awful.util")
9 local tag = require("awful.tag")
15 local setmetatable
= setmetatable
24 -- we use require("awful.screen") inside functions to prevent circular dependencies.
27 --- Useful client manipulation functions.
34 client
.data
.focus
= {}
35 client
.data
.urgent
= {}
36 client
.data
.marked
= {}
37 client
.data
.properties
= setmetatable({}, { __mode
= 'k' })
38 client
.data
.persistent_properties_registered
= {} -- keys are names of persistent properties, value always true
39 client
.data
.persistent_properties_loaded
= setmetatable({}, { __mode
= 'k' }) -- keys are clients, value always true
44 client
.focus
.history
= {}
49 client
.shape
= require("awful.client.shape")
52 -- Jump to the given client. Takes care of focussing the screen, the right tag,
54 -- @param c the client to jump to
55 -- @param merge If true then merge tags when clients are not visible.
56 function client
.jumpto(c
, merge
)
57 local s
= capi
.client
.focus
and capi
.client
.focus
.screen
or capi
.mouse
.screen
60 capi
.mouse
.screen
= c
.screen
63 -- Try to make client visible, this also covers e.g. sticky
65 if t
and not c
:isvisible() then
78 --- Get the first client that got the urgent hint.
79 -- @return The first urgent client.
80 function client
.urgent
.get()
81 if #client
.data
.urgent
> 0 then
82 return client
.data
.urgent
[1]
84 -- fallback behaviour: iterate through clients and get the first urgent
85 local clients
= capi
.client
.get()
86 for k
, cl
in pairs(clients
) do
94 --- Jump to the client that received the urgent hint first.
95 -- @param merge If true then merge tags when clients are not visible.
96 function client
.urgent
.jumpto(merge
)
97 local c
= client
.urgent
.get()
99 client
.jumpto(c
, merge
)
103 --- Adds client to urgent stack.
104 -- @param c The client object.
105 -- @param prop The property which is updated.
106 function client
.urgent
.add(c
, prop
)
107 if type(c
) == "client" and prop
== "urgent" and c
.urgent
then
108 table.insert(client
.data
.urgent
, c
)
112 --- Remove client from urgent stack.
113 -- @param c The client object.
114 function client
.urgent
.delete(c
)
115 for k
, cl
in ipairs(client
.data
.urgent
) do
117 table.remove(client
.data
.urgent
, k
)
123 --- Remove a client from the focus history
124 -- @param c The client that must be removed.
125 function client
.focus
.history
.delete(c
)
126 for k
, v
in ipairs(client
.data
.focus
) do
128 table.remove(client
.data
.focus
, k
)
134 --- Filter out window that we do not want handled by focus.
135 -- This usually means that desktop, dock and splash windows are
136 -- not registered and cannot get focus.
137 -- @param c A client.
138 -- @return The same client if it's ok, nil otherwise.
139 function client
.focus
.filter(c
)
140 if c
.type == "desktop"
142 or c
.type == "splash"
143 or not c
.focusable
then
149 --- Update client focus history.
150 -- @param c The client that has been focused.
151 function client
.focus
.history
.add(c
)
152 -- Remove the client if its in stack
153 client
.focus
.history
.delete(c
)
154 -- Record the client has latest focused
155 table.insert(client
.data
.focus
, 1, c
)
158 --- Get the latest focused client for a screen in history.
159 -- @param screen The screen number to look for.
160 -- @param idx The index: 0 will return first candidate,
161 -- 1 will return second, etc.
163 function client
.focus
.history
.get(screen
, idx
)
164 -- When this counter is equal to idx, we return the client
166 local vc
= client
.visible(screen
)
167 for k
, c
in ipairs(client
.data
.focus
) do
168 if c
.screen
== screen
then
169 for j
, vcc
in ipairs(vc
) do
171 if counter
== idx
then
174 -- We found one, increment the counter only.
175 counter
= counter
+ 1
181 -- Argh nobody found in history, give the first one visible if there is one
182 -- that passes the filter.
184 for k
, v
in ipairs(vc
) do
185 if client
.focus
.filter(v
) then
192 --- Focus the previous client in history.
193 function client
.focus
.history
.previous()
194 local sel
= capi
.client
.focus
199 s
= capi
.mouse
.screen
201 local c
= client
.focus
.history
.get(s
, 1)
202 if c
then capi
.client
.focus
= c
end
205 --- Get visible clients from a screen.
206 -- @param screen The screen number, or nil for all screens.
207 -- @return A table with all visible clients.
208 function client
.visible(screen
)
209 local cls
= capi
.client
.get(screen
)
211 for k
, c
in pairs(cls
) do
212 if c
:isvisible() then
213 table.insert(vcls
, c
)
219 --- Get visible and tiled clients
220 -- @param screen The screen number, or nil for all screens.
221 -- @return A table with all visible and tiled clients.
222 function client
.tiled(screen
)
223 local clients
= client
.visible(screen
)
225 -- Remove floating clients
226 for k
, c
in pairs(clients
) do
227 if not client
.floating
.get(c
)
229 and not c
.maximized_vertical
230 and not c
.maximized_horizontal
then
231 table.insert(tclients
, c
)
237 --- Get a client by its relative index to the focused window.
238 -- @param i The index. Use 1 to get next, -1 to get previous.
239 -- @param c Optional client.
240 -- @return A client, or nil if no client is available.
241 function client
.next(i
, c
)
242 -- Get currently focused client
243 local sel
= c
or capi
.client
.focus
245 -- Get all visible clients
246 local cls
= client
.visible(sel
.screen
)
248 -- Remove all non-normal clients
249 for idx
, c
in ipairs(cls
) do
250 if client
.focus
.filter(c
) or c
== sel
then
251 table.insert(fcls
, c
)
255 -- Loop upon each client
256 for idx
, c
in ipairs(cls
) do
259 return cls
[util
.cycle(#cls
, idx
+ i
)]
265 --- Focus a client by the given direction.
266 -- @param dir The direction, can be either "up", "down", "left" or "right".
267 -- @param c Optional client.
268 function client
.focus
.bydirection(dir
, c
)
269 local sel
= c
or capi
.client
.focus
271 local cltbl
= client
.visible(sel
.screen
)
273 for i
,cl
in ipairs(cltbl
) do
274 geomtbl
[i
] = cl
:geometry()
277 local target
= util
.get_rectangle_in_direction(dir
, geomtbl
, sel
:geometry())
279 -- If we found a client to focus, then do it.
281 capi
.client
.focus
= cltbl
[target
]
286 --- Focus a client by the given direction. Moves across screens.
287 -- @param dir The direction, can be either "up", "down", "left" or "right".
288 -- @param c Optional client.
289 function client
.focus
.global_bydirection(dir
, c
)
290 screen
= screen
or require("awful.screen")
291 local sel
= c
or capi
.client
.focus
292 local scr
= capi
.mouse
.screen
297 -- change focus inside the screen
298 client
.focus
.bydirection(dir
, sel
)
300 -- if focus not changed, we must change screen
301 if sel
== capi
.client
.focus
then
302 screen
.focus_bydirection(dir
, scr
)
303 if scr
~= capi
.mouse
.screen
then
304 local cltbl
= client
.visible(capi
.mouse
.screen
)
306 for i
,cl
in ipairs(cltbl
) do
307 geomtbl
[i
] = cl
:geometry()
309 local target
= util
.get_rectangle_in_direction(dir
, geomtbl
, capi
.screen
[scr
].geometry
)
312 capi
.client
.focus
= cltbl
[target
]
318 --- Focus a client by its relative index.
319 -- @param i The index.
320 -- @param c Optional client.
321 function client
.focus
.byidx(i
, c
)
322 local target
= client
.next(i
, c
)
324 capi
.client
.focus
= target
328 --- Swap a client with another client in the given direction
329 -- @param dir The direction, can be either "up", "down", "left" or "right".
330 -- @param c Optional client.
331 function client
.swap
.bydirection(dir
, c
)
332 local sel
= c
or capi
.client
.focus
334 local cltbl
= client
.visible(sel
.screen
)
336 for i
,cl
in ipairs(cltbl
) do
337 geomtbl
[i
] = cl
:geometry()
339 local target
= util
.get_rectangle_in_direction(dir
, geomtbl
, sel
:geometry())
341 -- If we found a client to swap with, then go for it
343 cltbl
[target
]:swap(sel
)
348 --- Swap a client with another client in the given direction. Swaps across screens.
349 -- @param dir The direction, can be either "up", "down", "left" or "right".
350 -- @param c Optional client.
351 function client
.swap
.global_bydirection(dir
, c
)
352 screen
= screen
or require("awful.screen")
353 local sel
= c
or capi
.client
.focus
354 local scr
= capi
.mouse
.screen
361 client
.focus
.global_bydirection(dir
, sel
)
362 local c
= capi
.client
.focus
364 -- swapping inside a screen
365 if sel
.screen
== c
.screen
and sel
~= c
then
368 -- swapping to an empty screen
369 elseif sel
.screen
~= c
.screen
and sel
== c
then
370 client
.movetoscreen(sel
, capi
.mouse
.screen
)
372 --swapping to a nonempty screen
373 elseif sel
.screen
~= c
.screen
and sel
~= c
then
374 client
.movetoscreen(sel
, c
.screen
)
375 client
.movetoscreen(c
, scr
)
378 screen
.focus(sel
.screen
)
379 capi
.client
.focus
= sel
383 --- Swap a client by its relative index.
384 -- @param i The index.
385 -- @param c Optional client, otherwise focused one is used.
386 function client
.swap
.byidx(i
, c
)
387 local sel
= c
or capi
.client
.focus
388 local target
= client
.next(i
, sel
)
395 -- @param clockwise True to cycle clients clockwise.
396 -- @param screen Optional screen where to cycle clients.
397 function client
.cycle(clockwise
, screen
)
398 local screen
= screen
or capi
.mouse
.screen
399 local cls
= client
.visible(screen
)
400 -- We can't rotate without at least 2 clients, buddy.
402 local c
= table.remove(cls
, 1)
404 for i
= #cls
, 1, -1 do
408 for _
, rc
in pairs(cls
) do
415 --- Get the master window.
416 -- @param screen Optional screen number, otherwise screen mouse is used.
417 -- @return The master window.
418 function client
.getmaster(screen
)
419 local s
= screen
or capi
.mouse
.screen
420 return client
.visible(s
)[1]
423 --- Set the client as master: put it at the beginning of other windows.
424 -- @param c The window to set as master.
425 function client
.setmaster(c
)
426 local cls
= util
.table.reverse(capi
.client
.get(c
.screen
))
427 for k
, v
in pairs(cls
) do
432 --- Set the client as slave: put it at the end of other windows.
433 -- @param c The window to set as slave.
434 function client
.setslave(c
)
435 local cls
= capi
.client
.get(c
.screen
)
436 for k
, v
in pairs(cls
) do
441 --- Move/resize a client relative to current coordinates.
442 -- @param x The relative x coordinate.
443 -- @param y The relative y coordinate.
444 -- @param w The relative width.
445 -- @param h The relative height.
446 -- @param c The optional client, otherwise focused one is used.
447 function client
.moveresize(x
, y
, w
, h
, c
)
448 local sel
= c
or capi
.client
.focus
449 local geometry
= sel
:geometry()
450 geometry
['x'] = geometry
['x'] + x
451 geometry
['y'] = geometry
['y'] + y
452 geometry
['width'] = geometry
['width'] + w
453 geometry
['height'] = geometry
['height'] + h
454 sel
:geometry(geometry
)
457 --- Move a client to a tag.
458 -- @param target The tag to move the client to.
459 -- @param c Optional client to move, otherwise the focused one is used.
460 function client
.movetotag(target
, c
)
461 local sel
= c
or capi
.client
.focus
462 local s
= tag.getscreen(target
)
464 -- Set client on the same screen as the tag.
470 --- Toggle a tag on a client.
471 -- @param target The tag to toggle.
472 -- @param c Optional client to toggle, otherwise the focused one is used.
473 function client
.toggletag(target
, c
)
474 local sel
= c
or capi
.client
.focus
475 -- Check that tag and client screen are identical
476 if sel
and sel
.screen
== tag.getscreen(target
) then
477 local tags
= sel
:tags()
479 for i
, v
in ipairs(tags
) do
486 -- If it's the only tag for the window, stop.
487 if #tags
== 1 then return end
490 tags
[#tags
+ 1] = target
496 --- Move a client to a screen. Default is next screen, cycling.
497 -- @param c The client to move.
498 -- @param s The screen number, default to current + 1.
499 function client
.movetoscreen(c
, s
)
500 screen
= screen
or require("awful.screen")
501 local sel
= c
or capi
.client
.focus
503 local sc
= capi
.screen
.count()
507 if s
> sc
then s
= 1 elseif s
< 1 then s
= sc
end
513 --- Mark a client, and then call 'marked' hook.
514 -- @param c The client to mark, the focused one if not specified.
515 -- @return True if the client has been marked. False if the client was already marked.
516 function client
.mark(c
)
517 local cl
= c
or capi
.client
.focus
519 for k
, v
in pairs(client
.data
.marked
) do
525 table.insert(client
.data
.marked
, cl
)
528 cl
:emit_signal("marked")
533 --- Unmark a client and then call 'unmarked' hook.
534 -- @param c The client to unmark, or the focused one if not specified.
535 -- @return True if the client has been unmarked. False if the client was not marked.
536 function client
.unmark(c
)
537 local cl
= c
or capi
.client
.focus
539 for k
, v
in pairs(client
.data
.marked
) do
541 table.remove(client
.data
.marked
, k
)
542 cl
:emit_signal("unmarked")
550 --- Check if a client is marked.
551 -- @param c The client to check, or the focused one otherwise.
552 function client
.ismarked(c
)
553 local cl
= c
or capi
.client
.focus
555 for k
, v
in pairs(client
.data
.marked
) do
564 --- Toggle a client as marked.
565 -- @param c The client to toggle mark.
566 function client
.togglemarked(c
)
567 local cl
= c
or capi
.client
.focus
569 if not client
.mark(c
) then
574 --- Return the marked clients and empty the marked table.
575 -- @return A table with all marked clients.
576 function client
.getmarked()
577 for k
, v
in pairs(client
.data
.marked
) do
578 v
:emit_signal("unmarked")
581 t
= client
.data
.marked
582 client
.data
.marked
= {}
586 --- Set a client floating state, overriding auto-detection.
587 -- Floating client are not handled by tiling layouts.
588 -- @param c A client.
589 -- @param s True or false.
590 function client
.floating
.set(c
, s
)
591 local c
= c
or capi
.client
.focus
592 if c
and client
.property
.get(c
, "floating") ~= s
then
593 client
.property
.set(c
, "floating", s
)
596 c
:geometry(client
.property
.get(c
, "floating_geometry"))
602 local function store_floating_geometry(c
)
603 if client
.floating
.get(c
) then
604 client
.property
.set(c
, "floating_geometry", c
:geometry())
608 -- Store the initial client geometry.
609 capi
.client
.connect_signal("new", function(c
)
610 local function store_init_geometry(c
)
611 client
.property
.set(c
, "floating_geometry", c
:geometry())
612 c
:disconnect_signal("property::border_width", store_init_geometry
)
614 c
:connect_signal("property::border_width", store_init_geometry
)
617 capi
.client
.connect_signal("property::geometry", store_floating_geometry
)
619 --- Return if a client has a fixe size or not.
620 -- @param c The client.
621 function client
.isfixed(c
)
622 local c
= c
or capi
.client
.focus
623 if not c
then return end
624 local h
= c
.size_hints
625 if h
.min_width
and h
.max_width
626 and h
.max_height
and h
.min_height
627 and h
.min_width
> 0 and h
.max_width
> 0
628 and h
.max_height
> 0 and h
.min_height
> 0
629 and h
.min_width
== h
.max_width
630 and h
.min_height
== h
.max_height
then
636 --- Get a client floating state.
637 -- @param c A client.
638 -- @return True or false. Note that some windows might be floating even if you
639 -- did not set them manually. For example, windows with a type different than
641 function client
.floating
.get(c
)
642 local c
= c
or capi
.client
.focus
644 local value
= client
.property
.get(c
, "floating")
648 if c
.type ~= "normal"
650 or c
.maximized_vertical
651 or c
.maximized_horizontal
652 or client
.isfixed(c
) then
659 --- Toggle the floating state of a client between 'auto' and 'true'.
660 -- @param c A client.
661 function client
.floating
.toggle(c
)
662 local c
= c
or capi
.client
.focus
663 -- If it has been set to floating
664 if client
.floating
.get(c
) then
665 client
.floating
.set(c
, false)
667 client
.floating
.set(c
, true)
671 --- Remove the floating information on a client.
672 -- @param c The client.
673 function client
.floating
.delete(c
)
674 client
.floating
.set(c
, nil)
677 --- Restore (=unminimize) a random client.
678 -- @param s The screen to use.
679 -- @return The restored client if some client was restored, otherwise nil.
680 function client
.restore(s
)
681 local s
= s
or (capi
.client
.focus
and capi
.client
.focus
.screen
) or capi
.mouse
.screen
682 local cls
= capi
.client
.get(s
)
683 local tags
= tag.selectedlist(s
)
685 for k
, c
in pairs(cls
) do
686 local ctags
= c
:tags()
688 for k
, t
in ipairs(tags
) do
689 if util
.table.hasitem(ctags
, t
) then
699 -- Normalize a set of numbers to 1
700 -- @param set the set of numbers to normalize
701 -- @param num the number of numbers to normalize
702 local function normalize(set
, num
)
703 local num
= num
or #set
707 total
= total
+ set
[i
]
710 set
[i
] = set
[i
] / total
713 for i
,v
in ipairs(set
) do
717 for i
,v
in ipairs(set
) do
723 --- Calculate a client's column number, index in that column, and
724 -- number of visible clients in this column.
725 -- @param c the client
726 -- @return col the column number
727 -- @return idx index of the client in the column
728 -- @return num the number of visible clients in the column
729 function client
.idx(c
)
730 local c
= c
or capi
.client
.focus
731 if not c
then return end
733 local clients
= client
.tiled(c
.screen
)
735 for k
, cl
in ipairs(clients
) do
742 local t
= tag.selected(c
.screen
)
743 local nmaster
= tag.getnmaster(t
)
744 if idx
<= nmaster
then
745 return {idx
= idx
, col
=0, num
=nmaster
}
747 local nother
= #clients
- nmaster
750 -- rather than regenerate the column number we can calculate it
751 -- based on the how the tiling algorithm places clients we calculate
752 -- the column, we could easily use the for loop in the program but we can
754 local ncol
= tag.getncol(t
)
755 -- minimum number of clients per column
756 local percol
= math
.floor(nother
/ ncol
)
757 -- number of columns with an extra client
758 local overcol
= math
.fmod(nother
, ncol
)
759 -- number of columns filled with [percol] clients
760 local regcol
= ncol
- overcol
762 local col
= math
.floor( (idx
- 1) / percol
) + 1
764 -- col = math.floor( (idx - (percol*regcol) - 1) / (percol + 1) ) + regcol + 1
766 col
= math
.floor( (idx
+ regcol
+ percol
) / (percol
+1) )
767 -- calculate the index in the column
768 idx
= idx
- percol
*regcol
- (col
- regcol
- 1) * (percol
+1)
771 idx
= idx
- percol
*(col
-1)
774 return {idx
= idx
, col
=col
, num
=percol
}
778 --- Set the window factor of a client
779 -- @param wfact the window factor value
780 -- @param c the client
781 function client
.setwfact(wfact
, c
)
782 -- get the currently selected window
783 local c
= c
or capi
.client
.focus
784 if not c
or not c
:isvisible() then return end
786 local t
= tag.selected(c
.screen
)
787 local w
= client
.idx(c
)
789 local cls
= client
.tiled(tag.getscreen(t
))
790 local nmaster
= tag.getnmaster(t
)
792 -- n is the number of windows currently visible for which we have to be concerned with the properties
793 local data
= tag.getproperty(t
, "windowfact") or {}
794 local colfact
= data
[w
.col
]
796 colfact
[w
.idx
] = wfact
799 -- calculate the current denominator
803 total
= total
+ colfact
[i
]
807 -- normalize the windows
810 colfact
[i
] = (colfact
[i
] * rest
) / total
814 t
:emit_signal("property::windowfact")
817 --- Increment a client's window factor
818 -- @param add amount to increase the client's window
819 -- @param c the client
820 function client
.incwfact(add
, c
)
821 local c
= c
or capi
.client
.focus
822 if not c
then return end
824 local t
= tag.selected(c
.screen
)
826 local w
= client
.idx(c
)
828 local nmaster
= tag.getnmaster(t
)
829 local data
= tag.getproperty(t
, "windowfact") or {}
830 local colfact
= data
[w
.col
]
831 curr
= colfact
[w
.idx
] or 1
832 colfact
[w
.idx
] = curr
+ add
834 -- keep our ratios normalized
835 normalize(colfact
, w
.num
)
837 t
:emit_signal("property::windowfact")
840 --- Get a client dockable state.
841 -- @param c A client.
842 -- @return True or false. Note that some windows might be dockable even if you
843 -- did not set them manually. For example, windows with a type "utility", "toolbar"
845 function client
.dockable
.get(c
)
846 local value
= client
.property
.get(c
, "dockable")
848 -- Some sane defaults
850 if (c
.type == "utility" or c
.type == "toolbar" or c
.type == "dock") then
860 --- Set a client dockable state, overriding auto-detection.
861 -- With this enabled you can dock windows by moving them from the center
862 -- to the edge of the workarea.
863 -- @param c A client.
864 -- @param value True or false.
865 function client
.dockable
.set(c
, value
)
866 client
.property
.set(c
, "dockable", value
)
869 --- Get a client property.
870 -- @param c The client.
871 -- @param prop The property name.
872 -- @return The property.
873 function client
.property
.get(c
, prop
)
874 if not client
.data
.persistent_properties_loaded
[c
] then
875 client
.data
.persistent_properties_loaded
[c
] = true
876 for p
in pairs(client
.data
.persistent_properties_registered
) do
877 local value
= c
:get_xproperty("awful.client.property." .. prop
)
879 client
.property
.set(c
, p
, value
)
883 if client
.data
.properties
[c
] then
884 return client
.data
.properties
[c
][prop
]
888 --- Set a client property.
889 -- This properties are internal to awful. Some are used to move clients, etc.
890 -- @param c The client.
891 -- @param prop The property name.
892 -- @param value The value.
893 function client
.property
.set(c
, prop
, value
)
894 if not client
.data
.properties
[c
] then
895 client
.data
.properties
[c
] = {}
897 if client
.data
.persistent_properties_registered
[prop
] then
898 c
:set_xproperty("awful.client.property." .. prop
, value
)
900 client
.data
.properties
[c
][prop
] = value
901 c
:emit_signal("property::" .. prop
)
904 --- Set a client property to be persistent across restarts (via X properties).
905 -- @param prop The property name.
906 -- @param type The type (used for register_xproperty).
907 -- One of "string", "number" or "boolean".
908 function client
.property
.persist(prop
, type)
909 local xprop
= "awful.client.property." .. prop
910 capi
.awesome
.register_xproperty(xprop
, type)
911 client
.data
.persistent_properties_registered
[prop
] = true
913 -- Make already-set properties persistent
914 for c
, tab
in pairs(client
.data
.properties
) do
915 if client
.data
.properties
[c
] and client
.data
.properties
[c
][prop
] ~= nil then
916 c
:set_xproperty(xprop
, client
.data
.properties
[c
][prop
])
922 -- Returns an iterator to cycle through, starting from the client in focus or
923 -- the given index, all clients that match a given criteria.
925 -- @param filter a function that returns true to indicate a positive match
926 -- @param start what index to start iterating from. Defaults to using the
927 -- index of the currently focused client.
928 -- @param s which screen to use. nil means all screens.
931 -- -- e.g. to un-minimize all urxvt instances:
932 -- local urxvt = function (c)
933 -- return awful.rules.match(c, {class = "URxvt"})
936 -- for c in awful.client.iterate(urxvt) do
937 -- c.minimized = false
939 function client
.iterate(filter
, start
, s
)
940 local clients
= capi
.client
.get(s
)
941 local focused
= capi
.client
.focus
942 local start
= start
or util
.table.hasitem(clients
, focused
)
943 return util
.table.iterate(clients
, filter
, start
)
947 -- Switch to a client matching the given condition if running, else spawn it.
949 -- If multiple clients match the given condition then the next one is
952 -- @param cmd the command to execute
953 -- @param matcher a function that returns true to indicate a matching client
954 -- @param merge if true then merge tags when clients are not visible
957 -- -- run or raise urxvt (perhaps, with tabs) on modkey + semicolon
958 -- awful.key({ modkey, }, 'semicolon', function ()
959 -- local matcher = function (c)
960 -- return awful.rules.match(c, {class = 'URxvt'})
962 -- awful.client.run_or_raise('urxvt', matcher)
964 function client
.run_or_raise(cmd
, matcher
, merge
)
965 local clients
= capi
.client
.get()
966 local findex
= util
.table.hasitem(clients
, capi
.client
.focus
) or 1
967 local start
= util
.cycle(#clients
, findex
+ 1)
969 for c
in client
.iterate(matcher
, start
) do
970 client
.jumpto(c
, merge
)
974 -- client not found, spawn it
978 -- Register standards signals
979 capi
.client
.add_signal("property::floating_geometry")
980 capi
.client
.add_signal("property::floating")
981 capi
.client
.add_signal("property::dockable")
982 capi
.client
.add_signal("marked")
983 capi
.client
.add_signal("unmarked")
985 capi
.client
.connect_signal("focus", client
.focus
.history
.add
)
986 capi
.client
.connect_signal("unmanage", client
.focus
.history
.delete
)
988 capi
.client
.connect_signal("property::urgent", client
.urgent
.add
)
989 capi
.client
.connect_signal("focus", client
.urgent
.delete
)
990 capi
.client
.connect_signal("unmanage", client
.urgent
.delete
)
992 capi
.client
.connect_signal("unmanage", client
.floating
.delete
)
994 -- Register persistent properties
995 client
.property
.persist("floating", "boolean")
999 -- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80