Skip to content

feat: task manager from qam#1121

Open
xXJSONDeruloXx wants to merge 4 commits intoutkarshdalal:masterfrom
xXJSONDeruloXx:feat/qam-launchers
Open

feat: task manager from qam#1121
xXJSONDeruloXx wants to merge 4 commits intoutkarshdalal:masterfrom
xXJSONDeruloXx:feat/qam-launchers

Conversation

@xXJSONDeruloXx
Copy link
Copy Markdown
Contributor

@xXJSONDeruloXx xXJSONDeruloXx commented Apr 6, 2026

Description

adds a new view to quick menu that lets you see a list of running procs, and quickly kill them if needed.

Recording

image

Checklist

  • If I have access to #code-changes, I have discussed this change there and it has been green-lighted. If I do not have access, I have still provided clear context in this PR. If I skip both, I accept that this change may face delays in review, may not be reviewed at all, or may be closed.
  • I have attached a recording of the change.
  • I have read and agree to the contribution guidelines in CONTRIBUTING.md.

Summary by cubic

Adds a Task Manager tab in the Quick Menu with a live list of running Wine EXEs and memory usage. You can now see and end processes without leaving the game.

  • New Features
    • Task Manager tab in QuickMenu with a live “Running EXEs” list; refreshes every 2s while the tab is open, shows non‑essential apps first, and lets you tap/click to end a process via WinHandler (WOW64 processes marked “*32”).
    • ProcessHelper parses ps RSS and exposes bytes for each process to support memory display.

Written for commit 1604e34. Summary will update on new commits.

Summary by CodeRabbit

  • New Features
    • Added a TOOLS tab to the quick menu for process management
    • Users can now view and terminate running Wine processes directly from the interface
    • Displays active process count and memory information
    • Extended language support for multiple regions

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 6, 2026

📝 Walkthrough

Walkthrough

The PR introduces a new TOOLS tab to the QuickMenu component displaying active Wine processes with kill functionality. It extends QuickMenu's signature with wine handler and process list parameters, implements polling logic in XServerScreen to fetch process snapshots, enriches ProcessInfo with memory data, and adds localized UI strings across 16 languages.

Changes

Cohort / File(s) Summary
QuickMenu UI Components
app/src/main/java/app/gamenative/ui/component/QuickMenu.kt
Added TOOLS tab with new ToolsQuickMenuTab and QuickMenuProcessRow composables. Extended function signature to accept winHandler, wineProcesses list, loading flag, and visibility callback. Implemented marquee scrolling for process titles and kill-process actions via key press and click handlers.
XServerScreen Integration
app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt
Added Wine process polling mechanism with requestWineProcessSnapshot() helper and repeated fetch loop when TOOLS tab is visible. Manages three new state variables: quickMenuToolsVisible, quickMenuWineProcesses, and quickMenuWineProcessesLoading. Processes are sorted by essentiality and memory usage.
Process Data Model
app/src/main/java/com/winlator/core/ProcessHelper.java
Extended ProcessInfo with new rssBytes field tracking memory usage. Constructor overload added; existing constructor now delegates to 4-argument version with default rssBytes = 0L. Updated ps parsing to extract RSS column and convert KiB to bytes.
Internationalization
app/src/main/res/values*/strings.xml
Added tools_wine_processes_running_hint (process count hint with %1$d placeholder) and tools_wine_processes_empty (empty-state message) across 16 locales (default + 15 translations).

Sequence Diagram(s)

