/*
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/specific_linux.h"
#include "base/platform/base_platform_info.h"
#include "base/platform/linux/base_linux_xcb_utilities.h"
#include "base/platform/linux/base_linux_gtk_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"
#include "mainwindow.h"
#include "storage/localstorage.h"
#include "core/update_checker.h"
#include "window/window_controller.h"
#include "core/application.h"
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
#include "platform/linux/linux_notification_service_watcher.h"
#include "platform/linux/linux_gsd_media_keys.h"
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
#include <QtWidgets/QApplication>
#include <QtWidgets/QDesktopWidget>
#include <QtCore/QStandardPaths>
#include <QtCore/QProcess>
#include <QtGui/QWindow>
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
#include <QtDBus/QDBusInterface>
#include <QtDBus/QDBusConnection>
#include <QtDBus/QDBusConnectionInterface>
#include <QtDBus/QDBusMessage>
#include <QtDBus/QDBusReply>
#include <QtDBus/QDBusError>
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
#include <glib.h>
extern "C" {
#undef signals
#include <gio/gio.h>
#define signals public
} // extern "C"
#include <sys/stat.h>
#include <sys/types.h>
#include <cstdlib>
#include <unistd.h>
#include <dirent.h>
#include <pwd.h>
#include <iostream>
using namespace Platform;
using BaseGtkIntegration = base::Platform::GtkIntegration;
using Platform::internal::WaylandIntegration;
using Platform::internal::GtkIntegration;
Q_DECLARE_METATYPE(QMargins);
namespace Platform {
namespace {
constexpr auto kDesktopFile = ":/misc/telegramdesktop.desktop"_cs;
constexpr auto kIconName = "telegram"_cs;
constexpr auto kHandlerTypeName = "x-scheme-handler/tg"_cs;
constexpr auto kXDGDesktopPortalService = "org.freedesktop.portal.Desktop"_cs;
constexpr auto kXDGDesktopPortalObjectPath = "/org/freedesktop/portal/desktop"_cs;
constexpr auto kPropertiesInterface = "org.freedesktop.DBus.Properties"_cs;
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
std::unique_ptr<internal::NotificationServiceWatcher> NSWInstance;
QStringList ListDBusActivatableNames() {
static const auto Result = [&] {
const auto message = QDBusMessage::createMethodCall(
qsl("org.freedesktop.DBus"),
qsl("/org/freedesktop/DBus"),
qsl("org.freedesktop.DBus"),
qsl("ListActivatableNames"));
const QDBusReply<QStringList> reply = QDBusConnection::sessionBus()
.call(message);
if (reply.isValid()) {
return reply.value();
} else if (reply.error().type() != QDBusError::Disconnected) {
LOG(("ListActivatableNames Error: %1: %2")
.arg(reply.error().name())
.arg(reply.error().message()));
}
return QStringList{};
}();
return Result;
}
void PortalAutostart(bool autostart, bool silent = false) {
if (cExeName().isEmpty()) {
return;
}
QVariantMap options;
options["reason"] = tr::lng_settings_auto_start(tr::now);
options["autostart"] = autostart;
options["commandline"] = QStringList{
cExeName(),
qsl("-workdir"),
cWorkingDir(),
qsl("-autostart")
};
options["dbus-activatable"] = false;
auto message = QDBusMessage::createMethodCall(
kXDGDesktopPortalService.utf16(),
kXDGDesktopPortalObjectPath.utf16(),
qsl("org.freedesktop.portal.Background"),
qsl("RequestBackground"));
const auto parentWindowId = [&] {
if (const auto activeWindow = Core::App().activeWindow()) {
if (!IsWayland()) {
return qsl("x11:%1").arg(QString::number(
activeWindow->widget().get()->windowHandle()->winId(),
16));
}
}
return QString();
}();
message.setArguments({
parentWindowId,
options
});
if (silent) {
QDBusConnection::sessionBus().send(message);
return;
}
const QDBusError error = QDBusConnection::sessionBus().call(message);
if (error.isValid()) {
LOG(("Flatpak Autostart Error: %1: %2")
.arg(error.name())
.arg(error.message()));
}
}
bool IsXDGDesktopPortalPresent() {
static const auto Result = QDBusInterface(
kXDGDesktopPortalService.utf16(),
kXDGDesktopPortalObjectPath.utf16()).isValid();
return Result;
}
bool IsXDGDesktopPortalKDEPresent() {
static const auto Result = QDBusInterface(
qsl("org.freedesktop.impl.portal.desktop.kde"),
kXDGDesktopPortalObjectPath.utf16()).isValid();
<