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.

125 lines
5.4 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
  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) and mouse.current_widget_geometries 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. widget:emit_signal("cascade::kill")
  55. if root_layer.focused then
  56. root_layer.focused:emit_signal("cascade::kill")
  57. end
  58. end
  59. if type(element[2]) == "string" then
  60. new_element:connect_signal("button::press",style.button.onpress)
  61. new_element:connect_signal("button::press",function(widget)
  62. awful.spawn(element[2])
  63. end)
  64. new_element:connect_signal("button::release",onpress)
  65. elseif type(element[2]) == "function" then
  66. new_element:connect_signal("button::press",style.button.onpress)
  67. new_element:connect_signal("button::press",element[2])
  68. new_element:connect_signal("button::release",onpress)
  69. elseif type(element[2]) == "table" then
  70. local layout = {
  71. spacing = style.base.spacing,
  72. layout = wibox.layout.fixed.vertical
  73. }
  74. for k,v in pairs(element[2]) do
  75. table.insert(layout,menu_builder(v,layout,root_layer))
  76. end
  77. local next_layer = awful.popup(t.popup(layout,{
  78. visible = false,
  79. ontop = true,
  80. preferred_positions = {"right","left"},
  81. preferred_anchors = {"front","back"},
  82. }))
  83. local function open_layer(widget)
  84. if layer.focused == widget and
  85. next_layer.visible then
  86. return
  87. end
  88. if layer.focused then
  89. layer.focused:emit_signal("cascade::close")
  90. end
  91. layer.focused = widget
  92. position_popup(next_layer, new_element, style)
  93. end
  94. local onclose = function()
  95. style.button.onrelease(new_element)
  96. if layout.focused then
  97. layout.focused:emit_signal("cascade::close")
  98. end
  99. next_layer.visible = false
  100. end
  101. new_element:connect_signal("cascade::close",onclose)
  102. new_element:connect_signal("cascade::kill",onclose)
  103. -- that sweet "just move the mouse 4head" navigation
  104. if style.base.menu_slide then
  105. new_element:connect_signal("mouse::enter",open_layer)
  106. new_element:connect_signal("mouse::enter",style.button.onpress)
  107. else
  108. new_element:connect_signal("button::press",style.button.onpress)
  109. new_element:connect_signal("button::press",open_layer)
  110. end
  111. end
  112. return new_element
  113. end
  114. local root_layer = {
  115. layout = wibox.layout.fixed.vertical,
  116. id = "menu_root",
  117. spacing = style.base.spacing
  118. }
  119. for k,v in pairs(args.items) do
  120. table.insert(root_layer,menu_builder(v,root_layer,root_layer))
  121. end
  122. return root_layer
  123. end