Compare commits

..

13 Commits

Author SHA1 Message Date
John Preston
cade53aa0a Version 2.8.4.
- Crash fixes in WebView on Windows.
2021-07-01 11:05:21 +03:00
GitHub Action
2fdcda7536 Update User-Agent for DNS to Chrome 91.0.4472.114. 2021-07-01 10:48:17 +03:00
Ilya Fedin
7e6439e4f8 Fix counting screen bottom point when restoring geometry 2021-06-30 00:27:39 +03:00
Ilya Fedin
f07ee7f590 Update lib_base and cmake_helpers 2021-06-29 17:35:39 +03:00
Ilya Fedin
02db4e01fa Get rid of qt5ct 2021-06-29 17:35:39 +03:00
Ilya Fedin
8d75078a42 Use Glib::MainLoop instead of QEventLoop in glib code 2021-06-29 15:10:08 +03:00
John Preston
0e25ef7524 Handle WinRT exceptions in WebView. 2021-06-29 14:08:50 +03:00
John Preston
8608d8aa4d Crash Fix: Destroy WebView before the container. 2021-06-29 11:07:47 +03:00
sammiee5311
c1a7332a5e Shorten if statement
Shorten if statement
2021-06-29 10:38:35 +03:00
Ilya Fedin
c3fb392906 Clean dbus-specific code in main_window_linux.h 2021-06-29 10:30:48 +03:00
Ilya Fedin
a59bfdb2f8 Fix handleNativeSurfaceChanged when dbus integration is disabled 2021-06-29 10:30:48 +03:00
Ilya Fedin
79f96480c2 Use QMenuBar instead of own global menu implementation on Linux 2021-06-29 10:30:48 +03:00
John Preston
60cbd96d91 Version 2.8.3.
- Fix crashes in OpenSSL on macOS.
2021-06-28 13:51:06 +03:00
27 changed files with 339 additions and 540 deletions

3
.gitmodules vendored
View File

@@ -76,9 +76,6 @@
[submodule "Telegram/ThirdParty/hime"]
path = Telegram/ThirdParty/hime
url = https://github.com/hime-ime/hime.git
[submodule "Telegram/ThirdParty/qt5ct"]
path = Telegram/ThirdParty/qt5ct
url = https://github.com/desktop-app/qt5ct.git
[submodule "Telegram/ThirdParty/fcitx5-qt"]
path = Telegram/ThirdParty/fcitx5-qt
url = https://github.com/fcitx/fcitx5-qt.git

View File

@@ -94,7 +94,6 @@ if (LINUX)
target_link_libraries(Telegram
PRIVATE
desktop-app::external_statusnotifieritem
desktop-app::external_dbusmenu_qt
)
endif()

View File

@@ -9,7 +9,7 @@
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
ProcessorArchitecture="ARCHITECTURE"
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
Version="2.8.2.0" />
Version="2.8.4.0" />
<Properties>
<DisplayName>Telegram Desktop</DisplayName>
<PublisherDisplayName>Telegram Messenger LLP</PublisherDisplayName>

View File

@@ -44,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,8,2,0
PRODUCTVERSION 2,8,2,0
FILEVERSION 2,8,4,0
PRODUCTVERSION 2,8,4,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -62,10 +62,10 @@ BEGIN
BEGIN
VALUE "CompanyName", "Telegram FZ-LLC"
VALUE "FileDescription", "Telegram Desktop"
VALUE "FileVersion", "2.8.2.0"
VALUE "FileVersion", "2.8.4.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2021"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "2.8.2.0"
VALUE "ProductVersion", "2.8.4.0"
END
END
BLOCK "VarFileInfo"

View File

@@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,8,2,0
PRODUCTVERSION 2,8,2,0
FILEVERSION 2,8,4,0
PRODUCTVERSION 2,8,4,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -53,10 +53,10 @@ BEGIN
BEGIN
VALUE "CompanyName", "Telegram FZ-LLC"
VALUE "FileDescription", "Telegram Desktop Updater"
VALUE "FileVersion", "2.8.2.0"
VALUE "FileVersion", "2.8.4.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2021"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "2.8.2.0"
VALUE "ProductVersion", "2.8.4.0"
END
END
BLOCK "VarFileInfo"

View File

@@ -22,7 +22,7 @@ constexpr auto AppId = "{53F49750-6209-4FBF-9CA8-7A333C87D1ED}"_cs;
constexpr auto AppNameOld = "Telegram Win (Unofficial)"_cs;
constexpr auto AppName = "Telegram Desktop"_cs;
constexpr auto AppFile = "Telegram"_cs;
constexpr auto AppVersion = 2008002;
constexpr auto AppVersionStr = "2.8.2";
constexpr auto AppVersion = 2008004;
constexpr auto AppVersionStr = "2.8.4";
constexpr auto AppBetaVersion = false;
constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION;

View File

@@ -65,7 +65,7 @@ QByteArray DnsUserAgent() {
static const auto kResult = QByteArray(
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/90.0.4430.85 Safari/537.36");
"Chrome/91.0.4472.114 Safari/537.36");
return kResult;
}

View File

