| 736 | } |
| 737 | |
| 738 | void Container::contextMenu( const QPoint& pos ) |
| 739 | { |
| 740 | Q_D(Container); |
| 741 | |
| 742 | QWidget* senderWidget = qobject_cast<QWidget*>(sender()); |
| 743 | Q_ASSERT(senderWidget); |
| 744 | |
| 745 | int currentTab = d->tabBar->tabAt(pos); |
| 746 | |
| 747 | QMenu menu; |
| 748 | // Polish before creating a native window below. The style could want change the surface format |
| 749 | // of the window which will have no effect when the native window has already been created. |
| 750 | menu.ensurePolished(); |
| 751 | // At least for positioning on Wayland the window the menu belongs to |
| 752 | // needs to be set. We cannot set senderWidget as parent because some actions (e.g. split view) |
| 753 | // result in sync destruction of the senderWidget, which then would also prematurely |
| 754 | // destruct the menu object |
| 755 | // Workaround (best known currently, check again API of Qt >5.9): |
| 756 | menu.winId(); // trigger being a native widget already, to ensure windowHandle created |
| 757 | auto parentWindowHandle = senderWidget->windowHandle(); |
| 758 | if (!parentWindowHandle) { |
| 759 | parentWindowHandle = senderWidget->nativeParentWidget()->windowHandle(); |
| 760 | } |
| 761 | menu.windowHandle()->setTransientParent(parentWindowHandle); |
| 762 | |
| 763 | Sublime::View* view = viewForWidget(widget(currentTab)); |
| 764 | emit tabContextMenuRequested(view, &menu); |
| 765 | |
| 766 | menu.addSeparator(); |
| 767 | QAction* copyPathAction = nullptr; |
| 768 | QAction* closeTabAction = nullptr; |
| 769 | QAction* closeOtherTabsAction = nullptr; |
| 770 | if (view) { |
| 771 | copyPathAction = menu.addAction(QIcon::fromTheme(QStringLiteral("edit-copy")), |
| 772 | i18nc("@action:inmenu", "Copy Filename")); |
| 773 | menu.addSeparator(); |
| 774 | closeTabAction = menu.addAction(QIcon::fromTheme(QStringLiteral("document-close")), |
| 775 | i18nc("@action:inmenu", "Close")); |
| 776 | closeOtherTabsAction = menu.addAction(QIcon::fromTheme(QStringLiteral("document-close")), |
| 777 | i18nc("@action:inmenu", "Close All Other")); |
| 778 | } |
| 779 | QAction* closeAllTabsAction = menu.addAction(QIcon::fromTheme(QStringLiteral("document-close")), i18nc("@action:inmenu", "Close All")); |
| 780 | |
| 781 | QAction* triggered = menu.exec(senderWidget->mapToGlobal(pos)); |
| 782 | |
| 783 | if (triggered) { |
| 784 | if ( triggered == closeTabAction ) { |
| 785 | requestClose(currentTab); |
| 786 | } else if ( triggered == closeOtherTabsAction ) { |
| 787 | // activate the remaining tab |
| 788 | widgetActivated(currentTab); |
| 789 | // first get the widgets to be closed since otherwise the indices will be wrong |
| 790 | QList<QWidget*> otherTabs; |
| 791 | for ( int i = 0; i < count(); ++i ) { |
| 792 | if ( i != currentTab ) { |
| 793 | otherTabs << widget(i); |
| 794 | } |
| 795 | } |