feat: show the bubble on gnome
This commit is contained in:
1 parent
f232f796fc
commit
2a9b0d3f91
28 files changed
+2278
-1077
No files matched your search
@@ -0,0 +1,39 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "bubbleservice.h"
|
||||
|
||||
#include "bubblecontroller.h"
|
||||
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusError>
|
||||
|
||||
BubbleService::BubbleService(BubbleController *bubble, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_bubble(bubble)
|
||||
{
|
||||
const auto changed = [this] {
|
||||
Q_EMIT StateChanged(GetState());
|
||||
};
|
||||
connect(bubble, &BubbleController::phaseChanged, this, changed);
|
||||
connect(bubble, &BubbleController::messageChanged, this, changed);
|
||||
connect(bubble, &BubbleController::faceSeenChanged, this, changed);
|
||||
connect(bubble, &BubbleController::styleChanged, this, changed);
|
||||
connect(bubble, &BubbleController::paceChanged, this, changed);
|
||||
|
||||
QDBusConnection bus = QDBusConnection::sessionBus();
|
||||
if (!bus.registerService(QStringLiteral("io.github.loonixtools.FaceUnlock"))
|
||||
|| !bus.registerObject(QStringLiteral("/io/github/loonixtools/FaceUnlock"), this, QDBusConnection::ExportScriptableContents)) {
|
||||
qWarning("cannot offer the bubble on the session bus: %s", qPrintable(bus.lastError().message()));
|
||||
}
|
||||
}
|
||||
|
||||
QVariantMap BubbleService::GetState() const
|
||||
{
|
||||
return {
|
||||
{QStringLiteral("phase"), m_bubble->phase()},
|
||||
{QStringLiteral("message"), m_bubble->message()},
|
||||
{QStringLiteral("faceSeen"), m_bubble->faceSeen()},
|
||||
{QStringLiteral("style"), m_bubble->style()},
|
||||
{QStringLiteral("pace"), m_bubble->pace()},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
//
|
||||
// The bubble's state on the session bus, for GNOME. GNOME lets no program
|
||||
// draw above its windows or its lock screen; only a GNOME Shell extension
|
||||
// may. face-unlock's extension (res/gnome-shell) draws the bubble from what
|
||||
// this says: io.github.loonixtools.FaceUnlock, /io/github/loonixtools/FaceUnlock.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QVariantMap>
|
||||
|
||||
class BubbleController;
|
||||
|
||||
class BubbleService : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_CLASSINFO("D-Bus Interface", "io.github.loonixtools.FaceUnlock.Bubble")
|
||||
public:
|
||||
explicit BubbleService(BubbleController *bubble, QObject *parent = nullptr);
|
||||
|
||||
// phase, message, faceSeen, style, pace: what BubbleController has.
|
||||
Q_SCRIPTABLE QVariantMap GetState() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
Q_SCRIPTABLE void StateChanged(const QVariantMap &state);
|
||||
|
||||
private:
|
||||
BubbleController *m_bubble;
|
||||
};
|
||||
@@ -12,9 +12,10 @@
|
||||
// request has to be made for every new surface role, before it is mapped, so
|
||||
// it is repeated each time the window is shown again.
|
||||
//
|
||||
// Other compositors have no such thing. On Hyprland and Niri the lock screen
|
||||
// covers the bubble, which shows again with the tick once it is gone. GNOME
|
||||
// has no layer-shell at all, so there is no bubble there (see main.cpp).
|
||||
// Other compositors have no such thing: on Hyprland and Niri the lock screen
|
||||
// covers the bubble, which shows the tick once it is gone. GNOME has no
|
||||
// layer-shell at all; there face-unlock's GNOME Shell extension draws the
|
||||
// bubble (BubbleService).
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
+8
-3
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "agentsocket.h"
|
||||
#include "bubblecontroller.h"
|
||||
#include "bubbleservice.h"
|
||||
#include "bubblewindow.h"
|
||||
#include "enrollcontroller.h"
|
||||
#include "lockcontroller.h"
|
||||
@@ -112,8 +113,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
BubbleController bubble(&config);
|
||||
// The bubble floats above everything as a layer-shell surface. GNOME has
|
||||
// none, and a normal window cannot stay on top or pick its place, so
|
||||
// there it does without.
|
||||
// none, and a normal window cannot stay on top or pick its place: there
|
||||
// face-unlock's GNOME Shell extension draws it, from what this tells it.
|
||||
std::unique_ptr<BubbleWindow> window;
|
||||
if (Wayland::hasGlobal("zwlr_layer_shell_v1")) {
|
||||
window = std::make_unique<BubbleWindow>(&engine, &bubble);
|
||||
@@ -121,7 +122,7 @@ int main(int argc, char **argv)
|
||||
|
||||
if (parser.isSet(demoOpt)) {
|
||||
if (!window) {
|
||||
qWarning("this desktop has no layer-shell, so there is no bubble to show");
|
||||
qWarning("this desktop has no layer-shell; on GNOME the extension draws the bubble");
|
||||
return 1;
|
||||
}
|
||||
scheduleDemo(&bubble);
|
||||
@@ -135,6 +136,10 @@ int main(int argc, char **argv)
|
||||
}
|
||||
socket.listen();
|
||||
QObject::connect(&socket, &AgentSocket::scanEvent, &bubble, &BubbleController::daemonEvent);
|
||||
std::unique_ptr<BubbleService> service;
|
||||
if (!window) {
|
||||
service = std::make_unique<BubbleService>(&bubble);
|
||||
}
|
||||
|
||||
LockController lock(&bubble, &config);
|
||||
return app.exec();
|
||||
|
||||
@@ -111,6 +111,16 @@ fu_do_enable() {
|
||||
[[ $CFG_SUDO == yes ]] && ! fu_pam_enabled sudo && fu_root pam-enable sudo
|
||||
[[ $CFG_POLKIT == yes ]] && ! fu_pam_enabled polkit-1 && fu_root pam-enable polkit-1
|
||||
|
||||
case "$FU_DESKTOP" in
|
||||
gnome)
|
||||
fu_gnome_extension_enable
|
||||
case $? in
|
||||
1) fu_bad "$(fu_msg "Could not switch on the GNOME extension that shows the bubble.")" ;;
|
||||
2) fu_note "$(fu_msg "Log out and back in once: then GNOME shows the bubble too.")" ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
fu_ok "$(fu_msg "Face unlock is on. Lock the screen and look at it to try.")"
|
||||
if [[ $CFG_SUDO != yes && $CFG_POLKIT != yes ]]; then
|
||||
fu_note "$(fu_msg "It can do sudo and admin prompts too. See Settings.")"
|
||||
@@ -120,6 +130,7 @@ fu_do_enable() {
|
||||
fu_do_disable() {
|
||||
fu_config_set Enabled no || { fu_bad "$(fu_msg "Could not save the setting.")"; return 1; }
|
||||
fu_agent_available && fu_agent_disable
|
||||
[[ $FU_DESKTOP == gnome ]] && fu_gnome_extension_disable
|
||||
|
||||
local service
|
||||
for service in "${FU_PAM_SERVICES[@]}"; do
|
||||
|
||||
+8
-9
@@ -276,8 +276,7 @@ fu_ui_status() {
|
||||
# heading, with only the label after it
|
||||
# type bool, choice (steps through the choices) or camera
|
||||
# needs a bool setting this one does nothing without; it is dimmed while
|
||||
# that is off. Layers is no setting: whether the desktop can show
|
||||
# the bubble at all (GNOME cannot).
|
||||
# that is off
|
||||
FU_SETTINGS=(
|
||||
"group|Lock screen"
|
||||
"user|LockScreen|bool|yes|Unlock with your face"
|
||||
@@ -295,7 +294,7 @@ FU_SETTINGS=(
|
||||
"sys|Adapt|bool|yes|Learn from every unlock"
|
||||
"sys|SkipLidClosed|bool|yes|Not when the lid is closed"
|
||||
"group|Bubble"
|
||||
"user|Bubble|bool|yes|Show the bubble||Layers"
|
||||
"user|Bubble|bool|yes|Show the bubble"
|
||||
"user|BubbleStyle|choice|full|Style|full,minimal|Bubble"
|
||||
"user|AnimationSpeed|choice|normal|Animation speed|slow,normal,fast|Bubble"
|
||||
"user|BubbleForPrompts|bool|yes|Also for sudo and admin prompts||Bubble"
|
||||
@@ -304,10 +303,12 @@ FU_SETTINGS=(
|
||||
# fu_setting_help <Key> <value>
|
||||
# What a setting does, shown under the list for the selected one.
|
||||
fu_setting_help() {
|
||||
if [[ $FU_DESKTOP == gnome && $1 =~ ^(Bubble|BubbleStyle|AnimationSpeed|BubbleForPrompts)$ ]]; then
|
||||
fu_msg "GNOME does not let other programs show above its windows, so there is no bubble on GNOME."
|
||||
return
|
||||
fi
|
||||
case "$FU_DESKTOP:$1" in
|
||||
gnome:Bubble)
|
||||
fu_msg "On GNOME a small GNOME extension shows the bubble. Turning face unlock on switches it on."
|
||||
return
|
||||
;;
|
||||
esac
|
||||
case "$1:$2" in
|
||||
LockScreen:*) fu_msg "Unlocks the lock screen when it sees your face. Off: only your password works there." ;;
|
||||
ScanOnWake:*) fu_msg "Scans when you press a key or move the mouse on the lock screen, and when the computer wakes up." ;;
|
||||
@@ -523,8 +524,6 @@ fu_ui_settings() {
|
||||
values[i]="$FU_SETTING_VALUE"
|
||||
current[${keys[i]}]="$FU_SETTING_VALUE"
|
||||
done
|
||||
current[Layers]=yes
|
||||
[[ $FU_DESKTOP == gnome ]] && current[Layers]=no current[Bubble]=no
|
||||
dirty=0
|
||||
fi
|
||||
|
||||
|
||||
@@ -145,6 +145,46 @@ fu_agent_hint() {
|
||||
fi
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# The bubble's GNOME Shell extension
|
||||
# ---------------------------------------------------------------------------
|
||||
# GNOME lets no program draw above its windows; its extensions may. The
|
||||
# package brings one, and turning face unlock on switches it on.
|
||||
|
||||
FU_GNOME_EXTENSION="face-unlock@loonixtools.github.io"
|
||||
|
||||
# fu_gnome_extension_enable
|
||||
# gnome-extensions only knows the extensions GNOME found when the session
|
||||
# started. One that came with the package later goes straight into the
|
||||
# setting, and GNOME loads it at the next login: returns 2 then.
|
||||
fu_gnome_extension_enable() {
|
||||
local list new
|
||||
fu_have gsettings || return 1
|
||||
if gnome-extensions info "$FU_GNOME_EXTENSION" > /dev/null 2>&1; then
|
||||
gnome-extensions enable "$FU_GNOME_EXTENSION" > /dev/null 2>&1 && return 0
|
||||
fi
|
||||
list="$(gsettings get org.gnome.shell enabled-extensions 2>/dev/null)" || return 1
|
||||
case "$list" in
|
||||
*"'$FU_GNOME_EXTENSION'"*) return 2 ;;
|
||||
'@as []'|'[]') new="['$FU_GNOME_EXTENSION']" ;;
|
||||
*) new="${list%]}, '$FU_GNOME_EXTENSION']" ;;
|
||||
esac
|
||||
gsettings set org.gnome.shell enabled-extensions "$new" || return 1
|
||||
return 2
|
||||
}
|
||||
|
||||
fu_gnome_extension_disable() {
|
||||
local list
|
||||
fu_have gsettings || return 0
|
||||
gnome-extensions disable "$FU_GNOME_EXTENSION" > /dev/null 2>&1 && return 0
|
||||
list="$(gsettings get org.gnome.shell enabled-extensions 2>/dev/null)" || return 0
|
||||
list="${list//, \'$FU_GNOME_EXTENSION\'/}"
|
||||
list="${list//\'$FU_GNOME_EXTENSION\', /}"
|
||||
list="${list//\'$FU_GNOME_EXTENSION\'/}"
|
||||
[[ $list == '[]' ]] && list='@as []'
|
||||
gsettings set org.gnome.shell enabled-extensions "$list" > /dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
fu_agent_disable() {
|
||||
systemctl --user disable --now "$FU_UNIT_AGENT" > /dev/null 2>&1 || true
|
||||
}
|
||||
Reference in new issue
Block a user