diff --git a/.travis/build.sh b/.travis/build.sh index 99ca6d464e..6e0a0ae0d8 100755 --- a/.travis/build.sh +++ b/.travis/build.sh @@ -108,7 +108,7 @@ build() { cd "$srcdir/Libraries/qt${_qtver}" ./configure -prefix "$srcdir/qt" -release -opensource -confirm-license -qt-zlib \ -qt-libpng -qt-libjpeg -qt-freetype -qt-harfbuzz -qt-pcre -qt-xcb \ - -qt-xkbcommon-x11 -no-opengl -static -nomake examples -nomake tests + -qt-xkbcommon-x11 -no-opengl -no-gtkstyle -static -nomake examples -nomake tests make --silent -j4 make --silent -j4 install diff --git a/Telegram/SourceFiles/main.cpp b/Telegram/SourceFiles/main.cpp index e010502d5d..3fc2ce67ad 100644 --- a/Telegram/SourceFiles/main.cpp +++ b/Telegram/SourceFiles/main.cpp @@ -44,21 +44,9 @@ int main(int argc, char *argv[]) { Logs::start(); // must be started before Platform is started Platform::start(); // must be started before QApplication is created - // prepare fake args to disable QT_STYLE_OVERRIDE env variable - // currently this is required in some desktop environments, including Xubuntu 15.10 - // when we don't default style to "none" Qt dynamically loads GTK somehow internally and - // our own GTK dynamic load and usage leads GTK errors and freeze of the current main thread - // we can't disable our own GTK loading because it is required by libappindicator, which - // provides the tray icon for this system, because Qt tray icon is broken there - // see https://github.com/telegramdesktop/tdesktop/issues/1774 - QByteArray args[] = { "-style=0" }; - static const int a_cnt = sizeof(args) / sizeof(args[0]); - int a_argc = a_cnt + 1; - char *a_argv[a_cnt + 1] = { argv[0], args[0].data() }; - int result = 0; { - Application app(a_argc, a_argv); + Application app(argc, argv); result = app.exec(); } diff --git a/Telegram/SourceFiles/platform/linux/file_dialog_linux.cpp b/Telegram/SourceFiles/platform/linux/file_dialog_linux.cpp index 9a2577c4e2..f47e871c6b 100644 --- a/Telegram/SourceFiles/platform/linux/file_dialog_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/file_dialog_linux.cpp @@ -115,20 +115,17 @@ bool Get(QStringList &files, QByteArray &remoteContent, const QString &caption, namespace internal { -QGtkDialog::QGtkDialog(GtkWidget *gtkWidget) : gtkWidget(gtkWidget) -{ - g_signal_connect_swapped(G_OBJECT(gtkWidget), "response", G_CALLBACK(onResponse), this); - g_signal_connect(G_OBJECT(gtkWidget), "delete-event", G_CALLBACK(Libs::gtk_widget_hide_on_delete), NULL); +QGtkDialog::QGtkDialog(GtkWidget *gtkWidget) : gtkWidget(gtkWidget) { + Libs::g_signal_connect_swapped_helper(Libs::g_object_cast(gtkWidget), "response", GCallback(onResponse), this); + Libs::g_signal_connect_helper(Libs::g_object_cast(gtkWidget), "delete-event", GCallback(Libs::gtk_widget_hide_on_delete), NULL); } -QGtkDialog::~QGtkDialog() -{ +QGtkDialog::~QGtkDialog() { Libs::gtk_clipboard_store(Libs::gtk_clipboard_get(GDK_SELECTION_CLIPBOARD)); Libs::gtk_widget_destroy(gtkWidget); } -GtkDialog *QGtkDialog::gtkDialog() const -{ +GtkDialog *QGtkDialog::gtkDialog() const { return Libs::gtk_dialog_cast(gtkWidget); } @@ -183,8 +180,7 @@ void QGtkDialog::onResponse(QGtkDialog *dialog, int response) { emit dialog->reject(); } -void QGtkDialog::onParentWindowDestroyed() -{ +void QGtkDialog::onParentWindowDestroyed() { // The Gtk*DialogHelper classes own this object. Make sure the parent doesn't delete it. setParent(nullptr); } @@ -224,8 +220,8 @@ GtkFileDialog::GtkFileDialog(QWidget *parent, const QString &caption, const QStr connect(d.data(), SIGNAL(accept()), this, SLOT(onAccepted())); connect(d.data(), SIGNAL(reject()), this, SLOT(onRejected())); - g_signal_connect(Libs::gtk_file_chooser_cast(d->gtkDialog()), "selection-changed", G_CALLBACK(onSelectionChanged), this); - g_signal_connect_swapped(Libs::gtk_file_chooser_cast(d->gtkDialog()), "current-folder-changed", G_CALLBACK(onCurrentFolderChanged), this); + Libs::g_signal_connect_helper(Libs::gtk_file_chooser_cast(d->gtkDialog()), "selection-changed", G_CALLBACK(onSelectionChanged), this); + Libs::g_signal_connect_swapped_helper(Libs::gtk_file_chooser_cast(d->gtkDialog()), "current-folder-changed", G_CALLBACK(onCurrentFolderChanged), this); } GtkFileDialog::~GtkFileDialog() { @@ -313,7 +309,7 @@ QDir GtkFileDialog::directory() const { gchar *folder = Libs::gtk_file_chooser_get_current_folder(Libs::gtk_file_chooser_cast(gtkDialog)); if (folder) { ret = QString::fromUtf8(folder); - g_free(folder); + Libs::g_free(folder); } return QDir(ret); } @@ -334,7 +330,7 @@ QStringList GtkFileDialog::selectedFiles() const { GSList *filenames = Libs::gtk_file_chooser_get_filenames(Libs::gtk_file_chooser_cast(gtkDialog)); for (GSList *it = filenames; it; it = it->next) selection += QString::fromUtf8((const char*)it->data); - g_slist_free(filenames); + Libs::g_slist_free(filenames); return selection; } diff --git a/Telegram/SourceFiles/platform/linux/linux_gdk_helper.cpp b/Telegram/SourceFiles/platform/linux/linux_gdk_helper.cpp index 80d29af2d6..17e93b8603 100644 --- a/Telegram/SourceFiles/platform/linux/linux_gdk_helper.cpp +++ b/Telegram/SourceFiles/platform/linux/linux_gdk_helper.cpp @@ -51,19 +51,15 @@ using f_gdk_x11_drawable_get_xid = XID(*)(GdkDrawable*); f_gdk_x11_drawable_get_xid gdk_x11_drawable_get_xid = nullptr; // Gtk 3 - -// To be able to compile with gtk-2.0 headers as well -#ifndef GDK_TYPE_X11_WINDOW -#define GDK_TYPE_X11_WINDOW (gdk_x11_window_get_type()) -#endif // GDK_TYPE_X11_WINDOW - -#ifndef GDK_IS_X11_WINDOW -#define GDK_IS_X11_WINDOW(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), GDK_TYPE_X11_WINDOW)) -#endif // GDK_IS_X11_WINDOW - using f_gdk_x11_window_get_type = GType (*)(void); f_gdk_x11_window_get_type gdk_x11_window_get_type = nullptr; +// To be able to compile with gtk-2.0 headers as well +template +inline bool gdk_is_x11_window_check(Object *obj) { + return Libs::g_type_cit_helper(obj, gdk_x11_window_get_type()); +} + using f_gdk_window_get_display = GdkDisplay*(*)(GdkWindow *window); f_gdk_window_get_display gdk_window_get_display = nullptr; @@ -106,7 +102,7 @@ void XSetTransientForHint(GdkWindow *window, quintptr winId) { gdk_x11_drawable_get_xid(window), winId); } else if (gdk_helper_loaded == GtkLoaded::Gtk3) { - if (GDK_IS_X11_WINDOW(window)) { + 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); diff --git a/Telegram/SourceFiles/platform/linux/linux_libs.cpp b/Telegram/SourceFiles/platform/linux/linux_libs.cpp index 3311ddca36..484b6c534d 100644 --- a/Telegram/SourceFiles/platform/linux/linux_libs.cpp +++ b/Telegram/SourceFiles/platform/linux/linux_libs.cpp @@ -90,10 +90,13 @@ bool setupGtkBase(QLibrary &lib_gtk) { if (!load(lib_gtk, "gtk_dialog_run", gtk_dialog_run)) return false; if (!load(lib_gtk, "g_type_check_instance_cast", g_type_check_instance_cast)) return false; + if (!load(lib_gtk, "g_type_check_instance_is_a", g_type_check_instance_is_a)) return false; if (!load(lib_gtk, "g_signal_connect_data", g_signal_connect_data)) return false; if (!load(lib_gtk, "g_object_ref_sink", g_object_ref_sink)) return false; if (!load(lib_gtk, "g_object_unref", g_object_unref)) return false; + if (!load(lib_gtk, "g_free", g_free)) return false; + if (!load(lib_gtk, "g_slist_free", g_slist_free)) return false; DEBUG_LOG(("Library gtk functions loaded!")); if (!gtk_init_check(0, 0)) { @@ -164,6 +167,7 @@ f_gdk_window_focus gdk_window_focus = nullptr; f_gtk_dialog_get_type gtk_dialog_get_type = nullptr; f_gtk_dialog_run gtk_dialog_run = nullptr; f_g_type_check_instance_cast g_type_check_instance_cast = nullptr; +f_g_type_check_instance_is_a g_type_check_instance_is_a = nullptr; f_g_signal_connect_data g_signal_connect_data = nullptr; f_app_indicator_new app_indicator_new = nullptr; f_app_indicator_set_status app_indicator_set_status = nullptr; @@ -186,6 +190,8 @@ f_gtk_get_current_event_time gtk_get_current_event_time = nullptr; f_g_object_ref_sink g_object_ref_sink = nullptr; f_g_object_unref g_object_unref = nullptr; f_g_idle_add g_idle_add = nullptr; +f_g_free g_free = nullptr; +f_g_slist_free g_slist_free = nullptr; #ifndef TDESKTOP_DISABLE_UNITY_INTEGRATION f_unity_launcher_entry_set_count unity_launcher_entry_set_count = nullptr; f_unity_launcher_entry_set_count_visible unity_launcher_entry_set_count_visible = nullptr; diff --git a/Telegram/SourceFiles/platform/linux/linux_libs.h b/Telegram/SourceFiles/platform/linux/linux_libs.h index b83214be5c..d51db1c677 100644 --- a/Telegram/SourceFiles/platform/linux/linux_libs.h +++ b/Telegram/SourceFiles/platform/linux/linux_libs.h @@ -198,6 +198,11 @@ inline GtkDialog *gtk_dialog_cast(Object *obj) { return g_type_cic_helper(obj, gtk_dialog_get_type()); } +template +inline GObject *g_object_cast(Object *obj) { + return g_type_cic_helper(obj, G_TYPE_OBJECT); +} + typedef GType (*f_gtk_file_chooser_get_type)(void) G_GNUC_CONST; extern f_gtk_file_chooser_get_type gtk_file_chooser_get_type; @@ -222,15 +227,34 @@ inline GtkWindow *gtk_window_cast(Object *obj) { return g_type_cic_helper(obj, gtk_window_get_type()); } +typedef gboolean (*f_g_type_check_instance_is_a)(GTypeInstance *instance, GType iface_type) G_GNUC_PURE; +extern f_g_type_check_instance_is_a g_type_check_instance_is_a; + +template +inline bool g_type_cit_helper(Object *instance, GType iface_type) { + if (!instance) return false; + + auto ginstance = reinterpret_cast(instance); + if (ginstance->g_class && ginstance->g_class->g_type == iface_type) { + return true; + } + return g_type_check_instance_is_a(ginstance, iface_type); +} + typedef gint (*f_gtk_dialog_run)(GtkDialog *dialog); extern f_gtk_dialog_run gtk_dialog_run; typedef gulong (*f_g_signal_connect_data)(gpointer instance, const gchar *detailed_signal, GCallback c_handler, gpointer data, GClosureNotify destroy_data, GConnectFlags connect_flags); extern f_g_signal_connect_data g_signal_connect_data; + inline gulong g_signal_connect_helper(gpointer instance, const gchar *detailed_signal, GCallback c_handler, gpointer data) { return g_signal_connect_data(instance, detailed_signal, c_handler, data, NULL, (GConnectFlags)0); } +inline gulong g_signal_connect_swapped_helper(gpointer instance, const gchar *detailed_signal, GCallback c_handler, gpointer data) { + return g_signal_connect_data(instance, detailed_signal, c_handler, data, NULL, G_CONNECT_SWAPPED); +} + typedef AppIndicator* (*f_app_indicator_new)(const gchar *id, const gchar *icon_name, AppIndicatorCategory category); extern f_app_indicator_new app_indicator_new; @@ -294,6 +318,12 @@ extern f_g_object_unref g_object_unref; typedef guint (*f_g_idle_add)(GSourceFunc function, gpointer data); extern f_g_idle_add g_idle_add; +typedef void (*f_g_free)(gpointer mem); +extern f_g_free g_free; + +typedef void (*f_g_slist_free)(GSList *list); +extern f_g_slist_free g_slist_free; + #ifndef TDESKTOP_DISABLE_UNITY_INTEGRATION typedef void (*f_unity_launcher_entry_set_count)(UnityLauncherEntry* self, gint64 value); extern f_unity_launcher_entry_set_count unity_launcher_entry_set_count; diff --git a/doc/building-qmake.md b/doc/building-qmake.md index 55bf8c53be..ffeb1832be 100644 --- a/doc/building-qmake.md +++ b/doc/building-qmake.md @@ -72,7 +72,7 @@ Building cd "$srcdir/Libraries/QtStatic" ./configure -prefix "$srcdir/qt" -release -opensource -confirm-license -qt-zlib \ -qt-libpng -qt-libjpeg -qt-freetype -qt-harfbuzz -qt-pcre -qt-xcb \ - -qt-xkbcommon-x11 -no-opengl -static -nomake examples -nomake tests + -qt-xkbcommon-x11 -no-opengl -no-gtkstyle -static -nomake examples -nomake tests make module-qtbase module-qtimageformats make module-qtbase-install_subtargets module-qtimageformats-install_subtargets diff --git a/doc/building-qtcreator.md b/doc/building-qtcreator.md index eb605ed15c..18695f1284 100644 --- a/doc/building-qtcreator.md +++ b/doc/building-qtcreator.md @@ -147,7 +147,7 @@ Install some packages for Qt (see **/home/user/TBuild/Libraries/qt5_6_0/qtbase/s In Terminal go to **/home/user/TBuild/Libraries/qt5_6_0** and there run - OPENSSL_LIBS='-L/usr/local/ssl/lib -lssl -lcrypto' ./configure -prefix "/usr/local/tdesktop/Qt-5.6.0" -release -force-debug-info -opensource -confirm-license -qt-zlib -qt-libpng -qt-libjpeg -qt-freetype -qt-harfbuzz -qt-pcre -qt-xcb -qt-xkbcommon-x11 -no-opengl -static -openssl-linked -nomake examples -nomake tests + OPENSSL_LIBS='-L/usr/local/ssl/lib -lssl -lcrypto' ./configure -prefix "/usr/local/tdesktop/Qt-5.6.0" -release -force-debug-info -opensource -confirm-license -qt-zlib -qt-libpng -qt-libjpeg -qt-freetype -qt-harfbuzz -qt-pcre -qt-xcb -qt-xkbcommon-x11 -no-opengl -no-gtkstyle -static -openssl-linked -nomake examples -nomake tests make -j4 sudo make install