mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Initial support of separate windows for accounts.
This commit is contained in:
parent
86ed2745e3
commit
7023b013ce
32 changed files with 323 additions and 143 deletions
|
@ -123,22 +123,18 @@ using UpdatedFileReferences = Data::UpdatedFileReferences;
|
||||||
|
|
||||||
[[nodiscard]] std::shared_ptr<Window::Show> ShowForPeer(
|
[[nodiscard]] std::shared_ptr<Window::Show> ShowForPeer(
|
||||||
not_null<PeerData*> peer) {
|
not_null<PeerData*> peer) {
|
||||||
const auto separate = Core::App().separateWindowForPeer(peer);
|
return std::make_shared<Window::Show>(Core::App().windowFor(peer));
|
||||||
const auto window = separate ? separate : Core::App().primaryWindow();
|
|
||||||
return std::make_shared<Window::Show>(window);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowChannelsLimitBox(not_null<PeerData*> peer) {
|
void ShowChannelsLimitBox(not_null<PeerData*> peer) {
|
||||||
const auto primary = Core::App().primaryWindow();
|
if (const auto window = Core::App().windowFor(peer)) {
|
||||||
if (!primary) {
|
window->invokeForSessionController(
|
||||||
return;
|
&peer->session().account(),
|
||||||
|
peer,
|
||||||
|
[&](not_null<Window::SessionController*> controller) {
|
||||||
|
controller->show(Box(ChannelsLimitBox, &peer->session()));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
primary->invokeForSessionController(
|
|
||||||
&peer->session().account(),
|
|
||||||
peer,
|
|
||||||
[&](not_null<Window::SessionController*> controller) {
|
|
||||||
controller->show(Box(ChannelsLimitBox, &peer->session()));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -20,7 +20,7 @@ void showBox(
|
||||||
LayerOptions options,
|
LayerOptions options,
|
||||||
anim::type animated) {
|
anim::type animated) {
|
||||||
const auto window = Core::IsAppLaunched()
|
const auto window = Core::IsAppLaunched()
|
||||||
? Core::App().primaryWindow()
|
? Core::App().activePrimaryWindow()
|
||||||
: nullptr;
|
: nullptr;
|
||||||
if (window) {
|
if (window) {
|
||||||
window->show(std::move(content), options, animated);
|
window->show(std::move(content), options, animated);
|
||||||
|
@ -31,7 +31,7 @@ void showBox(
|
||||||
|
|
||||||
void hideLayer(anim::type animated) {
|
void hideLayer(anim::type animated) {
|
||||||
const auto window = Core::IsAppLaunched()
|
const auto window = Core::IsAppLaunched()
|
||||||
? Core::App().primaryWindow()
|
? Core::App().activePrimaryWindow()
|
||||||
: nullptr;
|
: nullptr;
|
||||||
if (window) {
|
if (window) {
|
||||||
window->hideLayer(animated);
|
window->hideLayer(animated);
|
||||||
|
@ -40,7 +40,7 @@ void hideLayer(anim::type animated) {
|
||||||
|
|
||||||
bool isLayerShown() {
|
bool isLayerShown() {
|
||||||
const auto window = Core::IsAppLaunched()
|
const auto window = Core::IsAppLaunched()
|
||||||
? Core::App().primaryWindow()
|
? Core::App().activePrimaryWindow()
|
||||||
: nullptr;
|
: nullptr;
|
||||||
return window && window->isLayerShown();
|
return window && window->isLayerShown();
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,10 +69,11 @@ void ChangeFilterById(
|
||||||
MTP_flags(MTPmessages_UpdateDialogFilter::Flag::f_filter),
|
MTP_flags(MTPmessages_UpdateDialogFilter::Flag::f_filter),
|
||||||
MTP_int(filter.id()),
|
MTP_int(filter.id()),
|
||||||
filter.tl()
|
filter.tl()
|
||||||
)).done([=, chat = history->peer->name(), name = filter.title()]{
|
)).done([=, chat = history->peer->name(), name = filter.title()] {
|
||||||
// Since only the primary window has dialogs list,
|
// Since only the primary window has dialogs list,
|
||||||
// We can safely show toast there.
|
// We can safely show toast there.
|
||||||
if (const auto controller = Core::App().primaryWindow()) {
|
const auto account = &history->session().account();
|
||||||
|
if (const auto controller = Core::App().windowFor(account)) {
|
||||||
auto text = (add
|
auto text = (add
|
||||||
? tr::lng_filters_toast_add
|
? tr::lng_filters_toast_add
|
||||||
: tr::lng_filters_toast_remove)(
|
: tr::lng_filters_toast_remove)(
|
||||||
|
|
|
@ -1194,10 +1194,7 @@ base::unique_qptr<Ui::PopupMenu> Members::Controller::createRowContextMenu(
|
||||||
const auto admin = IsGroupCallAdmin(_peer, participantPeer);
|
const auto admin = IsGroupCallAdmin(_peer, participantPeer);
|
||||||
const auto session = &_peer->session();
|
const auto session = &_peer->session();
|
||||||
const auto getCurrentWindow = [=]() -> Window::SessionController* {
|
const auto getCurrentWindow = [=]() -> Window::SessionController* {
|
||||||
if (const auto window = Core::App().separateWindowForPeer(
|
if (const auto window = Core::App().windowFor(participantPeer)) {
|
||||||
participantPeer)) {
|
|
||||||
return window->sessionController();
|
|
||||||
} else if (const auto window = Core::App().primaryWindow()) {
|
|
||||||
if (const auto controller = window->sessionController()) {
|
if (const auto controller = window->sessionController()) {
|
||||||
if (&controller->session() == session) {
|
if (&controller->session() == session) {
|
||||||
return controller;
|
return controller;
|
||||||
|
|
|
@ -186,8 +186,9 @@ Application::~Application() {
|
||||||
// Depend on primaryWindow() for now :(
|
// Depend on primaryWindow() for now :(
|
||||||
Shortcuts::Finish();
|
Shortcuts::Finish();
|
||||||
|
|
||||||
|
_closingAsyncWindows.clear();
|
||||||
_secondaryWindows.clear();
|
_secondaryWindows.clear();
|
||||||
_primaryWindow = nullptr;
|
_primaryWindows.clear();
|
||||||
_mediaView = nullptr;
|
_mediaView = nullptr;
|
||||||
_notifications->clearAllFast();
|
_notifications->clearAllFast();
|
||||||
|
|
||||||
|
@ -280,13 +281,15 @@ void Application::run() {
|
||||||
// Create mime database, so it won't be slow later.
|
// Create mime database, so it won't be slow later.
|
||||||
QMimeDatabase().mimeTypeForName(u"text/plain"_q);
|
QMimeDatabase().mimeTypeForName(u"text/plain"_q);
|
||||||
|
|
||||||
_primaryWindow = std::make_unique<Window::Controller>();
|
_primaryWindows.emplace(nullptr, std::make_unique<Window::Controller>());
|
||||||
_lastActiveWindow = _primaryWindow.get();
|
_lastActiveWindow
|
||||||
|
= _lastActivePrimaryWindow
|
||||||
|
= _primaryWindows.front().second.get();
|
||||||
|
|
||||||
_domain->activeChanges(
|
_domain->activeChanges(
|
||||||
) | rpl::start_with_next([=](not_null<Main::Account*> account) {
|
) | rpl::start_with_next([=](not_null<Main::Account*> account) {
|
||||||
_primaryWindow->showAccount(account);
|
showAccount(account);
|
||||||
}, _primaryWindow->widget()->lifetime());
|
}, _lifetime);
|
||||||
|
|
||||||
(
|
(
|
||||||
_domain->activeValue(
|
_domain->activeValue(
|
||||||
|
@ -303,15 +306,15 @@ void Application::run() {
|
||||||
) | rpl::start_with_next([=](not_null<Main::Account*> account) {
|
) | rpl::start_with_next([=](not_null<Main::Account*> account) {
|
||||||
const auto ordered = _domain->orderedAccounts();
|
const auto ordered = _domain->orderedAccounts();
|
||||||
const auto it = ranges::find(ordered, account);
|
const auto it = ranges::find(ordered, account);
|
||||||
if (it != end(ordered)) {
|
if (_lastActivePrimaryWindow && it != end(ordered)) {
|
||||||
const auto index = std::distance(begin(ordered), it);
|
const auto index = std::distance(begin(ordered), it);
|
||||||
if ((index + 1) > _domain->maxAccounts()) {
|
if ((index + 1) > _domain->maxAccounts()) {
|
||||||
_primaryWindow->show(Box(
|
_lastActivePrimaryWindow->show(Box(
|
||||||
AccountsLimitBox,
|
AccountsLimitBox,
|
||||||
&account->session()));
|
&account->session()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, _primaryWindow->widget()->lifetime());
|
}, _lifetime);
|
||||||
|
|
||||||
QCoreApplication::instance()->installEventFilter(this);
|
QCoreApplication::instance()->installEventFilter(this);
|
||||||
|
|
||||||
|
@ -332,20 +335,20 @@ void Application::run() {
|
||||||
|
|
||||||
startTray();
|
startTray();
|
||||||
|
|
||||||
_primaryWindow->widget()->show();
|
_lastActivePrimaryWindow->widget()->show();
|
||||||
|
|
||||||
const auto currentGeometry = _primaryWindow->widget()->geometry();
|
const auto current = _lastActivePrimaryWindow->widget()->geometry();
|
||||||
_mediaView = std::make_unique<Media::View::OverlayWidget>();
|
_mediaView = std::make_unique<Media::View::OverlayWidget>();
|
||||||
_primaryWindow->widget()->Ui::RpWidget::setGeometry(currentGeometry);
|
_lastActivePrimaryWindow->widget()->Ui::RpWidget::setGeometry(current);
|
||||||
|
|
||||||
DEBUG_LOG(("Application Info: showing."));
|
DEBUG_LOG(("Application Info: showing."));
|
||||||
_primaryWindow->finishFirstShow();
|
_lastActivePrimaryWindow->finishFirstShow();
|
||||||
|
|
||||||
if (!_primaryWindow->locked() && cStartToSettings()) {
|
if (!_lastActivePrimaryWindow->locked() && cStartToSettings()) {
|
||||||
_primaryWindow->showSettings();
|
_lastActivePrimaryWindow->showSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
_primaryWindow->updateIsActiveFocus();
|
_lastActivePrimaryWindow->updateIsActiveFocus();
|
||||||
|
|
||||||
for (const auto &error : Shortcuts::Errors()) {
|
for (const auto &error : Shortcuts::Errors()) {
|
||||||
LOG(("Shortcuts Error: %1").arg(error));
|
LOG(("Shortcuts Error: %1").arg(error));
|
||||||
|
@ -362,11 +365,6 @@ void Application::run() {
|
||||||
_mediaView->show(std::move(request));
|
_mediaView->show(std::move(request));
|
||||||
}
|
}
|
||||||
}, _lifetime);
|
}, _lifetime);
|
||||||
_primaryWindow->openInMediaViewRequests(
|
|
||||||
) | rpl::start_to_stream(
|
|
||||||
_openInMediaViewRequests,
|
|
||||||
_primaryWindow->lifetime());
|
|
||||||
|
|
||||||
{
|
{
|
||||||
const auto countries = std::make_shared<Countries::Manager>(
|
const auto countries = std::make_shared<Countries::Manager>(
|
||||||
_domain.get());
|
_domain.get());
|
||||||
|
@ -374,6 +372,25 @@ void Application::run() {
|
||||||
[[maybe_unused]] const auto countriesCopy = countries;
|
[[maybe_unused]] const auto countriesCopy = countries;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
processCreatedWindow(_lastActivePrimaryWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::showAccount(not_null<Main::Account*> account) {
|
||||||
|
if (const auto separate = separateWindowForAccount(account)) {
|
||||||
|
_lastActivePrimaryWindow = separate;
|
||||||
|
separate->activate();
|
||||||
|
} else if (const auto last = activePrimaryWindow()) {
|
||||||
|
for (auto &[key, window] : _primaryWindows) {
|
||||||
|
if (window.get() == last && key != account.get()) {
|
||||||
|
auto found = std::move(window);
|
||||||
|
_primaryWindows.remove(key);
|
||||||
|
_primaryWindows.emplace(account, std::move(found));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
last->showAccount(account);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::showOpenGLCrashNotification() {
|
void Application::showOpenGLCrashNotification() {
|
||||||
|
@ -390,7 +407,7 @@ void Application::showOpenGLCrashNotification() {
|
||||||
Core::App().settings().setDisableOpenGL(true);
|
Core::App().settings().setDisableOpenGL(true);
|
||||||
Local::writeSettings();
|
Local::writeSettings();
|
||||||
};
|
};
|
||||||
_primaryWindow->show(Ui::MakeConfirmBox({
|
_lastActivePrimaryWindow->show(Ui::MakeConfirmBox({
|
||||||
.text = ""
|
.text = ""
|
||||||
"There may be a problem with your graphics drivers and OpenGL. "
|
"There may be a problem with your graphics drivers and OpenGL. "
|
||||||
"Try updating your drivers.\n\n"
|
"Try updating your drivers.\n\n"
|
||||||
|
@ -447,15 +464,15 @@ void Application::startSystemDarkModeViewer() {
|
||||||
|
|
||||||
void Application::enumerateWindows(Fn<void(
|
void Application::enumerateWindows(Fn<void(
|
||||||
not_null<Window::Controller*>)> callback) const {
|
not_null<Window::Controller*>)> callback) const {
|
||||||
if (_primaryWindow) {
|
for (const auto &window : ranges::views::values(_primaryWindows)) {
|
||||||
callback(_primaryWindow.get());
|
callback(window.get());
|
||||||
}
|
}
|
||||||
for (const auto &window : ranges::views::values(_secondaryWindows)) {
|
for (const auto &window : ranges::views::values(_secondaryWindows)) {
|
||||||
callback(window.get());
|
callback(window.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::processSecondaryWindow(
|
void Application::processCreatedWindow(
|
||||||
not_null<Window::Controller*> window) {
|
not_null<Window::Controller*> window) {
|
||||||
window->openInMediaViewRequests(
|
window->openInMediaViewRequests(
|
||||||
) | rpl::start_to_stream(_openInMediaViewRequests, window->lifetime());
|
) | rpl::start_to_stream(_openInMediaViewRequests, window->lifetime());
|
||||||
|
@ -468,21 +485,29 @@ void Application::startTray() {
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
enumerateWindows([&](WindowRaw w) { w->updateIsActive(); });
|
enumerateWindows([&](WindowRaw w) { w->updateIsActive(); });
|
||||||
_tray->updateMenuText();
|
_tray->updateMenuText();
|
||||||
}, _primaryWindow->widget()->lifetime());
|
}, _lifetime);
|
||||||
|
|
||||||
_tray->showFromTrayRequests(
|
_tray->showFromTrayRequests(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
const auto last = _lastActiveWindow;
|
const auto last = _lastActiveWindow;
|
||||||
enumerateWindows([&](WindowRaw w) { w->widget()->showFromTray(); });
|
const auto primary = _lastActivePrimaryWindow;
|
||||||
if (last) {
|
enumerateWindows([&](WindowRaw w) {
|
||||||
|
if (w != last && w != primary) {
|
||||||
|
w->widget()->showFromTray();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (primary) {
|
||||||
|
primary->widget()->showFromTray();
|
||||||
|
}
|
||||||
|
if (last && last != primary) {
|
||||||
last->widget()->showFromTray();
|
last->widget()->showFromTray();
|
||||||
}
|
}
|
||||||
}, _primaryWindow->widget()->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(); });
|
||||||
}, _primaryWindow->widget()->lifetime());
|
}, _lifetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Application::prepareEmojiSourceImages()
|
auto Application::prepareEmojiSourceImages()
|
||||||
|
@ -504,10 +529,10 @@ void Application::clearEmojiSourceImages() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Application::isActiveForTrayMenu() const {
|
bool Application::isActiveForTrayMenu() const {
|
||||||
if (_primaryWindow && _primaryWindow->widget()->isActiveForTrayMenu()) {
|
return ranges::any_of(ranges::views::values(_primaryWindows), [=](
|
||||||
return true;
|
const std::unique_ptr<Window::Controller> &controller) {
|
||||||
}
|
return controller->widget()->isActiveForTrayMenu();
|
||||||
return ranges::any_of(ranges::views::values(_secondaryWindows), [=](
|
}) || ranges::any_of(ranges::views::values(_secondaryWindows), [=](
|
||||||
const std::unique_ptr<Window::Controller> &controller) {
|
const std::unique_ptr<Window::Controller> &controller) {
|
||||||
return controller->widget()->isActiveForTrayMenu();
|
return controller->widget()->isActiveForTrayMenu();
|
||||||
});
|
});
|
||||||
|
@ -562,8 +587,8 @@ bool Application::eventFilter(QObject *object, QEvent *e) {
|
||||||
cSetStartUrl(url.mid(0, 8192));
|
cSetStartUrl(url.mid(0, 8192));
|
||||||
checkStartUrl();
|
checkStartUrl();
|
||||||
}
|
}
|
||||||
if (StartUrlRequiresActivate(url)) {
|
if (_lastActivePrimaryWindow && StartUrlRequiresActivate(url)) {
|
||||||
_primaryWindow->activate();
|
_lastActivePrimaryWindow->activate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
@ -804,15 +829,15 @@ void Application::checkLocalTime() {
|
||||||
|
|
||||||
void Application::handleAppActivated() {
|
void Application::handleAppActivated() {
|
||||||
checkLocalTime();
|
checkLocalTime();
|
||||||
if (_primaryWindow) {
|
if (_lastActiveWindow) {
|
||||||
_primaryWindow->updateIsActiveFocus();
|
_lastActiveWindow->updateIsActiveFocus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::handleAppDeactivated() {
|
void Application::handleAppDeactivated() {
|
||||||
if (_primaryWindow) {
|
enumerateWindows([&](not_null<Window::Controller*> w) {
|
||||||
_primaryWindow->updateIsActiveBlur();
|
w->updateIsActiveBlur();
|
||||||
}
|
});
|
||||||
const auto session = _lastActiveWindow
|
const auto session = _lastActiveWindow
|
||||||
? _lastActiveWindow->maybeSession()
|
? _lastActiveWindow->maybeSession()
|
||||||
: nullptr;
|
: nullptr;
|
||||||
|
@ -845,8 +870,8 @@ void Application::switchDebugMode() {
|
||||||
Logs::SetDebugEnabled(true);
|
Logs::SetDebugEnabled(true);
|
||||||
_launcher->writeDebugModeSetting();
|
_launcher->writeDebugModeSetting();
|
||||||
DEBUG_LOG(("Debug logs started."));
|
DEBUG_LOG(("Debug logs started."));
|
||||||
if (_primaryWindow) {
|
if (_lastActivePrimaryWindow) {
|
||||||
_primaryWindow->hideLayer();
|
_lastActivePrimaryWindow->hideLayer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -959,13 +984,17 @@ bool Application::canApplyLangPackWithoutRestart() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::checkSendPaths() {
|
void Application::checkSendPaths() {
|
||||||
if (!cSendPaths().isEmpty() && _primaryWindow && !_primaryWindow->locked()) {
|
if (!cSendPaths().isEmpty()
|
||||||
_primaryWindow->widget()->sendPaths();
|
&& _lastActivePrimaryWindow
|
||||||
|
&& !_lastActivePrimaryWindow->locked()) {
|
||||||
|
_lastActivePrimaryWindow->widget()->sendPaths();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::checkStartUrl() {
|
void Application::checkStartUrl() {
|
||||||
if (!cStartUrl().isEmpty() && _primaryWindow && !_primaryWindow->locked()) {
|
if (!cStartUrl().isEmpty()
|
||||||
|
&& _lastActivePrimaryWindow
|
||||||
|
&& !_lastActivePrimaryWindow->locked()) {
|
||||||
const auto url = cStartUrl();
|
const auto url = cStartUrl();
|
||||||
cSetStartUrl(QString());
|
cSetStartUrl(QString());
|
||||||
if (!openLocalUrl(url, {})) {
|
if (!openLocalUrl(url, {})) {
|
||||||
|
@ -1029,8 +1058,8 @@ bool Application::openCustomUrl(
|
||||||
const auto my = context.value<ClickHandlerContext>();
|
const auto my = context.value<ClickHandlerContext>();
|
||||||
const auto controller = my.sessionWindow.get()
|
const auto controller = my.sessionWindow.get()
|
||||||
? my.sessionWindow.get()
|
? my.sessionWindow.get()
|
||||||
: _primaryWindow
|
: _lastActivePrimaryWindow
|
||||||
? _primaryWindow->sessionController()
|
? _lastActivePrimaryWindow->sessionController()
|
||||||
: nullptr;
|
: nullptr;
|
||||||
|
|
||||||
using namespace qthelp;
|
using namespace qthelp;
|
||||||
|
@ -1042,11 +1071,10 @@ bool Application::openCustomUrl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::preventOrInvoke(Fn<void()> &&callback) {
|
void Application::preventOrInvoke(Fn<void()> &&callback) {
|
||||||
_primaryWindow->preventOrInvoke(std::move(callback));
|
_lastActivePrimaryWindow->preventOrInvoke(std::move(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::lockByPasscode() {
|
void Application::lockByPasscode() {
|
||||||
|
@ -1150,7 +1178,7 @@ void Application::localPasscodeChanged() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Application::hasActiveWindow(not_null<Main::Session*> session) const {
|
bool Application::hasActiveWindow(not_null<Main::Session*> session) const {
|
||||||
if (Quitting() || !_primaryWindow) {
|
if (Quitting() || !_lastActiveWindow) {
|
||||||
return false;
|
return false;
|
||||||
} else if (_calls->hasActivePanel(session)) {
|
} else if (_calls->hasActivePanel(session)) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -1161,8 +1189,18 @@ bool Application::hasActiveWindow(not_null<Main::Session*> session) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Window::Controller *Application::primaryWindow() const {
|
Window::Controller *Application::activePrimaryWindow() const {
|
||||||
return _primaryWindow.get();
|
return _lastActivePrimaryWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
Window::Controller *Application::separateWindowForAccount(
|
||||||
|
not_null<Main::Account*> account) const {
|
||||||
|
for (const auto &[openedAccount, window] : _primaryWindows) {
|
||||||
|
if (openedAccount == account.get()) {
|
||||||
|
return window.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Window::Controller *Application::separateWindowForPeer(
|
Window::Controller *Application::separateWindowForPeer(
|
||||||
|
@ -1194,22 +1232,98 @@ Window::Controller *Application::ensureSeparateWindowForPeer(
|
||||||
peer->owner().history(peer),
|
peer->owner().history(peer),
|
||||||
std::make_unique<Window::Controller>(peer, showAtMsgId)
|
std::make_unique<Window::Controller>(peer, showAtMsgId)
|
||||||
).first->second.get();
|
).first->second.get();
|
||||||
processSecondaryWindow(result);
|
processCreatedWindow(result);
|
||||||
result->widget()->show();
|
result->widget()->show();
|
||||||
result->finishFirstShow();
|
result->finishFirstShow();
|
||||||
return activate(result);
|
return activate(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Window::Controller *Application::ensureSeparateWindowForAccount(
|
||||||
|
not_null<Main::Account*> account) {
|
||||||
|
const auto activate = [&](not_null<Window::Controller*> window) {
|
||||||
|
window->activate();
|
||||||
|
return window;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (const auto existing = separateWindowForAccount(account)) {
|
||||||
|
return activate(existing);
|
||||||
|
}
|
||||||
|
const auto result = _primaryWindows.emplace(
|
||||||
|
account,
|
||||||
|
std::make_unique<Window::Controller>(account)
|
||||||
|
).first->second.get();
|
||||||
|
processCreatedWindow(result);
|
||||||
|
result->widget()->show();
|
||||||
|
result->finishFirstShow();
|
||||||
|
return activate(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
Window::Controller *Application::windowFor(not_null<PeerData*> peer) const {
|
||||||
|
if (const auto separate = separateWindowForPeer(peer)) {
|
||||||
|
return separate;
|
||||||
|
}
|
||||||
|
return windowFor(&peer->account());
|
||||||
|
}
|
||||||
|
|
||||||
|
Window::Controller *Application::windowFor(
|
||||||
|
not_null<Main::Account*> account) const {
|
||||||
|
if (const auto separate = separateWindowForAccount(account)) {
|
||||||
|
return separate;
|
||||||
|
}
|
||||||
|
return activePrimaryWindow();
|
||||||
|
}
|
||||||
|
|
||||||
Window::Controller *Application::activeWindow() const {
|
Window::Controller *Application::activeWindow() const {
|
||||||
return _lastActiveWindow;
|
return _lastActiveWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Application::closeNonLastAsync(not_null<Window::Controller*> window) {
|
||||||
|
const auto hasOther = [&] {
|
||||||
|
for (const auto &[account, primary] : _primaryWindows) {
|
||||||
|
if (!_closingAsyncWindows.contains(primary.get())
|
||||||
|
&& primary.get() != window
|
||||||
|
&& primary->maybeSession()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}();
|
||||||
|
if (!hasOther) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_closingAsyncWindows.emplace(window);
|
||||||
|
crl::on_main(window, [=] { closeWindow(window); });
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void Application::closeWindow(not_null<Window::Controller*> window) {
|
void Application::closeWindow(not_null<Window::Controller*> window) {
|
||||||
|
const auto next = (_primaryWindows.front().second.get() != window)
|
||||||
|
? _primaryWindows.front().second.get()
|
||||||
|
: (_primaryWindows.back().second.get() != window)
|
||||||
|
? _primaryWindows.back().second.get()
|
||||||
|
: nullptr;
|
||||||
|
if (_lastActivePrimaryWindow == window) {
|
||||||
|
_lastActivePrimaryWindow = next;
|
||||||
|
}
|
||||||
|
if (_lastActiveWindow == window) {
|
||||||
|
_lastActiveWindow = next;
|
||||||
|
if (_lastActiveWindow) {
|
||||||
|
_lastActiveWindow->activate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_closingAsyncWindows.remove(window);
|
||||||
|
for (auto i = begin(_primaryWindows); i != end(_primaryWindows);) {
|
||||||
|
if (i->second.get() == window) {
|
||||||
|
Assert(_lastActiveWindow != window);
|
||||||
|
Assert(_lastActivePrimaryWindow != window);
|
||||||
|
i = _primaryWindows.erase(i);
|
||||||
|
} else {
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
for (auto i = begin(_secondaryWindows); i != end(_secondaryWindows);) {
|
for (auto i = begin(_secondaryWindows); i != end(_secondaryWindows);) {
|
||||||
if (i->second.get() == window) {
|
if (i->second.get() == window) {
|
||||||
if (_lastActiveWindow == window) {
|
Assert(_lastActiveWindow != window);
|
||||||
_lastActiveWindow = _primaryWindow.get();
|
|
||||||
}
|
|
||||||
i = _secondaryWindows.erase(i);
|
i = _secondaryWindows.erase(i);
|
||||||
} else {
|
} else {
|
||||||
++i;
|
++i;
|
||||||
|
@ -1218,11 +1332,12 @@ void Application::closeWindow(not_null<Window::Controller*> window) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::closeChatFromWindows(not_null<PeerData*> peer) {
|
void Application::closeChatFromWindows(not_null<PeerData*> peer) {
|
||||||
|
if (const auto window = windowFor(peer)
|
||||||
|
; window && !window->isPrimary()) {
|
||||||
|
closeWindow(window);
|
||||||
|
}
|
||||||
for (const auto &[history, window] : _secondaryWindows) {
|
for (const auto &[history, window] : _secondaryWindows) {
|
||||||
if (history->peer == peer) {
|
if (const auto session = window->sessionController()) {
|
||||||
closeWindow(window.get());
|
|
||||||
break;
|
|
||||||
} else if (const auto session = window->sessionController()) {
|
|
||||||
if (session->activeChatCurrent().peer() == peer) {
|
if (session->activeChatCurrent().peer() == peer) {
|
||||||
session->showPeerHistory(
|
session->showPeerHistory(
|
||||||
window->singlePeer()->id,
|
window->singlePeer()->id,
|
||||||
|
@ -1230,8 +1345,8 @@ void Application::closeChatFromWindows(not_null<PeerData*> peer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_primaryWindow && _primaryWindow->sessionController()) {
|
if (const auto window = windowFor(&peer->account())) {
|
||||||
const auto primary = _primaryWindow->sessionController();
|
const auto primary = window->sessionController();
|
||||||
if ((primary->activeChatCurrent().peer() == peer)
|
if ((primary->activeChatCurrent().peer() == peer)
|
||||||
&& (&primary->session() == &peer->session())) {
|
&& (&primary->session() == &peer->session())) {
|
||||||
primary->clearSectionStack();
|
primary->clearSectionStack();
|
||||||
|
@ -1249,6 +1364,10 @@ void Application::windowActivated(not_null<Window::Controller*> window) {
|
||||||
const auto now = window;
|
const auto now = window;
|
||||||
_lastActiveWindow = window;
|
_lastActiveWindow = window;
|
||||||
|
|
||||||
|
if (window->isPrimary()) {
|
||||||
|
_lastActivePrimaryWindow = window;
|
||||||
|
}
|
||||||
|
|
||||||
const auto wasSession = was ? was->maybeSession() : nullptr;
|
const auto wasSession = was ? was->maybeSession() : nullptr;
|
||||||
const auto nowSession = now->maybeSession();
|
const auto nowSession = now->maybeSession();
|
||||||
if (wasSession != nowSession) {
|
if (wasSession != nowSession) {
|
||||||
|
@ -1410,8 +1529,8 @@ void Application::quitPreventFinished() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::quitDelayed() {
|
void Application::quitDelayed() {
|
||||||
if (_primaryWindow) {
|
for (const auto &[account, window] : _primaryWindows) {
|
||||||
_primaryWindow->widget()->hide();
|
window->widget()->hide();
|
||||||
}
|
}
|
||||||
for (const auto &[history, window] : _secondaryWindows) {
|
for (const auto &[history, window] : _secondaryWindows) {
|
||||||
window->widget()->hide();
|
window->widget()->hide();
|
||||||
|
|
|
@ -152,13 +152,25 @@ public:
|
||||||
|
|
||||||
// Windows interface.
|
// Windows interface.
|
||||||
bool hasActiveWindow(not_null<Main::Session*> session) const;
|
bool hasActiveWindow(not_null<Main::Session*> session) const;
|
||||||
[[nodiscard]] Window::Controller *primaryWindow() const;
|
|
||||||
|
// Don't auto-switch.
|
||||||
[[nodiscard]] Window::Controller *activeWindow() const;
|
[[nodiscard]] Window::Controller *activeWindow() const;
|
||||||
|
[[nodiscard]] Window::Controller *activePrimaryWindow() const;
|
||||||
|
[[nodiscard]] Window::Controller *separateWindowForAccount(
|
||||||
|
not_null<Main::Account*> account) const;
|
||||||
[[nodiscard]] Window::Controller *separateWindowForPeer(
|
[[nodiscard]] Window::Controller *separateWindowForPeer(
|
||||||
not_null<PeerData*> peer) const;
|
not_null<PeerData*> peer) const;
|
||||||
Window::Controller *ensureSeparateWindowForPeer(
|
Window::Controller *ensureSeparateWindowForPeer(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
MsgId showAtMsgId);
|
MsgId showAtMsgId);
|
||||||
|
Window::Controller *ensureSeparateWindowForAccount(
|
||||||
|
not_null<Main::Account*> account);
|
||||||
|
[[nodiscard]] Window::Controller *windowFor( // Doesn't auto-switch.
|
||||||
|
not_null<PeerData*> peer) const;
|
||||||
|
[[nodiscard]] Window::Controller *windowFor( // Doesn't auto-switch.
|
||||||
|
not_null<Main::Account*> account) const;
|
||||||
|
[[nodiscard]] bool closeNonLastAsync(
|
||||||
|
not_null<Window::Controller*> window);
|
||||||
void closeWindow(not_null<Window::Controller*> window);
|
void closeWindow(not_null<Window::Controller*> window);
|
||||||
void windowActivated(not_null<Window::Controller*> window);
|
void windowActivated(not_null<Window::Controller*> window);
|
||||||
bool closeActiveWindow();
|
bool closeActiveWindow();
|
||||||
|
@ -325,9 +337,10 @@ private:
|
||||||
void startSystemDarkModeViewer();
|
void startSystemDarkModeViewer();
|
||||||
void startTray();
|
void startTray();
|
||||||
|
|
||||||
|
void showAccount(not_null<Main::Account*> account);
|
||||||
void enumerateWindows(
|
void enumerateWindows(
|
||||||
Fn<void(not_null<Window::Controller*>)> callback) const;
|
Fn<void(not_null<Window::Controller*>)> callback) const;
|
||||||
void processSecondaryWindow(not_null<Window::Controller*> window);
|
void processCreatedWindow(not_null<Window::Controller*> window);
|
||||||
|
|
||||||
friend void QuitAttempt();
|
friend void QuitAttempt();
|
||||||
void quitDelayed();
|
void quitDelayed();
|
||||||
|
@ -375,11 +388,15 @@ private:
|
||||||
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;
|
||||||
const std::unique_ptr<Calls::Instance> _calls;
|
const std::unique_ptr<Calls::Instance> _calls;
|
||||||
std::unique_ptr<Window::Controller> _primaryWindow;
|
base::flat_map<
|
||||||
|
Main::Account*,
|
||||||
|
std::unique_ptr<Window::Controller>> _primaryWindows;
|
||||||
|
base::flat_set<not_null<Window::Controller*>> _closingAsyncWindows;
|
||||||
base::flat_map<
|
base::flat_map<
|
||||||
not_null<History*>,
|
not_null<History*>,
|
||||||
std::unique_ptr<Window::Controller>> _secondaryWindows;
|
std::unique_ptr<Window::Controller>> _secondaryWindows;
|
||||||
Window::Controller *_lastActiveWindow = nullptr;
|
Window::Controller *_lastActiveWindow = nullptr;
|
||||||
|
Window::Controller *_lastActivePrimaryWindow = nullptr;
|
||||||
|
|
||||||
std::unique_ptr<Media::View::OverlayWidget> _mediaView;
|
std::unique_ptr<Media::View::OverlayWidget> _mediaView;
|
||||||
const std::unique_ptr<Lang::Instance> _langpack;
|
const std::unique_ptr<Lang::Instance> _langpack;
|
||||||
|
|
|
@ -661,8 +661,8 @@ void Sandbox::closeApplication() {
|
||||||
uint64 Sandbox::execExternal(const QString &cmd) {
|
uint64 Sandbox::execExternal(const QString &cmd) {
|
||||||
DEBUG_LOG(("Sandbox Info: executing external command '%1'").arg(cmd));
|
DEBUG_LOG(("Sandbox Info: executing external command '%1'").arg(cmd));
|
||||||
if (cmd == "show") {
|
if (cmd == "show") {
|
||||||
if (Core::IsAppLaunched() && Core::App().primaryWindow()) {
|
if (Core::IsAppLaunched() && Core::App().activePrimaryWindow()) {
|
||||||
const auto window = Core::App().primaryWindow();
|
const auto window = Core::App().activePrimaryWindow();
|
||||||
window->activate();
|
window->activate();
|
||||||
return Platform::ActivationWindowId(window->widget());
|
return Platform::ActivationWindowId(window->widget());
|
||||||
} else if (const auto window = PreLaunchWindow::instance()) {
|
} else if (const auto window = PreLaunchWindow::instance()) {
|
||||||
|
|
|
@ -443,7 +443,7 @@ void Manager::set(const QString &keys, Command command, bool replace) {
|
||||||
}
|
}
|
||||||
auto shortcut = base::make_unique_q<QShortcut>(
|
auto shortcut = base::make_unique_q<QShortcut>(
|
||||||
result,
|
result,
|
||||||
Core::App().primaryWindow()->widget().get(),
|
Core::App().activePrimaryWindow()->widget().get(), // #TODO windows
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
Qt::ApplicationShortcut);
|
Qt::ApplicationShortcut);
|
||||||
|
|
|
@ -124,7 +124,8 @@ QString UiIntegration::angleBackendFilePath() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void UiIntegration::textActionsUpdated() {
|
void UiIntegration::textActionsUpdated() {
|
||||||
if (const auto window = Core::App().primaryWindow()) {
|
// #TODO windows global menu
|
||||||
|
if (const auto window = Core::App().activePrimaryWindow()) {
|
||||||
window->widget()->updateGlobalMenu();
|
window->widget()->updateGlobalMenu();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1649,7 +1649,7 @@ void UpdateApplication() {
|
||||||
} else {
|
} else {
|
||||||
cSetAutoUpdate(true);
|
cSetAutoUpdate(true);
|
||||||
const auto window = Core::IsAppLaunched()
|
const auto window = Core::IsAppLaunched()
|
||||||
? Core::App().primaryWindow()
|
? Core::App().activePrimaryWindow()
|
||||||
: nullptr;
|
: nullptr;
|
||||||
if (window) {
|
if (window) {
|
||||||
if (const auto controller = window->sessionController()) {
|
if (const auto controller = window->sessionController()) {
|
||||||
|
|
|
@ -508,9 +508,13 @@ HistoryItem *DownloadManager::lookupLoadingItem(
|
||||||
void DownloadManager::loadingStopWithConfirmation(
|
void DownloadManager::loadingStopWithConfirmation(
|
||||||
Fn<void()> callback,
|
Fn<void()> callback,
|
||||||
Main::Session *onlyInSession) {
|
Main::Session *onlyInSession) {
|
||||||
const auto window = Core::App().primaryWindow();
|
|
||||||
const auto item = lookupLoadingItem(onlyInSession);
|
const auto item = lookupLoadingItem(onlyInSession);
|
||||||
if (!window || !item) {
|
if (!item) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto window = Core::App().windowFor(
|
||||||
|
&item->history()->session().account());
|
||||||
|
if (!window) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto weak = base::make_weak(&item->history()->session());
|
const auto weak = base::make_weak(&item->history()->session());
|
||||||
|
|
|
@ -70,7 +70,7 @@ namespace {
|
||||||
constexpr auto kHashtagResultsLimit = 5;
|
constexpr auto kHashtagResultsLimit = 5;
|
||||||
constexpr auto kStartReorderThreshold = 30;
|
constexpr auto kStartReorderThreshold = 30;
|
||||||
|
|
||||||
base::options::toggle TabbedPanelShowOnClick({
|
base::options::toggle CtrlClickChatNewWindow({
|
||||||
.id = kOptionCtrlClickChatNewWindow,
|
.id = kOptionCtrlClickChatNewWindow,
|
||||||
.name = "New chat window by Ctrl+Click",
|
.name = "New chat window by Ctrl+Click",
|
||||||
.description = "Open chat in a new window by Ctrl+Click "
|
.description = "Open chat in a new window by Ctrl+Click "
|
||||||
|
@ -3310,7 +3310,7 @@ bool InnerWidget::chooseRow(
|
||||||
const auto modifyChosenRow = [](
|
const auto modifyChosenRow = [](
|
||||||
ChosenRow row,
|
ChosenRow row,
|
||||||
Qt::KeyboardModifiers modifiers) {
|
Qt::KeyboardModifiers modifiers) {
|
||||||
if (TabbedPanelShowOnClick.value()) {
|
if (CtrlClickChatNewWindow.value()) {
|
||||||
row.newWindow = (modifiers & Qt::ControlModifier);
|
row.newWindow = (modifiers & Qt::ControlModifier);
|
||||||
}
|
}
|
||||||
return row;
|
return row;
|
||||||
|
|
|
@ -732,8 +732,9 @@ HistoryWidget::HistoryWidget(
|
||||||
if (flags & PeerUpdateFlag::UnavailableReason) {
|
if (flags & PeerUpdateFlag::UnavailableReason) {
|
||||||
const auto unavailable = _peer->computeUnavailableReason();
|
const auto unavailable = _peer->computeUnavailableReason();
|
||||||
if (!unavailable.isEmpty()) {
|
if (!unavailable.isEmpty()) {
|
||||||
|
const auto account = &_peer->account();
|
||||||
closeCurrent();
|
closeCurrent();
|
||||||
if (const auto primary = Core::App().primaryWindow()) {
|
if (const auto primary = Core::App().windowFor(account)) {
|
||||||
primary->show(Ui::MakeInformBox(unavailable));
|
primary->show(Ui::MakeInformBox(unavailable));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -3017,7 +3018,7 @@ void HistoryWidget::messagesFailed(const MTP::Error &error, int requestId) {
|
||||||
|| error.type() == u"USER_BANNED_IN_CHANNEL"_q) {
|
|| error.type() == u"USER_BANNED_IN_CHANNEL"_q) {
|
||||||
auto was = _peer;
|
auto was = _peer;
|
||||||
closeCurrent();
|
closeCurrent();
|
||||||
if (const auto primary = Core::App().primaryWindow()) {
|
if (const auto primary = Core::App().windowFor(&was->account())) {
|
||||||
Ui::ShowMultilineToast({
|
Ui::ShowMultilineToast({
|
||||||
.parentOverride = Window::Show(primary).toastParent(),
|
.parentOverride = Window::Show(primary).toastParent(),
|
||||||
.text = { (was && was->isMegagroup())
|
.text = { (was && was->isMegagroup())
|
||||||
|
|
|
@ -75,7 +75,7 @@ Storage::StartResult Domain::start(const QByteArray &passcode) {
|
||||||
|
|
||||||
void Domain::finish() {
|
void Domain::finish() {
|
||||||
_accountToActivate = -1;
|
_accountToActivate = -1;
|
||||||
_active = nullptr;
|
_active.reset(nullptr);
|
||||||
base::take(_accounts);
|
base::take(_accounts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -417,9 +417,13 @@ void Domain::checkForLastProductionConfig(
|
||||||
}
|
}
|
||||||
|
|
||||||
void Domain::maybeActivate(not_null<Main::Account*> account) {
|
void Domain::maybeActivate(not_null<Main::Account*> account) {
|
||||||
Core::App().preventOrInvoke(crl::guard(account, [=] {
|
if (Core::App().separateWindowForAccount(account)) {
|
||||||
activate(account);
|
activate(account);
|
||||||
}));
|
} else {
|
||||||
|
Core::App().preventOrInvoke(crl::guard(account, [=] {
|
||||||
|
activate(account);
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Domain::activate(not_null<Main::Account*> account) {
|
void Domain::activate(not_null<Main::Account*> account) {
|
||||||
|
|
|
@ -20,6 +20,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "chat_helpers/stickers_emoji_pack.h"
|
#include "chat_helpers/stickers_emoji_pack.h"
|
||||||
#include "chat_helpers/stickers_dice_pack.h"
|
#include "chat_helpers/stickers_dice_pack.h"
|
||||||
#include "chat_helpers/stickers_gift_box_pack.h"
|
#include "chat_helpers/stickers_gift_box_pack.h"
|
||||||
|
#include "history/history.h"
|
||||||
|
#include "history/history_item.h"
|
||||||
#include "inline_bots/bot_attach_web_view.h"
|
#include "inline_bots/bot_attach_web_view.h"
|
||||||
#include "storage/file_download.h"
|
#include "storage/file_download.h"
|
||||||
#include "storage/download_manager_mtproto.h"
|
#include "storage/download_manager_mtproto.h"
|
||||||
|
@ -411,12 +413,12 @@ bool Session::uploadsInProgress() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::uploadsStopWithConfirmation(Fn<void()> done) {
|
void Session::uploadsStopWithConfirmation(Fn<void()> done) {
|
||||||
const auto window = Core::App().primaryWindow();
|
|
||||||
if (!window) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const auto id = _uploader->currentUploadId();
|
const auto id = _uploader->currentUploadId();
|
||||||
const auto exists = !!data().message(id);
|
const auto message = data().message(id);
|
||||||
|
const auto exists = (message != nullptr);
|
||||||
|
const auto window = message
|
||||||
|
? Core::App().windowFor(message->history()->peer)
|
||||||
|
: Core::App().activePrimaryWindow();
|
||||||
auto box = Box([=](not_null<Ui::GenericBox*> box) {
|
auto box = Box([=](not_null<Ui::GenericBox*> box) {
|
||||||
box->addRow(
|
box->addRow(
|
||||||
object_ptr<Ui::FlatLabel>(
|
object_ptr<Ui::FlatLabel>(
|
||||||
|
|
|
@ -1214,10 +1214,22 @@ bool MainWidget::showHistoryInDifferentWindow(
|
||||||
showAtMsgId);
|
showAtMsgId);
|
||||||
separate->activate();
|
separate->activate();
|
||||||
return true;
|
return true;
|
||||||
} else if (isPrimary() || (singlePeer()->id == peerId)) {
|
} else if (isPrimary()) {
|
||||||
|
const auto primary = Core::App().separateWindowForAccount(
|
||||||
|
&peer->account());
|
||||||
|
if (primary != &_controller->window()) {
|
||||||
|
primary->sessionController()->showPeerHistory(
|
||||||
|
peerId,
|
||||||
|
params,
|
||||||
|
showAtMsgId);
|
||||||
|
primary->activate();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} else if (singlePeer()->id == peerId) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const auto primary = Core::App().primaryWindow();
|
const auto primary = Core::App().activePrimaryWindow();
|
||||||
if (&primary->account() != &session().account()) {
|
if (&primary->account() != &session().account()) {
|
||||||
primary->showAccount(&session().account());
|
primary->showAccount(&session().account());
|
||||||
}
|
}
|
||||||
|
|
|
@ -666,11 +666,8 @@ void MainWindow::closeEvent(QCloseEvent *e) {
|
||||||
e->accept();
|
e->accept();
|
||||||
Core::Quit();
|
Core::Quit();
|
||||||
return;
|
return;
|
||||||
} else if (!isPrimary()) {
|
} else if (Core::App().closeNonLastAsync(&controller())) {
|
||||||
e->accept();
|
e->accept();
|
||||||
crl::on_main(this, [=] {
|
|
||||||
Core::App().closeWindow(&controller());
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
e->ignore();
|
e->ignore();
|
||||||
|
|
|
@ -308,7 +308,8 @@ void Instance::clearStreamed(not_null<Data*> data, bool savePosition) {
|
||||||
data->streamed = nullptr;
|
data->streamed = nullptr;
|
||||||
|
|
||||||
_roundPlaying = false;
|
_roundPlaying = false;
|
||||||
if (const auto window = Core::App().primaryWindow()) {
|
// #TODO windows
|
||||||
|
if (const auto window = Core::App().activePrimaryWindow()) {
|
||||||
if (const auto controller = window->sessionController()) {
|
if (const auto controller = window->sessionController()) {
|
||||||
controller->disableGifPauseReason(
|
controller->disableGifPauseReason(
|
||||||
Window::GifPauseReason::RoundPlaying);
|
Window::GifPauseReason::RoundPlaying);
|
||||||
|
@ -1292,7 +1293,8 @@ void Instance::handleStreamingUpdate(
|
||||||
requestRoundVideoRepaint();
|
requestRoundVideoRepaint();
|
||||||
});
|
});
|
||||||
_roundPlaying = true;
|
_roundPlaying = true;
|
||||||
if (const auto window = Core::App().primaryWindow()) {
|
// #TODO windows
|
||||||
|
if (const auto window = Core::App().activePrimaryWindow()) {
|
||||||
if (const auto controller = window->sessionController()) {
|
if (const auto controller = window->sessionController()) {
|
||||||
controller->enableGifPauseReason(
|
controller->enableGifPauseReason(
|
||||||
Window::GifPauseReason::RoundPlaying);
|
Window::GifPauseReason::RoundPlaying);
|
||||||
|
|
|
@ -4835,7 +4835,14 @@ Window::SessionController *OverlayWidget::findWindow(bool switchTo) const {
|
||||||
|
|
||||||
if (switchTo) {
|
if (switchTo) {
|
||||||
auto controllerPtr = (Window::SessionController*)nullptr;
|
auto controllerPtr = (Window::SessionController*)nullptr;
|
||||||
const auto anyWindow = window ? window : Core::App().primaryWindow();
|
const auto account = &_session->account();
|
||||||
|
const auto sessionWindow = Core::App().windowFor(account);
|
||||||
|
const auto anyWindow = (sessionWindow
|
||||||
|
&& &sessionWindow->account() == account)
|
||||||
|
? sessionWindow
|
||||||
|
: window
|
||||||
|
? window
|
||||||
|
: sessionWindow;
|
||||||
if (anyWindow) {
|
if (anyWindow) {
|
||||||
anyWindow->invokeForSessionController(
|
anyWindow->invokeForSessionController(
|
||||||
&_session->account(),
|
&_session->account(),
|
||||||
|
|
|
@ -270,7 +270,7 @@ void LaunchGApplication() {
|
||||||
app->signal_activate().connect([] {
|
app->signal_activate().connect([] {
|
||||||
Core::Sandbox::Instance().customEnterFromEventLoop([] {
|
Core::Sandbox::Instance().customEnterFromEventLoop([] {
|
||||||
const auto window = Core::IsAppLaunched()
|
const auto window = Core::IsAppLaunched()
|
||||||
? Core::App().primaryWindow()
|
? Core::App().activePrimaryWindow()
|
||||||
: nullptr;
|
: nullptr;
|
||||||
if (window) {
|
if (window) {
|
||||||
window->activate();
|
window->activate();
|
||||||
|
@ -298,7 +298,7 @@ void LaunchGApplication() {
|
||||||
}
|
}
|
||||||
if (Core::StartUrlRequiresActivate(url)) {
|
if (Core::StartUrlRequiresActivate(url)) {
|
||||||
const auto window = Core::IsAppLaunched()
|
const auto window = Core::IsAppLaunched()
|
||||||
? Core::App().primaryWindow()
|
? Core::App().activePrimaryWindow()
|
||||||
: nullptr;
|
: nullptr;
|
||||||
if (window) {
|
if (window) {
|
||||||
window->activate();
|
window->activate();
|
||||||
|
|
|
@ -26,8 +26,9 @@ namespace Platform {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
[[nodiscard]] QWidget *Parent() {
|
[[nodiscard]] QWidget *Parent() {
|
||||||
Expects(Core::App().primaryWindow() != nullptr);
|
Expects(Core::App().activePrimaryWindow() != nullptr);
|
||||||
return Core::App().primaryWindow()->widget();
|
|
||||||
|
return Core::App().activePrimaryWindow()->widget();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -767,7 +767,7 @@ TimeId CalculateOnlineTill(not_null<PeerData*> peer) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto active = Core::App().primaryWindow();
|
const auto active = Core::App().activePrimaryWindow();
|
||||||
const auto controller = active ? active->sessionController() : nullptr;
|
const auto controller = active ? active->sessionController() : nullptr;
|
||||||
const auto openFolder = [=] {
|
const auto openFolder = [=] {
|
||||||
const auto folder = _session->data().folderLoaded(Data::Folder::kId);
|
const auto folder = _session->data().folderLoaded(Data::Folder::kId);
|
||||||
|
|
|
@ -223,8 +223,9 @@ void UpdateIcon(const NSStatusItem *status) {
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] QWidget *Parent() {
|
[[nodiscard]] QWidget *Parent() {
|
||||||
Expects(Core::App().primaryWindow() != nullptr);
|
Expects(Core::App().activePrimaryWindow() != nullptr);
|
||||||
return Core::App().primaryWindow()->widget();
|
|
||||||
|
return Core::App().activePrimaryWindow()->widget();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -22,8 +22,8 @@ namespace Platform {
|
||||||
// account, with 100% scale and without "px" dimensions, because thats
|
// account, with 100% scale and without "px" dimensions, because thats
|
||||||
// how it will look in real launched macOS app.
|
// how it will look in real launched macOS app.
|
||||||
int PreviewTitleHeight() {
|
int PreviewTitleHeight() {
|
||||||
if (auto window = Core::App().primaryWindow()) {
|
if (const auto window = Core::App().activePrimaryWindow()) {
|
||||||
if (auto height = window->widget()->getCustomTitleHeight()) {
|
if (const auto height = window->widget()->getCustomTitleHeight()) {
|
||||||
return height;
|
return height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -206,12 +206,8 @@ void MainWindow::shadowsDeactivate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::destroyedFromSystem() {
|
void MainWindow::destroyedFromSystem() {
|
||||||
if (isPrimary()) {
|
if (!Core::App().closeNonLastAsync(&controller())) {
|
||||||
Core::Quit();
|
Core::Quit();
|
||||||
} else {
|
|
||||||
crl::on_main(this, [=] {
|
|
||||||
Core::App().closeWindow(&controller());
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,8 +90,9 @@ constexpr auto kTooltipDelay = crl::time(10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] QWidget *Parent() {
|
[[nodiscard]] QWidget *Parent() {
|
||||||
Expects(Core::App().primaryWindow() != nullptr);
|
Expects(Core::App().activePrimaryWindow() != nullptr);
|
||||||
return Core::App().primaryWindow()->widget();
|
|
||||||
|
return Core::App().activePrimaryWindow()->widget();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -135,7 +136,7 @@ void Tray::updateIcon() {
|
||||||
}
|
}
|
||||||
const auto counter = Core::App().unreadBadge();
|
const auto counter = Core::App().unreadBadge();
|
||||||
const auto muted = Core::App().unreadBadgeMuted();
|
const auto muted = Core::App().unreadBadgeMuted();
|
||||||
const auto controller = Core::App().primaryWindow();
|
const auto controller = Core::App().activePrimaryWindow();
|
||||||
const auto session = !controller
|
const auto session = !controller
|
||||||
? nullptr
|
? nullptr
|
||||||
: !controller->sessionController()
|
: !controller->sessionController()
|
||||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "settings/settings_information.h"
|
#include "settings/settings_information.h"
|
||||||
|
|
||||||
|
#include "dialogs/dialogs_inner_widget.h" // kOptionCtrlClickChatNewWindow.
|
||||||
#include "editor/photo_editor_layer_widget.h"
|
#include "editor/photo_editor_layer_widget.h"
|
||||||
#include "settings/settings_common.h"
|
#include "settings/settings_common.h"
|
||||||
#include "ui/wrap/vertical_layout.h"
|
#include "ui/wrap/vertical_layout.h"
|
||||||
|
@ -51,6 +52,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "api/api_user_names.h"
|
#include "api/api_user_names.h"
|
||||||
#include "core/file_utilities.h"
|
#include "core/file_utilities.h"
|
||||||
#include "base/call_delayed.h"
|
#include "base/call_delayed.h"
|
||||||
|
#include "base/options.h"
|
||||||
#include "base/unixtime.h"
|
#include "base/unixtime.h"
|
||||||
#include "base/random.h"
|
#include "base/random.h"
|
||||||
#include "styles/style_dialogs.h" // dialogsPremiumIcon
|
#include "styles/style_dialogs.h" // dialogsPremiumIcon
|
||||||
|
@ -560,7 +562,7 @@ void SetupAccountsWrap(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Window::SessionController*> window,
|
not_null<Window::SessionController*> window,
|
||||||
not_null<Main::Account*> account,
|
not_null<Main::Account*> account,
|
||||||
Fn<void()> callback,
|
Fn<void(Qt::KeyboardModifiers)> callback,
|
||||||
bool locked) {
|
bool locked) {
|
||||||
const auto active = (account == &Core::App().activeAccount());
|
const auto active = (account == &Core::App().activeAccount());
|
||||||
const auto session = &account->session();
|
const auto session = &account->session();
|
||||||
|
@ -642,7 +644,7 @@ void SetupAccountsWrap(
|
||||||
raw->clicks(
|
raw->clicks(
|
||||||
) | rpl::start_with_next([=](Qt::MouseButton which) {
|
) | rpl::start_with_next([=](Qt::MouseButton which) {
|
||||||
if (which == Qt::LeftButton) {
|
if (which == Qt::LeftButton) {
|
||||||
callback();
|
callback(raw->clickModifiers());
|
||||||
return;
|
return;
|
||||||
} else if (which != Qt::RightButton) {
|
} else if (which != Qt::RightButton) {
|
||||||
return;
|
return;
|
||||||
|
@ -854,17 +856,24 @@ void AccountsList::rebuild() {
|
||||||
button = nullptr;
|
button = nullptr;
|
||||||
} else if (!button) {
|
} else if (!button) {
|
||||||
const auto nextIsLocked = (inner->count() >= premiumLimit);
|
const auto nextIsLocked = (inner->count() >= premiumLimit);
|
||||||
auto callback = [=] {
|
auto callback = [=](Qt::KeyboardModifiers modifiers) {
|
||||||
if (_reordering) {
|
if (_reordering) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (account == &Core::App().domain().active()) {
|
if (account == &_controller->session().account()) {
|
||||||
_currentAccountActivations.fire({});
|
_currentAccountActivations.fire({});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const auto newWindow = (modifiers & Qt::ControlModifier)
|
||||||
|
&& base::options::lookup<bool>(
|
||||||
|
Dialogs::kOptionCtrlClickChatNewWindow).value();
|
||||||
auto activate = [=, guard = _accountSwitchGuard.make_guard()]{
|
auto activate = [=, guard = _accountSwitchGuard.make_guard()]{
|
||||||
if (guard) {
|
if (guard) {
|
||||||
_reorder->finishReordering();
|
_reorder->finishReordering();
|
||||||
|
if (newWindow) {
|
||||||
|
Core::App().ensureSeparateWindowForAccount(
|
||||||
|
account);
|
||||||
|
}
|
||||||
Core::App().domain().maybeActivate(account);
|
Core::App().domain().maybeActivate(account);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -565,7 +565,8 @@ void System::showNext() {
|
||||||
const auto &settings = Core::App().settings();
|
const auto &settings = Core::App().settings();
|
||||||
if (alertThread) {
|
if (alertThread) {
|
||||||
if (settings.flashBounceNotify() && !_manager->skipFlashBounce()) {
|
if (settings.flashBounceNotify() && !_manager->skipFlashBounce()) {
|
||||||
if (const auto window = Core::App().primaryWindow()) {
|
const auto peer = alertThread->peer();
|
||||||
|
if (const auto window = Core::App().windowFor(peer)) {
|
||||||
if (const auto handle = window->widget()->windowHandle()) {
|
if (const auto handle = window->widget()->windowHandle()) {
|
||||||
handle->alert(kSystemAlertDuration);
|
handle->alert(kSystemAlertDuration);
|
||||||
// (handle, SLOT(_q_clearAlert())); in the future.
|
// (handle, SLOT(_q_clearAlert())); in the future.
|
||||||
|
|
|
@ -47,15 +47,17 @@ namespace Notifications {
|
||||||
namespace Default {
|
namespace Default {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
QPoint notificationStartPosition() {
|
[[nodiscard]] QPoint notificationStartPosition() {
|
||||||
const auto corner = Core::App().settings().notificationsCorner();
|
const auto corner = Core::App().settings().notificationsCorner();
|
||||||
const auto window = Core::App().primaryWindow();
|
const auto window = Core::App().activePrimaryWindow();
|
||||||
const auto r = window
|
const auto r = window
|
||||||
? window->widget()->desktopRect()
|
? window->widget()->desktopRect()
|
||||||
: QGuiApplication::primaryScreen()->availableGeometry();
|
: QGuiApplication::primaryScreen()->availableGeometry();
|
||||||
const auto isLeft = Core::Settings::IsLeftCorner(corner);
|
const auto isLeft = Core::Settings::IsLeftCorner(corner);
|
||||||
const auto isTop = Core::Settings::IsTopCorner(corner);
|
const auto isTop = Core::Settings::IsTopCorner(corner);
|
||||||
const auto x = (isLeft == rtl()) ? (r.x() + r.width() - st::notifyWidth - st::notifyDeltaX) : (r.x() + st::notifyDeltaX);
|
const auto x = (isLeft == rtl())
|
||||||
|
? (r.x() + r.width() - st::notifyWidth - st::notifyDeltaX)
|
||||||
|
: (r.x() + st::notifyDeltaX);
|
||||||
const auto y = isTop ? r.y() : (r.y() + r.height());
|
const auto y = isTop ? r.y() : (r.y() + r.height());
|
||||||
return QPoint(x, y);
|
return QPoint(x, y);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,11 @@ namespace Window {
|
||||||
Controller::Controller() : Controller(CreateArgs{}) {
|
Controller::Controller() : Controller(CreateArgs{}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Controller::Controller(not_null<Main::Account*> account)
|
||||||
|
: Controller(CreateArgs{}) {
|
||||||
|
showAccount(account);
|
||||||
|
}
|
||||||
|
|
||||||
Controller::Controller(
|
Controller::Controller(
|
||||||
not_null<PeerData*> singlePeer,
|
not_null<PeerData*> singlePeer,
|
||||||
MsgId showAtMsgId)
|
MsgId showAtMsgId)
|
||||||
|
|
|
@ -25,6 +25,7 @@ namespace Window {
|
||||||
class Controller final : public base::has_weak_ptr {
|
class Controller final : public base::has_weak_ptr {
|
||||||
public:
|
public:
|
||||||
Controller();
|
Controller();
|
||||||
|
explicit Controller(not_null<Main::Account*> account);
|
||||||
Controller(
|
Controller(
|
||||||
not_null<PeerData*> singlePeer,
|
not_null<PeerData*> singlePeer,
|
||||||
MsgId showAtMsgId);
|
MsgId showAtMsgId);
|
||||||
|
|
|
@ -71,6 +71,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/boxes/confirm_box.h"
|
#include "ui/boxes/confirm_box.h"
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
#include "main/main_account.h"
|
||||||
|
#include "main/main_domain.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "main/main_session_settings.h"
|
#include "main/main_session_settings.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
|
@ -977,9 +979,10 @@ void SessionController::showForum(
|
||||||
not_null<Data::Forum*> forum,
|
not_null<Data::Forum*> forum,
|
||||||
const SectionShow ¶ms) {
|
const SectionShow ¶ms) {
|
||||||
if (!isPrimary()) {
|
if (!isPrimary()) {
|
||||||
const auto primary = Core::App().primaryWindow();
|
auto primary = Core::App().windowFor(&session().account());
|
||||||
if (&primary->account() != &session().account()) {
|
if (&primary->account() != &session().account()) {
|
||||||
primary->showAccount(&session().account());
|
Core::App().domain().activate(&session().account());
|
||||||
|
primary = Core::App().windowFor(&session().account());
|
||||||
}
|
}
|
||||||
if (&primary->account() == &session().account()) {
|
if (&primary->account() == &session().account()) {
|
||||||
primary->sessionController()->showForum(forum, params);
|
primary->sessionController()->showForum(forum, params);
|
||||||
|
|
Loading…
Add table
Reference in a new issue