Reno is the second iteration of the AWMTK-powered AwesomeWM config.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

152 lines
6.0 KiB

2 years ago
  1. -- This file is part of Reno desktop.
  2. --
  3. -- Reno desktop is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
  4. --
  5. -- Reno desktop is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  6. --
  7. -- You should have received a copy of the GNU General Public License along with Reno desktop. If not, see <https://www.gnu.org/licenses/>.
  8. -- JSON layout builder
  9. local json = require("dkjson")
  10. local gears = require("gears")
  11. local wibox = require("wibox")
  12. local awful = require("awful")
  13. local menu = require("context_menu")
  14. local builtins = {
  15. h_spacer = function(o)
  16. return {
  17. forced_width = o.size or 3,
  18. widget = wibox.container.background
  19. }
  20. end,
  21. v_spacer = function(o)
  22. return {
  23. forced_height = o.size or 3,
  24. widget = wibox.container.background
  25. }
  26. end
  27. -- Insert your other builtins here
  28. }
  29. -- Load a bunch of builtins from awful.titlebar
  30. for _,name in pairs({
  31. "titlewidget","iconwidget","floatingbutton",
  32. "maximizedbutton","minimizebutton","closebutton",
  33. "ontopbutton","stickybutton"
  34. }) do
  35. builtins[name] = function(o)
  36. o.widget = awful.titlebar.widget[name](o.client)
  37. return o
  38. end
  39. end
  40. return function(description,opts)
  41. local style = opts.style or {}
  42. local c = opts.client
  43. local s = opts.screen
  44. local buttons = opts.buttons
  45. -- Build a layout given a JSON description, a style and client
  46. -- (if applicable)
  47. local test,err = json.decode(description)
  48. if not test then
  49. error("Builder failure: "..err)
  50. end
  51. local function inner_builder(struct,options,vertical)
  52. if struct.widget then -- External widget descriptions
  53. local args = gears.table.join({
  54. layout = (struct.layout and inner_builder(struct.layout,options)),
  55. client = (struct.client and c),
  56. screen = (struct.screen and s),
  57. vertical = (function()
  58. if type(struct.vertical) ~= "nil" then
  59. return struct.vertical
  60. end
  61. return vertical
  62. end)()
  63. },struct.options or {},options.passthrough or {})
  64. return require(struct.widget)(args)
  65. elseif struct.list then -- List descriptions
  66. local list = {
  67. layout = wibox.layout.fixed[(
  68. (struct.vertical and "vertical") or
  69. "horizontal"
  70. )],
  71. spacing = style.spacing or struct.spacing
  72. }
  73. for _,v in pairs(struct.list) do
  74. if v.draggable then
  75. list.buttons = buttons
  76. else
  77. local new_obj = inner_builder(v,options,struct.vertical)
  78. if new_obj then
  79. table.insert(list,new_obj)
  80. end
  81. end
  82. end
  83. return list
  84. elseif struct.align then -- Align structure descriptions
  85. local orient = (
  86. (struct.vertical and "vertical") or
  87. "horizontal"
  88. )
  89. local list = {
  90. {
  91. layout = wibox.layout.fixed[orient],
  92. spacing = style.spacing or struct.spacing
  93. },{
  94. layout = wibox.layout.flex[orient],
  95. spacing = style.spacing or struct.spacing
  96. },{
  97. -- Simulating "spacing" parameter
  98. widget = builtins[(struct.vertical and "v_spacer") or
  99. "h_spacer"]({size = style.spacing}),
  100. layout = wibox.layout.fixed[orient],
  101. spacing = style.spacing or struct.spacing
  102. },
  103. layout = wibox.layout.align[orient],
  104. }
  105. for k,v in pairs({"left","center","right"}) do
  106. for _,obj in pairs(struct.align[v]) do
  107. if obj.draggable then
  108. list[k].buttons = buttons
  109. else
  110. local new_obj = inner_builder(obj,options,struct.vertical)
  111. if new_obj then
  112. table.insert(list[k],new_obj)
  113. end
  114. end
  115. end
  116. end
  117. -- Part of simulating "spacing" parameter
  118. table.insert(list[1],builtins[(struct.vertical and "v_spacer") or
  119. "h_spacer"]({size = style.spacing}))
  120. return list
  121. elseif struct.builtin then -- Builtin widget descriptions
  122. if not builtins[struct.builtin] then
  123. error("Builtin not defined: "..struct.builtin)
  124. end
  125. return builtins[struct.builtin](gears.table.join({
  126. client = (struct.client and c)
  127. },struct.options or {}))
  128. elseif struct.multimenu then -- Multimenus, or otherwise "Context menu mergers".
  129. -- These merge multiple menus into one using the menu_parent argument.
  130. local multimenu = menu({items={}})
  131. local newopts = {}
  132. for k,v in pairs(options) do
  133. newopts[k] = v
  134. end
  135. newopts.passthrough = options.passthrough or {}
  136. newopts.passthrough.menu_parent = multimenu
  137. for _,v in pairs(struct.multimenu) do
  138. inner_builder(v,newopts,struct.vertical)
  139. end
  140. return multimenu
  141. end
  142. -- If this gets interpreted it's safe to say none of the constructions
  143. -- above got matched.
  144. print("Object dump: ")
  145. gears.debug.dump(struct)
  146. error("Builder error: invalid object description")
  147. end
  148. return inner_builder(test,opts),test.context_options
  149. end