If you try to load two pages at the same time, on two separate QWebViews, you run into some very strange issues. I think this may be some annoying threading issue deep within the core, but I'm a noob and don't really know. Here is a quick test case that makes two QWebViews that each load digg.com. It logs the output in two QTextEdit windows. ------------- main.cpp ------------- #include <QtGui/QApplication> #include "logger.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); for (int i = 0; i < 2; ++i) { Logger *log = new Logger(); QWebView *web = new QWebView(); QObject::connect(web, SIGNAL(loadFinished(bool)), log, SLOT(onLoadFinished(bool))); web->load(QUrl("http://digg.com")); log->show(); } return a.exec(); } ------------ logger.h ------------ #ifndef LOGGER_H #define LOGGER_H #include <QTextEdit> #include <QWebView> #include <QWebFrame> class Logger : public QTextEdit { Q_OBJECT public: Logger(QWidget *p = 0) : QTextEdit(p) {} public slots: void onLoadFinished(bool ok) { if (ok) this->append("Load successful"); else this->append("Load failed"); QString html = ((QWebView*)sender())->page()->mainFrame()->toHtml(); int htmlSize = (html.isNull() || html.isEmpty()) ? 0 : html.length(); this->append(QString("Html size: %1").arg(htmlSize)); } }; #endif // LOGGER_H -- -- Expected Output: -- *Log 1 and 2* Load successful Html size: 92735 -- Actual Output: -- *Log 1* Load successful Html size: 92735 *Log 2* Load successful Html size: 2057 Load successful Html size: 92571 Load successful Html size: 92735 - Other notes: This appears to work as expected for google.com (your results may vary), but digg.com and other websites will fail. Not sure what the common factor is.
Which Qt version are you using?
4.6.2
Okay, this is an obvious issue with the JavaScript core. With JS disabled, the expected results are obtained. However, permanently disabling JS is an ugly hack that is not an option for many applications. This should perhaps be the #1 issue to fix for QtWebKit in my opinion. When two separate QWebViews can't even load a page and parse JavaScript simultaneously without disrupting each other in subtle ways, how can we expect tabbed browsers to operate correctly?
I can reproduce on Linux against trunk (r58872).
digg.com creates several iframes. Every time a frame has loaded, this is reported to FrameLoaderClientQt. And FrameLoaderClientQt::postProgressFinishedNotification() decides to emit loadFinished() for more than one frame. Modifying the testcase to connect to view->page()->mainFrame()'s loadFinished() signal reveals that it's the "Load successful, Html size: 2057" that comes from the mainframe of one view, the two other signals are due to other frames.
Not saying your hypothesis is wrong, in fact it makes a lot of sense, but just wondering how come one of the Loggers only emits 1 load while the other does many? Theoretically they are loading the same page...?
Also I think the HTML size 2057 is === to an empty string (iirc the MAX_STRING "buffer" is like 2058 or something?), because when I try to print it, it's blank.
Created attachment 56371 [details] Gtk testcase Similar testcase for Gtk. Output: 0x960a808 load status changed: 0 0x960a8e0 load status changed: 0 0x960a808 load status changed: 1 0x960a8e0 load status changed: 1 0x960a8e0 load status changed: 2 load_finished_cb(0x960a8e0, 0x9625b80) 0x960a808 load status changed: 3 0x960a8e0 load status changed: 3 load_finished_cb(0x960a8e0, 0x963c2f0) 0x960a808 load status changed: 2 load_finished_cb(0x960a808, 0x9621f80) So load-finished is emitted twice for one of the views. And the load-status change order seems fishy for one of the views too (WEBKIT_LOAD_FINISHED before WEBKIT_LOAD_FIRST_VISUALLY_NON_EMPTY_LAYOUT). With only one view this is the output (which is fine): 0x9bdb808 load status changed: 0 0x9bdb808 load status changed: 1 0x9bdb808 load status changed: 3 0x9bdb808 load status changed: 2 load_finished_cb(0x9bdb808, 0x9bf3380) Either Qt and Gtk are both doing something wrong, or the bug is deeper in WebCore. For sure, WebCore/loader/ProgressTracker.cpp is calling finalProgressComplete() more than once; this is what causes the multiple loadFinished() / load-finished signals. ProgressTracker is associated with a Page, not Frame, so that seems wrong. For what it's worth, it looks like the page is eventually loading correctly in both views, it's just the progress notification that's incorrect. Could it be that digg lazily creates some frames/content from JS, and the WebKit loader can't anticipate this? Who wants to try it with a WebView on Mac to see how many times a WebViewProgressFinishedNotification is posted?
I am pretty sure this is expected behavior. A scripted webpage can finish loading, then fire a timeout that causes more content to be required to be loaded, and then finish loading that, finishing a second time. Pages that dynamically loads content is going to finish loading several times.
(In reply to comment #9) > I am pretty sure this is expected behavior. A scripted webpage can finish loading, then fire a timeout that causes more content to be required to be loaded, and then finish loading that, finishing a second time. > > Pages that dynamically loads content is going to finish loading several times. loadFinished should only be emitted at the end of provisional load, there should be no signal after the initial load. Unless if a new subframe is created, which produces the behavior explained in comment #5.