mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
Auto merge of #24008 - paulrouget:urlhandler, r=jdm
HoloLens URL handler Handles servo URLS. For example, in any browser, a link to `servo://https://servo.org` will load `https://servo.org` will open and load the servo app. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/24008) <!-- Reviewable:end -->
This commit is contained in:
commit
de76163846
10 changed files with 91 additions and 40 deletions
|
@ -62,8 +62,29 @@ void App::OnLaunched(LaunchActivatedEventArgs const &e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::OnSuspending([[maybe_unused]] IInspectable const &sender,
|
void App::OnActivated(IActivatedEventArgs const &args) {
|
||||||
[[maybe_unused]] SuspendingEventArgs const &e) {
|
if (args.Kind() ==
|
||||||
|
Windows::ApplicationModel::Activation::ActivationKind::Protocol) {
|
||||||
|
auto protocolActivatedEventArgs{args.as<
|
||||||
|
Windows::ApplicationModel::Activation::ProtocolActivatedEventArgs>()};
|
||||||
|
|
||||||
|
Frame rootFrame{nullptr};
|
||||||
|
|
||||||
|
auto content = Window::Current().Content();
|
||||||
|
if (content == nullptr) {
|
||||||
|
rootFrame = Frame();
|
||||||
|
rootFrame.Navigate(xaml_typename<ServoApp::BrowserPage>());
|
||||||
|
Window::Current().Content(rootFrame);
|
||||||
|
Window::Current().Activate();
|
||||||
|
} else {
|
||||||
|
rootFrame = content.try_as<Frame>();
|
||||||
|
}
|
||||||
|
auto page = rootFrame.Content().try_as<BrowserPage>();
|
||||||
|
page->LoadServoURI(protocolActivatedEventArgs.Uri());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void App::OnSuspending(IInspectable const &, SuspendingEventArgs const &) {
|
||||||
auto content = Window::Current().Content();
|
auto content = Window::Current().Content();
|
||||||
Frame rootFrame = content.try_as<Frame>();
|
Frame rootFrame = content.try_as<Frame>();
|
||||||
auto page = rootFrame.Content().try_as<BrowserPage>();
|
auto page = rootFrame.Content().try_as<BrowserPage>();
|
||||||
|
|
|
@ -11,6 +11,8 @@ struct App : AppT<App> {
|
||||||
|
|
||||||
void OnLaunched(
|
void OnLaunched(
|
||||||
Windows::ApplicationModel::Activation::LaunchActivatedEventArgs const &);
|
Windows::ApplicationModel::Activation::LaunchActivatedEventArgs const &);
|
||||||
|
void App::OnActivated(
|
||||||
|
Windows::ApplicationModel::Activation::IActivatedEventArgs const &args);
|
||||||
void OnSuspending(IInspectable const &,
|
void OnSuspending(IInspectable const &,
|
||||||
Windows::ApplicationModel::SuspendingEventArgs const &);
|
Windows::ApplicationModel::SuspendingEventArgs const &);
|
||||||
void OnNavigationFailed(
|
void OnNavigationFailed(
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "BrowserPage.h"
|
#include "BrowserPage.h"
|
||||||
#include "BrowserPage.g.cpp"
|
#include "BrowserPage.g.cpp"
|
||||||
|
|
||||||
|
using namespace winrt::Windows::Foundation;
|
||||||
using namespace winrt::Windows::UI::Xaml;
|
using namespace winrt::Windows::UI::Xaml;
|
||||||
using namespace winrt::Windows::UI::Core;
|
using namespace winrt::Windows::UI::Core;
|
||||||
using namespace winrt::Windows::UI::ViewManagement;
|
using namespace winrt::Windows::UI::ViewManagement;
|
||||||
|
@ -36,10 +37,20 @@ void BrowserPage::BindServoEvents() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void BrowserPage::Shutdown() {
|
void BrowserPage::LoadServoURI(Uri uri) {
|
||||||
servoControl().Shutdown();
|
auto scheme = uri.SchemeName();
|
||||||
|
|
||||||
|
if (scheme != SERVO_SCHEME) {
|
||||||
|
log("Unexpected URL: ", uri.RawUri().c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::wstring raw{uri.RawUri()};
|
||||||
|
auto raw2 = raw.substr(SERVO_SCHEME_SLASH_SLASH.size());
|
||||||
|
servoControl().LoadURIOrSearch(raw2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BrowserPage::Shutdown() { servoControl().Shutdown(); }
|
||||||
|
|
||||||
/**** USER INTERACTIONS WITH UI ****/
|
/**** USER INTERACTIONS WITH UI ****/
|
||||||
|
|
||||||
void BrowserPage::OnBackButtonClicked(IInspectable const &,
|
void BrowserPage::OnBackButtonClicked(IInspectable const &,
|
||||||
|
@ -62,7 +73,7 @@ void BrowserPage::OnStopButtonClicked(IInspectable const &,
|
||||||
servoControl().Stop();
|
servoControl().Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BrowserPage::OnURLEdited(IInspectable const &sender,
|
void BrowserPage::OnURLEdited(IInspectable const &,
|
||||||
Input::KeyRoutedEventArgs const &e) {
|
Input::KeyRoutedEventArgs const &e) {
|
||||||
if (e.Key() == Windows::System::VirtualKey::Enter) {
|
if (e.Key() == Windows::System::VirtualKey::Enter) {
|
||||||
servoControl().Focus(FocusState::Programmatic);
|
servoControl().Focus(FocusState::Programmatic);
|
||||||
|
|
|
@ -9,6 +9,9 @@
|
||||||
|
|
||||||
namespace winrt::ServoApp::implementation {
|
namespace winrt::ServoApp::implementation {
|
||||||
|
|
||||||
|
static const hstring SERVO_SCHEME = L"servo";
|
||||||
|
static const hstring SERVO_SCHEME_SLASH_SLASH = L"servo://";
|
||||||
|
|
||||||
struct BrowserPage : BrowserPageT<BrowserPage> {
|
struct BrowserPage : BrowserPageT<BrowserPage> {
|
||||||
public:
|
public:
|
||||||
BrowserPage();
|
BrowserPage();
|
||||||
|
@ -18,12 +21,13 @@ public:
|
||||||
void OnBackButtonClicked(Windows::Foundation::IInspectable const &,
|
void OnBackButtonClicked(Windows::Foundation::IInspectable const &,
|
||||||
Windows::UI::Xaml::RoutedEventArgs const &);
|
Windows::UI::Xaml::RoutedEventArgs const &);
|
||||||
void OnReloadButtonClicked(Windows::Foundation::IInspectable const &,
|
void OnReloadButtonClicked(Windows::Foundation::IInspectable const &,
|
||||||
Windows::UI::Xaml::RoutedEventArgs const &);
|
Windows::UI::Xaml::RoutedEventArgs const &);
|
||||||
void OnStopButtonClicked(Windows::Foundation::IInspectable const &,
|
void OnStopButtonClicked(Windows::Foundation::IInspectable const &,
|
||||||
Windows::UI::Xaml::RoutedEventArgs const &);
|
Windows::UI::Xaml::RoutedEventArgs const &);
|
||||||
void OnURLEdited(Windows::Foundation::IInspectable const &,
|
void OnURLEdited(Windows::Foundation::IInspectable const &,
|
||||||
Windows::UI::Xaml::Input::KeyRoutedEventArgs const &);
|
Windows::UI::Xaml::Input::KeyRoutedEventArgs const &);
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
void LoadServoURI(Windows::Foundation::Uri uri);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void BindServoEvents();
|
void BindServoEvents();
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" IgnorableNamespaces="uap mp">
|
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" IgnorableNamespaces="uap mp">
|
||||||
<Identity
|
<Identity Name="1d265729-8836-4bd3-9992-4cb111d1068b" Publisher="CN=paul" Version="1.0.0.0" />
|
||||||
Name="1d265729-8836-4bd3-9992-4cb111d1068b"
|
<mp:PhoneIdentity PhoneProductId="1d265729-8836-4bd3-9992-4cb111d1068b" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
|
||||||
Publisher="CN=paul"
|
|
||||||
Version="1.0.0.0" />
|
|
||||||
<mp:PhoneIdentity PhoneProductId="1d265729-8836-4bd3-9992-4cb111d1068b" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
|
|
||||||
<Properties>
|
<Properties>
|
||||||
<DisplayName>ServoApp</DisplayName>
|
<DisplayName>ServoApp</DisplayName>
|
||||||
<PublisherDisplayName>paul</PublisherDisplayName>
|
<PublisherDisplayName>Mozilla</PublisherDisplayName>
|
||||||
<Logo>Assets\StoreLogo.png</Logo>
|
<Logo>Assets\StoreLogo.png</Logo>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Dependencies>
|
<Dependencies>
|
||||||
|
@ -18,12 +15,19 @@
|
||||||
</Resources>
|
</Resources>
|
||||||
<Applications>
|
<Applications>
|
||||||
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="ServoApp.App">
|
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="ServoApp.App">
|
||||||
<uap:VisualElements DisplayName="ServoApp" Description="Project for a single page C++/WinRT Universal Windows Platform (UWP) app with no predefined layout"
|
<uap:VisualElements DisplayName="ServoApp" Description="A Servo-based browser." Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" BackgroundColor="transparent">
|
||||||
Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" BackgroundColor="transparent">
|
|
||||||
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png">
|
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png">
|
||||||
</uap:DefaultTile>
|
</uap:DefaultTile>
|
||||||
<uap:SplashScreen Image="Assets\SplashScreen.png" />
|
<uap:SplashScreen Image="Assets\SplashScreen.png" />
|
||||||
</uap:VisualElements>
|
</uap:VisualElements>
|
||||||
|
<Extensions>
|
||||||
|
<uap:Extension Category="windows.protocol">
|
||||||
|
<uap:Protocol Name="servo">
|
||||||
|
<uap:Logo>Assets\StoreLogo.png</uap:Logo>
|
||||||
|
<uap:DisplayName>Servo URL</uap:DisplayName>
|
||||||
|
</uap:Protocol>
|
||||||
|
</uap:Extension>
|
||||||
|
</Extensions>
|
||||||
</Application>
|
</Application>
|
||||||
</Applications>
|
</Applications>
|
||||||
<Capabilities>
|
<Capabilities>
|
||||||
|
|
|
@ -32,12 +32,13 @@ void on_panic(const char *backtrace) {
|
||||||
throw hresult_error(E_FAIL, char2hstring(backtrace));
|
throw hresult_error(E_FAIL, char2hstring(backtrace));
|
||||||
}
|
}
|
||||||
|
|
||||||
Servo::Servo(GLsizei width, GLsizei height, ServoDelegate &aDelegate)
|
Servo::Servo(hstring url, GLsizei width, GLsizei height,
|
||||||
|
ServoDelegate &aDelegate)
|
||||||
: mWindowHeight(height), mWindowWidth(width), mDelegate(aDelegate) {
|
: mWindowHeight(height), mWindowWidth(width), mDelegate(aDelegate) {
|
||||||
|
|
||||||
capi::CInitOptions o;
|
capi::CInitOptions o;
|
||||||
o.args = "--pref dom.webxr.enabled";
|
o.args = "--pref dom.webxr.enabled";
|
||||||
o.url = "https://servo.org";
|
o.url = *hstring2char(url);
|
||||||
o.width = mWindowWidth;
|
o.width = mWindowWidth;
|
||||||
o.height = mWindowHeight;
|
o.height = mWindowHeight;
|
||||||
o.density = 1.0;
|
o.density = 1.0;
|
||||||
|
@ -78,4 +79,13 @@ winrt::hstring char2hstring(const char *c_str) {
|
||||||
return str3;
|
return str3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<char *> hstring2char(hstring hstr) {
|
||||||
|
const wchar_t *wc = hstr.c_str();
|
||||||
|
size_t size = hstr.size() + 1;
|
||||||
|
char *str = new char[size];
|
||||||
|
size_t converted = 0;
|
||||||
|
wcstombs_s(&converted, str, size, wc, hstr.size());
|
||||||
|
return std::make_unique<char*>(str);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace winrt::servo
|
} // namespace winrt::servo
|
||||||
|
|
|
@ -16,6 +16,9 @@ extern "C" {
|
||||||
}
|
}
|
||||||
} // namespace capi
|
} // namespace capi
|
||||||
|
|
||||||
|
hstring char2hstring(const char *);
|
||||||
|
std::unique_ptr<char *> hstring2char(hstring);
|
||||||
|
|
||||||
class ServoDelegate {
|
class ServoDelegate {
|
||||||
public:
|
public:
|
||||||
// Called from any thread
|
// Called from any thread
|
||||||
|
@ -39,7 +42,7 @@ protected:
|
||||||
|
|
||||||
class Servo {
|
class Servo {
|
||||||
public:
|
public:
|
||||||
Servo(GLsizei, GLsizei, ServoDelegate &);
|
Servo(hstring, GLsizei, GLsizei, ServoDelegate &);
|
||||||
~Servo();
|
~Servo();
|
||||||
ServoDelegate &Delegate() { return mDelegate; }
|
ServoDelegate &Delegate() { return mDelegate; }
|
||||||
|
|
||||||
|
@ -49,19 +52,12 @@ public:
|
||||||
void SetBatchMode(bool mode) { capi::set_batch_mode(mode); }
|
void SetBatchMode(bool mode) { capi::set_batch_mode(mode); }
|
||||||
void GoForward() { capi::go_forward(); }
|
void GoForward() { capi::go_forward(); }
|
||||||
void GoBack() { capi::go_back(); }
|
void GoBack() { capi::go_back(); }
|
||||||
void Click(float x, float y) { capi::click(x, y); }
|
void Click(float x, float y) { capi::click((int32_t)x, (int32_t)y); }
|
||||||
void Reload() { capi::reload(); }
|
void Reload() { capi::reload(); }
|
||||||
void Stop() { capi::stop(); }
|
void Stop() { capi::stop(); }
|
||||||
void LoadUri(hstring uri) {
|
void LoadUri(hstring uri) { capi::load_uri(*hstring2char(uri)); }
|
||||||
const wchar_t* wc = uri.c_str();
|
|
||||||
size_t size = uri.size() + 1;
|
|
||||||
char* str = new char[size];
|
|
||||||
size_t converted = 0;
|
|
||||||
wcstombs_s(&converted, str, size, wc, uri.size());
|
|
||||||
capi::load_uri(str);
|
|
||||||
}
|
|
||||||
void Scroll(float dx, float dy, float x, float y) {
|
void Scroll(float dx, float dy, float x, float y) {
|
||||||
capi::scroll(dx, dy, x, y);
|
capi::scroll((int32_t)dx, (int32_t)dy, (int32_t)x, (int32_t)y);
|
||||||
}
|
}
|
||||||
void SetSize(GLsizei width, GLsizei height) {
|
void SetSize(GLsizei width, GLsizei height) {
|
||||||
if (width != mWindowWidth || height != mWindowHeight) {
|
if (width != mWindowWidth || height != mWindowHeight) {
|
||||||
|
@ -82,6 +78,4 @@ private:
|
||||||
// the Servo instance. See https://github.com/servo/servo/issues/22967
|
// the Servo instance. See https://github.com/servo/servo/issues/22967
|
||||||
static Servo *sServo = nullptr;
|
static Servo *sServo = nullptr;
|
||||||
|
|
||||||
hstring char2hstring(const char *c_str);
|
} // namespace winrt::servo
|
||||||
|
|
||||||
} // namespace servo
|
|
||||||
|
|
|
@ -44,8 +44,7 @@ void ServoControl::OnLoaded(IInspectable const &, RoutedEventArgs const &) {
|
||||||
|
|
||||||
Controls::SwapChainPanel ServoControl::Panel() {
|
Controls::SwapChainPanel ServoControl::Panel() {
|
||||||
// FIXME: is there a better way of doing this?
|
// FIXME: is there a better way of doing this?
|
||||||
return GetTemplateChild(L"swapChainPanel")
|
return GetTemplateChild(L"swapChainPanel").as<Controls::SwapChainPanel>();
|
||||||
.as<Controls::SwapChainPanel>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServoControl::CreateRenderSurface() {
|
void ServoControl::CreateRenderSurface() {
|
||||||
|
@ -105,12 +104,17 @@ Uri ServoControl::LoadURIOrSearch(hstring input) {
|
||||||
hstring input2 = L"https://" + input;
|
hstring input2 = L"https://" + input;
|
||||||
uri = TryParseURI(input2);
|
uri = TryParseURI(input2);
|
||||||
if (uri == std::nullopt || !has_dot) {
|
if (uri == std::nullopt || !has_dot) {
|
||||||
hstring input3 = L"https://duckduckgo.com/html/?q=" + Uri::EscapeComponent(input);
|
hstring input3 =
|
||||||
|
L"https://duckduckgo.com/html/?q=" + Uri::EscapeComponent(input);
|
||||||
uri = TryParseURI(input3);
|
uri = TryParseURI(input3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto finalUri = uri.value();
|
auto finalUri = uri.value();
|
||||||
RunOnGLThread([=] { mServo->LoadUri(finalUri.ToString()); });
|
if (!mLooping) {
|
||||||
|
mInitialURL = finalUri.ToString();
|
||||||
|
} else {
|
||||||
|
RunOnGLThread([=] { mServo->LoadUri(finalUri.ToString()); });
|
||||||
|
}
|
||||||
return finalUri;
|
return finalUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,7 +140,7 @@ void ServoControl::Loop() {
|
||||||
if (mServo == nullptr) {
|
if (mServo == nullptr) {
|
||||||
log("Entering loop");
|
log("Entering loop");
|
||||||
ServoDelegate *sd = static_cast<ServoDelegate *>(this);
|
ServoDelegate *sd = static_cast<ServoDelegate *>(this);
|
||||||
mServo = std::make_unique<Servo>(panelWidth, panelHeight, *sd);
|
mServo = std::make_unique<Servo>(mInitialURL, panelWidth, panelHeight, *sd);
|
||||||
} else {
|
} else {
|
||||||
// FIXME: this will fail since create_task didn't pick the thread
|
// FIXME: this will fail since create_task didn't pick the thread
|
||||||
// where Servo was running initially.
|
// where Servo was running initially.
|
||||||
|
|
|
@ -63,6 +63,7 @@ private:
|
||||||
winrt::event<HistoryChangedDelegate> mOnHistoryChangedEvent;
|
winrt::event<HistoryChangedDelegate> mOnHistoryChangedEvent;
|
||||||
winrt::event<LoadStatusChangedDelegate> mOnLoadStartedEvent;
|
winrt::event<LoadStatusChangedDelegate> mOnLoadStartedEvent;
|
||||||
winrt::event<LoadStatusChangedDelegate> mOnLoadEndedEvent;
|
winrt::event<LoadStatusChangedDelegate> mOnLoadEndedEvent;
|
||||||
|
hstring mInitialURL = L"https://servo.org";
|
||||||
|
|
||||||
Windows::UI::Xaml::Controls::SwapChainPanel ServoControl::Panel();
|
Windows::UI::Xaml::Controls::SwapChainPanel ServoControl::Panel();
|
||||||
void CreateRenderSurface();
|
void CreateRenderSurface();
|
||||||
|
@ -76,7 +77,7 @@ private:
|
||||||
std::optional<Windows::Foundation::Uri> TryParseURI(hstring input) {
|
std::optional<Windows::Foundation::Uri> TryParseURI(hstring input) {
|
||||||
try {
|
try {
|
||||||
return Windows::Foundation::Uri(input);
|
return Windows::Foundation::Uri(input);
|
||||||
} catch (hresult_invalid_argument const &e) {
|
} catch (hresult_invalid_argument const &) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,13 +41,13 @@
|
||||||
#include <winrt/Windows.Storage.Streams.h>
|
#include <winrt/Windows.Storage.Streams.h>
|
||||||
#include <winrt/Windows.UI.Core.h>
|
#include <winrt/Windows.UI.Core.h>
|
||||||
#include <winrt/Windows.UI.Input.Spatial.h>
|
#include <winrt/Windows.UI.Input.Spatial.h>
|
||||||
#include "winrt/Windows.UI.Popups.h"
|
#include <winrt/Windows.UI.Popups.h>
|
||||||
#include "winrt/Windows.UI.ViewManagement.h"
|
#include <winrt/Windows.UI.ViewManagement.h>
|
||||||
#include <winrt/Windows.UI.Xaml.Controls.h>
|
#include <winrt/Windows.UI.Xaml.Controls.h>
|
||||||
#include <winrt/Windows.UI.Xaml.Controls.Primitives.h>
|
#include <winrt/Windows.UI.Xaml.Controls.Primitives.h>
|
||||||
#include <winrt/Windows.UI.Xaml.Data.h>
|
#include <winrt/Windows.UI.Xaml.Data.h>
|
||||||
#include <winrt/Windows.UI.Xaml.h>
|
#include <winrt/Windows.UI.Xaml.h>
|
||||||
#include "winrt/Windows.UI.Xaml.Input.h"
|
#include <winrt/Windows.UI.Xaml.Input.h>
|
||||||
#include <winrt/Windows.UI.Xaml.Interop.h>
|
#include <winrt/Windows.UI.Xaml.Interop.h>
|
||||||
#include <winrt/Windows.UI.Xaml.Markup.h>
|
#include <winrt/Windows.UI.Xaml.Markup.h>
|
||||||
#include <winrt/Windows.UI.Xaml.Navigation.h>
|
#include <winrt/Windows.UI.Xaml.Navigation.h>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue