Skip to content
Permalink
Branch: master
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
1233 lines (1152 sloc) 41.2 KB
-- Standard awesome library
local gears = require("gears")
local awful = require("awful")
awful.rules = require("awful.rules")
require("awful.autofocus")
-- Widget and layout library
local wibox = require("wibox")
-- Theme handling library
local beautiful = require("beautiful")
-- Notification library
local naughty = require("naughty")
local menubar = require("menubar")
-- for fcitx-chttrans
table.insert(naughty.config.icon_dirs, '/usr/share/icons/hicolor/48x48/apps/')
table.insert(naughty.config.icon_dirs, '/usr/share/icons/hicolor/48x48/status/')
local empathy = require("empathy")
local myutil = require("myutil")
local fixwidthtextbox = require("fixwidthtextbox")
local menu = require("menu")
local ok, localconf = pcall(require, "local")
if ok and localconf.scale then
scale = localconf.scale
else
scale = 1
end
if scale ~= 1 then
local dpi = 96 * scale
require("lgi").PangoCairo.FontMap.get_default():set_resolution(dpi)
awful.util.spawn("xrandr --dpi " .. dpi, false)
end
os.setlocale("")
-- A debugging func
n = function(n) naughty.notify{title="消息", text=tostring(n)} end
last_bat_warning = 0
-- {{{ Error handling
-- Check if awesome encountered an error during startup and fell back to
-- another config (This code will only ever execute for the fallback config)
if awesome.startup_errors then
naughty.notify({ preset = naughty.config.presets.critical,
title = "Oops, there were errors during startup!",
text = awesome.startup_errors })
end
-- Handle runtime errors after startup
do
local in_error = false
awesome.connect_signal("debug::error", function (err)
-- Make sure we don't go into an endless error loop
if in_error then return end
in_error = true
naughty.notify({ preset = naughty.config.presets.critical,
title = "Oops, an error happened!",
text = err })
in_error = false
end)
end
-- }}}
-- {{{ Variable definitions
-- Themes define colours, icons, and wallpapers
beautiful.init(awful.util.getdir("config") .. "/theme.lua")
-- This is used later as the default terminal and editor to run.
terminal = "xfce4-terminal"
editor = "gvim"
editor_cmd = editor
-- Default modkey.
-- Usually, Mod4 is the key with a logo between Control and Alt.
-- If you do not like this or do not have such a key,
-- I suggest you to remap Mod4 to another key using xmodmap or other tools.
-- However, you can use another modifier like Mod1, but it may interact with others.
modkey = "Mod4"
-- Table of layouts to cover with awful.layout.inc, order matters.
local layouts =
{
awful.layout.suit.floating,
awful.layout.suit.tile,
awful.layout.suit.tile.left,
awful.layout.suit.tile.bottom,
awful.layout.suit.tile.top,
awful.layout.suit.fair,
awful.layout.suit.fair.horizontal,
-- awful.layout.suit.spiral,
-- awful.layout.suit.spiral.dwindle,
awful.layout.suit.max,
awful.layout.suit.max.fullscreen,
awful.layout.suit.magnifier,
}
-- }}}
-- {{{ Functions
function get_memory_usage()
local ret = {}
for l in io.lines('/proc/meminfo') do
local k, v = l:match("([^:]+):%s+(%d+)")
ret[k] = tonumber(v)
end
return ret
end
function string_split(string, pat, plain)
local ret = {}
local pos = 0
local start, stop
local t_insert = table.insert
while true do
start, stop = string:find(pat, pos, plain)
if not start then
t_insert(ret, string:sub(pos))
break
end
t_insert(ret, string:sub(pos, start-1))
pos = stop + 1
end
return ret
end
function parse_key(string)
local t_insert = table.insert
local parts = string_split(string, '[+-]')
local last = table.remove(parts)
local ret = {}
for _, p in ipairs(parts) do
p_ = p:lower()
local m
if p_ == 'ctrl' then
m = 'Control'
elseif p_ == 'alt' then
m = 'Mod1'
else
m = p
end
t_insert(ret, m)
end
return ret, last
end
_key_map_cache = {}
function map_client_key(client, key_map)
local t_insert = table.insert
local keys
if _key_map_cache[key_map] then
keys = awful.util.table.join(client:keys(), _key_map_cache[key_map])
else
keys = {}
for from, to in pairs(key_map) do
local mod, key = parse_key(from)
local key = awful.key(mod, key, function(c)
awful.util.spawn(
'xdotool key --clearmodifiers --window '
.. c.window .. ' ' .. to)
end)
for _, k in ipairs(key) do
t_insert(keys, k)
end
end
_key_map_cache[key_map] = keys
keys = awful.util.table.join(client:keys(), keys)
end
client:keys(keys)
end
-- }}}
-- {{{ Wallpaper
if beautiful.wallpaper then
for s = 1, screen.count() do
gears.wallpaper.maximized(beautiful.wallpaper, s, true)
end
end
-- }}}
-- {{{ Tags
-- Define a tag table which hold all screen tags.
tags_name = { "1", "2", "3", "4", "5文件", "6聊天", "7GVIM", "8", "9火狐", '0' }
tags_layout = {
awful.layout.suit.tile,
awful.layout.suit.tile,
awful.layout.suit.tile,
awful.layout.suit.tile,
awful.layout.suit.tile,
empathy,
awful.layout.suit.tile,
awful.layout.suit.tile,
awful.layout.suit.floating,
awful.layout.suit.floating,
}
tags = {}
revtags = {}
for s = 1, screen.count() do
-- Each screen has its own tag table.
tags[s] = awful.tag(tags_name, s, tags_layout)
revtags[s] = {}
for i, t in ipairs(tags[s]) do
revtags[s][t] = i
end
end
-- }}}
-- {{{ Menu
-- Create a laucher widget and a main menu
local myawesomemenu = {
{ "编辑配置 (&E)", editor_cmd .. " " .. awesome.conffile },
{ "重新加载 (&R)", awesome.restart, '/usr/share/icons/gnome/16x16/actions/stock_refresh.png' },
{ "注销 (&L)", awesome.quit },
}
local mymenu = {
{ "&Nautilus", "nautilus --no-desktop /home/lilydjwg/tmpfs", '/usr/share/icons/gnome/32x32/apps/system-file-manager.png' },
{ "&Wireshark", "wireshark", '/usr/share/icons/hicolor/32x32/apps/wireshark.png'},
{ "&VirtualBox", "VirtualBox", '/usr/share/icons/hicolor/32x32/mimetypes/virtualbox.png' },
{ "文档查看器 (&E)", "evince", '/usr/share/icons/hicolor/16x16/apps/evince.png' },
}
mymainmenu = awful.menu({ items = { { "Awesome", myawesomemenu, beautiful.awesome_icon },
{ "终端 (&T)", terminal, '/usr/share/icons/gnome/32x32/apps/utilities-terminal.png' },
{ "G&VIM", "gvim", '/usr/share/pixmaps/gvim.png' },
{ "火狐 (&F)", "firefox-nightly -P nightly", '/usr/share/icons/hicolor/32x32/apps/firefox.png' },
{ "常用 (&U)", mymenu },
{ "应用程序 (&A)", xdgmenu(terminal) },
{ "挂起 (&S)", "systemctl suspend" },
{ "关机 (&H)", "zenity --question --title '关机' --text '你确定关机吗?' --default-cancel && systemctl poweroff", '/usr/share/icons/gnome/16x16/actions/gtk-quit.png' },
}
})
mylauncher = awful.widget.launcher({ image = beautiful.awesome_icon,
menu = mymainmenu })
-- Menubar configuration
menubar.utils.terminal = terminal -- Set the terminal for applications that require it
-- }}}
-- {{{ Wibox
-- Create a textclock widget
mytextclock = awful.widget.textclock(" %Y年%m月%d日 %H:%M:%S %A ", 1)
-- {{{ my widgets
-- {{{ Network speed indicator
function update_netstat()
local interval = netwidget_clock.timeout
local netif, text
local f = io.open('/proc/net/route')
for line in f:lines() do
netif = line:match('^(%w+)%s+00000000%s')
if netif then
break
end
end
f:close()
if netif then
local down, up
f = io.open('/proc/net/dev')
for line in f:lines() do
-- Match wmaster0 as well as rt0 (multiple leading spaces)
local name, recv, send = string.match(line, "^%s*(%w+):%s+(%d+)%s+%d+%s+%d+%s+%d+%s+%d+%s+%d+%s+%d+%s+%d+%s+(%d+)")
if name == netif then
if netdata[name] == nil then
-- Default values on the first run
netdata[name] = {}
down, up = 0, 0
else
down = (recv - netdata[name][1]) / interval
up = (send - netdata[name][2]) / interval
end
netdata[name][1] = recv
netdata[name][2] = send
break
end
end
f:close()
down = string.format('%.1f', down / 1024)
up = string.format('%.1f', up / 1024)
text = '↓<span color="#5798d9">'.. down ..'</span> ↑<span color="#c2ba62">'.. up ..'</span>'
else
netdata = {} -- clear as the interface may have been reset
text = '(No network)'
end
netwidget:set_markup(text)
end
netdata = {}
netwidget = fixwidthtextbox('(net)')
netwidget.width = 100 * scale
netwidget:set_align('center')
netwidget_clock = timer({ timeout = 2 })
netwidget_clock:connect_signal("timeout", update_netstat)
netwidget_clock:start()
update_netstat()
-- }}}
-- {{{ memory usage indicator
function update_memwidget()
local meminfo = get_memory_usage()
local free
if meminfo.MemAvailable then
-- Linux 3.14+
free = meminfo.MemAvailable
else
free = meminfo.MemFree + meminfo.Buffers + meminfo.Cached
end
local total = meminfo.MemTotal
local percent = 100 - math.floor(free / total * 100 + 0.5)
memwidget:set_markup('Mem <span color="#90ee90">'.. percent ..'%</span>')
end
memwidget = fixwidthtextbox('Mem ??')
memwidget.width = 55 * scale
update_memwidget()
mem_clock = timer({ timeout = 5 })
mem_clock:connect_signal("timeout", update_memwidget)
mem_clock:start()
-- }}}
-- {{{ CPU Temperature
function update_cputemp()
local pipe = io.popen('sensors coretemp-isa-0000')
if not pipe then
cputempwidget:set_markup('CPU <span color="red">ERR</span>℃')
return
end
local temp = 0
for line in pipe:lines() do
local newtemp = line:match('^Core [^:]+:%s+%+([0-9.]+)°C')
if newtemp then
newtemp = tonumber(newtemp)
if temp < newtemp then
temp = newtemp
end
end
end
pipe:close()
cputempwidget:set_markup('CPU <span color="#008000">'..temp..'</span>℃')
end
cputempwidget = fixwidthtextbox('CPU ??℃')
cputempwidget.width = 60 * scale
update_cputemp()
cputemp_clock = timer({ timeout = 5 })
cputemp_clock:connect_signal("timeout", update_cputemp)
cputemp_clock:start()
-- }}}
--{{{ battery indicator, using the acpi command
local battery_state = {
-- Unknown = '<span color="yellow">? ',
Unknown = '<span color="#0000ff">↯',
Idle = '<span color="#0000ff">↯',
Charging = '<span color="green">+ ',
Discharging = '<span color="#1e90ff">– ',
}
function update_batwidget()
local pipe = io.popen('acpi')
if not pipe then
batwidget:set_markup('<span color="red">ERR</span>')
return
end
--[[
Battery 0: Unknown, 97%
Battery 1: Unknown, 99%
Battery 0: Discharging, 97%, discharging at zero rate - will never fully discharge.
Battery 1: Unknown, 99%
Battery 0: Discharging, 96%, 02:25:51 remaining
Battery 1: Unknown, 99%
]]
local bats = {}
local max_percent = 0
local max_percent_index = 0
local index = 0
for line in pipe:lines() do
index = index + 1
local state, percent, rest = line:match('^Battery %d+:%s+([^,]+), ([0-9.]+)%%(.*)')
local t
if rest ~= '' then
t = rest:match('[1-9]*%d:%d+')
end
if not t then t = '' end
percent = tonumber(percent)
if percent > max_percent then
max_percent = percent
max_percent_index = index
end
table.insert(bats, {state, percent, t})
end
pipe:close()
if index == 0 then
batwidget:set_markup('<span color="red">ERR</span>')
return
end
if max_percent <= 30 then
if bats[max_percent_index][1] == 'Discharging' then
local t = os.time()
if t - last_bat_warning > 60 * 5 then
naughty.notify{
preset = naughty.config.presets.critical,
title = "电量警报",
text = '电池电量只剩下 ' .. max_percent .. '% 了!',
}
last_bat_warning = t
end
if max_percent <= 10 and not dont_hibernate then
awful.util.spawn("systemctl hibernate")
end
end
end
local text = ' '
for i, v in ipairs(bats) do
local percent = v[2]
if percent <= 30 then
percent = '<span color="red">' .. percent .. '</span>'
end
text = text .. (battery_state[v[1]] or battery_state.Unknown) .. percent .. '%'
.. (v[3] ~= '' and (' ' .. v[3]) or '') .. '</span>'
if i ~= #bats then
text = text .. ' '
end
end
batwidget:set_markup(text)
end
batwidget = wibox.widget.textbox('↯??%')
update_batwidget()
bat_clock = timer({ timeout = 5 })
bat_clock:connect_signal("timeout", update_batwidget)
bat_clock:start()
-- }}}
-- {{{ Volume Controller
function volumectl (mode, widget)
if mode == "update" then
local f = io.popen("pamixer --get-volume")
local volume = f:read("*all")
f:close()
if not tonumber(volume) then
widget:set_markup("<span color='red'>ERR</span>")
do return end
end
volume = string.format("% 3d", volume)
f = io.popen("pamixer --get-mute")
local muted = f:read("*all")
f:close()
if muted:gsub('%s+', '') == "false" then
volume = '' .. volume .. "%"
else
volume = '' .. volume .. "<span color='red'>M</span>"
end
widget:set_markup(volume)
elseif mode == "up" then
local f = io.popen("pamixer --allow-boost --increase 5")
f:read("*all")
f:close()
volumectl("update", widget)
elseif mode == "down" then
local f = io.popen("pamixer --allow-boost --decrease 5")
f:read("*all")
f:close()
volumectl("update", widget)
else
local f = io.popen("pamixer --toggle-mute")
f:read("*all")
f:close()
volumectl("update", widget)
end
end
volume_clock = timer({ timeout = 10 })
volume_clock:connect_signal("timeout", function () volumectl("update", volumewidget) end)
volume_clock:start()
volumewidget = fixwidthtextbox('(volume)')
volumewidget.width = 48 * scale
volumewidget:set_align('right')
volumewidget:buttons(awful.util.table.join(
awful.button({ }, 4, function () volumectl("up", volumewidget) end),
awful.button({ }, 5, function () volumectl("down", volumewidget) end),
awful.button({ }, 3, function () awful.util.spawn("pavucontrol") end),
awful.button({ }, 1, function () volumectl("mute", volumewidget) end)
))
volumectl("update", volumewidget)
--}}}
-- {{{ GitHub contribution indicator
github_contributed = awful.util.getdir("config") .. "/image/github_contributed.png"
github_not_contributed = awful.util.getdir("config") .. "/image/github_not_contributed.png"
github_widget = wibox.widget.imagebox()
function update_github(has_contributions)
if has_contributions then
github_widget:set_image(github_contributed)
else
github_widget:set_image(github_not_contributed)
end
end
update_github(false)
-- }}}
-- }}}
-- {{{ Create a wibox for each screen and add it
mywibox = {}
mypromptbox = {}
mylayoutbox = {}
mytaglist = {}
mytaglist.buttons = awful.util.table.join(
awful.button({ }, 1, awful.tag.viewonly),
awful.button({ modkey }, 1, awful.client.movetotag),
awful.button({ }, 3, awful.tag.viewtoggle),
awful.button({ modkey }, 3, awful.client.toggletag),
awful.button({ }, 4, function(t) awful.tag.viewprev(awful.tag.getscreen(t)) end),
awful.button({ }, 5, function(t) awful.tag.viewnext(awful.tag.getscreen(t)) end)
)
mytasklist = {}
mytasklist.buttons = awful.util.table.join(
awful.button({ }, 1, function (c)
if c == client.focus and not c.minimized then
c.minimized = true
else
-- Without this, the following
-- :isvisible() makes no sense
c.minimized = false
if not c:isvisible() then
awful.tag.viewonly(c:tags()[1])
end
-- This will also un-minimize
-- the client, if needed
client.focus = c
c:raise()
end
end),
awful.button({ }, 2, function (c)
c:kill()
end),
awful.button({ }, 3, function ()
if instance then
instance:hide()
instance = nil
else
instance = awful.menu.clients({ width=250 * scale })
end
end),
awful.button({ }, 4, function ()
awful.client.focus.byidx(1)
if client.focus then client.focus:raise() end
end),
awful.button({ }, 5, function ()
awful.client.focus.byidx(-1)
if client.focus then client.focus:raise() end
end))
for s = 1, screen.count() do
-- Create a promptbox for each screen
mypromptbox[s] = awful.widget.prompt()
-- Create an imagebox widget which will contains an icon indicating which layout we're using.
-- We need one layoutbox per screen.
mylayoutbox[s] = awful.widget.layoutbox(s)
mylayoutbox[s]:buttons(awful.util.table.join(
awful.button({ }, 1, function () awful.layout.inc(layouts, 1) end),
awful.button({ }, 3, function () awful.layout.inc(layouts, -1) end),
awful.button({ }, 4, function () awful.layout.inc(layouts, 1) end),
awful.button({ }, 5, function () awful.layout.inc(layouts, -1) end)))
-- Create a taglist widget
mytaglist[s] = awful.widget.taglist(s, awful.widget.taglist.filter.all, mytaglist.buttons)
-- Create a tasklist widget
mytasklist[s] = awful.widget.tasklist(s, awful.widget.tasklist.filter.currenttags, mytasklist.buttons)
-- Create the wibox
mywibox[s] = awful.wibox({ position = "top", screen = s, height = 18 * scale })
if s == 2 then
mywibox[s]:set_fg('#ffffff')
end
-- Widgets that are aligned to the left
local left_layout = wibox.layout.fixed.horizontal()
left_layout:add(mylauncher)
left_layout:add(mytaglist[s])
left_layout:add(mypromptbox[s])
-- Widgets that are aligned to the right
local right_layout = wibox.layout.fixed.horizontal()
-- screen 2 is e-ink
if s == 1 then
right_layout:add(memwidget)
right_layout:add(cputempwidget)
right_layout:add(batwidget)
right_layout:add(netwidget)
right_layout:add(volumewidget)
end
if s == 1 then right_layout:add(wibox.widget.systray()) end
if s == 1 then
right_layout:add(mytextclock)
right_layout:add(github_widget)
else
mytextclock2 = awful.widget.textclock(" %Y年%m月%d日 %H:%M %A ", 1)
right_layout:add(mytextclock2)
end
right_layout:add(mylayoutbox[s])
-- Now bring it all together (with the tasklist in the middle)
local layout = wibox.layout.align.horizontal()
layout:set_left(left_layout)
layout:set_middle(mytasklist[s])
layout:set_right(right_layout)
mywibox[s]:set_widget(layout)
end -- }}}
-- }}}
-- {{{ Mouse bindings
root.buttons(awful.util.table.join(
awful.button({ }, 3, function () mymainmenu:toggle() end),
awful.button({ }, 4, awful.tag.viewprev),
awful.button({ }, 5, awful.tag.viewnext)
))
-- }}}
-- {{{ Key bindings
-- {{{ Functions
local movebyrelidx = function (n, view) -- {{{
-- view: 要转到那个 tag 吗?
local screen = mouse.screen
local which = (revtags[screen][awful.tag.selected()]+n) % #tags[screen]
if which == 0 then which = #tags[screen] end
if client.focus and tags[client.focus.screen][which] then
awful.client.movetotag(tags[client.focus.screen][which])
end
if view and tags[screen][which] then
awful.tag.viewonly(tags[screen][which])
end
end -- }}}
local keynumber_reg = function (i, which) -- {{{
if not which then
which = i
end
globalkeys = awful.util.table.join(globalkeys,
awful.key({ modkey }, i,
function ()
local screen = mouse.screen
if tags[screen][which] then
awful.tag.viewonly(tags[screen][which])
end
end),
awful.key({ modkey, "Control" }, i,
function ()
local screen = mouse.screen
if tags[screen][which] then
awful.tag.viewtoggle(tags[screen][which])
end
end),
awful.key({ modkey, "Shift" }, i,
-- 移动窗口后跳转过去
function ()
if client.focus and tags[client.focus.screen][which] then
awful.client.movetotag(tags[client.focus.screen][which])
end
local screen = mouse.screen
if tags[screen][which] then
awful.tag.viewonly(tags[screen][which])
end
end),
awful.key({ modkey, "Mod1" }, i,
-- 只移动窗口,不跳转过去
function ()
if client.focus and tags[client.focus.screen][which] then
awful.client.movetotag(tags[client.focus.screen][which])
end
end),
awful.key({ modkey, "Control", "Shift" }, i,
function ()
if client.focus and tags[client.focus.screen][which] then
awful.client.toggletag(tags[client.focus.screen][which])
end
end))
end -- }}}
-- {{{ per client keys
tm_keys = {
['alt+1'] = 'ctrl+1',
['alt+2'] = 'ctrl+2',
['alt+3'] = 'ctrl+3',
['alt+4'] = 'ctrl+4',
['alt+5'] = 'ctrl+5',
['alt+6'] = 'ctrl+6',
['alt+7'] = 'ctrl+7',
['alt+8'] = 'ctrl+8',
['alt+9'] = 'ctrl+9',
-- 上/下一个标签页
['ctrl+Page_Up'] = 'ctrl+Left',
['ctrl+Page_Down'] = 'ctrl+Right',
}
-- not work, see https://bugs.launchpad.net/ubuntu/+source/xdotool/+bug/1011333
evince_keys = {
b = 'Page_Up',
}
emacs_keys = {
['ctrl+f'] = 'Right',
['ctrl+b'] = 'Left',
['ctrl+p'] = 'Up',
['ctrl+n'] = 'Down',
['ctrl+a'] = 'ctrl+Home',
['ctrl+e'] = 'ctrl+End',
-- the following two doesn't work with Qt (4 & 5) programs
['alt+f'] = 'ctrl+Right',
['alt+b'] = 'ctrl+Left',
}
-- }}}
-- }}}
-- {{{ globalkeys
globalkeys = awful.util.table.join(
awful.key({ modkey, }, "Left", awful.tag.viewprev ),
awful.key({ modkey, }, "Right", awful.tag.viewnext ),
awful.key({ modkey, }, "Escape", awful.tag.history.restore),
awful.key({ modkey, }, "j",
function ()
awful.client.focus.byidx( 1)
if client.focus then client.focus:raise() end
end),
awful.key({ modkey, }, "k",
function ()
awful.client.focus.byidx(-1)
if client.focus then client.focus:raise() end
end),
awful.key({ modkey, }, "w", function () mymainmenu:show() end),
-- Layout manipulation
awful.key({ modkey, "Shift" }, "j", function () awful.client.swap.byidx( 1) end),
awful.key({ modkey, "Shift" }, "k", function () awful.client.swap.byidx( -1) end),
awful.key({ modkey, "Control" }, "j", function () awful.screen.focus_relative( 1) end),
awful.key({ modkey, "Control" }, "k", function () awful.screen.focus_relative(-1) end),
awful.key({ modkey, }, "u", awful.client.urgent.jumpto),
awful.key({ modkey, }, "Tab",
function ()
awful.client.focus.history.previous()
if client.focus then
client.focus:raise()
end
end),
-- Standard program
awful.key({ modkey, }, "Return",
function ()
-- Go and find a terminal for me
myutil.run_or_raise("xfce4-terminal --role=TempTerm --geometry=80x24+401+205", { role = "TempTerm" })
end),
awful.key({ modkey, "Control" }, "r", awesome.restart),
awful.key({ modkey, "Control" }, "q", awesome.quit),
awful.key({ modkey, }, "l", function () awful.tag.incmwfact( 0.05) end),
awful.key({ modkey, }, "h", function () awful.tag.incmwfact(-0.05) end),
awful.key({ modkey, "Shift" }, "h", function () awful.tag.incnmaster( 1) end),
awful.key({ modkey, "Shift" }, "l", function () awful.tag.incnmaster(-1) end),
awful.key({ modkey, "Control" }, "h", function () awful.tag.incncol( 1) end),
awful.key({ modkey, "Control" }, "l", function () awful.tag.incncol(-1) end),
awful.key({ modkey, }, "space", function () awful.layout.inc(layouts, 1) end),
awful.key({ modkey, "Shift" }, "space", function () awful.layout.inc(layouts, -1) end),
awful.key({ modkey, "Shift" }, "s",
function ()
-- because they may be not focusable
local c = mouse.object_under_pointer()
if c then
c.sticky = not c.sticky
end
end),
-- Prompt
awful.key({ modkey }, "r", function () mypromptbox[mouse.screen]:run() end),
awful.key({ "Mod1" }, "F2", function () awful.util.spawn('xfce4-appfinder', false) end),
awful.key({ modkey, "Shift" }, "x", function () awful.util.spawn('openmsg_qq.py', false) end),
-- Menubar
awful.key({ modkey, "Mod1" }, "p", function() menubar.show() end),
-- Switching tags
awful.key({ modkey, }, "p", awful.tag.viewprev ),
awful.key({ modkey, }, "n", awful.tag.viewnext ),
awful.key({ modkey, "Shift" }, "p",
function ()
movebyrelidx(-1, true)
end),
awful.key({ modkey, "Shift" }, "n",
function ()
movebyrelidx(1, true)
end),
-- Screenshot
awful.key({ }, "Print",
function ()
awful.util.spawn_with_shell('maim ~/tmpfs/$(date +"%Y-%m-%d_%H:%M:%S").png')
naughty.notify({title="截图", text="全屏截图已保存。"})
end),
-- Alt-Tab
awful.key({ "Mod1", }, "Tab",
function ()
awful.client.focus.byidx( 1)
if client.focus then client.focus:raise() end
end),
awful.key({ "Mod1", "Shift" }, "Tab",
function ()
awful.client.focus.byidx(-1)
if client.focus then client.focus:raise() end
end),
-- Unminimize clients
awful.key({ modkey, "Control" }, "m",
function ()
local allclients = client.get(mouse.screen)
for _, c in ipairs(allclients) do
if c.minimized and c:tags()[mouse.screen] == awful.tag.selected(mouse.screen) then
c.minimized = false
client.focus = c
c:raise()
return
end
end
end),
-- My programs
awful.key({ modkey, }, "g", function () awful.util.spawn("gvim") end),
awful.key({ "Control", "Mod1", "Shift" }, "x", function () awful.util.spawn("xkill") end),
awful.key({ "Control", "Mod1" }, "l", function () awful.util.spawn("leave") end),
awful.key({ modkey, }, "x", function () awful.util.spawn("openmsg.py", false) end),
awful.key({ modkey, }, "t", function () awful.util.spawn(terminal) end),
awful.key({ modkey, "Shift" }, "Return",
function ()
awful.util.spawn("xfce4-terminal --role=TempTerm --geometry=80x24+343+180")
end),
-- htop
awful.key({ modkey, }, "z",
function ()
if client.focus and client.focus.role == 'FullScreenHtop' then
awful.client.movetotag(tags[mouse.screen][10], client.focus)
else
myutil.run_or_raise("xfce4-terminal --role=FullScreenHtop -e 'htop'", { role = "FullScreenHtop" })
end
end),
-- My floating windows -> tag10
awful.key({ modkey, }, "q",
function ()
local c = client.focus
if not c then return end
if c.role == 'FullScreenHtop' or c.role == 'TempTerm' then
awful.client.movetotag(tags[mouse.screen][10], c)
end
end),
-- sdcv
awful.key({ modkey }, "d",
function ()
local new_word = selection()
if _dict_notify ~= nil then
naughty.destroy(_dict_notify)
_dict_notify = nil
if _old_word == new_word then
return
end
end
_old_word = new_word
local fc = ""
local f
if new_word:match("%d+%.%d+%.%d+%.%d+") then
f = io.popen("cip "..new_word)
elseif new_word:match(':') and new_word:match("[0-9a-fA-F:]+") then
f = io.popen("cip "..new_word)
else
f = io.popen("sdcv -n --utf8-output -u 'stardict1.3英汉辞典' '"..new_word.."'")
end
for line in f:lines() do
fc = fc .. line .. '\n'
end
f:close()
_dict_notify = naughty.notify({ text = fc, timeout = 5, width = 320 * scale })
end),
awful.key({ modkey, "Shift" }, "d", function ()
awful.util.spawn('ydcv-notify')
end),
-- Volume
awful.key({ }, 'XF86AudioRaiseVolume', function () volumectl("up", volumewidget) end),
awful.key({ }, 'XF86AudioLowerVolume', function () volumectl("down", volumewidget) end),
awful.key({ }, 'XF86AudioMute', function () volumectl("mute", volumewidget) end)
) -- }}}
-- {{{ clientkeys
clientkeys = awful.util.table.join(
awful.key({ modkey, }, "f", function (c) c.fullscreen = not c.fullscreen end),
awful.key({ modkey, }, "c", function (c) c:kill() end),
awful.key({ modkey, "Control" }, "space", awful.client.floating.toggle ),
awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end),
awful.key({ modkey, }, "o", awful.client.movetoscreen ),
awful.key({ modkey, }, "a", function (c) c.above = not c.above end),
awful.key({ modkey, }, "s", function (c) c.sticky = not c.sticky end),
awful.key({ modkey, "Shift" }, "m",
function (c)
-- The client currently has the input focus, so it cannot be
-- minimized, since minimized clients can't have the focus.
c.minimized = true
end),
awful.key({ modkey, }, "m",
function (c)
c.maximized_horizontal = not c.maximized_horizontal
c.maximized_vertical = not c.maximized_vertical
end),
awful.key({ modkey, "Shift" }, "c",
function (c)
if not awful.client.floating.get(c) then return end
awful.placement.centered(c)
end)
) -- }}}
-- {{{ Switching to the numbered tag
do
local keynumber = math.min(9, #tags[1]);
for i = 1, keynumber do
keynumber_reg(i)
end
if #tags[1] >= 10 then
keynumber_reg(0, 10)
end
end
-- }}}
-- {{{ clientbuttons
clientbuttons = awful.util.table.join(
awful.button({ }, 1, function (c)
client.focus = c
if c.class and (c.class == 'Gimp' or c.class == 'Gimp-2.8') then
else
c:raise()
end
end),
awful.button({ modkey }, 1, awful.mouse.client.move),
awful.button({ modkey }, 2, function (c) client.focus = c; c:kill() end),
awful.button({ modkey }, 3, function (c) awful.mouse.client.resize(c, "bottom_right") end))
-- }}}
-- Set keys
root.keys(globalkeys)
-- }}}
-- {{{ Rules
local old_filter = awful.client.focus.filter
function myfocus_filter(c)
if old_filter(c) then
-- TM.exe completion pop-up windows
if (c.instance == 'tm.exe' or c.instance == 'TIM.exe')
and c.above and c.skip_taskbar
and (c.type == 'normal' or c.type == 'dialog') -- dialog type is for tooltip windows
and (c.class == 'qq.exe' or c.class == 'QQ.exe' or c.class == 'TIM.exe') then
return nil
-- This works with tooltips and some popup-menus
elseif c.class == 'Wine' and c.above == true then
return nil
elseif c.class == 'WeChat.exe' and (
c.name == 'CMenuWnd' or not c.name
or c.name == 'SessionChatRoomDetailWnd'
) then -- 微信菜单
c.border_width = 0
do return nil end
elseif (c.class == 'Wine' or c.class == 'QQ.exe' or c.class == 'qq.exe')
and c.type == 'dialog'
and c.skip_taskbar == true
and c.size_hints.max_width and c.size_hints.max_width < 160
then
-- for popup item menus of Photoshop CS5
return nil
-- popups for Settings page in Firefox
elseif c.skip_taskbar and c.instance == 'Popup' and c.class == 'Firefox' then
return nil
elseif c.class == 'Key-mon' then
return nil
else
return c
end
end
end
awful.client.focus.filter = myfocus_filter
awful.rules.rules = {
-- All clients will match this rule.
{
rule = { },
properties = {
border_width = beautiful.border_width,
border_color = beautiful.border_normal,
focus = myfocus_filter,
keys = clientkeys,
buttons = clientbuttons,
}
}, {
rule = { class = "Screenruler" },
properties = {
floating = true,
focus = false,
border_width = 0,
}
}, {
rule = { role = "FullScreenHtop" },
properties = {
maximized_horizontal = true,
maximized_vertical = true,
}
}, {
rule = { class = "Firefox", instance = "firefox" },
properties = { floating = true }
}, {
rule = {
class = "Firefox",
skip_taskbar = true,
instance = 'Popup',
},
properties = {
floating = true,
border_width = 0,
}
}, {
rule = {
class = "Nightly",
skip_taskbar = true,
instance = 'Popup',
},
properties = {
floating = true,
border_width = 0,
}
}, {
rule = { class = "Wireshark", name = "Wireshark" }, -- wireshark startup window
properties = { floating = true }
}, {
rule_any = {
instance = {
'qq.exe', 'QQ.exe', 'TIM.exe',
'QQExternal.exe', -- QQ 截图
'deepin-music-player',
'wechat.exe', 'wechatupdate.exe',
},
},
properties = {
-- This, together with myfocus_filter, make the popup menus flicker taskbars less
-- Non-focusable menus may cause TM2013preview1 to not highlight menu
-- items on hover and crash.
-- Also for deepin-music, removing borders and floating pop-ups
focusable = true,
floating = true,
border_width = 0,
}
}, {
rule = {
-- mainly for picpick
class = "Wine",
above = true,
},
properties = {
floating = true,
border_width = 0,
}
}, {
rule = {
-- for WinHex
class = "Wine",
instance = "WinHex.exe",
name = "数据解释器",
},
properties = {
floating = true,
border_width = 0,
}
}, {
rule = {
class = "Wine",
skip_taskbar = true,
type = "dialog",
},
callback = function (c)
if c.size_hints.max_width and c.size_hints.max_width < 160 then
-- for popup item menus of Photoshop CS5
c.border_width = 0
end
end,
}, {
rule = {
-- 白板的工具栏
name = 'frmPresentationTool',
instance = 'picpick.exe',
},
properties = {
ontop = true,
}
}, {
rule_any = {
class = {
'Flashplayer', 'Gnome-mplayer', 'Totem',
'Eog', 'feh', 'Display', 'Gimp', 'Gimp-2.6',
'Screenkey', 'TempTerm', 'AliWangWang',
'Dia', 'Pavucontrol', 'Stardict', 'XEyes', 'Skype',
'Xfce4-appfinder', 'Pinentry',
"/usr/lib/firefox/plugin-container",
"/opt/firefox-nightly/plugin-container",
'WeChat.exe',
},
name = {
'文件传输', 'Firefox 首选项', '暂存器', 'Keyboard',
},
instance = {
'Browser', -- 火狐的关于对话框
'MATLAB', -- splash
},
role = {
'TempTerm',
},
},
properties = {
floating = true,
}
}, {
rule = {
instance = "xfce4-notifyd",
},
properties = {
border_width = 0,
focus = false,
}
}, {
rule = {
class = "Key-mon",
},
properties = {
border_width = 0,
focus = false,
focusable = false,
opacity = 0.65,
sticky = true,
}
},
}
-- }}}
-- {{{ Signals
-- Signal function to execute when a new client appears.
qqad_blocked = 0
client.connect_signal("manage", function (c, startup)
-- Enable sloppy focus
c:connect_signal("mouse::leave", function(c)
if awful.layout.get(c.screen) ~= awful.layout.suit.magnifier
and myfocus_filter(c) then
client_unfocused = c.window
end
end)
c:connect_signal("mouse::enter", function(c)
-- 如果离开后又进入同一窗口则忽略,这解决了由于输入条而造成的焦点移动
if client_unfocused ~= c.window
and awful.layout.get(c.screen) ~= awful.layout.suit.magnifier
and myfocus_filter(c) then
client.focus = c
end
end)
if not startup then
-- Set the windows at the slave,
-- i.e. put it at the end of others instead of setting it master.
-- awful.client.setslave(c)
-- Put windows in a smart way, only if they does not set an initial position.
if not c.size_hints.user_position and not c.size_hints.program_position then
awful.placement.no_overlap(c)
awful.placement.no_offscreen(c)
end
end
if c.instance == 'empathy-chat' or (c.role == 'conversation' and c.class == 'Pidgin') then
local t
t = c:tags()
if #t == 1 and t[1] == tags[mouse.screen][6] then
awful.util.spawn_with_shell('sleep 0.1 && fcitx-remote -T', false)
else
awful.client.movetotag(tags[mouse.screen][6], c)
end
elseif c.class == 'qTox' then
map_client_key(c, emacs_keys)
elseif c.class == 'Evince' then
map_client_key(c, evince_keys)
elseif c.name == '中文输入' then
awful.util.spawn_with_shell('sleep 0.05 && fcitx-remote -T', false)
elseif c.instance == 'QQ.exe' or c.instance == 'qq.exe' then
-- naughty.notify({title="新窗口", text="名称为 ".. c.name ..",class 为 " .. c.class:gsub('&', '&amp;') .. " 的窗口已接受管理。", preset=naughty.config.presets.critical})
if c.name and (c.name == '腾讯网迷你版' or c.name == '京东' or c.name:match('^腾讯.+新闻$')) then
qqad_blocked = qqad_blocked + 1
naughty.notify({title="QQ广告屏蔽 " .. qqad_blocked, text="检测到一个符合条件的窗口,标题为".. c.name ..""})
c:kill()
else
map_client_key(c, tm_keys)
map_client_key(c, emacs_keys)
end
elseif c.class == 'MPlayer' or c.class == 'mpv' then
awful.client.floating.set(c, true)
awful.placement.centered(c)
end
end)
client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end)
client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end)
-- }}}
-- {{{ other things
pcall(function()
package.cpath = package.cpath .. ';/home/lilydjwg/scripts/lua/cmod/?.so'
local clua = require('clua')
clua.setsubreap(true)
clua.ignore_SIGCHLD()
local pid = 1
while pid > 0 do
_, pid = clua.reap()
end
end)
awful.util.spawn("awesomeup", false)
awful.tag.viewonly(tags[1][6])
-- vim: set fdm=marker et sw=4:
-- }}}
You can’t perform that action at this time.