summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlya Fedin <fedin-ilja2010@ya.ru>2021-05-10 12:53:34 +0400
committerJohn Preston <johnprestonmail@gmail.com>2021-05-11 10:53:32 +0300
commit680a9a7ca7d9dde6c79a6340e3ca003e6ccfd8a5 (patch)
treea6743f831a1d75155a9e528a8010eaadb4d1de39
parent7de8d6f9ac56e1148369e9f4716244f452e23d49 (diff)
Implement parent setting for portal and gtk dialogs on Wayland via xdg-foreign-v2
-rw-r--r--Telegram/SourceFiles/platform/linux/linux_gdk_helper.cpp136
-rw-r--r--Telegram/SourceFiles/platform/linux/linux_gdk_helper.h4
-rw-r--r--Telegram/SourceFiles/platform/linux/linux_gtk_file_dialog.cpp5
-rw-r--r--Telegram/SourceFiles/platform/linux/linux_gtk_open_with_dialog.cpp7
-rw-r--r--Telegram/SourceFiles/platform/linux/linux_wayland_integration.cpp58
-rw-r--r--Telegram/SourceFiles/platform/linux/linux_wayland_integration.h1
-rw-r--r--Telegram/SourceFiles/platform/linux/linux_wayland_integration_dummy.cpp4
-rw-r--r--Telegram/SourceFiles/platform/linux/linux_xdp_file_dialog.cpp18
-rw-r--r--Telegram/SourceFiles/platform/linux/linux_xdp_open_with_dialog.cpp27
-rw-r--r--Telegram/SourceFiles/platform/linux/specific_linux.cpp24
10 files changed, 199 insertions, 85 deletions
diff --git a/Telegram/SourceFiles/platform/linux/linux_gdk_helper.cpp b/Telegram/SourceFiles/platform/linux/linux_gdk_helper.cpp
index ab65c36ccb..568c634065 100644
--- a/Telegram/SourceFiles/platform/linux/linux_gdk_helper.cpp
+++ b/Telegram/SourceFiles/platform/linux/linux_gdk_helper.cpp
@@ -7,8 +7,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "platform/linux/linux_gdk_helper.h"
+#include "base/platform/linux/base_linux_gtk_integration.h"
#include "base/platform/linux/base_linux_gtk_integration_p.h"
#include "platform/linux/linux_gtk_integration_p.h"
+#include "platform/linux/linux_wayland_integration.h"
+
+#include <QtGui/QWindow>
#ifndef DESKTOP_APP_DISABLE_X11_INTEGRATION
extern "C" {
@@ -16,19 +20,21 @@ extern "C" {
} // extern "C"
#endif // !DESKTOP_APP_DISABLE_X11_INTEGRATION
+// CentOS 7 seem to be too old for needed definitions,
+// so don't include until we link to gtk directly.
+#if !defined DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION && defined LINK_TO_GTK
+extern "C" {
+#include <gdk/gdkwayland.h>
+} // extern "C"
+#endif // !DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION && LINK_TO_GTK
+
namespace Platform {
namespace internal {
+namespace {
+using base::Platform::GtkIntegration;
using namespace Platform::Gtk;
-enum class GtkLoaded {
- GtkNone,
- Gtk2,
- Gtk3,
-};
-
-GtkLoaded gdk_helper_loaded = GtkLoaded::GtkNone;
-
#ifndef DESKTOP_APP_DISABLE_X11_INTEGRATION
// To be able to compile with gtk-3.0 headers as well
#define GdkDrawable GdkWindow
@@ -60,61 +66,91 @@ using f_gdk_x11_window_get_xid = Window(*)(GdkWindow *window);
f_gdk_x11_window_get_xid gdk_x11_window_get_xid = nullptr;
#endif // !DESKTOP_APP_DISABLE_X11_INTEGRATION
-bool GdkHelperLoadGtk2(QLibrary &lib) {
+#ifndef DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION
+using f_gdk_wayland_window_get_type = GType (*)(void);
+f_gdk_wayland_window_get_type gdk_wayland_window_get_type = nullptr;
+
+template <typename Object>
+inline bool gdk_is_wayland_window_check(Object *obj) {
+ return g_type_cit_helper(obj, gdk_wayland_window_get_type());
+}
+
+using f_gdk_wayland_window_set_transient_for_exported = gboolean(*)(GdkWindow *window, char *parent_handle_str);
+f_gdk_wayland_window_set_transient_for_exported gdk_wayland_window_set_transient_for_exported = nullptr;
+#endif // !DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION
+
+void GdkHelperLoadGtk2(QLibrary &lib) {
#ifndef DESKTOP_APP_DISABLE_X11_INTEGRATION
-#ifdef LINK_TO_GTK
- return false;
-#else // LINK_TO_GTK
- if (!LOAD_GTK_SYMBOL(lib, gdk_x11_drawable_get_xdisplay)) return false;
- if (!LOAD_GTK_SYMBOL(lib, gdk_x11_drawable_get_xid)) return false;
- return true;
-#endif // !LINK_TO_GTK
-#else // !DESKTOP_APP_DISABLE_X11_INTEGRATION
- return false;
-#endif // DESKTOP_APP_DISABLE_X11_INTEGRATION
+ LOAD_GTK_SYMBOL(lib, gdk_x11_drawable_get_xdisplay);
+ LOAD_GTK_SYMBOL(lib, gdk_x11_drawable_get_xid);
+#endif // !DESKTOP_APP_DISABLE_X11_INTEGRATION
}
-bool GdkHelperLoadGtk3(QLibrary &lib) {
+void GdkHelperLoadGtk3(QLibrary &lib) {
#ifndef DESKTOP_APP_DISABLE_X11_INTEGRATION
- if (!LOAD_GTK_SYMBOL(lib, gdk_x11_window_get_type)) return false;
- if (!LOAD_GTK_SYMBOL(lib, gdk_window_get_display)) return false;
- if (!LOAD_GTK_SYMBOL(lib, gdk_x11_display_get_xdisplay)) return false;
- if (!LOAD_GTK_SYMBOL(lib, gdk_x11_window_get_xid)) return false;
- return true;
-#else // !DESKTOP_APP_DISABLE_X11_INTEGRATION
- return false;
-#endif // DESKTOP_APP_DISABLE_X11_INTEGRATION
+ LOAD_GTK_SYMBOL(lib, gdk_x11_window_get_type);
+ LOAD_GTK_SYMBOL(lib, gdk_window_get_display);
+ LOAD_GTK_SYMBOL(lib, gdk_x11_display_get_xdisplay);
+ LOAD_GTK_SYMBOL(lib, gdk_x11_window_get_xid);
+#endif // !DESKTOP_APP_DISABLE_X11_INTEGRATION
+#ifndef DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION
+ LOAD_GTK_SYMBOL(lib, gdk_wayland_window_get_type);
+ LOAD_GTK_SYMBOL(lib, gdk_wayland_window_set_transient_for_exported);
+#endif // !DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION
}
+} // namespace
+
void GdkHelperLoad(QLibrary &lib) {
- gdk_helper_loaded = GtkLoaded::GtkNone;
- if (GdkHelperLoadGtk3(lib)) {
- gdk_helper_loaded = GtkLoaded::Gtk3;
- } else if (GdkHelperLoadGtk2(lib)) {
- gdk_helper_loaded = GtkLoaded::Gtk2;
+ if (const auto integration = GtkIntegration::Instance()) {
+ if (integration->checkVersion(3, 0, 0)) {
+ GdkHelperLoadGtk3(lib);
+ } else {
+ GdkHelperLoadGtk2(lib);
+ }
}
}
-bool GdkHelperLoaded() {
+void GdkSetTransientFor(GdkWindow *window, QWindow *parent) {
+#ifndef DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION
+ if (gdk_wayland_window_get_type != nullptr
+ && gdk_wayland_window_set_transient_for_exported != nullptr
+ && gdk_is_wayland_window_check(window)) {
+ if (const auto integration = WaylandIntegration::Instance()) {
+ if (const auto handle = integration->nativeHandle(parent)
+ ; !handle.isEmpty()) {
+ auto handleUtf8 = handle.toUtf8();
+ gdk_wayland_window_set_transient_for_exported(
+ window,
+ handleUtf8.data());
+ return;
+ }
+ }
+ }
+#endif // !DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION
+
#ifndef DESKTOP_APP_DISABLE_X11_INTEGRATION
- return gdk_helper_loaded != GtkLoaded::GtkNone;
-#else // !DESKTOP_APP_DISABLE_X11_INTEGRATION
- return true;
-#endif // DESKTOP_APP_DISABLE_X11_INTEGRATION
-}
+ if (gdk_x11_window_get_type != nullptr
+ && gdk_x11_display_get_xdisplay != nullptr
+ && gdk_x11_window_get_xid != nullptr
+ && gdk_window_get_display != nullptr
+ && gdk_is_x11_window_check(window)) {
+ XSetTransientForHint(
+ gdk_x11_display_get_xdisplay(gdk_window_get_display(window)),
+ gdk_x11_window_get_xid(window),
+ parent->winId());
+ return;
+ }
+#endif // !DESKTOP_APP_DISABLE_X11_INTEGRATION
-void XSetTransientForHint(GdkWindow *window, quintptr winId) {
#ifndef DESKTOP_APP_DISABLE_X11_INTEGRATION
- if (gdk_helper_loaded == GtkLoaded::Gtk2) {
- ::XSetTransientForHint(gdk_x11_drawable_get_xdisplay(window),
- gdk_x11_drawable_get_xid(window),
- winId);
- } else if (gdk_helper_loaded == GtkLoaded::Gtk3) {
- if (gdk_is_x11_window_check(window)) {
- ::XSetTransientForHint(gdk_x11_display_get_xdisplay(gdk_window_get_display(window)),
- gdk_x11_window_get_xid(window),
- winId);
- }
+ if (gdk_x11_drawable_get_xdisplay != nullptr
+ && gdk_x11_drawable_get_xid != nullptr) {
+ XSetTransientForHint(
+ gdk_x11_drawable_get_xdisplay(window),
+ gdk_x11_drawable_get_xid(window),
+ parent->winId());
+ return;
}
#endif // !DESKTOP_APP_DISABLE_X11_INTEGRATION
}
diff --git a/Telegram/SourceFiles/platform/linux/linux_gdk_helper.h b/Telegram/SourceFiles/platform/linux/linux_gdk_helper.h
index 6ca9536892..df06803c9e 100644
--- a/Telegram/SourceFiles/platform/linux/linux_gdk_helper.h
+++ b/Telegram/SourceFiles/platform/linux/linux_gdk_helper.h
@@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once
class QLibrary;
+class QWindow;
extern "C" {
#include <gtk/gtk.h>
@@ -18,8 +19,7 @@ namespace Platform {
namespace internal {
void GdkHelperLoad(QLibrary &lib);
-bool GdkHelperLoaded();
-void XSetTransientForHint(GdkWindow *window, quintptr winId);
+void GdkSetTransientFor(GdkWindow *window, QWindow *parent);
} // namespace internal
} // namespace Platform
diff --git a/Telegram/SourceFiles/platform/linux/linux_gtk_file_dialog.cpp b/Telegram/SourceFiles/platform/linux/linux_gtk_file_dialog.cpp
index 9befbf8973..1c00393655 100644
--- a/Telegram/SourceFiles/platform/linux/linux_gtk_file_dialog.cpp
+++ b/Telegram/SourceFiles/platform/linux/linux_gtk_file_dialog.cpp
@@ -70,8 +70,7 @@ QStringList cleanFilterList(const QString &filter) {
}
bool Supported() {
- return internal::GdkHelperLoaded()
- && (gtk_widget_hide_on_delete != nullptr)
+ return (gtk_widget_hide_on_delete != nullptr)
&& (gtk_clipboard_store != nullptr)
&& (gtk_clipboard_get != nullptr)
&& (gtk_widget_destroy != nullptr)
@@ -273,7 +272,7 @@ void QGtkDialog::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindo
gtk_widget_realize(gtkWidget); // creates X window
if (parent) {
- internal::XSetTransientForHint(gtk_widget_get_window(gtkWidget), parent->winId());
+ internal::GdkSetTransientFor(gtk_widget_get_window(gtkWidget), parent);
}
if (modality != Qt::NonModal) {
diff --git a/Telegram/SourceFiles/platform/linux/linux_gtk_open_with_dialog.cpp b/Telegram/SourceFiles/platform/linux/linux_gtk_open_with_dialog.cpp
index 1c8710bae5..4994ebe7dc 100644
--- a/Telegram/SourceFiles/platform/linux/linux_gtk_open_with_dialog.cpp
+++ b/Telegram/SourceFiles/platform/linux/linux_gtk_open_with_dialog.cpp
@@ -22,8 +22,7 @@ namespace {
using namespace Platform::Gtk;
bool Supported() {
- return Platform::internal::GdkHelperLoaded()
- && (gtk_app_chooser_dialog_new != nullptr)
+ return (gtk_app_chooser_dialog_new != nullptr)
&& (gtk_app_chooser_get_app_info != nullptr)
&& (gtk_app_chooser_get_type != nullptr)
&& (gtk_widget_get_window != nullptr)
@@ -70,9 +69,9 @@ bool GtkOpenWithDialog::exec() {
gtk_widget_realize(_gtkWidget);
if (const auto activeWindow = Core::App().activeWindow()) {
- Platform::internal::XSetTransientForHint(
+ Platform::internal::GdkSetTransientFor(
gtk_widget_get_window(_gtkWidget),
- activeWindow->widget().get()->windowHandle()->winId());
+ activeWindow->widget()->windowHandle());
}
QGuiApplicationPrivate::showModalWindow(this);
diff --git a/Telegram/SourceFiles/platform/linux/linux_wayland_integration.cpp b/Telegram/SourceFiles/platform/linux/linux_wayland_integration.cpp
index a3ff427615..6586988d89 100644
--- a/Telegram/SourceFiles/platform/linux/linux_wayland_integration.cpp
+++ b/Telegram/SourceFiles/platform/linux/linux_wayland_integration.cpp
@@ -9,8 +9,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/platform/base_platform_info.h"
+#include <QtCore/QCoreApplication>
#include <connection_thread.h>
#include <registry.h>
+#include <surface.h>
+#include <xdgforeign.h>
using namespace KWayland::Client;
@@ -25,6 +28,10 @@ public:
return _registry;
}
+ [[nodiscard]] XdgExporter *xdgExporter() {
+ return _xdgExporter.get();
+ }
+
[[nodiscard]] QEventLoop &interfacesLoop() {
return _interfacesLoop;
}
@@ -35,12 +42,25 @@ public:
private:
ConnectionThread _connection;
+ ConnectionThread *_applicationConnection = nullptr;
Registry _registry;
+ Registry _applicationRegistry;
+ std::unique_ptr<XdgExporter> _xdgExporter;
QEventLoop _interfacesLoop;
bool _interfacesAnnounced = false;
};
-WaylandIntegration::Private::Private() {
+WaylandIntegration::Private::Private()
+: _applicationConnection(ConnectionThread::fromApplication(this)) {
+ _applicationRegistry.create(_applicationConnection);
+ _applicationRegistry.setup();
+
+ connect(
+ _applicationConnection,
+ &ConnectionThread::connectionDied,
+ &_applicationRegistry,
+ &Registry::destroy);
+
connect(&_connection, &ConnectionThread::connected, [=] {
LOG(("Successfully connected to Wayland server at socket: %1")
.arg(_connection.socketName()));
@@ -62,6 +82,22 @@ WaylandIntegration::Private::Private() {
}
});
+ connect(
+ &_applicationRegistry,
+ &Registry::exporterUnstableV2Announced,
+ [=](uint name, uint version) {
+ _xdgExporter = {
+ _applicationRegistry.createXdgExporter(name, version),
+ std::default_delete<XdgExporter>(),
+ };
+
+ connect(
+ QCoreApplication::instance(),
+ &QCoreApplication::aboutToQuit,
+ this,
+ [=] { _xdgExporter = nullptr; });
+ });
+
_connection.initConnection();
}
@@ -89,5 +125,25 @@ bool WaylandIntegration::supportsXdgDecoration() {
Registry::Interface::XdgDecorationUnstableV1);
}
+QString WaylandIntegration::nativeHandle(QWindow *window) {
+ if (const auto exporter = _private->xdgExporter()) {
+ if (const auto surface = Surface::fromWindow(window)) {
+ if (const auto exported = exporter->exportTopLevel(
+ surface,
+ _private->xdgExporter())) {
+ QEventLoop loop;
+ QObject::connect(
+ exported,
+ &XdgExported::done,
+ &loop,
+ &QEventLoop::quit);
+ loop.exec();
+ return exported->handle();
+ }
+ }
+ }
+ return {};
+}
+
} // namespace internal
} // namespace Platform
diff --git a/Telegram/SourceFiles/platform/linux/linux_wayland_integration.h b/Telegram/SourceFiles/platform/linux/linux_wayland_integration.h
index b2f7161846..a41d342098 100644
--- a/Telegram/SourceFiles/platform/linux/linux_wayland_integration.h
+++ b/Telegram/SourceFiles/platform/linux/linux_wayland_integration.h
@@ -15,6 +15,7 @@ public:
static WaylandIntegration *Instance();
void waitForInterfaceAnnounce();
bool supportsXdgDecoration();
+ QString nativeHandle(QWindow *window);
private:
WaylandIntegration();
diff --git a/Telegram/SourceFiles/platform/linux/linux_wayland_integration_dummy.cpp b/Telegram/SourceFiles/platform/linux/linux_wayland_integration_dummy.cpp
index 166e8b575d..2b4068553c 100644
--- a/Telegram/SourceFiles/platform/linux/linux_wayland_integration_dummy.cpp
+++ b/Telegram/SourceFiles/platform/linux/linux_wayland_integration_dummy.cpp
@@ -33,5 +33,9 @@ bool WaylandIntegration::supportsXdgDecoration() {
return false;
}
+QString WaylandIntegration::nativeHandle(QWindow *window) {
+ return {};
+}
+
} // namespace internal
} // namespace Platform
diff --git a/Telegram/SourceFiles/platform/linux/linux_xdp_file_dialog.cpp b/Telegram/SourceFiles/platform/linux/linux_xdp_file_dialog.cpp
index c9476a0c50..543908f24a 100644
--- a/Telegram/SourceFiles/platform/linux/linux_xdp_file_dialog.cpp
+++ b/Telegram/SourceFiles/platform/linux/linux_xdp_file_dialog.cpp
@@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "platform/platform_file_utilities.h"
#include "base/platform/base_platform_info.h"
#include "base/platform/linux/base_linux_glibmm_helper.h"
+#include "platform/linux/linux_wayland_integration.h"
#include "storage/localstorage.h"
#include "base/openssl_help.h"
#include "base/qt_adapters.h"
@@ -20,6 +21,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <glibmm.h>
#include <giomm.h>
+using Platform::internal::WaylandIntegration;
+
namespace Platform {
namespace FileDialog {
namespace XDP {
@@ -207,7 +210,7 @@ private:
uint _requestSignalId = 0;
// Options
- WId _winId = 0;
+ QWindow *_parent = nullptr;
QFileDialog::Options _options;
QFileDialog::AcceptMode _acceptMode = QFileDialog::AcceptOpen;
QFileDialog::FileMode _fileMode = QFileDialog::ExistingFile;
@@ -266,8 +269,13 @@ XDPFileDialog::~XDPFileDialog() {
void XDPFileDialog::openPortal() {
std::stringstream parentWindowId;
- if (IsX11()) {
- parentWindowId << "x11:" << std::hex << _winId;
+ if (const auto integration = WaylandIntegration::Instance()) {
+ if (const auto handle = integration->nativeHandle(_parent)
+ ; !handle.isEmpty()) {
+ parentWindowId << "wayland:" << handle.toStdString();
+ }
+ } else if (IsX11() && _parent) {
+ parentWindowId << "x11:" << std::hex << _parent->winId();
}
std::map<Glib::ustring, Glib::VariantBase> options;
@@ -408,7 +416,7 @@ void XDPFileDialog::openPortal() {
+ uniqueName
+ '/'
+ handleToken;
-
+
const auto responseCallback = crl::guard(this, [=](
const Glib::RefPtr<Gio::DBus::Connection> &connection,
const Glib::ustring &sender_name,
@@ -629,7 +637,7 @@ void XDPFileDialog::showHelper(
Qt::WindowModality windowModality,
QWindow *parent) {
_modal = windowModality != Qt::NonModal;
- _winId = parent ? parent->winId() : 0;
+ _parent = parent;
openPortal();
}
diff --git a/Telegram/SourceFiles/platform/linux/linux_xdp_open_with_dialog.cpp b/Telegram/SourceFiles/platform/linux/linux_xdp_open_with_dialog.cpp
index 64d3db95dd..810bfeb21d 100644
--- a/Telegram/SourceFiles/platform/linux/linux_xdp_open_with_dialog.cpp
+++ b/Telegram/SourceFiles/platform/linux/linux_xdp_open_with_dialog.cpp
@@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/platform/base_platform_info.h"
#include "base/platform/linux/base_linux_glibmm_helper.h"
+#include "platform/linux/linux_wayland_integration.h"
#include "core/application.h"
#include "window/window_controller.h"
#include "base/openssl_help.h"
@@ -21,6 +22,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <giomm.h>
#include <private/qguiapplication_p.h>
+using Platform::internal::WaylandIntegration;
+
namespace Platform {
namespace File {
namespace internal {
@@ -80,18 +83,22 @@ bool XDPOpenWithDialog::exec() {
const auto parentWindowId = [&]() -> Glib::ustring {
std::stringstream result;
- if (const auto activeWindow = Core::App().activeWindow()) {
- if (IsX11()) {
- result
- << "x11:"
- << std::hex
- << activeWindow
- ->widget()
- .get()
- ->windowHandle()
- ->winId();
+
+ const auto activeWindow = Core::App().activeWindow();
+ if (!activeWindow) {
+ return result.str();
+ }
+
+ const auto window = activeWindow->widget()->windowHandle();
+ if (const auto integration = WaylandIntegration::Instance()) {
+ if (const auto handle = integration->nativeHandle(window)
+ ; !handle.isEmpty()) {
+ result << "wayland:" << handle.toStdString();
}
+ } else if (IsX11()) {
+ result << "x11:" << std::hex << window->winId();
}
+
return result.str();
}();
diff --git a/Telegram/SourceFiles/platform/linux/specific_linux.cpp b/Telegram/SourceFiles/platform/linux/specific_linux.cpp
index 890a7c0c4a..971bf3a50f 100644
--- a/Telegram/SourceFiles/platform/linux/specific_linux.cpp
+++ b/Telegram/SourceFiles/platform/linux/specific_linux.cpp
@@ -102,18 +102,22 @@ PortalAutostart::PortalAutostart(bool start, bool silent) {
const auto parentWindowId = [&]() -> Glib::ustring {
std::stringstream result;
- if (const auto activeWindow = Core::App().activeWindow()) {
- if (IsX11()) {
- result
- << "x11:"
- << std::hex
- << activeWindow
- ->widget()
- .get()
- ->windowHandle()
- ->winId();
+
+ const auto activeWindow = Core::App().activeWindow();
+ if (!activeWindow) {
+ return result.str();
+ }
+
+ const auto window = activeWindow->widget()->windowHandle();
+ if (const auto integration = WaylandIntegration::Instance()) {
+ if (const auto handle = integration->nativeHandle(window)
+ ; !handle.isEmpty()) {
+ result << "wayland:" << handle.toStdString();
}
+ } else if (IsX11()) {
+ result << "x11:" << std::hex << window->winId();
}
+
return result.str();
}();