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.

111 lines
4.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
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. -- Client context menu base
  9. local awmtk2 = require("awmtk2")
  10. local wibox = require("wibox")
  11. local awful = require("awful")
  12. local gears = require("gears")
  13. local builder = require("builder")
  14. local ask = require("asckey")
  15. local digger = require("digger")
  16. local style = awmtk2.create_style("client_menu",
  17. awmtk2.generic.composite_widget,{})
  18. local templates = awmtk2.create_template_lib("client_menu",awmtk2.templates,{})
  19. local t = awmtk2.build_templates(templates,style,false)
  20. -- Create a global context menu for clients first
  21. -- This saves us memory on not creating separate menus for every client
  22. if not context_menu then
  23. -- load client menu config
  24. local config_file = io.open(root_path.."/themes/"..global.theme..'/config/client_menu.json',"r")
  25. local config
  26. if config_file then
  27. config = config_file:read("*a")
  28. config_file:close()
  29. else
  30. config = [[{"list":[{"widget":"widgets.clientcontrols"}]}]]
  31. end
  32. context_menu = awful.popup(t.popup(builder(
  33. config,
  34. {
  35. style = style.base,
  36. }
  37. )))
  38. -- Close context menu on right click
  39. context_menu:connect_signal("button::press",function(_,_,_,b)
  40. if b == 3 then
  41. context_menu.visible = false
  42. end
  43. end)
  44. -- Generate a list of all existing menu_root objects
  45. local menus = digger(context_menu.widget,"menu_root")
  46. local context_menu_size = context_menu.width * context_menu.height
  47. context_menu.widget:connect_signal("widget::size_changed",function()
  48. -- Attach callbacks to close context_menu to new buttons
  49. local already_managed = {}
  50. for _,v in pairs(menus) do
  51. already_managed[v] = true
  52. end
  53. menus = digger(context_menu.widget,"menu_root")
  54. for _,v in pairs(menus) do
  55. if not already_managed[v] then
  56. v:connect_signal("cascade::kill",function()
  57. context_menu.visible = false
  58. end)
  59. end
  60. end
  61. end)
  62. -- Close all cascading menus if our menu becomes invisible
  63. context_menu:connect_signal("property::visible",function()
  64. local current_context_menu_size = context_menu.height * context_menu.width
  65. if current_context_menu_size ~= context_menu_size then
  66. context_menu:emit_signal("widget::size_changed")
  67. context_menu_size = current_context_menu_size
  68. end
  69. if not context_menu.visible then
  70. for _,v in pairs(menus) do
  71. v:emit_signal_recursive("cascade::kill")
  72. end
  73. end
  74. end)
  75. -- If client became unfocused, close menu
  76. client.connect_signal("focus",function()
  77. context_menu.visible = false
  78. end)
  79. -- If any of the menus emits cascade::kill, close the menu
  80. for _,v in pairs(menus) do
  81. v:connect_signal("cascade::kill",function()
  82. context_menu.visible = false
  83. end)
  84. end
  85. end
  86. root.keys(gears.table.join(
  87. root.keys(),
  88. ask.k(":client.menu",function()
  89. context_menu.visible = (not context_menu.visible)
  90. if context_menu.visible then
  91. context_menu.x = client.focus.x + 10
  92. context_menu.y = client.focus.y + 10
  93. end
  94. end,{description = "Open client menu", group = "client"})
  95. ))
  96. return function(args)
  97. local widget = wibox.widget({
  98. widget = awful.widget.clienticon,
  99. client = args.client
  100. })
  101. widget:connect_signal("button::press",function()
  102. context_menu.visible = (not context_menu.visible)
  103. if context_menu.visible then
  104. context_menu.x = mouse.coords().x
  105. context_menu.y = mouse.coords().y
  106. end
  107. end)
  108. return widget
  109. end