When using a global key combo to lock the screen, often the WM (or
whatever) will still have an active grab on the keyboard by the time we
try to get our own grab.
We don't actually depend on libxcb-randr or libxcb-xfixes, because the
Rust xcb crate implements extensions by autogenerating XCB message
structs, and then using the main libxcb message sending functions (not
the C functions in each extension library) to send the requests.
Previously I was just presenting a static username/password box, and
then running PAM with pre-set credentials. This works just fine when
PAM is expecting a username and password, but if it's expecting
something like a fingerprint scan or a hardware security token, this
wouldn't entirely work right. Well, it would "work", but the
username/password dialog would be displayed, and then hitting "Unlock"
would start a different auth process with no visible feedback as to
what's supposed to happen.
This also means I need to switch PAM wrapper crates; the one I was using
before did not allow passing a fixed username to the underlying
pam_start() call, which meant that PAM would try to prompt the user for
it, which is not what we want.
Sometimes we get notifications from randr of changes where the new setup
is exactly like the old. The main annoying time this happens is when
the system resumes from suspend. This is probably why there's often a
flash of the desktop right after resuming: we're destroying the old
blanker windows and creating new ones, even though the setup is exactly
the same.
Previously we only trigger unblanking or showing the unlock dialog if
core key or motion events come through. Now we also do this when xinput
events come in. We also now reset the last-user-activity time for core
events.
This also changes xcb-xembed to explicitly only handle core events.
I'm not sure if we can trust the state of things if the wait() call
actually fails (as in, the call itself returns an error), so let's just
let the dialog die and hope that if there's more user activity it'll
start up again properly.
This also stops using -1 as auth failed, and moves all failure statuses
to positive numbers. It looks like Exiting with -1 ends up setting the
status to 255 on exit, but then in the locker, it sees this as 255 and
not -1, since things get coerced into 32-bit integers.
We never quit the main loop, but if something odd happens that causes it
to quit outside our control, ensure that we don't return the "auth
success" status code.
Changes the auth failed label into an auth status label, and prints a
dot once every half second while authenticating.
Also reduces the post-auth-failed pause to 1 second; 2 seconds is longer
than it seems.
If the user presses enter or escape in order to get the unlock dialog to
show in the first place, forwarding that event to the dialog will only
cause it to close immediately.
Also took the opportunity to clean up the dependencies where I have my
own patches. I'm now using the cargo 'patch' section so that the
dependencies specified in the individual Cargo.toml files are clean.
By default it'll look at your environment to try to figure out which
display manager is used in order to start a new session. We first try
the org.freedesktop.DisplayManager dbus interface, and if that fails,
inspect XDG_SESSION_DESKTOP to try to figure out which display manager
is running.
The user can also still specify the correct display manager, or a custom
command.
I gave up on getting it to build on bullseye, as its cargo/rustc is too
old for the 2021 edition. Building newer deb packages of rust is
apparently a difficult, manual process. I tried installing rustup and
pulling the latest compiler, but that failed with strange errors that I
am tired of debugging.
I don't think it's even possible to use gtk4 to build a dialog, as gtk4
has dropped GtkPlug/GtkSocket and doesn't support embedding anymore.
They also don't seem to give access to enough internals so I can build
it myself.