Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Documentation/api-compat.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ API compatibility is a build-time check that ensures that an `implementation` as

For `WPF on .NET Core`, this means the following:
* All `WPF on .NET Core` reference assemblies contain **at least** the API surface area contained by `WPF on .NET Framework 4.8` reference assemblies.
* All hand-crafted reference assemblies for `WPF on .NET Core` contain **exactly** the needed API surface area defined by their corresponding runtime assemblies.
* All hand-crafted reference assemblies for `WPF on .NET Core` contain **exactly** the needed API surface area defined by their corresponding runtime assemblies. (If you're adding new API surface area, you will need to update the hand-crafted reference assemblies, following [these instructions](https://github.com/dotnet/wpf/blob/main/Documentation/gen-api.md).)

This is accomplished by the use of the [Arcade API Compatibility tool](https://github.com/dotnet/arcade/blob/master/src/Microsoft.DotNet.ApiCompat) with some modifications to fit our specific needs.

Expand Down
10 changes: 6 additions & 4 deletions Documentation/gen-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,14 @@ GenAPI can be run by setting the following MSBuild property while building.
When a build is run with that property enabled, GenAPI will read the runtime assembly and generate a new `{AssemblyName}.cs` file under the ref directory in the assembly's source tree.

This new file will contain the newly created surface area and will need to be checked in along with the runtime assembly change. The next build without `GenerateReferenceAssemblySource` enabled will no longer display an ApiCompat error as the surface area will now match the baseline.
### Issues with GenAPI
Often, GenAPI will generate code output that will contain code that is either private, internal, or creates build errors. For this reason a developer usually cannot just use the output of GenAPI directly. Instead, the developer should do the following:

### Workflow for GenAPI
GenAPI generates a lot of code that is either private, internal, or causes build errors. For this reason a developer usually cannot just use the output of GenAPI directly. Instead, the developer should do the following:
* Build with GenAPI enabled
* Diff the output file against the previous version
* Extract just the new surface area (and related code) from the generated code
* Revert the generated file
* Extract just the new surface area and related code from the generated code (this is typically a very small fraction of the diff)
* Restore the generated file
* Add back the new surface area to the reference assembly code
* Ensure that nothing in the new surface area is private or internal unless requried by XAML compilation or other reference assemblies
* Restore all other files GenAPI may have generated
* Rebuild without GenAPI enabled and verify there are no ApiCompat errors
5 changes: 3 additions & 2 deletions eng/WpfArcadeSdk/tools/ApiCompat.targets
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
and !($(MSBuildProjectName.Contains('_wpftmp')))">true</RunNetFrameworkApiCompat>
</PropertyGroup>

<!-- Only enable Ref API Compat for the lib projects using hand-crafted reference assemblies -->
<PropertyGroup Condition="'$(RunRefApiCompat)'==''">
<!-- Only enable Ref API Compat for the lib projects using hand-crafted reference assemblies,
but not if we're generating the reference assemblies -->
Copy link
Member

Choose a reason for hiding this comment

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

nit: $(GenerateReferenceAssemblySource)'!='true' for when it is explicitly false.

<PropertyGroup Condition="'$(RunRefApiCompat)'=='' and '$(GenerateReferenceAssemblySource)'==''">
<RunRefApiCompat>false</RunRefApiCompat>
<RunRefApiCompat Condition="'$(RefApiCompatNeededProjects)'!=''
and $(RefApiCompatNeededProjects.Contains('$(MSBuildProjectName);'))
Expand Down
172 changes: 172 additions & 0 deletions src/Microsoft.DotNet.Wpf/specs/0spec_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
> See comments in Markdown for how to use this spec template

<!-- The purpose of this spec is to describe new APIs, in a way
that will transfer to docs.microsoft.com (DMC).

There are two audiences for the spec. The first are people that want to evaluate and give feedback on the API, as part of
the submission process. When it's complete it will be incorporated into the public documentation at
http://docs.microsoft.com (DMC).
Hopefully we'll be able to copy it mostly verbatim. So the second audience is everyone that reads there to learn how
and why to use this API. Some of this text also shows up in Visual Studio Intellisense.

For example, much of the examples and descriptions in the RadialGradientBrush API spec
(https://github.com/microsoft/microsoft-ui-xaml-specs/blob/master/active/RadialGradientBrush/RadialGradientBrush.md)
were carried over to the public API page on DMC
(https://docs.microsoft.com/en-us/windows/winui/api/microsoft.ui.xaml.media.radialgradientbrush?view=winui-2.5)


Once the API is on DMC, that becomes the official copy, and this spec becomes an archive. For example if the description is updated,
that only needs to happen on DMC and needn't be duplicated here.

Samples:
* New class (RadialGradientBrush):
https://github.com/microsoft/microsoft-ui-xaml-specs/blob/master/active/RadialGradientBrush/RadialGradientBrush.md
* New member on an existing class (UIElement.ProtectedCursor):
https://github.com/microsoft/microsoft-ui-xaml-specs/blob/master/active/UIElement/ElementCursor.md

[TODO - replace the examples with ones from the dotnet-wpf repo.
The only example there now is the tooltip spec, which isn't typical because it refers so much to information that's external
to WPF (or to MS for that matter).]

Style guide:
* Speak to the developer who will be learning/using this API.
("You use this to..." rather than "the developer uses this to...")
* Use hard returns to keep the page width within ~100 columns.
(Otherwise it's more difficult to leave comments in a GitHub PR.)
* Talk about an API's behavior, not its implementation
(Speak to the developer using this API, not to the team implementing this API)
* A picture says a thousand words.
* An example says a million words.
* Keep examples realistic but simple; don't add unrelated complications
(An example that passes a stream needn't show the process of launching the File-Open dialog.)

-->

Title
==

# Background

<!--
Use this section to provide background context for the new API(s)
in this spec. This is where to explain (briefly) the intent of the APIs,
why they're needed, how they relate to existing APIs, and other similar
information that helps reviewers read the rest of the document.

This section doesn't get copied to DMC; it's just an aid to reading this spec.

For a simple example see the spec for the UIElement.ProtectedCursor property
(TBD)
which has some of the thinking about how this Xaml API relates to existing
Composition and WPF APIs. This is interesting background but not the kind of information
that would land on DMC.
-->

# Conceptual pages (How To)

_(This is conceptual documentation that will go to docs.microsoft.com "how to" page)_

<!--
All APIs have a page on DMC, some APIs or groups of APIs have an additional high level,
conceptual page (internally called a "how-to" page). This section can be used for that content.

For example, there are several Xaml controls for different forms of text input,
and then there's also a conceptual pages that discusses them collectively
(https://docs.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/text-controls)

Another way to use this section is as a draft of a blog post that introduces the new feature.

Sometimes it's difficult to decide if text belons on a how-to page or an API page.
It's not important to decide on that here, we can always adjust it when copying to DMC.
-->

# API Pages

_(Each of the following L2 sections correspond to a page that will be on docs.microsoft.com)_

<!--
Notes:
* The first line of each of these sections should become that first line on the DMC page,
which then becomes the description you see in Intellisense.
* Each page can have description, examples, and remarks.
Remarks are where the documentation calls out special considerations that the developer should be aware of.
* It can be helpful at the top of an API page (or after the Intellisense text) to add the API signature in C#
* Add a "_Spec note: ..._" to add a note that's useful in this spec but shouldn't go to DMC.
* Show _examples_, not _samples_; an example is a snippet, a sample is a full working app.

It's not necessary to have a section for every class member:
* If its purpose and usage is obvious from it's name/type, it's not necessary to include it.
* If its purpose and usage is obvious other than a brief description, put it in a table in the "Other [class] Members" section.
-->

## MyExample class

Brief description of this class.

Introduction to one or more example usages of a MyExample class:

```c#
...

```

Remarks about the MyExample class


## MyExample.PropertyOne property

Brief description about the MyExample.PropertyOne property.

_Spec note: internal comment about this property that won't go into the public docs._

Introduction to one or more usages of the MyExample.PropertyOne property.


## Other MyExample members


| Name | Description
|-|-|
| PropertyTwo | Brief description of the PropertyTwo property (defaults to ...) |
| MethodOne | Brief description of the MethodOne method |

# Spec notes
<!--
This is an optional section. It's often clearer to put non-public
details in a separate section, rather than embed them in the public
spec. And it makes the doc team's job easier.
-->
This section describes details that are not part of the public documentation, but are nevertheless important.

# Discussion
<!--
This is an optional section, not copied to DMC.
It's where you can add historical notes,
how design decisions were reached, alternatives not taken,
intentional omissions, future directions, or anything else that
helps the internal audience - reviewers, implementers, testers - understand the feature.
-->

# Summary of behavior changes
<!-- This is an optional sectional, useful when your work involves
substantial changes to existing behavior (as opposed to, or in addition
to, new APIs). List them here, as a checklist for the internal
audience. Don't include explanations or any other new information -
that should have been covered earlier.
-->
For convenience, here are the behavior changes described in detail above.

# API Details
<!--
List the APIs in "signature form" - no code, no comments.
-->
For convenience, here is a summary of the new public API surface.

```c#
runtimeclass MyExample
{
int PropertyOne { get; set; }
string PropertyTwo { get; private set; }
void MethodOne();
}
```
12 changes: 7 additions & 5 deletions src/Microsoft.DotNet.Wpf/specs/tooltip.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ Gets or sets whether the ToolTip is shown when its parent element acquires keybo
Setting this property on a ToolTip element helps control whether to open the tooltip when its parent element acquires focus by keyboard navigation.
See `ToolTipService.ShowsToolTipOnKeyboardFocus` (the previous section) for details.

# Implementation
# Spec Notes
This section describes details that are not part of the public documentation, but are nevertheless important.

**ShowDuration property**.
Expand Down Expand Up @@ -258,6 +258,8 @@ Unfortunately this only helps in .NET 6.0, as servicing updates to older version
[ET] discussed what that really means - whether to act on KeyDown or KeyUp, whether combinations should cause both the combination action and dismiss the tooltip (e.g. should Ctrl+C both copy text and dismiss the tooltip), etc.
The interpretation given here is the consensus.

[FD] doesn't say whether Ctrl closes any tooltip, or just the one whose parent has focus. The consensus in [ET] was that Ctrl closes the tooltip whose parent has focus, provided it was opened from the keyboard.

[FD] and [MAS] allude to the delay before opening a tooltip, but don't specify how long that should be, or whether it should be different for keyboard vs. mouse.
The consensus in [ET] was
* the keyboard delay should be no less than the mouse delay
Expand All @@ -278,15 +280,15 @@ For convenience, here are the behavior changes described in detail above.

1. Change default value for `ToolTipService.ShowDuration` property from 5000 to `Int32.MaxValue`.
2. Moving the mouse within the safe area does not close the tooltip.
3. (6.0 only) Properties `ToolTip.ShowsToolTipOnKeyboardFocus` and `TooltipService.ShowsToolTipOnKeyboardFocus` control whether acquiring keyboard focus shows the tooltip.
3. (6.0 only) Properties `ToolTip.ShowsToolTipOnKeyboardFocus` and `TooltipService.ShowsToolTipOnKeyboardFocus` control whether keyboard navigation shows the tooltip.
4. Ctrl closes the tooltip.
5. Ctrl+Shift+F10 opens the tooltip immediately, rather than after `InitialShowDelay`.
6. RibbonToolTips default to showing on focus acquisition.
6. RibbonToolTips default to showing on keyboard navigation.
7. Change default value for `ToolTipService.InitialShowDelay` property from `SystemParameters.MouseHoverTimeMilliseconds` to 1000.

Also, some changes were previously made in .NET 4.8 (and appear in .NET Core 3.0, 3.1, and .NET 5.0), without documentation:

1. Keyboard focus opens the tooltip. (Except for RibbonToolTip.)
1. Keyboard navigation opens the tooltip. (Except for RibbonToolTip.)
2. Ctrl-Shift-F10 opens or closes the tooltip.

# API Details
Expand All @@ -297,7 +299,7 @@ For convenience, here is a summary of the new public API surface.
```c#
class ToolTipService
{
public static DependencyProperty ShowsToolTipOnKeyboardFocus;
public static DependencyProperty ShowsToolTipOnKeyboardFocusProperty;
public static bool? GetShowsToolTipOnKeyboardFocus(DependencyObject d);
public static void SetShowsToolTipOnKeyboardFocus(DependencyObject d, bool? value);
}
Expand Down