Docs

Everything beyond install — build, configure, internals, troubleshooting, contributing. Install and FAQ live on the home page.

Build from source

Standard CMake build. Install KDE Frameworks 6 + Qt 6 dev headers first (see Dependencies), then:

git clone https://github.com/xarbit/plasma6-applet-appgrid.git
cd plasma6-applet-appgrid
cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr
cmake --build build -j$(nproc)
sudo cmake --install build
kquitapp6 plasmashell && kstart plasmashell

Pass -DAPPGRID_UNIVERSAL_BUILD=ON to compile in the opt-in update checker (only used by the universal-tarball CI build). Pass -DAPPGRID_VERSION_OVERRIDE=<ver> to bake an explicit version string into the binary (see Versioning).

Arch users: a PKGBUILD ships at the repo root. Build a proper pacman package with makepkg -sf, install via sudo pacman -U.

Development builds

Every push to main is published to a separate -dev channel — bleeding-edge, rebuilt on every commit. Expect breakage; it’s for testing fixes before they land in a release, not for daily use.

Arch (AUR):

yay -S plasma6-applets-appgrid-git

A -git VCS package — it builds the latest main. Plain yay -Syu won’t detect new commits; rebuild with yay -Syu --devel to pull updates.

Fedora (Copr):

sudo dnf copr enable scujas/plasma-applet-appgrid-dev
sudo dnf install plasma-applet-appgrid

Ubuntu (Launchpad PPA):

sudo add-apt-repository ppa:xarbit/plasma-applet-appgrid-dev
sudo apt install plasma-applet-appgrid

There’s no -dev channel for the universal tarball — build from source for that. To leave the dev channel, remove the -dev repo (or the -git package) and switch to the stable Copr / PPA / AUR.

Dependencies (per distro)

Authoritative dep lists live alongside their packaging spec — keep these in sync with what you actually install.

Core runtime: plasma-workspace, libplasma, kservice, ki18n, kio, kpackage, kcoreaddons, kconfig, kwindowsystem, krunner, kirigami, layer-shell-qt, plasma-activities, plasma-activities-stats, qt6-base, qt6-declarative.

CMake build options

Pass with -D<option>=<value> on the cmake -B build invocation.

OptionDefaultEffect
APPGRID_VERSION_OVERRIDE(empty — derived from git)Bake an explicit version string into the binary. CI passes this for every release so the binary self-reports the exact release tag (see Versioning).
APPGRID_UNIVERSAL_BUILDOFFCompile in the opt-in update checker. ON only for the universal-tarball CI job; distro packages leave this OFF so the package manager handles updates.
ENABLE_X11ONCompile X11-specific session support (frameless window flags + manual screen positioning for the Center variant on X11). Turn OFF for Wayland-only builds (Plasma 6.8+).
BUILD_TESTINGOFFBuild the C++ + QML test suite. See Running the test suite.

Standard CMake options also apply: CMAKE_BUILD_TYPE (Release / RelWithDebInfo / Debug / None), CMAKE_INSTALL_PREFIX (default /usr/local — set to /usr for system installs), KDE_INSTALL_QTPLUGINDIR (override the Qt plugin install path — the Universal Package CI pins this to lib/qt6/plugins).

Configuration reference

Right-click the AppGrid panel icon → Configure AppGrid. Settings marked (Center only) apply only to the AppGrid Center variant; the Panel variant uses Plasma’s native popup for those.

