From e9ed077d7e52c421f8af8e17fea79c00dc73a5ce Mon Sep 17 00:00:00 2001 From: Jameson Li Date: Wed, 23 Sep 2020 15:33:15 -0700 Subject: [PATCH 1/4] Create SystemCursorId --- specs/SystemCursorId | 87 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 specs/SystemCursorId diff --git a/specs/SystemCursorId b/specs/SystemCursorId new file mode 100644 index 000000000..b3c97c9d4 --- /dev/null +++ b/specs/SystemCursorId @@ -0,0 +1,87 @@ +# Background + +In visual hosting, the current cursor image cannot be determined easily by the +hosting application easily. For example, if the cursor over the WebView is also +over a textbox inside of the WebView, the cursor should usually be IDC_IBEAM. +And by default, the cursor is IDC_ARROW. Currently, we return the what the +cursor should be as an HCURSOR object (After calling LoadCursor on those IDC +values). The hosting application can then use the HCURSOR object to change the +current cursor to the correct image. + +However, Office already has a well established way of using cursors internally +by using IDC_* values and there is no easy way to convert the HCURSOR object we +are returning into an IDC value after it's been created. + +This new API is to enable hosting applications like Office to get the current +IDC value of the cursor instead of the HCURSOR as an option. + + +# Description + +The `SystemCursorId` property will return the current system cursor ID reproted +by the underlying rendering engine for WebView2. It is not meant to return a +value for any custom cursors, such as those defined by CSS. + +It can be used at any time but will only change after a `CursorChanged` event. + + +# Examples + +```cpp +CHECK_FAILURE(m_compositionController->add_CursorChanged( + Callback( + [this](ICoreWebView2ExperimentalCompositionController* sender, IUnknown* args) + -> HRESULT { + HRESULT hr = S_OK; + HCURSOR cursor; + UINT32 cursorId; + wil::com_ptr compositionController2 = + m_controller.query(); + CHECK_FAILURE(compositionController2->get_SystemCursorId(&cursorId)); + cursor = ::LoadCursor(nullptr, MAKEINTRESOURCE(cursorId)); + if (cursor == nullptr) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + } + + if (SUCCEEDED(hr)) + { + SetClassLongPtr( + m_appWindow->GetMainWindow() /* HWND */, GCLP_HCURSOR, (LONG_PTR)cursor); + } + return hr; + }) + .Get(), + &m_cursorChangedToken)); + + +# API Notes + +See [API Details](#api-details) section below for API reference. + +# API Details + +/// This interface is continuation of the +/// ICoreWebView2ExperimentalCompositionController interface. +[uuid(279ae616-b7cb-4946-8da3-dc853645d2ba), object, pointer_default(unique)] +interface ICoreWebView2ExperimentalCompositionController2 : IUnknown { + /// The current system cursor ID reported by the underlying rendering engine + /// for WebView. For example, most of the time, when the cursor is over text, + /// this will return the int value for IDC_IBEAM. The systemCursorId is only + /// valid if the rendering engine reports a default Windows cursor resource + /// value. See: + /// https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-loadcursorw + /// Otherwise, if custom CSS cursors are being used, this will return 0. + /// To actually use systemCursorId in LoadCursor or LoadImage, + /// MAKEINTRESOURCE must be called on it first. + /// + /// \snippet ViewComponent.cpp SystemCursorId + [propget] HRESULT SystemCursorId([out, retval] UINT32* systemCursorId); +} + +# Appendix + +I expect that most apps will use the get_Cursor API which returns an HCURSOR (Or +the UWP equivalent that will be implemented in the future that will return a +CoreCursor) outside of Office as HCURSOR is more comprehensive and covers the +scenarios in which custom cursors are used. From 3429572e4f0fcc8e8302a940dc1cde7a80487fab Mon Sep 17 00:00:00 2001 From: Jameson Li Date: Tue, 29 Sep 2020 19:37:59 -0700 Subject: [PATCH 2/4] Update SystemCursorId update from feedback --- specs/SystemCursorId | 55 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 10 deletions(-) diff --git a/specs/SystemCursorId b/specs/SystemCursorId index b3c97c9d4..9258691b6 100644 --- a/specs/SystemCursorId +++ b/specs/SystemCursorId @@ -1,12 +1,12 @@ # Background -In visual hosting, the current cursor image cannot be determined easily by the -hosting application easily. For example, if the cursor over the WebView is also -over a textbox inside of the WebView, the cursor should usually be IDC_IBEAM. -And by default, the cursor is IDC_ARROW. Currently, we return the what the -cursor should be as an HCURSOR object (After calling LoadCursor on those IDC -values). The hosting application can then use the HCURSOR object to change the -current cursor to the correct image. +When an app is using composition hosting to host WebView, the current cursor +image cannot be determined easily by the hosting application. For example, if +the cursor over the WebView is also over a textbox inside of the WebView, the +cursor should usually be IDC_IBEAM. And by default, the cursor is IDC_ARROW. +Currently, we return the what the cursor should be as an HCURSOR object (After +calling LoadCursor on those IDC values). The hosting application can then use +the HCURSOR object to change the current cursor to the correct image. However, Office already has a well established way of using cursors internally by using IDC_* values and there is no easy way to convert the HCURSOR object we @@ -15,15 +15,21 @@ are returning into an IDC value after it's been created. This new API is to enable hosting applications like Office to get the current IDC value of the cursor instead of the HCURSOR as an option. +Note that this is a COM and .NET spec as WinRT uses a separate enum structure to +identify cursor IDs. + # Description -The `SystemCursorId` property will return the current system cursor ID reproted +The `SystemCursorId` property will return the current system cursor ID reported by the underlying rendering engine for WebView2. It is not meant to return a value for any custom cursors, such as those defined by CSS. It can be used at any time but will only change after a `CursorChanged` event. +Note that developers should generally use the `Cursor` property to support cases +where there may be custom cursors. + # Examples @@ -59,12 +65,14 @@ CHECK_FAILURE(m_compositionController->add_CursorChanged( See [API Details](#api-details) section below for API reference. + # API Details +```cpp /// This interface is continuation of the -/// ICoreWebView2ExperimentalCompositionController interface. +/// ICoreWebView2CompositionController interface. [uuid(279ae616-b7cb-4946-8da3-dc853645d2ba), object, pointer_default(unique)] -interface ICoreWebView2ExperimentalCompositionController2 : IUnknown { +interface ICoreWebView2CompositionController2 : ICoreWebView2CompositionController { /// The current system cursor ID reported by the underlying rendering engine /// for WebView. For example, most of the time, when the cursor is over text, /// this will return the int value for IDC_IBEAM. The systemCursorId is only @@ -79,6 +87,33 @@ interface ICoreWebView2ExperimentalCompositionController2 : IUnknown { [propget] HRESULT SystemCursorId([out, retval] UINT32* systemCursorId); } +```c# +namespace Microsoft.Web.WebView2.Core +{ + // + // Summary: + // This class is an extension of the CoreWebView2CompositionController class to support composition + // hosting. + public class CoreWebView2CompositionController2 : CoreWebView2CompositionController + { + // + // Summary: + // The current system cursor ID that WebView thinks it should be. + // + // Remarks: + // The current system cursor ID reported by the underlying rendering engine + // for WebView. For example, most of the time, when the cursor is over text, + // this will return the int value for IDC_IBEAM. The SystemCursorId is only + // valid if the rendering engine reports a default Windows cursor resource + // value. See: + // https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-loadcursorw + // Otherwise, if custom CSS cursors are being used, this will return 0. + // To create a Cursor object, create an IntPtr from the returned uint to + // pass into the constructor + public Uint32 SystemCursorId { get; } + } +} + # Appendix I expect that most apps will use the get_Cursor API which returns an HCURSOR (Or From ef7a3b7fa7cfa69999b50302dad30fe200073b7e Mon Sep 17 00:00:00 2001 From: Jameson Li Date: Wed, 30 Sep 2020 15:33:48 -0700 Subject: [PATCH 3/4] Update SystemCursorId --- specs/SystemCursorId | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/SystemCursorId b/specs/SystemCursorId index 9258691b6..3692033f4 100644 --- a/specs/SystemCursorId +++ b/specs/SystemCursorId @@ -94,7 +94,7 @@ namespace Microsoft.Web.WebView2.Core // Summary: // This class is an extension of the CoreWebView2CompositionController class to support composition // hosting. - public class CoreWebView2CompositionController2 : CoreWebView2CompositionController + public class CoreWebView2CompositionController2 { // // Summary: From 34a1474ae9b45b7125ac156eb1b69e7c9ef95649 Mon Sep 17 00:00:00 2001 From: Jameson Li Date: Wed, 30 Sep 2020 15:36:37 -0700 Subject: [PATCH 4/4] Rename SystemCursorId to SystemCursorId.md --- specs/{SystemCursorId => SystemCursorId.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename specs/{SystemCursorId => SystemCursorId.md} (100%) diff --git a/specs/SystemCursorId b/specs/SystemCursorId.md similarity index 100% rename from specs/SystemCursorId rename to specs/SystemCursorId.md