@@ -43,6 +43,21 @@ struct Panel::Progress {
rpl::lifetime geometryLifetime;
};
struct Panel::WebviewWithLifetime {
WebviewWithLifetime(
QWidget *parent = nullptr,
Webview::WindowConfig config = Webview::WindowConfig());
Webview::Window window;
rpl::lifetime lifetime;
};
Panel::WebviewWithLifetime::WebviewWithLifetime(
QWidget *parent,
Webview::WindowConfig config)
: window(parent, std::move(config)) {
}
Panel::Progress::Progress(QWidget *parent, Fn<QRect()> rect)
: widget(parent)
, animation(
@@ -68,7 +83,7 @@ Panel::Panel(not_null<PanelDelegate*> delegate)
}
Panel::~Panel() {
// Destroy _widget before _webview.
_webview = nullptr;
_progress = nullptr;
_widget = nullptr;
}
@@ -451,7 +466,7 @@ bool Panel::showWebview(
}
showWebviewProgress();
_widget->destroyLayer();
_webview->navigate(url);
_webview->window.navigate(url);
_widget->setBackAllowed(allowBack);
if (bottomText) {
const auto &padding = st::paymentsPanelPadding;
@@ -490,14 +505,14 @@ bool Panel::createWebview() {
}, bottom->lifetime());
container->show();
_webview = std::make_unique<Webview::Window>(
_webview = std::make_unique<WebviewWithLifetime>(
container.get(),
Webview::WindowConfig{
.userDataPath = _delegate->panelWebviewDataPath(),
});
const auto raw = _webview.get();
const auto raw = &_webview->window;
QObject::connect(container.get(), &QObject::destroyed, [=] {
if (_webview.get() == raw) {
if (_webview && &_webview->window == raw) {
_webview = nullptr;
if (_webviewProgress) {
hideWebviewProgress();
@@ -517,7 +532,7 @@ bool Panel::createWebview() {
container->geometryValue(
) | rpl::start_with_next([=](QRect geometry) {
raw->widget()->setGeometry(geometry);
}, container->lifetime());
}, _webview->lifetime);
raw->setMessageHandler([=](const QJsonDocument &message) {
const auto save = _saveWebviewInformation

View File

@@ -17,7 +17,6 @@ class Checkbox;
} // namespace Ui
namespace Webview {
class Window;
struct Available;
} // namespace Webview
@@ -88,6 +87,7 @@ public:
private:
struct Progress;
struct WebviewWithLifetime;
bool createWebview();
void showWebviewProgress();
@@ -103,7 +103,7 @@ private:
const not_null<PanelDelegate*> _delegate;
std::unique_ptr<SeparatePanel> _widget;
std::unique_ptr<Webview::Window> _webview;
std::unique_ptr<WebviewWithLifetime> _webview;
std::unique_ptr<RpWidget> _webviewBottom;
std::unique_ptr<Progress> _progress;
QPointer<Checkbox> _saveWebviewInformation;

View File

@@ -14,7 +14,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <surface.h>
#include <xdgforeign.h>
#include <plasmashell.h>
#include <appmenu.h>
using namespace KWayland::Client;
@@ -37,10 +36,6 @@ public:
return _plasmaShell.get();
}
[[nodiscard]] AppMenuManager *appMenuManager() {
return _appMenuManager.get();
}
[[nodiscard]] QEventLoop &interfacesLoop() {
return _interfacesLoop;
}
@@ -56,7 +51,6 @@ private:
Registry _applicationRegistry;
std::unique_ptr<XdgExporter> _xdgExporter;
std::unique_ptr<PlasmaShell> _plasmaShell;
std::unique_ptr<AppMenuManager> _appMenuManager;
QEventLoop _interfacesLoop;
bool _interfacesAnnounced = false;
};
@@ -123,21 +117,6 @@ WaylandIntegration::Private::Private()
&PlasmaShell::destroy);
});
connect(
&_applicationRegistry,
&Registry::appMenuAnnounced,
[=](uint name, uint version) {
_appMenuManager = std::unique_ptr<AppMenuManager>{
_applicationRegistry.createAppMenuManager(name, version),
};
connect(
_applicationConnection,
&ConnectionThread::connectionDied,
_appMenuManager.get(),
&AppMenuManager::destroy);
});
_connection.initConnection();
}
@@ -208,27 +187,5 @@ void WaylandIntegration::skipTaskbar(QWindow *window, bool skip) {
plasmaSurface->setSkipTaskbar(skip);
}
void WaylandIntegration::registerAppMenu(
QWindow *window,
const QString &serviceName,
const QString &objectPath) {
const auto manager = _private->appMenuManager();
if (!manager) {
return;
}
const auto surface = Surface::fromWindow(window);
if (!surface) {
return;
}
const auto appMenu = manager->create(surface, surface);
if (!appMenu) {
return;
}
appMenu->setAddress(serviceName, objectPath);
}
} // namespace internal
} // namespace Platform

View File

@@ -18,10 +18,6 @@ public:
[[nodiscard]] QString nativeHandle(QWindow *window);
[[nodiscard]] bool skipTaskbarSupported();
void skipTaskbar(QWindow *window, bool skip);
void registerAppMenu(
QWindow *window,
const QString &serviceName,
const QString &objectPath);
private:
WaylandIntegration();

View File

@@ -44,11 +44,5 @@ bool WaylandIntegration::skipTaskbarSupported() {
void WaylandIntegration::skipTaskbar(QWindow *window, bool skip) {
}
void WaylandIntegration::registerAppMenu(
QWindow *window,
const QString &serviceName,
const QString &objectPath) {
}
} // namespace internal
} // namespace Platform

View File

