diff options
author | Paul Rouget <me@paulrouget.com> | 2020-06-17 11:36:04 +0200 |
---|---|---|
committer | Josh Matthews <josh@joshmatthews.net> | 2020-06-17 23:22:22 -0400 |
commit | bd8c7d6f4d0c84f901bb0822cb48deb38b86037f (patch) | |
tree | da48d8fd646a2d0b111fd4d672d95bb1471545f7 /support/hololens | |
parent | 2560e78f11d197f40b3a44069cf68a0609d7081a (diff) | |
download | servo-bd8c7d6f4d0c84f901bb0822cb48deb38b86037f.tar.gz servo-bd8c7d6f4d0c84f901bb0822cb48deb38b86037f.zip |
[UWP] Basic console panel
Diffstat (limited to 'support/hololens')
-rw-r--r-- | support/hololens/ServoApp/BrowserPage.cpp | 91 | ||||
-rw-r--r-- | support/hololens/ServoApp/BrowserPage.h | 9 | ||||
-rw-r--r-- | support/hololens/ServoApp/BrowserPage.xaml | 8 | ||||
-rw-r--r-- | support/hololens/ServoApp/Devtools/Client.cpp | 237 | ||||
-rw-r--r-- | support/hololens/ServoApp/Devtools/Client.h | 57 | ||||
-rw-r--r-- | support/hololens/ServoApp/ServoApp.vcxproj | 4 | ||||
-rw-r--r-- | support/hololens/ServoApp/ServoApp.vcxproj.filters | 9 | ||||
-rw-r--r-- | support/hololens/ServoApp/Strings/en-US/Resources.resw | 3 | ||||
-rw-r--r-- | support/hololens/ServoApp/pch.h | 15 |
9 files changed, 400 insertions, 33 deletions
diff --git a/support/hololens/ServoApp/BrowserPage.cpp b/support/hololens/ServoApp/BrowserPage.cpp index e81578a48d6..85b1c0c5885 100644 --- a/support/hololens/ServoApp/BrowserPage.cpp +++ b/support/hololens/ServoApp/BrowserPage.cpp @@ -7,11 +7,7 @@ #include "BrowserPage.h" #include "BrowserPage.g.cpp" #include "DefaultUrl.h" - -#include "winrt/Microsoft.UI.Xaml.Controls.h" -#include "winrt/Microsoft.UI.Xaml.XamlTypeInfo.h" -#include "winrt/Windows.UI.Text.h" -#include "winrt/Windows.UI.Xaml.Documents.h" // For Run.Text() +#include "Devtools/Client.h" using namespace std::placeholders; using namespace winrt::Windows::Foundation; @@ -21,7 +17,9 @@ using namespace winrt::Windows::UI::ViewManagement; using namespace winrt::Windows::ApplicationModel::Core; using namespace winrt::Windows::ApplicationModel::Resources; using namespace winrt::Windows::UI::Notifications; +using namespace winrt::Windows::Data::Json; using namespace winrt::Windows::Data::Xml::Dom; +using namespace winrt::servo; namespace winrt::ServoApp::implementation { @@ -46,6 +44,7 @@ void BrowserPage::BindServoEvents() { reloadButton().Visibility(Visibility::Collapsed); stopButton().IsEnabled(true); stopButton().Visibility(Visibility::Visible); + devtoolsButton().IsEnabled(true); }); servoControl().OnLoadEnded([=] { urlbarLoadingIndicator().IsActive(false); @@ -64,22 +63,20 @@ void BrowserPage::BindServoEvents() { urlTextbox().GotFocus(std::bind(&BrowserPage::OnURLFocused, this, _1)); servoControl().OnMediaSessionMetadata( [=](hstring title, hstring artist, hstring album) {}); - servoControl().OnMediaSessionPlaybackStateChange( - [=](const auto &, int state) { - if (state == servo::Servo::MediaSessionPlaybackState::None) { - mediaControls().Visibility(Visibility::Collapsed); - return; - } - mediaControls().Visibility(Visibility::Visible); - playButton().Visibility( - state == servo::Servo::MediaSessionPlaybackState::Paused - ? Visibility::Visible - : Visibility::Collapsed); - pauseButton().Visibility( - state == servo::Servo::MediaSessionPlaybackState::Paused - ? Visibility::Collapsed - : Visibility::Visible); - }); + servoControl().OnMediaSessionPlaybackStateChange([=](const auto &, + int state) { + if (state == Servo::MediaSessionPlaybackState::None) { + mediaControls().Visibility(Visibility::Collapsed); + return; + } + mediaControls().Visibility(Visibility::Visible); + playButton().Visibility(state == Servo::MediaSessionPlaybackState::Paused + ? Visibility::Visible + : Visibility::Collapsed); + pauseButton().Visibility(state == Servo::MediaSessionPlaybackState::Paused + ? Visibility::Collapsed + : Visibility::Visible); + }); servoControl().OnDevtoolsStatusChanged( [=](DevtoolsStatus status, unsigned int port) { mDevtoolsStatus = status; @@ -276,11 +273,49 @@ void BrowserPage::OnPrefererenceSearchboxEdited( } } +void BrowserPage::OnDevtoolsMessage(DevtoolsMessageLevel level, hstring source, + hstring body) { + Dispatcher().RunAsync(CoreDispatcherPriority::Low, [=] { + // Temporary text-based logs. Should use gridview. + auto paragraph = Documents::Paragraph(); + + auto run1 = Documents::Run(); + if (level == DevtoolsMessageLevel::Warn) { + run1.Text(L"warn: "); + } else if (level == DevtoolsMessageLevel::Error) { + run1.Text(L"error: "); + } else if (level == DevtoolsMessageLevel::None) { + run1.Text(L""); + } + paragraph.Inlines().Append(run1); + + auto run2 = Documents::Run(); + run2.Text(body); + paragraph.Inlines().Append(run2); + + auto run3 = Documents::Run(); + run3.Text(L" " + source); + paragraph.Inlines().Append(run3); + + DevtoolsConsoleOutput().Blocks().Append(paragraph); + + // Scroll to last message + auto offset = DevtoolsConsoleScrollViewer().ExtentHeight(); + DevtoolsConsoleScrollViewer().ChangeView(nullptr, offset, nullptr); + }); +} + +void BrowserPage::OnDevtoolsDetached() {} + void BrowserPage::OnDevtoolsButtonClicked(IInspectable const &, RoutedEventArgs const &) { if (toolbox().Visibility() == Visibility::Visible) { prefList().Children().Clear(); toolbox().Visibility(Visibility::Collapsed); + DevtoolsConsoleOutput().Blocks().Clear(); + if (mDevtoolsClient != nullptr) { + mDevtoolsClient->Stop(); + } return; } @@ -290,10 +325,16 @@ void BrowserPage::OnDevtoolsButtonClicked(IInspectable const &, auto resourceLoader = ResourceLoader::GetForCurrentView(); if (mDevtoolsStatus == DevtoolsStatus::Running) { + hstring port = to_hstring(mDevtoolsPort); + if (mDevtoolsClient == nullptr) { + DevtoolsDelegate *dd = static_cast<DevtoolsDelegate *>(this); + mDevtoolsClient = + std::make_unique<DevtoolsClient>(L"localhost", port, *dd); + } + mDevtoolsClient->Run(); std::wstring message = resourceLoader.GetString(L"devtoolsStatus/Running").c_str(); - std::wstring formatted = - format(message, std::to_wstring(mDevtoolsPort).c_str()); + std::wstring formatted = format(message, port.c_str()); DevtoolsStatusMessage().Text(formatted); } else if (mDevtoolsStatus == DevtoolsStatus::Failed) { DevtoolsStatusMessage().Text( @@ -317,12 +358,12 @@ void BrowserPage::OnURLEdited(IInspectable const &, void BrowserPage::OnMediaControlsPlayClicked(IInspectable const &, RoutedEventArgs const &) { servoControl().SendMediaSessionAction( - static_cast<int32_t>(servo::Servo::MediaSessionActionType::Play)); + static_cast<int32_t>(Servo::MediaSessionActionType::Play)); } void BrowserPage::OnMediaControlsPauseClicked(IInspectable const &, RoutedEventArgs const &) { servoControl().SendMediaSessionAction( - static_cast<int32_t>(servo::Servo::MediaSessionActionType::Pause)); + static_cast<int32_t>(Servo::MediaSessionActionType::Pause)); } } // namespace winrt::ServoApp::implementation diff --git a/support/hololens/ServoApp/BrowserPage.h b/support/hololens/ServoApp/BrowserPage.h index bae31d22ff3..1b4a53bc636 100644 --- a/support/hololens/ServoApp/BrowserPage.h +++ b/support/hololens/ServoApp/BrowserPage.h @@ -5,18 +5,20 @@ #pragma once #include "BrowserPage.g.h" -#include "ServoControl\ServoControl.h" +#include "ServoControl/ServoControl.h" +#include "Devtools/Client.h" namespace winrt::ServoApp::implementation { using namespace winrt::Windows; +using namespace winrt::Windows::Data::Json; using namespace winrt::Windows::Foundation; using namespace winrt::Windows::UI::Xaml; static const hstring SERVO_SCHEME = L"fxr"; static const hstring SERVO_SCHEME_SLASH_SLASH = L"fxr://"; -struct BrowserPage : BrowserPageT<BrowserPage> { +struct BrowserPage : BrowserPageT<BrowserPage>, public servo::DevtoolsDelegate { public: BrowserPage(); @@ -41,6 +43,8 @@ public: RoutedEventArgs const &); void OnPrefererenceSearchboxEdited(IInspectable const &, Input::KeyRoutedEventArgs const &); + void OnDevtoolsMessage(servo::DevtoolsMessageLevel, hstring, hstring); + void OnDevtoolsDetached(); private: void UpdatePref(ServoApp::Pref, Controls::Control); @@ -48,6 +52,7 @@ private: void BuildPrefList(); DevtoolsStatus mDevtoolsStatus = DevtoolsStatus::Stopped; unsigned int mDevtoolsPort = 0; + std::unique_ptr<servo::DevtoolsClient> mDevtoolsClient; }; } // namespace winrt::ServoApp::implementation diff --git a/support/hololens/ServoApp/BrowserPage.xaml b/support/hololens/ServoApp/BrowserPage.xaml index 7954ad828e4..bb034bba5fb 100644 --- a/support/hololens/ServoApp/BrowserPage.xaml +++ b/support/hololens/ServoApp/BrowserPage.xaml @@ -130,7 +130,7 @@ </TextBox.KeyboardAccelerators> </TextBox> <StackPanel Orientation="Horizontal" Grid.Column="2"> - <Button Style="{StaticResource NavigationBarButton}" x:Name="devtoolsButton" x:Uid="devtoolsButton" IsTabStop="true" Click="OnDevtoolsButtonClicked"> + <Button Style="{StaticResource NavigationBarButton}" x:Name="devtoolsButton" IsEnabled="false" x:Uid="devtoolsButton" IsTabStop="true" Click="OnDevtoolsButtonClicked"> <Image Source="Assets/UI/devtools.png" Height="18"></Image> </Button> <ProgressRing x:Name="urlbarLoadingIndicator" Margin="10,0"/> @@ -149,6 +149,12 @@ </Button> </Grid> </muxc:TabView.TabStripFooter> + <muxc:TabViewItem x:Uid="devtoolsTabConsole" IsClosable="False"> + <ScrollViewer x:Name="DevtoolsConsoleScrollViewer" VerticalScrollMode="Enabled" HorizontalScrollMode="Enabled"> + <RichTextBlock x:Name="DevtoolsConsoleOutput" FontSize="10" FontFamily="Consolas" LineHeight="14"> + </RichTextBlock> + </ScrollViewer> + </muxc:TabViewItem> <muxc:TabViewItem x:Uid="devtoolsTabServer" IsClosable="False"> <TextBlock x:Name="DevtoolsStatusMessage" Margin="10"></TextBlock> </muxc:TabViewItem> diff --git a/support/hololens/ServoApp/Devtools/Client.cpp b/support/hololens/ServoApp/Devtools/Client.cpp new file mode 100644 index 00000000000..8a10ce65cdc --- /dev/null +++ b/support/hololens/ServoApp/Devtools/Client.cpp @@ -0,0 +1,237 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#include "pch.h" +#include "strutils.h" +#include "Client.h" + +using namespace winrt::Windows::Data::Json; +using namespace winrt::Windows::Foundation; +using namespace winrt::Windows::Networking; +using namespace winrt::Windows::Storage::Streams; + +namespace winrt::servo { + +void DevtoolsClient::Stop() { + if (mReceiving && mReceiveOp.has_value() && + mReceiveOp->Status() != AsyncStatus::Completed) { + mReceiveOp->Cancel(); + } +} + +void DevtoolsClient::Run() { + if (mReceiving) { + throw hresult_error(E_FAIL, L"Already running"); + } + mReceiving = true; + auto socket = Sockets::StreamSocket(); + auto hostname = HostName(mHostname); + auto connecting = socket.ConnectAsync(hostname, mPort); + connecting.Completed([=](const auto &, const auto &) { + mDataReader = DataReader(socket.InputStream()); + mDataWriter = DataWriter(socket.OutputStream()); + mReceiveOp = {Loop()}; + mReceiveOp->Completed([=](const auto &, const auto &) { + mReceiveOp = {}; + mDataReader->DetachStream(); + mDataWriter->DetachStream(); + mReceiving = false; + mDelegate.OnDevtoolsDetached(); + }); + }); +} + +IAsyncAction DevtoolsClient::Loop() { + auto cancellation = co_await winrt::get_cancellation_token(); + cancellation.callback([=] { + if (mReaderOp.Status() != AsyncStatus::Completed) { + mReaderOp.Cancel(); + } + }); + + while (!cancellation()) { + unsigned int len = 0; + while (!cancellation()) { + mReaderOp = mDataReader->LoadAsync(1); + co_await mReaderOp; + hstring c = mDataReader->ReadString(1); + if (c == L":") + break; + try { + unsigned int digit = std::stoi(c.c_str()); + len = 10 * len + digit; + } catch (...) { + throw hresult_error(E_FAIL, L"Can't parse message header:" + c); + } + if (len >= 10000) { + throw hresult_error(E_FAIL, L"Message length too long"); + } + } + if (cancellation()) { + break; + } + hstring request = L""; + mReaderOp = mDataReader->LoadAsync(len); + auto bytesLoaded = co_await mReaderOp; + request = request + mDataReader->ReadString(bytesLoaded); + JsonObject json; + if (!JsonObject::TryParse(request, json)) { + throw hresult_error(E_FAIL, L"Can't parse message: " + request); + } + HandleMessage(json); + } +} + +void DevtoolsClient::HandleMessage(JsonObject obj) { + // Basic devtools protocol implementation: + // https://docs.firefox-dev.tools/backend/protocol.html + + if (obj.HasKey(L"from") && obj.GetNamedString(L"from") == L"root") { + if (obj.HasKey(L"applicationType")) { + // First message. Ask for the current tab + JsonObject out; + out.Insert(L"to", JsonValue::CreateStringValue(L"root")); + out.Insert(L"type", JsonValue::CreateStringValue(L"getTab")); + Send(out); + return; + } else if (obj.HasKey(L"tab")) { + // Got the current tab. + auto tab = obj.GetNamedObject(L"tab"); + if (tab.HasKey(L"actor")) { + // Attach to tab, and ask for cached messaged + JsonObject msg1; + msg1.Insert(L"to", tab.GetNamedValue(L"actor")); + msg1.Insert(L"type", JsonValue::CreateStringValue(L"attach")); + Send(msg1); + JsonObject msg2; + msg2.Insert(L"to", tab.GetNamedValue(L"consoleActor")); + msg2.Insert(L"type", + JsonValue::CreateStringValue(L"getCachedMessages")); + JsonArray types; + types.Append(JsonValue::CreateStringValue(L"PageError")); + types.Append(JsonValue::CreateStringValue(L"ConsoleAPI")); + msg2.Insert(L"messageTypes", types); + Send(msg2); + return; + } + } + } else if (obj.HasKey(L"type")) { // Not from root + if (obj.GetNamedString(L"type") == L"pageError") { + // Got a page error + HandlePageError(obj.GetNamedObject(L"pageError")); + return; + } else if (obj.GetNamedString(L"type") == L"consoleAPICall") { + // console.* calls + auto message = obj.GetNamedObject(L"message"); + HandleConsoleMessage(message); + return; + } else if (obj.GetNamedString(L"type") == L"tabAttached") { + // Ignore + return; + } else if (obj.GetNamedString(L"type") == L"networkEvent") { + // Ignore + return; + } else if (obj.GetNamedString(L"type") == L"tabNavigated") { + // Ignore + return; + } else if (obj.GetNamedString(L"type") == L"networkEventUpdate") { + // FIXME: log if there is a non-200 HTTP response + return; + } + } else if (obj.HasKey(L"messages")) { + // Response to getCachedMessages + for (auto messageValue : obj.GetNamedArray(L"messages")) { + auto message = messageValue.GetObject(); + if (message.GetNamedString(L"_type") == L"ConsoleAPI") { + HandleConsoleMessage(message); + } else if (message.GetNamedString(L"_type") == L"PageError") { + HandlePageError(message); + } else { + HandleNonHandledMessage(message); + } + } + return; + } + HandleNonHandledMessage(obj); +} + +DevtoolsMessageLevel DevtoolsClient::ParseLevel(JsonObject message) { + if (message.GetNamedBoolean(L"error", false)) { + return DevtoolsMessageLevel::Error; + } + if (message.GetNamedBoolean(L"warning", false)) { + return DevtoolsMessageLevel::Warn; + } + if (message.GetNamedBoolean(L"exception", false)) { + return DevtoolsMessageLevel::Error; + } + auto level = message.GetNamedString(L"level", L""); + if (level == L"warn") { + return DevtoolsMessageLevel::Warn; + } else if (level == L"error") { + return DevtoolsMessageLevel::Error; + } + return DevtoolsMessageLevel::None; +} + +hstring DevtoolsClient::ParseSource(JsonObject message) { + auto source = message.GetNamedString(L"filename", L"<>"); + if (message.HasKey(L"lineNumber")) { + source = source + L":" + to_hstring(message.GetNamedNumber(L"lineNumber")); + } + if (message.HasKey(L"columnNumber")) { + source = + source + L":" + to_hstring(message.GetNamedNumber(L"columnNumber")); + } + return source; +} + +void DevtoolsClient::HandlePageError(JsonObject message) { + auto source = ParseSource(message); + auto body = message.GetNamedString(L"errorMessage", L""); + auto level = ParseLevel(message); + mDelegate.OnDevtoolsMessage(level, source, body); +} + +void DevtoolsClient::HandleConsoleMessage(JsonObject message) { + auto source = ParseSource(message); + auto level = ParseLevel(message); + hstring body = L""; + for (auto arg : message.GetNamedArray(L"arguments")) { + body = body + arg.Stringify(); + } + mDelegate.OnDevtoolsMessage(level, source, body); +} + +void DevtoolsClient::HandleNonHandledMessage(JsonObject message) { + auto level = DevtoolsMessageLevel::Warn; + auto body = L"Unhandled devtools message: " + message.Stringify(); + mDelegate.OnDevtoolsMessage(level, L"", body); +} + +void DevtoolsClient::SendPendingObjects() { + if (mPendingObjects.empty() || mSending) { + return; + } + mSending = true; + auto obj = mPendingObjects.front(); + mPendingObjects.erase(mPendingObjects.begin()); + hstring msg = obj.Stringify(); + hstring size = to_hstring(msg.size()); + hstring request = size + L":" + msg; + mDataWriter->WriteString(request); + mDataWriter->StoreAsync().Completed([=](const auto &, const auto &) { + mDataWriter->FlushAsync().Completed([=](const auto &, const auto &) { + mSending = false; + SendPendingObjects(); + }); + }); +} + +void DevtoolsClient::Send(JsonObject obj) { + mPendingObjects.push_back(obj); + SendPendingObjects(); +} + +} // namespace winrt::servo diff --git a/support/hololens/ServoApp/Devtools/Client.h b/support/hololens/ServoApp/Devtools/Client.h new file mode 100644 index 00000000000..162d2e33e07 --- /dev/null +++ b/support/hololens/ServoApp/Devtools/Client.h @@ -0,0 +1,57 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#pragma once + +#include "pch.h" + +namespace winrt::servo { +using namespace winrt::Windows::Storage::Streams; +using namespace winrt::Windows::Data::Json; +using namespace winrt::Windows::Foundation; +using namespace winrt::Windows::Networking::Sockets; + +class DevtoolsDelegate; + +enum DevtoolsMessageLevel { Error, Warn, None }; + +class DevtoolsClient { + +public: + DevtoolsClient(hstring hostname, hstring port, DevtoolsDelegate &d) + : mDelegate(d), mHostname(hostname), mPort(port){}; + + ~DevtoolsClient() { Stop(); } + void Run(); + void Stop(); + void Send(JsonObject); + +private: + hstring mPort; + hstring mHostname; + DevtoolsDelegate &mDelegate; + std::optional<DataReader> mDataReader; + std::optional<DataWriter> mDataWriter; + std::optional<IAsyncAction> mReceiveOp; + std::vector<JsonObject> mPendingObjects; + IAsyncOperation<unsigned int> mReaderOp; + bool mSending = false; + bool mReceiving = false; + void SendPendingObjects(); + IAsyncAction Loop(); + DevtoolsMessageLevel ParseLevel(JsonObject); + hstring ParseSource(JsonObject); + void HandleMessage(JsonObject); + void HandlePageError(JsonObject); + void HandleConsoleMessage(JsonObject); + void HandleNonHandledMessage(JsonObject); +}; + +class DevtoolsDelegate { +public: + virtual void OnDevtoolsMessage(DevtoolsMessageLevel, hstring, hstring) = 0; + virtual void OnDevtoolsDetached() = 0; +}; + +} // namespace winrt::servo diff --git a/support/hololens/ServoApp/ServoApp.vcxproj b/support/hololens/ServoApp/ServoApp.vcxproj index 040bd8cc7dc..0d819c3fffc 100644 --- a/support/hololens/ServoApp/ServoApp.vcxproj +++ b/support/hololens/ServoApp/ServoApp.vcxproj @@ -119,6 +119,7 @@ </Link> </ItemDefinitionGroup> <ItemGroup> + <ClInclude Include="Devtools\Client.h" /> <ClInclude Include="strutils.h" /> <ClInclude Include="pch.h" /> <ClInclude Include="App.h"> @@ -913,6 +914,7 @@ <Image Include="Assets\Wide310x150Logo.scale-400.png" /> </ItemGroup> <ItemGroup> + <ClCompile Include="Devtools\Client.cpp" /> <ClCompile Include="pch.cpp"> <PrecompiledHeader>Create</PrecompiledHeader> </ClCompile> @@ -964,4 +966,4 @@ <Error Condition="!Exists('..\packages\ANGLE.WindowsStore.Servo.2.1.19\build\native\ANGLE.WindowsStore.Servo.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\ANGLE.WindowsStore.Servo.2.1.19\build\native\ANGLE.WindowsStore.Servo.targets'))" /> <Error Condition="!Exists('..\packages\Microsoft.UI.Xaml.2.4.2\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.UI.Xaml.2.4.2\build\native\Microsoft.UI.Xaml.targets'))" /> </Target> -</Project> +</Project>
\ No newline at end of file diff --git a/support/hololens/ServoApp/ServoApp.vcxproj.filters b/support/hololens/ServoApp/ServoApp.vcxproj.filters index 4348585239a..4bb5ad598a7 100644 --- a/support/hololens/ServoApp/ServoApp.vcxproj.filters +++ b/support/hololens/ServoApp/ServoApp.vcxproj.filters @@ -21,6 +21,9 @@ <ClCompile Include="ServoControl\ServoControl.cpp"> <Filter>ServoControl</Filter> </ClCompile> + <ClCompile Include="Devtools\Client.cpp"> + <Filter>Devtools</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="pch.h" /> @@ -37,6 +40,9 @@ </ClInclude> <ClInclude Include="DefaultUrl.h" /> <ClInclude Include="strutils.h" /> + <ClInclude Include="Devtools\Client.h"> + <Filter>Devtools</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <Image Include="Assets\Wide310x150Logo.scale-200.png"> @@ -896,6 +902,9 @@ <Filter Include="Strings\fr-FR"> <UniqueIdentifier>{b7d3273d-a27c-4176-87a1-3d5222b796b3}</UniqueIdentifier> </Filter> + <Filter Include="Devtools"> + <UniqueIdentifier>{12da8b9d-c14a-4be1-8328-c4e729fdfd3b}</UniqueIdentifier> + </Filter> </ItemGroup> <ItemGroup> <None Include="PropertySheet.props" /> diff --git a/support/hololens/ServoApp/Strings/en-US/Resources.resw b/support/hololens/ServoApp/Strings/en-US/Resources.resw index 8f496bef051..b2a0052477a 100644 --- a/support/hololens/ServoApp/Strings/en-US/Resources.resw +++ b/support/hololens/ServoApp/Strings/en-US/Resources.resw @@ -111,6 +111,9 @@ <data name="devtoolsTabServer.[using:Microsoft.UI.Xaml.Controls]TabViewItem.Header" xml:space="preserve"> <value>Devtools Server</value> </data> + <data name="devtoolsTabConsole.[using:Microsoft.UI.Xaml.Controls]TabViewItem.Header" xml:space="preserve"> + <value>Console</value> + </data> <data name="devtoolsTabPrefs.[using:Microsoft.UI.Xaml.Controls]TabViewItem.Header" xml:space="preserve"> <value>Preferences</value> </data> diff --git a/support/hololens/ServoApp/pch.h b/support/hololens/ServoApp/pch.h index ff5db96a994..fe0197dd58d 100644 --- a/support/hololens/ServoApp/pch.h +++ b/support/hololens/ServoApp/pch.h @@ -14,6 +14,7 @@ #include <d3d11_4.h> #include <DirectXColors.h> #include <dwrite_2.h> +#include <sstream> #include <Windows.Graphics.Directx.Direct3D11.Interop.h> #include <windows.h> #include <WindowsNumerics.h> @@ -36,6 +37,7 @@ #include <winrt/Windows.Gaming.Input.h> #include <winrt/Windows.Graphics.Display.h> #include <winrt/Windows.Graphics.Holographic.h> +#include <winrt/Windows.Networking.Sockets.h> #include <winrt/Windows.Perception.People.h> #include <winrt/Windows.Perception.Spatial.h> #include <winrt/Windows.Storage.h> @@ -49,14 +51,19 @@ #include <winrt/Windows.UI.Xaml.Controls.Primitives.h> #include <winrt/Windows.UI.Xaml.Data.h> #include <winrt/Windows.UI.Xaml.h> +#include <winrt/Windows.UI.Xaml.Documents.h> #include <winrt/Windows.UI.Xaml.Input.h> #include <winrt/Windows.UI.Xaml.Interop.h> #include <winrt/Windows.UI.Xaml.Markup.h> #include <winrt/Windows.UI.Xaml.Navigation.h> #include <winrt/Windows.UI.Notifications.h> +#include <winrt/Windows.UI.Text.h> #include <winrt/Windows.Data.Xml.Dom.h> +#include <winrt/Windows.Storage.Streams.h> +#include <winrt/Windows.Data.Json.h> -#include "winrt/Microsoft.UI.Xaml.Automation.Peers.h" -#include "winrt/Microsoft.UI.Xaml.Controls.Primitives.h" -#include "winrt/Microsoft.UI.Xaml.Media.h" -#include "winrt/Microsoft.UI.Xaml.XamlTypeInfo.h"
\ No newline at end of file +#include <winrt/Microsoft.UI.Xaml.Automation.Peers.h> +#include <winrt/Microsoft.UI.Xaml.Controls.h> +#include <winrt/Microsoft.UI.Xaml.Controls.Primitives.h> +#include <winrt/Microsoft.UI.Xaml.Media.h> +#include <winrt/Microsoft.UI.Xaml.XamlTypeInfo.h> |