summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser')
-rwxr-xr-xchrome/browser/automation/automation_provider.cc6
-rw-r--r--chrome/browser/gtk/constrained_window_gtk.cc63
-rw-r--r--chrome/browser/gtk/constrained_window_gtk.h64
-rw-r--r--chrome/browser/login_prompt_gtk.cc312
-rw-r--r--chrome/browser/renderer_host/resource_dispatcher_host.cc5
-rw-r--r--chrome/browser/tab_contents/constrained_window.h33
-rw-r--r--chrome/browser/tab_contents/tab_contents.cc7
-rw-r--r--chrome/browser/tab_contents/tab_contents.h4
-rw-r--r--chrome/browser/tab_contents/tab_contents_view_gtk.cc52
-rw-r--r--chrome/browser/tab_contents/tab_contents_view_gtk.h14
-rw-r--r--chrome/browser/views/constrained_window_win.cc (renamed from chrome/browser/views/constrained_window_impl.cc)43
-rw-r--r--chrome/browser/views/constrained_window_win.h (renamed from chrome/browser/views/constrained_window_impl.h)22
12 files changed, 567 insertions, 58 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc
index 7cde178..bcfd7a5 100755
--- a/chrome/browser/automation/automation_provider.cc
+++ b/chrome/browser/automation/automation_provider.cc
@@ -60,10 +60,14 @@
#include "chrome/browser/character_encoding.h"
#include "chrome/browser/download/save_package.h"
#include "chrome/browser/external_tab_container.h"
-#include "chrome/browser/login_prompt.h"
#include "chrome/browser/printing/print_job.h"
#endif // defined(OS_WIN)
+#if defined(OS_WIN) || defined(OS_LINUX)
+// TODO(port): Port these to the mac.
+#include "chrome/browser/login_prompt.h"
+#endif
+
#if defined(OS_WIN)
#include "chrome/browser/views/bookmark_bar_view.h"
#include "views/widget/root_view.h"
diff --git a/chrome/browser/gtk/constrained_window_gtk.cc b/chrome/browser/gtk/constrained_window_gtk.cc
new file mode 100644
index 0000000..21b45b8
--- /dev/null
+++ b/chrome/browser/gtk/constrained_window_gtk.cc
@@ -0,0 +1,63 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/gtk/constrained_window_gtk.h"
+
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/tab_contents/tab_contents_view_gtk.h"
+#include "chrome/common/gtk_util.h"
+
+// The minimal border around the edge of the notification.
+const int kSmallPadding = 2;
+
+ConstrainedWindowGtk::ConstrainedWindowGtk(
+ TabContents* owner, ConstrainedWindowGtkDelegate* delegate)
+ : owner_(owner),
+ delegate_(delegate) {
+ DCHECK(owner);
+ DCHECK(delegate);
+ GtkWidget* dialog = delegate->GetWidgetRoot();
+
+ // Unlike other users of CreateBorderBin, we need a dedicated frame around
+ // our "window".
+ GtkWidget* ebox = gtk_event_box_new();
+ GtkWidget* frame = gtk_frame_new(NULL);
+ gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_OUT);
+ GtkWidget* alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
+ gtk_alignment_set_padding(GTK_ALIGNMENT(alignment),
+ kSmallPadding, kSmallPadding, kSmallPadding, kSmallPadding);
+ gtk_container_add(GTK_CONTAINER(alignment), dialog);
+ gtk_container_add(GTK_CONTAINER(frame), alignment);
+ gtk_container_add(GTK_CONTAINER(ebox), frame);
+ border_.Own(ebox);
+
+ gtk_widget_show_all(border_.get());
+
+ // We collaborate with TabContentsViewGtk and stick ourselves in the
+ // TabContentsViewGtk's floating container.
+ ContainingView()->AttachConstrainedWindow(this);
+}
+
+ConstrainedWindowGtk::~ConstrainedWindowGtk() {
+ border_.Destroy();
+}
+
+void ConstrainedWindowGtk::CloseConstrainedWindow() {
+ ContainingView()->RemoveConstrainedWindow(this);
+ delegate_->DeleteDelegate();
+ owner_->WillClose(this);
+
+ delete this;
+}
+
+TabContentsViewGtk* ConstrainedWindowGtk::ContainingView() {
+ return static_cast<TabContentsViewGtk*>(owner_->view());
+}
+
+// static
+ConstrainedWindow* ConstrainedWindow::CreateConstrainedDialog(
+ TabContents* parent,
+ ConstrainedWindowGtkDelegate* delegate) {
+ return new ConstrainedWindowGtk(parent, delegate);
+}
diff --git a/chrome/browser/gtk/constrained_window_gtk.h b/chrome/browser/gtk/constrained_window_gtk.h
new file mode 100644
index 0000000..91fa9ac
--- /dev/null
+++ b/chrome/browser/gtk/constrained_window_gtk.h
@@ -0,0 +1,64 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_GTK_CONSTRAINED_WINDOW_GTK_H_
+#define CHROME_BROWSER_GTK_CONSTRAINED_WINDOW_GTK_H_
+
+#include "chrome/browser/tab_contents/constrained_window.h"
+
+#include "base/basictypes.h"
+#include "chrome/common/owned_widget_gtk.h"
+
+class TabContents;
+class TabContentsViewGtk;
+typedef struct _GtkWidget GtkWidget;
+
+class ConstrainedWindowGtkDelegate {
+ public:
+ // Returns the widget that will be put in the constrained window's container.
+ virtual GtkWidget* GetWidgetRoot() = 0;
+
+ // Tells the delegate to either delete itself or set up a task to delete
+ // itself later.
+ virtual void DeleteDelegate() = 0;
+};
+
+// Constrained window implementation for the GTK port. Unlike the Win32 system,
+// ConstrainedWindowGtk doesn't draw draggable fake windows and instead just
+// centers the dialog. It is thus an order of magnitude simpler.
+class ConstrainedWindowGtk : public ConstrainedWindow {
+ public:
+ virtual ~ConstrainedWindowGtk();
+
+ // Overridden from ConstrainedWindow:
+ virtual void CloseConstrainedWindow();
+
+ // Returns the TabContents that constrains this Constrained Window.
+ TabContents* owner() const { return owner_; }
+
+ // Returns the toplevel widget that displays this "window".
+ GtkWidget* widget() { return border_.get(); }
+
+ // Returns the View that we collaborate with to position ourselves.
+ TabContentsViewGtk* ContainingView();
+
+ private:
+ friend class ConstrainedWindow;
+
+ ConstrainedWindowGtk(TabContents* owner,
+ ConstrainedWindowGtkDelegate* delegate);
+
+ // The TabContents that owns and constrains this ConstrainedWindow.
+ TabContents* owner_;
+
+ // The top level widget container that exports to our TabContentsViewGtk.
+ OwnedWidgetGtk border_;
+
+ // Delegate that provides the contents of this constrained window.
+ ConstrainedWindowGtkDelegate* delegate_;
+
+ DISALLOW_COPY_AND_ASSIGN(ConstrainedWindowGtk);
+};
+
+#endif // CHROME_BROWSER_GTK_CONSTRAINED_WINDOW_GTK_H_
diff --git a/chrome/browser/login_prompt_gtk.cc b/chrome/browser/login_prompt_gtk.cc
new file mode 100644
index 0000000..f52f2ee
--- /dev/null
+++ b/chrome/browser/login_prompt_gtk.cc
@@ -0,0 +1,312 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/login_prompt.h"
+
+#include <gtk/gtk.h>
+
+#include "app/l10n_util.h"
+#include "base/message_loop.h"
+#include "chrome/browser/gtk/constrained_window_gtk.h"
+#include "chrome/browser/password_manager/password_manager.h"
+#include "chrome/browser/tab_contents/navigation_controller.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/tab_contents/tab_util.h"
+#include "chrome/common/gtk_util.h"
+#include "chrome/common/notification_service.h"
+#include "grit/generated_resources.h"
+#include "net/url_request/url_request.h"
+
+using webkit_glue::PasswordForm;
+
+// ----------------------------------------------------------------------------
+// LoginHandlerGtk
+
+// This class simply forwards the authentication from the LoginView (on
+// the UI thread) to the URLRequest (on the I/O thread).
+// This class uses ref counting to ensure that it lives until all InvokeLaters
+// have been called.
+class LoginHandlerGtk : public LoginHandler,
+ public base::RefCountedThreadSafe<LoginHandlerGtk>,
+ public ConstrainedWindowGtkDelegate {
+ public:
+ LoginHandlerGtk(URLRequest* request, MessageLoop* ui_loop)
+ : handled_auth_(false),
+ dialog_(NULL),
+ ui_loop_(ui_loop),
+ request_(request),
+ request_loop_(MessageLoop::current()),
+ password_manager_(NULL) {
+ DCHECK(request_) << "LoginHandlerGtk constructed with NULL request";
+
+ AddRef(); // matched by ReleaseLater.
+ if (!tab_util::GetTabContentsID(request_, &render_process_host_id_,
+ &tab_contents_id_)) {
+ NOTREACHED();
+ }
+ }
+
+ virtual ~LoginHandlerGtk() {
+ root_.Destroy();
+ }
+
+ // LoginHandler:
+ virtual void BuildViewForPasswordManager(PasswordManager* manager,
+ std::wstring explanation) {
+ DCHECK(MessageLoop::current() == ui_loop_);
+
+ root_.Own(gtk_vbox_new(NULL, gtk_util::kContentAreaBorder));
+ gtk_box_pack_start(GTK_BOX(root_.get()),
+ gtk_label_new(WideToUTF8(explanation).c_str()),
+ FALSE, FALSE, 0);
+
+ username_entry_ = gtk_entry_new();
+ gtk_entry_set_activates_default(GTK_ENTRY(username_entry_), TRUE);
+
+ password_entry_ = gtk_entry_new();
+ gtk_entry_set_activates_default(GTK_ENTRY(password_entry_), TRUE);
+ gtk_entry_set_visibility(GTK_ENTRY(password_entry_), FALSE);
+
+ GtkWidget* table = gtk_util::CreateLabeledControlsGroup(
+ l10n_util::GetStringUTF8(IDS_LOGIN_DIALOG_USERNAME_FIELD).c_str(),
+ username_entry_,
+ l10n_util::GetStringUTF8(IDS_LOGIN_DIALOG_PASSWORD_FIELD).c_str(),
+ password_entry_,
+ NULL);
+ gtk_box_pack_start(GTK_BOX(root_.get()), table, FALSE, FALSE, 0);
+
+ GtkWidget* hbox = gtk_hbox_new(FALSE, 12);
+ gtk_box_pack_start(GTK_BOX(root_.get()), hbox, FALSE, FALSE, 0);
+
+ GtkWidget* ok = gtk_button_new_from_stock(GTK_STOCK_OK);
+ gtk_button_set_label(
+ GTK_BUTTON(ok),
+ l10n_util::GetStringUTF8(IDS_LOGIN_DIALOG_OK_BUTTON_LABEL).c_str());
+ g_signal_connect(ok, "clicked", G_CALLBACK(OnOKClicked), this);
+ gtk_box_pack_end(GTK_BOX(hbox), ok, FALSE, FALSE, 0);
+
+ GtkWidget* cancel = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
+ g_signal_connect(cancel, "clicked", G_CALLBACK(OnCancelClicked), this);
+ gtk_box_pack_end(GTK_BOX(hbox), cancel, FALSE, FALSE, 0);
+
+ // Scary thread safety note: This can potentially be called *after* SetAuth
+ // or CancelAuth (say, if the request was cancelled before the UI thread got
+ // control). However, that's OK since any UI interaction in those functions
+ // will occur via an InvokeLater on the UI thread, which is guaranteed
+ // to happen after this is called (since this was InvokeLater'd first).
+ dialog_ = GetTabContentsForLogin()->CreateConstrainedDialog(this);
+
+ // Now that we have attached ourself to the window, we can make our OK
+ // button the default action and mess with the focus.
+ GTK_WIDGET_SET_FLAGS(ok, GTK_CAN_DEFAULT);
+ gtk_widget_grab_default(ok);
+ gtk_widget_grab_focus(username_entry_);
+
+ SendNotifications();
+ }
+
+ virtual void SetPasswordForm(const webkit_glue::PasswordForm& form) {
+ password_form_ = form;
+ }
+
+ virtual void SetPasswordManager(PasswordManager* password_manager) {
+ password_manager_ = password_manager;
+ }
+
+ virtual TabContents* GetTabContentsForLogin() {
+ DCHECK(MessageLoop::current() == ui_loop_);
+
+ return tab_util::GetTabContentsByID(render_process_host_id_,
+ tab_contents_id_);
+ }
+
+ virtual void SetAuth(const std::wstring& username,
+ const std::wstring& password) {
+ if (WasAuthHandled(true))
+ return;
+
+ // Tell the password manager the credentials were submitted / accepted.
+ if (password_manager_) {
+ password_form_.username_value = username;
+ password_form_.password_value = password;
+ password_manager_->ProvisionallySavePassword(password_form_);
+ }
+
+ ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &LoginHandlerGtk::CloseContentsDeferred));
+ ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &LoginHandlerGtk::SendNotifications));
+ request_loop_->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &LoginHandlerGtk::SetAuthDeferred, username, password));
+ }
+
+ virtual void CancelAuth() {
+ if (WasAuthHandled(true))
+ return;
+
+ ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &LoginHandlerGtk::CloseContentsDeferred));
+ ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &LoginHandlerGtk::SendNotifications));
+ request_loop_->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &LoginHandlerGtk::CancelAuthDeferred));
+ }
+
+ virtual void OnRequestCancelled() {
+ DCHECK(MessageLoop::current() == request_loop_) <<
+ "Why is OnRequestCancelled called from the UI thread?";
+
+ // Reference is no longer valid.
+ request_ = NULL;
+
+ // Give up on auth if the request was cancelled.
+ CancelAuth();
+ }
+
+ // Overridden from ConstrainedWindowGtkDelegate:
+ virtual GtkWidget* GetWidgetRoot() {
+ return root_.get();
+ }
+
+ virtual void DeleteDelegate() {
+ if (!WasAuthHandled(true)) {
+ request_loop_->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &LoginHandlerGtk::CancelAuthDeferred));
+ SendNotifications();
+ }
+
+ // Delete this object once all InvokeLaters have been called.
+ request_loop_->ReleaseSoon(FROM_HERE, this);
+ }
+
+ private:
+ friend class LoginPrompt;
+
+ // Calls SetAuth from the request_loop.
+ void SetAuthDeferred(const std::wstring& username,
+ const std::wstring& password) {
+ DCHECK(MessageLoop::current() == request_loop_);
+
+ if (request_) {
+ request_->SetAuth(username, password);
+ ResetLoginHandlerForRequest(request_);
+ }
+ }
+
+ // Calls CancelAuth from the request_loop.
+ void CancelAuthDeferred() {
+ DCHECK(MessageLoop::current() == request_loop_);
+
+ if (request_) {
+ request_->CancelAuth();
+ // Verify that CancelAuth does destroy the request via our delegate.
+ DCHECK(request_ != NULL);
+ ResetLoginHandlerForRequest(request_);
+ }
+ }
+
+ // Closes the view_contents from the UI loop.
+ void CloseContentsDeferred() {
+ DCHECK(MessageLoop::current() == ui_loop_);
+
+ // The hosting ConstrainedWindow may have been freed.
+ if (dialog_)
+ dialog_->CloseConstrainedWindow();
+ }
+
+ // Returns whether authentication had been handled (SetAuth or CancelAuth).
+ // If |set_handled| is true, it will mark authentication as handled.
+ bool WasAuthHandled(bool set_handled) {
+ AutoLock lock(handled_auth_lock_);
+ bool was_handled = handled_auth_;
+ if (set_handled)
+ handled_auth_ = true;
+ return was_handled;
+ }
+
+ // Notify observers that authentication is needed or received. The automation
+ // proxy uses this for testing.
+ void SendNotifications() {
+ DCHECK(MessageLoop::current() == ui_loop_);
+
+ NotificationService* service = NotificationService::current();
+ TabContents* requesting_contents = GetTabContentsForLogin();
+ if (!requesting_contents)
+ return;
+
+ NavigationController* controller = &requesting_contents->controller();
+
+ if (!WasAuthHandled(false)) {
+ LoginNotificationDetails details(this);
+ service->Notify(NotificationType::AUTH_NEEDED,
+ Source<NavigationController>(controller),
+ Details<LoginNotificationDetails>(&details));
+ } else {
+ service->Notify(NotificationType::AUTH_SUPPLIED,
+ Source<NavigationController>(controller),
+ NotificationService::NoDetails());
+ }
+ }
+
+ static void OnOKClicked(GtkButton *button, LoginHandlerGtk* handler) {
+ DCHECK(MessageLoop::current() == handler->ui_loop_);
+
+ handler->SetAuth(
+ UTF8ToWide(gtk_entry_get_text(GTK_ENTRY(handler->username_entry_))),
+ UTF8ToWide(gtk_entry_get_text(GTK_ENTRY(handler->password_entry_))));
+ }
+
+ static void OnCancelClicked(GtkButton *button, LoginHandlerGtk* handler) {
+ DCHECK(MessageLoop::current() == handler->ui_loop_);
+ handler->CancelAuth();
+ }
+
+ // True if we've handled auth (SetAuth or CancelAuth has been called).
+ bool handled_auth_;
+ Lock handled_auth_lock_;
+
+ // The ConstrainedWindow that is hosting our LoginView.
+ // This should only be accessed on the ui_loop_.
+ ConstrainedWindow* dialog_;
+
+ // The MessageLoop of the thread that the ChromeViewContents lives in.
+ MessageLoop* ui_loop_;
+
+ // The request that wants login data.
+ // This should only be accessed on the request_loop_.
+ URLRequest* request_;
+
+ // The MessageLoop of the thread that the URLRequest lives in.
+ MessageLoop* request_loop_;
+
+ // The PasswordForm sent to the PasswordManager. This is so we can refer to it
+ // when later notifying the password manager if the credentials were accepted
+ // or rejected.
+ // This should only be accessed on the ui_loop_.
+ PasswordForm password_form_;
+
+ // Points to the password manager owned by the TabContents requesting auth.
+ // Can be null if the TabContents is not a TabContents.
+ // This should only be accessed on the ui_loop_.
+ PasswordManager* password_manager_;
+
+ // Cached from the URLRequest, in case it goes NULL on us.
+ int render_process_host_id_;
+ int tab_contents_id_;
+
+ // The GtkWidgets that form our visual hierarchy:
+ // The root container we pass to our parent.
+ OwnedWidgetGtk root_;
+
+ // GtkEntry widgets that the user types into.
+ GtkWidget* username_entry_;
+ GtkWidget* password_entry_;
+
+ DISALLOW_COPY_AND_ASSIGN(LoginHandlerGtk);
+};
+
+// static
+LoginHandler* LoginHandler::Create(URLRequest* request, MessageLoop* ui_loop) {
+ return new LoginHandlerGtk(request, ui_loop);
+}
diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.cc b/chrome/browser/renderer_host/resource_dispatcher_host.cc
index 32de83b..68e9a47 100644
--- a/chrome/browser/renderer_host/resource_dispatcher_host.cc
+++ b/chrome/browser/renderer_host/resource_dispatcher_host.cc
@@ -50,11 +50,14 @@
#if defined(OS_POSIX)
#include "chrome/common/temp_scaffolding_stubs.h"
#elif defined(OS_WIN)
-#include "chrome/browser/login_prompt.h"
#include "chrome/browser/renderer_host/render_view_host_delegate.h"
#include "chrome/browser/safe_browsing/safe_browsing_service.h"
#endif
+#if defined(OS_WIN) || defined(OS_LINUX)
+#include "chrome/browser/login_prompt.h"
+#endif
+
// Uncomment to enable logging of request traffic.
// #define LOG_RESOURCE_DISPATCHER_REQUESTS
diff --git a/chrome/browser/tab_contents/constrained_window.h b/chrome/browser/tab_contents/constrained_window.h
index 35679a5..437f820b 100644
--- a/chrome/browser/tab_contents/constrained_window.h
+++ b/chrome/browser/tab_contents/constrained_window.h
@@ -8,16 +8,22 @@
#include "chrome/common/page_transition_types.h"
#include "webkit/glue/window_open_disposition.h"
-class ConstrainedWindow;
+// The different platform specific subclasses use different delegates for their
+// dialogs.
+#if defined(OS_WIN)
namespace views {
-class View;
class WindowDelegate;
}
-namespace gfx {
-class Point;
-class Rect;
-}
-class GURL;
+typedef views::WindowDelegate ConstrainedWindowDelegate;
+#elif defined(OS_LINUX)
+class ConstrainedWindowGtkDelegate;
+typedef ConstrainedWindowGtkDelegate ConstrainedWindowDelegate;
+#elif defined(OS_MACOSX)
+// TODO(port): Change this type when Mac gets ConstrainedWindows. It is here
+// only to make things compile. There is no user or consumer of this type.
+typedef void* ConstrainedWindowDelegate;
+#endif
+
class TabContents;
///////////////////////////////////////////////////////////////////////////////
@@ -28,18 +34,15 @@ class TabContents;
//
class ConstrainedWindow {
public:
- // Create a Constrained Window that contains a views::View subclass
- // that provides the client area. Typical uses include the HTTP Basic Auth
- // prompt. The caller must provide an object implementing
- // views::WindowDelegate so that the Constrained Window can be properly
- // configured. If |initial_bounds| is empty, the dialog will be centered
- // within the constraining TabContents.
+ // Create a Constrained Window that contains a platform specific client
+ // area. Typical uses include the HTTP Basic Auth prompt. The caller must
+ // provide a delegate to describe the content area and to respond to events.
static ConstrainedWindow* CreateConstrainedDialog(
TabContents* owner,
- views::WindowDelegate* window_delegate);
+ ConstrainedWindowDelegate* delegate);
// Closes the Constrained Window.
virtual void CloseConstrainedWindow() = 0;
};
-#endif // #ifndef CHROME_TAB_CONTENTS_BROWSER_CONSTRAINED_WINDOW_H_
+#endif // CHROME_BROWSER_TAB_CONTENTS_CONSTRAINED_WINDOW_H_
diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc
index fe2ce0d..fe18cf2 100644
--- a/chrome/browser/tab_contents/tab_contents.cc
+++ b/chrome/browser/tab_contents/tab_contents.cc
@@ -735,12 +735,11 @@ void TabContents::CreateShortcut() {
render_view_host()->GetApplicationInfo(pending_install_.page_id);
}
-#if defined(OS_WIN)
+#if defined(OS_WIN) || defined(OS_LINUX)
ConstrainedWindow* TabContents::CreateConstrainedDialog(
- views::WindowDelegate* window_delegate) {
+ ConstrainedWindowDelegate* delegate) {
ConstrainedWindow* window =
- ConstrainedWindow::CreateConstrainedDialog(
- this, window_delegate);
+ ConstrainedWindow::CreateConstrainedDialog(this, delegate);
child_windows_.push_back(window);
return window;
}
diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h
index a94b6e1..04c61d5 100644
--- a/chrome/browser/tab_contents/tab_contents.h
+++ b/chrome/browser/tab_contents/tab_contents.h
@@ -323,14 +323,14 @@ class TabContents : public PageNavigator,
// Window management ---------------------------------------------------------
-#if defined(OS_WIN)
+#if defined(OS_WIN) || defined(OS_LINUX)
// Create a new window constrained to this TabContents' clip and visibility.
// The window is initialized by using the supplied delegate to obtain basic
// window characteristics, and the supplied view for the content. The window
// is sized according to the preferred size of the content_view, and centered
// within the contents.
ConstrainedWindow* CreateConstrainedDialog(
- views::WindowDelegate* window_delegate);
+ ConstrainedWindowDelegate* delegate);
#endif
// Adds a new tab or window with the given already-created contents
diff --git a/chrome/browser/tab_contents/tab_contents_view_gtk.cc b/chrome/browser/tab_contents/tab_contents_view_gtk.cc
index 3443b84..9b62e55 100644
--- a/chrome/browser/tab_contents/tab_contents_view_gtk.cc
+++ b/chrome/browser/tab_contents/tab_contents_view_gtk.cc
@@ -15,6 +15,7 @@
#include "chrome/browser/download/download_shelf.h"
#include "chrome/browser/gtk/blocked_popup_container_view_gtk.h"
#include "chrome/browser/gtk/browser_window_gtk.h"
+#include "chrome/browser/gtk/constrained_window_gtk.h"
#include "chrome/browser/gtk/gtk_floating_container.h"
#include "chrome/browser/gtk/sad_tab_gtk.h"
#include "chrome/browser/renderer_host/render_view_host.h"
@@ -139,6 +140,28 @@ void TabContentsViewGtk::RemoveBlockedPopupView(
popup_view_ = NULL;
}
+void TabContentsViewGtk::AttachConstrainedWindow(
+ ConstrainedWindowGtk* constrained_window) {
+ DCHECK(find(constrained_windows_.begin(), constrained_windows_.end(),
+ constrained_window) == constrained_windows_.end());
+
+ constrained_windows_.push_back(constrained_window);
+ gtk_floating_container_add_floating(GTK_FLOATING_CONTAINER(floating_.get()),
+ constrained_window->widget());
+}
+
+void TabContentsViewGtk::RemoveConstrainedWindow(
+ ConstrainedWindowGtk* constrained_window) {
+ std::vector<ConstrainedWindowGtk*>::iterator item =
+ find(constrained_windows_.begin(), constrained_windows_.end(),
+ constrained_window);
+ DCHECK(item != constrained_windows_.end());
+
+ gtk_container_remove(GTK_CONTAINER(floating_.get()),
+ constrained_window->widget());
+ constrained_windows_.erase(item);
+}
+
void TabContentsViewGtk::CreateView() {
// Windows uses this to do initialization, but we do all our initialization
// in the constructor.
@@ -384,4 +407,33 @@ void TabContentsViewGtk::OnSetFloatingPosition(
widget, "y", &value);
g_value_unset(&value);
}
+
+ // Place each ConstrainedWindow in the center of the view.
+ int half_view_width = std::max((allocation->x + allocation->width) / 2, 0);
+ int half_view_height = std::max((allocation->y + allocation->height) / 2, 0);
+ std::vector<ConstrainedWindowGtk*>::iterator it =
+ tab_contents_view->constrained_windows_.begin();
+ std::vector<ConstrainedWindowGtk*>::iterator end =
+ tab_contents_view->constrained_windows_.end();
+ for (; it != end; ++it) {
+ GtkWidget* widget = (*it)->widget();
+ DCHECK(widget->parent == tab_contents_view->floating_.get());
+
+ GtkRequisition requisition;
+ gtk_widget_size_request(widget, &requisition);
+
+ GValue value = { 0, };
+ g_value_init(&value, G_TYPE_INT);
+
+ int child_x = std::max(half_view_width - (requisition.width / 2), 0);
+ g_value_set_int(&value, child_x);
+ gtk_container_child_set_property(GTK_CONTAINER(floating_container),
+ widget, "x", &value);
+
+ int child_y = std::max(half_view_height - (requisition.height / 2), 0);
+ g_value_set_int(&value, child_y);
+ gtk_container_child_set_property(GTK_CONTAINER(floating_container),
+ widget, "y", &value);
+ g_value_unset(&value);
+ }
}
diff --git a/chrome/browser/tab_contents/tab_contents_view_gtk.h b/chrome/browser/tab_contents/tab_contents_view_gtk.h
index 8c85421..74de6dd 100644
--- a/chrome/browser/tab_contents/tab_contents_view_gtk.h
+++ b/chrome/browser/tab_contents/tab_contents_view_gtk.h
@@ -7,6 +7,8 @@
#include <gtk/gtk.h>
+#include <vector>
+
#include "base/scoped_ptr.h"
#include "chrome/browser/gtk/focus_store_gtk.h"
#include "chrome/browser/tab_contents/tab_contents_view.h"
@@ -15,6 +17,7 @@
#include "chrome/common/owned_widget_gtk.h"
class BlockedPopupContainerViewGtk;
+class ConstrainedWindowGtk;
class RenderViewContextMenuGtk;
class SadTabGtk;
typedef struct _GtkFloatingContainer GtkFloatingContainer;
@@ -33,6 +36,11 @@ class TabContentsViewGtk : public TabContentsView,
void AttachBlockedPopupView(BlockedPopupContainerViewGtk* popup_view);
void RemoveBlockedPopupView(BlockedPopupContainerViewGtk* popup_view);
+ // Unlike Windows, ConstrainedWindows need to collaborate with the
+ // TabContentsViewGtk to position the dialogs.
+ void AttachConstrainedWindow(ConstrainedWindowGtk* constrained_window);
+ void RemoveConstrainedWindow(ConstrainedWindowGtk* constrained_window);
+
// TabContentsView implementation --------------------------------------------
virtual void CreateView();
@@ -109,8 +117,14 @@ class TabContentsViewGtk : public TabContentsView,
FocusStoreGtk focus_store_;
+ // Our UI for controlling popups (or NULL if no popup windows have been
+ // opened). |popup_view_| is owned by the TabContents, not the view.
BlockedPopupContainerViewGtk* popup_view_;
+ // Each individual UI for constrained dialogs currently displayed. The
+ // objects in this vector are owned by the TabContents, not the view.
+ std::vector<ConstrainedWindowGtk*> constrained_windows_;
+
DISALLOW_COPY_AND_ASSIGN(TabContentsViewGtk);
};
diff --git a/chrome/browser/views/constrained_window_impl.cc b/chrome/browser/views/constrained_window_win.cc
index 75f3771..f641f6f 100644
--- a/chrome/browser/views/constrained_window_impl.cc
+++ b/chrome/browser/views/constrained_window_win.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/views/constrained_window_impl.h"
+#include "chrome/browser/views/constrained_window_win.h"
#include "app/gfx/canvas.h"
#include "app/gfx/font.h"
@@ -16,7 +16,6 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tab_contents/tab_contents_view.h"
#include "chrome/browser/toolbar_model.h"
#include "chrome/browser/views/frame/browser_view.h"
@@ -160,7 +159,7 @@ class ConstrainedWindowFrameView
: public views::NonClientFrameView,
public views::ButtonListener {
public:
- explicit ConstrainedWindowFrameView(ConstrainedWindowImpl* container);
+ explicit ConstrainedWindowFrameView(ConstrainedWindowWin* container);
virtual ~ConstrainedWindowFrameView();
void UpdateWindowTitle();
@@ -223,7 +222,7 @@ class ConstrainedWindowFrameView
// Loads the appropriate set of WindowResources for the frame view.
void InitWindowResources();
- ConstrainedWindowImpl* container_;
+ ConstrainedWindowWin* container_;
scoped_ptr<views::WindowResources> resources_;
@@ -275,7 +274,7 @@ const SkColor kContentsBorderShadow = SkColorSetARGB(51, 0, 0, 0);
// ConstrainedWindowFrameView, public:
ConstrainedWindowFrameView::ConstrainedWindowFrameView(
- ConstrainedWindowImpl* container)
+ ConstrainedWindowWin* container)
: NonClientFrameView(),
container_(container),
close_button_(new views::ImageButton(this)) {
@@ -575,24 +574,24 @@ void ConstrainedWindowFrameView::InitClass() {
}
////////////////////////////////////////////////////////////////////////////////
-// ConstrainedWindowImpl, public:
+// ConstrainedWindowWin, public:
// The space (in pixels) between minimized pop-ups stacked horizontally and
// vertically.
static const int kPopupRepositionOffset = 5;
static const int kConstrainedWindowEdgePadding = 10;
-ConstrainedWindowImpl::~ConstrainedWindowImpl() {
+ConstrainedWindowWin::~ConstrainedWindowWin() {
}
////////////////////////////////////////////////////////////////////////////////
-// ConstrainedWindowImpl, ConstrainedWindow implementation:
+// ConstrainedWindowWin, ConstrainedWindow implementation:
-views::NonClientFrameView* ConstrainedWindowImpl::CreateFrameViewForWindow() {
+views::NonClientFrameView* ConstrainedWindowWin::CreateFrameViewForWindow() {
return new ConstrainedWindowFrameView(this);
}
-void ConstrainedWindowImpl::CloseConstrainedWindow() {
+void ConstrainedWindowWin::CloseConstrainedWindow() {
// Broadcast to all observers of NOTIFY_CWINDOW_CLOSED.
// One example of such an observer is AutomationCWindowTracker in the
// automation component.
@@ -603,7 +602,7 @@ void ConstrainedWindowImpl::CloseConstrainedWindow() {
Close();
}
-std::wstring ConstrainedWindowImpl::GetWindowTitle() const {
+std::wstring ConstrainedWindowWin::GetWindowTitle() const {
std::wstring display_title;
if (GetDelegate())
display_title = GetDelegate()->GetWindowTitle();
@@ -613,14 +612,14 @@ std::wstring ConstrainedWindowImpl::GetWindowTitle() const {
return display_title;
}
-const gfx::Rect& ConstrainedWindowImpl::GetCurrentBounds() const {
+const gfx::Rect& ConstrainedWindowWin::GetCurrentBounds() const {
return current_bounds_;
}
////////////////////////////////////////////////////////////////////////////////
-// ConstrainedWindowImpl, private:
+// ConstrainedWindowWin, private:
-ConstrainedWindowImpl::ConstrainedWindowImpl(
+ConstrainedWindowWin::ConstrainedWindowWin(
TabContents* owner,
views::WindowDelegate* window_delegate)
: WindowWin(window_delegate),
@@ -636,7 +635,7 @@ ConstrainedWindowImpl::ConstrainedWindowImpl(
ActivateConstrainedWindow();
}
-void ConstrainedWindowImpl::ActivateConstrainedWindow() {
+void ConstrainedWindowWin::ActivateConstrainedWindow() {
// Other pop-ups are simply moved to the front of the z-order.
SetWindowPos(HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
@@ -659,9 +658,9 @@ void ConstrainedWindowImpl::ActivateConstrainedWindow() {
}
////////////////////////////////////////////////////////////////////////////////
-// ConstrainedWindowImpl, views::WidgetWin overrides:
+// ConstrainedWindowWin, views::WidgetWin overrides:
-void ConstrainedWindowImpl::OnDestroy() {
+void ConstrainedWindowWin::OnDestroy() {
// We do this here, rather than |Close|, since the window may be destroyed in
// a way other than by some other component calling Close, e.g. by the native
// window hierarchy closing. We are guaranteed to receive a WM_DESTROY
@@ -686,7 +685,7 @@ void ConstrainedWindowImpl::OnDestroy() {
WindowWin::OnDestroy();
}
-void ConstrainedWindowImpl::OnFinalMessage(HWND window) {
+void ConstrainedWindowWin::OnFinalMessage(HWND window) {
// Tell our constraining TabContents that we've gone so it can update its
// list.
owner_->WillClose(this);
@@ -694,7 +693,7 @@ void ConstrainedWindowImpl::OnFinalMessage(HWND window) {
WindowWin::OnFinalMessage(window);
}
-LRESULT ConstrainedWindowImpl::OnMouseActivate(HWND window,
+LRESULT ConstrainedWindowWin::OnMouseActivate(HWND window,
UINT hittest_code,
UINT message) {
// We only detach the window if the user clicked on the title bar. That
@@ -708,7 +707,7 @@ LRESULT ConstrainedWindowImpl::OnMouseActivate(HWND window,
return MA_ACTIVATE;
}
-void ConstrainedWindowImpl::OnWindowPosChanged(WINDOWPOS* window_pos) {
+void ConstrainedWindowWin::OnWindowPosChanged(WINDOWPOS* window_pos) {
// If the window was moved or sized, tell the owner.
if (!(window_pos->flags & SWP_NOMOVE) || !(window_pos->flags & SWP_NOSIZE))
owner_->DidMoveOrResize(this);
@@ -720,7 +719,7 @@ void ConstrainedWindowImpl::OnWindowPosChanged(WINDOWPOS* window_pos) {
ConstrainedWindow* ConstrainedWindow::CreateConstrainedDialog(
TabContents* parent,
views::WindowDelegate* window_delegate) {
- ConstrainedWindowImpl* window = new ConstrainedWindowImpl(parent,
- window_delegate);
+ ConstrainedWindowWin* window = new ConstrainedWindowWin(parent,
+ window_delegate);
return window;
}
diff --git a/chrome/browser/views/constrained_window_impl.h b/chrome/browser/views/constrained_window_win.h
index 1afd658..a91a736 100644
--- a/chrome/browser/views/constrained_window_impl.h
+++ b/chrome/browser/views/constrained_window_win.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_BROWSER_CONSTRAINED_WINDOW_IMPL_H_
-#define CHROME_BROWSER_CONSTRAINED_WINDOW_IMPL_H_
+#ifndef CHROME_BROWSER_VIEWS_CONSTRAINED_WINDOW_WIN_H_
+#define CHROME_BROWSER_VIEWS_CONSTRAINED_WINDOW_WIN_H_
#include "base/gfx/rect.h"
#include "chrome/browser/tab_contents/constrained_window.h"
@@ -18,15 +18,15 @@ class WindowDelegate;
}
///////////////////////////////////////////////////////////////////////////////
-// ConstrainedWindowImpl
+// ConstrainedWindowWin
//
// A ConstrainedWindow implementation that implements a Constrained Window as
// a child HWND with a custom window frame.
//
-class ConstrainedWindowImpl : public ConstrainedWindow,
+class ConstrainedWindowWin : public ConstrainedWindow,
public views::WindowWin {
public:
- virtual ~ConstrainedWindowImpl();
+ virtual ~ConstrainedWindowWin();
// Returns the TabContents that constrains this Constrained Window.
TabContents* owner() const { return owner_; }
@@ -51,8 +51,8 @@ class ConstrainedWindowImpl : public ConstrainedWindow,
// Use the static factory methods on ConstrainedWindow to construct a
// ConstrainedWindow.
- ConstrainedWindowImpl(TabContents* owner,
- views::WindowDelegate* window_delegate);
+ ConstrainedWindowWin(TabContents* owner,
+ views::WindowDelegate* window_delegate);
// Moves this window to the front of the Z-order and registers us with the
// focus manager.
@@ -65,10 +65,6 @@ class ConstrainedWindowImpl : public ConstrainedWindow,
// when this window is destroyed.
bool focus_restoration_disabled_;
- // true if this window is really a constrained dialog. This is set by
- // InitAsDialog().
- bool is_dialog_;
-
// Current "anchor point", the lower right point at which we render
// the constrained title bar.
gfx::Point anchor_point_;
@@ -76,7 +72,7 @@ class ConstrainedWindowImpl : public ConstrainedWindow,
// Current display rectangle (relative to owner_'s visible area).
gfx::Rect current_bounds_;
- DISALLOW_COPY_AND_ASSIGN(ConstrainedWindowImpl);
+ DISALLOW_COPY_AND_ASSIGN(ConstrainedWindowWin);
};
-#endif // #ifndef CHROME_BROWSER_CONSTRAINED_WINDOW_IMPL_H_
+#endif // #ifndef CHROME_BROWSER_VIEWS_CONSTRAINED_WINDOW_WIN_H_