summaryrefslogtreecommitdiffstats
path: root/chrome/browser/views
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/views')
-rw-r--r--chrome/browser/views/browser_views.vcproj52
-rw-r--r--chrome/browser/views/old_frames/frame_view.cc109
-rw-r--r--chrome/browser/views/old_frames/frame_view.h70
-rw-r--r--chrome/browser/views/old_frames/point_buffer.cc60
-rw-r--r--chrome/browser/views/old_frames/point_buffer.h61
-rw-r--r--chrome/browser/views/old_frames/simple_vista_frame.cc240
-rw-r--r--chrome/browser/views/old_frames/simple_vista_frame.h85
-rw-r--r--chrome/browser/views/old_frames/simple_xp_frame.cc403
-rw-r--r--chrome/browser/views/old_frames/simple_xp_frame.h177
-rw-r--r--chrome/browser/views/old_frames/vista_frame.cc1636
-rw-r--r--chrome/browser/views/old_frames/vista_frame.h414
-rw-r--r--chrome/browser/views/old_frames/xp_frame.cc2523
-rw-r--r--chrome/browser/views/old_frames/xp_frame.h528
-rw-r--r--chrome/browser/views/tabs/tab_strip.cc1
14 files changed, 6358 insertions, 1 deletions
diff --git a/chrome/browser/views/browser_views.vcproj b/chrome/browser/views/browser_views.vcproj
index d7072d7..15054b5 100644
--- a/chrome/browser/views/browser_views.vcproj
+++ b/chrome/browser/views/browser_views.vcproj
@@ -381,6 +381,58 @@
>
</File>
</Filter>
+ <Filter
+ Name="Frame (Old)"
+ >
+ <File
+ RelativePath=".\old_frames\frame_view.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\old_frames\frame_view.h"
+ >
+ </File>
+ <File
+ RelativePath=".\old_frames\point_buffer.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\old_frames\point_buffer.h"
+ >
+ </File>
+ <File
+ RelativePath=".\old_frames\simple_vista_frame.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\old_frames\simple_vista_frame.h"
+ >
+ </File>
+ <File
+ RelativePath=".\old_frames\simple_xp_frame.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\old_frames\simple_xp_frame.h"
+ >
+ </File>
+ <File
+ RelativePath=".\old_frames\vista_frame.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\old_frames\vista_frame.h"
+ >
+ </File>
+ <File
+ RelativePath=".\old_frames\xp_frame.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\old_frames\xp_frame.h"
+ >
+ </File>
+ </Filter>
<File
RelativePath=".\about_chrome_view.cc"
>
diff --git a/chrome/browser/views/old_frames/frame_view.cc b/chrome/browser/views/old_frames/frame_view.cc
new file mode 100644
index 0000000..3375d07
--- /dev/null
+++ b/chrome/browser/views/old_frames/frame_view.cc
@@ -0,0 +1,109 @@
+// 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/old_frames/frame_view.h"
+
+#include "chrome/browser/browser_window.h"
+#include "chrome/browser/views/tabs/tab_strip.h"
+#include "chrome/common/drag_drop_types.h"
+#include "chrome/common/os_exchange_data.h"
+
+FrameView::FrameView(BrowserWindow* window)
+ : window_(window),
+ can_drop_(false),
+ forwarding_to_tab_strip_(false) {
+}
+
+void FrameView::AddViewToDropList(ChromeViews::View* view) {
+ dropable_views_.insert(view);
+}
+
+bool FrameView::CanDrop(const OSExchangeData& data) {
+ can_drop_ = (window_->GetTabStrip()->IsVisible() &&
+ !window_->GetTabStrip()->IsAnimating() &&
+ data.HasURL());
+ return can_drop_;
+}
+
+void FrameView::OnDragEntered(const ChromeViews::DropTargetEvent& event) {
+ if (can_drop_ && ShouldForwardToTabStrip(event)) {
+ forwarding_to_tab_strip_ = true;
+ scoped_ptr<ChromeViews::DropTargetEvent> mapped_event(
+ MapEventToTabStrip(event));
+ window_->GetTabStrip()->OnDragEntered(*mapped_event.get());
+ }
+}
+
+int FrameView::OnDragUpdated(const ChromeViews::DropTargetEvent& event) {
+ if (can_drop_) {
+ if (ShouldForwardToTabStrip(event)) {
+ scoped_ptr<ChromeViews::DropTargetEvent> mapped_event(
+ MapEventToTabStrip(event));
+ if (!forwarding_to_tab_strip_) {
+ window_->GetTabStrip()->OnDragEntered(*mapped_event.get());
+ forwarding_to_tab_strip_ = true;
+ }
+ return window_->GetTabStrip()->OnDragUpdated(*mapped_event.get());
+ } else if (forwarding_to_tab_strip_) {
+ forwarding_to_tab_strip_ = false;
+ window_->GetTabStrip()->OnDragExited();
+ }
+ }
+ return DragDropTypes::DRAG_NONE;
+}
+
+void FrameView::OnDragExited() {
+ if (forwarding_to_tab_strip_) {
+ forwarding_to_tab_strip_ = false;
+ window_->GetTabStrip()->OnDragExited();
+ }
+}
+
+int FrameView::OnPerformDrop(const ChromeViews::DropTargetEvent& event) {
+ if (forwarding_to_tab_strip_) {
+ forwarding_to_tab_strip_ = false;
+ scoped_ptr<ChromeViews::DropTargetEvent> mapped_event(
+ MapEventToTabStrip(event));
+ return window_->GetTabStrip()->OnPerformDrop(*mapped_event.get());
+ }
+ return DragDropTypes::DRAG_NONE;
+}
+
+bool FrameView::ShouldForwardToTabStrip(
+ const ChromeViews::DropTargetEvent& event) {
+ if (!window_->GetTabStrip()->IsVisible())
+ return false;
+
+ const int tab_y = window_->GetTabStrip()->GetY();
+ const int tab_height = window_->GetTabStrip()->GetHeight();
+ if (event.GetY() >= tab_y + tab_height)
+ return false;
+
+ if (event.GetY() >= tab_y)
+ return true;
+
+ // Mouse isn't over the tab strip. Only forward if the mouse isn't over
+ // another view on the tab strip or is over a view we were told the user can
+ // drop on.
+ ChromeViews::View* view_over_mouse =
+ GetViewForPoint(CPoint(event.GetX(), event.GetY()));
+ return (view_over_mouse == this ||
+ view_over_mouse == window_->GetTabStrip() ||
+ dropable_views_.find(view_over_mouse) != dropable_views_.end());
+}
+
+void FrameView::ViewHierarchyChanged(bool is_add, View* parent, View* child) {
+ if (!is_add)
+ dropable_views_.erase(child);
+}
+
+ChromeViews::DropTargetEvent* FrameView::MapEventToTabStrip(
+ const ChromeViews::DropTargetEvent& event) {
+ gfx::Point tab_strip_loc(event.location());
+ ConvertPointToView(this, window_->GetTabStrip(), &tab_strip_loc);
+ return new ChromeViews::DropTargetEvent(event.GetData(), tab_strip_loc.x(),
+ tab_strip_loc.y(),
+ event.GetSourceOperations());
+}
+
diff --git a/chrome/browser/views/old_frames/frame_view.h b/chrome/browser/views/old_frames/frame_view.h
new file mode 100644
index 0000000..81e3010
--- /dev/null
+++ b/chrome/browser/views/old_frames/frame_view.h
@@ -0,0 +1,70 @@
+// 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_FRAME_VIEW_H__
+#define CHROME_BROWSER_FRAME_VIEW_H__
+
+#include <set>
+
+#include "chrome/views/view.h"
+
+class BrowserWindow;
+class OSExchangeData;
+
+// FrameView is the View that contains all the views of the BrowserWindow
+// (XPFrame or VistaFrame). FrameView forwards all drag and drop messages to
+// the TabStrip.
+class FrameView : public ChromeViews::View {
+ public:
+ explicit FrameView(BrowserWindow* frame);
+ virtual ~FrameView() {}
+
+ // Adds view to the set of views that drops are allowed to occur on. You only
+ // need invoke this for views whose y-coordinate extends above the tab strip
+ // and you want to allow drops on.
+ void AddViewToDropList(ChromeViews::View* view);
+
+ protected:
+ // As long as ShouldForwardToTabStrip returns true, drag and drop methods
+ // are forwarded to the tab strip.
+ virtual bool CanDrop(const OSExchangeData& data);
+ virtual void OnDragEntered(const ChromeViews::DropTargetEvent& event);
+ virtual int OnDragUpdated(const ChromeViews::DropTargetEvent& event);
+ virtual void OnDragExited();
+ virtual int OnPerformDrop(const ChromeViews::DropTargetEvent& event);
+
+ // Returns true if the event should be forwarded to the TabStrip. This returns
+ // true if y coordinate is less than the bottom of the tab strip, and is not
+ // over another child view.
+ virtual bool ShouldForwardToTabStrip(
+ const ChromeViews::DropTargetEvent& event);
+
+ // Overriden to remove views from dropable_views_.
+ virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child);
+
+ private:
+ // Creates and returns a new DropTargetEvent in the coordinates of the
+ // TabStrip.
+ ChromeViews::DropTargetEvent* MapEventToTabStrip(
+ const ChromeViews::DropTargetEvent& event);
+
+ // The BrowserWindow we're the child of.
+ BrowserWindow* window_;
+
+ // Initially set in CanDrop by invoking the same method on the TabStrip.
+ bool can_drop_;
+
+ // If true, drag and drop events are being forwarded to the tab strip.
+ // This is used to determine when to send OnDragExited and OnDragExited
+ // to the tab strip.
+ bool forwarding_to_tab_strip_;
+
+ // Set of additional views drops are allowed on. We do NOT own these.
+ std::set<ChromeViews::View*> dropable_views_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(FrameView);
+};
+
+#endif // CHROME_BROWSER_FRAME_VIEW_H__
+
diff --git a/chrome/browser/views/old_frames/point_buffer.cc b/chrome/browser/views/old_frames/point_buffer.cc
new file mode 100644
index 0000000..e9ff263
--- /dev/null
+++ b/chrome/browser/views/old_frames/point_buffer.cc
@@ -0,0 +1,60 @@
+// 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/old_frames/point_buffer.h"
+
+#include "base/logging.h"
+
+PointBuffer::PointBuffer() : points_(NULL),
+ next_(0),
+ max_count_(0) {
+}
+
+PointBuffer::~PointBuffer() {
+ if (points_) {
+ delete []points_;
+ }
+}
+
+void PointBuffer::AddPoint(int x, int y) {
+ POINT t;
+ t.x = x;
+ t.y = y;
+ AddPoint(t);
+}
+
+void PointBuffer::AddPoint(const POINT &p) {
+ GrowPointBufferIfNeeded();
+ points_[next_++] = p;
+}
+
+HRGN PointBuffer::GetCurrentPolygonRegion() const {
+ return ::CreatePolygonRgn(points_, next_, ALTERNATE);
+}
+
+void PointBuffer::GrowPointBufferIfNeeded() {
+ if (next_ == max_count_) {
+ int nmc = 32 + (max_count_ * 2);
+ POINT *new_buffer = new POINT[nmc];
+
+ if (next_ > 0) {
+ memcpy(new_buffer, points_, sizeof(POINT) * next_);
+ delete []points_;
+ }
+
+ points_ = new_buffer;
+ max_count_ = nmc;
+ }
+}
+
+#if 0
+void PointBuffer::Log() {
+ LOG(INFO) << "PointBuffer {";
+ int i;
+ for (i=0 ; i < next_ ; i++) {
+ LOG(INFO) << "\t" << points_[i].x << ", " << points_[i].y;
+ }
+}
+#endif
+
diff --git a/chrome/browser/views/old_frames/point_buffer.h b/chrome/browser/views/old_frames/point_buffer.h
new file mode 100644
index 0000000..94a0808
--- /dev/null
+++ b/chrome/browser/views/old_frames/point_buffer.h
@@ -0,0 +1,61 @@
+// 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_OLD_FRAMES_POINT_BUFFER_H__
+#define CHROME_BROWSER_VIEWS_OLD_FRAMES_POINT_BUFFER_H__
+
+#include <windows.h>
+
+#include "base/basictypes.h"
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// PointBuffer class
+//
+// A facility to accumulate 2d points and produce polygon regions.
+//
+////////////////////////////////////////////////////////////////////////////////
+class PointBuffer {
+ public:
+
+ //
+ // Create an empty path buffer
+ //
+ PointBuffer();
+
+ ~PointBuffer();
+
+ //
+ // Add a point in the buffer
+ //
+ void AddPoint(const POINT &p);
+ void AddPoint(int x, int y);
+
+ //
+ // Return new polygon region matching the current points.
+ // It is the caller's responsability to delete the returned region by using
+ // ::DeleteObject()
+ //
+ HRGN GetCurrentPolygonRegion() const;
+
+#if 0
+ void Log();
+#endif
+
+ private:
+
+ //
+ // Grow the point buffer if we are out of space
+ //
+ void GrowPointBufferIfNeeded();
+
+ POINT *points_;
+ int next_;
+ int max_count_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(PointBuffer);
+};
+
+#endif // CHROME_BROWSER_VIEWS_OLD_FRAMES_POINT_BUFFER_H__
+
diff --git a/chrome/browser/views/old_frames/simple_vista_frame.cc b/chrome/browser/views/old_frames/simple_vista_frame.cc
new file mode 100644
index 0000000..fc25e6a
--- /dev/null
+++ b/chrome/browser/views/old_frames/simple_vista_frame.cc
@@ -0,0 +1,240 @@
+// 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/old_frames/simple_vista_frame.h"
+
+#include "chrome/app/theme/theme_resources.h"
+#include "chrome/browser/browser.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/tab_contents.h"
+#include "chrome/browser/tab_contents_container_view.h"
+#include "chrome/browser/web_app.h"
+#include "chrome/browser/web_app_icon_manager.h"
+#include "chrome/browser/web_contents.h"
+#include "chrome/common/chrome_constants.h"
+#include "chrome/common/gfx/icon_util.h"
+#include "chrome/common/l10n_util.h"
+#include "chrome/common/resource_bundle.h"
+#include "net/base/net_util.h"
+
+#include "chromium_strings.h"
+#include "generated_resources.h"
+
+// Number of frames for our throbber.
+static const int kThrobberIconCount = 24;
+
+// How outdented the location bar should be (so that the DWM client area
+// border masks the location bar frame).
+static const int kLocationBarOutdent = 2;
+// Spacing between the location bar and the content area.
+static const int kLocationBarSpacing = 1;
+
+// Each throbber frame.
+static HICON g_throbber_icons[kThrobberIconCount];
+
+static bool g_throbber_initialized = false;
+
+static void InitThrobberIcons() {
+ if (!g_throbber_initialized) {
+ ResourceBundle &rb = ResourceBundle::GetSharedInstance();
+ for (int i = 0; i < kThrobberIconCount; ++i) {
+ g_throbber_icons[i] = rb.LoadThemeIcon(IDR_THROBBER_01 + i);
+ DCHECK(g_throbber_icons[i]);
+ }
+ g_throbber_initialized = true;
+ }
+}
+
+// static
+SimpleVistaFrame* SimpleVistaFrame::CreateFrame(const gfx::Rect& bounds,
+ Browser* browser) {
+ SimpleVistaFrame* instance = new SimpleVistaFrame(browser);
+ instance->Create(NULL, bounds.ToRECT(),
+ l10n_util::GetString(IDS_PRODUCT_NAME).c_str());
+ instance->InitAfterHWNDCreated();
+ instance->SetIsOffTheRecord(browser->profile()->IsOffTheRecord());
+ ChromeViews::FocusManager::CreateFocusManager(instance->m_hWnd,
+ instance->GetRootView());
+ return instance;
+}
+
+SimpleVistaFrame::SimpleVistaFrame(Browser* browser)
+ : VistaFrame(browser),
+ throbber_running_(false),
+ throbber_frame_(0),
+ location_bar_(NULL) {
+}
+
+SimpleVistaFrame::~SimpleVistaFrame() {
+}
+
+void SimpleVistaFrame::Init() {
+ VistaFrame::Init();
+ location_bar_ = new LocationBarView(browser_->profile(),
+ browser_->controller(),
+ browser_->toolbar_model(),
+ this, true);
+ frame_view_->AddChildView(location_bar_);
+ location_bar_->Init();
+
+ // Constrained popups that were unconstrained will need to set up a
+ // throbber.
+ UpdateTitleBar();
+}
+
+void SimpleVistaFrame::SetWindowTitle(const std::wstring& title) {
+ std::wstring t;
+ if (browser_->IsApplication()) {
+ t = title;
+ } else {
+ t = Browser::ComputePopupTitle(browser_->GetSelectedTabContents()->GetURL(),
+ title);
+ }
+
+ VistaFrame::SetWindowTitle(t);
+ SetWindowText(t.c_str());
+ UpdateLocationBar();
+}
+
+void SimpleVistaFrame::ShowTabContents(TabContents* selected_contents) {
+ VistaFrame::ShowTabContents(selected_contents);
+ icon_manager_->SetContents(selected_contents);
+ UpdateLocationBar();
+}
+
+void SimpleVistaFrame::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
+ // figure out how big all the UI bits are.
+ Layout();
+
+ // These calculations are a copy from VistaFrame and we used to just use
+ // that implementation. The problem is that we overload Layout() which
+ // then references our location_bar_, which doesn't get compensated for
+ // in VistaFrame::SizeToContents().
+ CRect window_bounds, client_bounds;
+ GetBounds(&window_bounds, true);
+ GetBounds(&client_bounds, false);
+ int left_edge_width = client_bounds.left - window_bounds.left;
+ int top_edge_height = client_bounds.top - window_bounds.top +
+ location_bar_->GetHeight();
+ int right_edge_width = window_bounds.right - client_bounds.right;
+ int bottom_edge_height = window_bounds.bottom - client_bounds.bottom;
+
+ // Now resize the window. This will result in Layout() getting called again
+ // and the contents getting sized to the value specified in |contents_bounds|
+ SetWindowPos(NULL, contents_bounds.x() - left_edge_width,
+ contents_bounds.y() - top_edge_height,
+ contents_bounds.width() + left_edge_width + right_edge_width,
+ contents_bounds.height() + top_edge_height + bottom_edge_height,
+ SWP_NOZORDER | SWP_NOACTIVATE);
+}
+
+LRESULT SimpleVistaFrame::OnNCHitTest(const CPoint& pt) {
+ SetMsgHandled(false);
+ return 0;
+}
+
+LRESULT SimpleVistaFrame::OnNCCalcSize(BOOL w_param, LPARAM l_param) {
+ SetMsgHandled(false);
+ return 0;
+}
+
+void SimpleVistaFrame::OnNCLButtonDown(UINT flags, const CPoint& pt) {
+ if (flags == HTSYSMENU) {
+ POINT p = {0, 0};
+ ::ClientToScreen(*this, &p);
+ browser_->RunSimpleFrameMenu(p, *this);
+ SetMsgHandled(true);
+ } else {
+ SetMsgHandled(false);
+ }
+}
+
+void SimpleVistaFrame::StartThrobber() {
+ if (!throbber_running_) {
+ icon_manager_->SetUpdatesEnabled(false);
+ throbber_running_ = true;
+ throbber_frame_ = 0;
+ InitThrobberIcons();
+ ::SendMessage(*this, WM_SETICON, static_cast<WPARAM>(ICON_SMALL),
+ reinterpret_cast<LPARAM>(g_throbber_icons[throbber_frame_]));
+ }
+}
+
+void SimpleVistaFrame::DisplayNextThrobberFrame() {
+ throbber_frame_ = (throbber_frame_ + 1) % kThrobberIconCount;
+ ::SendMessage(*this, WM_SETICON, static_cast<WPARAM>(ICON_SMALL),
+ reinterpret_cast<LPARAM>(g_throbber_icons[throbber_frame_]));
+}
+
+bool SimpleVistaFrame::IsThrobberRunning() {
+ return throbber_running_;
+}
+
+void SimpleVistaFrame::StopThrobber() {
+ if (throbber_running_) {
+ throbber_running_ = false;
+ icon_manager_->SetUpdatesEnabled(true);
+ }
+}
+
+void SimpleVistaFrame::ValidateThrobber() {
+ if (!browser_)
+ return;
+ TabContents* tc = browser_->GetSelectedTabContents();
+ if (IsThrobberRunning()) {
+ if (!tc || !tc->is_loading())
+ StopThrobber();
+ else
+ DisplayNextThrobberFrame();
+ } else if (tc && tc->is_loading()) {
+ StartThrobber();
+ }
+}
+
+void SimpleVistaFrame::Layout() {
+ VistaFrame::Layout();
+
+ // This happens while executing Init().
+ if (!location_bar_)
+ return;
+
+ if (browser_->ShouldDisplayURLField()) {
+ TabContentsContainerView* container = GetTabContentsContainer();
+ CSize s;
+ location_bar_->GetPreferredSize(&s);
+ location_bar_->SetBounds(container->GetX() - kLocationBarOutdent,
+ container->GetY() - kLocationBarOutdent,
+ container->GetWidth() + kLocationBarOutdent * 2,
+ s.cy);
+ container->SetBounds(container->GetX(),
+ location_bar_->GetY() + location_bar_->GetHeight() -
+ kLocationBarSpacing, container->GetWidth(),
+ container->GetHeight() - location_bar_->GetHeight() +
+ 3);
+ location_bar_->SetVisible(true);
+ location_bar_->Layout();
+ } else {
+ location_bar_->SetVisible(false);
+ }
+}
+
+void SimpleVistaFrame::InitAfterHWNDCreated() {
+ icon_manager_.reset(new WebAppIconManager(*this));
+ VistaFrame::InitAfterHWNDCreated();
+}
+
+TabContents* SimpleVistaFrame::GetTabContents() {
+ return browser_->GetSelectedTabContents();
+}
+
+void SimpleVistaFrame::OnInputInProgress(bool in_progress) {
+}
+
+void SimpleVistaFrame::UpdateLocationBar() {
+ if (location_bar_ && location_bar_->IsVisible())
+ location_bar_->Update(NULL);
+}
+
diff --git a/chrome/browser/views/old_frames/simple_vista_frame.h b/chrome/browser/views/old_frames/simple_vista_frame.h
new file mode 100644
index 0000000..c267f7d
--- /dev/null
+++ b/chrome/browser/views/old_frames/simple_vista_frame.h
@@ -0,0 +1,85 @@
+// 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_OLD_FRAMES_SIMPLE_VISTA_FRAME_H__
+#define CHROME_BROWSER_VIEWS_OLD_FRAMES_SIMPLE_VISTA_FRAME_H__
+
+#include "chrome/browser/views/location_bar_view.h"
+#include "chrome/browser/views/old_frames/vista_frame.h"
+
+class WebAppIconManager;
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// A simple vista frame that contains a browser object. This frame doesn't show
+// any tab. It is used for web applications. It will likely be used in the
+// future for detached popups.
+//
+// This window simply uses the traditional Vista look and feel.
+//
+////////////////////////////////////////////////////////////////////////////////
+class SimpleVistaFrame : public VistaFrame,
+ public LocationBarView::Delegate {
+ public:
+ // Invoked by ChromeFrame::CreateChromeFrame to create a new SimpleVistaFrame.
+ // An empty |bounds| means that Windows should decide where to place the
+ // window.
+ static SimpleVistaFrame* CreateFrame(const gfx::Rect& bounds,
+ Browser* browser);
+
+ virtual ~SimpleVistaFrame();
+
+ virtual void Init();
+
+ // LocationBarView delegate.
+ virtual TabContents* GetTabContents();
+ virtual void OnInputInProgress(bool in_progress);
+
+ protected:
+ // Overridden from VistaFrame.
+ virtual bool IsTabStripVisible() const { return false; }
+ virtual bool IsToolBarVisible() const { return false; }
+ virtual bool SupportsBookmarkBar() const { return false; }
+ virtual void SetWindowTitle(const std::wstring& title);
+ virtual void ShowTabContents(TabContents* selected_contents);
+ virtual void SizeToContents(const gfx::Rect& contents_bounds);
+ virtual LRESULT OnNCHitTest(const CPoint& pt);
+ virtual LRESULT OnNCCalcSize(BOOL w_param, LPARAM l_param);
+ virtual void OnNCLButtonDown(UINT flags, const CPoint& pt);
+ virtual void ValidateThrobber();
+
+ virtual void Layout();
+
+ // Overriden to create the WebAppIconManager, then invoke super.
+ virtual void InitAfterHWNDCreated();
+
+ private:
+ explicit SimpleVistaFrame(Browser* browser);
+
+ void StartThrobber();
+ bool IsThrobberRunning();
+ void DisplayNextThrobberFrame();
+ void StopThrobber();
+
+ // Update the location bar if it is visible.
+ void UpdateLocationBar();
+
+ // Set the current window icon. Use NULL for a default icon.
+ void SetCurrentIcon(HICON icon);
+
+ // We change the window icon for the throbber.
+ bool throbber_running_;
+
+ // Current throbber frame.
+ int throbber_frame_;
+
+ // The optional location bar for popup windows.
+ LocationBarView* location_bar_;
+
+ scoped_ptr<WebAppIconManager> icon_manager_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(SimpleVistaFrame);
+};
+#endif // CHROME_BROWSER_VIEWS_OLD_FRAMES_SIMPLE_VISTA_FRAME_H__
+
diff --git a/chrome/browser/views/old_frames/simple_xp_frame.cc b/chrome/browser/views/old_frames/simple_xp_frame.cc
new file mode 100644
index 0000000..4c4d506
--- /dev/null
+++ b/chrome/browser/views/old_frames/simple_xp_frame.cc
@@ -0,0 +1,403 @@
+// 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/old_frames/simple_xp_frame.h"
+
+#include "chrome/app/theme/theme_resources.h"
+#include "base/string_util.h"
+#include "chrome/browser/browser.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/tab_contents.h"
+#include "chrome/browser/tab_contents_container_view.h"
+#include "chrome/browser/views/location_bar_view.h"
+#include "chrome/browser/views/tabs/tab.h"
+#include "chrome/browser/web_app.h"
+#include "chrome/browser/web_app_icon_manager.h"
+#include "chrome/browser/web_contents.h"
+#include "chrome/common/win_util.h"
+#include "chrome/common/chrome_constants.h"
+#include "chrome/common/gfx/chrome_canvas.h"
+#include "chrome/common/resource_bundle.h"
+#include "chrome/common/l10n_util.h"
+#include "chrome/views/focus_manager.h"
+#include "chrome/views/label.h"
+#include "chrome/views/text_field.h"
+#include "net/base/net_util.h"
+#include "SkBitmap.h"
+
+#include "chromium_strings.h"
+#include "generated_resources.h"
+
+// The title bar text color.
+static const SkColor kTitleBarTextColor = SkColorSetRGB(255, 255, 255);
+
+// How thick is the top resize bar.
+static const int kTopResizeBarHeight = 3;
+
+// Left margin on the left side of the favicon.
+static const int kFavIconMargin = 1;
+
+// Label offset.
+static const int kLabelVerticalOffset = -1;
+
+// Padding between the favicon and the text.
+static const int kFavIconPadding = 4;
+
+// Background color for the button hot state.
+static const SkColor kHotColor = SkColorSetRGB(49, 106, 197);
+
+// distance between contents and drop arrow.
+static const int kHorizMargin = 4;
+
+// Border all around the menu.
+static const int kHorizBorderSize = 2;
+static const int kVertBorderSize = 1;
+
+// 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;
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// TitleBarMenuButton implementation.
+//
+////////////////////////////////////////////////////////////////////////////////
+TitleBarMenuButton::TitleBarMenuButton(SimpleXPFrameTitleBar* title_bar)
+ : ChromeViews::MenuButton(L"", title_bar, false),
+ contents_(NULL),
+ title_bar_(title_bar) {
+ ResourceBundle &rb = ResourceBundle::GetSharedInstance();
+ drop_arrow_ = rb.GetBitmapNamed(IDR_APP_DROPARROW);
+}
+
+TitleBarMenuButton::~TitleBarMenuButton() {
+}
+
+void TitleBarMenuButton::SetContents(ChromeViews::View* contents) {
+ contents_ = contents;
+}
+
+void TitleBarMenuButton::GetPreferredSize(CSize *out) {
+ if (contents_)
+ contents_->GetPreferredSize(out);
+ else
+ out->cx = out->cy = 0;
+
+ out->cx += drop_arrow_->width() + kHorizMargin + (2 * kHorizBorderSize);
+ out->cy = std::max(drop_arrow_->height(), static_cast<int>(out->cy));
+ out->cy += (2 * kVertBorderSize);
+}
+
+void TitleBarMenuButton::Paint(ChromeCanvas* canvas) {
+ if (GetState() == TextButton::BS_HOT ||
+ GetState() == TextButton::BS_PUSHED || menu_visible_) {
+ canvas->FillRectInt(kHotColor, 0, 0, GetWidth(), GetHeight());
+ }
+
+ if (contents_) {
+ CSize s;
+ contents_->GetPreferredSize(&s);
+ // Note: we use a floating view in this case because we never want the
+ // contents to process any event.
+ PaintFloatingView(canvas,
+ contents_,
+ kVertBorderSize,
+ (GetHeight() - s.cy) / 2,
+ GetWidth() - kHorizMargin - drop_arrow_->width() -
+ (2 * kHorizBorderSize),
+ s.cy);
+ }
+
+ // We can not use the mirroring infrastructure in ChromeViews in order to
+ // mirror the drop down arrow because is is drawn directly on the canvas
+ // (instead of using a child View). Thus, we should mirror its position
+ // manually.
+ gfx::Rect arrow_bounds(GetWidth() - drop_arrow_->width() - kHorizBorderSize,
+ (GetHeight() - drop_arrow_->height()) / 2,
+ drop_arrow_->width(),
+ drop_arrow_->height());
+ arrow_bounds.set_x(MirroredLeftPointForRect(arrow_bounds));
+ canvas->DrawBitmapInt(*drop_arrow_, arrow_bounds.x(), arrow_bounds.y());
+}
+
+bool TitleBarMenuButton::OnMousePressed(const ChromeViews::MouseEvent& e) {
+ if (e.GetFlags() & ChromeViews::MouseEvent::EF_IS_DOUBLE_CLICK) {
+ if (!HitTest(WTL::CPoint(e.GetX(), e.GetY())))
+ return true;
+ title_bar_->CloseWindow();
+ return true;
+ } else {
+ return MenuButton::OnMousePressed(e);
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// SimpleXPFrameTitleBar implementation.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+SimpleXPFrameTitleBar::SimpleXPFrameTitleBar(SimpleXPFrame* parent)
+ : parent_(parent) {
+ DCHECK(parent);
+ tab_icon_.reset(new TabIconView(this));
+ tab_icon_->set_is_light(true);
+ menu_button_ = new TitleBarMenuButton(this);
+ menu_button_->SetContents(tab_icon_view());
+ AddChildView(menu_button_);
+
+ tab_icon_->Update();
+
+ label_ = new ChromeViews::Label();
+ label_->SetColor(kTitleBarTextColor);
+ label_->SetHorizontalAlignment(ChromeViews::Label::ALIGN_LEFT);
+ AddChildView(label_);
+}
+
+SimpleXPFrameTitleBar::~SimpleXPFrameTitleBar() {
+}
+
+TabContents* SimpleXPFrameTitleBar::GetCurrentTabContents() {
+ return parent_->GetCurrentContents();
+}
+
+SkBitmap SimpleXPFrameTitleBar::GetFavIcon() {
+ // Only use the favicon if we're a web application.
+ TabContents* contents = GetCurrentTabContents();
+ if (parent_->IsApplication()) {
+ TabContents* contents = GetCurrentTabContents();
+ WebContents* web_contents = contents->AsWebContents();
+ if (web_contents) {
+ // If it's a web contents, pull the favicon from the WebApp, and fallback
+ // to the icon.
+ WebApp* web_app = web_contents->web_app();
+ if (web_app && !web_app->GetFavIcon().isNull())
+ return web_app->GetFavIcon();
+ }
+ if (contents) {
+ SkBitmap favicon = contents->GetFavIcon();
+ if (!favicon.isNull())
+ return favicon;
+ }
+ }
+
+ // Otherwise, use the default icon.
+ return SkBitmap();
+}
+
+void SimpleXPFrameTitleBar::RunMenu(ChromeViews::View* source,
+ const CPoint& pt, HWND hwnd) {
+ // Make sure we calculate the menu position based on the display bounds of
+ // the menu button. The display bounds are different than the actual bounds
+ // when the UI layout is RTL and hence we use the mirroring transformation
+ // flag. We also adjust the menu position because RTL menus use a different
+ // anchor point.
+ CPoint p(menu_button_->GetX(APPLY_MIRRORING_TRANSFORMATION),
+ menu_button_->GetY() + menu_button_->GetHeight());
+
+ if (UILayoutIsRightToLeft())
+ p.x += menu_button_->GetWidth();
+ View::ConvertPointToScreen(this, &p);
+ parent_->RunMenu(p, hwnd);
+}
+
+void SimpleXPFrameTitleBar::Layout() {
+ CSize s;
+ menu_button_->GetPreferredSize(&s);
+ menu_button_->SetBounds(kFavIconMargin, (GetHeight() - s.cy) / 2,
+ s.cx, s.cy);
+ menu_button_->Layout();
+ label_->SetBounds(menu_button_->GetX() + menu_button_->GetWidth() +
+ kFavIconPadding, kLabelVerticalOffset,
+ GetWidth() - (menu_button_->GetX() +
+ menu_button_->GetWidth() + kFavIconPadding),
+ GetHeight());
+}
+
+bool SimpleXPFrameTitleBar::WillHandleMouseEvent(int x, int y) {
+ // If the locale is RTL, we must query for the bounds of the menu button in
+ // a way that returns the mirrored position and not the position set using
+ // SetX()/SetBounds().
+ CPoint p(x - menu_button_->GetX(APPLY_MIRRORING_TRANSFORMATION),
+ y - menu_button_->GetY());
+ return menu_button_->HitTest(p);
+}
+
+void SimpleXPFrameTitleBar::SetWindowTitle(std::wstring s) {
+ if (parent_->IsApplication()) {
+ std::wstring t(s);
+ Browser::FormatTitleForDisplay(&t);
+ label_->SetText(t);
+ } else {
+ label_->SetText(Browser::ComputePopupTitle(
+ GetCurrentTabContents()->GetURL(), s));
+ }
+}
+
+void SimpleXPFrameTitleBar::ValidateThrobber() {
+ tab_icon_->Update();
+ menu_button_->SchedulePaint();
+}
+
+void SimpleXPFrameTitleBar::CloseWindow() {
+ parent_->Close();
+}
+
+void SimpleXPFrameTitleBar::Update() {
+ tab_icon_->Update();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// SimpleXPFrame implementation.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+// static
+SimpleXPFrame* SimpleXPFrame::CreateFrame(const gfx::Rect& bounds,
+ Browser* browser) {
+ SimpleXPFrame* instance = new SimpleXPFrame(browser);
+ instance->Create(NULL, bounds.ToRECT(),
+ l10n_util::GetString(IDS_PRODUCT_NAME).c_str());
+ instance->InitAfterHWNDCreated();
+ instance->SetIsOffTheRecord(browser->profile()->IsOffTheRecord());
+ ChromeViews::FocusManager::CreateFocusManager(instance->m_hWnd,
+ instance->GetRootView());
+ return instance;
+}
+
+SimpleXPFrame::SimpleXPFrame(Browser* browser)
+ : XPFrame(browser),
+ title_bar_(NULL),
+ location_bar_(NULL) {
+}
+
+void SimpleXPFrame::InitAfterHWNDCreated() {
+ icon_manager_.reset(new WebAppIconManager(*this));
+ XPFrame::InitAfterHWNDCreated();
+}
+
+SimpleXPFrame::~SimpleXPFrame() {
+}
+
+void SimpleXPFrame::Init() {
+ XPFrame::Init();
+ if (IsTitleBarVisible()) {
+ title_bar_ = new SimpleXPFrameTitleBar(this);
+ GetFrameView()->AddChildView(title_bar_);
+ }
+
+ location_bar_ = new LocationBarView(browser_->profile(),
+ browser_->controller(),
+ browser_->toolbar_model(),
+ this, true);
+ GetFrameView()->AddChildView(location_bar_);
+ location_bar_->Init();
+
+ // Constrained popups that were unconstrained will need to set up a
+ // throbber.
+ UpdateTitleBar();
+}
+
+TabContents* SimpleXPFrame::GetCurrentContents() {
+ if (browser_)
+ return browser_->GetSelectedTabContents();
+ else
+ return NULL;
+}
+
+void SimpleXPFrame::Layout() {
+ XPFrame::Layout();
+ if (IsTitleBarVisible()) {
+ TabContentsContainerView* tccv = GetTabContentsContainer();
+ DCHECK(tccv);
+ title_bar_->SetBounds(tccv->GetX(), 0,
+ GetButtonXOrigin() - tccv->GetX(),
+ GetContentsYOrigin());
+ title_bar_->Layout();
+ }
+
+ if (browser_->ShouldDisplayURLField()) {
+ TabContentsContainerView* container = GetTabContentsContainer();
+ CSize s;
+ location_bar_->GetPreferredSize(&s);
+ location_bar_->SetBounds(container->GetX() - kLocationBarOffset,
+ container->GetY(),
+ container->GetWidth() + kLocationBarOffset * 2,
+ s.cy);
+ container->SetBounds(container->GetX(),
+ location_bar_->GetY() + location_bar_->GetHeight() +
+ kLocationBarSpacing, container->GetWidth(),
+ container->GetHeight() - location_bar_->GetHeight() -
+ 1);
+ location_bar_->SetVisible(true);
+ location_bar_->Layout();
+ } else {
+ location_bar_->SetVisible(false);
+ }
+}
+
+LRESULT SimpleXPFrame::OnNCHitTest(const CPoint& pt) {
+ if (IsTitleBarVisible()) {
+ CPoint p(pt);
+ ChromeViews::View::ConvertPointToView(NULL, title_bar_, &p);
+ if (!title_bar_->WillHandleMouseEvent(p.x, p.y) &&
+ p.x >= 0 && p.y >= kTopResizeBarHeight &&
+ p.x < title_bar_->GetWidth() &&
+ p.y < title_bar_->GetHeight()) {
+ return HTCAPTION;
+ }
+ }
+ return XPFrame::OnNCHitTest(pt);
+}
+
+void SimpleXPFrame::SetWindowTitle(const std::wstring& title) {
+ if (IsTitleBarVisible())
+ title_bar_->SetWindowTitle(title);
+ XPFrame::SetWindowTitle(title);
+}
+
+void SimpleXPFrame::UpdateTitleBar() {
+ if (IsTitleBarVisible()) {
+ title_bar_->Update();
+ title_bar_->SchedulePaint();
+ }
+ UpdateLocationBar();
+}
+
+void SimpleXPFrame::ValidateThrobber() {
+ if (IsTitleBarVisible())
+ title_bar_->ValidateThrobber();
+}
+
+void SimpleXPFrame::RunMenu(const CPoint& pt, HWND hwnd) {
+ browser_->RunSimpleFrameMenu(pt, hwnd);
+}
+
+void SimpleXPFrame::ShowTabContents(TabContents* selected_contents) {
+ XPFrame::ShowTabContents(selected_contents);
+
+ icon_manager_->SetContents(selected_contents);
+
+ UpdateLocationBar();
+}
+
+bool SimpleXPFrame::IsApplication() const {
+ return browser_->IsApplication();
+}
+
+void SimpleXPFrame::UpdateLocationBar() {
+ if (location_bar_ && location_bar_->IsVisible())
+ location_bar_->Update(NULL);
+}
+
+TabContents* SimpleXPFrame::GetTabContents() {
+ return GetCurrentContents();
+}
+
+void SimpleXPFrame::OnInputInProgress(bool in_progress) {
+}
+
diff --git a/chrome/browser/views/old_frames/simple_xp_frame.h b/chrome/browser/views/old_frames/simple_xp_frame.h
new file mode 100644
index 0000000..24a8a25
--- /dev/null
+++ b/chrome/browser/views/old_frames/simple_xp_frame.h
@@ -0,0 +1,177 @@
+// 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_OLD_FRAMES_SIMPLE_XP_FRAME_H__
+#define CHROME_BROWSER_VIEWS_OLD_FRAMES_SIMPLE_XP_FRAME_H__
+
+#include "chrome/browser/views/location_bar_view.h"
+#include "chrome/browser/views/old_frames/xp_frame.h"
+#include "chrome/browser/views/tab_icon_view.h"
+#include "chrome/views/menu_button.h"
+#include "chrome/views/view_menu_delegate.h"
+
+class SimpleXPFrameTitleBar;
+class WebAppIconManager;
+
+namespace ChromeViews {
+class Label;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// A simple frame that contains a browser object. This frame doesn't show any
+// tab. It is used for web applications. It will likely be used in the future
+// for detached popups.
+//
+////////////////////////////////////////////////////////////////////////////////
+class SimpleXPFrame : public XPFrame,
+ public LocationBarView::Delegate {
+ public:
+ // Invoked by ChromeFrame::CreateChromeFrame to create a new SimpleXPFrame.
+ // An empty |bounds| means that Windows should decide where to place the
+ // window.
+ static SimpleXPFrame* CreateFrame(const gfx::Rect& bounds, Browser* browser);
+
+ virtual ~SimpleXPFrame();
+
+ // Overridden from XPFrame.
+ virtual void Init();
+ virtual void Layout();
+ virtual bool IsTabStripVisible() const { return false; }
+ virtual bool IsToolBarVisible() const { return false; }
+ virtual bool SupportsBookmarkBar() const { return false; }
+#ifdef CHROME_PERSONALIZATION
+ virtual bool PersonalizationEnabled() const { return false; }
+#endif
+ virtual LRESULT OnNCHitTest(const CPoint& pt);
+ virtual void SetWindowTitle(const std::wstring& title);
+ virtual void ValidateThrobber();
+ virtual void ShowTabContents(TabContents* selected_contents);
+ virtual void UpdateTitleBar();
+
+ // Return the currently visible contents.
+ TabContents* GetCurrentContents();
+
+ void RunMenu(const CPoint& pt, HWND hwnd);
+
+ // Returns true if this popup contains a popup which has been created
+ // by a browser with a minimal chrome.
+ bool IsApplication() const;
+
+ // LocationBarView delegate.
+ virtual TabContents* GetTabContents();
+ virtual void OnInputInProgress(bool in_progress);
+
+ protected:
+ explicit SimpleXPFrame(Browser* browser);
+
+ // The default implementation has a title bar. Override if not needed.
+ virtual bool IsTitleBarVisible() { return true; }
+
+ // Overriden to create the WebAppIconManager, then invoke super.
+ virtual void InitAfterHWNDCreated();
+
+ private:
+ // Set the current window icon. Use NULL for a default icon.
+ void SetCurrentIcon(HICON icon);
+
+ // Update the location bar if it is visible.
+ void UpdateLocationBar();
+
+ // The simple frame title bar including favicon, menu and title.
+ SimpleXPFrameTitleBar* title_bar_;
+
+ // The optional URL field.
+ //SimplifiedURLField* url_field_;
+ LocationBarView* location_bar_;
+
+ // Handles the icon for web apps.
+ scoped_ptr<WebAppIconManager> icon_manager_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(SimpleXPFrame);
+};
+
+class SimpleXPFrameTitleBar;
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// A custom menu button for the custom title bar.
+//
+////////////////////////////////////////////////////////////////////////////////
+class TitleBarMenuButton : public ChromeViews::MenuButton {
+ public:
+ explicit TitleBarMenuButton(SimpleXPFrameTitleBar* title_bar);
+ virtual ~TitleBarMenuButton();
+
+ // Set the contents view which is the view presenting the menu icon.
+ void SetContents(ChromeViews::View* contents);
+
+ // overridden from View
+ virtual void GetPreferredSize(CSize *out);
+ virtual void Paint(ChromeCanvas* canvas);
+ virtual bool OnMousePressed(const ChromeViews::MouseEvent& e);
+
+ private:
+ // The drop arrow icon.
+ SkBitmap* drop_arrow_;
+
+ // The contents is an additional view positioned before the drop down.
+ ChromeViews::View* contents_;
+
+ // The title bar that created this instance.
+ SimpleXPFrameTitleBar* title_bar_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(TitleBarMenuButton);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Custom title bar.
+//
+////////////////////////////////////////////////////////////////////////////////
+class SimpleXPFrameTitleBar : public ChromeViews::View,
+ public TabIconView::TabContentsProvider,
+ public ChromeViews::ViewMenuDelegate {
+ public:
+ explicit SimpleXPFrameTitleBar(SimpleXPFrame* parent);
+ virtual ~SimpleXPFrameTitleBar();
+
+ // Overriden from TabIconView::TabContentsProvider:
+ virtual TabContents* GetCurrentTabContents();
+ virtual SkBitmap GetFavIcon();
+
+ virtual void RunMenu(ChromeViews::View* source, const CPoint& pt, HWND hwnd);
+ virtual void Layout();
+ bool WillHandleMouseEvent(int x, int y);
+ void SetWindowTitle(std::wstring s);
+ void ValidateThrobber();
+ void CloseWindow();
+
+ // Updates the state of the tab icon.
+ void Update();
+
+ TabIconView* tab_icon_view() const { return tab_icon_.get(); }
+
+ private:
+ // The menu button.
+ TitleBarMenuButton* menu_button_;
+
+ // The tab icon.
+ scoped_ptr<TabIconView> tab_icon_;
+
+ // The corresponding SimpleXPFrame.
+ SimpleXPFrame* parent_;
+
+ // The window title.
+ ChromeViews::Label* label_;
+
+ // Lazily created chrome icon. Created and used as the icon in the
+ // TabIconView for all non-Application windows.
+ SkBitmap* chrome_icon_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(SimpleXPFrameTitleBar);
+};
+
+#endif // CHROME_BROWSER_VIEWS_OLD_FRAMES_SIMPLE_XP_FRAME_H__
+
diff --git a/chrome/browser/views/old_frames/vista_frame.cc b/chrome/browser/views/old_frames/vista_frame.cc
new file mode 100644
index 0000000..faa1213
--- /dev/null
+++ b/chrome/browser/views/old_frames/vista_frame.cc
@@ -0,0 +1,1636 @@
+// 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/old_frames/vista_frame.h"
+
+#include <windows.h>
+#include <atlbase.h>
+#include <atlapp.h>
+#include <atltheme.h>
+#include <commctrl.h>
+#include <dwmapi.h>
+#include <limits>
+
+#include "base/gfx/native_theme.h"
+#include "base/logging.h"
+#include "chrome/app/theme/theme_resources.h"
+#include "chrome/browser/browser.h"
+#include "chrome/browser/browser_list.h"
+#include "chrome/browser/frame_util.h"
+#include "chrome/browser/suspend_controller.h"
+#include "chrome/browser/tab_contents.h"
+#include "chrome/browser/tab_contents_container_view.h"
+#include "chrome/browser/view_ids.h"
+#include "chrome/browser/views/bookmark_bar_view.h"
+#include "chrome/browser/views/download_shelf_view.h"
+#include "chrome/browser/views/frame/browser_view.h"
+#include "chrome/browser/views/tabs/tab_strip.h"
+#include "chrome/common/chrome_constants.h"
+#include "chrome/common/gfx/chrome_canvas.h"
+#include "chrome/common/l10n_util.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/common/resource_bundle.h"
+#include "chrome/common/win_util.h"
+#include "chrome/views/accessibility/view_accessibility.h"
+#include "chrome/views/aero_tooltip_manager.h"
+#include "chrome/views/background.h"
+#include "chrome/views/event.h"
+#include "chrome/views/hwnd_view_container.h"
+#include "chrome/views/hwnd_notification_source.h"
+
+#include "chromium_strings.h"
+#include "generated_resources.h"
+
+// By how much the toolbar overlaps with the tab strip.
+static const int kToolbarOverlapVertOffset = 3;
+
+// How much space on the right is not used for the tab strip (to provide
+// separation between the tabs and the window controls).
+static const int kTabStripRightHorizOffset = 30;
+
+static const int kResizeCornerSize = 12;
+static const int kResizeBorder = 5;
+static const int kTitlebarHeight = 14;
+static const int kTabShadowSize = 2;
+
+// The line drawn to separate tab end contents.
+static const int kSeparationLineHeight = 1;
+
+// OTR image offsets.
+static const int kOTRImageHorizMargin = 2;
+static const int kOTRImageVertMargin = 2;
+
+// Distributor logo offsets.
+static const int kDistributorLogoVerticalOffset = 3;
+
+// The DWM puts a light border around the client area - we need to
+// take this border size into account when we reduce its size so that
+// we don't draw our content border dropshadow images over the top.
+static const int kDwmBorderSize = 1;
+
+// When laying out the tabstrip, we size it such that it fits to the left of
+// the window controls. We get the bounds of the window controls by sending a
+// message to the window, but Windows answers the question assuming 96 dpi and
+// a fairly conventional screen layout (i.e. not rotated etc). So we need to
+// hack around this by making sure the tabstrip is at least this amount inset
+// from the right side of the window.
+static const int kWindowControlsMinOffset = 100;
+
+//static
+bool VistaFrame::g_initialized = FALSE;
+
+//static
+SkBitmap** VistaFrame::g_bitmaps;
+
+static const int kImageNames[] = { IDR_CONTENT_BOTTOM_CENTER,
+ IDR_CONTENT_BOTTOM_LEFT_CORNER,
+ IDR_CONTENT_BOTTOM_RIGHT_CORNER,
+ IDR_CONTENT_LEFT_SIDE,
+ IDR_CONTENT_RIGHT_SIDE,
+ IDR_CONTENT_TOP_CENTER,
+ IDR_CONTENT_TOP_LEFT_CORNER,
+ IDR_CONTENT_TOP_RIGHT_CORNER,
+};
+
+typedef enum { CT_BOTTOM_CENTER = 0, CT_BOTTOM_LEFT_CORNER,
+ CT_BOTTOM_RIGHT_CORNER, CT_LEFT_SIDE, CT_RIGHT_SIDE,
+ CT_TOP_CENTER, CT_TOP_LEFT_CORNER, CT_TOP_RIGHT_CORNER };
+
+using ChromeViews::Accelerator;
+using ChromeViews::FocusManager;
+
+//static
+VistaFrame* VistaFrame::CreateFrame(const gfx::Rect& bounds,
+ Browser* browser,
+ bool is_off_the_record) {
+ VistaFrame* instance = new VistaFrame(browser);
+ instance->Create(NULL, bounds.ToRECT(),
+ l10n_util::GetString(IDS_PRODUCT_NAME).c_str());
+ instance->InitAfterHWNDCreated();
+ instance->SetIsOffTheRecord(is_off_the_record);
+ FocusManager::CreateFocusManager(instance->m_hWnd, instance->GetRootView());
+ return instance;
+}
+
+VistaFrame::VistaFrame(Browser* browser)
+ : browser_(browser),
+ root_view_(this),
+ tabstrip_(NULL),
+ active_bookmark_bar_(NULL),
+ tab_contents_container_(NULL),
+ custom_window_enabled_(false),
+ saved_window_placement_(false),
+ on_mouse_leave_armed_(false),
+ in_drag_session_(false),
+ shelf_view_(NULL),
+ bookmark_bar_view_(NULL),
+ info_bar_view_(NULL),
+ is_off_the_record_(false),
+ off_the_record_image_(NULL),
+ distributor_logo_(NULL),
+ ignore_ncactivate_(false),
+ should_save_window_placement_(browser->GetType() != BrowserType::BROWSER),
+ browser_view_(NULL) {
+ InitializeIfNeeded();
+}
+
+void VistaFrame::InitializeIfNeeded() {
+ if (!g_initialized) {
+ ResourceBundle &rb = ResourceBundle::GetSharedInstance();
+ g_bitmaps = new SkBitmap*[arraysize(kImageNames)];
+ for (int i = 0; i < arraysize(kImageNames); i++)
+ g_bitmaps[i] = rb.GetBitmapNamed(kImageNames[i]);
+ g_initialized = TRUE;
+ }
+}
+
+VistaFrame::~VistaFrame() {
+ DestroyBrowser();
+}
+
+// On Vista (unlike on XP), we let the OS render the Windows decor (close
+// button, maximize button, etc.). Since the mirroring infrastructure in
+// ChromeViews does not rely on HWND flipping, the Windows decor on Vista are
+// not mirrored for RTL locales; that is, they appear on the upper right
+// instead of on the upper left (see bug http://b/issue?id=1128173).
+//
+// Due to the above, we need to be careful when positioning the tabstrip and
+// the OTR image. The OTR image and the tabstrip are automatically mirrored for
+// RTL locales by the mirroring infrastructure. In order to make sure they are
+// not mirrored, we flip them manually so make sure they don't overlap the
+// Windows decor. Unfortunately, there is no cleaner way to do this because the
+// current ChromeViews mirroring API does not allow mirroring the position of
+// a subset of child Views; in other words, once a View is mirrored (in our
+// case frame_view_), then the positions of all its child Views (including, in
+// our case, the OTR image and the tabstrip) are mirrored. Once bug mentioned
+// above is fixed, we won't need to perform any manual mirroring.
+void VistaFrame::Layout() {
+ CRect client_rect;
+ GetClientRect(&client_rect);
+ int width = client_rect.Width();
+ int height = client_rect.Height();
+
+ root_view_.SetBounds(0, 0, width, height);
+ frame_view_->SetBounds(0, 0, width, height);
+
+ if (IsTabStripVisible()) {
+ tabstrip_->SetVisible(true);
+ int tabstrip_x = g_bitmaps[CT_LEFT_SIDE]->width();
+ if (is_off_the_record_) {
+ off_the_record_image_->SetVisible(true);
+ CSize otr_image_size;
+ off_the_record_image_->GetPreferredSize(&otr_image_size);
+ tabstrip_x += otr_image_size.cx + (2 * kOTRImageHorizMargin);
+ gfx::Rect off_the_record_bounds;
+ if (IsZoomed()) {
+ off_the_record_bounds.SetRect(g_bitmaps[CT_LEFT_SIDE]->width(),
+ kResizeBorder,
+ otr_image_size.cx,
+ tabstrip_->GetPreferredHeight() -
+ kToolbarOverlapVertOffset + 1);
+ } else {
+ off_the_record_bounds.SetRect(g_bitmaps[CT_LEFT_SIDE]->width(),
+ kResizeBorder + kTitlebarHeight +
+ tabstrip_->GetPreferredHeight() -
+ otr_image_size.cy -
+ kToolbarOverlapVertOffset + 1,
+ otr_image_size.cx,
+ otr_image_size.cy);
+ }
+
+ if (frame_view_->UILayoutIsRightToLeft())
+ off_the_record_bounds.set_x(frame_view_->MirroredLeftPointForRect(
+ off_the_record_bounds));
+ off_the_record_image_->SetBounds(off_the_record_bounds.x(),
+ off_the_record_bounds.y(),
+ off_the_record_bounds.width(),
+ off_the_record_bounds.height());
+
+ }
+
+ // Figure out where the minimize button is for layout purposes.
+ TITLEBARINFOEX titlebar_info;
+ titlebar_info.cbSize = sizeof(TITLEBARINFOEX);
+ SendMessage(WM_GETTITLEBARINFOEX, 0, (WPARAM)&titlebar_info);
+
+ // rgrect[2] refers to the minimize button. min_offset will
+ // be the distance between the right side of the window
+ // and the minimize button.
+ CRect window_rect;
+ GetWindowRect(&window_rect);
+ int min_offset = window_rect.right - titlebar_info.rgrect[2].left;
+
+ // If we are maxmized, the tab strip will be in line with the window
+ // controls, so we need to make sure they don't overlap.
+ int zoomed_offset = 0;
+ if (distributor_logo_) {
+ if(IsZoomed()) {
+ zoomed_offset = std::max(min_offset, kWindowControlsMinOffset);
+
+ // Hide the distributor logo if we're zoomed.
+ distributor_logo_->SetVisible(false);
+ } else {
+ CSize distributor_logo_size;
+ distributor_logo_->GetPreferredSize(&distributor_logo_size);
+
+ int logo_x;
+ // Because of Bug 1128173, our Window controls aren't actually flipped
+ // on Vista, yet all our math and layout presumes that they are.
+ if (frame_view_->UILayoutIsRightToLeft())
+ logo_x = width - distributor_logo_size.cx;
+ else
+ logo_x = width - min_offset - distributor_logo_size.cx;
+
+ distributor_logo_->SetVisible(true);
+ distributor_logo_->SetBounds(logo_x,
+ kDistributorLogoVerticalOffset,
+ distributor_logo_size.cx,
+ distributor_logo_size.cy);
+ }
+ }
+
+ gfx::Rect tabstrip_bounds(tabstrip_x,
+ kResizeBorder + (IsZoomed() ?
+ kDwmBorderSize : kTitlebarHeight),
+ width - tabstrip_x - kTabStripRightHorizOffset -
+ zoomed_offset,
+ tabstrip_->GetPreferredHeight());
+ if (frame_view_->UILayoutIsRightToLeft() &&
+ (IsZoomed() || is_off_the_record_))
+ tabstrip_bounds.set_x(
+ frame_view_->MirroredLeftPointForRect(tabstrip_bounds));
+ tabstrip_->SetBounds(tabstrip_bounds.x(),
+ tabstrip_bounds.y(),
+ tabstrip_bounds.width(),
+ tabstrip_bounds.height());
+
+ frame_view_->SetContentsOffset(tabstrip_->GetY() +
+ tabstrip_->GetHeight() -
+ kToolbarOverlapVertOffset);
+ } else {
+ tabstrip_->SetBounds(0, 0, 0, 0);
+ tabstrip_->SetVisible(false);
+ if (is_off_the_record_)
+ off_the_record_image_->SetVisible(false);
+ }
+
+ int toolbar_bottom;
+ if (IsToolBarVisible()) {
+ browser_view_->SetVisible(true);
+ browser_view_->SetBounds(g_bitmaps[CT_LEFT_SIDE]->width(),
+ tabstrip_->GetY() + tabstrip_->GetHeight() -
+ kToolbarOverlapVertOffset,
+ width - g_bitmaps[CT_LEFT_SIDE]->width() -
+ g_bitmaps[CT_RIGHT_SIDE]->width(),
+ g_bitmaps[CT_TOP_CENTER]->height());
+ browser_view_->Layout();
+ toolbar_bottom = browser_view_->GetY() + browser_view_->GetHeight();
+ } else {
+ browser_view_->SetBounds(0, 0, 0, 0);
+ browser_view_->SetVisible(false);
+ toolbar_bottom = tabstrip_->GetY() + tabstrip_->GetHeight();
+ }
+ int browser_x, browser_y;
+ int browser_w, browser_h;
+
+ if (IsTabStripVisible()) {
+ browser_x = g_bitmaps[CT_LEFT_SIDE]->width();
+ browser_y = toolbar_bottom;
+ browser_w = width - g_bitmaps[CT_LEFT_SIDE]->width() -
+ g_bitmaps[CT_RIGHT_SIDE]->width();
+ browser_h = height - browser_y - g_bitmaps[CT_BOTTOM_CENTER]->height();
+ } else {
+ browser_x = 0;
+ browser_y = toolbar_bottom;
+ browser_w = width;
+ browser_h = height;
+ }
+
+ CSize preferred_size;
+ if (shelf_view_) {
+ shelf_view_->GetPreferredSize(&preferred_size);
+ shelf_view_->SetBounds(browser_x,
+ height - g_bitmaps[CT_BOTTOM_CENTER]->height() -
+ preferred_size.cy,
+ browser_w,
+ preferred_size.cy);
+ browser_h -= preferred_size.cy;
+ }
+
+ CSize bookmark_bar_size;
+ CSize info_bar_size;
+
+ if (bookmark_bar_view_.get())
+ bookmark_bar_view_->GetPreferredSize(&bookmark_bar_size);
+
+ if (info_bar_view_)
+ info_bar_view_->GetPreferredSize(&info_bar_size);
+
+ // If we're showing a bookmarks bar in the new tab page style and we
+ // have an infobar showing, we need to flip them.
+ if (info_bar_view_ &&
+ bookmark_bar_view_.get() &&
+ bookmark_bar_view_->IsNewTabPage() &&
+ !bookmark_bar_view_->IsAlwaysShown()) {
+ info_bar_view_->SetBounds(browser_x,
+ browser_y,
+ browser_w,
+ info_bar_size.cy);
+ browser_h -= info_bar_size.cy;
+
+ browser_y += info_bar_size.cy - kSeparationLineHeight;
+
+ bookmark_bar_view_->SetBounds(browser_x,
+ browser_y,
+ browser_w,
+ bookmark_bar_size.cy);
+ browser_h -= bookmark_bar_size.cy - kSeparationLineHeight;
+ browser_y += bookmark_bar_size.cy;
+ } else {
+ if (bookmark_bar_view_.get()) {
+ // We want our bookmarks bar to be responsible for drawing its own
+ // separator, so we let it overlap ours.
+ browser_y -= kSeparationLineHeight;
+
+ bookmark_bar_view_->SetBounds(browser_x,
+ browser_y,
+ browser_w,
+ bookmark_bar_size.cy);
+ browser_h -= bookmark_bar_size.cy - kSeparationLineHeight;
+ browser_y += bookmark_bar_size.cy;
+ }
+
+ if (info_bar_view_) {
+ info_bar_view_->SetBounds(browser_x,
+ browser_y,
+ browser_w,
+ info_bar_size.cy);
+ browser_h -= info_bar_size.cy;
+ browser_y += info_bar_size.cy;
+ }
+ }
+
+ // While our OnNCCalcSize handler does a good job of covering most of the
+ // cases where we need to do this, it unfortunately doesn't cover the
+ // case where we're returning from maximized mode.
+ ResetDWMFrame();
+
+ tab_contents_container_->SetBounds(browser_x,
+ browser_y,
+ browser_w,
+ browser_h);
+
+ browser_view_->LayoutStatusBubble(browser_y + browser_h);
+
+ frame_view_->SchedulePaint();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// BrowserWindow implementation
+//
+////////////////////////////////////////////////////////////////////////////////
+
+void VistaFrame::Init() {
+ FrameUtil::RegisterBrowserWindow(this);
+
+ // Link the HWND with its root view so we can retrieve the RootView from the
+ // HWND for automation purposes.
+ ChromeViews::SetRootViewForHWND(m_hWnd, &root_view_);
+
+ frame_view_ = new VistaFrameView(this);
+ root_view_.AddChildView(frame_view_);
+ root_view_.SetAccessibleName(l10n_util::GetString(IDS_PRODUCT_NAME));
+ frame_view_->SetAccessibleName(l10n_util::GetString(IDS_PRODUCT_NAME));
+
+ browser_view_ = new BrowserView(this, browser_, NULL, NULL);
+ frame_view_->AddChildView(browser_view_);
+
+ tabstrip_ = CreateTabStrip(browser_);
+ tabstrip_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_TABSTRIP));
+ frame_view_->AddChildView(tabstrip_);
+
+ ResourceBundle &rb = ResourceBundle::GetSharedInstance();
+
+ if (is_off_the_record_) {
+ off_the_record_image_ = new ChromeViews::ImageView();
+ frame_view_->AddViewToDropList(off_the_record_image_);
+ SkBitmap* otr_icon = rb.GetBitmapNamed(IDR_OTR_ICON);
+ off_the_record_image_->SetImage(*otr_icon);
+ off_the_record_image_->SetTooltipText(
+ l10n_util::GetString(IDS_OFF_THE_RECORD_TOOLTIP));
+ off_the_record_image_->SetVerticalAlignment(
+ ChromeViews::ImageView::LEADING);
+ frame_view_->AddChildView(off_the_record_image_);
+ }
+
+ SkBitmap* image = rb.GetBitmapNamed(IDR_DISTRIBUTOR_LOGO);
+ if (!image->isNull()) {
+ distributor_logo_ = new ChromeViews::ImageView();
+ frame_view_->AddViewToDropList(distributor_logo_);
+ distributor_logo_->SetImage(image);
+ frame_view_->AddChildView(distributor_logo_);
+ }
+
+ tab_contents_container_ = new TabContentsContainerView();
+ frame_view_->AddChildView(tab_contents_container_);
+
+ // Add the task manager item to the system menu before the last entry.
+ task_manager_label_text_ = l10n_util::GetString(IDS_TASKMANAGER);
+ HMENU system_menu = ::GetSystemMenu(m_hWnd, FALSE);
+ int index = ::GetMenuItemCount(system_menu) - 1;
+ if (index < 0) {
+ NOTREACHED();
+ // Paranoia check.
+ index = 0;
+ }
+
+ // First we add the separator.
+ MENUITEMINFO menu_info;
+ memset(&menu_info, 0, sizeof(MENUITEMINFO));
+ menu_info.cbSize = sizeof(MENUITEMINFO);
+ menu_info.fMask = MIIM_FTYPE;
+ menu_info.fType = MFT_SEPARATOR;
+ ::InsertMenuItem(system_menu, index, TRUE, &menu_info);
+ // Then the actual menu.
+ menu_info.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING;
+ menu_info.fType = MFT_STRING;
+ menu_info.fState = MFS_ENABLED;
+ menu_info.wID = IDC_TASKMANAGER;
+ menu_info.dwTypeData = const_cast<wchar_t*>(task_manager_label_text_.c_str());
+ ::InsertMenuItem(system_menu, index, TRUE, &menu_info);
+
+ // Register accelerators.
+ HACCEL accelerators_table = AtlLoadAccelerators(IDR_MAINFRAME);
+ DCHECK(accelerators_table);
+ FrameUtil::LoadAccelerators(this, accelerators_table, this);
+
+ ShelfVisibilityChanged();
+ root_view_.OnViewContainerCreated();
+ Layout();
+}
+
+TabStrip* VistaFrame::CreateTabStrip(Browser* browser) {
+ return new TabStrip(browser->tabstrip_model());
+}
+
+void VistaFrame::Show(int command, bool adjust_to_fit) {
+ if (adjust_to_fit)
+ win_util::AdjustWindowToFit(*this);
+ ::ShowWindow(*this, command);
+}
+
+// This is called when we receive WM_ENDSESSION. In Vista the we have 5 seconds
+// or will be forcefully terminated if we get stuck servicing this message and
+// not pump the final messages.
+void VistaFrame::OnEndSession(BOOL ending, UINT logoff) {
+ tabstrip_->AbortActiveDragSession();
+ FrameUtil::EndSession();
+}
+
+// Note: called directly by the handler macros to handle WM_CLOSE messages.
+void VistaFrame::Close() {
+ // You cannot close a frame for which there is an active originating drag
+ // session.
+ if (tabstrip_->IsDragSessionActive())
+ return;
+
+ // Give beforeunload handlers the chance to cancel the close before we hide
+ // the window below.
+ if (!browser_->ShouldCloseWindow())
+ return;
+
+ // We call this here so that the window position gets saved before moving
+ // the window into hyperspace.
+ if (!saved_window_placement_ && should_save_window_placement_ && browser_) {
+ browser_->SaveWindowPlacement();
+ browser_->SaveWindowPlacementToDatabase();
+ saved_window_placement_ = true;
+ }
+
+ if (browser_ && !browser_->tabstrip_model()->empty()) {
+ // Tab strip isn't empty. Hide the window (so it appears to have closed
+ // immediately) and close all the tabs, allowing the renderers to shut
+ // down. When the tab strip is empty we'll be called back recursively.
+ // NOTE: Don't use ShowWindow(SW_HIDE) here, otherwise end session blocks
+ // here.
+ SetWindowPos(NULL, 0, 0, 0, 0,
+ SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOMOVE |
+ SWP_NOREPOSITION | SWP_NOSIZE | SWP_NOZORDER);
+ browser_->OnWindowClosing();
+ } else {
+ // Empty tab strip, it's now safe to clean-up.
+ root_view_.OnViewContainerDestroyed();
+
+ NotificationService::current()->Notify(
+ NOTIFY_WINDOW_CLOSED, Source<HWND>(m_hWnd),
+ NotificationService::NoDetails());
+
+ DestroyWindow();
+ }
+}
+
+void* VistaFrame::GetPlatformID() {
+ return reinterpret_cast<void*>(m_hWnd);
+}
+
+void VistaFrame::SetAcceleratorTable(
+ std::map<Accelerator, int>* accelerator_table) {
+ accelerator_table_.reset(accelerator_table);
+}
+
+bool VistaFrame::GetAccelerator(int cmd_id,
+ ChromeViews::Accelerator* accelerator) {
+ std::map<ChromeViews::Accelerator, int>::iterator it =
+ accelerator_table_->begin();
+ for (; it != accelerator_table_->end(); ++it) {
+ if(it->second == cmd_id) {
+ *accelerator = it->first;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool VistaFrame::AcceleratorPressed(const Accelerator& accelerator) {
+ DCHECK(accelerator_table_.get());
+ std::map<Accelerator, int>::const_iterator iter =
+ accelerator_table_->find(accelerator);
+ DCHECK(iter != accelerator_table_->end());
+
+ int command_id = iter->second;
+ if (browser_->SupportsCommand(command_id) &&
+ browser_->IsCommandEnabled(command_id)) {
+ browser_->ExecuteCommand(command_id);
+ return true;
+ }
+ return false;
+}
+
+gfx::Rect VistaFrame::GetNormalBounds() {
+ WINDOWPLACEMENT wp;
+ wp.length = sizeof(wp);
+ const bool ret = !!GetWindowPlacement(&wp);
+ DCHECK(ret);
+ return gfx::Rect(wp.rcNormalPosition);
+}
+
+bool VistaFrame::IsMaximized() {
+ return !!IsZoomed();
+}
+
+gfx::Rect VistaFrame::GetBoundsForContentBounds(const gfx::Rect content_rect) {
+ if (tab_contents_container_->GetX() == 0 &&
+ tab_contents_container_->GetWidth() == 0) {
+ Layout();
+ }
+
+ CPoint p(0, 0);
+ ChromeViews::View::ConvertPointToViewContainer(tab_contents_container_, &p);
+ CRect bounds;
+ GetBounds(&bounds, true);
+
+ gfx::Rect r;
+ r.set_x(content_rect.x() - p.x);
+ r.set_y(content_rect.y() - p.y);
+ r.set_width(p.x + content_rect.width() +
+ (bounds.Width() - (p.x + tab_contents_container_->GetWidth())));
+ r.set_height(p.y + content_rect.height() +
+ (bounds.Height() - (p.y +
+ tab_contents_container_->GetHeight())));
+ return r;
+}
+
+void VistaFrame::InfoBubbleShowing() {
+ ignore_ncactivate_ = true;
+}
+
+ToolbarStarToggle* VistaFrame::GetStarButton() const {
+ return NULL;
+}
+
+LocationBarView* VistaFrame::GetLocationBarView() const {
+ return NULL;
+}
+
+GoButton* VistaFrame::GetGoButton() const {
+ return NULL;
+}
+
+BookmarkBarView* VistaFrame::GetBookmarkBarView() {
+ TabContents* current_tab = browser_->GetSelectedTabContents();
+ if (!current_tab || !current_tab->profile())
+ return NULL;
+
+ if (!bookmark_bar_view_.get()) {
+ bookmark_bar_view_.reset(new BookmarkBarView(current_tab->profile(),
+ browser_));
+ bookmark_bar_view_->SetParentOwned(false);
+ } else {
+ bookmark_bar_view_->SetProfile(current_tab->profile());
+ }
+ bookmark_bar_view_->SetPageNavigator(current_tab);
+ return bookmark_bar_view_.get();
+}
+
+BrowserView* VistaFrame::GetBrowserView() const {
+ return browser_view_;
+}
+
+void VistaFrame::UpdateToolbar(TabContents* contents,
+ bool should_restore_state) {
+}
+
+void VistaFrame::ProfileChanged(Profile* profile) {
+}
+
+void VistaFrame::FocusToolbar() {
+}
+
+bool VistaFrame::IsBookmarkBarVisible() const {
+ if (!bookmark_bar_view_.get())
+ return false;
+
+ if (bookmark_bar_view_->IsNewTabPage() || bookmark_bar_view_->IsAnimating())
+ return true;
+
+ CSize sz;
+ bookmark_bar_view_->GetPreferredSize(&sz);
+ // 1 is the minimum in GetPreferredSize for the bookmark bar.
+ return sz.cy > 1;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Events
+//
+////////////////////////////////////////////////////////////////////////////////
+
+LRESULT VistaFrame::OnSettingChange(UINT u_msg, WPARAM w_param, LPARAM l_param,
+ BOOL& handled) {
+ // Set this to false, if we actually handle the message, we'll set it to
+ // true below.
+ handled = FALSE;
+ if (w_param != SPI_SETWORKAREA)
+ return 0; // Return value is effectively ignored in atlwin.h.
+
+ win_util::AdjustWindowToFit(m_hWnd);
+ handled = TRUE;
+ return 0; // Return value is effectively ignored in atlwin.h.
+}
+
+LRESULT VistaFrame::OnNCActivate(BOOL param) {
+ if (ignore_ncactivate_) {
+ ignore_ncactivate_ = false;
+ return DefWindowProc(WM_NCACTIVATE, TRUE, 0);
+ }
+ SetMsgHandled(false);
+ return 0;
+}
+
+BOOL VistaFrame::OnPowerBroadcast(DWORD power_event, DWORD data) {
+ if (PBT_APMSUSPEND == power_event) {
+ SuspendController::OnSuspend(browser_->profile());
+ return TRUE;
+ } else if (PBT_APMRESUMEAUTOMATIC == power_event) {
+ SuspendController::OnResume(browser_->profile());
+ return TRUE;
+ }
+
+ SetMsgHandled(FALSE);
+ return FALSE;
+}
+
+void VistaFrame::OnThemeChanged() {
+ // Notify NativeTheme.
+ gfx::NativeTheme::instance()->CloseHandles();
+}
+
+void VistaFrame::OnMouseButtonDown(UINT flags, const CPoint& pt) {
+ if (m_hWnd == NULL) {
+ return;
+ }
+
+ if (ProcessMousePressed(pt, flags, FALSE)) {
+ SetMsgHandled(TRUE);
+ } else {
+ SetMsgHandled(FALSE);
+ }
+}
+
+void VistaFrame::OnMouseButtonUp(UINT flags, const CPoint& pt) {
+ if (m_hWnd == NULL) {
+ return;
+ }
+
+ if (in_drag_session_) {
+ ProcessMouseReleased(pt, flags);
+ }
+}
+
+void VistaFrame::OnMouseButtonDblClk(UINT flags, const CPoint& pt) {
+ if (ProcessMousePressed(pt, flags, TRUE)) {
+ SetMsgHandled(TRUE);
+ } else {
+ SetMsgHandled(FALSE);
+ }
+}
+
+void VistaFrame::OnLButtonUp(UINT flags, const CPoint& pt) {
+ OnMouseButtonUp(flags | MK_LBUTTON, pt);
+}
+
+void VistaFrame::OnMButtonUp(UINT flags, const CPoint& pt) {
+ OnMouseButtonUp(flags | MK_MBUTTON, pt);
+}
+
+void VistaFrame::OnRButtonUp(UINT flags, const CPoint& pt) {
+ OnMouseButtonUp(flags | MK_RBUTTON, pt);
+}
+
+void VistaFrame::OnNCMButtonDown(UINT flags, const CPoint& pt) {
+ // The point is in screen coordinate system so we need to convert
+ CRect window_rect;
+ GetWindowRect(&window_rect);
+ CPoint point(pt);
+ point.x -= window_rect.left;
+ point.y -= window_rect.top;
+
+ // Yes we need to add MK_MBUTTON. Windows doesn't include it
+ OnMouseButtonDown(flags | MK_MBUTTON, point);
+}
+
+void VistaFrame::OnNCRButtonDown(UINT flags, const CPoint& pt) {
+ if (flags == HTCAPTION) {
+ HMENU system_menu = ::GetSystemMenu(*this, FALSE);
+ int id = ::TrackPopupMenu(system_menu,
+ TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD,
+ pt.x,
+ pt.y,
+ 0,
+ *this,
+ NULL);
+ if (id)
+ ::SendMessage(*this,
+ WM_SYSCOMMAND,
+ id,
+ 0);
+ } else {
+ SetMsgHandled(FALSE);
+ }
+}
+
+void VistaFrame::OnMouseMove(UINT flags, const CPoint& pt) {
+ if (m_hWnd == NULL) {
+ return;
+ }
+
+ if (in_drag_session_) {
+ ProcessMouseDragged(pt, flags);
+ } else {
+ ArmOnMouseLeave();
+ ProcessMouseMoved(pt, flags);
+ }
+}
+
+void VistaFrame::OnMouseLeave() {
+ if (m_hWnd == NULL) {
+ return;
+ }
+
+ ProcessMouseExited();
+ on_mouse_leave_armed_ = false;
+}
+
+LRESULT VistaFrame::OnGetObject(UINT uMsg, WPARAM w_param, LPARAM object_id) {
+ LRESULT reference_result = static_cast<LRESULT>(0L);
+
+ // Accessibility readers will send an OBJID_CLIENT message
+ if (OBJID_CLIENT == object_id) {
+ // If our MSAA root is already created, reuse that pointer. Otherwise,
+ // create a new one.
+ if (!accessibility_root_) {
+ CComObject<ViewAccessibility>* instance = NULL;
+
+ HRESULT hr = CComObject<ViewAccessibility>::CreateInstance(&instance);
+ DCHECK(SUCCEEDED(hr));
+
+ if (!instance) {
+ // Return with failure.
+ return static_cast<LRESULT>(0L);
+ }
+
+ CComPtr<IAccessible> accessibility_instance(instance);
+
+ if (!SUCCEEDED(instance->Initialize(&root_view_))) {
+ // Return with failure.
+ return static_cast<LRESULT>(0L);
+ }
+
+ // All is well, assign the temp instance to the class smart pointer
+ accessibility_root_.Attach(accessibility_instance.Detach());
+
+ if (!accessibility_root_) {
+ // Return with failure.
+ return static_cast<LRESULT>(0L);
+ }
+
+ // Notify that an instance of IAccessible was allocated for m_hWnd
+ ::NotifyWinEvent(EVENT_OBJECT_CREATE, m_hWnd, OBJID_CLIENT,
+ CHILDID_SELF);
+ }
+
+ // Create a reference to ViewAccessibility that MSAA will marshall
+ // to the client.
+ reference_result = LresultFromObject(IID_IAccessible, w_param,
+ static_cast<IAccessible*>(accessibility_root_));
+ }
+ return reference_result;
+}
+
+void VistaFrame::OnKeyDown(TCHAR c, UINT rep_cnt, UINT flags) {
+ ChromeViews::KeyEvent event(ChromeViews::Event::ET_KEY_PRESSED, c,
+ rep_cnt, flags);
+ root_view_.ProcessKeyEvent(event);
+}
+
+void VistaFrame::OnKeyUp(TCHAR c, UINT rep_cnt, UINT flags) {
+ ChromeViews::KeyEvent event(ChromeViews::Event::ET_KEY_RELEASED, c,
+ rep_cnt, flags);
+ root_view_.ProcessKeyEvent(event);
+}
+
+LRESULT VistaFrame::OnAppCommand(
+ HWND w_param, short app_command, WORD device, int keystate) {
+ if (browser_ && !browser_->ExecuteWindowsAppCommand(app_command))
+ SetMsgHandled(FALSE);
+ return 0;
+}
+
+void VistaFrame::OnCommand(UINT notification_code,
+ int command_id,
+ HWND window) {
+ if (browser_ && browser_->SupportsCommand(command_id)) {
+ browser_->ExecuteCommand(command_id);
+ } else {
+ SetMsgHandled(FALSE);
+ }
+}
+
+void VistaFrame::OnSysCommand(UINT notification_code, CPoint click) {
+ switch (notification_code) {
+ case IDC_TASKMANAGER:
+ if (browser_)
+ browser_->ExecuteCommand(IDC_TASKMANAGER);
+ break;
+ default:
+ // Use the default implementation for any other command.
+ SetMsgHandled(FALSE);
+ break;
+ }
+}
+
+void VistaFrame::OnMove(const CSize& size) {
+ if (!saved_window_placement_ && should_save_window_placement_ )
+ browser_->SaveWindowPlacementToDatabase();
+
+ browser_->WindowMoved();
+}
+
+void VistaFrame::OnMoving(UINT param, LPRECT new_bounds) {
+ // We want to let the browser know that the window moved so that it can
+ // update the positions of any dependent WS_POPUPs
+ browser_->WindowMoved();
+}
+
+void VistaFrame::OnSize(UINT param, const CSize& size) {
+ Layout();
+
+ if (root_view_.NeedsPainting(false)) {
+ PaintNow(root_view_.GetScheduledPaintRect());
+ }
+
+ if (!saved_window_placement_ && should_save_window_placement_)
+ browser_->SaveWindowPlacementToDatabase();
+}
+
+void VistaFrame::OnFinalMessage(HWND hwnd) {
+ delete this;
+}
+
+void VistaFrame::OnNCLButtonDown(UINT flags, const CPoint& pt) {
+ SetMsgHandled(false);
+}
+
+LRESULT VistaFrame::OnNCCalcSize(BOOL w_param, LPARAM l_param) {
+ // By default the client side is set to the window size which is what
+ // we want.
+ if (w_param == TRUE) {
+ // Calculate new NCCALCSIZE_PARAMS based on custom NCA inset.
+ NCCALCSIZE_PARAMS *pncsp = reinterpret_cast<NCCALCSIZE_PARAMS*>(l_param);
+
+ // Hack necessary to stop black background flicker, we cut out
+ // resizeborder here to save us from having to do too much
+ // addition and subtraction in Layout(). We don't cut off the
+ // top + titlebar as that prevents the window controls from
+ // highlighting.
+ pncsp->rgrc[0].left = pncsp->rgrc[0].left + kResizeBorder;
+ pncsp->rgrc[0].right = pncsp->rgrc[0].right - kResizeBorder;
+ pncsp->rgrc[0].bottom = pncsp->rgrc[0].bottom - kResizeBorder;
+
+ // We need to reset the frame, as Vista resets it whenever it changes
+ // composition modes (and NCCALCSIZE is the closest thing we get to
+ // a reliable message about the change).
+ ResetDWMFrame();
+
+ SetMsgHandled(TRUE);
+ return 0;
+ }
+
+ SetMsgHandled(FALSE);
+ return 0;
+}
+
+LRESULT VistaFrame::OnNCHitTest(const CPoint& pt) {
+ SetMsgHandled(TRUE);
+
+ // Test the caption buttons
+ LRESULT l_res;
+ BOOL dwm_processed = DwmDefWindowProc(m_hWnd,
+ WM_NCHITTEST,
+ 0,
+ (LPARAM)MAKELONG(pt.x, pt.y),
+ &l_res);
+
+ if (dwm_processed) {
+ return l_res;
+ }
+
+ CRect cr;
+ GetBounds(&cr, false);
+
+ CPoint tab_pt(pt);
+ ChromeViews::View::ConvertPointToView(NULL, tabstrip_, &tab_pt);
+
+ // If we are over the tabstrip
+ if (tab_pt.x > 0 && tab_pt.y >= kTabShadowSize &&
+ tab_pt.x < tabstrip_->GetWidth() &&
+ tab_pt.y < tabstrip_->GetHeight()) {
+ ChromeViews::View* v = tabstrip_->GetViewForPoint(tab_pt);
+ if (v == tabstrip_)
+ return HTCAPTION;
+
+ // If the view under mouse is a tab, check if the tab strip allows tab
+ // dragging or not. If not, return caption to get window dragging.
+ if (v->GetClassName() == Tab::kTabClassName &&
+ !tabstrip_->HasAvailableDragActions())
+ return HTCAPTION;
+
+ return HTCLIENT;
+ }
+
+ CPoint p(pt);
+ CRect r;
+ GetWindowRect(&r);
+
+ // Convert from screen to window coordinates
+ p.x -= r.left;
+ p.y -= r.top;
+
+ if (p.x < kResizeBorder + g_bitmaps[CT_LEFT_SIDE]->width()) {
+ if (p.y < kResizeCornerSize) {
+ return HTTOPLEFT;
+ } else if (p.y >= (r.Height() - kResizeCornerSize)) {
+ return HTBOTTOMLEFT;
+ } else {
+ return HTLEFT;
+ }
+ // BOTTOM_LEFT / TOP_LEFT horizontal extensions
+ } else if (p.x < kResizeCornerSize) {
+ if (p.y < kResizeBorder) {
+ return HTTOPLEFT;
+ } else if (p.y >= (r.Height() - kResizeBorder)) {
+ return HTBOTTOMLEFT;
+ }
+ // EAST / BOTTOMRIGHT / TOPRIGHT edge
+ } else if (p.x >= (r.Width() - kResizeBorder -
+ g_bitmaps[CT_RIGHT_SIDE]->width())) {
+ if (p.y < kResizeCornerSize) {
+ return HTTOPRIGHT;
+ } else if (p.y >= (r.Height() - kResizeCornerSize)) {
+ return HTBOTTOMRIGHT;
+ } else {
+ return HTRIGHT;
+ }
+ // EAST / BOTTOMRIGHT / TOPRIGHT horizontal extensions
+ } else if (p.x >= (r.Width() - kResizeCornerSize)) {
+ if (p.y < kResizeBorder) {
+ return HTTOPRIGHT;
+ } else if (p.y >= (r.Height() - kResizeBorder)) {
+ return HTBOTTOMRIGHT;
+ }
+ // TOP edge
+ } else if (p.y < kResizeBorder) {
+ return HTTOP;
+ // BOTTOM edge
+ } else if (p.y >= (r.Height() - kResizeBorder -
+ g_bitmaps[CT_BOTTOM_CENTER]->height())) {
+ return HTBOTTOM;
+ }
+
+ if (p.y <= tabstrip_->GetY() + tabstrip_->GetHeight()) {
+ return HTCAPTION;
+ }
+
+ SetMsgHandled(FALSE);
+ return 0;
+}
+
+void VistaFrame::OnActivate(UINT n_state, BOOL is_minimized, HWND other) {
+ if (FrameUtil::ActivateAppModalDialog(browser_))
+ return;
+
+ // Enable our custom window if we haven't already (this works in combination
+ // with our NCCALCSIZE handler).
+ if (!custom_window_enabled_) {
+ RECT rcClient;
+ ::GetWindowRect(m_hWnd, &rcClient);
+ ::SetWindowPos(
+ m_hWnd,
+ NULL,
+ rcClient.left, rcClient.top,
+ rcClient.right - rcClient.left, rcClient.bottom - rcClient.top,
+ SWP_FRAMECHANGED);
+ custom_window_enabled_ = true;
+
+ // We need to fire this here as well as in OnNCCalcSize, as that function
+ // does not fire at the right time for this to work when opening the
+ // window.
+ ResetDWMFrame();
+ }
+
+ SetMsgHandled(FALSE);
+ if (!is_minimized)
+ browser_->WindowActivationChanged(n_state != WA_INACTIVE);
+}
+
+int VistaFrame::OnMouseActivate(CWindow wndTopLevel, UINT nHitTest,
+ UINT message) {
+ return FrameUtil::ActivateAppModalDialog(browser_) ? MA_NOACTIVATEANDEAT
+ : MA_ACTIVATE;
+}
+
+void VistaFrame::OnPaint(HDC dc) {
+ // Warning: on Vista the ChromeCanvasPaint *must* use an opaque flag of true
+ // so that ChromeCanvasPaint performs a BitBlt and not an alpha blend.
+ //
+ root_view_.OnPaint(*this);
+}
+
+LRESULT VistaFrame::OnEraseBkgnd(HDC dc) {
+ SetMsgHandled(TRUE);
+ return 0;
+}
+
+void VistaFrame::ArmOnMouseLeave() {
+ if (!on_mouse_leave_armed_) {
+ TRACKMOUSEEVENT tme;
+ tme.cbSize = sizeof(tme);
+ tme.dwFlags = TME_LEAVE;
+ tme.hwndTrack = *this;
+ tme.dwHoverTime = 0;
+ TrackMouseEvent(&tme);
+ on_mouse_leave_armed_ = TRUE;
+ }
+}
+
+void VistaFrame::OnCaptureChanged(HWND hwnd) {
+ if (in_drag_session_)
+ root_view_.ProcessMouseDragCanceled();
+ in_drag_session_ = false;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// View events propagation
+//
+////////////////////////////////////////////////////////////////////////////////
+
+bool VistaFrame::ProcessMousePressed(const CPoint& pt, UINT flags,
+ bool dbl_click) {
+ using namespace ChromeViews;
+ MouseEvent mouse_pressed(Event::ET_MOUSE_PRESSED,
+ pt.x,
+ pt.y,
+ (dbl_click ? MouseEvent::EF_IS_DOUBLE_CLICK : 0) |
+ Event::ConvertWindowsFlags(flags));
+ if (root_view_.OnMousePressed(mouse_pressed)) {
+ // If an additional button is pressed during a drag session we don't want
+ // to call SetCapture() again as it will result in no more events.
+ if (!in_drag_session_) {
+ in_drag_session_ = true;
+ SetCapture();
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void VistaFrame::ProcessMouseDragged(const CPoint& pt, UINT flags) {
+ using namespace ChromeViews;
+ MouseEvent drag_event(Event::ET_MOUSE_DRAGGED,
+ pt.x,
+ pt.y,
+ Event::ConvertWindowsFlags(flags));
+ root_view_.OnMouseDragged(drag_event);
+}
+
+void VistaFrame::ProcessMouseReleased(const CPoint& pt, UINT flags) {
+ using namespace ChromeViews;
+ if (in_drag_session_) {
+ in_drag_session_ = false;
+ ReleaseCapture();
+ }
+ MouseEvent mouse_released(Event::ET_MOUSE_RELEASED,
+ pt.x,
+ pt.y,
+ Event::ConvertWindowsFlags(flags));
+ root_view_.OnMouseReleased(mouse_released, false);
+}
+
+void VistaFrame::ProcessMouseMoved(const CPoint &pt, UINT flags) {
+ using namespace ChromeViews;
+ MouseEvent mouse_move(Event::ET_MOUSE_MOVED,
+ pt.x,
+ pt.y,
+ Event::ConvertWindowsFlags(flags));
+ root_view_.OnMouseMoved(mouse_move);
+}
+
+void VistaFrame::ProcessMouseExited() {
+ root_view_.ProcessOnMouseExited();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// ChromeViews::ViewContainer
+//
+////////////////////////////////////////////////////////////////////////////////
+
+void VistaFrame::GetBounds(CRect *out, bool including_frame) const {
+ if (including_frame) {
+ GetWindowRect(out);
+ } else {
+ GetClientRect(out);
+
+ POINT p = {0, 0};
+ ::ClientToScreen(*this, &p);
+
+ out->left += p.x;
+ out->top += p.y;
+ out->right += p.x;
+ out->bottom += p.y;
+ }
+}
+
+void VistaFrame::MoveToFront(bool should_activate) {
+ int flags = SWP_NOMOVE | SWP_NOSIZE;
+ if (!should_activate) {
+ flags |= SWP_NOACTIVATE;
+ }
+ SetWindowPos(HWND_TOP, 0, 0, 0, 0, flags);
+ SetForegroundWindow(*this);
+}
+
+HWND VistaFrame::GetHWND() const {
+ return m_hWnd;
+}
+
+void VistaFrame::PaintNow(const CRect& update_rect) {
+ if (!update_rect.IsRectNull() && IsVisible()) {
+ RedrawWindow(update_rect,
+ NULL,
+ RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_NOERASE);
+ }
+}
+
+ChromeViews::RootView* VistaFrame::GetRootView() {
+ return const_cast<ChromeViews::RootView*>(&root_view_);
+}
+
+bool VistaFrame::IsVisible() {
+ return !!::IsWindowVisible(*this);
+}
+
+bool VistaFrame::IsActive() {
+ return win_util::IsWindowActive(*this);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// VistaFrameView
+//
+////////////////////////////////////////////////////////////////////////////////
+void VistaFrame::VistaFrameView::PaintContentsBorder(ChromeCanvas* canvas,
+ int x,
+ int y,
+ int w,
+ int h) {
+ if (!parent_->IsTabStripVisible())
+ return;
+ int ro, bo;
+ canvas->DrawBitmapInt(*g_bitmaps[CT_TOP_LEFT_CORNER], x, y);
+ canvas->TileImageInt(*g_bitmaps[CT_TOP_CENTER],
+ x + g_bitmaps[CT_TOP_LEFT_CORNER]->width(),
+ y,
+ w - g_bitmaps[CT_TOP_LEFT_CORNER]->width() -
+ g_bitmaps[CT_TOP_RIGHT_CORNER]->width(),
+ g_bitmaps[CT_TOP_CENTER]->height());
+ ro = x + w - g_bitmaps[CT_TOP_RIGHT_CORNER]->width();
+ canvas->DrawBitmapInt(*g_bitmaps[CT_TOP_RIGHT_CORNER], ro, y);
+ canvas->TileImageInt(*g_bitmaps[CT_RIGHT_SIDE],
+ ro,
+ y + g_bitmaps[CT_TOP_RIGHT_CORNER]->height(),
+ g_bitmaps[CT_RIGHT_SIDE]->width(),
+ h - (g_bitmaps[CT_TOP_RIGHT_CORNER]->height() +
+ g_bitmaps[CT_BOTTOM_RIGHT_CORNER]->height()));
+ bo = y + h - g_bitmaps[CT_BOTTOM_RIGHT_CORNER]->height();
+ canvas->DrawBitmapInt(*g_bitmaps[CT_BOTTOM_RIGHT_CORNER],
+ x + w - g_bitmaps[CT_BOTTOM_RIGHT_CORNER]->width(),
+ bo);
+
+ canvas->TileImageInt(*g_bitmaps[CT_BOTTOM_CENTER],
+ x + g_bitmaps[CT_BOTTOM_LEFT_CORNER]->width(),
+ bo,
+ w - (g_bitmaps[CT_BOTTOM_LEFT_CORNER]->width() +
+ g_bitmaps[CT_BOTTOM_RIGHT_CORNER]->width()),
+ g_bitmaps[CT_BOTTOM_CENTER]->height());
+ canvas->DrawBitmapInt(*g_bitmaps[CT_BOTTOM_LEFT_CORNER], x, bo);
+ canvas->TileImageInt(*g_bitmaps[CT_LEFT_SIDE],
+ x,
+ y + g_bitmaps[CT_TOP_LEFT_CORNER]->height(),
+ g_bitmaps[CT_LEFT_SIDE]->width(),
+ h - (g_bitmaps[CT_TOP_LEFT_CORNER]->height() +
+ g_bitmaps[CT_BOTTOM_LEFT_CORNER]->height()));
+}
+
+void VistaFrame::VistaFrameView::Paint(ChromeCanvas* canvas) {
+ canvas->save();
+
+ // When painting the border, exclude the contents area. This will prevent the
+ // border bitmaps (which might be larger than the visible area) from coming
+ // into the content area when there is no tab painted yet.
+ int x = parent_->tab_contents_container_->GetX();
+ int y = parent_->tab_contents_container_->GetY();
+ SkRect clip;
+ clip.set(SkIntToScalar(x), SkIntToScalar(y),
+ SkIntToScalar(x + parent_->tab_contents_container_->GetWidth()),
+ SkIntToScalar(y + parent_->tab_contents_container_->GetHeight()));
+ canvas->clipRect(clip, SkRegion::kDifference_Op);
+
+ PaintContentsBorder(canvas,
+ 0,
+ contents_offset_,
+ GetWidth(),
+ GetHeight() - contents_offset_);
+
+ canvas->restore();
+}
+
+void VistaFrame::VistaFrameView::SetContentsOffset(int o) {
+ contents_offset_ = o;
+}
+
+bool VistaFrame::VistaFrameView::GetAccessibleRole(VARIANT* role) {
+ DCHECK(role);
+
+ role->vt = VT_I4;
+ role->lVal = ROLE_SYSTEM_CLIENT;
+ return true;
+}
+
+bool VistaFrame::VistaFrameView::GetAccessibleName(std::wstring* name) {
+ if (!accessible_name_.empty()) {
+ name->assign(accessible_name_);
+ return true;
+ }
+ return false;
+}
+
+void VistaFrame::VistaFrameView::SetAccessibleName(const std::wstring& name) {
+ accessible_name_.assign(name);
+}
+
+// Helper function to extract the min/max x-coordinate as well as the max
+// y coordinate from the TITLEBARINFOEX struct at the specified index.
+static void UpdatePosition(const TITLEBARINFOEX& info,
+ int element,
+ int* min_x,
+ int* max_x,
+ int* max_y) {
+ if ((info.rgstate[element] & (STATE_SYSTEM_INVISIBLE |
+ STATE_SYSTEM_OFFSCREEN |
+ STATE_SYSTEM_UNAVAILABLE)) == 0) {
+ *min_x = std::min(*min_x, static_cast<int>(info.rgrect[element].left));
+ *max_x = std::max(*max_x, static_cast<int>(info.rgrect[element].right));
+ *max_y = std::max(*max_y, static_cast<int>(info.rgrect[element].bottom));
+ }
+}
+
+bool VistaFrame::VistaFrameView::ShouldForwardToTabStrip(
+ const ChromeViews::DropTargetEvent& event) {
+ if (!FrameView::ShouldForwardToTabStrip(event))
+ return false;
+
+ TITLEBARINFOEX titlebar_info;
+ titlebar_info.cbSize = sizeof(TITLEBARINFOEX);
+ SendMessage(parent_->m_hWnd, WM_GETTITLEBARINFOEX, 0, (WPARAM)&titlebar_info);
+
+ int min_x = std::numeric_limits<int>::max();
+ int max_x = std::numeric_limits<int>::min();
+ int max_y = std::numeric_limits<int>::min();
+
+ // 2 is the minimize button.
+ UpdatePosition(titlebar_info, 2, &min_x, &max_x, &max_y);
+ // 3 is the maximize button.
+ UpdatePosition(titlebar_info, 3, &min_x, &max_x, &max_y);
+ // 5 is the close button.
+ UpdatePosition(titlebar_info, 5, &min_x, &max_x, &max_y);
+
+ if (min_x != std::numeric_limits<int>::max() &&
+ max_x != std::numeric_limits<int>::min() &&
+ max_y != std::numeric_limits<int>::min()) {
+ CPoint screen_drag_point(event.GetX(), event.GetY());
+ ConvertPointToScreen(this, &screen_drag_point);
+ if (screen_drag_point.x >= min_x && screen_drag_point.x <= max_x &&
+ screen_drag_point.y <= max_y) {
+ return false;
+ }
+ }
+ return true;
+}
+
+LRESULT VistaFrame::OnMouseRange(UINT u_msg, WPARAM w_param, LPARAM l_param,
+ BOOL& handled) {
+ // Tooltip handling is broken in Vista when using custom frames, so
+ // we have to implement a lot of this ourselves.
+ tooltip_manager_->OnMouse(u_msg, w_param, l_param);
+ handled = FALSE;
+
+ return 0;
+}
+
+LRESULT VistaFrame::OnNotify(int w_param, NMHDR* l_param) {
+ bool handled;
+ LRESULT result = tooltip_manager_->OnNotify(w_param, l_param, &handled);
+ SetMsgHandled(handled);
+ return result;
+}
+
+ChromeViews::TooltipManager* VistaFrame::GetTooltipManager() {
+ return tooltip_manager_.get();
+}
+
+StatusBubble* VistaFrame::GetStatusBubble() {
+ return NULL;
+}
+
+void VistaFrame::InitAfterHWNDCreated() {
+ tooltip_manager_.reset(new ChromeViews::AeroTooltipManager(this, m_hWnd));
+}
+
+void VistaFrame::ResetDWMFrame() {
+ if (IsTabStripVisible()) {
+ // Note: we don't use DwmEnableBlurBehindWindow because any region not
+ // included in the glass region is composited source over. This means
+ // that anything drawn directly with GDI appears fully transparent.
+ //
+ // We want this region to extend past our content border images, as they
+ // may be partially-transparent.
+ MARGINS margins = {kDwmBorderSize +
+ g_bitmaps[CT_TOP_LEFT_CORNER]->width(),
+ kDwmBorderSize +
+ g_bitmaps[CT_TOP_RIGHT_CORNER]->width(),
+ kDwmBorderSize +
+ IsToolBarVisible() ?
+ browser_view_->GetY() + kToolbarOverlapVertOffset :
+ tabstrip_->GetHeight(),
+ kDwmBorderSize +
+ g_bitmaps[CT_BOTTOM_CENTER]->height()};
+
+ DwmExtendFrameIntoClientArea(*this, &margins);
+ }
+}
+
+void VistaFrame::ShelfVisibilityChanged() {
+ ShelfVisibilityChangedImpl(browser_->GetSelectedTabContents());
+}
+
+void VistaFrame::SelectedTabToolbarSizeChanged(bool is_animating) {
+ if (is_animating) {
+ tab_contents_container_->set_fast_resize(true);
+ ShelfVisibilityChanged();
+ tab_contents_container_->set_fast_resize(false);
+ } else {
+ ShelfVisibilityChanged();
+ tab_contents_container_->UpdateHWNDBounds();
+ }
+}
+
+bool VistaFrame::UpdateChildViewAndLayout(ChromeViews::View* new_view,
+ ChromeViews::View** view) {
+ DCHECK(view);
+ if (*view == new_view) {
+ // The views haven't changed, if the views pref changed schedule a layout.
+ if (new_view) {
+ CSize pref_size;
+ new_view->GetPreferredSize(&pref_size);
+ if (pref_size.cy != new_view->GetHeight())
+ return true;
+ }
+ return false;
+ }
+
+ // The views differ, and one may be null (but not both). Remove the old
+ // view (if it non-null), and add the new one (if it is non-null). If the
+ // height has changed, schedule a layout, otherwise reuse the existing
+ // bounds to avoid scheduling a layout.
+
+ int current_height = 0;
+ if (*view) {
+ current_height = (*view)->GetHeight();
+ root_view_.RemoveChildView(*view);
+ }
+
+ int new_height = 0;
+ if (new_view) {
+ CSize preferred_size;
+ new_view->GetPreferredSize(&preferred_size);
+ new_height = preferred_size.cy;
+ root_view_.AddChildView(new_view);
+ }
+
+ bool changed = false;
+ if (new_height != current_height) {
+ changed = true;
+ } else if (new_view && *view) {
+ // The view changed, but the new view wants the same size, give it the
+ // bounds of the last view and have it repaint.
+ CRect last_bounds;
+ (*view)->GetBounds(&last_bounds);
+ new_view->SetBounds(last_bounds.left, last_bounds.top,
+ last_bounds.Width(), last_bounds.Height());
+ new_view->SchedulePaint();
+ } else if (new_view) {
+ DCHECK(new_height == 0);
+ // The heights are the same, but the old view is null. This only happens
+ // when the height is zero. Zero out the bounds.
+ new_view->SetBounds(0, 0, 0, 0);
+ }
+ *view = new_view;
+ return changed;
+}
+
+void VistaFrame::SetWindowTitle(const std::wstring& title) {
+ SetWindowText(title.c_str());
+}
+
+void VistaFrame::Activate() {
+ if (IsIconic())
+ ShowWindow(SW_RESTORE);
+ MoveToFront(true);
+}
+
+void VistaFrame::FlashFrame() {
+ FLASHWINFO flash_window_info;
+ flash_window_info.cbSize = sizeof(FLASHWINFO);
+ flash_window_info.hwnd = GetHWND();
+ flash_window_info.dwFlags = FLASHW_ALL;
+ flash_window_info.uCount = 4;
+ flash_window_info.dwTimeout = 0;
+ ::FlashWindowEx(&flash_window_info);
+}
+
+void VistaFrame::ShowTabContents(TabContents* selected_contents) {
+ tab_contents_container_->SetTabContents(selected_contents);
+
+ // Force a LoadingStateChanged notification because the TabContents
+ // could be loading (such as when the user unconstrains a tab.
+ if (selected_contents && selected_contents->delegate())
+ selected_contents->delegate()->LoadingStateChanged(selected_contents);
+
+ ShelfVisibilityChangedImpl(selected_contents);
+}
+
+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(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
+ // figure out how big all the UI bits are.
+ Layout();
+
+ // Now figure out the height of the non-client area (the Native windows
+ // chrome) by comparing the window bounds to the client bounds.
+ CRect window_bounds, client_bounds;
+ GetBounds(&window_bounds, true);
+ GetBounds(&client_bounds, false);
+ int left_edge_width = client_bounds.left - window_bounds.left;
+ int top_edge_height = client_bounds.top - window_bounds.top;
+ int right_edge_width = window_bounds.right - client_bounds.right;
+ int bottom_edge_height = window_bounds.bottom - client_bounds.bottom;
+
+ // Now resize the window. This will result in Layout() getting called again
+ // and the contents getting sized to the value specified in |contents_bounds|
+ SetWindowPos(NULL, contents_bounds.x() - left_edge_width,
+ contents_bounds.y() - top_edge_height,
+ contents_bounds.width() + left_edge_width + right_edge_width,
+ contents_bounds.height() + top_edge_height + bottom_edge_height,
+ SWP_NOZORDER | SWP_NOACTIVATE);
+}
+
+void VistaFrame::SetIsOffTheRecord(bool value) {
+ is_off_the_record_ = value;
+}
+
+TabContentsContainerView* VistaFrame::GetTabContentsContainer() {
+ return tab_contents_container_;
+}
+
+void VistaFrame::DestroyBrowser() {
+ // TODO(beng): (Cleanup) tidy this up, just fixing the build red for now.
+ // Need to do this first, before the browser_ is deleted and we can't remove
+ // the tabstrip from the model's observer list because the model was
+ // destroyed with browser_.
+ if (browser_) {
+ if (bookmark_bar_view_.get() && bookmark_bar_view_->GetParent()) {
+ // The bookmark bar should not be parented by the time we get here.
+ // If you hit this NOTREACHED file a bug with the trace.
+ NOTREACHED();
+ bookmark_bar_view_->GetParent()->RemoveChildView(bookmark_bar_view_.get());
+ }
+
+ // Explicitly delete the BookmarkBarView now. That way we don't have to
+ // worry about the BookmarkBarView potentially outliving the Browser &
+ // Profile.
+ bookmark_bar_view_.reset(NULL);
+
+ browser_->tabstrip_model()->RemoveObserver(tabstrip_);
+ delete browser_;
+ browser_ = NULL;
+ }
+}
+
+void VistaFrame::ShelfVisibilityChangedImpl(TabContents* current_tab) {
+ // Coalesce layouts.
+ bool changed = false;
+
+ ChromeViews::View* new_shelf = NULL;
+ if (current_tab && current_tab->IsDownloadShelfVisible())
+ new_shelf = current_tab->GetDownloadShelfView();
+ changed |= UpdateChildViewAndLayout(new_shelf, &shelf_view_);
+
+ ChromeViews::View* new_info_bar = NULL;
+ if (current_tab && current_tab->IsInfoBarVisible())
+ new_info_bar = current_tab->GetInfoBarView();
+ changed |= UpdateChildViewAndLayout(new_info_bar, &info_bar_view_);
+
+ ChromeViews::View* new_bookmark_bar_view = NULL;
+ if (SupportsBookmarkBar())
+ new_bookmark_bar_view = GetBookmarkBarView();
+ changed |= UpdateChildViewAndLayout(new_bookmark_bar_view,
+ &active_bookmark_bar_);
+
+ // Only do a layout if the current contents is non-null. We assume that if the
+ // contents is NULL, we're either being destroyed, or ShowTabContents is going
+ // to be invoked with a non-null TabContents again so that there is no need
+ // in doing a layout now (and would result in extra work/invalidation on
+ // tab switches).
+ if (changed && current_tab)
+ Layout();
+}
diff --git a/chrome/browser/views/old_frames/vista_frame.h b/chrome/browser/views/old_frames/vista_frame.h
new file mode 100644
index 0000000..b812db1
--- /dev/null
+++ b/chrome/browser/views/old_frames/vista_frame.h
@@ -0,0 +1,414 @@
+// 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_OLD_FRAMES_VISTA_FRAME_H__
+#define CHROME_BROWSER_VIEWS_OLD_FRAMES_VISTA_FRAME_H__
+
+#include <windows.h>
+#include <atlbase.h>
+#include <atlcrack.h>
+#include <atlapp.h>
+#include <atlframe.h>
+
+#include "base/message_loop.h"
+#include "chrome/app/chrome_dll_resource.h"
+#include "chrome/browser/browser_window.h"
+#include "chrome/browser/views/old_frames/frame_view.h"
+#include "chrome/browser/views/status_bubble.h"
+#include "chrome/views/view_container.h"
+#include "chrome/views/root_view.h"
+#include "chrome/views/hwnd_view.h"
+#include "chrome/views/image_view.h"
+#include "chrome/views/tooltip_manager.h"
+
+#define VISTA_FRAME_CLASSNAME L"Chrome_VistaFrame"
+
+class BookmarkBarView;
+class Browser;
+class BrowserView;
+class TabContentsContainerView;
+class ChromeViews::FocusManager;
+class SkBitmap;
+class TabStrip;
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// VistaFrame class
+//
+// A CWindowImpl subclass that implements our main frame on Windows Vista
+//
+////////////////////////////////////////////////////////////////////////////////
+class VistaFrame : public BrowserWindow,
+ public CWindowImpl<VistaFrame,
+ CWindow,
+ CWinTraits<WS_OVERLAPPEDWINDOW |
+ WS_CLIPCHILDREN>>,
+ public ChromeViews::ViewContainer,
+ public ChromeViews::AcceleratorTarget {
+ public:
+ // Create a new VistaFrame given the bounds and provided browser.
+ // |bounds| may be empty to let Windows decide where to place the window.
+ // The browser_window object acts both as a container for the actual
+ // browser contents as well as a source for the tab strip and the toolbar.
+ // |is_off_the_record| defines whether this window should represent an off the
+ // record session.
+ //
+ // Note: this method creates an HWND for the frame but doesn't initialize
+ // the view hierarchy. The browser creates its HWND from the frame HWND
+ // and then calls Init() on the frame to finalize the initialization
+ static VistaFrame* CreateFrame(const gfx::Rect& bounds,
+ Browser* browser,
+ bool is_off_the_record);
+
+ virtual ~VistaFrame();
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // Events
+ ////////////////////////////////////////////////////////////////////////////////
+
+ DECLARE_FRAME_WND_CLASS_EX(VISTA_FRAME_CLASSNAME,
+ IDR_MAINFRAME,
+ CS_DBLCLKS,
+ NULL)
+
+ BEGIN_MSG_MAP(VistaFrame)
+ MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseRange)
+ MESSAGE_HANDLER(WM_MOUSELEAVE, OnMouseRange)
+ MESSAGE_HANDLER(WM_NCMOUSELEAVE, OnMouseRange)
+ MESSAGE_HANDLER(WM_NCMOUSEMOVE, OnMouseRange)
+ MESSAGE_RANGE_HANDLER(WM_SETTINGCHANGE, WM_SETTINGCHANGE, OnSettingChange)
+ MSG_WM_LBUTTONDOWN(OnMouseButtonDown)
+ MSG_WM_LBUTTONUP(OnLButtonUp);
+ MSG_WM_LBUTTONDBLCLK(OnMouseButtonDblClk)
+ MSG_WM_MBUTTONDOWN(OnMouseButtonDown)
+ MSG_WM_MBUTTONUP(OnMButtonUp);
+ MSG_WM_MBUTTONDBLCLK(OnMouseButtonDblClk);
+ MSG_WM_RBUTTONDOWN(OnMouseButtonDown)
+ MSG_WM_RBUTTONUP(OnRButtonUp);
+ MSG_WM_NCMBUTTONDOWN(OnNCMButtonDown)
+ MSG_WM_NCRBUTTONDOWN(OnNCRButtonDown)
+ MSG_WM_RBUTTONDBLCLK(OnMouseButtonDblClk);
+ MESSAGE_HANDLER_EX(WM_GETOBJECT, OnGetObject); // To avoid edit atlcrack.h.
+ MSG_WM_KEYDOWN(OnKeyDown);
+ MSG_WM_KEYUP(OnKeyUp);
+ MSG_WM_MOUSEMOVE(OnMouseMove)
+ MSG_WM_MOUSELEAVE(OnMouseLeave)
+ MSG_WM_CLOSE(Close) // Note: Calls Close() directly, there is no OnClose()
+ MSG_WM_ENDSESSION(OnEndSession)
+ MSG_WM_APPCOMMAND(OnAppCommand)
+ MSG_WM_COMMAND(OnCommand)
+ MSG_WM_SYSCOMMAND(OnSysCommand)
+ MSG_WM_SIZE(OnSize)
+ MSG_WM_MOVE(OnMove)
+ MSG_WM_MOVING(OnMoving)
+ MSG_WM_ACTIVATE(OnActivate)
+ MSG_WM_PAINT(OnPaint)
+ MSG_WM_ERASEBKGND(OnEraseBkgnd)
+ MSG_WM_NCHITTEST(OnNCHitTest)
+ MSG_WM_NCCALCSIZE(OnNCCalcSize)
+ MSG_WM_CAPTURECHANGED(OnCaptureChanged)
+ MSG_WM_NOTIFY(OnNotify)
+ MSG_WM_NCLBUTTONDOWN(OnNCLButtonDown)
+ MSG_WM_NCACTIVATE(OnNCActivate)
+ MSG_WM_MOUSEACTIVATE(OnMouseActivate)
+ MSG_WM_POWERBROADCAST(OnPowerBroadcast)
+ MSG_WM_THEMECHANGED(OnThemeChanged)
+ REFLECT_NOTIFICATIONS()
+ END_MSG_MAP()
+
+ void OnEndSession(BOOL ending, UINT logoff);
+ void OnActivate(UINT n_state, BOOL is_minimized, HWND other);
+ int OnMouseActivate(CWindow wndTopLevel, UINT nHitTest, UINT message);
+ void OnMouseButtonDown(UINT flags, const CPoint& pt);
+ void OnMouseButtonUp(UINT flags, const CPoint& pt);
+ void OnLButtonUp(UINT flags, const CPoint& pt);
+ void OnMouseButtonDblClk(UINT flags, const CPoint& pt);
+ void OnMButtonUp(UINT flags, const CPoint& pt);
+ void OnRButtonUp(UINT flags, const CPoint& pt);
+ void OnNCMButtonDown(UINT flags, const CPoint& pt);
+ void OnNCRButtonDown(UINT flags, const CPoint& pt);
+ void OnMouseMove(UINT flags, const CPoint& pt);
+ void OnMouseLeave();
+ void OnKeyDown(TCHAR c, UINT rep_cnt, UINT flags);
+ void OnKeyUp(TCHAR c, UINT rep_cnt, UINT flags);
+ LRESULT OnGetObject(UINT uMsg, WPARAM w_param, LPARAM l_param);
+ LRESULT OnAppCommand(
+ HWND w_param, short app_command, WORD device, int keystate);
+ void OnCommand(UINT notification_code, int command_id, HWND window);
+ void OnSysCommand(UINT notification_code, CPoint click);
+ void OnMove(const CSize& size);
+ void OnMoving(UINT param, const LPRECT new_bounds);
+ void OnSize(UINT param, const CSize& size);
+ void OnFinalMessage(HWND hwnd);
+ void OnPaint(HDC dc);
+ LRESULT OnEraseBkgnd(HDC dc);
+
+ void ArmOnMouseLeave();
+ void OnCaptureChanged(HWND hwnd);
+ LRESULT OnMouseRange(UINT u_msg, WPARAM w_param, LPARAM l_param,
+ BOOL& handled);
+ LRESULT OnNotify(int w_param, NMHDR* hdr);
+ LRESULT OnSettingChange(UINT u_msg, WPARAM w_param, LPARAM l_param,
+ BOOL& handled);
+ LRESULT OnNCActivate(BOOL param);
+ BOOL OnPowerBroadcast(DWORD power_event, DWORD data);
+ void OnThemeChanged();
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // BrowserWindow implementation
+ ////////////////////////////////////////////////////////////////////////////////
+
+ virtual void Init();
+ virtual void Show(int command, bool adjust_to_fit);
+ virtual void Close();
+ 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<ChromeViews::Accelerator, int>* accelerator_table);
+ virtual bool AcceleratorPressed(const ChromeViews::Accelerator& accelerator);
+ virtual gfx::Rect GetNormalBounds();
+ virtual bool IsMaximized();
+ virtual gfx::Rect GetBoundsForContentBounds(const gfx::Rect content_rect);
+ virtual void InfoBubbleShowing();
+ virtual ToolbarStarToggle* GetStarButton() const;
+ virtual LocationBarView* GetLocationBarView() const;
+ virtual GoButton* GetGoButton() const;
+ virtual BookmarkBarView* GetBookmarkBarView();
+ virtual BrowserView* GetBrowserView() const;
+ virtual void UpdateToolbar(TabContents* contents, bool should_restore_state);
+ virtual void ProfileChanged(Profile* profile);
+ virtual void FocusToolbar();
+ virtual bool IsBookmarkBarVisible() const;
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // ChromeViews::ViewContainer
+ ////////////////////////////////////////////////////////////////////////////////
+
+ virtual void GetBounds(CRect *out, bool including_frame) const;
+ virtual void MoveToFront(bool should_activate);
+ virtual HWND GetHWND() const;
+ virtual void PaintNow(const CRect& update_rect);
+ virtual ChromeViews::RootView* GetRootView();
+ virtual bool IsVisible();
+ virtual bool IsActive();
+ virtual ChromeViews::TooltipManager* GetTooltipManager();
+ virtual StatusBubble* GetStatusBubble();
+ virtual bool GetAccelerator(int cmd_id,
+ ChromeViews::Accelerator* accelerator);
+
+ virtual void ShelfVisibilityChanged();
+ virtual void SelectedTabToolbarSizeChanged(bool is_animating);
+ virtual void SetWindowTitle(const std::wstring& title);
+ virtual void Activate();
+ virtual void FlashFrame();
+
+ protected:
+ explicit VistaFrame(Browser* browser);
+
+ // For subclassers.
+ virtual bool IsTabStripVisible() const { return true; }
+ virtual bool IsToolBarVisible() const { return true; }
+ virtual bool SupportsBookmarkBar() const { return true; }
+
+ // Invoked after the HWND has been created but before the window is showing.
+ // This registers tooltips. If you override, be sure and invoke this
+ // implementation.
+ virtual void InitAfterHWNDCreated();
+
+ // Override as needed.
+ virtual LRESULT OnNCHitTest(const CPoint& pt);
+ virtual LRESULT OnNCCalcSize(BOOL w_param, LPARAM l_param);
+ virtual void OnNCLButtonDown(UINT flags, const CPoint& pt);
+
+ // Create a default tab strip. Override as needed.
+ virtual TabStrip* CreateTabStrip(Browser* browser);
+
+ // Set whether this frame represents an off the record session. This is
+ // currently only called during initialization.
+ void SetIsOffTheRecord(bool value);
+
+ // Layout the various views
+ virtual void Layout();
+
+ // Return the tab contents container.
+ TabContentsContainerView* GetTabContentsContainer();
+
+ virtual void DestroyBrowser();
+
+ // The Browser that created this frame
+ Browser* browser_;
+
+ // Top level frame view
+ class VistaFrameView;
+ VistaFrameView* frame_view_;
+
+ friend class VistaFrameView;
+
+ // The view we use to display the background under tab / toolbar area
+ class VistaFrameView : public FrameView {
+ public:
+ explicit VistaFrameView(VistaFrame* parent)
+ : FrameView(parent),
+ contents_offset_(0),
+ parent_(parent) {
+ }
+
+ virtual void Paint(ChromeCanvas* canvas);
+
+ void SetContentsOffset(int o);
+
+ // Accessibility information
+ bool GetAccessibleRole(VARIANT* role);
+
+ // Returns a brief, identifying string, containing a unique, readable name.
+ bool GetAccessibleName(std::wstring* name);
+
+ // Assigns an accessible string name.
+ void SetAccessibleName(const std::wstring& name);
+
+ protected:
+ // Overriden to return false if over the min/max/close buttons of the frame.
+ virtual bool ShouldForwardToTabStrip(
+ const ChromeViews::DropTargetEvent& event);
+
+ private:
+ void PaintContentsBorder(ChromeCanvas* canvas,
+ int x,
+ int y,
+ int w,
+ int h);
+
+ int contents_offset_;
+
+ VistaFrame* parent_;
+
+ // Storage of strings needed for accessibility.
+ std::wstring accessible_name_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(VistaFrameView);
+ };
+
+ private:
+ //
+ // View events propagation
+ //
+ bool ProcessMousePressed(const CPoint& pt, UINT flags, bool dbl_click);
+ void ProcessMouseDragged(const CPoint& pt, UINT flags);
+ void ProcessMouseReleased(const CPoint& pt, UINT flags);
+ void ProcessMouseMoved(const CPoint &pt, UINT flags);
+ void ProcessMouseExited();
+
+ // Reset the black DWM frame (the black non-glass area with lightly-colored
+ // border that sits behind our content). Generally there's no single place
+ // to call this, as Vista likes to reset the frame in different situations
+ // (return from maximize, non-composited > composited, app launch), and
+ // the notifications we receive and the timing of those notifications
+ // varies so wildly that we end up having to call this in many different
+ // message handlers.
+ void ResetDWMFrame();
+
+ // Initialize static members the first time this is invoked
+ static void InitializeIfNeeded();
+
+ // Updates a single view. If *view differs from new_view the old view is
+ // removed and the new view is added.
+ //
+ // This is intended to be used when swapping in/out child views that are
+ // referenced via a field.
+ //
+ // This function returns true if anything was changed. The caller should
+ // ensure that Layout() is eventually called in this case.
+ bool UpdateChildViewAndLayout(ChromeViews::View* new_view,
+ ChromeViews::View** view);
+
+ // Implementation for ShelfVisibilityChanged(). Updates the various shelf
+ // fields. If one of the shelves has changed (or it's size has changed) and
+ // current_tab is non-NULL layout occurs.
+ void ShelfVisibilityChangedImpl(TabContents* current_tab);
+
+ // Root view
+ ChromeViews::RootView root_view_;
+
+ // Tooltip Manager
+ scoped_ptr<ChromeViews::TooltipManager> tooltip_manager_;
+
+ // The optional container for the off the record icon.
+ ChromeViews::ImageView* off_the_record_image_;
+
+ // The container for the distributor logo.
+ ChromeViews::ImageView* distributor_logo_;
+
+ // The view that contains the tabs and any associated controls.
+ TabStrip* tabstrip_;
+
+ // The bookmark bar. This is lazily created.
+ scoped_ptr<BookmarkBarView> bookmark_bar_view_;
+
+ // The visible bookmark bar. NULL if none is visible.
+ ChromeViews::View* active_bookmark_bar_;
+
+ // Browser contents
+ TabContentsContainerView* tab_contents_container_;
+
+ // Whether we enabled our custom window yet.
+ bool custom_window_enabled_;
+
+ // Whether we saved the window placement yet.
+ bool saved_window_placement_;
+
+ // whether we are expecting a mouse leave event
+ bool on_mouse_leave_armed_;
+
+ // whether we are currently processing a view level drag session
+ bool in_drag_session_;
+
+ // A view positioned at the bottom of the frame.
+ ChromeViews::View* shelf_view_;
+
+ // A view positioned beneath the bookmark bar view.
+ // Implementation mirrors shelf_view_
+ ChromeViews::View* info_bar_view_;
+
+ // We need to own the text of the menu, the Windows API does not copy it.
+ std::wstring task_manager_label_text_;
+
+ // A mapping between accelerators and commands.
+ scoped_ptr<std::map<ChromeViews::Accelerator, int>> accelerator_table_;
+
+ // Whether this frame represents an off the record session.
+ bool is_off_the_record_;
+
+ // Static resources
+ static bool g_initialized;
+ static SkBitmap** g_bitmaps;
+
+ // Instance of accessibility information and handling for MSAA root
+ CComPtr<IAccessible> accessibility_root_;
+
+ // This is used to make sure we visually look active when the bubble is shown
+ // even though we aren't active. When the info bubble is shown it takes
+ // activation. Visually we still want the frame to look active. To make the
+ // frame look active when we get WM_NCACTIVATE and ignore_ncactivate_ is
+ // true, we tell the frame it is still active. When the info bubble closes we
+ // tell the window it is no longer active. This results in painting the
+ // active frame even though we aren't active.
+ bool ignore_ncactivate_;
+
+ // Whether we should save the bounds of the window. We don't want to
+ // save the default size of windows for certain classes of windows
+ // like unconstrained popups. Defaults to true.
+ bool should_save_window_placement_;
+
+ // A view that holds the client-area contents of the browser window.
+ BrowserView* browser_view_;
+
+ 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
new file mode 100644
index 0000000..6a33d77
--- /dev/null
+++ b/chrome/browser/views/old_frames/xp_frame.cc
@@ -0,0 +1,2523 @@
+// 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/old_frames/xp_frame.h"
+
+#include <windows.h>
+
+#include "base/command_line.h"
+#include "base/gfx/native_theme.h"
+#include "base/gfx/rect.h"
+#include "chrome/app/theme/theme_resources.h"
+#include "chrome/browser/browser.h"
+#include "chrome/browser/browser_list.h"
+#include "chrome/browser/frame_util.h"
+#include "chrome/browser/suspend_controller.h"
+#include "chrome/browser/tab_contents.h"
+#include "chrome/browser/tab_contents_container_view.h"
+#include "chrome/browser/tabs/tab_strip_model.h"
+#include "chrome/browser/view_ids.h"
+#include "chrome/browser/views/bookmark_bar_view.h"
+#include "chrome/browser/views/download_shelf_view.h"
+#include "chrome/browser/views/frame/browser_view.h"
+#include "chrome/browser/views/old_frames/point_buffer.h"
+#include "chrome/browser/views/tabs/tab_strip.h"
+#include "chrome/common/chrome_constants.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/gfx/chrome_canvas.h"
+#include "chrome/common/l10n_util.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/common/resource_bundle.h"
+#include "chrome/common/win_util.h"
+#include "chrome/views/accessibility/view_accessibility.h"
+#include "chrome/views/accelerator.h"
+#include "chrome/views/background.h"
+#include "chrome/views/event.h"
+#include "chrome/views/focus_manager.h"
+#include "chrome/views/hwnd_view_container.h"
+#include "chrome/views/hwnd_notification_source.h"
+#include "chrome/views/tooltip_manager.h"
+#include "chrome/views/view.h"
+
+#include "chromium_strings.h"
+#include "generated_resources.h"
+
+// Needed for accessibility support.
+// NOTE(klink): To comply with a directive from Darin, I have added
+// this #pragma directive instead of adding "oleacc.lib" to a project file.
+#pragma comment(lib, "oleacc.lib")
+
+// Layout constants and image size dependent values
+static const int kZoomedTopMargin = 1;
+static const int kZoomedBottomMargin = 1;
+
+static const int kTopMargin = 16;
+static const int kContentBorderHorizOffset = 2;
+static const int kContentBorderVertTopOffset = 37;
+static const int kContentBorderVertBottomOffset = 2;
+static const int kToolbarOverlapVertOffset = 3;
+static const int kTabShadowSize = 2;
+
+static const int kDistributorLogoHorizontalOffset = 7;
+static const int kDistributorLogoVerticalOffset = 3;
+
+// Size of a corner. We use this when drawing a black background in maximized
+// mode
+static const int kCornerSize = 4;
+
+// The visual size of the curved window corners - used when masking out the
+// corners when resizing. This should vary as the shape of the curve varies
+// in OnSize.
+static const int kCurvedCornerSize = 3;
+
+static int g_title_bar_height;
+static int g_bottom_margin;
+static int g_left_margin;
+static int g_right_margin;
+
+static const int kResizeAreaSize = 5;
+static const int kResizeAreaNorthSize = 3;
+static const int kResizeAreaCornerSize = 16;
+static const int kWindowControlsTopOffset = 1;
+static const int kWindowControlsRightOffset = 4;
+static const int kWindowControlsTopZoomedOffset = 1;
+static const int kWindowControlsRightZoomedOffset = 3;
+
+// Number of pixels still visible when the toolbar is invisible.
+static const int kCollapsedToolbarHeight = 4;
+
+// Minimum title bar height used when the tab strip is not visible.
+static const int kMinTitleBarHeight = 25;
+
+// OTR image offsets.
+static const int kOTRImageHorizMargin = 2;
+static const int kOTRImageVertMargin = 2;
+
+// The line drawn to separate tab end contents.
+static const int kSeparationLineHeight = 1;
+static const SkColor kSeparationLineColor = SkColorSetRGB(178, 178, 178);
+
+// Padding between the tab strip and the window controls in maximized mode.
+static const int kZoomedStripPadding = 16;
+
+using ChromeViews::Accelerator;
+using ChromeViews::FocusManager;
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// RegionsUnderInfo class
+//
+// A facility to enumerate the windows obscured by a window. For each window,
+// a region is provided.
+//
+////////////////////////////////////////////////////////////////////////////////
+class RegionsUnderInfo {
+ public:
+ explicit RegionsUnderInfo(HWND hwnd) : hwnd_(hwnd),
+ found_hwnd_(false) {
+ CRect window_rect;
+ ::GetWindowRect(hwnd, &window_rect);
+ hwnd_rgn_ = ::CreateRectRgn(window_rect.left, window_rect.top,
+ window_rect.right, window_rect.bottom);
+ Init();
+ }
+
+ ~RegionsUnderInfo() {
+ int i, region_count;
+ region_count = static_cast<int>(regions_.size());
+ for (i = 0; i < region_count; i++) {
+ ::DeleteObject(regions_[i]);
+ }
+
+ ::DeleteObject(hwnd_rgn_);
+ }
+
+ int GetWindowCount() {
+ return static_cast<int>(windows_.size());
+ }
+
+ HWND GetWindowAt(int index) {
+ return windows_[index];
+ }
+
+ HRGN GetRegionAt(int index) {
+ return regions_[index];
+ }
+
+ private:
+ static BOOL CALLBACK WindowEnumProc(HWND hwnd, LPARAM lParam) {
+ RegionsUnderInfo* rui =
+ reinterpret_cast<RegionsUnderInfo*>(lParam);
+
+ if (hwnd == rui->hwnd_) {
+ rui->found_hwnd_ = true;
+ return TRUE;
+ }
+
+ int status = ERROR;
+ bool should_delete_rgn = true;
+ if (rui->found_hwnd_) {
+ if (::IsWindowVisible(hwnd)) {
+ RECT r;
+ ::GetWindowRect(hwnd, &r);
+ HRGN tmp = ::CreateRectRgn(r.left, r.top, r.right, r.bottom);
+ if (::CombineRgn(tmp,
+ rui->hwnd_rgn_,
+ tmp,
+ RGN_AND) != NULLREGION) {
+ // Remove that intersection to exclude any window below
+ int status = ::CombineRgn(rui->hwnd_rgn_,
+ rui->hwnd_rgn_,
+ tmp,
+ RGN_DIFF);
+
+ // We have an interesction, add it with the region in hwnd
+ // coordinate system
+ ::OffsetRgn(tmp, -r.left, -r.top);
+ rui->windows_.push_back(hwnd);
+ rui->regions_.push_back(tmp);
+ should_delete_rgn = false;
+ }
+ if (should_delete_rgn) {
+ ::DeleteObject(tmp);
+ }
+ }
+ }
+
+ // If hwnd_rgn_ is NULL, we are done
+ if (status == NULLREGION) {
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+ }
+
+ void Init() {
+ ::EnumWindows(WindowEnumProc, reinterpret_cast<LPARAM>(this));
+ }
+
+
+ HWND hwnd_;
+ HRGN hwnd_rgn_;
+ bool found_hwnd_;
+ std::vector<HWND> windows_;
+ std::vector<HRGN> regions_;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// XPFrame implementation
+//
+////////////////////////////////////////////////////////////////////////////////
+
+// static
+bool XPFrame::g_initialized = FALSE;
+
+// static
+HCURSOR XPFrame::g_resize_cursors[4];
+
+// static
+SkBitmap** XPFrame::g_bitmaps;
+
+// static
+SkBitmap** XPFrame::g_otr_bitmaps;
+
+// Possible frame action.
+enum FrameActionTag {
+ MINIATURIZE_TAG = 0,
+ MAXIMIZE_TAG,
+ RESTORE_TAG,
+ CLOSE_TAG,
+};
+
+static const int kImageNames[] = { IDR_WINDOW_BOTTOM_CENTER,
+ IDR_WINDOW_BOTTOM_LEFT_CORNER,
+ IDR_WINDOW_BOTTOM_RIGHT_CORNER,
+ IDR_WINDOW_LEFT_SIDE,
+ IDR_WINDOW_RIGHT_SIDE,
+ IDR_WINDOW_TOP_CENTER,
+ IDR_WINDOW_TOP_LEFT_CORNER,
+ IDR_WINDOW_TOP_RIGHT_CORNER,
+ IDR_CONTENT_BOTTOM_CENTER,
+ IDR_CONTENT_BOTTOM_LEFT_CORNER,
+ IDR_CONTENT_BOTTOM_RIGHT_CORNER,
+ IDR_CONTENT_LEFT_SIDE,
+ IDR_CONTENT_RIGHT_SIDE,
+ IDR_CONTENT_TOP_CENTER,
+ IDR_CONTENT_TOP_LEFT_CORNER,
+ IDR_CONTENT_TOP_RIGHT_CORNER,
+ IDR_DEWINDOW_BOTTOM_CENTER,
+ IDR_DEWINDOW_BOTTOM_LEFT_CORNER,
+ IDR_DEWINDOW_BOTTOM_RIGHT_CORNER,
+ IDR_DEWINDOW_LEFT_SIDE,
+ IDR_DEWINDOW_RIGHT_SIDE,
+ IDR_DEWINDOW_TOP_CENTER,
+ IDR_DEWINDOW_TOP_LEFT_CORNER,
+ IDR_DEWINDOW_TOP_RIGHT_CORNER,
+ IDR_APP_TOP_LEFT,
+ IDR_APP_TOP_CENTER,
+ IDR_APP_TOP_RIGHT
+};
+
+static const int kOTRImageNames[] = { IDR_WINDOW_BOTTOM_CENTER_OTR,
+ IDR_WINDOW_BOTTOM_LEFT_CORNER_OTR,
+ IDR_WINDOW_BOTTOM_RIGHT_CORNER_OTR,
+ IDR_WINDOW_LEFT_SIDE_OTR,
+ IDR_WINDOW_RIGHT_SIDE_OTR,
+ IDR_WINDOW_TOP_CENTER_OTR,
+ IDR_WINDOW_TOP_LEFT_CORNER_OTR,
+ IDR_WINDOW_TOP_RIGHT_CORNER_OTR,
+ IDR_CONTENT_BOTTOM_CENTER,
+ IDR_CONTENT_BOTTOM_LEFT_CORNER,
+ IDR_CONTENT_BOTTOM_RIGHT_CORNER,
+ IDR_CONTENT_LEFT_SIDE,
+ IDR_CONTENT_RIGHT_SIDE,
+ IDR_CONTENT_TOP_CENTER,
+ IDR_CONTENT_TOP_LEFT_CORNER,
+ IDR_CONTENT_TOP_RIGHT_CORNER,
+ IDR_DEWINDOW_BOTTOM_CENTER_OTR,
+ IDR_DEWINDOW_BOTTOM_LEFT_CORNER_OTR,
+ IDR_DEWINDOW_BOTTOM_RIGHT_CORNER_OTR,
+ IDR_DEWINDOW_LEFT_SIDE_OTR,
+ IDR_DEWINDOW_RIGHT_SIDE_OTR,
+ IDR_DEWINDOW_TOP_CENTER_OTR,
+ IDR_DEWINDOW_TOP_LEFT_CORNER_OTR,
+ IDR_DEWINDOW_TOP_RIGHT_CORNER_OTR,
+ IDR_APP_TOP_LEFT,
+ IDR_APP_TOP_CENTER,
+ IDR_APP_TOP_RIGHT
+};
+
+typedef enum { BOTTOM_CENTER = 0, BOTTOM_LEFT_CORNER, BOTTOM_RIGHT_CORNER,
+ LEFT_SIDE, RIGHT_SIDE, TOP_CENTER, TOP_LEFT_CORNER,
+ TOP_RIGHT_CORNER, CT_BOTTOM_CENTER,
+ CT_BOTTOM_LEFT_CORNER, CT_BOTTOM_RIGHT_CORNER, CT_LEFT_SIDE,
+ CT_RIGHT_SIDE, CT_TOP_CENTER, CT_TOP_LEFT_CORNER,
+ CT_TOP_RIGHT_CORNER, DE_BOTTOM_CENTER,
+ DE_BOTTOM_LEFT_CORNER, DE_BOTTOM_RIGHT_CORNER, DE_LEFT_SIDE,
+ DE_RIGHT_SIDE, DE_TOP_CENTER, DE_TOP_LEFT_CORNER,
+ DE_TOP_RIGHT_CORNER,
+ APP_TOP_LEFT, APP_TOP_CENTER, APP_TOP_RIGHT
+};
+
+// static
+XPFrame* XPFrame::CreateFrame(const gfx::Rect& bounds,
+ Browser* browser,
+ bool is_otr) {
+ XPFrame* instance = new XPFrame(browser);
+ instance->Create(NULL, bounds.ToRECT(),
+ l10n_util::GetString(IDS_PRODUCT_NAME).c_str());
+ instance->InitAfterHWNDCreated();
+ instance->SetIsOffTheRecord(is_otr);
+#ifdef CHROME_PERSONALIZATION
+ instance->EnablePersonalization(CommandLine().HasSwitch(
+ switches::kEnableP13n));
+#endif
+ FocusManager::CreateFocusManager(instance->m_hWnd, &(instance->root_view_));
+ return instance;
+}
+
+XPFrame::XPFrame(Browser* browser)
+ : browser_(browser),
+ root_view_(this),
+ frame_view_(NULL),
+ tabstrip_(NULL),
+ active_bookmark_bar_(NULL),
+ tab_contents_container_(NULL),
+ min_button_(NULL),
+ max_button_(NULL),
+ restore_button_(NULL),
+ close_button_(NULL),
+ should_save_window_placement_(browser->GetType() != BrowserType::BROWSER),
+ saved_window_placement_(false),
+ current_action_(FA_NONE),
+ on_mouse_leave_armed_(false),
+ previous_cursor_(NULL),
+ minimum_size_(100, 100),
+ shelf_view_(NULL),
+ bookmark_bar_view_(NULL),
+ info_bar_view_(NULL),
+ is_active_(false),
+ is_off_the_record_(false),
+ title_bar_height_(0),
+ off_the_record_image_(NULL),
+ distributor_logo_(NULL),
+ ignore_ncactivate_(false),
+#ifdef CHROME_PERSONALIZATION
+ personalization_enabled_(false),
+ personalization_(NULL),
+#endif
+ paint_as_active_(false),
+ browser_view_(NULL) {
+ InitializeIfNeeded();
+}
+
+XPFrame::~XPFrame() {
+ DestroyBrowser();
+}
+
+void XPFrame::InitAfterHWNDCreated() {
+ tooltip_manager_.reset(new ChromeViews::TooltipManager(this, m_hWnd));
+}
+
+ChromeViews::TooltipManager* XPFrame::GetTooltipManager() {
+ return tooltip_manager_.get();
+}
+
+StatusBubble* XPFrame::GetStatusBubble() {
+ return NULL;
+}
+
+void XPFrame::InitializeIfNeeded() {
+ if (!g_initialized) {
+ g_resize_cursors[RC_VERTICAL] = LoadCursor(NULL, IDC_SIZENS);
+ g_resize_cursors[RC_HORIZONTAL] = LoadCursor(NULL, IDC_SIZEWE);
+ g_resize_cursors[RC_NESW] = LoadCursor(NULL, IDC_SIZENESW);
+ g_resize_cursors[RC_NWSE] = LoadCursor(NULL, IDC_SIZENWSE);
+
+ ResourceBundle &rb = ResourceBundle::GetSharedInstance();
+ g_bitmaps = new SkBitmap*[arraysize(kImageNames)];
+ g_otr_bitmaps = new SkBitmap*[arraysize(kOTRImageNames)];
+ for (int i = 0; i < arraysize(kImageNames); i++) {
+ g_bitmaps[i] = rb.GetBitmapNamed(kImageNames[i]);
+ g_otr_bitmaps[i] = rb.GetBitmapNamed(kOTRImageNames[i]);
+ }
+
+ g_bottom_margin = (int) kContentBorderVertBottomOffset +
+ g_bitmaps[CT_BOTTOM_CENTER]->height();
+ g_left_margin = (int) kContentBorderHorizOffset +
+ g_bitmaps[CT_LEFT_SIDE]->width();
+ g_right_margin = g_left_margin;
+ g_title_bar_height = (int) kContentBorderVertTopOffset +
+ g_bitmaps[CT_TOP_CENTER]->height();
+
+ g_initialized = TRUE;
+ }
+}
+
+void XPFrame::Init() {
+ ResourceBundle &rb = ResourceBundle::GetSharedInstance();
+
+ FrameUtil::RegisterBrowserWindow(this);
+
+ // Link the HWND with its root view so we can retrieve the RootView from the
+ // HWND for automation purposes.
+ ChromeViews::SetRootViewForHWND(m_hWnd, &root_view_);
+
+ // Remove the WS_CAPTION explicitely because we don't want a window style
+ // title bar
+ SetWindowLongPtr(GWL_STYLE,
+ (GetWindowLongPtr(GWL_STYLE) & ~WS_CAPTION) | WS_BORDER);
+
+ frame_view_ = new XPFrameView(this);
+ root_view_.AddChildView(frame_view_);
+ root_view_.SetAccessibleName(l10n_util::GetString(IDS_PRODUCT_NAME));
+ frame_view_->SetAccessibleName(l10n_util::GetString(IDS_PRODUCT_NAME));
+
+ // Use a white background. This will be the color of the content area until
+ // the first tab has started, so we want it to look minimally jarring when
+ // it is replaced by web content.
+ //
+ // TODO(brettw) if we have a preference for default page background, this
+ // color should be the same.
+ root_view_.SetBackground(
+ ChromeViews::Background::CreateSolidBackground(SK_ColorWHITE));
+
+ browser_view_ = new BrowserView(this, browser_, NULL, NULL);
+ frame_view_->AddChildView(browser_view_);
+
+ tabstrip_ = CreateTabStrip(browser_);
+ tabstrip_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_TABSTRIP));
+ frame_view_->AddChildView(tabstrip_);
+
+ tab_contents_container_ = new TabContentsContainerView();
+ frame_view_->AddChildView(tab_contents_container_);
+
+#ifdef CHROME_PERSONALIZATION
+ if (PersonalizationEnabled()) {
+ personalization_ = Personalization::CreateFramePersonalization(
+ browser_->profile(), frame_view_);
+ }
+#endif
+
+ if (is_off_the_record_) {
+ off_the_record_image_ = new ChromeViews::ImageView();
+ SkBitmap* otr_icon = rb.GetBitmapNamed(IDR_OTR_ICON);
+ off_the_record_image_->SetImage(*otr_icon);
+ off_the_record_image_->SetTooltipText(
+ l10n_util::GetString(IDS_OFF_THE_RECORD_TOOLTIP));
+ frame_view_->AddChildView(off_the_record_image_);
+ frame_view_->AddViewToDropList(off_the_record_image_);
+ }
+
+ SkBitmap* image = rb.GetBitmapNamed(IDR_DISTRIBUTOR_LOGO_LIGHT);
+ if (!image->isNull()) {
+ distributor_logo_ = new ChromeViews::ImageView();
+ frame_view_->AddViewToDropList(distributor_logo_);
+ distributor_logo_->SetImage(image);
+ frame_view_->AddChildView(distributor_logo_);
+ }
+
+ min_button_ = new ChromeViews::Button();
+ min_button_->SetListener(this, MINIATURIZE_TAG);
+ min_button_->SetImage(ChromeViews::Button::BS_NORMAL,
+ rb.GetBitmapNamed(IDR_MINIMIZE));
+ min_button_->SetImage(ChromeViews::Button::BS_HOT,
+ rb.GetBitmapNamed(IDR_MINIMIZE_H));
+ min_button_->SetImage(ChromeViews::Button::BS_PUSHED,
+ rb.GetBitmapNamed(IDR_MINIMIZE_P));
+ min_button_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_MINIMIZE));
+ min_button_->SetTooltipText(
+ l10n_util::GetString(IDS_XPFRAME_MINIMIZE_TOOLTIP));
+ frame_view_->AddChildView(min_button_);
+
+ max_button_ = new ChromeViews::Button();
+ max_button_->SetListener(this, MAXIMIZE_TAG);
+ max_button_->SetImage(ChromeViews::Button::BS_NORMAL,
+ rb.GetBitmapNamed(IDR_MAXIMIZE));
+ max_button_->SetImage(ChromeViews::Button::BS_HOT,
+ rb.GetBitmapNamed(IDR_MAXIMIZE_H));
+ max_button_->SetImage(ChromeViews::Button::BS_PUSHED,
+ rb.GetBitmapNamed(IDR_MAXIMIZE_P));
+ max_button_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_MAXIMIZE));
+ max_button_->SetTooltipText(
+ l10n_util::GetString(IDS_XPFRAME_MAXIMIZE_TOOLTIP));
+ frame_view_->AddChildView(max_button_);
+
+ restore_button_ = new ChromeViews::Button();
+ restore_button_->SetListener(this, RESTORE_TAG);
+ restore_button_->SetImage(ChromeViews::Button::BS_NORMAL,
+ rb.GetBitmapNamed(IDR_RESTORE));
+ restore_button_->SetImage(ChromeViews::Button::BS_HOT,
+ rb.GetBitmapNamed(IDR_RESTORE_H));
+ restore_button_->SetImage(ChromeViews::Button::BS_PUSHED,
+ rb.GetBitmapNamed(IDR_RESTORE_P));
+ restore_button_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_RESTORE));
+ restore_button_->SetTooltipText(
+ l10n_util::GetString(IDS_XPFRAME_RESTORE_TOOLTIP));
+ frame_view_->AddChildView(restore_button_);
+
+ close_button_ = new ChromeViews::Button();
+ close_button_->SetListener(this, CLOSE_TAG);
+ close_button_->SetImage(ChromeViews::Button::BS_NORMAL,
+ rb.GetBitmapNamed(IDR_CLOSE));
+ close_button_->SetImage(ChromeViews::Button::BS_HOT,
+ rb.GetBitmapNamed(IDR_CLOSE_H));
+ close_button_->SetImage(ChromeViews::Button::BS_PUSHED,
+ rb.GetBitmapNamed(IDR_CLOSE_P));
+ close_button_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_CLOSE));
+ close_button_->SetTooltipText(
+ l10n_util::GetString(IDS_XPFRAME_CLOSE_TOOLTIP));
+ frame_view_->AddChildView(close_button_);
+
+ // Add the task manager item to the system menu before the last entry.
+ task_manager_label_text_ = l10n_util::GetString(IDS_TASKMANAGER);
+ HMENU system_menu = ::GetSystemMenu(m_hWnd, FALSE);
+ int index = ::GetMenuItemCount(system_menu) - 1;
+ if (index < 0) {
+ // Paranoia check.
+ index = 0;
+ }
+
+ // First we add the separator.
+ MENUITEMINFO menu_info;
+ memset(&menu_info, 0, sizeof(MENUITEMINFO));
+ menu_info.cbSize = sizeof(MENUITEMINFO);
+ menu_info.fMask = MIIM_FTYPE;
+ menu_info.fType = MFT_SEPARATOR;
+ ::InsertMenuItem(system_menu, index, TRUE, &menu_info);
+ // Then the actual menu.
+ menu_info.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING;
+ menu_info.fType = MFT_STRING;
+ menu_info.fState = MFS_ENABLED;
+ menu_info.wID = IDC_TASKMANAGER;
+ menu_info.dwTypeData = const_cast<wchar_t*>(task_manager_label_text_.c_str());
+ ::InsertMenuItem(system_menu, index, TRUE, &menu_info);
+
+ // Register accelerators.
+ HACCEL accelerators_table = AtlLoadAccelerators(IDR_MAINFRAME);
+ DCHECK(accelerators_table);
+ FrameUtil::LoadAccelerators(this, accelerators_table, this);
+
+ ShelfVisibilityChanged();
+ root_view_.OnViewContainerCreated();
+}
+
+TabStrip* XPFrame::CreateTabStrip(Browser* browser) {
+ return new TabStrip(browser->tabstrip_model());
+}
+
+void XPFrame::Show(int command, bool adjust_to_fit) {
+ if (adjust_to_fit)
+ win_util::AdjustWindowToFit(*this);
+ ::ShowWindow(*this, command);
+}
+
+void* XPFrame::GetPlatformID() {
+ return reinterpret_cast<void*>(m_hWnd);
+}
+
+int XPFrame::GetContentsYOrigin() {
+ int min_y = tab_contents_container_->GetY();
+ if (info_bar_view_)
+ min_y = std::min(min_y, info_bar_view_->GetY());
+
+ if (bookmark_bar_view_.get())
+ min_y = std::min(min_y, bookmark_bar_view_->GetY());
+
+ return min_y;
+}
+
+SkBitmap** XPFrame::GetFrameBitmaps() {
+ if (is_off_the_record_)
+ return g_otr_bitmaps;
+ else
+ return g_bitmaps;
+}
+
+void XPFrame::Layout() {
+ CRect client_rect;
+ GetClientRect(&client_rect);
+ int width = client_rect.Width();
+ int height = client_rect.Height();
+
+ root_view_.SetBounds(0, 0, width, height);
+ frame_view_->SetBounds(0, 0, width, height);
+
+ CSize preferred_size;
+
+ if (IsZoomed()) {
+ close_button_->GetPreferredSize(&preferred_size);
+ close_button_->SetImageAlignment(ChromeViews::Button::ALIGN_LEFT,
+ ChromeViews::Button::ALIGN_BOTTOM);
+ close_button_->SetBounds(width - preferred_size.cx -
+ kWindowControlsRightZoomedOffset,
+ 0,
+ preferred_size.cx +
+ kWindowControlsRightZoomedOffset,
+ preferred_size.cy +
+ kWindowControlsTopZoomedOffset);
+
+ max_button_->SetVisible(false);
+
+ restore_button_->SetVisible(true);
+ restore_button_->GetPreferredSize(&preferred_size);
+ restore_button_->SetImageAlignment(ChromeViews::Button::ALIGN_LEFT,
+ ChromeViews::Button::ALIGN_BOTTOM);
+ restore_button_->SetBounds(close_button_->GetX() - preferred_size.cx,
+ 0,
+ preferred_size.cx,
+ preferred_size.cy +
+ kWindowControlsTopZoomedOffset);
+
+ min_button_->GetPreferredSize(&preferred_size);
+ min_button_->SetImageAlignment(ChromeViews::Button::ALIGN_LEFT,
+ ChromeViews::Button::ALIGN_BOTTOM);
+ min_button_->SetBounds(restore_button_->GetX() - preferred_size.cx,
+ 0,
+ preferred_size.cx,
+ preferred_size.cy +
+ kWindowControlsTopZoomedOffset);
+
+ } else {
+ close_button_->GetPreferredSize(&preferred_size);
+ close_button_->SetImageAlignment(ChromeViews::Button::ALIGN_LEFT,
+ ChromeViews::Button::ALIGN_TOP);
+ close_button_->SetBounds(width - kWindowControlsRightOffset -
+ preferred_size.cx,
+ kWindowControlsTopOffset,
+ preferred_size.cx,
+ preferred_size.cy);
+
+ restore_button_->SetVisible(false);
+
+ max_button_->SetVisible(true);
+ max_button_->GetPreferredSize(&preferred_size);
+ max_button_->SetImageAlignment(ChromeViews::Button::ALIGN_LEFT,
+ ChromeViews::Button::ALIGN_TOP);
+ max_button_->SetBounds(close_button_->GetX() - preferred_size.cx,
+ kWindowControlsTopOffset,
+ preferred_size.cx,
+ preferred_size.cy);
+
+ min_button_->GetPreferredSize(&preferred_size);
+ min_button_->SetImageAlignment(ChromeViews::Button::ALIGN_LEFT,
+ ChromeViews::Button::ALIGN_TOP);
+ min_button_->SetBounds(max_button_->GetX() - preferred_size.cx,
+ kWindowControlsTopOffset,
+ preferred_size.cx,
+ preferred_size.cy);
+ }
+
+ int right_limit = min_button_->GetX();
+ int left_margin;
+ int right_margin;
+ int bottom_margin;
+ int top_margin;
+
+ SkBitmap** bitmaps = GetFrameBitmaps();
+ if (IsZoomed()) {
+ right_limit -= kZoomedStripPadding;
+ top_margin = kZoomedTopMargin;
+ bottom_margin = kZoomedBottomMargin;
+ left_margin = 0;
+ right_margin = 0;
+ } else {
+ top_margin = kTopMargin;
+ bottom_margin = g_bottom_margin;
+ left_margin = g_left_margin;
+ right_margin = g_right_margin;
+ }
+
+ int last_y = top_margin - 1;
+ if (IsTabStripVisible()) {
+ int tab_strip_x = left_margin;
+
+ if (is_off_the_record_) {
+ CSize otr_image_size;
+ off_the_record_image_->GetPreferredSize(&otr_image_size);
+ tab_strip_x += otr_image_size.cx + (2 * kOTRImageHorizMargin);
+ if (IsZoomed()) {
+ off_the_record_image_->SetBounds(left_margin + kOTRImageHorizMargin,
+ top_margin + 1,
+ otr_image_size.cx,
+ tabstrip_->GetPreferredHeight() -
+ kToolbarOverlapVertOffset - 1);
+ } else {
+ off_the_record_image_->SetBounds(left_margin + kOTRImageHorizMargin,
+ top_margin - 1 +
+ tabstrip_->GetPreferredHeight() -
+ otr_image_size.cy -
+ kOTRImageVertMargin,
+ otr_image_size.cx,
+ otr_image_size.cy);
+ }
+ }
+
+ if (distributor_logo_) {
+ if (IsZoomed()) {
+ distributor_logo_->SetVisible(false);
+ } else {
+ CSize distributor_logo_size;
+ distributor_logo_->GetPreferredSize(&distributor_logo_size);
+ distributor_logo_->SetVisible(true);
+ distributor_logo_->SetBounds(min_button_->GetX() -
+ distributor_logo_size.cx -
+ kDistributorLogoHorizontalOffset,
+ kDistributorLogoVerticalOffset,
+ distributor_logo_size.cx,
+ distributor_logo_size.cy);
+ }
+ }
+
+ tabstrip_->SetBounds(tab_strip_x, top_margin - 1,
+ right_limit - tab_strip_x - right_margin,
+ tabstrip_->GetPreferredHeight());
+
+ last_y = tabstrip_->GetY() + tabstrip_->GetHeight();
+ } else {
+ tabstrip_->SetBounds(0, 0, 0, 0);
+ tabstrip_->SetVisible(false);
+ if (is_off_the_record_)
+ off_the_record_image_->SetVisible(false);
+ }
+
+ int browser_view_width = width - left_margin - right_margin;
+#ifdef CHROME_PERSONALIZATION
+ if (PersonalizationEnabled())
+ Personalization::AdjustBrowserView(personalization_, &browser_view_width);
+#endif
+
+ if (IsToolBarVisible()) {
+ browser_view_->SetVisible(true);
+ browser_view_->SetBounds(left_margin,
+ last_y - kToolbarOverlapVertOffset,
+ browser_view_width,
+ bitmaps[CT_TOP_CENTER]->height());
+ browser_view_->Layout();
+ title_bar_height_ = browser_view_->GetY();
+ last_y = browser_view_->GetY() + browser_view_->GetHeight();
+ } else {
+ // If the tab strip is visible, we need to expose the toolbar for a small
+ // offset. (kCollapsedToolbarHeight).
+ if (IsTabStripVisible()) {
+ title_bar_height_ = last_y;
+ last_y += kCollapsedToolbarHeight;
+ } else {
+ last_y = std::max(kMinTitleBarHeight,
+ close_button_->GetY() + close_button_->GetHeight());
+ title_bar_height_ = last_y;
+ }
+ browser_view_->SetVisible(false);
+ }
+
+ int browser_h = height - last_y - bottom_margin;
+ if (shelf_view_) {
+ shelf_view_->GetPreferredSize(&preferred_size);
+ shelf_view_->SetBounds(left_margin,
+ height - bottom_margin - preferred_size.cy,
+ width - left_margin - right_margin,
+ preferred_size.cy);
+ browser_h -= preferred_size.cy;
+ }
+
+ int bookmark_bar_height = 0;
+
+ CSize bookmark_bar_size;
+ CSize info_bar_size;
+
+ if (bookmark_bar_view_.get()) {
+ bookmark_bar_view_->GetPreferredSize(&bookmark_bar_size);
+ bookmark_bar_height = bookmark_bar_size.cy;
+ }
+
+ if (info_bar_view_)
+ info_bar_view_->GetPreferredSize(&info_bar_size);
+
+ // If we're showing a bookmarks bar in the new tab page style and we
+ // have an infobar showing, we need to flip them.
+ if (info_bar_view_ &&
+ bookmark_bar_view_.get() &&
+ bookmark_bar_view_->IsNewTabPage() &&
+ !bookmark_bar_view_->IsAlwaysShown()) {
+ info_bar_view_->SetBounds(left_margin,
+ last_y,
+ client_rect.Width() - left_margin - right_margin,
+ info_bar_size.cy);
+ browser_h -= info_bar_size.cy;
+ last_y += info_bar_size.cy;
+
+ last_y -= kSeparationLineHeight;
+
+ bookmark_bar_view_->SetBounds(left_margin,
+ last_y,
+ client_rect.Width() - left_margin -
+ right_margin,
+ bookmark_bar_size.cy);
+ browser_h -= (bookmark_bar_size.cy - kSeparationLineHeight);
+ last_y += bookmark_bar_size.cy;
+ } else {
+ if (bookmark_bar_view_.get()) {
+ // We want our bookmarks bar to be responsible for drawing its own
+ // separator, so we let it overlap ours.
+ last_y -= kSeparationLineHeight;
+
+ bookmark_bar_view_->SetBounds(left_margin,
+ last_y,
+ client_rect.Width() - left_margin -
+ right_margin,
+ bookmark_bar_size.cy);
+ browser_h -= (bookmark_bar_size.cy - kSeparationLineHeight);
+ last_y += bookmark_bar_size.cy;
+ }
+
+ if (info_bar_view_) {
+ info_bar_view_->SetBounds(left_margin,
+ last_y,
+ client_rect.Width() -
+ left_margin - right_margin,
+ info_bar_size.cy);
+ browser_h -= info_bar_size.cy;
+ last_y += info_bar_size.cy;
+ }
+ }
+
+ tab_contents_container_->SetBounds(left_margin,
+ last_y,
+ width - left_margin - right_margin,
+ browser_h);
+#ifdef CHROME_PERSONALIZATION
+ if (PersonalizationEnabled()) {
+ Personalization::ConfigureFramePersonalization(personalization_,
+ browser_view_, top_margin);
+ }
+#endif
+
+ browser_view_->LayoutStatusBubble(last_y + browser_h);
+
+ frame_view_->SchedulePaint();
+}
+
+// This is called when we receive WM_ENDSESSION. We have 5 seconds to quit
+// the application or we are going to be flagged as flaky.
+void XPFrame::OnEndSession(BOOL ending, UINT logoff) {
+ tabstrip_->AbortActiveDragSession();
+ FrameUtil::EndSession();
+}
+
+// Note: called directly by the handler macros to handle WM_CLOSE messages.
+void XPFrame::Close() {
+ // You cannot close a frame for which there is an active originating drag
+ // session.
+ if (tabstrip_->IsDragSessionActive())
+ return;
+
+ // Give beforeunload handlers the chance to cancel the close before we hide
+ // the window below.
+ if (!browser_->ShouldCloseWindow())
+ return;
+
+ // We call this here so that the window position gets saved before moving
+ // the window into hyperspace.
+ if (!saved_window_placement_ && should_save_window_placement_ && browser_) {
+ browser_->SaveWindowPlacement();
+ browser_->SaveWindowPlacementToDatabase();
+ saved_window_placement_ = true;
+ }
+
+ if (browser_ && !browser_->tabstrip_model()->empty()) {
+ // Tab strip isn't empty. Hide the window (so it appears to have closed
+ // immediately) and close all the tabs, allowing the renderers to shut
+ // down. When the tab strip is empty we'll be called back recursively.
+ if (current_action_ == FA_RESIZING)
+ StopWindowResize();
+ // NOTE: Don't use ShowWindow(SW_HIDE) here, otherwise end session blocks
+ // here.
+ SetWindowPos(NULL, 0, 0, 0, 0,
+ SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOMOVE |
+ SWP_NOREPOSITION | SWP_NOSIZE | SWP_NOZORDER);
+ browser_->OnWindowClosing();
+ } else {
+ // Empty tab strip, it's now safe to do the final clean-up.
+
+ root_view_.OnViewContainerDestroyed();
+
+ NotificationService::current()->Notify(
+ NOTIFY_WINDOW_CLOSED, Source<HWND>(m_hWnd),
+ NotificationService::NoDetails());
+ DestroyWindow();
+ }
+}
+
+void XPFrame::OnFinalMessage(HWND hwnd) {
+ delete this;
+}
+
+void XPFrame::SetAcceleratorTable(
+ std::map<Accelerator, int>* accelerator_table) {
+ accelerator_table_.reset(accelerator_table);
+}
+
+bool XPFrame::GetAccelerator(int cmd_id, ChromeViews::Accelerator* accelerator)
+ {
+ std::map<ChromeViews::Accelerator, int>::iterator it =
+ accelerator_table_->begin();
+ for (; it != accelerator_table_->end(); ++it) {
+ if (it->second == cmd_id) {
+ *accelerator = it->first;
+ return true;
+ }
+ }
+ return false;
+}
+
+
+bool XPFrame::AcceleratorPressed(const Accelerator& accelerator) {
+ DCHECK(accelerator_table_.get());
+ std::map<Accelerator, int>::const_iterator iter =
+ accelerator_table_->find(accelerator);
+ DCHECK(iter != accelerator_table_->end());
+
+ int command_id = iter->second;
+ if (browser_->SupportsCommand(command_id) &&
+ browser_->IsCommandEnabled(command_id)) {
+ browser_->ExecuteCommand(command_id);
+ return true;
+ }
+ return false;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Events
+//
+////////////////////////////////////////////////////////////////////////////////
+LRESULT XPFrame::OnSettingChange(UINT u_msg, WPARAM w_param, LPARAM l_param,
+ BOOL& handled) {
+ // Set this to false, if we actually handle the message, we'll set it to
+ // true below.
+ handled = FALSE;
+ if (w_param != SPI_SETWORKAREA)
+ return 0; // Return value is effectively ignored in atlwin.h.
+
+ win_util::AdjustWindowToFit(m_hWnd);
+ handled = TRUE;
+ return 0; // Return value is effectively ignored in atlwin.h.
+}
+
+LRESULT XPFrame::OnNCCalcSize(BOOL w_param, LPARAM l_param) {
+ // By default the client side is set to the window size which is what
+ // we want.
+ return 0;
+}
+
+LRESULT XPFrame::OnNCPaint(HRGN param) {
+ return 0;
+}
+
+LRESULT XPFrame::OnMouseRange(UINT u_msg, WPARAM w_param, LPARAM l_param,
+ BOOL& handled) {
+ tooltip_manager_->OnMouse(u_msg, w_param, l_param);
+ handled = FALSE;
+ return 0;
+}
+
+LRESULT XPFrame::OnNotify(int w_param, NMHDR* l_param) {
+ bool handled;
+ LRESULT result = tooltip_manager_->OnNotify(w_param, l_param, &handled);
+ SetMsgHandled(handled);
+ return result;
+}
+
+void XPFrame::OnMove(const CSize& size) {
+ if (!saved_window_placement_ && should_save_window_placement_)
+ browser_->SaveWindowPlacementToDatabase();
+
+ browser_->WindowMoved();
+}
+
+void XPFrame::OnMoving(UINT param, const LPRECT new_bounds) {
+ // We want to let the browser know that the window moved so that it can
+ // update the positions of any dependent WS_POPUPs
+ browser_->WindowMoved();
+}
+
+void XPFrame::OnSize(UINT param, const CSize& size) {
+ if (IsZoomed()) {
+ SetWindowRgn(NULL, TRUE);
+ } else if (IsIconic()) {
+ // After minimizing the window, Windows will send us an OnSize
+ // message where size is equal to the bounds of the entry in the
+ // task bar. This is obviously bogus for our purposes and will
+ // just confuse Layout() so bail.
+ return;
+ } else {
+ PointBuffer o;
+
+ // Redefine the window visible region for the new size
+ o.AddPoint(0, 3);
+ o.AddPoint(1, 1);
+ o.AddPoint(3, 0);
+
+ o.AddPoint(size.cx - 3, 0);
+ o.AddPoint(size.cx - 1, 1);
+ o.AddPoint(size.cx - 1, 3);
+ o.AddPoint(size.cx - 0, 3);
+
+ o.AddPoint(size.cx, size.cy);
+ o.AddPoint(0, size.cy);
+
+ // When resizing we don't want an extra paint to limit flicker
+ SetWindowRgn(o.GetCurrentPolygonRegion(),
+ current_action_ == FA_RESIZING ? FALSE : TRUE);
+ }
+
+ // Layout our views
+ Layout();
+
+ // We paint immediately during a resize because it will feel laggy otherwise.
+ if (root_view_.NeedsPainting(false)) {
+ RedrawWindow(root_view_.GetScheduledPaintRect(),
+ NULL,
+ RDW_UPDATENOW | RDW_INVALIDATE | RDW_ALLCHILDREN);
+ MessageLoopForUI::current()->PumpOutPendingPaintMessages();
+ }
+
+ if (!saved_window_placement_ && should_save_window_placement_)
+ browser_->SaveWindowPlacementToDatabase();
+}
+
+void XPFrame::OnNCLButtonDown(UINT flags, const CPoint& pt) {
+ // DefWindowProc implementation for WM_NCLBUTTONDOWN will allow a
+ // maximized window to move if the window size is less than screen
+ // size. We have to handle this message to suppress this behavior.
+ if (ShouldWorkAroundAutoHideTaskbar() && IsZoomed()) {
+ if (GetForegroundWindow() != m_hWnd) {
+ SetForegroundWindow(m_hWnd);
+ }
+ } else {
+ SetMsgHandled(FALSE);
+ }
+}
+
+void XPFrame::OnNCMButtonDown(UINT flags, const CPoint& pt) {
+ // The point is in screen coordinate system so we need to convert
+ CRect window_rect;
+ GetWindowRect(&window_rect);
+ CPoint point(pt);
+ point.x -= window_rect.left;
+ point.y -= window_rect.top;
+
+ // Yes we need to add MK_MBUTTON. Windows doesn't include it
+ OnMouseButtonDown(flags | MK_MBUTTON, point);
+}
+
+void XPFrame::OnNCRButtonDown(UINT flags, const CPoint& pt) {
+ // The point is in screen coordinate system so we need to convert
+ CRect window_rect;
+ GetWindowRect(&window_rect);
+ CPoint point(pt);
+ point.x -= window_rect.left;
+ point.y -= window_rect.top;
+
+ // Yes we need to add MK_RBUTTON. Windows doesn't include it
+ OnMouseButtonDown(flags | MK_RBUTTON, point);
+}
+
+void XPFrame::OnMouseButtonDown(UINT flags, const CPoint& pt) {
+ using namespace ChromeViews;
+ if (m_hWnd == NULL || !IsWindowVisible()) {
+ return;
+ }
+
+ CRect original_rect;
+
+ GetWindowRect(&original_rect);
+ int width = original_rect.Width();
+ int height= original_rect.Height();
+
+ if (!ProcessMousePressed(pt, flags, FALSE)) {
+ // Edge case when showing a menu that will close the window.
+ if (!IsVisible())
+ return;
+ if (flags & MK_LBUTTON) {
+ if (!IsZoomed()) {
+ ResizeMode rm = ComputeResizeMode(pt.x, pt.y, width, height);
+ if (rm != RM_UNDEFINED) {
+ StartWindowResize(rm, pt);
+ }
+ }
+ } else if (flags & MK_RBUTTON && pt.y < title_bar_height_) {
+ CRect r;
+ ::GetWindowRect(*this, &r);
+ ShowSystemMenu(r.left + pt.x, r.top + pt.y);
+ }
+ }
+}
+
+void XPFrame::OnMouseButtonUp(UINT flags, const CPoint& pt) {
+ if (m_hWnd == NULL) {
+ return;
+ }
+
+ if (flags & MK_LBUTTON) {
+ switch (current_action_) {
+ case FA_RESIZING:
+ StopWindowResize();
+ break;
+ case FA_FORWARDING:
+ ProcessMouseReleased(pt, flags);
+ break;
+ }
+ } else {
+ ProcessMouseReleased(pt, flags);
+ }
+}
+
+void XPFrame::OnMouseButtonDblClk(UINT flags, const CPoint& pt) {
+ if (m_hWnd == NULL) {
+ return;
+ }
+
+ if (!ProcessMousePressed(pt, flags, TRUE)) {
+ CRect original_rect;
+ GetWindowRect(&original_rect);
+ int width = original_rect.Width();
+ int height= original_rect.Height();
+
+ // If the user double clicked on a resize area, ignore.
+ if (ComputeResizeMode(pt.x, pt.y, width, height) == RM_UNDEFINED &&
+ pt.y < title_bar_height_) {
+ if (flags & MK_LBUTTON) {
+ if (IsZoomed()) {
+ ShowWindow(SW_RESTORE);
+ } else {
+ ShowWindow(SW_MAXIMIZE);
+ }
+ }
+ }
+ }
+}
+
+void XPFrame::OnLButtonUp(UINT flags, const CPoint& pt) {
+ OnMouseButtonUp(flags | MK_LBUTTON, pt);
+}
+
+void XPFrame::OnMButtonUp(UINT flags, const CPoint& pt) {
+ OnMouseButtonUp(flags | MK_MBUTTON, pt);
+}
+
+void XPFrame::OnRButtonUp(UINT flags, const CPoint& pt) {
+ OnMouseButtonUp(flags | MK_RBUTTON, pt);
+}
+
+void XPFrame::OnMouseMove(UINT flags, const CPoint& pt) {
+ if (m_hWnd == NULL) {
+ return;
+ }
+
+ switch (current_action_) {
+ case FA_NONE: {
+ ArmOnMouseLeave();
+ ProcessMouseMoved(pt, flags);
+ if (!IsZoomed()) {
+ CRect r;
+ GetWindowRect(&r);
+ XPFrame::ResizeMode rm = ComputeResizeMode(pt.x,
+ pt.y,
+ r.Width(),
+ r.Height());
+ SetResizeCursor(rm);
+ }
+ break;
+ }
+ case FA_RESIZING: {
+ ProcessWindowResize(pt);
+ break;
+ }
+ case FA_FORWARDING: {
+ ProcessMouseDragged(pt, flags);
+ break;
+ }
+ }
+}
+
+void XPFrame::OnMouseLeave() {
+ if (m_hWnd == NULL) {
+ return;
+ }
+ ProcessMouseExited();
+ on_mouse_leave_armed_ = FALSE;
+}
+
+LRESULT XPFrame::OnGetObject(UINT uMsg, WPARAM w_param, LPARAM object_id) {
+ LRESULT reference_result = static_cast<LRESULT>(0L);
+
+ // Accessibility readers will send an OBJID_CLIENT message
+ if (OBJID_CLIENT == object_id) {
+ // If our MSAA root is already created, reuse that pointer. Otherwise,
+ // create a new one.
+ if (!accessibility_root_) {
+ CComObject<ViewAccessibility>* instance = NULL;
+
+ HRESULT hr = CComObject<ViewAccessibility>::CreateInstance(&instance);
+ DCHECK(SUCCEEDED(hr));
+
+ if (!instance) {
+ // Return with failure.
+ return static_cast<LRESULT>(0L);
+ }
+
+ CComPtr<IAccessible> accessibility_instance(instance);
+
+ if (!SUCCEEDED(instance->Initialize(&root_view_))) {
+ // Return with failure.
+ return static_cast<LRESULT>(0L);
+ }
+
+ // All is well, assign the temp instance to the class smart pointer
+ accessibility_root_.Attach(accessibility_instance.Detach());
+
+ if (!accessibility_root_) {
+ // Return with failure.
+ return static_cast<LRESULT>(0L);
+ }
+
+ // Notify that an instance of IAccessible was allocated for m_hWnd
+ ::NotifyWinEvent(EVENT_OBJECT_CREATE, m_hWnd, OBJID_CLIENT,
+ CHILDID_SELF);
+ }
+
+ // Create a reference to ViewAccessibility that MSAA will marshall
+ // to the client.
+ reference_result = LresultFromObject(IID_IAccessible, w_param,
+ static_cast<IAccessible*>(accessibility_root_));
+ }
+ return reference_result;
+}
+
+void XPFrame::OnKeyDown(TCHAR c, UINT rep_cnt, UINT flags) {
+ ChromeViews::KeyEvent event(ChromeViews::Event::ET_KEY_PRESSED, c,
+ rep_cnt, flags);
+ root_view_.ProcessKeyEvent(event);
+}
+
+void XPFrame::OnKeyUp(TCHAR c, UINT rep_cnt, UINT flags) {
+ ChromeViews::KeyEvent event(ChromeViews::Event::ET_KEY_RELEASED, c,
+ rep_cnt, flags);
+ root_view_.ProcessKeyEvent(event);
+}
+
+void XPFrame::OnActivate(UINT n_state, BOOL is_minimized, HWND other) {
+ if (FrameUtil::ActivateAppModalDialog(browser_))
+ return;
+
+ // We get deactivation notices before the window is deactivated,
+ // so we need our Paint methods to know which type of window to
+ // draw.
+ is_active_ = (n_state != WA_INACTIVE);
+
+ if (!is_minimized) {
+ browser_->WindowActivationChanged(is_active_);
+
+ // Redraw the frame.
+ frame_view_->SchedulePaint();
+
+ // We need to force a paint now, as a user dragging a window
+ // will block painting operations while the move is in progress.
+ PaintNow(root_view_.GetScheduledPaintRect());
+ }
+}
+
+int XPFrame::OnMouseActivate(CWindow wndTopLevel, UINT nHitTest, UINT message) {
+ return FrameUtil::ActivateAppModalDialog(browser_) ? MA_NOACTIVATEANDEAT
+ : MA_ACTIVATE;
+}
+
+void XPFrame::OnPaint(HDC dc) {
+ root_view_.OnPaint(*this);
+}
+
+LRESULT XPFrame::OnEraseBkgnd(HDC dc) {
+ SetMsgHandled(TRUE);
+ return 1;
+}
+
+void XPFrame::OnMinMaxInfo(LPMINMAXINFO mm_info) {
+ // From MINMAXINFO documentation:
+ // For systems with multiple monitors, the ptMaxSize and ptMaxPosition members
+ // describe the maximized size and position of the window on the primary
+ // monitor, even if the window ultimately maximizes onto a secondary monitor.
+ // In that case, the window manager adjusts these values to compensate for
+ // differences between the primary monitor and the monitor that displays the
+ // window. Thus, if the user leaves ptMaxSize untouched, a window on a monitor
+ // larger than the primary monitor maximizes to the size of the larger
+ // monitor.
+ //
+ // But what the documentation doesn't say is that we need to compensate for
+ // the taskbar. :/
+ //
+ // - So use the primary monitor for position and size calculation.
+ // - Take in account the existence or not of the task bar in the destination
+ // monitor and adjust accordingly.
+ // 99% of the time, they will contain mostly the same information.
+
+ HMONITOR primary_monitor = ::MonitorFromWindow(NULL,
+ MONITOR_DEFAULTTOPRIMARY);
+ MONITORINFO primary_info;
+ primary_info.cbSize = sizeof(primary_info);
+ GetMonitorInfo(primary_monitor, &primary_info);
+
+ HMONITOR destination_monitor = ::MonitorFromWindow(m_hWnd,
+ MONITOR_DEFAULTTONEAREST);
+ MONITORINFO destination_info;
+ destination_info.cbSize = sizeof(destination_info);
+ GetMonitorInfo(destination_monitor, &destination_info);
+
+ // Take in account the destination monitor taskbar location but the primary
+ // monitor size.
+ int primary_monitor_width =
+ primary_info.rcMonitor.right - primary_info.rcMonitor.left;
+ int primary_monitor_height =
+ primary_info.rcMonitor.bottom - primary_info.rcMonitor.top;
+ mm_info->ptMaxSize.x =
+ primary_monitor_width -
+ (destination_info.rcMonitor.right - destination_info.rcWork.right) -
+ (destination_info.rcWork.left - destination_info.rcMonitor.left);
+ mm_info->ptMaxSize.y =
+ primary_monitor_height -
+ (destination_info.rcMonitor.bottom - destination_info.rcWork.bottom) -
+ (destination_info.rcWork.top - destination_info.rcMonitor.top);
+
+ mm_info->ptMaxPosition.x = destination_info.rcWork.left -
+ destination_info.rcMonitor.left;
+ mm_info->ptMaxPosition.y = destination_info.rcWork.top -
+ destination_info.rcMonitor.top;
+
+ if (primary_monitor == destination_monitor) {
+ // Only add support for auto-hidding taskbar on primary monitor.
+ if (ShouldWorkAroundAutoHideTaskbar() &&
+ EqualRect(&destination_info.rcWork, &destination_info.rcMonitor)) {
+ mm_info->ptMaxSize.y--;
+ }
+ } else {
+ // If the taskbar is on the second monitor, the difference in monitor size
+ // won't be added. The reason: if the maximized size is less than the
+ // primary monitor size, it won't get resized to the full screen of the
+ // destination monitor (!) The position will get fixed in any case, just not
+ // the size. The problem is that if we preemptly add the monitor size
+ // difference, the window will get larger than the primary monitor size and
+ // Windows will add (again) the monitor size difference!
+ //
+ // So for now, simply don't support the taskbar on a secondary monitor with
+ // different monitor sizes.
+#ifdef BUG_943445_FIXED
+ if (mm_info->ptMaxSize.x < primary_monitor_width ||
+ mm_info->ptMaxSize.y < primary_monitor_height) {
+ int dst_monitor_width = destination_info.rcMonitor.right -
+ destination_info.rcMonitor.left;
+ mm_info->ptMaxSize.x += (dst_monitor_width - primary_monitor_width);
+ int dst_monitor_height = destination_info.rcMonitor.bottom -
+ destination_info.rcMonitor.top;
+ mm_info->ptMaxSize.y += (dst_monitor_height - primary_monitor_height);
+ }
+#endif // BUG_943445_FIXED
+ }
+ // If you fully understand what's going on, you can now appreciate the joyness
+ // of programming on Windows.
+}
+
+void XPFrame::OnCaptureChanged(HWND hwnd) {
+ if (current_action_ == FA_FORWARDING)
+ root_view_.ProcessMouseDragCanceled();
+ current_action_ = FA_NONE;
+}
+
+LRESULT XPFrame::OnNCHitTest(const CPoint& pt) {
+ CPoint p(pt);
+ CRect r;
+ GetWindowRect(&r);
+
+ // Convert from screen to window coordinates
+ p.x -= r.left;
+ p.y -= r.top;
+
+ if (!IsTabStripVisible() &&
+ ComputeResizeMode(p.x, p.y, r.Width(), r.Height()) == RM_UNDEFINED &&
+ root_view_.GetViewForPoint(p) == frame_view_) {
+ return HTCAPTION;
+ }
+
+ CPoint tsp(p);
+ ChromeViews::View::ConvertPointToView(&root_view_, tabstrip_, &tsp);
+
+ // If the mouse is over the tabstrip. Check if we should move the window or
+ // capture the mouse.
+ if (tabstrip_->CanProcessInputEvents() && tabstrip_->HitTest(tsp)) {
+ // The top few pixels of a tab strip are a dropshadow - as we're pretty
+ // starved of draggable area, let's give it to window dragging (this
+ // also makes sense visually.
+ if (!IsZoomed() && tsp.y < kTabShadowSize)
+ return HTCAPTION;
+
+ ChromeViews::View* v = tabstrip_->GetViewForPoint(tsp);
+ // If there is not tab at this location, claim the hit was in the title
+ // bar to get a move action.
+ if (v == tabstrip_)
+ return HTCAPTION;
+
+ // If the view under mouse is a tab, check if the tab strip allows tab
+ // dragging or not. If not, return caption to get window dragging.
+ if (v->GetClassName() == Tab::kTabClassName &&
+ !tabstrip_->HasAvailableDragActions())
+ return HTCAPTION;
+ } else {
+ // The mouse is not above the tab strip. If there is no control under it,
+ // let's move the window.
+ if (ComputeResizeMode(p.x, p.y, r.Width(), r.Height()) == RM_UNDEFINED) {
+ ChromeViews::View* v = root_view_.GetViewForPoint(p);
+ if (v == frame_view_ || v == off_the_record_image_ ||
+ v == distributor_logo_) {
+ return HTCAPTION;
+ }
+ }
+ }
+
+ SetMsgHandled(FALSE);
+ return 0;
+}
+
+void XPFrame::ArmOnMouseLeave() {
+ if (!on_mouse_leave_armed_) {
+ TRACKMOUSEEVENT tme;
+ tme.cbSize = sizeof(tme);
+ tme.dwFlags = TME_LEAVE;
+ tme.hwndTrack = *this;
+ tme.dwHoverTime = 0;
+ TrackMouseEvent(&tme);
+ on_mouse_leave_armed_ = TRUE;
+ }
+}
+
+void XPFrame::OnInitMenu(HMENU menu) {
+ BOOL is_iconic = IsIconic();
+ BOOL is_zoomed = IsZoomed();
+
+ if (is_iconic || is_zoomed) {
+ ::EnableMenuItem(menu, SC_RESTORE, MF_BYCOMMAND | MF_ENABLED);
+ ::EnableMenuItem(menu, SC_MOVE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
+ ::EnableMenuItem(menu, SC_SIZE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
+ if (is_iconic) {
+ ::EnableMenuItem(menu, SC_MAXIMIZE, MF_BYCOMMAND | MF_ENABLED);
+ ::EnableMenuItem(menu, SC_MINIMIZE, MF_BYCOMMAND | MF_DISABLED |
+ MF_GRAYED);
+ } else {
+ ::EnableMenuItem(menu, SC_MAXIMIZE, MF_BYCOMMAND | MF_DISABLED |
+ MF_GRAYED);
+ ::EnableMenuItem(menu, SC_MINIMIZE, MF_BYCOMMAND | MF_ENABLED);
+ }
+ } else {
+ ::EnableMenuItem(menu, SC_RESTORE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
+ ::EnableMenuItem(menu, SC_MOVE, MF_BYCOMMAND | MF_ENABLED);
+ ::EnableMenuItem(menu, SC_SIZE, MF_BYCOMMAND | MF_ENABLED);
+ ::EnableMenuItem(menu, SC_MAXIMIZE, MF_BYCOMMAND | MF_ENABLED);
+ ::EnableMenuItem(menu, SC_MINIMIZE, MF_BYCOMMAND | MF_ENABLED);
+ }
+}
+
+void XPFrame::ShowSystemMenu(int x, int y) {
+ HMENU system_menu = ::GetSystemMenu(*this, FALSE);
+ int id = ::TrackPopupMenu(system_menu,
+ TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD,
+ x,
+ y,
+ 0,
+ *this,
+ NULL);
+ if (id) {
+ ::SendMessage(*this,
+ WM_SYSCOMMAND,
+ id,
+ 0);
+ }
+}
+
+LRESULT XPFrame::OnNCActivate(BOOL param) {
+ if (ignore_ncactivate_) {
+ ignore_ncactivate_ = false;
+ return DefWindowProc(WM_NCACTIVATE, TRUE, 0);
+ }
+ SetMsgHandled(false);
+ return 0;
+}
+
+BOOL XPFrame::OnPowerBroadcast(DWORD power_event, DWORD data) {
+ if (PBT_APMSUSPEND == power_event) {
+ SuspendController::OnSuspend(browser_->profile());
+ return TRUE;
+ } else if (PBT_APMRESUMEAUTOMATIC == power_event) {
+ SuspendController::OnResume(browser_->profile());
+ return TRUE;
+ }
+
+ SetMsgHandled(FALSE);
+ return FALSE;
+}
+
+void XPFrame::OnThemeChanged() {
+ // Notify NativeTheme.
+ gfx::NativeTheme::instance()->CloseHandles();
+}
+
+LRESULT XPFrame::OnAppCommand(
+ HWND w_param, short app_command, WORD device, int keystate) {
+ if (browser_ && !browser_->ExecuteWindowsAppCommand(app_command))
+ SetMsgHandled(FALSE);
+ return 0;
+}
+
+void XPFrame::OnCommand(UINT notification_code,
+ int command_id,
+ HWND window) {
+ if (browser_ && browser_->SupportsCommand(command_id)) {
+ browser_->ExecuteCommand(command_id);
+ } else {
+ SetMsgHandled(FALSE);
+ }
+}
+
+void XPFrame::OnSysCommand(UINT notification_code, CPoint click) {
+ switch (notification_code) {
+ case SC_CLOSE:
+ Close();
+ break;
+ case SC_MAXIMIZE:
+ ShowWindow(IsZoomed() ? SW_RESTORE : SW_MAXIMIZE);
+ break;
+ case IDC_TASKMANAGER:
+ if (browser_)
+ browser_->ExecuteCommand(IDC_TASKMANAGER);
+ break;
+
+ // Note that we avoid calling ShowWindow(SW_SHOWMINIMIZED) when we get a
+ // minimized system command because doing so will minimize the window but
+ // won't put the window at the bottom of the z-order window list. Instead,
+ // we pass the minimized event to the default window procedure.
+ case SC_MINIMIZE:
+ default:
+ // Use the default implementation for any other command.
+ SetMsgHandled(FALSE);
+ break;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Button:::ButtonListener
+//
+////////////////////////////////////////////////////////////////////////////////
+
+void XPFrame::ButtonPressed(ChromeViews::BaseButton *sender) {
+ switch (sender->GetTag()) {
+ case MINIATURIZE_TAG:
+ // We deliberately don't call ShowWindow(SW_SHOWMINIMIZED) directly
+ // because doing that will minimize the window, but won't put the window
+ // in the right z-order location.
+ //
+ // In order to minimize the window correctly, we need to post a system
+ // command which will be passed to the default window procedure for
+ // correct handling.
+ ::PostMessage(*this, WM_SYSCOMMAND, SC_MINIMIZE, 0);
+ break;
+ case MAXIMIZE_TAG:
+ ShowWindow(SW_MAXIMIZE);
+ break;
+ case RESTORE_TAG:
+ ShowWindow(SW_RESTORE);
+ break;
+ case CLOSE_TAG:
+ Close();
+ break;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Window move and resize
+//
+////////////////////////////////////////////////////////////////////////////////
+
+bool XPFrame::ShouldRefreshCurrentTabContents() {
+ if (browser_->tabstrip_model()) {
+ TabContents* tc = browser_->GetSelectedTabContents();
+ if (tc) {
+ HWND tc_hwnd = tc->GetContainerHWND();
+ return !!(::GetWindowLongPtr(tc_hwnd, GWL_STYLE) & WS_CLIPCHILDREN);
+ }
+ }
+ return false;
+}
+
+void XPFrame::StartWindowResize(ResizeMode mode, const CPoint &pt) {
+ SetCapture();
+ current_action_ = FA_RESIZING;
+ current_resize_mode_ = mode;
+
+ SetResizeCursor(mode);
+
+ GetWindowRect(&previous_bounds_);
+ drag_origin_ = pt;
+ drag_origin_.x += previous_bounds_.left;
+ drag_origin_.y += previous_bounds_.top;
+}
+
+void XPFrame::ProcessWindowResize(const CPoint &pt) {
+ CPoint current(pt);
+ CRect rect;
+ CRect new_rect(previous_bounds_);
+ CPoint initial(drag_origin_);
+ GetWindowRect(&rect);
+
+ current.x += rect.left;
+ current.y += rect.top;
+
+ switch (current_resize_mode_) {
+ case RM_NORTH:
+ new_rect.top = std::min(new_rect.bottom - minimum_size_.cy,
+ new_rect.top + (current.y - initial.y));
+ break;
+ case RM_NORTH_EAST:
+ new_rect.top = std::min(new_rect.bottom - minimum_size_.cy,
+ new_rect.top + (current.y - initial.y));
+ new_rect.right = std::max(new_rect.left + minimum_size_.cx,
+ new_rect.right + (current.x - initial.x));
+ break;
+ case RM_EAST:
+ new_rect.right = std::max(new_rect.left + minimum_size_.cx,
+ new_rect.right + (current.x - initial.x));
+ break;
+ case RM_SOUTH_EAST:
+ new_rect.right = std::max(new_rect.left + minimum_size_.cx,
+ new_rect.right + (current.x - initial.x));
+ new_rect.bottom = std::max(new_rect.top + minimum_size_.cy,
+ new_rect.bottom + (current.y - initial.y));
+ break;
+ case RM_SOUTH:
+ new_rect.bottom = std::max(new_rect.top + minimum_size_.cy,
+ new_rect.bottom + (current.y - initial.y));
+ break;
+ case RM_SOUTH_WEST:
+ new_rect.left = std::min(new_rect.right - minimum_size_.cx,
+ new_rect.left + (current.x - initial.x));
+ new_rect.bottom = std::max(new_rect.top + minimum_size_.cy,
+ new_rect.bottom + (current.y - initial.y));
+ break;
+ case RM_WEST:
+ new_rect.left = std::min(new_rect.right - minimum_size_.cx,
+ new_rect.left + (current.x - initial.x));
+ break;
+ case RM_NORTH_WEST:
+ new_rect.left = std::min(new_rect.right - minimum_size_.cx,
+ new_rect.left + (current.x - initial.x));
+ new_rect.top = std::min(new_rect.bottom - minimum_size_.cy,
+ new_rect.top + (current.y - initial.y));
+ break;
+ }
+
+ if (!EqualRect(rect, new_rect)) {
+ // Performing the refresh appears to be faster than simply calling
+ // MoveWindow(... , TRUE)
+ MoveWindow(new_rect.left,
+ new_rect.top,
+ new_rect.Width(),
+ new_rect.Height(),
+ FALSE);
+ HWND h = GetDesktopWindow();
+ HRGN rgn = ::CreateRectRgn(rect.left, rect.top, rect.right, rect.bottom);
+ HRGN rgn2 = ::CreateRectRgn(new_rect.left,
+ new_rect.top,
+ new_rect.right,
+ new_rect.bottom);
+
+ // Erase the corners
+ HRGN rgn3 = ::CreateRectRgn(rect.left,
+ rect.top,
+ rect.left + kCurvedCornerSize,
+ rect.top + kCurvedCornerSize);
+ HRGN rgn4 = ::CreateRectRgn(rect.right - kCurvedCornerSize,
+ rect.top,
+ rect.right,
+ rect.top + kCurvedCornerSize);
+ HRGN rgn5 = ::CreateRectRgn(new_rect.left,
+ new_rect.top,
+ new_rect.left + kCurvedCornerSize,
+ new_rect.top + kCurvedCornerSize);
+ HRGN rgn6 = ::CreateRectRgn(new_rect.right - kCurvedCornerSize,
+ new_rect.top,
+ new_rect.right,
+ new_rect.top + kCurvedCornerSize);
+
+ ::CombineRgn(rgn, rgn, rgn2, RGN_OR);
+ ::CombineRgn(rgn, rgn, rgn3, RGN_OR);
+ ::CombineRgn(rgn, rgn, rgn4, RGN_OR);
+ ::CombineRgn(rgn, rgn, rgn5, RGN_OR);
+ ::CombineRgn(rgn, rgn, rgn6, RGN_OR);
+
+ ::RedrawWindow(h, NULL, rgn, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN);
+ ::DeleteObject(rgn);
+ ::DeleteObject(rgn2);
+ ::DeleteObject(rgn3);
+ ::DeleteObject(rgn4);
+ ::DeleteObject(rgn5);
+ ::DeleteObject(rgn6);
+ }
+}
+
+void XPFrame::StopWindowResize() {
+ current_action_ = FA_NONE;
+ ReleaseCapture();
+}
+
+XPFrame::ResizeMode XPFrame::ComputeResizeMode(int x,
+ int y,
+ int width,
+ int height) {
+ // Make sure we're not over a window control (they overlap our resize area).
+ if (x >= min_button_->GetX() &&
+ x < close_button_->GetX() + close_button_->GetWidth() &&
+ y >= min_button_->GetY() &&
+ y < min_button_->GetY() + min_button_->GetHeight()) {
+ return RM_UNDEFINED;
+ }
+
+ ResizeMode mode = RM_UNDEFINED;
+
+ // WEST / SOUTH_WEST / NORTH_WEST edge
+ if (x < kResizeAreaSize) {
+ if (y < kResizeAreaCornerSize) {
+ mode = RM_NORTH_WEST;
+ } else if (y >= (height - kResizeAreaCornerSize)) {
+ mode = RM_SOUTH_WEST;
+ } else {
+ mode = RM_WEST;
+ }
+ // SOUTH_WEST / NORTH_WEST horizontal extensions
+ } else if (x < kResizeAreaCornerSize) {
+ if (y < kResizeAreaNorthSize) {
+ mode = RM_NORTH_WEST;
+ } else if (y >= (height - kResizeAreaSize)) {
+ mode = RM_SOUTH_WEST;
+ }
+ // EAST / SOUTH_EAST / NORTH_EAST edge
+ } else if (x >= (width - kResizeAreaSize)) {
+ if (y < kResizeAreaCornerSize) {
+ mode = RM_NORTH_EAST;
+ } else if (y >= (height - kResizeAreaCornerSize)) {
+ mode = RM_SOUTH_EAST;
+ } else if (x >= (width - kResizeAreaSize)) {
+ mode = RM_EAST;
+ }
+ // EAST / SOUTH_EAST / NORTH_EAST horizontal extensions
+ } else if (x >= (width - kResizeAreaCornerSize)) {
+ if (y < kResizeAreaNorthSize) {
+ mode = RM_NORTH_EAST;
+ } else if (y >= (height - kResizeAreaSize)) {
+ mode = RM_SOUTH_EAST;
+ }
+ // NORTH edge
+ } else if (y < kResizeAreaNorthSize) {
+ mode = RM_NORTH;
+ // SOUTH edge
+ } else if (y >= (height - kResizeAreaSize)) {
+ mode = RM_SOUTH;
+ }
+
+ return mode;
+}
+
+void XPFrame::SetResizeCursor(ResizeMode r_mode) {
+ static ResizeCursor map[] = { RC_VERTICAL, // unefined
+ RC_VERTICAL, RC_NESW, RC_HORIZONTAL, RC_NWSE,
+ RC_VERTICAL, RC_NESW, RC_HORIZONTAL, RC_NWSE };
+
+ if (r_mode == RM_UNDEFINED) {
+ if (previous_cursor_) {
+ SetCursor(previous_cursor_);
+ previous_cursor_ = NULL;
+ }
+ } else {
+ HCURSOR cursor = g_resize_cursors[map[r_mode]];
+ HCURSOR prev_cursor = SetCursor(cursor);
+ if (prev_cursor != cursor) {
+ previous_cursor_ = cursor;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// ViewContainer
+//
+////////////////////////////////////////////////////////////////////////////////
+
+void XPFrame::GetBounds(CRect *out, bool including_frame) const {
+ // We ignore including_frame because our XP frame doesn't have any NC area
+ GetWindowRect(out);
+}
+
+bool XPFrame::IsMaximized() {
+ return !!IsZoomed();
+}
+
+gfx::Rect XPFrame::GetBoundsForContentBounds(const gfx::Rect content_rect) {
+ if (tab_contents_container_->GetX() == 0 &&
+ tab_contents_container_->GetWidth() == 0) {
+ Layout();
+ }
+
+ CPoint p(0, 0);
+ ChromeViews::View::ConvertPointToViewContainer(tab_contents_container_, &p);
+ CRect bounds;
+ GetBounds(&bounds, true);
+
+ gfx::Rect r;
+ r.set_x(content_rect.x() - p.x);
+ r.set_y(content_rect.y() - p.y);
+ r.set_width(p.x + content_rect.width() +
+ (bounds.Width() - (p.x + tab_contents_container_->GetWidth())));
+ r.set_height(p.y + content_rect.height() +
+ (bounds.Height() - (p.y +
+ tab_contents_container_->GetHeight())));
+ return r;
+}
+
+void XPFrame::InfoBubbleShowing() {
+ ignore_ncactivate_ = true;
+ paint_as_active_ = true;
+}
+
+void XPFrame::InfoBubbleClosing() {
+ paint_as_active_ = false;
+ BrowserWindow::InfoBubbleClosing();
+ // How we render the frame has changed, we need to force a paint otherwise
+ // visually the user won't be able to tell.
+ InvalidateRect(NULL, false);
+}
+
+ToolbarStarToggle* XPFrame::GetStarButton() const {
+ return browser_view_->GetStarButton();
+}
+
+LocationBarView* XPFrame::GetLocationBarView() const {
+ return browser_view_->GetLocationBarView();
+}
+
+GoButton* XPFrame::GetGoButton() const {
+ return browser_view_->GetGoButton();
+}
+
+BookmarkBarView* XPFrame::GetBookmarkBarView() {
+ TabContents* current_tab = browser_->GetSelectedTabContents();
+ if (!current_tab || !current_tab->profile())
+ return NULL;
+
+ if (!bookmark_bar_view_.get()) {
+ bookmark_bar_view_.reset(new BookmarkBarView(current_tab->profile(),
+ browser_));
+ bookmark_bar_view_->SetParentOwned(false);
+ } else {
+ bookmark_bar_view_->SetProfile(current_tab->profile());
+ }
+ bookmark_bar_view_->SetPageNavigator(current_tab);
+ return bookmark_bar_view_.get();
+}
+
+BrowserView* XPFrame::GetBrowserView() const {
+ return browser_view_;
+}
+
+void XPFrame::UpdateToolbar(TabContents* contents, bool should_restore_state) {
+ browser_view_->UpdateToolbar(contents, should_restore_state);
+}
+
+void XPFrame::ProfileChanged(Profile* profile) {
+ browser_view_->ProfileChanged(profile);
+}
+
+void XPFrame::FocusToolbar() {
+ browser_view_->FocusToolbar();
+}
+
+bool XPFrame::IsBookmarkBarVisible() const {
+ if (!bookmark_bar_view_.get())
+ return false;
+
+ if (bookmark_bar_view_->IsNewTabPage() || bookmark_bar_view_->IsAnimating())
+ return true;
+
+ CSize sz;
+ bookmark_bar_view_->GetPreferredSize(&sz);
+ // 1 is the minimum in GetPreferredSize for the bookmark bar.
+ return sz.cy > 1;
+}
+
+void XPFrame::MoveToFront(bool should_activate) {
+ int flags = SWP_NOMOVE | SWP_NOSIZE;
+ if (!should_activate) {
+ flags |= SWP_NOACTIVATE;
+ }
+ SetWindowPos(HWND_TOP, 0, 0, 0, 0, flags);
+ SetForegroundWindow(*this);
+}
+
+HWND XPFrame::GetHWND() const {
+ return m_hWnd;
+}
+
+void XPFrame::PaintNow(const CRect& update_rect) {
+ if (!update_rect.IsRectNull() && IsVisible()) {
+ RedrawWindow(update_rect,
+ NULL,
+ // While we don't seem to need RDW_NOERASE here for correctness
+ // (unlike Vista), I don't know whether it would hurt.
+ RDW_INVALIDATE | RDW_ALLCHILDREN);
+ }
+}
+
+ChromeViews::RootView* XPFrame::GetRootView() {
+ return const_cast<ChromeViews::RootView*>(&root_view_);
+}
+
+bool XPFrame::IsVisible() {
+ return !!::IsWindowVisible(*this);
+}
+
+bool XPFrame::IsActive() {
+ return win_util::IsWindowActive(*this);
+}
+
+bool XPFrame::ProcessMousePressed(const CPoint &pt,
+ UINT flags,
+ bool dbl_click) {
+ using namespace ChromeViews;
+ MouseEvent mouse_pressed(Event::ET_MOUSE_PRESSED,
+ pt.x,
+ pt.y,
+ (dbl_click ? MouseEvent::EF_IS_DOUBLE_CLICK : 0) |
+ Event::ConvertWindowsFlags(flags));
+ if (root_view_.OnMousePressed(mouse_pressed)) {
+ // If an additional button is pressed during a drag session we don't want
+ // to call SetCapture() again as it will result in no more events.
+ if (current_action_ != FA_FORWARDING) {
+ current_action_ = FA_FORWARDING;
+ SetCapture();
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void XPFrame::ProcessMouseDragged(const CPoint &pt, UINT flags) {
+ using namespace ChromeViews;
+ MouseEvent drag_event(Event::ET_MOUSE_DRAGGED,
+ pt.x,
+ pt.y,
+ Event::ConvertWindowsFlags(flags));
+ root_view_.OnMouseDragged(drag_event);
+}
+
+void XPFrame::ProcessMouseReleased(const CPoint &pt, UINT flags) {
+ using namespace ChromeViews;
+
+ current_action_ = FA_NONE;
+ ReleaseCapture();
+
+ MouseEvent mouse_released(Event::ET_MOUSE_RELEASED,
+ pt.x,
+ pt.y,
+ Event::ConvertWindowsFlags(flags));
+ root_view_.OnMouseReleased(mouse_released, false);
+}
+
+void XPFrame::ProcessMouseMoved(const CPoint& pt, UINT flags) {
+ using namespace ChromeViews;
+ MouseEvent mouse_move(Event::ET_MOUSE_MOVED,
+ pt.x,
+ pt.y,
+ Event::ConvertWindowsFlags(flags));
+ root_view_.OnMouseMoved(mouse_move);
+}
+
+void XPFrame::ProcessMouseExited() {
+ root_view_.ProcessOnMouseExited();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// XPFrameView
+//
+////////////////////////////////////////////////////////////////////////////////
+
+void XPFrame::XPFrameView::PaintFrameBorder(ChromeCanvas* canvas) {
+ int width = GetWidth();
+ int height = GetHeight();
+ int x, y;
+ x = 0;
+ y = 0;
+
+ static const SkBitmap * top_left_corner;
+ static const SkBitmap * top_center;
+ static const SkBitmap * top_right_corner;
+ static const SkBitmap * left_side;
+ static const SkBitmap * right_side;
+ static const SkBitmap * bottom_left_corner;
+ static const SkBitmap * bottom_center;
+ static const SkBitmap * bottom_right_corner;
+
+ SkBitmap** bitmaps = parent_->GetFrameBitmaps();
+
+ if (parent_->PaintAsActive()) {
+ top_left_corner = bitmaps[TOP_LEFT_CORNER];
+ top_center = bitmaps[TOP_CENTER];
+ top_right_corner = bitmaps[TOP_RIGHT_CORNER];
+ left_side = bitmaps[LEFT_SIDE];
+ right_side = bitmaps[RIGHT_SIDE];
+ bottom_left_corner = bitmaps[BOTTOM_LEFT_CORNER];
+ bottom_center = bitmaps[BOTTOM_CENTER];
+ bottom_right_corner = bitmaps[BOTTOM_RIGHT_CORNER];
+ } else {
+ top_left_corner = bitmaps[DE_TOP_LEFT_CORNER];
+ top_center = bitmaps[DE_TOP_CENTER];
+ top_right_corner = bitmaps[DE_TOP_RIGHT_CORNER];
+ left_side = bitmaps[DE_LEFT_SIDE];
+ right_side = bitmaps[DE_RIGHT_SIDE];
+ bottom_left_corner = bitmaps[DE_BOTTOM_LEFT_CORNER];
+ bottom_center = bitmaps[DE_BOTTOM_CENTER];
+ bottom_right_corner = bitmaps[DE_BOTTOM_RIGHT_CORNER];
+ }
+
+ int variable_width = width - top_left_corner->width() -
+ top_right_corner->width();
+ int variable_height = height - top_right_corner->height() -
+ bottom_right_corner->height();
+
+ // Top
+ canvas->DrawBitmapInt(*top_left_corner, x, y);
+ canvas->TileImageInt(*top_center,
+ x + top_left_corner->width(),
+ y,
+ variable_width,
+ top_center->height());
+ x = width - top_right_corner->width();
+ canvas->DrawBitmapInt(*top_right_corner, x, y);
+
+ // Right side
+ canvas->TileImageInt(*right_side,
+ x,
+ top_right_corner->height(),
+ right_side->width(),
+ variable_height);
+
+ // Bottom
+ canvas->DrawBitmapInt(*bottom_right_corner,
+ width - bottom_right_corner->width(),
+ height - bottom_right_corner->height());
+ canvas->TileImageInt(*bottom_center,
+ bottom_left_corner->width(),
+ height - bottom_center->height(),
+ variable_width,
+ bottom_center->height());
+ canvas->DrawBitmapInt(*bottom_left_corner,
+ 0,
+ height - bottom_left_corner->height());
+
+ // Left
+ canvas->TileImageInt(*left_side,
+ 0,
+ top_left_corner->height(),
+ left_side->width(),
+ variable_height);
+}
+
+void XPFrame::XPFrameView::PaintFrameBorderZoomed(ChromeCanvas* canvas) {
+ int width = GetWidth();
+ int height = GetHeight();
+
+ static const SkBitmap * maximized_top;
+ static const SkBitmap * maximized_bottom;
+
+ SkBitmap** bitmaps = parent_->GetFrameBitmaps();
+ if (parent_->PaintAsActive()) {
+ maximized_top = bitmaps[TOP_CENTER];
+ maximized_bottom = bitmaps[BOTTOM_CENTER];
+ } else {
+ maximized_top = bitmaps[DE_TOP_CENTER];
+ maximized_bottom = bitmaps[DE_BOTTOM_CENTER];
+ }
+
+ canvas->TileImageInt(*maximized_top,
+ 0,
+ 0,
+ width,
+ maximized_top->height());
+ canvas->TileImageInt(*maximized_bottom,
+ 0,
+ height - maximized_bottom->height(),
+ width,
+ maximized_bottom->height());
+}
+
+void XPFrame::XPFrameView::PaintContentsBorder(ChromeCanvas* canvas,
+ int x,
+ int y,
+ int w,
+ int h) {
+ SkBitmap** bitmaps = parent_->GetFrameBitmaps();
+
+ int ro, bo;
+ ro = x + w - bitmaps[CT_TOP_RIGHT_CORNER]->width();
+ bo = y + h - bitmaps[CT_BOTTOM_RIGHT_CORNER]->height();
+ int start_y;
+
+ if (parent_->IsTabStripVisible() || parent_->IsToolBarVisible()) {
+ int top_height = bitmaps[CT_TOP_RIGHT_CORNER]->height();
+ canvas->DrawBitmapInt(*bitmaps[CT_TOP_LEFT_CORNER], x, y);
+
+ canvas->TileImageInt(*bitmaps[CT_TOP_CENTER],
+ x + bitmaps[CT_TOP_LEFT_CORNER]->width(),
+ y,
+ w - bitmaps[CT_TOP_LEFT_CORNER]->width() -
+ bitmaps[CT_TOP_RIGHT_CORNER]->width(),
+ bitmaps[CT_TOP_CENTER]->height());
+
+ canvas->DrawBitmapInt(*bitmaps[CT_TOP_RIGHT_CORNER], ro, y);
+ start_y = y + bitmaps[CT_TOP_RIGHT_CORNER]->height();
+
+ // If the toolbar is not visible, we need to draw a line at the top of the
+ // actual contents.
+ if (!parent_->IsToolBarVisible()) {
+ canvas->FillRectInt(kSeparationLineColor,
+ x + bitmaps[CT_TOP_LEFT_CORNER]->width(),
+ y + kCollapsedToolbarHeight +
+ kToolbarOverlapVertOffset - kSeparationLineHeight,
+ w - bitmaps[CT_TOP_LEFT_CORNER]->width() -
+ bitmaps[CT_TOP_RIGHT_CORNER]->width(),
+ kSeparationLineHeight);
+ }
+ } else {
+ int by = y - bitmaps[APP_TOP_LEFT]->height() + 1;
+ canvas->DrawBitmapInt(*bitmaps[APP_TOP_LEFT], x, by);
+ canvas->TileImageInt(*bitmaps[APP_TOP_CENTER],
+ x + bitmaps[APP_TOP_LEFT]->width(),
+ by,
+ w - bitmaps[APP_TOP_LEFT]->width() -
+ bitmaps[APP_TOP_RIGHT]->width(),
+ bitmaps[APP_TOP_CENTER]->height());
+ canvas->DrawBitmapInt(*bitmaps[APP_TOP_RIGHT],
+ x + w - bitmaps[APP_TOP_RIGHT]->width(),
+ by);
+ start_y = y + 1;
+ }
+
+ canvas->TileImageInt(*bitmaps[CT_RIGHT_SIDE],
+ ro,
+ start_y,
+ bitmaps[CT_RIGHT_SIDE]->width(),
+ bo - start_y);
+
+ canvas->DrawBitmapInt(*bitmaps[CT_BOTTOM_RIGHT_CORNER],
+ x + w - bitmaps[CT_BOTTOM_RIGHT_CORNER]->width(),
+ bo);
+
+ canvas->TileImageInt(*bitmaps[CT_BOTTOM_CENTER],
+ x + bitmaps[CT_BOTTOM_LEFT_CORNER]->width(),
+ bo,
+ w - (bitmaps[CT_BOTTOM_LEFT_CORNER]->width() +
+ bitmaps[CT_BOTTOM_RIGHT_CORNER]->width()),
+ bitmaps[CT_BOTTOM_CENTER]->height());
+
+ canvas->DrawBitmapInt(*bitmaps[CT_BOTTOM_LEFT_CORNER], x, bo);
+
+ canvas->TileImageInt(*bitmaps[CT_LEFT_SIDE],
+ x,
+ start_y,
+ bitmaps[CT_LEFT_SIDE]->width(),
+ bo - start_y);
+}
+
+void XPFrame::XPFrameView::PaintContentsBorderZoomed(ChromeCanvas* canvas,
+ int x,
+ int y,
+ int w) {
+ SkBitmap** bitmaps = parent_->GetFrameBitmaps();
+ canvas->TileImageInt(*bitmaps[CT_TOP_CENTER],
+ x,
+ y,
+ w,
+ bitmaps[CT_TOP_CENTER]->height());
+
+ // If the toolbar is not visible, we need to draw a line at the top of the
+ // actual contents.
+ if (!parent_->IsToolBarVisible()) {
+ canvas->FillRectInt(kSeparationLineColor, x, y + kCollapsedToolbarHeight +
+ kToolbarOverlapVertOffset - 1, w, 1);
+ }
+}
+
+void XPFrame::XPFrameView::Paint(ChromeCanvas* canvas) {
+ canvas->save();
+
+ // When painting the border, exclude the contents area. This will prevent the
+ // border bitmaps (which might be larger than the visible area) from coming
+ // into the content area when there is no tab painted yet.
+ int x = parent_->tab_contents_container_->GetX();
+ int y = parent_->tab_contents_container_->GetY();
+ SkRect clip;
+ clip.set(SkIntToScalar(x), SkIntToScalar(y),
+ SkIntToScalar(x + parent_->tab_contents_container_->GetWidth()),
+ SkIntToScalar(y + parent_->tab_contents_container_->GetHeight()));
+ canvas->clipRect(clip, SkRegion::kDifference_Op);
+
+ if (parent_->IsZoomed()) {
+ PaintFrameBorderZoomed(canvas);
+ int y;
+ bool should_draw_separator = false;
+ if (parent_->IsToolBarVisible()) {
+ y = parent_->browser_view_->GetY();
+ } else if (parent_->IsTabStripVisible()) {
+ y = parent_->GetContentsYOrigin() - kCollapsedToolbarHeight -
+ kToolbarOverlapVertOffset;
+ } else {
+ y = parent_->GetContentsYOrigin();
+ }
+
+ PaintContentsBorderZoomed(canvas, 0, y, GetWidth());
+ } else {
+ PaintFrameBorder(canvas);
+ int y, height;
+ if (parent_->IsToolBarVisible()) {
+ y = parent_->browser_view_->GetY();
+ height = GetHeight() - (parent_->browser_view_->GetY() +
+ kContentBorderVertBottomOffset);
+ } else {
+ if (parent_->IsTabStripVisible()) {
+ y = parent_->GetContentsYOrigin() - kCollapsedToolbarHeight -
+ kToolbarOverlapVertOffset;
+ } else {
+ y = parent_->GetContentsYOrigin();
+ }
+ height = GetHeight() - y - kContentBorderVertBottomOffset;
+ }
+
+ PaintContentsBorder(canvas, kContentBorderHorizOffset, y,
+ GetWidth() - (2 * kContentBorderHorizOffset),
+ height);
+ }
+
+ canvas->restore();
+}
+
+bool XPFrame::XPFrameView::GetAccessibleRole(VARIANT* role) {
+ DCHECK(role);
+
+ role->vt = VT_I4;
+ role->lVal = ROLE_SYSTEM_CLIENT;
+ return true;
+}
+
+bool XPFrame::XPFrameView::GetAccessibleName(std::wstring* name) {
+ if (!accessible_name_.empty()) {
+ name->assign(accessible_name_);
+ return true;
+ }
+ return false;
+}
+
+void XPFrame::XPFrameView::SetAccessibleName(const std::wstring& name) {
+ accessible_name_.assign(name);
+}
+
+bool XPFrame::XPFrameView::ShouldForwardToTabStrip(
+ const ChromeViews::DropTargetEvent& event) {
+ if (!FrameView::ShouldForwardToTabStrip(event))
+ return false;
+ if (parent_->IsZoomed() && event.GetX() >= parent_->min_button_->GetX() &&
+ event.GetY() < (parent_->min_button_->GetY() +
+ parent_->min_button_->GetHeight())) {
+ return false;
+ }
+ return true;
+}
+
+void XPFrame::ShelfVisibilityChanged() {
+ ShelfVisibilityChangedImpl(browser_->GetSelectedTabContents());
+}
+
+void XPFrame::SelectedTabToolbarSizeChanged(bool is_animating) {
+ if (is_animating) {
+ tab_contents_container_->set_fast_resize(true);
+ ShelfVisibilityChanged();
+ tab_contents_container_->set_fast_resize(false);
+ } else {
+ ShelfVisibilityChanged();
+ tab_contents_container_->UpdateHWNDBounds();
+ }
+}
+
+bool XPFrame::UpdateChildViewAndLayout(ChromeViews::View* new_view,
+ ChromeViews::View** view) {
+ DCHECK(view);
+ if (*view == new_view) {
+ // The views haven't changed, if the views pref changed schedule a layout.
+ if (new_view) {
+ CSize pref_size;
+ new_view->GetPreferredSize(&pref_size);
+ if (pref_size.cy != new_view->GetHeight())
+ return true;
+ }
+ return false;
+ }
+
+ // The views differ, and one may be null (but not both). Remove the old
+ // view (if it non-null), and add the new one (if it is non-null). If the
+ // height has changed, schedule a layout, otherwise reuse the existing
+ // bounds to avoid scheduling a layout.
+
+ int current_height = 0;
+ if (*view) {
+ current_height = (*view)->GetHeight();
+ root_view_.RemoveChildView(*view);
+ }
+
+ int new_height = 0;
+ if (new_view) {
+ CSize preferred_size;
+ new_view->GetPreferredSize(&preferred_size);
+ new_height = preferred_size.cy;
+ root_view_.AddChildView(new_view);
+ }
+ bool changed = false;
+ if (new_height != current_height) {
+ changed = true;
+ } else if (new_view && *view) {
+ // The view changed, but the new view wants the same size, give it the
+ // bounds of the last view and have it repaint.
+ CRect last_bounds;
+ (*view)->GetBounds(&last_bounds);
+ new_view->SetBounds(last_bounds.left, last_bounds.top,
+ last_bounds.Width(), last_bounds.Height());
+ new_view->SchedulePaint();
+ } else if (new_view) {
+ DCHECK(new_height == 0);
+ // The heights are the same, but the old view is null. This only happens
+ // when the height is zero. Zero out the bounds.
+ new_view->SetBounds(0, 0, 0, 0);
+ }
+ *view = new_view;
+ return changed;
+}
+
+void XPFrame::SetWindowTitle(const std::wstring& title) {
+ SetWindowText(title.c_str());
+}
+
+void XPFrame::Activate() {
+ if (IsIconic())
+ ShowWindow(SW_RESTORE);
+ MoveToFront(true);
+}
+
+void XPFrame::FlashFrame() {
+ FLASHWINFO flash_window_info;
+ flash_window_info.cbSize = sizeof(FLASHWINFO);
+ flash_window_info.hwnd = GetHWND();
+ flash_window_info.dwFlags = FLASHW_ALL;
+ flash_window_info.uCount = 4;
+ flash_window_info.dwTimeout = 0;
+ ::FlashWindowEx(&flash_window_info);
+}
+
+void XPFrame::ShowTabContents(TabContents* selected_contents) {
+ tab_contents_container_->SetTabContents(selected_contents);
+
+ // Force a LoadingStateChanged notification because the TabContents
+ // could be loading (such as when the user unconstrains a tab.
+ if (selected_contents && selected_contents->delegate())
+ selected_contents->delegate()->LoadingStateChanged(selected_contents);
+
+ ShelfVisibilityChangedImpl(selected_contents);
+}
+
+TabStrip* XPFrame::GetTabStrip() const {
+ return tabstrip_;
+}
+
+gfx::Rect XPFrame::GetNormalBounds() {
+ WINDOWPLACEMENT wp;
+ wp.length = sizeof(wp);
+ const bool ret = !!GetWindowPlacement(&wp);
+ DCHECK(ret);
+ 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(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
+ // ChromeViews::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
+ // figure out how big all the UI bits are.
+ Layout();
+
+ // Then we calculate the size of the window chrome, this is the stuff that
+ // needs to be positioned around the edges of contents_bounds.
+ CRect bounds;
+ tab_contents_container_->GetBounds(&bounds);
+ CRect cr;
+ GetClientRect(&cr);
+ int toolbar_height = bounds.top;
+ int left_edge_width = bounds.left;
+ int right_edge_width = cr.Width() - bounds.right;
+ int bottom_edge_height = cr.Height() - bounds.bottom;
+
+ // Now resize the window. This will result in Layout() getting called again
+ // and the contents getting sized to the value specified in |contents_bounds|
+ SetWindowPos(NULL, contents_bounds.x() - left_edge_width,
+ contents_bounds.y() - toolbar_height,
+ contents_bounds.width() + left_edge_width + right_edge_width,
+ contents_bounds.height() + toolbar_height + bottom_edge_height,
+ SWP_NOZORDER | SWP_NOACTIVATE);
+}
+
+bool XPFrame::ShouldWorkAroundAutoHideTaskbar() {
+ // Check the command line flag to see if we want to prevent
+ // the work around for maximize and auto-hide task bar.
+ // See bug#861590
+ static bool should_work_around_auto_hide_taskbar = true;
+ return should_work_around_auto_hide_taskbar;
+}
+
+void XPFrame::SetIsOffTheRecord(bool value) {
+ is_off_the_record_ = value;
+}
+
+void XPFrame::DestroyBrowser() {
+ // TODO(beng): (Cleanup) tidy this up, just fixing the build red for now.
+ // Need to do this first, before the browser_ is deleted and we can't remove
+ // the tabstrip from the model's observer list because the model was
+ // destroyed with browser_.
+ if (browser_) {
+ if (bookmark_bar_view_.get() && bookmark_bar_view_->GetParent()) {
+ // The bookmark bar should not be parented by the time we get here.
+ // If you hit this NOTREACHED file a bug with the trace.
+ NOTREACHED();
+ bookmark_bar_view_->GetParent()->RemoveChildView(bookmark_bar_view_.get());
+ }
+
+ // Explicitly delete the BookmarkBarView now. That way we don't have to
+ // worry about the BookmarkBarView potentially outliving the Browser &
+ // Profile.
+ bookmark_bar_view_.reset(NULL);
+
+ browser_->tabstrip_model()->RemoveObserver(tabstrip_);
+ delete browser_;
+ browser_ = NULL;
+ }
+}
+
+void XPFrame::ShelfVisibilityChangedImpl(TabContents* current_tab) {
+ // Coalesce layouts.
+ bool changed = false;
+
+ ChromeViews::View* new_shelf = NULL;
+ if (current_tab && current_tab->IsDownloadShelfVisible())
+ new_shelf = current_tab->GetDownloadShelfView();
+ changed |= UpdateChildViewAndLayout(new_shelf, &shelf_view_);
+
+ ChromeViews::View* new_info_bar = NULL;
+ if (current_tab && current_tab->IsInfoBarVisible())
+ new_info_bar = current_tab->GetInfoBarView();
+ changed |= UpdateChildViewAndLayout(new_info_bar, &info_bar_view_);
+
+ ChromeViews::View* new_bookmark_bar_view = NULL;
+ if (SupportsBookmarkBar())
+ new_bookmark_bar_view = GetBookmarkBarView();
+ changed |= UpdateChildViewAndLayout(new_bookmark_bar_view,
+ &active_bookmark_bar_);
+
+ // Only do a layout if the current contents is non-null. We assume that if the
+ // contents is NULL, we're either being destroyed, or ShowTabContents is going
+ // to be invoked with a non-null TabContents again so that there is no need
+ // in doing a layout now (and would result in extra work/invalidation on
+ // tab switches).
+ if (changed && current_tab)
+ Layout();
+}
+
diff --git a/chrome/browser/views/old_frames/xp_frame.h b/chrome/browser/views/old_frames/xp_frame.h
new file mode 100644
index 0000000..e91ffff
--- /dev/null
+++ b/chrome/browser/views/old_frames/xp_frame.h
@@ -0,0 +1,528 @@
+// 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_OLD_FRAMES_XP_FRAME_H__
+#define CHROME_BROWSER_VIEWS_OLD_FRAMES_XP_FRAME_H__
+
+#include <windows.h>
+#include <atlbase.h>
+#include <atlcrack.h>
+#include <atlapp.h>
+#include <atlframe.h>
+
+#include "base/message_loop.h"
+#include "chrome/app/chrome_dll_resource.h"
+#include "chrome/browser/browser_window.h"
+#include "chrome/browser/views/old_frames/frame_view.h"
+#include "chrome/browser/views/status_bubble.h"
+#include "chrome/views/view_container.h"
+#include "chrome/views/button.h"
+#include "chrome/views/hwnd_view.h"
+#include "chrome/views/root_view.h"
+#include "chrome/views/image_view.h"
+#ifdef CHROME_PERSONALIZATION
+#include "chrome/personalization/personalization.h"
+#endif
+
+#define XP_FRAME_CLASSNAME L"Chrome_XPFrame"
+
+class BrowserView;
+class BookmarkBarView;
+class Browser;
+class TabContentsContainerView;
+class TabStrip;
+class TemporaryPlaceholder;
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// XPFrame class
+//
+// A CWindowImpl subclass that implements our main frame on Windows XP
+//
+// The window paints and handles its title bar and controls. It also supports
+// a ChromeView hierarchy for the tabs and toolbar
+//
+////////////////////////////////////////////////////////////////////////////////
+class XPFrame : public BrowserWindow,
+ public CWindowImpl<XPFrame,
+ CWindow,
+ CWinTraits<WS_SYSMENU |
+ WS_MINIMIZEBOX |
+ WS_MAXIMIZEBOX |
+ WS_CLIPCHILDREN>>,
+ public ChromeViews::BaseButton::ButtonListener,
+ public ChromeViews::ViewContainer,
+ public ChromeViews::AcceleratorTarget {
+ public:
+
+ // Create a new XPFrame given the bounds and provided browser.
+ // |bounds| may be empty to let Windows decide where to place the window.
+ // The browser_window object acts both as a container for the actual
+ // browser contents as well as a source for the tab strip and the toolbar.
+ // |is_off_the_record| defines whether this window should represent an off the
+ // record session.
+ //
+ // Note: this method creates an HWND for the frame but doesn't initialize
+ // the view hierarchy. The browser creates its HWND from the frame HWND
+ // and then calls Init() on the frame to finalize the initialization
+ static XPFrame* CreateFrame(const gfx::Rect& bounds, Browser* browser,
+ bool is_off_the_record);
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // BrowserWindow implementation
+ ////////////////////////////////////////////////////////////////////////////////
+ virtual ~XPFrame();
+ virtual void Init();
+ virtual void Show(int command, bool adjust_to_fit);
+ virtual void Close();
+ virtual void* GetPlatformID();
+ virtual void SetAcceleratorTable(
+ std::map<ChromeViews::Accelerator, int>* accelerator_table);
+ virtual bool AcceleratorPressed(const ChromeViews::Accelerator& accelerator);
+ virtual gfx::Rect GetNormalBounds();
+ virtual bool IsMaximized();
+ virtual gfx::Rect GetBoundsForContentBounds(const gfx::Rect content_rect);
+ virtual void InfoBubbleShowing();
+ virtual void InfoBubbleClosing();
+ virtual ToolbarStarToggle* GetStarButton() const;
+ virtual LocationBarView* GetLocationBarView() const;
+ virtual GoButton* GetGoButton() const;
+ virtual BookmarkBarView* GetBookmarkBarView();
+ virtual BrowserView* GetBrowserView() const;
+ virtual void UpdateToolbar(TabContents* contents, bool should_restore_state);
+ virtual void ProfileChanged(Profile* profile);
+ virtual void FocusToolbar();
+ virtual bool IsBookmarkBarVisible() const;
+
+ //
+ // CWindowImpl event management magic. See atlcrack.h
+ //
+ DECLARE_FRAME_WND_CLASS_EX(XP_FRAME_CLASSNAME,
+ IDR_MAINFRAME,
+ CS_DBLCLKS,
+ WHITE_BRUSH)
+
+ BEGIN_MSG_MAP(HaloFrame)
+ MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseRange)
+ MESSAGE_RANGE_HANDLER(WM_NCMOUSEMOVE, WM_NCMOUSEMOVE, OnMouseRange)
+ MESSAGE_RANGE_HANDLER(WM_SETTINGCHANGE, WM_SETTINGCHANGE, OnSettingChange)
+ MSG_WM_NCCALCSIZE(OnNCCalcSize);
+ MSG_WM_NCPAINT(OnNCPaint);
+
+ MSG_WM_NCACTIVATE(OnNCActivate)
+ MSG_WM_LBUTTONDOWN(OnMouseButtonDown)
+ MSG_WM_LBUTTONUP(OnLButtonUp);
+ MSG_WM_LBUTTONDBLCLK(OnMouseButtonDblClk)
+ MSG_WM_MBUTTONDOWN(OnMouseButtonDown)
+ MSG_WM_MBUTTONUP(OnMButtonUp);
+ MSG_WM_MBUTTONDBLCLK(OnMouseButtonDblClk);
+ MSG_WM_RBUTTONDOWN(OnMouseButtonDown)
+ MSG_WM_NCLBUTTONDOWN(OnNCLButtonDown)
+ MSG_WM_NCMBUTTONDOWN(OnNCMButtonDown)
+ MSG_WM_NCRBUTTONDOWN(OnNCRButtonDown)
+ MSG_WM_RBUTTONUP(OnRButtonUp);
+ MSG_WM_RBUTTONDBLCLK(OnMouseButtonDblClk);
+ MESSAGE_HANDLER_EX(WM_GETOBJECT, OnGetObject); // To avoid edit atlcrack.h.
+ MSG_WM_KEYDOWN(OnKeyDown);
+ MSG_WM_KEYUP(OnKeyUp);
+ MSG_WM_MOUSEMOVE(OnMouseMove)
+ MSG_WM_MOUSELEAVE(OnMouseLeave)
+ MSG_WM_CLOSE(Close) // Note: Calls Close() directly, there is no OnClose()
+ MSG_WM_ENDSESSION(OnEndSession)
+ MSG_WM_APPCOMMAND(OnAppCommand)
+ MSG_WM_COMMAND(OnCommand)
+ MSG_WM_SYSCOMMAND(OnSysCommand)
+ MSG_WM_ACTIVATE(OnActivate)
+ MSG_WM_PAINT(OnPaint)
+ MSG_WM_ERASEBKGND(OnEraseBkgnd)
+ MSG_WM_GETMINMAXINFO(OnMinMaxInfo)
+ MSG_WM_CAPTURECHANGED(OnCaptureChanged)
+ MSG_WM_SIZE(OnSize)
+ MSG_WM_MOVE(OnMove)
+ MSG_WM_MOVING(OnMoving)
+ MSG_WM_NCHITTEST(OnNCHitTest)
+ MSG_WM_INITMENU(OnInitMenu)
+ MSG_WM_NOTIFY(OnNotify)
+ MSG_WM_MOUSEACTIVATE(OnMouseActivate)
+ MSG_WM_POWERBROADCAST(OnPowerBroadcast)
+ MSG_WM_THEMECHANGED(OnThemeChanged)
+ REFLECT_NOTIFICATIONS()
+ END_MSG_MAP()
+
+ void OnFinalMessage(HWND hwnd);
+
+ // ChromeViews::BaseButton::ButtonListener
+ void ButtonPressed(ChromeViews::BaseButton *sender);
+
+ //
+ // ViewContainer
+ virtual void GetBounds(CRect *out, bool including_frame) const;
+ virtual void MoveToFront(bool should_activate);
+ virtual HWND GetHWND() const;
+ virtual void PaintNow(const CRect& update_rect);
+ virtual ChromeViews::RootView* GetRootView();
+ virtual bool IsVisible();
+ virtual bool IsActive();
+ virtual ChromeViews::TooltipManager* GetTooltipManager();
+ virtual StatusBubble* GetStatusBubble();
+ virtual bool GetAccelerator(int cmd_id,
+ ChromeViews::Accelerator* accelerator);
+
+ virtual void ShelfVisibilityChanged();
+ virtual void SelectedTabToolbarSizeChanged(bool is_animating);
+ virtual void SetWindowTitle(const std::wstring& title);
+ virtual void Activate();
+ virtual void FlashFrame();
+
+ 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.
+ bool PaintAsActive() const { return is_active_ || paint_as_active_; }
+
+ protected:
+ // Invoked after the HWND has been created but before the window is showing.
+ // This registers tooltips. If you override, be sure and invoke this
+ // implementation.
+ virtual void InitAfterHWNDCreated();
+
+ XPFrame(Browser* browser);
+
+ // Offer subclasses an opportunity to change how the tabstrip is created.
+ // The default implementation allocates a normal tab strip.
+ virtual TabStrip* CreateTabStrip(Browser* browser);
+
+ // Override and return false if no tab strip or toolbar should be visible.
+ // Default method returns true.
+ virtual bool IsTabStripVisible() const { return true; }
+
+ // Override and return false if no toolbar should be visible. Default method
+ // returns true.
+ virtual bool IsToolBarVisible() const { return true; }
+
+#ifdef CHROME_PERSONALIZATION
+ virtual bool PersonalizationEnabled() const {
+ return personalization_enabled_;
+ }
+
+ void EnablePersonalization(bool enable_personalization) {
+ personalization_enabled_ = enable_personalization;
+ }
+#endif
+
+ // Return the frame view.
+ ChromeViews::View* GetFrameView() { return frame_view_; }
+
+ // Return the tab contents container.
+ TabContentsContainerView* GetTabContentsContainer() {
+ return tab_contents_container_;
+ }
+
+ // Return the X origin of the the first frame control button.
+ int GetButtonXOrigin() {
+ return min_button_->GetX();
+ }
+
+ // Return the Y location of the contents or infobar.
+ int GetContentsYOrigin();
+
+ // Give subclasses an opportunity to never show the bookmark bar. We use this
+ // for the application window. Default method returns true.
+ virtual bool SupportsBookmarkBar() const { return true; }
+
+ virtual LRESULT OnNCHitTest(const CPoint& pt);
+
+ // Layout all views given the available size
+ virtual void Layout();
+
+ // Set whether this frame represents an off the record session. This is
+ // currently only called during initialization.
+ void SetIsOffTheRecord(bool value);
+
+ virtual void DestroyBrowser();
+
+ // The Browser instance that created this instance
+ Browser* browser_;
+ private:
+ enum FrameAction {FA_NONE = 0, FA_RESIZING, FA_FORWARDING};
+
+ enum ResizeMode {RM_UNDEFINED = 0, RM_NORTH, RM_NORTH_EAST, RM_EAST,
+ RM_SOUTH_EAST, RM_SOUTH, RM_SOUTH_WEST, RM_WEST,
+ RM_NORTH_WEST};
+
+ enum ResizeCursor {RC_VERTICAL = 0, RC_HORIZONTAL, RC_NESW, RC_NWSE};
+
+ LRESULT OnMouseRange(UINT u_msg, WPARAM w_param, LPARAM l_param,
+ BOOL& handled);
+ LRESULT OnNotify(int w_param, NMHDR* hdr);
+ LRESULT OnSettingChange(UINT u_msg, WPARAM w_param, LPARAM l_param,
+ BOOL& handled);
+
+ // The view we use for our background
+ class XPFrameView : public FrameView {
+ public:
+ XPFrameView(XPFrame* parent) : FrameView(parent), parent_(parent) {
+ }
+ virtual void Paint(ChromeCanvas* canvas);
+ virtual std::string GetClassName() const {
+ return "chrome/browser/views/XPFrameView";
+ }
+ // Accessibility information
+ bool GetAccessibleRole(VARIANT* role);
+
+ // Returns a brief, identifying string, containing a unique, readable name.
+ bool GetAccessibleName(std::wstring* name);
+
+ // Assigns an accessible string name.
+ void SetAccessibleName(const std::wstring& name);
+
+ protected:
+ // Overriden to return false if maximized and over the min/max/close
+ // button.
+ virtual bool ShouldForwardToTabStrip(
+ const ChromeViews::DropTargetEvent& event);
+
+ private:
+ void PaintFrameBorder(ChromeCanvas* canvas);
+ void PaintFrameBorderZoomed(ChromeCanvas* canvas);
+ void PaintContentsBorder(ChromeCanvas* canvas,
+ int x,
+ int y,
+ int w,
+ int h);
+ void PaintContentsBorderZoomed(ChromeCanvas* canvas,
+ int x,
+ int y,
+ int w);
+ XPFrame* parent_;
+
+ // Storage of strings needed for accessibility.
+ std::wstring accessible_name_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(XPFrameView);
+ };
+
+ friend class XPFrameView;
+
+ //
+ // Windows event handlers
+ //
+
+ void OnEndSession(BOOL ending, UINT logoff);
+
+ LRESULT OnNCCalcSize(BOOL w_param, LPARAM l_param);
+ LRESULT OnNCPaint(HRGN param);
+
+ void OnMove(const CSize& size);
+ void OnMoving(UINT param, const LPRECT new_bounds);
+ void OnSize(UINT param, const CSize& size);
+ void OnMouseButtonDown(UINT flags, const CPoint& pt);
+ void OnNCLButtonDown(UINT flags, const CPoint& pt);
+ void OnNCMButtonDown(UINT flags, const CPoint& pt);
+ void OnNCRButtonDown(UINT flags, const CPoint& pt);
+ void OnMouseButtonUp(UINT flags, const CPoint& pt);
+ void OnMouseButtonDblClk(UINT flags, const CPoint& pt);
+ void OnLButtonUp(UINT flags, const CPoint& pt);
+ void OnMButtonUp(UINT flags, const CPoint& pt);
+ void OnRButtonUp(UINT flags, const CPoint& pt);
+ void OnMouseMove(UINT flags, const CPoint& pt);
+ void OnMouseLeave();
+ void OnKeyDown(TCHAR c, UINT rep_cnt, UINT flags);
+ void OnKeyUp(TCHAR c, UINT rep_cnt, UINT flags);
+ LRESULT OnGetObject(UINT uMsg, WPARAM w_param, LPARAM l_param);
+
+ LRESULT OnAppCommand(
+ HWND w_param, short app_command, WORD device, int keystate);
+ void OnCommand(UINT notification_code, int command_id, HWND window);
+ void OnSysCommand(UINT notification_code, CPoint click);
+ void OnActivate(UINT n_state, BOOL is_minimized, HWND other);
+ int OnMouseActivate(CWindow wndTopLevel, UINT nHitTest, UINT message);
+ void OnPaint(HDC dc);
+ LRESULT OnEraseBkgnd(HDC dc);
+ void OnMinMaxInfo(LPMINMAXINFO mm_info);
+ void OnCaptureChanged(HWND hwnd);
+ void OnInitMenu(HMENU menu);
+ void ArmOnMouseLeave();
+ void ShowSystemMenu(int x, int y);
+
+ LRESULT OnNCActivate(BOOL param);
+ BOOL OnPowerBroadcast(DWORD power_event, DWORD data);
+ void OnThemeChanged();
+
+ // Window resize
+ // Note: we cannot use the standard window resize because we don't have
+ // a frame. Returning HTSIZE from WM_NCHITTEST doesn't work
+ void StartWindowResize(ResizeMode mode, const CPoint &pt);
+ void ProcessWindowResize(const CPoint &pt);
+ void StopWindowResize();
+
+ // Compute a ResizeMode given a point (x,y) and the current size
+ // of the window (width,height). This method returns UNDEFINED
+ // if no resizing should occur.
+ ResizeMode ComputeResizeMode(int x, int y, int width, int height);
+
+ //
+ // Change the cursor as needed given the desired ResizeMode
+ void SetResizeCursor(ResizeMode r_mode);
+
+ // Check whether the selected tab needs some extra painting during
+ // move or resize because it obstructs its contents (WebContents)
+ bool ShouldRefreshCurrentTabContents();
+
+ //
+ // View events propagation
+ //
+ bool ProcessMousePressed(const CPoint& pt, UINT flags, bool dbl_click);
+ void ProcessMouseDragged(const CPoint& pt, UINT flags);
+ void ProcessMouseReleased(const CPoint& pt, UINT flags);
+ void ProcessMouseMoved(const CPoint &pt, UINT flags);
+ void ProcessMouseExited();
+
+ // Updates either the infobar or the bottom shelf depending on the views
+ // passed in.
+ void UpdateShelfViews(int view_top, int preferred_height,
+ ChromeViews::View* new_view,
+ ChromeViews::View** current_view,
+ int* last_height);
+
+ // If the workaround to prevent taskbar from hiding behind maximizing
+ // xp_frame is enabled.
+ bool ShouldWorkAroundAutoHideTaskbar();
+
+ // Updates a single view. If *view differs from new_view the old view is
+ // removed and the new view is added.
+ //
+ // This is intended to be used when swapping in/out child views that are
+ // referenced via a field.
+ //
+ // This function returns true if anything was changed. The caller should
+ // ensure that Layout() is eventually called in this case.
+ bool UpdateChildViewAndLayout(ChromeViews::View* new_view,
+ ChromeViews::View** view);
+
+ // Return the set of bitmaps that should be used to draw this frame.
+ SkBitmap** GetFrameBitmaps();
+
+ // Implementation for ShelfVisibilityChanged(). Updates the various shelf
+ // fields. If one of the shelves has changed (or it's size has changed) and
+ // current_tab is non-NULL layout occurs.
+ void ShelfVisibilityChangedImpl(TabContents* current_tab);
+
+ // Root view
+ ChromeViews::RootView root_view_;
+
+ // Top level view used to render the frame itself including the title bar
+ XPFrameView* frame_view_;
+
+ // Browser contents
+ TabContentsContainerView* tab_contents_container_;
+
+ // Frame buttons
+ ChromeViews::Button* min_button_;
+ ChromeViews::Button* max_button_;
+ ChromeViews::Button* restore_button_;
+ ChromeViews::Button* close_button_;
+
+ // Whether we should save the bounds of the window. We don't want to
+ // save the default size of windows for certain classes of windows
+ // like unconstrained popups. Defaults to true.
+ bool should_save_window_placement_;
+
+ // Whether we saved the window placement yet.
+ bool saved_window_placement_;
+
+ // Current frame ui action
+ FrameAction current_action_;
+
+ // Whether the frame is currently active
+ bool is_active_;
+
+ // whether we are expecting a mouse leave event
+ bool on_mouse_leave_armed_;
+
+ // Point containing the coordinate of the first event during
+ // a window dragging or resizing session
+ CPoint drag_origin_;
+
+ // Rectangle containing the original window bounds during
+ // a window dragging or resizing session. It is in screen
+ // coordinate system
+ CRect previous_bounds_;
+
+ // Initialize static members the first time this is invoked
+ static void InitializeIfNeeded();
+
+ // cursor storage
+ HCURSOR previous_cursor_;
+
+ // Current resize mode
+ ResizeMode current_resize_mode_;
+
+ // Frame min size
+ CSize minimum_size_;
+
+ scoped_ptr<ChromeViews::TooltipManager> tooltip_manager_;
+
+ // A view positioned at the bottom of the frame.
+ ChromeViews::View* shelf_view_;
+
+ // A view positioned beneath the bookmark bar.
+ // Implementation mirrors shelf_view_
+ ChromeViews::View* info_bar_view_;
+
+ // The view that contains the tabs and any associated controls.
+ TabStrip* tabstrip_;
+
+ // The bookmark bar. This is lazily created.
+ scoped_ptr<BookmarkBarView> bookmark_bar_view_;
+
+ // The visible bookmark bar. NULL if none is visible.
+ ChromeViews::View* active_bookmark_bar_;
+
+ // The optional container for the off the record icon.
+ ChromeViews::ImageView* off_the_record_image_;
+
+ // The container for the distributor logo.
+ ChromeViews::ImageView* distributor_logo_;
+
+ // We need to own the text of the menu, the Windows API does not copy it.
+ std::wstring task_manager_label_text_;
+
+ // A mapping between accelerators and commands.
+ scoped_ptr<std::map<ChromeViews::Accelerator, int>> accelerator_table_;
+
+ // Whether this frame represents an off the record session.
+ bool is_off_the_record_;
+
+#ifdef CHROME_PERSONALIZATION
+ FramePersonalization personalization_;
+ bool personalization_enabled_;
+#endif
+
+ // Set during layout. Total height of the title bar.
+ int title_bar_height_;
+
+ static bool g_initialized;
+ static HCURSOR g_resize_cursors[4];
+ static SkBitmap** g_bitmaps;
+ static SkBitmap** g_otr_bitmaps;
+
+ // Instance of accessibility information and handling for MSAA root
+ CComPtr<IAccessible> accessibility_root_;
+
+ // See note in VistaFrame for a description of this.
+ bool ignore_ncactivate_;
+ bool paint_as_active_;
+
+ // A view that holds the client-area contents of the browser window.
+ BrowserView* browser_view_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(XPFrame);
+};
+
+#endif // CHROME_BROWSER_VIEWS_OLD_FRAMES_XP_FRAME_H__
+
diff --git a/chrome/browser/views/tabs/tab_strip.cc b/chrome/browser/views/tabs/tab_strip.cc
index 2b8dc61..1bafdca 100644
--- a/chrome/browser/views/tabs/tab_strip.cc
+++ b/chrome/browser/views/tabs/tab_strip.cc
@@ -13,7 +13,6 @@
#include "chrome/browser/view_ids.h"
#include "chrome/browser/views/tabs/dragged_tab_controller.h"
#include "chrome/browser/views/tabs/tab.h"
-#include "chrome/browser/vista_frame.h"
#include "chrome/browser/web_contents.h"
#include "chrome/common/drag_drop_types.h"
#include "chrome/common/gfx/chrome_canvas.h"