PDA

View Full Version : QWebEngine file chooser return value on cancel



RolandHughes
29th July 2015, 19:40
All,

Using QWebEngine under Linux. When the upload button is clicked on the Web page a file chooser dialog pops up as expected. It doesn't look like the other file choosers on the platform, so I assume the Chromium code is providing its own. Since I cannot get a console and we are locked at 5.4, I was wondering if anyone knew what the embedded chrome file chooser returns (if anything) when a cancel is pressed. Is there per chance a signal which gets fired out to my application? What does it send to the Web page?

The Webcontent developers have something which works on most platforms, except this one, but the lack of debug makes this a PITA. When we cancel out of the dialog the Web page gray screens out, since it is frameless and fullscreen, not much to see. It "acts like" the url is getting cleared, which may be a side effect/but with the file chooser, making the assumption it was being used for a local file load to the main browser when the cancel button is hit.

I'm going to turn on the frame and stuff so I can see if the url is really getting cleared, but knowing that won't really assist in a work around. At an application level I need to determine when the file chooser has been launched and when it was cancelled so I can save the current URL and reload it.

Thanks,

RolandHughes
30th July 2015, 01:32
This appears to be a bug in the file chooser used by QWebEngine. Chromium uses the standard system file selector and behaves as expected with the web content. The file chooser provided by QWebEngine is calling the watcher twice. First with a null and the second time with a valid empty object so the watcher does nothing. Removing the watcher completely causes the same grey/gray screen because the removal of the dialog causes something bad to happen to the actual page content, but not the url.

Have to do more debugging tomorrow after some sleep. Definitely a problem with this ported chromium code though.

anda_skoa
30th July 2015, 08:38
Maybe you can reimplement http://doc.qt.io/qt-5/qwebenginepage.html#chooseFiles and show your own file dialog?

Cheers,
_

RolandHughes
30th July 2015, 14:32
Maybe you can reimplement http://doc.qt.io/qt-5/qwebenginepage.html#chooseFiles and show your own file dialog?

Cheers,
_

Since I'm not a JSon or Angular coder it took a bit to diagnose, but, every other browser file chooser does not return on cancel. This one returns first a NULL, then an empty files[]. The "quick fix" is/was to work around the bogus return in the code. Yes, you are correct. The proper fix would be to use the OS provided file chooser like other applications on the platform. That said, I'm a bit tired of going to bed at midnight or later then being back to work by 8am. There is sooo much else to get done before the next release in just a few days.

RolandHughes
30th July 2015, 21:22
Maybe you can reimplement http://doc.qt.io/qt-5/qwebenginepage.html#chooseFiles and show your own file dialog?

Cheers,
_


Ultimately I had to derive a class and patch the bug (because we aren't building Qt from scratch). The fix appears below:



// Code stolen from QWebEnginePage so we could FIX it. Browser had real problems when a stringlist containing an
// empty list returned.
QStringList MyWebEnginePage::chooseFiles(FileSelectionMode mode, const QStringList &oldFiles, const QStringList &acceptedMimeTypes)
{
// FIXME: Should we expose this in QWebPage's API ? Right now it is very open and can contain a mix and match of file extensions $
// can work with) and mimetypes ranging from text/plain or images/* to application/vnd.openxmlformats-officedocument.spreadsheetm$
Q_UNUSED(acceptedMimeTypes);
QStringList ret;
QStringList emptyList;
switch (static_cast<WebContentsAdapterClient::FileChooserMode>(mode)) {
case WebContentsAdapterClient::OpenMultiple:
ret = QFileDialog::getOpenFileNames(view(), QString());
break;
// Chromium extension, not exposed as part of the public API for now.
case WebContentsAdapterClient::UploadFolder:
ret << QFileDialog::getExistingDirectory(view(), tr("Select folder to upload")) + QLatin1Char('/');
break;
case WebContentsAdapterClient::Save:
ret << QFileDialog::getSaveFileName(view(), QString(), (QStandardPaths::writableLocation(QStandardPaths:: DownloadLocation) + oldFiles.first()));
break;
default:
case WebContentsAdapterClient::Open:
ret << QFileDialog::getOpenFileName(view(), QString(), oldFiles.first());
break;
}

// Needed fix
if (ret.count() > 0)
{
if (ret[0].trimmed().length() > 0)
return ret;
}

return emptyList;

}


Returning a QStringList with an empty string in it hoses things up. Returning an empty list makes them work just fine. At some point I need to log a bug.

anda_skoa
31st July 2015, 08:35
Right, this is what I was suggeting :)

Cheers,
_