@@ -578,20 +578,23 @@ int XDPFileDialog::exec() {
// HACK we have to avoid returning until we emit
// that the dialog was accepted or rejected
QEventLoop loop;
const auto context = Glib::MainContext::create();
const auto loop = Glib::MainLoop::create(context);
g_main_context_push_thread_default(context->gobj());
rpl::lifetime lifetime;
accepted(
) | rpl::start_with_next([&] {
loop.quit();
loop->quit();
}, lifetime);
rejected(
) | rpl::start_with_next([&] {
loop.quit();
loop->quit();
}, lifetime);
loop.exec();
loop->run();
g_main_context_pop_thread_default(context->gobj());
if (guard.isNull()) {
return QDialog::Rejected;

View File

@@ -33,19 +33,9 @@ constexpr auto kXDGDesktopPortalObjectPath = "/org/freedesktop/portal/desktop"_c
constexpr auto kXDGDesktopPortalOpenURIInterface = "org.freedesktop.portal.OpenURI"_cs;
constexpr auto kPropertiesInterface = "org.freedesktop.DBus.Properties"_cs;
class XDPOpenWithDialog : public QWindow {
public:
XDPOpenWithDialog(const QString &filepath)
: _filepath(filepath.toStdString()) {
}
} // namespace
bool exec();
private:
Glib::ustring _filepath;
};
bool XDPOpenWithDialog::exec() {
bool ShowXDPOpenWithDialog(const QString &filepath) {
try {
const auto connection = Gio::DBus::Connection::get_sync(
Gio::DBus::BusType::BUS_TYPE_SESSION);
@@ -69,8 +59,10 @@ bool XDPOpenWithDialog::exec() {
return false;
}
const auto filepathUtf8 = filepath.toUtf8();
const auto fd = open(
_filepath.c_str(),
filepathUtf8.constData(),
O_RDONLY);
if (fd == -1) {
@@ -113,7 +105,9 @@ bool XDPOpenWithDialog::exec() {
+ '/'
+ handleToken;
QEventLoop loop;
const auto context = Glib::MainContext::create();
const auto loop = Glib::MainLoop::create(context);
g_main_context_push_thread_default(context->gobj());
const auto signalId = connection->signal_subscribe(
[&](
@@ -123,7 +117,7 @@ bool XDPOpenWithDialog::exec() {
const Glib::ustring &interface_name,
const Glib::ustring &signal_name,
const Glib::VariantContainerBase &parameters) {
loop.quit();
loop->quit();
},
std::string(kXDGDesktopPortalService),
"org.freedesktop.portal.Request",
@@ -166,9 +160,11 @@ bool XDPOpenWithDialog::exec() {
std::string(kXDGDesktopPortalService));
if (signalId != 0) {
QGuiApplicationPrivate::showModalWindow(this);
loop.exec();
QGuiApplicationPrivate::hideModalWindow(this);
QWindow window;
QGuiApplicationPrivate::showModalWindow(&window);
loop->run();
g_main_context_pop_thread_default(context->gobj());
QGuiApplicationPrivate::hideModalWindow(&window);
}
return true;
@@ -178,12 +174,6 @@ bool XDPOpenWithDialog::exec() {
return false;
}
} // namespace
bool ShowXDPOpenWithDialog(const QString &filepath) {
return XDPOpenWithDialog(filepath).exec();
}
} // namespace internal
} // namespace File
} // namespace Platform

View File

@@ -43,15 +43,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <QtCore/QSize>
#include <QtCore/QTemporaryFile>
#include <QtGui/QWindow>
#include <QtWidgets/QMenuBar>
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
#include <QtDBus/QDBusConnection>
#include <QtDBus/QDBusMessage>
#include <QtDBus/QDBusObjectPath>
#include <QtDBus/QDBusMetaType>
#include <statusnotifieritem.h>
#include <dbusmenuexporter.h>
#include <glibmm.h>
#include <giomm.h>
@@ -74,12 +71,6 @@ constexpr auto kSNIWatcherService = "org.kde.StatusNotifierWatcher"_cs;
constexpr auto kSNIWatcherObjectPath = "/StatusNotifierWatcher"_cs;
constexpr auto kSNIWatcherInterface = kSNIWatcherService;
constexpr auto kAppMenuService = "com.canonical.AppMenu.Registrar"_cs;
constexpr auto kAppMenuObjectPath = "/com/canonical/AppMenu/Registrar"_cs;
constexpr auto kAppMenuInterface = kAppMenuService;
constexpr auto kMainMenuObjectPath = "/MenuBar"_cs;
bool TrayIconMuted = true;
int32 TrayIconCount = 0;
base::flat_map<int, QImage> TrayIconImageBack;
@@ -364,6 +355,31 @@ QIcon TrayIconGen(int counter, bool muted) {
return result;
}
void SendKeySequence(
Qt::Key key,
Qt::KeyboardModifiers modifiers = Qt::NoModifier) {
const auto focused = QApplication::focusWidget();
if (qobject_cast<QLineEdit*>(focused)
|| qobject_cast<QTextEdit*>(focused)
|| qobject_cast<HistoryInner*>(focused)) {
QApplication::postEvent(
focused,
new QKeyEvent(QEvent::KeyPress, key, modifiers));
QApplication::postEvent(
focused,
new QKeyEvent(QEvent::KeyRelease, key, modifiers));
}
}
void ForceDisabled(QAction *action, bool disabled) {
if (action->isEnabled()) {
if (disabled) action->setDisabled(true);
} else if (!disabled) {
action->setDisabled(false);
}
}
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
bool IsIndicatorApplication() {
// Hack for indicator-application,
@@ -520,104 +536,161 @@ uint djbStringHash(const std::string &string) {
}
return hash;
}
bool IsAppMenuSupported() {
try {
const auto connection = Gio::DBus::Connection::get_sync(
Gio::DBus::BusType::BUS_TYPE_SESSION);
return base::Platform::DBus::NameHasOwner(
connection,
std::string(kAppMenuService));
} catch (...) {
}
return false;
}
// This call must be made from the same bus connection as DBusMenuExporter
// So it must use QDBusConnection
void RegisterAppMenu(QWindow *window, const QString &menuPath) {
if (const auto integration = WaylandIntegration::Instance()) {
integration->registerAppMenu(
window,
QDBusConnection::sessionBus().baseService(),
menuPath);
return;
}
auto message = QDBusMessage::createMethodCall(
kAppMenuService.utf16(),
kAppMenuObjectPath.utf16(),
kAppMenuInterface.utf16(),
qsl("RegisterWindow"));
message.setArguments({
window->winId(),
QVariant::fromValue(QDBusObjectPath(menuPath))
});
QDBusConnection::sessionBus().send(message);
}
// This call must be made from the same bus connection as DBusMenuExporter
// So it must use QDBusConnection
void UnregisterAppMenu(QWindow *window) {
if (const auto integration = WaylandIntegration::Instance()) {
return;
}
auto message = QDBusMessage::createMethodCall(
kAppMenuService.utf16(),
kAppMenuObjectPath.utf16(),
kAppMenuInterface.utf16(),
qsl("UnregisterWindow"));
message.setArguments({
window->winId()
});
QDBusConnection::sessionBus().send(message);
}
void SendKeySequence(
Qt::Key key,
Qt::KeyboardModifiers modifiers = Qt::NoModifier) {
const auto focused = QApplication::focusWidget();
if (qobject_cast<QLineEdit*>(focused)
|| qobject_cast<QTextEdit*>(focused)
|| qobject_cast<HistoryInner*>(focused)) {
QApplication::postEvent(
focused,
new QKeyEvent(QEvent::KeyPress, key, modifiers));
QApplication::postEvent(
focused,
new QKeyEvent(QEvent::KeyRelease, key, modifiers));
}
}
void ForceDisabled(QAction *action, bool disabled) {
if (action->isEnabled()) {
if (disabled) action->setDisabled(true);
} else if (!disabled) {
action->setDisabled(false);
}
}
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
} // namespace
class MainWindow::Private {
public:
explicit Private(not_null<MainWindow*> window)
: _public(window) {
}
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
Glib::RefPtr<Gio::DBus::Connection> dbusConnection;
StatusNotifierItem *sniTrayIcon = nullptr;
uint sniRegisteredSignalId = 0;
uint sniWatcherId = 0;
std::unique_ptr<QTemporaryFile> trayIconFile;
void setSNITrayIcon(int counter, bool muted);
void attachToSNITrayIcon();
void handleSNIHostRegistered();
void handleSNIOwnerChanged(
const QString &service,
const QString &oldOwner,
const QString &newOwner);
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
private:
not_null<MainWindow*> _public;
};
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
void MainWindow::Private::setSNITrayIcon(int counter, bool muted) {
const auto iconName = GetTrayIconName(counter, muted);
const auto panelIconName = GetPanelIconName(counter, muted);
if (iconName == panelIconName) {
if (sniTrayIcon->iconName() == iconName) {
return;
}
sniTrayIcon->setIconByName(iconName);
sniTrayIcon->setToolTipIconByName(iconName);
} else if (IsIndicatorApplication()) {
if (!IsIconRegenerationNeeded(counter, muted)
&& trayIconFile
&& sniTrayIcon->iconName() == trayIconFile->fileName()) {
return;
}
const auto icon = TrayIconGen(counter, muted);
trayIconFile = TrayIconFile(icon, _public);
if (trayIconFile) {
// indicator-application doesn't support tooltips
sniTrayIcon->setIconByName(trayIconFile->fileName());
}
} else {
if (!IsIconRegenerationNeeded(counter, muted)
&& !sniTrayIcon->iconPixmap().isEmpty()
&& sniTrayIcon->iconName().isEmpty()) {
return;
}
const auto icon = TrayIconGen(counter, muted);
sniTrayIcon->setIconByPixmap(icon);
sniTrayIcon->setToolTipIconByPixmap(icon);
}
}
void MainWindow::Private::attachToSNITrayIcon() {
sniTrayIcon->setToolTipTitle(AppName.utf16());
connect(sniTrayIcon,
&StatusNotifierItem::activateRequested,
[=](const QPoint &) {
Core::Sandbox::Instance().customEnterFromEventLoop([&] {
_public->handleTrayIconActication(QSystemTrayIcon::Trigger);
});
});
connect(sniTrayIcon,
&StatusNotifierItem::secondaryActivateRequested,
[=](const QPoint &) {
Core::Sandbox::Instance().customEnterFromEventLoop([&] {
_public->handleTrayIconActication(QSystemTrayIcon::MiddleClick);
});
});
}
void MainWindow::Private::handleSNIHostRegistered() {
if (_public->_sniAvailable) {
return;
}
_public->_sniAvailable = true;
if (Core::App().settings().workMode() == WorkMode::WindowOnly) {
return;
}
LOG(("Switching to SNI tray icon..."));
if (_public->trayIcon) {
_public->trayIcon->setContextMenu(nullptr);
_public->trayIcon->deleteLater();
}
_public->trayIcon = nullptr;
_public->psSetupTrayIcon();
SkipTaskbar(
_public->windowHandle(),
Core::App().settings().workMode() == WorkMode::TrayOnly);
}
void MainWindow::Private::handleSNIOwnerChanged(
const QString &service,
const QString &oldOwner,
const QString &newOwner) {
_public->_sniAvailable = IsSNIAvailable();
if (Core::App().settings().workMode() == WorkMode::WindowOnly) {
return;
}
if (oldOwner.isEmpty() && !newOwner.isEmpty() && _public->_sniAvailable) {
LOG(("Switching to SNI tray icon..."));
} else if (!oldOwner.isEmpty() && newOwner.isEmpty()) {
LOG(("Switching to Qt tray icon..."));
} else {
return;
}
if (_public->trayIcon) {
_public->trayIcon->setContextMenu(0);
_public->trayIcon->deleteLater();
}
_public->trayIcon = nullptr;
if (_public->trayAvailable()) {
_public->psSetupTrayIcon();
} else {
LOG(("System tray is not available."));
}
SkipTaskbar(
_public->windowHandle(),
(Core::App().settings().workMode() == WorkMode::TrayOnly)
&& _public->trayAvailable());
}
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
MainWindow::MainWindow(not_null<Window::Controller*> controller)
: Window::MainWindow(controller)
, _private(std::make_unique<Private>()) {
, _private(std::make_unique<Private>(this)) {
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
qDBusRegisterMetaType<ToolTip>();
qDBusRegisterMetaType<IconPixmap>();
@@ -626,63 +699,6 @@ MainWindow::MainWindow(not_null<Window::Controller*> controller)
}
void MainWindow::initHook() {
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
_sniAvailable = IsSNIAvailable();
_appMenuSupported = IsAppMenuSupported();
try {
_private->dbusConnection = Gio::DBus::Connection::get_sync(
Gio::DBus::BusType::BUS_TYPE_SESSION);
_sniRegisteredSignalId = _private->dbusConnection->signal_subscribe(
[](
const Glib::RefPtr<Gio::DBus::Connection> &connection,
const Glib::ustring &sender_name,
const Glib::ustring &object_path,
const Glib::ustring &interface_name,
const Glib::ustring &signal_name,
const Glib::VariantContainerBase &parameters) {
if (signal_name == "StatusNotifierHostRegistered") {
crl::on_main([] {
if (const auto window = App::wnd()) {
window->handleSNIHostRegistered();
}
});
}
},
std::string(kSNIWatcherService),
std::string(kSNIWatcherInterface),
"StatusNotifierHostRegistered",
std::string(kSNIWatcherObjectPath));
_sniWatcherId = base::Platform::DBus::RegisterServiceWatcher(
_private->dbusConnection,
std::string(kSNIWatcherService),
[=](
const Glib::ustring &service,
const Glib::ustring &oldOwner,
const Glib::ustring &newOwner) {
handleSNIOwnerChanged(
QString::fromStdString(service),
QString::fromStdString(oldOwner),
QString::fromStdString(newOwner));
});
_appMenuWatcherId = base::Platform::DBus::RegisterServiceWatcher(
_private->dbusConnection,
std::string(kAppMenuService),
[=](
const Glib::ustring &service,
const Glib::ustring &oldOwner,
const Glib::ustring &newOwner) {
handleAppMenuOwnerChanged(
QString::fromStdString(service),
QString::fromStdString(oldOwner),
QString::fromStdString(newOwner));
});
} catch (...) {
}
base::install_event_filter(windowHandle(), [=](not_null<QEvent*> e) {
if (e->type() == QEvent::Expose) {
auto ee = static_cast<QExposeEvent*>(e.get());
@@ -704,10 +720,47 @@ void MainWindow::initHook() {
return base::EventFilterResult::Continue;
});
if (_appMenuSupported) {
LOG(("Using D-Bus global menu."));
} else {
LOG(("Not using D-Bus global menu."));
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
_sniAvailable = IsSNIAvailable();
try {
_private->dbusConnection = Gio::DBus::Connection::get_sync(
Gio::DBus::BusType::BUS_TYPE_SESSION);
_private->sniRegisteredSignalId = _private->dbusConnection->signal_subscribe(
[](
const Glib::RefPtr<Gio::DBus::Connection> &connection,
const Glib::ustring &sender_name,
const Glib::ustring &object_path,
const Glib::ustring &interface_name,
const Glib::ustring &signal_name,
const Glib::VariantContainerBase &parameters) {
if (signal_name == "StatusNotifierHostRegistered") {
crl::on_main([] {
if (const auto window = App::wnd()) {
window->_private->handleSNIHostRegistered();
}
});
}
},
std::string(kSNIWatcherService),
std::string(kSNIWatcherInterface),
"StatusNotifierHostRegistered",
std::string(kSNIWatcherObjectPath));
_private->sniWatcherId = base::Platform::DBus::RegisterServiceWatcher(
_private->dbusConnection,
std::string(kSNIWatcherService),
[=](
const Glib::ustring &service,
const Glib::ustring &oldOwner,
const Glib::ustring &newOwner) {
_private->handleSNIOwnerChanged(
QString::fromStdString(service),
QString::fromStdString(oldOwner),
QString::fromStdString(newOwner));
});
} catch (...) {
}
if (UseUnityCounter()) {
@@ -726,7 +779,7 @@ void MainWindow::initHook() {
bool MainWindow::hasTrayIcon() const {
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
return trayIcon || (_sniAvailable && _sniTrayIcon);
return trayIcon || (_sniAvailable && _private->sniTrayIcon);
#else
return trayIcon;
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
@@ -744,147 +797,6 @@ void MainWindow::psShowTrayMenu() {
void MainWindow::psTrayMenuUpdated() {
}
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
void MainWindow::setSNITrayIcon(int counter, bool muted) {
const auto iconName = GetTrayIconName(counter, muted);
const auto panelIconName = GetPanelIconName(counter, muted);
if (iconName == panelIconName) {
if (_sniTrayIcon->iconName() == iconName) {
return;
}
_sniTrayIcon->setIconByName(iconName);
_sniTrayIcon->setToolTipIconByName(iconName);
} else if (IsIndicatorApplication()) {
if (!IsIconRegenerationNeeded(counter, muted)
&& _trayIconFile
&& _sniTrayIcon->iconName() == _trayIconFile->fileName()) {
return;
}
const auto icon = TrayIconGen(counter, muted);
_trayIconFile = TrayIconFile(icon, this);
if (_trayIconFile) {
// indicator-application doesn't support tooltips
_sniTrayIcon->setIconByName(_trayIconFile->fileName());
}
} else {
if (!IsIconRegenerationNeeded(counter, muted)
&& !_sniTrayIcon->iconPixmap().isEmpty()
&& _sniTrayIcon->iconName().isEmpty()) {
return;
}
const auto icon = TrayIconGen(counter, muted);
_sniTrayIcon->setIconByPixmap(icon);
_sniTrayIcon->setToolTipIconByPixmap(icon);
}
}
void MainWindow::attachToSNITrayIcon() {
_sniTrayIcon->setToolTipTitle(AppName.utf16());
connect(_sniTrayIcon,
&StatusNotifierItem::activateRequested,
this,
[=](const QPoint &) {
Core::Sandbox::Instance().customEnterFromEventLoop([&] {
handleTrayIconActication(QSystemTrayIcon::Trigger);
});
});
connect(_sniTrayIcon,
&StatusNotifierItem::secondaryActivateRequested,
this,
[=](const QPoint &) {
Core::Sandbox::Instance().customEnterFromEventLoop([&] {
handleTrayIconActication(QSystemTrayIcon::MiddleClick);
});
});
}
void MainWindow::handleSNIHostRegistered() {
if (_sniAvailable) {
return;
}
_sniAvailable = true;
if (Core::App().settings().workMode() == WorkMode::WindowOnly) {
return;
}
LOG(("Switching to SNI tray icon..."));
if (trayIcon) {
trayIcon->setContextMenu(nullptr);
trayIcon->deleteLater();
}
trayIcon = nullptr;
psSetupTrayIcon();
SkipTaskbar(
windowHandle(),
Core::App().settings().workMode() == WorkMode::TrayOnly);
}
void MainWindow::handleSNIOwnerChanged(
const QString &service,
const QString &oldOwner,
const QString &newOwner) {
_sniAvailable = IsSNIAvailable();
if (Core::App().settings().workMode() == WorkMode::WindowOnly) {
return;
}
if (oldOwner.isEmpty() && !newOwner.isEmpty() && _sniAvailable) {
LOG(("Switching to SNI tray icon..."));
} else if (!oldOwner.isEmpty() && newOwner.isEmpty()) {
LOG(("Switching to Qt tray icon..."));
} else {
return;
}
if (trayIcon) {
trayIcon->setContextMenu(0);
trayIcon->deleteLater();
}
trayIcon = nullptr;
if (trayAvailable()) {
psSetupTrayIcon();
} else {
LOG(("System tray is not available."));
}
SkipTaskbar(
windowHandle(),
(Core::App().settings().workMode() == WorkMode::TrayOnly)
&& trayAvailable());
}
void MainWindow::handleAppMenuOwnerChanged(
const QString &service,
const QString &oldOwner,
const QString &newOwner) {
if (oldOwner.isEmpty() && !newOwner.isEmpty()) {
_appMenuSupported = true;
LOG(("Using D-Bus global menu."));
} else if (!oldOwner.isEmpty() && newOwner.isEmpty()) {
_appMenuSupported = false;
LOG(("Not using D-Bus global menu."));
}
if (_appMenuSupported && _mainMenuExporter) {
RegisterAppMenu(windowHandle(), kMainMenuObjectPath.utf16());
} else {
UnregisterAppMenu(windowHandle());
}
}
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
void MainWindow::psSetupTrayIcon() {
const auto counter = Core::App().unreadBadge();
const auto muted = Core::App().unreadBadgeMuted();
@@ -892,16 +804,16 @@ void MainWindow::psSetupTrayIcon() {
if (_sniAvailable) {
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
LOG(("Using SNI tray icon."));
if (!_sniTrayIcon) {
_sniTrayIcon = new StatusNotifierItem(
if (!_private->sniTrayIcon) {
_private->sniTrayIcon = new StatusNotifierItem(
QCoreApplication::applicationName(),
this);
_sniTrayIcon->setTitle(AppName.utf16());
_sniTrayIcon->setContextMenu(trayIconMenu);
setSNITrayIcon(counter, muted);
_private->sniTrayIcon->setTitle(AppName.utf16());
_private->sniTrayIcon->setContextMenu(trayIconMenu);
_private->setSNITrayIcon(counter, muted);
attachToSNITrayIcon();
_private->attachToSNITrayIcon();
}
updateIconCounters();
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
@@ -924,11 +836,11 @@ void MainWindow::workmodeUpdated(Core::Settings::WorkMode mode) {
return;
} else if (mode == WorkMode::WindowOnly) {
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
if (_sniTrayIcon) {
_sniTrayIcon->setContextMenu(0);
_sniTrayIcon->deleteLater();
if (_private->sniTrayIcon) {
_private->sniTrayIcon->setContextMenu(0);
_private->sniTrayIcon->deleteLater();
}
_sniTrayIcon = nullptr;
_private->sniTrayIcon = nullptr;
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
if (trayIcon) {
@@ -992,8 +904,8 @@ void MainWindow::updateIconCounters() {
}
}
if (_sniTrayIcon) {
setSNITrayIcon(counter, muted);
if (_private->sniTrayIcon) {
_private->setSNITrayIcon(counter, muted);
}
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
@@ -1007,16 +919,6 @@ void MainWindow::initTrayMenuHook() {
_trayIconMenuXEmbed->deleteOnHide(false);
}
#ifdef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
void MainWindow::createGlobalMenu() {
}
void MainWindow::updateGlobalMenuHook() {
}
#else // DESKTOP_APP_DISABLE_DBUS_INTEGRATION
void MainWindow::createGlobalMenu() {
const auto ensureWindowShown = [=] {
if (isHidden()) {
@@ -1024,7 +926,8 @@ void MainWindow::createGlobalMenu() {
}
};
psMainMenu = new QMenu(this);
psMainMenu = new QMenuBar(this);
psMainMenu->hide();
auto file = psMainMenu->addMenu(tr::lng_mac_menu_file(tr::now));
@@ -1201,14 +1104,6 @@ void MainWindow::createGlobalMenu() {
about->setMenuRole(QAction::AboutQtRole);
_mainMenuExporter = new DBusMenuExporter(
kMainMenuObjectPath.utf16(),
psMainMenu);
if (_appMenuSupported) {
RegisterAppMenu(windowHandle(), kMainMenuObjectPath.utf16());
}
updateGlobalMenu();
}
@@ -1327,8 +1222,6 @@ void MainWindow::updateGlobalMenuHook() {
ForceDisabled(psClearFormat, !markdownEnabled);
}
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
void MainWindow::handleNativeSurfaceChanged(bool exist) {
if (exist) {
SkipTaskbar(
@@ -1336,45 +1229,21 @@ void MainWindow::handleNativeSurfaceChanged(bool exist) {
(Core::App().settings().workMode() == WorkMode::TrayOnly)
&& trayAvailable());
}
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
if (_appMenuSupported && _mainMenuExporter) {
if (exist) {
RegisterAppMenu(windowHandle(), kMainMenuObjectPath.utf16());
} else {
UnregisterAppMenu(windowHandle());
}
}
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
}
MainWindow::~MainWindow() {
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
if (_private->dbusConnection) {
if (_sniRegisteredSignalId != 0) {
if (_private->sniRegisteredSignalId != 0) {
_private->dbusConnection->signal_unsubscribe(
_sniRegisteredSignalId);
_private->sniRegisteredSignalId);
}
if (_sniWatcherId != 0) {
if (_private->sniWatcherId != 0) {
_private->dbusConnection->signal_unsubscribe(
_sniWatcherId);
}
if (_appMenuWatcherId != 0) {
_private->dbusConnection->signal_unsubscribe(
_appMenuWatcherId);
_private->sniWatcherId);
}
}
delete _sniTrayIcon;
if (_appMenuSupported) {
UnregisterAppMenu(windowHandle());
}
delete _mainMenuExporter;
delete psMainMenu;
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
}

View File

@@ -10,16 +10,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "platform/platform_main_window.h"
#include "base/unique_qptr.h"
class QMenuBar;
namespace Ui {
class PopupMenu;
} // namespace Ui
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
class QTemporaryFile;
class DBusMenuExporter;
class StatusNotifierItem;
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
namespace Platform {
class MainWindow : public Window::MainWindow {
@@ -70,24 +66,13 @@ protected:
private:
class Private;
friend class Private;
const std::unique_ptr<Private> _private;
bool _sniAvailable = false;
base::unique_qptr<Ui::PopupMenu> _trayIconMenuXEmbed;
void updateIconCounters();
void handleNativeSurfaceChanged(bool exist);
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
StatusNotifierItem *_sniTrayIcon = nullptr;
uint _sniRegisteredSignalId = 0;
uint _sniWatcherId = 0;
uint _appMenuWatcherId = 0;
std::unique_ptr<QTemporaryFile> _trayIconFile;
bool _appMenuSupported = false;
DBusMenuExporter *_mainMenuExporter = nullptr;
QMenu *psMainMenu = nullptr;
QMenuBar *psMainMenu = nullptr;
QAction *psLogout = nullptr;
QAction *psUndo = nullptr;
QAction *psRedo = nullptr;
@@ -108,19 +93,8 @@ private:
QAction *psMonospace = nullptr;
QAction *psClearFormat = nullptr;
void setSNITrayIcon(int counter, bool muted);
void attachToSNITrayIcon();
void handleSNIHostRegistered();
void handleSNIOwnerChanged(
const QString &service,
const QString &oldOwner,
const QString &newOwner);
void handleAppMenuOwnerChanged(
const QString &service,
const QString &oldOwner,
const QString &newOwner);
void updateIconCounters();
void handleNativeSurfaceChanged(bool exist);
void psLinuxUndo();
void psLinuxRedo();
@@ -136,7 +110,6 @@ private:
void psLinuxStrikeOut();
void psLinuxMonospace();
void psLinuxClearFormat();
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
};

View File

@@ -85,12 +85,7 @@ constexpr auto kSnapcraftSettingsInterface = kSnapcraftSettingsService;
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
std::unique_ptr<internal::NotificationServiceWatcher> NSWInstance;
class PortalAutostart : public QWindow {
public:
PortalAutostart(bool start, bool silent = false);
};
PortalAutostart::PortalAutostart(bool start, bool silent) {
void PortalAutostart(bool start, bool silent) {
if (cExeName().isEmpty()) {
return;
}
@@ -149,7 +144,9 @@ PortalAutostart::PortalAutostart(bool start, bool silent) {
+ '/'
+ handleToken;
QEventLoop loop;
const auto context = Glib::MainContext::create();
const auto loop = Glib::MainLoop::create(context);
g_main_context_push_thread_default(context->gobj());
const auto signalId = connection->signal_subscribe(
[&](
@@ -175,7 +172,7 @@ PortalAutostart::PortalAutostart(bool start, bool silent) {
}
}
loop.quit();
loop->quit();
},
std::string(kXDGDesktopPortalService),
"org.freedesktop.portal.Request",
@@ -199,9 +196,11 @@ PortalAutostart::PortalAutostart(bool start, bool silent) {
std::string(kXDGDesktopPortalService));
if (signalId != 0) {
QGuiApplicationPrivate::showModalWindow(this);
loop.exec();
QGuiApplicationPrivate::hideModalWindow(this);
QWindow window;
QGuiApplicationPrivate::showModalWindow(&window);
loop->run();
g_main_context_pop_thread_default(context->gobj());
QGuiApplicationPrivate::hideModalWindow(&window);
}
} catch (const Glib::Error &e) {
if (!silent) {
@@ -211,12 +210,7 @@ PortalAutostart::PortalAutostart(bool start, bool silent) {
}
}
class SnapDefaultHandler : public QWindow {
public:
SnapDefaultHandler(const QString &protocol);
};
SnapDefaultHandler::SnapDefaultHandler(const QString &protocol) {
void SnapDefaultHandler(const QString &protocol) {
try {
const auto connection = Gio::DBus::Connection::get_sync(
Gio::DBus::BusType::BUS_TYPE_SESSION);
@@ -241,7 +235,9 @@ SnapDefaultHandler::SnapDefaultHandler(const QString &protocol) {
return;
}
QEventLoop loop;
const auto context = Glib::MainContext::create();
const auto loop = Glib::MainLoop::create(context);
g_main_context_push_thread_default(context->gobj());
connection->call(
std::string(kSnapcraftSettingsObjectPath),
@@ -260,13 +256,15 @@ SnapDefaultHandler::SnapDefaultHandler(const QString &protocol) {
QString::fromStdString(e.what())));
}
loop.quit();
loop->quit();
},
std::string(kSnapcraftSettingsService));
QGuiApplicationPrivate::showModalWindow(this);
loop.exec();
QGuiApplicationPrivate::hideModalWindow(this);
QWindow window;
QGuiApplicationPrivate::showModalWindow(&window);
loop->run();
g_main_context_pop_thread_default(context->gobj());
QGuiApplicationPrivate::hideModalWindow(&window);
} catch (const Glib::Error &e) {
LOG(("Snap Default Handler Error: %1").arg(
QString::fromStdString(e.what())));

View File

@@ -532,28 +532,30 @@ void MainWindow::initSize() {
if (position.w > w) position.w = w;
if (position.h > h) position.h = h;
const auto rightPoint = position.x + position.w;
if (rightPoint > w) {
const auto distance = rightPoint - w;
const auto screenRightPoint = x + w;
if (rightPoint > screenRightPoint) {
const auto distance = rightPoint - screenRightPoint;
const auto newXPos = position.x - distance;
if (newXPos >= x) {
position.x = newXPos;
} else {
position.x = x;
const auto newRightPoint = position.x + position.w;
const auto newDistance = newRightPoint - w;
const auto newDistance = newRightPoint - screenRightPoint;
position.w -= newDistance;
}
}
const auto bottomPoint = position.y + position.h;
if (bottomPoint > h) {
const auto distance = bottomPoint - h;
const auto screenBottomPoint = y + h;
if (bottomPoint > screenBottomPoint) {
const auto distance = bottomPoint - screenBottomPoint;
const auto newYPos = position.y - distance;
if (newYPos >= y) {
position.y = newYPos;
} else {
position.y = y;
const auto newBottomPoint = position.y + position.h;
const auto newDistance = newBottomPoint - h;
const auto newDistance = newBottomPoint - screenBottomPoint;
position.h -= newDistance;
}
}

View File

@@ -1,7 +1,7 @@
AppVersion 2008002
AppVersion 2008004
AppVersionStrMajor 2.8
AppVersionStrSmall 2.8.2
AppVersionStr 2.8.2
AppVersionStrSmall 2.8.4
AppVersionStr 2.8.4
BetaChannel 0
AlphaVersion 0
AppVersionOriginal 2.8.2
AppVersionOriginal 2.8.4

View File

@@ -22,7 +22,7 @@ def error(message):
print('[ERROR] ' + message)
finish(1)
if sys.platform == 'win32' and not 'COMSPEC' in os.environ:
if sys.platform == 'win32' and 'COMSPEC' not in os.environ:
error('COMSPEC environment variable is not set.')
executePath = os.getcwd()
@@ -39,9 +39,9 @@ if os.path.isfile(officialTargetFile):
officialTarget = line.strip()
arch = ''
if officialTarget == 'win' or officialTarget == 'uwp':
if officialTarget in ['win', 'uwp']:
arch = 'x86'
elif officialTarget == 'win64' or officialTarget == 'uwp64':
elif officialTarget in ['win64', 'uwp64']:
arch = 'x64'
if officialTarget != '':

View File

@@ -1,3 +1,11 @@
2.8.4 (01.07.21)
- Crash fixes in WebView on Windows.
2.8.3 (28.06.21)
- Fix crashes in OpenSSL on macOS.
2.8.2 (27.06.21)
- Attempt to fix random crashes on macOS.

2
cmake

Submodule cmake updated: 1d59503a24...4a63a30c17

View File

@@ -92,8 +92,8 @@ Go to ***BuildPath*** and run
git clone https://github.com/openssl/openssl openssl_1_1_1
cd openssl_1_1_1
git checkout OpenSSL_1_1_1k
./Configure --prefix=/usr/local/macos no-tests darwin64-x86_64-cc -static -g3 $MIN_VER
git checkout OpenSSL_1_1_1-stable
./Configure --prefix=/usr/local/macos no-shared no-tests darwin64-x86_64-cc $MIN_VER
make build_libs $MAKE_THREADS_CNT
cd ..

View File

@@ -117,7 +117,6 @@ parts:
- -DTDESKTOP_API_ID=611335
- -DTDESKTOP_API_HASH=d524b414d21f4d37f08684c1df41ac9c
- -DDESKTOP_APP_USE_PACKAGED_LAZY=ON
- -DDESKTOP_APP_USE_PACKAGED_LAZY_PLATFORMTHEMES=OFF
- -DTDESKTOP_LAUNCHER_BASENAME=telegram-desktop_telegram-desktop
override-pull: |
snapcraftctl pull