constantin-net

rc_v084_desktop

Dec 28th, 2024
10
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 102.02 KB | None | 0 0
  1. -- v084 desktop
  2. -- Standard awesome library
  3. local gears         = require("gears")
  4. local awful         = require("awful")
  5. local menu          = require("menu_mod")
  6. require("awful.autofocus")
  7. -- Widget and layout library
  8. local wibox         = require("wibox")
  9. -- Theme handling library
  10. local beautiful     = require("beautiful")
  11. -- Notification library
  12. local naughty       = require("naughty")
  13. local vicious       = require("vicious")
  14. local menubar       = require("menubar")
  15. local hotkeys_popup = require("awful.hotkeys_popup").widget
  16. -- Freedesktop menu
  17. local freedesktop   = require("freedesktop")
  18. -- Enable VIM help for hotkeys widget when client with matching name is opened:
  19. require("awful.hotkeys_popup.keys.vim")
  20. os.setlocale("ru_RU.UTF-8")
  21.  
  22. awful.menu = menu -- menu_mod
  23.  
  24. -- {{{ Error handling
  25. --
  26. if awesome.startup_errors then
  27.     naughty.notify({ preset = naughty.config.presets.critical, position = "bottom_left", timeout = 1,
  28.                                   title = "Oops, there were errors during startup!",
  29.                                   text = awesome.startup_errors })
  30. end
  31. -- Handle runtime errors after startup
  32. do
  33.     local in_error = false
  34.     awesome.connect_signal("debug::error", function (err)
  35.         -- Make sure we don't go into an endless error loop
  36.         if in_error then return end
  37.         in_error = true
  38.         naughty.notify({ preset = naughty.config.presets.critical, position = "bottom_left",
  39.                                       title = "Oops, an error happened!",
  40.                                       text = tostring(err) })
  41.         in_error = false
  42.     end)
  43. end
  44. --]]
  45. -- }}}
  46.  
  47. -- {{{ Variable definitions
  48. -- Themes define colours, icons, font and wallpapers.
  49. config_dir = awful.util.getdir("config")
  50. user       = string.match( awful.util.getdir("config"), '^/home/(%a+)')
  51. theme      = "gtk3"
  52.  
  53. beautiful.init( config_dir .. "themes/" .. theme .. "/theme.lua")
  54. local icons_size = beautiful.menu_height-2
  55. if beautiful.icon_theme == nil then beautiful.icon_theme = "Adwaita" end
  56. if beautiful.radius < 3 then beautiful.radius = 3 end
  57. if beautiful.radius > 9 then beautiful.radius = 9 end
  58.  
  59. awesome.set_preferred_icon_size(beautiful.menu_height)
  60.  
  61. -- This is used later as the default terminal and editor to run.
  62. browser         = "firefox"
  63. --browser         = "chromium"
  64. filemanager     = "spacefm"
  65. gui_editor      = "geany"
  66. terminal        = os.getenv("TERMINAL") or "lxterminal"
  67. xterminal       = "xterm"
  68. mocp_terminal   = "sakura"
  69. vkboard         = "onboard"
  70. smag            = "xzoom"
  71. --torrent_client  = "qbittorrent"
  72. torrent_client  = "transmission-gtk"
  73. smixer_gui      = "pavucontrol"
  74. geditor         = "gimp"
  75. calc            = "galculator"
  76. comixreader     = "mcomix"
  77. mindmaps        = "vym"
  78.  
  79. -- rofi
  80. rofi              = "/usr/local/sbin/rofi-1.6.1"
  81. rofi_cmd_drun     = rofi .. " -modi drun -show drun -config ~/.config/rofi/config-apps.rasi -theme ~/.config/rofi/theme-apps.rasi"
  82. rofi_cmd_run      = rofi .. " -modi run -show run -config ~/.config/rofi/config-apps.rasi -theme ~/.config/rofi/theme-apps.rasi"
  83. rofi_cmd_window   = rofi .. " -show window -modi window -config ~/.config/rofi/config-apps.rasi -theme ~/.config/rofi/theme-apps.rasi"
  84. rofi_file_browser = rofi .. " -modi drun,file-browser -show file-browser -config ~/.config/rofi/config-apps.rasi -theme ~/.config/rofi/theme-apps.rasi"
  85. rofi_cmd_combi    = rofi .. " -show combi -combi-modi 'window,drun' -modi combi -config ~/.config/rofi/config.rasi -theme ~/.config/rofi/theme.rasi"
  86.  
  87. -- scrot
  88. scrot_dir_command = "'mv $f /home/" .. user .. "/Изображения/PrintScreen/'"
  89. scr_full          = "scrot -m -z -e " .. scrot_dir_command
  90. scr_area          = "sleep 0.2; scrot -f -s -e " .. scrot_dir_command
  91. scr_area_delay    = "sleep 0.2; scrot -d 5 -s -e " .. scrot_dir_command
  92. scr_active_window = "scrot -z -u -e " .. scrot_dir_command --]]
  93. --[[ Gnome-screenshot
  94. scr_full          = "gnome-screenshot"
  95. scr_area          = "sleep 0.2; gnome-screenshot -a"
  96. scr_area_delay    = "sleep 0.2; gnome-screenshot -d 5"
  97. scr_active_window = "gnome-screenshot -w"--]]
  98.  
  99. -- ~/.config/pulse/default.pa
  100. -- set-card-profile <card_name> output:<output_profile>+input:<input_profile>
  101.  
  102. function dir_exists(dir)
  103.     return os.rename(dir,dir)
  104. end
  105.  
  106. local icons_path = "/usr/share/icons/" .. beautiful.icon_theme .. "/"
  107. if dir_exists(icons_path) == nil then icons_path = "/home/" .. user .. "/.icons/".. beautiful.icon_theme .. "/" end
  108. local theme_icons_size = "24x24"
  109.  
  110. -- Icons
  111. beautiful.media_play     = icons_path .. theme_icons_size .. "/actions/media-playback-start.png"
  112. beautiful.home           = icons_path .. theme_icons_size .. "/actions/go-home.png"
  113. beautiful.media_next     = icons_path .. theme_icons_size .. "/actions/media-skip-forward.png"
  114. beautiful.media_prev     = icons_path .. theme_icons_size .. "/actions/media-skip-backward.png"
  115. beautiful.media_pause    = icons_path .. theme_icons_size .. "/actions/media-playback-pause.png"
  116. beautiful.media_playlist = icons_path .. theme_icons_size .. "/actions/format-justify-fill.png"
  117. beautiful.media_shuffle  = icons_path .. theme_icons_size .. "/status/media-playlist-shuffle.png"
  118. beautiful.media_repeat   = icons_path .. theme_icons_size .. "/status/media-playlist-repeat.png"
  119. beautiful.close_key      = icons_path .. theme_icons_size .. "/actions/window-close.png"
  120.  
  121. -- Tags
  122. web_tag  = "web"   -- 1
  123. misc_tag  = "misc"  -- 2
  124. media_tag = "media" -- 3
  125. files_tag = "files" -- 4
  126.  
  127. modkey         = "Mod4"
  128. -- Table of layouts to cover with awful.layout.inc, order matters.
  129. awful.layout.layouts = {
  130.     awful.layout.suit.max,
  131.     --awful.layout.suit.tile,
  132.     --awful.layout.suit.floating,
  133.     --awful.layout.suit.fair,
  134.     --awful.layout.suit.spiral,
  135.     --awful.layout.suit.spiral.dwindle,
  136.     --awful.layout.suit.tile.left,
  137.     awful.layout.suit.tile.bottom,
  138.     --awful.layout.suit.tile.top,
  139.     --awful.layout.suit.fair.horizontal,
  140.     --awful.layout.suit.max.fullscreen,
  141.     --awful.layout.suit.magnifier,
  142.     --awful.layout.suit.corner.nw,
  143.     --awful.layout.suit.corner.ne,
  144.     --awful.layout.suit.corner.sw,
  145.     --awful.layout.suit.corner.se,
  146. }
  147. -- }}}
  148.  
  149. -- {{{ Helper functions
  150.  
  151. function run_once(prg)
  152.     if not prg then
  153.         do return nil end
  154.     end
  155.     awful.spawn.with_shell("ps ux | grep -v grep | grep -q '" .. prg .. "' || (" .. prg .. ")")
  156. end
  157.  
  158. function spawn_client_once(command,target_tag)
  159.     run_once(command)
  160.     local screen = awful.screen.focused() local tag = screen.tags[target_tag] if tag then tag:view_only() end
  161. end
  162.  
  163. function client_menu_toggle_fn()
  164.     local instance = nil
  165.     return function ()
  166.         if instance and instance.wibox.visible then
  167.             instance:hide()
  168.             instance = nil
  169.         else
  170.             instance = awful.menu.clients({ theme = { width = beautiful.menu_width*2 } })
  171.         end
  172.     end
  173. end
  174.  
  175. screen_index_mark = function(n)
  176.     if n.index == 1 then return "" else return n.index end
  177. end
  178.  
  179. -- Icons
  180. --moblin icon theme
  181. beautiful.empty_icon = config_dir .. "icons2/do.png"
  182.  
  183. -- Net menu v2.1
  184. -- fsudo
  185. wifi_menu_exec = function ( iface, ap )
  186.     if string.find(ap,'""') then awful.spawn.with_shell(xterminal .. " -geometry 30x10 -e 'wpa_connect2 ".. iface .. " hidden'")
  187.     else awful.spawn.with_shell(xterminal .. " -geometry 30x10 -e 'wpa_connect2 " .. iface .. " " .. ap .. "'")
  188.     end
  189. end
  190. local aps_terms = {}
  191. function wifi_menu ( iface )
  192.     awful.spawn.with_shell("fsudo -c | sudo -S ifconfig " .. iface .. " up")
  193.     awful.spawn.easy_async({"bash", "-c", "fsudo -c | sudo -S iwlist ".. iface .. " scan 2>/dev/null | awk -F':' '/ESSID/{print $2}' | nl -w2 -n rz -s '=' "},
  194.         function (aps)
  195.             table.insert(aps_terms, {"wi-fi:", _ })
  196.             for l in string.gmatch(aps, "[^\n]*") do
  197.                 if l ~= "" then
  198.                     local item = { l, function() wifi_menu_exec(iface,l) end }
  199.                     table.insert(aps_terms, item)
  200.                 end
  201.             end
  202.             table.insert(aps_terms, {"APs: " .. #aps_terms-1, _ })
  203.             table.insert(aps_terms, {"refresh", function() mywifimenu:hide() wifi_menu ( iface ) end })
  204.             mywifimenu = awful.menu( {items = aps_terms} )
  205.             mywifimenu:update()
  206.             mywifimenu:show()
  207.         end
  208.     )
  209.     aps_terms = {}
  210. end
  211. --[[ text net_menu widget
  212. net_menu_widget        = wibox.widget.textbox( ) -- ⇵⇄ text widget
  213. net_menu_widget.valign = 'center'
  214. net_menu_widget.align  = 'center'
  215. net_menu_widget:set_text("⇋") --]]
  216. -- icon net_menu widget
  217. net_menu_widget = wibox.widget {
  218.     forced_height = beautiful.base_size,
  219.     forced_width  = beautiful.base_size,
  220.     widget        = wibox.widget.imagebox
  221. }
  222. net_menu_widget:set_resize(true)
  223. net_menu_widget:set_image(beautiful.net_en_off)
  224.  
  225. net_icon_widget = wibox.widget {
  226.     {
  227.         net_menu_widget,
  228.         margins = 2,
  229.         widget  = wibox.container.margin,
  230.     },
  231.     bg     = beautiful.bg_normal,
  232.     widget = wibox.container.background,
  233. }
  234.  
  235. net_menu_widget_timer = gears.timer { timeout = 5, autostart = true, call_now = true }
  236. local icon_chooser = beautiful.net_en_off
  237. net_menu_widget_timer:connect_signal("timeout", function()
  238.     awful.spawn.easy_async({"bash", "-c", "ip -4 -br a"},
  239.         function(out)
  240.             for l in string.gmatch( out, "(.-)\n" ) do
  241.                 local net_name = string.match(l, "^(%S+).*")
  242.                 local net_id = string.sub(net_name, 1, 2)
  243.                 if net_id ~= "lo" then
  244.                     if net_id == "wl" then
  245.                         awful.spawn.easy_async({"bash", "-c", "iwconfig " .. net_name},
  246.                             function(wireless)
  247.                                 local unassociated = string.find(wireless, "Access Point: Not-Associated", 1, true)
  248.                                 if not unassociated then
  249.                                     local percent = tonumber(string.match(wireless, "Link Quality=(%d?%d?%d)"))
  250.                                     if percent == 0 or nil then icon_chooser = beautiful.net_wl_off
  251.                                     elseif percent > 0 and percent < 28 then icon_chooser = beautiful.net_wl_low
  252.                                     elseif percent >= 28  and percent < 60 then icon_chooser = beautiful.net_wl_ok
  253.                                     elseif percent >= 60 and percent < 95 then icon_chooser = beautiful.net_wl_good
  254.                                     elseif percent >=95 then icon_chooser = beautiful.net_wl_full
  255.                                     end
  256.                                 end
  257.                                 net_menu_widget:set_image(icon_chooser)
  258.                             end
  259.                         )
  260.                     else
  261.                         icon_chooser = beautiful.net_en_on
  262.                     end
  263.                 else
  264.                     icon_chooser = beautiful.net_en_off
  265.                 end
  266.             end
  267.         end)
  268.     net_menu_widget:set_image(icon_chooser)
  269.     end
  270. )--]]
  271.  
  272. local myifacemenu = awful.menu({ })
  273. function net_menu (  )
  274.     local count = #myifacemenu.items
  275.     myifacemenu = nil
  276.     myifacemenu = awful.menu({ })
  277.     local net_items_table = {}
  278.     local iface_list = {}
  279.     awful.spawn.easy_async({"bash", "-c", "ls /sys/class/net"},
  280.         function (out)
  281.             for iface in string.gmatch(out, "[^\n]*") do
  282.                 if iface ~= nil and string.len(iface) > 0 and iface ~= "lo" then
  283.                     table.insert(iface_list,iface)
  284.                 end
  285.             end
  286.             for _,iface in pairs(iface_list) do
  287.                 awful.spawn.easy_async({"bash", "-c", "ip -4 l show " .. iface .. " && ip -4 a show " .. iface .. " && iwconfig " .. iface },
  288.                     function(out)
  289.                         local cmd      = xterminal .. " -geometry 30x10 -e "
  290.                         local onoff, info, onoff_cmd, setup_title, setup_title2, setup_cmd, setup_cmd2, ap_name = "", "", "", "", "", "", "", ""
  291.                         local icon     = beautiful.net_en_on
  292.                         local state    = out
  293.                         local up_state = string.find(state, "inet ", 1, true)
  294.                         if up_state then
  295.                             onoff     = "disconnect"
  296.                             onoff_cmd = cmd .. "\"fsudo -c | sudo -S -p ' ' netmenu_off " .. iface .. "\""
  297.                             local ip_local = string.match(state, "inet (%d*.%d*.%d*.%d*/%d*)")
  298.                             if ip_local == nil then info = "   " else info = ip_local end
  299.                         else
  300.                             onoff = "connect"
  301.                             if string.sub(iface, 3, 3) == "x" then onoff_cmd = cmd .. "\"fsudo -c | sudo -S -p ' ' dhclient " .. iface .."\""
  302.                             else onoff_cmd = cmd .. "\"fsudo -c | sudo -S -p ' ' ifup " .. iface .. "\""
  303.                             end
  304.                             info = "   "
  305.                             if string.find(state, "NO-CARRIER", 1, true) then info = "   " end
  306.                         end
  307.                         if string.sub(iface, 1, 2) == "wl" then
  308.                             ap_name = string.match(state, 'ESSID:%"([^%"]+)"')
  309.                             if ap_name == nil then ap_name = "n/a" end
  310.                             icon = beautiful.net_wl
  311.                             if not up_state then
  312.                                 onoff     = "last network"
  313.                                 onoff_cmd = cmd .. " wpa_connect2 " .. iface .. " last &"
  314.                             else
  315.                                 onoff     = "✖ " .. ap_name
  316.                             end
  317.                             setup_title  = "search Wi-Fi"
  318.                             setup_cmd    = function() wifi_menu( iface ) end
  319.                             setup_title2 = "connect to hidden..."
  320.                             setup_cmd2   = cmd .. " wpa_connect2 ".. iface .. " hidden &"
  321.                         else
  322.                             setup_title  = "Auto"
  323.                             setup_cmd    = function() awful.spawn (cmd .. "\"fsudo -c | sudo -S -p ' ' dhclient " .. iface .. "\"") end
  324.                             setup_title2 = "Edit config"
  325.                             setup_cmd2   = cmd .. "\"sudo netmenu_new_conf " .. iface .. "\""
  326.                         end
  327.                         res = {
  328.                                 { iface, _, icon },
  329.                                 { "   "..onoff, function() awful.spawn(onoff_cmd) end },
  330.                                 { "   setup", { { setup_title, setup_cmd },
  331.                                                 { "config",{ { "Static", function() awful.spawn(cmd .. "\"sudo netmenu_setup_iface " .. iface .. " s\"" ) end },
  332.                                                   { "Auto", function() awful.spawn(cmd .. "\"fsudo -c | sudo -S -p ' ' netmenu_setup_iface " .. iface .. " d\"") end },
  333.                                                   { "Manual", function() awful.spawn(cmd .. "\"fsudo -c | sudo -S -p ' ' netmenu_setup_iface " .. iface .. " m\"" ) end } } },
  334.                                                   { setup_title2, function() awful.spawn(setup_cmd2) end },
  335.                                               },
  336.                                 },
  337.                                 { "   "..info, function() naughty.notify({text = out}) end },
  338.                         }
  339.                         for i=1,#res do
  340.                             net_items_table[#net_items_table+1] = res[i]
  341.                         end
  342.                         if iface_list[#iface_list] == iface then
  343.                             table.insert(net_items_table, {"iface: " .. math.ceil(#net_items_table/4), _ })
  344.                             for _, v in pairs(net_items_table) do myifacemenu:add(v) end
  345.                             myifacemenu:update()
  346.                             myifacemenu:show()
  347.                         end
  348.                     end
  349.                 )
  350.             end
  351.         end
  352.     )
  353. end
  354.  
  355. function net_menu_toggle_fn()
  356.     instance = nil
  357.     return function ()
  358.         if instance and instance.wibox.visible then
  359.             instance:hide()
  360.             instance = nil
  361.         else
  362.             net_menu()
  363.             instance = myifacemenu
  364.         end
  365.     end
  366. end
  367.  
  368. net_icon_widget:buttons(gears.table.join(
  369.     awful.button({ }, 1, _, net_menu_toggle_fn() )
  370. ))
  371.  
  372. -- Display switch menu
  373. local mydisplaymenu = awful.menu( { } )
  374. local function get_screen_id(s)
  375.     local name = ""
  376.     for i, _ in pairs(s.outputs) do
  377.         name = tostring(i)
  378.     end
  379.     return name
  380. end
  381. local mydisplaymenu = awful.menu( { } )
  382. function display_menu ( )
  383.     local current_display = get_screen_id(awful.screen.focused())
  384.     mydisplaymenu = nil
  385.     mydisplaymenu = awful.menu( { } )
  386.     awful.spawn.easy_async({"bash", "-c", "xrandr"},
  387.         function(out)
  388.             local displays = {}
  389.             local s = {}
  390.             local d = {}
  391.             for l in string.gmatch(out, "[^\n]*") do
  392.                 if string.find(l, " connected") then -- display name
  393.                     table.insert(d, {string.match(l, "(%u+-?%d+)"),{}})
  394.                 else
  395.                     if not string.find(l, "disconnected") and not string.find(l, "Screen") and l ~="" then -- size and rate
  396.                         local r = {}
  397.                         local size = string.match(l, "(%d+x%d+)")
  398.                         for i in string.gmatch(l, "(%d+%p%d+)") do
  399.                             local disp = d[#d][1]
  400.                             local cmd = "xrandr --output " .. disp .. " --mode " .. size .. " --rate " .. i
  401.                             local exec = { }
  402.                             table.insert(exec, { "Set " .. disp, function() awful.spawn( cmd ) awesome.restart() end })
  403.                             table.insert( r, { i, exec } )
  404.                         end
  405.                         table.insert(s, {size, r} )
  406.                     end
  407.                 end
  408.             end
  409.             local t = {}
  410.             for _,disp in pairs(d) do
  411.                 local t1 = {}
  412.                 for _,size in pairs(s) do
  413.                     if string.find( string.gsub(size[2][1][2][1][1], "([-:])", " "), string.gsub(disp[1], "([-:])", " ")) then
  414.                         table.insert(t1,size)
  415.                     end
  416.                 end
  417.                 table.insert(t,{disp[1],t1})
  418.             end
  419.             for _,disp in pairs(d) do
  420.                 local item = disp[1]
  421.                 if item ~= "" and not string.find( string.gsub(item, "([-:])", " "), string.gsub(current_display, "([-:])", " ")) then
  422.                     table.insert(t, { current_display .. " <-> " .. item, {
  423.                                       { "duplicate", function() awful.spawn("xrandr --output " .. item .. " --same-as " .. current_display .. " --auto") awesome.restart() end },
  424.                                       { "switch",    function() awful.spawn("xrandr --output " .. item .. " --auto --output " .. current_display .." --off") awesome.restart() end },
  425.                                       { "extend",    {
  426.                                         {"left",  function() awful.spawn("xrandr --output " .. current_display .. " --auto --output " .. item .. " --auto --left-of "  .. current_display ) awesome.restart() end },
  427.                                         {"above", function() awful.spawn("xrandr --output " .. current_display .. " --auto --output " .. item .. " --auto --above " .. current_display ) awesome.restart() end },
  428.                                         {"right", function() awful.spawn("xrandr --output " .. current_display .. " --auto --output " .. item .. " --auto --right-of "  .. current_display ) awesome.restart() end },
  429.                                         {"below", function() awful.spawn("xrandr --output " .. current_display .. " --auto --output " .. item .. " --auto --below " .. current_display ) awesome.restart() end },
  430.                     }}}})
  431.                 end
  432.             end
  433.             table.insert(t, {"connected: " .. #d, function()
  434.                     for num,disp in pairs(d) do
  435.                         naughty.notify({
  436.                             text     = "\t" .. disp[1] .. "\t\t",
  437.                             title    = "\t\t" .. tostring(num),
  438.                             screen   = num, -- ???
  439.                             font     = beautiful.font_name .. " " .. beautiful.base_size + 40,
  440.                             position = "top_middle",
  441.                         })
  442.                     end
  443.                 end}
  444.             )
  445.             mydisplaymenu = awful.menu(t)
  446.             mydisplaymenu:update()
  447.             mydisplaymenu:show()
  448.         end
  449.     )
  450. end
  451. function display_menu_toggle_fn()
  452.     instance = nil
  453.     return function ()
  454.         if instance and instance.wibox.visible then
  455.             instance:hide()
  456.             instance = nil
  457.         else
  458.             display_menu()
  459.             instance = mydisplaymenu
  460.         end
  461.     end
  462. end
  463. --display_widget = wibox.widget { widget = wibox.widget.textbox }
  464. --display_widget:set_text(" ▢ ")
  465. --display_widget:buttons(gears.table.join(
  466. --    awful.button({ }, 1, nil, display_menu_toggle_fn() )
  467. --))
  468.  
  469. -- }}}
  470.  
  471. -- {{{ Menu
  472. -- Create a launcher widget and a main menu
  473. myawesomemenu = {
  474.     { "hotkeys",     function() return false, hotkeys_popup.show_help end },
  475.     { "manual",      terminal .. " -e man awesome" },
  476.     { "edit config", gui_editor .. " " .. awesome.conffile },
  477.     { "restart",     awesome.restart }
  478. }
  479. myaccessmenu = {
  480.     { "keyboard",    vkboard },
  481.     { "magnifier",   smag },
  482.     { "screenshot",  scr_full }
  483. }
  484. myappsmenu = {
  485.     { "mocp",          mocp_terminal .. " -e /usr/bin/mocp" },
  486.     { "geany",         gui_editor },
  487.     { "xterm",         xterminal },
  488.     { "calculator",    calc },
  489.     { "accessibility", myaccessmenu },
  490.     { "run command",   rofi_cmd_run },
  491.     { "all apps",      rofi_cmd_drun },
  492. }
  493. myexitmenu = {
  494.     { "display",   "xset dpms force off" },
  495.     { "log out",   function() awesome.quit() end },
  496.     { "suspend",   "systemctl suspend" },
  497.     { "hibernate", "systemctl hibernate" },
  498.     { "reboot",    "systemctl reboot -i" },
  499.     { "shutdown",  "systemctl poweroff" }
  500. }
  501. myexitmenu_now = awful.menu ( myexitmenu )
  502. mysetupmenu = {
  503.     { "✿ theme",   config_dir .. "/theme_switch.sh" },
  504.     { "⇋ network", net_menu_toggle_fn()},
  505.     { "▢ display", display_menu_toggle_fn()},
  506.     { "♫ sound",   smixer_gui },
  507.     { "⎙  printer", browser .. " http://localhost:631" },
  508.     { "awesomewm",  myawesomemenu, beautiful.awesome_icon }
  509. }
  510. mymainmenu = awful.menu ({
  511.     { "files",   function() spawn_client_once(filemanager,4) end },
  512.     { "browser", function() spawn_client_once(browser,1) end },
  513.     { "apps",    myappsmenu },
  514.     { "setup",   mysetupmenu },
  515.     { "exit",    "rofi-shutdown-menu.sh" },
  516. })
  517.  
  518. -- Launcher
  519. mylauncher = wibox.widget {
  520.     forced_height = beautiful.menu_height,
  521.     forced_width  = beautiful.menu_height,
  522.     clip_shape    = function(cr, width, height) gears.shape.partially_rounded_rect(cr, width, height, true, true, false, true, beautiful.radius-1 ) end,
  523.     widget        = wibox.widget.imagebox
  524. }
  525. mylauncher:set_resize(true)
  526. mylauncher:set_image(beautiful.awesome_icon)
  527. mylauncher:buttons(gears.table.join(
  528.     awful.button({ }, 1, nil, function () mymainmenu:toggle() end)
  529. ))
  530. mylauncher:connect_signal("mouse::enter", function() mylauncher:set_image(beautiful.awesome_icon_hover) end)
  531. mylauncher:connect_signal("mouse::leave", function() mylauncher:set_image(beautiful.awesome_icon) end)
  532.  
  533. -- Icon widgets
  534. myicons = {}
  535. myicons.__index = myicons
  536. function myicons:new(image)
  537.     local obj = wibox.widget {
  538.         forced_height = beautiful.menu_height*2,
  539.         forced_width  = beautiful.menu_height*2,
  540.         image         = image,
  541.         resize        = true,
  542.         widget        = wibox.widget.imagebox
  543.     }
  544.     setmetatable(obj, self)
  545.     return obj;
  546. end
  547.  
  548. appsicon = myicons:new(beautiful.apps_icon)
  549. appsicon:buttons(gears.table.join(
  550.     awful.button({ }, 1, nil, function() awful.spawn(rofi_cmd_drun)   end ),
  551.     awful.button({ }, 3, nil, function() awful.spawn(rofi_cmd_window) end )
  552. ))
  553.  
  554. emptyicon = myicons:new(beautiful.empty_icon)
  555.  
  556. -- ⌨
  557. mykeyboardlayout = awful.widget.keyboardlayout()
  558. mykeyboardlayout.widget.align  = 'center'
  559. mykeyboardlayout.widget.valign = 'center'
  560.  
  561. -- Menubar configuration
  562. menubar.utils.terminal = terminal -- Set the terminal for applications that require it
  563. -- }}}
  564.  
  565. -- {{{ Wibar
  566.  
  567. separator = wibox.widget.textbox('<span color="' .. beautiful.border_focus .. '">⋅</span>') -- ⋮∙
  568. separator:set_forced_width(beautiful.menu_height)
  569. separator:set_forced_height(beautiful.menu_height)
  570.  
  571. volumebar = wibox.widget {
  572.     widget           = wibox.widget.progressbar,
  573.     margins          = 5,
  574.     shape            = function(cr, width, height) gears.shape.rounded_rect(cr, width, height, beautiful.radius-3) end,
  575.     color            = beautiful.border_focus,
  576.     background_color = beautiful.border_normal,
  577.     max_value        = 100,
  578.     --ticks            = true,
  579.     --ticks_size       = 15,
  580.     --ticks_gap        = 5,
  581. }
  582. sound_widget = wibox.widget {
  583.     widget        = wibox.widget.textbox,
  584.     align         = 'center',
  585.     valign        = 'center',
  586.     forced_height = beautiful.menu_height,
  587.     forced_width  = beautiful.menu_height,
  588.     --font          = beautiful.font_name .. " " .. beautiful.base_size + 5,
  589.     wrap          = "char",
  590. }
  591. sound_widget:set_markup("<span color='" .. beautiful.border_focus .. "'>♫</span>\n")
  592.  
  593. function get_volume_level(vol_string, vol_format)
  594.     local volume_level = string.match(vol_string, vol_format)
  595.     if volume_level == nil then volume_level=0x0000 end
  596.     volume_level = tonumber(string.format("%04x", volume_level),"16")
  597.     return volume_level
  598. end
  599.  
  600. -- Volume widget (pa) v2.1
  601. volumecfg          = {}
  602. volumecfg          = wibox.widget.textbox( )
  603. volumecfg.align    = "center"
  604. volumecfg.valign   = "center"
  605. volumecfg.font     = beautiful.font_name .. " " .. beautiful.base_size
  606. volumecfg.pa_init  = false
  607. volumecfg.pa_sink  = ""
  608. volumecfg.get_sink = function ()
  609.     awful.spawn.easy_async({"bash", "-c","pacmd dump | grep -e set-default-sink"},
  610.         function(out)
  611.             local sink = string.match(out, "%s(.+)\n")
  612.             if sink == nil then volumecfg.pa_sink = "" else volumecfg.pa_sink = sink end
  613.         end
  614.     )
  615. end
  616. volumecfg.get_sink()
  617. volumecfg.mixercommand = function (pa_command)
  618.     awful.spawn.easy_async({"bash", "-c", pa_command .. ' && pacmd dump | grep -e "set-sink-volume ' .. volumecfg.pa_sink .. '" -e "set-sink-mute ' .. volumecfg.pa_sink .. '"'},
  619.         function(out)
  620.             volume_f = get_volume_level(out, "(0x%x%x%x%x?%x)")
  621.             local volume_p = math.ceil(volume_f/655)
  622.             local volume = tostring(volume_p)
  623.             local unmuted = string.find(out, " no", 1, true)
  624.             volumebar:set_value(volume_p)
  625.             if unmuted then volume = "♫" .. volume volumebar:set_color(beautiful.border_focus)
  626.             else volume = "♩" volumebar:set_color(beautiful.fg_minimize)
  627.             end
  628.             volumecfg:set_text(volume)
  629.         end)
  630. end
  631. volumecfg.update = function ()
  632.     volumecfg.get_sink()
  633.     volumecfg.mixercommand("pactl set-sink-volume " .. volumecfg.pa_sink .. " +0")
  634. end
  635. volumecfg.update()
  636. volumecfg.up = function ()
  637.     volumecfg.get_sink()
  638.     local add_volume = " +1310"
  639.     if (volume_f+1310)> 65500 then add_volume = " 65500" end
  640.     volumecfg.mixercommand("pactl set-sink-volume " .. volumecfg.pa_sink .. add_volume)
  641.     mouse.screen.popup_volume.visible = true mouse.screen.popup_volume_timer:again()
  642. end
  643. volumecfg.down = function ()
  644.     volumecfg.get_sink()
  645.     volumecfg.mixercommand("pactl set-sink-volume " .. volumecfg.pa_sink .. " -1310") mouse.screen.popup_volume.visible = true mouse.screen.popup_volume_timer:again()
  646. end
  647. volumecfg.toggle = function ()
  648.     volumecfg.get_sink()
  649.     volumecfg.mixercommand("pactl set-sink-mute " .. volumecfg.pa_sink .. " toggle") mouse.screen.popup_volume.visible = true mouse.screen.popup_volume_timer:again()
  650. end
  651. volumebar:buttons(gears.table.join(
  652.     awful.button({ }, 4, function () volumecfg.up() end),
  653.     awful.button({ }, 5, function () volumecfg.down() end)
  654. ))
  655. -- clickable volume bar
  656. volumebar:connect_signal("button::press", function(_,xpl,_,b,_,fwr)
  657.     local volume = math.ceil(65500 * xpl/fwr.height)
  658.     if b == 1 then volumecfg.get_sink() volumecfg.mixercommand("pactl set-sink-volume " .. volumecfg.pa_sink .. " " .. volume ) end
  659. end)
  660. volumebar:connect_signal("button::release", function(_,xpl,_,b,_,fwr)
  661.     local volume = math.ceil(65500 * xpl/fwr.height)
  662.     if b == 1 then volumecfg.get_sink() volumecfg.mixercommand("pactl set-sink-volume " .. volumecfg.pa_sink .. " " .. volume ) end
  663. end)
  664.  
  665. volumecfg:buttons(gears.table.join(
  666.     awful.button({ }, 4, function () volumecfg.up()          end),
  667.     awful.button({ }, 5, function () volumecfg.down()        end),
  668.     awful.button({ }, 3, nil, function () awful.spawn(smixer_gui) end),
  669.     awful.button({ }, 2, function () volumecfg.update()      end),
  670.     awful.button({ }, 1, function () volumecfg.toggle()      end)
  671. ))
  672.  
  673. -- Create a textclock widget and calendar
  674. mytextclock        = wibox.widget.textclock("%H:%M")
  675. mytextclock.valign = 'center'
  676. mytextclock.align  = 'center'
  677.  
  678. local calendar = wibox.widget {
  679.     date          = os.date('*t'),
  680.     font          = "Helvetica Neue " .. beautiful.base_size,
  681.     long_weekdays = true,
  682.     widget        = wibox.widget.calendar.month,
  683. }
  684.  
  685. mytextdate = wibox.widget {
  686.     widget       = wibox.widget.textclock("%d"),
  687.     font         = "Helvetica Neue " .. beautiful.base_size,
  688.     align        = 'center',
  689.     valign       = 'center',
  690.     forced_width = 250,
  691. }
  692.  
  693. mytexthours = wibox.widget {
  694.     widget = wibox.widget.textclock("%H"),
  695.     font   = "Helvetica Neue " .. beautiful.menu_height + 6,
  696.     align  = 'right',
  697.     valign = 'bottom',
  698. }
  699.  
  700. mytextminutes = wibox.widget {
  701.     widget = wibox.widget.textclock("%M"),
  702.     font   = "Helvetica Neue " .. beautiful.base_size + 6,
  703.     align  = 'left',
  704.     valign = 'top',
  705. }
  706.  
  707. popup_date_dt = awful.popup {
  708.     ontop     = false,
  709.     visible   = true,
  710.     bg        = string.sub(beautiful.bg_normal, 1, 7) .. "00",
  711.     fg        = beautiful.fg_normal,
  712.     placement = function (self) awful.placement.top_right(self, { margins = { top = 10, right = beautiful.menu_height + 40 } }) end,
  713.     widget    = {
  714.         {
  715.             { widget = mytexthours },
  716.             { widget = mytextminutes },
  717.             layout = wibox.layout.fixed.horizontal,
  718.         },
  719.         top    = 1,
  720.         bottom = 1,
  721.         widget = wibox.container.margin,
  722.     },
  723. }
  724.  
  725. popup_date = awful.popup {
  726.     ontop     = true,
  727.     visible   = false,
  728.     placement = function (self) awful.placement.top_right (self, { margins = { top = beautiful.menu_height + 40, right = 10 } }) end,
  729.     bg        = string.sub(beautiful.bg_normal, 1, 7),
  730.     fg        = beautiful.fg_normal,
  731.     shape     = function(cr, width, height) gears.shape.rounded_rect(cr, width, height, beautiful.radius-1) end,
  732.     widget    = {
  733.         {
  734.             --{
  735.             --    { widget = mytexthours },
  736.             --    { widget = mytextminutes },
  737.             --    layout = wibox.layout.flex.horizontal,
  738.             --},
  739.             {
  740.                 { widget = mytextdate },
  741.                 { widget = calendar },
  742.                 layout = wibox.layout.fixed.vertical,
  743.                 expand = 'none',
  744.             },
  745.             layout = wibox.layout.fixed.vertical,
  746.         },
  747.         margins = beautiful.menu_height,
  748.         widget  = wibox.container.margin,
  749.     }
  750. }
  751.  
  752. popup_date:buttons(gears.table.join(
  753.                 awful.button({}, 3, nil, function()
  754.                     local a = calendar:get_date()
  755.                     a.month = a.month + 1
  756.                     calendar:set_date(nil)
  757.                     calendar:set_date(a)
  758.                 end),
  759.                 awful.button({}, 2, nil, function()
  760.                     calendar:set_date(nil) -- the new date is not set without removing the old one
  761.                     calendar:set_date(os.date('*t'))
  762.                 end),
  763.                 awful.button({}, 1, nil, function()
  764.                     local a = calendar:get_date()
  765.                     a.month = a.month - 1
  766.                     calendar:set_date(nil)
  767.                     calendar:set_date(a)
  768.                 end)
  769.             ))
  770.  
  771. popup_date_dt:connect_signal("button::press",
  772.     function(_, _, _, button)
  773.         if button == 1 then
  774.             if popup_date.visible then
  775.             -- to faster render the calendar refresh it and just hide
  776.                 calendar:set_date(nil) -- the new date is not set without removing the old one
  777.                 calendar:set_date(os.date('*t'))
  778.                 --popup_date:set_widget(nil) -- just in case
  779.                 --popup_date:set_widget(calendar)
  780.                 popup_date.visible = not popup_date.visible
  781.             else
  782.                 popup_date.visible = true
  783.             end
  784.        
  785.         end
  786.     end
  787. )
  788.  
  789. -- MOC widget
  790. mocwidget = {}
  791. mocwidget.twd = {}
  792. mocwidget.twd.__index = twd
  793.  
  794. function mocwidget.twd:new()
  795.     local obj = wibox.widget {
  796.             wrap = "char",
  797.             widget        = wibox.widget.textbox,
  798.             forced_height = beautiful.menu_height,
  799.             forced_width  = beautiful.menu_width
  800.     }
  801.     setmetatable(obj, self)
  802.     return obj;
  803. end
  804.  
  805. mocwidget.w_title = mocwidget.twd:new()
  806. mocwidget.w_artist = mocwidget.twd:new()
  807. mocwidget.w_album = mocwidget.twd:new()
  808.  
  809. mocline = wibox.widget {
  810.     widget           = wibox.widget.progressbar,
  811.     forced_height    = beautiful.base_size - 3,
  812.     forced_width     = beautiful.menu_width,
  813.     background_color = beautiful.notification_bg,
  814.     shape            = gears.shape.rounded_bar,
  815.     color            = beautiful.border_focus,
  816.     max_value        = 1,
  817. }
  818.  
  819. mocwidget.t = gears.timer { timeout = 1, call_now = true }
  820. mocwidget.t:connect_signal("timeout", function() mocline_draw(nil,true) end)
  821. mocwidget.t:start() --init timer
  822. mocwidget.t.start_new( 1, function ()
  823.     mocwidget.t:stop()
  824.     return false
  825. end)
  826.  
  827. function mocline_draw(position, auto)
  828.     awful.spawn.easy_async({"bash", "-c", "mocp -i"}, function(moc_info)
  829.         local ls, ts, pos = 0, 0, 0
  830.         if moc_info == nil then moc_info = "State: STOP"
  831.         else
  832.             moc_state_lines = string.match(moc_info, "State: %a*")
  833.             if moc_state_lines == nil then moc_state_lines = "State: STOP" end
  834.         end
  835.         moc_state = string.gsub(moc_state_lines,"State: ","")
  836.         if moc_state == "STOP" or nil then
  837.             moc_string = " ..."
  838.             mocp_pause_button:set_image(beautiful.media_play)
  839.             mocline.visible = false
  840.         elseif moc_state == "PLAY" or moc_state == "PAUSE" then
  841.             if moc_state == "PAUSE" then
  842.                 mocline.visible = false
  843.                 mocp_pause_button:set_image(beautiful.media_play)
  844.                 return
  845.             end
  846.             moc_artist  = string.gsub(string.match(moc_info, "Artist: %C*"), "Artist: ","")
  847.             moc_title   = string.gsub(string.match(moc_info, "SongTitle: %C*"), "SongTitle: ","")
  848.             moc_album   = string.gsub(string.match(moc_info, "Album: %C*"), "Album: ","")
  849.             moc_path    = string.gsub(string.match(moc_info, "File: %C*"), "File: ", "")
  850.             moc_file    = string.gsub(moc_path, "^.*/","")
  851.             moc_artist  = string.gsub(moc_artist, "&amp;", "&")
  852.             --if string.len(moc_title) >=75 then moc_title = " title" else if string.len(moc_artist) >= 85 then moc_artist = "VA " end end
  853.             moc_title   = string.gsub(moc_title, "&amp;", "&")
  854.             moc_album   = string.gsub(moc_album, "&amp;", "&")
  855.             moc_file    = string.gsub(moc_file, "&amp;", "&")
  856.             moc_cs      = string.gsub(string.match(moc_info, "CurrentSec: %d+"),"CurrentSec: ","")
  857.             ts          = string.match(moc_info, "TotalSec: %d+")
  858.             if ts ~= nil then moc_ts = string.gsub(ts,"TotalSec: ","") else moc_ts = 0 end
  859.             if moc_artist == "" or nil then moc_artist = " " end
  860.             if moc_title  == "" or nil then moc_title = moc_file end
  861.             if moc_album  == "" or nil then moc_album = " " end
  862.             if moc_state  == "PLAY" then mocline.visible = true mocp_pause_button:set_image(beautiful.media_pause) end
  863.             mocwidget.w_title:set_text(moc_title or " ")
  864.             mocwidget.w_artist:set_text("@ " .. moc_artist or " ")
  865.             mocwidget.w_album:set_text("⦾ " .. moc_album or " ")
  866.             ls  = moc_ts - moc_cs
  867.             pos = moc_cs/moc_ts
  868.             if auto == true then
  869.                 mocline:set_value(pos)
  870.             else  
  871.                 if position ~= nil and ls > 12 then
  872.                     mocline:set_value(position-0.01)
  873.                     pos = position
  874.                 else
  875.                     mocline:set_value(pos)
  876.                 end
  877.                 mocwidget.t:stop()
  878.                 mocwidget.t.start_new( 1.2, function ()
  879.                     mocline_draw(nil,true)
  880.                     mocwidget.t:start()
  881.                     return false
  882.                 end)
  883.             end
  884.         end
  885.     end)
  886. end
  887.  
  888. -- clickable progressbar
  889. mocline:connect_signal("button::press", function(_,xpl,_,b,_,fwr)
  890.     local p = xpl/fwr.width
  891.     local percent = math.floor(100 * p)
  892.     if b == 1 then
  893.         cmd = "mocp -j " .. percent .. "%"
  894.         awful.spawn.with_shell(cmd)
  895.         mocline_draw(p,false)
  896.     end
  897. end)
  898. -- mocp functions
  899. function mocp_pause()
  900.     awful.spawn.easy_async({"bash", "-c","mocp -i"},
  901.         function(out)
  902.             local moc_state  = ""
  903.             local init_state = string.match(out, "State: %a*")
  904.             if init_state ~= nil then moc_state = string.gsub( init_state ,"State: ","") else moc_state = "STOP" end
  905.             if moc_state == "PLAY" then
  906.                 awful.spawn.with_shell("mocp -P")
  907.             elseif moc_state == "PAUSE" then
  908.                 awful.spawn.with_shell("mocp -U")
  909.             end
  910.         end)
  911.     return false
  912. end
  913. function mocp_func(f)
  914. -- -Ppause -fnext -rprev -pplaylist -cclear -k{ +|-N}seek -t{ shuffle|repeat}toggle
  915.     awful.spawn.with_shell( "mocp -" .. f )
  916.     return false
  917. end
  918. function mocp_enqueue()
  919.     awful.spawn.with_shell("xte 'key a'")
  920.     return false
  921. end
  922. mocline:buttons(gears.table.join(
  923.     awful.button({ }, 5, function () mocp_func("k -10") end),
  924.     awful.button({ }, 4, function () mocp_func("k +10")  end)
  925.     ))
  926. mocp_play_button        = wibox.widget.textbox ( )
  927. mocp_play_button.valign = 'center'
  928. mocp_play_button.align  = 'center'
  929. mocp_play_button:set_markup("<span color='" .. beautiful.border_focus .. "'>▷</span>")
  930. --mocp_play_button:set_text(" ▷ ")
  931. mocp_play_button:buttons(gears.table.join(
  932.     awful.button({ }, 3, nil,function () spawn_client_once(mocp_terminal .. " -e /usr/bin/mocp",3) end)
  933.     ))
  934. mocp_album_cover = wibox.widget {
  935.     forced_height = beautiful.menu_height * 4,
  936.     forced_width = beautiful.menu_height * 4,
  937.     resize = true,
  938.     widget = wibox.widget.imagebox,
  939. }
  940. mocp_album_cover:set_image("/home/" .. user .. "/.moc/default_album.png")
  941. mocp_album_cover:buttons(gears.table.join(
  942.     awful.button({ }, 1, function () awful.spawn.with_shell("xte 'key Return'")    end),
  943.     awful.button({ }, 2, function () awful.spawn.with_shell("xte 'key Tab'")       end),
  944.     awful.button({ }, 3, function () awful.spawn.with_shell("xte 'key BackSpace'") end),
  945.     awful.button({ }, 4, function () awful.spawn.with_shell("xte 'key Up'")        end),
  946.     awful.button({ }, 5, function () awful.spawn.with_shell("xte 'key Down'")      end)
  947. ))
  948. mocp_buttons = {}
  949. mocp_buttons.__index = mocp_buttons
  950. function mocp_buttons:new(image)
  951.     local obj = wibox.widget {
  952.         forced_height = icons_size,
  953.         forced_width  = icons_size,
  954.         image         = image,
  955.         resize        = true,
  956.         widget        = wibox.widget.imagebox
  957.     }
  958.     setmetatable(obj, self)
  959.     return obj;
  960. end
  961.  
  962. mocp_pause_button = mocp_buttons:new(beautiful.media_play)
  963. mocp_pause_button:buttons(gears.table.join(
  964.     awful.button({ }, 1, nil, function() mocp_pause() end),
  965.     awful.button({ }, 3, nil, function() local c = client.focus if c.class == "Sakura" then awful.spawn.with_shell("xte 'keydown Shift_L' 'key g' 'keyup Shift_L'") end end)
  966. ))
  967. mocp_pause_button.tip = awful.tooltip { delay_show = 2 }
  968. mocp_pause_button.tip:add_to_object(mocp_pause_button)
  969. mocp_pause_button.tip.text = "1 - play\n3 - go dir"
  970.  
  971. mocp_next_button = mocp_buttons:new(beautiful.media_next)
  972. mocp_next_button:buttons(gears.table.join(
  973.     awful.button({ }, 1, nil, function() mocp_func("f") end)
  974. ))
  975. mocp_prev_button = mocp_buttons:new(beautiful.media_prev)
  976. mocp_prev_button:buttons(gears.table.join(
  977.     awful.button({ }, 1, nil, function() mocp_func("r") end)
  978. ))
  979. mocp_playlist_button = mocp_buttons:new(beautiful.media_playlist)
  980. mocp_playlist_button:buttons(gears.table.join(
  981.     awful.button({ }, 1, nil, function() mocp_func("p") end),
  982.     awful.button({ }, 2, nil, function() mocp_func("c") end),
  983.     awful.button({ }, 3, nil, function() local c = client.focus if c.class == "Sakura" then mocp_enqueue() end end)
  984. ))
  985. mocp_playlist_button.tip = awful.tooltip { delay_show = 2 }
  986. mocp_playlist_button.tip:add_to_object(mocp_playlist_button)
  987. mocp_playlist_button.tip.text = "1 - play\n2 - clear\n3 - add"
  988.  
  989. mocp_shuffle_button = mocp_buttons:new(beautiful.media_shuffle)
  990. mocp_shuffle_button:buttons(gears.table.join(
  991.     awful.button({ }, 1, nil, function() mocp_func("t shuffle") end)
  992. ))
  993. mocp_repeat_button = mocp_buttons:new(beautiful.media_repeat)
  994. mocp_repeat_button:buttons(gears.table.join(
  995.     awful.button({ }, 1, nil, function() mocp_func("t repeat") end)
  996. ))
  997.  
  998. mocp_play_button:connect_signal("button::release",
  999.     function(_, _, _, button)
  1000.         if button == 1 then
  1001.             if mouse.screen.popup_mocp.visible then
  1002.                 mouse.screen.popup_mocp.visible = not mouse.screen.popup_mocp.visible
  1003.                 mocwidget.t:stop()
  1004.             else
  1005.                
  1006.                 mouse.screen.popup_mocp.visible = true
  1007.                 mocline_draw(nil,false)
  1008.                 mocwidget.t:again()
  1009.                 mocp_album_cover:set_image(gears.surface.load_uncached("/home/" .. user .. "/.moc/current_album.png"))
  1010.             end
  1011.         end
  1012.     end
  1013. )
  1014.  
  1015. -- Scrot
  1016. scr_button        = wibox.widget.textbox( )
  1017. scr_button.valign = 'center'
  1018. scr_button.align  = 'center'
  1019. scr_button:set_text("⬚")
  1020. scr_button:buttons(gears.table.join(
  1021.     awful.button({ }, 1, function () awful.spawn.with_shell(scr_area)        end),
  1022.     awful.button({ }, 2, function () awful.spawn.with_shell(scr_full)        end),
  1023.     awful.button({ }, 3, function () awful.spawn.with_shell(scr_area_delay)  end)
  1024. ))
  1025.  
  1026. -- Battery indicator (example)(v084)
  1027. mybatterybar = wibox.widget {
  1028.    {
  1029.         min_value        = 0,
  1030.         max_value        = 100,
  1031.         color            = beautiful.border_focus,
  1032.         background_color = beautiful.bg_normal,
  1033.         border_width     = 1,
  1034.         border_color     = beautiful.border_focus,
  1035.         --forced_width     = beautiful.menu_height,
  1036.         --forced_height    = beautiful.menu_height,
  1037.         shape = function(cr) -- custom scalable shape
  1038.             local h = beautiful.menu_height
  1039.             cr:move_to( 2,      0.25*h )
  1040.             cr:line_to( 2,      0.75*h )
  1041.             cr:line_to( 0.87*h, 0.75*h )
  1042.             cr:line_to( 0.87*h, 0.6*h  )
  1043.             cr:line_to( 0.95*h, 0.6*h  )
  1044.             cr:line_to( 0.95*h, 0.4*h  )
  1045.             cr:line_to( 0.87*h, 0.4*h  )
  1046.             cr:line_to( 0.87*h, 0.25*h )
  1047.             cr:close_path()
  1048.         end,
  1049.         id               = "mypb",
  1050.         widget           = wibox.widget.progressbar,
  1051.         value            = 0,
  1052.     },
  1053.     {
  1054.         id     = "mytb",
  1055.         --text   = "0",
  1056.         markup = "<span color='" .. beautiful.fg_focus .. "'>0</span>",
  1057.         wrap   = "char",
  1058.         valign = "center", --vertical popup
  1059.         align  = "center", --vertical popup
  1060.         widget = wibox.widget.textbox,
  1061.         font   = beautiful.font_name .. " Bold " .. math.ceil(beautiful.menu_height/3.45),
  1062.     },
  1063.     layout            = wibox.layout.stack,
  1064.     horizontal_offset = 0,
  1065.     vertical_offset   = 0,
  1066.     forced_width      = beautiful.menu_height,
  1067.     forced_height     = beautiful.menu_height,
  1068.     --spacing           = 0,
  1069.     set_battery = function(self, val)
  1070.         if beautiful.menu_height < 25 then self.mytb.markup = "<span color='" .. beautiful.fg_focus .. "'> </span>" --self.mytb.text = " "
  1071.         else self.mytb.markup = "<span color='" .. beautiful.fg_focus .. "'> " .. val .."</span>" --self.mytb.text  = " ".. val end
  1072.         end
  1073.         self.mypb.value = val
  1074.     end
  1075. }
  1076. local battery_tooltip = " "
  1077. local battery_on = false
  1078. battery_timer = gears.timer {
  1079.     timeout   = 5,
  1080.     call_now  = true,
  1081.     autostart = false,
  1082.     callback  = function()
  1083.         awful.spawn.easy_async({"bash", "-c", "acpi"},
  1084.             function(out)
  1085.                 local percent = tonumber(string.match(out, "(%d?%d?%d)%%"))
  1086.                 battery_state = string.match(out, ": (%a+),")
  1087.                 battery_time  = tostring(string.match(out, "(%d%d:%d%d):"))
  1088.                 if battery_state == nil then battery_state = "n/a" end
  1089.                 if percent       == 100 then battery_time = " full" end
  1090.                 if percent       == nil then percent = 0 end
  1091.                 if percent       <  11 and battery_state == "Discharging" then awful.spawn("systemctl suspend") end
  1092.                 mybatterybar.battery = percent
  1093.                 battery_tooltip = "<span size='xx-large'>" .. percent .. "%</span>\n\n" .. battery_state .. ": " .. battery_time .. "\n"
  1094.             end
  1095.         )
  1096.     end
  1097. }
  1098.  
  1099. battery_timer.start_new( 0, function ()
  1100.     awful.spawn.easy_async({"bash", "-c", "acpi"},
  1101.         function(stdout,stderr)
  1102.             if not string.find(stderr, "No support", 1, true) and stdout ~= "" then
  1103.                 battery_timer:start()
  1104.                 battery_on = true
  1105.             else
  1106.                 battery_on = false
  1107.             end
  1108.             if not battery_on then mybatterybar.visible = false end
  1109.             return false
  1110.         end
  1111.     )
  1112. end)
  1113.  
  1114. local mybattery_t = awful.tooltip { delay_show = 1.5 }
  1115. mybattery_t.wibox.shape = function(cr, width, height) gears.shape.rounded_rect(cr, width, height, beautiful.radius-1) end
  1116. mybattery_t:add_to_object(mybatterybar)
  1117. mybatterybar:connect_signal('mouse::enter', function()
  1118.     mybattery_t.markup = battery_tooltip
  1119. end)--]]
  1120.  
  1121. -- unused
  1122. -- Kanji show widget
  1123. --[[kanji = {}
  1124. kanji.w = wibox.widget {
  1125.     widget = wibox.widget.textbox,
  1126.     text = " 漢字 "
  1127. }
  1128. kanji.t = awful.tooltip { }
  1129. kanji.t:add_to_object(kanji.w)
  1130. kanji.timer = gears.timer {
  1131.     timeout   = 120,
  1132.     call_now  = true,
  1133.     autostart = true,
  1134.     callback  = function()
  1135.         awful.spawn.easy_async({"bash", "-c", "cat ".. config_dir .. "/jlpt5_4_list.txt | head -n`shuf -i 1-320 -n 1` | tail -n1"},
  1136.             function(out)
  1137.                 local kanji_current = string.match(out, "^(.*);.*;")
  1138.                 local on_kun = string.match(out, ";(.*);")
  1139.                 local rus = string.match(out, "^.*;(.*)$")
  1140.                 kanji.w:set_text(kanji_current)
  1141.                 kanji.t.text = on_kun .. "\n" .. rus
  1142.             end
  1143.         )
  1144.     end
  1145. }--]]
  1146.  
  1147. -- Create a wibox for each screen and add it
  1148. local taglist_buttons = gears.table.join(
  1149.                     awful.button({ }, 1, function(t) t:view_only() end),
  1150.                     awful.button({ modkey }, 1, function(t)
  1151.                                               if client.focus then
  1152.                                                   client.focus:move_to_tag(t)
  1153.                                               end
  1154.                                           end),
  1155.                    --[[ awful.button({ }, 2, function(t)
  1156.                                               if client.focus then
  1157.                                                   local c = client.focus
  1158.                                                   if c.fullscreen then
  1159.                                                       c.fullscreen = not c.fullscreen
  1160.                                                   else c.fullscreen = true
  1161.                                                   end
  1162.                                                  
  1163.                                               end
  1164.                                           end),--]]
  1165.                     --awful.button({ }, 4, function(t) awful.tag.viewnext(t.screen) end),
  1166.                     --awful.button({ }, 5, function(t) awful.tag.viewprev(t.screen) end),
  1167.                     awful.button({ }, 3, awful.tag.viewtoggle),
  1168.                     awful.button({ modkey }, 3, function(t)
  1169.                                               if client.focus then
  1170.                                                   client.focus:toggle_tag(t)
  1171.                                               end
  1172.                                           end)
  1173. )
  1174. close_menu = awful.menu ({})
  1175. close_menu.wibox.shape = function(cr, width, height) gears.shape.rounded_rect(cr, width, height, beautiful.radius-1) end
  1176.  
  1177. local tasklist_buttons = gears.table.join(
  1178.                      awful.button({ }, 1, function (c)
  1179.                                               if c == client.focus then
  1180.                                                   c.minimized = true
  1181.                                               else
  1182.                                                   -- Without this, the following
  1183.                                                   -- :isvisible() makes no sense
  1184.                                                   c.minimized = false
  1185.                                                   if not c:isvisible() and c.first_tag then
  1186.                                                       c.first_tag:view_only()
  1187.                                                   end
  1188.                                                   -- This will also un-minimize
  1189.                                                   -- the client, if needed
  1190.                                                   client.focus = c
  1191.                                                   c:raise()
  1192.                                               end
  1193.                                           end),
  1194.                      -- TODO
  1195.                      awful.button({ }, 3, function(c) --client_menu_toggle_fn()
  1196.                                               awful.client.swap.byidx(-1)
  1197.                                               client.focus = c
  1198.                                               c:raise()
  1199.                                           end
  1200.                      ),
  1201.                      awful.button({ }, 2, function (c)
  1202.                                               if c:isvisible() then
  1203.                                                   c.first_tag:view_only()
  1204.                                               end
  1205.                                               client.focus = c
  1206.                                               c:kill()
  1207.                                           end)
  1208.                      --awful.button({ }, 4, function () awful.client.focus.byidx(1) end),
  1209.                      --awful.button({ }, 5, function () awful.client.focus.byidx(-1) end)),
  1210.                      --awful.button({ }, 3, client_menu_toggle_fn() )
  1211. )
  1212.  
  1213. -- Wallpaper
  1214. local function set_wallpaper(s)
  1215.     if beautiful.wallpaper then
  1216.         local wallpaper = beautiful.wallpaper
  1217.         -- If wallpaper is a function, call it with the screen
  1218.         if type(wallpaper) == "function" then
  1219.             wallpaper = wallpaper(s)
  1220.         else
  1221. -- set (pattern)    Set the current wallpaper.
  1222. -- centered (surf, s, background, scale)    Set a centered wallpaper.
  1223. -- tiled (surf, s, offset)  Set a tiled wallpaper.
  1224. -- maximized (surf, s, ignore_aspect, offset)   Set a maximized wallpaper.
  1225. -- fit (surf, s, background)    Set a fitting wallpaper.
  1226.             gears.wallpaper.maximized(wallpaper, s, false)
  1227.         end
  1228.     end
  1229. end
  1230. -- Re-set wallpaper when a screen's geometry changes (e.g. different resolution)
  1231. screen.connect_signal("property::geometry", set_wallpaper)
  1232.  
  1233. empty_widget = wibox.widget {
  1234.     widget = wibox.widget.textbox,
  1235. }
  1236. empty_widget:set_text(" ")
  1237. --empty_widget:set_forced_width(5)
  1238. --empty_widget:set_forced_height(beautiful.menu_height)
  1239.  
  1240. awful.screen.connect_for_each_screen(function(s)
  1241.     -- Wallpaper
  1242.     set_wallpaper(s)
  1243.     -- Tags
  1244.     if s.index == 1 then
  1245.         awful.tag.add(web_tag, {
  1246.             --icon                = "/path/to/icon1.png",
  1247.             --gap_single_client   = true,
  1248.             --gap                 = 5,
  1249.             --master_fill_policy  = "master_width_factor",
  1250.             layout              = awful.layout.suit.tile,
  1251.             master_width_factor = 0.71,
  1252.             master_count        = 1,
  1253.             screen              = 1,
  1254.             selected            = true,
  1255.             index               = 1,
  1256.         })
  1257.         awful.tag.add(misc_tag, {
  1258.             layout = awful.layout.suit.fair,
  1259.             screen = 1,
  1260.             index  = 2,
  1261.         })
  1262.         awful.tag.add(media_tag, {
  1263.             layout = awful.layout.suit.max,
  1264.             screen = 1,
  1265.             index  = 3,
  1266.         })
  1267.         awful.tag.add(files_tag, {
  1268.             layout = awful.layout.suit.spiral.dwindle,
  1269.             screen = 1,
  1270.             index  = 4,
  1271.         })
  1272.     else
  1273.         awful.tag.add("Screen " .. screen_index_mark(s), {
  1274.             layout   = awful.layout.suit.spiral.dwindle,
  1275.             screen   = s,
  1276.             index    = 1,
  1277.             --gap      = 0,
  1278.             selected = true,
  1279.         })
  1280.     end
  1281.     -- Create a promptbox for each screen
  1282.     s.mypromptbox = awful.widget.prompt()
  1283.     -- Create an imagebox widget which will contains an icon indicating which layout we're using.
  1284.     -- We need one layoutbox per screen.
  1285.     --s.mylayoutbox = awful.widget.layoutbox()
  1286.     s.mylayoutbox = wibox.widget {
  1287.         {
  1288.             awful.widget.layoutbox(s),
  1289.             margins = 2,
  1290.             widget = wibox.container.margin,
  1291.         },
  1292.         bg     = beautiful.bg_normal,
  1293.         widget = wibox.container.background,
  1294.     }
  1295.     s.mylayoutbox:buttons(gears.table.join(
  1296.             --awful.button({ }, 4, function () awful.layout.inc( 1) end),
  1297.             --awful.button({ }, 5, function () awful.layout.inc(-1) end),
  1298.             awful.button({ }, 1, function () awful.layout.inc( 1) end),
  1299.             awful.button({ }, 3, function () awful.layout.inc(-1) end)
  1300.     ))
  1301.     s.mylayoutbox:set_forced_width(beautiful.menu_height-8)
  1302.     s.mylayoutbox:set_forced_height(beautiful.menu_height-8)
  1303.     -- Volume popup
  1304.     s.popup_volume = awful.popup {
  1305.         ontop     = true,
  1306.         visible   = false,
  1307.         screen    = s,
  1308.         shape     = function(cr, width, height) gears.shape.rounded_rect(cr, width, height, beautiful.radius-1) end,
  1309.         placement = function(self,s) awful.placement.top_right( self, { margins = { top = beautiful.menu_height, right = beautiful.menu_height } }) end,
  1310.         widget    = {
  1311.             {
  1312.                 {
  1313.                     { widget = volumebar },
  1314.                     forced_height = beautiful.menu_height*5,
  1315.                     forced_width  = beautiful.menu_height,
  1316.                     direction     = 'east',
  1317.                     layout        = wibox.container.rotate,
  1318.                 },
  1319.                 { widget = sound_widget },
  1320.                 layout = wibox.layout.fixed.vertical,
  1321.             },
  1322.             widget  = wibox.container.margin,
  1323.         },
  1324.     }
  1325.     s.popup_volume_timer = gears.timer { timeout = 2.1 }
  1326.     s.popup_volume_timer:connect_signal("timeout", function() s.popup_volume.visible = false s.popup_volume_timer:stop() end)
  1327.     s.popup_volume:connect_signal("mouse::enter", function(w) s.popup_volume.visible = true s.popup_volume_timer:again() end)
  1328.     s.popup_volume:connect_signal("mouse::move", function(w) s.popup_volume.visible = true s.popup_volume_timer:again() end)
  1329.     -- Mocp popup
  1330.     s.popup_mocp = awful.popup {
  1331.         ontop        = true,
  1332.         visible      = false,
  1333.         screen       = s,
  1334.         shape        = function(cr, width, height) gears.shape.partially_rounded_rect(cr, width, height, true, true, false, true, beautiful.radius-1 ) end,
  1335.         placement    = function(self) awful.placement.right( self, { margins = { right = beautiful.menu_height + 40 } }) end,
  1336.         border_width = 1,
  1337.         border_color = beautiful.border_focus,
  1338.         widget       = {
  1339.             {
  1340.                 {
  1341.                     {
  1342.                         {
  1343.                             {
  1344.                                 { widget = mocp_album_cover, },
  1345.                                 bg         = beautiful.bg_normal,
  1346.                                 shape_clip = true,
  1347.                                 shape      = function(cr, width, height) gears.shape.partially_rounded_rect(cr, width, height, true, true, false, true, (beautiful.radius-1)*2) end,
  1348.                                 widget     = wibox.container.background,
  1349.                             },
  1350.                             margins = 5,
  1351.                             widget  = wibox.container.margin,
  1352.                         },
  1353.                         {
  1354.                             {
  1355.                                 { widget = mocp_playlist_button },
  1356.                                 { widget = mocp_shuffle_button },
  1357.                                 { widget = mocp_repeat_button },
  1358.                                 layout = wibox.layout.align.horizontal,
  1359.                                 expand = 'none',
  1360.                             },
  1361.                             { widget = mocwidget.w_artist },
  1362.                             { widget = mocwidget.w_album },
  1363.                             { widget = mocwidget.w_title },
  1364.                             layout = wibox.layout.fixed.vertical,
  1365.                         },
  1366.                         layout = wibox.layout.fixed.horizontal,
  1367.                     },
  1368.                     layout = wibox.layout.fixed.horizontal,
  1369.                 },
  1370.                 { widget = mocline },
  1371.                 {
  1372.                     { widget = mocp_prev_button },
  1373.                     { widget = mocp_pause_button },
  1374.                     { widget = mocp_next_button },
  1375.                     layout = wibox.layout.align.horizontal,
  1376.                     expand = 'none',
  1377.                 },
  1378.                 layout = wibox.layout.fixed.vertical,
  1379.             },
  1380.             margins = 10,
  1381.             widget  = wibox.container.margin,
  1382.         },
  1383.     }
  1384.     -- Create a taglist widget
  1385.     s.mytaglist = awful.widget.taglist { --(s, awful.widget.taglist.filter.all, taglist_buttons)
  1386.         screen  = s,
  1387.         filter  = awful.widget.taglist.filter.all,
  1388.         buttons = taglist_buttons,
  1389.         style   = {
  1390.             shape = function(cr, width, height) gears.shape.rounded_bar (cr, 0, 0) end, --tag bg shape is nothing
  1391.         },
  1392.         layout  = {
  1393.             spacing = 20,
  1394.             layout  = wibox.layout.fixed.horizontal,
  1395.         },
  1396.         widget_template = {
  1397.             {
  1398.                 {
  1399.                     layout = wibox.layout.fixed.vertical,
  1400.                     {
  1401.                         {
  1402.                             {
  1403.                                 left    = 0,
  1404.                                 right   = 0,
  1405.                                 top     = math.ceil(beautiful.menu_height/2), -- slider area height
  1406.                                 bottom  = 0,
  1407.                                 opacity = 0,
  1408.                                 widget = wibox.container.margin
  1409.                             },
  1410.                             id           = 'slider',
  1411.                             bg           = '#ffffff',
  1412.                             forced_width = beautiful.menu_height, -- slider area width
  1413.                             shape        = function(cr, width, height) gears.shape.rounded_bar (cr, math.ceil(beautiful.menu_height/2)-1, math.ceil(beautiful.menu_height/4)-1) end,
  1414.                             widget       = wibox.container.background,
  1415.                             opacity = 0.83,
  1416.                         },
  1417.                         top    = math.ceil(beautiful.menu_height/4), -- slider area height
  1418.                         widget = wibox.container.margin,
  1419.                     },
  1420.                     --[[{
  1421.                         {
  1422.                             id     = 'text_role',
  1423.                             widget = wibox.widget.textbox,
  1424.                         },
  1425.                         left   = 1,
  1426.                         top    = -1,
  1427.                         right  = 1,
  1428.                         widget = wibox.container.margin,
  1429.                     },--]]
  1430.                 },
  1431.                 margins = 0,
  1432.                 widget = wibox.container.margin,
  1433.             },
  1434.             id              = 'background_role',
  1435.             opacity         = 1,
  1436.             widget          = wibox.container.background,
  1437.             create_callback = function(self, c3, index, objects)
  1438.                 local focused = false
  1439.                 for _, x in pairs(awful.screen.focused().selected_tags) do
  1440.                     if x.index == index then
  1441.                         focused = true
  1442.                         break
  1443.                     end
  1444.                 end
  1445.                 if awful.tag.getproperty(c3, "urgent") then
  1446.                     self:get_children_by_id("slider")[1].bg = beautiful.bg_urgent
  1447.                 else
  1448.                     self:get_children_by_id("slider")[1].bg = beautiful.border_focus
  1449.                 end
  1450.                 if focused then
  1451.                     self:get_children_by_id("slider")[1].shape = function(cr, width, height) gears.shape.rounded_bar (cr, beautiful.menu_height-5, math.ceil(beautiful.menu_height/2)-1) end
  1452.                 else
  1453.                     self:get_children_by_id("slider")[1].shape = function(cr, width, height) gears.shape.rounded_bar (cr, math.ceil(beautiful.menu_height/2)-1, math.ceil(beautiful.menu_height/2)-1) end
  1454.                 end
  1455.             end,
  1456.             update_callback = function(self, c3, index, objects)
  1457.                 local focused = false
  1458.                 for _, x in pairs(awful.screen.focused().selected_tags) do
  1459.                     if x.index == index then
  1460.                         focused = true
  1461.                         break
  1462.                     end
  1463.                 end
  1464.                 if awful.tag.getproperty(c3, "urgent") then
  1465.                     self:get_children_by_id("slider")[1].bg = beautiful.bg_urgent
  1466.                 else
  1467.                     self:get_children_by_id("slider")[1].bg = beautiful.border_focus
  1468.                 end
  1469.                 if focused then
  1470.                     self:get_children_by_id("slider")[1].shape = function(cr, width, height) gears.shape.rounded_bar (cr, beautiful.menu_height-5, math.ceil(beautiful.menu_height/2)-1) end
  1471.                 else
  1472.                     self:get_children_by_id("slider")[1].shape = function(cr, width, height) gears.shape.rounded_bar (cr, math.ceil(beautiful.menu_height/2)-1, math.ceil(beautiful.menu_height/2)-1) end
  1473.                 end
  1474.             end
  1475.             },
  1476.     }--]]
  1477.     -- Taglist popup
  1478.     s.task_popup_top = awful.popup {
  1479.         ontop         = false,
  1480.         visible       = true,
  1481.         screen        = s,
  1482.         border_width  = 0,
  1483.         border_color  = beautiful.border_focus,
  1484.         --forced_height = beautiful.menu_height,
  1485.         bg            = "#00000000",
  1486.         shape         = function(cr, width, height) gears.shape.rounded_rect(cr, width, height, beautiful.radius-1) end,
  1487.         placement     = function (self,s) awful.placement.top( self, { margins = { top = 10 } }) end,
  1488.         widget        = {
  1489.             {
  1490.                 --mylauncher,
  1491.                 --mybatterybar,
  1492.                 s.mytaglist,
  1493.                 --s.mytasklist,
  1494.                 spacing    = 10,
  1495.                 layout     = wibox.layout.fixed.horizontal,
  1496.                 fill_space = true,
  1497.             },
  1498.             left = 40, right = 30, top = 5, bottom = 5,
  1499.             widget = wibox.container.margin,
  1500.         }
  1501.     }
  1502.     -- Create a tasklist widget
  1503.     s.mytasklist = awful.widget.tasklist {
  1504.         screen  = s,
  1505.         filter  = awful.widget.tasklist.filter.alltags,
  1506.         buttons = tasklist_buttons,
  1507.         style   = {
  1508.             shape = function(cr, width, height) gears.shape.rounded_rect(cr, width, height, beautiful.radius-1) end,
  1509.         },
  1510.         layout  = {
  1511.             spacing         = 10,
  1512.             forced_num_rows = 1,
  1513.             layout          = wibox.layout.grid.horizontal,
  1514.         },
  1515.         widget_template = {
  1516.             {
  1517.                 {
  1518.                     id     = 'clienticon',
  1519.                     widget = awful.widget.clienticon,
  1520.                 },
  1521.                 margins = 1,
  1522.                 widget  = wibox.container.margin,
  1523.             },
  1524.             id              = 'background_role',
  1525.             forced_width    = beautiful.menu_height*2,
  1526.             forced_height   = beautiful.menu_height*2,
  1527.             widget          = wibox.container.background,
  1528.             create_callback = function(self, c, index, objects) --luacheck: no unused
  1529.             if not c.icon then self.widget.widget = emptyicon end
  1530.                 self:get_children_by_id('clienticon')[1].client = c
  1531.                 local c_tip = awful.tooltip {
  1532.                     delay_show           = 0.7,
  1533.                     align                = "top_left",
  1534.                     shape                = function(cr, width, height) gears.shape.rounded_rect(cr, width, height, beautiful.radius-1) end,
  1535.                     border_width         = 1,
  1536.                     border_color         = beautiful.border_focus,
  1537.                     mode                 = "outside",
  1538.                     preferred_positions  = {"top", "left"},
  1539.                     preferred_alignments = {"middle",},
  1540.                     margins              = 6,
  1541.                     timer_function       = function() return c.class .. " | " .. c.name end,
  1542.                     timeout              = 1,
  1543.                 }
  1544.                 c_tip.wibox.shape = function(cr, width, height) gears.shape.rounded_rect(cr, width, height, beautiful.radius-1) end
  1545.                 c_tip:add_to_object(self)
  1546.             end,
  1547.         },
  1548.     }
  1549.     -- Dock popup
  1550.     s.task_popup_bottom_min = awful.popup {
  1551.         ontop     = true,
  1552.         screen    = s,
  1553.         visible   = true,
  1554.         shape     = function(cr, width, height) gears.shape.partially_rounded_rect (cr, width, height, true, true, false, false, beautiful.radius-1) end,
  1555.         placement = function (self,s) awful.placement.bottom( self ) end,
  1556.         widget    = {
  1557.             { widget = empty_widget },
  1558.             layout        = wibox.layout.align.vertical,
  1559.             forced_width  = beautiful.menu_height*8,
  1560.             forced_height = 2,
  1561.             expand        = 'outside',
  1562.         },
  1563.     }
  1564.     s.task_popup_bottom = awful.popup {
  1565.         ontop         = true,
  1566.         visible       = false,
  1567.         screen        = s,
  1568.         border_width  = 0,
  1569.         border_color  = beautiful.border_focus,
  1570.         --forced_height = beautiful.menu_height,
  1571.         shape         = function(cr, width, height) gears.shape.partially_rounded_rect(cr, width, height, true, true, false, false, beautiful.radius*2) end,
  1572.         placement     = function (self,s) awful.placement.bottom( self ) end,
  1573.         widget        = {
  1574.             {
  1575.                 --mylauncher,
  1576.                 --mybatterybar,
  1577.                 --s.mytaglist,
  1578.                 appsicon,
  1579.                 s.mytasklist,
  1580.                 spacing       = 10,
  1581.                 layout        = wibox.layout.fixed.horizontal,
  1582.                 --forced_height = beautiful.menu_height,
  1583.                 fill_space    = true,
  1584.             },
  1585.             left = 50+beautiful.menu_height, right = 40+beautiful.menu_height, top = 5, bottom = 5,
  1586.             widget = wibox.container.margin,
  1587.         },
  1588.     }
  1589.     s.task_popup_bottom_timer = gears.timer { timeout = 3 }
  1590.     s.task_popup_bottom_timer:connect_signal("timeout", function(t) s.task_popup_bottom.visible = false s.task_popup_bottom_min.visible = true t:stop() end)
  1591.     s.task_popup_bottom_min:connect_signal("mouse::enter", function(w) s.task_popup_bottom.visible = true w.visible = false end)
  1592.     s.task_popup_bottom:connect_signal("mouse::leave", function(w) s.task_popup_bottom_timer:again() end)
  1593.     -- Task popup (example)
  1594.     s.task_popup = awful.popup {
  1595.         screen       = s,
  1596.         border_color = beautiful.border_normal,
  1597.         border_width = 2,
  1598.         ontop        = true,
  1599.         placement    = awful.placement.centered,
  1600.         shape        = function(cr, width, height) gears.shape.rounded_rect(cr, width, height, 10) end,
  1601.         visible      = false,
  1602.         widget       = awful.widget.tasklist {
  1603.             screen  = s,
  1604.             filter  = awful.widget.tasklist.filter.allscreen,
  1605.             buttons = tasklist_buttons,
  1606.             style   = {
  1607.                 shape = function(cr, width, height) gears.shape.rounded_rect(cr, width, height, 6) end,
  1608.             },
  1609.             layout = {
  1610.                 spacing         = 4,
  1611.                 forced_num_rows = 2,
  1612.                 layout          = wibox.layout.grid.horizontal
  1613.             },
  1614.             widget_template = {
  1615.                 {
  1616.                     {
  1617.                         id     = 'clienticon',
  1618.                         widget = awful.widget.clienticon,
  1619.                     },
  1620.                     margins = 4,
  1621.                     widget  = wibox.container.margin,
  1622.                 },
  1623.                 id              = 'background_role',
  1624.                 forced_width    = beautiful.menu_height*2,
  1625.                 forced_height   = beautiful.menu_height*2,
  1626.                 widget          = wibox.container.background,
  1627.                 create_callback = function(self, c, index, objects) --luacheck: no unused
  1628.                     if not c.icon then self.widget.widget = emptyicon end
  1629.                     self:get_children_by_id('clienticon')[1].client = c
  1630.                 end,
  1631.             },
  1632.         },
  1633.     }
  1634.     s.task_popup_timer = gears.timer { timeout = 2 }
  1635.     s.task_popup_timer:connect_signal("timeout", function(t) s.task_popup.visible = false t:stop() end)
  1636.     s.task_popup:connect_signal("mouse::enter", function(w)
  1637.         w.visible = true s.task_popup_timer:again()
  1638.     end)
  1639.     s.task_popup:connect_signal("mouse::move", function(w)
  1640.         w.visible = true s.task_popup_timer:again()
  1641.     end)
  1642.     -- Systray
  1643.     s.mysystray = wibox.widget.systray()
  1644.     s.mysystray:set_base_size(beautiful.menu_height)
  1645.     s.mysystray:set_horizontal(false)
  1646.     s.mysystray:set_screen(s)
  1647.     s.mysystray:set_reverse(true)
  1648.     -- Launcher popup
  1649.     s.tray_popup_topleft = awful.popup {
  1650.         ontop     = false,
  1651.         visible   = true,
  1652.         shape     = function(cr, width, height) gears.shape.rounded_rect (cr, width, height, beautiful.radius-1) end,
  1653.         screen    = s,
  1654.         placement = function (self,s) awful.placement.top_left( self, { margins = { top = 10, left = 10 } }) end,
  1655.         widget    = {
  1656.             {
  1657.                 mylauncher,
  1658.                 s.mysystray,
  1659.                 mybatterybar,
  1660.                 spacing = 5,
  1661.                 layout = wibox.layout.fixed.vertical,
  1662.                 forced_width = beautiful.menu_height,
  1663.             },
  1664.             left = 10, right = 10, top = 10, bottom = 0,
  1665.             widget  = wibox.container.margin,
  1666.         },
  1667.     }
  1668.     -- KB layout indicator
  1669.     s.popup_bottomright = awful.popup {
  1670.         ontop     = true,
  1671.         visible   = false,
  1672.         shape     = function(cr, width, height) gears.shape.rounded_rect (cr, width, height, beautiful.radius-1) end,
  1673.         screen    = s,
  1674.         placement = function (self,s) awful.placement.bottom_right( self, { margins = { bottom = beautiful.useless_gap*2, right = 10 } }) end,
  1675.         widget    = {
  1676.             {
  1677.                 mykeyboardlayout,
  1678.                 spacing      = 5,
  1679.                 layout       = wibox.layout.fixed.vertical,
  1680.                 forced_width = beautiful.menu_height*2,
  1681.             },
  1682.             left = 1, right = 1, top = 1, bottom = 1,
  1683.             widget  = wibox.container.margin,
  1684.         },
  1685.     }
  1686.     s.popup_bottomright_timer = gears.timer { timeout = 1 }
  1687.     s.popup_bottomright_timer:connect_signal("timeout", function(t) s.popup_bottomright.visible = false t:stop() end)
  1688.     -- Side bar
  1689.     s.sidebar_min = awful.popup {
  1690.         ontop     = true,
  1691.         screen    = s,
  1692.         visible   = true,
  1693.         shape     = function(cr, width, height) gears.shape.partially_rounded_rect (cr, width, height, true, false, false, true, beautiful.radius-1) end,
  1694.         placement = function (self,s) awful.placement.right( self ) end,
  1695.         widget    = {
  1696.             { widget = empty_widget },
  1697.             layout        = wibox.layout.align.vertical,
  1698.             forced_height = beautiful.menu_height*8,
  1699.             forced_width  = 2,
  1700.             expand        = 'outside',
  1701.         },
  1702.     }
  1703.     s.sidebar_min:buttons(gears.table.join(
  1704.         awful.button({ }, 4, function () volumecfg.up() end),
  1705.         awful.button({ }, 5, function () volumecfg.down() end)
  1706.     ))
  1707.     s.sidebar = awful.popup {
  1708.         ontop     = true,
  1709.         visible   = false,
  1710.         shape     = function(cr, width, height) gears.shape.partially_rounded_rect (cr, width, height, true, false, false, true, beautiful.radius-1) end,
  1711.         screen    = s,
  1712.         placement = function (self,s) awful.placement.right( self ) end,
  1713.         widget    = {
  1714.             {
  1715.                 {
  1716.                     {
  1717.                         mytextclock,
  1718.                         layout = wibox.layout.fixed.vertical,
  1719.                     },
  1720.                     volumecfg,
  1721.                     { -- grid
  1722.                         mocp_play_button,
  1723.                         s.mylayoutbox,
  1724.                         mykeyboardlayout,
  1725.                         --net_menu_widget,
  1726.                         net_icon_widget,
  1727.                         scr_button,
  1728.                         layout = wibox.layout.grid.vertical,
  1729.                         forced_num_rows = 2,
  1730.                         forced_num_cols = 2,
  1731.                         homogeneous     = true,
  1732.                         expand          = false,
  1733.                     },
  1734.                     forced_height = beautiful.menu_height*6,
  1735.                     layout        = wibox.layout.align.vertical,
  1736.                     expand        = 'inside',
  1737.                 },
  1738.                 layout = wibox.layout.fixed.vertical
  1739.             },
  1740.             margins = 10,
  1741.             widget  = wibox.container.margin,
  1742.         },
  1743.     }
  1744.     s.sidebar:buttons(gears.table.join(
  1745.         awful.button({ }, 4, function () volumecfg.up() end),
  1746.         awful.button({ }, 5, function () volumecfg.down() end)
  1747.     ))
  1748.     s.sidebar_timer = gears.timer { timeout = 3 }
  1749.     s.sidebar_timer:connect_signal("timeout", function(t) s.sidebar.visible = false s.sidebar_min.visible = true t:stop() end)
  1750.     s.sidebar_min:connect_signal("mouse::enter", function(w) s.sidebar.visible = true w.visible = false end)
  1751.     s.sidebar:connect_signal("mouse::leave", function(w) s.sidebar_timer:again() end)    
  1752. end)
  1753. -- }}}
  1754.  
  1755. -- pa init volume
  1756. mouse.screen.popup_volume_timer.start_new( 5, function ()
  1757.     volumecfg.update()
  1758.     return false
  1759. end)
  1760.  
  1761. -- Hide popups and menus
  1762. local do_on_click = function()
  1763.     -- mocp
  1764.     for s in screen do s.popup_mocp.visible = false end
  1765.     if mocwidget.t.started then mocwidget.t:stop()  end
  1766.     -- menu
  1767.     mymainmenu:hide() myifacemenu:hide() mydisplaymenu:hide()
  1768. end
  1769.  
  1770. -- {{{ Mouse bindings
  1771. root.buttons(gears.table.join(
  1772.     --awful.button({ }, 4, awful.tag.viewnext),
  1773.     --awful.button({ }, 5, awful.tag.viewprev),
  1774.     --awful.button({ }, 3, client_menu_toggle_fn() ),
  1775.     awful.button({ }, 1, function () do_on_click() end)
  1776. ))
  1777. -- }}}
  1778. -- Test window switcher
  1779. local tiled_c = false
  1780. local tiled = function()
  1781.     if tiled_c == false then awful.client.focus.byidx(-1) awful.layout.inc(1) tiled_c = true
  1782.     else awful.layout.inc(1) tiled_c = false
  1783.     end
  1784. end
  1785. -- Show task popup
  1786. local function task_popup_play_tab()
  1787.     for s in screen do
  1788.     s.task_popup.visible = true s.task_popup_timer:again()
  1789.     end
  1790.     local all_clients = awful.client.iterate(function (x) return true end)
  1791.     for c in awful.client.iterate(function (x) return true end) do
  1792.         if client.focus ~= c then
  1793.             awful.tag.viewmore(c:tags(), c.screen)
  1794.             client.focus = c
  1795.             client.focus:raise()
  1796.             c:emit_signal("request::activate", "ewmh", {raise = true})
  1797.             return
  1798.         end
  1799.     end
  1800. end
  1801. local function task_popup_play()
  1802.     mouse.screen.task_popup.visible = true mouse.screen.task_popup_timer:again()
  1803. end
  1804.  
  1805. -- {{{ Key bindings
  1806. globalkeys = gears.table.join(
  1807.     awful.key({ modkey            }, "e", function () spawn_client_once(filemanager,4) end,--awful.spawn(rofi_file_browser) end,
  1808.               {description = "rofi file browser", group = "rofi"}),
  1809.     awful.key({ modkey            }, "a", function () awful.spawn(rofi_cmd_drun) end,
  1810.               {description = "rofi drun", group = "rofi"}),
  1811.     awful.key({ modkey,           }, "s",      hotkeys_popup.show_help,
  1812.               {description="show help", group="awesome"}),
  1813.     awful.key({ modkey,           }, "Right", function() awful.tag.viewidx(1) task_popup_play() end,
  1814.               {description = "view previous", group = "tag"}),
  1815.     awful.key({ modkey,           }, "Left", function() awful.tag.viewidx(-1) task_popup_play() end,
  1816.               {description = "view next", group = "tag"}),
  1817.     awful.key({ modkey,           }, "Escape", awful.tag.history.restore,
  1818.               {description = "go back", group = "tag"}),
  1819.     awful.key({ modkey,           }, "Up",
  1820.         function ()
  1821.             awful.client.focus.byidx( 1) task_popup_play()
  1822.         end,
  1823.               {description = "focus next by index", group = "client"}
  1824.     ),
  1825.     awful.key({ modkey,           }, "Down",
  1826.         function ()
  1827.             awful.client.focus.byidx(-1) task_popup_play()
  1828.         end,
  1829.               {description = "focus previous by index", group = "client"}
  1830.     ),
  1831.     awful.key({ modkey,           }, "w", function () mymainmenu:show() end,
  1832.     --awful.key({ modkey,           }, "w", function () awful.spawn(rofi_cmd_window) end,
  1833.               {description = "show main menu", group = "awesome"}),
  1834.     -- Layout manipulation
  1835.     awful.key({ modkey, "Shift"   }, "Right", function () awful.client.swap.byidx(  1)    end,
  1836.               {description = "swap with next client by index", group = "client"}),
  1837.     awful.key({ modkey, "Shift"   }, "Left", function () awful.client.swap.byidx( -1)    end,
  1838.               {description = "swap with previous client by index", group = "client"}),
  1839.     awful.key({ modkey, "Control" }, "j", function () awful.screen.focus_relative( 1) end,
  1840.               {description = "focus the next screen", group = "screen"}),
  1841.     awful.key({ modkey, "Control" }, "k", function () awful.screen.focus_relative(-1) end,
  1842.               {description = "focus the previous screen", group = "screen"}),
  1843.     awful.key({ modkey,           }, "u", function() awful.client.urgent.jumpto() end,
  1844.               {description = "jump to urgent client", group = "client"}),
  1845.     awful.key({ modkey, "Shift"   }, "Tab", client_menu_toggle_fn(),
  1846.               {description = "open client menu", group = "client"}),
  1847.     awful.key({ modkey,           }, "Tab", function () task_popup_play_tab() end,
  1848.               {description = "switch windows via popup", group = "client"}),
  1849.     --[[awful.key({ modkey,           }, "Tab",
  1850.         function ()
  1851.             task_popup.visible = true task_popup_timer:again()
  1852.             local all_clients = awful.client.iterate(function (x) return true end)
  1853.             for c in awful.client.iterate(function (x) return true end) do
  1854.                 if client.focus ~= c then
  1855.                     awful.tag.viewmore(c:tags(), c.screen)
  1856.                     client.focus = c
  1857.                     client.focus:raise()
  1858.                     c:emit_signal("request::activate", "ewmh", {raise = true})
  1859.                     return
  1860.                 end
  1861.             end
  1862.         end,
  1863.         {description = "switch clients", group = "client"}),--]]
  1864.     -- Standard program
  1865.     awful.key({ modkey,           }, "Return", function () awful.spawn(terminal) end,
  1866.               {description = "open a terminal", group = "launcher"}),
  1867.     awful.key({ modkey,           }, "z", function () awful.spawn("rofi-translate-run-enru") end,
  1868.               {description = "open a rofi translate", group = "launcher"}),
  1869.     awful.key({ modkey, "Shift"   }, "z", function () awful.spawn("rofi-translate-run-ruen") end,
  1870.               {description = "open a rofi translate", group = "launcher"}),
  1871.     awful.key({ modkey, "Control" }, "r", awesome.restart,
  1872.               {description = "reload awesome", group = "awesome"}),
  1873.     awful.key({ modkey, "Shift"   }, "q", awesome.quit,
  1874.               {description = "quit awesome", group = "awesome"}),
  1875.     awful.key({ modkey,           }, "l",     function () awful.tag.incmwfact( 0.05)                 end,
  1876.               {description = "increase master width factor", group = "layout"}),
  1877.     awful.key({ modkey,           }, "h",     function () awful.tag.incmwfact(-0.05)                 end,
  1878.               {description = "decrease master width factor", group = "layout"}),
  1879.     awful.key({ modkey, "Shift"   }, "h",     function () awful.tag.incnmaster( 1, nil, true)        end,
  1880.               {description = "increase the number of master clients", group = "layout"}),
  1881.     awful.key({ modkey, "Shift"   }, "l",     function () awful.tag.incnmaster(-1, nil, true)        end,
  1882.               {description = "decrease the number of master clients", group = "layout"}),
  1883.     awful.key({ modkey, "Control" }, "h",     function () awful.tag.incncol( 1, nil, true)           end,
  1884.               {description = "increase the number of columns", group = "layout"}),
  1885.     awful.key({ modkey, "Control" }, "l",     function () awful.tag.incncol(-1, nil, true)           end,
  1886.               {description = "decrease the number of columns", group = "layout"}),
  1887.     awful.key({ modkey,           }, "space", function () awful.layout.inc(-1) end,
  1888.               {description = "select previous", group = "layout"}),
  1889.     awful.key({ modkey            }, "b", function () awful.spawn(browser)          end,
  1890.               {description = "launch Browser", group = "launcher"}),
  1891.     awful.key({ modkey, "Control" }, "d", display_menu_toggle_fn(),
  1892.               {description = "show display_switch menu", group = "menu"}),
  1893.     awful.key({                   }, "Print", function () awful.spawn.with_shell(scr_full)   end,
  1894.               {description = "capture a screenshot", group = "screenshot"}),
  1895.     awful.key({ modkey,           }, "Print", function () awful.spawn.with_shell(scr_area) end,
  1896.               {description = "capture a screenshot of a selection", group = "screenshot"}),
  1897.     awful.key({ modkey, "Shift"   }, "Print", function () awful.spawn.with_shell(scr_active_window)   end,
  1898.               {description = "capture a screenshot of an active window", group = "screenshot"}),
  1899.     awful.key({ modkey, "Shift"   }, "n", net_menu_toggle_fn(),
  1900.               {description = "net menu", group = "menu"}),
  1901.     awful.key({ modkey, "Control" }, "n",
  1902.               function ()
  1903.                   local c = awful.client.restore()
  1904.                   -- Focus restored client
  1905.                   if c then
  1906.                       client.focus = c
  1907.                       c:raise()
  1908.                   end
  1909.               end,
  1910.               {description = "restore minimized", group = "client"}),
  1911.     -- Prompt
  1912.     awful.key({ modkey            }, "r", function () awful.spawn(rofi_cmd_run)
  1913.             --awful.screen.focused().mypromptbox:run()
  1914.         end,
  1915.               {description = "run prompt", group = "launcher"}),
  1916.     --[[awful.key({ modkey, "Shift"   }, "r",
  1917.               function ()
  1918.                   awful.prompt.run {
  1919.                     prompt       = "Run Lua code: ",
  1920.                     textbox      = awful.screen.focused().mypromptbox.widget,
  1921.                     exe_callback = awful.util.eval,
  1922.                     history_path = awful.util.get_cache_dir() .. "/history_eval"
  1923.                   }
  1924.               end,
  1925.               {description = "lua execute prompt", group = "awesome"}),--]]
  1926.     -- Menubar
  1927.     awful.key({ modkey            }, "p", function() menubar.show() end,
  1928.               {description = "show the menubar", group = "launcher"}),
  1929.     -- XF86
  1930.     --awful.key({ }, "XF86WakeUp", function () volumecfg.down() end),
  1931.     --awful.key({ }, "XF86Display", function() end ),
  1932.     awful.key({ }, "XF86Sleep", function () awful.spawn("rofi-shutdown-menu.sh") end,
  1933.               {description = "show poweroff screen", group = "mediakeys"}),
  1934.     awful.key({ }, "XF86PowerOff", function () awful.spawn("rofi-shutdown-menu.sh") end,
  1935.               {description = "show poweroff screen", group = "mediakeys"}),
  1936.     awful.key({ }, "XF86AudioMute", function () volumecfg.toggle() end,
  1937.               {description = "toggle mute", group = "mediakeys"}),
  1938.     awful.key({ }, "XF86AudioRaiseVolume", function () volumecfg.up() end,
  1939.               {description = "volume up", group = "mediakeys"}),
  1940.     awful.key({ }, "XF86AudioLowerVolume", function () volumecfg.down() end,
  1941.               {description = "volume down", group = "mediakeys"}),
  1942.     awful.key({ }, "XF86Calculator", function() awful.spawn(calc) end,
  1943.               {description = "run calculator", group = "mediakeys"}),
  1944.     awful.key({ }, "XF86AudioMedia", function() spawn_client_once(mocp_terminal .. " -e /usr/bin/mocp",3) end,
  1945.               {description = "run player", group = "mediakeys"})
  1946. )
  1947.  
  1948. clientkeys = gears.table.join(
  1949.     awful.key({ modkey,           }, "f",
  1950.         function (c)
  1951.             c.fullscreen = not c.fullscreen
  1952.             c:raise()
  1953.         end,
  1954.         {description = "toggle fullscreen", group = "client"}),
  1955.     awful.key({ modkey, "Shift"   }, "c",      function (c) c:kill()                         end,
  1956.               {description = "close", group = "client"}),
  1957.     awful.key({ modkey, "Control" }, "space",  function (c) c.floating = not c.floating        end,
  1958.               {description = "toggle floating", group = "client"}),
  1959.     awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end,
  1960.               {description = "move to master", group = "client"}),
  1961.     awful.key({ modkey,           }, "o",      function (c) c:move_to_screen()               end,
  1962.               {description = "move to screen", group = "client"}),
  1963.     awful.key({ modkey,           }, "t",      function (c) c.ontop = not c.ontop            end,
  1964.               {description = "toggle keep on top", group = "client"}),
  1965.     awful.key({ modkey, "Shift"   }, "t",
  1966.         function (c)
  1967.             t = awful.tag.add(c.class or "N/A", {screen=c.screen, volatile=true})
  1968.             if not t then return end
  1969.             local tags = c:tags()
  1970.             table.insert(tags, t)
  1971.             c:tags(tags)
  1972.             c:move_to_tag(t)
  1973.             awful.tag.viewonly(t)
  1974.         end,
  1975.               {description = "move client to new tag", group = "client"}),
  1976.     awful.key({ modkey,           }, "n",
  1977.         function (c)
  1978.             -- The client currently has the input focus, so it cannot be
  1979.             -- minimized, since minimized clients can't have the focus.
  1980.             c.minimized = true
  1981.         end ,
  1982.         {description = "minimize", group = "client"}),
  1983.     awful.key({ modkey,           }, "m",
  1984.         function (c)
  1985.             c.maximized = not c.maximized
  1986.             c:raise()
  1987.         end ,
  1988.         {description = "ex((un)maximize) raise sakura terminal with mocp client", group = "client"}),
  1989.     awful.key({ modkey, "Control" }, "m",
  1990.         function (c)
  1991.             c.maximized_vertical = not c.maximized_vertical
  1992.             c:raise()
  1993.         end ,
  1994.         {description = "(un)maximize vertically", group = "client"}),
  1995.     awful.key({ modkey, "Shift"   }, "m",
  1996.         function (c)
  1997.             c.maximized_horizontal = not c.maximized_horizontal
  1998.             c:raise()
  1999.         end ,
  2000.         {description = "(un)maximize horizontally", group = "client"})
  2001. )
  2002.  
  2003. -- Bind all key numbers to tags.
  2004. -- Be careful: we use keycodes to make it work on any keyboard layout.
  2005. -- This should map on the top row of your keyboard, usually 1 to 9.
  2006. for i = 1, 9 do
  2007.     globalkeys = gears.table.join(globalkeys,
  2008.         -- View tag only.
  2009.         awful.key({ modkey }, "#" .. i + 9,
  2010.                   function ()
  2011.                         local screen = awful.screen.focused()
  2012.                         local tag = screen.tags[i]
  2013.                         if tag then
  2014.                            tag:view_only()
  2015.                         end
  2016.                   end,
  2017.                   {description = "view tag #"..i, group = "tag"}),
  2018.         -- Toggle tag display.
  2019.         awful.key({ modkey, "Control" }, "#" .. i + 9,
  2020.                   function ()
  2021.                       local screen = awful.screen.focused()
  2022.                       local tag = screen.tags[i]
  2023.                       if tag then
  2024.                          awful.tag.viewtoggle(tag)
  2025.                       end
  2026.                   end,
  2027.                   {description = "toggle tag #" .. i, group = "tag"}),
  2028.         -- Move client to tag.
  2029.         awful.key({ modkey, "Shift" }, "#" .. i + 9,
  2030.                   function ()
  2031.                       if client.focus then
  2032.                           local tag = client.focus.screen.tags[i]
  2033.                           if tag then
  2034.                               client.focus:move_to_tag(tag)
  2035.                           end
  2036.                      end
  2037.                   end,
  2038.                   {description = "move focused client to tag #"..i, group = "tag"}),
  2039.         -- Toggle tag on focused client.
  2040.         awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9,
  2041.                   function ()
  2042.                       if client.focus then
  2043.                           local tag = client.focus.screen.tags[i]
  2044.                           if tag then
  2045.                               client.focus:toggle_tag(tag)
  2046.                           end
  2047.                       end
  2048.                   end,
  2049.                   {description = "toggle focused client on tag #" .. i, group = "tag"})
  2050.     )
  2051. end
  2052.  
  2053. clientbuttons = gears.table.join(
  2054.     awful.button({ }, 1, function (c) if c.name ~= "Onboard" then -- unfocusable screen keyboard
  2055.                                           client.focus = c
  2056.                                       end
  2057.                                       c:raise()
  2058.                                       do_on_click()
  2059.     end),
  2060.     awful.button({ }, 2, function (c) if c.name ~= "Onboard" then -- unfocusable screen keyboard
  2061.                                           client.focus = c
  2062.                                       end
  2063.                                       c:raise()
  2064.                                       do_on_click()
  2065.     end),
  2066.     awful.button({ }, 3, function (c) if c.name ~= "Onboard" then -- unfocusable screen keyboard
  2067.                                           client.focus = c
  2068.                                       end
  2069.                                       c:raise()
  2070.                                       do_on_click()
  2071.     end),--]]
  2072.     awful.button({ modkey }, 1, awful.mouse.client.move),
  2073.     awful.button({ modkey }, 3, awful.mouse.client.resize)
  2074. )
  2075.  
  2076. -- Set keys
  2077. root.keys(globalkeys)
  2078. -- }}}
  2079.  
  2080. -- {{{ Rules
  2081. -- Rules to apply to new clients (through the "manage" signal).
  2082. awful.rules.rules = {
  2083.     -- All clients will match this rule.
  2084.     { rule = { },
  2085.       properties = {
  2086.         border_width      = beautiful.border_width,
  2087.         --border_color = beautiful.border_normal,
  2088.         titlebars_enabled = true,
  2089.         focus             = awful.client.focus.filter,
  2090.         raise             = true,
  2091.         keys              = clientkeys,
  2092.         buttons           = clientbuttons,
  2093.         size_hints_honor  = false, -- Remove gaps between terminals
  2094.         screen            = 1,--awful.screen.preferred,
  2095.         maximized         = false,
  2096.         callback          = awful.client.setslave,
  2097.         placement         = awful.placement.no_overlap+awful.placement.no_offscreen
  2098.       }
  2099.     },
  2100.     -- Add titlebars to normal clients and dialogs
  2101.     { rule_any = {type = { "dialog" } },
  2102.       properties = { titlebars_enabled = true }
  2103.     },
  2104.     -- Floating clients
  2105.     { rule_any = {
  2106.         class = {
  2107.             "Pavucontrol",  "Xarchiver",            "Calcoo",       "Galculator",
  2108.             "Wine",         "Qemu-system-x86_64",   "Gtk-chtheme",  "discord",
  2109.             "Discord",      "libreoffice",          "Geany",        "Gnome-screenshot",
  2110.             "Xsane",        "Gtk-theme-switch2",
  2111.         },
  2112.         name = {
  2113.             "Event Tester",  -- xev.
  2114.         },
  2115.                 role = {
  2116.             "pop-up",       -- e.g. Google Chrome's (detached) Developer Tools.
  2117.         }
  2118.       }, properties = { floating = true, titlebars_enabled = true, placement = awful.placement.centered, maximized = false } },
  2119.     { rule = { class = "Sakura" },
  2120.        properties = { tag = media_tag, switchtotag = true } },
  2121.     { rule_any = { class = { "qpdfview", "Viewnior", "MComix", "Gimp" } },
  2122.        properties = { titlebars_enabled = true } },
  2123.     { rule = { role = "Popup" },
  2124.        properties = { titlebars_enabled = false } },
  2125.     { rule_any = { class = { "qBittorrent", "Transmission-gtk" } },
  2126.        properties = { tag = web_tag, switchtotag = true, titlebars_enabled = true } },
  2127.     { rule = { role = "browser" },
  2128.        --callback = function (c) naughty.notify({text = c.name}) end,
  2129.        properties = { tag = web_tag, switchtotag = true, floating = false } },
  2130.     { rule = { role = "GtkFileChooserDialog" },
  2131.        properties = { floating = true, placement = awful.placement.centered, titlebars_enabled = true } },
  2132.     { rule = { role = "file_manager" },
  2133.        properties = { tag = files_tag, switchtotag = true, switchtotag = true } },
  2134.     { rule = { name = "Поиск файлов" },
  2135.        properties = { titlebars_enabled = true } },
  2136.     { rule_any = { class = { "X-terminal-emulator", "Lxterminal" } },
  2137.        properties = { tag = misc_tag, switchtotag = true } },
  2138.     { rule_any = { role = { "PictureInPicture", "text_dialog", "task_dialog", "rename_dialog" }, name = { "Просмотр медиа" } },
  2139.        properties = { titlebars_enabled = true, ontop = true, floating = true, maximized = false, sticky = true, placement = awful.placement.centered } },
  2140.     { rule = { class = "XTerm" },
  2141.        properties = { placement = awful.placement.bottom_right, focus = true, ontop = false, floating = true, maximized_horizontal = false, maximized_vertical = false, sticky = true, } },
  2142.     { rule_any = { class = { "mpv", "vlc" } },
  2143.        callback = function(c)
  2144.            awful.spawn.with_shell("mocp -P")
  2145.        end,
  2146.        properties = { titlebars_enabled = true } },
  2147.     { rule = { class = "Onboard" },
  2148.        properties = { titlebars_enabled = false, floating = true, focusable = false, focus = false, ontop = true, sticky = true, } },
  2149.     { rule = { icon_name = "xzoom" },
  2150.        properties = { titlebars_enabled = true, floating = true, focusable = false, focus = false, ontop = true, sticky = true, placement = awful.placement.centered } },
  2151. }
  2152. -- }}}
  2153.  
  2154. -- {{{ Signals
  2155.  
  2156. -- Signal function to execute when a new client appears.
  2157. client.connect_signal("manage", function (c)
  2158.     c.border_color = beautiful.bg_normal
  2159.     -- Set the windows at the slave,
  2160.     -- i.e. put it at the end of others instead of setting it master.
  2161.     -- if not awesome.startup then awful.client.setslave(c) end
  2162.     --awful.client.setslave(c)
  2163.     if awesome.startup and
  2164.       not c.size_hints.user_position
  2165.       and not c.size_hints.program_position then
  2166.         -- Prevent clients from being unreachable after screen count changes.
  2167.         awful.placement.no_offscreen(c)
  2168.     end
  2169. end)
  2170.  
  2171. awful.titlebar.enable_tooltip = false
  2172. -- Add a titlebar if titlebars_enabled is set to true in the rules.
  2173. client.connect_signal("request::titlebars", function(c)
  2174.     local titlebar_right = {
  2175.         awful.titlebar.widget.stickybutton   (c),
  2176.         awful.titlebar.widget.ontopbutton    (c),
  2177.         awful.titlebar.widget.floatingbutton (c),
  2178.         layout = wibox.layout.fixed.horizontal(),
  2179.     }
  2180.     local titlebar_left = {
  2181.         --mykeyboardlayout,
  2182.         awful.titlebar.widget.maximizedbutton(c),
  2183.         awful.titlebar.widget.minimizebutton (c),
  2184.         layout = wibox.layout.fixed.horizontal(),
  2185.     }
  2186.     -- buttons for the titlebar
  2187.     local buttons = gears.table.join(
  2188.         awful.button({ }, 1, function()
  2189.             c:emit_signal("request::activate", "titlebar", {raise = true})
  2190.             awful.mouse.client.move(c)
  2191.         end),
  2192.         awful.button({ }, 3, function()
  2193.             c:emit_signal("request::activate", "titlebar", {raise = true})
  2194.             awful.mouse.client.resize(c)
  2195.         end)
  2196.     )
  2197.  
  2198.     local top_titlebar = awful.titlebar(c, {
  2199.         size            = 4,
  2200.         enable_tooltip  = false,
  2201.         position        = 'top',
  2202.     }) : setup {
  2203.         {
  2204.             {
  2205.                 bg     = c.border_color,
  2206.                 widget = wibox.container.background,
  2207.             },
  2208.             top    = 2,
  2209.             left   = 2,
  2210.             right  = 2,
  2211.             widget = wibox.container.margin
  2212.         },
  2213.  
  2214.         bg     = c.border_color,
  2215.         widget = wibox.container.background,
  2216.     }
  2217.  
  2218.     local bottom_titlebar = awful.titlebar(c, {
  2219.         size            = beautiful.menu_height+15,
  2220.         enable_tooltip  = false,
  2221.         position        = 'bottom',
  2222.     })
  2223.     bottom_titlebar:setup {
  2224.         { -- Left
  2225.             {
  2226.                 {
  2227.                     {
  2228.                         awful.titlebar.widget.closebutton (c),
  2229.                         top = 4, bottom = 4,
  2230.                         widget = wibox.container.margin,
  2231.                     },
  2232.                     layout = wibox.layout.fixed.horizontal,
  2233.                 },
  2234.                 titlebar_left,
  2235.                 layout  = wibox.layout.fixed.horizontal,
  2236.                 spacing = 5,
  2237.             },
  2238.             margins = 10,
  2239.             widget  = wibox.container.margin,
  2240.         },
  2241.         { -- Middle
  2242.             { -- Title
  2243.                 align  = "center",
  2244.                 font   = beautiful.font_name .. " " ..  tostring(math.ceil(0.85*beautiful.base_size)),
  2245.                 widget = awful.titlebar.widget.titlewidget(c),
  2246.             },
  2247.             buttons = buttons,
  2248.             layout  = wibox.layout.flex.horizontal,
  2249.         },
  2250.         { -- Right
  2251.             {
  2252.                 titlebar_right,
  2253.                 --[[{
  2254.                     awful.titlebar.widget.iconwidget(c),
  2255.                     buttons = buttons,
  2256.                     layout  = wibox.layout.fixed.horizontal,
  2257.                 },--]]
  2258.                 layout  = wibox.layout.fixed.horizontal,
  2259.                 spacing = 5,
  2260.             },
  2261.             margins = 10,
  2262.             widget  = wibox.container.margin,
  2263.         },
  2264.         layout = wibox.layout.align.horizontal,
  2265.     }
  2266.  
  2267.     local left_titlebar = awful.titlebar(c, {
  2268.         size            = 4,
  2269.         enable_tooltip  = false,
  2270.         position        = 'left',
  2271.     })
  2272.     left_titlebar:setup {
  2273.         {
  2274.             {
  2275.                 bg     = c.border_color,
  2276.                 widget = wibox.container.background
  2277.             },
  2278.             left   = 2,
  2279.             widget = wibox.container.margin
  2280.         },
  2281.         bg     =  c.border_color,
  2282.         widget = wibox.container.background,
  2283.     }
  2284.  
  2285.     local right_titlebar = awful.titlebar(c, {
  2286.         size            = 4,
  2287.         enable_tooltip  = false,
  2288.         position        = 'right',
  2289.     })
  2290.     right_titlebar:setup {
  2291.         {
  2292.             {
  2293.                 bg     = c.border_color,
  2294.                 widget = wibox.container.background
  2295.             },
  2296.             right  = 2,
  2297.             widget = wibox.container.margin
  2298.         },
  2299.         bg     = c.border_color,
  2300.         widget = wibox.container.background
  2301.     }
  2302. end)
  2303.  
  2304. -- OnSongChange.sh signal
  2305. awesome.connect_signal("music::changed",
  2306.     function()
  2307.         mocp_album_cover:set_image(gears.surface.load_uncached("/home/" .. user .. "/.moc/current_album.png"))
  2308.     end
  2309. )
  2310.  
  2311. awesome.connect_signal("xkb::group_changed",
  2312.     function()
  2313.         mouse.screen.popup_bottomright.visible = true
  2314.         mouse.screen.popup_bottomright_timer:again()
  2315.     end
  2316. )
  2317.  
  2318. client.connect_signal("property::size", function(c)
  2319.     if c.fullscreen then
  2320.         c.shape = gears.shape.rectangle
  2321.     else c.shape = function(cr,w,h) gears.shape.rounded_rect(cr,w,h,beautiful.radius-1) end
  2322.     end
  2323. end
  2324. )
  2325.  
  2326. -- unused
  2327. --[[ Enable sloppy focus, so that focus follows mouse.
  2328. client.connect_signal("mouse::enter", function(c)
  2329.     if awful.layout.get(c.screen) ~= awful.layout.suit.magnifier
  2330.         and awful.client.focus.filter(c) then
  2331.         client.focus = c
  2332.     end
  2333. end)--]]
  2334. --client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end)
  2335. --client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end)
  2336. --[[ hint: focus client under mouse
  2337. tag.connect_signal("property::selected",
  2338.     function (t)
  2339.         local selected = tostring(t.selected) == "true"
  2340.         if selected then
  2341.             local mouseX = mouse.coords().x
  2342.             local mouseY = mouse.coords().y
  2343.             for k,v in pairs(t.screen.all_clients) do
  2344.                 if v.first_tag.index==t.index and mouseX>=v.x and mouseX<=(v.x+v.width) and mouseY>=v.y and mouseY<=(v.y+v.height) then
  2345.                     client.focus = v
  2346.                     v:raise()
  2347.                 end
  2348.             end
  2349.         end
  2350.     end
  2351. )--]]
  2352. --[[client.connect_signal("property::fullscreen", function(c)
  2353.     c.shape = gears.shape.rectangle
  2354. end
  2355. )--]]
  2356. --[[client.connect_signal("property::floating", function (c)
  2357.     if c.floating then
  2358.         awful.titlebar.show(c)
  2359.     else
  2360.         awful.titlebar.hide(c)
  2361.     end
  2362. end
  2363. )--]]
  2364. -- }}}
  2365.  
  2366. -- Autorun
  2367. run_once("/usr/bin/mocp --server")
  2368. run_once(config_dir.."/theme_terminals.sh '" .. string.sub(beautiful.bg_normal,1,7) .. "' '" .. string.sub(beautiful.fg_normal,1,7) .. "'")
  2369. run_once("lxpolkit &")
  2370. --run_once("onboard &")
  2371. --run_once("irexec -d")
  2372.  
Add Comment
Please, Sign In to add comment