Detach SystemMediaControls from Window::Controller.

This commit is contained in:
John Preston 2023-01-19 09:38:52 +04:00
parent 6b8f80bd63
commit cdfdccbb66
12 changed files with 67 additions and 53 deletions

View file

@ -65,6 +65,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "media/player/media_player_instance.h" #include "media/player/media_player_instance.h"
#include "media/player/media_player_float.h" #include "media/player/media_player_float.h"
#include "media/clip/media_clip_reader.h" // For Media::Clip::Finish(). #include "media/clip/media_clip_reader.h" // For Media::Clip::Finish().
#include "media/system_media_controls_manager.h"
#include "window/notifications_manager.h" #include "window/notifications_manager.h"
#include "window/themes/window_theme.h" #include "window/themes/window_theme.h"
#include "window/window_lock_widgets.h" #include "window/window_lock_widgets.h"
@ -147,6 +148,9 @@ Application::Application(not_null<Launcher*> launcher)
, _audio(std::make_unique<Media::Audio::Instance>()) , _audio(std::make_unique<Media::Audio::Instance>())
, _fallbackProductionConfig( , _fallbackProductionConfig(
std::make_unique<MTP::Config>(MTP::Environment::Production)) std::make_unique<MTP::Config>(MTP::Environment::Production))
, _mediaControlsManager(MediaControlsManager::Supported()
? std::make_unique<MediaControlsManager>()
: nullptr)
, _downloadManager(std::make_unique<Data::DownloadManager>()) , _downloadManager(std::make_unique<Data::DownloadManager>())
, _domain(std::make_unique<Main::Domain>(cDataFile())) , _domain(std::make_unique<Main::Domain>(cDataFile()))
, _exportManager(std::make_unique<Export::Manager>()) , _exportManager(std::make_unique<Export::Manager>())
@ -484,27 +488,33 @@ void Application::startTray() {
_tray->showFromTrayRequests( _tray->showFromTrayRequests(
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
const auto last = _lastActiveWindow; activate();
const auto primary = _lastActivePrimaryWindow;
enumerateWindows([&](WindowRaw w) {
if (w != last && w != primary) {
w->widget()->showFromTray();
}
});
if (primary) {
primary->widget()->showFromTray();
}
if (last && last != primary) {
last->widget()->showFromTray();
}
}, _lifetime); }, _lifetime);
_tray->hideToTrayRequests( _tray->hideToTrayRequests(
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
enumerateWindows([&](WindowRaw w) { w->widget()->minimizeToTray(); }); enumerateWindows([&](WindowRaw w) {
w->widget()->minimizeToTray();
});
}, _lifetime); }, _lifetime);
} }
void Application::activate() {
const auto last = _lastActiveWindow;
const auto primary = _lastActivePrimaryWindow;
enumerateWindows([&](not_null<Window::Controller*> w) {
if (w != last && w != primary) {
w->widget()->showFromTray();
}
});
if (primary) {
primary->widget()->showFromTray();
}
if (last && last != primary) {
last->widget()->showFromTray();
}
}
auto Application::prepareEmojiSourceImages() auto Application::prepareEmojiSourceImages()
-> std::shared_ptr<Ui::Emoji::UniversalImages> { -> std::shared_ptr<Ui::Emoji::UniversalImages> {
const auto &images = Ui::Emoji::SourceImages(); const auto &images = Ui::Emoji::SourceImages();

View file

@ -71,6 +71,7 @@ namespace Player {
class FloatController; class FloatController;
class FloatDelegate; class FloatDelegate;
} // namespace Player } // namespace Player
class SystemMediaControlsManager;
} // namespace Media } // namespace Media
namespace Lang { namespace Lang {
@ -180,6 +181,7 @@ public:
void checkSystemDarkMode(); void checkSystemDarkMode();
[[nodiscard]] bool isActiveForTrayMenu() const; [[nodiscard]] bool isActiveForTrayMenu() const;
void closeChatFromWindows(not_null<PeerData*> peer); void closeChatFromWindows(not_null<PeerData*> peer);
void activate();
// Media view interface. // Media view interface.
bool hideMediaView(); bool hideMediaView();
@ -384,6 +386,8 @@ private:
// Mutable because is created in run() after OpenSSL is inited. // Mutable because is created in run() after OpenSSL is inited.
std::unique_ptr<Window::Notifications::System> _notifications; std::unique_ptr<Window::Notifications::System> _notifications;
using MediaControlsManager = Media::SystemMediaControlsManager;
const std::unique_ptr<MediaControlsManager> _mediaControlsManager;
const std::unique_ptr<Data::DownloadManager> _downloadManager; const std::unique_ptr<Data::DownloadManager> _downloadManager;
const std::unique_ptr<Main::Domain> _domain; const std::unique_ptr<Main::Domain> _domain;
const std::unique_ptr<Export::Manager> _exportManager; const std::unique_ptr<Export::Manager> _exportManager;

View file

@ -287,6 +287,11 @@ MainWidget::MainWidget(
_exportTopBar->finishAnimating(); _exportTopBar->finishAnimating();
} }
Media::Player::instance()->closePlayerRequests(
) | rpl::start_with_next([=] {
closeBothPlayers();
}, lifetime());
Media::Player::instance()->updatedNotifier( Media::Player::instance()->updatedNotifier(
) | rpl::start_with_next([=](const Media::Player::TrackState &state) { ) | rpl::start_with_next([=](const Media::Player::TrackState &state) {
handleAudioUpdate(state); handleAudioUpdate(state);
@ -357,14 +362,16 @@ MainWidget::MainWidget(
Media::Player::instance()->tracksFinished( Media::Player::instance()->tracksFinished(
) | rpl::start_with_next([=](AudioMsgId::Type type) { ) | rpl::start_with_next([=](AudioMsgId::Type type) {
if (type == AudioMsgId::Type::Voice) { if (type == AudioMsgId::Type::Voice) {
const auto songState = Media::Player::instance()->getState(AudioMsgId::Type::Song); const auto songState = Media::Player::instance()->getState(
AudioMsgId::Type::Song);
if (!songState.id || IsStoppedOrStopping(songState.state)) { if (!songState.id || IsStoppedOrStopping(songState.state)) {
closeBothPlayers(); Media::Player::instance()->stopAndClose();
} }
} else if (type == AudioMsgId::Type::Song) { } else if (type == AudioMsgId::Type::Song) {
const auto songState = Media::Player::instance()->getState(AudioMsgId::Type::Song); const auto songState = Media::Player::instance()->getState(
AudioMsgId::Type::Song);
if (!songState.id) { if (!songState.id) {
closeBothPlayers(); Media::Player::instance()->stopAndClose();
} }
} }
}, lifetime()); }, lifetime());
@ -767,7 +774,7 @@ void MainWidget::handleAudioUpdate(const Media::Player::TrackState &state) {
if (!Media::Player::IsStoppedOrStopping(state.state)) { if (!Media::Player::IsStoppedOrStopping(state.state)) {
createPlayer(); createPlayer();
} else if (state.state == State::StoppedAtStart) { } else if (state.state == State::StoppedAtStart) {
closeBothPlayers(); Media::Player::instance()->stopAndClose();
} }
if (const auto item = session().data().message(state.id.contextId())) { if (const auto item = session().data().message(state.id.contextId())) {
@ -788,12 +795,7 @@ void MainWidget::closeBothPlayers() {
if (_player) { if (_player) {
_player->hide(anim::type::normal); _player->hide(anim::type::normal);
} }
_playerPlaylist->hideIgnoringEnterEvents(); _playerPlaylist->hideIgnoringEnterEvents();
Media::Player::instance()->stop(AudioMsgId::Type::Voice);
Media::Player::instance()->stop(AudioMsgId::Type::Song);
Shortcuts::ToggleMediaShortcuts(false);
} }
void MainWidget::stopAndClosePlayer() { void MainWidget::stopAndClosePlayer() {
@ -814,7 +816,9 @@ void MainWidget::createPlayer() {
) | rpl::start_with_next( ) | rpl::start_with_next(
[this] { playerHeightUpdated(); }, [this] { playerHeightUpdated(); },
_player->lifetime()); _player->lifetime());
_player->entity()->setCloseCallback([=] { closeBothPlayers(); }); _player->entity()->setCloseCallback([=] {
Media::Player::instance()->stopAndClose();
});
_player->entity()->setShowItemCallback([=]( _player->entity()->setShowItemCallback([=](
not_null<const HistoryItem*> item) { not_null<const HistoryItem*> item) {
_controller->showMessage(item); _controller->showMessage(item);

View file

@ -233,7 +233,6 @@ public:
using FloatDelegate::floatPlayerAreaUpdated; using FloatDelegate::floatPlayerAreaUpdated;
void closeBothPlayers();
void stopAndClosePlayer(); void stopAndClosePlayer();
bool preventsCloseSection(Fn<void()> callback) const; bool preventsCloseSection(Fn<void()> callback) const;
@ -302,6 +301,8 @@ private:
void hiderLayer(base::unique_qptr<Window::HistoryHider> h); void hiderLayer(base::unique_qptr<Window::HistoryHider> h);
void clearHider(not_null<Window::HistoryHider*> instance); void clearHider(not_null<Window::HistoryHider*> instance);
void closeBothPlayers();
[[nodiscard]] auto floatPlayerDelegate() [[nodiscard]] auto floatPlayerDelegate()
-> not_null<Media::Player::FloatDelegate*>; -> not_null<Media::Player::FloatDelegate*>;
not_null<Ui::RpWidget*> floatPlayerWidget() override; not_null<Ui::RpWidget*> floatPlayerWidget() override;

View file

@ -31,7 +31,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "main/main_account.h" // Account::sessionValue. #include "main/main_account.h" // Account::sessionValue.
#include "main/main_domain.h" #include "main/main_domain.h"
#include "mainwidget.h" #include "mainwidget.h"
#include "media/system_media_controls_manager.h"
#include "ui/boxes/confirm_box.h" #include "ui/boxes/confirm_box.h"
#include "boxes/connection_box.h" #include "boxes/connection_box.h"
#include "storage/storage_account.h" #include "storage/storage_account.h"
@ -126,11 +125,6 @@ void MainWindow::initHook() {
this, this,
[=] { checkActivation(); }, [=] { checkActivation(); },
Qt::QueuedConnection); Qt::QueuedConnection);
if (Media::SystemMediaControlsManager::Supported()) {
using MediaManager = Media::SystemMediaControlsManager;
_mediaControlsManager = std::make_unique<MediaManager>(&controller());
}
} }
void MainWindow::applyInitialWorkMode() { void MainWindow::applyInitialWorkMode() {

View file

@ -19,10 +19,6 @@ class Widget;
enum class EnterPoint : uchar; enum class EnterPoint : uchar;
} // namespace Intro } // namespace Intro
namespace Media {
class SystemMediaControlsManager;
} // namespace Media
namespace Window { namespace Window {
class MediaPreviewWidget; class MediaPreviewWidget;
class SectionMemento; class SectionMemento;
@ -136,8 +132,6 @@ private:
void themeUpdated(const Window::Theme::BackgroundUpdate &data); void themeUpdated(const Window::Theme::BackgroundUpdate &data);
std::unique_ptr<Media::SystemMediaControlsManager> _mediaControlsManager;
QPoint _lastMousePosition; QPoint _lastMousePosition;
object_ptr<Window::PasscodeLockWidget> _passcodeLock = { nullptr }; object_ptr<Window::PasscodeLockWidget> _passcodeLock = { nullptr };

View file

@ -1280,6 +1280,15 @@ bool Instance::pauseGifByRoundVideo() const {
return _roundPlaying; return _roundPlaying;
} }
void Instance::stopAndClose() {
_closePlayerRequests.fire({});
stop(AudioMsgId::Type::Voice);
stop(AudioMsgId::Type::Song);
Shortcuts::ToggleMediaShortcuts(false);
}
void Instance::handleStreamingUpdate( void Instance::handleStreamingUpdate(
not_null<Data*> data, not_null<Data*> data,
Streaming::Update &&update) { Streaming::Update &&update) {

View file

@ -168,6 +168,11 @@ public:
[[nodiscard]] bool pauseGifByRoundVideo() const; [[nodiscard]] bool pauseGifByRoundVideo() const;
[[nodiscard]] rpl::producer<> closePlayerRequests() const {
return _closePlayerRequests.events();
}
void stopAndClose();
private: private:
using SharedMediaType = Storage::SharedMediaType; using SharedMediaType = Storage::SharedMediaType;
using SliceKey = SparseIdsMergedSlice::Key; using SliceKey = SparseIdsMergedSlice::Key;
@ -312,6 +317,7 @@ private:
rpl::event_stream<AudioMsgId::Type> _playerStartedPlay; rpl::event_stream<AudioMsgId::Type> _playerStartedPlay;
rpl::event_stream<TrackState> _updatedNotifier; rpl::event_stream<TrackState> _updatedNotifier;
rpl::event_stream<SeekingChanges> _seekingChanges; rpl::event_stream<SeekingChanges> _seekingChanges;
rpl::event_stream<> _closePlayerRequests;
rpl::lifetime _lifetime; rpl::lifetime _lifetime;
}; };

View file

@ -14,14 +14,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_document.h" #include "data/data_document.h"
#include "data/data_document_media.h" #include "data/data_document_media.h"
#include "data/data_file_origin.h" #include "data/data_file_origin.h"
#include "mainwidget.h"
#include "main/main_account.h" #include "main/main_account.h"
#include "main/main_session.h" #include "main/main_session.h"
#include "media/audio/media_audio.h" #include "media/audio/media_audio.h"
#include "media/streaming/media_streaming_instance.h" #include "media/streaming/media_streaming_instance.h"
#include "media/streaming/media_streaming_player.h" #include "media/streaming/media_streaming_player.h"
#include "ui/text/format_song_document_name.h" #include "ui/text/format_song_document_name.h"
#include "window/window_controller.h"
#include <ksandbox.h> #include <ksandbox.h>
@ -45,8 +43,7 @@ bool SystemMediaControlsManager::Supported() {
return base::Platform::SystemMediaControls::Supported(); return base::Platform::SystemMediaControls::Supported();
} }
SystemMediaControlsManager::SystemMediaControlsManager( SystemMediaControlsManager::SystemMediaControlsManager()
not_null<Window::Controller*> controller)
: _controls(std::make_unique<base::Platform::SystemMediaControls>()) { : _controls(std::make_unique<base::Platform::SystemMediaControls>()) {
using PlaybackStatus = using PlaybackStatus =
@ -58,7 +55,7 @@ SystemMediaControlsManager::SystemMediaControlsManager(
_controls->setServiceName(u"tdesktop"_q); _controls->setServiceName(u"tdesktop"_q);
} }
_controls->setApplicationName(AppName.utf16()); _controls->setApplicationName(AppName.utf16());
const auto inited = _controls->init(controller->widget()); const auto inited = _controls->init();
if (!inited) { if (!inited) {
LOG(("SystemMediaControlsManager failed to init.")); LOG(("SystemMediaControlsManager failed to init."));
return; return;
@ -227,7 +224,7 @@ SystemMediaControlsManager::SystemMediaControlsManager(
case Command::Next: mediaPlayer->next(type); break; case Command::Next: mediaPlayer->next(type); break;
case Command::Previous: mediaPlayer->previous(type); break; case Command::Previous: mediaPlayer->previous(type); break;
case Command::Stop: mediaPlayer->stop(type); break; case Command::Stop: mediaPlayer->stop(type); break;
case Command::Raise: controller->widget()->showFromTray(); break; case Command::Raise: Core::App().activate(); break;
case Command::LoopNone: { case Command::LoopNone: {
Core::App().settings().setPlayerRepeatMode(RepeatMode::None); Core::App().settings().setPlayerRepeatMode(RepeatMode::None);
Core::App().saveSettingsDelayed(); Core::App().saveSettingsDelayed();
@ -252,9 +249,7 @@ SystemMediaControlsManager::SystemMediaControlsManager(
break; break;
} }
case Command::Quit: { case Command::Quit: {
if (const auto main = controller->widget()->sessionContent()) { Media::Player::instance()->stopAndClose();
main->closeBothPlayers();
}
break; break;
} }
} }

View file

@ -30,7 +30,7 @@ namespace Media {
class SystemMediaControlsManager { class SystemMediaControlsManager {
public: public:
SystemMediaControlsManager(not_null<Window::Controller*> controller); SystemMediaControlsManager();
~SystemMediaControlsManager(); ~SystemMediaControlsManager();
static bool Supported(); static bool Supported();

View file

@ -15,7 +15,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/stickers/data_stickers.h" // Stickers::setsRef() #include "data/stickers/data_stickers.h" // Stickers::setsRef()
#include "main/main_domain.h" #include "main/main_domain.h"
#include "main/main_session.h" #include "main/main_session.h"
#include "mainwidget.h" // MainWidget::closeBothPlayers
#include "media/audio/media_audio_capture.h" #include "media/audio/media_audio_capture.h"
#include "media/player/media_player_instance.h" #include "media/player/media_player_instance.h"
#include "platform/mac/touchbar/mac_touchbar_audio.h" #include "platform/mac/touchbar/mac_touchbar_audio.h"
@ -171,9 +170,7 @@ const auto kAudioItemIdentifier = @"touchbarAudio";
autorelease]; autorelease];
item.groupTouchBar = touchBar; item.groupTouchBar = touchBar;
[touchBar closeRequests] | rpl::start_with_next([=] { [touchBar closeRequests] | rpl::start_with_next([=] {
if (const auto session = _controller->sessionController()) { Media::Player::instance()->stopAndClose();
session->content()->closeBothPlayers();
}
}, [item lifetime]); }, [item lifetime]);
return [item autorelease]; return [item autorelease];
} }

@ -1 +1 @@
Subproject commit a21505416a8e64368925e02f13de2d97f7b476b3 Subproject commit 17cac57d9ed5bf8250861a4d11ddf2b4e4e5d641