sequenceDiagram
    participant XServerScreen
    participant QuickMenu
    participant QuickMenuProcessRow
    participant WinHandler
    participant ProcessHelper

    XServerScreen->>XServerScreen: User opens TOOLS tab
    activate XServerScreen
    XServerScreen->>XServerScreen: quickMenuToolsVisible = true
    XServerScreen->>WinHandler: requestWineProcessSnapshot()
    activate WinHandler
    WinHandler->>ProcessHelper: listProcesses()
    activate ProcessHelper
    ProcessHelper->>ProcessHelper: Parse ps output<br/>(extract RSS bytes)
    ProcessHelper-->>WinHandler: Return ProcessInfo list
    deactivate ProcessHelper
    WinHandler-->>XServerScreen: Process snapshot
    deactivate WinHandler
    XServerScreen->>XServerScreen: Sort by essentiality<br/>then memory usage
    XServerScreen->>QuickMenu: Pass wineProcesses list
    deactivate XServerScreen

    XServerScreen->>QuickMenu: Render TOOLS tab
    activate QuickMenu
    QuickMenu->>QuickMenu: Show process count hint
    loop For each process
        QuickMenu->>QuickMenuProcessRow: Render process row
        activate QuickMenuProcessRow
        QuickMenuProcessRow->>QuickMenuProcessRow: Apply focus styling<br/>Marquee title
        deactivate QuickMenuProcessRow
    end
    deactivate QuickMenu

    User->>QuickMenuProcessRow: Tap/Click or Press Key
    activate QuickMenuProcessRow
    QuickMenuProcessRow->>QuickMenuProcessRow: onEndProcess callback
    QuickMenuProcessRow->>WinHandler: killProcess(name, pid)
    activate WinHandler
    WinHandler->>WinHandler: Terminate process
    deactivate WinHandler
    deactivate QuickMenuProcessRow

    XServerScreen->>XServerScreen: Poll interval delay
    XServerScreen->>XServerScreen: Repeat fetch loop<br/>if TOOLS still visible
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • PR #686: Modifies QuickMenu UI and its integration in XServerScreen, with this PR building upon those foundational changes by adding the new TOOLS tab functionality and extended parameters.

Suggested reviewers

  • morganwalkup

Poem

🐰 A TOOLS tab hops into view,
With processes listed, all on cue,
Click and tap to send them away,
Memory-tracked, every single day! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: task manager from qam' clearly identifies the main change: adding a Task Manager feature to the Quick Menu (QAM). It is concise and directly related to the primary objective of the PR.
Description check ✅ Passed The PR description covers all required sections from the template: a clear description of what changed and why, an attached recording/screenshot, and a completed checklist confirming discussions, recording attachment, and contribution guidelines agreement.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@xXJSONDeruloXx xXJSONDeruloXx marked this pull request as ready for review April 13, 2026 02:19
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
app/src/main/java/app/gamenative/ui/component/QuickMenu.kt (2)

585-585: Optional: Hoist scroll state to QuickMenu for consistency.

The scrollState is defined locally here, whereas other tabs (hudScrollState, effectsScrollState, controllerScrollState) have their scroll states defined at the QuickMenu level. This means the TOOLS tab loses scroll position when switching tabs.

