Add "ctrl-click-chat-new-window" option.

This commit is contained in:
John Preston 2022-06-07 22:05:37 +04:00
parent 896d39bc6a
commit a780fbd09b
22 changed files with 192 additions and 104 deletions

View file

@ -66,7 +66,9 @@ void ShowPeerInfoSync(not_null<PeerData*> peer) {
// we can safely use activeWindow. // we can safely use activeWindow.
if (const auto window = Core::App().activeWindow()) { if (const auto window = Core::App().activeWindow()) {
if (const auto controller = window->sessionController()) { if (const auto controller = window->sessionController()) {
controller->showPeerInfo(peer); if (&controller->session() == &peer->session()) {
controller->showPeerInfo(peer);
}
} }
} }
} }

View file

@ -1198,7 +1198,7 @@ base::unique_qptr<Ui::PopupMenu> Members::Controller::createRowContextMenu(
if (const auto window = Core::App().separateWindowForPeer( if (const auto window = Core::App().separateWindowForPeer(
participantPeer)) { participantPeer)) {
return window->sessionController(); return window->sessionController();
} else if (const auto window = Core::App().activeWindow()) { } 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;

View file

@ -1264,7 +1264,7 @@ object_ptr<TabbedSelector::InnerFooter> StickersListWidget::createFooter() {
_footer->openSettingsRequests( _footer->openSettingsRequests(
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
const auto onlyFeatured = _footer->hasOnlyFeaturedSets(); const auto onlyFeatured = _footer->hasOnlyFeaturedSets();
Ui::show(Box<StickersBox>( controller()->show(Box<StickersBox>(
controller(), controller(),
(onlyFeatured (onlyFeatured
? StickersBox::Section::Featured ? StickersBox::Section::Featured

View file

@ -323,7 +323,7 @@ void Application::run() {
DEBUG_LOG(("Application Info: window created...")); DEBUG_LOG(("Application Info: window created..."));
// Depend on activeWindow() for now :( // Depend on primaryWindow() for now :(
startShortcuts(); startShortcuts();
startDomain(); startDomain();
@ -1170,6 +1170,26 @@ Window::Controller *Application::activeWindow() const {
return _lastActiveWindow; return _lastActiveWindow;
} }
void Application::closeWindow(not_null<Window::Controller*> window) {
for (auto i = begin(_secondaryWindows); i != end(_secondaryWindows);) {
if (i->second.get() == window) {
if (_lastActiveWindow == window) {
_lastActiveWindow = _primaryWindow.get();
}
i = _secondaryWindows.erase(i);
} else {
++i;
}
}
}
void Application::windowActivated(not_null<Window::Controller*> window) {
_lastActiveWindow = window;
if (_mediaView && !_mediaView->isHidden()) {
_mediaView->activate();
}
}
bool Application::closeActiveWindow() { bool Application::closeActiveWindow() {
if (hideMediaView()) { if (hideMediaView()) {
return true; return true;
@ -1198,11 +1218,12 @@ bool Application::minimizeActiveWindow() {
} }
QWidget *Application::getFileDialogParent() { QWidget *Application::getFileDialogParent() {
return (_mediaView && !_mediaView->isHidden()) if (const auto view = _mediaView.get(); view && !view->isHidden()) {
? static_cast<QWidget*>(_mediaView->widget()) return view->widget();
: activeWindow() } else if (const auto active = activeWindow()) {
? static_cast<QWidget*>(activeWindow()->widget()) return active->widget();
: nullptr; }
return nullptr;
} }
void Application::notifyFileDialogShown(bool shown) { void Application::notifyFileDialogShown(bool shown) {
@ -1211,12 +1232,6 @@ void Application::notifyFileDialogShown(bool shown) {
} }
} }
void Application::checkMediaViewActivation() {
if (_mediaView && !_mediaView->isHidden()) {
_mediaView->activate();
}
}
QPoint Application::getPointForCallPanelCenter() const { QPoint Application::getPointForCallPanelCenter() const {
if (const auto window = activeWindow()) { if (const auto window = activeWindow()) {
return window->getPointForCallPanelCenter(); return window->getPointForCallPanelCenter();

View file

@ -162,6 +162,8 @@ public:
Window::Controller *ensureSeparateWindowForPeer( Window::Controller *ensureSeparateWindowForPeer(
not_null<PeerData*> peer, not_null<PeerData*> peer,
MsgId showAtMsgId); MsgId showAtMsgId);
void closeWindow(not_null<Window::Controller*> window);
void windowActivated(not_null<Window::Controller*> window);
bool closeActiveWindow(); bool closeActiveWindow();
bool minimizeActiveWindow(); bool minimizeActiveWindow();
[[nodiscard]] QWidget *getFileDialogParent(); [[nodiscard]] QWidget *getFileDialogParent();
@ -170,7 +172,6 @@ public:
[[nodiscard]] bool isActiveForTrayMenu() const; [[nodiscard]] bool isActiveForTrayMenu() const;
// Media view interface. // Media view interface.
void checkMediaViewActivation();
bool hideMediaView(); bool hideMediaView();
[[nodiscard]] QPoint getPointForCallPanelCenter() const; [[nodiscard]] QPoint getPointForCallPanelCenter() const;

View file

@ -44,8 +44,6 @@ enum class OrderMode;
namespace Core { namespace Core {
struct WindowPosition { struct WindowPosition {
WindowPosition() = default;
int32 moncrc = 0; int32 moncrc = 0;
int maximized = 0; int maximized = 0;
int scale = 0; int scale = 0;

View file

@ -35,6 +35,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/stickers/data_stickers.h" #include "data/stickers/data_stickers.h"
#include "data/data_send_action.h" #include "data/data_send_action.h"
#include "base/unixtime.h" #include "base/unixtime.h"
#include "base/options.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "mainwidget.h" #include "mainwidget.h"
@ -64,6 +65,13 @@ namespace {
constexpr auto kHashtagResultsLimit = 5; constexpr auto kHashtagResultsLimit = 5;
constexpr auto kStartReorderThreshold = 30; constexpr auto kStartReorderThreshold = 30;
base::options::toggle TabbedPanelShowOnClick({
.id = kOptionCtrlClickChatNewWindow,
.name = "New chat window by Ctrl+Click",
.description = "Open chat in a new window by Ctrl+Click "
"(Cmd+Click on macOS).",
});
int FixedOnTopDialogsCount(not_null<Dialogs::IndexedList*> list) { int FixedOnTopDialogsCount(not_null<Dialogs::IndexedList*> list) {
auto result = 0; auto result = 0;
for (const auto &row : *list) { for (const auto &row : *list) {
@ -92,6 +100,8 @@ int PinnedDialogsCount(
} // namespace } // namespace
const char kOptionCtrlClickChatNewWindow[] = "ctrl-click-chat-new-window";
struct InnerWidget::CollapsedRow { struct InnerWidget::CollapsedRow {
CollapsedRow(Data::Folder *folder) : folder(folder) { CollapsedRow(Data::Folder *folder) : folder(folder) {
} }
@ -2801,9 +2811,9 @@ bool InnerWidget::chooseRow(Qt::KeyboardModifiers modifiers) {
const auto modifyChosenRow = []( const auto modifyChosenRow = [](
ChosenRow row, ChosenRow row,
Qt::KeyboardModifiers modifiers) { Qt::KeyboardModifiers modifiers) {
#ifdef _DEBUG if (TabbedPanelShowOnClick.value()) {
row.newWindow = (modifiers & Qt::ControlModifier); row.newWindow = (modifiers & Qt::ControlModifier);
#endif }
return row; return row;
}; };
const auto chosen = modifyChosenRow(computeChosenRow(), modifiers); const auto chosen = modifyChosenRow(computeChosenRow(), modifiers);

View file

@ -45,6 +45,8 @@ class VideoUserpic;
namespace Dialogs { namespace Dialogs {
extern const char kOptionCtrlClickChatNewWindow[];
class Row; class Row;
class FakeRow; class FakeRow;
class IndexedList; class IndexedList;

View file

@ -479,7 +479,11 @@ void Manager::applyListFilters() {
if (icon.premium if (icon.premium
&& !_allowSendingPremium && !_allowSendingPremium
&& !_buttonAlreadyList.contains(emoji)) { && !_buttonAlreadyList.contains(emoji)) {
showPremiumLock = &icon; if (_premiumPossible) {
showPremiumLock = &icon;
} else {
clearStateForHidden(icon);
}
} else { } else {
icon.premiumLock = false; icon.premiumLock = false;
if (emoji == _favorite) { if (emoji == _favorite) {
@ -572,7 +576,10 @@ void Manager::showButtonDelayed() {
void Manager::applyList( void Manager::applyList(
const std::vector<Data::Reaction> &list, const std::vector<Data::Reaction> &list,
const QString &favorite) { const QString &favorite,
bool premiumPossible) {
const auto possibleChanged = (_premiumPossible != premiumPossible);
_premiumPossible = premiumPossible;
const auto proj = [](const auto &obj) { const auto proj = [](const auto &obj) {
return std::tie( return std::tie(
obj.emoji, obj.emoji,
@ -585,7 +592,7 @@ void Manager::applyList(
_favorite = favorite; _favorite = favorite;
} }
if (ranges::equal(_list, list, ranges::equal_to(), proj, proj)) { if (ranges::equal(_list, list, ranges::equal_to(), proj, proj)) {
if (favoriteChanged) { if (favoriteChanged || possibleChanged) {
applyListFilters(); applyListFilters();
} }
return; return;
@ -1659,7 +1666,8 @@ void SetupManagerList(
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
manager->applyList( manager->applyList(
reactions->list(Data::Reactions::Type::Active), reactions->list(Data::Reactions::Type::Active),
reactions->favorite()); reactions->favorite(),
session->premiumPossible());
}, manager->lifetime()); }, manager->lifetime());
std::move( std::move(

View file

@ -147,7 +147,8 @@ public:
void applyList( void applyList(
const std::vector<Data::Reaction> &list, const std::vector<Data::Reaction> &list,
const QString &favorite); const QString &favorite,
bool premiumPossible);
void updateAllowedSublist(AllowedSublist filter); void updateAllowedSublist(AllowedSublist filter);
void updateAllowSendingPremium(bool allow); void updateAllowSendingPremium(bool allow);
[[nodiscard]] const AllowedSublist &allowedSublist() const; [[nodiscard]] const AllowedSublist &allowedSublist() const;
@ -348,6 +349,7 @@ private:
rpl::lifetime _loadCacheLifetime; rpl::lifetime _loadCacheLifetime;
bool _showingAll = false; bool _showingAll = false;
bool _allowSendingPremium = false; bool _allowSendingPremium = false;
bool _premiumPossible = false;
mutable int _selectedIcon = -1; mutable int _selectedIcon = -1;
std::optional<ButtonParameters> _scheduledParameters; std::optional<ButtonParameters> _scheduledParameters;

View file

@ -84,6 +84,7 @@ TopBarWidget::TopBarWidget(
not_null<Window::SessionController*> controller) not_null<Window::SessionController*> controller)
: RpWidget(parent) : RpWidget(parent)
, _controller(controller) , _controller(controller)
, _primaryWindow(controller->isPrimary())
, _clear(this, tr::lng_selected_clear(), st::topBarClearButton) , _clear(this, tr::lng_selected_clear(), st::topBarClearButton)
, _forward(this, tr::lng_selected_forward(), st::defaultActiveButton) , _forward(this, tr::lng_selected_forward(), st::defaultActiveButton)
, _sendNow(this, tr::lng_selected_send_now(), st::defaultActiveButton) , _sendNow(this, tr::lng_selected_send_now(), st::defaultActiveButton)
@ -846,10 +847,10 @@ void TopBarWidget::updateControlsGeometry() {
_leftTaken = smallDialogsColumn ? (width() - _back->width()) / 2 : 0; _leftTaken = smallDialogsColumn ? (width() - _back->width()) / 2 : 0;
_back->moveToLeft(_leftTaken, otherButtonsTop); _back->moveToLeft(_leftTaken, otherButtonsTop);
_leftTaken += _back->width(); _leftTaken += _back->width();
if (_info && !_info->isHidden()) { }
_info->moveToLeft(_leftTaken, otherButtonsTop); if (_info && !_info->isHidden()) {
_leftTaken += _info->width(); _info->moveToLeft(_leftTaken, otherButtonsTop);
} _leftTaken += _info->width();
} }
_rightTaken = 0; _rightTaken = 0;
@ -908,7 +909,8 @@ void TopBarWidget::updateControlsVisibility() {
_back->setVisible(backVisible && !_chooseForReportReason); _back->setVisible(backVisible && !_chooseForReportReason);
_cancelChoose->setVisible(_chooseForReportReason.has_value()); _cancelChoose->setVisible(_chooseForReportReason.has_value());
if (_info) { if (_info) {
_info->setVisible(isOneColumn && !_chooseForReportReason); _info->setVisible((isOneColumn || !_primaryWindow)
&& !_chooseForReportReason);
} }
if (_unreadBadge) { if (_unreadBadge) {
_unreadBadge->setVisible(!_chooseForReportReason); _unreadBadge->setVisible(!_chooseForReportReason);

View file

@ -153,6 +153,7 @@ private:
[[nodiscard]] bool showSelectedActions() const; [[nodiscard]] bool showSelectedActions() const;
const not_null<Window::SessionController*> _controller; const not_null<Window::SessionController*> _controller;
const bool _primaryWindow = false;
ActiveChat _activeChat; ActiveChat _activeChat;
QString _customTitleText; QString _customTitleText;
std::unique_ptr<EmojiInteractionSeenAnimation> _emojiInteractionSeen; std::unique_ptr<EmojiInteractionSeenAnimation> _emojiInteractionSeen;

View file

@ -1912,7 +1912,7 @@ QPixmap MainWidget::grabForShowAnimation(const Window::SectionSlideParams &param
result = Ui::GrabWidget(this, QRect( result = Ui::GrabWidget(this, QRect(
0, 0,
sectionTop, sectionTop,
_dialogsWidth, width(),
height() - sectionTop)); height() - sectionTop));
} else { } else {
if (_sideShadow) { if (_sideShadow) {
@ -2163,7 +2163,7 @@ void MainWidget::updateControlsGeometry() {
auto dialogsWidth = _dialogs auto dialogsWidth = _dialogs
? qRound(_a_dialogsWidth.value(_dialogsWidth)) ? qRound(_a_dialogsWidth.value(_dialogsWidth))
: isOneColumn() : isOneColumn()
? _dialogsWidth ? width()
: 0; : 0;
if (isOneColumn()) { if (isOneColumn()) {
if (_callTopBar) { if (_callTopBar) {
@ -2276,7 +2276,7 @@ void MainWidget::updateControlsGeometry() {
} }
void MainWidget::refreshResizeAreas() { void MainWidget::refreshResizeAreas() {
if (!isOneColumn()) { if (!isOneColumn() && _dialogs) {
ensureFirstColumnResizeAreaCreated(); ensureFirstColumnResizeAreaCreated();
_firstColumnResizeArea->setGeometryToLeft( _firstColumnResizeArea->setGeometryToLeft(
_history->x(), _history->x(),
@ -2314,6 +2314,8 @@ void MainWidget::createResizeArea(
} }
void MainWidget::ensureFirstColumnResizeAreaCreated() { void MainWidget::ensureFirstColumnResizeAreaCreated() {
Expects(_dialogs != nullptr);
if (_firstColumnResizeArea) { if (_firstColumnResizeArea) {
return; return;
} }

View file

@ -127,20 +127,22 @@ void MainWindow::applyInitialWorkMode() {
const auto workMode = Core::App().settings().workMode(); const auto workMode = Core::App().settings().workMode();
workmodeUpdated(workMode); workmodeUpdated(workMode);
if (Core::App().settings().windowPosition().maximized) { if (controller().isPrimary()) {
DEBUG_LOG(("Window Pos: First show, setting maximized.")); if (Core::App().settings().windowPosition().maximized) {
setWindowState(Qt::WindowMaximized); DEBUG_LOG(("Window Pos: First show, setting maximized."));
} setWindowState(Qt::WindowMaximized);
if (cStartInTray() }
|| (cLaunchMode() == LaunchModeAutoStart if (!cStartInTray()
&& cStartMinimized() || (cLaunchMode() == LaunchModeAutoStart
&& !Core::App().passcodeLocked())) { && cStartMinimized()
DEBUG_LOG(("Window Pos: First show, setting minimized after.")); && !Core::App().passcodeLocked())) {
if (workMode == Core::Settings::WorkMode::TrayOnly DEBUG_LOG(("Window Pos: First show, setting minimized after."));
|| workMode == Core::Settings::WorkMode::WindowAndTray) { if (workMode == Core::Settings::WorkMode::TrayOnly
hide(); || workMode == Core::Settings::WorkMode::WindowAndTray) {
} else { hide();
setWindowState(windowState() | Qt::WindowMinimized); } else {
setWindowState(windowState() | Qt::WindowMinimized);
}
} }
} }
setPositionInited(); setPositionInited();
@ -645,22 +647,28 @@ void MainWindow::closeEvent(QCloseEvent *e) {
if (Core::Sandbox::Instance().isSavingSession() || Core::Quitting()) { if (Core::Sandbox::Instance().isSavingSession() || Core::Quitting()) {
e->accept(); e->accept();
Core::Quit(); Core::Quit();
} else { return;
e->ignore(); } else if (!isPrimary()) {
const auto hasAuth = [&] { e->accept();
if (!Core::App().domain().started()) { crl::on_main(this, [=] {
return false; Core::App().closeWindow(&controller());
} });
for (const auto &[_, account] : Core::App().domain().accounts()) { return;
if (account->sessionExists()) { }
return true; e->ignore();
} const auto hasAuth = [&] {
} if (!Core::App().domain().started()) {
return false; return false;
}();
if (!hasAuth || !hideNoQuit()) {
Core::Quit();
} }
for (const auto &[_, account] : Core::App().domain().accounts()) {
if (account->sessionExists()) {
return true;
}
}
return false;
}();
if (!hasAuth || !hideNoQuit()) {
Core::Quit();
} }
} }

View file

@ -768,7 +768,7 @@ TimeId CalculateOnlineTill(not_null<PeerData*> peer) {
return; return;
} }
const auto active = Core::App().activeWindow(); const auto active = Core::App().primaryWindow();
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);

View file

@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/options.h" #include "base/options.h"
#include "core/application.h" #include "core/application.h"
#include "chat_helpers/tabbed_panel.h" #include "chat_helpers/tabbed_panel.h"
#include "dialogs/dialogs_inner_widget.h"
#include "history/history_widget.h" #include "history/history_widget.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "media/player/media_player_instance.h" #include "media/player/media_player_instance.h"
@ -134,6 +135,7 @@ void SetupExperimental(
addToggle(ChatHelpers::kOptionTabbedPanelShowOnClick); addToggle(ChatHelpers::kOptionTabbedPanelShowOnClick);
addToggle(Window::kOptionViewProfileInChatsListContextMenu); addToggle(Window::kOptionViewProfileInChatsListContextMenu);
addToggle(Dialogs::kOptionCtrlClickChatNewWindow);
addToggle(Ui::GL::kOptionAllowLinuxNvidiaOpenGL); addToggle(Ui::GL::kOptionAllowLinuxNvidiaOpenGL);
addToggle(Media::Player::kOptionDisableAutoplayNext); addToggle(Media::Player::kOptionDisableAutoplayNext);
addToggle(Settings::kOptionMonoSettingsIcons); addToggle(Settings::kOptionMonoSettingsIcons);

View file

@ -489,7 +489,7 @@ void MainWindow::handleStateChanged(Qt::WindowState state) {
void MainWindow::handleActiveChanged() { void MainWindow::handleActiveChanged() {
if (isActiveWindow()) { if (isActiveWindow()) {
Core::App().checkMediaViewActivation(); Core::App().windowActivated(&controller());
} }
} }
@ -737,10 +737,9 @@ void MainWindow::initGeometry() {
if (initGeometryFromSystem()) { if (initGeometryFromSystem()) {
return; return;
} }
// #TODO windows
const auto geometry = countInitialGeometry(isPrimary() const auto geometry = countInitialGeometry(isPrimary()
? positionFromSettings() ? positionFromSettings()
: Core::WindowPosition()); : SecondaryInitPosition());
DEBUG_LOG(("Window Pos: Setting first %1, %2, %3, %4" DEBUG_LOG(("Window Pos: Setting first %1, %2, %3, %4"
).arg(geometry.x() ).arg(geometry.x()
).arg(geometry.y() ).arg(geometry.y()
@ -836,30 +835,7 @@ void MainWindow::savePosition(Qt::WindowState state) {
realPosition.moncrc = 0; realPosition.moncrc = 0;
DEBUG_LOG(("Window Pos: Saving non-maximized position: %1, %2, %3, %4").arg(realPosition.x).arg(realPosition.y).arg(realPosition.w).arg(realPosition.h)); DEBUG_LOG(("Window Pos: Saving non-maximized position: %1, %2, %3, %4").arg(realPosition.x).arg(realPosition.y).arg(realPosition.w).arg(realPosition.h));
realPosition = withScreenInPosition(realPosition);
auto centerX = realPosition.x + realPosition.w / 2;
auto centerY = realPosition.y + realPosition.h / 2;
int minDelta = 0;
QScreen *chosen = nullptr;
const auto screens = QGuiApplication::screens();
for (auto screen : screens) {
auto delta = (screen->geometry().center() - QPoint(centerX, centerY)).manhattanLength();
if (!chosen || delta < minDelta) {
minDelta = delta;
chosen = screen;
}
}
if (chosen) {
auto screenGeometry = chosen->geometry();
DEBUG_LOG(("Window Pos: Screen found, geometry: %1, %2, %3, %4"
).arg(screenGeometry.x()
).arg(screenGeometry.y()
).arg(screenGeometry.width()
).arg(screenGeometry.height()));
realPosition.x -= screenGeometry.x();
realPosition.y -= screenGeometry.y();
realPosition.moncrc = screenNameChecksum(chosen->name());
}
} }
if (realPosition.w >= st::windowMinWidth && realPosition.h >= st::windowMinHeight) { if (realPosition.w >= st::windowMinWidth && realPosition.h >= st::windowMinHeight) {
if (realPosition.x != savedPosition.x if (realPosition.x != savedPosition.x
@ -882,6 +858,51 @@ void MainWindow::savePosition(Qt::WindowState state) {
} }
} }
Core::WindowPosition MainWindow::withScreenInPosition(
Core::WindowPosition position) const {
auto centerX = position.x + position.w / 2;
auto centerY = position.y + position.h / 2;
int minDelta = 0;
QScreen *chosen = nullptr;
const auto screens = QGuiApplication::screens();
for (auto screen : screens) {
auto delta = (screen->geometry().center() - QPoint(centerX, centerY)).manhattanLength();
if (!chosen || delta < minDelta) {
minDelta = delta;
chosen = screen;
}
}
if (!chosen) {
return position;
}
auto screenGeometry = chosen->geometry();
DEBUG_LOG(("Window Pos: Screen found, geometry: %1, %2, %3, %4"
).arg(screenGeometry.x()
).arg(screenGeometry.y()
).arg(screenGeometry.width()
).arg(screenGeometry.height()));
position.x -= screenGeometry.x();
position.y -= screenGeometry.y();
position.moncrc = screenNameChecksum(chosen->name());
return position;
}
Core::WindowPosition MainWindow::SecondaryInitPosition() {
const auto active = Core::App().activeWindow();
if (!active) {
return {};
}
const auto geometry = active->widget()->geometry();
const auto skip = st::windowMinWidth / 6;
return active->widget()->withScreenInPosition({
.scale = cScale(),
.x = geometry.x() + skip,
.y = geometry.y() + skip,
.w = st::windowMinWidth,
.h = st::windowDefaultHeight,
});
}
bool MainWindow::minimizeToTray() { bool MainWindow::minimizeToTray() {
if (Core::Quitting()/* || !hasTrayIcon()*/) { if (Core::Quitting()/* || !hasTrayIcon()*/) {
return false; return false;

View file

@ -75,6 +75,9 @@ public:
void activate(); void activate();
[[nodiscard]] QRect desktopRect() const; [[nodiscard]] QRect desktopRect() const;
[[nodiscard]] Core::WindowPosition withScreenInPosition(
Core::WindowPosition position) const;
[[nodiscard]] static Core::WindowPosition SecondaryInitPosition();
void init(); void init();

View file

@ -96,6 +96,10 @@ void Controller::showAccount(
_account->sessionValue( _account->sessionValue(
) | rpl::start_with_next([=](Main::Session *session) { ) | rpl::start_with_next([=](Main::Session *session) {
if (!session && !isPrimary()) {
Core::App().closeWindow(this);
return;
}
const auto was = base::take(_sessionController); const auto was = base::take(_sessionController);
_sessionController = session _sessionController = session
? std::make_unique<SessionController>(session, this) ? std::make_unique<SessionController>(session, this)
@ -119,9 +123,6 @@ void Controller::showAccount(
}, _sessionController->lifetime()); }, _sessionController->lifetime());
widget()->setInnerFocus(); widget()->setInnerFocus();
} else if (!isPrimary()) {
// #TODO windows test
close();
} else { } else {
setupIntro(); setupIntro();
_widget.updateGlobalMenu(); _widget.updateGlobalMenu();
@ -230,7 +231,7 @@ void Controller::showTermsDelete() {
if (const auto session = account().maybeSession()) { if (const auto session = account().maybeSession()) {
session->termsDeleteNow(); session->termsDeleteNow();
} else { } else {
Ui::hideLayer(); hideLayer();
} }
}; };
show( show(
@ -327,6 +328,10 @@ void Controller::showRightColumn(object_ptr<TWidget> widget) {
_widget.showRightColumn(std::move(widget)); _widget.showRightColumn(std::move(widget));
} }
void Controller::hideLayer(anim::type animated) {
_widget.ui_showBox({ nullptr }, Ui::LayerOption::CloseOther, animated);
}
void Controller::hideSettingsAndLayer(anim::type animated) { void Controller::hideSettingsAndLayer(anim::type animated) {
_widget.ui_hideSettingsAndLayer(animated); _widget.ui_hideSettingsAndLayer(animated);
} }

View file

@ -83,6 +83,7 @@ public:
void showRightColumn(object_ptr<TWidget> widget); void showRightColumn(object_ptr<TWidget> widget);
void hideLayer(anim::type animated = anim::type::normal);
void hideSettingsAndLayer(anim::type animated = anim::type::normal); void hideSettingsAndLayer(anim::type animated = anim::type::normal);
void activate(); void activate();

View file

@ -243,7 +243,7 @@ void SessionNavigation::resolveDone(
const MTPcontacts_ResolvedPeer &result, const MTPcontacts_ResolvedPeer &result,
Fn<void(not_null<PeerData*>)> done) { Fn<void(not_null<PeerData*>)> done) {
_resolveRequestId = 0; _resolveRequestId = 0;
Ui::hideLayer(); parentController()->hideLayer();
result.match([&](const MTPDcontacts_resolvedPeer &data) { result.match([&](const MTPDcontacts_resolvedPeer &data) {
_session->data().processUsers(data.vusers()); _session->data().processUsers(data.vusers());
_session->data().processChats(data.vchats()); _session->data().processChats(data.vchats());
@ -598,6 +598,7 @@ SessionController::SessionController(
, _window(window) , _window(window)
, _emojiInteractions( , _emojiInteractions(
std::make_unique<ChatHelpers::EmojiInteractions>(session)) std::make_unique<ChatHelpers::EmojiInteractions>(session))
, _isPrimary(window->isPrimary())
, _sendingAnimation( , _sendingAnimation(
std::make_unique<Ui::MessageSendingAnimationController>(this)) std::make_unique<Ui::MessageSendingAnimationController>(this))
, _tabbedSelector( , _tabbedSelector(
@ -700,7 +701,7 @@ PeerData *SessionController::singlePeer() const {
} }
bool SessionController::isPrimary() const { bool SessionController::isPrimary() const {
return _window->isPrimary(); return _isPrimary;
} }
not_null<::MainWindow*> SessionController::widget() const { not_null<::MainWindow*> SessionController::widget() const {
@ -762,7 +763,7 @@ void SessionController::initSupportMode() {
} }
void SessionController::toggleFiltersMenu(bool enabled) { void SessionController::toggleFiltersMenu(bool enabled) {
if (!isPrimary() || (!enabled == !_filters)) { if (!_isPrimary || (!enabled == !_filters)) {
return; return;
} else if (enabled) { } else if (enabled) {
_filters = std::make_unique<FiltersMenu>( _filters = std::make_unique<FiltersMenu>(
@ -1009,7 +1010,7 @@ int SessionController::dialogsSmallColumnWidth() const {
} }
int SessionController::minimalThreeColumnWidth() const { int SessionController::minimalThreeColumnWidth() const {
return st::columnMinimalWidthLeft return (_isPrimary ? st::columnMinimalWidthLeft : 0)
+ st::columnMinimalWidthMain + st::columnMinimalWidthMain
+ st::columnMinimalWidthThird; + st::columnMinimalWidthThird;
} }
@ -1032,7 +1033,7 @@ auto SessionController::computeColumnLayout() const -> ColumnLayout {
auto useOneColumnLayout = [&] { auto useOneColumnLayout = [&] {
auto minimalNormal = st::columnMinimalWidthLeft auto minimalNormal = st::columnMinimalWidthLeft
+ st::columnMinimalWidthMain; + st::columnMinimalWidthMain;
if (bodyWidth < minimalNormal) { if (_isPrimary && bodyWidth < minimalNormal) {
return true; return true;
} }
return false; return false;
@ -1074,6 +1075,9 @@ auto SessionController::computeColumnLayout() const -> ColumnLayout {
} }
int SessionController::countDialogsWidthFromRatio(int bodyWidth) const { int SessionController::countDialogsWidthFromRatio(int bodyWidth) const {
if (!_isPrimary) {
return 0;
}
auto result = qRound(bodyWidth * Core::App().settings().dialogsWidthRatio()); auto result = qRound(bodyWidth * Core::App().settings().dialogsWidthRatio());
accumulate_max(result, st::columnMinimalWidthLeft); accumulate_max(result, st::columnMinimalWidthLeft);
// accumulate_min(result, st::columnMaximalWidthLeft); // accumulate_min(result, st::columnMaximalWidthLeft);
@ -1102,8 +1106,8 @@ SessionController::ShrinkResult SessionController::shrinkDialogsAndThirdColumns(
if (thirdWidthNew < st::columnMinimalWidthThird) { if (thirdWidthNew < st::columnMinimalWidthThird) {
thirdWidthNew = st::columnMinimalWidthThird; thirdWidthNew = st::columnMinimalWidthThird;
dialogsWidthNew = bodyWidth - thirdWidthNew - chatWidth; dialogsWidthNew = bodyWidth - thirdWidthNew - chatWidth;
Assert(dialogsWidthNew >= st::columnMinimalWidthLeft); Assert(!_isPrimary || dialogsWidthNew >= st::columnMinimalWidthLeft);
} else if (dialogsWidthNew < st::columnMinimalWidthLeft) { } else if (_isPrimary && dialogsWidthNew < st::columnMinimalWidthLeft) {
dialogsWidthNew = st::columnMinimalWidthLeft; dialogsWidthNew = st::columnMinimalWidthLeft;
thirdWidthNew = bodyWidth - dialogsWidthNew - chatWidth; thirdWidthNew = bodyWidth - dialogsWidthNew - chatWidth;
Assert(thirdWidthNew >= st::columnMinimalWidthThird); Assert(thirdWidthNew >= st::columnMinimalWidthThird);
@ -1240,8 +1244,8 @@ void SessionController::startOrJoinGroupCall(
const auto askConfirmation = [&](QString text, QString button) { const auto askConfirmation = [&](QString text, QString button) {
show(Ui::MakeConfirmBox({ show(Ui::MakeConfirmBox({
.text = text, .text = text,
.confirmed = crl::guard(this, [=, hash = args.joinHash] { .confirmed = crl::guard(this,[=, hash = args.joinHash] {
Ui::hideLayer(); hideLayer();
startOrJoinGroupCall(peer, { hash, JoinConfirm::None }); startOrJoinGroupCall(peer, { hash, JoinConfirm::None });
}), }),
.confirmText = button, .confirmText = button,
@ -1597,7 +1601,7 @@ QPointer<Ui::BoxContent> SessionController::show(
} }
void SessionController::hideLayer(anim::type animated) { void SessionController::hideLayer(anim::type animated) {
show({ nullptr }, Ui::LayerOption::CloseOther, animated); _window->hideLayer(animated);
} }
void SessionController::openPhoto( void SessionController::openPhoto(

View file

@ -554,6 +554,7 @@ private:
const not_null<Controller*> _window; const not_null<Controller*> _window;
const std::unique_ptr<ChatHelpers::EmojiInteractions> _emojiInteractions; const std::unique_ptr<ChatHelpers::EmojiInteractions> _emojiInteractions;
const bool _isPrimary = false;
using SendingAnimation = Ui::MessageSendingAnimationController; using SendingAnimation = Ui::MessageSendingAnimationController;
const std::unique_ptr<SendingAnimation> _sendingAnimation; const std::unique_ptr<SendingAnimation> _sendingAnimation;