macOS: Send a filename QFileOpenEvent if invalid URL, deprecate openFile

When the string we receive from the system doesn't parse into a valid
QUrl (because QUrl requires a valid IDN), then we shouldn't send the
QFileOpenEvent based on that invalid QUrl, but instead pass the string
through as the file name.

The file name is anyway not guaranteed to be path to a file that can be
opened, as per the existence of QFileOpenEvent::open and the repective
documentation stating:
"some files cannot be opened by name, but require specific information
stored in this event."

However, that API is not useful at all, the implementation just opens
the passed-in QFile, using the stored file name. There's no way
to override this, and QFileOpenEvent is a locked class with all data
stored inline. So we can't even redirect to a platform-implementation.
Deprecate that function. Applications should interpret the string
returned by file(), which might not be a path to a local file.

Fixes: QTBUG-98384
Change-Id: Iff75489de9d7c5fc034f44c0bda4963b2efb1925
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
Volker Hilsheimer 2023-02-28 15:28:20 +01:00
parent ac6c7aa12f
commit 76c63936d3
3 changed files with 20 additions and 3 deletions

View File

@ -3625,19 +3625,23 @@ Q_IMPL_EVENT_COMMON(QFileOpenEvent)
/*!
\fn QString QFileOpenEvent::file() const
Returns the file that is being opened.
Returns the name of the file that the application should open.
This is not guaranteed to be the path to a local file.
*/
/*!
\fn QUrl QFileOpenEvent::url() const
Returns the url that is being opened.
Returns the url that the application should open.
\since 4.6
*/
#if QT_DEPRECATED_SINCE(6, 6)
/*!
\fn bool QFileOpenEvent::openFile(QFile &file, QIODevice::OpenMode flags) const
\deprecated [6.6] interpret the string returned by file()
Opens a QFile on the \a file referenced by this event in the mode specified
by \a flags. Returns \c true if successful; otherwise returns \c false.
@ -3652,6 +3656,7 @@ bool QFileOpenEvent::openFile(QFile &file, QIODevice::OpenMode flags) const
file.setFileName(m_file);
return file.open(flags);
}
#endif
#ifndef QT_NO_TOOLBAR
/*!

View File

@ -852,7 +852,10 @@ public:
inline QString file() const { return m_file; }
QUrl url() const { return m_url; }
#if QT_DEPRECATED_SINCE(6, 6)
QT_DEPRECATED_VERSION_X_6_6("Interpret the string returned by file()")
bool openFile(QFile &file, QIODevice::OpenMode flags) const;
#endif
private:
QString m_file;
QUrl m_url;

View File

@ -318,7 +318,16 @@ QT_USE_NAMESPACE
{
Q_UNUSED(replyEvent);
NSString *urlString = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
QWindowSystemInterface::handleFileOpenEvent(QUrl(QString::fromNSString(urlString)));
// The string we get from the requesting application might not necessarily meet
// QUrl's requirement for a IDN-compliant host. So if we can't parse into a QUrl,
// then we pass the string on to the application as the name of a file (and
// QFileOpenEvent::file is not guaranteed to be the path to a local, open'able
// file anyway).
const QString qurlString = QString::fromNSString(urlString);
if (const QUrl url(qurlString); url.isValid())
QWindowSystemInterface::handleFileOpenEvent(url);
else
QWindowSystemInterface::handleFileOpenEvent(qurlString);
}
@end