diff --git a/Telegram/Resources/icons/menu/new_window.png b/Telegram/Resources/icons/menu/new_window.png new file mode 100644 index 000000000..5b926de16 Binary files /dev/null and b/Telegram/Resources/icons/menu/new_window.png differ diff --git a/Telegram/Resources/icons/menu/new_window@2x.png b/Telegram/Resources/icons/menu/new_window@2x.png new file mode 100644 index 000000000..6003b7f75 Binary files /dev/null and b/Telegram/Resources/icons/menu/new_window@2x.png differ diff --git a/Telegram/Resources/icons/menu/new_window@3x.png b/Telegram/Resources/icons/menu/new_window@3x.png new file mode 100644 index 000000000..873e18171 Binary files /dev/null and b/Telegram/Resources/icons/menu/new_window@3x.png differ diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index f942fccb1..275e297b8 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -2124,6 +2124,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_choose_files" = "Choose files"; "lng_game_tag" = "Game"; +"lng_context_new_window" = "Open in new window"; "lng_context_view_profile" = "View profile"; "lng_context_send_message" = "Send message"; "lng_context_view_group" = "View group info"; diff --git a/Telegram/SourceFiles/calls/calls.style b/Telegram/SourceFiles/calls/calls.style index 79e7677ca..8fc8445b3 100644 --- a/Telegram/SourceFiles/calls/calls.style +++ b/Telegram/SourceFiles/calls/calls.style @@ -519,7 +519,7 @@ groupCallMenu: Menu(defaultMenu) { padding: margins(0px, 4px, 0px, 4px); fg: groupCallMenuBgOver; } - arrow: icon {{ "dropdown_submenu_arrow", groupCallMemberNotJoinedStatus }}; + arrow: icon {{ "menu/submenu_arrow", groupCallMemberNotJoinedStatus }}; ripple: RippleAnimation(defaultRippleAnimation) { color: groupCallMenuBgRipple; diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index e65be7111..08b9ad537 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -60,6 +60,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "api/api_chat_filters.h" #include "base/qt/qt_common_adapters.h" #include "styles/style_dialogs.h" +#include "styles/style_chat.h" // popupMenuExpandedSeparator #include "styles/style_chat_helpers.h" #include "styles/style_window.h" #include "styles/style_menu_icons.h" @@ -70,13 +71,6 @@ namespace { constexpr auto kHashtagResultsLimit = 5; constexpr auto kStartReorderThreshold = 30; -base::options::toggle CtrlClickChatNewWindow({ - .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 list) { auto result = 0; for (const auto &row : *list) { @@ -105,8 +99,6 @@ int PinnedDialogsCount( } // namespace -const char kOptionCtrlClickChatNewWindow[] = "ctrl-click-chat-new-window"; - struct InnerWidget::CollapsedRow { CollapsedRow(Data::Folder *folder) : folder(folder) { } @@ -2206,7 +2198,7 @@ void InnerWidget::contextMenuEvent(QContextMenuEvent *e) { _menu = base::make_unique_q( this, - row.fullId ? st::defaultPopupMenu : st::popupMenuWithIcons); + row.fullId ? st::defaultPopupMenu : st::popupMenuExpandedSeparator); if (row.fullId) { if (session().supportMode()) { fillSupportSearchMenu(_menu.get()); @@ -3310,9 +3302,7 @@ bool InnerWidget::chooseRow( const auto modifyChosenRow = []( ChosenRow row, Qt::KeyboardModifiers modifiers) { - if (CtrlClickChatNewWindow.value()) { - row.newWindow = (modifiers & Qt::ControlModifier); - } + row.newWindow = (modifiers & Qt::ControlModifier); return row; }; auto chosen = modifyChosenRow(computeChosenRow(), modifiers); diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h index ec9aa015d..00d06ba99 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h @@ -54,8 +54,6 @@ struct TopicJumpCache; namespace Dialogs { -extern const char kOptionCtrlClickChatNewWindow[]; - class Row; class FakeRow; class IndexedList; diff --git a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp index a0b0867cc..ac7e00de3 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp @@ -484,24 +484,8 @@ void Widget::chosenRow(const ChosenRow &row) { const auto showAtMsgId = controller()->uniqueChatsInSearchResults() ? ShowAtUnreadMsgId : row.message.fullId.msg; - if (row.newWindow && controller()->canShowSeparateWindow(peer)) { - const auto active = controller()->activeChatCurrent(); - const auto fromActive = active.history() - ? (active.history()->peer == peer) - : false; - const auto toSeparate = [=] { - Core::App().ensureSeparateWindowForPeer( - peer, - showAtMsgId); - }; - if (fromActive) { - controller()->window().preventOrInvoke([=] { - controller()->clearSectionStack(); - toSeparate(); - }); - } else { - toSeparate(); - } + if (row.newWindow) { + controller()->showInNewWindow(peer, showAtMsgId); } else { controller()->showThread( history, diff --git a/Telegram/SourceFiles/media/view/media_view.style b/Telegram/SourceFiles/media/view/media_view.style index 0405886d1..bc8f8beb2 100644 --- a/Telegram/SourceFiles/media/view/media_view.style +++ b/Telegram/SourceFiles/media/view/media_view.style @@ -192,7 +192,7 @@ mediaviewControlsMenu: Menu(defaultMenu) { fg: mediaviewPlaybackIconRipple; } - arrow: icon {{ "dropdown_submenu_arrow", mediaviewPlaybackProgressFg }}; + arrow: icon {{ "menu/submenu_arrow", mediaviewPlaybackProgressFg }}; ripple: RippleAnimation(defaultRippleAnimation) { color: mediaviewPlaybackIconRipple; diff --git a/Telegram/SourceFiles/settings/settings_experimental.cpp b/Telegram/SourceFiles/settings/settings_experimental.cpp index 61163ac90..8359cf233 100644 --- a/Telegram/SourceFiles/settings/settings_experimental.cpp +++ b/Telegram/SourceFiles/settings/settings_experimental.cpp @@ -18,7 +18,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "core/application.h" #include "core/launcher.h" #include "chat_helpers/tabbed_panel.h" -#include "dialogs/dialogs_inner_widget.h" #include "lang/lang_keys.h" #include "mainwindow.h" #include "media/player/media_player_instance.h" @@ -140,7 +139,6 @@ void SetupExperimental( addToggle(ChatHelpers::kOptionTabbedPanelShowOnClick); addToggle(Core::kOptionFractionalScalingEnabled); addToggle(Window::kOptionViewProfileInChatsListContextMenu); - addToggle(Dialogs::kOptionCtrlClickChatNewWindow); addToggle(Ui::GL::kOptionAllowLinuxNvidiaOpenGL); addToggle(Ui::kOptionUseSmallMsgBubbleRadius); addToggle(Media::Player::kOptionDisableAutoplayNext); diff --git a/Telegram/SourceFiles/settings/settings_information.cpp b/Telegram/SourceFiles/settings/settings_information.cpp index 8f4931526..01f58aac0 100644 --- a/Telegram/SourceFiles/settings/settings_information.cpp +++ b/Telegram/SourceFiles/settings/settings_information.cpp @@ -7,7 +7,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "settings/settings_information.h" -#include "dialogs/dialogs_inner_widget.h" // kOptionCtrlClickChatNewWindow. #include "editor/photo_editor_layer_widget.h" #include "settings/settings_common.h" #include "ui/wrap/vertical_layout.h" @@ -23,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/boxes/confirm_box.h" #include "ui/controls/userpic_button.h" #include "ui/text/text_utilities.h" +#include "ui/delayed_activation.h" #include "ui/painter.h" #include "ui/unread_badge_paint.h" #include "core/application.h" @@ -55,6 +55,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/options.h" #include "base/unixtime.h" #include "base/random.h" +#include "styles/style_chat.h" // popupMenuExpandedSeparator #include "styles/style_dialogs.h" // dialogsPremiumIcon #include "styles/style_layers.h" #include "styles/style_settings.h" @@ -670,9 +671,16 @@ void SetupAccountsWrap( } state->menu = base::make_unique_q( raw, - st::popupMenuWithIcons); + st::popupMenuExpandedSeparator); const auto addAction = Ui::Menu::CreateAddActionCallback( state->menu); + addAction(tr::lng_context_new_window(tr::now), [=] { + Ui::PreventDelayedActivation(); + Core::App().ensureSeparateWindowForAccount(account); + Core::App().domain().maybeActivate(account); + }, &st::menuIconNewWindow); + Window::AddSeparatorAndShiftUp(addAction); + addAction(tr::lng_profile_copy_phone(tr::now), [=] { const auto phone = rpl::variable( Info::Profile::PhoneValue(session->user())); @@ -812,9 +820,7 @@ not_null*> AccountsList::setupAdd() { ) | rpl::start_with_next([=](Qt::MouseButton which) { if (which == Qt::LeftButton) { const auto modifiers = button->clickModifiers(); - const auto newWindow = (modifiers & Qt::ControlModifier) - && base::options::lookup( - Dialogs::kOptionCtrlClickChatNewWindow).value(); + const auto newWindow = (modifiers & Qt::ControlModifier); add(Environment::Production, newWindow); return; } else if (which != Qt::RightButton @@ -884,9 +890,7 @@ void AccountsList::rebuild() { _currentAccountActivations.fire({}); return; } - const auto newWindow = (modifiers & Qt::ControlModifier) - && base::options::lookup( - Dialogs::kOptionCtrlClickChatNewWindow).value(); + const auto newWindow = (modifiers & Qt::ControlModifier); auto activate = [=, guard = _accountSwitchGuard.make_guard()]{ if (guard) { _reorder->finishReordering(); diff --git a/Telegram/SourceFiles/ui/menu_icons.style b/Telegram/SourceFiles/ui/menu_icons.style index fef75c9ad..142cc47f0 100644 --- a/Telegram/SourceFiles/ui/menu_icons.style +++ b/Telegram/SourceFiles/ui/menu_icons.style @@ -99,6 +99,7 @@ menuIconSpoilerOff: icon {{ "menu/spoiler_off", menuIconColor }}; menuIconDisable: icon {{ "menu/disable", menuIconColor }}; menuIconPhotoSet: icon {{ "menu/photo_set", menuIconColor }}; menuIconPhotoSuggest: icon {{ "menu/photo_suggest", menuIconColor }}; +menuIconNewWindow: icon {{ "menu/new_window", menuIconColor }}; menuIconTTLAny: icon {{ "menu/auto_delete_plain", menuIconColor }}; menuIconTTLAnyTextPosition: point(11px, 22px); diff --git a/Telegram/SourceFiles/window/window_controller.h b/Telegram/SourceFiles/window/window_controller.h index 69693da24..b106a4d51 100644 --- a/Telegram/SourceFiles/window/window_controller.h +++ b/Telegram/SourceFiles/window/window_controller.h @@ -147,7 +147,6 @@ private: MsgId singlePeerShowAtMsgId); void setupSideBar(); void sideBarChanged(); - void logoutWithChecks(Main::Account *account); void showBox( object_ptr content, diff --git a/Telegram/SourceFiles/window/window_peer_menu.cpp b/Telegram/SourceFiles/window/window_peer_menu.cpp index 56ad3f55d..2e00071fa 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.cpp +++ b/Telegram/SourceFiles/window/window_peer_menu.cpp @@ -41,6 +41,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/widgets/menu/menu_add_action_callback_factory.h" #include "ui/layers/generic_box.h" #include "ui/toasts/common_toasts.h" +#include "ui/delayed_activation.h" #include "main/main_session.h" #include "main/main_session_settings.h" #include "menu/menu_mute.h" @@ -81,6 +82,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "core/application.h" #include "export/export_manager.h" #include "boxes/peers/edit_peer_info_box.h" +#include "styles/style_chat.h" #include "styles/style_layers.h" #include "styles/style_boxes.h" #include "styles/style_window.h" // st::windowMinWidth @@ -254,6 +256,7 @@ private: void addToggleMuteSubmenu(bool addSeparator); void addSupportInfo(); void addInfo(); + void addNewWindow(); void addToggleFolder(); void addToggleUnreadMark(); void addToggleArchive(); @@ -597,6 +600,25 @@ void Filler::addToggleUnreadMark() { }, (unread ? &st::menuIconMarkRead : &st::menuIconMarkUnread)); } +void Filler::addNewWindow() { + const auto history = _request.key.history(); + if (!_peer + || _topic + || _peer->isForum() + || (history + && history->useTopPromotion() + && !history->topPromotionType().isEmpty())) { + return; + } + const auto peer = _peer; + const auto controller = _controller; + _addAction(tr::lng_context_new_window(tr::now), [=] { + Ui::PreventDelayedActivation(); + controller->showInNewWindow(peer); + }, &st::menuIconNewWindow); + AddSeparatorAndShiftUp(_addAction); +} + void Filler::addToggleArchive() { if (!_peer || _topic) { return; @@ -1162,6 +1184,7 @@ void Filler::addVideoChat() { } void Filler::fillContextMenuActions() { + addNewWindow(); addHidePromotion(); addToggleArchive(); addTogglePin(); @@ -2413,4 +2436,17 @@ void MarkAsReadThread(not_null thread) { } } +void AddSeparatorAndShiftUp(const PeerMenuCallback &addAction) { + addAction({ .isSeparator = true }); + + const auto &st = st::popupMenuExpandedSeparator.menu; + const auto shift = st::popupMenuExpandedSeparator.scrollPadding.top() + + st.itemPadding.top() + + st.itemStyle.font->height + + st.itemPadding.bottom() + + st.separator.padding.top() + + st.separator.width / 2; + addAction({ .addTopShift = -shift }); +} + } // namespace Window diff --git a/Telegram/SourceFiles/window/window_peer_menu.h b/Telegram/SourceFiles/window/window_peer_menu.h index ebe249dd0..d224197d1 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.h +++ b/Telegram/SourceFiles/window/window_peer_menu.h @@ -164,4 +164,6 @@ void UnpinAllMessages( [[nodiscard]] bool IsUnreadThread(not_null thread); void MarkAsReadThread(not_null thread); +void AddSeparatorAndShiftUp(const PeerMenuCallback &addAction); + } // namespace Window diff --git a/Telegram/SourceFiles/window/window_session_controller.cpp b/Telegram/SourceFiles/window/window_session_controller.cpp index 67b82fba9..81a369019 100644 --- a/Telegram/SourceFiles/window/window_session_controller.cpp +++ b/Telegram/SourceFiles/window/window_session_controller.cpp @@ -1460,7 +1460,7 @@ void SessionController::closeThirdSection() { bool SessionController::canShowSeparateWindow( not_null peer) const { - return peer->computeUnavailableReason().isEmpty(); + return !peer->isForum() && peer->computeUnavailableReason().isEmpty(); } void SessionController::showPeer(not_null peer, MsgId msgId) { @@ -1690,6 +1690,33 @@ void SessionController::clearChooseReportMessages() { content()->clearChooseReportMessages(); } +void SessionController::showInNewWindow( + not_null peer, + MsgId msgId) { + if (!canShowSeparateWindow(peer)) { + showThread( + peer->owner().history(peer), + msgId, + Window::SectionShow::Way::ClearStack); + return; + } + const auto active = activeChatCurrent(); + const auto fromActive = active.history() + ? (active.history()->peer == peer) + : false; + const auto toSeparate = [=] { + Core::App().ensureSeparateWindowForPeer(peer, msgId); + }; + if (fromActive) { + window().preventOrInvoke([=] { + clearSectionStack(); + toSeparate(); + }); + } else { + toSeparate(); + } +} + void SessionController::toggleChooseChatTheme(not_null peer) { content()->toggleChooseChatTheme(peer); } diff --git a/Telegram/SourceFiles/window/window_session_controller.h b/Telegram/SourceFiles/window/window_session_controller.h index 76f12014a..dad287fd5 100644 --- a/Telegram/SourceFiles/window/window_session_controller.h +++ b/Telegram/SourceFiles/window/window_session_controller.h @@ -477,6 +477,10 @@ public: Fn done); void clearChooseReportMessages(); + void showInNewWindow( + not_null peer, + MsgId msgId = ShowAtUnreadMsgId); + void toggleChooseChatTheme(not_null peer); [[nodiscard]] bool dialogsListFocused() const { diff --git a/Telegram/lib_ui b/Telegram/lib_ui index 30e765785..98fa93787 160000 --- a/Telegram/lib_ui +++ b/Telegram/lib_ui @@ -1 +1 @@ -Subproject commit 30e765785946f3e4aa89d1b1b7fa2118b612a8a0 +Subproject commit 98fa93787a13d8ad9427facb465500fe3179860e