terminal: don’t unref a not-yet-referenced key-binding set

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 commit is contained in:
Daniel Eklöf 2022-09-05 19:23:40 +02:00
parent c311229b9e
commit d2e67689ea
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
6 changed files with 35 additions and 31 deletions

View file

@ -178,15 +178,16 @@ static bool kbd_initialized = false;
struct key_binding_set *
key_binding_for(
struct key_binding_manager *mgr, const struct terminal *term,
struct key_binding_manager *mgr, const struct config *conf,
const struct seat *seat)
{
return &kbd;
}
void
key_binding_new_for_term(
struct key_binding_manager *mgr, const struct terminal *term)
key_binding_new_for_conf(
struct key_binding_manager *mgr, const struct wayland *wayl,
const struct config *conf)
{
if (!kbd_initialized) {
kbd_initialized = true;
@ -201,7 +202,7 @@ key_binding_new_for_term(
}
void
key_binding_unref_term(struct key_binding_manager *mgr, const struct terminal *term)
key_binding_unref(struct key_binding_manager *mgr, const struct config *conf)
{
}