UWP: Preference panel

This commit is contained in:
Paul Rouget 2020-06-05 14:03:49 +02:00
parent 479afcfb8e
commit dd2ebce57e
14 changed files with 482 additions and 43 deletions

View file

@ -1,6 +1,7 @@
#include "pch.h"
#include "Servo.h"
#include <EGL/egl.h>
#include "../DefaultUrl.h"
namespace winrt::servo {
@ -130,10 +131,64 @@ Servo::Servo(hstring url, hstring args, GLsizei width, GLsizei height,
: mWindowHeight(height), mWindowWidth(width), mDelegate(aDelegate) {
SetEnvironmentVariableA("PreviewRuntimeEnabled", "1");
Windows::Storage::ApplicationDataContainer localSettings =
Windows::Storage::ApplicationData::Current().LocalSettings();
if (!localSettings.Containers().HasKey(L"servoUserPrefs")) {
Windows::Storage::ApplicationDataContainer container =
localSettings.CreateContainer(
L"servoUserPrefs",
Windows::Storage::ApplicationDataCreateDisposition::Always);
}
auto prefs = localSettings.Containers().Lookup(L"servoUserPrefs");
if (!prefs.Values().HasKey(L"shell.homepage")) {
prefs.Values().Insert(L"shell.homepage", box_value(DEFAULT_URL));
}
if (!prefs.Values().HasKey(L"dom.webxr.enabled")) {
prefs.Values().Insert(L"dom.webxr.enabled", box_value(true));
}
std::vector<capi::CPref> cprefs;
for (auto pref : prefs.Values()) {
auto key = *hstring2char(pref.Key());
auto value = pref.Value();
auto type = value.as<Windows::Foundation::IPropertyValue>().Type();
capi::CPref pref;
pref.key = key;
pref.pref_type = capi::CPrefType::Missing;
pref.value = NULL;
if (type == Windows::Foundation::PropertyType::Boolean) {
pref.pref_type = capi::CPrefType::Bool;
auto val = unbox_value<bool>(value);
pref.value = &val;
} else if (type == Windows::Foundation::PropertyType::String) {
pref.pref_type = capi::CPrefType::Str;
pref.value = *hstring2char(unbox_value<hstring>(value));
} else if (type == Windows::Foundation::PropertyType::Int64) {
pref.pref_type = capi::CPrefType::Int;
auto val = unbox_value<int64_t>(value);
pref.value = &val;
} else if (type == Windows::Foundation::PropertyType::Double) {
pref.pref_type = capi::CPrefType::Float;
auto val = unbox_value<double>(value);
pref.value = &val;
} else if (type == Windows::Foundation::PropertyType::Empty) {
pref.pref_type = capi::CPrefType::Missing;
} else {
log("skipping pref %s. Unknown type", key);
continue;
}
cprefs.push_back(pref);
}
capi::CPrefList prefsList = {cprefs.size(), cprefs.data()};
capi::CInitOptions o;
hstring defaultPrefs = L" --pref dom.webxr.enabled --devtools";
o.args = *hstring2char(args + defaultPrefs);
o.url = *hstring2char(url);
o.prefs = &prefsList;
o.args = *hstring2char(args + L"--devtools");
o.width = mWindowWidth;
o.height = mWindowHeight;
o.density = dpi;
@ -221,6 +276,96 @@ Servo::~Servo() {
CloseHandle(sLogHandle);
}
Servo::PrefTuple Servo::SetFloatPref(hstring key, double val) {
auto ckey = *hstring2char(key);
capi::set_float_pref(ckey, val);
auto updatedPref = WrapPref(capi::get_pref(ckey));
SaveUserPref(updatedPref);
return updatedPref;
}
Servo::PrefTuple Servo::SetIntPref(hstring key, int64_t val) {
auto ckey = *hstring2char(key);
capi::set_int_pref(ckey, val);
auto updatedPref = WrapPref(capi::get_pref(ckey));
SaveUserPref(updatedPref);
return updatedPref;
}
Servo::PrefTuple Servo::SetBoolPref(hstring key, bool val) {
auto ckey = *hstring2char(key);
capi::set_bool_pref(ckey, val);
auto updatedPref = WrapPref(capi::get_pref(ckey));
SaveUserPref(updatedPref);
return updatedPref;
}
Servo::PrefTuple Servo::SetStringPref(hstring key, hstring val) {
auto ckey = *hstring2char(key);
auto cval = *hstring2char(val);
capi::set_str_pref(ckey, cval);
auto updatedPref = WrapPref(capi::get_pref(ckey));
SaveUserPref(updatedPref);
return updatedPref;
}
Servo::PrefTuple Servo::ResetPref(hstring key) {
auto ckey = *hstring2char(key);
capi::reset_pref(ckey);
auto updatedPref = WrapPref(capi::get_pref(ckey));
SaveUserPref(updatedPref);
return updatedPref;
}
void Servo::SaveUserPref(PrefTuple pref) {
auto localSettings =
Windows::Storage::ApplicationData::Current().LocalSettings();
auto values = localSettings.Containers().Lookup(L"servoUserPrefs").Values();
auto [key, val, isDefault] = pref;
if (isDefault) {
values.Remove(key);
} else {
values.Insert(key, val);
}
}
Servo::PrefTuple Servo::WrapPref(capi::CPref pref) {
winrt::Windows::Foundation::IInspectable val;
if (pref.pref_type == capi::CPrefType::Bool) {
val = box_value(*(capi::get_pref_as_bool(pref.value)));
} else if (pref.pref_type == capi::CPrefType::Int) {
val = box_value(*(capi::get_pref_as_int(pref.value)));
} else if (pref.pref_type == capi::CPrefType::Float) {
val = box_value(*(capi::get_pref_as_float(pref.value)));
} else if (pref.pref_type == capi::CPrefType::Str) {
val = box_value(char2hstring(capi::get_pref_as_str(pref.value)));
}
auto key = char2hstring(pref.key);
auto isDefault = pref.is_default;
Servo::PrefTuple t{key, val, isDefault};
return t;
}
Servo::PrefTuple Servo::GetPref(hstring key) {
auto ckey = *hstring2char(key);
return WrapPref(capi::get_pref(ckey));
}
std::vector<Servo::PrefTuple> Servo::GetPrefs() {
if (sServo == nullptr) {
return {};
}
auto prefs = capi::get_prefs();
std::vector<
std::tuple<hstring, winrt::Windows::Foundation::IInspectable, bool>>
vec;
for (auto i = 0; i < prefs.len; i++) {
auto pref = WrapPref(prefs.list[i]);
vec.push_back(pref);
}
return vec;
}
winrt::hstring char2hstring(const char *c_str) {
// FIXME: any better way of doing this?
auto str = std::string(c_str);

View file

@ -29,12 +29,23 @@ public:
~Servo();
ServoDelegate &Delegate() { return mDelegate; }
typedef std::tuple<hstring, winrt::Windows::Foundation::IInspectable, bool>
PrefTuple;
static std::vector<PrefTuple> GetPrefs();
static PrefTuple GetPref(hstring key);
static PrefTuple SetBoolPref(hstring key, bool val);
static PrefTuple SetStringPref(hstring key, hstring val);
static PrefTuple SetIntPref(hstring key, int64_t val);
static PrefTuple SetFloatPref(hstring key, double val);
static PrefTuple ResetPref(hstring key);
typedef capi::CMouseButton MouseButton;
typedef capi::CPromptResult PromptResult;
typedef capi::CContextMenuResult ContextMenuResult;
typedef capi::CMediaSessionActionType MediaSessionActionType;
typedef capi::CMediaSessionPlaybackState MediaSessionPlaybackState;
typedef capi::CDevtoolsServerState DevtoolsServerState;
typedef capi::CPrefType CPrefType;
void PerformUpdates() { capi::perform_updates(); }
void DeInit() { capi::deinit(); }
@ -85,6 +96,8 @@ private:
ServoDelegate &mDelegate;
GLsizei mWindowWidth;
GLsizei mWindowHeight;
static void SaveUserPref(PrefTuple);
static PrefTuple WrapPref(capi::CPref cpref);
};
class ServoDelegate {

View file

@ -1,6 +1,7 @@
#include "pch.h"
#include "ServoControl.h"
#include "ServoControl.g.cpp"
#include "Pref.g.cpp"
#include <stdlib.h>
using namespace std::placeholders;
@ -275,10 +276,19 @@ hstring ServoControl::LoadURIOrSearch(hstring input) {
}
// Doesn't look like a URI. Let's search for the string.
hstring searchUri =
L"https://duckduckgo.com/html/?q=" + Uri::EscapeComponent(input);
TryLoadUri(searchUri);
return searchUri;
auto escapedInput = Uri::EscapeComponent(input);
std::wstring searchUri =
unbox_value<hstring>(std::get<1>(Servo::GetPref(L"shell.searchpage")))
.c_str();
std::wstring keyword = L"%s";
size_t start_pos = searchUri.find(keyword);
if (start_pos == std::string::npos)
searchUri = searchUri + escapedInput;
else
searchUri.replace(start_pos, keyword.length(), escapedInput);
hstring finalUri{searchUri};
TryLoadUri(finalUri);
return finalUri;
}
void ServoControl::SendMediaSessionAction(int32_t action) {
@ -580,4 +590,13 @@ template <typename Callable> void ServoControl::RunOnUIThread(Callable cb) {
Dispatcher().RunAsync(CoreDispatcherPriority::High, cb);
}
Collections::IVector<ServoApp::Pref> ServoControl::Preferences() {
std::vector<ServoApp::Pref> prefs;
for (auto [key, val, isDefault] : Servo::GetPrefs()) {
prefs.push_back(ServoApp::Pref(key, val, isDefault));
}
return winrt::single_threaded_observable_vector<ServoApp::Pref>(
std::move(prefs));
}
} // namespace winrt::ServoApp::implementation

View file

@ -1,5 +1,6 @@
#pragma once
#include "ServoControl.g.h"
#include "Pref.g.h"
#include "OpenGLES.h"
#include "Servo.h"
#include "DefaultUrl.h"
@ -7,10 +8,30 @@
using namespace winrt::Windows::Foundation::Collections;
namespace winrt::ServoApp::implementation {
struct Pref : PrefT<Pref> {
public:
Pref(hstring key, IInspectable value, bool isDefault) {
mKey = key;
mValue = value;
mIsDefault = isDefault;
};
IInspectable Value() { return mValue; }
hstring Key() { return mKey; }
bool IsDefault() { return mIsDefault; }
private:
hstring mKey;
IInspectable mValue;
bool mIsDefault;
};
struct ServoControl : ServoControlT<ServoControl>, public servo::ServoDelegate {
ServoControl();
Windows::Foundation::Collections::IVector<ServoApp::Pref> Preferences();
void GoBack();
void GoForward();
void Reload();
@ -20,6 +41,36 @@ struct ServoControl : ServoControlT<ServoControl>, public servo::ServoDelegate {
hstring LoadURIOrSearch(hstring);
void SendMediaSessionAction(int32_t);
ServoApp::Pref SetBoolPref(hstring aKey, bool aVal) {
auto [key, val, isDefault] = servo::Servo::SetBoolPref(aKey, aVal);
return ServoApp::Pref(key, val, isDefault);
}
ServoApp::Pref SetStringPref(hstring aKey, hstring aVal) {
auto [key, val, isDefault] = servo::Servo::SetStringPref(aKey, aVal);
return ServoApp::Pref(key, val, isDefault);
}
ServoApp::Pref SetIntPref(hstring aKey, int64_t aVal) {
auto [key, val, isDefault] = servo::Servo::SetIntPref(aKey, aVal);
return ServoApp::Pref(key, val, isDefault);
}
ServoApp::Pref SetFloatPref(hstring aKey, double aVal) {
auto [key, val, isDefault] = servo::Servo::SetFloatPref(aKey, aVal);
return ServoApp::Pref(key, val, isDefault);
}
ServoApp::Pref ResetPref(hstring aKey) {
auto [key, val, isDefault] = servo::Servo::ResetPref(aKey);
return ServoApp::Pref(key, val, isDefault);
}
ServoApp::Pref GetPref(hstring aKey) {
auto [key, val, isDefault] = servo::Servo::GetPref(aKey);
return ServoApp::Pref(key, val, isDefault);
}
void OnLoaded(IInspectable const &,
Windows::UI::Xaml::RoutedEventArgs const &);
@ -223,4 +274,5 @@ private:
namespace winrt::ServoApp::factory_implementation {
struct ServoControl
: ServoControlT<ServoControl, implementation::ServoControl> {};
struct Pref : PrefT<Pref, implementation::Pref> {};
} // namespace winrt::ServoApp::factory_implementation

View file

@ -11,6 +11,14 @@ namespace ServoApp {
Failed,
};
runtimeclass Pref
{
Pref(String key, IInspectable val, Boolean isDefault);
IInspectable Value { get; };
String Key { get; };
Boolean IsDefault { get; };
}
runtimeclass ServoControl : Windows.UI.Xaml.Controls.Control {
ServoControl();
void GoBack();
@ -33,5 +41,12 @@ namespace ServoApp {
event Windows.Foundation.EventHandler<String> OnURLChanged;
event MediaSessionMetadataDelegate OnMediaSessionMetadata;
event Windows.Foundation.EventHandler<int> OnMediaSessionPlaybackStateChange;
Windows.Foundation.Collections.IVector<Pref> Preferences { get; };
Pref GetPref(String key);
Pref SetBoolPref(String key, Boolean val);
Pref SetIntPref(String key, Int64 val);
Pref SetFloatPref(String key, Double val);
Pref SetStringPref(String key, String val);
Pref ResetPref(String key);
}
} // namespace ServoApp