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.

241 lines
8.8 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
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. local gears = require("gears")
  9. local awmtk2 = require("awmtk2")
  10. local wibox = require("wibox")
  11. local awful = require("awful")
  12. local beautiful = require("beautiful")
  13. local builder = require("builder")
  14. local mbarutils = require("menubar").utils
  15. local menugen = require("context_menu")
  16. local json = require("dkjson")
  17. local function read_file(fname)
  18. local fhandler = io.open(fname,"r")
  19. if fhandler then
  20. local data = fhandler:read("*a")
  21. fhandler:close()
  22. return data
  23. end
  24. end
  25. -- {{{ Placeholder Icons
  26. client.connect_signal("request::titlebars",function(c)
  27. if (not c.icon) and beautiful.icon_default then
  28. c.icon = beautiful.icon_default._native
  29. end
  30. end)
  31. -- }}}
  32. do -- {{{ Global widgets
  33. local config_file = io.open(root_path.."/themes/"..global.theme.."/config/global.json","r")
  34. local config
  35. if config_file then
  36. config = config_file:read("*a")
  37. config_file:close()
  38. else
  39. config = "[]"
  40. end
  41. for k,v in pairs(json.decode(config) or {}) do
  42. require(k)(v)
  43. end
  44. end -- }}}
  45. do --{{{ Screen
  46. local wibar_config = {}
  47. local style = awmtk2.create_style("wibar",awmtk2.generic.composite_widget,{})
  48. for k,v in pairs({"wibar_top","wibar_bottom","wibar_left","wibar_right"}) do
  49. style[v] = awmtk2.create_delta(v, {},
  50. (beautiful.widgets and beautiful.widgets.wibar) or {},
  51. style.wibar)
  52. wibar_config[v] = read_file(root_path.."/themes/"..global.theme.."/config/"..v..".json")
  53. end
  54. local templates = awmtk2.create_template_lib("wibar",awmtk2.templates,{})
  55. local t = awmtk2.build_templates(templates,style)
  56. awful.screen.connect_for_each_screen(function(s)
  57. for k,v in pairs({"wibar_top","wibar_bottom","wibar_left","wibar_right"}) do
  58. local contents = { widget = wibox.container.background }
  59. if wibar_config[v] then
  60. contents = builder(wibar_config[v],{
  61. client = c,
  62. style = style[v],
  63. buttons = buttons,
  64. screen = s,
  65. passthrough = {
  66. vertical = ((v == "wibar_left") or
  67. (v == "wibar_right"))
  68. }
  69. })
  70. s[v] = awful.wibar({
  71. -- There really isn't a better way to do this. I wish there was.
  72. position = v:gsub("wibar_",""),
  73. screen = s,
  74. visible = true,
  75. stretch = style[v].stretch,
  76. ontop = style[v].ontop,
  77. width = style[v].width,
  78. height = style[v].height,
  79. border_width = style[v].border_width,
  80. border_color = style[v].border_color,
  81. opacity = style[v].opacity or 1,
  82. shape = style[v].shape,
  83. bg = style[v].bg_normal,
  84. bgimage = style[v].bgimage_normal,
  85. fg = style[v].fg,
  86. input_passthrough = style[v].input_passthrough
  87. })
  88. s[v]:setup(t.wibar(contents))
  89. end
  90. end
  91. end)
  92. end -- }}}
  93. do -- {{{ Titlebars
  94. local titlebar_config = {}
  95. local style = awmtk2.create_style("titlebar",awmtk2.generic.composite_widget,{})
  96. for k,v in pairs({"titlebar_top","titlebar_left","titlebar_right","titlebar_bottom"}) do
  97. -- Create styles for each titlebar
  98. style[v] = awmtk2.create_delta(v, {},
  99. (beautiful.widgets and beautiful.widgets.titlebar) or {},
  100. style.titlebar)
  101. -- Load in json layouts for titlebars
  102. titlebar_config[v] = read_file(root_path.."/themes/"..global.theme.."/config/"..v..".json")
  103. end
  104. local templates = awmtk2.create_template_lib("titlebar",awmtk2.templates,{})
  105. local t = awmtk2.build_templates(templates,style)
  106. -- Add titlebars to normal windows
  107. table.insert(awful.rules.rules,
  108. { rule_any = {type = { "normal", "dialog" }
  109. }, properties = { titlebars_enabled = true }
  110. }
  111. )
  112. local window_shape_hide = function(cr, width, height)
  113. return gears.shape.partially_rounded_rect(cr,width,height,
  114. false,false,false,false,0)
  115. end
  116. local window_shape = beautiful.window_shape or function(cr, width, height)
  117. return gears.shape.partially_rounded_rect(cr,width,height,
  118. true,true,false,false,beautiful.window_rounding)
  119. end
  120. client.connect_signal("manage", function(c)
  121. c.shape = window_shape
  122. end)
  123. local titlebars_on = true
  124. awesome.connect_signal("titlebar::toggle",function()
  125. titlebars_on = not titlebars_on
  126. for _,c in ipairs(client.get()) do
  127. if titlebars_on then
  128. for _, pos in ipairs({"top","bottom","left","right"}) do
  129. awful.titlebar.show(c,pos)
  130. end
  131. c.shape = window_shape
  132. c:emit_signal("titlebar::perform_action",function(titlebar)
  133. titlebar.widget.visible = true
  134. end)
  135. else
  136. for _, pos in ipairs({"top","bottom","left","right"}) do
  137. awful.titlebar.hide(c,pos)
  138. end
  139. c.shape = window_shape_hide
  140. c:emit_signal("titlebar::perform_action",function(titlebar)
  141. titlebar.widget.visible = false
  142. end)
  143. end
  144. end
  145. end)
  146. -- Second manage call to create hidden titlebars
  147. client.connect_signal("manage",function(c)
  148. -- Drag and resize buttons
  149. local buttons = gears.table.join(
  150. awful.button({}, 1, function()
  151. c:emit_signal("request::activate","titlebar",{raise=true})
  152. awful.mouse.client.move(c)
  153. end),
  154. awful.button({}, 3, function()
  155. c:emit_signal("request::activate","titlebar",{raise=true})
  156. awful.mouse.client.resize(c)
  157. end)
  158. )
  159. -- Building the titlebars
  160. for k,v in pairs({"titlebar_top","titlebar_bottom","titlebar_left","titlebar_right"}) do
  161. -- Build content of the titlebar
  162. local contents = { widget = wibox.widget.textbox, text = "" }
  163. if titlebar_config[v] then
  164. contents = builder(titlebar_config[v],{
  165. client = c,
  166. screen = c.screen,
  167. style = style[v],
  168. buttons = buttons
  169. })
  170. end
  171. -- Create the base
  172. local titlebar = awful.titlebar(c,{
  173. size = style[v].size or 0,
  174. position = v:gsub("titlebar_",""),
  175. bg_normal = style[v].bg_normal,
  176. bg_focus = style[v].bg_focus,
  177. bgimage_normal = style[v].bgimage_normal,
  178. bgimage_focus = style[v].bgimage_focus,
  179. fg_normal = style[v].fg_normal,
  180. fg_focus = style[v].fg_focus,
  181. font = style[v].font
  182. })
  183. -- Compile and build titlebar
  184. titlebar:setup(t.titlebar({
  185. contents,
  186. widget = wibox.container.background
  187. }))
  188. -- Since new clients will be placed without titlebars, we need to apply placement rules again
  189. awful.rules.rules[1].properties.placement(c)
  190. -- Callbacks for focus/unfocus of titlebars
  191. if style[v].onfocus then
  192. c:connect_signal("focus",function()
  193. style[v].onfocus(titlebar)
  194. end)
  195. end
  196. if style[v].onunfocus then
  197. c:connect_signal("unfocus",function()
  198. style[v].onunfocus(titlebar)
  199. end)
  200. end
  201. -- Activate focus callback if our client is focused
  202. if (c == client.focus) and (style[v].onfocus) then
  203. style[v].onfocus(titlebar)
  204. end
  205. -- Add a titlebar toggle signal
  206. c:connect_signal("titlebar::toggle",function(c)
  207. titlebar.widget.visible = not titlebar.widget.visible
  208. if titlebar.widget.visible then
  209. awful.titlebar.show(c,v:gsub("titlebar_",""))
  210. c.shape = window_shape
  211. else
  212. awful.titlebar.hide(c,v:gsub("titlebar_",""))
  213. c.shape = window_shape_hide
  214. end
  215. end)
  216. c:connect_signal("titlebar::perform_action",function(c,f)
  217. f(titlebar)
  218. end)
  219. -- Add rules for hiding titlebars on creation
  220. if (not titlebars_on) or
  221. (c.titlebars_enabled == false) or
  222. (c.requests_no_titlebar == true) then
  223. titlebar.widget.visible = false
  224. c.shape = window_shape_hide
  225. awful.titlebar.hide(c,v:gsub("titlebar_",""))
  226. end
  227. end
  228. end)
  229. end --}}}