Commit graph

4068 commits

Author SHA1 Message Date
26945e83fa Show Waydroid apps in Game Center
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.
2026-04-24 09:40:53 +02:00
a8e76002f4 Improve Waydroid app management
Handle unavailable Waydroid sessions more cleanly and add KCM controls for launching apps, Game Shell visibility, and compatibility overrides.
2026-04-24 09:35:28 +02:00
eb177e0394 Harden VDF token parsing
Handle unterminated quoted strings as invalid tokens and stop returning raw pointers to entries in the game list.
2026-04-22 12:42:55 +02:00
4dd0e17afb Track launch state in Game Center
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.
2026-04-22 11:36:49 +02:00
d913c2ab0a Improve SDL gamepad prompts and feedback
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.
2026-04-21 09:57:51 +02:00
55f778ebe8 Refine gaming quick settings visuals and toggles
Expose missing gaming controls directly in the panel so they
remain reachable in convergence mode. Add toggles for DND,
Launch Hint, Night Color, and Perf Overlay with gamepad focus
order updates.

Restyle brightness and volume sliders with rounded Plasma-themed
tracks and handles to remove harsh bar visuals while keeping
existing behavior unchanged.
2026-04-21 09:08:49 +02:00
62243b7f64 Add gaming session control backends
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.
2026-04-21 09:08:03 +02:00
bcb985c652 Add quick settings panel and game sources
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.
2026-04-20 14:09:33 +02:00
4a9a5b2a97 Add empty state, gamepad task controls, and X: Close
Show a PlaceholderMessage in the grid when no games are found,
with context-aware text for empty library vs no search results.

Map gamepad A to activate and X to close in RunningGamesView.
Update the legend bar to show X: Close when running tasks are
visible.
2026-04-20 11:39:58 +02:00
daa8fc7d8a Extract common launch logic into launchEntry
Both launch() and launchByStorageId() duplicated the process
spawn, signal emission, and timestamp bookkeeping. Move it to
a single private launchEntry(GameEntry&) method.
2026-04-20 11:39:50 +02:00
a1044567cd Map shoulder buttons, Start, and right stick
LB/RB cycle through source filter tabs (All/Steam/Desktop).
Start toggles focus between the search field and the grid.
Right stick Y-axis smoothly scrolls the grid at 60 Hz with
speed proportional to deflection. Update the gamepad legend
to show the new bindings.
2026-04-20 11:34:25 +02:00
764a8708f6 Deduplicate games found from multiple sources
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.
2026-04-20 11:24:03 +02:00
d58f691c7a Add left-stick navigation and launch fade transition
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.
2026-04-20 11:23:55 +02:00
2a171f3964 Fix overlay rendering, hover blink, and dead-end state
The cover art tile used layer.effect with a plain Item instead
of a ShaderEffect, which broke the overlay rendering. Replace
with a clipped Rectangle wrapper.

Remove Behavior on color from the grid delegate background —
GridView currentIndex changes on hover caused the highlight
color to flash visibly between cells.

Fix dangling taskList reference in the gamepad ButtonA and
DPadDown handlers (taskList lives inside RunningGamesView).

Auto-reopen Game Center when the last window closes in gaming
mode so the user is never stranded on a bare wallpaper.
2026-04-20 10:32:30 +02:00
976c770af4 Add cover art, search, filters, and recently played
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).
2026-04-20 10:03:41 +02:00
1bf8cfb2ba Add gamingshellplugin with SDL3 and game library
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.
2026-04-20 09:46:41 +02:00
70fa861b30 Harden gaming mode and fix startup crash
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.
2026-04-20 09:46:32 +02:00
50ea5976ce Fix HUD crash, clarify exit dialog, hide hint tile
LayerShell windows with non-spanning anchors (AnchorTop|AnchorRight)
crash the compositor when made invisible because Qt briefly resizes
the surface to 0 before unmapping it. Wrap GamingHUD in a Loader so
the window is destroyed rather than hidden.

Replace the generic 'Yes / Cancel' exit dialog with 'Keep Playing /
Leave' in both the Game Center header and the QS tile, matching the
mental model of a couch user.

The 'Launch Hint' QS tile is now hidden (available: false) when
gaming mode is off so it does not clutter the regular action drawer.
2026-04-19 14:10:51 +02:00
6ac9c58d93 Add Game Center overlay
Full-screen layer-shell overlay containing a game library grid
(XDG Game category, filtered via ApplicationListSearchModel) and
a panel of running tasks built on TaskManager.TasksModel.

