Skip to content

Add settings page navigation to flow-launcher:// deep links - #4628

Draft
Garulf wants to merge 5 commits into
feature/query-command-line-argfrom
feature/settings-deeplink-navigation
Draft

Add settings page navigation to flow-launcher:// deep links#4628
Garulf wants to merge 5 commits into
feature/query-command-line-argfrom
feature/settings-deeplink-navigation

Conversation

@Garulf

@Garulf Garulf commented Aug 23, 2026

Copy link
Copy Markdown
Member

What

Extends the flow-launcher://settings deep link from #4565 so links can open a specific settings pane, jump to an installed plugin in the Plugins pane, or pre-fill the Plugin Store search.

Stacked on #4565 (feature/query-command-line-arg). Will retarget to dev once that merges; only the last 5 commits are new here.

Link Behavior
flow-launcher://settings unchanged, opens settings at General
flow-launcher://settings/general / theme / hotkey / proxy / about opens that pane
flow-launcher://settings/plugins opens the Plugins pane
flow-launcher://settings/plugins?plugin=<id> Plugins pane with the filter pre-set to that plugin's name; unknown id shows an error notification and still opens the pane unfiltered (id match is case-insensitive, same as plugin/install)
flow-launcher://settings/store?q=<term> Plugin Store pane with the search box pre-filled
flow-launcher://settings/<anything else> existing unrecognized-link error path

How

  • DeepLink.cs: a public SettingsPages map (verb to pane type) drives the handler registrations, so the documented links, the dispatch table, and the tests share one source of truth. settings/plugins resolves the id via loaded plugins; settings/store passes q through; whitespace-only params are treated as absent.
  • SettingWindowViewModel: one-shot pending destination (pane type + optional filter text) with consume-once accessors, so a later manual visit never re-applies a stale destination or filter.
  • SettingWindow: the frame-loaded handler consumes the pending page instead of always selecting General (resetting the stale page type first so navigation actually fires); an already open window is navigated via NavigateToPendingPage, which re-navigates the frame directly when the target pane is already selected so a new filter still applies.
  • SettingsPanePlugins / SettingsPanePluginStore: consume the pending filter in OnNavigatedTo and assign it to their existing FilterText.
  • Two new strings in en.xaml for the unknown-plugin notification.

Tests

  • Unit: DeepLinkTest covers every documented link mapping (including case-insensitivity and an unmapped subpage), plus plugin/q parameter extraction; SettingWindowViewModelTest covers the consume-once semantics.
  • Manual (Windows) matrix in progress, draft until complete:
    1. Each pane link, cold and warm start
    2. ?plugin=<installed id> filters; unknown id shows the notification and opens unfiltered
    3. ?q=clipboard pre-fills the store search
    4. Warm same-pane link updates the filter
    5. Reopening settings manually shows no stale filter
    6. Close settings on the Plugins pane, then cold-start flow-launcher://settings/plugins (regression check for the stale page type)
    7. Plain flow-launcher://settings unchanged

Summary by cubic

Summary of changes

Adds navigation for flow-launcher://settings deep links so links can open a specific pane, jump to an installed plugin in Plugins, or pre-fill the Plugin Store search. Previously, flow-launcher://settings always opened General; now subpaths select panes, Plugins supports ?plugin=<id>, Store supports ?q=<term>, and unknown plugin ids show a notification while still opening Plugins.

  • Changed behavior/logic:
    • Deep link dispatch now derives settings handlers from a single SettingsPages map; the same map drives tests and routing.
    • settings/plugins?plugin=<id> looks up installed plugins case-insensitively; whitespace-only parameters are ignored.
    • Settings window resets a stale page type and re-navigates the current pane so new filters apply even when already open.
    • Added user-facing strings for the unknown-plugin notification.
  • New behavior/logic:
    • Added OpenSettingsPage and HandleSettingsPlugins, plus a consume-once pending navigation state on SettingWindowViewModel.
    • Plugins and Store panes consume pending filter text in OnNavigatedTo.
    • New NavigateToPendingPage enables warm navigation to the target pane.
    • Tests cover link-to-pane mappings, parameter extraction, case-insensitivity, and consume-once semantics.
  • Removed behavior/logic:
    • Replaced the single “always open General” settings handler with per-pane handlers built from SettingsPages.
    • Removed duplicated string literals for settings/plugins and settings/store.
  • Memory impact:
    • Negligible. Adds a small immutable SettingsPages map and two short-lived fields for pending navigation on an existing singleton view model.
  • Security risks:
    • Low. Parameters are normalized and only drive in-app navigation and filtering; no elevated actions are executed. Unknown plugin ids result in a local notification only.
  • Unit tests:
    • DeepLinkTest validates all documented settings links and parameter parsing.
    • SettingWindowViewModelTest verifies one-shot pending navigation and default behaviors.

Release Note

You can now open specific Settings pages via links (for example, Plugins or Store) and even pre-fill plugin filters or store search directly from a flow-launcher://settings/... link.

Written for commit 72fe41d. Summary will update on new commits.

Review in cubic

Garulf added 5 commits August 19, 2026 19:45
The singleton SettingWindowViewModel's _pageType survives across window
open/close cycles because panes only set it in OnNavigatedTo. A cold-start
deep link targeting the same pane as the last session made SetPageType
return false, so NavigationView_SelectionChanged never navigated the frame.
Reset it to null before selecting the pending item, mirroring the existing
normal-open branch.

Also make settings/plugins plugin id lookup case-insensitive to match
InstallByIdAsync's comparison in the same file, treat whitespace-only
filters and plugin ids as absent, and replace the duplicated
"settings/plugins"/"settings/store" string literals with shared consts
used by both the SettingsPages map and the handler switch.
@github-actions github-actions Bot added this to the 2.2.0 milestone Aug 23, 2026
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