Hi,
first: sorry for taking so long to answer. Also, fear not, list, I'm
replying to both Vlamy's mails in this one.
I, too, am relying heavily on that run_or_raise function found on the
wiki. And the I've this little shellscript, that implements a
run_or_raise functionality for terminal programs running in tmux(1).
Browsed your code, seems like a nice modular approach, but I was already
into modifying the 'modal keybindings' approach, that too is found on
the wiki.
I've settled to some funny binds in my workflow, and have attached my
actual rc.lua if anyone cares to try it out. Beware, it's a really
minimal, KISS, configuration. A little synapsis is included at the
beginning of the file.
The reason I asked the initial question was, that the current system of
reading keyboard input relies on at least one client being active (which
seldom to never happens, 'cause there's always at least one urxvtc(1)
window open on my battlestation ;)
cheers, mih
Willy Malvault (vlamy) writes:
> Le 31/10/2013 23:13, Michael Hauser a écrit :
> >Hi,
> >
> >quick question: why the distinction between global and client keys and
> >how to unify?
> From what I understood, in default rc.lua : functions associated to keys in
> clientkeys take a client as parameter (often referenced as parameter "c"),
> while global keys don't. But nothing prevent you to unify both (to confirm).
> >
> >Perhaps I just don't see how to adress a focused client with global key
> >bindings?
> I don't understand your problem, as default rc.lua already does that, at
> least for maximize/redraw,....
> >
> >I'm in the process of implementing a modal UI (vim like) and don't want
> >the need of a second key, if no client is on the screen…
> I did something like this (with my own understanding of what a modal UI is),
> which might help/inspire you :
> https://github.com/Vlamy/dotfiles/blob/master/awesome/furious.lua
>
> Ok ! Its draft, and I planned some month ago to clean it an publish, but
> .... :)
>
> Anyway, it implements modal behavior as it allows to define modes to wich
> you can associate keys. I used it to implement "run_or_raise", "catch" (i.e.
> bring target client to current tag" and "dropdowm" behavior with client, but
> it also work with global keys (tested, even if I found it useless with
> global actions).
>
> For example with Gvim and Urxvt :
>
> * ROR mode (mod + "t"):
> o mod + "t" + "e" --> "run_or_raise Gvim"
> o mod + "t" + "s" --> "run_or_raise urxvt"
>
> * catch mode (mod + "s"):
> o mod + "s" + "e" --> "grab Gvim"
> o mod + "s" + "t" l--> "grab urxvt"
>
> * drop mode (mod + "r"):
> o mod + "r" + "e" lanch "dropdown Gvim"
> o mod + "r" + "s" lanch "dropdown urxvt"
>
> It's useful to me, but I don't know if it will suite to your needs.
>
> It's GPL, but if you wan't to pick something and release later under a less
> restrictive license, I can modify the license on request.
>
> I hope it's heplful for you (and maybe for other awesome fans).
> Do not hesitate to ask questions about the code :)
>
> Vlamy.
> >
> >
> >BTW, awesome rocks!
> >
> >
> >cheers, mih
> >
>
--
'aware water' is an anagram for 'we are at war'
--[[ tessellated's awesome rc.lua
following the KISS principle
• use two layouts, `max' (default) or `tiled.top'
• vim(1)like modal binds, see `mdy'
» manipulate (move, resize, …) clients with keyboard
» extra binds for » Asus EeePC HP 1015PX
» Apple
wireless keyboard
» no rat/touchpad needed, limited support
• run or raise » most programs
» terminal apps in tmux(1)
• dmenu(1) to start programs
• wibox just tasklist » hidden by default,
autohide
» no
widgets
» no icons
• dynamic tagging thanks to `tyrannical'
• eyecandy » no borders
» no titlebars
» no wallpaper (use black root)
» no X11 startup notification
» compton(1) for shadows/fading
usage tips:
• always have one urxvtc(1) named `terminal' running,
to ensure that at least one client is visible
--]]
-- 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")
-- Dynamic tagging library
local tyrannical = require("tyrannical")
-- {{{ 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
local modkey = "Mod4"
-- Themes define colours, icons, and wallpapers
beautiful.init("/usr/share/awesome/themes/default/theme.lua")
theme.font = "Terminus 20"
theme.fg_normal = "#555555"
theme.fg_focus = "#aaaaaa"
theme.fg_minimize = "#111111"
theme.bg_normal = "#000000"
theme.bg_focus = theme.bg_normal
theme.bg_minimize = theme.bg_normal
theme.border_width = 0
theme.tasklist_disable_icon = true
--theme.wallpaper = nil
theme.wallpaper =
"/home/mih/.config/awesome/black_1024x600.png"
-- This is used later as the default terminal and editor to run.
local terminal = "terminal"
local editor = os.getenv("EDITOR") or "vim"
local editor_cmd = terminal .. " -e " .. editor
local titlebars_enabled = nil
local wibox_autohide_seconds = 7
local mdy = {
-- I'm using XkbLayout:us, so KP_Add is mapped to
-- the useless `><|' key next to Shift_L on my German keyboards,
-- eg.: xmodmap -e "keycode 94 = KP_Add KP_Subtract"
trigger = "KP_Add",
-- mode indication
prompt = {
client = "client",
layout = "layout",
eeepc = "EeePC",
normal = ":"
},
position = "bottom_left",
bg = "#114211",
-- echo = true, echo_timeout = .5,
-- move or resize steps in pixels
x = 16,
y = 16,
key = {
-- also see globalkeys/clientkeys for more binds
Return = function () ror( terminal,{ name = "terminal" })
end,
Tab = function () awful.client.focus.history.previous()
if client.focus
then
client.focus:raise()
end end,
Esacape = function (c) c:swap(awful.client.getmaster()) end,
Shift_L = function () ror( "luakit.zsh", { class = "luakit"
}) end,
Shift_R = function () -- Right Shift == Redshift !!! ☺
awful.util.spawn( "redshift.zsh
--toggle") end,
Super_L = function () awful.util.spawn( "xzoom.zsh" ) end,
Super_R = function () -- Super_R mapped to Menu key
awful.util.spawn( "dmenu.zsh")
end,
-- didn't work suddenly
-- Alt_L = function () -- Alt_L == Alternative Layout
-- awful.layout.inc(layouts, 1)
end,
Delete = function () awful.util.spawn( "lock.zsh" ) end,
a = function () ror( terminal, {name = "terminal" })
awful.util.spawn (
"aware-run.sh ncmpc" ) end,
b = function () ror( terminal, {name = "terminal" })
awful.util.spawn (
"aware-run.sh bmon" ) end,
c = function () ror( terminal, {name = "terminal" })
awful.util.spawn (
"aware-run.sh irssi" ) end,
d = function (c) c:kill() end,
e = function () ror( terminal,{ name = "terminal" })
awful.util.spawn (
"aware-run.sh notes" ) end,
f = function () awful.util.spawn( "sysinfo.zsh --notify" ) end,
g = function () ror( "gimp --no-splash", { class = "Gimp" })
end,
h = function () ror( terminal,{ name = "terminal" })
awful.util.spawn (
"aware-run.sh htop" ) end,
i = function () awful.util.spawn( "i" ) end,
j = function(c) c.minimized = true end,
k = awful.client.restore,
-- l =
m = function () ror( terminal,{ name = "terminal" })
awful.util.spawn (
"aware-run.sh mutt" ) end,
n = function () ror( terminal,{ name = "terminal" })
awful.util.spawn (
"aware-run.sh newsbeuter" ) end,
o = function (c) c.ontop = not c.ontop end,
p = function () ror( terminal,{ name = "terminal" })
awful.util.spawn (
"aware-run.sh top" ) end,
-- q = do nothing in `normal mode'
r = function (c) c:redraw() end,
s = function () ror( terminal,{ name = "terminal" })
awful.util.spawn (
"aware-run.sh root" ) end,
t = function () ror( terminal, {name = "terminal" })
awful.util.spawn (
"aware-run.sh rtorrent" ) end,
u = awful.client.urgent.jumpto,
v = function () ror( terminal,{ name = "terminal" })
awful.util.spawn (
"aware-run.sh alsamixer" ) end,
w = function (c) mywibox_toggle () end,
-- x = client manipulation
y = awful.client.togglemarked,
z = function () ror( terminal,{ name = "terminal" })
awful.util.spawn (
"aware-run.sh zsh" ) end
}
}
-- Table of layouts to cover with awful.layout.inc, order matters.
local layouts = {
awful.layout.suit.max,
awful.layout.suit.tile.top
--[[ # DON'T FORGET THE COMMA !!!
awful.layout.suit.fair.horizontal
awful.layout.suit.tile.bottom
awful.layout.suit.tile
awful.layout.suit.floating,
awful.layout.suit.tile.left,
awful.layout.suit.fair,
awful.layout.suit.spiral,
awful.layout.suit.spiral.dwindle,
awful.layout.suit.max.fullscreen,
awful.layout.suit.magnifier
--]]
}
-- }}}
---[[ Wallpaper
if beautiful.wallpaper then
for s = 1, screen.count() do
gears.wallpaper.maximized(beautiful.wallpaper, s, true)
end
end
--]]
--[[ Dynamic tagging, see `tyrannical'…
-- Define a tag table which hold all screen tags.
tags = {}
for s = 1, screen.count() do
-- Each screen has its own tag table.
tags[s] = awful.tag({ 1, 2, 3, 4, 5, 6, 7, 8, 9 }, s, layouts[1])
end
--]]
tyrannical.settings.default_layout = awful.layout.suit.max
tyrannical.tags = {
{
name = "terminal",
init = true,
floating = false,
--screen = {1,1}, -- Create this tag on
screen 1 and screen 2
--layout = awful.layout.suit.max, -- Use the max layout
--icon = "~net.png", -- Use this icon for the tag
(uncomment with a real path)
-- exclusive = true, -- Refuse any other type of
clients (by classes)
class = { --Accept the following classes, refuse everything else
(because of "exclusive=true")
"urxvt" , "XTerm", "xev"
}
},
{
name = "www", init = false,
-- exclusive = true,
-- screen = screen.count()>1 and 2 or 1,-- Setup on screen 2 if
there is more than 1 screen, else on screen 1
class = { "luakit", "Opera", "Firefox", "Dillo", "Chromium" }
},
{ name = "media", init = false,
class = { "mpv", "vlc" }
},
{ name = "images", init = false,
class = { "feh" }
},
{ name = "gfx", init = false,
class = { "Blender", "Gimp", "Inkscape" }
},
--[[ {
name = "Files",
init = true,
exclusive = true,
screen = 1,
layout = awful.layout.suit.tile,
exec_once = {"dolphin"}, --When the tag is accessed for the first
time, execute this command
class = {
"Thunar", "Konqueror", "Dolphin", "ark", "Nautilus","emelfm"
}
},
{
name = "Develop",
init = true,
exclusive = true,
screen = 1,
clone_on = 2, -- Create a single instance of this tag on screen 1,
but also show it on screen 2
-- The tag can be used on both screen, but only one at
once
layout = awful.layout.suit.max ,
class ={
"Kate", "KDevelop", "Codeblocks", "Code::Blocks" , "DDD", "kate4"}
},
{
name = "Doc",
init = false, -- This tag wont be created at startup, but will
be when one of the
-- client in the "class" section will start. It
will be created on
-- the client startup screen
exclusive = true,
layout = awful.layout.suit.max,
class = {
"Assistant" , "Okular" , "Evince" , "EPDFviewer" ,
"xpdf",
"Xpdf" , }
},
--]]
}
-- Ignore the tag "exclusive" property for the following clients (matched by
classes)
tyrannical.properties.intrusive = {
"pinentry", "gtksu", "xcalc", "Gradient editor",
"Paste Special", "Background color","kcolorchooser",
"plasmoidviewer", "Xephyr", "plasmaengineexplorer"
}
-- Ignore the tiled layout for the matching clients
tyrannical.properties.floating = {
"gtksu", "Gimp", "xcalc", "yakuake", "Select Color$", "New Form", "Insert
Picture"
}
-- Make the matching clients (by classes) on top of the default layout
tyrannical.properties.ontop = {
"Xephyr"
}
-- Force the matching clients (by classes) to be centered on the screen on init
tyrannical.properties.centered = {
"xchrom"
}
tyrannical.settings.block_children_focus_stealing = true --Block popups ()
tyrannical.settings.group_children = true --Force popups/dialogs to have the
same tags as the parent client
-- {{{ Menu
--[[ Create a laucher widget and a main menu
myawesomemenu = {
--{ "manual", terminal .. " -e man awesome" },
--{ "edit config", editor_cmd .. " " .. awesome.conffile },
{ "restart", awesome.restart },
{ "quit", awesome.quit }
}
mymainmenu = awful.menu({
items = { { "awesome", myawesomemenu, beautiful.awesome_icon },
{ "open terminal", terminal }
}})
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()
--]]
--[[ Battery indiacator widget, fed by shellscript
mybatteryprogressbar = awful.widget.progressbar()
mybatteryprogressbar:set_width(42)
--mybatteryprogressbar:set_height(wibox_height)
mybatteryprogressbar:set_vertical(false)
mybatteryprogressbar:set_background_color('#663311')
mybatteryprogressbar:set_color('#004422')
mybatteryprogressbar:set_value(1)
--]]
-- 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.viewnext(awful.tag.getscreen(t)) end),
awful.button({ }, 5, function(t)
awful.tag.viewprev(awful.tag.getscreen(t)) end)
)
mytasklist = {}
mytasklist.buttons = awful.util.table.join(
awful.button({ }, 1, function (c)
if c == client.focus 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),
--[[ client menu
awful.button({ }, 3, function ()
if instance then
instance:hide()
instance = nil
else
instance =
awful.menu.clients({ width=250 })
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)))
-- 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 = "bottom", height = "24", ontop =
true, screen = s })
-- wibox autohide signals.
mywibox[s]:connect_signal("mouse::enter", function ()
mywibox_autohide:stop()
end)
mywibox[s]:connect_signal("mouse::leave", function ()
mywibox_autohide.timeout = wibox_autohide_seconds
mywibox_autohide:start()
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(mytext)
--left_layout:add(mypromptbox[s])
-- Widgets that are aligned to the right
local right_layout = wibox.layout.fixed.horizontal()
if s == 1 then right_layout:add(wibox.widget.systray()) end
--right_layout:add(mybatteryprogressbar)
--right_layout:add(mytextclock)
--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
---[[ Hide wibox at startup.
mywibox[mouse.screen].visible = false
--]]
-- Autohide wibox.
mywibox_autohide = timer { timeout = wibox_autohide_timeout }
mywibox_autohide:connect_signal("timeout", function()
mywibox[mouse.screen].visible = false
mywibox_autohide:stop()
end)
-- }}}
---[[ Rat binds
root.buttons(awful.util.table.join(
awful.button({ }, 1, awful.tag.viewnext),
awful.button({ }, 3, awful.tag.viewprev)
))
--]]
-- {{{ Key binds
globalkeys = awful.util.table.join(
awful.key({ modkey }, mdy.trigger, function(c)
local mdy_verbosity = naughty.notify({ text =
mdy.prompt.normal, bg = mdy.bg, position = mdy.position, timeout = 0 }),id
keygrabber.run(function(mod, key, event)
if event == "release" then return true end
naughty.destroy( mdy_verbosity )
if mdy.echo then
naughty.notify({ text = mdy.prompt.normal ..
key, bg = mdy.bg, position = mdy.position, timeout = mdy.echo_timeout })
end
keygrabber.stop()
if mdy.key[key] then
mdy.key[key](c)
end
return true
end)
end),
awful.key({ modkey }, "Tab", awful.tag.history.restore ),
awful.key({ modkey }, "Left", awful.tag.viewprev ),
awful.key({ modkey }, "Right", awful.tag.viewnext ),
awful.key({ modkey }, "Down",
function ()
awful.client.focus.byidx( 1)
if client.focus then client.focus:raise() end
end),
awful.key({ modkey }, "Up",
function ()
awful.client.focus.byidx(-1)
if client.focus then client.focus:raise() end
end),
---[[ Multimedia
awful.key({ modkey, "Shift" }, "Left", function () awful.util.spawn(
"mpc-notify.zsh prev") end),
awful.key({ modkey, "Shift" }, "Down", function () awful.util.spawn(
"mpc-notify.zsh toggle") end),
awful.key({ modkey, "Shift" },"Right", function () awful.util.spawn(
"mpc-notify.zsh next") end),
awful.key({ modkey, "Shift" }, "Up", function () awful.util.spawn(
"volume.zsh toggle" ) end),
awful.key({ modkey }, "Next", function () awful.util.spawn( "volume.zsh down" )
end),
awful.key({ modkey }, "Prior",function () awful.util.spawn( "volume.zsh up" )
end),
awful.key({ modkey }, "Home", function () awful.util.spawn( "xbacklight.zsh
decrease")end),
awful.key({ modkey }, "End", function () awful.util.spawn( "xbacklight.zsh
increase") end),
--]]
---[[ Screenshots
awful.key({ modkey }, "p", function () awful.util.spawn( "screenshot.zsh")
end),
awful.key({ modkey, "Shift" }, "p", function () awful.util.spawn(
"screenshot.zsh --view") end),
--]]
-- Hardware specific binds
---[[ Asus Eee PC 1015PX
awful.key({ } ,"XF86Launch1", function () awful.util.spawn( "true") end), --
Fn+F9
awful.key({ } ,"XF86Launch6", function () awful.util.spawn( "touchpad.zsh
toggle") end), -- Fn+space
--]]
---[[ Apple Wireless Keyboard
awful.key({ } ,"XF86MonBrightnessDown", function () awful.util.spawn(
"xbacklight.zsh decrease") end),
awful.key({ }, "XF86MonBrightnessUp", function () awful.util.spawn(
"xbacklight.zsh increase") end),
-- client key: XF86LaunchA == client.floating.toggle
awful.key({ }, "XF86LaunchB", function () awful.layout.inc(layouts, 1) end),
awful.key({ }, "XF86KbdBrightnessDown", awful.tag.viewnext),
awful.key({ }, "XF86KbdBrightnessUp", function () awful.util.spawn(
"sysinfo.zsh --notify" ) end),
awful.key({ }, "XF86AudioPrev", function () awful.util.spawn( "mpc-notify.zsh
prev") end),
awful.key({ }, "XF86AudioPlay", function () awful.util.spawn( "mpc-notify.zsh
toggle" ) end),
awful.key({ }, "XF86AudioNext", function () awful.util.spawn( "mpc-notify.zsh
next") end),
awful.key({ }, "XF86AudioMute", function () awful.util.spawn( "volume.zsh
toggle" ) end),
awful.key({ }, "XF86AudioLowerVolume", function () awful.util.spawn(
"volume.zsh down" ) end),
awful.key({ }, "XF86AudioRaiseVolume", function () awful.util.spawn(
"volume.zsh up" ) end),
--]]
---[[ last resort?
awful.key({ modkey }, "Return", function () ror("urxvt",{ name = "urxvt" }) end)
)
clientkeys = awful.util.table.join(
-- TODO Gotta try this someday…
awful.key({ modkey }, "o", awful.client.movetoscreen ),
-- Apple Wireless Keyboard
awful.key({ }, "XF86LaunchA", awful.client.floating.toggle ),
-- trigger mdy
awful.key({ }, mdy.trigger, function(c)
local mdy_verbosity = naughty.notify({ text =
mdy.prompt.normal, bg = mdy.bg, position = mdy.position, timeout = 0}), id
keygrabber.run(function(mod, key, event)
if event == "release" then return true end
naughty.destroy( mdy_verbosity )
if mdy.echo then
naughty.notify({ text = mdy.prompt.normal ..
key, bg = mdy.bg, position = mdy.position, timeout = mdy.echo_timeout })
end
keygrabber.stop()
if key == "." then ror( "ac", { name = "awesome
configuration" })
elseif key == "," then ror( "NetHack.zsh", { name =
"NetHack" })
elseif key == "-" then awesome.restart()
elseif key == "=" then awful.util.spawn(
"screenshot.zsh")
elseif key == " " then awful.client.floating.toggle(c)
elseif key == "0" then
awful.util.spawn( "xsession.zsh --kill" ) --
awesome.quit
elseif key == "1" or key == "2" or key == "3"
or key == "4" or key == "5" or key == "6"
or key == "7" or key == "8" or key == "9" then
local screen = mouse.screen
local tag =
awful.tag.gettags(screen)[tonumber(key)]
if tag then
awful.tag.viewonly(tag)
end
elseif key == "/" then
awful.util.spawn ( "aware-run.sh allnet" )
elseif key == "Right" then
local tag =
awful.tag.gettags(client.focus.screen)[tonumber(key)]
awful.tag.viewnext(tag)
elseif key == "Left" then
local tag =
awful.tag.gettags(client.focus.screen)[tonumber(key)]
awful.tag.viewprev(tag)
elseif key == "Up" then
awful.client.focus.byidx( 1)
if client.focus then client.focus:raise() end
elseif key == "Down" then
awful.client.focus.byidx(-1)
if client.focus then client.focus:raise() end
---[[ floating client manipulation
elseif key == "x" then
local mdy_verbosity = naughty.notify({ text =
mdy.prompt.normal .. mdy.prompt.client, bg = mdy.bg, position = mdy.position,
timeout = 0}), id
-- remember client's floating state
local previous_floating_state =
awful.client.floating.get(c)
-- and automatically make active client floating
if previous_floating_state == false then
awful.client.floating.set(c, true)
end
keygrabber.run(function(mod, key, event)
if event == "press" then
-- vertical / horizontal resize
if key == "g" then awful.client.moveresize(0,-mdy.y,0,2*mdy.y)
elseif key == "t" then awful.client.moveresize(0,mdy.y,0,2*-mdy.y)
elseif key == "o" or key == "End" then
awful.client.moveresize(-mdy.x,0,2*mdy.x,0)
elseif key == "y" or key == "Home" then
awful.client.moveresize(mdy.x,0,2*-mdy.x,0)
-- resize
elseif key == "i" or key == "Page_Up" then
awful.client.moveresize(-mdy.x,-mdy.y,2*mdy.x,2*mdy.y)
elseif key == "u" or key == "Page_Down" then
awful.client.moveresize(mdy.x,mdy.y,2*-mdy.x,2*-mdy.y)
-- move
elseif key == "h" or key == "Left" then
awful.client.moveresize(-mdy.x,0,0,0)
elseif key == "j" or key == "Down" then
awful.client.moveresize(0,mdy.y,0,0)
elseif key == "k" or key == "Up" then
awful.client.moveresize(0,-mdy.y,0,0)
elseif key == "l" or key == "Right" then
awful.client.moveresize(mdy.x,0,0,0)
-- move to tag number
elseif key == "1" or key == "2" or key == "3"
or key == "4" or key == "5" or key == "6"
or key == "7" or key == "8" or key == "9" then
local tag =
awful.tag.gettags(client.focus.screen)[tonumber(key)]
awful.client.movetotag(tag)
awful.tag.viewonly(tag)
-- other stuff
elseif key == " " then awful.client.floating.toggle ()
elseif key == "f" then c.fullscreen = not c.fullscreen
elseif key == "m" then c.maximized_horizontal = not c.maximized_horizontal
c.maximized_vertical = not
c.maximized_vertical
elseif key == ";" then c.ontop = not c.ontop
elseif key == "d" then
c:kill()
naughty.destroy( mdy_verbosity )
keygrabber.stop()
elseif key == "w" then mywibox_toggle ()
elseif key == "q" or key == "Escape" then
if previous_floating_state == false then
awful.client.floating.delete(c)
end
naughty.destroy( mdy_verbosity )
keygrabber.stop()
elseif key == "Return" or key == "+" then
naughty.destroy( mdy_verbosity )
keygrabber.stop()
end
end
end)
--]]
---[[ layout manipulation
elseif key == "Alt_L" then -- ALTernative Layout
local mdy_verbosity = naughty.notify({ text =
mdy.prompt.normal .. mdy.prompt.layout, bg = mdy.bg, position = mdy.position,
timeout = 0}), id
local previous_layout = awful.layout.getname()
-- default layout `max' makes no sense here
if previous_layout == "max" then
awful.layout.set(awful.layout.suit.tile.top)
end
keygrabber.run(function(mod, key, event)
if event == "press" then
if key == "o" or key == "End" then awful.screen.focus_relative( 1)
elseif key == "i" or key == "Page_Up" then awful.client.swap.byidx( 1)
elseif key == "u" or key == "Page_Down" then awful.client.swap.byidx( -1)
elseif key == "y" or key == "Home" then awful.screen.focus_relative(-1)
elseif key == "h" or key == "Left" then awful.client.incwfact(-0.05)
elseif key == "j" or key == "Down" then awful.tag.incmwfact(-0.05)
elseif key == "k" or key == "Up" then awful.tag.incmwfact( 0.05)
elseif key == "l" or key == "Right" then awful.client.incwfact( 0.05)
elseif key == "Alt_L" or key == " " then
awful.layout.inc(layouts, 1)
elseif key == "Shift_L" then
c:swap(awful.client.getmaster())
elseif key == "w" then mywibox_toggle ()
elseif key == "q" or key == "Escape" then
if previous_layout == "max" then
awful.layout.set(awful.layout.suit.max)
end
naughty.destroy( mdy_verbosity )
keygrabber.stop()
elseif key == "Return" or key == "+" then
naughty.destroy( mdy_verbosity )
keygrabber.stop()
end
end
end)
--]]
---[[ Asus EeePC
elseif key == "`" then
local mdy_verbosity = naughty.notify({ text =
mdy.prompt.normal .. mdy.prompt.eeepc, bg = mdy.bg, position = mdy.position,
timeout = 0}),id
keygrabber.run(function(mod, key, event)
if event == "press" then
if key == "F5" or key == "d" then awful.util.spawn( "xbacklight.zsh
decrease")
elseif key == "F6" or key == "s" then awful.util.spawn( "xbacklight.zsh
increase")
elseif key == "F7" or key == "Left" then awful.util.spawn( "mpc-notify.zsh
prev")
elseif key == "F8" or key == "Page_Down" then awful.util.spawn( "mpc-notify.zsh
toggle")
elseif key == "F9" or key == "Right" then awful.util.spawn( "mpc-notify.zsh
next")
elseif key == "F10" or key == "m" then awful.util.spawn( "volume.zsh toggle"
)
elseif key == "F11" or key == "Down" then awful.util.spawn( "volume.zsh down" )
elseif key == "F12" or key == "Up" then awful.util.spawn( "volume.zsh up" )
elseif key == "q" or key == "Return" or key == "+" then
naughty.destroy( mdy_verbosity )
keygrabber.stop()
end
end
end)
--]]
elseif mdy.key[key] then
mdy.key[key](c)
end
return true
end)
end)
)
-- Bind all number keys to tags
-- Be careful: we use keycodes to make it works on any keyboard layout.
-- This should map on the top row of your keyboard, usually 1 to 9.
for i = 1, 9 do
globalkeys = awful.util.table.join(globalkeys,
--[[ switch tag
awful.key({ modkey }, "#" .. i + 9,
function ()
local screen = mouse.screen
local tag = awful.tag.gettags(screen)[i]
if tag then
awful.tag.viewonly(tag)
end
end),
--]]
awful.key({ modkey }, "#" .. i + 9,
function ()
local screen = mouse.screen
local tag = awful.tag.gettags(screen)[i]
if tag then
awful.tag.viewtoggle(tag)
end
end),
awful.key({ modkey, "Shift" }, "#" .. i + 9,
function ()
local tag = awful.tag.gettags(client.focus.screen)[i]
if client.focus and tag then
awful.client.toggletag(tag)
end
end))
end
clientbuttons = awful.util.table.join(
awful.button({ }, 1, function (c) client.focus = c; c:raise() end),
-- semi obsolete; mind button order reverse of default
awful.button({ modkey }, 1, awful.mouse.client.resize),
awful.button({ modkey }, 3, awful.mouse.client.move)
)
-- Set keys
root.keys(globalkeys)
-- }}}
-- {{{ Rules
awful.rules.rules = {
-- All clients will match this rule.
{ rule = { },
properties = { floating = true,
focus = awful.client.focus.filter,
size_hints_honor = false, -- no gaps
between clients
keys = clientkeys,
buttons = clientbuttons } },
---[[ because xzoom(1)
{ rule_any = { class = {
"Chromium", "Dillo", "Firefox", "luakit", "Opera", "Blender", "feh",
"mpv", "URxvt", "Ardour", "MuPDF", "FBReader", "Stellarium", "Ario"
} }, properties = {
floating = false,
-- tag = tags [1][2]
} },
--]]
}
-- }}}
function mywibox_toggle ()
if mywibox[mouse.screen].visible then
mywibox_autohide:stop()
mywibox_autohide.timeout = 0
else
mywibox_autohide.timeout = wibox_autohide_seconds
mywibox_autohide:start()
end
mywibox[mouse.screen].visible = not mywibox[mouse.screen].visible
end
-- {{{ Signals
-- Signal function to execute when a new client appears.
client.connect_signal("manage", function (c, startup)
---[[ sloppy focus
c:connect_signal("mouse::enter", function(c)
if awful.layout.get(c.screen) ~= awful.layout.suit.magnifier
and awful.client.focus.filter(c) then
client.focus = c
end
end)
--]]
if not startup then
-- set client to slave
-- i.e. put it at the end of others instead of setting it master
-- Why did I disable this?
awful.client.setslave(c)
-- Put clients in a smart way, if they don't 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 titlebars_enabled and (c.type == "normal" or c.type == "dialog") then
-- buttons for the titlebar
local buttons = awful.util.table.join(
awful.button({ }, 1, function()
client.focus = c
c:raise()
awful.mouse.client.move(c)
end),
awful.button({ }, 3, function()
client.focus = c
c:raise()
awful.mouse.client.resize(c)
end)
)
-- Widgets that are aligned to the left
local left_layout = wibox.layout.fixed.horizontal()
left_layout:add(awful.titlebar.widget.iconwidget(c))
left_layout:buttons(buttons)
-- Widgets that are aligned to the right
local right_layout = wibox.layout.fixed.horizontal()
right_layout:add(awful.titlebar.widget.floatingbutton(c))
right_layout:add(awful.titlebar.widget.maximizedbutton(c))
right_layout:add(awful.titlebar.widget.stickybutton(c))
right_layout:add(awful.titlebar.widget.ontopbutton(c))
right_layout:add(awful.titlebar.widget.closebutton(c))
-- The title goes in the middle
local middle_layout = wibox.layout.flex.horizontal()
local title = awful.titlebar.widget.titlewidget(c)
title:set_align("center")
middle_layout:add(title)
middle_layout:buttons(buttons)
-- Now bring it all together
local layout = wibox.layout.align.horizontal()
layout:set_left(left_layout)
layout:set_right(right_layout)
layout:set_middle(middle_layout)
awful.titlebar(c):set_widget(layout)
end
end)
---[[
local spawn_without_startup_notification = awful.util.spawn
awful.util.spawn = function (s) spawn_without_startup_notification(s, false) end
--]]
---[[
--- Spawn cmd if no client can be found matching properties
-- If such a client can be found, pop to first tag where it is visible, and
give it focus
-- @param cmd the command to execute
-- @param properties a table of properties to match against clients. Possible
entries: any properties of the client object
function ror(cmd, properties)
local clients = client.get()
local focused = awful.client.next(0)
local findex = 0
local matched_clients = {}
local n = 0
for i, c in pairs(clients) do
--make an array of matched clients
if match(properties, c) then
n = n + 1
matched_clients[n] = c
if c == focused then
findex = n
end
end
end
if n > 0 then
local c = matched_clients[1]
-- if the focused window matched switch focus to next in list
if 0 < findex and findex < n then
c = matched_clients[findex+1]
end
local ctags = c:tags()
if #ctags == 0 then
-- ctags is empty, show client on current tag
local curtag = awful.tag.selected()
awful.client.movetotag(curtag, c)
else
-- Otherwise, go to first tag client is visible on
awful.tag.viewonly(ctags[1])
end
-- And then focus the client
client.focus = c
c:raise()
return
end
awful.util.spawn(cmd)
end
-- True if all pairs in table1 are present in table2
function match (table1, table2)
for k, v in pairs(table1) do
if table2[k] ~= v and not table2[k]:find(v) then
return false
end
end
return true
end
--]]
--[[ Border color indicates focused client
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)
--]]