PDA

View Full Version : window freeze



brcontainer
16th May 2013, 18:35
What would be the best way to prevent a window freeze the other windows?

I tried to move my QMainWindow to a thread (QMainWindow::moveToThread), but this is not possible for the widgets can not be moved.

I'd like to open a new window in a separate process.

The reason is that if this new page has a script to freeze the window he ends up freezing all other windows.


class myWebPage : public QWebPage {
QWebPage * createWindow(QWebPage::WebWindowType type) {
Q_UNUSED(type);
QMainWindow *wx = new mBROWSERQT(NULL,true);
QWebView *wv = wx->findChild<QWebView*>("mybrowsertest");

wx->showNormal();
return wv->page();
}
};

...

ui->mybrowsertest->setPage(new myWebPage());

wysota
17th May 2013, 06:35
JavaScript inside a webview shouldn't freeze anything. You can subclass QWebPage and reimplement shouldInterruptJavaScript() if you want however this is not exactly what you want.

brcontainer
17th May 2013, 11:39
JavaScript inside a webview shouldn't freeze anything. You can subclass QWebPage and reimplement shouldInterruptJavaScript() if you want however this is not exactly what you want.

thanks for the reply.

But not only is the javascript that froze the windows,
there are ways to freeze up window with PHP/.net/jsp.

Is there any way I can pass variables and commands a QWebView in a program to another QWebView in another program?

wysota
17th May 2013, 13:02
there are ways to freeze up window with PHP/.net/jsp.
Those languages run on server side and not on the client. I don't see how this relates to your problem.


Is there any way I can pass variables and commands a QWebView in a program to another QWebView in another program?
You can do anything you want if you implement it. There are several IPC methods available in computer world. If you teach both programs to use them then you can pass information between different programs.

brcontainer
17th May 2013, 13:38
Thanks again for your quick response.


You can do anything you want if you implement it. There are several IPC methods available in computer world. If you teach both programs to use them then you can pass information between different programs.

I had read about IPC, but I'm having trouble reimplement createWindow.

An example of this is that I also tried Qfuture::run", however when passing the QWebpage for createWindow he hangs anyway. I believe I have to reimplement createWindow with Qfuture.

How could I reimplement createWindow (or QWebPage, QWebFrame, etc.) with functions like Thread (To do something like the thread) ?

wysota
17th May 2013, 15:23
I have no idea what you are trying to do. Why do you wish to reimplement createWindow()?

brcontainer
17th May 2013, 15:40
Thanks for the help and the quick response.


I have no idea what you are trying to do. Why do you wish to reimplement createWindow()?

Every time I click an anchor with target="_blank" (or run the window.open) the QWebPage performing QWebPage::createWindow.

The QWebPage::createWindow need to get the new QWebPage who will receive the target="_blank" (or target="name").

But to send to send a page that can freeze, it also ends up freezing the window PARENT and other windows created by QWebPage::createWindow.

I need to isolate the QWebPage but without affecting the functionality of the targets, window.opener and parent.window.

The only browser I've seen that works this way is the Google Chrome, if one tab has a Javascript that cause freezing, only the tab (or window) freezes, the other tabs work normally (the other tabs and windows do not freeze).

wysota
17th May 2013, 15:51
createWindow() returns a QWebView and not QWebPage.

Chrome does out-of-process handling of web pages thus if one page locks the whole process, other pages can continue because they have their own processes.

brcontainer
17th May 2013, 16:03
Thanks again for the quick response.


createWindow() returns a QWebView and not QWebPage.
both QWebVieW as Qwebpage has createWindow ( http://qt-project.org/doc/qt-4.8/qwebpage.html#protected-functions )

Example:

class myWebPage : public QWebPage {
protected:
virtual QString userAgentForUrl(const QUrl & url) const {
Q_UNUSED(url);
return UA;
}

QWebPage * createWindow(QWebPage::WebWindowType type) {
return new QWebPage;
}
};


Chrome does out-of-process handling of web pages thus if one page locks the whole process, other pages can continue because they have their own processes.
I know that, but I just used it as an example for you to understand. I wonder if it has something to do with Qt?

Could you help me with this? Thanks

wysota
17th May 2013, 23:52
If you state your problem clearly then maybe someone can help. As I said, JavaScript alone will not freeze your browser as it is periodically interrupted so that the browser can process its events. When QtWebKit detects a long running script, it will pop up a window asking whether you want to abort the script or not.

brcontainer
18th May 2013, 03:36
If you state your problem clearly then maybe someone can help. As I said, JavaScript alone will not freeze your browser as it is periodically interrupted so that the browser can process its events. When QtWebKit detects a long running script, it will pop up a window asking whether you want to abort the script or not.

test my app (open-source QT5):
http://www.mediafire.com/download.php?85zm06bvwv9lyow

Note that clicking on anchor test Freeze all application windows freeze.

I need the window open for anchor "test Freeze" freezes and that the other windows continue to work normally (without freezing).

I wonder if you could help me?
Thanks.

wysota
18th May 2013, 08:26
https://bugs.webkit.org/show_bug.cgi?id=79040

brcontainer
18th May 2013, 13:36
https://bugs.webkit.org/show_bug.cgi?id=79040

Hello @wysota
I appreciate your attempt to help me, but it does have to do with my question.

And I'm not the problem JavaScript engine, I just want to separate the "QWebView" into something like multi-processes (eg. QFuture, QThread, etc.).

I'll try to be more simple and clear in the question:

How to separate the QWebView (or QwebPage, QWebFrame, etc.) into something like multi-processes (eg. QFuture, QThread, etc.)?

wysota
18th May 2013, 15:15
And I'm not the problem JavaScript engine, I just want to separate the "QWebView" into something like multi-processes (eg. QFuture, QThread, etc.).

QFuture and QThread have nothing to do with multi-processing. If you want multiprocessing then you need to implement a master process that will act as a container for all the pages and you need to implement the slave that will let itself be embedded into the master process. There is nothing in Qt that can help you with that directly. It is not something that you can do in 10 minutes. If you want, have a look at Chromium sources.

Edit: here is something that might help you: http://blog.chromium.org/2008/09/multi-process-architecture.html

brcontainer
18th May 2013, 18:30
QFuture and QThread have nothing to do with multi-processing. If you want multiprocessing then you need to implement a master process that will act as a container for all the pages and you need to implement the slave that will let itself be embedded into the master process. There is nothing in Qt that can help you with that directly. It is not something that you can do in 10 minutes. If you want, have a look at Chromium sources.

I could use QFuture with QWebPage::acceptNavigationRequest, the problem is that I want to do this with QWebPage::createWindow, but I do not know how to "rewrite" the QWebPage::createWindow to work with QFuture.

See what I got:

class myWebPage : public QWebPage
{
QWebPage *p;
void Test(const QUrl & url){
QWebView *p = new QWebView;
p->show();
p->setUrl(url);
}

bool acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, NavigationType type) {
QUrl url = request.url();
if(parentFrame==false){
firstFrame = frame;
parentFrame = true;
} else {
if(frame != firstFrame){
QtConcurrent::run(this,&myWebPage::Teste,url);
}
}
return QWebPage::acceptNavigationRequest(frame,request,ty pe);
}
};

This code works with target="" but does not work with window.open, so I need to understand how to rewrite the QWebPage::createWindow

Could you help me with this?

wysota
18th May 2013, 21:57
I could use QFuture with QWebPage::acceptNavigationRequest, the problem is that I want to do this with QWebPage::createWindow, but I do not know how to "rewrite" the QWebPage::createWindow to work with QFuture.
It won't work because all GUI-related work has to be done in the same thread. Thus QWebPage and its related QWebView have to live in the same thread and QWebView and all the other webviews have to live in the same thread. Thus all pages and all views have to live in the same thread. Hence freezing one will freeze them all. Multiprocessing is the only possible solution here and as I already said this can't be done by reimplementing one or two virtual methods here and there.

I'm afraid fixing the bug I mentioned and which you said did not relate to your problem is your only possible solution now short of reimplementing Chromium :)

brcontainer
18th May 2013, 22:22
I thought of two things

1 - if I'm not mistaken some modern platforms have "Dbus", there is something for Windows (or better crossplatform)?
2 - Is there any project "Chromium+QT" that does not require the "cygwin"?

Thanks.

wysota
18th May 2013, 22:32
1 - if I'm not mistaken some modern platforms have "Dbus", there is something for Windows (or better crossplatform)?
I don't see how that's helpful to you. There are multiple IPC mechanisms that you can use such as local sockets or shared memory and they suit the situation much better because d-bus doesn't provide any security and I doubt you'd want someone to tamper with your browser slaves.


2 - Is there any project "Chromium+QT" that does not require the "cygwin"?

I don't think chromium requires cygwin. Qt has nothing to do with this since Chromium is not based on Qt.

brcontainer
18th May 2013, 23:21
I don't see how that's helpful to you. There are multiple IPC mechanisms that you can use such as local sockets or shared memory and they suit the situation much better because d-bus doesn't provide any security and I doubt you'd want someone to tamper with your browser slaves.
sorry my english is that sometimes fails, I meant something like dbus.

How could I use Socket or SharedMemory with QWebPage::createWindow?



I don't think chromium requires cygwin. Qt has nothing to do with this since Chromium is not based on Qt.
You're right, cygwin is optional, failure was in my reading. About "QT + Chromium", what I mean is if there is some project ported to QT that use Chromium (but so googled there is nothing like that).


Unfortunately I am losing hope of creating an efficient application.
Thanks.

wysota
18th May 2013, 23:42
How could I use Socket or SharedMemory with QWebPage::createWindow?
You couldn't. And if you keep going back to that method, you won't be making any progress. createWindow itself will not help you prevent freezing web browser windows.


what I mean is if there is some project ported to QT that use Chromium (but so googled there is nothing like that).
Using Chromium itself doesn't make much sense, it is probably too bloated for you anyway. You could probably make some use of Chromium Embedded Framework (https://code.google.com/p/chromiumembedded/) but that gives you a complete browser environment that you have no influence on.


Unfortunately I am losing hope of creating an efficient application.
As I said, this task can't be done in 10 minutes of coding.

Here is what Chromium does more or less:
http://www.chromium.org/developers/design-documents/multi-process-architecture

You can probably come up with a solution that implements a similar architecture but again -- not in 10 minutes of coding.

Here is a general description of IPC they use:

http://www.chromium.org/developers/design-documents/inter-process-communication

brcontainer
14th September 2013, 19:14
Great news for developers QT, we will soon have the Qt WebEngine (QT + blink):

http://blog.qt.digia.com/blog/2013/09/12/introducing-the-qt-webengine/

:)