diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8112d59..f17f764 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,19 +17,37 @@ permissions: jobs: deb: - name: Debian package + name: Debian package (${{ matrix.name }}) runs-on: ubuntu-latest - # Plasma 6 arrived in Debian with trixie. - container: debian:trixie + # The package depends on the exact Qt it was built against, so each + # distribution gets a build and an APT repository of its own. + strategy: + matrix: + include: + # Plasma 6 arrived in Debian with trixie. + - name: Debian 13 + image: debian:trixie + codename: trixie + suffix: "~deb13" + - name: Kubuntu 26.04 + image: ubuntu:26.04 + codename: resolute + suffix: "~ubuntu26.04" + container: ${{ matrix.image }} + env: + DEBIAN_FRONTEND: noninteractive steps: - name: Install the build tools run: | apt-get update -qq + # Older Qt has the Wayland client tools in a package of their own. + extra="" + [ -n "$(apt-cache madison qt6-wayland-dev-tools)" ] && extra="qt6-wayland-dev-tools" apt-get install -y --no-install-recommends \ ca-certificates curl git make cmake g++ pkg-config gettext scdoc dpkg-dev \ - qt6-base-dev qt6-base-private-dev qt6-declarative-dev \ - qt6-wayland-dev qt6-wayland-dev-tools qt6-wayland-private-dev \ - liblayershellqtinterface-dev libkf6idletime-dev libkf6i18n-dev \ + qt6-base-dev qt6-base-dev-tools qt6-base-private-dev qt6-declarative-dev \ + qt6-wayland-dev qt6-wayland-private-dev $extra \ + liblayershellqtinterface-dev libkf6i18n-dev \ libopencv-dev libpam0g-dev libsystemd-dev - uses: actions/checkout@v7 @@ -38,6 +56,8 @@ jobs: run: packaging/check-version.sh "${{ github.ref_name }}" - run: packaging/build-deb.sh + env: + DEB_SUFFIX: ${{ matrix.suffix }} - name: Look inside what was built run: | @@ -46,7 +66,7 @@ jobs: - uses: actions/upload-artifact@v7 with: - name: deb + name: deb-${{ matrix.codename }} path: dist/*.deb if-no-files-found: error @@ -174,8 +194,10 @@ jobs: - name: Check that what was written can be verified if: steps.key.outputs.present == 'yes' run: | - gpg --verify pages/deb/InRelease - gpg --verify pages/deb/Release.gpg pages/deb/Release + for suite in pages/deb/*/; do + gpg --verify "$suite/InRelease" + gpg --verify "$suite/Release.gpg" "$suite/Release" + done gpg --verify pages/rpm/repodata/repomd.xml.asc pages/rpm/repodata/repomd.xml - uses: actions/upload-artifact@v7 @@ -199,11 +221,22 @@ jobs: git push "https://x-access-token:${GH_TOKEN}@github.com/${{ github.repository }}.git" HEAD:gh-pages verify-apt: - name: Install from the APT repository + name: Install from the APT repository (${{ matrix.name }}) needs: publish if: inputs.dry_run runs-on: ubuntu-latest - container: debian:trixie + strategy: + matrix: + include: + - name: Debian 13 + image: debian:trixie + codename: trixie + - name: Kubuntu 26.04 + image: ubuntu:26.04 + codename: resolute + container: ${{ matrix.image }} + env: + DEBIAN_FRONTEND: noninteractive steps: - uses: actions/download-artifact@v8 with: @@ -214,7 +247,7 @@ jobs: apt-get update -qq && apt-get install -y --no-install-recommends gpg install -d -m 0755 /etc/apt/keyrings gpg --dearmor -o /etc/apt/keyrings/plasma-face-unlock.gpg < pages/KEY.gpg - echo "deb [signed-by=/etc/apt/keyrings/plasma-face-unlock.gpg] file://$PWD/pages/deb ./" \ + echo "deb [signed-by=/etc/apt/keyrings/plasma-face-unlock.gpg] file://$PWD/pages/deb/${{ matrix.codename }} ./" \ > /etc/apt/sources.list.d/plasma-face-unlock.list apt-get update apt-get install -y plasma-face-unlock diff --git a/CMakeLists.txt b/CMakeLists.txt index 74bceb3..440fd8f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -133,8 +133,12 @@ if(PFU_BUILD_AGENT) find_package(Qt6 6.5 REQUIRED COMPONENTS Gui Quick WaylandClient) # The bubble needs the Wayland surface of its window, which only the # private API hands out. It is the same one Plasma itself uses for this. - set(QT_NO_PRIVATE_MODULE_WARNING ON) - find_package(Qt6 REQUIRED COMPONENTS GuiPrivate WaylandClientPrivate) + # Newer Qt ships the private modules as packages of their own; older Qt + # (6.8 in Debian 13) brings them along with the public ones. + if(EXISTS "${Qt6_DIR}/../Qt6GuiPrivate/Qt6GuiPrivateConfig.cmake") + set(QT_NO_PRIVATE_MODULE_WARNING ON) + find_package(Qt6 REQUIRED COMPONENTS GuiPrivate WaylandClientPrivate) + endif() find_package(LayerShellQt REQUIRED) find_package(KF6I18n REQUIRED) diff --git a/README.md b/README.md index 1cefdfd..6a59caa 100644 --- a/README.md +++ b/README.md @@ -7,12 +7,12 @@
- Look at the screen and it unlocks. Works for the lock screen, sudo and admin prompts, and a photo of you is not enough. + Look at the screen and it unlocks: the lock screen, sudo and admin prompts. A photo of you is not enough.
-Come back to your locked screen, move the mouse, look at it: a little bubble drops down at the top,
-the face in it looks around, two green rings spin and land around a tick, and you are in. The same
-for `sudo` in a terminal and for the admin password prompts of Plasma, if you want. Everything runs
-on your machine, and your face is stored as numbers, never as a picture.
+Come back to your locked screen and look at it. A bubble drops down at the top, finds your face,
+and you are in. It works for `sudo` and Plasma's admin prompts too, if you want. Everything runs on
+your computer, and your face is saved as numbers, never as a picture.
-The look of the bubble and the photo check are inspired by [Glance](https://github.com/jonnyoo/glance)
-(face unlock for the Mac). The code is written from scratch for Plasma.
+## Install
-## How to use
-
-Just run `plasma-face-unlock`. This will open the configuration TUI that looks like this:
-
-```
- Plasma Face Unlock
-
- Face unlock ON
-
- Faces 2 (Felix, Felix with glasses)
- Camera Integrated Camera
- Lock screen on
- sudo on
- Admin prompts off
- Photo check strict (blink or turn your head)
- Last unlock 2 minutes ago
-
- [1] Turn face unlock on or off
- [2] Add a face
- [3] Faces
- [4] Settings
- [5] Try it
- [q] Quit
-
- >
-```
-
-Press `[1]`. The first time, it opens the setup window: look at the camera, then move your head
-slowly in a circle until the ring around the picture is full (like setting up Face ID on a phone).
-It asks for your password once before it adds the face. After that, lock the screen and look at it.
-
-`[5]` does one scan and shows what the camera sees, which helps a lot when something does not work.
-`[4]` has everything else:
-
-```
- Settings
-
- ▸ Unlock the lock screen ON
- Look when somebody comes back to the screen ON
- Look right after the screen locks OFF
-
- Use for sudo in a terminal* ON
- Use for admin prompts* OFF
-
- Photo check* strict (blink or turn your head)
- How closely a face has to match* normal
- Only while looking at the screen* ON
- Camera* automatic (Integrated Camera)
- How long one look lasts* 5 seconds
- Learn from every unlock* ON
- Not while the lid is closed* ON
-
- Show the bubble at the top ON
- Bubble style island with the face
- Animation speed normal
- Bubble for sudo and admin prompts too ON
-
- Settings marked * are for the whole computer and ask for your password.
- Up/Down: select, Space or Right: change, q: back
-```
-
-## How to install
-
-**Arch**
+**Arch, CachyOS, EndeavourOS, Manjaro** (AUR)
```bash
yay -S plasma-face-unlock
```
-**Fedora**
+**Fedora 44**
```bash
sudo curl -fsSL -o /etc/yum.repos.d/plasma-face-unlock.repo \
@@ -114,117 +49,96 @@ sudo curl -fsSL -o /etc/yum.repos.d/plasma-face-unlock.repo \
sudo dnf install plasma-face-unlock
```
-**Debian** (13 or newer) **and Kubuntu** (25.04 or newer)
+**Debian 13**
```bash
sudo install -d -m 0755 /etc/apt/keyrings
curl -fsSL https://loonixtools.github.io/plasma-face-unlock/KEY.gpg \
| sudo gpg --dearmor -o /etc/apt/keyrings/plasma-face-unlock.gpg
-echo "deb [signed-by=/etc/apt/keyrings/plasma-face-unlock.gpg] https://loonixtools.github.io/plasma-face-unlock/deb ./" \
+echo "deb [signed-by=/etc/apt/keyrings/plasma-face-unlock.gpg] https://loonixtools.github.io/plasma-face-unlock/deb/trixie ./" \
| sudo tee /etc/apt/sources.list.d/plasma-face-unlock.list
sudo apt update && sudo apt install plasma-face-unlock
```
-You need Plasma 6 on Wayland and a camera. An infrared camera (the Windows Hello kind) works too.
+**Kubuntu 26.04**
+
+```bash
+sudo install -d -m 0755 /etc/apt/keyrings
+curl -fsSL https://loonixtools.github.io/plasma-face-unlock/KEY.gpg \
+ | sudo gpg --dearmor -o /etc/apt/keyrings/plasma-face-unlock.gpg
+echo "deb [signed-by=/etc/apt/keyrings/plasma-face-unlock.gpg] https://loonixtools.github.io/plasma-face-unlock/deb/resolute ./" \
+ | sudo tee /etc/apt/sources.list.d/plasma-face-unlock.list
+sudo apt update && sudo apt install plasma-face-unlock
+```
+
+Updates then come with your normal system updates.
+
+You need Plasma 6 on Wayland and a camera. Infrared cameras (the Windows Hello kind) work too.
+
+## How to use
+
+```bash
+plasma-face-unlock
+```
+
+This opens a menu. Press **1** and follow the setup window: look at the camera, then turn your head
+slowly in a circle until the ring is full. Then lock the screen and look at it.
+
+| Key | |
+|---|---|
+| **1** | Turn face unlock on or off |
+| **2** | Add another face, for example with glasses |
+| **3** | Rename, turn off or delete faces |
+| **4** | Settings: sudo, admin prompts, photo check, camera, bubble style, animation speed and more |
+| **5** | One test scan that shows what the camera sees. Try this first when something does not work. |
+
+Without the menu: `plasma-face-unlock enable`, `disable`, `setup [NAME]`, `faces`, `remove ID`,
+`test` and `status`.
## Is it safe?
-**It is a convenience, not a security upgrade.** A phone builds a 3D map of your face with a dot
-projector. A webcam only sees a flat picture, so this cannot be as safe as Face ID. What it does:
+It is a convenience, not a security upgrade. Face ID on a phone sees your face in 3D. A webcam only
+sees a flat picture.
-- A photo, printed or on a phone, held up and turned any way, **does not** get in. With the photo
- check on *strict* (the default) the face has to blink or turn a little, and a photo can do neither.
-- A screen or a glossy print held up to the camera throws back one big flat reflection, and a phone
- has straight edges around the face. Both fail the scan straight away.
-- A **video** of you blinking can still get through. So can, some of the time, a photo that is
- curled a lot and turned a lot.
+- A photo does not get in: the face has to blink or turn a little, and a photo can do neither.
+- A phone or tablet held up to the camera is caught by its reflection and its straight edges.
+- A video of you can still get in.
- Five failed tries in a row pause it for 15 minutes, or until you use your password.
-- Your face data can only be read by root. Adding or deleting a face always needs your password,
- never a face.
-- sudo and admin prompts never take a face over SSH, or when you are not sitting at the machine.
+- Only root can read your face data. Adding or deleting a face always needs your password.
+- sudo and admin prompts never take a face over SSH.
-If the machine guards something that matters, leave sudo and admin prompts off.
+If the computer guards something important, leave sudo and admin prompts off.
## How it works
-Four parts:
-
| | |
|---|---|
-| `plasma-face-unlockd` | Runs as root, started on demand. Owns the camera and the face data, and decides. |
-| `plasma-face-unlock-agent` | Runs in your session. Watches the lock screen, draws the bubble, is the setup window. |
-| `pam_plasma_face_unlock.so` | Lets sudo and polkit ask the daemon. |
-| `plasma-face-unlock` | This menu. |
+| `plasma-face-unlockd` | Runs as root when needed. It owns the camera and the face data and decides. |
+| `plasma-face-unlock-agent` | Runs in your session. It watches the lock screen and draws the bubble. |
+| `pam_plasma_face_unlock.so` | Lets sudo and admin prompts ask the daemon. No match: you type your password as usual. |
+| `plasma-face-unlock` | The menu. |
-Faces are found with **YuNet** and turned into 128 numbers with **SFace**, two small networks from
-the OpenCV model zoo that run on the CPU in a few milliseconds. Two pictures of the same person give
-numbers that point the same way; how much they do is the match.
+Two small networks from the OpenCV model zoo find the face (YuNet) and turn it into numbers (SFace).
+They run on the CPU in a few milliseconds. The lock screen is unlocked through logind, the same way
+`loginctl unlock-session` does it. `man plasma-face-unlock` has all the details.
-**The photo check** looks for a sign of life on top of the match:
-
-- **Blink:** the dark of both eyes shrinks to a line and comes back within the fraction of a second a
- blink takes, while the rest of the face holds still.
-- **Head turn:** the eyes and the corners of the mouth lie close to one plane, so for a flat picture
- they predict exactly where the nose has to go when it is turned. A real nose sticks out of that
- plane and misses the prediction by about as much as the head turned.
-
-The head turn check is tested against simulated heads and photos (`make test`): photos turned up to
-60 degrees at heavy camera noise never pass, real heads of all shapes pass 98% of the time.
-
-**The lock screen** is not unlocked through its password prompt (Plasma runs fingerprints there, but
-only once per lock). Instead the agent notices the screen locking, scans when you come back (a key,
-the mouse, the lid, waking from sleep), and unlocks the session through logind, just like
-`loginctl unlock-session`. KWin lets the bubble show above the lock screen because the agent's desktop
-file asks for it.
-
-**sudo and admin prompts** get one line in front of their PAM stack:
-
-```
--auth sufficient /usr/lib/security/pam_plasma_face_unlock.so
-```
-
-A match lets you in, anything else falls through to the password. The dash makes PAM skip it quietly
-if the module is ever missing, so sudo keeps working even after uninstalling. Turning it off takes out
-exactly that line.
-
-The man page (`man plasma-face-unlock`) has all the details.
-
-## Commands
-
-| Command | |
-|---|---|
-| `plasma-face-unlock` | Interactive menu |
-| `… enable` | Turn on (sets up a face first if needed) |
-| `… disable` | Turn off, keep the faces |
-| `… setup [NAME]` | Add a face |
-| `… faces` | List the faces |
-| `… remove ID` | Delete a face |
-| `… test` | One scan, with what the camera sees |
-| `… status` | What is on |
-
-## Building from source
+## Build from source
```bash
-make models # downloads the two networks, checked against pinned checksums
+make models # downloads the two networks and checks them
make
make test
sudo make install
```
-Needs CMake, a C++20 compiler, Qt 6 (Core, DBus, Network, Gui, Quick, WaylandClient), LayerShellQt,
-KI18n, OpenCV 4.5.4 or newer with the DNN module, Linux-PAM and libsystemd. Optionally
-`msgfmt` (gettext) for translations and `scdoc` for the man page. Supports `PREFIX` and `DESTDIR`.
-`make check` runs syntax checks and shellcheck.
-
-To try it without a camera, point the camera setting at a folder of pictures (`images:/path`) or a
-video (`file:/path.mp4`) in `/etc/plasma-face-unlock/config`.
-
-See [packaging/README.md](packaging/README.md) for release builds and repo signing.
+You need CMake, a C++20 compiler, Qt 6, LayerShellQt, KI18n, OpenCV 4.5.4 or newer (with DNN),
+Linux-PAM and libsystemd. `scdoc` and `msgfmt` are optional (man page, translations).
+[packaging/README.md](packaging/README.md) explains releases.
## Credits
-- [Glance](https://github.com/jonnyoo/glance) by Jonathan Zhou (MIT): the idea, the look of the bubble
- and the model of deny and confirm cues.
+- [Glance](https://github.com/jonnyoo/glance) by Jonathan Zhou (MIT): face unlock for the Mac. The
+ idea, the look of the bubble and the photo check come from there. The code here is new.
- [YuNet](https://github.com/opencv/opencv_zoo/tree/main/models/face_detection_yunet) (MIT) and
[SFace](https://github.com/opencv/opencv_zoo/tree/main/models/face_recognition_sface) (Apache-2.0)
from the OpenCV model zoo.
diff --git a/packaging/README.md b/packaging/README.md
index da2a811..d587f10 100644
--- a/packaging/README.md
+++ b/packaging/README.md
@@ -20,6 +20,12 @@ development packages to build: Debian 13 (trixie) and current Fedora have
them. The Debian package's library dependencies are read off the binaries by
`dpkg-shlibdeps`; RPM does the same on its own.
+The program uses Qt's private API, so a package only fits the Qt it was built
+against. The `.deb` is therefore built twice, in Debian 13 and in Ubuntu 26.04
+(for Kubuntu), with a suffix on the version (`~deb13`, `~ubuntu26.04`), and each
+gets an APT repository of its own: `deb/trixie` and `deb/resolute`. The RPM is
+built on the current Fedora.
+
The two networks (YuNet and SFace, from the OpenCV model zoo) are not in the
repository. `make models` downloads them and checks them against the
checksums in the Makefile. The RPM spec and the PKGBUILD list them as sources
diff --git a/packaging/build-deb.sh b/packaging/build-deb.sh
index b752633..ad978b5 100755
--- a/packaging/build-deb.sh
+++ b/packaging/build-deb.sh
@@ -18,6 +18,9 @@ set -euo pipefail
here="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
version="${1:-$(make -s -C "$here" version)}"
+# The package depends on the exact Qt of the distribution it is built on, so
+# each one gets a build of its own, told apart by a suffix: ~deb13, ~ubuntu26.04.
+debversion="$version${DEB_SUFFIX:-}"
name=plasma-face-unlock
# A package without its man page or its translations is not a package this
@@ -49,7 +52,7 @@ depends="$(cd "$work" && dpkg-shlibdeps -O "${elves[@]/#/-e}" 2>/dev/null | sed
[[ -n $depends ]] || { echo "$0: dpkg-shlibdeps found no dependencies" >&2; exit 1; }
install -d "$root/DEBIAN"
-sed -e "s|@VERSION@|$version|g" -e "s|@ARCH@|$arch|g" -e "s|@DEPENDS@|$depends|g" \
+sed -e "s|@VERSION@|$debversion|g" -e "s|@ARCH@|$arch|g" -e "s|@DEPENDS@|$depends|g" \
"$here/packaging/deb/control" > "$root/DEBIAN/control"
install -Dm644 "$here/packaging/deb/copyright" "$root/usr/share/doc/$name/copyright"
@@ -69,7 +72,7 @@ chmod 755 "$root/DEBIAN/prerm"
| LC_ALL=C sort -z | xargs -0 md5sum > DEBIAN/md5sums )
mkdir -p "$here/dist"
-out="$here/dist/${name}_${version}_${arch}.deb"
+out="$here/dist/${name}_${debversion}_${arch}.deb"
dpkg-deb --root-owner-group --build "$root" "$out" > /dev/null
echo "$out"
diff --git a/packaging/pages/index.html b/packaging/pages/index.html
index 384ebeb..e43605b 100644
--- a/packaging/pages/index.html
+++ b/packaging/pages/index.html
@@ -76,16 +76,25 @@
documentation are on GitHub.
-sudo install -d -m 0755 /etc/apt/keyrings
curl -fsSL @BASEURL@/KEY.gpg \
| sudo gpg --dearmor -o /etc/apt/keyrings/plasma-face-unlock.gpg
-echo "deb [signed-by=/etc/apt/keyrings/plasma-face-unlock.gpg] @BASEURL@/deb ./" \
+echo "deb [signed-by=/etc/apt/keyrings/plasma-face-unlock.gpg] @BASEURL@/deb/trixie ./" \
| sudo tee /etc/apt/sources.list.d/plasma-face-unlock.list
sudo apt update
sudo apt install plasma-face-unlock
-sudo install -d -m 0755 /etc/apt/keyrings
+curl -fsSL @BASEURL@/KEY.gpg \
+ | sudo gpg --dearmor -o /etc/apt/keyrings/plasma-face-unlock.gpg
+echo "deb [signed-by=/etc/apt/keyrings/plasma-face-unlock.gpg] @BASEURL@/deb/resolute ./" \
+ | sudo tee /etc/apt/sources.list.d/plasma-face-unlock.list
+sudo apt update
+sudo apt install plasma-face-unlock
+
+sudo curl -fsSL -o /etc/yum.repos.d/plasma-face-unlock.repo \
@BASEURL@/plasma-face-unlock.repo
sudo dnf install plasma-face-unlock
diff --git a/packaging/publish-repos.sh b/packaging/publish-repos.sh
index 2512159..ae9444c 100755
--- a/packaging/publish-repos.sh
+++ b/packaging/publish-repos.sh
@@ -24,46 +24,34 @@ base_url="${PFU_REPO_URL:-https://loonixtools.github.io/plasma-face-unlock}"
keyid="$(gpg --list-secret-keys --with-colons | awk -F: '/^sec:/ { print $5; exit }')"
[[ -n $keyid ]] || { echo "$0: no secret key in the keyring" >&2; exit 1; }
-mkdir -p "$pages/deb" "$pages/rpm"
-cp -- "$incoming"/*.deb "$pages/deb/"
+mkdir -p "$pages/rpm"
cp -- "$incoming"/*.rpm "$pages/rpm/"
-# ---------------------------------------------------------------------------
-# APT
-# ---------------------------------------------------------------------------
-# A flat repository: the packages and their index sit in one directory and the
-# sources line ends in "./". There is one distribution here and it is the same
-# package for all of them, so the suite and component machinery of a pool
-# layout would describe nothing.
-(
- cd "$pages/deb"
+# One APT repository per distribution: each .deb depends on the exact Qt it was
+# built against, and its version carries the suffix saying which one that was.
+for suite in trixie:deb13 resolute:ubuntu26.04; do
+ codename="${suite%%:*}"
+ tag="${suite#*:}"
+ mkdir -p "$pages/deb/$codename"
+ cp -- "$incoming"/*"~${tag}_"*.deb "$pages/deb/$codename/"
+ (
+ cd "$pages/deb/$codename"
+ rm -f Packages Packages.gz Release Release.gpg InRelease
+ dpkg-scanpackages --multiversion . > Packages
+ gzip -9kf Packages
+ apt-ftparchive \
+ -o APT::FTPArchive::Release::Origin=plasma-face-unlock \
+ -o APT::FTPArchive::Release::Label=plasma-face-unlock \
+ -o APT::FTPArchive::Release::Suite="$codename" \
+ -o APT::FTPArchive::Release::Codename="$codename" \
+ -o APT::FTPArchive::Release::Architectures=amd64 \
+ -o APT::FTPArchive::Release::Components=main \
+ release . > Release
+ gpg --batch --yes --local-user "$keyid" --clearsign --output InRelease Release
+ gpg --batch --yes --local-user "$keyid" --detach-sign --armor --output Release.gpg Release
+ )
+done
- # The old index must be gone before the new one is written: apt-ftparchive
- # hashes every file in the directory, and a Release that hashes the
- # previous Release is a Release that cannot be verified.
- rm -f Packages Packages.gz Release Release.gpg InRelease
-
- dpkg-scanpackages --multiversion . > Packages
- gzip -9kf Packages
-
- apt-ftparchive \
- -o APT::FTPArchive::Release::Origin=plasma-face-unlock \
- -o APT::FTPArchive::Release::Label=plasma-face-unlock \
- -o APT::FTPArchive::Release::Suite=stable \
- -o APT::FTPArchive::Release::Codename=stable \
- -o APT::FTPArchive::Release::Architectures=amd64 \
- -o APT::FTPArchive::Release::Components=main \
- release . > Release
-
- # Both signatures: InRelease is what current apt fetches, Release.gpg is
- # what an older one falls back to.
- gpg --batch --yes --local-user "$keyid" --clearsign --output InRelease Release
- gpg --batch --yes --local-user "$keyid" --detach-sign --armor --output Release.gpg Release
-)
-
-# ---------------------------------------------------------------------------
-# RPM
-# ---------------------------------------------------------------------------
(
cd "$pages/rpm"
createrepo_c --quiet --update .
@@ -85,4 +73,4 @@ sed "s|@BASEURL@|$base_url|g" "$here/packaging/pages/plasma-face-unlock.repo" \
touch "$pages/.nojekyll"
echo "signed with $keyid"
-ls -1 "$pages/deb" "$pages/rpm"
+ls -1 "$pages"/deb/* "$pages/rpm"
diff --git a/src/agent/bubblewindow.cpp b/src/agent/bubblewindow.cpp
index af1afc3..4f9b28b 100644
--- a/src/agent/bubblewindow.cpp
+++ b/src/agent/bubblewindow.cpp
@@ -68,7 +68,6 @@ void BubbleWindow::create()
// rather than being pushed down below it.
layer->setExclusiveZone(-1);
layer->setKeyboardInteractivity(LayerShellQt::Window::KeyboardInteractivityNone);
- layer->setActivateOnShow(false);
// KWin makes a window type of the scope and takes one it does not
// know for a normal window. Its scale effect then opens and closes
// that with a blur forced behind the whole, mostly clear window: a