Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cade53aa0a | ||
|
|
2fdcda7536 | ||
|
|
7e6439e4f8 | ||
|
|
f07ee7f590 | ||
|
|
02db4e01fa | ||
|
|
8d75078a42 | ||
|
|
0e25ef7524 | ||
|
|
8608d8aa4d | ||
|
|
c1a7332a5e | ||
|
|
c3fb392906 | ||
|
|
a59bfdb2f8 | ||
|
|
79f96480c2 | ||
|
|
60cbd96d91 |
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -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
|
||||
|
||||
@@ -94,7 +94,6 @@ if (LINUX)
|
||||
target_link_libraries(Telegram
|
||||
PRIVATE
|
||||
desktop-app::external_statusnotifieritem
|
||||
desktop-app::external_dbusmenu_qt
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 ¶meters) {
|
||||
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
|
||||
|
||||
@@ -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 ¶meters) {
|
||||
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 ¶meters) {
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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())));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
1
Telegram/ThirdParty/qt5ct
vendored
1
Telegram/ThirdParty/qt5ct
vendored
Submodule Telegram/ThirdParty/qt5ct deleted from 9f60cd2352
@@ -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
|
||||
|
||||
@@ -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 != '':
|
||||
|
||||
Submodule Telegram/lib_base updated: 01d152af4c...90ff8b523b
Submodule Telegram/lib_webview updated: eb812476ab...a480827e30
@@ -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
2
cmake
Submodule cmake updated: 1d59503a24...4a63a30c17
@@ -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 ..
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user