mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Expose gtk integration to lib_base
This commit is contained in:
parent
a9c08552c8
commit
f1ee5b5704
14 changed files with 114 additions and 550 deletions
2
.github/workflows/linux.yml
vendored
2
.github/workflows/linux.yml
vendored
|
@ -63,7 +63,7 @@ jobs:
|
||||||
- ""
|
- ""
|
||||||
- "DESKTOP_APP_DISABLE_DBUS_INTEGRATION"
|
- "DESKTOP_APP_DISABLE_DBUS_INTEGRATION"
|
||||||
- "DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION"
|
- "DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION"
|
||||||
- "TDESKTOP_DISABLE_GTK_INTEGRATION"
|
- "DESKTOP_APP_DISABLE_GTK_INTEGRATION"
|
||||||
|
|
||||||
env:
|
env:
|
||||||
UPLOAD_ARTIFACT: "false"
|
UPLOAD_ARTIFACT: "false"
|
||||||
|
|
|
@ -104,7 +104,7 @@ if (LINUX)
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (NOT TDESKTOP_DISABLE_GTK_INTEGRATION)
|
if (NOT DESKTOP_APP_DISABLE_GTK_INTEGRATION)
|
||||||
find_package(PkgConfig REQUIRED)
|
find_package(PkgConfig REQUIRED)
|
||||||
|
|
||||||
if (DESKTOP_APP_USE_PACKAGED AND NOT DESKTOP_APP_USE_PACKAGED_LAZY)
|
if (DESKTOP_APP_USE_PACKAGED AND NOT DESKTOP_APP_USE_PACKAGED_LAZY)
|
||||||
|
@ -842,8 +842,6 @@ PRIVATE
|
||||||
platform/linux/linux_wayland_integration.h
|
platform/linux/linux_wayland_integration.h
|
||||||
platform/linux/linux_xdp_file_dialog.cpp
|
platform/linux/linux_xdp_file_dialog.cpp
|
||||||
platform/linux/linux_xdp_file_dialog.h
|
platform/linux/linux_xdp_file_dialog.h
|
||||||
platform/linux/linux_xlib_helper.cpp
|
|
||||||
platform/linux/linux_xlib_helper.h
|
|
||||||
platform/linux/file_utilities_linux.cpp
|
platform/linux/file_utilities_linux.cpp
|
||||||
platform/linux/file_utilities_linux.h
|
platform/linux/file_utilities_linux.h
|
||||||
platform/linux/launcher_linux.cpp
|
platform/linux/launcher_linux.cpp
|
||||||
|
@ -1128,7 +1126,7 @@ if (NOT LINUX)
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (LINUX AND DESKTOP_APP_DISABLE_DBUS_INTEGRATION)
|
if (DESKTOP_APP_DISABLE_DBUS_INTEGRATION)
|
||||||
remove_target_sources(Telegram ${src_loc}
|
remove_target_sources(Telegram ${src_loc}
|
||||||
platform/linux/linux_gsd_media_keys.cpp
|
platform/linux/linux_gsd_media_keys.cpp
|
||||||
platform/linux/linux_gsd_media_keys.h
|
platform/linux/linux_gsd_media_keys.h
|
||||||
|
@ -1145,12 +1143,12 @@ if (LINUX AND DESKTOP_APP_DISABLE_DBUS_INTEGRATION)
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (LINUX AND DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION)
|
if (DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION)
|
||||||
remove_target_sources(Telegram ${src_loc} platform/linux/linux_wayland_integration.cpp)
|
remove_target_sources(Telegram ${src_loc} platform/linux/linux_wayland_integration.cpp)
|
||||||
nice_target_sources(Telegram ${src_loc} PRIVATE platform/linux/linux_wayland_integration_dummy.cpp)
|
nice_target_sources(Telegram ${src_loc} PRIVATE platform/linux/linux_wayland_integration_dummy.cpp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (LINUX AND TDESKTOP_DISABLE_GTK_INTEGRATION)
|
if (DESKTOP_APP_DISABLE_GTK_INTEGRATION)
|
||||||
remove_target_sources(Telegram ${src_loc}
|
remove_target_sources(Telegram ${src_loc}
|
||||||
platform/linux/linux_gdk_helper.cpp
|
platform/linux/linux_gdk_helper.cpp
|
||||||
platform/linux/linux_gdk_helper.h
|
platform/linux/linux_gdk_helper.h
|
||||||
|
@ -1160,8 +1158,6 @@ if (LINUX AND TDESKTOP_DISABLE_GTK_INTEGRATION)
|
||||||
platform/linux/linux_gtk_integration.cpp
|
platform/linux/linux_gtk_integration.cpp
|
||||||
platform/linux/linux_open_with_dialog.cpp
|
platform/linux/linux_open_with_dialog.cpp
|
||||||
platform/linux/linux_open_with_dialog.h
|
platform/linux/linux_open_with_dialog.h
|
||||||
platform/linux/linux_xlib_helper.cpp
|
|
||||||
platform/linux/linux_xlib_helper.h
|
|
||||||
)
|
)
|
||||||
|
|
||||||
nice_target_sources(Telegram ${src_loc}
|
nice_target_sources(Telegram ${src_loc}
|
||||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "platform/linux/linux_gdk_helper.h"
|
#include "platform/linux/linux_gdk_helper.h"
|
||||||
|
|
||||||
|
#include "base/platform/linux/base_linux_gtk_integration_p.h"
|
||||||
#include "platform/linux/linux_gtk_integration_p.h"
|
#include "platform/linux/linux_gtk_integration_p.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
|
@ -642,7 +642,7 @@ bool Supported() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Use(Type type) {
|
bool Use(Type type) {
|
||||||
return IsGtkIntegrationForced()
|
return qEnvironmentVariableIsSet("TDESKTOP_USE_GTK_FILE_DIALOG")
|
||||||
|| DesktopEnvironment::IsGtkBased()
|
|| DesktopEnvironment::IsGtkBased()
|
||||||
// use as a fallback for portal dialog
|
// use as a fallback for portal dialog
|
||||||
|| UseXDGDesktopPortal();
|
|| UseXDGDesktopPortal();
|
||||||
|
|
|
@ -7,149 +7,30 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "platform/linux/linux_gtk_integration.h"
|
#include "platform/linux/linux_gtk_integration.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_gtk_integration_p.h"
|
||||||
#include "base/platform/base_platform_info.h"
|
|
||||||
#include "platform/linux/linux_xlib_helper.h"
|
|
||||||
#include "platform/linux/linux_gdk_helper.h"
|
#include "platform/linux/linux_gdk_helper.h"
|
||||||
#include "platform/linux/linux_gtk_file_dialog.h"
|
#include "platform/linux/linux_gtk_file_dialog.h"
|
||||||
#include "platform/linux/linux_open_with_dialog.h"
|
#include "platform/linux/linux_open_with_dialog.h"
|
||||||
#include "platform/linux/specific_linux.h"
|
#include "platform/linux/specific_linux.h"
|
||||||
|
#include "ui/platform/ui_platform_utility.h"
|
||||||
#include "core/sandbox.h"
|
#include "core/sandbox.h"
|
||||||
#include "core/core_settings.h"
|
#include "core/core_settings.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "main/main_domain.h"
|
|
||||||
#include "mainwindow.h"
|
|
||||||
|
|
||||||
namespace Platform {
|
namespace Platform {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
using namespace Platform::Gtk;
|
using namespace Platform::Gtk;
|
||||||
|
using BaseGtkIntegration = base::Platform::GtkIntegration;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
bool GtkTriedToInit = false;
|
bool Loaded = false;
|
||||||
bool GtkLoaded = false;
|
|
||||||
|
|
||||||
bool LoadLibrary(QLibrary &lib, const char *name, int version) {
|
QLibrary &Library() {
|
||||||
#ifdef LINK_TO_GTK
|
return BaseGtkIntegration::Instance()->library();
|
||||||
return true;
|
|
||||||
#else // LINK_TO_GTK
|
|
||||||
DEBUG_LOG(("Loading '%1' with version %2...").arg(
|
|
||||||
QLatin1String(name)).arg(version));
|
|
||||||
lib.setFileNameAndVersion(QLatin1String(name), version);
|
|
||||||
if (lib.load()) {
|
|
||||||
DEBUG_LOG(("Loaded '%1' with version %2!").arg(
|
|
||||||
QLatin1String(name)).arg(version));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
lib.setFileNameAndVersion(QLatin1String(name), QString());
|
|
||||||
if (lib.load()) {
|
|
||||||
DEBUG_LOG(("Loaded '%1' without version!").arg(QLatin1String(name)));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
LOG(("Could not load '%1' with version %2 :(").arg(
|
|
||||||
QLatin1String(name)).arg(version));
|
|
||||||
return false;
|
|
||||||
#endif // !LINK_TO_GTK
|
|
||||||
}
|
|
||||||
|
|
||||||
void GtkMessageHandler(
|
|
||||||
const gchar *log_domain,
|
|
||||||
GLogLevelFlags log_level,
|
|
||||||
const gchar *message,
|
|
||||||
gpointer unused_data) {
|
|
||||||
// Silence false-positive Gtk warnings (we are using Xlib to set
|
|
||||||
// the WM_TRANSIENT_FOR hint).
|
|
||||||
if (message != qstr("GtkDialog mapped without a transient parent. "
|
|
||||||
"This is discouraged.")) {
|
|
||||||
// For other messages, call the default handler.
|
|
||||||
g_log_default_handler(log_domain, log_level, message, unused_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SetupGtkBase(QLibrary &lib_gtk) {
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_init_check", gtk_init_check)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_check_version", gtk_check_version)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_settings_get_default", gtk_settings_get_default)) return false;
|
|
||||||
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_widget_show", gtk_widget_show)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_widget_hide", gtk_widget_hide)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_widget_get_window", gtk_widget_get_window)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_widget_realize", gtk_widget_realize)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_widget_hide_on_delete", gtk_widget_hide_on_delete)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_widget_destroy", gtk_widget_destroy)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_clipboard_get", gtk_clipboard_get)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_clipboard_store", gtk_clipboard_store)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_clipboard_wait_for_contents", gtk_clipboard_wait_for_contents)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_clipboard_wait_for_image", gtk_clipboard_wait_for_image)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_selection_data_targets_include_image", gtk_selection_data_targets_include_image)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_selection_data_free", gtk_selection_data_free)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_file_chooser_dialog_new", gtk_file_chooser_dialog_new)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_file_chooser_get_type", gtk_file_chooser_get_type)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_image_get_type", gtk_image_get_type)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_file_chooser_set_current_folder", gtk_file_chooser_set_current_folder)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_file_chooser_get_current_folder", gtk_file_chooser_get_current_folder)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_file_chooser_set_current_name", gtk_file_chooser_set_current_name)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_file_chooser_select_filename", gtk_file_chooser_select_filename)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_file_chooser_get_filenames", gtk_file_chooser_get_filenames)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_file_chooser_set_filter", gtk_file_chooser_set_filter)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_file_chooser_get_filter", gtk_file_chooser_get_filter)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_window_get_type", gtk_window_get_type)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_window_set_title", gtk_window_set_title)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_file_chooser_set_local_only", gtk_file_chooser_set_local_only)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_file_chooser_set_action", gtk_file_chooser_set_action)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_file_chooser_set_select_multiple", gtk_file_chooser_set_select_multiple)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_file_chooser_set_do_overwrite_confirmation", gtk_file_chooser_set_do_overwrite_confirmation)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_file_chooser_remove_filter", gtk_file_chooser_remove_filter)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_file_filter_set_name", gtk_file_filter_set_name)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_file_filter_add_pattern", gtk_file_filter_add_pattern)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_file_chooser_add_filter", gtk_file_chooser_add_filter)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_file_chooser_set_preview_widget", gtk_file_chooser_set_preview_widget)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_file_chooser_get_preview_filename", gtk_file_chooser_get_preview_filename)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_file_chooser_set_preview_widget_active", gtk_file_chooser_set_preview_widget_active)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_file_filter_new", gtk_file_filter_new)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_image_new", gtk_image_new)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_image_set_from_pixbuf", gtk_image_set_from_pixbuf)) return false;
|
|
||||||
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gdk_window_set_modal_hint", gdk_window_set_modal_hint)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gdk_window_focus", gdk_window_focus)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_dialog_get_type", gtk_dialog_get_type)) return false;
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gtk_dialog_run", gtk_dialog_run)) return false;
|
|
||||||
|
|
||||||
if (!LOAD_GTK_SYMBOL(lib_gtk, "gdk_atom_intern", gdk_atom_intern)) return false;
|
|
||||||
|
|
||||||
if (LOAD_GTK_SYMBOL(lib_gtk, "gdk_set_allowed_backends", gdk_set_allowed_backends)) {
|
|
||||||
// We work only with Wayland and X11 GDK backends.
|
|
||||||
// Otherwise we get segfault in Ubuntu 17.04 in gtk_init_check() call.
|
|
||||||
// See https://github.com/telegramdesktop/tdesktop/issues/3176
|
|
||||||
// See https://github.com/telegramdesktop/tdesktop/issues/3162
|
|
||||||
if(IsWayland()) {
|
|
||||||
DEBUG_LOG(("Limit allowed GDK backends to wayland,x11"));
|
|
||||||
gdk_set_allowed_backends("wayland,x11");
|
|
||||||
} else {
|
|
||||||
DEBUG_LOG(("Limit allowed GDK backends to x11,wayland"));
|
|
||||||
gdk_set_allowed_backends("x11,wayland");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// gtk_init will reset the Xlib error handler,
|
|
||||||
// and that causes Qt applications to quit on X errors.
|
|
||||||
// Therefore, we need to manually restore it.
|
|
||||||
XErrorHandlerRestorer handlerRestorer;
|
|
||||||
|
|
||||||
DEBUG_LOG(("Library gtk functions loaded!"));
|
|
||||||
GtkTriedToInit = true;
|
|
||||||
if (!gtk_init_check(0, 0)) {
|
|
||||||
gtk_init_check = nullptr;
|
|
||||||
DEBUG_LOG(("Failed to gtk_init_check(0, 0)!"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
DEBUG_LOG(("Checked gtk with gtk_init_check!"));
|
|
||||||
|
|
||||||
// Use our custom log handler.
|
|
||||||
g_log_set_handler("Gtk", G_LOG_LEVEL_MESSAGE, GtkMessageHandler, nullptr);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetImageFromClipboardSupported() {
|
bool GetImageFromClipboardSupported() {
|
||||||
|
@ -166,47 +47,6 @@ bool GetImageFromClipboardSupported() {
|
||||||
&& (gdk_atom_intern != nullptr);
|
&& (gdk_atom_intern != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
std::optional<T> GtkSetting(const QString &propertyName) {
|
|
||||||
const auto integration = GtkIntegration::Instance();
|
|
||||||
if (!integration
|
|
||||||
|| !integration->loaded()
|
|
||||||
|| gtk_settings_get_default == nullptr) {
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
auto settings = gtk_settings_get_default();
|
|
||||||
T value;
|
|
||||||
g_object_get(settings, propertyName.toUtf8(), &value, nullptr);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IconThemeShouldBeSet() {
|
|
||||||
// change the icon theme only if
|
|
||||||
// it isn't already set by a platformtheme plugin
|
|
||||||
// if QT_QPA_PLATFORMTHEME=(gtk2|gtk3), then force-apply the icon theme
|
|
||||||
static const auto Result =
|
|
||||||
// QGenericUnixTheme
|
|
||||||
(QIcon::themeName() == qstr("hicolor")
|
|
||||||
&& QIcon::fallbackThemeName() == qstr("hicolor"))
|
|
||||||
// QGnomeTheme
|
|
||||||
|| (QIcon::themeName() == qstr("Adwaita")
|
|
||||||
&& QIcon::fallbackThemeName() == qstr("gnome"))
|
|
||||||
// qt5ct
|
|
||||||
|| (QIcon::themeName().isEmpty()
|
|
||||||
&& QIcon::fallbackThemeName().isEmpty())
|
|
||||||
|| IsGtkIntegrationForced();
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CursorSizeShouldBeSet() {
|
|
||||||
// change the cursor size only on Wayland and if it wasn't already set
|
|
||||||
static const auto Result = IsWayland()
|
|
||||||
&& qEnvironmentVariableIsEmpty("XCURSOR_SIZE");
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetScaleFactor() {
|
void SetScaleFactor() {
|
||||||
Core::Sandbox::Instance().customEnterFromEventLoop([] {
|
Core::Sandbox::Instance().customEnterFromEventLoop([] {
|
||||||
const auto integration = GtkIntegration::Instance();
|
const auto integration = GtkIntegration::Instance();
|
||||||
|
@ -225,61 +65,6 @@ void SetScaleFactor() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetIconTheme() {
|
|
||||||
Core::Sandbox::Instance().customEnterFromEventLoop([] {
|
|
||||||
const auto integration = GtkIntegration::Instance();
|
|
||||||
if (!integration || !IconThemeShouldBeSet()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto themeName = integration->getStringSetting(
|
|
||||||
qsl("gtk-icon-theme-name"));
|
|
||||||
|
|
||||||
const auto fallbackThemeName = integration->getStringSetting(
|
|
||||||
qsl("gtk-fallback-icon-theme"));
|
|
||||||
|
|
||||||
if (!themeName.has_value() || !fallbackThemeName.has_value()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG_LOG(("Setting GTK icon theme"));
|
|
||||||
|
|
||||||
QIcon::setThemeName(*themeName);
|
|
||||||
QIcon::setFallbackThemeName(*fallbackThemeName);
|
|
||||||
|
|
||||||
DEBUG_LOG(("New icon theme: %1").arg(QIcon::themeName()));
|
|
||||||
DEBUG_LOG(("New fallback icon theme: %1").arg(
|
|
||||||
QIcon::fallbackThemeName()));
|
|
||||||
|
|
||||||
SetApplicationIcon(Window::CreateIcon());
|
|
||||||
if (App::wnd()) {
|
|
||||||
App::wnd()->setWindowIcon(Window::CreateIcon());
|
|
||||||
}
|
|
||||||
|
|
||||||
Core::App().domain().notifyUnreadBadgeChanged();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetCursorSize() {
|
|
||||||
Core::Sandbox::Instance().customEnterFromEventLoop([] {
|
|
||||||
const auto integration = GtkIntegration::Instance();
|
|
||||||
if (!integration || !CursorSizeShouldBeSet()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto newCursorSize = integration->getIntSetting(
|
|
||||||
qsl("gtk-cursor-theme-size"));
|
|
||||||
|
|
||||||
if (!newCursorSize.has_value()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG_LOG(("Setting GTK cursor size"));
|
|
||||||
qputenv("XCURSOR_SIZE", QByteArray::number(*newCursorSize));
|
|
||||||
DEBUG_LOG(("New cursor size: %1").arg(*newCursorSize));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void DarkModeChanged() {
|
void DarkModeChanged() {
|
||||||
Core::Sandbox::Instance().customEnterFromEventLoop([] {
|
Core::Sandbox::Instance().customEnterFromEventLoop([] {
|
||||||
Core::App().settings().setSystemDarkMode(IsDarkMode());
|
Core::App().settings().setSystemDarkMode(IsDarkMode());
|
||||||
|
@ -299,10 +84,7 @@ GtkIntegration::GtkIntegration() {
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkIntegration *GtkIntegration::Instance() {
|
GtkIntegration *GtkIntegration::Instance() {
|
||||||
static const auto useGtkIntegration = !qEnvironmentVariableIsSet(
|
if (!BaseGtkIntegration::Instance()) {
|
||||||
kDisableGtkIntegration.utf8());
|
|
||||||
|
|
||||||
if (!useGtkIntegration) {
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,131 +93,107 @@ GtkIntegration *GtkIntegration::Instance() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GtkIntegration::load() {
|
void GtkIntegration::load() {
|
||||||
Expects(!GtkLoaded);
|
Expects(!loaded());
|
||||||
DEBUG_LOG(("Loading GTK"));
|
|
||||||
|
|
||||||
QLibrary lib_gtk;
|
if (!BaseGtkIntegration::Instance()->loaded()) {
|
||||||
lib_gtk.setLoadHints(QLibrary::DeepBindHint);
|
return;
|
||||||
|
|
||||||
if (LoadLibrary(lib_gtk, "gtk-3", 0)) {
|
|
||||||
GtkLoaded = SetupGtkBase(lib_gtk);
|
|
||||||
}
|
|
||||||
if (!GtkLoaded
|
|
||||||
&& !GtkTriedToInit
|
|
||||||
&& LoadLibrary(lib_gtk, "gtk-x11-2.0", 0)) {
|
|
||||||
GtkLoaded = SetupGtkBase(lib_gtk);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GtkLoaded) {
|
LOAD_GTK_SYMBOL(Library(), "gtk_widget_show", gtk_widget_show);
|
||||||
LOAD_GTK_SYMBOL(lib_gtk, "gdk_display_get_default", gdk_display_get_default);
|
LOAD_GTK_SYMBOL(Library(), "gtk_widget_hide", gtk_widget_hide);
|
||||||
LOAD_GTK_SYMBOL(lib_gtk, "gdk_display_get_monitor", gdk_display_get_monitor);
|
LOAD_GTK_SYMBOL(Library(), "gtk_widget_get_window", gtk_widget_get_window);
|
||||||
LOAD_GTK_SYMBOL(lib_gtk, "gdk_display_get_primary_monitor", gdk_display_get_primary_monitor);
|
LOAD_GTK_SYMBOL(Library(), "gtk_widget_realize", gtk_widget_realize);
|
||||||
LOAD_GTK_SYMBOL(lib_gtk, "gdk_monitor_get_scale_factor", gdk_monitor_get_scale_factor);
|
LOAD_GTK_SYMBOL(Library(), "gtk_widget_hide_on_delete", gtk_widget_hide_on_delete);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_widget_destroy", gtk_widget_destroy);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_clipboard_get", gtk_clipboard_get);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_clipboard_store", gtk_clipboard_store);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_clipboard_wait_for_contents", gtk_clipboard_wait_for_contents);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_clipboard_wait_for_image", gtk_clipboard_wait_for_image);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_selection_data_targets_include_image", gtk_selection_data_targets_include_image);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_selection_data_free", gtk_selection_data_free);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_file_chooser_dialog_new", gtk_file_chooser_dialog_new);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_file_chooser_get_type", gtk_file_chooser_get_type);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_image_get_type", gtk_image_get_type);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_file_chooser_set_current_folder", gtk_file_chooser_set_current_folder);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_file_chooser_get_current_folder", gtk_file_chooser_get_current_folder);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_file_chooser_set_current_name", gtk_file_chooser_set_current_name);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_file_chooser_select_filename", gtk_file_chooser_select_filename);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_file_chooser_get_filenames", gtk_file_chooser_get_filenames);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_file_chooser_set_filter", gtk_file_chooser_set_filter);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_file_chooser_get_filter", gtk_file_chooser_get_filter);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_window_get_type", gtk_window_get_type);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_window_set_title", gtk_window_set_title);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_file_chooser_set_local_only", gtk_file_chooser_set_local_only);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_file_chooser_set_action", gtk_file_chooser_set_action);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_file_chooser_set_select_multiple", gtk_file_chooser_set_select_multiple);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_file_chooser_set_do_overwrite_confirmation", gtk_file_chooser_set_do_overwrite_confirmation);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_file_chooser_remove_filter", gtk_file_chooser_remove_filter);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_file_filter_set_name", gtk_file_filter_set_name);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_file_filter_add_pattern", gtk_file_filter_add_pattern);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_file_chooser_add_filter", gtk_file_chooser_add_filter);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_file_chooser_set_preview_widget", gtk_file_chooser_set_preview_widget);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_file_chooser_get_preview_filename", gtk_file_chooser_get_preview_filename);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_file_chooser_set_preview_widget_active", gtk_file_chooser_set_preview_widget_active);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_file_filter_new", gtk_file_filter_new);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_image_new", gtk_image_new);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_image_set_from_pixbuf", gtk_image_set_from_pixbuf);
|
||||||
|
|
||||||
LOAD_GTK_SYMBOL(lib_gtk, "gdk_pixbuf_new_from_file_at_size", gdk_pixbuf_new_from_file_at_size);
|
LOAD_GTK_SYMBOL(Library(), "gdk_window_set_modal_hint", gdk_window_set_modal_hint);
|
||||||
LOAD_GTK_SYMBOL(lib_gtk, "gdk_pixbuf_get_has_alpha", gdk_pixbuf_get_has_alpha);
|
LOAD_GTK_SYMBOL(Library(), "gdk_window_focus", gdk_window_focus);
|
||||||
LOAD_GTK_SYMBOL(lib_gtk, "gdk_pixbuf_get_pixels", gdk_pixbuf_get_pixels);
|
LOAD_GTK_SYMBOL(Library(), "gtk_dialog_get_type", gtk_dialog_get_type);
|
||||||
LOAD_GTK_SYMBOL(lib_gtk, "gdk_pixbuf_get_width", gdk_pixbuf_get_width);
|
LOAD_GTK_SYMBOL(Library(), "gtk_dialog_run", gtk_dialog_run);
|
||||||
LOAD_GTK_SYMBOL(lib_gtk, "gdk_pixbuf_get_height", gdk_pixbuf_get_height);
|
|
||||||
LOAD_GTK_SYMBOL(lib_gtk, "gdk_pixbuf_get_rowstride", gdk_pixbuf_get_rowstride);
|
|
||||||
|
|
||||||
GdkHelperLoad(lib_gtk);
|
LOAD_GTK_SYMBOL(Library(), "gdk_atom_intern", gdk_atom_intern);
|
||||||
|
|
||||||
LOAD_GTK_SYMBOL(lib_gtk, "gtk_dialog_get_widget_for_response", gtk_dialog_get_widget_for_response);
|
LOAD_GTK_SYMBOL(Library(), "gdk_display_get_default", gdk_display_get_default);
|
||||||
LOAD_GTK_SYMBOL(lib_gtk, "gtk_button_set_label", gtk_button_set_label);
|
LOAD_GTK_SYMBOL(Library(), "gdk_display_get_monitor", gdk_display_get_monitor);
|
||||||
LOAD_GTK_SYMBOL(lib_gtk, "gtk_button_get_type", gtk_button_get_type);
|
LOAD_GTK_SYMBOL(Library(), "gdk_display_get_primary_monitor", gdk_display_get_primary_monitor);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gdk_monitor_get_scale_factor", gdk_monitor_get_scale_factor);
|
||||||
|
|
||||||
LOAD_GTK_SYMBOL(lib_gtk, "gtk_app_chooser_dialog_new", gtk_app_chooser_dialog_new);
|
LOAD_GTK_SYMBOL(Library(), "gdk_pixbuf_new_from_file_at_size", gdk_pixbuf_new_from_file_at_size);
|
||||||
LOAD_GTK_SYMBOL(lib_gtk, "gtk_app_chooser_get_app_info", gtk_app_chooser_get_app_info);
|
LOAD_GTK_SYMBOL(Library(), "gdk_pixbuf_get_has_alpha", gdk_pixbuf_get_has_alpha);
|
||||||
LOAD_GTK_SYMBOL(lib_gtk, "gtk_app_chooser_get_type", gtk_app_chooser_get_type);
|
LOAD_GTK_SYMBOL(Library(), "gdk_pixbuf_get_pixels", gdk_pixbuf_get_pixels);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gdk_pixbuf_get_width", gdk_pixbuf_get_width);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gdk_pixbuf_get_height", gdk_pixbuf_get_height);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gdk_pixbuf_get_rowstride", gdk_pixbuf_get_rowstride);
|
||||||
|
|
||||||
SetScaleFactor();
|
GdkHelperLoad(Library());
|
||||||
SetIconTheme();
|
|
||||||
SetCursorSize();
|
|
||||||
|
|
||||||
const auto settings = gtk_settings_get_default();
|
LOAD_GTK_SYMBOL(Library(), "gtk_dialog_get_widget_for_response", gtk_dialog_get_widget_for_response);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_button_set_label", gtk_button_set_label);
|
||||||
|
LOAD_GTK_SYMBOL(Library(), "gtk_button_get_type", gtk_button_get_type);
|
||||||
|
|
||||||
g_signal_connect(
|
LOAD_GTK_SYMBOL(Library(), "gtk_app_chooser_dialog_new", gtk_app_chooser_dialog_new);
|
||||||
settings,
|
LOAD_GTK_SYMBOL(Library(), "gtk_app_chooser_get_app_info", gtk_app_chooser_get_app_info);
|
||||||
"notify::gtk-icon-theme-name",
|
LOAD_GTK_SYMBOL(Library(), "gtk_app_chooser_get_type", gtk_app_chooser_get_type);
|
||||||
G_CALLBACK(SetIconTheme),
|
|
||||||
nullptr);
|
|
||||||
|
|
||||||
g_signal_connect(
|
Loaded = true;
|
||||||
settings,
|
|
||||||
"notify::gtk-theme-name",
|
|
||||||
G_CALLBACK(DarkModeChanged),
|
|
||||||
nullptr);
|
|
||||||
|
|
||||||
g_signal_connect(
|
SetScaleFactor();
|
||||||
settings,
|
|
||||||
"notify::gtk-cursor-theme-size",
|
|
||||||
G_CALLBACK(SetCursorSize),
|
|
||||||
nullptr);
|
|
||||||
|
|
||||||
if (checkVersion(3, 0, 0)) {
|
BaseGtkIntegration::Instance()->connectToSetting(
|
||||||
g_signal_connect(
|
"gtk-theme-name",
|
||||||
settings,
|
DarkModeChanged);
|
||||||
"notify::gtk-application-prefer-dark-theme",
|
|
||||||
G_CALLBACK(DarkModeChanged),
|
|
||||||
nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (checkVersion(3, 12, 0)) {
|
if (BaseGtkIntegration::Instance()->checkVersion(3, 0, 0)) {
|
||||||
g_signal_connect(
|
BaseGtkIntegration::Instance()->connectToSetting(
|
||||||
settings,
|
"gtk-application-prefer-dark-theme",
|
||||||
"notify::gtk-decoration-layout",
|
DarkModeChanged);
|
||||||
G_CALLBACK(DecorationLayoutChanged),
|
}
|
||||||
nullptr);
|
|
||||||
}
|
if (BaseGtkIntegration::Instance()->checkVersion(3, 12, 0)) {
|
||||||
} else {
|
BaseGtkIntegration::Instance()->connectToSetting(
|
||||||
LOG(("Could not load gtk-3 or gtk-x11-2.0!"));
|
"gtk-decoration-layout",
|
||||||
|
DecorationLayoutChanged);
|
||||||
|
|
||||||
|
BaseGtkIntegration::Instance()->connectToSetting(
|
||||||
|
"gtk-decoration-layout",
|
||||||
|
Ui::Platform::NotifyTitleControlsLayoutChanged);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GtkIntegration::loaded() const {
|
bool GtkIntegration::loaded() const {
|
||||||
return GtkLoaded;
|
return Loaded;
|
||||||
}
|
|
||||||
|
|
||||||
bool GtkIntegration::checkVersion(uint major, uint minor, uint micro) const {
|
|
||||||
return (loaded() && gtk_check_version != nullptr)
|
|
||||||
? !gtk_check_version(major, minor, micro)
|
|
||||||
: false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<bool> GtkIntegration::getBoolSetting(
|
|
||||||
const QString &propertyName) const {
|
|
||||||
const auto value = GtkSetting<gboolean>(propertyName);
|
|
||||||
if (!value.has_value()) {
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
DEBUG_LOG(("Getting GTK setting, %1: %2")
|
|
||||||
.arg(propertyName)
|
|
||||||
.arg(Logs::b(*value)));
|
|
||||||
return *value;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<int> GtkIntegration::getIntSetting(
|
|
||||||
const QString &propertyName) const {
|
|
||||||
const auto value = GtkSetting<gint>(propertyName);
|
|
||||||
if (value.has_value()) {
|
|
||||||
DEBUG_LOG(("Getting GTK setting, %1: %2")
|
|
||||||
.arg(propertyName)
|
|
||||||
.arg(*value));
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<QString> GtkIntegration::getStringSetting(
|
|
||||||
const QString &propertyName) const {
|
|
||||||
auto value = GtkSetting<gchararray>(propertyName);
|
|
||||||
if (!value.has_value()) {
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
const auto str = QString::fromUtf8(*value);
|
|
||||||
g_free(*value);
|
|
||||||
DEBUG_LOG(("Getting GTK setting, %1: '%2'").arg(propertyName).arg(str));
|
|
||||||
return str;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<int> GtkIntegration::scaleFactor() const {
|
std::optional<int> GtkIntegration::scaleFactor() const {
|
||||||
|
|
|
@ -12,27 +12,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
namespace Platform {
|
namespace Platform {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
inline constexpr auto kDisableGtkIntegration = "TDESKTOP_DISABLE_GTK_INTEGRATION"_cs;
|
|
||||||
|
|
||||||
class GtkIntegration {
|
class GtkIntegration {
|
||||||
public:
|
public:
|
||||||
static GtkIntegration *Instance();
|
static GtkIntegration *Instance();
|
||||||
|
|
||||||
void load();
|
void load();
|
||||||
[[nodiscard]] bool loaded() const;
|
[[nodiscard]] bool loaded() const;
|
||||||
[[nodiscard]] bool checkVersion(
|
|
||||||
uint major,
|
|
||||||
uint minor,
|
|
||||||
uint micro) const;
|
|
||||||
|
|
||||||
[[nodiscard]] std::optional<bool> getBoolSetting(
|
|
||||||
const QString &propertyName) const;
|
|
||||||
|
|
||||||
[[nodiscard]] std::optional<int> getIntSetting(
|
|
||||||
const QString &propertyName) const;
|
|
||||||
|
|
||||||
[[nodiscard]] std::optional<QString> getStringSetting(
|
|
||||||
const QString &propertyName) const;
|
|
||||||
|
|
||||||
[[nodiscard]] std::optional<int> scaleFactor() const;
|
[[nodiscard]] std::optional<int> scaleFactor() const;
|
||||||
|
|
||||||
|
|
|
@ -24,25 +24,6 @@ bool GtkIntegration::loaded() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GtkIntegration::checkVersion(uint major, uint minor, uint micro) const {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<bool> GtkIntegration::getBoolSetting(
|
|
||||||
const QString &propertyName) const {
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<int> GtkIntegration::getIntSetting(
|
|
||||||
const QString &propertyName) const {
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<QString> GtkIntegration::getStringSetting(
|
|
||||||
const QString &propertyName) const {
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<int> GtkIntegration::scaleFactor() const {
|
std::optional<int> GtkIntegration::scaleFactor() const {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QtCore/QLibrary>
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#undef signals
|
#undef signals
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
@ -16,16 +14,6 @@ extern "C" {
|
||||||
#define signals public
|
#define signals public
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|
||||||
#if defined DESKTOP_APP_USE_PACKAGED && !defined DESKTOP_APP_USE_PACKAGED_LAZY
|
|
||||||
#define LINK_TO_GTK
|
|
||||||
#endif // DESKTOP_APP_USE_PACKAGED && !DESKTOP_APP_USE_PACKAGED_LAZY
|
|
||||||
|
|
||||||
#ifdef LINK_TO_GTK
|
|
||||||
#define LOAD_GTK_SYMBOL(lib, name, func) (func = ::func)
|
|
||||||
#else // LINK_TO_GTK
|
|
||||||
#define LOAD_GTK_SYMBOL Platform::Gtk::LoadSymbol
|
|
||||||
#endif // !LINK_TO_GTK
|
|
||||||
|
|
||||||
// To be able to compile with gtk-2.0 headers as well
|
// To be able to compile with gtk-2.0 headers as well
|
||||||
typedef struct _GdkMonitor GdkMonitor;
|
typedef struct _GdkMonitor GdkMonitor;
|
||||||
typedef struct _GtkAppChooser GtkAppChooser;
|
typedef struct _GtkAppChooser GtkAppChooser;
|
||||||
|
@ -33,24 +21,6 @@ typedef struct _GtkAppChooser GtkAppChooser;
|
||||||
namespace Platform {
|
namespace Platform {
|
||||||
namespace Gtk {
|
namespace Gtk {
|
||||||
|
|
||||||
template <typename Function>
|
|
||||||
bool LoadSymbol(QLibrary &lib, const char *name, Function &func) {
|
|
||||||
func = nullptr;
|
|
||||||
if (!lib.isLoaded()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
func = reinterpret_cast<Function>(lib.resolve(name));
|
|
||||||
if (func) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
LOG(("Error: failed to load '%1' function!").arg(name));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline gboolean (*gtk_init_check)(int *argc, char ***argv) = nullptr;
|
|
||||||
inline const gchar* (*gtk_check_version)(guint required_major, guint required_minor, guint required_micro) = nullptr;
|
|
||||||
inline GtkSettings* (*gtk_settings_get_default)(void) = nullptr;
|
|
||||||
inline void (*gtk_widget_show)(GtkWidget *widget) = nullptr;
|
inline void (*gtk_widget_show)(GtkWidget *widget) = nullptr;
|
||||||
inline void (*gtk_widget_hide)(GtkWidget *widget) = nullptr;
|
inline void (*gtk_widget_hide)(GtkWidget *widget) = nullptr;
|
||||||
inline GdkWindow* (*gtk_widget_get_window)(GtkWidget *widget) = nullptr;
|
inline GdkWindow* (*gtk_widget_get_window)(GtkWidget *widget) = nullptr;
|
||||||
|
@ -90,7 +60,6 @@ inline GtkWidget* (*gtk_image_new)(void) = nullptr;
|
||||||
inline void (*gtk_image_set_from_pixbuf)(GtkImage *image, GdkPixbuf *pixbuf) = nullptr;
|
inline void (*gtk_image_set_from_pixbuf)(GtkImage *image, GdkPixbuf *pixbuf) = nullptr;
|
||||||
inline GtkWidget* (*gtk_app_chooser_dialog_new)(GtkWindow *parent, GtkDialogFlags flags, GFile *file) = nullptr;
|
inline GtkWidget* (*gtk_app_chooser_dialog_new)(GtkWindow *parent, GtkDialogFlags flags, GFile *file) = nullptr;
|
||||||
inline GAppInfo* (*gtk_app_chooser_get_app_info)(GtkAppChooser *self) = nullptr;
|
inline GAppInfo* (*gtk_app_chooser_get_app_info)(GtkAppChooser *self) = nullptr;
|
||||||
inline void (*gdk_set_allowed_backends)(const gchar *backends) = nullptr;
|
|
||||||
inline void (*gdk_window_set_modal_hint)(GdkWindow *window, gboolean modal) = nullptr;
|
inline void (*gdk_window_set_modal_hint)(GdkWindow *window, gboolean modal) = nullptr;
|
||||||
inline void (*gdk_window_focus)(GdkWindow *window, guint32 timestamp) = nullptr;
|
inline void (*gdk_window_focus)(GdkWindow *window, guint32 timestamp) = nullptr;
|
||||||
|
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#include "platform/linux/linux_xlib_helper.h"
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Platform {
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
class XErrorHandlerRestorer::Private {
|
|
||||||
public:
|
|
||||||
Private()
|
|
||||||
: _oldErrorHandler(XSetErrorHandler(nullptr)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
~Private() {
|
|
||||||
XSetErrorHandler(_oldErrorHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
int (*_oldErrorHandler)(Display *, XErrorEvent *);
|
|
||||||
};
|
|
||||||
|
|
||||||
XErrorHandlerRestorer::XErrorHandlerRestorer()
|
|
||||||
: _private(std::make_unique<Private>()) {
|
|
||||||
}
|
|
||||||
|
|
||||||
XErrorHandlerRestorer::~XErrorHandlerRestorer() = default;
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace Platform
|
|
|
@ -1,24 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace Platform {
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
class XErrorHandlerRestorer {
|
|
||||||
public:
|
|
||||||
XErrorHandlerRestorer();
|
|
||||||
~XErrorHandlerRestorer();
|
|
||||||
|
|
||||||
private:
|
|
||||||
class Private;
|
|
||||||
const std::unique_ptr<Private> _private;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace Platform
|
|
|
@ -24,7 +24,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "window/window_controller.h"
|
#include "window/window_controller.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "base/platform/base_platform_info.h"
|
#include "base/platform/base_platform_info.h"
|
||||||
#include "base/platform/linux/base_xcb_utilities_linux.h"
|
#include "base/platform/linux/base_linux_xcb_utilities.h"
|
||||||
#include "base/call_delayed.h"
|
#include "base/call_delayed.h"
|
||||||
#include "ui/widgets/popup_menu.h"
|
#include "ui/widgets/popup_menu.h"
|
||||||
#include "ui/widgets/input_fields.h"
|
#include "ui/widgets/input_fields.h"
|
||||||
|
|
|
@ -8,7 +8,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "platform/linux/specific_linux.h"
|
#include "platform/linux/specific_linux.h"
|
||||||
|
|
||||||
#include "base/platform/base_platform_info.h"
|
#include "base/platform/base_platform_info.h"
|
||||||
#include "base/platform/linux/base_xcb_utilities_linux.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_desktop_environment.h"
|
||||||
#include "platform/linux/linux_gtk_integration.h"
|
#include "platform/linux/linux_gtk_integration.h"
|
||||||
#include "platform/linux/linux_wayland_integration.h"
|
#include "platform/linux/linux_wayland_integration.h"
|
||||||
|
@ -60,6 +61,7 @@ extern "C" {
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
using namespace Platform;
|
using namespace Platform;
|
||||||
|
using BaseGtkIntegration = base::Platform::GtkIntegration;
|
||||||
using Platform::internal::WaylandIntegration;
|
using Platform::internal::WaylandIntegration;
|
||||||
using Platform::internal::GtkIntegration;
|
using Platform::internal::GtkIntegration;
|
||||||
|
|
||||||
|
@ -68,8 +70,6 @@ Q_DECLARE_METATYPE(QMargins);
|
||||||
namespace Platform {
|
namespace Platform {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr auto kIgnoreGtkIncompatibility = "TDESKTOP_I_KNOW_ABOUT_GTK_INCOMPATIBILITY"_cs;
|
|
||||||
|
|
||||||
constexpr auto kDesktopFile = ":/misc/telegramdesktop.desktop"_cs;
|
constexpr auto kDesktopFile = ":/misc/telegramdesktop.desktop"_cs;
|
||||||
constexpr auto kIconName = "telegram"_cs;
|
constexpr auto kIconName = "telegram"_cs;
|
||||||
constexpr auto kHandlerTypeName = "x-scheme-handler/tg"_cs;
|
constexpr auto kHandlerTypeName = "x-scheme-handler/tg"_cs;
|
||||||
|
@ -80,8 +80,6 @@ constexpr auto kPropertiesInterface = "org.freedesktop.DBus.Properties"_cs;
|
||||||
|
|
||||||
constexpr auto kXCBFrameExtentsAtomName = "_GTK_FRAME_EXTENTS"_cs;
|
constexpr auto kXCBFrameExtentsAtomName = "_GTK_FRAME_EXTENTS"_cs;
|
||||||
|
|
||||||
QStringList PlatformThemes;
|
|
||||||
|
|
||||||
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
|
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
|
||||||
std::unique_ptr<internal::NotificationServiceWatcher> NSWInstance;
|
std::unique_ptr<internal::NotificationServiceWatcher> NSWInstance;
|
||||||
|
|
||||||
|
@ -562,27 +560,6 @@ bool InSnap() {
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsStaticBinary() {
|
|
||||||
#ifdef DESKTOP_APP_USE_PACKAGED
|
|
||||||
return false;
|
|
||||||
#else // DESKTOP_APP_USE_PACKAGED
|
|
||||||
return true;
|
|
||||||
#endif // !DESKTOP_APP_USE_PACKAGED
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsGtkIntegrationForced() {
|
|
||||||
static const auto Result = [&] {
|
|
||||||
if (!GtkIntegration::Instance()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return PlatformThemes.contains(qstr("gtk3"), Qt::CaseInsensitive)
|
|
||||||
|| PlatformThemes.contains(qstr("gtk2"), Qt::CaseInsensitive);
|
|
||||||
}();
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AreQtPluginsBundled() {
|
bool AreQtPluginsBundled() {
|
||||||
#if !defined DESKTOP_APP_USE_PACKAGED || defined DESKTOP_APP_USE_PACKAGED_LAZY
|
#if !defined DESKTOP_APP_USE_PACKAGED || defined DESKTOP_APP_USE_PACKAGED_LAZY
|
||||||
return true;
|
return true;
|
||||||
|
@ -719,7 +696,7 @@ QImage GetImageFromClipboard() {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<bool> IsDarkMode() {
|
std::optional<bool> IsDarkMode() {
|
||||||
const auto integration = GtkIntegration::Instance();
|
const auto integration = BaseGtkIntegration::Instance();
|
||||||
if (!integration) {
|
if (!integration) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
@ -832,7 +809,7 @@ bool WindowsNeedShadow() {
|
||||||
|
|
||||||
Window::ControlsLayout WindowControlsLayout() {
|
Window::ControlsLayout WindowControlsLayout() {
|
||||||
const auto gtkResult = []() -> std::optional<Window::ControlsLayout> {
|
const auto gtkResult = []() -> std::optional<Window::ControlsLayout> {
|
||||||
const auto integration = GtkIntegration::Instance();
|
const auto integration = BaseGtkIntegration::Instance();
|
||||||
if (!integration || !integration->checkVersion(3, 12, 0)) {
|
if (!integration || !integration->checkVersion(3, 12, 0)) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
@ -962,53 +939,15 @@ int psFixPrevious() {
|
||||||
namespace Platform {
|
namespace Platform {
|
||||||
|
|
||||||
void start() {
|
void start() {
|
||||||
PlatformThemes = QString::fromUtf8(qgetenv("QT_QPA_PLATFORMTHEME"))
|
|
||||||
.split(':', base::QStringSkipEmptyParts);
|
|
||||||
|
|
||||||
LOG(("Launcher filename: %1").arg(GetLauncherFilename()));
|
LOG(("Launcher filename: %1").arg(GetLauncherFilename()));
|
||||||
|
|
||||||
qputenv("PULSE_PROP_application.name", AppName.utf8());
|
qputenv("PULSE_PROP_application.name", AppName.utf8());
|
||||||
qputenv("PULSE_PROP_application.icon_name", GetIconName().toLatin1());
|
qputenv("PULSE_PROP_application.icon_name", GetIconName().toLatin1());
|
||||||
|
|
||||||
// if gtk integration and qgtk3/qgtk2 platformtheme (or qgtk2 style)
|
if (const auto integration = BaseGtkIntegration::Instance()) {
|
||||||
// is used at the same time, the app will crash
|
integration->prepareEnvironment();
|
||||||
if (GtkIntegration::Instance()
|
} else {
|
||||||
&& !IsStaticBinary()
|
g_warning("GTK integration is disabled, some feature unavailable. ");
|
||||||
&& !qEnvironmentVariableIsSet(
|
|
||||||
kIgnoreGtkIncompatibility.utf8())) {
|
|
||||||
g_warning(
|
|
||||||
"Unfortunately, GTK integration "
|
|
||||||
"conflicts with qgtk2 platformtheme and style. "
|
|
||||||
"Therefore, QT_QPA_PLATFORMTHEME "
|
|
||||||
"and QT_STYLE_OVERRIDE will be unset.");
|
|
||||||
|
|
||||||
g_message(
|
|
||||||
"This can be ignored by setting %s environment variable "
|
|
||||||
"to any value, however, if qgtk2 theme or style is used, "
|
|
||||||
"this will lead to a crash.",
|
|
||||||
kIgnoreGtkIncompatibility.utf8().constData());
|
|
||||||
|
|
||||||
g_message(
|
|
||||||
"GTK integration can be disabled by setting %s to any value. "
|
|
||||||
"Keep in mind that this will lead to clipboard issues "
|
|
||||||
"and tdesktop will be unable to get settings from GTK "
|
|
||||||
"(such as decoration layout, dark mode & more).",
|
|
||||||
internal::kDisableGtkIntegration.utf8().constData());
|
|
||||||
|
|
||||||
qunsetenv("QT_QPA_PLATFORMTHEME");
|
|
||||||
qunsetenv("QT_STYLE_OVERRIDE");
|
|
||||||
|
|
||||||
// Don't allow qgtk3 to init gtk earlier than us
|
|
||||||
if (DesktopEnvironment::IsGtkBased()) {
|
|
||||||
QApplication::setDesktopSettingsAware(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!GtkIntegration::Instance()) {
|
|
||||||
g_warning(
|
|
||||||
"GTK integration was disabled on build or in runtime. "
|
|
||||||
"This will lead to clipboard issues and a lack of some features "
|
|
||||||
"(like Auto-Night Mode or system window controls layout).");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DESKTOP_APP_USE_PACKAGED_RLOTTIE
|
#ifdef DESKTOP_APP_USE_PACKAGED_RLOTTIE
|
||||||
|
@ -1227,13 +1166,17 @@ void start() {
|
||||||
DEBUG_LOG(("Icon theme: %1").arg(QIcon::themeName()));
|
DEBUG_LOG(("Icon theme: %1").arg(QIcon::themeName()));
|
||||||
DEBUG_LOG(("Fallback icon theme: %1").arg(QIcon::fallbackThemeName()));
|
DEBUG_LOG(("Fallback icon theme: %1").arg(QIcon::fallbackThemeName()));
|
||||||
|
|
||||||
|
if (const auto integration = BaseGtkIntegration::Instance()) {
|
||||||
|
integration->load();
|
||||||
|
}
|
||||||
|
|
||||||
if (const auto integration = GtkIntegration::Instance()) {
|
if (const auto integration = GtkIntegration::Instance()) {
|
||||||
integration->load();
|
integration->load();
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait for interface announce to know if native window frame is supported
|
// wait for interface announce to know if native window frame is supported
|
||||||
if (const auto waylandIntegration = WaylandIntegration::Instance()) {
|
if (const auto integration = WaylandIntegration::Instance()) {
|
||||||
waylandIntegration->waitForInterfaceAnnounce();
|
integration->waitForInterfaceAnnounce();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
|
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
|
||||||
|
|
|
@ -17,9 +17,7 @@ namespace Platform {
|
||||||
|
|
||||||
bool InFlatpak();
|
bool InFlatpak();
|
||||||
bool InSnap();
|
bool InSnap();
|
||||||
bool IsStaticBinary();
|
|
||||||
bool AreQtPluginsBundled();
|
bool AreQtPluginsBundled();
|
||||||
bool IsGtkIntegrationForced();
|
|
||||||
bool UseXDGDesktopPortal();
|
bool UseXDGDesktopPortal();
|
||||||
bool CanOpenDirectoryWithPortal();
|
bool CanOpenDirectoryWithPortal();
|
||||||
bool IsNotificationServiceActivatable();
|
bool IsNotificationServiceActivatable();
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
# For license and copyright information please follow this link:
|
# For license and copyright information please follow this link:
|
||||||
# https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
# https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
option(TDESKTOP_DISABLE_GTK_INTEGRATION "Disable all code for GTK integration (Linux only)." OFF)
|
|
||||||
option(TDESKTOP_API_TEST "Use test API credentials." OFF)
|
option(TDESKTOP_API_TEST "Use test API credentials." OFF)
|
||||||
set(TDESKTOP_API_ID "0" CACHE STRING "Provide 'api_id' for the Telegram API access.")
|
set(TDESKTOP_API_ID "0" CACHE STRING "Provide 'api_id' for the Telegram API access.")
|
||||||
set(TDESKTOP_API_HASH "" CACHE STRING "Provide 'api_hash' for the Telegram API access.")
|
set(TDESKTOP_API_HASH "" CACHE STRING "Provide 'api_hash' for the Telegram API access.")
|
||||||
|
@ -52,10 +51,6 @@ if (DESKTOP_APP_SPECIAL_TARGET)
|
||||||
target_compile_definitions(Telegram PRIVATE TDESKTOP_ALLOW_CLOSED_ALPHA)
|
target_compile_definitions(Telegram PRIVATE TDESKTOP_ALLOW_CLOSED_ALPHA)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (TDESKTOP_DISABLE_GTK_INTEGRATION)
|
|
||||||
target_compile_definitions(Telegram PRIVATE TDESKTOP_DISABLE_GTK_INTEGRATION)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (NOT TDESKTOP_LAUNCHER_BASENAME)
|
if (NOT TDESKTOP_LAUNCHER_BASENAME)
|
||||||
set(TDESKTOP_LAUNCHER_BASENAME "telegramdesktop")
|
set(TDESKTOP_LAUNCHER_BASENAME "telegramdesktop")
|
||||||
endif()
|
endif()
|
||||||
|
|
Loading…
Add table
Reference in a new issue