This adds limited support for OSC-99, kitty desktop notifications[^1]. We
support everything defined by the "protocol", except:
* 'a': action to perform on notification activation. Since we don't
trigger the notification ourselves (over D-Bus), we don't know a)
which ID the notification got, or b) when it is clicked.
* ... and that's it. Everything else is supported
To be explicit, we *do* support:
* Chunked notifications (d=0|1), allowing the application to append
data to a notification in chunks, before it's finally displayed.
* Plain UTF-8, or base64-encoded UTF-8 payload (e=0|1).
* Notification identifier (i=xyz).
* Payload type (p=title|body).
* When to honor the notification (o=always|unfocused|invisible), with
the following quirks:
- we don't know when the window is invisible, thus it's treated as
'unfocused'.
- the foot option 'notify-focus-inhibit' overrides 'always'
* Urgency (u=0|1|2)
[^1]: https://sw.kovidgoyal.net/kitty/desktop-notifications/
When background alpha is changed at runtime (using OSC-11), we (may)
have to update the opaque hint we send to the compositor.
We must also update the subpixel mode used when rendering font
glyphs.
Why?
When the window is fully opaque, we use wl_surface_set_opaque_region()
on the entire surface, to hint to the compositor that it doesn’t have
to blend the window content with whatever is behind the
window. Obviously, if alpha is changed from opaque, to transparent (or
semi-transparent), that hint must be removed.
Sub-pixel mode is harder to explain, but in short, we can’t do
subpixel hinting with a (semi-)transparent background. Thus, similar
to the opaque hint, subpixel antialiasing must be enabled/disabled
when background alpha is changed.
On my system, GCC doesn't output its name when passing the --version
flag:
$ cc --version
cc (Debian 12.2.0-3) 12.2.0
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
As the Free Software Foundation is unlikely to write another compiler, I
think that searching for the foundation's name instead of GCC is a good
enough fix (and I'm almost sure we wouldn't be the first ones to do so).
This used to work because we never free:d any of the rows. Now
however, we do free (some of) them when reverse scrolling. This means
we can no longer re-use the rows between the two screens.
Closes#1196
We execute xtgettcap in the parent terminal. Thus we don’t know if it
implements XTGETTCAP, and thus it’s not guaranteed to exit - it may
hang indefinitely waiting for a reply.
Fix by not actually quering anything.
Fixes:
../utils/xtgettcap.c:175:1: error: ‘/home/daniel/src/foot/src/utils/xtgettcap.p/xtgettcap.c.gcda’ profile count data file not found [-Werror=missing-profile]
Key-binding sets are bound to a seat/configuration pair. The conf
reference is done when a new terminal instance is created.
When that same terminal instance is destroyed, the key binding set is
unref:ed.
If the terminal instance is destroyed *before* the key binding set has
been referenced, we’ll still unref it. This creates an imbalance.
In particular, when the there is exactly one other terminal instance
referencing that same key binding set, that terminal instance will
trigger a foot server crash as soon as it receives a key press/release
event. This happens because the next-to-last terminal instance brought
the reference count of the binding set down to 0, causing it to be
free:d.
Thus, we *must* reference the binding set *before* we can error
out (when instantiating a new terminal instance).
At this point, we don’t yet have a valid terminal instance. But,
that’s ok, because all the key_binding_new_for_term() did with the
terminal instance was get the "struct wayland" and "struct config"
pointers. So, rename the function and simply pass these pointers
explicitly.
Similarly, change key_binding_for() to take a "struct config" pointer,
rather than a "struct terminal" pointer.
Also rename key_binding_unref_term() -> key_binding_unref().
This is an application of the xdg activation protocol that will allow
compositors to associate new foot toplevels with the command that
launched them.
footclient receives an activation token from the launcher which the
compositor can use to track application startup. It passes the token
to the foot server, which then activates the new window with the token
to complete the startup sequence.
Grapheme shaping is now enabled by default in foot. However, when
generating the profiling data in PGO builds, this results in skewed
optimizations.
The end result is worse benchmark results regardless of whether
grapheme-shaping is enabled or not (when running the benchmarks).
Without pixman renderer override pgo builds in cage/sway require
access to actual render devices. In Gentoo's case the builds are run
as ordinary user and within a "sandbox" which prevents and logs access
outside of predefined places during build.
So let's default to pixman renderer for the PGO builds. Hopefully that
won't matter for the pgo optimizations to do the right thing within foot.
That locale may not exist. Instead, require the user/build script to
explicitly set an UTF-8 locale.
Document this in INSTALL.md, and in the bundled PKGBUILD.
Appears to work, but cage spams a lot of
00:00:08.026 [types/wlr_output.c:720] Basic output test failed for HEADLESS-1
00:00:08.036 [types/wlr_output.c:720] Basic output test failed for HEADLESS-1
All scripts are in the ‘pgo’ directory:
* options: command line options for generate-alt-random-writes.py,
sourced by other scripts.
* pgo.sh: top-level script, generates a meson build directory, selects
a PGO method, generates the profiling data, re-configures the meson
build directory and does the final build.
This script is intended to be used by end-users, and shows _how_ to
integrate the script primitives.
Build servers will most likely *not* want to use this script as-is.
* partial.sh: generates alt-random-write data and runs “foot{,client}
--version”, and then feeds the alt-random data to the PGO helper
binary. Does not require a running Wayland session. Touches
$blddir/pgo-ok on success.
* full-inner.sh: runs “footclient --version”, and then a complex
“foot” command that first generates alt-random-write data, and then
“cat’s” it. Requires a running Wayland session, *but*, this script
is usually not called directly (see below). Touches $blddir/pgo-ok
onsucces..
* full-current-session.sh: runs full-inner.sh. That is, it runs foot
in the currently running Wayland session. Note that this will pop up a
foot window.
* full-headless-sway.sh: generates a custom Sway configuration that
exec’s foot-headless-sway-inner.sh (see below), and then executes a
headless Sway. In other words, this script does a *full* PGO build,
but *without* requiring a running Wayland session. Requires Sway >=
1.6.2.
* full-headless-sway.sh: runs full-inner.sh + “swaymsg exit”.
To do a custom PGO build, without using pgo.sh, you’d need to:
CFLAGS=”$CFLAGS -O3” meson --buildtype=release -Db_lto=true
meson configure -Db_pgo=generate
ninja
ninja test (only needed if tllist+fcft are built as subprojects)
Run *one* of:
- partial.sh
- full-current-session.sh
- full-headless-sway.sh
meson configure -D b_pgo=use
ninja
Add stubs for shm_chain_new(), shm_chain_free() and shm_unref(). This
fixes ‘pgo’ linking failures in the ‘generate’ phase when doing a PGO
build with clang.
Closes#642
This ensures different seat’s don’t step on each others IME pre-edit
state.
It also removes most dependencies on having a valid term pointer for
many IME operations.
We’re still not all the way, since we support disabling IME with a
private mode, which is per terminal, not seat.
Thus, we still require the seat to have keyboard focus on one of our
windows.
Closes#324. But note that *rendering* of multiple seat’s IME pre-edit
strings is still broken.
Add fdm_signal_add() and fdm_signal_del(). Signals added to the fdm
will be monitored, and the provided callback called as “soon as
possible” from the main context (i.e not from the signal handler
context).
Monitored signals are *blocked* by default. We use epoll_pwait() to
unblock them while we’re polling. This allows us to do race-free
signal detection.
We use a single handler for all monitored signals; the handler simply
updates the signal’s slot in a global array (sized to fit SIGRTMAX
signals).
When epoll_pwait() returns EINTR, we loop the global array. The
callback associated with each signal that fired is called.