Skip to content

[Bug]: Cross-app — two buttons that delete immediately wear a non-destructive style, and danger is marked two different ways #2008

Description

@laurentiu021

Problem

Found while fixing #1615 (Shortcut Cleaner's "Delete Selected" wore SecondaryButton). That was not an
isolated slip, but the class is much narrower than a first sweep suggests, and worth writing down
precisely so nobody re-litigates it.

Two buttons perform an immediate, unrecoverable change while looking like an ordinary action:

View Button Command What it does at click time Style
Audio Mixer Delete DeletePresetCommand rewrites the presets file on disk straight away; the code's own comment says "there is no undo" GhostButton
Environment Variables Delete DeleteVariableCommand removes the user or machine environment variable GhostButton

Both already show a confirmation dialog, so the safety gate is present. What is missing is the visual
signal before the click: in both rows the delete button is the least conspicuous control.

Separately, danger is marked two different ways. Process Manager's per-row kill button is a
GhostButton with Foreground="{DynamicResource Danger}" — red text on a transparent button. It is the
only place in the app that marks danger this way; everywhere else uses DangerButton. It is not
unmarked, so this is a uniformity issue rather than a safety one, but it means a future reader has two
patterns to choose from for one meaning.

What is NOT wrong (checked, so it is not re-raised)

A label sweep flags 18 buttons; most are false positives, and I confirmed each against its command:

  • RemoveDirectory (Environment Variables), RemoveEntry (DNS & Hosts), RemoveItem (File Shredder)
    and RemoveTarget (Ping) only mutate an in-memory collection. The change reaches the system through a
    separate explicit Apply/Save. Staged edits are not destructive at click time, so GhostButton is
    correct for all four.
  • Purge standby list (Standby Memory) drops a memory cache. No user data is involved; PrimaryButton
    is right.
  • RemoveExclusion (Defender) increases protection.
  • Select common bloat (Debloater) only changes a selection.

Why there is no guard for this

I tried to make it mechanical and both candidate rules fail against the real code, so this needs human
judgement per button:

  1. By label — the regex that catches "Delete"/"Remove"/"Shred" also catches "Deselect All",
    "Remove duplicates" and "Save current as preset". Precision is far too low to gate a build on.
  2. By confirmation dialog — appealing, since a command calling DialogService.Instance.Confirm
    looks like the app marking its own irreversible actions. It does not hold: of 25 buttons bound to a
    confirming command, only 3 wear a destructive style, and the other 22 are mostly correct as they are.
    SelectAll confirms because selecting everything is a big action, and ApplyChanges confirms because
    it writes staged edits. Confirmation means "this is significant", not "this destroys something".

So this stays a review judgement rather than a CI check. Recording the two failed rules here so the next
person does not spend the same time rediscovering that they do not work.

Expected behavior

The two buttons above use DangerButton, matching Shortcut Cleaner, Debloater, Uninstaller, File
Shredder, Scheduled Maintenance, Edge/OneDrive and File Lock. Process Manager's kill button picks one
mechanism — most likely DangerButton sized down for a row, rather than a one-off red foreground.

Affected tab

Audio Mixer, Environment Variables, Process Manager.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinguxVisual or interaction improvement

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions