init.lua 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. --[[
  2. Lain
  3. Layouts, widgets and utilities for Awesome WM
  4. Utilities section
  5. Licensed under GNU General Public License v2
  6. * (c) 2013, Luca CPZ
  7. * (c) 2010-2012, Peter Hofmann
  8. --]]
  9. local awful = require("awful")
  10. local sqrt = math.sqrt
  11. local pairs = pairs
  12. local client = client
  13. local tonumber = tonumber
  14. local wrequire = require("lain.helpers").wrequire
  15. local setmetatable = setmetatable
  16. -- Lain utilities submodule
  17. -- lain.util
  18. local util = { _NAME = "lain.util" }
  19. -- Like awful.menu.clients, but only show clients of currently selected tags
  20. function util.menu_clients_current_tags(menu, args)
  21. -- List of currently selected tags.
  22. local cls_tags = awful.screen.focused().selected_tags
  23. if cls_tags == nil then return nil end
  24. -- Final list of menu items.
  25. local cls_t = {}
  26. -- For each selected tag get all clients of that tag and add them to
  27. -- the menu. A click on a menu item will raise that client.
  28. for i = 1,#cls_tags do
  29. local t = cls_tags[i]
  30. local cls = t:clients()
  31. for _, c in pairs(cls) do
  32. cls_t[#cls_t + 1] = { awful.util.escape(c.name) or "",
  33. function ()
  34. c.minimized = false
  35. client.focus = c
  36. c:raise()
  37. end,
  38. c.icon }
  39. end
  40. end
  41. -- No clients? Then quit.
  42. if #cls_t <= 0 then return nil end
  43. -- menu may contain some predefined values, otherwise start with a
  44. -- fresh menu.
  45. if not menu then menu = {} end
  46. -- Set the list of items and show the menu.
  47. menu.items = cls_t
  48. local m = awful.menu(menu)
  49. m:show(args)
  50. return m
  51. end
  52. -- Magnify a client: set it to "float" and resize it.
  53. function util.magnify_client(c, width_f, height_f)
  54. if c and not c.floating then
  55. util.magnified_client = c
  56. util.mc(c, width_f, height_f)
  57. else
  58. util.magnified_client = nil
  59. c.floating = false
  60. end
  61. end
  62. -- https://github.com/lcpz/lain/issues/195
  63. function util.mc(c, width_f, height_f)
  64. c = c or util.magnified_client
  65. if not c then return end
  66. c.floating = true
  67. local s = awful.screen.focused()
  68. local mg = s.workarea
  69. local g = {}
  70. local mwfact = width_f or s.selected_tag.master_width_factor or 0.5
  71. g.width = sqrt(mwfact) * mg.width
  72. g.height = sqrt(height_f or mwfact) * mg.height
  73. g.x = mg.x + (mg.width - g.width) / 2
  74. g.y = mg.y + (mg.height - g.height) / 2
  75. if c then c:geometry(g) end -- if c is still a valid object
  76. end
  77. -- Non-empty tag browsing
  78. -- direction in {-1, 1} <-> {previous, next} non-empty tag
  79. function util.tag_view_nonempty(direction, sc)
  80. local s = sc or awful.screen.focused()
  81. for _ = 1, #s.tags do
  82. awful.tag.viewidx(direction, s)
  83. if #s.clients > 0 then
  84. return
  85. end
  86. end
  87. end
  88. -- {{{ Dynamic tagging
  89. -- Add a new tag
  90. function util.add_tag(layout)
  91. awful.prompt.run {
  92. prompt = "New tag name: ",
  93. textbox = awful.screen.focused().mypromptbox.widget,
  94. exe_callback = function(name)
  95. if not name or #name == 0 then return end
  96. awful.tag.add(name, { screen = awful.screen.focused(), layout = layout or awful.layout.suit.tile }):view_only()
  97. end
  98. }
  99. end
  100. -- Rename current tag
  101. function util.rename_tag()
  102. awful.prompt.run {
  103. prompt = "Rename tag: ",
  104. textbox = awful.screen.focused().mypromptbox.widget,
  105. exe_callback = function(new_name)
  106. if not new_name or #new_name == 0 then return end
  107. local t = awful.screen.focused().selected_tag
  108. if t then
  109. t.name = new_name
  110. end
  111. end
  112. }
  113. end
  114. -- Move current tag
  115. -- pos in {-1, 1} <-> {previous, next} tag position
  116. function util.move_tag(pos)
  117. local tag = awful.screen.focused().selected_tag
  118. if tonumber(pos) <= -1 then
  119. awful.tag.move(tag.index - 1, tag)
  120. else
  121. awful.tag.move(tag.index + 1, tag)
  122. end
  123. end
  124. -- Delete current tag
  125. -- Any rule set on the tag shall be broken
  126. function util.delete_tag()
  127. local t = awful.screen.focused().selected_tag
  128. if not t then return end
  129. t:delete()
  130. end
  131. -- }}}
  132. -- On the fly useless gaps change
  133. function util.useless_gaps_resize(thatmuch, s, t)
  134. local scr = s or awful.screen.focused()
  135. local tag = t or scr.selected_tag
  136. tag.gap = tag.gap + tonumber(thatmuch)
  137. awful.layout.arrange(scr)
  138. end
  139. return setmetatable(util, { __index = wrequire })