rc.lua 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679
  1. -- {{{ Required libraries
  2. local awesome, client, mouse, screen, tag = awesome, client, mouse, screen, tag
  3. local ipairs, string, os, table, tostring, tonumber, type = ipairs, string, os,
  4. table, tostring,
  5. tonumber, type
  6. -- Standard awesome library
  7. local gears = require("gears") -- Utilities such as color parsing and objects
  8. local awful = require("awful") -- Everything related to window managment
  9. require("awful.autofocus")
  10. -- Widget and layout library
  11. local wibox = require("wibox")
  12. -- Theme handling library
  13. local beautiful = require("beautiful")
  14. -- Notification library
  15. local naughty = require("naughty")
  16. -- Enable hotkeys help widget for VIM and other apps
  17. -- when client with a matching name is opened:
  18. local hotkeys_popup = require("awful.hotkeys_popup")
  19. require("awful.hotkeys_popup.keys")
  20. local my_table = awful.util.table or gears.table
  21. -- Color vars
  22. local c_bg = '#2f4452'
  23. local c_fg = '#cbd0ec'
  24. local c_ter = '#617698'
  25. local c_sec = '#31375a'
  26. local c_pri = '#5c4e90'
  27. -- {{{ Error handling
  28. -- Check if awesome encountered an error during startup and fell back to
  29. -- another config (This code will only ever execute for the fallback config)
  30. if awesome.startup_errors then
  31. naughty.notify({
  32. preset = naughty.config.presets.critical,
  33. title = "Oops, there were errors during startup!",
  34. text = awesome.startup_errors
  35. })
  36. end
  37. -- Handle runtime errors after startup
  38. do
  39. local in_error = false
  40. awesome.connect_signal("debug::error", function(err)
  41. if in_error then return end
  42. in_error = true
  43. naughty.notify({
  44. preset = naughty.config.presets.critical,
  45. title = "Oops, an error happened!",
  46. text = tostring(err)
  47. })
  48. in_error = false
  49. end)
  50. end
  51. -- {{{ Autostart windowless processes
  52. local function run_once(cmd_arr)
  53. for _, cmd in ipairs(cmd_arr) do
  54. awful.spawn.with_shell(string.format(
  55. "pgrep -u $USER -fx '%s' > /dev/null || (%s)",
  56. cmd, cmd))
  57. end
  58. end
  59. run_once({"unclutter -root"}) -- entries must be comma-separated
  60. local chosen_theme = ""
  61. beautiful.init(
  62. string.format(
  63. "%s/.config/awesome/themes/%s/theme.lua",
  64. os.getenv("HOME"), chosen_theme
  65. ))
  66. -- modkey or mod4 = super key
  67. local modkey = "Mod4"
  68. local altkey = "Mod1"
  69. local ctrlKey = "Control"
  70. -- personal variables
  71. -- change these variables if you want
  72. local browser1 = "librewolf"
  73. local browser2 = "firefox"
  74. local browser3 = "brave"
  75. local editor = os.getenv("EDITOR") or "nano"
  76. local editorgui = "codium"
  77. local filemanager = "pcmanfm"
  78. local mailclient = "evolution"
  79. local mediaplayer = "mpv"
  80. local terminal = "alacritty"
  81. local virtualmachine = "virtualbox"
  82. -- awesome variables
  83. awful.util.terminal = terminal
  84. awful.util.tagnames = {
  85. "一", "二", "三", "四", "五", "六", "七", "八", "九", "十"
  86. }
  87. awful.layout.suit.tile.left.mirror = true
  88. awful.layout.layouts = {
  89. awful.layout.suit.tile, awful.layout.suit.floating,
  90. awful.layout.suit.tile.left, awful.layout.suit.tile.bottom,
  91. awful.layout.suit.tile.top,
  92. awful.layout.suit.max,
  93. awful.layout.suit.magnifier
  94. }
  95. -- {{{ Screen
  96. -- Re-set wallpaper when a screen's geometry changes (e.g. different resolution)
  97. screen.connect_signal("property::geometry", function(s)
  98. -- Wallpaper
  99. if beautiful.wallpaper then
  100. local wallpaper = beautiful.wallpaper
  101. -- If wallpaper is a function, call it with the screen
  102. if type(wallpaper) == "function" then wallpaper = wallpaper(s) end
  103. gears.wallpaper.maximized(wallpaper, s, true)
  104. end
  105. end)
  106. -- No borders when rearranging only 1 non-floating or maximized client
  107. screen.connect_signal("arrange", function(s)
  108. local only_one = #s.tiled_clients == 1
  109. for _, c in pairs(s.clients) do
  110. if only_one and not c.floating or c.maximized then
  111. c.border_width = 2
  112. else
  113. c.border_width = beautiful.border_width
  114. end
  115. end
  116. end)
  117. -- Create a wibox for each screen and add it
  118. awful.screen.connect_for_each_screen(
  119. function(s)
  120. beautiful.at_screen_connect(s)
  121. s.systray = wibox.widget.systray()
  122. s.systray.visible = true
  123. end
  124. )
  125. globalkeys = my_table.join(
  126. -- HOTKEYS
  127. awful.key({modkey}, "w",
  128. function()
  129. awful.util.spawn(browser1)
  130. end,
  131. {description = browser1, group = "hotkeys"}),
  132. awful.key({modkey}, "r",
  133. function()
  134. awful.spawn(
  135. string.format(
  136. "dmenu_run -i -l 8 -nb '%s' -nf '%s' -sb '%s' -sf '%s' -fn NotoMonoRegular:bold:pixelsize=14",
  137. c_bg, c_fg, c_pri, c_bg))
  138. end,
  139. {description = "show dmenu", group = "hotkeys"}),
  140. awful.key({modkey}, "x",
  141. function()
  142. awful.util.spawn("suclos")
  143. end,
  144. {description = "exit", group = "hotkeys"}),
  145. awful.key({modkey}, "p",
  146. function()
  147. awful.spawn.with_shell("$HOME/screenshotutil.sh")
  148. end,
  149. {description = "Screenshot", group = "hotkeys"}),
  150. -- SUPER
  151. awful.key({modkey}, "v",
  152. function()
  153. awful.util.spawn("pavucontrol")
  154. end,
  155. {description = "pulseaudio control", group = "super"}),
  156. awful.key({modkey}, "Return",
  157. function()
  158. awful.spawn(terminal)
  159. end,
  160. {description = terminal, group = "super"}),
  161. awful.key({modkey}, "e",
  162. function()
  163. awful.util.spawn(filemanager)
  164. end,
  165. {description = filemanager, group = "super"}),
  166. -- ALT + CTRL
  167. awful.key({ctrlKey, altkey}, "f",
  168. function()
  169. awful.util.spawn(browser2)
  170. end,
  171. {description = browser2, group = "alt+ctrl"}),
  172. awful.key({ctrlKey, altkey}, "g",
  173. function()
  174. awful.util.spawn(browser3)
  175. end,
  176. {description = browser3,group = "alt+ctrl"}),
  177. awful.key({ctrlKey, altkey}, "o",
  178. function()
  179. awful.spawn.with_shell("$HOME/.config/awesome/scripts/picom-toggle.sh")
  180. end,
  181. {description = "Picom toggle", group = "alt+ctrl"}),
  182. -- ALTKEY
  183. awful.key({altkey}, "Left",
  184. function()
  185. awful.util.spawn("variety -p")
  186. end,
  187. {description = "Wallpaper previous", group = "altkey"}),
  188. awful.key({altkey}, "Right",
  189. function()
  190. awful.util.spawn("variety -n")
  191. end,
  192. {description = "Wallpaper next", group = "altkey"}),
  193. awful.key({altkey}, "Up",
  194. function()
  195. awful.util.spawn("variety --pause")
  196. end,
  197. {description = "Wallpaper pause", group = "altkey"}),
  198. awful.key({altkey}, "Down",
  199. function()
  200. awful.util.spawn("variety --resume")
  201. end,
  202. {description = "Wallpaper resume", group = "altkey"}),
  203. -- AWESOME
  204. awful.key({modkey}, "s",
  205. hotkeys_popup.show_help,
  206. {description = "show help",group = "awesome"}),
  207. awful.key({modkey}, "b",
  208. function()
  209. for s in screen do
  210. s.mywibox.visible = not s.mywibox.visible
  211. if s.mybottomwibox then
  212. s.mybottomwibox.visible = not s.mybottomwibox.visible
  213. end
  214. end
  215. end,
  216. {description = "toggle wibox", group = "awesome"}),
  217. awful.key({modkey, "Shift"}, "r",
  218. awesome.restart,
  219. {description = "reload awesome",group = "awesome"}),
  220. awful.key({altkey}, "x",
  221. function()
  222. awful.prompt.run {
  223. prompt = "Run Lua code: ",
  224. textbox = awful.screen.focused().mypromptbox.widget,
  225. exe_callback = awful.util.eval,
  226. history_path = awful.util.get_cache_dir() .. "/history_eval"
  227. }
  228. end,
  229. {description = "lua execute prompt", group = "awesome"}),
  230. -- TAG
  231. awful.key({modkey}, "Left",
  232. awful.tag.viewprev,
  233. {description = "view previous", group = "tag"}),
  234. awful.key({modkey}, "Right",
  235. awful.tag.viewnext,
  236. {description = "view next", group = "tag"}),
  237. awful.key({altkey}, "Tab",
  238. awful.tag.viewnext,
  239. {description = "view next", group = "tag"}),
  240. awful.key({altkey, "Shift"}, "Tab",
  241. awful.tag.viewprev,
  242. {description = "view previous",group = "tag"}),
  243. -- CLIENT
  244. awful.key({altkey}, "j",
  245. function ()
  246. awful.client.focus.byidx( 1)
  247. end,
  248. {description = "focus next by index", group = "client"}),
  249. awful.key({modkey}, "j",
  250. function()
  251. awful.client.focus.global_bydirection("down")
  252. if client.focus then
  253. client.focus:raise()
  254. end
  255. end,
  256. {description = "focus down", group = "client"}),
  257. awful.key({modkey}, "k",
  258. function()
  259. awful.client.focus.global_bydirection("up")
  260. if client.focus then
  261. client.focus:raise()
  262. end
  263. end,
  264. {description = "focus up", group = "client"}),
  265. awful.key({modkey}, "h",
  266. function()
  267. awful.client.focus.global_bydirection("left")
  268. if client.focus then
  269. client.focus:raise()
  270. end
  271. end,
  272. {description = "focus left", group = "client"}),
  273. awful.key({modkey}, "l",
  274. function()
  275. awful.client.focus.global_bydirection("right")
  276. if client.focus then
  277. client.focus:raise()
  278. end
  279. end,
  280. {description = "focus right", group = "client"}),
  281. awful.key({modkey, "Shift"}, "j",
  282. function()
  283. awful.client.swap.byidx(1)
  284. end,
  285. {description = "swap with next client by index", group = "client"}),
  286. awful.key({modkey, "Shift"}, "k",
  287. function()
  288. awful.client.swap.byidx(-1)
  289. end,
  290. {description = "swap with previous client by index", group = "client"}),
  291. awful.key({modkey}, "u",
  292. awful.client.urgent.jumpto,
  293. {description = "jump to urgent client",group = "client"}),
  294. awful.key({ctrlKey}, "Tab",
  295. function()
  296. awful.client.focus.history.previous()
  297. if client.focus then
  298. client.focus:raise()
  299. end
  300. end,
  301. {description = "go back", group = "client"}),
  302. awful.key({modkey, "Control"}, "n",
  303. function()
  304. local c = awful.client.restore()
  305. if c then
  306. client.focus = c
  307. c:raise()
  308. end
  309. end,
  310. {description = "restore minimized", group = "client"}),
  311. -- LAYOUT
  312. awful.key({altkey, "Shift"}, "l",
  313. function()
  314. awful.tag.incmwfact(0.05)
  315. end,
  316. {description = "increase master width factor", group = "layout"}),
  317. awful.key({altkey, "Shift"}, "h",
  318. function()
  319. awful.tag.incmwfact(-0.05)
  320. end,
  321. {description = "decrease master width factor",group = "layout"}),
  322. awful.key({modkey, "Shift"}, "h",
  323. function()
  324. awful.tag.incnmaster(1, nil, true)
  325. end,
  326. {description = "increase the number of master clients",group = "layout"}),
  327. awful.key({modkey, "Shift"}, "l",
  328. function()
  329. awful.tag.incnmaster(-1, nil, true)
  330. end,
  331. {description = "decrease the number of master clients",group = "layout"}),
  332. awful.key({modkey, "Control"}, "h",
  333. function()
  334. awful.tag.incncol(1, nil, true)
  335. end,
  336. {description = "increase the number of columns",group = "layout"}),
  337. awful.key({modkey, "Control"}, "l",
  338. function()
  339. awful.tag.incncol(-1, nil, true)
  340. end,
  341. {description = "decrease the number of columns",group = "layout"}),
  342. awful.key({modkey}, "space",
  343. function()
  344. awful.layout.inc(1)
  345. end,
  346. {description = "select next", group = "layout"}),
  347. -- VOLUME
  348. awful.key({ctrlKey, "Shift"}, "=",
  349. function()
  350. os.execute(string.format("amixer -q set %s 5%%+", beautiful.volume.channel))
  351. beautiful.volume.update()
  352. end,
  353. {description = "Raise volume", group = "Volume"}),
  354. awful.key({ctrlKey, "Shift"}, "-",
  355. function()
  356. os.execute(string.format("amixer -q set %s 5%%-", beautiful.volume.channel))
  357. beautiful.volume.update()
  358. end,
  359. {description = "Lower volume", group = "Volume"}),
  360. awful.key({ctrlKey, "Shift"}, "m",
  361. function()
  362. os.execute(
  363. string.format(
  364. "amixer -q set %s toggle",
  365. beautiful.volume.togglechannel or beautiful.volume.channel))
  366. beautiful.volume.update()
  367. end,
  368. {description = "Mute", group = "Volume"}),
  369. awful.key({ctrlKey, "Shift"}, "p",
  370. function()
  371. os.execute("pacmd set-default-sink 0")
  372. end,
  373. {description = "Sink to speakers", group = "Volume"}),
  374. awful.key({ctrlKey, "Shift"}, "h",
  375. function()
  376. os.execute("pacmd set-default-sink 1")
  377. end,
  378. {description = "Sink to headset", group = "Volume"})
  379. )
  380. clientkeys = my_table.join(
  381. -- HOTKEYS
  382. awful.key({modkey, "Shift"}, "q",
  383. function(c)
  384. c:kill()
  385. end,
  386. {description = "close", group = "hotkeys"}),
  387. -- CLIENT
  388. awful.key({modkey}, "f",
  389. function(c)
  390. c.fullscreen = not c.fullscreen
  391. c:raise()
  392. end,
  393. {description = "toggle fullscreen", group = "client"}),
  394. awful.key({modkey, "Shift"}, "space",
  395. awful.client.floating.toggle,
  396. {description = "toggle floating",group = "client"}),
  397. awful.key({modkey}, "n",
  398. function(c)
  399. c.minimized = true
  400. end,
  401. {description = "minimize", group = "client"}),
  402. awful.key({modkey}, "m",
  403. function(c)
  404. c.maximized = not c.maximized
  405. c:raise()
  406. end,
  407. {description = "maximize", group = "client"})
  408. )
  409. -- Bind all key numbers to tags.
  410. -- Be careful: we use keycodes to make it works on any keyboard layout.
  411. -- This should map on the top row of your keyboard, usually 1 to 9.
  412. for i = 1, 9 do
  413. -- Hack to only show tags 1 and 9 in the shortcut window (mod+s)
  414. local descr_view, descr_toggle, descr_move, descr_toggle_focus
  415. if i == 1 or i == 9 then
  416. descr_view = {description = "view tag #", group = "tag"}
  417. descr_toggle = {description = "toggle tag #", group = "tag"}
  418. descr_move = {
  419. description = "move focused client to tag #",
  420. group = "tag"
  421. }
  422. descr_toggle_focus = {
  423. description = "toggle focused client on tag #",
  424. group = "tag"
  425. }
  426. end
  427. globalkeys = my_table.join(globalkeys,
  428. awful.key({modkey}, "#" .. i + 9,
  429. function()
  430. local screen = awful.screen.focused()
  431. local tag = screen.tags[i]
  432. if tag then
  433. tag:view_only()
  434. end
  435. end,
  436. descr_view),
  437. awful.key({modkey, "Control"}, "#" .. i + 9,
  438. function()
  439. local screen = awful.screen.focused()
  440. local tag = screen.tags[i]
  441. if tag then
  442. awful.tag.viewtoggle(tag)
  443. end
  444. end,
  445. descr_toggle),
  446. awful.key({modkey, "Shift"}, "#" .. i + 9,
  447. function()
  448. if client.focus then
  449. local tag = client.focus.screen.tags[i]
  450. if tag then
  451. client.focus:move_to_tag(tag)
  452. tag:view_only()
  453. end
  454. end
  455. end,
  456. descr_move),
  457. awful.key({modkey, "Control", "Shift"}, "#" .. i + 9,
  458. function()
  459. if client.focus then
  460. local tag = client.focus.screen.tags[i]
  461. if tag then
  462. client.focus:toggle_tag(tag)
  463. end
  464. end
  465. end,
  466. descr_toggle_focus)
  467. )
  468. end
  469. clientbuttons = gears.table.join(
  470. awful.button({}, 1,
  471. function(c)
  472. c:emit_signal("request::activate", "mouse_click", {raise = true})
  473. end),
  474. awful.button({modkey}, 1,
  475. function(c)
  476. c:emit_signal("request::activate", "mouse_click", {raise = true})
  477. awful.mouse.client.move(c)
  478. end),
  479. awful.button({modkey}, 3,
  480. function(c)
  481. c:emit_signal("request::activate", "mouse_click", {raise = true})
  482. awful.mouse.client.resize(c)
  483. end)
  484. )
  485. -- Set keys
  486. root.keys(globalkeys)
  487. -- }}}
  488. -- {{{ Rules
  489. -- Rules to apply to new clients (through the "manage" signal).
  490. awful.rules.rules = {
  491. -- All clients will match this rule.
  492. {
  493. rule = {},
  494. properties = {
  495. border_width = beautiful.border_width,
  496. border_color = beautiful.border_normal,
  497. focus = awful.client.focus.filter,
  498. raise = true,
  499. keys = clientkeys,
  500. buttons = clientbuttons,
  501. screen = awful.screen.preferred,
  502. placement = awful.placement.no_overlap +
  503. awful.placement.no_offscreen,
  504. size_hints_honor = false
  505. }
  506. },
  507. {
  508. rule_any = {type = {"dialog", "normal"}},
  509. properties = {titlebars_enabled = false}
  510. },
  511. {rule = {class = editorgui}, properties = {maximized = true}},
  512. }
  513. -- {{{ Signals
  514. -- Signal function to execute when a new client appears.
  515. client.connect_signal("manage", function(c)
  516. -- Set the windows at the slave,
  517. -- i.e. put it at the end of others instead of setting it master.
  518. -- if not awesome.startup then awful.client.setslave(c) end
  519. if awesome.startup and not c.size_hints.user_position and
  520. not c.size_hints.program_position then
  521. -- Prevent clients from being unreachable after screen count changes.
  522. awful.placement.no_offscreen(c)
  523. end
  524. end)
  525. -- Add a titlebar if titlebars_enabled is set to true in the rules.
  526. client.connect_signal("request::titlebars", function(c)
  527. -- Custom
  528. if beautiful.titlebar_fun then
  529. beautiful.titlebar_fun(c)
  530. return
  531. end
  532. -- Default
  533. -- buttons for the titlebar
  534. local buttons = my_table.join(awful.button({}, 1, function()
  535. c:emit_signal("request::activate", "titlebar", {raise = true})
  536. awful.mouse.client.move(c)
  537. end), awful.button({}, 3, function()
  538. c:emit_signal("request::activate", "titlebar", {raise = true})
  539. awful.mouse.client.resize(c)
  540. end))
  541. awful.titlebar(c, {size = dpi(21)}):setup{
  542. { -- Left
  543. awful.titlebar.widget.iconwidget(c),
  544. buttons = buttons,
  545. layout = wibox.layout.fixed.horizontal
  546. },
  547. { -- Middle
  548. { -- Title
  549. align = "center",
  550. widget = awful.titlebar.widget.titlewidget(c)
  551. },
  552. buttons = buttons,
  553. layout = wibox.layout.flex.horizontal
  554. },
  555. { -- Right
  556. awful.titlebar.widget.floatingbutton(c),
  557. awful.titlebar.widget.maximizedbutton(c),
  558. awful.titlebar.widget.stickybutton(c),
  559. awful.titlebar.widget.ontopbutton(c),
  560. awful.titlebar.widget.closebutton(c),
  561. layout = wibox.layout.fixed.horizontal()
  562. },
  563. layout = wibox.layout.align.horizontal
  564. }
  565. end)
  566. -- Enable sloppy focus, so that focus follows mouse.
  567. client.connect_signal("mouse::enter", function(c)
  568. c:emit_signal("request::activate", "mouse_enter", {raise = false})
  569. end)
  570. client.connect_signal("focus",
  571. function(c) c.border_color = beautiful.border_focus end)
  572. client.connect_signal("unfocus",
  573. function(c) c.border_color = beautiful.border_normal end)
  574. -- }}}
  575. -- Autostart applications
  576. awful.spawn.with_shell("~/.config/awesome/autostart.sh")
  577. awful.spawn.with_shell("picom -b --config $HOME/.config/awesome/picom.conf")