rc.lua 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209
  1. --[[
  2. Awesome WM Configuration 1.1
  3. Distopico Vegan <distopico [at] riseup [dot] net>
  4. Licensed under GPL3
  5. --]]
  6. -- Standard awesome library
  7. local gears = require("gears")
  8. local awful = require("awful")
  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").widget
  17. -- Aditional libraries
  18. local cyclefocus = require("libs/cyclefocus")
  19. -- Custom widgets
  20. local myvolume = require("widgets/volume")
  21. local mybrightness = require("widgets/brightness")
  22. local mybattery = require("widgets/battery")
  23. local mywifi = require("widgets/wifi")
  24. local mycpufreq = require("widgets/cpufreq")
  25. require("awful.autofocus")
  26. -- {{{ Error handling
  27. -- Check if awesome encountered an error during startup and fell back to
  28. -- another config (This code will only ever execute for the fallback config)
  29. if awesome.startup_errors then
  30. naughty.notify({ preset = naughty.config.presets.critical,
  31. title = "Oops, there were errors during startup!",
  32. text = awesome.startup_errors })
  33. end
  34. -- Handle runtime errors after startup
  35. do
  36. local in_error = false
  37. awesome.connect_signal(
  38. "debug::error", function (err)
  39. -- Make sure we don't go into an endless error loop
  40. if in_error then return end
  41. in_error = true
  42. naughty.notify({ preset = naughty.config.presets.critical,
  43. title = "Oops, an error happened!",
  44. text = tostring(err) })
  45. in_error = false
  46. end)
  47. end
  48. -- }}}
  49. -- {{{ Variable definitions
  50. sloppy_focus = false
  51. notify_suspended = false
  52. --Configure home path so you dont have too
  53. home_path = os.getenv("HOME") .. "/"
  54. config_path = home_path .. ".config/awesome/"
  55. -- Themes define colours, icons, font and wallpapers.
  56. beautiful.init(config_path .. "theme/theme.lua")
  57. -- This is used later as the default terminal and editor to run.
  58. terminal = "urxvtc" or "urxvt" or "terminator" or "gnome-terminal" or "xterm"
  59. editor = os.getenv("EDITOR") or "nano" or "emacs"
  60. editor_cmd = terminal .. " -e " .. editor
  61. -- user defined
  62. browser = "iceweasel"
  63. browser2 = "firefox"
  64. graphics = "gimp"
  65. musicplr = terminal .. " -e ncmpcpp "
  66. -- Default modkey.
  67. -- Usually, Mod4 is the key with a logo between Control and Alt.
  68. -- If you do not like this or do not have such a key,
  69. -- I suggest you to remap Mod4 to another key using xmodmap or other tools.
  70. -- However, you can use another modifier like Mod1, but it may interact with others.
  71. modkey = "Mod4"
  72. altkey = "Mod1"
  73. local dbus_login = "dbus-send --system --print-reply --dest=org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager."
  74. local screenshot_sound = config_path .. "theme/sounds/camera-shutter.oga"
  75. local screenshot_dir = home_path .. "Pictures/Screenshots/"
  76. -- {{{ Helper functions
  77. local function initial_setup()
  78. if not gears.filesystem.is_dir(screenshot_dir) then
  79. gears.filesystem.make_directories(screenshot_dir)
  80. end
  81. end
  82. local function client_menu_toggle ()
  83. local instance = nil
  84. return function ()
  85. if instance and instance.wibox.visible then
  86. instance:hide()
  87. instance = nil
  88. else
  89. instance = awful.menu.clients({ theme = { width = 250 } })
  90. end
  91. end
  92. end
  93. local function client_set_border(c)
  94. -- Fix inconsistent border behaviour when maximizing/fullscreen clients
  95. if c.fullscreen then
  96. c.border_width = 0
  97. elseif c.border_width == 0 and not c.no_border then
  98. c.border_width = beautiful.border_width
  99. end
  100. end
  101. local function client_resize (key, c)
  102. if c == nil then
  103. c = client.focus
  104. end
  105. if c.floating then
  106. if key == "Up" then c:relative_move(0, 0, 0, -5)
  107. elseif key == "Down" then c:relative_move(0, 0, 0, 5)
  108. elseif key == "Right" then c:relative_move(0, 0, 5, 0)
  109. elseif key == "Left" then c:relative_move(0, 0, -5, 0)
  110. elseif key == "Next" then c:relative_move( 20, 20, -40, -40)
  111. elseif key == "Prior" then c:relative_move(-20, -20, 40, 40)
  112. else
  113. return false
  114. end
  115. else
  116. if key == "Up" then awful.client.incwfact(-0.05)
  117. elseif key == "Down" then awful.client.incwfact(0.05)
  118. elseif key == "Right" then awful.tag.incmwfact(0.05)
  119. elseif key == "Left" then awful.tag.incmwfact(-0.05)
  120. else
  121. return false
  122. end
  123. end
  124. return true
  125. end
  126. local function tag_view_nonempty (direction, screen)
  127. -- Non-empty tag browsing from lain
  128. -- direction in {-1, 1} <-> {previous, next} non-empty tag
  129. local s = screen or awful.screen.focused()
  130. for i = 1, #s.tags do
  131. awful.tag.viewidx(direction, s)
  132. if #s.clients > 0 then
  133. return
  134. end
  135. end
  136. end
  137. function unless_gap_resize(size, screen, tag)
  138. local s = screen or awful.screen.focused()
  139. local t = tag or s.selected_tag
  140. if size == 0 then
  141. t.gap = beautiful.useless_gap
  142. else
  143. t.gap = t.gap + tonumber(size)
  144. end
  145. awful.layout.arrange(s)
  146. end
  147. local function notify_callback (args)
  148. if args.freedesktop_hints ~= nil and args.freedesktop_hints.urgency == "\2" then
  149. args.ignore_suspend = true
  150. end
  151. for _, c in pairs(awful.screen.object.get_clients()) do
  152. if c.fullscreen then
  153. if not naughty.is_suspended() then
  154. naughty.suspend()
  155. end
  156. return
  157. end
  158. end
  159. if naughty.is_suspended() and not notify_suspended then
  160. naughty.resume()
  161. end
  162. return args
  163. end
  164. local function system_lock ()
  165. awful.spawn("loginctl lock-session")
  166. end
  167. local function system_suspend ()
  168. awful.spawn(dbus_login .. "Suspend boolean:true")
  169. end
  170. local function system_hibernate ()
  171. awful.prompt.run {
  172. prompt = "Hibernate (type 'yes' to confirm)? ",
  173. textbox = awful.screen.focused().mypromptbox.widget,
  174. exe_callback = function (t)
  175. if string.lower(t) == "yes" then
  176. awful.spawn(dbus_login .. "Hibernate boolean:true")
  177. end
  178. end,
  179. completion_callback = function (t, p, n)
  180. return awful.completion.generic(t, p, n, {"no", "NO", "yes", "YES"})
  181. end
  182. }
  183. end
  184. local function system_hybrid_sleep ()
  185. awful.prompt.run {
  186. prompt = "Hybrid Sleep (type 'yes' to confirm)? ",
  187. textbox = awful.screen.focused().mypromptbox.widget,
  188. exe_callback = function (t)
  189. if string.lower(t) == "yes" then
  190. awful.spawn(dbus_login .. "HybridSleep boolean:true")
  191. end
  192. end,
  193. completion_callback = function (t, p, n)
  194. return awful.completion.generic(t, p, n, {"no", "NO", "yes", "YES"})
  195. end
  196. }
  197. end
  198. local function system_reboot ()
  199. awful.prompt.run {
  200. prompt = "Reboot (type 'yes' to confirm)? ",
  201. textbox = awful.screen.focused().mypromptbox.widget,
  202. exe_callback = function (t)
  203. if string.lower(t) == "yes" then
  204. awesome.emit_signal("exit", nil)
  205. awful.spawn(dbus_login .. "Reboot boolean:true")
  206. end
  207. end,
  208. completion_callback = function (t, p, n)
  209. return awful.completion.generic(t, p, n, {"no", "NO", "yes", "YES"})
  210. end
  211. }
  212. end
  213. local function system_power_off ()
  214. awful.prompt.run {
  215. prompt = "Power Off (type 'yes' to confirm)? ",
  216. textbox = awful.screen.focused().mypromptbox.widget,
  217. exe_callback = function (t)
  218. if string.lower(t) == "yes" then
  219. awesome.emit_signal("exit", nil)
  220. awful.spawn(dbus_login .. "PowerOff boolean:true")
  221. end
  222. end,
  223. completion_callback = function (t, p, n)
  224. return awful.completion.generic(t, p, n, {"no", "NO", "yes", "YES"})
  225. end
  226. }
  227. end
  228. local function take_screenshot (opts)
  229. if opts == nil then
  230. opts = ""
  231. end
  232. awful.spawn.easy_async_with_shell("maim " .. screenshot_dir .. "screenshot-$(date +%Y-%m-%d_%H-%M-%S).png " .. opts,
  233. function ()
  234. awful.spawn.with_shell("ogg123 " .. screenshot_sound)
  235. end)
  236. end
  237. local function set_wallpaper(s, wallpaper)
  238. local wallpaper = wallpaper or beautiful.wallpaper
  239. -- Re-calculate wallpapers size
  240. if wallpaper then
  241. -- If wallpaper is a function, call it with the screen
  242. if type(wallpaper) == "function" then
  243. wallpaper = wallpaper(s)
  244. end
  245. gears.wallpaper.maximized(wallpaper, s, false)
  246. end
  247. end
  248. local function load_wallpaper (wallpaper_path)
  249. local wallpaper = config_path .. "theme/_wall.jpg"
  250. -- TODO: replace io.open with a non-blocking
  251. -- https://awesomewm.org/doc/api/libraries/awful.spawn.html
  252. local ln = io.popen("ln -sfn '" .. wallpaper_path .. "' '" .. config_path .. "theme/_wall.jpg'")
  253. ln:close()
  254. -- set new wallpaper for all screens
  255. for s = 1, screen.count() do
  256. set_wallpaper(s, wallpaper)
  257. end
  258. end
  259. local function get_wallpaper_menu (wallpaper_path, is_submenu)
  260. local wallpaper_path = wallpaper_path or home_path .. "Pictures/Wallpapers"
  261. local wallmenu = {}
  262. if not is_submenu then
  263. local default_item = {
  264. "Default",
  265. function ()
  266. awful.spawn.with_shell("rm " .. config_path .. "theme/_wall.jpg")
  267. for s = 1, screen.count() do
  268. set_wallpaper(s)
  269. end
  270. end
  271. }
  272. table.insert(wallmenu, default_item)
  273. end
  274. local files = io.popen("ls -1 --group-directories-first '" .. wallpaper_path .. "'")
  275. for line in files:lines() do
  276. local line_len = string.len(line) * 10
  277. if string.match(line, "%.png$") or string.match(line ,"%.jp[e]?g$") then
  278. local wallpaper_name = line
  279. local wallpaper = wallpaper_path .. "/" .. wallpaper_name
  280. local item = { wallpaper_name, function () load_wallpaper(wallpaper) end, theme={ width=line_len } }
  281. table.insert(wallmenu, item)
  282. else
  283. local dir_name = line
  284. local sub_path = wallpaper_path .. "/" .. dir_name
  285. local check = io.open(sub_path, "r")
  286. if check ~= nil then
  287. local ok, err, code = check:read(1)
  288. check:close()
  289. if code == 21 then
  290. local sub_items = get_wallpaper_menu(sub_path, true)
  291. if next(sub_items) ~= nil then
  292. table.insert(wallmenu, { dir_name, sub_items, theme={ width=line_len } })
  293. end
  294. end
  295. end
  296. end
  297. end
  298. files:close()
  299. return wallmenu
  300. end
  301. --}}}
  302. -- Notification
  303. naughty.config.notify_callback = notify_callback
  304. naughty.config.defaults.timeout = 10
  305. -- Cyclefocus
  306. cyclefocus.show_clients = false
  307. cyclefocus.focus_clients = false
  308. cyclefocus.display_prev_count = 1
  309. cyclefocus.default_preset = {
  310. position = "top_left", -- deprecated options
  311. timeout = 0,
  312. margin = 3,
  313. border_width = 1,
  314. border_color = "#001E21",
  315. fg = "#00ffff",
  316. bg = "#001214"
  317. }
  318. --}}}
  319. -- Table of layouts to cover with awful.layout.inc, order matters.
  320. awful.layout.layouts = {
  321. awful.layout.suit.floating,
  322. awful.layout.suit.tile,
  323. awful.layout.suit.tile.left,
  324. awful.layout.suit.tile.bottom,
  325. awful.layout.suit.tile.top,
  326. awful.layout.suit.fair,
  327. awful.layout.suit.fair.horizontal,
  328. awful.layout.suit.spiral,
  329. awful.layout.suit.spiral.dwindle,
  330. awful.layout.suit.max,
  331. awful.layout.suit.max.fullscreen,
  332. awful.layout.suit.magnifier,
  333. awful.layout.suit.corner.nw,
  334. awful.layout.suit.corner.ne,
  335. awful.layout.suit.corner.sw,
  336. awful.layout.suit.corner.se,
  337. }
  338. -- }}}
  339. -- {{{ Menu
  340. -- Create a launcher widget and a main menu
  341. myawesomemenu = {
  342. { "&hotkeys", function() return false, hotkeys_popup.show_help end},
  343. { "&manual", terminal .. " -e man awesome" },
  344. { "&edit config", editor_cmd .. " " .. awesome.conffile },
  345. { "&restart", awesome.restart },
  346. { "&quit", function() awesome.quit() end}
  347. }
  348. mysystemmenu = {
  349. --{ "manual", tools.terminal .. " -e man awesome" },
  350. { "&lock", system_lock },
  351. { "&suspend", system_suspend },
  352. { "hi&bernate", system_hibernate },
  353. { "hybri&d sleep", system_hybrid_sleep },
  354. { "&reboot", system_reboot },
  355. { "&power off", system_power_off }
  356. }
  357. mywallpapermenu = get_wallpaper_menu()
  358. mymainmenu = awful.menu({
  359. items = {
  360. { "&Awesome", myawesomemenu, beautiful.menu_icon },
  361. { "&System", mysystemmenu },
  362. { "&Wallpapers", mywallpapermenu },
  363. { "&Terminal", terminal }
  364. }
  365. })
  366. mylauncher = awful.widget.launcher({ image = beautiful.awesome_icon,
  367. menu = mymainmenu })
  368. -- Menubar configuration
  369. app_folders = { "~/.local/share/applications", "/usr/share/applications/", "/usr/local/share/applications" }
  370. menubar.menu_gen.all_menu_dirs = app_folders
  371. menubar.utils.terminal = terminal -- Set the terminal for applications that require it
  372. -- }}}
  373. -- Keyboard map indicator and switcher
  374. mykeyboardlayout = awful.widget.keyboardlayout()
  375. -- {{{ Wibar
  376. -- Create a wibox for each screen and add it
  377. local taglist_buttons = gears.table.join(
  378. awful.button({ }, 1, function(t) t:view_only() end),
  379. awful.button({ modkey }, 1, function(t)
  380. if client.focus then
  381. client.focus:move_to_tag(t)
  382. end
  383. end),
  384. awful.button({ }, 3, awful.tag.viewtoggle),
  385. awful.button({ modkey }, 3, function(t)
  386. if client.focus then
  387. client.focus:toggle_tag(t)
  388. end
  389. end),
  390. awful.button({ }, 4, function(t) awful.tag.viewnext(t.screen) end),
  391. awful.button({ }, 5, function(t) awful.tag.viewprev(t.screen) end)
  392. )
  393. local tasklist_buttons = gears.table.join(
  394. awful.button({ }, 1, function (c)
  395. if c == client.focus then
  396. c.minimized = true
  397. else
  398. -- Without this, the following
  399. -- :isvisible() makes no sense
  400. c.minimized = false
  401. if not c:isvisible() and c.first_tag then
  402. c.first_tag:view_only()
  403. end
  404. -- This will also un-minimize
  405. -- the client, if needed
  406. client.focus = c
  407. c:raise()
  408. end
  409. end),
  410. awful.button({ }, 3, client_menu_toggle()),
  411. awful.button({ }, 4, function ()
  412. awful.client.focus.byidx(1)
  413. end),
  414. awful.button({ }, 5, function ()
  415. awful.client.focus.byidx(-1)
  416. end))
  417. -- Create a systray widget
  418. local xresources = require("beautiful.xresources")
  419. local dpi = xresources.apply_dpi
  420. local mysystray = wibox.widget.systray()
  421. local mysystraymargin = wibox.container.margin(mysystray, 2, 2, 2, 2)
  422. -- Create a textclock widget
  423. local mytextclock = wibox.widget.textclock()
  424. local calendar = awful.widget.calendar_popup.month()
  425. calendar:attach(mytextclock, "tr")
  426. awful.screen.connect_for_each_screen(function(s)
  427. -- Widgets separators
  428. local separator1px = wibox.widget.imagebox()
  429. separator1px:set_image(beautiful.get().spr1px)
  430. local separator2px = wibox.widget.imagebox()
  431. separator2px:set_image(beautiful.get().spr2px)
  432. local separator4px = wibox.widget.imagebox()
  433. separator4px:set_image(beautiful.get().spr4px)
  434. local separator5px = wibox.widget.imagebox()
  435. separator5px:set_image(beautiful.get().spr5px)
  436. local separator10px = wibox.widget.imagebox()
  437. separator10px:set_image(beautiful.get().spr10px)
  438. -- Wallpaper
  439. set_wallpaper(s)
  440. -- Each screen has its own tag table.
  441. layouts = awful.layout.layouts
  442. tags = {
  443. names = { "1", "2", "3", "4", "5", "6" },
  444. layouts = { layouts[1], layouts[2], layouts[10], layouts[10], layouts[1], layouts[12] }
  445. }
  446. awful.tag(tags.names, s, tags.layouts)
  447. -- Create a promptbox for each screen
  448. s.mypromptbox = awful.widget.prompt()
  449. -- Create an imagebox widget which will contains an icon indicating which layout we're using.
  450. -- We need one layoutbox per screen.
  451. s.mylayoutbox = awful.widget.layoutbox(s)
  452. s.mylayoutbox:buttons(gears.table.join(
  453. awful.button({ }, 1, function () awful.layout.inc(layouts, 1) end),
  454. awful.button({ }, 3, function () awful.layout.inc(layouts, -1) end),
  455. awful.button({ }, 4, function () awful.layout.inc(layouts, 1) end),
  456. awful.button({ }, 5, function () awful.layout.inc(layouts, -1) end)))
  457. -- Create a taglist widget
  458. s.mytaglist = awful.widget.taglist(s, awful.widget.taglist.filter.all, taglist_buttons)
  459. -- Create a tasklist widget
  460. s.mytasklist = awful.widget.tasklist(s, awful.widget.tasklist.filter.currenttags, tasklist_buttons)
  461. -- Create the wibox
  462. s.mywibox = awful.wibox({ position = "top", screen = s })
  463. -- Widgets that are aligned to the left
  464. local left_layout = wibox.layout.fixed.horizontal()
  465. if s.index == 1 then
  466. left_layout:add(mylauncher)
  467. end
  468. left_layout:add(s.mytaglist)
  469. left_layout:add(s.mypromptbox)
  470. left_layout:add(separator10px)
  471. -- Widgets that are aligned to the right
  472. local right_layout = wibox.layout.fixed.horizontal()
  473. if s.index == 1 then
  474. right_layout:add(mysystraymargin)
  475. right_layout:add(separator2px)
  476. right_layout:add(mykeyboardlayout)
  477. right_layout:add(separator2px)
  478. right_layout:add(mycpufreq.text)
  479. right_layout:add(separator2px)
  480. right_layout:add(myvolume.icon)
  481. right_layout:add(separator1px)
  482. right_layout:add(mybrightness.icon)
  483. if mybattery.hasbattery then
  484. right_layout:add(separator1px)
  485. right_layout:add(mybattery.icon)
  486. end
  487. if mywifi.haswifi then
  488. right_layout:add(separator1px)
  489. right_layout:add(mywifi.icon)
  490. end
  491. right_layout:add(mytextclock)
  492. end
  493. right_layout:add(s.mylayoutbox)
  494. -- Add widgets to the wibox
  495. s.mywibox:setup {
  496. layout = wibox.layout.align.horizontal,
  497. left_layout, -- Left widget
  498. s.mytasklist, -- Middle widget
  499. right_layout, -- Right widget
  500. }
  501. end)
  502. -- }}}
  503. -- {{{ Mouse bindings
  504. root.buttons(gears.table.join(
  505. awful.button({ }, 3, function () mymainmenu:toggle() end),
  506. awful.button({ }, 4, awful.tag.viewnext),
  507. awful.button({ }, 5, awful.tag.viewprev)
  508. ))
  509. -- }}}
  510. -- {{{ Key bindings
  511. globalkeys = gears.table.join(
  512. awful.key({ modkey, }, "s", hotkeys_popup.show_help,
  513. {description="show help", group="awesome"}),
  514. awful.key({ modkey, }, "Left", awful.tag.viewprev,
  515. {description = "view previous", group = "tag"}),
  516. awful.key({ modkey, }, "Right", awful.tag.viewnext,
  517. {description = "view next", group = "tag"}),
  518. awful.key({ modkey, }, "Escape", awful.tag.history.restore,
  519. {description = "go back", group = "tag"}),
  520. -- Non-empty tag browsing
  521. awful.key({ modkey, }, "Next",
  522. function ()
  523. tag_view_nonempty(1)
  524. end, {description = "focus next non-empty tag", group = "tag"}),
  525. awful.key({ modkey, }, "Prior",
  526. function ()
  527. tag_view_nonempty(-1)
  528. end, {description = "focus previous non-empty tag", group = "tag"}),
  529. -- Unless gaps resize
  530. awful.key({ modkey, "Control" }, "+",
  531. function ()
  532. unless_gap_resize(1)
  533. end, {description = "increase unless gap size on current screen and tag", group = "layout"}),
  534. awful.key({ modkey, "Control" }, "-",
  535. function ()
  536. unless_gap_resize(-1)
  537. end, {description = "reduce unless gap size on current screen and tag", group = "layout"}),
  538. awful.key({ modkey, "Control" }, "0",
  539. function ()
  540. unless_gap_resize(0)
  541. end, {description = "reset unless gap size on current screen and tag", group = "layout"}),
  542. -- Take a screenshot
  543. awful.key({ }, "Print", take_screenshot,
  544. {description = "print a screenshot", group = "screenshot"}),
  545. awful.key({ altkey }, "Print", function () take_screenshot("--delay=10") end,
  546. {description = "print a screenshot after 10 sec", group = "screenshot"}),
  547. awful.key({ modkey }, "Print", function () take_screenshot("-s") end,
  548. {description = "print a screenshot by area", group = "screenshot"}),
  549. -- Default client focus
  550. awful.key({ modkey, }, "j",
  551. function ()
  552. awful.client.focus.byidx( 1)
  553. if client.focus then client.focus:raise() end
  554. end, {description = "focus next by index", group = "client"}),
  555. awful.key({ modkey, }, "k",
  556. function ()
  557. awful.client.focus.byidx(-1)
  558. if client.focus then client.focus:raise() end
  559. end, {description = "focus previous by index", group = "client"}),
  560. -- Layout manipulation
  561. awful.key({ modkey, "Shift" }, "j", function () awful.client.swap.byidx(1) end,
  562. {description = "swap with next client by index", group = "client"}),
  563. awful.key({ modkey, "Shift" }, "k", function () awful.client.swap.byidx(-1) end,
  564. {description = "swap with previous client by index", group = "client"}),
  565. awful.key({ modkey, "Control" }, "j", function () awful.screen.focus_relative(1) end,
  566. {description = "focus the next screen", group = "screen"}),
  567. awful.key({ modkey, "Control" }, "k", function () awful.screen.focus_relative(-1) end,
  568. {description = "focus the previous screen", group = "screen"}),
  569. awful.key({ modkey, }, "u", awful.client.urgent.jumpto,
  570. {description = "jump to urgent client", group = "client"}),
  571. awful.key({ modkey, }, "Tab",
  572. function ()
  573. awful.client.focus.history.previous()
  574. if client.focus then
  575. client.focus:raise()
  576. end
  577. end, {description = "go back", group = "client"}),
  578. awful.key({ altkey, }, "Tab",
  579. function(c)
  580. cyclefocus.cycle(1)
  581. end, {description = "cycle focus next client", group = "client"}),
  582. awful.key({ altkey, "Shift" }, "Tab",
  583. function(c)
  584. cyclefocus.cycle(-1)
  585. end, {description = "cycle focus previous client", group = "client"}),
  586. awful.key({ modkey, }, "l", function () client_resize('Right') end,
  587. {description = "increase master width factor", group = "layout"}),
  588. awful.key({ modkey, }, "h", function () client_resize('Left') end,
  589. {description = "decrease master width factor", group = "layout"}),
  590. awful.key({ modkey, altkey }, "l", function () client_resize('Up') end,
  591. {description = "increase client height factor", group = "layout"}),
  592. awful.key({ modkey, altkey }, "h", function () client_resize('Down') end,
  593. {description = "decrease client height factor", group = "layout"}),
  594. awful.key({ modkey, "Shift" }, "h", function () awful.tag.incnmaster( 1) end,
  595. {description = "increase the number of master clients", group = "layout"}),
  596. awful.key({ modkey, "Shift" }, "l", function () awful.tag.incnmaster(-1) end,
  597. {description = "decrease the number of master clients", group = "layout"}),
  598. awful.key({ modkey, "Control" }, "h", function () awful.tag.incncol( 1) end,
  599. {description = "increase the number of columns", group = "layout"}),
  600. awful.key({ modkey, "Control" }, "l", function () awful.tag.incncol(-1) end,
  601. {description = "decrease the number of columns", group = "layout"}),
  602. awful.key({ modkey, }, "space", function () awful.layout.inc(layouts, 1) end,
  603. {description = "select next layout", group = "layout"}),
  604. awful.key({ modkey, "Shift" }, "space", function () awful.layout.inc(layouts, -1) end,
  605. {description = "select previous layout", group = "layout"}),
  606. awful.key({ modkey, "Control" }, "t",
  607. function ()
  608. awful.layout.set(awful.layout.suit.tile)
  609. end, {description = "switch to tile layout", group = "layout"}),
  610. awful.key({ modkey, "Control" }, "m",
  611. function ()
  612. awful.layout.set(awful.layout.suit.max)
  613. end, {description = "switch to max layout", group = "layout"}),
  614. awful.key({ modkey, "Control" }, "f",
  615. function ()
  616. awful.layout.set(awful.layout.suit.floating)
  617. end, {description = "switch to floating layout", group = "layout"}),
  618. awful.key({ modkey, "Control" }, "n",
  619. function ()
  620. local c = awful.client.restore()
  621. -- Focus restored client
  622. if c then
  623. client.focus = c
  624. c:raise()
  625. end
  626. end, {description = "restore minimized", group = "client"}),
  627. -- Standard program
  628. awful.key({ modkey, }, "Return", function () awful.spawn(terminal) end,
  629. {description = "open a terminal", group = "launcher"}),
  630. awful.key({ modkey, "Control" }, "r", awesome.restart,
  631. {description = "reload awesome", group = "awesome"}),
  632. awful.key({ modkey, "Shift" }, "q", awesome.quit,
  633. {description = "quit awesome", group = "awesome"}),
  634. -- System volume
  635. awful.key({ }, "XF86AudioRaiseVolume", myvolume.raise),
  636. awful.key({ }, "XF86AudioLowerVolume", myvolume.lower),
  637. awful.key({ }, "XF86AudioMute", myvolume.mute),
  638. -- System brightness
  639. awful.key({ }, "XF86MonBrightnessDown", function() mybrightness:down() end),
  640. awful.key({ }, "XF86MonBrightnessUp", function() mybrightness:up() end),
  641. -- Toggle sloppy focus
  642. awful.key({ modkey, "Shift" }, "s",
  643. function ()
  644. sloppy_focus = not sloppy_focus
  645. end, {description = "toggle sloppy focus", group = "client"}),
  646. -- Notifications
  647. awful.key({ modkey, "Shift" }, "s",
  648. function ()
  649. -- TODO: move to external widget with icon
  650. if naughty.is_suspended() then
  651. notify_suspended = false
  652. naughty.resume()
  653. else
  654. notify_suspended = true
  655. naughty.suspend()
  656. end
  657. end, {description = "enabled/disable notifications", group = "awesome"}),
  658. awful.key({ modkey, "Shift" }, "d", naughty.destroy_all_notifications,
  659. {description = "clear notifications", group = "awesome"}),
  660. -- System
  661. awful.key({ modkey, }, "Home", system_lock,
  662. {description = "lock the screen", group = "system"}),
  663. awful.key({ modkey, }, "End", system_suspend,
  664. {description = "suspend the system", group = "system"}),
  665. awful.key({ }, "XF86Sleep", system_suspend),
  666. awful.key({ modkey, "Shift" }, "Home", system_hibernate,
  667. {description = "hibernate the system", group = "system"}),
  668. awful.key({ modkey }, "XF86Sleep", system_hibernate),
  669. awful.key({ modkey, "Shift" }, "End", system_hybrid_sleep,
  670. {description = "send to hybrid sleep", group = "system"}),
  671. awful.key({ modkey, }, "Insert", system_reboot,
  672. {description = "reboot the system", group = "system"}),
  673. awful.key({ modkey, }, "Delete", system_power_off,
  674. {description = "shutdown the system", group = "system"}),
  675. -- Prompt
  676. awful.key({ modkey }, "r",
  677. function ()
  678. awful.prompt.run {
  679. prompt = "Run: ",
  680. textbox = awful.screen.focused().mypromptbox.widget,
  681. completion_callback = awful.completion.shell,
  682. history_path = awful.util.get_cache_dir() .. "/history"
  683. }
  684. end,
  685. {description = "run prompt", group = "launcher"}),
  686. awful.key({ modkey, }, "x",
  687. function ()
  688. awful.prompt.run {
  689. prompt = "Run Lua code: ",
  690. textbox = awful.screen.focused().mypromptbox.widget,
  691. exe_callback = awful.util.eval,
  692. history_path = awful.util.get_cache_dir() .. "/history_eval"
  693. }
  694. end,
  695. {description = "lua execute prompt", group = "awesome"}),
  696. -- Menubar
  697. awful.key({ altkey }, "Escape",
  698. function ()
  699. -- If you want to always position the menu on the same place set coordinates
  700. awful.menu.menu_keys.down = { "Down", "Alt_L" }
  701. awful.menu.clients({theme = { width = 250 }}, { keygrabber=true, coords={x=525, y=330} })
  702. end, {description = "show app switcher", group = "awesome"}),
  703. awful.key({ modkey, }, "a", function () awful.spawn("rofi -show", false) end,
  704. {description = "show rofi", group = "launcher"}),
  705. awful.key({ modkey, }, "p", function() menubar.show() end,
  706. {description = "show the menubar", group = "launcher"}),
  707. awful.key({ modkey, }, "w", function () mymainmenu:show() end,
  708. {description = "show main menu", group = "awesome"}),
  709. awful.key({ modkey, "Shift" }, "w",
  710. function ()
  711. mymainmenu:show({ keygrabber = true })
  712. end, {description = "show main menu with keygrabber", group = "awesome"})
  713. )
  714. clientkeys = gears.table.join(
  715. awful.key({ modkey, }, "f",
  716. function (c)
  717. c.fullscreen = not c.fullscreen
  718. c:raise()
  719. end, {description = "toggle fullscreen", group = "client"}),
  720. awful.key({ altkey, }, "F2",
  721. function (c)
  722. if c.pid then
  723. awful.spawn("kill -9 " .. c.pid)
  724. else
  725. awful.spawn("xkill")
  726. end
  727. end,
  728. {description = "kill", group = "client"}),
  729. awful.key({ altkey, }, "F4", function (c) c:kill() end,
  730. {description = "close", group = "client"}),
  731. awful.key({ modkey, "Shift" }, "c", function (c) c:kill() end,
  732. {description = "close", group = "client"}),
  733. awful.key({ modkey, "Control" }, "space", awful.client.floating.toggle,
  734. {description = "toggle floating", group = "client"}),
  735. awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end,
  736. {description = "move to master", group = "client"}),
  737. awful.key({ modkey, "Shift" }, "Left", function (c) awful.client.setmaster(c) end,
  738. {description = "set to master", group = "client"}),
  739. awful.key({ modkey, "Shift" }, "Right", function (c) awful.client.setslave(c) end,
  740. {description = "move to slave", group = "client"}),
  741. awful.key({ modkey, }, "o", function (c) c:move_to_screen() end,
  742. {description = "move to screen", group = "client"}),
  743. awful.key({ modkey, }, "t", function (c) c.ontop = not c.ontop end,
  744. {description = "toggle keep on top", group = "client"}),
  745. awful.key({ modkey, }, "y", function (c) c.sticky = not c.sticky end,
  746. {description = "toggle keep sticky", group = "client"}),
  747. awful.key({ modkey, "Shift" }, "t",
  748. function (c)
  749. awful.titlebar.toggle(c)
  750. end,
  751. {description = "toggle title bar", group = "client"}),
  752. awful.key({ modkey, }, "n",
  753. function (c)
  754. -- The client currently has the input focus, so it cannot be
  755. -- minimized, since minimized clients can't have the focus.
  756. c.minimized = true
  757. end, {description = "minimize", group = "client"}),
  758. awful.key({ modkey, }, "m",
  759. function (c)
  760. c.maximized = not c.maximized
  761. c:raise()
  762. end, {description = "(un)maximize", group = "client"}),
  763. awful.key({ modkey, altkey }, "m",
  764. function (c)
  765. c.maximized_horizontal = not c.maximized_horizontal
  766. c.maximized_vertical = not c.maximized_vertical
  767. c:raise()
  768. end, {description = "(un)maximize horizontally/vertically", group = "client"}),
  769. awful.key({ modkey, "Shift" }, "m",
  770. function (c)
  771. c.maximized_horizontal = not c.maximized_horizontal
  772. c:raise()
  773. end, {description = "(un)maximize horizontally", group = "client"}),
  774. awful.key({ modkey, "Control" }, "m",
  775. function (c)
  776. c.maximized_vertical = not c.maximized_vertical
  777. c:raise()
  778. end, {description = "(un)maximize vertically", group = "client"}),
  779. -- Snap
  780. awful.key({ modkey, }, "Up",
  781. function (c)
  782. c.maximized = true
  783. c:raise()
  784. end, {description = "maximize", group = "client"}),
  785. awful.key({ modkey, }, "Down",
  786. function (c)
  787. c.maximized = false
  788. c:raise()
  789. awful.placement.centered(c,nil)
  790. end, {description = "unmaximize", group = "client"}),
  791. -- Resize
  792. awful.key({ modkey, altkey }, "s",
  793. function (c)
  794. keygrabber.run(function(mod, key, event)
  795. if event == "release" then return end
  796. local makeResize = client_resize(key, c)
  797. if makeResize == false then
  798. keygrabber.stop()
  799. end
  800. end)
  801. end, {description = "resize the client", group = "client"})
  802. )
  803. -- Bind all key numbers to tags.
  804. -- Be careful: we use keycodes to make it works on any keyboard layout.
  805. -- This should map on the top row of your keyboard, usually 1 to 9.
  806. for i = 1, 9 do
  807. globalkeys = gears.table.join(
  808. globalkeys,
  809. -- View tag only.
  810. awful.key({ modkey }, "#" .. i + 9,
  811. function ()
  812. local screen = awful.screen.focused()
  813. local tag = screen.tags[i]
  814. if tag then
  815. tag:view_only()
  816. end
  817. end,
  818. {description = "view tag #"..i, group = "tag"}),
  819. -- Toggle tag display.
  820. awful.key({ modkey, "Control" }, "#" .. i + 9,
  821. function ()
  822. local screen = awful.screen.focused()
  823. local tag = screen.tags[i]
  824. if tag then
  825. awful.tag.viewtoggle(tag)
  826. end
  827. end,
  828. {description = "toggle tag #" .. i, group = "tag"}),
  829. -- Move client to tag.
  830. awful.key({ modkey, "Shift" }, "#" .. i + 9,
  831. function ()
  832. if client.focus then
  833. local tag = client.focus.screen.tags[i]
  834. if tag then
  835. client.focus:move_to_tag(tag)
  836. end
  837. end
  838. end,
  839. {description = "move focused client to tag #"..i, group = "tag"}),
  840. -- Toggle tag on focused client.
  841. awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9,
  842. function ()
  843. if client.focus then
  844. local tag = client.focus.screen.tags[i]
  845. if tag then
  846. client.focus:toggle_tag(tag)
  847. end
  848. end
  849. end,
  850. {description = "toggle focused client on tag #" .. i, group = "tag"})
  851. )
  852. end
  853. clientbuttons = gears.table.join(
  854. awful.button({ }, 1, function (c) client.focus = c; c:raise() end),
  855. awful.button({ modkey }, 1, awful.mouse.client.move),
  856. awful.button({ modkey }, 3, awful.mouse.client.resize))
  857. -- Set keys
  858. root.keys(globalkeys)
  859. -- }}}
  860. function titlebar_add(c)
  861. -- buttons for the titlebar
  862. local buttons = gears.table.join(
  863. awful.button({ }, 1, function()
  864. c:emit_signal("request::activate", "titlebar", {raise = true})
  865. awful.mouse.client.move(c)
  866. end),
  867. awful.button({ }, 3, function()
  868. c:emit_signal("request::activate", "titlebar", {raise = true})
  869. awful.mouse.client.resize(c)
  870. end)
  871. )
  872. awful.titlebar(c, {size = 16}) : setup
  873. {
  874. { -- Left
  875. -- awful.titlebar.widget.iconwidget(c),
  876. buttons = buttons,
  877. layout = wibox.layout.fixed.horizontal
  878. },
  879. { -- Middle
  880. { -- Title
  881. align = "center",
  882. widget = awful.titlebar.widget.titlewidget(c)
  883. },
  884. buttons = buttons,
  885. layout = wibox.layout.flex.horizontal
  886. },
  887. { -- Right
  888. awful.titlebar.widget.floatingbutton (c),
  889. awful.titlebar.widget.maximizedbutton(c),
  890. awful.titlebar.widget.stickybutton (c),
  891. awful.titlebar.widget.ontopbutton (c),
  892. awful.titlebar.widget.closebutton (c),
  893. layout = wibox.layout.fixed.horizontal()
  894. },
  895. layout = wibox.layout.align.horizontal
  896. }
  897. end
  898. function awful.rules.extra_properties.icon (c, value, props)
  899. awful.spawn.with_shell("xseticon -id " .. c.window .. " " .. value)
  900. end
  901. function awful.rules.extra_properties.titlebars_show (c, value, props)
  902. -- Custom property to hide/show titlebars
  903. -- titlebar.toggle doesn't work fine if 'titlebars_enabled' is false
  904. if value then
  905. awful.titlebar.show(c)
  906. else
  907. awful.titlebar.hide(c)
  908. end
  909. end
  910. -- {{{ Rules
  911. -- Rules to apply to new clients (through the "manage" signal).
  912. screen_max = screen:count()
  913. awful.rules.rules = {
  914. -- All clients will match this rule.
  915. { rule = { },
  916. properties = {
  917. border_width = beautiful.border_width,
  918. border_color = beautiful.border_normal,
  919. focus = awful.client.focus.filter,
  920. raise = true,
  921. keys = clientkeys,
  922. buttons = clientbuttons,
  923. screen = awful.screen.preferred,
  924. titlebars_enabled = true,
  925. titlebars_show = false,
  926. placement = awful.placement.no_overlap+awful.placement.no_offscreen
  927. }
  928. },
  929. -- Floating clients.
  930. { rule_any = {
  931. instance = {
  932. "DTA", -- Firefox addon DownThemAll.
  933. "copyq", -- Includes session name in class.
  934. "pinentry",
  935. },
  936. class = {
  937. "Arandr",
  938. "Gpick",
  939. "Kruler",
  940. "MessageWin", -- kalarm.
  941. "Sxiv",
  942. "Tor Browser", -- Needs a fixed window size to avoid fingerprinting by screen size.
  943. "Wpa_gui",
  944. "pinentry",
  945. "veromix",
  946. "xtightvncviewer"},
  947. name = {
  948. "Event Tester", -- xev.
  949. },
  950. role = {
  951. "AlarmWindow", -- Thunderbird's calendar.
  952. "pop-up", -- e.g. Developer Tools.
  953. "About"
  954. }
  955. }, properties = { floating = true }},
  956. -- Add titlebars to normal clients and dialogs
  957. { rule_any = { type = { "dialog" }},
  958. except_any = { role = { "notify_dialog" }},
  959. properties = {
  960. titlebars_show = true,
  961. floating = true,
  962. screen = awful.screen.focused,
  963. placement = awful.placement.under_mouse+awful.placement.no_offscreen,
  964. callback = awful.client.setslave
  965. }
  966. },
  967. -- Custom
  968. { rule_any = { class = { "MPlayer", "mpv" } },
  969. properties = { floating = true }
  970. },
  971. { rule = { instance = "mps" },
  972. properties = {
  973. screen = 2,
  974. tag = "2",
  975. placement = awful.placement.top_left,
  976. skip_taskbar = true,
  977. floating = true,
  978. ontop = true,
  979. focusable = false,
  980. focus = false,
  981. width = 200,
  982. honor_padding = true,
  983. callback = function(c)
  984. c:relative_move(12, 5, c.width, c.height)
  985. end
  986. }
  987. },
  988. { rule = { class = "Gimp.*" },
  989. properties = { tag = "6", floating = true }
  990. },
  991. { rule_any = { class = { "URxvt", ".*ermina.*" } },
  992. properties = { tag = "2", size_hints_honor = false, icon = "/usr/share/icons/Moka/48x48/apps/terminal.png" }
  993. },
  994. { rule = { class = "Emacs" },
  995. properties = { tag = "3", switch_to_tags = true, size_hints_honor = false }
  996. },
  997. { rule_any = { instance = { "Lf" }, name = { ".*Lf.*" } },
  998. properties = { tag = "6", screen = screen_max, size_hints_honor = false, icon = "/usr/share/icons/Moka/48x48/apps/file-manager.png" }
  999. },
  1000. { rule_any = { instance = { "Mc", "Nnn" }, name = { ".*mc .*", ".*Nnn.*" } },
  1001. properties = { tag = "6", screen = 1, switch_to_tags = true, size_hints_honor = false, icon = "/usr/share/icons/Moka/48x48/apps/file-manager.png" }
  1002. },
  1003. { rule_any = { role = { "browser" }, class = { "Epiphany" }},
  1004. properties = { tag = "4", maximized_vertical = true, maximized_horizontal = true }
  1005. },
  1006. { rule_any = { instance = { "WeeChat" }, name = { ".*weeChat.*" } },
  1007. properties = {
  1008. tag = "5", switch_to_tags = true, maximized_vertical = true, maximized_horizontal = true, icon = "/usr/share/icons/hicolor/32x32/apps/weechat.png"
  1009. }
  1010. },
  1011. { rule_any = { name = {"^Android Emulator*", "^Emulator"} },
  1012. properties = {
  1013. floating = true,
  1014. callback = function(c)
  1015. -- force due the behavior in property::size
  1016. c.border_width = 0
  1017. c.no_border = true
  1018. end
  1019. }
  1020. },
  1021. { rule = { name = "^Emulator", type = "utility"},
  1022. properties = {
  1023. skip_taskbar = true,
  1024. focusable = false
  1025. }
  1026. },
  1027. {
  1028. rule = { class = "jetbrains-studio", name="^win[0-9]+$" },
  1029. properties = {
  1030. placement = awful.placement.no_offscreen,
  1031. screen = awful.screen.preferred,
  1032. border_width = 0,
  1033. titlebars_enabled = false,
  1034. titlebars_show = false,
  1035. focusable = false,
  1036. }
  1037. },
  1038. { rule = { instance = "Pidgin" },
  1039. properties = { tag = "5", size_hints_honor = false, floating = true }
  1040. },
  1041. { rule = { class = "Pidgin", role = "conversation" },
  1042. properties = {
  1043. tag = "5", screen = 1, width = 500, height = 350, placement = awful.placement.top_right,
  1044. callback = function(c)
  1045. c:relative_move(320, 10, c.width, c.height)
  1046. end
  1047. }},
  1048. { rule = { class = "Pidgin", role = "buddy_list" },
  1049. properties = {
  1050. tag = "5", screen = 1, width = 150, height = 350, placement = awful.placement.top_left,
  1051. callback = function(c)
  1052. awful.client.setmaster(c)
  1053. c:relative_move(20, 10, c.width, c.height)
  1054. end
  1055. },
  1056. },
  1057. { rule = { class = "Kodi" },
  1058. properties = { tag = "1", screen = 2, fullscreen = true, ontop = true, switch_to_tags = true }
  1059. },
  1060. { rule = { name = "Media viewer" },
  1061. properties = { fullscreen = true, ontop = true, size_hints_honor = true }
  1062. }
  1063. }
  1064. -- }}}
  1065. -- {{{ Signals
  1066. -- Re-set wallpaper when a screen's geometry changes (e.g. different resolution)
  1067. screen.connect_signal("property::geometry", function(s) set_wallpaper(s) end)
  1068. -- Signal function to execute when a new client appears.
  1069. client.connect_signal(
  1070. "manage", function (c)
  1071. -- Set the windows at the slave,
  1072. -- i.e. put it at the end of others instead of setting it master.
  1073. -- if not awesome.startup then awful.client.setslave(c) end
  1074. if awesome.startup
  1075. and not c.size_hints.user_position
  1076. and not c.size_hints.program_position then
  1077. -- Prevent clients from being unreachable after screen count changes.
  1078. awful.placement.no_offscreen(c)
  1079. end
  1080. end)
  1081. -- Add a titlebar if titlebars_enabled is set to true in the rules.
  1082. client.connect_signal("request::titlebars", titlebar_add)
  1083. -- Enable sloppy focus, so that focus follows mouse.
  1084. client.connect_signal(
  1085. "mouse::enter", function(c)
  1086. if sloppy_focus and awful.layout.get(c.screen) ~= awful.layout.suit.magnifier
  1087. and awful.client.focus.filter(c) then
  1088. c:emit_signal("request::activate", "mouse_enter", {raise = false})
  1089. end
  1090. end)
  1091. client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end)
  1092. client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end)
  1093. client.connect_signal("property::size", client_set_border)
  1094. client.connect_signal("property::fullscreen", client_set_border)
  1095. -- }}}
  1096. -- {{{ Autorun apps and initial setup
  1097. awful.spawn.with_shell(config_path .. "autorun.sh", false)
  1098. initial_setup()
  1099. -- }}}