Skip to content

Commit 34447e6

Browse files
authored
Merge pull request #963 from MicrosoftEdge/rasterizationscale-draft
Create RasterizationScale.md
2 parents f2abacd + fb3663a commit 34447e6

1 file changed

Lines changed: 164 additions & 0 deletions

File tree

specs/RasterizationScale.md

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
# Background
2+
The WebView attempts to detects monitor scale changes and applies the monitor DPI scale to all UI produced by the WebView.
3+
When the host app has a DPI awareness of PerMonitorV2, then all child HWNDs receive WM_DPICHANGED.
4+
The WebView can check the current monitor DPI scale when it receives WM_DPICHANGED.
5+
But if the host app is just PerMonitor aware (not v2), then only the top level window receives WM_DPICHANGED.
6+
The WebView could try to use other metrics (like resize) to check the DPI, but resize is not guaranteed in that scenario.
7+
From [GitHub feedback](https://github.com/MicrosoftEdge/WebView2Feedback/issues/65),
8+
we also know that there are consumers of WebView that want to explicitly set a custom DPI scale for WebView.
9+
10+
In this document we describe the updated API. We'd appreciate your feedback.
11+
12+
13+
# Description
14+
To allow the app to control the DPI scale of WebView, we are adding a `RasterizationScale` property to the CoreWebView2Controller interface.
15+
The RasterizationScale property controls the DPI scaling for all UI in WebView.
16+
17+
In order to maintain compatibility with apps developed before this API existed,
18+
WebView2 continues to detect monitor scale changes by default and will update the RasterizationScale property.
19+
When the RasterizationScale property is updated, the `RasterizationScaleChanged` event is raised.
20+
The app can tell WebView2 to stop updating the RasterizationScale property by changing
21+
`ShouldDetectMonitorDpiScaleChanges` from the default value of true, to false.
22+
23+
# Examples
24+
The following code snippets show how to use the RasterizationScale and ShouldDetectMonitorScaleChanges properties,
25+
and now to listen to the RasterizationScaleChanged event.
26+
## Win32 C++
27+
```cpp
28+
void ViewComponent::SetRasterizationScale(float additionalScale)
29+
{
30+
CHECK_FAILURE(m_controller->put_ShouldDetectMonitorScaleChanges(FALSE));
31+
m_webviewAdditionalRasterizationScale = additionalScale;
32+
// RasterizationScale is typically the monitor DPI scale and text scaling, but
33+
// the app could add an additional scale for its own scenarios.
34+
double rasterizationScale =
35+
additionalScale * m_appWindow->GetDpiScale() * m_appWindow->GetTextScale();
36+
CHECK_FAILURE(m_controller->put_RasterizationScale(rasterizationScale));
37+
}
38+
39+
Callback<ICoreWebView2RasterizationScaleChangedEventHandler>(
40+
[this](ICoreWebView2Controller* sender, IUnknown* args) -> HRESULT {
41+
double rasterizationScale;
42+
CHECK_FAILURE(m_controller->get_RasterizationScale(&rasterizationScale));
43+
44+
std::wstring message = L"WebView2APISample (RasterizationScale: " +
45+
std::to_wstring(int(rasterizationScale * 100)) + L"%)";
46+
SetWindowText(m_appWindow->GetMainWindow(), message.c_str());
47+
return S_OK;
48+
})
49+
.Get(), &m_rasterizationScaleChangedToken));
50+
```
51+
## .Net
52+
```c#
53+
public void SetRasterizationScale(double additionalScale)
54+
{
55+
CoreWebView2Controller.ShouldDetectMonitorScaleChanges = false;
56+
m_webviewAdditionalRasterizationScale = additionalScale;
57+
58+
// RasterizationScale is typically the monitor DPI scale and text scaling, but
59+
// the app could add an additional scale for its own scenarios.
60+
double rasterizationScale = additionalScale * GetDpiScale() * GetTextScale();
61+
CoreWebView2Controller.RasterizationScale = rasterizationScale;
62+
}
63+
```
64+
65+
66+
# API Notes
67+
See [API Details](#api-details) section below for API reference.
68+
69+
# API Details
70+
## Win32 C++
71+
```c#
72+
interface ICoreWebView2Controller2 : ICoreWebView2Controller {
73+
/// The rasterization scale for the WebView. The rasterization scale is the
74+
/// combination of the monitor DPI scale and text scaling set by the user.
75+
/// This value should be updated when the DPI scale of the app's top level
76+
/// window changes (i.e. monitor DPI scale changes or window changes monitor)
77+
/// or when the text scale factor of the system changes.
78+
///
79+
/// \snippet AppWindow.cpp DPIChanged
80+
///
81+
/// \snippet AppWindow.cpp TextScaleChanged1
82+
///
83+
/// \snippet AppWindow.cpp TextScaleChanged2
84+
///
85+
/// Rasterization scale applies to the WebView content, as well as
86+
/// popups, context menus, scroll bars, and so on. Normal app scaling scenarios
87+
/// should use the ZoomFactor property or SetBoundsAndZoomFactor API which
88+
/// only scale the rendered HTML content and not popups, context menus, scroll bars and so on.
89+
///
90+
/// \snippet ViewComponent.cpp RasterizationScale
91+
[propget] HRESULT RasterizationScale([out, retval] double* scale);
92+
// Set the rasteriation scale property.
93+
[propput] HRESULT RasterizationScale([in] double scale);
94+
95+
/// ShouldDetectMonitorScaleChanges property determines whether the WebView
96+
/// attempts to track monitor DPI scale changes. When true, the WebView will
97+
/// track monitor DPI scale changes, update the RasterizationScale property,
98+
/// and raises RasterizationScaleChanged event. Attempting to set RasterizationScale
99+
/// while ShouldDetectMonitorScaleChanges is true will result in RasterizationScaleChanged
100+
/// being raised and the value restored to match the monitor DPI scale.
101+
/// When false, the WebView will not track monitor DPI scale changes, and the app
102+
/// must update the RasterizationScale property itself. RasterizationScaleChanged
103+
/// event will never raise when ShouldDetectMonitorScaleChanges is false.
104+
[propget] HRESULT ShouldDetectMonitorScaleChanges([out, retval] BOOL* value);
105+
/// Set the ShouldDetectMonitorScaleChanges property.
106+
[propput] HRESULT ShouldDetectMonitorScaleChanges([in] BOOL value);
107+
108+
/// Add an event handler for the RasterizationScaleChanged event.
109+
/// The event is raised when the WebView detects that the monitor DPI scale
110+
/// has changed, ShouldDetectMonitorScaleChanges is true, and the WebView has
111+
/// changed the RasterizationScale property.
112+
///
113+
/// \snippet ViewComponent.cpp RasterizationScaleChanged
114+
HRESULT add_RasterizationScaleChanged(
115+
[in] ICoreWebView2RasterizationScaleChangedEventHandler*
116+
eventHandler,
117+
[out] EventRegistrationToken* token);
118+
/// Remove an event handler previously added with
119+
/// add_RasterizationScaleChanged.
120+
HRESULT remove_RasterizationScaleChanged(
121+
[in] EventRegistrationToken token);
122+
}
123+
interface ICoreWebView2RasterizationScaleChangedEventHandler : IUnknown {
124+
/// Called to provide the implementer with the event args for the
125+
/// corresponding event. There are no event args and the args
126+
/// parameter will be null.
127+
HRESULT Invoke(
128+
[in] ICoreWebView2Controller2* sender,
129+
[in] IUnknown* args);
130+
}
131+
```
132+
## .Net and WinRT
133+
```c#
134+
namespace Microsoft.Web.WebView2.Core
135+
{
136+
public partial class CoreWebView2Controller
137+
{
138+
/// <summary>
139+
/// Gets or sets the WebView rasterization scale.
140+
/// </summary>
141+
/// <remarks>
142+
/// The rasterization scale is the combination of the monitor DPI scale and text scaling set by the user. This value shoud be updated when the DPI scale of the app's top level window changes (i.e. monitor DPI scale changes or the window changes monitor) or when the text scale factor of the system changes.
143+
/// Rasterization scale applies to the WebView content, as well as popups, context menus, scroll bars, and so on. Normal app scaling scenarios should use the <see cref="CoreWebView2.ZoomFactor"/> property or <see cref="CoreWebView2.SetBoundsAndZoomFactor"/> method.
144+
/// </remarks>
145+
public double RasterizationScale { get; set;};
146+
147+
/// <summary>
148+
/// Determines whether the WebView will detect monitor scale changes.
149+
/// </summary>
150+
/// <remarks>
151+
/// ShouldDetectMonitorScaleChanges property determines whether the WebView attempts to track monitor DPI scale schanges. When true, the WebView will track monitor DPI scale changes, update the <see cref="CoreWebView2.RasterizationScale"/> property, and fire <see cref="CoreWebView2.RasterizationScaleChanged"/> event. When false, the WebView will not track monitor DPI scale changes, and the app must update the <see cref="CoreWebView2.RasterizationScale"/> property itself. <see cref="CoreWebView2.RasterizationScaleChanged"/> event will never fire when ShouldDetectMonitorScaleChanges is false.
152+
/// </remarks>
153+
public bool ShouldDetectMonitorScaleChanges {get; set;};
154+
155+
/// <summary>
156+
/// RasterizationScalechanged is raised when the <see cref="CoreWebView2Controller.RasterizationScale"/> property changes.
157+
/// </summary>
158+
/// <remarks>
159+
/// The event is raised when the Webview detects that the monitor DPI scale has changed, <see cref="CoreWebView2Controller.ShouldDetectMonitorScaleChanges"/> is true, and the Webview has changed the <see cref="CoreWebView2Controller.RasterizationScale"/> property.
160+
/// </remarks>
161+
/// <seealso cref="CoreWebView2Controller.RasterizationScale"/>
162+
public event EventHandler<object> RasterizationScaleChanged;
163+
}
164+
```

0 commit comments

Comments
 (0)