Custom scroll bar in WebKit / Chromium.

This commit is contained in:
John Preston 2022-04-12 19:48:32 +04:00
parent 9510d38929
commit d4cb56a73d
10 changed files with 52 additions and 20 deletions

View file

@ -27,6 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "window/themes/window_theme.h" #include "window/themes/window_theme.h"
#include "window/window_controller.h" #include "window/window_controller.h"
#include "window/window_session_controller.h" #include "window/window_session_controller.h"
#include "webview/webview_interface.h"
#include "core/application.h" #include "core/application.h"
#include "core/local_url_handlers.h" #include "core/local_url_handlers.h"
#include "ui/basic_click_handlers.h" #include "ui/basic_click_handlers.h"
@ -366,7 +367,7 @@ void AttachWebView::request(const WebViewButton &button) {
_bot->inputUser, _bot->inputUser,
MTP_bytes(button.url), MTP_bytes(button.url),
MTP_string(_startCommand), MTP_string(_startCommand),
MTP_dataJSON(MTP_bytes(Window::Theme::WebViewParams())), MTP_dataJSON(MTP_bytes(Window::Theme::WebViewParams().json)),
MTPint() // reply_to_msg_id MTPint() // reply_to_msg_id
)).done([=](const MTPWebViewResult &result) { )).done([=](const MTPWebViewResult &result) {
_requestId = 0; _requestId = 0;
@ -559,7 +560,7 @@ void AttachWebView::requestSimple(const WebViewButton &button) {
MTP_flags(Flag::f_theme_params), MTP_flags(Flag::f_theme_params),
_bot->inputUser, _bot->inputUser,
MTP_bytes(button.url), MTP_bytes(button.url),
MTP_dataJSON(MTP_bytes(Window::Theme::WebViewParams())) MTP_dataJSON(MTP_bytes(Window::Theme::WebViewParams().json))
)).done([=](const MTPSimpleWebViewResult &result) { )).done([=](const MTPSimpleWebViewResult &result) {
_requestId = 0; _requestId = 0;
result.match([&](const MTPDsimpleWebViewResultUrl &data) { result.match([&](const MTPDsimpleWebViewResultUrl &data) {
@ -589,7 +590,7 @@ void AttachWebView::requestMenu(
_bot->inputUser, _bot->inputUser,
MTP_string(url), MTP_string(url),
MTPstring(), MTPstring(),
MTP_dataJSON(MTP_bytes(Window::Theme::WebViewParams())), MTP_dataJSON(MTP_bytes(Window::Theme::WebViewParams().json)),
MTPint() MTPint()
)).done([=](const MTPWebViewResult &result) { )).done([=](const MTPWebViewResult &result) {
_requestId = 0; _requestId = 0;
@ -644,7 +645,7 @@ void AttachWebView::show(
Expects(_bot != nullptr && _peer != nullptr); Expects(_bot != nullptr && _peer != nullptr);
const auto close = crl::guard(this, [=] { const auto close = crl::guard(this, [=] {
cancel(); crl::on_main(this, [=] { cancel(); });
}); });
const auto sendData = crl::guard(this, [=](QByteArray data) { const auto sendData = crl::guard(this, [=](QByteArray data) {
if (_peer != _bot || queryId) { if (_peer != _bot || queryId) {
@ -669,7 +670,7 @@ void AttachWebView::show(
return false; return false;
} }
UrlClickHandler::Open(local, {}); UrlClickHandler::Open(local, {});
crl::on_main(close); close();
return true; return true;
}; };
auto title = Info::Profile::NameValue( auto title = Info::Profile::NameValue(

View file

@ -24,6 +24,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "apiwrap.h" #include "apiwrap.h"
#include "api/api_cloud_password.h" #include "api/api_cloud_password.h"
#include "window/themes/window_theme.h" #include "window/themes/window_theme.h"
#include "webview/webview_interface.h"
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonObject> #include <QJsonObject>

View file

@ -29,6 +29,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "apiwrap.h" #include "apiwrap.h"
#include "core/core_cloud_password.h" #include "core/core_cloud_password.h"
#include "window/themes/window_theme.h" #include "window/themes/window_theme.h"
#include "webview/webview_interface.h"
#include "styles/style_payments.h" // paymentsThumbnailSize. #include "styles/style_payments.h" // paymentsThumbnailSize.
#include <QtCore/QJsonDocument> #include <QtCore/QJsonDocument>
@ -242,7 +243,7 @@ void Form::requestForm() {
MTP_flags(MTPpayments_GetPaymentForm::Flag::f_theme_params), MTP_flags(MTPpayments_GetPaymentForm::Flag::f_theme_params),
_peer->input, _peer->input,
MTP_int(_msgId), MTP_int(_msgId),
MTP_dataJSON(MTP_bytes(Window::Theme::WebViewParams())) MTP_dataJSON(MTP_bytes(Window::Theme::WebViewParams().json))
)).done([=](const MTPpayments_PaymentForm &result) { )).done([=](const MTPpayments_PaymentForm &result) {
hideProgress(); hideProgress();
result.match([&](const auto &data) { result.match([&](const auto &data) {

View file

@ -783,15 +783,20 @@ void Panel::showWebviewError(
showCriticalError(rich); showCriticalError(rich);
} }
void Panel::updateThemeParams(const QByteArray &json) { void Panel::updateThemeParams(const Webview::ThemeParams &params) {
if (!_webview || !_webview->window.widget()) { if (!_webview || !_webview->window.widget()) {
return; return;
} }
_webview->window.updateTheme(
params.scrollBg,
params.scrollBgOver,
params.scrollBarBg,
params.scrollBarBgOver);
_webview->window.eval(R"( _webview->window.eval(R"(
if (window.TelegramGameProxy) { if (window.TelegramGameProxy) {
window.TelegramGameProxy.receiveEvent( window.TelegramGameProxy.receiveEvent(
"theme_changed", "theme_changed",
{ "theme_params": )" + json + R"( }); { "theme_params": )" + params.json + R"( });
} }
)"); )");
} }

View file

@ -18,6 +18,7 @@ class Checkbox;
namespace Webview { namespace Webview {
struct Available; struct Available;
struct ThemeParams;
} // namespace Webview } // namespace Webview
namespace Payments::Ui { namespace Payments::Ui {
@ -76,7 +77,7 @@ public:
const QString &url, const QString &url,
bool allowBack, bool allowBack,
rpl::producer<QString> bottomText); rpl::producer<QString> bottomText);
void updateThemeParams(const QByteArray &json); void updateThemeParams(const Webview::ThemeParams &params);
[[nodiscard]] rpl::producer<> backRequests() const; [[nodiscard]] rpl::producer<> backRequests() const;

View file

@ -307,7 +307,7 @@ Panel::Panel(
Fn<bool(QString)> handleLocalUri, Fn<bool(QString)> handleLocalUri,
Fn<void(QByteArray)> sendData, Fn<void(QByteArray)> sendData,
Fn<void()> close, Fn<void()> close,
Fn<QByteArray()> themeParams) Fn<Webview::ThemeParams()> themeParams)
: _userDataPath(userDataPath) : _userDataPath(userDataPath)
, _handleLocalUri(std::move(handleLocalUri)) , _handleLocalUri(std::move(handleLocalUri))
, _sendData(std::move(sendData)) , _sendData(std::move(sendData))
@ -465,6 +465,7 @@ void Panel::hideWebviewProgress() {
bool Panel::showWebview( bool Panel::showWebview(
const QString &url, const QString &url,
const Webview::ThemeParams &params,
rpl::producer<QString> bottomText) { rpl::producer<QString> bottomText) {
if (!_webview && !createWebview()) { if (!_webview && !createWebview()) {
return false; return false;
@ -472,6 +473,7 @@ bool Panel::showWebview(
const auto allowBack = false; const auto allowBack = false;
showWebviewProgress(); showWebviewProgress();
_widget->destroyLayer(); _widget->destroyLayer();
updateThemeParams(params);
_webview->window.navigate(url); _webview->window.navigate(url);
_widget->setBackAllowed(allowBack); _widget->setBackAllowed(allowBack);
if (bottomText) { if (bottomText) {
@ -523,6 +525,7 @@ bool Panel::createWebview() {
.userDataPath = _userDataPath, .userDataPath = _userDataPath,
}); });
const auto raw = &_webview->window; const auto raw = &_webview->window;
QObject::connect(container, &QObject::destroyed, [=] { QObject::connect(container, &QObject::destroyed, [=] {
if (_webview && &_webview->window == raw) { if (_webview && &_webview->window == raw) {
_webview = nullptr; _webview = nullptr;
@ -741,11 +744,16 @@ void Panel::showCriticalError(const TextWithEntities &text) {
_widget->showInner(std::move(error)); _widget->showInner(std::move(error));
} }
void Panel::updateThemeParams(const QByteArray &json) { void Panel::updateThemeParams(const Webview::ThemeParams &params) {
if (!_webview || !_webview->window.widget()) { if (!_webview || !_webview->window.widget()) {
return; return;
} }
postEvent("theme_changed", "\"theme_params\": " + json); _webview->window.updateTheme(
params.scrollBg,
params.scrollBgOver,
params.scrollBarBg,
params.scrollBarBgOver);
postEvent("theme_changed", "\"theme_params\": " + params.json);
} }
void Panel::postEvent(const QString &event, const QString &data) { void Panel::postEvent(const QString &event, const QString &data) {
@ -803,6 +811,7 @@ rpl::lifetime &Panel::lifetime() {
} }
std::unique_ptr<Panel> Show(Args &&args) { std::unique_ptr<Panel> Show(Args &&args) {
const auto params = args.themeParams();
auto result = std::make_unique<Panel>( auto result = std::make_unique<Panel>(
args.userDataPath, args.userDataPath,
std::move(args.title), std::move(args.title),
@ -810,7 +819,7 @@ std::unique_ptr<Panel> Show(Args &&args) {
std::move(args.sendData), std::move(args.sendData),
std::move(args.close), std::move(args.close),
std::move(args.themeParams)); std::move(args.themeParams));
if (!result->showWebview(args.url, std::move(args.bottom))) { if (!result->showWebview(args.url, params, std::move(args.bottom))) {
const auto available = Webview::Availability(); const auto available = Webview::Availability();
if (available.error != Webview::Available::Error::None) { if (available.error != Webview::Available::Error::None) {
result->showWebviewError( result->showWebviewError(

View file

@ -17,6 +17,7 @@ class SeparatePanel;
namespace Webview { namespace Webview {
struct Available; struct Available;
struct ThemeParams;
} // namespace Webview } // namespace Webview
namespace Ui::BotWebView { namespace Ui::BotWebView {
@ -36,7 +37,7 @@ public:
Fn<bool(QString)> handleLocalUri, Fn<bool(QString)> handleLocalUri,
Fn<void(QByteArray)> sendData, Fn<void(QByteArray)> sendData,
Fn<void()> close, Fn<void()> close,
Fn<QByteArray()> themeParams); Fn<Webview::ThemeParams()> themeParams);
~Panel(); ~Panel();
void requestActivate(); void requestActivate();
@ -44,6 +45,7 @@ public:
bool showWebview( bool showWebview(
const QString &url, const QString &url,
const Webview::ThemeParams &params,
rpl::producer<QString> bottomText); rpl::producer<QString> bottomText);
void showBox(object_ptr<BoxContent> box); void showBox(object_ptr<BoxContent> box);
@ -53,7 +55,7 @@ public:
const QString &text, const QString &text,
const Webview::Available &information); const Webview::Available &information);
void updateThemeParams(const QByteArray &json); void updateThemeParams(const Webview::ThemeParams &params);
[[nodiscard]] rpl::lifetime &lifetime(); [[nodiscard]] rpl::lifetime &lifetime();
@ -101,7 +103,7 @@ struct Args {
Fn<bool(QString)> handleLocalUri; Fn<bool(QString)> handleLocalUri;
Fn<void(QByteArray)> sendData; Fn<void(QByteArray)> sendData;
Fn<void()> close; Fn<void()> close;
Fn<QByteArray()> themeParams; Fn<Webview::ThemeParams()> themeParams;
}; };
[[nodiscard]] std::unique_ptr<Panel> Show(Args &&args); [[nodiscard]] std::unique_ptr<Panel> Show(Args &&args);

View file

@ -32,6 +32,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/style/style_palette_colorizer.h" #include "ui/style/style_palette_colorizer.h"
#include "ui/ui_utility.h" #include "ui/ui_utility.h"
#include "ui/boxes/confirm_box.h" #include "ui/boxes/confirm_box.h"
#include "webview/webview_interface.h"
#include "boxes/background_box.h" #include "boxes/background_box.h"
#include "core/application.h" #include "core/application.h"
#include "styles/style_widgets.h" #include "styles/style_widgets.h"
@ -1491,7 +1492,7 @@ bool ReadPaletteValues(const QByteArray &content, Fn<bool(QLatin1String name, QL
return true; return true;
} }
[[nodiscard]] QByteArray WebViewParams() { [[nodiscard]] Webview::ThemeParams WebViewParams() {
const auto colors = std::vector<std::pair<QString, const style::color&>>{ const auto colors = std::vector<std::pair<QString, const style::color&>>{
{ "bg_color", st::windowBg }, { "bg_color", st::windowBg },
{ "text_color", st::windowFg }, { "text_color", st::windowFg },
@ -1514,7 +1515,14 @@ bool ReadPaletteValues(const QByteArray &content, Fn<bool(QLatin1String name, QL
}; };
object.insert(name, '#' + hex(r) + hex(g) + hex(b)); object.insert(name, '#' + hex(r) + hex(g) + hex(b));
} }
return QJsonDocument(object).toJson(QJsonDocument::Compact); return {
.scrollBg = st::scrollBg->c,
.scrollBgOver = st::scrollBgOver->c,
.scrollBarBg = st::scrollBarBg->c,
.scrollBarBgOver = st::scrollBarBgOver->c,
.json = QJsonDocument(object).toJson(QJsonDocument::Compact),
};
} }
} // namespace Theme } // namespace Theme

View file

@ -27,6 +27,10 @@ namespace Ui {
struct ChatThemeBackground; struct ChatThemeBackground;
} // namespace Ui } // namespace Ui
namespace Webview {
struct ThemeParams;
} // namespace Webview
namespace Window { namespace Window {
namespace Theme { namespace Theme {
@ -293,7 +297,7 @@ bool ReadPaletteValues(
const QByteArray &content, const QByteArray &content,
Fn<bool(QLatin1String name, QLatin1String value)> callback); Fn<bool(QLatin1String name, QLatin1String value)> callback);
[[nodiscard]] QByteArray WebViewParams(); [[nodiscard]] Webview::ThemeParams WebViewParams();
} // namespace Theme } // namespace Theme
} // namespace Window } // namespace Window

@ -1 +1 @@
Subproject commit 0ec43c57bb4b22807d060cbe50e6a11d3a8a2182 Subproject commit cc510d306b51ea83360fd0c0a41ec87fbf698535