Fixed deadlocks when adding a new tab. The WebView needs to be created int the

app thread indeed, but the app thread may already be blocking on the window lock,
we we cannot wait for a synchronous reply from the app in the window thread.
Refactored the tab creation and reused it in the LauncherWindow constructor.
Added the ability to load a URL in the new tab right away.


git-svn-id: http://svn.haiku-os.org/webpositive/webkit/trunk@160 94f232f2-1747-11df-bad5-a5bfde151594
This commit is contained in:
stippi
2010-02-21 13:13:03 +00:00
parent 14c76a6546
commit 56bdbcc74e
4 changed files with 46 additions and 31 deletions
+18 -4
View File
@@ -165,10 +165,13 @@ void LauncherApp::MessageReceived(BMessage* message)
newWindow(url); newWindow(url);
break; break;
} }
case CREATE_WEBVIEW: { case NEW_TAB: {
BMessage reply; LauncherWindow* window;
reply.AddPointer("view", new WebView("web_view")); if (message->FindPointer("window", reinterpret_cast<void**>(&window)) != B_OK)
message->SendReply(&reply); break;
BString url;
message->FindString("url", &url);
newTab(window, url);
break; break;
} }
case WINDOW_OPENED: case WINDOW_OPENED:
@@ -276,6 +279,17 @@ void LauncherApp::newWindow(const BString& url)
window->currentWebView()->loadRequest(url.String()); window->currentWebView()->loadRequest(url.String());
} }
void LauncherApp::newTab(LauncherWindow* window, const BString& url)
{
if (!window->Lock())
return;
window->newTab();
window->Unlock();
if (url.Length())
window->currentWebView()->loadRequest(url.String());
}
// #pragma mark - // #pragma mark -
int main(int, char**) int main(int, char**)
+1 -4
View File
@@ -36,10 +36,6 @@ class BFile;
class DownloadWindow; class DownloadWindow;
class LauncherWindow; class LauncherWindow;
enum {
CREATE_WEBVIEW = 'crwb'
};
class LauncherApp : public BApplication { class LauncherApp : public BApplication {
public: public:
LauncherApp(); LauncherApp();
@@ -55,6 +51,7 @@ public:
private: private:
bool openSettingsFile(BFile& file, uint32 mode); bool openSettingsFile(BFile& file, uint32 mode);
void newWindow(const BString& url); void newWindow(const BString& url);
void newTab(LauncherWindow* window, const BString& url);
int m_windowCount; int m_windowCount;
BRect m_lastWindowFrame; BRect m_lastWindowFrame;
+24 -23
View File
@@ -77,7 +77,6 @@ enum {
TEXT_FIND_NEXT = 'fndn', TEXT_FIND_NEXT = 'fndn',
TEXT_FIND_PREVIOUS = 'fndp', TEXT_FIND_PREVIOUS = 'fndp',
NEW_TAB = 'ntab',
CLOSE_TAB = 'ctab' CLOSE_TAB = 'ctab'
}; };
@@ -97,11 +96,7 @@ LauncherWindow::LauncherWindow(BRect frame, const BMessenger& downloadListener,
B_AUTO_UPDATE_SIZE_LIMITS | B_ASYNCHRONOUS_CONTROLS) B_AUTO_UPDATE_SIZE_LIMITS | B_ASYNCHRONOUS_CONTROLS)
{ {
m_tabView = new WebTabView("tabview", BMessenger(this)); m_tabView = new WebTabView("tabview", BMessenger(this));
WebView* webView = new WebView("web_view");
m_tabView->AddTab(webView);
m_tabView->TabAt(0L)->SetLabel("New Tab");
m_tabView->setTarget(BMessenger(this)); m_tabView->setTarget(BMessenger(this));
setCurrentWebView(webView);
if (toolbarPolicy == HaveToolbar) { if (toolbarPolicy == HaveToolbar) {
// Menu // Menu
@@ -112,9 +107,12 @@ LauncherWindow::LauncherWindow(BRect frame, const BMessenger& downloadListener,
BMenuItem* newItem = new BMenuItem("New window", newWindowMessage, 'N'); BMenuItem* newItem = new BMenuItem("New window", newWindowMessage, 'N');
menu->AddItem(newItem); menu->AddItem(newItem);
newItem->SetTarget(be_app); newItem->SetTarget(be_app);
newItem = new BMenuItem("New tab", new BMessage(NEW_TAB), 'T'); BMessage* newTabMessage = new BMessage(NEW_TAB);
newTabMessage->AddString("url", "");
newTabMessage->AddPointer("window", this);
newItem = new BMenuItem("New tab", newTabMessage, 'T');
menu->AddItem(newItem); menu->AddItem(newItem);
newItem->SetTarget(this); newItem->SetTarget(be_app);
menu->AddSeparatorItem(); menu->AddSeparatorItem();
menu->AddItem(new BMenuItem("Close window", new BMessage(B_QUIT_REQUESTED), 'W')); menu->AddItem(new BMenuItem("Close window", new BMessage(B_QUIT_REQUESTED), 'W'));
menu->AddItem(new BMenuItem("Close tab", new BMessage(CLOSE_TAB), 'W', B_SHIFT_KEY)); menu->AddItem(new BMenuItem("Close tab", new BMessage(CLOSE_TAB), 'W', B_SHIFT_KEY));
@@ -220,11 +218,15 @@ LauncherWindow::LauncherWindow(BRect frame, const BMessenger& downloadListener,
m_statusText = 0; m_statusText = 0;
m_loadingProgressBar = 0; m_loadingProgressBar = 0;
WebView* webView = new WebView("web_view");
setCurrentWebView(webView);
AddChild(BGroupLayoutBuilder(B_VERTICAL, 7) AddChild(BGroupLayoutBuilder(B_VERTICAL, 7)
.Add(currentWebView()) .Add(currentWebView())
); );
} }
newTab();
currentWebView()->webPage()->SetDownloadListener(downloadListener); currentWebView()->webPage()->SetDownloadListener(downloadListener);
m_findGroup->SetVisible(false); m_findGroup->SetVisible(false);
@@ -234,8 +236,6 @@ LauncherWindow::LauncherWindow(BRect frame, const BMessenger& downloadListener,
AddShortcut('F', B_COMMAND_KEY, new BMessage(TEXT_SHOW_FIND_GROUP)); AddShortcut('F', B_COMMAND_KEY, new BMessage(TEXT_SHOW_FIND_GROUP));
AddShortcut('F', B_COMMAND_KEY | B_SHIFT_KEY, new BMessage(TEXT_HIDE_FIND_GROUP)); AddShortcut('F', B_COMMAND_KEY | B_SHIFT_KEY, new BMessage(TEXT_HIDE_FIND_GROUP));
navigationCapabilitiesChanged(false, false, false, currentWebView());
be_app->PostMessage(WINDOW_OPENED); be_app->PostMessage(WINDOW_OPENED);
} }
@@ -333,21 +333,9 @@ void LauncherWindow::MessageReceived(BMessage* message)
be_app->PostMessage(message); be_app->PostMessage(message);
break; break;
case NEW_TAB: {
BMessage reply;
be_app_messenger.SendMessage(CREATE_WEBVIEW, &reply);
WebView *view = NULL;
reply.FindPointer("view", reinterpret_cast<void **>(&view));
m_tabView->AddTab(view);
m_tabView->TabAt(m_tabView->CountTabs() - 1)->SetLabel("New tab");
m_tabView->Select(m_tabView->CountTabs() - 1);
navigationCapabilitiesChanged(false, false, false, currentWebView());
m_url->MakeFocus(true);
break;
}
case CLOSE_TAB: { case CLOSE_TAB: {
if (m_tabView->CountTabs() > 0) printf("CLOSE_TAB\n");
if (m_tabView->CountTabs() > 1)
delete m_tabView->RemoveTab(m_tabView->FocusTab()); delete m_tabView->RemoveTab(m_tabView->FocusTab());
break; break;
} }
@@ -418,6 +406,19 @@ void LauncherWindow::MenusBeginning()
history->Unlock(); history->Unlock();
} }
void LauncherWindow::newTab()
{
// Executed in app thread (new BWebPage needs to be created in app thread).
WebView* webView = new WebView("web_view");
m_tabView->AddTab(webView);
m_tabView->TabAt(m_tabView->CountTabs() - 1)->SetLabel("New tab");
m_tabView->Select(m_tabView->CountTabs() - 1);
setCurrentWebView(webView);
navigationCapabilitiesChanged(false, false, false, webView);
if (m_url)
m_url->MakeFocus(true);
}
// #pragma mark - Notification API // #pragma mark - Notification API
void LauncherWindow::navigationRequested(const BString& url, WebView* view) void LauncherWindow::navigationRequested(const BString& url, WebView* view)
+3
View File
@@ -51,6 +51,7 @@ enum ToolbarPolicy {
enum { enum {
NEW_WINDOW = 'nwnd', NEW_WINDOW = 'nwnd',
NEW_TAB = 'ntab',
WINDOW_OPENED = 'wndo', WINDOW_OPENED = 'wndo',
WINDOW_CLOSED = 'wndc', WINDOW_CLOSED = 'wndc',
SHOW_DOWNLOAD_WINDOW = 'sdwd' SHOW_DOWNLOAD_WINDOW = 'sdwd'
@@ -66,6 +67,8 @@ public:
virtual bool QuitRequested(); virtual bool QuitRequested();
virtual void MenusBeginning(); virtual void MenusBeginning();
void newTab();
private: private:
// WebPage notification API implementations // WebPage notification API implementations
virtual void navigationRequested(const BString& url, WebView* view); virtual void navigationRequested(const BString& url, WebView* view);