summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorerg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-04 01:29:24 +0000
committererg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-04 01:29:24 +0000
commitbfd3886dea49078beed60f12b2c98e180172a2e7 (patch)
tree8bf0efa36b74a03a5425cbccc4a4b46b9b8ce0b9 /chrome
parent57ecbe8836e353ba61860ca2f8ef2b6ddca75d6a (diff)
downloadchromium_src-bfd3886dea49078beed60f12b2c98e180172a2e7.zip
chromium_src-bfd3886dea49078beed60f12b2c98e180172a2e7.tar.gz
chromium_src-bfd3886dea49078beed60f12b2c98e180172a2e7.tar.bz2
Revert change r4523 because Vista doesn't like it.
TBR=nsylvain git-svn-id: svn://svn.chromium.org/chrome/trunk/src@4539 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/app/generated_resources.grd3
-rw-r--r--chrome/app/theme/menu_droparrow.pngbin2932 -> 0 bytes
-rw-r--r--chrome/app/theme/theme_resources.h1
-rw-r--r--chrome/app/theme/theme_resources.rc1
-rw-r--r--chrome/browser/browser.cc37
-rw-r--r--chrome/browser/browser.h6
-rw-r--r--chrome/browser/browser_window.h13
-rw-r--r--chrome/browser/constrained_window.h71
-rw-r--r--chrome/browser/external_tab_container.cc8
-rw-r--r--chrome/browser/external_tab_container.h5
-rw-r--r--chrome/browser/tab_contents.cc73
-rw-r--r--chrome/browser/tab_contents.h31
-rw-r--r--chrome/browser/tab_contents_delegate.h16
-rw-r--r--chrome/browser/views/blocked_popup_container.cc532
-rw-r--r--chrome/browser/views/blocked_popup_container.h161
-rw-r--r--chrome/browser/views/browser_views.vcproj16
-rw-r--r--chrome/browser/views/constrained_window_animation.cc31
-rw-r--r--chrome/browser/views/constrained_window_animation.h30
-rw-r--r--chrome/browser/views/constrained_window_impl.cc685
-rw-r--r--chrome/browser/views/constrained_window_impl.h119
-rw-r--r--chrome/browser/views/constrained_window_impl_interactive_uitest.cc54
-rw-r--r--chrome/browser/views/frame/browser_view.cc7
-rw-r--r--chrome/browser/views/frame/browser_view.h4
-rw-r--r--chrome/browser/views/frame/browser_view2.cc35
-rw-r--r--chrome/browser/views/frame/browser_view2.h4
-rw-r--r--chrome/browser/views/old_frames/vista_frame.cc22
-rw-r--r--chrome/browser/views/old_frames/vista_frame.h4
-rw-r--r--chrome/browser/views/old_frames/xp_frame.cc31
-rw-r--r--chrome/browser/views/old_frames/xp_frame.h3
-rw-r--r--chrome/views/menu_button.cc3
30 files changed, 1234 insertions, 772 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index cad0bfb..214da38 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -3165,9 +3165,6 @@ each locale. -->
<message name="IDS_POPUPS_BLOCKED_COUNT" desc="Message on the blocked popup window">
Pop-ups Blocked: <ph name="COUNT">$1<ex>2</ex></ph>
</message>
- <message name="IDS_POPUP_TITLE_FORMAT" desc="Order of URL - Title on the popup">
- <ph name="URL">$1</ph> - <ph name="Window Title">$2</ph>
- </message>
<!-- Multiple download warning-->
<message name="IDS_MULTI_DOWNLOAD_WARNING" desc="Warning invoked if multiple downloads are attempted without user interaction.">
diff --git a/chrome/app/theme/menu_droparrow.png b/chrome/app/theme/menu_droparrow.png
deleted file mode 100644
index 9cc81e0..0000000
--- a/chrome/app/theme/menu_droparrow.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/theme_resources.h b/chrome/app/theme/theme_resources.h
index e46c444..a4cba37 100644
--- a/chrome/app/theme/theme_resources.h
+++ b/chrome/app/theme/theme_resources.h
@@ -314,4 +314,3 @@
#define IDR_PRODUCT_LOGO 9306
#define IDR_DISTRIBUTOR_LOGO 9307
#define IDR_DISTRIBUTOR_LOGO_LIGHT 9308
-#define IDR_MENU_DROPARROW 9309
diff --git a/chrome/app/theme/theme_resources.rc b/chrome/app/theme/theme_resources.rc
index abc8199..58c3e8b 100644
--- a/chrome/app/theme/theme_resources.rc
+++ b/chrome/app/theme/theme_resources.rc
@@ -303,4 +303,3 @@ IDR_FIND_DLG_RIGHT_BB_BACKGROUND BINDATA "find_dlg_right_bb_bg.png"
IDR_FIND_DLG_MIDDLE_BB_BACKGROUND BINDATA "find_dlg_middle_bb_bg.png"
IDR_THROBBER_LIGHT BINDATA "throbber_light.png"
IDR_OTR_ICON_STANDALONE BINDATA "otr_icon_standalone.png"
-IDR_MENU_DROPARROW BINDATA "menu_droparrow.png"
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc
index 016b43b..dcb7082 100644
--- a/chrome/browser/browser.cc
+++ b/chrome/browser/browser.cc
@@ -732,6 +732,42 @@ void Browser::AddNewContents(TabContents* source,
}
}
+void Browser::StartDraggingDetachedContents(TabContents* source,
+ TabContents* new_contents,
+ const gfx::Rect& contents_bounds,
+ const gfx::Point& mouse_pt,
+ int frame_component) {
+ if (!g_browser_process->IsUsingNewFrames()) {
+ BrowserType::Type new_type = BrowserType::BROWSER;
+
+ // If this is a minimal chrome browser, propagate to detached contents to
+ // avoid having URL fields in popups.
+ if (type_ == BrowserType::APPLICATION)
+ new_type = type_;
+
+ Browser* browser = new Browser(contents_bounds, SIZE_TO_CONTENTS, profile_,
+ new_type, L"");
+ browser->AddNewContents(
+ source, new_contents, NEW_FOREGROUND_TAB, contents_bounds, true);
+ browser->Show();
+ browser->window_->ContinueDetachConstrainedWindowDrag(
+ mouse_pt, frame_component);
+ } else {
+ // If we're inside an application frame, preserve that type (i.e. don't
+ // show a location bar on the new window), otherwise open a tab-less
+ // browser window with a location bar.
+ BrowserType::Type new_type =
+ type_ == BrowserType::APPLICATION ? type_ : BrowserType::BROWSER;
+ Browser* browser = new Browser(contents_bounds, SW_SHOWNORMAL, profile_,
+ BrowserType::BROWSER, std::wstring());
+ browser->AddNewContents(source, new_contents,
+ NEW_FOREGROUND_TAB, gfx::Rect(), true);
+ browser->Show();
+ browser->window()->ContinueDetachConstrainedWindowDrag(mouse_pt,
+ frame_component);
+ }
+}
+
void Browser::ActivateContents(TabContents* contents) {
tabstrip_model_.SelectTabContentsAt(
tabstrip_model_.GetIndexOfTabContents(contents), false);
@@ -1841,3 +1877,4 @@ void Browser::FormatTitleForDisplay(std::wstring* title) {
current_index = match_index;
}
}
+
diff --git a/chrome/browser/browser.h b/chrome/browser/browser.h
index 58e32d0..c1b7b53 100644
--- a/chrome/browser/browser.h
+++ b/chrome/browser/browser.h
@@ -273,6 +273,11 @@ class Browser : public TabStripModelDelegate,
WindowOpenDisposition disposition,
const gfx::Rect& initial_pos,
bool user_gesture);
+ virtual void StartDraggingDetachedContents(TabContents* source,
+ TabContents* new_contents,
+ const gfx::Rect& contents_bounds,
+ const gfx::Point& mouse_pt,
+ int frame_component);
virtual void ActivateContents(TabContents* contents);
virtual void LoadingStateChanged(TabContents* source);
virtual void CloseContents(TabContents* source);
@@ -617,3 +622,4 @@ class Browser : public TabStripModelDelegate,
};
#endif // CHROME_BROWSER_BROWSER_H_
+
diff --git a/chrome/browser/browser_window.h b/chrome/browser/browser_window.h
index 6f0e6ec..4012ddf 100644
--- a/chrome/browser/browser_window.h
+++ b/chrome/browser/browser_window.h
@@ -92,6 +92,18 @@ class BrowserWindow {
// TODO(beng): REMOVE
virtual void ShowTabContents(TabContents* contents) {}
+ // Continue a drag gesture that began with a constrained window. When the
+ // user drags a constrained window such that their mouse pointer leaves the
+ // bounds of the constraining HWND, the window is detached and the drag
+ // gesture continues except for this top level frame.
+ // |mouse_pt| is the position of the cursor in screen coordinates.
+ // |frame_component| is the component returned by WM_NCHITTEST for |mouse_pt|
+ // on the constrained window. This is passed to ensure we initiate the
+ // correct action (move, resize, etc).
+ virtual void ContinueDetachConstrainedWindowDrag(
+ const gfx::Point& mouse_pt,
+ int frame_component) = 0;
+
// Sizes the frame to match the specified desired bounds for the contents.
// |contents_bounds| are in screen coordinates.
// TODO(beng): REMOVE
@@ -177,3 +189,4 @@ class BrowserWindow {
};
#endif // CHROME_BROWSER_BROWSER_WINDOW_H__
+
diff --git a/chrome/browser/constrained_window.h b/chrome/browser/constrained_window.h
index d703ad2..04c0af9 100644
--- a/chrome/browser/constrained_window.h
+++ b/chrome/browser/constrained_window.h
@@ -21,6 +21,53 @@ class GURL;
class TabContents;
///////////////////////////////////////////////////////////////////////////////
+// ConstrainedTabContentsDelegate
+//
+// An object that implements this interface is managing one or more
+// constrained windows. This interface is used to inform the delegate about
+// events within the Constrained Window.
+//
+class ConstrainedTabContentsDelegate {
+ public:
+ // Called when the contained TabContents creates a new TabContents. The
+ // ConstrainedWindow has no way to present the new TabContents, so it just
+ // lets the delegate decide what to do.
+ virtual void AddNewContents(ConstrainedWindow* window,
+ TabContents* new_contents,
+ WindowOpenDisposition disposition,
+ const gfx::Rect& initial_pos,
+ bool user_gesture) = 0;
+
+ // Called to open a URL in a the specified manner.
+ virtual void OpenURL(ConstrainedWindow* window,
+ const GURL& url,
+ const GURL& referrer,
+ WindowOpenDisposition disposition,
+ PageTransition::Type transition) = 0;
+
+ // Called when the window is about to be closed.
+ virtual void WillClose(ConstrainedWindow* window) = 0;
+
+ // Called when the window's contents should be detached into a top-level
+ // window. The delegate is expected to have re-parented the TabContents by
+ // the time this method returns.
+ // |contents_bounds| is the bounds of the TabContents after the detach
+ // action. These are in screen coordinates and are for the TabContents _only_
+ // - the window UI should be created around it at an appropriate size.
+ // |mouse_pt| is the position of the cursor in screen coordinates.
+ // |frame_component| is the part of the constrained window frame that
+ // corresponds to |mouse_pt| as returned by WM_NCHITTEST.
+ virtual void DetachContents(ConstrainedWindow* window,
+ TabContents* contents,
+ const gfx::Rect& contents_bounds,
+ const gfx::Point& mouse_pt,
+ int frame_component) = 0;
+
+ // Called when the window is moved or resized.
+ virtual void DidMoveOrResize(ConstrainedWindow* window) = 0;
+};
+
+///////////////////////////////////////////////////////////////////////////////
// ConstrainedWindow
//
// This interface represents a window that is constrained to a TabContents'
@@ -40,6 +87,21 @@ class ConstrainedWindow {
views::View* contents_view,
views::WindowDelegate* window_delegate);
+ // Create a Constrained Window that contains a TabContents subclass, e.g. for
+ // a web popup. |initial_bounds| specifies the desired position of the
+ // |constrained_contents|, not the bounds of the window itself.
+ // |user_gesture| specifies whether or not this window was opened as a result
+ // of a user input event, or is an unsolicited popup.
+ static ConstrainedWindow* CreateConstrainedPopup(
+ TabContents* owner,
+ const gfx::Rect& initial_bounds,
+ TabContents* constrained_contents);
+
+ // Activates the Constrained Window, which has the effect of detaching it if
+ // it contains a WebContents, otherwise just brings it to the front of the
+ // z-order.
+ virtual void ActivateConstrainedWindow() = 0;
+
// Closes the Constrained Window.
virtual void CloseConstrainedWindow() = 0;
@@ -48,6 +110,11 @@ class ConstrainedWindow {
virtual void RepositionConstrainedWindowTo(
const gfx::Point& anchor_point) = 0;
+ // Returns true if the Constrained Window is being "suppressed" (i.e.
+ // positioned to the bottom right of the constraining TabContents) because it
+ // was opened without a user gesture.
+ virtual bool IsSuppressedConstrainedWindow() const = 0;
+
// Tells the Constrained Window that the constraining TabContents was hidden,
// e.g. via a tab switch.
virtual void WasHidden() = 0;
@@ -59,6 +126,9 @@ class ConstrainedWindow {
// Returns the title of the Constrained Window.
virtual std::wstring GetWindowTitle() const = 0;
+ // Updates the Window's title and repaints the titlebar
+ virtual void UpdateWindowTitle() = 0;
+
// Returns the current display rectangle (relative to its
// parent). This method is only called from the unit tests to check
// the location/size of a constrained window.
@@ -66,3 +136,4 @@ class ConstrainedWindow {
};
#endif // #ifndef CHROME_BROWSER_CONSTRAINED_WINDOW_H__
+
diff --git a/chrome/browser/external_tab_container.cc b/chrome/browser/external_tab_container.cc
index ea1f7e3..c97d15d 100644
--- a/chrome/browser/external_tab_container.cc
+++ b/chrome/browser/external_tab_container.cc
@@ -170,6 +170,13 @@ void ExternalTabContainer::AddNewContents(TabContents* source,
bool user_gesture) {
}
+void ExternalTabContainer::StartDraggingDetachedContents(
+ TabContents* source,
+ TabContents* new_contents,
+ const gfx::Rect& contents_bounds,
+ const gfx::Point& mouse_pt) {
+}
+
void ExternalTabContainer::ActivateContents(TabContents* contents) {
}
@@ -329,3 +336,4 @@ ExternalTabContainer* ExternalTabContainer::GetContainerForTab(
GetProp(parent_window, kWindowObjectKey));
return container;
}
+
diff --git a/chrome/browser/external_tab_container.h b/chrome/browser/external_tab_container.h
index bb8b21f..1f694a0 100644
--- a/chrome/browser/external_tab_container.h
+++ b/chrome/browser/external_tab_container.h
@@ -66,6 +66,10 @@ class ExternalTabContainer : public TabContentsDelegate,
WindowOpenDisposition disposition,
const gfx::Rect& initial_pos,
bool user_gesture);
+ virtual void StartDraggingDetachedContents(TabContents* source,
+ TabContents* new_contents,
+ const gfx::Rect& contents_bounds,
+ const gfx::Point& mouse_pt);
virtual void ActivateContents(TabContents* contents);
virtual void LoadingStateChanged(TabContents* source);
virtual void CloseContents(TabContents* source);
@@ -143,3 +147,4 @@ class ExternalTabContainer : public TabContentsDelegate,
};
#endif // CHROME_BROWSER_EXTERNAL_TAB_CONTAINER_H__
+
diff --git a/chrome/browser/tab_contents.cc b/chrome/browser/tab_contents.cc
index 0215ec7..931d415 100644
--- a/chrome/browser/tab_contents.cc
+++ b/chrome/browser/tab_contents.cc
@@ -8,7 +8,6 @@
#include "chrome/browser/navigation_entry.h"
#include "chrome/browser/views/download_shelf_view.h"
#include "chrome/browser/views/download_started_animation.h"
-#include "chrome/browser/views/blocked_popup_container.h"
#include "chrome/browser/web_contents.h"
#include "chrome/browser/tab_contents_delegate.h"
#include "chrome/common/l10n_util.h"
@@ -44,7 +43,6 @@ TabContents::TabContents(TabContentsType type)
saved_location_bar_state_(NULL),
shelf_visible_(false),
max_page_id_(-1),
- blocked_popups_(NULL),
capturing_contents_(false) {
last_focused_view_storage_id_ =
views::ViewStorage::GetSharedInstance()->CreateStorageID();
@@ -292,25 +290,25 @@ void TabContents::AddNewContents(TabContents* new_contents,
void TabContents::AddConstrainedPopup(TabContents* new_contents,
const gfx::Rect& initial_pos) {
- if (!blocked_popups_) {
- CRect client_rect;
- GetClientRect(GetContainerHWND(), &client_rect);
- gfx::Point anchor_position(
- client_rect.Width() -
- views::NativeScrollBar::GetVerticalScrollBarWidth(),
- client_rect.Height());
-
- blocked_popups_ = BlockedPopupContainer::Create(
- this, profile(), anchor_position);
- child_windows_.push_back(blocked_popups_);
- }
+ ConstrainedWindow* window =
+ ConstrainedWindow::CreateConstrainedPopup(
+ this, initial_pos, new_contents);
+ child_windows_.push_back(window);
- blocked_popups_->AddTabContents(new_contents, initial_pos);
+ CRect client_rect;
+ GetClientRect(GetContainerHWND(), &client_rect);
+ gfx::Size new_size(client_rect.Width(), client_rect.Height());
+ RepositionSupressedPopupsToFit(new_size);
}
void TabContents::CloseAllSuppressedPopups() {
- if (blocked_popups_)
- blocked_popups_->CloseAllPopups();
+ // Close all auto positioned child windows to "clean up" the workspace.
+ int count = static_cast<int>(child_windows_.size());
+ for (int i = count - 1; i >= 0; --i) {
+ ConstrainedWindow* window = child_windows_.at(i);
+ if (window->IsSuppressedConstrainedWindow())
+ window->CloseConstrainedWindow();
+ }
}
void TabContents::Focus() {
@@ -446,15 +444,28 @@ void TabContents::MigrateShelfViewFrom(TabContents* tab_contents) {
tab_contents->ReleaseDownloadShelfView();
}
+void TabContents::AddNewContents(ConstrainedWindow* window,
+ TabContents* new_contents,
+ WindowOpenDisposition disposition,
+ const gfx::Rect& initial_pos,
+ bool user_gesture) {
+ AddNewContents(new_contents, disposition, initial_pos, user_gesture);
+}
+
+void TabContents::OpenURL(ConstrainedWindow* window,
+ const GURL& url,
+ const GURL& referrer,
+ WindowOpenDisposition disposition,
+ PageTransition::Type transition) {
+ OpenURL(url, referrer, disposition, transition);
+}
+
void TabContents::WillClose(ConstrainedWindow* window) {
ConstrainedWindowList::iterator it =
find(child_windows_.begin(), child_windows_.end(), window);
if (it != child_windows_.end())
child_windows_.erase(it);
- if (window == blocked_popups_)
- blocked_popups_ = NULL;
-
if (::IsWindow(GetContainerHWND())) {
CRect client_rect;
GetClientRect(GetContainerHWND(), &client_rect);
@@ -463,6 +474,19 @@ void TabContents::WillClose(ConstrainedWindow* window) {
}
}
+void TabContents::DetachContents(ConstrainedWindow* window,
+ TabContents* contents,
+ const gfx::Rect& contents_bounds,
+ const gfx::Point& mouse_pt,
+ int frame_component) {
+ WillClose(window);
+ if (delegate_) {
+ contents->DisassociateFromPopupCount();
+ delegate_->StartDraggingDetachedContents(
+ this, contents, contents_bounds, mouse_pt, frame_component);
+ }
+}
+
void TabContents::DidMoveOrResize(ConstrainedWindow* window) {
UpdateWindow(GetContainerHWND());
}
@@ -508,9 +532,12 @@ void TabContents::RepositionSupressedPopupsToFit(const gfx::Size& new_size) {
new_size.width() -
views::NativeScrollBar::GetVerticalScrollBarWidth(),
new_size.height());
-
- if (blocked_popups_)
- blocked_popups_->RepositionConstrainedWindowTo(anchor_position);
+ int window_count = static_cast<int>(child_windows_.size());
+ for (int i = window_count - 1; i >= 0; --i) {
+ ConstrainedWindow* window = child_windows_.at(i);
+ if (window->IsSuppressedConstrainedWindow())
+ window->RepositionConstrainedWindowTo(anchor_position);
+ }
}
void TabContents::ReleaseDownloadShelfView() {
diff --git a/chrome/browser/tab_contents.h b/chrome/browser/tab_contents.h
index f4d981e..54a9e45 100644
--- a/chrome/browser/tab_contents.h
+++ b/chrome/browser/tab_contents.h
@@ -23,7 +23,6 @@ namespace views {
class WindowDelegate;
}
-class BlockedPopupContainer;
class DOMUIHost;
class DownloadItem;
class DownloadShelfView;
@@ -53,7 +52,8 @@ class WebContents;
// the NavigationController makes the active TabContents inactive, notifies the
// TabContentsDelegate that the TabContents is being replaced, and then
// activates the new TabContents.
-class TabContents : public PageNavigator {
+class TabContents : public PageNavigator,
+ public ConstrainedTabContentsDelegate {
public:
// Flags passed to the TabContentsDelegate.NavigationStateChanged to tell it
// what has changed. Combine them to update more than one thing.
@@ -411,11 +411,25 @@ class TabContents : public PageNavigator {
// want to generalize this if we need to migrate some other state.
static void MigrateShelfView(TabContents* from, TabContents* to);
- // Called when a ConstrainedWindow we own is about to be closed.
- void WillClose(ConstrainedWindow* window);
+ // ConstrainedTabContentsDelegate --------------------------------------------
- // Called when a ConstrainedWindow we own is moved or resized.
- void DidMoveOrResize(ConstrainedWindow* window);
+ virtual void AddNewContents(ConstrainedWindow* window,
+ TabContents* contents,
+ WindowOpenDisposition disposition,
+ const gfx::Rect& initial_pos,
+ bool user_gesture);
+ virtual void OpenURL(ConstrainedWindow* window,
+ const GURL& url,
+ const GURL& referrer,
+ WindowOpenDisposition disposition,
+ PageTransition::Type transition);
+ virtual void WillClose(ConstrainedWindow* window);
+ virtual void DetachContents(ConstrainedWindow* window,
+ TabContents* contents,
+ const gfx::Rect& contents_bounds,
+ const gfx::Point& mouse_pt,
+ int frame_component);
+ virtual void DidMoveOrResize(ConstrainedWindow* window);
protected:
friend class NavigationController;
@@ -503,11 +517,6 @@ class TabContents : public PageNavigator {
// See capturing_contents() above.
bool capturing_contents_;
- // ConstrainedWindow with additional methods for managing blocked
- // popups. This pointer alsog goes in |child_windows_| for ownership,
- // repositioning, etc.
- BlockedPopupContainer* blocked_popups_;
-
DISALLOW_COPY_AND_ASSIGN(TabContents);
};
diff --git a/chrome/browser/tab_contents_delegate.h b/chrome/browser/tab_contents_delegate.h
index 2365757..401fe9e 100644
--- a/chrome/browser/tab_contents_delegate.h
+++ b/chrome/browser/tab_contents_delegate.h
@@ -59,6 +59,21 @@ class TabContentsDelegate : public PageNavigator {
const gfx::Rect& initial_pos,
bool user_gesture) = 0;
+ // Called when while dragging constrained TabContents, the mouse pointer
+ // moves outside the bounds of the constraining contents. The delegate can
+ // use this as an opportunity to continue the drag in a detached window.
+ // |contents_bounds| is the bounds of the constrained TabContents in screen
+ // coordinates.
+ // |mouse_pt| is the position of the mouse pointer in screen coordinates.
+ // |frame_component| is the part of the constrained window frame that
+ // corresponds to |mouse_pt| as returned by WM_NCHITTEST.
+ virtual void StartDraggingDetachedContents(
+ TabContents* source,
+ TabContents* new_contents,
+ const gfx::Rect& contents_bounds,
+ const gfx::Point& mouse_pt,
+ int frame_component) { }
+
// Selects the specified contents, bringing its container to the front.
virtual void ActivateContents(TabContents* contents) = 0;
@@ -145,3 +160,4 @@ class TabContentsDelegate : public PageNavigator {
};
#endif // CHROME_BROWSER_TAB_CONTENTS_DELEGATE_H_
+
diff --git a/chrome/browser/views/blocked_popup_container.cc b/chrome/browser/views/blocked_popup_container.cc
deleted file mode 100644
index e69e859..0000000
--- a/chrome/browser/views/blocked_popup_container.cc
+++ /dev/null
@@ -1,532 +0,0 @@
-// Copyright (c) 2008 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/views/blocked_popup_container.h"
-
-#include "chrome/app/theme/theme_resources.h"
-#include "chrome/browser/profile.h"
-#include "chrome/browser/tab_contents.h"
-#include "chrome/common/gfx/chrome_canvas.h"
-#include "chrome/common/resource_bundle.h"
-#include "chrome/views/background.h"
-#include "chrome/views/button.h"
-#include "chrome/views/menu_button.h"
-#include "chrome/views/menu.h"
-#include "chrome/common/l10n_util.h"
-#include "chrome/common/pref_names.h"
-#include "chrome/common/gfx/path.h"
-
-#include "generated_resources.h"
-
-#include <math.h>
-
-const int kNotifyMenuItem = -1;
-
-// A number larger than the internal popup count on the Renderer; meant for
-// preventing a compromised renderer from exhausting GDI memory by spawning
-// infinite windows.
-const int kImpossibleNumberOfPopups = 30;
-
-// A small border around all widgets
-const int kSmallPadding = 2;
-
-// The background color of the blocked popup notification
-//static const SkColor kBackgroundColor = SkColorSetRGB(222, 234, 248);
-static const SkColor kBackgroundColorTop = SkColorSetRGB(255, 242, 183);
-static const SkColor kBackgroundColorBottom = SkColorSetRGB(250, 230, 145);
-
-// The border color of the blocked popup notification. This is the same as the
-// border around the inside of the tab contents.
-static const SkColor kBorderColor = SkColorSetRGB(190, 205, 223);
-// Thickness of the border.
-static const int kBorderSize = 1;
-
-// Duration of the showing/hiding animations.
-static const int kShowAnimationDurationMS = 200;
-static const int kHideAnimationDurationMS = 120;
-static const int kFramerate = 25;
-
-// Rounded corner radius (in pixels)
-static const int kBackgroundCornerRadius = 4;
-
-// Rounded corner definition for the
-static const SkScalar kRoundedCornerRad[8] = {
- // Top left corner
- SkIntToScalar(kBackgroundCornerRadius),
- SkIntToScalar(kBackgroundCornerRadius),
- // Top right corner
- SkIntToScalar(kBackgroundCornerRadius),
- SkIntToScalar(kBackgroundCornerRadius),
- // Bottom right corner
- 0,
- 0,
- // Bottom left corner
- 0,
- 0
-};
-
-////////////////////////////////////////////////////////////////////////////////
-// BlockedPopupContainerView
-//
-// The view presented to the user notifying them of the number of popups
-// blocked.
-//
-class BlockedPopupContainerView : public views::View,
- public views::BaseButton::ButtonListener,
- public Menu::Delegate {
- public:
- explicit BlockedPopupContainerView(BlockedPopupContainer* container);
- ~BlockedPopupContainerView();
-
- // Sets the label on the menu button
- void UpdatePopupCountLabel();
-
- // Overridden from views::View:
- virtual void Paint(ChromeCanvas* canvas);
- virtual void Layout();
- virtual gfx::Size GetPreferredSize();
-
- // Overridden from views::ButtonListener::ButtonPressed:
- virtual void ButtonPressed(views::BaseButton* sender);
-
- // Overridden from Menu::Delegate:
- virtual bool IsItemChecked(int id) const;
- virtual void ExecuteCommand(int id);
-
- private:
- // Our owner and HWND parent.
- BlockedPopupContainer* container_;
-
- // The button which brings up the popup menu.
- views::MenuButton* popup_count_label_;
-
- // Our "X" button.
- views::Button* close_button_;
-
- /// Popup menu shown to user.
- scoped_ptr<Menu> launch_menu_;
-};
-
-BlockedPopupContainerView::BlockedPopupContainerView(
- BlockedPopupContainer* container)
- : container_(container) {
- ResourceBundle &rb = ResourceBundle::GetSharedInstance();
-
- // Create a button with a multidigit number to reserve space.
- popup_count_label_ = new views::MenuButton(
- l10n_util::GetStringF(IDS_POPUPS_BLOCKED_COUNT, IntToWString(99)),
- NULL, true);
- popup_count_label_->SetTextAlignment(views::TextButton::ALIGN_CENTER);
- popup_count_label_->SetListener(this, 1);
- AddChildView(popup_count_label_);
-
- // For now, we steal the Find close button, since it looks OK.
- close_button_ = new views::Button();
- close_button_->SetFocusable(true);
- close_button_->SetImage(views::Button::BS_NORMAL,
- rb.GetBitmapNamed(IDR_CLOSE_BAR));
- close_button_->SetImage(views::Button::BS_HOT,
- rb.GetBitmapNamed(IDR_CLOSE_BAR_H));
- close_button_->SetImage(views::Button::BS_PUSHED,
- rb.GetBitmapNamed(IDR_CLOSE_BAR_P));
- close_button_->SetListener(this, 0);
- AddChildView(close_button_);
-
- SetBackground(views::Background::CreateStandardPanelBackground());
- UpdatePopupCountLabel();
-}
-
-BlockedPopupContainerView::~BlockedPopupContainerView() {
-}
-
-void BlockedPopupContainerView::UpdatePopupCountLabel() {
- popup_count_label_->SetText(container_->GetWindowTitle());
- Layout();
- SchedulePaint();
-}
-
-void BlockedPopupContainerView::Paint(ChromeCanvas* canvas) {
- View::Paint(canvas);
- // Draw the standard background
-
- SkRect rect;
- rect.set(0, 0, SkIntToScalar(width()), SkIntToScalar(height()));
-
- // Draw the border
- SkPaint border_paint;
- border_paint.setFlags(SkPaint::kAntiAlias_Flag);
- border_paint.setStyle(SkPaint::kStroke_Style);
- border_paint.setColor(kBorderColor);
- SkPath border_path;
- border_path.addRoundRect(rect, kRoundedCornerRad, SkPath::kCW_Direction);
- canvas->drawPath(border_path, border_paint);
-}
-
-void BlockedPopupContainerView::Layout() {
- gfx::Size panel_size = GetPreferredSize();
- gfx::Size button_size = close_button_->GetPreferredSize();
- gfx::Size sz = popup_count_label_->GetPreferredSize();
-
- popup_count_label_->SetBounds(kSmallPadding, kSmallPadding,
- sz.width(),
- sz.height());
-
- int close_button_padding =
- static_cast<int>(ceil(panel_size.height() / 2.0) -
- ceil(button_size.height() / 2.0));
- close_button_->SetBounds(width() - button_size.width() - close_button_padding,
- close_button_padding,
- button_size.width(),
- button_size.height());
-}
-
-gfx::Size BlockedPopupContainerView::GetPreferredSize() {
- gfx::Size prefsize = popup_count_label_->GetPreferredSize();
- prefsize.Enlarge(close_button_->GetPreferredSize().width(), 0);
- // Add padding to all sides of the |popup_count_label_| except the right.
- prefsize.Enlarge(kSmallPadding, 2 * kSmallPadding);
-
- // Add padding to the left and right side of |close_button_| equal to its
- // horizontal/vertical spacing.
- gfx::Size button_size = close_button_->GetPreferredSize();
- int close_button_padding =
- static_cast<int>(ceil(prefsize.height() / 2.0) -
- ceil(button_size.height() / 2.0));
- prefsize.Enlarge(2 * close_button_padding, 0);
-
- return prefsize;
-}
-
-void BlockedPopupContainerView::ButtonPressed(views::BaseButton* sender) {
- if (sender == popup_count_label_) {
- // Menu goes here.
- launch_menu_.reset(new Menu(this, Menu::TOPLEFT, container_->GetHWND()));
-
- int item_count = container_->GetTabContentsCount();
- for (int i = 0; i < item_count; ++i) {
- std::wstring label = container_->GetDisplayStringForItem(i);
- // We can't just use the index into container_ here because Menu reserves
- // the value 0 as the nop command.
- launch_menu_->AppendMenuItem(i + 1, label, Menu::NORMAL);
- }
-
- launch_menu_->AppendSeparator();
- launch_menu_->AppendMenuItem(
- kNotifyMenuItem,
- l10n_util::GetString(IDS_OPTIONS_SHOWPOPUPBLOCKEDNOTIFICATION),
- Menu::NORMAL);
-
- CPoint cursor_pos;
- ::GetCursorPos(&cursor_pos);
- launch_menu_->RunMenuAt(cursor_pos.x, cursor_pos.y);
- } else if (sender == close_button_) {
- container_->set_dismissed();
- container_->CloseAllPopups();
- }
-}
-
-bool BlockedPopupContainerView::IsItemChecked(int id) const {
- if (id == kNotifyMenuItem)
- return container_->GetShowBlockedPopupNotification();
-
- return false;
-}
-
-void BlockedPopupContainerView::ExecuteCommand(int id) {
- if (id == kNotifyMenuItem) {
- container_->ToggleBlockedPopupNotification();
- } else {
- // Decrement id since all index based commands have 1 added to them. (See
- // ButtonPressed() for detail).
- container_->LaunchPopupIndex(id - 1);
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// BlockedPopupContainer
-
-// static
-BlockedPopupContainer* BlockedPopupContainer::Create(
- TabContents* owner, Profile* profile, const gfx::Point& initial_anchor) {
- BlockedPopupContainer* c = new BlockedPopupContainer(owner, profile);
- c->Init(initial_anchor);
- return c;
-}
-
-BlockedPopupContainer::~BlockedPopupContainer() {
-}
-
-BlockedPopupContainer::BlockedPopupContainer(TabContents* owner,
- Profile* profile)
- : Animation(kFramerate, NULL),
- owner_(owner),
- container_view_(NULL),
- has_been_dismissed_(false),
- in_show_animation_(false),
- visibility_percentage_(0) {
- block_popup_pref_.Init(
- prefs::kBlockPopups, profile->GetPrefs(), NULL);
-}
-
-void BlockedPopupContainer::ToggleBlockedPopupNotification() {
- bool current = block_popup_pref_.GetValue();
- block_popup_pref_.SetValue(!current);
-}
-
-bool BlockedPopupContainer::GetShowBlockedPopupNotification() {
- return ! block_popup_pref_.GetValue();
-}
-
-void BlockedPopupContainer::AddTabContents(TabContents* blocked_contents,
- const gfx::Rect& bounds) {
- if (has_been_dismissed_) {
- // We simply bounce this popup without notice.
- blocked_contents->CloseContents();
- return;
- }
-
- if (blocked_popups_.size() > kImpossibleNumberOfPopups) {
- blocked_contents->CloseContents();
- LOG(INFO) << "Warning: Renderer is sending more popups to us then should be"
- " possible. Renderer compromised?";
- return;
- }
-
- blocked_contents->set_delegate(this);
- blocked_popups_.push_back(std::make_pair(blocked_contents, bounds));
- container_view_->UpdatePopupCountLabel();
-
- ShowSelf();
-}
-
-void BlockedPopupContainer::LaunchPopupIndex(int index) {
- if (static_cast<size_t>(index) < blocked_popups_.size()) {
- TabContents* contents = blocked_popups_[index].first;
- gfx::Rect bounds = blocked_popups_[index].second;
- blocked_popups_.erase(blocked_popups_.begin() + index);
- container_view_->UpdatePopupCountLabel();
-
- contents->set_delegate(NULL);
- contents->DisassociateFromPopupCount();
-
- // Pass this TabContents back to our owner, forcing the window to be
- // displayed since user_gesture is true.
- owner_->AddNewContents(contents, NEW_POPUP, bounds, true);
- }
-
- if (blocked_popups_.size() == 0)
- CloseAllPopups();
-}
-
-int BlockedPopupContainer::GetTabContentsCount() const {
- return blocked_popups_.size();
-}
-
-std::wstring BlockedPopupContainer::GetDisplayStringForItem(int index) {
- const GURL& url = blocked_popups_[index].first->GetURL().GetOrigin();
-
- std::wstring label =
- l10n_util::GetStringF(IDS_POPUP_TITLE_FORMAT,
- UTF8ToWide(url.possibly_invalid_spec()),
- blocked_popups_[index].first->GetTitle());
- return label;
-}
-
-void BlockedPopupContainer::CloseAllPopups() {
- CloseEachTabContents();
- container_view_->UpdatePopupCountLabel();
- HideSelf();
-}
-
-/////////////////////////////////////////////////////////////////////////////////
-// Override from ConstrainedWindow:
-
-void BlockedPopupContainer::CloseConstrainedWindow() {
- CloseEachTabContents();
-
- // Broadcast to all observers of NOTIFY_CWINDOW_CLOSED.
- // One example of such an observer is AutomationCWindowTracker in the
- // automation component.
- NotificationService::current()->Notify(NOTIFY_CWINDOW_CLOSED,
- Source<ConstrainedWindow>(this),
- NotificationService::NoDetails());
-
- Close();
-}
-
-void BlockedPopupContainer::RepositionConstrainedWindowTo(
- const gfx::Point& anchor_point) {
- anchor_point_ = anchor_point;
- SetPosition();
-}
-
-std::wstring BlockedPopupContainer::GetWindowTitle() const {
- return l10n_util::GetStringF(IDS_POPUPS_BLOCKED_COUNT,
- IntToWString(GetTabContentsCount()));
-}
-
-const gfx::Rect& BlockedPopupContainer::GetCurrentBounds() const {
- return bounds_;
-}
-
-/////////////////////////////////////////////////////////////////////////////////
-// Override from TabContentsDelegate:
-void BlockedPopupContainer::OpenURLFromTab(TabContents* source,
- const GURL& url, const GURL& referrer,
- WindowOpenDisposition disposition,
- PageTransition::Type transition) {
- owner_->OpenURL(url, referrer, disposition, transition);
-}
-
-void BlockedPopupContainer::ReplaceContents(TabContents* source,
- TabContents* new_contents) {
- // Walk the vector to find the correct TabContents and replace it.
- bool found = false;
- gfx::Rect rect;
- for (std::vector<std::pair<TabContents*, gfx::Rect> >::iterator it =
- blocked_popups_.begin(); it != blocked_popups_.end(); ++it) {
- if (it->first == source) {
- rect = it->second;
- found = true;
- blocked_popups_.erase(it);
- break;
- }
- }
-
- if (found)
- blocked_popups_.push_back(std::make_pair(new_contents, rect));
-}
-
-void BlockedPopupContainer::AddNewContents(TabContents* source,
- TabContents* new_contents,
- WindowOpenDisposition disposition,
- const gfx::Rect& initial_pos,
- bool user_gesture) {
- owner_->AddNewContents(new_contents, disposition, initial_pos,
- user_gesture);
-}
-
-void BlockedPopupContainer::CloseContents(TabContents* source) {
- for (std::vector<std::pair<TabContents*, gfx::Rect> >::iterator it =
- blocked_popups_.begin(); it != blocked_popups_.end(); ++it) {
- if (it->first == source) {
- blocked_popups_.erase(it);
- break;
- }
- }
-
- if (blocked_popups_.size() == 0)
- CloseAllPopups();
-}
-
-void BlockedPopupContainer::MoveContents(TabContents* source,
- const gfx::Rect& pos) {
- for (std::vector<std::pair<TabContents*, gfx::Rect> >::iterator it =
- blocked_popups_.begin(); it != blocked_popups_.end(); ++it) {
- if (it->first == source) {
- it->second = pos;
- break;
- }
- }
-}
-
-bool BlockedPopupContainer::IsPopup(TabContents* source) {
- return true;
-}
-
-TabContents* BlockedPopupContainer::GetConstrainingContents(
- TabContents* source) {
- return owner_;
-}
-
-/////////////////////////////////////////////////////////////////////////////////
-// Override from Animation:
-void BlockedPopupContainer::AnimateToState(double state) {
- if (in_show_animation_)
- visibility_percentage_ = state;
- else
- visibility_percentage_ = 1 - state;
-
- SetPosition();
-}
-
-/////////////////////////////////////////////////////////////////////////////////
-// Override from views::ContainerWin:
-void BlockedPopupContainer::OnFinalMessage(HWND window) {
- owner_->WillClose(this);
- CloseEachTabContents();
- ContainerWin::OnFinalMessage(window);
-}
-
-void BlockedPopupContainer::OnSize(UINT param, const CSize& size) {
- // Set the window region so we have rounded corners on the top.
- SkRect rect;
- rect.set(0, 0, SkIntToScalar(size.cx), SkIntToScalar(size.cy));
- gfx::Path path;
- path.addRoundRect(rect, kRoundedCornerRad, SkPath::kCW_Direction);
- SetWindowRgn(path.CreateHRGN(), TRUE);
-
- ChangeSize(param, size);
-}
-
-// private:
-
-void BlockedPopupContainer::Init(const gfx::Point& initial_anchor) {
- container_view_ = new BlockedPopupContainerView(this);
- container_view_->SetVisible(true);
-
- set_window_style(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
- ContainerWin::Init(owner_->GetContainerHWND(), gfx::Rect(), false);
- SetContentsView(container_view_);
- RepositionConstrainedWindowTo(initial_anchor);
-
- if (GetShowBlockedPopupNotification())
- ShowSelf();
- else
- has_been_dismissed_ = true;
-}
-
-void BlockedPopupContainer::HideSelf() {
- in_show_animation_ = false;
- Animation::SetDuration(kHideAnimationDurationMS);
- Animation::Start();
-}
-
-void BlockedPopupContainer::ShowSelf() {
- SetWindowPos(HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
- if (!Animation::IsAnimating() && visibility_percentage_ < 1.0) {
- in_show_animation_ = true;
- Animation::SetDuration(kShowAnimationDurationMS);
- Animation::Start();
- }
-}
-
-void BlockedPopupContainer::SetPosition() {
- gfx::Size size = container_view_->GetPreferredSize();
- int base_x = anchor_point_.x() - size.width();
- int base_y = anchor_point_.y() - size.height();
- // The bounds we report through the automation system are the real bounds;
- // the animation is short lived...
- bounds_ = gfx::Rect(gfx::Point(base_x, base_y), size);
-
- int real_height = static_cast<int>(size.height() * visibility_percentage_);
- int real_y = anchor_point_.y() - real_height;
-
- // Size this window to the bottom left corner starting at the anchor point.
- if (real_height > 0) {
- SetWindowPos(HWND_TOP, base_x, real_y, size.width(), real_height, 0);
- container_view_->SchedulePaint();
- } else {
- SetWindowPos(HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_HIDEWINDOW);
- }
-}
-
-void BlockedPopupContainer::CloseEachTabContents() {
- while (!blocked_popups_.empty()) {
- blocked_popups_.back().first->CloseContents();
- blocked_popups_.pop_back();
- }
-
- blocked_popups_.clear();
-}
diff --git a/chrome/browser/views/blocked_popup_container.h b/chrome/browser/views/blocked_popup_container.h
deleted file mode 100644
index de59a1e..0000000
--- a/chrome/browser/views/blocked_popup_container.h
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright (c) 2008 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_VIEWS_BLOCKED_POPUP_CONTAINER_H_
-#define CHROME_BROWSER_VIEWS_BLOCKED_POPUP_CONTAINER_H_
-
-#include <vector>
-
-#include "base/gfx/rect.h"
-#include "chrome/browser/constrained_window.h"
-#include "chrome/browser/tab_contents_delegate.h"
-#include "chrome/common/animation.h"
-#include "chrome/common/pref_member.h"
-#include "chrome/views/container_win.h"
-
-class BlockedPopupContainerView;
-class Profile;
-class TabContents;
-class TextButton;
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// BlockedPopupContainer
-//
-// This class takes ownership of TabContents that are unrequested popup
-// windows and presents an interface to the user for launching them. (Or never
-// showing them again)
-//
-class BlockedPopupContainer : public ConstrainedWindow,
- public TabContentsDelegate,
- public views::ContainerWin,
- public Animation {
- public:
- virtual ~BlockedPopupContainer();
-
- // Create a BlockedPopupContainer, anchoring the container to the lower right
- // corner.
- static BlockedPopupContainer* Create(
- TabContents* owner, Profile* profile, const gfx::Point& initial_anchor);
-
- // Toggles the preference to display this notification.
- void ToggleBlockedPopupNotification();
-
- // Gets the current state of the show blocked popup notification preference.
- bool GetShowBlockedPopupNotification();
-
- // Adds a Tabbed contents to this container. |bounds| are the window bounds
- // requested by the popup window.
- void AddTabContents(TabContents* blocked_contents, const gfx::Rect& bounds);
-
- // Creates a window from blocked popup |index|.
- void LaunchPopupIndex(int index);
-
- // Return the number of blocked popups
- int GetTabContentsCount() const;
-
- // Returns the string to display to the user in the menu for item |index|.
- std::wstring GetDisplayStringForItem(int index);
-
- // Deletes all popups and hides the interface parts.
- void CloseAllPopups();
-
- // Called to force this container to never show itself again.
- void set_dismissed() { has_been_dismissed_ = true; }
-
- // Override from ConstrainedWindow:
- virtual void CloseConstrainedWindow();
- virtual void RepositionConstrainedWindowTo(const gfx::Point& anchor_point);
- virtual void WasHidden() { }
- virtual void DidBecomeSelected() { }
- virtual std::wstring GetWindowTitle() const;
- virtual const gfx::Rect& GetCurrentBounds() const;
-
- // Override from TabContentsDelegate:
- virtual void OpenURLFromTab(TabContents* source,
- const GURL& url, const GURL& referrer,
- WindowOpenDisposition disposition,
- PageTransition::Type transition);
- virtual void NavigationStateChanged(const TabContents* source,
- unsigned changed_flags) { }
- virtual void ReplaceContents(TabContents* source,
- TabContents* new_contents);
- virtual void AddNewContents(TabContents* source,
- TabContents* new_contents,
- WindowOpenDisposition disposition,
- const gfx::Rect& initial_pos,
- bool user_gesture);
- virtual void ActivateContents(TabContents* contents) { }
- virtual void LoadingStateChanged(TabContents* source) { }
- virtual void CloseContents(TabContents* source);
- virtual void MoveContents(TabContents* source, const gfx::Rect& pos);
- virtual bool IsPopup(TabContents* source);
- virtual TabContents* GetConstrainingContents(TabContents* source);
- virtual void ToolbarSizeChanged(TabContents* source, bool is_animating) { }
- virtual void URLStarredChanged(TabContents* source, bool starred) { }
- virtual void UpdateTargetURL(TabContents* source, const GURL& url) { }
-
- // Override from Animation:
- virtual void AnimateToState(double state);
-
- protected:
- // Override from views::ContainerWin:
- virtual void OnFinalMessage(HWND window);
- virtual void OnSize(UINT param, const CSize& size);
-
- private:
- // Create a container for a certain TabContents.
- BlockedPopupContainer(TabContents* owner, Profile* profile);
-
- // Initialize our Views and positions us to the lower right corner of the
- // browser window.
- void Init(const gfx::Point& initial_anchor);
-
- // Hides the UI portion of the container.
- void HideSelf();
-
- // Shows the UI portion of the container.
- void ShowSelf();
-
- // Sets our position, based on our |anchor_point_| and on our
- // |visibility_percentage_|. This method is called whenever either of those
- // change.
- void SetPosition();
-
- // Send a CloseContents() to each message in |blocked_popups_|.
- void CloseEachTabContents();
-
- // The TabContents that owns and constrains this BlockedPopupContainer.
- TabContents* owner_;
-
- // TabContents.
- std::vector<std::pair<TabContents*, gfx::Rect> > blocked_popups_;
-
- // Our associated view object.
- BlockedPopupContainerView* container_view_;
-
- // Link to the show blocked popup preference. Used to both determine whether
- // we should show ourself to the user...
- BooleanPrefMember block_popup_pref_;
-
- // Once the container is hidden, this is set to prevent it from reappearing.
- bool has_been_dismissed_;
-
- // True while animation in; false while animating out.
- bool in_show_animation_;
-
- // Percentage of the window to show; used to animate in the notification.
- double visibility_percentage_;
-
- // The bounds to report to the automation system (may not equal our actual
- // bounds while animating in or out).
- gfx::Rect bounds_;
-
- // The bottom right corner of where we should appear in our parent window.
- gfx::Point anchor_point_;
-
- DISALLOW_COPY_AND_ASSIGN(BlockedPopupContainer);
-};
-
-#endif
diff --git a/chrome/browser/views/browser_views.vcproj b/chrome/browser/views/browser_views.vcproj
index 3463567..4a47e9a 100644
--- a/chrome/browser/views/browser_views.vcproj
+++ b/chrome/browser/views/browser_views.vcproj
@@ -462,14 +462,6 @@
>
</File>
<File
- RelativePath=".\blocked_popup_container.cc"
- >
- </File>
- <File
- RelativePath=".\blocked_popup_container.h"
- >
- </File>
- <File
RelativePath=".\bookmark_bar_view.cc"
>
</File>
@@ -534,6 +526,14 @@
>
</File>
<File
+ RelativePath=".\constrained_window_animation.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\constrained_window_animation.h"
+ >
+ </File>
+ <File
RelativePath=".\constrained_window_impl.cc"
>
</File>
diff --git a/chrome/browser/views/constrained_window_animation.cc b/chrome/browser/views/constrained_window_animation.cc
index e69de29..cedd0ba 100644
--- a/chrome/browser/views/constrained_window_animation.cc
+++ b/chrome/browser/views/constrained_window_animation.cc
@@ -0,0 +1,31 @@
+// Copyright (c) 2006-2008 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/views/constrained_window_animation.h"
+#include "chrome/browser/views/constrained_window_impl.h"
+
+// The duration of the animation.
+static const int kDuration = 360;
+
+// The frame-rate for the animation.
+static const int kFrameRate = 60;
+
+////////////////////////////////////////////////////////////////////////////////
+// ConstrainedWindowAnimation, public:
+
+ConstrainedWindowAnimation::ConstrainedWindowAnimation(
+ ConstrainedWindowImpl* window)
+ : Animation(kDuration, kFrameRate, NULL), window_(window) {
+}
+
+ConstrainedWindowAnimation::~ConstrainedWindowAnimation() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// ConstrainedWindowAnimation, Animation implementation:
+
+void ConstrainedWindowAnimation::AnimateToState(double state) {
+ window_->SetTitlebarVisibilityPercentage(state);
+}
+
diff --git a/chrome/browser/views/constrained_window_animation.h b/chrome/browser/views/constrained_window_animation.h
index e69de29..8504155 100644
--- a/chrome/browser/views/constrained_window_animation.h
+++ b/chrome/browser/views/constrained_window_animation.h
@@ -0,0 +1,30 @@
+// Copyright (c) 2006-2008 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_VIEWS_CONSTRAINED_WINDOW_ANIMATION_H__
+#define CHROME_BROWSER_VIEWS_CONSTRAINED_WINDOW_ANIMATION_H__
+
+#include "chrome/common/animation.h"
+
+class ConstrainedWindowImpl;
+
+// Animates a titlebar of a suppressed constrained window up from the
+// bottom of the screen.
+class ConstrainedWindowAnimation : public Animation {
+ public:
+ explicit ConstrainedWindowAnimation(ConstrainedWindowImpl* window);
+ virtual ~ConstrainedWindowAnimation();
+
+ // Overridden from Animation:
+ virtual void AnimateToState(double state);
+
+ private:
+ // The constrained window we're displaying.
+ ConstrainedWindowImpl* window_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(ConstrainedWindowAnimation);
+};
+
+#endif // CHROME_BROWSER_VIEWS_CONSTRAINED_WINDOW_ANIMATION_H__
+
diff --git a/chrome/browser/views/constrained_window_impl.cc b/chrome/browser/views/constrained_window_impl.cc
index a1da56c..abd10fa 100644
--- a/chrome/browser/views/constrained_window_impl.cc
+++ b/chrome/browser/views/constrained_window_impl.cc
@@ -8,6 +8,8 @@
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/app/theme/theme_resources.h"
#include "chrome/browser/tab_contents.h"
+#include "chrome/browser/views/constrained_window_animation.h"
+#include "chrome/browser/views/location_bar_view.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/toolbar_model.h"
@@ -180,7 +182,8 @@ SkBitmap* OTRWindowResources::bitmaps_[];
class ConstrainedWindowNonClientView
: public views::NonClientView,
- public views::BaseButton::ButtonListener {
+ public views::BaseButton::ButtonListener,
+ public LocationBarView::Delegate {
public:
ConstrainedWindowNonClientView(ConstrainedWindowImpl* container,
TabContents* owner);
@@ -191,14 +194,20 @@ class ConstrainedWindowNonClientView
// Calculates the pixel height of all pieces of a window that are
// not part of the webcontent display area.
+ int CalculateNonClientHeight(bool with_url_field) const;
gfx::Rect CalculateWindowBoundsForClientBounds(
- const gfx::Rect& client_bounds) const;
+ const gfx::Rect& client_bounds,
+ bool with_url_field) const;
void UpdateWindowTitle();
void set_window_delegate(views::WindowDelegate* window_delegate) {
window_delegate_ = window_delegate;
}
+ // Changes whether we display a throbber or the current favicon and
+ // forces a repaint of the titlebar.
+ void SetShowThrobber(bool show_throbber);
+
// Overridden from views::NonClientView:
virtual gfx::Rect CalculateClientAreaBounds(int width, int height) const;
virtual gfx::Size CalculateWindowSizeForClientSize(int width,
@@ -218,11 +227,28 @@ class ConstrainedWindowNonClientView
// Overridden from views::BaseButton::ButtonListener:
virtual void ButtonPressed(views::BaseButton* sender);
+ // Overridden from LocationBarView::Delegate:
+ virtual TabContents* GetTabContents();
+ virtual void OnInputInProgress(bool in_progress);
+
+ // Updates the current throbber animation frame; called from the
+ // overloaded Run() and from SetShowThrobber().
+ void UpdateThrobber();
+
+ // Whether we should display the throbber instead of the favicon.
+ bool should_show_throbber() const {
+ return show_throbber_ && current_throbber_frame_ != -1;
+ }
+
// Paints different parts of the window to the incoming canvas.
void PaintFrameBorder(ChromeCanvas* canvas);
void PaintTitleBar(ChromeCanvas* canvas);
+ void PaintThrobber(ChromeCanvas* canvas);
void PaintWindowTitle(ChromeCanvas* canvas);
+ void UpdateLocationBar();
+ bool ShouldDisplayURLField() const;
+
SkColor GetTitleColor() const {
if (container_->owner()->profile()->IsOffTheRecord() ||
!win_util::ShouldUseVistaFrame()) {
@@ -242,14 +268,58 @@ class ConstrainedWindowNonClientView
views::Button* close_button_;
+ LocationBarView* location_bar_;
+
+ // Specialization of ToolbarModel to obtain selected NavigationController for
+ // a constrained TabContents.
+ class ConstrainedWindowToolbarModel : public ToolbarModel {
+ public:
+ ConstrainedWindowToolbarModel(ConstrainedWindowImpl* constrained_window)
+ : constrained_window_(constrained_window) {
+ }
+ ~ConstrainedWindowToolbarModel() { }
+
+ protected:
+ virtual NavigationController* GetNavigationController() {
+ TabContents* tab = constrained_window_->constrained_contents();
+ return tab ? tab->controller() : NULL;
+ }
+
+ private:
+ ConstrainedWindowImpl* constrained_window_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(ConstrainedWindowToolbarModel);
+ };
+
+ // The model used for the states of the location bar.
+ ConstrainedWindowToolbarModel toolbar_model_;
+
+ // Whether we should display the animated throbber instead of the
+ // favicon.
+ bool show_throbber_;
+
+ // The timer used to update frames for the throbber.
+ base::RepeatingTimer<ConstrainedWindowNonClientView> throbber_timer_;
+
+ // The current index into the throbber image strip.
+ int current_throbber_frame_;
+
static void InitClass();
+ // The throbber to display while a constrained window is loading.
+ static SkBitmap throbber_frames_;
+
+ // The number of animation frames in throbber_frames_.
+ static int throbber_frame_count_;
+
// The font to be used to render the titlebar text.
static ChromeFont title_font_;
DISALLOW_EVIL_CONSTRUCTORS(ConstrainedWindowNonClientView);
};
+SkBitmap ConstrainedWindowNonClientView::throbber_frames_;
+int ConstrainedWindowNonClientView::throbber_frame_count_ = -1;
ChromeFont ConstrainedWindowNonClientView::title_font_;
static const int kWindowLeftSpacing = 5;
static const int kWindowControlsTopOffset = 1;
@@ -264,9 +334,16 @@ static const int kWindowHorizontalBorderSize = 5;
static const int kWindowVerticalBorderSize = 5;
static const int kWindowIconSize = 16;
+// How much wider or shorter the location bar is relative to the client area.
+static const int kLocationBarOffset = 2;
+// Spacing between the location bar and the content area.
+static const int kLocationBarSpacing = 1;
+
static const SkColor kContentsBorderShadow = SkColorSetARGB(51, 0, 0, 0);
static const SkColor kContentsBorderColor = SkColorSetRGB(219, 235, 255);
+static const int kThrobberFrameTimeMs = 30;
+
////////////////////////////////////////////////////////////////////////////////
// ConstrainedWindowNonClientView, public:
@@ -275,7 +352,11 @@ ConstrainedWindowNonClientView::ConstrainedWindowNonClientView(
: NonClientView(),
container_(container),
window_delegate_(NULL),
- close_button_(new views::Button) {
+ close_button_(new views::Button),
+ location_bar_(NULL),
+ show_throbber_(false),
+ current_throbber_frame_(-1),
+ toolbar_model_(container) {
InitClass();
if (owner->profile()->IsOffTheRecord()) {
resources_.reset(new OTRWindowResources);
@@ -297,11 +378,43 @@ ConstrainedWindowNonClientView::ConstrainedWindowNonClientView(
views::Button::ALIGN_MIDDLE);
close_button_->SetListener(this, 0);
AddChildView(close_button_);
+
+ // Note: we don't need for a controller because no input event will be ever
+ // processed from a constrained window.
+ location_bar_ = new LocationBarView(owner->profile(),
+ NULL,
+ &toolbar_model_,
+ this,
+ true);
+ AddChildView(location_bar_);
}
ConstrainedWindowNonClientView::~ConstrainedWindowNonClientView() {
}
+void ConstrainedWindowNonClientView::UpdateLocationBar() {
+ if (ShouldDisplayURLField()) {
+ std::wstring url_spec;
+ TabContents* tab = container_->constrained_contents();
+ url_spec = gfx::ElideUrl(tab->GetURL(),
+ ChromeFont(),
+ 0,
+ tab->profile()->GetPrefs()->GetString(prefs::kAcceptLanguages));
+ std::wstring ev_text, ev_tooltip_text;
+ tab->GetSSLEVText(&ev_text, &ev_tooltip_text),
+ location_bar_->Update(NULL);
+ }
+}
+
+bool ConstrainedWindowNonClientView::ShouldDisplayURLField() const {
+ // If the dialog is not fully initialized, default to showing the URL field.
+ if (!container_ || !container_->owner() || !container_->owner()->delegate())
+ return true;
+
+ return !container_->is_dialog() &&
+ container_->owner()->delegate()->ShouldDisplayURLField();
+}
+
int ConstrainedWindowNonClientView::CalculateTitlebarHeight() const {
int height;
if (window_delegate_ && window_delegate_->ShouldShowWindowTitle()) {
@@ -313,9 +426,18 @@ int ConstrainedWindowNonClientView::CalculateTitlebarHeight() const {
return height;
}
+int ConstrainedWindowNonClientView::CalculateNonClientHeight(
+ bool with_url_field) const {
+ int r = CalculateTitlebarHeight();
+ if (with_url_field)
+ r += location_bar_->GetPreferredSize().height();
+ return r;
+}
+
gfx::Rect ConstrainedWindowNonClientView::CalculateWindowBoundsForClientBounds(
- const gfx::Rect& client_bounds) const {
- int non_client_height = CalculateTitlebarHeight();
+ const gfx::Rect& client_bounds,
+ bool with_url_field) const {
+ int non_client_height = CalculateNonClientHeight(with_url_field);
gfx::Rect window_bounds = client_bounds;
window_bounds.set_width(
window_bounds.width() + 2 * kWindowHorizontalBorderSize);
@@ -329,6 +451,25 @@ gfx::Rect ConstrainedWindowNonClientView::CalculateWindowBoundsForClientBounds(
void ConstrainedWindowNonClientView::UpdateWindowTitle() {
SchedulePaint(title_bounds_, false);
+ UpdateLocationBar();
+}
+
+void ConstrainedWindowNonClientView::SetShowThrobber(bool show_throbber) {
+ show_throbber_ = show_throbber;
+
+ if (show_throbber) {
+ if (!throbber_timer_.IsRunning())
+ throbber_timer_.Start(
+ TimeDelta::FromMilliseconds(kThrobberFrameTimeMs), this,
+ &ConstrainedWindowNonClientView::UpdateThrobber);
+ } else {
+ if (throbber_timer_.IsRunning()) {
+ throbber_timer_.Stop();
+ UpdateThrobber();
+ }
+ }
+
+ Layout();
}
////////////////////////////////////////////////////////////////////////////////
@@ -337,7 +478,7 @@ void ConstrainedWindowNonClientView::UpdateWindowTitle() {
gfx::Rect ConstrainedWindowNonClientView::CalculateClientAreaBounds(
int width,
int height) const {
- int non_client_height = CalculateTitlebarHeight();
+ int non_client_height = CalculateNonClientHeight(ShouldDisplayURLField());
return gfx::Rect(kWindowHorizontalBorderSize, non_client_height,
std::max(0, width - (2 * kWindowHorizontalBorderSize)),
std::max(0, height - non_client_height - kWindowVerticalBorderSize));
@@ -349,7 +490,8 @@ gfx::Size ConstrainedWindowNonClientView::CalculateWindowSizeForClientSize(
// This is only used for truly constrained windows, which does not include
// popups generated from a user gesture since those are detached immediately.
gfx::Rect window_bounds =
- CalculateWindowBoundsForClientBounds(gfx::Rect(0, 0, width, height));
+ CalculateWindowBoundsForClientBounds(gfx::Rect(0, 0, width, height),
+ ShouldDisplayURLField());
return window_bounds.size();
}
@@ -427,7 +569,18 @@ void ConstrainedWindowNonClientView::Paint(ChromeCanvas* canvas) {
}
void ConstrainedWindowNonClientView::Layout() {
+ bool should_display_url_field = false;
+ if (location_bar_) {
+ should_display_url_field = ShouldDisplayURLField();
+ location_bar_->SetVisible(should_display_url_field);
+ }
+
+ int location_bar_height = 0;
gfx::Size ps;
+ if (should_display_url_field) {
+ ps = location_bar_->GetPreferredSize();
+ location_bar_height = ps.height();
+ }
ps = close_button_->GetPreferredSize();
close_button_->SetBounds(width() - ps.width() - kWindowControlsRightOffset,
@@ -435,6 +588,15 @@ void ConstrainedWindowNonClientView::Layout() {
int titlebar_height = CalculateTitlebarHeight();
if (window_delegate_) {
+ if (show_throbber_) {
+ int icon_y = (titlebar_height - kWindowIconSize) / 2;
+ icon_bounds_.SetRect(kWindowLeftSpacing, icon_y, 0, 0);
+ icon_bounds_.set_width(kWindowIconSize);
+ icon_bounds_.set_height(kWindowIconSize);
+ } else {
+ icon_bounds_.SetRect(0, 0, 0, 0);
+ }
+
if (window_delegate_->ShouldShowWindowTitle()) {
int spacing = kWindowLeftSpacing;
int title_right = close_button_->x() - spacing;
@@ -451,13 +613,21 @@ void ConstrainedWindowNonClientView::Layout() {
}
client_bounds_ = CalculateClientAreaBounds(width(), height());
+ if (should_display_url_field) {
+ location_bar_->SetBounds(client_bounds_.x() - kLocationBarOffset,
+ client_bounds_.y() - location_bar_height -
+ kLocationBarSpacing,
+ client_bounds_.width() + kLocationBarOffset * 2,
+ location_bar_height);
+ location_bar_->Layout();
+ }
container_->client_view()->SetBounds(client_bounds_);
}
gfx::Size ConstrainedWindowNonClientView::GetPreferredSize() {
gfx::Size prefsize = container_->client_view()->GetPreferredSize();
- prefsize.Enlarge(2 * kWindowHorizontalBorderSize,
- CalculateTitlebarHeight() +
+ prefsize.Enlarge(2 * kWindowHorizontalBorderSize,
+ CalculateNonClientHeight(ShouldDisplayURLField()) +
kWindowVerticalBorderSize);
return prefsize;
}
@@ -470,6 +640,8 @@ void ConstrainedWindowNonClientView::ViewHierarchyChanged(bool is_add,
// subsequently resized all the parent-child relationships are established.
if (is_add && GetContainer() && child == this)
AddChildView(container_->client_view());
+ if (location_bar_ && !location_bar_->IsInitialized())
+ location_bar_->Init();
}
}
@@ -483,8 +655,27 @@ void ConstrainedWindowNonClientView::ButtonPressed(views::BaseButton* sender) {
}
////////////////////////////////////////////////////////////////////////////////
+// ConstrainedWindowNonClientView, LocationBarView::Delegate
+// implementation:
+TabContents* ConstrainedWindowNonClientView::GetTabContents() {
+ return container_->owner();
+}
+
+void ConstrainedWindowNonClientView::OnInputInProgress(bool in_progress) {
+}
+
+////////////////////////////////////////////////////////////////////////////////
// ConstrainedWindowNonClientView, private:
+void ConstrainedWindowNonClientView::UpdateThrobber() {
+ if (show_throbber_)
+ current_throbber_frame_ = ++current_throbber_frame_ % throbber_frame_count_;
+ else
+ current_throbber_frame_ = -1;
+
+ SchedulePaint();
+}
+
void ConstrainedWindowNonClientView::PaintFrameBorder(ChromeCanvas* canvas) {
SkBitmap* top_left_corner = resources_->GetPartBitmap(FRAME_TOP_LEFT_CORNER);
SkBitmap* top_right_corner =
@@ -547,11 +738,24 @@ void ConstrainedWindowNonClientView::PaintTitleBar(ChromeCanvas* canvas) {
if (!window_delegate_)
return;
+ if (should_show_throbber())
+ PaintThrobber(canvas);
+
if (window_delegate_->ShouldShowWindowTitle()) {
PaintWindowTitle(canvas);
}
}
+void ConstrainedWindowNonClientView::PaintThrobber(ChromeCanvas* canvas) {
+ int image_size = throbber_frames_.height();
+ int image_offset = current_throbber_frame_ * image_size;
+ canvas->DrawBitmapInt(throbber_frames_,
+ image_offset, 0, image_size, image_size,
+ icon_bounds_.x(), icon_bounds_.y(),
+ image_size, image_size,
+ false);
+}
+
void ConstrainedWindowNonClientView::PaintWindowTitle(ChromeCanvas* canvas) {
int title_x = MirroredLeftPointForRect(title_bounds_);
canvas->DrawStringInt(container_->GetWindowTitle(), title_font_,
@@ -563,6 +767,13 @@ void ConstrainedWindowNonClientView::PaintWindowTitle(ChromeCanvas* canvas) {
void ConstrainedWindowNonClientView::InitClass() {
static bool initialized = false;
if (!initialized) {
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+
+ throbber_frames_ = *rb.GetBitmapNamed(IDR_THROBBER);
+ DCHECK(throbber_frames_.width() % throbber_frames_.height() == 0);
+ throbber_frame_count_ =
+ throbber_frames_.width() / throbber_frames_.height();
+
title_font_ = win_util::GetWindowTitleFont();
initialized = true;
@@ -570,6 +781,44 @@ void ConstrainedWindowNonClientView::InitClass() {
}
////////////////////////////////////////////////////////////////////////////////
+// ConstrainedTabContentsWindowDelegate
+
+class ConstrainedTabContentsWindowDelegate : public views::WindowDelegate {
+ public:
+ explicit ConstrainedTabContentsWindowDelegate(TabContents* contents)
+ : contents_(contents),
+ contents_view_(NULL) {
+ }
+
+ void set_contents_view(views::View* contents_view) {
+ contents_view_ = contents_view;
+ }
+
+ // views::WindowDelegate implementation:
+ virtual bool CanResize() const {
+ return true;
+ }
+ virtual std::wstring GetWindowTitle() const {
+ return contents_->GetTitle();
+ }
+ virtual bool ShouldShowWindowIcon() const {
+ return false;
+ }
+ virtual SkBitmap GetWindowIcon() {
+ return contents_->GetFavIcon();
+ }
+ virtual views::View* GetContentsView() {
+ return contents_view_;
+ }
+
+ private:
+ TabContents* contents_;
+ views::View* contents_view_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(ConstrainedTabContentsWindowDelegate);
+};
+
+////////////////////////////////////////////////////////////////////////////////
// ConstrainedWindowImpl, public:
// The space (in pixels) between minimized pop-ups stacked horizontally and
@@ -587,11 +836,15 @@ ConstrainedWindowNonClientView* ConstrainedWindowImpl::non_client_view() {
return static_cast<ConstrainedWindowNonClientView*>(non_client_view_);
}
-void ConstrainedWindowImpl::UpdateWindowTitle() {
- UpdateUI(TabContents::INVALIDATE_TITLE);
-}
-
void ConstrainedWindowImpl::ActivateConstrainedWindow() {
+ if (CanDetach()) {
+ // Detachable pop-ups are torn out as soon as the window is activated.
+ Detach();
+ return;
+ }
+
+ StopSuppressedAnimationIfRunning();
+
// 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);
@@ -608,8 +861,21 @@ void ConstrainedWindowImpl::ActivateConstrainedWindow() {
// that case and replay them when the WebContents becomes selected.
focus_manager->StoreFocusedView();
- // Give our window the focus so we get keyboard messages.
- ::SetFocus(GetHWND());
+ if (constrained_contents_) {
+ // We contain another window, let's assume it knows how to process the
+ // focus and let's focus it.
+ // TODO(jcampan): so far this case is the WebContents case. We need to
+ // better find whether the inner window should get focus.
+ ::SetFocus(constrained_contents_->GetContainerHWND());
+ } else {
+ views::View* view_to_focus = NULL;
+ if (window_delegate())
+ view_to_focus = window_delegate()->GetInitiallyFocusedView();
+ if (view_to_focus)
+ view_to_focus->RequestFocus();
+ else // Give our window the focus so we get keyboard messages.
+ ::SetFocus(GetHWND());
+ }
}
}
@@ -624,53 +890,369 @@ void ConstrainedWindowImpl::CloseConstrainedWindow() {
Close();
}
+void ConstrainedWindowImpl::RepositionConstrainedWindowTo(
+ const gfx::Point& anchor_point) {
+ anchor_point_ = anchor_point;
+ ResizeConstrainedTitlebar();
+}
+
+bool ConstrainedWindowImpl::IsSuppressedConstrainedWindow() const {
+ return !is_dialog_;
+}
+
void ConstrainedWindowImpl::WasHidden() {
- DLOG(INFO) << "WasHidden";
+ if (constrained_contents_)
+ constrained_contents_->WasHidden();
}
void ConstrainedWindowImpl::DidBecomeSelected() {
- DLOG(INFO) << "DidBecomeSelected";
+ if (constrained_contents_)
+ constrained_contents_->DidBecomeSelected();
}
std::wstring ConstrainedWindowImpl::GetWindowTitle() const {
- std::wstring display_title;
+ // TODO(erg): (http://b/1085485) Need to decide if we what we want long term
+ // in our popup window titles.
+ std::wstring page_title;
if (window_delegate())
- display_title = window_delegate()->GetWindowTitle();
- else
- display_title = L"Untitled";
+ page_title = window_delegate()->GetWindowTitle();
+
+ std::wstring display_title;
+ bool title_set = false;
+ if (constrained_contents_) {
+ // TODO(erg): This is in the process of being translated now, but we need
+ // to do UI work so that display_title is "IDS_BLOCKED_POPUP - <page
+ // title>".
+ display_title = l10n_util::GetString(IDS_BLOCKED_POPUP);
+ title_set = true;
+ }
+
+ if (!title_set) {
+ if (page_title.empty())
+ display_title = L"Untitled";
+ else
+ display_title = page_title;
+ }
return display_title;
}
+void ConstrainedWindowImpl::UpdateWindowTitle() {
+ UpdateUI(TabContents::INVALIDATE_TITLE);
+}
+
const gfx::Rect& ConstrainedWindowImpl::GetCurrentBounds() const {
return current_bounds_;
}
////////////////////////////////////////////////////////////////////////////////
+// ConstrainedWindowImpl, TabContentsDelegate implementation:
+
+void ConstrainedWindowImpl::NavigationStateChanged(
+ const TabContents* source,
+ unsigned int changed_flags) {
+ UpdateUI(changed_flags);
+}
+
+void ConstrainedWindowImpl::ReplaceContents(TabContents* source,
+ TabContents* new_contents) {
+ source->set_delegate(NULL);
+
+ constrained_contents_ = new_contents;
+ constrained_contents_->set_delegate(this);
+ UpdateUI(TabContents::INVALIDATE_EVERYTHING);
+}
+
+void ConstrainedWindowImpl::AddNewContents(TabContents* source,
+ TabContents* new_contents,
+ WindowOpenDisposition disposition,
+ const gfx::Rect& initial_pos,
+ bool user_gesture) {
+ // Pass this to the delegate, since we can't open new tabs in the Constrained
+ // Window, they are sent up to the browser to open as new tabs.
+ owner_->AddNewContents(
+ this, new_contents, disposition, initial_pos, user_gesture);
+}
+
+void ConstrainedWindowImpl::ActivateContents(TabContents* contents) {
+ // Ask the delegate's (which is a TabContents) own TabContentsDelegate to
+ // activate itself...
+ owner_->delegate()->ActivateContents(owner_);
+
+ // Set as the foreground constrained window.
+ ActivateConstrainedWindow();
+}
+
+void ConstrainedWindowImpl::OpenURLFromTab(TabContents* source,
+ const GURL& url,
+ const GURL& referrer,
+ WindowOpenDisposition disposition,
+ PageTransition::Type transition) {
+ // We ignore source right now.
+ owner_->OpenURL(this, url, referrer, disposition, transition);
+}
+
+void ConstrainedWindowImpl::LoadingStateChanged(TabContents* source) {
+ // TODO(beng): (http://b/1085543) Implement a throbber for the Constrained
+ // Window.
+ UpdateUI(TabContents::INVALIDATE_EVERYTHING);
+ non_client_view()->SetShowThrobber(source->is_loading());
+}
+
+void ConstrainedWindowImpl::NavigateToPage(TabContents* source,
+ const GURL& url,
+ PageTransition::Type transition) {
+ UpdateUI(TabContents::INVALIDATE_EVERYTHING);
+}
+
+void ConstrainedWindowImpl::SetTitlebarVisibilityPercentage(double percentage) {
+ titlebar_visibility_ = percentage;
+ ResizeConstrainedTitlebar();
+}
+
+void ConstrainedWindowImpl::StartSuppressedAnimation() {
+ animation_.reset(new ConstrainedWindowAnimation(this));
+ animation_->Start();
+}
+
+void ConstrainedWindowImpl::StopSuppressedAnimationIfRunning() {
+ if(animation_.get()) {
+ animation_->Stop();
+ SetTitlebarVisibilityPercentage(1.0);
+ animation_.reset();
+ }
+}
+
+void ConstrainedWindowImpl::CloseContents(TabContents* source) {
+ Close();
+}
+
+void ConstrainedWindowImpl::MoveContents(TabContents* source,
+ const gfx::Rect& pos) {
+ if (!IsSuppressedConstrainedWindow())
+ SetWindowBounds(pos);
+ else
+ ResizeConstrainedWindow(pos.width(), pos.height());
+}
+
+bool ConstrainedWindowImpl::IsPopup(TabContents* source) {
+ return true;
+}
+
+TabContents* ConstrainedWindowImpl::GetConstrainingContents(
+ TabContents* source) {
+ return owner_;
+}
+
+void ConstrainedWindowImpl::ToolbarSizeChanged(TabContents* source,
+ bool finished) {
+ // We don't control the layout of anything that could be animating,
+ // so do nothing.
+}
+
+////////////////////////////////////////////////////////////////////////////////
// ConstrainedWindowImpl, private:
ConstrainedWindowImpl::ConstrainedWindowImpl(
TabContents* owner,
- views::WindowDelegate* window_delegate)
+ views::WindowDelegate* window_delegate,
+ TabContents* constrained_contents)
+ : CustomFrameWindow(window_delegate,
+ new ConstrainedWindowNonClientView(this, owner)),
+ contents_window_delegate_(window_delegate),
+ constrained_contents_(constrained_contents),
+ titlebar_visibility_(0.0) {
+ Init(owner);
+}
+
+ConstrainedWindowImpl::ConstrainedWindowImpl(
+ TabContents* owner,
+ views::WindowDelegate* window_delegate)
: CustomFrameWindow(window_delegate,
- new ConstrainedWindowNonClientView(this, owner)) {
+ new ConstrainedWindowNonClientView(this, owner)),
+ constrained_contents_(NULL) {
Init(owner);
}
void ConstrainedWindowImpl::Init(TabContents* owner) {
owner_ = owner;
focus_restoration_disabled_ = false;
+ is_dialog_ = false;
+ contents_container_ = NULL;
set_window_style(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CAPTION |
WS_THICKFRAME | WS_SYSMENU);
set_focus_on_creation(false);
}
+void ConstrainedWindowImpl::ResizeConstrainedTitlebar() {
+ DCHECK(constrained_contents_)
+ << "ResizeConstrainedTitlebar() is only valid for web popups";
+ // If we represent a web popup and we were not opened as the result of a
+ // user gesture, we override the position specified in |initial_bounds| to
+ // place ourselves at the bottom right of the parent HWND.
+ CRect this_bounds;
+ GetClientRect(&this_bounds);
+
+ ResizeConstrainedWindow(this_bounds.Width(), this_bounds.Height());
+}
+
+void ConstrainedWindowImpl::ResizeConstrainedWindow(int width, int height) {
+ DCHECK(constrained_contents_)
+ << "ResizeConstrainedTitlebar() is only valid for web popups";
+
+ // Make sure we aren't larger then our containing tab contents.
+ if (width > anchor_point_.x())
+ width = anchor_point_.x();
+
+ // Determine the height of the title bar of a constrained window, so
+ // that we can offset by that much vertically if necessary...
+ int titlebar_height = non_client_view()->CalculateTitlebarHeight();
+
+ int visible_titlebar_pixels =
+ static_cast<int>(titlebar_height * titlebar_visibility_);
+
+ int x = anchor_point_.x() - width;
+ int y = anchor_point_.y() - visible_titlebar_pixels;
+
+ // NOTE: Previously, we passed in |visible_titlebar_pixels| instead
+ // of |height|. This didn't actually change any of the properties of
+ // the child HWNDS. If we ever set the |anchor_point_| intelligently
+ // so that it deals with scrollbars, we'll need to change height
+ // back to |visible_titlebar_pixels| and find a different solution,
+ // otherwise part of the window will be displayed over the scrollbar.
+ SetWindowPos(NULL, x, y, width, height,
+ SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW);
+}
+
void ConstrainedWindowImpl::InitAsDialog(const gfx::Rect& initial_bounds) {
+ is_dialog_ = true;
non_client_view()->set_window_delegate(window_delegate());
CustomFrameWindow::Init(owner_->GetContainerHWND(), initial_bounds);
ActivateConstrainedWindow();
}
+void ConstrainedWindowImpl::InitWindowForContents(
+ TabContents* constrained_contents,
+ ConstrainedTabContentsWindowDelegate* delegate) {
+ constrained_contents_ = constrained_contents;
+ constrained_contents_->set_delegate(this);
+ contents_container_ = new views::HWNDView;
+ delegate->set_contents_view(contents_container_);
+ non_client_view()->set_window_delegate(contents_window_delegate_.get());
+}
+
+void ConstrainedWindowImpl::InitSizeForContents(
+ const gfx::Rect& initial_bounds) {
+ CustomFrameWindow::Init(owner_->GetContainerHWND(), initial_bounds);
+ contents_container_->Attach(constrained_contents_->GetContainerHWND());
+
+ // TODO(brettw) this should be done some other way, see
+ // WebContentsView::SizeContents.
+ if (constrained_contents_->AsWebContents()) {
+ // This should always be true, all constrained windows are WebContents.
+ constrained_contents_->AsWebContents()->view()->SizeContents(
+ gfx::Size(contents_container_->width(),
+ contents_container_->height()));
+ } else {
+ NOTREACHED();
+ }
+ current_bounds_ = initial_bounds;
+
+ // Note that this is HWND_TOP, not HWND_TOPMOST... this is important
+ // because otherwise the window will not be visible on top of the
+ // RenderWidgetHostView!
+ win_util::SetChildBounds(GetHWND(), GetParent(), HWND_TOP, initial_bounds,
+ kConstrainedWindowEdgePadding, 0);
+}
+
+bool ConstrainedWindowImpl::CanDetach() const {
+ // Constrained TabContentses can be detached, dialog boxes can't.
+ return constrained_contents_ ? true : false;
+}
+
+void ConstrainedWindowImpl::Detach() {
+ DCHECK(CanDetach());
+
+ StopSuppressedAnimationIfRunning();
+
+ // Tell the container not to restore focus to whatever view was focused last,
+ // since this will interfere with the new window activation in the case where
+ // a constrained window is destroyed by being detached.
+ focus_restoration_disabled_ = true;
+
+ // Detach the HWND immediately.
+ contents_container_->Detach();
+ contents_container_ = NULL;
+
+ // To try and create as seamless as possible a popup experience, web pop-ups
+ // are automatically detached when the user interacts with them. We can
+ // dial this back if we feel this is too much.
+
+ // The detached contents "should" be re-parented by the delegate's
+ // DetachContents, but we clear the delegate pointing to us just in case.
+ constrained_contents_->set_delegate(NULL);
+
+ // We want to detach the constrained window at the same position on screen
+ // as the constrained window, so we need to get its screen bounds.
+ CRect constrained_window_bounds;
+ GetBounds(&constrained_window_bounds, true);
+
+ // Obtain the constrained TabContents' size from its HWND...
+ CRect bounds;
+ ::GetWindowRect(constrained_contents_->GetContainerHWND(), &bounds);
+
+ // This block of code was added by Ben, and is simply false in any world with
+ // magic_browzr turned off. Eventually, the if block here should go away once
+ // we get rid of the old pre-magic_browzr window implementation, but for now
+ // (and at least the next beta release), it's here to stay and magic_browzr
+ // is off by default.
+ if (g_browser_process->IsUsingNewFrames()) {
+ // ... but overwrite its screen position with the screen position of its
+ // containing ConstrainedWindowImpl. We do this because the code called by
+ // |DetachContents| assumes the bounds contains position and size
+ // information similar to what is sent when a popup is not suppressed and
+ // must be opened, i.e. the position is the screen position of the top left
+ // of the detached popup window, and the size is the size of the content
+ // area.
+ bounds.SetRect(constrained_window_bounds.left,
+ constrained_window_bounds.top,
+ constrained_window_bounds.left + bounds.Width(),
+ constrained_window_bounds.top + bounds.Height());
+ }
+
+ // Save the cursor position so that we know where to send a mouse message
+ // when the new detached window is created.
+ CPoint cursor_pos;
+ ::GetCursorPos(&cursor_pos);
+ gfx::Point screen_point(cursor_pos.x, cursor_pos.y);
+
+ // Determine what aspect of the constrained frame was clicked on, so that we
+ // can continue the mouse move on this aspect of the detached frame.
+ int frame_component = static_cast<int>(OnNCHitTest(screen_point.ToPOINT()));
+
+ // Finally we actually detach the TabContents, and then clean up.
+ owner_->DetachContents(this, constrained_contents_, gfx::Rect(bounds),
+ screen_point, frame_component);
+ constrained_contents_ = NULL;
+ Close();
+}
+
+void ConstrainedWindowImpl::SetWindowBounds(const gfx::Rect& bounds) {
+ // Note: SetChildBounds ensures that the constrained window is constrained
+ // to the bounds of its parent, however there remains a bug where the
+ // window is positioned incorrectly when the outer window is opened on
+ // a monitor that has negative coords (e.g. secondary monitor to left
+ // of primary, see http://b/issue?id=967905.)
+ gfx::Size window_size = non_client_view()->CalculateWindowSizeForClientSize(
+ bounds.width(), bounds.height());
+
+ current_bounds_ = bounds;
+ current_bounds_.set_width(window_size.width());
+ current_bounds_.set_height(window_size.height());
+ win_util::SetChildBounds(GetHWND(), GetParent(), NULL, current_bounds_,
+ kConstrainedWindowEdgePadding, 0);
+}
+
void ConstrainedWindowImpl::UpdateUI(unsigned int changed_flags) {
if (changed_flags & TabContents::INVALIDATE_TITLE)
non_client_view()->UpdateWindowTitle();
@@ -700,6 +1282,20 @@ void ConstrainedWindowImpl::OnDestroy() {
focus_manager->RestoreFocusedView();
}
+ // If we have a child TabContents, we need to unhook it here so that it is
+ // not automatically WM_DESTROYed by virtue of the fact that it is part of
+ // our Window hierarchy. Rather, it needs to be destroyed just like top level
+ // TabContentses are: from OnMsgCloseACK in RenderWidgetHost. So we hide the
+ // TabContents and sever the parent relationship now. Note the GetParent
+ // check so that we don't hide and re-parent TabContentses that have been
+ // detached and re-attached into a new top level browser window via a user
+ // drag action.
+ if (constrained_contents_ &&
+ ::GetParent(constrained_contents_->GetContainerHWND()) == GetHWND()) {
+ ::ShowWindow(constrained_contents_->GetContainerHWND(), SW_HIDE);
+ ::SetParent(constrained_contents_->GetContainerHWND(), NULL);
+ }
+
// Make sure we call super so that it can do its cleanup.
Window::OnDestroy();
}
@@ -708,6 +1304,10 @@ void ConstrainedWindowImpl::OnFinalMessage(HWND window) {
// Tell our constraining TabContents that we've gone so it can update its
// list.
owner_->WillClose(this);
+ if (constrained_contents_) {
+ constrained_contents_->CloseContents();
+ constrained_contents_ = NULL;
+ }
ContainerWin::OnFinalMessage(window);
}
@@ -727,15 +1327,28 @@ void ConstrainedWindowImpl::OnGetMinMaxInfo(LPMINMAXINFO mm_info) {
LRESULT ConstrainedWindowImpl::OnMouseActivate(HWND window,
UINT hittest_code,
UINT message) {
+ // We need to store this value before we call ActivateConstrainedWindow()
+ // since the window may be detached and so this function will return false
+ // afterwards.
+ bool can_detach = CanDetach();
+
// We only detach the window if the user clicked on the title bar. That
// way, users can click inside the contents of legitimate popups obtained
// with a mouse gesture.
if (hittest_code != HTCLIENT && hittest_code != HTNOWHERE &&
hittest_code != HTCLOSE) {
ActivateConstrainedWindow();
+ } else {
+ // If the user did not click on the title bar, don't stop message
+ // propagation.
+ can_detach = false;
}
- return MA_ACTIVATE;
+ // If the popup can be detached, then we tell the parent window not to
+ // activate since we will already have adjusted activation ourselves. We also
+ // do _not_ eat the event otherwise the user will have to click again to
+ // interact with the popup.
+ return can_detach ? MA_NOACTIVATEANDEAT : MA_ACTIVATE;
}
void ConstrainedWindowImpl::OnWindowPosChanged(WINDOWPOS* window_pos) {
@@ -759,3 +1372,27 @@ ConstrainedWindow* ConstrainedWindow::CreateConstrainedDialog(
window->InitAsDialog(initial_bounds);
return window;
}
+
+// static
+ConstrainedWindow* ConstrainedWindow::CreateConstrainedPopup(
+ TabContents* parent,
+ const gfx::Rect& initial_bounds,
+ TabContents* constrained_contents) {
+ ConstrainedTabContentsWindowDelegate* d =
+ new ConstrainedTabContentsWindowDelegate(constrained_contents);
+ ConstrainedWindowImpl* window =
+ new ConstrainedWindowImpl(parent, d, constrained_contents);
+ window->InitWindowForContents(constrained_contents, d);
+
+ gfx::Rect window_bounds = window->non_client_view()->
+ CalculateWindowBoundsForClientBounds(
+ initial_bounds,
+ parent->delegate()->ShouldDisplayURLField());
+
+ window->InitSizeForContents(window_bounds);
+
+ // This is a constrained popup window and thus we need to animate it in.
+ window->StartSuppressedAnimation();
+
+ return window;
+}
diff --git a/chrome/browser/views/constrained_window_impl.h b/chrome/browser/views/constrained_window_impl.h
index f9371fe..479b173 100644
--- a/chrome/browser/views/constrained_window_impl.h
+++ b/chrome/browser/views/constrained_window_impl.h
@@ -25,31 +25,77 @@ class WindowDelegate;
// a child HWND with a custom window frame.
//
class ConstrainedWindowImpl : public ConstrainedWindow,
- public views::CustomFrameWindow {
+ public views::CustomFrameWindow,
+ public TabContentsDelegate {
public:
virtual ~ConstrainedWindowImpl();
// Returns the TabContents that constrains this Constrained Window.
TabContents* owner() const { return owner_; }
+ TabContents* constrained_contents() const { return constrained_contents_; }
// Returns the non-client view inside this Constrained Window.
// NOTE: Defining the function body here would require pulling in the
// declarations of ConstrainedWindowNonClientView, as well as all the classes
// it depends on, from the .cc file; the benefit isn't worth it.
ConstrainedWindowNonClientView* non_client_view();
- // Overridden from views::CustomFrameWindow:
- virtual void UpdateWindowTitle();
-
// Overridden from ConstrainedWindow:
virtual void CloseConstrainedWindow();
virtual void ActivateConstrainedWindow();
- virtual void RepositionConstrainedWindowTo(const gfx::Point& anchor_point) {}
+ virtual void RepositionConstrainedWindowTo(const gfx::Point& anchor_point);
+ virtual bool IsSuppressedConstrainedWindow() const;
virtual void WasHidden();
virtual void DidBecomeSelected();
virtual std::wstring GetWindowTitle() const;
+ virtual void UpdateWindowTitle();
virtual const gfx::Rect& GetCurrentBounds() const;
+ // Overridden from PageNavigator (TabContentsDelegate's base interface):
+ virtual void OpenURLFromTab(TabContents* source,
+ const GURL& url,
+ const GURL& referrer,
+ WindowOpenDisposition disposition,
+ PageTransition::Type transition);
+
+ // Overridden from TabContentsDelegate:
+ virtual void NavigationStateChanged(const TabContents* source,
+ unsigned changed_flags);
+ virtual void ReplaceContents(TabContents* source,
+ TabContents* new_contents);
+ virtual void AddNewContents(TabContents* source,
+ TabContents* new_contents,
+ WindowOpenDisposition disposition,
+ const gfx::Rect& initial_pos,
+ bool user_gesture);
+ virtual void ActivateContents(TabContents* contents);
+ virtual void LoadingStateChanged(TabContents* source);
+ virtual void CloseContents(TabContents* source);
+ virtual void MoveContents(TabContents* source, const gfx::Rect& pos);
+ virtual bool IsPopup(TabContents* source);
+ virtual TabContents* GetConstrainingContents(TabContents* source);
+ virtual void ToolbarSizeChanged(TabContents* source, bool is_animating);
+ virtual void URLStarredChanged(TabContents* source, bool) {}
+ virtual void UpdateTargetURL(TabContents* source, const GURL& url) {}
+ virtual bool CanBlur() const { return false; }
+
+ virtual void NavigateToPage(TabContents* source, const GURL& url,
+ PageTransition::Type transition);
+
+
+ bool is_dialog() { return is_dialog_; }
+
+ // Changes the visibility of the titlebar. |percentage| is a real
+ // number ranged 0,1.
+ void SetTitlebarVisibilityPercentage(double percentage);
+
+ // Starts a ConstrainedWindowAnimation to slide in the titlebar of
+ // this suppressed constrained popup window.
+ void StartSuppressedAnimation();
+
+ // Stops the ConstrainedWindowAnimation, making the entire titlebar visible.
+ void StopSuppressedAnimationIfRunning();
+
protected:
// Windows message handlers:
virtual void OnDestroy();
@@ -64,23 +110,78 @@ class ConstrainedWindowImpl : public ConstrainedWindow,
// Use the static factory methods on ConstrainedWindow to construct a
// ConstrainedWindow.
ConstrainedWindowImpl(TabContents* owner,
+ views::WindowDelegate* window_delegate,
+ TabContents* constrained_contents);
+ ConstrainedWindowImpl(TabContents* owner,
views::WindowDelegate* window_delegate);
void Init(TabContents* owner);
+ // Called after changing either the anchor point or titlebar
+ // visibility of a suppressed popup.
+ //
+ // @see RepositionConstrainedWindowTo
+ // @see SetTitlebarVisibilityPercentage
+ void ResizeConstrainedTitlebar();
+
+ // Called to change the size of a constrained window. Moves the
+ // window to the anchor point (taking titlebar visibility into
+ // account) and sets the pop up size.
+ void ResizeConstrainedWindow(int width, int height);
+
// Initialize the Constrained Window as a Constrained Dialog containing a
// views::View client area.
void InitAsDialog(const gfx::Rect& initial_bounds);
+ // Builds the underlying HWND and window delegates for a newly
+ // created popup window.
+ //
+ // We have to split the initialization process for a popup window in
+ // two because we first need to initialize a proper window delegate
+ // so that when we query for desired size, we get accurate data. If
+ // we didn't do this, windows will initialize to being smaller then
+ // the desired content size plus room for browser chrome.
+ void InitWindowForContents(TabContents* constrained_contents,
+ ConstrainedTabContentsWindowDelegate* delegate);
+
+ // Sets the initial bounds for a newly created popup window.
+ //
+ // This is the second part of the initialization process started
+ // with InitWindowForContents. For the parameter initial_bounds to
+ // have been calculated correctly, InitWindowForContents must have
+ // been run first.
+ void InitSizeForContents(const gfx::Rect& initial_bounds);
+
+ // Returns true if the Constrained Window can be detached from its owner.
+ bool CanDetach() const;
+
+ // Detach the Constrained TabContents from its owner.
+ void Detach();
+
// Updates the portions of the UI as specified in |changed_flags|.
void UpdateUI(unsigned int changed_flags);
+ // Place and size the window, constraining to the bounds of the |owner_|.
+ void SetWindowBounds(const gfx::Rect& bounds);
+
// The TabContents that owns and constrains this ConstrainedWindow.
TabContents* owner_;
+ // The TabContents constrained by |owner_|.
+ TabContents* constrained_contents_;
+
// True if focus should not be restored to whatever view was focused last
// when this window is destroyed.
bool focus_restoration_disabled_;
+ // A default views::WindowDelegate implementation for this window when
+ // a TabContents is being constrained. (For the Constrained Dialog case, the
+ // caller is required to provide the WindowDelegate).
+ scoped_ptr<views::WindowDelegate> contents_window_delegate_;
+
+ // We keep a reference on the HWNDView so we can properly detach the tab
+ // contents when detaching.
+ views::HWNDView* contents_container_;
+
// true if this window is really a constrained dialog. This is set by
// InitAsDialog().
bool is_dialog_;
@@ -89,6 +190,14 @@ class ConstrainedWindowImpl : public ConstrainedWindow,
// the constrained title bar.
gfx::Point anchor_point_;
+ // The 0,1 percentage representing what amount of a titlebar of a
+ // suppressed popup window should be visible. Used to animate those
+ // titlebars in.
+ double titlebar_visibility_;
+
+ // The animation class which animates constrained windows onto the page.
+ scoped_ptr<ConstrainedWindowAnimation> animation_;
+
// Current display rectangle (relative to owner_'s visible area).
gfx::Rect current_bounds_;
diff --git a/chrome/browser/views/constrained_window_impl_interactive_uitest.cc b/chrome/browser/views/constrained_window_impl_interactive_uitest.cc
index 5f672a3..860a009 100644
--- a/chrome/browser/views/constrained_window_impl_interactive_uitest.cc
+++ b/chrome/browser/views/constrained_window_impl_interactive_uitest.cc
@@ -92,9 +92,61 @@ TEST_F(InteractiveConstrainedWindowTest, TestOpenAndResizeTo) {
ASSERT_LT(rect.height(), 200);
}
+TEST_F(InteractiveConstrainedWindowTest, ClickingXClosesConstrained) {
+ // Clicking X on a constrained window should close the window instead of
+ // unconstrain it.
+ scoped_ptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
+ ASSERT_TRUE(browser.get());
+
+ scoped_ptr<WindowProxy> window(
+ automation()->GetWindowForBrowser(browser.get()));
+ ASSERT_TRUE(window.get());
+
+ scoped_ptr<TabProxy> tab(browser->GetTab(0));
+ ASSERT_TRUE(tab.get());
+
+ std::wstring filename(test_data_directory_);
+ file_util::AppendToPath(&filename, L"constrained_files");
+ file_util::AppendToPath(&filename,
+ L"constrained_window.html");
+ ASSERT_TRUE(tab->NavigateToURL(net::FilePathToFileURL(filename)));
+
+ // Wait for the animation to finish.
+ Sleep(1000);
+
+ // Calculate the center of the "X"
+ gfx::Rect tab_view_bounds;
+ ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_CONTAINER,
+ &tab_view_bounds, true));
+ gfx::Point constrained_close_button;
+ constrained_close_button.set_x(
+ tab_view_bounds.x() + tab_view_bounds.width() - kRightCloseButtonOffset);
+ constrained_close_button.set_y(
+ tab_view_bounds.y() + tab_view_bounds.height() -
+ kBottomCloseButtonOffset);
+
+ // Click that X.
+ POINT click_point(constrained_close_button.ToPOINT());
+ ASSERT_TRUE(window->SimulateOSClick(click_point,
+ views::Event::EF_LEFT_BUTTON_DOWN));
+
+ // Check that there is only one constrained window. (There would have been
+ // two pre-click).
+ int constrained_window_count;
+ EXPECT_TRUE(tab->WaitForChildWindowCountToChange(
+ 2, &constrained_window_count, 5000));
+ EXPECT_EQ(constrained_window_count, 1);
+
+ // Check that there is still only one window (so we know we didn't activate
+ // the constrained popup.)
+ int browser_window_count;
+ EXPECT_TRUE(automation()->GetBrowserWindowCount(&browser_window_count));
+ EXPECT_EQ(browser_window_count, 1);
+}
+
// Tests that in the window.open() equivalent of a fork bomb, we stop building
// windows.
-TEST_F(InteractiveConstrainedWindowTest, DISABLED_DontSpawnEndlessPopups) {
+TEST_F(InteractiveConstrainedWindowTest, DontSpawnEndlessPopups) {
scoped_ptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
ASSERT_TRUE(browser.get());
diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc
index 36ea812..cc415ec 100644
--- a/chrome/browser/views/frame/browser_view.cc
+++ b/chrome/browser/views/frame/browser_view.cc
@@ -113,6 +113,12 @@ void BrowserView::ShowTabContents(TabContents* contents) {
frame_->ShowTabContents(contents);
}
+void BrowserView::ContinueDetachConstrainedWindowDrag(
+ const gfx::Point& mouse_pt,
+ int frame_component) {
+ frame_->ContinueDetachConstrainedWindowDrag(mouse_pt, frame_component);
+}
+
void BrowserView::SizeToContents(const gfx::Rect& contents_bounds) {
frame_->SizeToContents(contents_bounds);
}
@@ -225,3 +231,4 @@ void BrowserView::ViewHierarchyChanged(bool is_add,
initialized_ = true;
}
}
+
diff --git a/chrome/browser/views/frame/browser_view.h b/chrome/browser/views/frame/browser_view.h
index a83d08a..5d81317 100644
--- a/chrome/browser/views/frame/browser_view.h
+++ b/chrome/browser/views/frame/browser_view.h
@@ -48,6 +48,9 @@ class BrowserView : public BrowserWindow,
virtual void Activate();
virtual void FlashFrame();
virtual void ShowTabContents(TabContents* contents);
+ virtual void ContinueDetachConstrainedWindowDrag(
+ const gfx::Point& mouse_pt,
+ int frame_component);
virtual void SizeToContents(const gfx::Rect& contents_bounds);
virtual void SetAcceleratorTable(
std::map<views::Accelerator, int>* accelerator_table);
@@ -102,3 +105,4 @@ class BrowserView : public BrowserWindow,
};
#endif // #ifndef CHROME_BROWSER_VIEWS_FRAME_BROWSER_VIEW_H_
+
diff --git a/chrome/browser/views/frame/browser_view2.cc b/chrome/browser/views/frame/browser_view2.cc
index 7081665..477a910 100644
--- a/chrome/browser/views/frame/browser_view2.cc
+++ b/chrome/browser/views/frame/browser_view2.cc
@@ -351,6 +351,40 @@ void BrowserView2::FlashFrame() {
FlashWindowEx(&fwi);
}
+void BrowserView2::ContinueDetachConstrainedWindowDrag(
+ const gfx::Point& mouse_point,
+ int frame_component) {
+ HWND vc_hwnd = GetContainer()->GetHWND();
+ if (frame_component == HTCLIENT) {
+ // If the user's mouse was over the content area of the popup when they
+ // clicked down, we need to re-play the mouse down event so as to actually
+ // send the click to the renderer. If we don't do this, the user needs to
+ // click again once the window is detached to interact.
+ HWND inner_hwnd = browser_->GetSelectedTabContents()->GetContentHWND();
+ POINT window_point = mouse_point.ToPOINT();
+ MapWindowPoints(HWND_DESKTOP, inner_hwnd, &window_point, 1);
+ PostMessage(inner_hwnd, WM_LBUTTONDOWN, MK_LBUTTON,
+ MAKELPARAM(window_point.x, window_point.y));
+ } else if (frame_component != HTNOWHERE) {
+ // The user's mouse is already moving, and the left button is down, but we
+ // need to start moving this frame, so we _post_ it a NCLBUTTONDOWN message
+ // with the corresponding frame component as supplied by the constrained
+ // window where the user clicked. This tricks Windows into believing the
+ // user just started performing that operation on the newly created window.
+ // All the frame moving and sizing is then handled automatically by
+ // Windows. We use PostMessage because we need to return to the message
+ // loop first for Windows' built in moving/sizing to be triggered.
+ POINTS pts;
+ pts.x = mouse_point.x();
+ pts.y = mouse_point.y();
+ PostMessage(vc_hwnd, WM_NCLBUTTONDOWN, frame_component,
+ reinterpret_cast<LPARAM>(&pts));
+ // Also make sure the right cursor for the action is set.
+ PostMessage(vc_hwnd, WM_SETCURSOR, reinterpret_cast<WPARAM>(vc_hwnd),
+ frame_component);
+ }
+}
+
void BrowserView2::SizeToContents(const gfx::Rect& contents_bounds) {
frame_->SizeToContents(contents_bounds);
}
@@ -1158,3 +1192,4 @@ void BrowserView2::InitClass() {
initialized = true;
}
}
+
diff --git a/chrome/browser/views/frame/browser_view2.h b/chrome/browser/views/frame/browser_view2.h
index 1399f65..a2d65f7 100644
--- a/chrome/browser/views/frame/browser_view2.h
+++ b/chrome/browser/views/frame/browser_view2.h
@@ -141,6 +141,9 @@ class BrowserView2 : public BrowserWindow,
virtual void UpdateTitleBar();
virtual void Activate();
virtual void FlashFrame();
+ virtual void ContinueDetachConstrainedWindowDrag(
+ const gfx::Point& mouse_point,
+ int frame_component);
virtual void SizeToContents(const gfx::Rect& contents_bounds);
virtual void SetAcceleratorTable(
std::map<views::Accelerator, int>* accelerator_table);
@@ -368,3 +371,4 @@ class BrowserView2 : public BrowserWindow,
};
#endif // #ifndef CHROME_BROWSER_VIEWS_FRAME_BROWSER_VIEW2_H_
+
diff --git a/chrome/browser/views/old_frames/vista_frame.cc b/chrome/browser/views/old_frames/vista_frame.cc
index 5dad752..0bc1714 100644
--- a/chrome/browser/views/old_frames/vista_frame.cc
+++ b/chrome/browser/views/old_frames/vista_frame.cc
@@ -1516,6 +1516,28 @@ TabStrip* VistaFrame::GetTabStrip() const {
return tabstrip_;
}
+void VistaFrame::ContinueDetachConstrainedWindowDrag(const gfx::Point& mouse_pt,
+ int frame_component) {
+ // Need to force a paint at this point so that the newly created window looks
+ // correct. (Otherwise parts of the tabstrip are clipped).
+ CRect cr;
+ GetClientRect(&cr);
+ PaintNow(gfx::Rect(cr));
+
+ // The user's mouse is already moving, and the left button is down, but we
+ // need to start moving this frame, so we _post_ it a NCLBUTTONDOWN message
+ // with the HTCAPTION flag to trick windows into believing the user just
+ // started dragging on the title bar. All the frame moving is then handled
+ // automatically by windows. Note that we use PostMessage here since we need
+ // to return to the message loop first otherwise Windows' built in move code
+ // will not be able to be triggered.
+ POINTS pts;
+ pts.x = mouse_pt.x();
+ pts.y = mouse_pt.y();
+ PostMessage(WM_NCLBUTTONDOWN, frame_component,
+ reinterpret_cast<LPARAM>(&pts));
+}
+
void VistaFrame::SizeToContents(const gfx::Rect& contents_bounds) {
// First we need to ensure everything has an initial size. Currently, the
// window has the wrong size, but that's OK, doing this will allow us to
diff --git a/chrome/browser/views/old_frames/vista_frame.h b/chrome/browser/views/old_frames/vista_frame.h
index a6aa6ad..ff5de5c 100644
--- a/chrome/browser/views/old_frames/vista_frame.h
+++ b/chrome/browser/views/old_frames/vista_frame.h
@@ -165,6 +165,9 @@ class VistaFrame : public BrowserWindow,
virtual void* GetPlatformID();
virtual void ShowTabContents(TabContents* contents);
virtual TabStrip* GetTabStrip() const;
+ virtual void ContinueDetachConstrainedWindowDrag(
+ const gfx::Point& mouse_pt,
+ int frame_component);
virtual void SizeToContents(const gfx::Rect& contents_bounds);
virtual void SetAcceleratorTable(
std::map<views::Accelerator, int>* accelerator_table);
@@ -408,3 +411,4 @@ class VistaFrame : public BrowserWindow,
DISALLOW_EVIL_CONSTRUCTORS(VistaFrame);
};
#endif // CHROME_BROWSER_VIEWS_OLD_FRAMES_VISTA_FRAME_H__
+
diff --git a/chrome/browser/views/old_frames/xp_frame.cc b/chrome/browser/views/old_frames/xp_frame.cc
index 5ebf22a..ca365b2 100644
--- a/chrome/browser/views/old_frames/xp_frame.cc
+++ b/chrome/browser/views/old_frames/xp_frame.cc
@@ -2385,6 +2385,35 @@ gfx::Rect XPFrame::GetNormalBounds() {
return gfx::Rect(wp.rcNormalPosition);
}
+void XPFrame::ContinueDetachConstrainedWindowDrag(const gfx::Point& mouse_pt,
+ int frame_component) {
+ // Need to force a paint at this point so that the newly created window looks
+ // correct. (Otherwise parts of the tabstrip are clipped).
+ CRect cr;
+ GetClientRect(&cr);
+ PaintNow(gfx::Rect(cr));
+
+ // The user's mouse is already moving, and the left button is down, but we
+ // need to start moving this frame, so we _post_ it a NCLBUTTONDOWN message
+ // with the HTCAPTION flag to trick windows into believing the user just
+ // started dragging on the title bar. All the frame moving is then handled
+ // automatically by windows. Note that we use PostMessage here since we need
+ // to return to the message loop first otherwise Windows' built in move code
+ // will not be able to be triggered.
+ POINTS pts;
+ pts.x = mouse_pt.x();
+ pts.y = mouse_pt.y();
+ if (frame_component == HTCAPTION) {
+ // XPFrame uses windows' standard move code, so this works.
+ PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, reinterpret_cast<LPARAM>(&pts));
+ } else {
+ // Because xpframe does its own resizing, and does not respond properly to
+ // WM_NCHITTEST, there's no reliable way for us to handle other frame
+ // component types. Alas. This will be corrected when XPFrame subclasses
+ // views::CustomFrameWindow, some day.
+ }
+}
+
void XPFrame::SizeToContents(const gfx::Rect& contents_bounds) {
// First we need to ensure everything has an initial size. Currently, the
// window has the wrong size, but that's OK, doing this will allow us to
@@ -2472,4 +2501,4 @@ void XPFrame::ShelfVisibilityChangedImpl(TabContents* current_tab) {
// tab switches).
if (needs_layout_ && current_tab)
Layout();
-}
+} \ No newline at end of file
diff --git a/chrome/browser/views/old_frames/xp_frame.h b/chrome/browser/views/old_frames/xp_frame.h
index 2f1fe5a..c73b47d 100644
--- a/chrome/browser/views/old_frames/xp_frame.h
+++ b/chrome/browser/views/old_frames/xp_frame.h
@@ -176,6 +176,8 @@ class XPFrame : public BrowserWindow,
virtual void ShowTabContents(TabContents* contents);
virtual TabStrip* GetTabStrip() const;
+ virtual void ContinueDetachConstrainedWindowDrag(const gfx::Point& mouse_pt,
+ int frame_component);
void SizeToContents(const gfx::Rect& contents_bounds);
// Returns true if the frame should be rendered in an active state.
@@ -523,3 +525,4 @@ class XPFrame : public BrowserWindow,
};
#endif // CHROME_BROWSER_VIEWS_OLD_FRAMES_XP_FRAME_H__
+
diff --git a/chrome/views/menu_button.cc b/chrome/views/menu_button.cc
index c0c3e2e..e9205b1 100644
--- a/chrome/views/menu_button.cc
+++ b/chrome/views/menu_button.cc
@@ -54,7 +54,7 @@ MenuButton::MenuButton(const std::wstring& text,
show_menu_marker_(show_menu_marker) {
if (kMenuMarker == NULL) {
kMenuMarker = ResourceBundle::GetSharedInstance()
- .GetBitmapNamed(IDR_MENU_DROPARROW);
+ .GetBitmapNamed(IDR_MENU_MARKER);
}
SetTextAlignment(TextButton::ALIGN_LEFT);
}
@@ -257,3 +257,4 @@ void MenuButton::OnMouseExited(const MouseEvent& event) {
}
} // namespace views
+