Replace GTK integration with xsettings + XDP

This commit is contained in:
Ilya Fedin 2021-09-03 19:49:48 +04:00 committed by John Preston
parent 434a7c5293
commit 05d4d58f8b
10 changed files with 149 additions and 313 deletions

View File

@ -62,7 +62,6 @@ jobs:
- "DESKTOP_APP_DISABLE_DBUS_INTEGRATION"
- "DESKTOP_APP_DISABLE_X11_INTEGRATION"
- "DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION"
- "DESKTOP_APP_DISABLE_GTK_INTEGRATION"
env:
UPLOAD_ARTIFACT: "false"
@ -90,7 +89,7 @@ jobs:
if [ -n "${{ matrix.defines }}" ]; then
DEFINE="-D ${{ matrix.defines }}=ON"
if [ "${{ matrix.defines }}" == "DESKTOP_APP_DISABLE_DBUS_INTEGRATION" ]; then
DEFINE="$DEFINE -D DESKTOP_APP_DISABLE_GTK_INTEGRATION=ON -D DESKTOP_APP_DISABLE_WEBKITGTK=ON"
DEFINE="$DEFINE -D DESKTOP_APP_DISABLE_WEBKITGTK=ON"
fi
echo Define from matrix: $DEFINE
echo "ARTIFACT_NAME=Telegram_${{ matrix.defines }}" >> $GITHUB_ENV

View File

@ -860,9 +860,6 @@ PRIVATE
payments/payments_form.h
platform/linux/linux_desktop_environment.cpp
platform/linux/linux_desktop_environment.h
platform/linux/linux_gtk_integration_dummy.cpp
platform/linux/linux_gtk_integration.cpp
platform/linux/linux_gtk_integration.h
platform/linux/linux_wayland_integration_dummy.cpp
platform/linux/linux_wayland_integration.cpp
platform/linux/linux_wayland_integration.h
@ -1165,16 +1162,6 @@ else()
)
endif()
if (DESKTOP_APP_DISABLE_GTK_INTEGRATION)
remove_target_sources(Telegram ${src_loc}
platform/linux/linux_gtk_integration.cpp
)
else()
remove_target_sources(Telegram ${src_loc}
platform/linux/linux_gtk_integration_dummy.cpp
)
endif()
if (DESKTOP_APP_USE_PACKAGED)
remove_target_sources(Telegram ${src_loc}
platform/mac/mac_iconv_helper.c

View File

@ -9,7 +9,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/crash_reports.h"
#include "core/update_checker.h"
#include "base/platform/linux/base_linux_gtk_integration.h"
#ifndef DESKTOP_APP_DISABLE_WEBKITGTK
#include "webview/platform/linux/webview_linux_webkit2gtk.h"
@ -63,20 +62,14 @@ int Launcher::exec() {
Glib::init();
Gio::init();
for (auto i = begin(_arguments), e = end(_arguments); i != e; ++i) {
if (*i == "-basegtkintegration" && std::distance(i, e) > 2) {
BaseGtkIntegration::SetServiceName(QString::fromStdString(*(i + 2)));
if (const auto integration = BaseGtkIntegration::Instance()) {
return integration->exec(QString::fromStdString(*(i + 1)));
}
return 1;
#ifndef DESKTOP_APP_DISABLE_WEBKITGTK
} else if (*i == "-webviewhelper" && std::distance(i, e) > 2) {
for (auto i = begin(_arguments), e = end(_arguments); i != e; ++i) {
if (*i == "-webviewhelper" && std::distance(i, e) > 2) {
Webview::WebKit2Gtk::SetServiceName(*(i + 2));
return Webview::WebKit2Gtk::Exec(*(i + 1));
#endif // !DESKTOP_APP_DISABLE_WEBKITGTK
}
}
#endif // !DESKTOP_APP_DISABLE_WEBKITGTK
return Core::Launcher::exec();
}

View File

@ -1,100 +0,0 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "platform/linux/linux_gtk_integration.h"
#ifdef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
#error "GTK integration depends on D-Bus integration."
#endif // DESKTOP_APP_DISABLE_DBUS_INTEGRATION
#include "base/platform/linux/base_linux_gtk_integration.h"
#include "base/platform/linux/base_linux_dbus_utilities.h"
#include "base/platform/base_platform_info.h"
#include <QtCore/QProcess>
#include <glibmm.h>
namespace Platform {
namespace internal {
namespace {
constexpr auto kBaseService = "org.telegram.desktop.BaseGtkIntegration-%1"_cs;
using BaseGtkIntegration = base::Platform::GtkIntegration;
} // namespace
QString GtkIntegration::AllowedBackends() {
return Platform::IsWayland()
? qsl("wayland,x11")
: Platform::IsX11()
? qsl("x11,wayland")
: QString();
}
void GtkIntegration::Start(Type type) {
if (type != Type::Base) {
return;
}
const auto d = QFile::encodeName(QDir(cWorkingDir()).absolutePath());
char h[33] = { 0 };
hashMd5Hex(d.constData(), d.size(), h);
BaseGtkIntegration::SetServiceName(kBaseService.utf16().arg(h));
const auto dbusName = [] {
try {
static const auto connection = Gio::DBus::Connection::get_sync(
Gio::DBus::BusType::BUS_TYPE_SESSION);
return QString::fromStdString(connection->get_unique_name());
} catch (...) {
return QString();
}
}();
if (dbusName.isEmpty()) {
return;
}
QProcess::startDetached(cExeDir() + cExeName(), {
qsl("-basegtkintegration"),
dbusName,
kBaseService.utf16().arg(h),
});
}
void GtkIntegration::Autorestart(Type type) {
if (type != Type::Base) {
return;
}
try {
static const auto connection = Gio::DBus::Connection::get_sync(
Gio::DBus::BusType::BUS_TYPE_SESSION);
base::Platform::DBus::RegisterServiceWatcher(
connection,
Glib::ustring(BaseGtkIntegration::ServiceName().toStdString()),
[=](
const Glib::ustring &service,
const Glib::ustring &oldOwner,
const Glib::ustring &newOwner) {
if (newOwner.empty()) {
Start(type);
} else if (const auto integration = BaseGtkIntegration::Instance()) {
integration->load(AllowedBackends());
}
});
} catch (...) {
}
}
} // namespace internal
} // namespace Platform

View File

@ -1,27 +0,0 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
namespace Platform {
namespace internal {
class GtkIntegration {
public:
enum class Type {
Base,
};
static QString AllowedBackends();
static void Start(Type type);
static void Autorestart(Type type);
};
} // namespace internal
} // namespace Platform

View File

@ -1,24 +0,0 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "platform/linux/linux_gtk_integration.h"
namespace Platform {
namespace internal {
QString GtkIntegration::AllowedBackends() {
return {};
}
void GtkIntegration::Start(Type type) {
}
void GtkIntegration::Autorestart(Type type) {
}
} // namespace internal
} // namespace Platform

View File

@ -10,10 +10,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/openssl_help.h"
#include "base/platform/base_platform_info.h"
#include "base/platform/linux/base_linux_glibmm_helper.h"
#include "base/platform/linux/base_linux_gtk_integration.h"
#include "ui/platform/linux/ui_linux_wayland_integration.h"
#include "platform/linux/linux_desktop_environment.h"
#include "platform/linux/linux_gtk_integration.h"
#include "platform/linux/linux_wayland_integration.h"
#include "base/qt_adapters.h"
#include "lang/lang_keys.h"
@ -33,6 +31,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#ifndef DESKTOP_APP_DISABLE_X11_INTEGRATION
#include "base/platform/linux/base_linux_xcb_utilities.h"
#include "base/platform/linux/base_linux_xsettings.h"
#endif // !DESKTOP_APP_DISABLE_X11_INTEGRATION
#ifndef DESKTOP_APP_DISABLE_WEBKITGTK
@ -64,10 +63,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <iostream>
using namespace Platform;
using BaseGtkIntegration = base::Platform::GtkIntegration;
using UiWaylandIntegration = Ui::Platform::WaylandIntegration;
using Platform::internal::WaylandIntegration;
using Platform::internal::GtkIntegration;
namespace Platform {
namespace {
@ -340,125 +337,6 @@ bool GenerateDesktopFile(
}
}
void SetDarkMode() {
[[maybe_unused]] static const auto Inited = [] {
QObject::connect(
qGuiApp,
&QGuiApplication::paletteChanged,
SetDarkMode);
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
using XDPSettingWatcher = base::Platform::XDP::SettingWatcher;
static const XDPSettingWatcher KdeColorSchemeWatcher(
[=](
const Glib::ustring &group,
const Glib::ustring &key,
const Glib::VariantBase &value) {
if (group == "org.kde.kdeglobals.General"
&& key == "ColorScheme") {
SetDarkMode();
}
});
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
const auto integration = BaseGtkIntegration::Instance();
if (integration) {
integration->connectToSetting(
"gtk-theme-name",
SetDarkMode);
if (integration->checkVersion(3, 0, 0)) {
integration->connectToSetting(
"gtk-application-prefer-dark-theme",
SetDarkMode);
}
}
return true;
}();
std::optional<bool> result;
const auto setter = gsl::finally([&] {
crl::on_main([=] {
Core::App().settings().setSystemDarkMode(result);
});
});
const auto styleName = QApplication::style()->metaObject()->className();
if (styleName != qstr("QFusionStyle")
&& styleName != qstr("QWindowsStyle")) {
result = false;
const auto paletteBackgroundGray = qGray(
QPalette().color(QPalette::Window).rgb());
if (paletteBackgroundGray < kDarkColorLimit) {
result = true;
return;
}
}
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
try {
using namespace base::Platform::XDP;
const auto kdeBackgroundColorOptional = ReadSetting(
"org.kde.kdeglobals.Colors:Window",
"BackgroundNormal");
if (kdeBackgroundColorOptional.has_value()) {
const auto kdeBackgroundColorList = QString::fromStdString(
base::Platform::GlibVariantCast<Glib::ustring>(
*kdeBackgroundColorOptional)).split(',');
if (kdeBackgroundColorList.size() >= 3) {
result = false;
const auto kdeBackgroundGray = qGray(
kdeBackgroundColorList[0].toInt(),
kdeBackgroundColorList[1].toInt(),
kdeBackgroundColorList[2].toInt());
if (kdeBackgroundGray < kDarkColorLimit) {
result = true;
return;
}
}
}
} catch (...) {
}
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
const auto integration = BaseGtkIntegration::Instance();
if (integration) {
if (integration->checkVersion(3, 0, 0)) {
const auto preferDarkTheme = integration->getBoolSetting(
qsl("gtk-application-prefer-dark-theme"));
if (preferDarkTheme.has_value()) {
result = false;
if (*preferDarkTheme) {
result = true;
return;
}
}
}
const auto themeName = integration->getStringSetting(
qsl("gtk-theme-name"));
if (themeName.has_value()) {
result = false;
if (themeName->contains(qsl("-dark"), Qt::CaseInsensitive)) {
result = true;
return;
}
}
}
}
} // namespace
void SetApplicationIcon(const QIcon &icon) {
@ -519,7 +397,147 @@ QString GetIconName() {
}
std::optional<bool> IsDarkMode() {
return Core::App().settings().systemDarkMode();
[[maybe_unused]] static const auto Inited = [] {
static const auto Setter = [] {
crl::on_main([] {
Core::App().settings().setSystemDarkMode(IsDarkMode());
});
};
QObject::connect(
qGuiApp,
&QGuiApplication::paletteChanged,
Setter);
#ifndef DESKTOP_APP_DISABLE_X11_INTEGRATION
using base::Platform::XCB::XSettings;
if (const auto xSettings = XSettings::Instance()) {
xSettings->registerCallbackForProperty("Net/ThemeName", [](
xcb_connection_t *,
const QByteArray &,
const QVariant &,
void *) {
Setter();
}, nullptr);
}
#endif // !DESKTOP_APP_DISABLE_X11_INTEGRATION
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
using XDPSettingWatcher = base::Platform::XDP::SettingWatcher;
static const XDPSettingWatcher GtkThemeWatcher(
[=](
const Glib::ustring &group,
const Glib::ustring &key,
const Glib::VariantBase &value) {
if (group == "org.gnome.desktop.interface"
&& key == "gtk-theme") {
Setter();
}
});
static const XDPSettingWatcher KdeColorSchemeWatcher(
[=](
const Glib::ustring &group,
const Glib::ustring &key,
const Glib::VariantBase &value) {
if (group == "org.kde.kdeglobals.General"
&& key == "ColorScheme") {
Setter();
}
});
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
return true;
}();
std::optional<bool> result;
const auto styleName = QApplication::style()->metaObject()->className();
if (styleName != qstr("QFusionStyle")
&& styleName != qstr("QWindowsStyle")) {
result = false;
const auto paletteBackgroundGray = qGray(
QPalette().color(QPalette::Window).rgb());
if (paletteBackgroundGray < kDarkColorLimit) {
result = true;
return result;
}
}
#ifndef DESKTOP_APP_DISABLE_X11_INTEGRATION
using base::Platform::XCB::XSettings;
if (const auto xSettings = XSettings::Instance()) {
const auto gtkThemeX = xSettings->setting("Net/ThemeName");
if (gtkThemeX.isValid()) {
result = false;
if (gtkThemeX.toString().contains(
qsl("-dark"),
Qt::CaseInsensitive)) {
result = true;
return result;
}
}
}
#endif // !DESKTOP_APP_DISABLE_X11_INTEGRATION
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
try {
using namespace base::Platform::XDP;
const auto gtkThemePortal = ReadSetting(
"org.gnome.desktop.interface",
"gtk-theme");
if (gtkThemePortal.has_value()) {
const auto gtkThemePortalString = QString::fromStdString(
base::Platform::GlibVariantCast<Glib::ustring>(
*gtkThemePortal));
result = false;
if (gtkThemePortalString.contains(
qsl("-dark"),
Qt::CaseInsensitive)) {
result = true;
return result;
}
}
} catch (...) {
}
try {
using namespace base::Platform::XDP;
const auto kdeBackgroundColorOptional = ReadSetting(
"org.kde.kdeglobals.Colors:Window",
"BackgroundNormal");
if (kdeBackgroundColorOptional.has_value()) {
const auto kdeBackgroundColorList = QString::fromStdString(
base::Platform::GlibVariantCast<Glib::ustring>(
*kdeBackgroundColorOptional)).split(',');
if (kdeBackgroundColorList.size() >= 3) {
result = false;
const auto kdeBackgroundGray = qGray(
kdeBackgroundColorList[0].toInt(),
kdeBackgroundColorList[1].toInt(),
kdeBackgroundColorList[2].toInt());
if (kdeBackgroundGray < kDarkColorLimit) {
result = true;
return result;
}
}
}
} catch (...) {
}
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
return result;
}
bool AutostartSupported() {
@ -653,8 +671,6 @@ void start() {
Glib::set_prgname(cExeName().toStdString());
Glib::set_application_name(std::string(AppName));
GtkIntegration::Start(GtkIntegration::Type::Base);
#ifndef DESKTOP_APP_DISABLE_WEBKITGTK
const auto d = QFile::encodeName(QDir(cWorkingDir()).absolutePath());
char h[33] = { 0 };
@ -792,19 +808,11 @@ void start() {
LOG(("Icon theme: %1").arg(QIcon::themeName()));
LOG(("Fallback icon theme: %1").arg(QIcon::fallbackThemeName()));
GtkIntegration::Autorestart(GtkIntegration::Type::Base);
if (const auto integration = BaseGtkIntegration::Instance()) {
integration->load(GtkIntegration::AllowedBackends());
}
// wait for interface announce to know if native window frame is supported
if (const auto integration = UiWaylandIntegration::Instance()) {
integration->waitForInterfaceAnnounce();
}
crl::async(SetDarkMode);
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
FileDialog::XDP::Start();
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION

@ -1 +1 @@
Subproject commit e3591a6778ba63affb039eec7798740815ea12dc
Subproject commit 4ccf5d6c8c7f04a3b4b583f713ada2434f3d8243

@ -1 +1 @@
Subproject commit 29f339e26e11af5d56c5da1d6536bee0233d5194
Subproject commit af1429cb87d765be7e70308a318ee20d2478ae74

2
cmake

@ -1 +1 @@
Subproject commit 995b1e4cbd4ba0c02cb7432401bef029f480d69b
Subproject commit 95ee188c7b86b4448acbcfb01a42ac139cee6388