Given the 2-second refresh interval for the process list, this may be acceptable, but hoisting the state would provide consistency.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/main/java/app/gamenative/ui/component/QuickMenu.kt` at line 585, Move
the local val scrollState = rememberScrollState() up into the QuickMenu
composable alongside hudScrollState, effectsScrollState and
controllerScrollState so the TOOLS tab preserves its scroll position; then
replace the local declaration in the TOOLS tab with a reference to that hoisted
scrollState (or pass it into the TOOLS tab child composable) so all tabs use
scroll state defined at QuickMenu level for consistent behavior.

614-617: Consider adding a confirmation step before killing processes.

Tapping a row immediately kills the process without confirmation. While this provides quick access, accidental taps could terminate important processes. Consider either:

  • A brief toast/snackbar with undo capability, or
  • A confirmation dialog for processes that aren't marked as safe to kill.

This is optional given the "tap to close" design intent mentioned in the PR.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/main/java/app/gamenative/ui/component/QuickMenu.kt` around lines 614
- 617, The quick-tap handler in QuickMenu.kt currently calls
winHandler?.killProcess(process.name, process.pid) directly in the onEndProcess
lambda; update this to present a confirmation UI (either a confirmation dialog
for non-safe processes or a brief snackbar with an undo for quick closes) before
calling winHandler?.killProcess. Specifically, change the onEndProcess flow to
check a process safety flag (e.g., process.safeToKill or process.isCritical) and
if not safe show a confirmation dialog and only call killProcess on confirm, or
for quick-close show a snackbar that delays the actual call and cancels it if
the user taps undo; ensure the final kill call still uses
winHandler?.killProcess(process.name, process.pid).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt`:
- Around line 245-284: The current code in requestWineProcessSnapshot replaces
WinHandler's single OnGetProcessInfoListener and can race with
startExitWatchForUnmappedGameWindow which does the same; instead, create a
single shared dispatcher/listener in this class (e.g., a private val
processInfoDispatcher: OnGetProcessInfoListener or a small manager object) that
you register once via
winHandler.setOnGetProcessInfoListener(processInfoDispatcher) and have that
dispatcher multiplex events to callers. Change requestWineProcessSnapshot to
enqueue a CompletableDeferred and expectedCount into the dispatcher (keyed by a
request token or by storing the deferred + logic in a list) rather than calling
setOnGetProcessInfoListener, and update startExitWatchForUnmappedGameWindow to
use the same dispatcher for its callbacks; ensure the finally blocks only
unregister the dispatcher when no pending consumers remain and synchronize
access with a mutex to serialize ownership.

In `@app/src/main/res/values-fr/strings.xml`:
- Line 252: Replace the awkward French phrasing in the string resource
tools_wine_processes_running_hint: change the text "%1$d en cours,
touchez/cliquez sur un processus pour le fermer" to a natural French sentence
that includes the noun "processus", for example "%1$d processus en cours,
touchez ou cliquez sur un processus pour le fermer" (or "%1$d processus en
cours, appuyez ou cliquez sur un processus pour le fermer") so the UI copy reads
naturally.

---

Nitpick comments:
In `@app/src/main/java/app/gamenative/ui/component/QuickMenu.kt`:
- Line 585: Move the local val scrollState = rememberScrollState() up into the
QuickMenu composable alongside hudScrollState, effectsScrollState and
controllerScrollState so the TOOLS tab preserves its scroll position; then
replace the local declaration in the TOOLS tab with a reference to that hoisted
scrollState (or pass it into the TOOLS tab child composable) so all tabs use
scroll state defined at QuickMenu level for consistent behavior.
- Around line 614-617: The quick-tap handler in QuickMenu.kt currently calls
winHandler?.killProcess(process.name, process.pid) directly in the onEndProcess
lambda; update this to present a confirmation UI (either a confirmation dialog
for non-safe processes or a brief snackbar with an undo for quick closes) before
calling winHandler?.killProcess. Specifically, change the onEndProcess flow to
check a process safety flag (e.g., process.safeToKill or process.isCritical) and
if not safe show a confirmation dialog and only call killProcess on confirm, or
for quick-close show a snackbar that delays the actual call and cancels it if
the user taps undo; ensure the final kill call still uses
winHandler?.killProcess(process.name, process.pid).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1c14806e-e3b7-43a5-bac7-75b53e23e6b9

📥 Commits

Reviewing files that changed from the base of the PR and between 55c0796 and 1604e34.

📒 Files selected for processing (17)
  • app/src/main/java/app/gamenative/ui/component/QuickMenu.kt
  • app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt
  • app/src/main/java/com/winlator/core/ProcessHelper.java
  • app/src/main/res/values-da/strings.xml
  • app/src/main/res/values-de/strings.xml
  • app/src/main/res/values-es/strings.xml
  • app/src/main/res/values-fr/strings.xml
  • app/src/main/res/values-it/strings.xml
  • app/src/main/res/values-ko/strings.xml
  • app/src/main/res/values-pl/strings.xml
  • app/src/main/res/values-pt-rBR/strings.xml
  • app/src/main/res/values-ro/strings.xml
  • app/src/main/res/values-ru/strings.xml
  • app/src/main/res/values-uk/strings.xml
  • app/src/main/res/values-zh-rCN/strings.xml
  • app/src/main/res/values-zh-rTW/strings.xml
  • app/src/main/res/values/strings.xml

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 issues found across 17 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="app/src/main/res/values-ru/strings.xml">

<violation number="1" location="app/src/main/res/values-ru/strings.xml:1168">
P2: Russian count-based hint uses a single fixed phrase, causing grammatically incorrect text for many numeric values.</violation>
</file>

<file name="app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt">

<violation number="1" location="app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt:277">
P1: Quick-menu process polling races with exit-watch by overwriting the single global WinHandler process listener, which can mix callbacks and corrupt process snapshots.</violation>
</file>

<file name="app/src/main/java/com/winlator/core/ProcessHelper.java">

<violation number="1" location="app/src/main/java/com/winlator/core/ProcessHelper.java:138">
P2: New RSS parsing from `ps` output is unchecked; malformed output can throw `NumberFormatException` and break subprocess listing flow.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

}

return try {
winHandler.setOnGetProcessInfoListener(listener)
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Quick-menu process polling races with exit-watch by overwriting the single global WinHandler process listener, which can mix callbacks and corrupt process snapshots.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt, line 277:

<comment>Quick-menu process polling races with exit-watch by overwriting the single global WinHandler process listener, which can mix callbacks and corrupt process snapshots.</comment>

<file context>
@@ -241,6 +242,48 @@ private fun buildEssentialProcessAllowlist(): Set<String> {
+    }
+
+    return try {
+        winHandler.setOnGetProcessInfoListener(listener)
+        winHandler.listProcesses()
+        withTimeoutOrNull(EXIT_PROCESS_RESPONSE_TIMEOUT_MS) {
</file context>
Fix with Cubic

<string name="tab_local">Пользовательское</string>
<string name="tab_steam">Steam</string>
<string name="task_manager">Менеджер задач</string>
<string name="tools_wine_processes_running_hint">%1$d запущено, нажмите/кликните по процессу, чтобы закрыть его</string>
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Russian count-based hint uses a single fixed phrase, causing grammatically incorrect text for many numeric values.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At app/src/main/res/values-ru/strings.xml, line 1168:

<comment>Russian count-based hint uses a single fixed phrase, causing grammatically incorrect text for many numeric values.</comment>

<file context>
@@ -1165,6 +1165,7 @@ https://gamenative.app
     <string name="tab_local">Пользовательское</string>
     <string name="tab_steam">Steam</string>
     <string name="task_manager">Менеджер задач</string>
+    <string name="tools_wine_processes_running_hint">%1$d запущено, нажмите/кликните по процессу, чтобы закрыть его</string>
     <string name="template_percent">%1$d процент.</string>
     <string name="thumbstick_buttons">Кнопки джойстика</string>
</file context>
Fix with Cubic

String user = parts[0];
int pid = Integer.parseInt(parts[1]);
int ppid = Integer.parseInt(parts[2]);
long rssKb = Long.parseLong(parts[4]);
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: New RSS parsing from ps output is unchecked; malformed output can throw NumberFormatException and break subprocess listing flow.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At app/src/main/java/com/winlator/core/ProcessHelper.java, line 138:

<comment>New RSS parsing from `ps` output is unchecked; malformed output can throw `NumberFormatException` and break subprocess listing flow.</comment>

<file context>
@@ -111,59 +117,29 @@ public static int exec(String command, String[] envp, File workingDir, Callback<
                         String user = parts[0];
                         int pid = Integer.parseInt(parts[1]);
                         int ppid = Integer.parseInt(parts[2]);
+                        long rssKb = Long.parseLong(parts[4]);
                         String processName = parts[8];
 
</file context>
Fix with Cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant