Mirror of Awesome WM window manager
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.

awesomerc.lua 22KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585
  1. -- If LuaRocks is installed, make sure that packages installed through it are
  2. -- found (e.g. lgi). If LuaRocks is not installed, do nothing.
  3. pcall(require, "luarocks.loader")
  4. -- @DOC_REQUIRE_SECTION@
  5. -- Standard awesome library
  6. local gears = require("gears")
  7. local awful = require("awful")
  8. require("awful.autofocus")
  9. -- Widget and layout library
  10. local wibox = require("wibox")
  11. -- Theme handling library
  12. local beautiful = require("beautiful")
  13. -- Notification library
  14. local naughty = require("naughty")
  15. local menubar = require("menubar")
  16. local hotkeys_popup = require("awful.hotkeys_popup")
  17. -- Enable hotkeys help widget for VIM and other apps
  18. -- when client with a matching name is opened:
  19. require("awful.hotkeys_popup.keys")
  20. -- {{{ Error handling
  21. -- Check if awesome encountered an error during startup and fell back to
  22. -- another config (This code will only ever execute for the fallback config)
  23. -- @DOC_ERROR_HANDLING@
  24. naughty.connect_signal("request::display_error", function(message, startup)
  25. naughty.notification {
  26. urgency = "critical",
  27. title = "Oops, an error happened"..(startup and " during startup!" or "!"),
  28. message = message
  29. }
  30. end)
  31. -- }}}
  32. -- {{{ Variable definitions
  33. -- @DOC_LOAD_THEME@
  34. -- Themes define colours, icons, font and wallpapers.
  35. beautiful.init(gears.filesystem.get_themes_dir() .. "default/theme.lua")
  36. -- @DOC_DEFAULT_APPLICATIONS@
  37. -- This is used later as the default terminal and editor to run.
  38. terminal = "xterm"
  39. editor = os.getenv("EDITOR") or "nano"
  40. editor_cmd = terminal .. " -e " .. editor
  41. -- Default modkey.
  42. -- Usually, Mod4 is the key with a logo between Control and Alt.
  43. -- If you do not like this or do not have such a key,
  44. -- I suggest you to remap Mod4 to another key using xmodmap or other tools.
  45. -- However, you can use another modifier like Mod1, but it may interact with others.
  46. modkey = "Mod4"
  47. -- @DOC_LAYOUT@
  48. -- Table of layouts to cover with awful.layout.inc, order matters.
  49. awful.layout.layouts = {
  50. awful.layout.suit.floating,
  51. awful.layout.suit.tile,
  52. awful.layout.suit.tile.left,
  53. awful.layout.suit.tile.bottom,
  54. awful.layout.suit.tile.top,
  55. awful.layout.suit.fair,
  56. awful.layout.suit.fair.horizontal,
  57. awful.layout.suit.spiral,
  58. awful.layout.suit.spiral.dwindle,
  59. awful.layout.suit.max,
  60. awful.layout.suit.max.fullscreen,
  61. awful.layout.suit.magnifier,
  62. awful.layout.suit.corner.nw,
  63. -- awful.layout.suit.corner.ne,
  64. -- awful.layout.suit.corner.sw,
  65. -- awful.layout.suit.corner.se,
  66. }
  67. -- }}}
  68. -- {{{ Menu
  69. -- @DOC_MENU@
  70. -- Create a launcher widget and a main menu
  71. myawesomemenu = {
  72. { "hotkeys", function() hotkeys_popup.show_help(nil, awful.screen.focused()) end },
  73. { "manual", terminal .. " -e man awesome" },
  74. { "edit config", editor_cmd .. " " .. awesome.conffile },
  75. { "restart", awesome.restart },
  76. { "quit", function() awesome.quit() end },
  77. }
  78. mymainmenu = awful.menu({ items = { { "awesome", myawesomemenu, beautiful.awesome_icon },
  79. { "open terminal", terminal }
  80. }
  81. })
  82. mylauncher = awful.widget.launcher({ image = beautiful.awesome_icon,
  83. menu = mymainmenu })
  84. -- Menubar configuration
  85. menubar.utils.terminal = terminal -- Set the terminal for applications that require it
  86. -- }}}
  87. -- Keyboard map indicator and switcher
  88. mykeyboardlayout = awful.widget.keyboardlayout()
  89. -- {{{ Wibar
  90. -- Create a textclock widget
  91. mytextclock = wibox.widget.textclock()
  92. -- Create a wibox for each screen and add it
  93. -- @TAGLIST_BUTTON@
  94. local taglist_buttons = {
  95. awful.button({ }, 1, function(t) t:view_only() end),
  96. awful.button({ modkey }, 1, function(t)
  97. if client.focus then
  98. client.focus:move_to_tag(t)
  99. end
  100. end),
  101. awful.button({ }, 3, awful.tag.viewtoggle),
  102. awful.button({ modkey }, 3, function(t)
  103. if client.focus then
  104. client.focus:toggle_tag(t)
  105. end
  106. end),
  107. awful.button({ }, 4, function(t) awful.tag.viewnext(t.screen) end),
  108. awful.button({ }, 5, function(t) awful.tag.viewprev(t.screen) end),
  109. }
  110. -- @TASKLIST_BUTTON@
  111. local tasklist_buttons = {
  112. awful.button({ }, 1, function (c)
  113. if c == client.focus then
  114. c.minimized = true
  115. else
  116. c:emit_signal(
  117. "request::activate",
  118. "tasklist",
  119. {raise = true}
  120. )
  121. end
  122. end),
  123. awful.button({ }, 3, function()
  124. awful.menu.client_list({ theme = { width = 250 } })
  125. end),
  126. awful.button({ }, 4, function ()
  127. awful.client.focus.byidx(1)
  128. end),
  129. awful.button({ }, 5, function ()
  130. awful.client.focus.byidx(-1)
  131. end),
  132. }
  133. -- @DOC_WALLPAPER@
  134. screen.connect_signal("request::wallpaper", function(s)
  135. -- Wallpaper
  136. if beautiful.wallpaper then
  137. local wallpaper = beautiful.wallpaper
  138. -- If wallpaper is a function, call it with the screen
  139. if type(wallpaper) == "function" then
  140. wallpaper = wallpaper(s)
  141. end
  142. gears.wallpaper.maximized(wallpaper, s, true)
  143. end
  144. end)
  145. -- @DOC_FOR_EACH_SCREEN@
  146. screen.connect_signal("request::desktop_decoration", function(s)
  147. -- Each screen has its own tag table.
  148. awful.tag({ "1", "2", "3", "4", "5", "6", "7", "8", "9" }, s, awful.layout.layouts[1])
  149. -- Create a promptbox for each screen
  150. s.mypromptbox = awful.widget.prompt()
  151. -- Create an imagebox widget which will contain an icon indicating which layout we're using.
  152. -- We need one layoutbox per screen.
  153. s.mylayoutbox = awful.widget.layoutbox {
  154. screen = s,
  155. buttons = {
  156. awful.button({ }, 1, function () awful.layout.inc( 1) end),
  157. awful.button({ }, 3, function () awful.layout.inc(-1) end),
  158. awful.button({ }, 4, function () awful.layout.inc( 1) end),
  159. awful.button({ }, 5, function () awful.layout.inc(-1) end),
  160. }
  161. }
  162. -- Create a taglist widget
  163. s.mytaglist = awful.widget.taglist {
  164. screen = s,
  165. filter = awful.widget.taglist.filter.all,
  166. buttons = taglist_buttons
  167. }
  168. -- Create a tasklist widget
  169. s.mytasklist = awful.widget.tasklist {
  170. screen = s,
  171. filter = awful.widget.tasklist.filter.currenttags,
  172. buttons = tasklist_buttons
  173. }
  174. -- @DOC_WIBAR@
  175. -- Create the wibox
  176. s.mywibox = awful.wibar({ position = "top", screen = s })
  177. -- @DOC_SETUP_WIDGETS@
  178. -- Add widgets to the wibox
  179. s.mywibox.widget = {
  180. layout = wibox.layout.align.horizontal,
  181. { -- Left widgets
  182. layout = wibox.layout.fixed.horizontal,
  183. mylauncher,
  184. s.mytaglist,
  185. s.mypromptbox,
  186. },
  187. s.mytasklist, -- Middle widget
  188. { -- Right widgets
  189. layout = wibox.layout.fixed.horizontal,
  190. mykeyboardlayout,
  191. wibox.widget.systray(),
  192. mytextclock,
  193. s.mylayoutbox,
  194. },
  195. }
  196. end)
  197. -- }}}
  198. -- {{{ Mouse bindings
  199. -- @DOC_ROOT_BUTTONS@
  200. awful.mouse.append_global_mousebindings({
  201. awful.button({ }, 3, function () mymainmenu:toggle() end),
  202. awful.button({ }, 4, awful.tag.viewnext),
  203. awful.button({ }, 5, awful.tag.viewprev),
  204. })
  205. -- }}}
  206. -- {{{ Key bindings
  207. -- @DOC_GLOBAL_KEYBINDINGS@
  208. -- General Awesome keys
  209. awful.keyboard.append_global_keybindings({
  210. awful.key({ modkey, }, "s", hotkeys_popup.show_help,
  211. {description="show help", group="awesome"}),
  212. awful.key({ modkey, }, "w", function () mymainmenu:show() end,
  213. {description = "show main menu", group = "awesome"}),
  214. awful.key({ modkey, "Control" }, "r", awesome.restart,
  215. {description = "reload awesome", group = "awesome"}),
  216. awful.key({ modkey, "Shift" }, "q", awesome.quit,
  217. {description = "quit awesome", group = "awesome"}),
  218. awful.key({ modkey }, "x",
  219. function ()
  220. awful.prompt.run {
  221. prompt = "Run Lua code: ",
  222. textbox = awful.screen.focused().mypromptbox.widget,
  223. exe_callback = awful.util.eval,
  224. history_path = awful.util.get_cache_dir() .. "/history_eval"
  225. }
  226. end,
  227. {description = "lua execute prompt", group = "awesome"}),
  228. awful.key({ modkey, }, "Return", function () awful.spawn(terminal) end,
  229. {description = "open a terminal", group = "launcher"}),
  230. awful.key({ modkey }, "r", function () awful.screen.focused().mypromptbox:run() end,
  231. {description = "run prompt", group = "launcher"}),
  232. awful.key({ modkey }, "p", function() menubar.show() end,
  233. {description = "show the menubar", group = "launcher"}),
  234. })
  235. -- Tags related keybindings
  236. awful.keyboard.append_global_keybindings({
  237. awful.key({ modkey, }, "Left", awful.tag.viewprev,
  238. {description = "view previous", group = "tag"}),
  239. awful.key({ modkey, }, "Right", awful.tag.viewnext,
  240. {description = "view next", group = "tag"}),
  241. awful.key({ modkey, }, "Escape", awful.tag.history.restore,
  242. {description = "go back", group = "tag"}),
  243. })
  244. -- Focus related keybindings
  245. awful.keyboard.append_global_keybindings({
  246. awful.key({ modkey, }, "j",
  247. function ()
  248. awful.client.focus.byidx( 1)
  249. end,
  250. {description = "focus next by index", group = "client"}
  251. ),
  252. awful.key({ modkey, }, "k",
  253. function ()
  254. awful.client.focus.byidx(-1)
  255. end,
  256. {description = "focus previous by index", group = "client"}
  257. ),
  258. awful.key({ modkey, }, "Tab",
  259. function ()
  260. awful.client.focus.history.previous()
  261. if client.focus then
  262. client.focus:raise()
  263. end
  264. end,
  265. {description = "go back", group = "client"}),
  266. awful.key({ modkey, "Control" }, "j", function () awful.screen.focus_relative( 1) end,
  267. {description = "focus the next screen", group = "screen"}),
  268. awful.key({ modkey, "Control" }, "k", function () awful.screen.focus_relative(-1) end,
  269. {description = "focus the previous screen", group = "screen"}),
  270. awful.key({ modkey, "Control" }, "n",
  271. function ()
  272. local c = awful.client.restore()
  273. -- Focus restored client
  274. if c then
  275. c:emit_signal(
  276. "request::activate", "key.unminimize", {raise = true}
  277. )
  278. end
  279. end,
  280. {description = "restore minimized", group = "client"}),
  281. })
  282. -- Layout related keybindings
  283. awful.keyboard.append_global_keybindings({
  284. awful.key({ modkey, "Shift" }, "j", function () awful.client.swap.byidx( 1) end,
  285. {description = "swap with next client by index", group = "client"}),
  286. awful.key({ modkey, "Shift" }, "k", function () awful.client.swap.byidx( -1) end,
  287. {description = "swap with previous client by index", group = "client"}),
  288. awful.key({ modkey, }, "u", awful.client.urgent.jumpto,
  289. {description = "jump to urgent client", group = "client"}),
  290. awful.key({ modkey, }, "l", function () awful.tag.incmwfact( 0.05) end,
  291. {description = "increase master width factor", group = "layout"}),
  292. awful.key({ modkey, }, "h", function () awful.tag.incmwfact(-0.05) end,
  293. {description = "decrease master width factor", group = "layout"}),
  294. awful.key({ modkey, "Shift" }, "h", function () awful.tag.incnmaster( 1, nil, true) end,
  295. {description = "increase the number of master clients", group = "layout"}),
  296. awful.key({ modkey, "Shift" }, "l", function () awful.tag.incnmaster(-1, nil, true) end,
  297. {description = "decrease the number of master clients", group = "layout"}),
  298. awful.key({ modkey, "Control" }, "h", function () awful.tag.incncol( 1, nil, true) end,
  299. {description = "increase the number of columns", group = "layout"}),
  300. awful.key({ modkey, "Control" }, "l", function () awful.tag.incncol(-1, nil, true) end,
  301. {description = "decrease the number of columns", group = "layout"}),
  302. awful.key({ modkey, }, "space", function () awful.layout.inc( 1) end,
  303. {description = "select next", group = "layout"}),
  304. awful.key({ modkey, "Shift" }, "space", function () awful.layout.inc(-1) end,
  305. {description = "select previous", group = "layout"}),
  306. })
  307. -- @DOC_CLIENT_KEYBINDINGS@
  308. clientkeys = {
  309. awful.key({ modkey, }, "f",
  310. function (c)
  311. c.fullscreen = not c.fullscreen
  312. c:raise()
  313. end,
  314. {description = "toggle fullscreen", group = "client"}),
  315. awful.key({ modkey, "Shift" }, "c", function (c) c:kill() end,
  316. {description = "close", group = "client"}),
  317. awful.key({ modkey, "Control" }, "space", awful.client.floating.toggle ,
  318. {description = "toggle floating", group = "client"}),
  319. awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end,
  320. {description = "move to master", group = "client"}),
  321. awful.key({ modkey, }, "o", function (c) c:move_to_screen() end,
  322. {description = "move to screen", group = "client"}),
  323. awful.key({ modkey, }, "t", function (c) c.ontop = not c.ontop end,
  324. {description = "toggle keep on top", group = "client"}),
  325. awful.key({ modkey, }, "n",
  326. function (c)
  327. -- The client currently has the input focus, so it cannot be
  328. -- minimized, since minimized clients can't have the focus.
  329. c.minimized = true
  330. end ,
  331. {description = "minimize", group = "client"}),
  332. awful.key({ modkey, }, "m",
  333. function (c)
  334. c.maximized = not c.maximized
  335. c:raise()
  336. end ,
  337. {description = "(un)maximize", group = "client"}),
  338. awful.key({ modkey, "Control" }, "m",
  339. function (c)
  340. c.maximized_vertical = not c.maximized_vertical
  341. c:raise()
  342. end ,
  343. {description = "(un)maximize vertically", group = "client"}),
  344. awful.key({ modkey, "Shift" }, "m",
  345. function (c)
  346. c.maximized_horizontal = not c.maximized_horizontal
  347. c:raise()
  348. end ,
  349. {description = "(un)maximize horizontally", group = "client"}),
  350. }
  351. -- @DOC_NUMBER_KEYBINDINGS@
  352. -- Bind all key numbers to tags.
  353. -- Be careful: we use keycodes to make it work on any keyboard layout.
  354. -- This should map on the top row of your keyboard, usually 1 to 9.
  355. for i = 1, 9 do
  356. -- View tag only.
  357. awful.keyboard.append_global_keybinding(awful.key(
  358. { modkey }, "#" .. i + 9,
  359. function ()
  360. local screen = awful.screen.focused()
  361. local tag = screen.tags[i]
  362. if tag then
  363. tag:view_only()
  364. end
  365. end,
  366. {description = "view tag #"..i, group = "tag"}
  367. ))
  368. -- Toggle tag display.
  369. awful.keyboard.append_global_keybinding(awful.key(
  370. { modkey, "Control" }, "#" .. i + 9,
  371. function ()
  372. local screen = awful.screen.focused()
  373. local tag = screen.tags[i]
  374. if tag then
  375. awful.tag.viewtoggle(tag)
  376. end
  377. end,
  378. {description = "toggle tag #" .. i, group = "tag"}
  379. ))
  380. -- Move client to tag.
  381. awful.keyboard.append_global_keybinding(awful.key(
  382. { modkey, "Shift" }, "#" .. i + 9,
  383. function ()
  384. if client.focus then
  385. local tag = client.focus.screen.tags[i]
  386. if tag then
  387. client.focus:move_to_tag(tag)
  388. end
  389. end
  390. end,
  391. {description = "move focused client to tag #"..i, group = "tag"}
  392. ))
  393. -- Toggle tag on focused client.
  394. awful.keyboard.append_global_keybinding(awful.key(
  395. { modkey, "Control", "Shift" }, "#" .. i + 9,
  396. function ()
  397. if client.focus then
  398. local tag = client.focus.screen.tags[i]
  399. if tag then
  400. client.focus:toggle_tag(tag)
  401. end
  402. end
  403. end,
  404. {description = "toggle focused client on tag #" .. i, group = "tag"}
  405. ))
  406. end
  407. -- @DOC_CLIENT_BUTTONS@
  408. clientbuttons = {
  409. awful.button({ }, 1, function (c)
  410. c:emit_signal("request::activate", "mouse_click", {raise = true})
  411. end),
  412. awful.button({ modkey }, 1, function (c)
  413. c:emit_signal("request::activate", "mouse_click", {raise = true})
  414. awful.mouse.client.move(c)
  415. end),
  416. awful.button({ modkey }, 3, function (c)
  417. c:emit_signal("request::activate", "mouse_click", {raise = true})
  418. awful.mouse.client.resize(c)
  419. end),
  420. }
  421. -- }}}
  422. -- {{{ Rules
  423. -- Rules to apply to new clients (through the "manage" signal).
  424. -- @DOC_RULES@
  425. awful.rules.rules = {
  426. -- @DOC_GLOBAL_RULE@
  427. -- All clients will match this rule.
  428. { rule = { },
  429. properties = { border_width = beautiful.border_width,
  430. border_color = beautiful.border_normal,
  431. focus = awful.client.focus.filter,
  432. raise = true,
  433. keys = clientkeys,
  434. buttons = clientbuttons,
  435. screen = awful.screen.preferred,
  436. placement = awful.placement.no_overlap+awful.placement.no_offscreen
  437. }
  438. },
  439. -- @DOC_FLOATING_RULE@
  440. -- Floating clients.
  441. { rule_any = {
  442. instance = {
  443. "DTA", -- Firefox addon DownThemAll.
  444. "copyq", -- Includes session name in class.
  445. "pinentry",
  446. },
  447. class = {
  448. "Arandr",
  449. "Blueman-manager",
  450. "Gpick",
  451. "Kruler",
  452. "MessageWin", -- kalarm.
  453. "Sxiv",
  454. "Tor Browser", -- Needs a fixed window size to avoid fingerprinting by screen size.
  455. "Wpa_gui",
  456. "veromix",
  457. "xtightvncviewer"},
  458. -- Note that the name property shown in xprop might be set slightly after creation of the client
  459. -- and the name shown there might not match defined rules here.
  460. name = {
  461. "Event Tester", -- xev.
  462. },
  463. role = {
  464. "AlarmWindow", -- Thunderbird's calendar.
  465. "ConfigManager", -- Thunderbird's about:config.
  466. "pop-up", -- e.g. Google Chrome's (detached) Developer Tools.
  467. }
  468. }, properties = { floating = true }},
  469. -- @DOC_DIALOG_RULE@
  470. -- Add titlebars to normal clients and dialogs
  471. { rule_any = {type = { "normal", "dialog" }
  472. -- @DOC_CSD_TITLEBARS@
  473. }, properties = { titlebars_enabled = true }
  474. },
  475. -- Set Firefox to always map on the tag named "2" on screen 1.
  476. -- { rule = { class = "Firefox" },
  477. -- properties = { screen = 1, tag = "2" } },
  478. }
  479. -- }}}
  480. -- {{{ Signals
  481. -- Signal function to execute when a new client appears.
  482. -- @DOC_MANAGE_HOOK@
  483. client.connect_signal("manage", function (c)
  484. -- Set the windows at the slave,
  485. -- i.e. put it at the end of others instead of setting it master.
  486. -- if not awesome.startup then awful.client.setslave(c) end
  487. if awesome.startup
  488. and not c.size_hints.user_position
  489. and not c.size_hints.program_position then
  490. -- Prevent clients from being unreachable after screen count changes.
  491. awful.placement.no_offscreen(c)
  492. end
  493. end)
  494. -- @DOC_TITLEBARS@
  495. -- Add a titlebar if titlebars_enabled is set to true in the rules.
  496. client.connect_signal("request::titlebars", function(c)
  497. -- buttons for the titlebar
  498. local buttons = {
  499. awful.button({ }, 1, function()
  500. c:emit_signal("request::activate", "titlebar", {raise = true})
  501. awful.mouse.client.move(c)
  502. end),
  503. awful.button({ }, 3, function()
  504. c:emit_signal("request::activate", "titlebar", {raise = true})
  505. awful.mouse.client.resize(c)
  506. end),
  507. }
  508. awful.titlebar(c).widget = {
  509. { -- Left
  510. awful.titlebar.widget.iconwidget(c),
  511. buttons = buttons,
  512. layout = wibox.layout.fixed.horizontal
  513. },
  514. { -- Middle
  515. { -- Title
  516. align = "center",
  517. widget = awful.titlebar.widget.titlewidget(c)
  518. },
  519. buttons = buttons,
  520. layout = wibox.layout.flex.horizontal
  521. },
  522. { -- Right
  523. awful.titlebar.widget.floatingbutton (c),
  524. awful.titlebar.widget.maximizedbutton(c),
  525. awful.titlebar.widget.stickybutton (c),
  526. awful.titlebar.widget.ontopbutton (c),
  527. awful.titlebar.widget.closebutton (c),
  528. layout = wibox.layout.fixed.horizontal()
  529. },
  530. layout = wibox.layout.align.horizontal
  531. }
  532. end)
  533. -- Enable sloppy focus, so that focus follows mouse.
  534. client.connect_signal("mouse::enter", function(c)
  535. c:emit_signal("request::activate", "mouse_enter", {raise = false})
  536. end)
  537. -- @DOC_BORDER@
  538. client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end)
  539. client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end)
  540. -- }}}