Keyboard-navigable with directional focus between the running
tasks row and the game grid. A persistent HUD button lets the
user return after launching a game. Exiting gaming mode requires
an explicit confirmation dialog.

The overlay is a Window with LayerShell.LayerTop so it sits above
running application windows without covering system notifications.
2026-04-19 13:51:20 +02:00
b0739dd9a7 Suppress shell chrome in gaming mode
Hide the navigation panel, status bar, and app drawer while
gamingModeEnabled is active. The KWin convergent-windows script
skips its window policy so game windows are not forcibly tiled
or maximized.

The Home button in gaming mode re-opens the Game Center overlay
rather than the app drawer. A configurable hint nudges the user
toward the HUD button after launching a game.
2026-04-19 13:51:08 +02:00
d901815c9d Add gaming mode setting and quick settings tiles
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.
2026-04-19 13:51:00 +02:00
e9dbfa5ea1 Enable keyboard control in convergence dock
Make the convergence dock fully usable from the keyboard.

Tab now reaches Home, favorites, running tasks, and Overview.
Left and right move across section boundaries, and Enter/Space
triggers the same actions as mouse clicks.

Also add accessible role/name/press actions for these controls
so screen readers expose meaningful button semantics.
2026-04-19 11:10:53 +02:00
e72beb7296 Show status bar down-arrow at rest in convergence 2026-04-19 09:22:53 +02:00
c4a2574bef Fade the dock thumbnail popup in and out
The popup snapped to visible/hidden instantly while every other
surface in the shell uses animated transitions. Add an opacity
fade over shortDuration so it matches the rest of the motion
language. State cleanup waits for the fade-out to finish.
2026-04-19 09:01:28 +02:00
e8bb4f2483 Use theme colors for the convergence dock
The dock background was a hardcoded dark fill because upstream
icon labels are white (for floating over wallpaper). Switching
to Theme.backgroundColor alone just made labels vanish on light
themes, so it kept getting reverted.

Fix the whole stack at once: background uses the Window color
set, hover highlights derive from Theme.textColor instead of
white, and delegate labels switch to Theme.textColor in
convergence mode (still white over wallpaper on mobile).
2026-04-19 08:56:44 +02:00
d4da69b2f2 Revert README videos to markdown image syntax
GitLab auto-renders ![](*.webm) as video players but strips
raw <video> HTML tags from rendered markdown.
2026-04-19 08:01:00 +02:00
53686d4ef0 Fix CI build and REUSE lint failures
Use QByteArray::data() instead of constData() for the
udev_device_set_sysattr_value call — Alpine libudev declares the
value parameter as char*, not const char*. Fix the SPDX license
identifier in CategoryPanel.qml from "EUPL 1.2" to "EUPL-1.2".
2026-04-19 07:26:02 +02:00
caef3bc82e Fix minor UI bugs and clean up dead code
Clamp FavouritesBar window indicator dots to at least 1 so a
running task with an empty WinIdList still shows a dot. Add
Accessible.onPressAction to CategoryPanel tiles. Remove dead
convergence-mode property bindings from NavigationPanelComponent
since it is hidden in that mode. Use HTML video tags for .webm
files in README so they render as playable video.
2026-04-19 07:01:55 +02:00
6a1631023e Theme-aware status bar hover and remove dead nav panel code
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.
2026-04-18 20:25:26 +02:00
9bf7b70d2b Fix homescreen includes, accessibility, and popup clamp
Remove duplicate KService include in favouritesmodel.cpp. Add
keyboard navigation and accessibility role to CategoryPanel
tiles. Clamp the FavouritesBar thumbnail popup position to
screen bounds so it does not overflow offscreen on edge items.
2026-04-18 20:25:05 +02:00
acecbcc86a Fix notification popup position in convergence mode
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.
2026-04-18 20:24:48 +02:00
aa4103f72a Add null guards in QuickSettingsDelegate and convergentwindows
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.
2026-04-18 20:24:28 +02:00
8fecdf1d2d Guard against invalid KPackage in AppletHost
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.
2026-04-18 20:24:11 +02:00
276912bf31 Fix dock reserver crash in convergence mode
navigationPanelThickness is explicitly 0 in convergence mode, so using
it as the layer-shell surface height triggered a Wayland protocol error
and crashed the shell. Use gridUnit * 3 directly, matching the dock bar
height set on FavouritesBar.
2026-04-18 19:41:10 +02:00
0d230c5397 Fix dangling pointers and missing null check in flashlight helper
The two const char* variables were pointing into QByteArray
temporaries that were destroyed at the end of each declaration
statement. By the time they were passed to udev, the memory was
freed. Hold the QByteArrays in named locals so the data stays
alive for the duration of the function.

