Reshape the convergence quick settings into a compact
promoted grid and add Clipboard, Disks & Devices, and a
drawer-hosted System Tray popup.
Retry applet popups when their full representation becomes
ready so the desktop utilities open reliably.
Animate dock item sizing and button opacity when toggling convergence
mode so the dock does not snap abruptly between states.
FavouritesBar: promote cell/icon/nav/pager/trash sizing properties to
writable and attach NumberAnimation Behaviors (InOutCubic, longDuration).
Home, Overview, and trash buttons fade in/out with an InOutQuad opacity
Behavior so they appear gradually rather than popping.
Dock overlay (main.qml): introduce an `active` guard property so the
window can be driven by opacity (InOutQuad, shortDuration) rather than
toggling visibility directly. Switch the dockOffset slide easing from
a directional InExpo/OutExpo pair to a single InOutCubic so the motion
feels symmetrical.
StatusBar: smooth the background colour and convergence affordance
transitions.
Expose snapLayoutsEnabled through MobileShellSettings and store it\nin plasmamobilerc.\n\nUse the setting in the Shift snap assist effect eligibility logic\nand add a Convergence KCM switch to control it.\n\nKeep the switch disabled when convergence is off, gaming mode is on,\nor dynamic tiling is enabled so window-placement ownership stays\nconsistent.
Expose dynamicTilingEnabled (default true) on MobileShellSettings,
stored under the General group of plasmamobilerc and re-emitted by
the existing config watcher. shift-tiling extends its activation
guard with this flag and clears the BSP layout when it goes false,
so users can fall back to KWin native quick-tile at will.
Add a quick-settings tile that surfaces the toggle. available is
gated on convergenceModeEnabled and !gamingModeEnabled, so the tile
is hidden on the phone form factor and during gaming sessions.
The coloured rectangle that paints over the bottom panel during an
app-launch animation was reset only by a change of
WindowMaximizedTracker.showingWindow. In convergence mode kwinrc
sets Placement=Centered, so launched apps stay non-maximized,
showingWindow never flips and the band remained on the panel
indefinitely.
Restart a 600 ms safety timer whenever the animation is triggered.
When it fires, clear colour and height to zero only if no maximized
or fullscreen window exists, preserving the original mobile reset
path while fixing the convergence one.
The header button used list-add icon and hard-coded white backgrounds
that did not match the dark theme. Change icon to configure (it opens
Configure Folio for advanced settings, not add-wallpaper), and use
Kirigami.Theme.backgroundColor for both the header and thumbnail
backgrounds.
When homescreen wallpaper is set, also persist the same image for lockscreen. Add a one-time migration in loadHomescreenSettings() that updates lockscreen when it is unset or still points to legacy Next wallpaper.
Introduce shared dock height/reveal constants and use them in folio and taskpanel to keep overlay and exclusion zone aligned. Keep dock backing stationary while only content slides, and add a CTest invariant script to prevent regressions.
Track docked state transitions in KScreenOSDProvider and only snapshot the initial convergence mode when transitioning into docked mode. This restores the previous user preference when outputs drop back to one.
Steam, Lutris, and Heroic filter tabs in the Game Center are now
only shown when those launchers are detected on the system. Detection
checks the native executable, known Flatpak data directories, and
standard data paths. The tab bar shrinks accordingly.
Drop the empty loadFlatpakGames() stub — desktop .desktop files
with the Game category are already covered by loadDesktopGames().
Remove InstalledRole: the field was always true and nothing in QML
consumed it.
gamepadAt() is an internal helper; drop Q_INVOKABLE so it isn't
part of the public QML surface.
Inject MangoHud when launching desktop and command-line games.
MANGOHUD_CONFIG is built per-launch via a QProcess instance so
env vars are isolated to each child process — qputenv is not used.
Global overlay toggle and FPS cap (Off/30/40/60) are stored as
properties on GameLauncherProvider and reflected in the quick
settings panel. Per-game overrides stored in plasmamobilerc under
[GamingPerGame/<storageId>] take precedence over the globals at
launch time.
Games can be pinned to the top of the grid. The pinned set is
persisted in plasmamobilerc [GamingPinned] and restored on start.
applyFilter() uses stable_sort so pinned games float to the top
while alphabetical order is preserved within each group.
Read the Waydroid allowlist from plasmamobilerc and treat matching
Waydroid launchers as their own source in the gaming shell.
Surface that source in Game Center so Android titles get their own tab,
source chip, and empty-state guidance.
Record recent launches only after the launcher reports success instead of
optimistically on every attempt. For desktop entries, wait for the
ApplicationLauncherJob result; for detached commands, use startDetached's
return value and show an inline error when startup fails.
Parse Steam libraryfolders and app manifests as KeyValues instead of
matching individual lines. This makes Steam discovery less brittle when
the files contain comments, nested blocks, or different formatting.
Keep Continue Playing visible alongside Running and show a temporary
launching state so the overlay does not pretend a task already exists.
Rename the GameMode status text to say what the shell actually knows.
Use SDL button labels so shell prompts match the connected
controller instead of always using Xbox-style wording. Expose
trigger rumble, touchpad count, gyro, and accelerometer support
through the gamepad wrapper and surface the relevant capability
labels in the overlay.
Enable background gamepad events and add short rumble feedback
for major shell actions such as opening quick settings, opening
the exit prompt, and launching a game.
Add PowerProfileControl and GameModeControl singletons and wire
them into gaming mode lifecycle handling. When gaming mode turns
on, keep DND on, switch to the performance profile when available,
and request GameMode. Restore previous state when gaming mode
turns off.
Add an overlayEnabled property in GameLauncherProvider so the
launcher can toggle MangoHud environment variables from QML.
Slide-out panel with brightness, volume, Wi-Fi, Bluetooth,
and airplane mode. Fully gamepad-navigable; D-pad and stick
input routed to the panel while open. System status bar
(clock, battery, connectivity) added to game center header.
Lutris games discovered from ~/.local/share/lutris/pga.db,
Heroic from ~/.config/heroic/store_cache/ JSON files.
Deduplication extended to cover all launcher sources.
Desktop entries launched via KIO::ApplicationLauncherJob to
expand Exec field codes. Generic commands parsed with
KShell::splitArgs. SQLite uses RAII cleanup guard.
Clamped SDL axis, rumble, and LED values. Renamed rumble
params from frequency to intensity. GamepadManager uses
singleton factory. setPlayerIndex checks SDL return.
FavouritesBar popup uses screen virtualX/Y for multi-monitor.
Both launch() and launchByStorageId() duplicated the process
spawn, signal emission, and timestamp bookkeeping. Move it to
a single private launchEntry(GameEntry&) method.
When a game appears as both a Steam manifest and an XDG
desktop entry, drop the desktop duplicate. Steam entries are
preferred because they carry cover artwork and route through
the Steam launcher for Proton compatibility.
Expose SDL_GamepadAxis as an Axis enum in GamepadManager so
QML can identify axis events by name.
Convert left-stick deflection into repeated grid navigation
events with a 150ms interval and 0.4 deadzone. First movement
fires immediately when the stick crosses the threshold.
Wrap game launches in a brief fade-to-black curtain (250ms)
before dismissing the overlay, giving visual feedback that the
launch is in progress.
Grid tiles now show Steam library artwork when available,
falling back to icon+label for games without cover art.
Cell proportions adjusted to 2:3 for portrait covers.
Search bar filters the library by name. Source tabs filter
by All/Steam/Desktop. Both properties live in C++ so QML
just binds filterString and sourceFilter.
"Continue Playing" row shows the last 5 launched games
with artwork, persisted across sessions via plasmamobilerc.
Remove orphaned GameTile.qml (replaced by inline delegate).
SDL3-backed gamepad manager polls at 60Hz, handles hotplug,
exposes battery/rumble/LED per device. Game launcher aggregates
XDG desktop entries, Steam appmanifests, and Flatpak into a
single sorted model.
Game Center uses the new model instead of folio's search model.
D-pad/A/B/Y navigate and launch. Guide button toggles the
overlay. Battery and controller status shown in the HUD.
Strut windows committed zero height to layer-shell during
early init, causing a protocol error and session exit. Wrap
height and exclusionZone in Math.max(1, ...) for top bar
and dock.
Persisted gamingModeEnabled=true with hardcoded
gameCenterOpen=false hid panels with no overlay visible.
Initialize gameCenterOpen from the stored setting.
Fix HUD visibility regression from an emergency visible:true
override. Various null-guard and positioning fixes from
static analysis across the gaming shell QML.
Add a gamingModeEnabled bool and a gamingDismissHintEnabled bool to
the shell settings plugin, persisted in plasmamobilerc [General],
following the same pattern as convergenceModeEnabled.
Two new quick settings tiles:
- org.kde.plasma.quicksetting.gaming: toggles gaming mode on/off,
shows explicit on/off label matching the convergence tile style.
- org.kde.plasma.quicksetting.gaminghint: shown while gaming mode
is active; dismisses the Game Center hint.
Both tiles are added to the default group in quicksettings config.
Use Kirigami.Theme.textColor for the status bar hover overlay
so it works on both light and dark themes instead of hardcoded
white. Remove convergence-mode branches from the navigation
panel left action since it is hidden in convergence mode and
the code paths were unreachable.
The input region Y was computed from the bottom of the screen
instead of from the top, causing the touch region to be offset
from the actual popup. Use openOffset directly since the popup
anchors to the top. Unify the popup margin into a single
property so the delegate x and the input-region regionX stay
consistent.
Check restrictedPermissions before opening the detail popup in
convergence mode. Guard against null output in the KWin script
window-setup handler to prevent TypeError when a window has no
assigned output yet.
loadPackage + setPath can produce an invalid package if the shell
package is missing. Guard with isValid() to avoid passing a bad
package to setKPackage. Add the QML_SINGLETON factory that the
QML engine requires for proper singleton instantiation.
find_package(KF6Auth) was placed after target_link_libraries, so
KF6::AuthCore could be undefined when the linker target was
created. Move it before target_link_libraries in both the
flashlight and waydroid helpers.
NavigationPanel: the taskStrip ListView checked contentWidth > width
to decide whether scrolling is enabled, which is wrong when the
panel is vertical. Check contentHeight > height in that case.
taskpanel: dockSpaceReserver used a hardcoded gridUnit * 3 for both
height and exclusionZone. Use navigationPanelHeight so the reserved
strip tracks the actual panel thickness.
NotificationDrawer referenced toolButtons, a sibling defined in
ContentContainer, not a local property. Add toolButtonsItem: Item
and wire it at the call site. Replace the magic literal 10 with
Kirigami.Units.largeSpacing while here.
The PageIndicator had a one-way binding to swipeView.currentIndex
that would break after a user tap. Make it bidirectional with a
Connections block and a loop guard on both sides.
AppletHost: setPreloadFullRepresentation(true) does not guarantee
fullRepresentationItem() is non-null on return — the applet loads
asynchronously. Wire a single-shot connection to
fullRepresentationItemChanged to emit appletReady() when the item
arrives.
TaskWidget: operationDescription() can return null for an unknown
operation name; bail out rather than dereferencing it.
Qt.rgba expects 0.0–1.0 floats. Passing 255 for R/G/B saturates
every channel to 1.0, producing opaque white instead of the
intended semi-transparent tint. Fix all call sites across
FavouritesBar, StatusBar, and AbstractDelegate.
The mobile popup system always anchored to top-center which
looked out of place on a desktop screen. In convergence mode,
position popups at the bottom-right corner and slide them in
from below. Swipe-to-dismiss flips to match (drag down to
dismiss instead of up). Stacked card previews and the popup
drawer tap area are hidden since notifications are already
accessible in the action drawer.
Replace the full-screen slide-down sheet with two fade-in cards
anchored to the top corners. Quick settings sit top-right,
notifications top-left capped at 60% screen height. Background
scrim reduced to 30%. Redundant clock header and status bar
hidden since both are already visible in the top panel.
Wi-Fi, Bluetooth, Sound and Battery behave differently from
toggle tiles: tapping them should open a detail panel, not
flip a switch. On a phone the long-press convention handles
this, but with a mouse long-press is unnatural.
Pull these four tiles out of the grid when convergence mode
is active and show them as full-width rows above the remaining
tiles. Each row has two click zones — a toggle pill on the
left that still switches the service on/off, and a detail
area on the right (name, status, chevron) that opens the
Plasma applet popup. The grid hides the duplicates so they
only appear once.
Long-pressing a mapped quick-settings tile in convergence
mode opens a floating popup with the Plasma applet UI
instead of launching System Settings. Unmapped tiles still
open Settings.
AppletHost creates a standalone Corona to host applets
outside the shell containment tree.
open() alone does not set intendedToBeVisible, so the drawer
immediately closes itself. Call the proper toggle path instead.
Also hide the drag handle since convergence users click.
Desktop users have no visual cue that the top bar opens quick
settings. Fade in a small arrow-down icon at the bottom center
when the mouse hovers, matching the arrow-up hint on the
favourites bar.
Drawer is inside the homescreen, which sits behind windows.
Home button minimized everything to reach it. Render it in
a LayerTop window instead and skip the blanket minimizeAll
in the D-Bus handler.
In phone mode, tapping a running app activates its existing
window. In convergence mode this prevents launching a new
instance of the same application.
Skip activateWindowByStorageId when convergence mode is
enabled so that launchApp is always reached, matching
standard desktop launcher behaviour.