2017-01-22 19:14:13 +01:00
|
|
|
|
# Tips for upgrading your configuration
|
2016-12-21 03:59:07 +01:00
|
|
|
|
|
2017-01-22 19:14:13 +01:00
|
|
|
|
<a name="v4"></a>
|
2016-12-21 03:59:07 +01:00
|
|
|
|
## From 3.5 to 4.0
|
|
|
|
|
|
|
|
|
|
The
|
|
|
|
|
**best advice is to start from the default `rc.lua` and backport any changes**
|
|
|
|
|
you might have added to your `rc.lua`.
|
|
|
|
|
This avoids most of the possible errors due to missing important changes.
|
|
|
|
|
|
|
|
|
|
If you still wish to ignore this advice, first read the
|
2017-01-22 19:14:13 +01:00
|
|
|
|
<a href="89-NEWS.md.html#v4">NEWS</a> section about the breaking changes. This
|
2016-12-21 03:59:07 +01:00
|
|
|
|
document assumes you did.
|
|
|
|
|
|
|
|
|
|
Be warned, even if it looks like it's working after changing some lines, **it wont
|
|
|
|
|
supports dynamic screen changes and will have many subtle bugs**. The changes
|
|
|
|
|
mentioned below **are important for the stability of your window manager**.
|
|
|
|
|
|
|
|
|
|
Here is a diff of the 3.5.9 `rc.lua` with the 4.0 one. All changes due to
|
|
|
|
|
new features and new syntaxes have been removed. A `-` in front of the line
|
|
|
|
|
correspond to content of the 3.5 `rc.lua` and `+` its replacement in 4.0.
|
|
|
|
|
|
|
|
|
|
This document does not cover the new features added in the Awesome 4 `rc.lua`,
|
|
|
|
|
it only covers the minimal required changes to have a properly behaving config.
|
|
|
|
|
|
|
|
|
|
To test during the port, we recommend the `Xephyr` X11 server.
|
|
|
|
|
|
|
|
|
|
If Awesome4 **is not installed yet**, we recommand to install it in its own
|
|
|
|
|
prefix to avoid conflicts in case you wish to stay on 3.5 for a little
|
|
|
|
|
longer:
|
|
|
|
|
|
|
|
|
|
cd path/to/awesome/code
|
|
|
|
|
mkdir -p $HOME/.config/awesome4
|
|
|
|
|
mkdir build -p
|
|
|
|
|
cd build
|
|
|
|
|
|
|
|
|
|
# Install in a local folder, this assumes all the dependencies are installed
|
|
|
|
|
cmake -DCMAKE_INSTALL_PREFIX=$HOME/awesome4_test ..
|
|
|
|
|
make -j4
|
|
|
|
|
|
|
|
|
|
# Use a copy of rc.lua to avoid it being overwritten accidentally
|
|
|
|
|
cp awesomerc.lua $HOME/.config/awesome4/rc.lua
|
|
|
|
|
|
|
|
|
|
make install
|
|
|
|
|
|
|
|
|
|
# Start Awesome in a 1280x800 window
|
|
|
|
|
Xephyr :1 -screen 1280x800 &
|
|
|
|
|
DISPLAY=:1 $HOME/awesome4_test/bin/awesome \
|
|
|
|
|
-c $HOME/.config/awesome4/rc.lua \
|
|
|
|
|
--search $HOME/awesome4_test/share/awesome/lib
|
|
|
|
|
|
|
|
|
|
If Awesome 4 is **already installed**, then backup your old `rc.lua` and overwrite
|
|
|
|
|
`~/.config/awesome/rc.lua` (replace this by another path if you use a custom
|
|
|
|
|
XDH config local directory). And only execute:
|
|
|
|
|
|
|
|
|
|
Xephyr :1 -screen 1280x800 &
|
|
|
|
|
DISPLAY=:1 awesome
|
|
|
|
|
|
|
|
|
|
Screens are now added and removed without reloading `rc.lua`. The wallpaper are
|
|
|
|
|
now set in a signal callback.
|
|
|
|
|
|
|
|
|
|
--- {{{ Wallpaper
|
|
|
|
|
-if `beautiful.wallpaper` then
|
|
|
|
|
- for s = 1, screen.count() do
|
|
|
|
|
- `gears.wallpaper.maximized`(beautiful.wallpaper, s, true)
|
|
|
|
|
- end
|
|
|
|
|
-end
|
|
|
|
|
--- }}}
|
|
|
|
|
|
|
|
|
|
+local function set_wallpaper(s)
|
|
|
|
|
+ -- Wallpaper
|
|
|
|
|
+ if `beautiful.wallpaper` then
|
|
|
|
|
+ local wallpaper = `beautiful.wallpaper`
|
|
|
|
|
+ -- If wallpaper is a function, call it with the screen
|
|
|
|
|
+ if type(wallpaper) == "function" then
|
|
|
|
|
+ wallpaper = wallpaper(s)
|
|
|
|
|
+ end
|
|
|
|
|
+ `gears.wallpaper.maximized`(wallpaper, s, true)
|
|
|
|
|
+ end
|
|
|
|
|
+end
|
|
|
|
|
+
|
|
|
|
|
+-- Re-set wallpaper when a screen's geometry changes (e.g. different resolution)
|
|
|
|
|
+`screen.connect_signal`("property::geometry", set_wallpaper)
|
|
|
|
|
|
|
|
|
|
Tags need to be created for each screens, the old static initialization cannot
|
|
|
|
|
work. Remove this section.
|
|
|
|
|
|
|
|
|
|
--- {{{ Tags
|
|
|
|
|
--- 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
|
|
|
|
|
--- }}}
|
|
|
|
|
|
2017-01-29 14:59:57 +01:00
|
|
|
|
The `quit` menu command must be wrapped in a function, otherwise an error
|
|
|
|
|
occurs due to mismatched argument types from the v4.0 `awful.menu` library.
|
|
|
|
|
|
2017-01-29 20:15:51 +01:00
|
|
|
|
-- {{{ Menu
|
2017-01-29 14:59:57 +01:00
|
|
|
|
-- 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 }
|
|
|
|
|
+ { "quit", function() awesome.quit() end}
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-21 03:59:07 +01:00
|
|
|
|
The textclock is now part of the `wibox` library, rename it.
|
|
|
|
|
|
2017-01-29 20:15:51 +01:00
|
|
|
|
-- {{{ Wibar
|
2016-12-21 03:59:07 +01:00
|
|
|
|
-- Create a textclock widget
|
|
|
|
|
-mytextclock = `awful.widget.textclock`()
|
|
|
|
|
+mytextclock = `wibox.widget.textclock`()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Widgets were previously added to static global tables. This isn't going to
|
|
|
|
|
behave correctly when screen are added and removed. Remove this section.
|
|
|
|
|
|
2017-01-29 14:59:57 +01:00
|
|
|
|
--- Create a wibox for each screen and add it
|
2016-12-21 03:59:07 +01:00
|
|
|
|
-mywibox = {}
|
|
|
|
|
-mypromptbox = {}
|
|
|
|
|
-mylayoutbox = {}
|
|
|
|
|
-mytaglist = {}
|
|
|
|
|
-mytasklist = {}
|
|
|
|
|
|
|
|
|
|
Many functions have been converted to methods. The old functions are deprecated,
|
|
|
|
|
they are still supported, but will be removed in the next release.
|
|
|
|
|
|
|
|
|
|
-mytaglist.buttons = awful.util.table.join(
|
|
|
|
|
+local taglist_buttons = awful.util.table.join(
|
|
|
|
|
- awful.button({ }, 1, `awful.tag.viewonly`),
|
|
|
|
|
+ awful.button({ }, 1, function(t) t:`view_only`() end),
|
|
|
|
|
- awful.button({ modkey }, 1, `awful.client.movetotag`),
|
|
|
|
|
+ awful.button({ modkey }, 1, function(t)
|
|
|
|
|
+ if `client.focus` then
|
|
|
|
|
+ `client.focus:move_to_tag`(t)
|
|
|
|
|
+ end
|
|
|
|
|
+ end),
|
|
|
|
|
`awful.button`({ }, 3, `awful.tag.viewtoggle`),
|
|
|
|
|
- `awful.button`({ modkey }, 3, `awful.client.toggletag`),
|
|
|
|
|
+ `awful.button`({ modkey }, 3, function(t)
|
|
|
|
|
+ if client.focus then
|
|
|
|
|
+ client.focus:toggle_tag(t)
|
|
|
|
|
+ end
|
|
|
|
|
+ end),
|
|
|
|
|
- `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)
|
|
|
|
|
+ `awful.button`({ }, 4, function(t) `awful.tag.viewnext`(t.screen) end),
|
|
|
|
|
+ `awful.button`({ }, 5, function(t) `awful.tag.viewprev`(t.screen) end)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
-mytasklist.buttons = awful.util.table.join(
|
|
|
|
|
+local tasklist_buttons = awful.util.table.join(
|
|
|
|
|
awful.button({ }, 1, function (c)
|
|
|
|
|
if c == `client.focus` then
|
|
|
|
|
c.minimized = true
|
2017-01-29 14:59:57 +01:00
|
|
|
|
else
|
2016-12-21 03:59:07 +01:00
|
|
|
|
-- Without this, the following
|
|
|
|
|
-- :isvisible() makes no sense
|
|
|
|
|
c.minimized = false
|
|
|
|
|
- if not c:isvisible() then
|
|
|
|
|
- `awful.tag.viewonly`(c:tags()[1])
|
|
|
|
|
+ if not c:isvisible() and c.`first_tag` then
|
|
|
|
|
+ c.first_tag:view_only()
|
|
|
|
|
end
|
|
|
|
|
-- This will also un-minimize
|
|
|
|
|
-- the client, if needed
|
2017-01-29 14:59:57 +01:00
|
|
|
|
`client.focus` = c
|
2016-12-21 03:59:07 +01:00
|
|
|
|
c:raise()
|
|
|
|
|
end
|
|
|
|
|
end),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
This section is **very important**. This is where adding and removing screens is
|
|
|
|
|
handled (including during startup). Note that the `mysomething` table
|
|
|
|
|
previously removed are replaced by custom screens attributes.
|
|
|
|
|
|
|
|
|
|
-for s = 1, `screen.count`() do
|
|
|
|
|
+`awful.screen.connect_for_each_screen`(function(s)
|
|
|
|
|
+ -- Wallpaper
|
|
|
|
|
+ set_wallpaper(s)
|
|
|
|
|
+
|
|
|
|
|
+ -- Each screen has its own tag table.
|
|
|
|
|
+ awful.tag({ "1", "2", "3", "4", "5", "6", "7", "8", "9" }, s, awful.layout.layouts[1])
|
|
|
|
|
+
|
|
|
|
|
-- Create a promptbox for each screen
|
|
|
|
|
- mypromptbox[s] = `awful.widget.prompt`()
|
|
|
|
|
+ s.mypromptbox = `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)
|
|
|
|
|
+ s.mylayoutbox = `awful.widget.layoutbox`(s)
|
|
|
|
|
- mylayoutbox[s]:buttons(`awful.util.table.join`(
|
|
|
|
|
+ s.mylayoutbox:buttons(`awful.util.table.join`(
|
|
|
|
|
`awful.button`({ }, 1, function () `awful.layout.inc`( 1) end),
|
|
|
|
|
`awful.button`({ }, 3, function () `awful.layout.inc`(-1) end),
|
|
|
|
|
`awful.button`({ }, 4, function () `awful.layout.inc`( 1) end),
|
|
|
|
|
`awful.button`({ }, 5, function () `awful.layout.inc`(-1) end)))
|
|
|
|
|
-- Create a taglist widget
|
|
|
|
|
- mytaglist[s] = `awful.widget.taglist`(s, `awful.widget.taglist.filter.all`, mytaglist.buttons)
|
|
|
|
|
+ s.mytaglist = `awful.widget.taglist`(s, `awful.widget.taglist.filter.all`, taglist_buttons)
|
|
|
|
|
|
|
|
|
|
-- Create a tasklist widget
|
|
|
|
|
- mytasklist[s] = `awful.widget.tasklist`(s, `awful.widget.tasklist.filter.currenttags`, mytasklist.buttons)
|
|
|
|
|
+ s.mytasklist = `awful.widget.tasklist`(s, `awful.widget.tasklist.filter.currenttags`, tasklist_buttons)
|
|
|
|
|
|
|
|
|
|
-- Create the wibox
|
|
|
|
|
- mywibox[s] = `awful.wibox`({ position = "top", screen = s })
|
|
|
|
|
+ s.mywibox = `awful.wibar`({ position = "top", screen = s })
|
|
|
|
|
|
|
|
|
|
-- 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])
|
|
|
|
|
+ left_layout:add(s.mytaglist)
|
|
|
|
|
+ left_layout:add(s.mypromptbox)
|
|
|
|
|
|
|
|
|
|
-- 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(wibox.widget.systray())
|
|
|
|
|
right_layout:add(mytextclock)
|
|
|
|
|
- right_layout:add(mylayoutbox[s])
|
|
|
|
|
+ right_layout:add(s.mylayoutbox)
|
|
|
|
|
|
|
|
|
|
-- 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_middle(s.mytasklist)
|
|
|
|
|
layout:set_right(right_layout)
|
|
|
|
|
|
|
|
|
|
- mywibox[s]:set_widget(layout)
|
|
|
|
|
+ s.mywibox:set_widget(layout)
|
|
|
|
|
end)
|
|
|
|
|
-- }}}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
`awful.util.spawn` is now called `awful.spawn`.
|
|
|
|
|
|
|
|
|
|
-- Standard program
|
|
|
|
|
- `awful.key`({ modkey, }, "Return", function () `awful.util.spawn`(terminal) end),
|
|
|
|
|
+ `awful.key`({ modkey, }, "Return", function () `awful.spawn`(terminal) end),
|
|
|
|
|
|
|
|
|
|
Another dynamic screen related changes.
|
|
|
|
|
|
2017-01-22 13:59:25 +01:00
|
|
|
|
⠀-- Prompt
|
2016-12-21 03:59:07 +01:00
|
|
|
|
- awful.key({ modkey }, "r", function () mypromptbox[mouse.screen]:run() end),
|
|
|
|
|
+ awful.key({ modkey }, "r", function () `awful.screen.focused`().mypromptbox:run() end),
|
|
|
|
|
|
|
|
|
|
`awful.prompt` now uses a more future proof arguments table instead of many
|
|
|
|
|
optional arguments.
|
|
|
|
|
|
2017-01-22 13:59:25 +01:00
|
|
|
|
⠀ awful.key({ modkey }, "x",
|
2016-12-21 03:59:07 +01:00
|
|
|
|
function ()
|
|
|
|
|
- `awful.prompt.run`({ prompt = "Run Lua code: " },
|
|
|
|
|
- mypromptbox[mouse.screen].widget,
|
|
|
|
|
- `awful.util.eval`, nil,
|
|
|
|
|
- `awful.util.getdir`("cache") .. "/history_eval")
|
|
|
|
|
- end),
|
|
|
|
|
+ awful.prompt.run {
|
|
|
|
|
+ prompt = "Run Lua code: ",
|
|
|
|
|
+ textbox = `awful.screen.focused`().mypromptbox.widget,
|
|
|
|
|
+ exe_callback = `awful.util.eval`,
|
|
|
|
|
+ history_path = `awful.util.get_cache_dir`() .. "/history_eval"
|
|
|
|
|
+ }
|
|
|
|
|
+ end),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Another function-to-method API change:
|
|
|
|
|
|
|
|
|
|
- `awful.key`({ modkey, }, "o", `awful.client.movetoscreen` ),
|
|
|
|
|
+ `awful.key`({ modkey, }, "o", function (c) c:`move_to_screen`() end),
|
|
|
|
|
|
|
|
|
|
The `mod4+[1-9]` keybindings also have some changes related to deprecated
|
|
|
|
|
functions.
|
|
|
|
|
|
|
|
|
|
-- Bind all key numbers 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
|
|
|
|
|
-- View tag only.
|
|
|
|
|
awful.key({ modkey }, "#" .. i + 9,
|
|
|
|
|
function ()
|
|
|
|
|
- local screen = `mouse.screen`
|
|
|
|
|
- local tag = `awful.tag.gettags`(screen)[i]
|
|
|
|
|
+ local screen = `awful.screen.focused`()
|
|
|
|
|
+ local tag = `screen.tags`[i]
|
|
|
|
|
if tag then
|
|
|
|
|
- `awful.tag.viewonly`(tag)
|
|
|
|
|
+ `tag:view_only`()
|
|
|
|
|
end
|
|
|
|
|
end),
|
|
|
|
|
- -- Toggle tag.
|
|
|
|
|
+ -- Toggle tag display.
|
|
|
|
|
awful.key({ modkey, "Control" }, "#" .. i + 9,
|
|
|
|
|
function ()
|
|
|
|
|
- local screen = `mouse.screen`
|
|
|
|
|
- local tag = `awful.tag.gettags`(screen)[i]
|
|
|
|
|
+ local screen = `awful.screen.focused`()
|
|
|
|
|
+ local tag = `screen.tags`[i]
|
|
|
|
|
if tag then
|
|
|
|
|
`awful.tag.viewtoggle`(tag)
|
|
|
|
|
end
|
|
|
|
|
for i = 1, 9 do
|
|
|
|
|
awful.key({ modkey, "Shift" }, "#" .. i + 9,
|
|
|
|
|
function ()
|
|
|
|
|
if client.focus then
|
|
|
|
|
- local tag = `awful.tag.gettags`(client.focus.screen)[i]
|
|
|
|
|
+ local tag = `client.focus.screen.tags`[i]
|
|
|
|
|
if tag then
|
|
|
|
|
- `awful.client.movetotag`(tag)
|
|
|
|
|
+ `client.focus:move_to_tag`(tag)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end),
|
|
|
|
|
- -- Toggle tag.
|
|
|
|
|
+ -- Toggle tag on focused client.
|
|
|
|
|
awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9,
|
|
|
|
|
function ()
|
|
|
|
|
if client.focus then
|
|
|
|
|
- local tag = `awful.tag.gettags`(client.focus.screen)[i]
|
|
|
|
|
+ local tag = `client.focus.screen.tags`[i]
|
|
|
|
|
if tag then
|
|
|
|
|
- `awful.client.toggletag`(tag)
|
|
|
|
|
+ `client.focus:toggle_tag`(tag)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
- end))
|
|
|
|
|
+ end),
|
|
|
|
|
+ )
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
The default rules need to be changed to avoid having offscreen clients:
|
|
|
|
|
|
|
|
|
|
awful.rules.rules = {
|
|
|
|
|
-- All clients will match this rule.
|
|
|
|
|
{ rule = { },
|
|
|
|
|
properties = { border_width = beautiful.border_width,
|
|
|
|
|
awful.rules.rules = {
|
|
|
|
|
focus = awful.client.focus.filter,
|
|
|
|
|
raise = true,
|
|
|
|
|
keys = clientkeys,
|
|
|
|
|
+ buttons = clientbuttons,
|
|
|
|
|
+ screen = `awful.screen.preferred`,
|
|
|
|
|
+ placement = `awful.placement.no_overlap`+`awful.placement.no_offscreen`
|
|
|
|
|
|
|
|
|
|
The `tags` global table has been removed to support dynamic screens, you can
|
|
|
|
|
now access tags by name.
|
|
|
|
|
|
|
|
|
|
- -- properties = { tag = tags[1][2] } },
|
|
|
|
|
+ -- properties = { screen = 1, tag = "2" } },
|
|
|
|
|
|
2017-02-03 16:47:21 +01:00
|
|
|
|
If you need to get the current client object in global context, currently you can use
|
|
|
|
|
`client.focus` for it. E.g., to mark/unmark the client:
|
2016-12-21 03:59:07 +01:00
|
|
|
|
|
2017-02-03 16:47:21 +01:00
|
|
|
|
- awful.client.mark()
|
|
|
|
|
+ client.focus.marked = true
|
|
|
|
|
|
|
|
|
|
- awful.client.unmark()
|
|
|
|
|
+ client.focus.marked = false
|