Remove BypassWindowManagerHint in MediaView / Passport.

It makes all kinds of usages buggy, including choose file dialog.

Fixes #4936.
I hope fixes #4950, I hope fixes #4955, I hope fixes #3553.
This commit is contained in:
John Preston 2018-07-19 17:27:09 +03:00
parent fae0bccc9c
commit be043a4437
25 changed files with 66 additions and 46 deletions

View File

@ -251,6 +251,7 @@ void PeerListController::setSearchNoResultsText(const QString &text) {
}
base::unique_qptr<Ui::PopupMenu> PeerListController::rowContextMenu(
QWidget *parent,
not_null<PeerListRow*> row) {
return nullptr;
}
@ -1020,7 +1021,7 @@ void PeerListContent::contextMenuEvent(QContextMenuEvent *e) {
}
if (const auto row = getRow(_contexted.index)) {
_contextMenu = _controller->rowContextMenu(row);
_contextMenu = _controller->rowContextMenu(this, row);
if (_contextMenu) {
_contextMenu->setDestroyedCallback(crl::guard(
this,

View File

@ -345,6 +345,7 @@ public:
virtual void itemDeselectedHook(not_null<PeerData*> peer) {
}
virtual base::unique_qptr<Ui::PopupMenu> rowContextMenu(
QWidget *parent,
not_null<PeerListRow*> row);
bool isSearchLoading() const {
return _searchController ? _searchController->isLoading() : false;

View File

@ -415,7 +415,7 @@ void Panel::reinitControls() {
}
void Panel::initLayout() {
setWindowFlags(Qt::WindowFlags(Qt::FramelessWindowHint) | Qt::WindowStaysOnTopHint | Qt::BypassWindowManagerHint | Qt::NoDropShadowWindowHint | Qt::Dialog);
setWindowFlags(Qt::WindowFlags(Qt::FramelessWindowHint) | Qt::WindowStaysOnTopHint | Qt::NoDropShadowWindowHint | Qt::Dialog);
setAttribute(Qt::WA_MacAlwaysShowToolWindow);
setAttribute(Qt::WA_NoSystemBackground, true);
setAttribute(Qt::WA_TranslucentBackground, true);

View File

@ -1514,7 +1514,7 @@ void DialogsInner::contextMenuEvent(QContextMenuEvent *e) {
mousePressReleased(_pressButton);
}
_menu = base::make_unique_q<Ui::PopupMenu>(nullptr);
_menu = base::make_unique_q<Ui::PopupMenu>(this);
if (const auto history = key.history()) {
Window::FillPeerMenu(
_controller,

View File

@ -941,7 +941,7 @@ void InnerWidget::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
isUponSelected = hasSelected;
}
_menu = base::make_unique_q<Ui::PopupMenu>(nullptr);
_menu = base::make_unique_q<Ui::PopupMenu>(this);
const auto link = ClickHandler::getActive();
auto view = App::hoveredItem()

View File

@ -1456,7 +1456,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
isUponSelected = hasSelected;
}
_menu = base::make_unique_q<Ui::PopupMenu>(nullptr);
_menu = base::make_unique_q<Ui::PopupMenu>(this);
const auto addItemActions = [&](HistoryItem *item) {
if (!item

View File

@ -434,7 +434,7 @@ void AddCopyLinkAction(
base::unique_qptr<Ui::PopupMenu> FillContextMenu(
not_null<ListWidget*> list,
const ContextMenuRequest &request) {
auto result = base::make_unique_q<Ui::PopupMenu>(nullptr);
auto result = base::make_unique_q<Ui::PopupMenu>(list);
const auto link = request.link;
const auto view = request.view;

View File

@ -188,11 +188,12 @@ void ChannelsController::rowActionClicked(not_null<PeerListRow*> row) {
}
base::unique_qptr<Ui::PopupMenu> ChannelsController::rowContextMenu(
QWidget *parent,
not_null<PeerListRow*> row) {
auto my = static_cast<Row*>(row.get());
auto channel = my->history()->peer->asChannel();
auto result = base::make_unique_q<Ui::PopupMenu>(nullptr);
auto result = base::make_unique_q<Ui::PopupMenu>(parent);
Window::PeerMenuAddMuteAction(channel, [&](
const QString &text,
Fn<void()> handler) {

View File

@ -33,6 +33,7 @@ public:
std::unique_ptr<PeerListRow> createRestoredRow(
not_null<PeerData*> peer) override;
base::unique_qptr<Ui::PopupMenu> rowContextMenu(
QWidget *parent,
not_null<PeerListRow*> row) override;
std::unique_ptr<PeerListState> saveState() const override;

View File

@ -929,6 +929,10 @@ void ListWidget::markLayoutsStale() {
}
}
bool ListWidget::preventAutoHide() const {
return (_contextMenu != nullptr) || (_actionBoxWeak != nullptr);
}
void ListWidget::saveState(not_null<Memento*> memento) {
if (_universalAroundId != kDefaultAroundId) {
auto state = countScrollState();
@ -1165,7 +1169,6 @@ void ListWidget::showContextMenu(
QContextMenuEvent *e,
ContextMenuSource source) {
if (_contextMenu) {
_contextMenu->deleteLater();
_contextMenu = nullptr;
repaintItem(_contextUniversalId);
}
@ -1217,7 +1220,7 @@ void ListWidget::showContextMenu(
auto link = ClickHandler::getActive();
_contextMenu = new Ui::PopupMenu(nullptr);
_contextMenu = base::make_unique_q<Ui::PopupMenu>(this);
_contextMenu->addAction(
lang(lng_context_to_msg),
[itemFullId = item->fullId()] {
@ -1347,7 +1350,6 @@ void ListWidget::showContextMenu(
_contextMenu->setDestroyedCallback(crl::guard(
this,
[this, universalId] {
_contextMenu = nullptr;
mouseActionUpdate(QCursor::pos());
repaintItem(universalId);
_checkForHide.fire({});
@ -2121,7 +2123,12 @@ auto ListWidget::findSectionAfterBottom(
[](const Section &section) { return section.top(); });
}
ListWidget::~ListWidget() = default;
ListWidget::~ListWidget() {
if (_contextMenu) {
// We don't want it to be called after ListWidget is destroyed.
_contextMenu->setDestroyedCallback(nullptr);
}
}
} // namespace Media
} // namespace Info

View File

@ -61,9 +61,7 @@ public:
rpl::producer<> checkForHide() const {
return _checkForHide.events();
}
bool preventAutoHide() const {
return (_contextMenu != nullptr) || (_actionBoxWeak != nullptr);
}
bool preventAutoHide() const;
void saveState(not_null<Memento*> memento);
void restoreState(not_null<Memento*> memento);
@ -304,7 +302,7 @@ private:
DragSelectAction _dragSelectAction = DragSelectAction::None;
bool _wasSelectedText = false; // was some text selected in current drag action
Ui::PopupMenu *_contextMenu = nullptr;
base::unique_qptr<Ui::PopupMenu> _contextMenu;
rpl::event_stream<> _checkForHide;
QPointer<Ui::RpWidget> _actionBoxWeak;
rpl::lifetime _actionBoxWeakLifetime;

View File

@ -40,6 +40,7 @@ public:
void rowClicked(not_null<PeerListRow*> row) override;
void rowActionClicked(not_null<PeerListRow*> row) override;
base::unique_qptr<Ui::PopupMenu> rowContextMenu(
QWidget *parent,
not_null<PeerListRow*> row) override;
rpl::producer<int> onlineCountValue() const override {
@ -266,12 +267,13 @@ void ChatMembersController::rowActionClicked(
}
base::unique_qptr<Ui::PopupMenu> ChatMembersController::rowContextMenu(
QWidget *parent,
not_null<PeerListRow*> row) {
auto my = static_cast<MemberListRow*>(row.get());
auto user = my->user();
auto canRemoveMember = my->canRemove();
auto result = base::make_unique_q<Ui::PopupMenu>(nullptr);
auto result = base::make_unique_q<Ui::PopupMenu>(parent);
result->addAction(
lang(lng_context_view_profile),
[weak = base::make_weak(this), user] {

View File

@ -117,7 +117,7 @@ MediaView::MediaView()
});
handleAuthSessionChange();
setWindowFlags(Qt::FramelessWindowHint | Qt::BypassWindowManagerHint | Qt::Tool | Qt::NoDropShadowWindowHint);
setWindowFlags(Qt::FramelessWindowHint);
moveToScreen();
setAttribute(Qt::WA_NoSystemBackground, true);
setAttribute(Qt::WA_TranslucentBackground, true);
@ -125,7 +125,7 @@ MediaView::MediaView()
hide();
createWinId();
if (cPlatform() == dbipWindows) {
if (cPlatform() != dbipMac && cPlatform() != dbipMacOld) {
setWindowState(Qt::WindowFullScreen);
}
@ -165,7 +165,8 @@ void MediaView::moveToScreen() {
if (activeWindowScreen && myScreen && myScreen != activeWindowScreen) {
windowHandle()->setScreen(activeWindowScreen);
}
auto available = activeWindow ? Sandbox::screenGeometry(activeWindow->geometry().center()) : QApplication::desktop()->screenGeometry();
const auto screen = activeWindowScreen ? activeWindowScreen : QApplication::primaryScreen();
const auto available = screen->geometry();
if (geometry() != available) {
setGeometry(available);
}
@ -2847,7 +2848,7 @@ void MediaView::contextMenuEvent(QContextMenuEvent *e) {
_menu->deleteLater();
_menu = 0;
}
_menu = new Ui::PopupMenu(nullptr, st::mediaviewPopupMenu);
_menu = new Ui::PopupMenu(this, st::mediaviewPopupMenu);
updateActions();
for_const (auto &action, _actions) {
_menu->addAction(action.text, this, action.member);

View File

@ -247,9 +247,6 @@ GtkDialog *QGtkDialog::gtkDialog() const {
}
void QGtkDialog::exec() {
if (auto w = App::wnd()) {
w->reActivateWindow();
}
if (modality() == Qt::ApplicationModal) {
// block input to the whole app, including other GTK dialogs
Libs::gtk_dialog_run(gtkDialog());
@ -413,6 +410,12 @@ int GtkFileDialog::exec() {
show();
if (const auto parent = parentWidget()) {
App::CallDelayed(200, parent, [=] {
parent->activateWindow();
});
}
QPointer<QDialog> guard = this;
d->exec();
if (guard.isNull())

View File

@ -94,11 +94,9 @@ QRect psDesktopRect() {
}
void psShowOverAll(QWidget *w, bool canFocus) {
w->show();
}
void psBringToBack(QWidget *w) {
w->hide();
}
QAbstractNativeEventFilter *psNativeEventFilter() {

View File

@ -221,7 +221,7 @@ Ui::PopupMenu *GroupMembersWidget::fillPeerMenu(PeerData *selectedPeer) {
return nullptr;
}
auto user = selectedPeer->asUser();
auto result = new Ui::PopupMenu(nullptr);
auto result = new Ui::PopupMenu(this);
result->addAction(lang(lng_context_view_profile), [selectedPeer] {
Ui::showPeerProfile(selectedPeer);
});

View File

@ -704,11 +704,12 @@ bool ParticipantsBoxController::canRestrictUser(
}
base::unique_qptr<Ui::PopupMenu> ParticipantsBoxController::rowContextMenu(
QWidget *parent,
not_null<PeerListRow*> row) {
Expects(row->peer()->isUser());
auto user = row->peer()->asUser();
auto result = base::make_unique_q<Ui::PopupMenu>(nullptr);
auto result = base::make_unique_q<Ui::PopupMenu>(parent);
result->addAction(
lang(lng_context_view_profile),
[weak = base::make_weak(this), user] {

View File

@ -70,6 +70,7 @@ public:
void rowClicked(not_null<PeerListRow*> row) override;
void rowActionClicked(not_null<PeerListRow*> row) override;
base::unique_qptr<Ui::PopupMenu> rowContextMenu(
QWidget *parent,
not_null<PeerListRow*> row) override;
void loadMoreRows() override;

View File

@ -1004,7 +1004,7 @@ void FlatInput::refreshPlaceholder() {
void FlatInput::contextMenuEvent(QContextMenuEvent *e) {
if (auto menu = createStandardContextMenu()) {
(new Ui::PopupMenu(nullptr, menu))->popup(e->globalPos());
(new Ui::PopupMenu(this, menu))->popup(e->globalPos());
}
}
@ -3170,7 +3170,7 @@ bool InputField::revertFormatReplace() {
void InputField::contextMenuEventInner(QContextMenuEvent *e) {
if (const auto menu = _inner->createStandardContextMenu()) {
addMarkdownActions(menu, e);
_contextMenu = base::make_unique_q<Ui::PopupMenu>(nullptr, menu);
_contextMenu = base::make_unique_q<Ui::PopupMenu>(this, menu);
_contextMenu->popup(e->globalPos());
}
}
@ -3670,7 +3670,7 @@ void MaskedInputField::setPlaceholder(Fn<QString()> placeholderFactory) {
void MaskedInputField::contextMenuEvent(QContextMenuEvent *e) {
if (auto menu = createStandardContextMenu()) {
(new Ui::PopupMenu(nullptr, menu))->popup(e->globalPos());
(new Ui::PopupMenu(this, menu))->popup(e->globalPos());
}
}

View File

@ -539,7 +539,7 @@ void FlatLabel::showContextMenu(QContextMenuEvent *e, ContextMenuReason reason)
uponSelection = hasSelection;
}
_contextMenu = new Ui::PopupMenu(nullptr);
_contextMenu = new Ui::PopupMenu(this);
if (fullSelection && !_contextCopyText.isEmpty()) {
_contextMenu->addAction(_contextCopyText, this, SLOT(onCopyContextText()));

View File

@ -16,20 +16,22 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Ui {
PopupMenu::PopupMenu(QWidget*, const style::PopupMenu &st)
: _st(st)
PopupMenu::PopupMenu(QWidget *parent, const style::PopupMenu &st)
: RpWidget(parent)
, _st(st)
, _menu(this, _st.menu) {
init();
}
PopupMenu::PopupMenu(QWidget*, QMenu *menu, const style::PopupMenu &st)
: _st(st)
PopupMenu::PopupMenu(QWidget *parent, QMenu *menu, const style::PopupMenu &st)
: RpWidget(parent)
, _st(st)
, _menu(this, menu, _st.menu) {
init();
for (auto action : actions()) {
if (auto submenu = action->menu()) {
auto it = _submenus.insert(action, new PopupMenu(nullptr, submenu, st));
auto it = _submenus.insert(action, new PopupMenu(parentWidget(), submenu, st));
it.value()->deleteOnHide(false);
}
}
@ -274,7 +276,6 @@ void PopupMenu::childHiding(PopupMenu *child) {
_activeSubmenu = SubmenuPointer();
}
if (!_hiding && !isHidden()) {
windowHandle()->requestActivate();
activateWindow();
}
}
@ -474,16 +475,19 @@ void PopupMenu::showMenu(const QPoint &p, PopupMenu *parent, TriggeredSource sou
psUpdateOverlayed(this);
show();
psShowOverAll(this);
windowHandle()->requestActivate();
activateWindow();
}
PopupMenu::~PopupMenu() {
for (auto submenu : base::take(_submenus)) {
for (const auto submenu : base::take(_submenus)) {
delete submenu;
}
if (auto w = App::wnd()) {
w->reActivateWindow();
if (const auto parent = parentWidget()) {
crl::on_main(parent, [=] {
if (!parent->isHidden()) {
parent->activateWindow();
}
});
}
if (_destroyedCallback) {
_destroyedCallback();

View File

@ -16,8 +16,8 @@ namespace Ui {
class PopupMenu : public Ui::RpWidget, private base::Subscriber {
public:
PopupMenu(QWidget*, const style::PopupMenu &st = st::defaultPopupMenu);
PopupMenu(QWidget*, QMenu *menu, const style::PopupMenu &st = st::defaultPopupMenu);
PopupMenu(QWidget *parent, const style::PopupMenu &st = st::defaultPopupMenu);
PopupMenu(QWidget *parent, QMenu *menu, const style::PopupMenu &st = st::defaultPopupMenu);
QAction *addAction(const QString &text, const QObject *receiver, const char* member, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr);
QAction *addAction(const QString &text, Fn<void()> callback, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr);

View File

@ -143,7 +143,6 @@ bool SeparatePanel::eventHook(QEvent *e) {
void SeparatePanel::initLayout() {
setWindowFlags(Qt::WindowFlags(Qt::FramelessWindowHint)
| Qt::WindowStaysOnTopHint
| Qt::BypassWindowManagerHint
| Qt::NoDropShadowWindowHint
| Qt::Dialog);
setAttribute(Qt::WA_MacAlwaysShowToolWindow);

View File

@ -427,7 +427,6 @@ void MainWindow::reActivateWindow() {
if (auto f = QApplication::focusWidget()) {
f->clearFocus();
}
windowHandle()->requestActivate();
w->activate();
if (auto f = QApplication::focusWidget()) {
f->clearFocus();

View File

@ -360,7 +360,10 @@ Widget::Widget(Manager *manager, QPoint startPosition, int shift, Direction shif
, _a_shift(animation(this, &Widget::step_shift)) {
setWindowOpacity(0.);
setWindowFlags(Qt::WindowFlags(Qt::FramelessWindowHint) | Qt::WindowStaysOnTopHint | Qt::BypassWindowManagerHint | Qt::NoDropShadowWindowHint | Qt::Tool);
setWindowFlags(Qt::WindowFlags(Qt::FramelessWindowHint)
| Qt::WindowStaysOnTopHint
| Qt::NoDropShadowWindowHint
| Qt::Tool);
setAttribute(Qt::WA_MacAlwaysShowToolWindow);
setAttribute(Qt::WA_OpaquePaintEvent);