diff --git a/Telegram/SourceFiles/calls/calls_group_panel.cpp b/Telegram/SourceFiles/calls/calls_group_panel.cpp index e659dc03d..f6e36c991 100644 --- a/Telegram/SourceFiles/calls/calls_group_panel.cpp +++ b/Telegram/SourceFiles/calls/calls_group_panel.cpp @@ -253,7 +253,6 @@ std::unique_ptr InviteContactsController::createRow( Panel::Panel(not_null call) : _call(call) , _peer(call->peer()) -, _window(std::make_unique(Core::App().getModalParent())) , _layerBg(std::make_unique(_window->body())) #ifndef Q_OS_MAC , _controls(std::make_unique( diff --git a/Telegram/SourceFiles/calls/calls_panel.cpp b/Telegram/SourceFiles/calls/calls_panel.cpp index 2c3f5e6c6..1411d02d0 100644 --- a/Telegram/SourceFiles/calls/calls_panel.cpp +++ b/Telegram/SourceFiles/calls/calls_panel.cpp @@ -33,7 +33,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/empty_userpic.h" #include "ui/emoji_config.h" #include "core/application.h" -#include "mainwindow.h" #include "lang/lang_keys.h" #include "main/main_session.h" #include "apiwrap.h" @@ -185,7 +184,6 @@ void Panel::Incoming::fillBottomShadow(QPainter &p) { Panel::Panel(not_null call) : _call(call) , _user(call->user()) -, _window(std::make_unique(Core::App().getModalParent())) #ifndef Q_OS_MAC , _controls(std::make_unique( _window->body(), diff --git a/Telegram/SourceFiles/core/application.cpp b/Telegram/SourceFiles/core/application.cpp index edc3dd4e8..48e224418 100644 --- a/Telegram/SourceFiles/core/application.cpp +++ b/Telegram/SourceFiles/core/application.cpp @@ -23,7 +23,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "core/ui_integration.h" #include "chat_helpers/emoji_keywords.h" #include "chat_helpers/stickers_emoji_image_loader.h" -#include "base/platform/base_platform_info.h" #include "base/platform/base_platform_last_input.h" #include "platform/platform_specific.h" #include "mainwindow.h" @@ -1002,13 +1001,6 @@ void Application::notifyFileDialogShown(bool shown) { } } -QWidget *Application::getModalParent() { - return (Platform::IsWayland() && activeWindow()) - ? activeWindow()->widget().get() - : nullptr; -} - - void Application::checkMediaViewActivation() { if (_mediaView && !_mediaView->isHidden()) { _mediaView->activateWindow(); diff --git a/Telegram/SourceFiles/core/application.h b/Telegram/SourceFiles/core/application.h index f41b9061f..5e58f9b5e 100644 --- a/Telegram/SourceFiles/core/application.h +++ b/Telegram/SourceFiles/core/application.h @@ -139,7 +139,6 @@ public: bool minimizeActiveWindow(); [[nodiscard]] QWidget *getFileDialogParent(); void notifyFileDialogShown(bool shown); - [[nodiscard]] QWidget *getModalParent(); void checkSystemDarkMode(); // Media view interface. diff --git a/Telegram/SourceFiles/kotato/settings.cpp b/Telegram/SourceFiles/kotato/settings.cpp index ca3a9c83d..4614fc505 100644 --- a/Telegram/SourceFiles/kotato/settings.cpp +++ b/Telegram/SourceFiles/kotato/settings.cpp @@ -213,7 +213,7 @@ bool gForwardChatOnClick = false; #if defined TDESKTOP_API_ID && defined TDESKTOP_API_HASH int gApiId = TDESKTOP_API_ID; -QString gApiHash = MACRO_TO_STRING(TDESKTOP_API_HASH); +QString gApiHash = QT_STRINGIFY(TDESKTOP_API_HASH); #else // TDESKTOP_API_ID && TDESKTOP_API_HASH diff --git a/Telegram/SourceFiles/logs.cpp b/Telegram/SourceFiles/logs.cpp index b8b7ee033..9941ab5ff 100644 --- a/Telegram/SourceFiles/logs.cpp +++ b/Telegram/SourceFiles/logs.cpp @@ -132,11 +132,11 @@ private: auto to = std::make_unique(_logsFilePath(type, postfix)); if (to->exists() && !to->remove()) { - LOG(("Could not delete '%1' file to start new logging!").arg(to->fileName())); + LOG(("Could not delete '%1' file to start new logging: %2").arg(to->fileName(), to->errorString())); return false; } if (!QFile(files[type]->fileName()).copy(to->fileName())) { // don't close files[type] yet - LOG(("Could not copy '%1' to '%2' to start new logging!").arg(files[type]->fileName(), to->fileName())); + LOG(("Could not copy '%1' to '%2' to start new logging: %3").arg(files[type]->fileName(), to->fileName(), to->errorString())); return false; } if (to->open(mode | QIODevice::Append)) { @@ -158,7 +158,7 @@ private: return true; } - LOG(("Could not open '%1' file to start new logging!").arg(to->fileName())); + LOG(("Could not open '%1' file to start new logging: %2").arg(to->fileName(), to->errorString())); return false; } else { bool found = false; @@ -209,7 +209,7 @@ NEW LOGGING INSTANCE STARTED!!!\n\ return true; } else if (type != LogDataMain) { - LOG(("Could not open debug log '%1'!").arg(files[type]->fileName())); + LOG(("Could not open debug log '%1': %2").arg(files[type]->fileName(), files[type]->errorString())); } return false; } diff --git a/Telegram/SourceFiles/media/view/media_view_pip.cpp b/Telegram/SourceFiles/media/view/media_view_pip.cpp index d00596889..f224f8045 100644 --- a/Telegram/SourceFiles/media/view/media_view_pip.cpp +++ b/Telegram/SourceFiles/media/view/media_view_pip.cpp @@ -373,8 +373,7 @@ QImage RotateFrameImage(QImage image, int rotation) { PipPanel::PipPanel( QWidget *parent, Fn paint) -: PipParent(Core::App().getModalParent()) -, _parent(parent) +: _parent(parent) , _paint(std::move(paint)) { setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint @@ -388,7 +387,17 @@ PipPanel::PipPanel( Ui::Platform::InitOnTopPanel(this); setMouseTracking(true); resize(0, 0); - show(); + hide(); + createWinId(); +} + +void PipPanel::setVisibleHook(bool visible) { + PipParent::setVisibleHook(visible); + + // workaround Qt's forced transient parent + if (visible) { + Ui::Platform::ClearTransientParent(this); + } } void PipPanel::setAspectRatio(QSize ratio) { diff --git a/Telegram/SourceFiles/media/view/media_view_pip.h b/Telegram/SourceFiles/media/view/media_view_pip.h index 544d6f9ed..a4a5f80e5 100644 --- a/Telegram/SourceFiles/media/view/media_view_pip.h +++ b/Telegram/SourceFiles/media/view/media_view_pip.h @@ -78,6 +78,8 @@ protected: void mouseReleaseEvent(QMouseEvent *e) override; void mouseMoveEvent(QMouseEvent *e) override; + void setVisibleHook(bool visible) override; + private: void setPositionDefault(); void setPositionOnScreen(Position position, QRect available); diff --git a/Telegram/SourceFiles/mtproto/details/mtproto_domain_resolver.cpp b/Telegram/SourceFiles/mtproto/details/mtproto_domain_resolver.cpp index 384723a14..8d6eb07ac 100644 --- a/Telegram/SourceFiles/mtproto/details/mtproto_domain_resolver.cpp +++ b/Telegram/SourceFiles/mtproto/details/mtproto_domain_resolver.cpp @@ -65,7 +65,7 @@ QByteArray DnsUserAgent() { static const auto kResult = QByteArray( "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " "AppleWebKit/537.36 (KHTML, like Gecko) " - "Chrome/88.0.4324.182 Safari/537.36"); + "Chrome/89.0.4389.90 Safari/537.36"); return kResult; } diff --git a/Telegram/SourceFiles/platform/linux/launcher_linux.cpp b/Telegram/SourceFiles/platform/linux/launcher_linux.cpp index 28e8e78d2..032b91bab 100644 --- a/Telegram/SourceFiles/platform/linux/launcher_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/launcher_linux.cpp @@ -66,7 +66,7 @@ void Launcher::initHook() { AppName.utf16().replace(' ', '_')); } - return qsl(MACRO_TO_STRING(TDESKTOP_LAUNCHER_BASENAME) ".desktop"); + return qsl(QT_STRINGIFY(TDESKTOP_LAUNCHER_BASENAME) ".desktop"); }()); } diff --git a/Telegram/SourceFiles/platform/linux/linux_mpris_support.cpp b/Telegram/SourceFiles/platform/linux/linux_mpris_support.cpp index 5dc9fd02a..9cd382425 100644 --- a/Telegram/SourceFiles/platform/linux/linux_mpris_support.cpp +++ b/Telegram/SourceFiles/platform/linux/linux_mpris_support.cpp @@ -21,7 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "main/main_account.h" #include "main/main_session.h" #include "mainwindow.h" -#include "app.h" +#include "mainwidget.h" #include #include @@ -33,13 +33,12 @@ namespace Platform { namespace internal { namespace { -constexpr auto kService = "org.mpris.MediaPlayer2.Kotatogram"_cs; +constexpr auto kService = "org.mpris.MediaPlayer2.tdesktop"_cs; constexpr auto kObjectPath = "/org/mpris/MediaPlayer2"_cs; constexpr auto kFakeTrackPath = "/org/telegram/desktop/track/0"_cs; constexpr auto kInterface = "org.mpris.MediaPlayer2"_cs; constexpr auto kPlayerInterface = "org.mpris.MediaPlayer2.Player"_cs; constexpr auto kPropertiesInterface = "org.freedesktop.DBus.Properties"_cs; -constexpr auto kSongType = AudioMsgId::Type::Song; constexpr auto kIntrospectionXML = R"INTROSPECTION( @@ -101,50 +100,56 @@ auto CreateMetadata( Data::DocumentMedia *trackView) { std::map result; - if (!Media::Player::IsStoppedOrStopping(state.state)) { - result["mpris:trackid"] = Glib::wrap(g_variant_new_object_path( - kFakeTrackPath.utf8().constData())); - result["mpris:length"] = Glib::Variant::create( - state.length * 1000); + if (Media::Player::IsStoppedOrStopping(state.state)) { + return result; + } - const auto audioData = state.id.audio(); - if (audioData) { + result["mpris:trackid"] = Glib::wrap(g_variant_new_object_path( + kFakeTrackPath.utf8().constData())); + result["mpris:length"] = Glib::Variant::create( + state.length * 1000); + result["xesam:title"] = Glib::Variant::create( + "Unknown Track"); + + const auto audioData = state.id.audio(); + if (audioData) { + if (!audioData->filename().isEmpty()) { result["xesam:title"] = Glib::Variant< Glib::ustring >::create(audioData->filename().toStdString()); - - if (audioData->isSong()) { - const auto songData = audioData->song(); - if (!songData->performer.isEmpty()) { - result["xesam:artist"] = Glib::Variant< - std::vector - >::create({ songData->performer.toStdString() }); - } - if (!songData->performer.isEmpty()) { - result["xesam:title"] = Glib::Variant< - Glib::ustring - >::create(songData->title.toStdString()); - } - } } - if (trackView) { - trackView->thumbnailWanted(Data::FileOrigin()); - if (trackView->thumbnail()) { - QByteArray thumbnailData; - QBuffer thumbnailBuffer(&thumbnailData); - trackView->thumbnail()->original().save( - &thumbnailBuffer, - "JPG", - 87); - - result["mpris:artUrl"] = Glib::Variant< - Glib::ustring - >::create("data:image/jpeg;base64," - + thumbnailData - .toBase64() - .toStdString()); + if (audioData->isSong()) { + const auto songData = audioData->song(); + if (!songData->performer.isEmpty()) { + result["xesam:artist"] = Glib::Variant< + std::vector + >::create({ songData->performer.toStdString() }); } + if (!songData->title.isEmpty()) { + result["xesam:title"] = Glib::Variant< + Glib::ustring + >::create(songData->title.toStdString()); + } + } + } + + if (trackView) { + trackView->thumbnailWanted(Data::FileOrigin()); + if (trackView->thumbnail()) { + QByteArray thumbnailData; + QBuffer thumbnailBuffer(&thumbnailData); + trackView->thumbnail()->original().save( + &thumbnailBuffer, + "JPG", + 87); + + result["mpris:artUrl"] = Glib::Variant< + Glib::ustring + >::create("data:image/jpeg;base64," + + thumbnailData + .toBase64() + .toStdString()); } } @@ -172,9 +177,13 @@ void HandleMethodCall( auto parametersCopy = parameters; if (method_name == "Quit") { - App::quit(); + if (const auto main = App::main()) { + main->closeBothPlayers(); + } } else if (method_name == "Raise") { - App::wnd()->showFromTray(); + if (const auto window = App::wnd()) { + window->showFromTray(); + } } else if (method_name == "Next") { Media::Player::instance()->next(); } else if (method_name == "Pause") { @@ -190,10 +199,10 @@ void HandleMethodCall( parametersCopy.get_child(0)); const auto state = Media::Player::instance()->getState( - kSongType); + Media::Player::instance()->getActiveType()); Media::Player::instance()->finishSeeking( - kSongType, + Media::Player::instance()->getActiveType(), float64(state.position * 1000 + offset) / (state.length * 1000)); } else if (method_name == "SetPosition") { @@ -201,10 +210,10 @@ void HandleMethodCall( parametersCopy.get_child(1)); const auto state = Media::Player::instance()->getState( - kSongType); + Media::Player::instance()->getActiveType()); Media::Player::instance()->finishSeeking( - kSongType, + Media::Player::instance()->getActiveType(), float64(position) / (state.length * 1000)); } else if (method_name == "Stop") { Media::Player::instance()->stop(); @@ -262,7 +271,7 @@ void HandleGetProperty( property = Glib::Variant::create(1.0); } else if (property_name == "Metadata") { const auto state = Media::Player::instance()->getState( - kSongType); + Media::Player::instance()->getActiveType()); const auto trackView = [&]() -> std::shared_ptr { const auto audioData = state.id.audio(); @@ -278,13 +287,13 @@ void HandleGetProperty( property = Glib::Variant::create(1.0); } else if (property_name == "PlaybackStatus") { const auto state = Media::Player::instance()->getState( - kSongType); + Media::Player::instance()->getActiveType()); property = Glib::Variant::create( PlaybackStatus(state.state)); } else if (property_name == "Position") { const auto state = Media::Player::instance()->getState( - kSongType); + Media::Player::instance()->getActiveType()); property = Glib::Variant::create(state.position * 1000); } else if (property_name == "Rate") { @@ -381,46 +390,46 @@ public: uint registerId = 0; uint playerRegisterId = 0; - std::map metadata; Glib::ustring playbackStatus; gint64 position = 0; + + DocumentData *audioData = nullptr; std::shared_ptr trackView; + Image *thumbnail = nullptr; rpl::lifetime lifetime; }; void MPRISSupport::Private::updateTrackState( const Media::Player::TrackState &state) { - if (state.id.type() != kSongType) { - return; - } - - const auto audioData = state.id.audio(); - if (audioData && audioData->isSongWithCover()) { - const auto view = audioData->createMediaView(); - if (!trackView || trackView->owner() != view->owner()) { - trackView = view; - } - } else { - trackView = nullptr; - } - - const auto currentMetadata = CreateMetadata(state, trackView.get()); + const auto currentAudioData = state.id.audio(); const auto currentPosition = state.position * 1000; const auto currentPlaybackStatus = PlaybackStatus(state.state); - if (!ranges::equal(currentMetadata, metadata, [&]( - const auto &item1, - const auto &item2) { - return item1.first == item2.first - && item1.second.equal(item2.second); - })) { - metadata = currentMetadata; + if (currentAudioData != audioData) { + audioData = currentAudioData; + if (audioData && audioData->isSongWithCover()) { + trackView = audioData->createMediaView(); + thumbnail = trackView->thumbnail(); + } else { + trackView = nullptr; + thumbnail = nullptr; + } + PlayerPropertyChanged( "Metadata", Glib::Variant< std::map - >::create(metadata)); + >::create(CreateMetadata(state, trackView.get()))); + } + + if (trackView && (trackView->thumbnail() != thumbnail)) { + thumbnail = trackView->thumbnail(); + PlayerPropertyChanged( + "Metadata", + Glib::Variant< + std::map + >::create(CreateMetadata(state, trackView.get()))); } if (currentPlaybackStatus != playbackStatus) { @@ -467,16 +476,20 @@ MPRISSupport::MPRISSupport() InterfaceVTable); _private->updateTrackState( - Media::Player::instance()->getState(kSongType)); + Media::Player::instance()->getState( + Media::Player::instance()->getActiveType())); Core::App().domain().active().session().downloaderTaskFinished( ) | rpl::start_with_next([=] { _private->updateTrackState( - Media::Player::instance()->getState(kSongType)); + Media::Player::instance()->getState( + Media::Player::instance()->getActiveType())); }, _private->lifetime); Media::Player::instance()->updatedNotifier( - ) | rpl::start_with_next([=]( + ) | rpl::filter([=](const Media::Player::TrackState &state) { + return state.id.type() == Media::Player::instance()->getActiveType(); + }) | rpl::start_with_next([=]( const Media::Player::TrackState &state) { _private->updateTrackState(state); }, _private->lifetime); diff --git a/Telegram/SourceFiles/platform/linux/linux_notification_service_watcher.cpp b/Telegram/SourceFiles/platform/linux/linux_notification_service_watcher.cpp index 8c5223b56..f0dc477bd 100644 --- a/Telegram/SourceFiles/platform/linux/linux_notification_service_watcher.cpp +++ b/Telegram/SourceFiles/platform/linux/linux_notification_service_watcher.cpp @@ -20,21 +20,21 @@ namespace Platform { namespace internal { namespace { -constexpr auto kNotificationService = "org.freedesktop.Notifications"_cs; +constexpr auto kService = "org.freedesktop.Notifications"_cs; -bool IsNotificationServiceActivatable() { - static const auto Result = [] { +auto Activatable() { + static const auto Result = []() -> std::optional { try { const auto connection = Gio::DBus::Connection::get_sync( Gio::DBus::BusType::BUS_TYPE_SESSION); return ranges::contains( base::Platform::DBus::ListActivatableNames(connection), - Glib::ustring(std::string(kNotificationService))); + Glib::ustring(std::string(kService))); } catch (...) { } - return false; + return std::nullopt; }(); return Result; @@ -56,14 +56,13 @@ NotificationServiceWatcher::NotificationServiceWatcher() _private->signalId = base::Platform::DBus::RegisterServiceWatcher( _private->dbusConnection, - std::string(kNotificationService), + std::string(kService), []( const Glib::ustring &service, const Glib::ustring &oldOwner, const Glib::ustring &newOwner) { if (!Core::App().domain().started() - || (IsNotificationServiceActivatable() - && newOwner.empty())) { + || (Activatable().value_or(true) && newOwner.empty())) { return; } diff --git a/Telegram/SourceFiles/platform/linux/linux_xdp_file_dialog.cpp b/Telegram/SourceFiles/platform/linux/linux_xdp_file_dialog.cpp index 720cce80b..14dd4302e 100644 --- a/Telegram/SourceFiles/platform/linux/linux_xdp_file_dialog.cpp +++ b/Telegram/SourceFiles/platform/linux/linux_xdp_file_dialog.cpp @@ -16,8 +16,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/openssl_help.h" #include "base/qt_adapters.h" -#include -#include #include #include @@ -282,7 +280,7 @@ void XDPFileDialog::openPortal() { if (_acceptMode == QFileDialog::AcceptSave) { if (!_directory.empty()) { options["current_folder"] = Glib::Variant::create( - _directory +'\0'); + _directory + '\0'); } if (!_selectedFiles.empty()) { @@ -302,8 +300,12 @@ void XDPFileDialog::openPortal() { if (!_mimeTypesFilters.empty()) { for (const auto &mimeTypeFilter : _mimeTypesFilters) { - const auto mimeType = QMimeDatabase().mimeTypeForName( - QString::fromStdString(mimeTypeFilter)); + auto mimeTypeUncertain = false; + const auto mimeType = Gio::content_type_guess( + mimeTypeFilter, + nullptr, + 0, + mimeTypeUncertain); // Creates e.g. (1, "image/png") const auto filterCondition = FilterCondition{ @@ -313,7 +315,7 @@ void XDPFileDialog::openPortal() { // Creates e.g. [("Images", [((1, "image/png"))])] filterList.push_back({ - mimeType.comment().toStdString(), + Gio::content_type_get_description(mimeType), FilterConditionList{filterCondition}, }); @@ -326,18 +328,16 @@ void XDPFileDialog::openPortal() { for (const auto &nameFilter : _nameFilters) { // Do parsing: // Supported format is ("Images (*.png *.jpg)") - const QRegularExpression regexp( - QString::fromLatin1(filterRegExp)); + const auto regexp = Glib::Regex::create(filterRegExp); - const QRegularExpressionMatch match = regexp.match( - QString::fromStdString(nameFilter)); + Glib::MatchInfo match; + regexp->match(nameFilter, match); - if (match.hasMatch()) { - const auto userVisibleName = match.captured(1).toStdString(); - const auto filterStrings = QStringListToStd( - match.captured(2).split( - QLatin1Char(' '), - base::QStringSkipEmptyParts)); + if (match.matches()) { + const auto userVisibleName = match.fetch(1); + const auto filterStrings = Glib::Regex::create(" ")->split( + match.fetch(2), + Glib::RegexMatchFlags::REGEX_MATCH_NOTEMPTY); if (filterStrings.empty()) { LOG(( diff --git a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp index afec532fe..cf5a07099 100644 --- a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp @@ -46,6 +46,40 @@ bool InhibitionSupported = false; std::optional CurrentServerInformation; QStringList CurrentCapabilities; +void StartServiceAsync( + Fn callback, + const Glib::RefPtr &cancellable = Glib::RefPtr()) { + try { + const auto connection = Gio::DBus::Connection::get_sync( + Gio::DBus::BusType::BUS_TYPE_SESSION); + + base::Platform::DBus::StartServiceByNameAsync( + connection, + std::string(kService), + [=](Fn result) { + try { + result(); // get the error if any + } catch (const Glib::Error &e) { + LOG(("Native Notification Error: %1").arg( + QString::fromStdString(e.what()))); + } catch (const std::exception &e) { + LOG(("Native Notification Error: %1").arg( + QString::fromStdString(e.what()))); + } + + crl::on_main([=] { callback(); }); + }, + cancellable); + + return; + } catch (const Glib::Error &e) { + LOG(("Native Notification Error: %1").arg( + QString::fromStdString(e.what()))); + } + + crl::on_main([=] { callback(); }); +} + bool GetServiceRegistered() { try { const auto connection = Gio::DBus::Connection::get_sync( @@ -125,7 +159,7 @@ void GetServerInformation( QString::fromStdString(e.what()))); } - crl::on_main([=] { callback({}); }); + crl::on_main([=] { callback(std::nullopt); }); }, std::string(kService)); @@ -244,6 +278,11 @@ bool Inhibited() { const auto connection = Gio::DBus::Connection::get_sync( Gio::DBus::BusType::BUS_TYPE_SESSION); + // a hack for snap's activation restriction + base::Platform::DBus::StartServiceByName( + connection, + std::string(kService)); + auto reply = connection->call_sync( std::string(kObjectPath), std::string(kPropertiesInterface), @@ -336,6 +375,7 @@ public: private: Glib::RefPtr _dbusConnection; + Glib::RefPtr _cancellable; base::weak_ptr _manager; Glib::ustring _title; @@ -350,13 +390,13 @@ private: uint _notificationClosedSignalId = 0; NotificationId _id; + void notificationShown( + const Glib::RefPtr &result); + void notificationClosed(uint id, uint reason); void actionInvoked(uint id, const Glib::ustring &actionName); void notificationReplied(uint id, const Glib::ustring &text); - void notificationShown( - const Glib::RefPtr &result); - void signalEmitted( const Glib::RefPtr &connection, const Glib::ustring &sender_name, @@ -376,7 +416,8 @@ NotificationData::NotificationData( const QString &msg, NotificationId id, bool hideReplyButton) -: _manager(manager) +: _cancellable(Gio::Cancellable::create()) +, _manager(manager) , _title(title.toStdString()) , _imageKey(GetImageKey(CurrentServerInformationValue().specVersion)) , _id(id) { @@ -475,6 +516,10 @@ NotificationData::NotificationData( } NotificationData::~NotificationData() { + if (_cancellable) { + _cancellable->cancel(); + } + if (_dbusConnection) { if (_actionInvokedSignalId != 0) { _dbusConnection->signal_unsubscribe(_actionInvokedSignalId); @@ -491,7 +536,8 @@ NotificationData::~NotificationData() { } void NotificationData::show() { - try { + // a hack for snap's activation restriction + StartServiceAsync([=] { const auto iconName = _imageKey.empty() || _hints.find(_imageKey) == end(_hints) ? Glib::ustring(GetIconName().toStdString()) @@ -513,16 +559,7 @@ void NotificationData::show() { }), sigc::mem_fun(this, &NotificationData::notificationShown), std::string(kService)); - } catch (const Glib::Error &e) { - LOG(("Native Notification Error: %1").arg( - QString::fromStdString(e.what()))); - - const auto manager = _manager; - const auto my = _id; - crl::on_main(manager, [=] { - manager->clearNotification(my); - }); - } + }, _cancellable); } void NotificationData::notificationShown( @@ -549,20 +586,15 @@ void NotificationData::notificationShown( } void NotificationData::close() { - try { - _dbusConnection->call( - std::string(kObjectPath), - std::string(kInterface), - "CloseNotification", - base::Platform::MakeGlibVariant(std::tuple{ - _notificationId, - }), - {}, - std::string(kService)); - } catch (const Glib::Error &e) { - LOG(("Native Notification Error: %1").arg( - QString::fromStdString(e.what()))); - } + _dbusConnection->call( + std::string(kObjectPath), + std::string(kInterface), + "CloseNotification", + base::Platform::MakeGlibVariant(std::tuple{ + _notificationId, + }), + {}, + std::string(kService)); } void NotificationData::setImage(const QString &imagePath) { @@ -710,8 +742,6 @@ bool ByDefault() { } void Create(Window::Notifications::System *system) { - ServiceRegistered = GetServiceRegistered(); - const auto managerSetter = [=] { using ManagerType = Window::Notifications::ManagerType; if ((Core::App().settings().nativeNotifications() && Supported()) @@ -726,13 +756,39 @@ void Create(Window::Notifications::System *system) { } }; - if (!ServiceRegistered) { - CurrentServerInformation = std::nullopt; - CurrentCapabilities = QStringList{}; - InhibitionSupported = false; - managerSetter(); - return; - } + const auto counter = std::make_shared(3); + const auto oneReady = [=] { + if (!--*counter) { + managerSetter(); + } + }; + + const auto serviceActivated = [=] { + ServiceRegistered = GetServiceRegistered(); + + if (!ServiceRegistered) { + CurrentServerInformation = std::nullopt; + CurrentCapabilities = QStringList{}; + InhibitionSupported = false; + managerSetter(); + return; + } + + GetServerInformation([=](const std::optional &result) { + CurrentServerInformation = result; + oneReady(); + }); + + GetCapabilities([=](const QStringList &result) { + CurrentCapabilities = result; + oneReady(); + }); + + GetInhibitionSupported([=](bool result) { + InhibitionSupported = result; + oneReady(); + }); + }; // There are some asserts that manager is not nullptr, // avoid crashes until some real manager is created @@ -741,27 +797,8 @@ void Create(Window::Notifications::System *system) { system->setManager(std::make_unique(system)); } - const auto counter = std::make_shared(3); - const auto oneReady = [=] { - if (!--*counter) { - managerSetter(); - } - }; - - GetServerInformation([=](const std::optional &result) { - CurrentServerInformation = result; - oneReady(); - }); - - GetCapabilities([=](const QStringList &result) { - CurrentCapabilities = result; - oneReady(); - }); - - GetInhibitionSupported([=](bool result) { - InhibitionSupported = result; - oneReady(); - }); + // snap doesn't allow access when the daemon is not running :( + StartServiceAsync(serviceActivated); } class Manager::Private { diff --git a/Telegram/SourceFiles/settings/settings_notifications.cpp b/Telegram/SourceFiles/settings/settings_notifications.cpp index 571c006a2..c0004dcc5 100644 --- a/Telegram/SourceFiles/settings/settings_notifications.cpp +++ b/Telegram/SourceFiles/settings/settings_notifications.cpp @@ -438,8 +438,7 @@ NotificationsCount::~NotificationsCount() { NotificationsCount::SampleWidget::SampleWidget( NotificationsCount *owner, const QPixmap &cache) -: QWidget(Core::App().getModalParent()) -, _owner(owner) +: _owner(owner) , _cache(cache) { const QSize size( cache.width() / cache.devicePixelRatio(), diff --git a/Telegram/SourceFiles/ui/widgets/separate_panel.cpp b/Telegram/SourceFiles/ui/widgets/separate_panel.cpp index 799405a79..281bc8387 100644 --- a/Telegram/SourceFiles/ui/widgets/separate_panel.cpp +++ b/Telegram/SourceFiles/ui/widgets/separate_panel.cpp @@ -31,8 +31,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Ui { SeparatePanel::SeparatePanel() -: RpWidget(Core::App().getModalParent()) -, _close(this, st::separatePanelClose) +: _close(this, st::separatePanelClose) , _back(this, object_ptr(this, st::separatePanelBack)) , _body(this) { setMouseTracking(true); diff --git a/Telegram/SourceFiles/window/notifications_manager_default.cpp b/Telegram/SourceFiles/window/notifications_manager_default.cpp index 503d2f2cc..d6cf3352e 100644 --- a/Telegram/SourceFiles/window/notifications_manager_default.cpp +++ b/Telegram/SourceFiles/window/notifications_manager_default.cpp @@ -30,7 +30,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/call_delayed.h" #include "facades.h" #include "app.h" -#include "mainwindow.h" #include "styles/style_dialogs.h" #include "styles/style_layers.h" #include "styles/style_window.h" @@ -422,8 +421,7 @@ Widget::Widget( QPoint startPosition, int shift, Direction shiftDirection) -: RpWidget(Core::App().getModalParent()) -, _manager(manager) +: _manager(manager) , _startPosition(startPosition) , _direction(shiftDirection) , _shift(shift) diff --git a/Telegram/lib_base b/Telegram/lib_base index c227e5d5e..abb86932a 160000 --- a/Telegram/lib_base +++ b/Telegram/lib_base @@ -1 +1 @@ -Subproject commit c227e5d5ee3bb07b6edaf128fbec665b54050387 +Subproject commit abb86932a6215f5df72941e466d22a760efa39de diff --git a/Telegram/lib_ui b/Telegram/lib_ui index 84a46ce77..50415733c 160000 --- a/Telegram/lib_ui +++ b/Telegram/lib_ui @@ -1 +1 @@ -Subproject commit 84a46ce77304eb38380ba76e7b418976008e3d02 +Subproject commit 50415733c8c4f6fccc8a9340102abb6a74209b6c