Skip to content

feat: task manager from qam#1121

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

feat: task manager from qam#1121
xXJSONDeruloXx wants to merge 5 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 that lists running Wine EXEs with memory usage and lets you end processes without leaving the game. The list auto-refreshes while the tab is open and prioritizes non‑essential apps.

  • New Features

    • Task Manager tab in QuickMenu with a live “Running EXEs” list (updates every 2s), shows non‑essential apps first, and lets you tap/click to end a process via WinHandler (WOW64 marked “*32”); includes memory per process and an empty state.
  • Refactors

    • ProcessHelper now inlines process user lookup and parses ps RSS to provide per‑process memory in bytes.

Written for commit 44720d8. Summary will update on new commits.

Summary by CodeRabbit

  • New Features
    • Added a TOOLS tab in the quick menu to view running Wine processes, show counts and memory hints, and end processes from the UI
    • Shows loading state, empty-state message, and focus/scroll behavior for long process names
  • Localization
    • Added localized UI strings for the new process hint in many languages

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 6, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9564f4e4-ea31-498c-802b-9cc56786f3a2

📥 Commits

Reviewing files that changed from the base of the PR and between 1604e34 and 44720d8.

📒 Files selected for processing (1)
  • app/src/main/java/com/winlator/core/ProcessHelper.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/src/main/java/com/winlator/core/ProcessHelper.java

📝 Walkthrough

Walkthrough

The PR adds a new TOOLS tab to QuickMenu to list and terminate Wine processes, extends QuickMenu's public signature to accept a WinHandler and process state, implements polling in XServerScreen to fetch/sort process snapshots, enriches ProcessInfo with RSS bytes, and adds localized strings.

Changes

Cohort / File(s) Summary
QuickMenu UI
app/src/main/java/app/gamenative/ui/component/QuickMenu.kt
Added TOOLS tab, ToolsQuickMenuTab, and QuickMenuProcessRow composables; extended QuickMenu signature with winHandler, wineProcesses, isWineProcessesLoading, and onToolsVisibilityChanged; added visibility LaunchedEffect, marquee titles, focus styling, and kill-process actions.
XServerScreen integration
app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt
Added requestWineProcessSnapshot() helper, polling loop triggered when TOOLS visible, new state vars (quickMenuToolsVisible, quickMenuWineProcesses, quickMenuWineProcessesLoading), and updated QuickMenu(...) invocation to pass handler/state.
Process model / helper
app/src/main/java/com/winlator/core/ProcessHelper.java
Added rssBytes to ProcessInfo, new 4-arg constructor, existing constructor delegates, updated ps parsing to extract RSS (KiB→bytes) and adjusted control flow.
Localization
app/src/main/res/values/.../strings.xml
Added tools_wine_processes_running_hint across many locales and tools_wine_processes_empty in default values/strings.xml for empty-state messaging.

Sequence Diagram(s)

sequenceDiagram
    participant User as User
    participant XServer as XServerScreen
    participant Quick as QuickMenu
    participant Row as QuickMenuProcessRow
    participant Win as WinHandler
    participant Proc as ProcessHelper

    User->>XServer: Open QuickMenu -> select TOOLS
    XServer->>XServer: quickMenuToolsVisible = true
    loop while TOOLS visible
        XServer->>Win: request wine process list
        Win->>Proc: listProcesses() / parse ps (rss)
        Proc-->>Win: ProcessInfo[]
        Win-->>XServer: snapshot
        XServer->>XServer: sort processes (essentiality, rss)
        XServer->>Quick: render TOOLS with wineProcesses
        Quick->>Row: render each process row
        User->>Row: click / keypress to end process
        Row->>Win: killProcess(name, pid)
        XServer->>XServer: delay (poll interval)
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • PR #686: Related QuickMenu and XServerScreen UI integration changes that this PR extends by adding the TOOLS tab and process-management flow.

Suggested reviewers

  • morganwalkup

Poem

🐰 A TOOLS tab hopped up from the lair,
Processes listed with memory to spare,
Tap, press, or click — send them to rest,
A rabbit’s small wrench to tidy the nest. ✨

🚥 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 clearly and concisely describes the main change: adding a task manager feature accessible from the Quick Access Menu (QAM).
Description check ✅ Passed The description includes a clear explanation of changes, an attached recording, completed checklist items, and an auto-generated summary from cubic; all required elements from the template are addressed.

✏️ 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

Comment thread app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt
Comment thread app/src/main/res/values-fr/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

Comment on lines -116 to -144
// First get our username using the id command
try {
java.lang.Process idProcess = Runtime.getRuntime().exec("id");
try (
InputStreamReader isr = new InputStreamReader(idProcess.getInputStream());
BufferedReader idReader = new BufferedReader(isr);
) {
String idOutput = idReader.readLine();
if (idOutput != null) {
// id output format: uid=10290(u0_a290) gid=10290(u0_a290) ...
int startIndex = idOutput.indexOf('(');
int endIndex = idOutput.indexOf(')');
if (startIndex != -1 && endIndex != -1) {
myUser = idOutput.substring(startIndex + 1, endIndex);
}
}
}
} catch (IOException e) {
Log.e("ProcessHelper", "Failed to retrieve user id in order to list processes: " + e);
return processes;
}

if (myUser == null) {
return processes;
}

// Log.d("ProcessHelper", "Found user value to be: " + myUser);

// Now get the processes
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

concerning that this was removed - this function is used in other places

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

or was it just moved to getCurrentProcessUser - if so, why? i don't see the function being used anywhere else so if it's not required please undo. As far as i know this file shouldn't need any changes

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

yeah was moved to a helper but prob not necessary here. There was one change to add rssBytes in processInfo and changes to ps parsing, so we can get per proc memory usage. will put it back where it was so diff is more obvious

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.

2 participants