SettingDescriptionDefault
IconPanel icon or custom imagedev.xarbit.appgrid (existing 1.7.x installs keep their prior icon)
Text labelOptional text next to the panel icon(empty)
Icons per row (Center)Columns in the grid5
Visible rows (Center)Rows visible before scrolling4
Icon sizeSmall (32 px), medium (48 px), large (64 px)Large
Sort orderAlphabetical, Most Used, By CategoryMost Used
Open on active screenOpen on mouse focus screen or panel screenOn
Show category barShow or hide the category filter barOn
Category tab styleCategory bar tabs: Default (text), Icon and text, or Icon onlyDefault
Open categories on hoverDwell on a category tab to select it without clickingOff
Search all appsSearch across categories regardless of active tabOn
Start with favoritesOpen showing favorites instead of all appsOff
Show recently usedRecently launched apps row at the top of the gridOn
Use system categoriesUse KDE Menu Editor categoriesOff
Hide empty categoriesHide categories with no appsOn
KRunner pluginsSearch bookmarks, files, websites via KRunnerOn
Inline completionGreyed completion of the best match in the search field, accepted with TabOn
Prefer frequently-used appsBias ranking with KActivities frecency (frequency + recency)On
Show Alt+1–9 badgeLaunch-shortcut badge on each result (shortcuts still work when off)On
Show hidden apps in searchKeep deliberately-hidden apps findable by nameOff
Terminal shellShell for t: commands/bin/sh
Show divider linesDividers between UI sectionsOn
Show scrollbarsScrollbars in grid and searchOff
Show tooltips on hoverApp description + install source on hoverOn
Show new app badgeGreen badge on newly installed appsOn
Drop shadow behind app iconsSoft drop shadow under each app icon in the gridOn
Hide labels on favorites tabRender the Favorites tab as icons only (no app names)Off
Sort favorites alphabeticallyAuto-sort favorites by name instead of manual orderOff
Reduce grid spacing (Center)Narrower cells for a tighter layout (the pre-1.9 width) instead of square cellsOff
Apply Size to app icons onlySize changes only the icons; labels, secondary icons and spacing stay at the defaultOff
Highlight icons on hoverSoft highlight behind an app icon on mouse hoverOn
Open/close animation (Center)None, Fade, Scale, Pop, Slide Up/Down, Glide, Buzz, Twist, Slam, Grow UpScale
Background blur (Center)Blur behind the launcherOn
Background contrast (Center)Plasma theme-tuned contrast filter behind the launcherOn
Use Plasma theme background (Center)Draw the panel using the active Plasma theme’s dialog SVG (matches the Panel variant)Off
Dim background (Center)Darken the screen behind the launcherOff
Compact mode (Center)Hide the grid and category bar until you start typing (Down arrow reveals)Off
Vertical position (Center)Offset the centered launcher up or down within the free space (−100 % = top, 0 % = centered, +100 % = bottom)0 %
Icon animationNone, Shake, Grow, Bounce, Spin, ShuffleShake
Animate icons on openPlay icon animation when launcher opensOn
Power & session buttonsPer-button show / hide and drag-reorder for sleep, restart, shutdown, session, lock, logout, switch userAll shown in default order
Show button labelsText labels on power / session buttonsOff
Background opacity (Center)Launcher background opacity85 %
Corner radius (Center)Custom corner radiusOff (uses Plasma theme)
Check for updates (Universal build only)Opt-in once-per-day check against the AppGrid release feedOff

Favorites storage

AppGrid stores favorites in KDE’s activity-aware favorites backend (KAStatsFavoritesModel, backed by KActivitiesStats from KDE Frameworks). It uses a single stable client id, dev.xarbit.appgrid.favorites.

What that means in practice:

Upgrading from an earlier version? See the migration notes.

Plasmoid variants & IDs

AppGrid ships as two plasmoids sharing a common C++ codebase but with separate metadata + applet IDs so they can be installed and configured independently. As of 1.9 each variant is a single compiled .so with its QML interface and metadata compiled in (no loose QML package), so after an update Plasma must be restarted to drop the old .so (see Restart Plasma after updating).

Both share the same grid, search, categories, quick commands, and favorite storage backend. Settings that don’t make sense for the panel variant (window-level blur, opacity, corner radius, open/close animation, multi-monitor screen selection) are managed by Plasma’s native popup instead and don’t appear in its Configure dialog.

Universal package internals

The Universal Package (appgrid-universal-<version>-<arch>.tar.gz) is built once per release against Fedora 42 (oldest mainstream distro shipping Plasma libs at SONAME 7) and runs on any Plasma 6.4+ system with matching SONAMEs. Install layout:

install.py preflight: refuses to run as root, validates $HOME, rejects existing system-wide installs (with the per-distro uninstall command), checks for plasmashell on PATH, runs ldd against the plugin to confirm every required library resolves (prints the per-distro install command for any missing deps), and mandatorily verifies SHA256SUMS over the payload before writing anything. Override --allow-coexist bypasses the system-wide-install refusal at your own risk.

Full guide bundled in every tarball: packages/universal/INSTALL.TXT.

Update checker — technical

The opt-in update checker (universal-tarball builds only — CMake flag APPGRID_UNIVERSAL_BUILD=ON) lives in src/updatechecker.cpp. Distro packages don’t link this in.

Test coverage: 62 cases in tests/test_updatechecker.cpp (version comparison, URL scheme validation, response-size cap, ETag rotation, state persistence).

Versioning scheme

The binary’s self-reported version (shown in the i: system-info view) is computed at build time by CMakeLists.txt in three priority tiers:

  1. If -DAPPGRID_VERSION_OVERRIDE=<ver> was passed, that wins. CI passes this for every release so the binary string matches the tarball filename + release tag exactly.
  2. Otherwise, if HEAD is exactly a release tag, use CMAKE_PROJECT_VERSION unchanged (e.g. "1.9.0").
  3. Otherwise it’s a local dev build between releases — derive {BASE}-dev.{N}+self.g{SHA} (where N is commits since the last tag and SHA is the 7-char short hash). The +self.g… build-metadata suffix flags the binary as hand-built (not a CI artifact). Per semver, build metadata is ignored for ordering — so update behaviour matches the equivalent CI build of the same git state. Useful in bug reports for telling local vs CI binaries apart at a glance.

Translations

Translation files live in po/ as <lang>/dev.xarbit.appgrid.po. To add or update a translation:

  1. Fork the repo, branch from main.
  2. For a new language: copy po/<closest-lang>/dev.xarbit.appgrid.po into a new po/<your-lang>/ directory; edit the msgstr entries.
  3. For an existing one: edit the .po file directly. Mark fuzzy entries with #, fuzzy until reviewed.
  4. Open a PR — keep changes scoped to translation files only; CI runs gettext validation.

Strings to translate are extracted from QML i18nd("dev.xarbit.appgrid", …) calls and C++ i18n(…) macros. Don’t add new msgid entries by hand — they’ll be regenerated on the next string-extraction pass and lost.

State file locations

Where AppGrid stores things on disk. Useful when debugging, wiping state, or migrating a setup to a new machine.

To wipe everything AppGrid wrote: uninstall (system package or ./uninstall.sh for universal), then delete the cache file + remove the AppGrid widget from your panel (this clears the per-applet config). Favorites in KActivitiesStats can be cleared via System Settings → Activities or by removing every favorite manually from the launcher.

Running the test suite

C++ and QML tests live in tests/. Configure with -DBUILD_TESTING=ON and run via ctest:

cmake -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=ON
cmake --build build -j$(nproc)
ctest --test-dir build --output-on-failure

Covered:

Open a PR with new tests when you fix a bug — CI runs ctest on every push.

Help & troubleshooting

Restart Plasma after updating

AppGrid’s QML is compiled into its .so, so a running plasmashell keeps the old version loaded until it restarts. After updating (any install method), log out and back in, or run:

kquitapp6 plasmashell && kstart plasmashell

Upgrading from AppGrid 1.7.x

1.8.0 migrates favorites to KDE’s activity-aware backend (KAStatsFavoritesModel — see Favorites storage). On first launch, AppGrid reads your existing legacy favoriteApps list and ports those entries into the new backend. The legacy list is kept as a backup so the migration is non-destructive — the flag favoritesPortedToKAstats in the plasmoid config tracks whether it has run.

If favorites look wrong after upgrading (missing entries, empty, ordering off): type i: in the search bar to open the system-info view. It shows the current migration status — KAStats entry count plus the legacy backup count — and a Re-run migration button. Clicking it clears the migration flag; on next open AppGrid recomputes the favorites list as the union of the legacy backup and current KAStats entries. Nothing is lost — missing legacy items are re-added.

If the entry counts in the i: view themselves look wrong, restart plasmashell to force a fresh model load: kquitapp6 plasmashell && kstart plasmashell.

Switching from a distro package to the Universal Package

Plasma can’t reliably load two copies of the same applet ID — uninstall the system package first, then run the universal installer. The bundled install.py detects the conflict and prints the matching uninstall command for your distro before doing anything.

Override with ./install.sh --allow-coexist at your own risk — Plasma will still load whichever plasmoid wins discovery on next session start, usually the system one.

Switching from the Universal Package back to a distro package

Run the bundled ./uninstall.sh from the tarball directory first — it reads ~/.local/share/appgrid/MANIFEST and removes only the files it placed. Then install the distro package the normal way. The ~/.config/plasma-workspace/env/appgrid-user-local.sh env script is removed too, so you do need one log-out / log-in after the swap.

AppGrid doesn’t show up after installing

  1. Restart plasmashell: kquitapp6 plasmashell && kstart plasmashell
  2. For the Universal Package specifically: log out + back in once on first install (Plasma needs to re-read its session env to pick up the new QT_PLUGIN_PATH).
  3. Right-click your panel launcher → Show Alternatives — AppGrid should appear in the list.
  4. If it’s still missing: check the installer’s ldd probe output for unresolved libraries (Universal Package), or journalctl --user -b | grep -i plasma for load errors.

Getting logs & debugging

AppGrid logs through Qt’s normal channels — there’s no separate log file. All messages surface in plasmashell’s journal. Every message AppGrid emits is prefixed with AppGrid: so it’s easy to filter.

Tail the plasmashell journal live:

journalctl --user -f -t plasmashell

Filter to AppGrid messages only:

journalctl --user -b -t plasmashell | grep AppGrid

Plugin loading problems (plasmoid doesn’t appear, “Couldn’t find plugin” errors): restart plasmashell with verbose Qt plugin logging attached to a terminal — this prints every plugin directory Qt scans and why each candidate is loaded or rejected.

kquitapp6 plasmashell
QT_DEBUG_PLUGINS=1 plasmashell --replace 2>&1 | tee plasmashell.log

For QML import errors specifically, add QML_IMPORT_TRACE=1 too. Both env vars are extremely noisy — only use for one-off debugging sessions.

Universal installer / uninstaller debugging: install.py and uninstall.py print every step to stdout; pass --dry-run to install.py to see what it would do without writing anything. Errors exit with non-zero status — pipe to a file with ./install.sh 2>&1 | tee install.log.

Update checker: inspect the cache file directly to see what the last check stored: cat ~/.cache/plasmashell/dev.xarbit.appgrid.update-checker.json. Force an immediate check by toggling the setting off and on (Configure AppGrid → Check the AppGrid website for new releases).

Iterating on the UI: because the QML is compiled into the .so, plasmoidviewer -a dev.xarbit.appgrid can’t load it from a loose package. Rebuild and restart plasmashell instead (cmake --build build && sudo cmake --install build && kquitapp6 plasmashell && kstart plasmashell). The QtQuickTest suite (see Running the test suite) is the fastest way to exercise QML logic without a full session.

Reporting a bug

Type i: in the search bar to open the system-info view, then click Copy — you’ll get a paste-ready report with your AppGrid version, install type (distro vs universal), Plasma version, Qt version, KF6 version, distro, and architecture. Attach it to the issue.

Open a new issue →

Real-time chat (Matrix)

Quick questions, install help, or “did anyone else hit this?” — easier in chat than an issue. AppGrid has a public Matrix space on matrix.org:

Don’t have a Matrix account? Sign up free at element.io (web/desktop/mobile) or any homeserver — federation means you can join from anywhere.