My Awesome Config
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1041 lines
41KB

  1. ----< Includes >------------------------------------------------------
  2. --
  3. local gears = require("gears")
  4. local awful = require("awful")
  5. require("awful.autofocus")
  6. -- Widget and layout library
  7. local wibox = require("wibox")
  8. -- Theme handling library
  9. local beautiful = require("beautiful")
  10. -- Notification library
  11. local naughty = require("naughty")
  12. local menubar = require("menubar")
  13. local hotkeys_popup = require("awful.hotkeys_popup").widget
  14. -- Enable VIM help for hotkeys widget when client with matching name is opened:
  15. require("awful.hotkeys_popup.keys.vim")
  16. --FreeDesktop
  17. require('freedesktop.menu')
  18. --require('freedesktop.utils')
  19. freedesktop.utils.icon_theme = 'gnome'
  20. local vicious = require("vicious")
  21. local wi = require("wi")
  22. local autostart = require("autostart")
  23. ----< Variables >-----------------------------------------------------
  24. --
  25. local home = os.getenv("HOME")
  26. local cfgpath = home.."/.config/awesome"
  27. local username = os.getenv("USER")
  28. local terminal = "urxvt +tr +sb"
  29. local editor = os.getenv("EDITOR") or "vim"
  30. local editor_cmd = terminal .. " -e " .. editor
  31. local modkey = "Mod1"
  32. local titlebars_enabled = false
  33. ----< Theme >---------------------------------------------------------
  34. --
  35. beautiful.init(cfgpath.."/themes/zenburn/theme.lua")
  36. -- Naughty
  37. --
  38. naughty.config.defaults.timeout = 5
  39. naughty.config.defaults.screen = 1
  40. naughty.config.defaults.position = "top_right"
  41. naughty.config.defaults.margin = 8
  42. naughty.config.defaults.gap = 1
  43. naughty.config.defaults.ontop = true
  44. naughty.config.defaults.font = "terminus 9"
  45. naughty.config.defaults.icon = nil
  46. naughty.config.defaults.icon_size = 256
  47. naughty.config.defaults.fg = beautiful.fg_tooltip
  48. naughty.config.defaults.bg = beautiful.bg_tooltip
  49. naughty.config.defaults.border_color = beautiful.border_tooltip
  50. naughty.config.defaults.border_width = 2
  51. naughty.config.defaults.hover_timeout = nil
  52. ----< Error handling >------------------------------------------------
  53. if awesome.startup_errors then
  54. naughty.notify({ preset = naughty.config.presets.critical,
  55. title = "Oops, there were errors during startup!",
  56. text = awesome.startup_errors })
  57. end
  58. -- Handle runtime errors after startup
  59. do
  60. local in_error = false
  61. awesome.connect_signal("debug::error", function (err)
  62. -- Make sure we don't go into an endless error loop
  63. if in_error then return end
  64. in_error = true
  65. naughty.notify({ preset = naughty.config.presets.critical,
  66. title = "Oops, an error happened!",
  67. text = tostring(err) })
  68. in_error = false
  69. end)
  70. end
  71. ----< Table of layouts >----------------------------------------------
  72. --
  73. awful.layout.layouts = {
  74. -- awful.layout.suit.floating,
  75. awful.layout.suit.tile,
  76. awful.layout.suit.tile.left,
  77. -- awful.layout.suit.tile.bottom,
  78. -- awful.layout.suit.tile.top,
  79. awful.layout.suit.fair,
  80. -- awful.layout.suit.fair.horizontal,
  81. -- awful.layout.suit.spiral,
  82. -- awful.layout.suit.spiral.dwindle,
  83. awful.layout.suit.max,
  84. -- awful.layout.suit.max.fullscreen,
  85. -- awful.layout.suit.magnifier,
  86. -- awful.layout.suit.corner.nw,
  87. -- awful.layout.suit.corner.ne,
  88. -- awful.layout.suit.corner.sw,
  89. -- awful.layout.suit.corner.se,
  90. }
  91. ----< Helper functions >--------------------------------------------------
  92. --
  93. local function client_menu_toggle_fn()
  94. local instance = nil
  95. return function ()
  96. if instance and instance.wibox.visible then
  97. instance:hide()
  98. instance = nil
  99. else
  100. instance = awful.menu.clients({ theme = { width = 250 } })
  101. end
  102. end
  103. end
  104. ----< Menu >--------------------------------------------------
  105. --
  106. -- Create a launcher widget and a main menu
  107. menu_items = freedesktop.menu.new()
  108. myawesomemenu = {
  109. { "next wall", cfgpath.."/set_wall.sh "..home.."/wallpapers/" },
  110. { "pm-suspend-hybrid", "sudo pm-suspend-hybrid" },
  111. { "pm-hibernate", "sudo pm-hibernate" },
  112. { "lock", "xscreensaver-command --lock" },
  113. { "reboot", "sudo shutdown -r now" },
  114. { "poweroff", "sudo poweroff" },
  115. { "hotkeys", function() return false, hotkeys_popup.show_help end},
  116. { "manual", terminal .. " -e man awesome" },
  117. { "edit config", editor_cmd .. " " .. awesome.conffile },
  118. { "restart", awesome.restart },
  119. { "quit", function() awesome.quit() end}
  120. }
  121. table.insert(menu_items, { "Awesome", myawesomemenu, beautiful.awesome_icon })
  122. mymainmenu = awful.menu({ items = menu_items })
  123. --{ { "awesome", myawesomemenu, beautiful.awesome_icon },
  124. -- { "open terminal", terminal }
  125. -- }
  126. -- })
  127. mylauncher = awful.widget.launcher({ image = beautiful.awesome_icon,
  128. menu = mymainmenu })
  129. -- Menubar configuration
  130. menubar.utils.terminal = terminal -- Set the terminal for applications that require it
  131. -- Keyboard map indicator and switcher
  132. mykeyboardlayout = awful.widget.keyboardlayout()
  133. ----< Widgets >-------------------------------------------------------
  134. --
  135. local spacer = wibox.widget.textbox()
  136. spacer:set_text(' ')
  137. -- Create a wibox for each screen and add it
  138. local myinfowibox = {}
  139. -- My Mail updater widget
  140. function mail_count(filename)
  141. local f = io.open(filename, "r")
  142. local l = nil
  143. if f ~= nil then
  144. l = f:read()
  145. if l == nil then
  146. l = "?"
  147. end
  148. f:close()
  149. else
  150. l = "?"
  151. end
  152. return l
  153. end
  154. local mail_tmp_path = "/tmp/"..username.."-mail_loop"
  155. local mailicon = wibox.widget.imagebox()
  156. mailicon:set_image(beautiful.widget_mailnew)
  157. function mail_on_click()
  158. os.execute ("pgrep thunderbird || thunderbird &")
  159. end
  160. mailicon:buttons(awful.util.table.join(awful.button({ }, 1, mail_on_click)))
  161. local mymail_mail = wibox.widget.textbox( "?" )
  162. gears.timer {
  163. timeout = 20,
  164. autostart = true,
  165. callback = function() mymail_mail:set_text ( mail_count(mail_tmp_path.."/mymail_count") ) end
  166. }
  167. mymail_mail:buttons(mailicon:buttons())
  168. -- local gmail_mail = wibox.widget.textbox( "?" )
  169. -- gears.timer {
  170. -- timeout = 20,
  171. -- autostart = true,
  172. -- callback = function() gmail_mail:set_text ( mail_count(mail_tmp_path.."/gmail_count") ) end
  173. -- }
  174. -- gmail_mail:buttons(mailicon:buttons())
  175. -- nVidia Optimus
  176. local optimus_icon = wibox.widget.imagebox()
  177. local optimus_overclocked = false
  178. optimus_icon:set_image(beautiful.widget_optimus_off)
  179. gears.timer {
  180. timeout = 3,
  181. autostart = true,
  182. callback = function()
  183. local f = io.open("/proc/acpi/bbswitch", "r")
  184. local l = nil
  185. if f ~= nil then
  186. l = f:read()
  187. if string.sub (l, 14) == "ON" then
  188. if optimus_overclocked == true then
  189. optimus_icon:set_image(beautiful.widget_optimus_overclocked)
  190. else
  191. optimus_icon:set_image(beautiful.widget_optimus_on)
  192. end
  193. else
  194. optimus_icon:set_image(beautiful.widget_optimus_off)
  195. optimus_overclocked = false
  196. end
  197. f:close()
  198. else
  199. optimus_icon:set_image(beautiful.widget_optimus_off)
  200. end
  201. end
  202. }
  203. optimus_icon:buttons(awful.util.table.join(
  204. awful.button({ }, 1,
  205. function ()
  206. os.execute ("pgrep nvidia-settings || optirun nvidia-settings -c :8 &")
  207. end
  208. ),
  209. awful.button({ }, 3,
  210. function ()
  211. os.execute ("optirun nvidia-settings -c :8 -a '[gpu:0]/GPUGraphicsClockOffset[2]=135' &")
  212. os.execute ("optirun nvidia-settings -c :8 -a '[gpu:0]/GPUMemoryTransferRateOffset[2]=560' &")
  213. optimus_overclocked = true
  214. end
  215. )
  216. ))
  217. -- Wi-Fi / Ethernet widgets
  218. local net_widget = wibox.widget.textbox()
  219. local icon_net = wibox.widget.imagebox()
  220. icon_net:set_image (beautiful.widget_wired)
  221. local icon_wifi = wibox.widget.imagebox()
  222. icon_wifi:set_image (beautiful.widget_wifi)
  223. -- Network buttons
  224. function show_nload (interface)
  225. os.execute ("pgrep --full --exact 'nload "..interface.."' || urxvt -e nload "..interface.." &")
  226. end
  227. function show_nethogs ()
  228. os.execute ("pgrep nethogs || urxvt -e sudo nethogs &")
  229. end
  230. icon_net:buttons(awful.util.table.join(awful.button({ }, 1, function () show_nload("wan0") end), awful.button({ }, 1, show_nethogs)))
  231. icon_wifi:buttons(awful.util.table.join(awful.button({ }, 1, function () show_nload("wifi0") end), awful.button({ }, 1, show_nethogs)))
  232. net_widget:buttons(awful.util.table.join(awful.button({ }, 1, function () show_nload("") end), awful.button({ }, 1, show_nethogs)))
  233. vicious.register(net_widget, vicious.widgets.net, '<span color="#A3D34D">${wan0 down_mb}</span>^<span color="#DB5786">${wan0 up_mb}</span> <span color="#848484">mb/s</span> <span color="#A3D34D">${wifi0 down_mb}</span>^<span color="#DB5786">${wifi0 up_mb}</span>', 2)
  234. -- VOL icon
  235. vicious.cache(vicious.widgets.volume)
  236. local volicon = wibox.widget.imagebox()
  237. volicon:set_image(beautiful.widget_vol)
  238. volicon:buttons(
  239. awful.util.table.join(
  240. -- awful.button({ }, 1, function () os.execute("pgrep alsamixer || urxvt -e alsamixer --view=all &") end),
  241. awful.button({ }, 1, function () os.execute("pgrep pavucontrol || pavucontrol &") end),
  242. awful.button({ }, 3, function () os.execute("pgrep alsamixer || urxvt -e alsamixer -c 1 &") end),
  243. awful.button({ }, 4, function () os.execute("pgrep -x amixer || amixer set Master 2%+") end),
  244. awful.button({ }, 5, function () os.execute("pgrep -x amixer || amixer set Master 2%-") end)
  245. )
  246. )
  247. volpct = wibox.widget.textbox()
  248. volpct:buttons(volicon:buttons())
  249. vicious.register(volpct, vicious.widgets.volume, "$1% ", nil, "Master")
  250. -- CPU icon
  251. vicious.cache(vicious.widgets.cpu)
  252. function show_htop ()
  253. os.execute ("pgrep htop || urxvt -e htop &")
  254. end
  255. local cpuicon = wibox.widget.imagebox()
  256. cpuicon:set_image(beautiful.widget_cpu)
  257. cpuicon:buttons(awful.util.table.join(awful.button({ }, 1, show_htop)))
  258. cpu = wibox.widget.textbox()
  259. cpu.fit = function (box,w,h)
  260. return 30,0
  261. end
  262. vicious.register(cpu, vicious.widgets.cpu, '<span color="#677ecc"> $1%</span>', 2)
  263. cpu:buttons(cpuicon:buttons())
  264. -- Memory icon
  265. vicious.cache(vicious.widgets.mem)
  266. function show_atop ()
  267. os.execute ("pgrep atop || urxvt -e atop &")
  268. end
  269. local memicon = wibox.widget.imagebox()
  270. memicon:set_image(beautiful.widget_ram)
  271. memicon:buttons(awful.util.table.join(awful.button({ }, 1, show_atop)))
  272. mem = wibox.widget.textbox()
  273. vicious.register(mem, vicious.widgets.mem, '<span color="#639150"> $1/$5% </span>', 2)
  274. mem:buttons(memicon:buttons())
  275. -- Disk icon
  276. vicious.cache(vicious.widgets.fs)
  277. function show_iotop ()
  278. os.execute ("pgrep iotop || urxvt -e sudo iotop --delay=4 &")
  279. end
  280. local diskicon = wibox.widget.imagebox()
  281. diskicon:set_image(beautiful.widget_disk)
  282. diskicon:buttons(awful.util.table.join(awful.button({ }, 1, show_iotop)))
  283. disk = wibox.widget.textbox()
  284. vicious.register(disk, vicious.widgets.fs, '<span color="#cc7c4b">${/home avail_gb}Gb </span>', 15)
  285. disk:buttons(diskicon:buttons())
  286. ----< Wibar >--------------------------------------------------
  287. --
  288. -- Create a textclock widget
  289. mytextclock = wibox.widget.textclock()
  290. mytextclock:buttons(gears.table.join(awful.button({ }, 1,
  291. function () os.execute ("xdg-open https://calendar.google.com/calendar/render?tab=wc#main_7%7Cmonth &") end
  292. )))
  293. -- Create a wibox for each screen and add it
  294. local taglist_buttons = gears.table.join(
  295. awful.button({ }, 1, function(t) t:view_only() end),
  296. awful.button({ modkey }, 1, function(t)
  297. if client.focus then
  298. client.focus:move_to_tag(t)
  299. end
  300. end),
  301. awful.button({ }, 3, awful.tag.viewtoggle),
  302. awful.button({ modkey }, 3, function(t)
  303. if client.focus then
  304. client.focus:toggle_tag(t)
  305. end
  306. end),
  307. awful.button({ }, 4, function(t) awful.tag.viewprev(t.screen) end),
  308. awful.button({ }, 5, function(t) awful.tag.viewnext(t.screen) end)
  309. )
  310. local tasklist_buttons = gears.table.join(
  311. awful.button({ }, 1, function (c)
  312. if c == client.focus then
  313. c.minimized = true
  314. else
  315. -- Without this, the following
  316. -- :isvisible() makes no sense
  317. c.minimized = false
  318. if not c:isvisible() and c.first_tag then
  319. c.first_tag:view_only()
  320. end
  321. -- This will also un-minimize
  322. -- the client, if needed
  323. client.focus = c
  324. c:raise()
  325. end
  326. end),
  327. awful.button({ }, 3, client_menu_toggle_fn()),
  328. awful.button({ }, 4, function ()
  329. awful.client.focus.byidx(-1)
  330. end),
  331. awful.button({ }, 5, function ()
  332. awful.client.focus.byidx(1)
  333. end))
  334. local function set_wallpaper(s)
  335. -- Wallpaper
  336. -- if beautiful.wallpaper then
  337. -- local wallpaper = beautiful.wallpaper
  338. -- -- If wallpaper is a function, call it with the screen
  339. -- if type(wallpaper) == "function" then
  340. -- wallpaper = wallpaper(s)
  341. -- end
  342. -- gears.wallpaper.maximized(wallpaper, s, true)
  343. -- end
  344. gears.wallpaper.maximized(cfgpath.."/wallpaper"..s.index..".slink", s, true)
  345. end
  346. -- Re-set wallpaper when a screen's geometry changes (e.g. different resolution)
  347. screen.connect_signal("property::geometry", set_wallpaper)
  348. awful.screen.connect_for_each_screen(function(s)
  349. -- Wallpaper
  350. set_wallpaper(s)
  351. -- Each screen has its own tag table.
  352. awful.tag({ "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-" }, s, awful.layout.layouts[4])
  353. awful.tag.add("+", {
  354. --icon = "/path/to/icon.png",
  355. layout = awful.layout.suit.fair,
  356. screen = s,
  357. })
  358. -- Create a promptbox for each screen
  359. s.mypromptbox = awful.widget.prompt()
  360. -- Create an imagebox widget which will contains an icon indicating which layout we're using.
  361. -- We need one layoutbox per screen.
  362. s.mylayoutbox = awful.widget.layoutbox(s)
  363. s.mylayoutbox:buttons(gears.table.join(
  364. awful.button({ }, 1, function () awful.layout.inc( 1) end),
  365. awful.button({ }, 3, function () awful.layout.inc(-1) end),
  366. awful.button({ }, 4, function () awful.layout.inc( 1) end),
  367. awful.button({ }, 5, function () awful.layout.inc(-1) end)))
  368. -- Create a taglist widget
  369. s.mytaglist = awful.widget.taglist(s, awful.widget.taglist.filter.all, taglist_buttons)
  370. -- Create a tasklist widget
  371. s.mytasklist = awful.widget.tasklist(s, awful.widget.tasklist.filter.currenttags, tasklist_buttons)
  372. -- Create the wibox
  373. s.mywibox = awful.wibar({ position = "top", screen = s, height = 15.5 })
  374. -- Add widgets to the wibox
  375. s.mywibox:setup {
  376. layout = wibox.layout.align.horizontal,
  377. { -- Left widgets
  378. layout = wibox.layout.fixed.horizontal,
  379. mylauncher,
  380. s.mytaglist,
  381. s.mypromptbox,
  382. },
  383. s.mytasklist, -- Middle widget
  384. { -- Right widgets
  385. layout = wibox.layout.fixed.horizontal,
  386. spacer,
  387. mailicon,
  388. mymail_mail,
  389. -- myslash = wibox.widget.textbox("+")
  390. -- myslash:buttons(mailicon:buttons())
  391. -- right_layout:add(myslash)
  392. -- right_layout:add(gmail_mail)
  393. spacer,
  394. cpuicon,
  395. cpu,
  396. memicon,
  397. mem,
  398. diskicon,
  399. disk,
  400. optimus_icon,
  401. spacer,
  402. baticon,
  403. batpct,
  404. spacer,
  405. icon_net,
  406. net_widget,
  407. icon_wifi,
  408. spacer,
  409. volicon,
  410. volpct,
  411. mykeyboardlayout,
  412. wibox.widget.systray(),
  413. mytextclock,
  414. s.mylayoutbox,
  415. },
  416. }
  417. end)
  418. ----< Mouse bindings >--------------------------------------------------
  419. --
  420. root.buttons(gears.table.join(
  421. awful.button({ }, 3, function () mymainmenu:toggle() end),
  422. awful.button({ }, 4, awful.tag.viewprev),
  423. awful.button({ }, 5, awful.tag.viewnext)
  424. ))
  425. ----< Key bindings >--------------------------------------------------
  426. --
  427. globalkeys = gears.table.join(
  428. awful.key({ modkey, }, "s", hotkeys_popup.show_help,
  429. {description="show help", group="awesome"}),
  430. awful.key({ modkey, }, "[", awful.tag.viewprev,
  431. {description = "view previous", group = "tag"}),
  432. awful.key({ modkey, }, "]", awful.tag.viewnext,
  433. {description = "view next", group = "tag"}),
  434. awful.key({ modkey, }, "Escape", awful.tag.history.restore,
  435. {description = "go back", group = "tag"}),
  436. awful.key({ modkey, }, "k",
  437. function ()
  438. awful.client.focus.byidx( 1)
  439. end,
  440. {description = "focus next by index", group = "client"}
  441. ),
  442. awful.key({ modkey, }, "j",
  443. function ()
  444. awful.client.focus.byidx(-1)
  445. end,
  446. {description = "focus previous by index", group = "client"}
  447. ),
  448. awful.key({ modkey, }, "w", function () mymainmenu:show() end,
  449. {description = "show main menu", group = "awesome"}),
  450. -- Layout manipulation
  451. awful.key({ modkey, "Shift" }, "k", function () awful.client.swap.byidx( 1) end,
  452. {description = "swap with next client by index", group = "client"}),
  453. awful.key({ modkey, "Shift" }, "j", function () awful.client.swap.byidx( -1) end,
  454. {description = "swap with previous client by index", group = "client"}),
  455. awful.key({ modkey, "Control" }, "k", function () awful.screen.focus_relative( 1) end,
  456. {description = "focus the next screen", group = "screen"}),
  457. awful.key({ modkey, "Control" }, "j", function () awful.screen.focus_relative(-1) end,
  458. {description = "focus the previous screen", group = "screen"}),
  459. awful.key({ modkey, }, "u", awful.client.urgent.jumpto,
  460. {description = "jump to urgent client", group = "client"}),
  461. awful.key({ modkey, }, "Tab",
  462. function ()
  463. awful.client.focus.history.previous()
  464. if client.focus then
  465. client.focus:raise()
  466. end
  467. end,
  468. {description = "go back", group = "client"}),
  469. -- Standard program
  470. awful.key({ modkey, }, "Return", function () awful.spawn(terminal) end,
  471. {description = "open a terminal", group = "launcher"}),
  472. awful.key({ modkey, "Control" }, "r", awesome.restart,
  473. {description = "reload awesome", group = "awesome"}),
  474. -- awful.key({ modkey, "Shift" }, "q", awesome.quit,
  475. -- {description = "quit awesome", group = "awesome"}),
  476. awful.key({ modkey, }, "l", function () awful.tag.incmwfact( 0.05) end,
  477. {description = "increase master width factor", group = "layout"}),
  478. awful.key({ modkey, }, "h", function () awful.tag.incmwfact(-0.05) end,
  479. {description = "decrease master width factor", group = "layout"}),
  480. awful.key({ modkey, "Shift" }, "h", function () awful.tag.incnmaster( 1, nil, true) end,
  481. {description = "increase the number of master clients", group = "layout"}),
  482. awful.key({ modkey, "Shift" }, "l", function () awful.tag.incnmaster(-1, nil, true) end,
  483. {description = "decrease the number of master clients", group = "layout"}),
  484. awful.key({ modkey, "Control" }, "h", function () awful.tag.incncol( 1, nil, true) end,
  485. {description = "increase the number of columns", group = "layout"}),
  486. awful.key({ modkey, "Control" }, "l", function () awful.tag.incncol(-1, nil, true) end,
  487. {description = "decrease the number of columns", group = "layout"}),
  488. awful.key({ modkey, }, "space", function () awful.layout.inc( 1) end,
  489. {description = "select next", group = "layout"}),
  490. awful.key({ modkey, "Shift" }, "space", function () awful.layout.inc(-1) end,
  491. {description = "select previous", group = "layout"}),
  492. awful.key({ modkey, "Shift" }, "u", function () awful.client.incwfact( 0.05) end,
  493. {description = "increase the number of rows", group = "layout"}),
  494. awful.key({ modkey, "Shift" }, "p", function () awful.client.incwfact(-0.05) end,
  495. {description = "decrease the number of rows", group = "layout"}),
  496. awful.key({ modkey, "Control" }, "n",
  497. function ()
  498. local c = awful.client.restore()
  499. -- Focus restored client
  500. if c then
  501. client.focus = c
  502. c:raise()
  503. end
  504. end,
  505. {description = "restore minimized", group = "client"}),
  506. -- Prompt
  507. awful.key({ modkey }, "r", function () awful.screen.focused().mypromptbox:run() end,
  508. {description = "run prompt", group = "launcher"}),
  509. awful.key({ modkey }, "x",
  510. function ()
  511. awful.prompt.run {
  512. prompt = "Run Lua code: ",
  513. textbox = awful.screen.focused().mypromptbox.widget,
  514. exe_callback = awful.util.eval,
  515. history_path = awful.util.get_cache_dir() .. "/history_eval"
  516. }
  517. end,
  518. {description = "lua execute prompt", group = "awesome"}),
  519. -- Menubar
  520. awful.key({ modkey }, "p", function() menubar.show() end,
  521. {description = "show the menubar", group = "launcher"}),
  522. -- Volume control --
  523. awful.key({ modkey }, ".", function () os.execute("pgrep -x amixer || amixer set Master 5%+") end, {description = "increase volume by 5%", group = "sound"}),
  524. awful.key({ modkey }, ",", function () os.execute("pgrep -x amixer || amixer set Master 5%-") end, {description = "decrease volume by 5%", group = "sound"}),
  525. awful.key({ modkey }, "/", function () awful.util.spawn("amixer sset Master toggle") end, {description = "mute / unmute", group = "sound"}),
  526. awful.key({ }, "XF86AudioRaiseVolume", function () os.execute("pgrep -x amixer || amixer set Master 5%+") end, {description = "increase volume by 5%", group = "sound"}),
  527. awful.key({ }, "XF86AudioLowerVolume", function () os.execute("pgrep -x amixer || amixer set Master 5%-") end, {description = "decrease volume by 5%", group = "sound"}),
  528. awful.key({ }, "XF86AudioMute", function () awful.util.spawn("amixer sset Master toggle") end, {description = "mute / unmute", group = "sound"}),
  529. -- Player control --
  530. awful.key({ modkey }, "p",function () awful.util.spawn( "mpc play" ); awful.util.spawn( "audacious -p" ) end, {description = "start play", group = "sound"} ),
  531. awful.key({ modkey }, ";",function () awful.util.spawn( "mpc pause" ); awful.util.spawn( "audacious -u" ) end, {description = "pause / play", group = "sound"} ),
  532. awful.key({ modkey }, "'",function () awful.util.spawn( "mpc prev" ); awful.util.spawn( "audacious -r" ) end, {description = "play previous song", group = "sound"} ),
  533. awful.key({ modkey }, "\\",function () awful.util.spawn( "mpc next" ); awful.util.spawn( "audacious -f" ) end, {description = "play next song", group = "sound"} ),
  534. awful.key({ }, "Print", function () awful.util.spawn_with_shell ("DATE=`date +%Y%m%d_%H%M%S`;"..
  535. "xsnap -nogui -file $HOME/screenshots/$DATE && gqview -r $HOME/screenshots/$DATE.png") end, {description = "print screen", group = "screen"}),
  536. -- Lock Screen --
  537. awful.key({ "Mod4" }, "l", function () os.execute ("xscreensaver-command --lock") end, {description = "Lock screen", group = "login"})
  538. )
  539. clientkeys = gears.table.join(
  540. awful.key({ modkey, }, "f",
  541. function (c)
  542. c.fullscreen = not c.fullscreen
  543. c:raise()
  544. end,
  545. {description = "toggle fullscreen", group = "client"}),
  546. awful.key({ modkey, "Shift" }, "c", function (c) c:kill() end,
  547. {description = "close", group = "client"}),
  548. awful.key({ modkey, "Control" }, "space", awful.client.floating.toggle ,
  549. {description = "toggle floating", group = "client"}),
  550. awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end,
  551. {description = "move to master", group = "client"}),
  552. awful.key({ modkey, }, "o", function (c) c:move_to_screen() end,
  553. {description = "move to screen", group = "client"}),
  554. awful.key({ modkey, }, "t", function (c) c.ontop = not c.ontop end,
  555. {description = "toggle keep on top", group = "client"}),
  556. awful.key({ modkey, }, "n",
  557. function (c)
  558. -- The client currently has the input focus, so it cannot be
  559. -- minimized, since minimized clients can't have the focus.
  560. c.minimized = true
  561. end ,
  562. {description = "minimize", group = "client"}),
  563. awful.key({ modkey, }, "m",
  564. function (c)
  565. c.maximized = not c.maximized
  566. c:raise()
  567. end ,
  568. {description = "(un)maximize", group = "client"}),
  569. awful.key({ modkey, "Control" }, "m",
  570. function (c)
  571. c.maximized_vertical = not c.maximized_vertical
  572. c:raise()
  573. end ,
  574. {description = "(un)maximize vertically", group = "client"}),
  575. awful.key({ modkey, "Shift" }, "m",
  576. function (c)
  577. c.maximized_horizontal = not c.maximized_horizontal
  578. c:raise()
  579. end ,
  580. {description = "(un)maximize horizontally", group = "client"})
  581. )
  582. -- Bind all key numbers to tags.
  583. -- Be careful: we use keycodes to make it work on any keyboard layout.
  584. -- This should map on the top row of your keyboard, usually 1 to 9.
  585. for i = 1, 12 do
  586. globalkeys = gears.table.join(globalkeys,
  587. -- View tag only.
  588. awful.key({ modkey }, "#" .. i + 9,
  589. function ()
  590. local screen = awful.screen.focused()
  591. local tag = screen.tags[i]
  592. if tag then
  593. tag:view_only()
  594. end
  595. end,
  596. {description = "view tag #"..i, group = "tag"}),
  597. -- Toggle tag display.
  598. awful.key({ modkey, "Control" }, "#" .. i + 9,
  599. function ()
  600. local screen = awful.screen.focused()
  601. local tag = screen.tags[i]
  602. if tag then
  603. awful.tag.viewtoggle(tag)
  604. end
  605. end,
  606. {description = "toggle tag #" .. i, group = "tag"}),
  607. -- Move client to tag.
  608. awful.key({ modkey, "Shift" }, "#" .. i + 9,
  609. function ()
  610. if client.focus then
  611. local tag = client.focus.screen.tags[i]
  612. if tag then
  613. client.focus:move_to_tag(tag)
  614. end
  615. end
  616. end,
  617. {description = "move focused client to tag #"..i, group = "tag"}),
  618. -- Toggle tag on focused client.
  619. awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9,
  620. function ()
  621. if client.focus then
  622. local tag = client.focus.screen.tags[i]
  623. if tag then
  624. client.focus:toggle_tag(tag)
  625. end
  626. end
  627. end,
  628. {description = "toggle focused client on tag #" .. i, group = "tag"})
  629. )
  630. end
  631. clientbuttons = gears.table.join(
  632. awful.button({ }, 1, function (c) client.focus = c; c:raise() end),
  633. awful.button({ modkey }, 1, awful.mouse.client.move),
  634. awful.button({ modkey }, 3, awful.mouse.client.resize))
  635. -- Set keys
  636. root.keys(globalkeys)
  637. ----< Rules >------------------------------------------------------
  638. -- Rules to apply to new clients (through the "manage" signal).
  639. awful.rules.rules = {
  640. -- All clients will match this rule.
  641. { rule = { },
  642. properties = { border_width = naughty.config.defaults.border_width,
  643. border_color = beautiful.border_normal,
  644. focus = awful.client.focus.filter,
  645. raise = true,
  646. keys = clientkeys,
  647. size_hints_honor = false,
  648. buttons = clientbuttons,
  649. screen = awful.screen.preferred,
  650. placement = awful.placement.no_overlap+awful.placement.no_offscreen
  651. }
  652. },
  653. -- Floating clients.
  654. { rule_any = {
  655. instance = {
  656. "DTA", -- Firefox addon DownThemAll.
  657. "copyq", -- Includes session name in class.
  658. },
  659. class = {
  660. "Arandr",
  661. "Gpick",
  662. "Kruler",
  663. "MessageWin", -- kalarm.
  664. "Sxiv",
  665. "Wpa_gui",
  666. "pinentry",
  667. "veromix",
  668. "xtightvncviewer"},
  669. name = {
  670. "Event Tester", -- xev.
  671. },
  672. role = {
  673. "AlarmWindow", -- Thunderbird's calendar.
  674. "pop-up", -- e.g. Google Chrome's (detached) Developer Tools.
  675. }
  676. }, properties = { floating = true }},
  677. -- Add titlebars to normal clients and dialogs
  678. { rule_any = {type = { "normal", "dialog" }
  679. }, properties = { titlebars_enabled = titlebars_enabled }
  680. },
  681. -- Set Firefox to always map on the tag named "2" on screen 1.
  682. -- { rule = { class = "Firefox" },
  683. -- properties = { screen = 1, tag = "2" } },
  684. { rule = { class = "URxvt" },
  685. properties = { tag = "2" } },
  686. { rule = { class = "Firefox" },
  687. properties = { tag = "1" } },
  688. { rule = { class = "Opera" },
  689. properties = { tag = "1" } },
  690. { rule = { class = "Thunderbird" },
  691. properties = { tag = "1" } },
  692. { rule = { class = "Geary" },
  693. properties = { tag = "1" } },
  694. { rule = { class = "Liferea" },
  695. properties = { tag = "1" } },
  696. { rule = { class = "VirtualBox" },
  697. properties = { tag = "3" } },
  698. { rule = { class = "Remmina" },
  699. properties = { tag = "3" } },
  700. { rule = { class = "Spicy" },
  701. properties = { tag = "3" } },
  702. { rule = { class = "Aqemu" },
  703. properties = { tag = "3" } },
  704. { rule = { name = "Instances - Vimperator" },
  705. properties = { tag = "3" } },
  706. { rule = { name = "VMs - .* - Vimperator" },
  707. properties = { tag = "3" } },
  708. { rule = { name = "noVNC - .* - Vimperator" },
  709. properties = { tag = "3" } },
  710. { rule = { class = "Soffice" },
  711. properties = { tag = "4" } },
  712. { rule = { class = "LibreOffice" },
  713. properties = { tag = "4" } },
  714. { rule = { class = "libreoffice-writer" },
  715. properties = { tag = "4" } },
  716. { rule = { class = "libreoffice-calc" },
  717. properties = { tag = "4" } },
  718. { rule = { class = "libreoffice-draw" },
  719. properties = { tag = "4" } },
  720. { rule = { class = "libreoffice-base" },
  721. properties = { tag = "4" } },
  722. { rule = { class = "libreoffice-math" },
  723. properties = { tag = "4" } },
  724. { rule = { class = "libreoffice-impress" },
  725. properties = { tag = "4" } },
  726. { rule = { class = "libreoffice-startcenter" },
  727. properties = { tag = "4" } },
  728. { rule = { class = "Okular" },
  729. properties = { tag = "4" } },
  730. { rule = { class = "Lyx" },
  731. properties = { tag = "4" } },
  732. { rule = { class = "Evince" },
  733. properties = { tag = "4" } },
  734. { rule = { class = "Qt Jambi application" },
  735. properties = { tag = "1" } },
  736. { rule = { class = "Pidgin" },
  737. properties = { tag = "+" } },
  738. { rule = { class = "Telegram" },
  739. properties = { tag = "+" } },
  740. { rule = { class = "Viber" },
  741. properties = { tag = "+" } },
  742. { rule = { class = "Stardict" },
  743. properties = { tag = "-" } },
  744. { rule = { class = "MPlayer" },
  745. properties = { floating = true } },
  746. { rule = { class = "Texreport-gtk" },
  747. properties = { floating = true } },
  748. { rule = { class = "etr" },
  749. properties = { tag = "6" } },
  750. { rule = { class = "Eboard" },
  751. properties = { tag = "6" } },
  752. { rule = { class = "charleygame-bin" },
  753. properties = { tag = "6" } },
  754. { rule = { class = "lincity-ng" },
  755. properties = { tag = "6" } },
  756. { rule = { class = "Kodi" },
  757. properties = { tag = "6" } },
  758. { rule = { class = "Vlc" },
  759. properties = { tag = "6" } },
  760. { rule = { class = "Audacious" },
  761. properties = { tag = "6" } },
  762. { rule = { class = "Audacity" },
  763. properties = { tag = "6" } },
  764. { rule = { class = "Gimp" },
  765. properties = { tag = "7" } },
  766. { rule = { class = "Blender" },
  767. properties = { tag = "7" } },
  768. { rule = { class = "Anjuta" },
  769. properties = { tag = "5" } },
  770. { rule = { class = "Android SDK Manager" },
  771. properties = { tag = "5" } },
  772. { rule = { class = "DDMS" },
  773. properties = { tag = "5" } },
  774. { rule = { class = "Gucharmap" },
  775. properties = { tag = "5" } },
  776. { rule = { class = "Pcmanfm" },
  777. properties = { tag = "4" } },
  778. { rule = { class = "Fm" },
  779. properties = { tag = "4" } },
  780. { rule = { class = "File-roller" },
  781. properties = { tag = "4" } },
  782. { rule = { class = "Clamtk" },
  783. properties = { tag = "4" } },
  784. { rule = { class = "Assistant" },
  785. properties = { tag = "5" } },
  786. { rule = { class = "Bluefish" },
  787. properties = { tag = "5" } },
  788. { rule = { class = "Designer" },
  789. properties = { tag = "5" } },
  790. { rule = { class = "Glade" },
  791. properties = { tag = "5" } },
  792. { rule = { class = "Geany" },
  793. properties = { tag = "5" } },
  794. { rule = { class = "Gvim" },
  795. properties = { tag = "5" } },
  796. { rule = { class = "Qtcreator" },
  797. properties = { tag = "5" } },
  798. { rule = { class = "Kcachegrind" },
  799. properties = { tag = "5" } },
  800. { rule = { class = "Wxmaxima" },
  801. properties = { tag = "5" } },
  802. { rule = { class = "0ad" },
  803. properties = { tag = "6" } },
  804. { rule = { class = "dosbox" },
  805. properties = { tag = "3" } },
  806. { rule = { class = "Steam" },
  807. properties = { tag = "6" } },
  808. { rule = { class = "supertux" },
  809. properties = { tag = "6" } },
  810. { rule = { name = "Minetest" },
  811. properties = { tag = "6" } },
  812. { rule = { name = "glxgears" },
  813. properties = { tag = "6" } },
  814. { rule = { class = "urbanterror" },
  815. properties = { tag = "6" } },
  816. { rule = { class = "warzone2100" },
  817. properties = { tag = "6" } },
  818. { rule = { class = "xonotic-sdl" },
  819. properties = { tag = "6" } },
  820. { rule = { class = "DarkPlaces" },
  821. properties = { tag = "6" } },
  822. { rule = { class = "Camorama" },
  823. properties = { tag = "6" } },
  824. { rule = { class = "Dia" },
  825. properties = { tag = "7" } },
  826. { rule = { class = "feh" },
  827. properties = { tag = "7" } },
  828. { rule = { class = "FreeCAD" },
  829. properties = { tag = "7" } },
  830. { rule = { class = "Gcolor2" },
  831. properties = { tag = "7" } },
  832. { rule = { class = "GQview" },
  833. properties = { tag = "7" } },
  834. { rule = { class = "Inkscape" },
  835. properties = { tag = "7" } },
  836. { rule = { class = "Shotwell" },
  837. properties = { tag = "7" } },
  838. { rule = { name = "Xdvi" },
  839. properties = { tag = "4" } },
  840. { rule = { class = "Deluge" },
  841. properties = { tag = "1" } },
  842. { rule = { class = "Eiskaltdcpp" },
  843. properties = { tag = "1" } },
  844. { rule = { class = "Ekiga" },
  845. properties = { tag = "+" } },
  846. { rule = { class = "Googleearth-bin" },
  847. properties = { tag = "1" } },
  848. { rule = { class = "Links" },
  849. properties = { tag = "1" } },
  850. { rule = { class = "Linphone" },
  851. properties = { tag = "1" } },
  852. { rule = { class = "psi" },
  853. properties = { tag = "+" } },
  854. { rule = { class = "Transmission" },
  855. properties = { tag = "1" } },
  856. { rule = { class = "Vncviewer" },
  857. properties = { tag = "3" } },
  858. { rule = { class = "Avidemux" },
  859. properties = { tag = "6" } },
  860. { rule = { class = "Xfburn" },
  861. properties = { tag = "6" } },
  862. { rule = { class = "Gtk-recordMyDesktop" },
  863. properties = { tag = "6" } },
  864. { rule = { class = "Qv4l2" },
  865. properties = { tag = "6" } },
  866. { rule = { class = "V4l2ucp" },
  867. properties = { tag = "6" } },
  868. { rule = { class = "TiMidity" },
  869. properties = { tag = "6" } },
  870. { rule = { class = "Gnumeric" },
  871. properties = { tag = "4" } },
  872. { rule = { class = "Yagf" },
  873. properties = { tag = "4" } },
  874. { rule = { class = "Xchm" },
  875. properties = { tag = "4" } },
  876. { rule = { class = "Flash-player-properties" },
  877. properties = { tag = "1" } },
  878. { rule = { class = "Libfm-pref-apps" },
  879. properties = { tag = "4" } },
  880. { rule = { class = "Qtconfig" },
  881. properties = { tag = "5" } },
  882. { rule = { class = "Baobab" },
  883. properties = { tag = "4" } },
  884. { rule = { class = "Gcdemu" },
  885. properties = { tag = "3" } },
  886. { rule = { class = "Wireshark" },
  887. properties = { tag = "1" } },
  888. { rule = { name = "Frozen-.*Bubble" },
  889. properties = { tag = "6" } },
  890. { rule = { class = "d-feet" },
  891. properties = { tag = "5" } },
  892. { rule = { class = "Cinelerra" },
  893. properties = { tag = "6" } },
  894. { rule = { class = "Kdenlive" },
  895. properties = { tag = "6" } },
  896. { rule = { class = "Dconf-editor" },
  897. properties = { tag = "5" } },
  898. }
  899. ----< Signals >------------------------------------------------------
  900. --
  901. -- Signal function to execute when a new client appears.
  902. client.connect_signal("manage", function (c)
  903. -- Set the windows at the slave,
  904. -- i.e. put it at the end of others instead of setting it master.
  905. -- if not awesome.startup then awful.client.setslave(c) end
  906. if awesome.startup and
  907. not c.size_hints.user_position
  908. and not c.size_hints.program_position then
  909. -- Prevent clients from being unreachable after screen count changes.
  910. awful.placement.no_offscreen(c)
  911. end
  912. end)
  913. -- Add a titlebar if titlebars_enabled is set to true in the rules.
  914. client.connect_signal("request::titlebars", function(c)
  915. -- buttons for the titlebar
  916. local buttons = gears.table.join(
  917. awful.button({ }, 1, function()
  918. client.focus = c
  919. c:raise()
  920. awful.mouse.client.move(c)
  921. end),
  922. awful.button({ }, 3, function()
  923. client.focus = c
  924. c:raise()
  925. awful.mouse.client.resize(c)
  926. end)
  927. )
  928. awful.titlebar(c) : setup {
  929. { -- Left
  930. awful.titlebar.widget.iconwidget(c),
  931. buttons = buttons,
  932. layout = wibox.layout.fixed.horizontal
  933. },
  934. { -- Middle
  935. { -- Title
  936. align = "center",
  937. widget = awful.titlebar.widget.titlewidget(c)
  938. },
  939. buttons = buttons,
  940. layout = wibox.layout.flex.horizontal
  941. },
  942. { -- Right
  943. awful.titlebar.widget.floatingbutton (c),
  944. awful.titlebar.widget.maximizedbutton(c),
  945. awful.titlebar.widget.stickybutton (c),
  946. awful.titlebar.widget.ontopbutton (c),
  947. awful.titlebar.widget.closebutton (c),
  948. layout = wibox.layout.fixed.horizontal()
  949. },
  950. layout = wibox.layout.align.horizontal
  951. }
  952. end)
  953. -- Enable sloppy focus, so that focus follows mouse.
  954. client.connect_signal("mouse::enter", function(c)
  955. if awful.layout.get(c.screen) ~= awful.layout.suit.magnifier
  956. and awful.client.focus.filter(c) then
  957. client.focus = c
  958. end
  959. end)
  960. client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end)
  961. client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end)
  962. -- Borders for floating windows
  963. screen.connect_signal("arrange", function(s)
  964. for _, c in pairs(s.clients) do
  965. if c.floating == true then
  966. c.border_width = naughty.config.defaults.border_width
  967. awful.titlebar.show(c)
  968. else
  969. c.border_width = 0
  970. awful.titlebar.hide(c)
  971. end
  972. end
  973. end)