udev_device_new_from_syspath returns NULL if the syspath is
invalid or the device disappears between enumeration and the
privileged call. Add an early-return guard so the subsequent
udev_device_set_sysattr_value call is never reached with a null
device pointer.

Also drop the unnecessary const_cast: udev_device_set_sysattr_value
takes const char*, not char*.
2026-04-18 19:41:04 +02:00
a09f349a34 Rename CHANGELOG to OVERVIEW, fix tiling typo
CHANGELOG.md held a project overview, not versioned entries.
Also fix a typo in the screenshot filename (tilling → tiling)
and the matching README reference.
2026-04-18 19:05:19 +02:00
a29019631e Fix KF6Auth find_package order in kauth helpers
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.
2026-04-18 19:05:11 +02:00
209570d3b2 Fix app list model filter ordering and reset handling
ApplicationListSearchModel: beginFilterChange() was called after
mutating m_categoryFilter, inverting the documented before/after
contract. Also add null checks for sourceModel() and
favouritesModel() in filterAcceptsRow.

CategoryPanel: add onModelReset to repopulate the category list
when the underlying model is fully reloaded, not just on individual
row insertions and removals.
2026-04-18 19:05:04 +02:00
667efec483 Fix panel interactive flag and reserved height
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.
2026-04-18 19:04:56 +02:00
9b94c200ee Fix action drawer toolButtons ref and page indicator sync
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.
2026-04-18 19:04:49 +02:00
2059f14faf Add null guards in AppletHost and TaskWidget
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.
2026-04-18 19:04:40 +02:00
76e027f630 Fix Qt.rgba color arguments
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.
2026-04-18 19:04:22 +02:00
dd7f087fac Add category filter panel to the app drawer
A panel between the drawer and the power panel lists the XDG
categories installed on the device as icon-and-label tiles.
Tapping one filters the app list; text search still applies
on top. The filter resets each time the drawer opens. Audio,
Video and Settings fold into their parent groups to match
Kickoff.
2026-04-18 13:20:13 +02:00
2a0e4428c7 Move close button to power panel
The dismiss button in the drawer header was isolated from the
other controls. Moving it to the top of the power panel groups
everything in one place and lets the power icons sit centered
between it and the user avatar.
2026-04-18 13:20:13 +02:00
d0b4cbe2b0 Switch power panel buttons to icon tiles
Labels are gone; each action shows only an icon with a tooltip
on hover, keeping the panel narrow. A user avatar at the bottom
opens User Accounts on click. The shadow is on a backing
Rectangle rather than via layer.enabled, which would rasterize
the panel and blur icons at non-integer scale.
2026-04-18 13:20:13 +02:00
6e48055b40 Clamp restored window below the dock
KWin restores geometry before the compositor re-commits the
exclusive zone, so the window can land partly behind the dock.
A deferred check clips the bottom edge once the round-trip
completes.
2026-04-18 13:20:13 +02:00
0b9ae2eca7 Narrow dock hit area to edge strip when hidden
The hidden dock's window still covered full height, blocking
toolbar buttons in maximized apps. Reduce the input region to
a thin strip at the screen edge while off-screen and restore
it on reveal. A debounce timer prevents an accidental edge
graze from reopening the dock.
2026-04-18 13:20:13 +02:00
3466a8c5d5 Fix trailing period in webm license header 2026-04-18 08:23:29 +02:00
5c3c3b9720 Add translucent background to convergence dock
The dock's LayerShell window is transparent; icon labels are
hardcoded white (designed to float over wallpaper on mobile).
A dark semi-transparent fill keeps labels legible on any
wallpaper without coupling to the Plasma theme color.
2026-04-18 08:23:24 +02:00
e4f4232cf2 Add power panel alongside app drawer in convergence mode
Shows a narrow card to the right of the app drawer popup with
Lock Screen, Restart, and Shut Down buttons. Uses SessionManagement
from org.kde.plasma.private.sessions directly, the same QML type
Logout.qml already uses. No C++ changes needed. Shares the drawer
open/close animation and dismisses with it.
2026-04-17 13:58:22 +02:00