From dcd6028e918e8d628eaa836d6f49e0e7564b3f6c Mon Sep 17 00:00:00 2001 From: John Preston Date: Sun, 26 Feb 2017 20:19:35 +0300 Subject: [PATCH] Loading libunity only in Unity and Pantheon. #3053 Commit 296c800b39 introduced a regression which caused crashes in some ArchLinux distros when attempting to load or use libunity. --- .../linux/linux_desktop_environment.cpp | 112 ++++++++++++++++++ .../linux/linux_desktop_environment.h | 76 ++++++++++++ .../SourceFiles/platform/linux/linux_libs.cpp | 13 +- .../platform/linux/main_window_linux.cpp | 7 +- Telegram/gyp/Telegram.gyp | 4 + 5 files changed, 204 insertions(+), 8 deletions(-) create mode 100644 Telegram/SourceFiles/platform/linux/linux_desktop_environment.cpp create mode 100644 Telegram/SourceFiles/platform/linux/linux_desktop_environment.h diff --git a/Telegram/SourceFiles/platform/linux/linux_desktop_environment.cpp b/Telegram/SourceFiles/platform/linux/linux_desktop_environment.cpp new file mode 100644 index 000000000..ac29a2300 --- /dev/null +++ b/Telegram/SourceFiles/platform/linux/linux_desktop_environment.cpp @@ -0,0 +1,112 @@ +/* +This file is part of Telegram Desktop, +the official desktop version of Telegram messaging app, see https://telegram.org + +Telegram Desktop is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +It is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +In addition, as a special exception, the copyright holders give permission +to link the code of portions of this program with the OpenSSL library. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org +*/ +#include "stdafx.h" +#include "platform/linux/linux_desktop_environment.h" + +namespace Platform { +namespace DesktopEnvironment { +namespace { + +QString GetEnv(const char *name) { + auto result = getenv(name); + return result ? QString::fromLatin1(result) : QString(); +} + +Type Compute() { + auto xdgCurrentDesktop = GetEnv("XDG_CURRENT_DESKTOP").toLower(); + auto list = xdgCurrentDesktop.split(':', QString::SkipEmptyParts); + auto desktopSession = GetEnv("DESKTOP_SESSION").toLower(); + auto kdeSession = GetEnv("KDE_SESSION_VERSION"); + + if (!list.isEmpty()) { + if (list.contains("unity")) { + // gnome-fallback sessions set XDG_CURRENT_DESKTOP to Unity + // DESKTOP_SESSION can be gnome-fallback or gnome-fallback-compiz + if (desktopSession.indexOf(qstr("gnome-fallback")) >= 0) { + return Type::Gnome; + } + return Type::Unity; + } else if (list.contains("xfce")) { + return Type::XFCE; + } else if (list.contains("pantheon")) { + return Type::Pantheon; + } else if (list.contains("gnome")) { + return Type::Gnome; + } else if (list.contains("kde")) { + if (kdeSession == qstr("5")) { + return Type::KDE5; + } + return Type::KDE4; + } + } + + if (!desktopSession.isEmpty()) { + if (desktopSession == qstr("gnome") || desktopSession == qstr("mate")) { + return Type::Gnome; + } else if (desktopSession == qstr("kde4") || desktopSession == qstr("kde-plasma")) { + return Type::KDE4; + } else if (desktopSession == qstr("kde")) { + // This may mean KDE4 on newer systems, so we have to check. + if (!kdeSession.isEmpty()) { + return Type::KDE4; + } + return Type::KDE3; + } else if (desktopSession.indexOf(qstr("xfce")) >= 0 || desktopSession == qstr("xubuntu")) { + return Type::XFCE; + } + } + + // Fall back on some older environment variables. + // Useful particularly in the DESKTOP_SESSION=default case. + if (!GetEnv("GNOME_DESKTOP_SESSION_ID").isEmpty()) { + return Type::Gnome; + } else if (!GetEnv("KDE_FULL_SESSION").isEmpty()) { + if (!kdeSession.isEmpty()) { + return Type::KDE4; + } + return Type::KDE3; + } + + return Type::Other; +} + +} // namespace + +// Thanks Chromium. +Type Get() { + static const auto result = Compute(); + return result; +} + +bool TryQtTrayIcon() { + return !IsPantheon() && !IsGnome(); +} + +bool PreferAppIndicatorTrayIcon() { + return IsXFCE() || IsUnity(); +} + +bool TryUnityCounter() { + return IsUnity() || IsPantheon(); +} + +} // namespace DesktopEnvironment +} // namespace Platform \ No newline at end of file diff --git a/Telegram/SourceFiles/platform/linux/linux_desktop_environment.h b/Telegram/SourceFiles/platform/linux/linux_desktop_environment.h new file mode 100644 index 000000000..43b676c8e --- /dev/null +++ b/Telegram/SourceFiles/platform/linux/linux_desktop_environment.h @@ -0,0 +1,76 @@ +/* +This file is part of Telegram Desktop, +the official desktop version of Telegram messaging app, see https://telegram.org + +Telegram Desktop is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +It is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +In addition, as a special exception, the copyright holders give permission +to link the code of portions of this program with the OpenSSL library. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org +*/ +#pragma once + +namespace Platform { +namespace DesktopEnvironment { + +enum class Type { + Other, + Gnome, + KDE3, + KDE4, + KDE5, + Unity, + XFCE, + Pantheon, +}; + +Type Get(); + +inline bool IsGnome() { + return Get() == Type::Gnome; +} + +inline bool IsKDE3() { + return Get() == Type::KDE3; +} + +inline bool IsKDE4() { + return Get() == Type::KDE4; +} + +inline bool IsKDE5() { + return Get() == Type::KDE5; +} + +inline bool IsKDE() { + return IsKDE3() || IsKDE4() || IsKDE5(); +} + +inline bool IsUnity() { + return Get() == Type::Unity; +} + +inline bool IsXFCE() { + return Get() == Type::XFCE; +} + +inline bool IsPantheon() { + return Get() == Type::Pantheon; +} + +bool TryQtTrayIcon(); +bool PreferAppIndicatorTrayIcon(); +bool TryUnityCounter(); + +} // namespace DesktopEnvironment +} // namespace Platform diff --git a/Telegram/SourceFiles/platform/linux/linux_libs.cpp b/Telegram/SourceFiles/platform/linux/linux_libs.cpp index 372a012fb..06cb5f132 100644 --- a/Telegram/SourceFiles/platform/linux/linux_libs.cpp +++ b/Telegram/SourceFiles/platform/linux/linux_libs.cpp @@ -23,6 +23,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "platform/linux/linux_gdk_helper.h" #include "platform/linux/linux_libnotify.h" +#include "platform/linux/linux_desktop_environment.h" namespace Platform { namespace Libs { @@ -271,12 +272,14 @@ void start() { } #ifndef TDESKTOP_DISABLE_UNITY_INTEGRATION - QLibrary lib_unity(qstr("unity"), 9, 0); - loadLibrary(lib_unity, "unity", 9); + if (DesktopEnvironment::TryUnityCounter()) { + QLibrary lib_unity(qstr("unity"), 9, 0); + loadLibrary(lib_unity, "unity", 9); - load(lib_unity, "unity_launcher_entry_get_for_desktop_id", unity_launcher_entry_get_for_desktop_id); - load(lib_unity, "unity_launcher_entry_set_count", unity_launcher_entry_set_count); - load(lib_unity, "unity_launcher_entry_set_count_visible", unity_launcher_entry_set_count_visible); + load(lib_unity, "unity_launcher_entry_get_for_desktop_id", unity_launcher_entry_get_for_desktop_id); + load(lib_unity, "unity_launcher_entry_set_count", unity_launcher_entry_set_count); + load(lib_unity, "unity_launcher_entry_set_count_visible", unity_launcher_entry_set_count_visible); + } #endif // !TDESKTOP_DISABLE_UNITY_INTEGRATION if (gtkLoaded) { diff --git a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp index e0ed58639..bcf4b6015 100644 --- a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp @@ -23,6 +23,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "styles/style_window.h" #include "platform/linux/linux_libs.h" +#include "platform/linux/linux_desktop_environment.h" #include "platform/platform_notifications_manager.h" #include "mainwindow.h" #include "application.h" @@ -377,9 +378,9 @@ bool MainWindow::psHasNativeNotifications() { } void MainWindow::LibsLoaded() { - QStringList cdesktop = QString(getenv("XDG_CURRENT_DESKTOP")).toLower().split(':'); - noQtTrayIcon = (cdesktop.contains(qstr("pantheon"))) || (cdesktop.contains(qstr("gnome"))); - tryAppIndicator = (cdesktop.contains(qstr("xfce")) || cdesktop.contains(qstr("unity"))); + auto cdesktop = Libs::CurrentDesktopStrings(); + noQtTrayIcon = !DesktopEnvironment::TryQtTrayIcon(); + tryAppIndicator = !DesktopEnvironment::PreferAppIndicatorTrayIcon(); if (noQtTrayIcon) cSetSupportTray(false); diff --git a/Telegram/gyp/Telegram.gyp b/Telegram/gyp/Telegram.gyp index 53aa6bf99..87040cc02 100644 --- a/Telegram/gyp/Telegram.gyp +++ b/Telegram/gyp/Telegram.gyp @@ -366,6 +366,8 @@ '<(src_loc)/pspecific_mac_p.h', '<(src_loc)/pspecific_linux.cpp', '<(src_loc)/pspecific_linux.h', + '<(src_loc)/platform/linux/linux_desktop_environment.cpp', + '<(src_loc)/platform/linux/linux_desktop_environment.h', '<(src_loc)/platform/linux/linux_gdk_helper.cpp', '<(src_loc)/platform/linux/linux_gdk_helper.h', '<(src_loc)/platform/linux/linux_libnotify.cpp', @@ -614,6 +616,8 @@ 'sources!': [ '<(src_loc)/pspecific_linux.cpp', '<(src_loc)/pspecific_linux.h', + '<(src_loc)/platform/linux/linux_desktop_environment.cpp', + '<(src_loc)/platform/linux/linux_desktop_environment.h', '<(src_loc)/platform/linux/linux_gdk_helper.cpp', '<(src_loc)/platform/linux/linux_gdk_helper.h', '<(src_loc)/platform/linux/linux_libnotify.cpp',