diff --git a/devel/202_106.md b/devel/202_106.md new file mode 100644 index 0000000000..c5ed3c6595 --- /dev/null +++ b/devel/202_106.md @@ -0,0 +1,29 @@ +# [202_106] Cmd+V paste not working in macOS save file dialog + +### How to test +1. Open Mogan on macOS +2. Copy some text to the clipboard +3. Open **Save As** dialog (File → Save as) +4. In the filename text field, press **Cmd+V** to paste +5. Verify the clipboard text is pasted into the filename field +6. Also verify **Cmd+C**, **Cmd+X**, **Cmd+A** work in the dialog +7. After closing the dialog, verify editor shortcuts still work normally + +## 2026/03/01 +### What +Temporarily disable QAction keyboard shortcuts while a native file dialog is open on macOS, then restore them after the dialog closes. + +### Why +On macOS, QAction shortcuts registered in the menu bar are converted to NSMenuItem key equivalents. When a native file dialog (NSSavePanel/NSOpenPanel) is shown via `QFileDialog::exec()`, pressing Cmd+V triggers the QAction for "Paste" in Mogan's menu bar instead of the standard Cocoa `paste:` action in the dialog's text field. This prevents users from pasting filenames in the Save As dialog. + +The `ShortcutOverride` mechanism in `QTMWidget::event()` does not help here because the QTMWidget does not have focus while a modal dialog is open. + +Fixes: https://github.com/XmacsLabs/mogan/issues/2894 + +### How +In `qt_chooser_widget_rep::perform_dialog()` in `src/Plugins/Qt/qt_chooser_widget.cpp`: + +- Before `dialog->exec()`: on macOS (`Q_OS_MACOS`), iterate all `QAction`s in the active window, save their shortcuts, then clear them via `action->setShortcut(QKeySequence())` +- After `dialog->exec()` returns: restore all saved shortcuts + +This removes the NSMenuItem key equivalents while the dialog is open, allowing the native dialog to process standard editing shortcuts (Cmd+V/C/X/A) through the Cocoa responder chain. diff --git a/src/Plugins/Qt/qt_chooser_widget.cpp b/src/Plugins/Qt/qt_chooser_widget.cpp index 86b48e9276..977803cc87 100644 --- a/src/Plugins/Qt/qt_chooser_widget.cpp +++ b/src/Plugins/Qt/qt_chooser_widget.cpp @@ -24,9 +24,11 @@ #include "mupdf_picture.hpp" #endif +#include #include #include #include +#include #include #include @@ -344,6 +346,24 @@ qt_chooser_widget_rep::perform_dialog () { r.moveCenter (pos); dialog->setGeometry (r); +#ifdef Q_OS_MACOS + // On macOS, QAction shortcuts registered in the menu bar become NSMenuItem + // key equivalents. When a native file dialog is open, these key equivalents + // intercept standard editing shortcuts (Cmd+V, Cmd+C, Cmd+X, Cmd+A) before + // the dialog's text field can handle them. Temporarily clearing all QAction + // shortcuts allows the native dialog to process these keys normally. + QList> savedShortcuts; + QWidget* mainWin= QApplication::activeWindow (); + if (mainWin) { + for (QAction* action : mainWin->findChildren ()) { + if (!action->shortcut ().isEmpty ()) { + savedShortcuts.append (qMakePair (action, action->shortcut ())); + action->setShortcut (QKeySequence ()); + } + } + } +#endif + QStringList fileNames; file= "#f"; if (dialog->exec ()) { @@ -429,6 +449,13 @@ qt_chooser_widget_rep::perform_dialog () { delete dialog; +#ifdef Q_OS_MACOS + // Restore menu shortcuts after the native dialog is closed + for (const auto& pair : savedShortcuts) { + pair.first->setShortcut (pair.second); + } +#endif + cmd (); if (!is_nil (quit)) quit (); }