Josh Soref 74a1a6eca2
Some checks are pending
Spell checking / Check Spelling (push) Waiting to run
Spell checking / Report (Push) (push) Blocked by required conditions
Spell checking / Report (PR) (push) Blocked by required conditions
Spell checking / Update PR (push) Waiting to run
Upgrade to check-spelling v0.0.24 (#36235)
This upgrades to [v0.0.24](https://github.com/check-spelling/check-spelling/releases/tag/v0.0.24).

A number of GitHub APIs are being turned off shortly, so you need to upgrade or various uncertain outcomes will occur.

There's a new accessibility forbidden pattern:

> Do not use `(click) here` links
> For more information, see:
> * https://www.w3.org/QA/Tips/noClickHere
> * https://webaim.org/techniques/hypertext/link_text
> * https://granicus.com/blog/why-click-here-links-are-bad/
> * https://heyoka.medium.com/dont-use-click-here-f32f445d1021
```pl
(?i)(?:>|\[)(?:(?:click |)here|link|(?:read |)more)(?:</|\]\()
```

There are some minor bugs that I'm aware of and which I've fixed since this release, but I don't expect to make another release this month.

I've added a pair of patterns for includes and pragmas. My argument is that the **compiler** will _generally_ tell you if you've misspelled an include and the **linker** will _generally_ tell you if you misspell a lib.

- There's a caveat here: If your include case-insensitively matches the referenced file (but doesn't properly match it), then unless you either use a case-sensitive file system (as opposed to case-preserving) or beg clang to warn, you won't notice when you make this specific mistake -- this matters in that a couple of Windows headers (e.g. Unknwn.h) have particular case and repositories don't tend to consistently/properly write them.
2024-12-06 10:33:08 -06:00

4.3 KiB

Architecture

Overview

PowerToys Run is a plugin-based .net core desktop application. It is written in WPF using Model-View-ViewModel (MVVM) structural design pattern. This article provides an overview of PowerToys Run architecture and introduces major components in the data flow.

Note : We refer to base application without plugins as PowerLauncher, which is same as the name of startup WPF project.

UI

PowerToys Run UI is written in the WPF framework. The UI code is present in the Powerlauncher project and is spanned across three high-level components: MainWindow.xaml, LauncherControl.xaml and ResultList.xaml. These components are discussed below.

Image of PowerToys Run UI Fig 1: PowerToys Run UI architecture

  1. MainWindow.xaml: This is the outermost-level UI control. It is composed of lower-level UI components such as LauncherControl.xaml and ResultList.xaml. The corresponding code-behind file implements all the UI related functionalities such as autosuggest, key-bindings, toggling visibility of WPF window and animations.
  2. LauncherControl.xaml: This control implements the UI component for editing query text.(marked in red in Fig 1) It consists of two overlapping WPF controls, TextBox and TextBlock. The outer TextBox is used for editing query whereas the inner TextBlock is used to display autosuggest text.
  3. ResultList.xaml: This control implements the UI component for displaying results (marked in green in Fig 1). It consists of a ListView WPF control with a custom ItemTemplate to display application logo, name, tooltip text, and context menu.

Data flow

The backend code is written using the Model-View-ViewModel (MVVM) structural design pattern. Plugins act as Model in this project. A detailed overview of the project's structure is given in Project Structure.

Flow of data between UI(view) and ViewModels

Data flow between View and ViewModel follows typical MVVM scheme. Properties in viewModels are bound to WPF controls and when these properties are updated, INotifyPropertyChanged handler is invoked, which in turn updates UI. The diagram below provides a rough sketch of the components involved. Flow of data between UI(view) and ViewModels Fig 2: Flow of data between UI and ViewModels.

Flow of data between ViewModels and Plugins(Model)

PowerLauncher interact with plugins using IPlugin and IDelayedExecutionPlugin interface. IPlugin is used for initialization and making queries which are fast (typically return results in less than 100ms).IDelayedExecutionPlugin is used for long-running queries and is implemented only when required. For example, IDelayedExecutionPlugin is implemented by indexer plugin for searching files with names of form *abc*.

    public interface IPlugin
    {
        // Query plugin
        List<Result> Query(Query query);

        // Initialize plugin
        void Init(PluginInitContext context);
    }

    public interface IDelayedExecutionPlugin : IFeatures
    {
        // Query plugin
        List<Result> Query(Query query, bool delayedExecution);
    }

Flow of data between UI(view) and ViewModels Fig 3: Flow of data between ViewModels and Plugins.

Requesting services from powerlauncher

Plugins could use the IPublicAPI interface to request services such as getting the current theme (for deciding logo background), displaying messages to the user, and toggling the visibility of PowerLauncher.