On Thu, Sep 10, 2026 at 12:47:53PM -0700, Daniel Gafni wrote:
> Is this a bug, or a feature that was removed in the new release?
> 
> I am happy to provide more information and to submit a ticket if I could
> get an account for the bug tracker.

Diagnosed as a consequence of switch from Qt5 -> Qt6 on mac build and
reportedly fixable for Qt >= 6.5 (can't test here).

The issue is unf untrivial so unless Koji or Stephan want to engage in review
and testing of the attached not much can be done.

Pavel
"Paste as PDF" missing on macOS since LyX 2.5
=============================================

Report (Claude Opus 5)
----------------------
Reported on lyx-devel 2026-09-10 (msg226801): in LyX 2.5.2 on macOS 15.7 the 
"Choose a filename to save the pasted
graphic as" dialog offers only PNG and JPEG. In 2.4.5 it offers PDF, PNG and 
JPEG. The documentation still describes
pasting as PDF.

Status: regression, not an intentional removal.

Analysis
--------
The PDF flavor of the macOS pasteboard is not known to Qt. LyX makes it visible 
by registering its own converter,
QMacPasteboardMimeGraphics in src/frontends/qt/GuiApplication.cpp, which maps 
the UTI com.adobe.pdf to the mime type
application/pdf.

That class was excluded from Qt6 builds in a9b0f5faae (2021-03-26, "Cmake build 
with qt6 on MAC", patch by
P. De Visschere), because Qt6 had dropped QMacPasteboardMime and the class no 
longer compiled:

    src/frontends/qt/GuiApplication.cpp:801
    #if defined(Q_OS_MAC) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
    // QMacPasteboardMimeGraphics can only be compiled on Mac.
    class QMacPasteboardMimeGraphics : public QMacPasteboardMime

Without the converter, GuiClipboard::hasGraphicsContents(PdfGraphicsType) 
reduces to
cache_.hasFormat("application/pdf"), which is never true under Qt6. 
PdfGraphicsType therefore never enters the list of
offered types in GuiClipboard::getPastedGraphicsFileName(), leaving PNG and 
JPEG.

The macOS binaries of 2.4.x are Qt5 builds, those of 2.5.x are Qt6 builds, 
which matches the reported 2.4.5 vs 2.5.2
difference. The same code is in master and in 2.5.x.

Side effect: LinkBack is affected as well. Detection goes through 
isLinkBackDataInPasteboard(), which queries
NSPasteboard directly and still works, but GuiClipboard::getAsGraphics() then 
reads cache_.data(pdfMimeType()) for
LinkBackGraphicsType, which is empty under Qt6, so the pasted file ends up 
empty.

Windows is not affected: the corresponding QWindowsMimeMetafile converter was 
ported to the Qt6 API in the same file.

Fix
---
Qt 6.5 reintroduced the API as the public class QUtiMimeConverter, with the 
same four virtual functions under new names
(utiForMime / mimeForUti instead of flavorFor / mimeFor, all const). The patch 
below selects the base class by Qt
version, following the scheme already used for the Windows converter in the 
same file, and keeps the Qt5 implementation
unchanged. Qt 6.0 to 6.4 keep the current behaviour; only private headers 
expose the converter API there.

Two differences from the Qt5 implementation: convertorName() and canConvert() 
are dropped, since Qt6 has no such virtual
functions (canConvert() is now non-virtual and derived from the two mapping 
functions), and an empty data list is
handled explicitly instead of calling data.first() unconditionally.

The patch applies to master and, with offsets, to 2.5.x. It is compile-checked 
on Linux only, where all hunks are
inactive. Testing on a macOS build with Qt >= 6.5 is needed:

 - copy content as PDF (for example from Preview) and paste it into LyX: the 
file dialog should offer
   "PDF Files (*.pdf)" next to PNG and JPEG, and the written file should be a 
valid PDF;
 - paste from a LinkBack-capable application and check that the resulting file 
is not empty;
 - lyx -dbg action logs the utiForMime / mimeForUti calls.

diff --git a/src/frontends/qt/GuiApplication.cpp 
b/src/frontends/qt/GuiApplication.cpp
index e48087bba6..c4dc059074 100644
--- a/src/frontends/qt/GuiApplication.cpp
+++ b/src/frontends/qt/GuiApplication.cpp
@@ -156,8 +156,14 @@ using QWindowsApplication = 
QNativeInterface::Private::QWindowsApplication;
 #  include <objidl.h>
 #endif
 
-#if defined(Q_OS_MAC) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
-#include <QMacPasteboardMime>
+#if defined(Q_OS_MAC)
+#  if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
+#    include <QtGui/QUtiMimeConverter>
+#    define QMACMIME QUtiMimeConverter
+#  elif (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
+#    include <QMacPasteboardMime>
+#    define QMACMIME QMacPasteboardMime
+#  endif
 #endif // Q_OS_MAC
 
 #include <exception>
@@ -782,12 +788,50 @@ public:
 //
 ////////////////////////////////////////////////////////////////////////
 
-#if defined(Q_OS_MAC) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
-// QMacPasteboardMimeGraphics can only be compiled on Mac.
+#ifdef QMACMIME
+// QMacPasteboardMimeGraphics can only be compiled on Mac. It teaches Qt the
+// com.adobe.pdf UTI, which it does not know about: without this converter
+// the PDF flavor of the pasteboard is invisible to us, and neither "Paste as
+// PDF" nor LinkBack work at all.
 
-class QMacPasteboardMimeGraphics : public QMacPasteboardMime
+class QMacPasteboardMimeGraphics : public QMACMIME
 {
 public:
+#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
+       QString utiForMime(QString const & mime) const override
+       {
+               LYXERR(Debug::ACTION, "utiForMime " << mime);
+               if (mime == pdfMimeType())
+                       return QLatin1String("com.adobe.pdf");
+               return QString();
+       }
+
+       QString mimeForUti(QString const & uti) const override
+       {
+               LYXERR(Debug::ACTION, "mimeForUti " << uti);
+               if (uti == QLatin1String("com.adobe.pdf"))
+                       return pdfMimeType();
+               return QString();
+       }
+
+       QVariant convertToMime(QString const & /*mime*/,
+               QList<QByteArray> const & data, QString const & /*uti*/) const 
override
+       {
+               if (data.isEmpty())
+                       return QVariant();
+               if (data.count() > 1)
+                       qWarning("QMacPasteboardMimeGraphics: Cannot handle 
multiple member data");
+               return data.first();
+       }
+
+       QList<QByteArray> convertFromMime(QString const & /*mime*/,
+               QVariant const & data, QString const & /*uti*/) const override
+       {
+               QList<QByteArray> ret;
+               ret.append(data.toByteArray());
+               return ret;
+       }
+#else
        QMacPasteboardMimeGraphics()
                : QMacPasteboardMime(MIME_QT_CONVERTOR|MIME_ALL)
        {}
@@ -830,6 +874,7 @@ public:
                ret.append(data.toByteArray());
                return ret;
        }
+#endif
 };
 #endif
 
@@ -1090,7 +1135,7 @@ struct GuiApplication::Private
        /// Holds previous application state on Mac
        Qt::ApplicationState last_state_;
 
-#if defined(Q_OS_MAC) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
+#ifdef QMACMIME
        /// Linkback mime handler for macOS.
        QMacPasteboardMimeGraphics mac_pasteboard_mime_;
 #endif
-- 
lyx-devel mailing list
[email protected]
https://lists.lyx.org/mailman/listinfo/lyx-devel

Reply via email to