56e727e026
There are two ways in which the input focus can change: Lua can request a change and the X11 server can inform us that the input focus changed (because some application changed it). In the first case, we still have to inform the X11 server about the desired change, in the second case we must not to avoid races due to X11's asynchronous nature. However, there was a case where we screwed up: When a focus change is still pending, meaning that Lua assigned the focus elsewhere, but we have not yet sent this focus change to the X11 server, we could get an event from the X11 server telling us that the focus changed. To make sure that the pending focus change is not lost, we sent the focus change out in this case (call to client_focus_refresh() in event_handle_focusin()). After sending out this pending call, we updated the internal state to record that whatever the X11 server just told us had the focus. The intention was that our just sent-out focus change will cause the X11 server to send a new event and our to-be-focused client then has the focus. However, if the pending focus change was for a client which only showed up in this event loop iteration, the client was still banned. This means that client_focus_refresh() would call client_unban() to be able to give the focus to this client. However, since awesome (partly) allows to "focus" currently banned clients, client_unban() recorded that there is a pending focus change. This caused confusion later on. In this specific bug, a main window opened a dialog, and when this dialog was closed, a new dialog window was opened immediately. When the first dialog was closed, Lua (the focus history) gave the input focus to the main window. Now, a new dialog showed up and Lua focused it. Next, we received the event from the X11 server telling us that the main window was focused. Because there was still a pending focus change to the new dialog window, event_handle_focusin() called client_focus_refresh() to send out this focus change. This set globalconf.focus.need_update to false and continued. However, because the new dialog only just now appeared, it was still banned, meaning that client_focus_refresh() had to call client_unban(). This set globalconf.focus.need_update to true. Thus, when client_focus_refresh() returned, globalconf.focus.need_update was incorrectly true. Next, event_handle_focusin() recorded that the main window had the focus. Thus, it now appeared as if there was a pending focus change for the main window. Next, we got the event from the X11 server telling us that the dialog is now focused, and because focus.need_update was set, awesome now send out a focus change request for the main window. Fix this race by unsetting globalconf.focus.need_update at the end of client_focus_refresh() and not at the beginning, thus making sure that client_unban() cannot set this flag again. Fixes: https://github.com/awesomeWM/awesome/issues/2220 Signed-off-by: Uli Schlachter <psychon@znc.in> |
||
---|---|---|
build-utils | ||
common | ||
docs | ||
icons | ||
lib | ||
manpages | ||
objects | ||
spec | ||
tests | ||
themes | ||
utils | ||
.busted | ||
.editorconfig | ||
.gitignore | ||
.luacheckrc | ||
.luacov | ||
.mergify.yml | ||
.travis.yml | ||
CMakeLists.txt | ||
ISSUE_TEMPLATE.md | ||
LICENSE | ||
Makefile | ||
Packaging.cmake | ||
README.md | ||
awesome-version-internal.h | ||
awesome.c | ||
awesome.desktop | ||
awesome.h | ||
awesomeConfig.cmake | ||
awesomerc.lua | ||
banning.c | ||
banning.h | ||
color.c | ||
color.h | ||
config.h | ||
dbus.c | ||
dbus.h | ||
draw.c | ||
draw.h | ||
event.c | ||
event.h | ||
ewmh.c | ||
ewmh.h | ||
globalconf.h | ||
keygrabber.c | ||
keygrabber.h | ||
luaa.c | ||
luaa.h | ||
mouse.c | ||
mouse.h | ||
mousegrabber.c | ||
mousegrabber.h | ||
property.c | ||
property.h | ||
root.c | ||
selection.c | ||
selection.h | ||
spawn.c | ||
spawn.h | ||
stack.c | ||
stack.h | ||
strut.c | ||
strut.h | ||
systray.c | ||
systray.h | ||
xkb.c | ||
xkb.h | ||
xrdb.c | ||
xrdb.h | ||
xwindow.c | ||
xwindow.h |
README.md
Readme
About Awesome
Awesome is a highly configurable, next generation framework window manager for X.
Building and installation
After extracting the dist tarball, run:
make
This will create a build directory, run cmake in it and build Awesome.
After building is finished, you can either install via make install
:
make install # you might need root permissions
or by auto-generating a .deb or .rpm package, for easy removal later on:
make package
sudo dpkg -i awesome-x.y.z.deb
# or
sudo rpm -Uvh awesome-x.y.z.rpm
NOTE: Awesome uses cmake
to build. In case you want to
pass arguments to cmake, please use the CMAKE_ARGS
environment variable. For
instance:
CMAKE_ARGS="-DCMAKE_INSTALL_PREFIX=/opt/awesome" make
Build dependencies
Awesome has the following dependencies (besides a more-or-less standard POSIX environment):
- CMake >= 3.0.0
- Lua >= 5.1.0 or LuaJIT
- LGI >= 0.8.0
- xproto >= 7.0.15
- libxcb >= 1.6 with support for the RandR, XTest, Xinerama, SHAPE and XKB extensions
- libxcb-cursor
- libxcb-util >= 0.3.8
- libxcb-keysyms >= 0.3.4
- libxcb-icccm >= 0.3.8
- xcb-util-xrm >= 1.0
- libxkbcommon with X11 support enabled
- libstartup-notification >= 0.10
- cairo with support for XCB and GObject introspection
- Pango with support for Cairo and GObject introspection
- GLib >= 2.40 with support for GObject introspection
- GIO with support for GObject introspection
- GdkPixbuf
- libX11 with xcb support
- Imagemagick's convert utility
- libxdg-basedir >= 1.0.0
Additionally, the following optional dependencies exist:
- DBus for DBus integration
and the
awesome-client
utility - asciidoctor for generating man pages
- gzip for compressing man pages
- ldoc >= 1.4.5 for generating the documentation
- busted for running unit tests
- luacheck for static code analysis
- LuaCov for collecting code coverage information
- libexecinfo on systems where libc does not provide
backtrace_symbols()
to generate slightly better backtraces on crashes Xephyr
orXvfb
for running integration tests- GTK+ >= 3.10 for
./themes/gtk/
Running Awesome
You can directly select Awesome from your display manager. If not, you can
add the following line to your .xinitrc to start Awesome using startx
or to .xsession
to start Awesome using your display manager:
exec awesome
In order to connect Awesome to a specific display, make sure that
the DISPLAY
environment variable is set correctly, e.g.:
DISPLAY=foo.bar:1 exec awesome
(This will start Awesome on display :1
of the host foo.bar.)
Configuration
The configuration of Awesome is done by creating a
$XDG_CONFIG_HOME/awesome/rc.lua
file, typically ~/.config/awesome/rc.lua
.
An example configuration named awesomerc.lua
is provided in the source.
Troubleshooting
On most systems any message printed by Awesome (including warnings and errors)
is written to ~/.xsession-errors
.
If Awesome does not start or the configuration file is not producing the desired results the user should examine this file to gain insight into the problem.
Debugging tips
You can call awesome
with gdb
like this:
DISPLAY=:2 gdb awesome
Then in gdb set any args and run it:
(gdb) set arg --replace
(gdb) run
Reporting issues
Please report any issues you may find on our bugtracker. You can submit pull requests on the github repository. Please read the contributing guide for any coding, documentation or patch guidelines.
Status
Documentation
Online documentation is available at https://awesomewm.org/apidoc/.
License
The project is licensed under GNU General Publice License v2 or later. You can read it online at (v2 or v3).