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.

124 lines
5.3 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
  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. -- POLYMENU - brutal deluxe
  9. -- This isn't in the widgets folder because it's too meta to be there
  10. local awful = require("awful")
  11. local gears = require("gears")
  12. local menubar_utils = require("menubar.utils")
  13. local wibox = require("wibox")
  14. local awmtk2 = require("awmtk2")
  15. local function position_popup(popup,widget,style)
  16. -- Position the popup somewhere nearby our original widget
  17. popup:move_next_to(mouse.current_wibox)
  18. -- Figure out the geometry of the base widget
  19. local widget_geo
  20. for k,v in pairs(mouse.current_widgets or {}) do
  21. if widget == v then
  22. widget_geo = mouse.current_widget_geometries[k]
  23. end
  24. end
  25. -- Align y coordinate of the popup to the button
  26. if widget_geo then
  27. local wibox_geo = mouse.current_wibox:geometry()
  28. if popup.current_anchor == "front" then
  29. popup.y = widget_geo.y + wibox_geo.y - style.popup.margins
  30. else
  31. popup.y = widget_geo.y + wibox_geo.y + style.popup.margins + widget_geo.height - popup:geometry().height
  32. end
  33. end
  34. -- Finally, make widget visible
  35. popup.visible = true
  36. end
  37. return function(args)
  38. -- A way to communicate that all widgets in menu got closed
  39. args.on_close = args.on_close or function() end
  40. local style = awmtk2.create_style("menu", awmtk2.default, args.style)
  41. local templates = awmtk2.create_template_lib("menu", awmtk2.templates, args.templates)
  42. local t = awmtk2.build_templates(templates,style)
  43. local function menu_builder(element,layer,root_layer)
  44. local new_element = wibox.widget(t.button(t.article({
  45. icon = element[3],
  46. resize = true,
  47. title = element[1]
  48. }),{
  49. forced_width = style.button.forced_width,
  50. forced_height = style.button.forced_height
  51. }))
  52. local onpress = function(widget)
  53. style.button.onrelease(widget)
  54. if root_layer.focused then
  55. root_layer.focused:emit_signal("cascade::kill")
  56. end
  57. end
  58. if type(element[2]) == "string" then
  59. new_element:connect_signal("button::press",style.button.onpress)
  60. new_element:connect_signal("button::press",function(widget)
  61. awful.spawn(element[2])
  62. end)
  63. new_element:connect_signal("button::release",onpress)
  64. elseif type(element[2]) == "function" then
  65. new_element:connect_signal("button::press",style.button.onpress)
  66. new_element:connect_signal("button::press",element[2])
  67. new_element:connect_signal("button::release",onpress)
  68. elseif type(element[2]) == "table" then
  69. local layout = {
  70. spacing = style.base.spacing,
  71. layout = wibox.layout.fixed.vertical
  72. }
  73. for k,v in pairs(element[2]) do
  74. table.insert(layout,menu_builder(v,layout,root_layer))
  75. end
  76. local next_layer = awful.popup(t.popup(layout,{
  77. visible = false,
  78. ontop = true,
  79. preferred_positions = {"right","left"},
  80. preferred_anchors = {"front","back"},
  81. }))
  82. local function open_layer(widget)
  83. if layer.focused == widget and
  84. next_layer.visible then
  85. return
  86. end
  87. if layer.focused then
  88. layer.focused:emit_signal("cascade::close")
  89. end
  90. layer.focused = widget
  91. position_popup(next_layer, new_element, style)
  92. end
  93. local onclose = function()
  94. style.button.onrelease(new_element)
  95. if layout.focused then
  96. layout.focused:emit_signal("cascade::close")
  97. end
  98. next_layer.visible = false
  99. end
  100. new_element:connect_signal("cascade::close",onclose)
  101. new_element:connect_signal("cascade::kill",onclose)
  102. -- that sweet "just move the mouse 4head" navigation
  103. if style.base.menu_slide then
  104. new_element:connect_signal("mouse::enter",open_layer)
  105. new_element:connect_signal("mouse::enter",style.button.onpress)
  106. else
  107. new_element:connect_signal("button::press",style.button.onpress)
  108. new_element:connect_signal("button::press",open_layer)
  109. end
  110. end
  111. return new_element
  112. end
  113. local root_layer = {
  114. layout = wibox.layout.fixed.vertical,
  115. id = "menu_root",
  116. spacing = style.base.spacing
  117. }
  118. for k,v in pairs(args.items) do
  119. table.insert(root_layer,menu_builder(v,root_layer,root_layer))
  120. end
  121. return root_layer
  122. end