summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorbrettw@google.com <brettw@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-10-10 20:34:35 +0000
committerbrettw@google.com <brettw@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-10-10 20:34:35 +0000
commitc80c563f3f32e49ce0087d899accf6a77de09ba6 (patch)
tree17f56be64796b691c7d323e08120acdac0e43d9f /chrome
parentb5108d1892eeb184b2679ce0658f5fe708e22016 (diff)
downloadchromium_src-c80c563f3f32e49ce0087d899accf6a77de09ba6.zip
chromium_src-c80c563f3f32e49ce0087d899accf6a77de09ba6.tar.gz
chromium_src-c80c563f3f32e49ce0087d899accf6a77de09ba6.tar.bz2
Start splitting out view-related stuff from WebContents into a new class WebContentsViewWin, accessed through an abstract interface WebContentsView. This is incomplete but is a good start. There are still a bunch of pass-throughs required for the TabContents overrides. These won't be able to be cleaned up until we kill TabContents.
Review URL: http://codereview.chromium.org/7205 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@3243 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/browser.vcproj12
-rw-r--r--chrome/browser/dom_ui/new_tab_ui.cc2
-rw-r--r--chrome/browser/jsmessage_box_handler.cc2
-rw-r--r--chrome/browser/tab_contents.cc2
-rw-r--r--chrome/browser/views/dom_view.cc1
-rw-r--r--chrome/browser/views/tab_contents_container_view.cc1
-rw-r--r--chrome/browser/web_contents.cc390
-rw-r--r--chrome/browser/web_contents.h82
-rw-r--r--chrome/browser/web_contents_view.h84
-rw-r--r--chrome/browser/web_contents_view_win.cc351
-rw-r--r--chrome/browser/web_contents_view_win.h86
11 files changed, 622 insertions, 391 deletions
diff --git a/chrome/browser/browser.vcproj b/chrome/browser/browser.vcproj
index c46d344..e437446 100644
--- a/chrome/browser/browser.vcproj
+++ b/chrome/browser/browser.vcproj
@@ -893,6 +893,18 @@
RelativePath=".\web_contents.h"
>
</File>
+ <File
+ RelativePath=".\web_contents_view.h"
+ >
+ </File>
+ <File
+ RelativePath=".\web_contents_view_win.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\web_contents_view_win.h"
+ >
+ </File>
</Filter>
<Filter
Name="Browser Window"
diff --git a/chrome/browser/dom_ui/new_tab_ui.cc b/chrome/browser/dom_ui/new_tab_ui.cc
index c96a5b5..dd2786a 100644
--- a/chrome/browser/dom_ui/new_tab_ui.cc
+++ b/chrome/browser/dom_ui/new_tab_ui.cc
@@ -819,7 +819,7 @@ void NewTabUIContents::SetInitialFocus() {
if (browser)
browser->FocusLocationBar();
else
- ::SetFocus(GetHWND());
+ ::SetFocus(GetContainerHWND());
}
bool NewTabUIContents::SupportsURL(GURL* url) {
diff --git a/chrome/browser/jsmessage_box_handler.cc b/chrome/browser/jsmessage_box_handler.cc
index 4bb020a..bcb4e92 100644
--- a/chrome/browser/jsmessage_box_handler.cc
+++ b/chrome/browser/jsmessage_box_handler.cc
@@ -132,7 +132,7 @@ void JavascriptMessageBoxHandler::ShowModalDialog() {
}
web_contents_->Activate();
- HWND root_hwnd = GetAncestor(web_contents_->GetHWND(), GA_ROOT);
+ HWND root_hwnd = GetAncestor(web_contents_->GetContainerHWND(), GA_ROOT);
dialog_ =
ChromeViews::Window::CreateChromeWindow(root_hwnd, gfx::Rect(), this);
dialog_->Show();
diff --git a/chrome/browser/tab_contents.cc b/chrome/browser/tab_contents.cc
index 4fa4dfe..f323524 100644
--- a/chrome/browser/tab_contents.cc
+++ b/chrome/browser/tab_contents.cc
@@ -13,6 +13,7 @@
#include "chrome/common/l10n_util.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
+#include "chrome/views/hwnd_view_container.h"
#include "chrome/views/native_scroll_bar.h"
#include "chrome/views/root_view.h"
#include "chrome/views/view.h"
@@ -349,6 +350,7 @@ void TabContents::StoreFocus() {
// If the focus was on the page, explicitly clear the focus so that we
// don't end up with the focused HWND not part of the window hierarchy.
+ // TODO(brettw) this should move to the view somehow.
HWND container_hwnd = GetContainerHWND();
if (container_hwnd) {
ChromeViews::View* focused_view = focus_manager->GetFocusedView();
diff --git a/chrome/browser/views/dom_view.cc b/chrome/browser/views/dom_view.cc
index 5a32d52..c97b605 100644
--- a/chrome/browser/views/dom_view.cc
+++ b/chrome/browser/views/dom_view.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/views/dom_view.h"
#include "chrome/browser/dom_ui/dom_ui_host.h"
+#include "chrome/views/hwnd_view_container.h"
DOMView::DOMView(const GURL& contents)
: contents_(contents), initialized_(false), host_(NULL) {
diff --git a/chrome/browser/views/tab_contents_container_view.cc b/chrome/browser/views/tab_contents_container_view.cc
index d6881652..0918ccf 100644
--- a/chrome/browser/views/tab_contents_container_view.cc
+++ b/chrome/browser/views/tab_contents_container_view.cc
@@ -13,6 +13,7 @@
#include "chrome/browser/tab_contents.h"
#include "chrome/browser/view_ids.h"
#include "chrome/browser/web_contents.h"
+#include "chrome/views/hwnd_view_container.h"
#include "chrome/views/root_view.h"
using ChromeViews::FocusTraversable;
diff --git a/chrome/browser/web_contents.cc b/chrome/browser/web_contents.cc
index d8eb687..723aa4f 100644
--- a/chrome/browser/web_contents.cc
+++ b/chrome/browser/web_contents.cc
@@ -34,21 +34,18 @@
#include "chrome/browser/render_widget_host_hwnd.h"
#include "chrome/browser/template_url_fetcher.h"
#include "chrome/browser/template_url_model.h"
-#include "chrome/browser/views/hung_renderer_view.h"
-#include "chrome/browser/views/sad_tab_view.h"
-#include "chrome/browser/web_drag_source.h"
-#include "chrome/browser/web_drop_target.h"
+#include "chrome/browser/views/hung_renderer_view.h" // TODO(brettw) delete me.
+#include "chrome/browser/views/sad_tab_view.h" // FIXME(brettw) delete me.
+#include "chrome/browser/web_contents_view.h"
+#include "chrome/browser/web_contents_view_win.h"
#include "chrome/common/chrome_switches.h"
-#include "chrome/common/gfx/chrome_canvas.h"
#include "chrome/common/l10n_util.h"
-#include "chrome/common/os_exchange_data.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
#include "chrome/common/resource_bundle.h"
#include "net/base/mime_util.h"
#include "net/base/registry_controlled_domain.h"
#include "webkit/glue/webkit_glue.h"
-#include "webkit/glue/plugins/webplugin_delegate_impl.h"
#include "generated_resources.h"
@@ -177,11 +174,11 @@ WebContents::WebContents(Profile* profile,
int routing_id,
HANDLE modal_dialog_event)
: TabContents(TAB_CONTENTS_WEB),
+ view_(new WebContentsViewWin(this)),
ALLOW_THIS_IN_INITIALIZER_LIST(
render_manager_(render_view_factory, this, this)),
render_view_factory_(render_view_factory),
has_page_title_(false),
- info_bar_visible_(false),
is_starred_(false),
printing_(*this),
notify_disconnection_(false),
@@ -311,7 +308,7 @@ void WebContents::Destroy() {
// Detach plugin windows so that they are not destroyed automatically.
// They will be cleaned up properly in plugin process.
- DetachPluginWindows();
+ view_->DetachPluginWindows();
NotifyDisconnected();
HungRendererWarning::HideForWebContents(this);
@@ -486,44 +483,34 @@ void WebContents::SizeContents(const gfx::Size& size) {
RepositionSupressedPopupsToFit(size);
}
-HWND WebContents::GetContentHWND() {
- if (!view())
- return NULL;
- return view()->GetPluginHWND();
+void WebContents::SetDownloadShelfVisible(bool visible) {
+ TabContents::SetDownloadShelfVisible(visible);
+ if (visible) {
+ // Always set this value as it reflects the last time the download shelf
+ // was made visible (even if it was already visible).
+ last_download_shelf_show_ = TimeTicks::Now();
+ }
}
+// Stupid view pass-throughs
void WebContents::CreateView(HWND parent_hwnd,
const gfx::Rect& initial_bounds) {
- set_delete_on_destroy(false);
- HWNDViewContainer::Init(parent_hwnd, initial_bounds, false);
-
- // Remove the root view drop target so we can register our own.
- RevokeDragDrop(GetHWND());
- drop_target_ = new WebDropTarget(GetHWND(), this);
+ view_->CreateView(parent_hwnd, initial_bounds);
}
-
-void WebContents::GetContainerBounds(gfx::Rect *out) const {
- CRect r;
- GetBounds(&r, false);
- *out = r;
+HWND WebContents::GetContainerHWND() const {
+ return view_->GetContainerHWND();
+}
+HWND WebContents::GetContentHWND() {
+ return view_->GetContentHWND();
+}
+bool WebContents::IsInfoBarVisible() {
+ return view_->IsInfoBarVisible();
}
-
InfoBarView* WebContents::GetInfoBarView() {
- if (info_bar_view_.get() == NULL) {
- info_bar_view_.reset(new InfoBarView(this));
- // The WebContents owns the info-bar.
- info_bar_view_->SetParentOwned(false);
- }
- return info_bar_view_.get();
+ return view_->GetInfoBarView();
}
-
-void WebContents::SetDownloadShelfVisible(bool visible) {
- TabContents::SetDownloadShelfVisible(visible);
- if (visible) {
- // Always set this value as it reflects the last time the download shelf
- // was made visible (even if it was already visible).
- last_download_shelf_show_ = TimeTicks::Now();
- }
+void WebContents::GetContainerBounds(gfx::Rect *out) const {
+ view_->GetContainerBounds(out);
}
void WebContents::OpenFindInPageWindow(const Browser& browser) {
@@ -637,14 +624,7 @@ void WebContents::OnJavaScriptMessageBoxClosed(IPC::Message* reply_msg,
}
void WebContents::SetInfoBarVisible(bool visible) {
- if (info_bar_visible_ != visible) {
- info_bar_visible_ = visible;
- if (info_bar_visible_) {
- // Invoke GetInfoBarView to force the info bar to be created.
- GetInfoBarView();
- }
- ToolbarSizeChanged(false);
- }
+ view_->SetInfoBarVisible(visible);
}
void WebContents::OnSavePage() {
@@ -747,6 +727,7 @@ Profile* WebContents::GetProfile() const {
}
void WebContents::CreateView(int route_id, HANDLE modal_dialog_event) {
+ // TODO(brettw) move this to the view.
WebContents* new_view = new WebContents(profile(),
GetSiteInstance(),
render_view_factory_,
@@ -758,11 +739,11 @@ void WebContents::CreateView(int route_id, HANDLE modal_dialog_event) {
// be parented to NULL. However doing that causes the corresponding view
// container windows to show up as overlapped windows, which causes
// other issues. We should fix this.
- HWND new_view_parent_window = ::GetAncestor(GetHWND(), GA_ROOT);
+ HWND new_view_parent_window = ::GetAncestor(GetContainerHWND(), GA_ROOT);
new_view->CreateView(new_view_parent_window, gfx::Rect());
// TODO(brettw) it seems bogus that we have to call this function on the
// newly created object and give it one of its own member variables.
- new_view->CreatePageView(new_view->render_view_host());
+ new_view->view_->CreatePageView(new_view->render_view_host());
// Don't show the view until we get enough context in ShowView.
pending_views_[route_id] = new_view;
@@ -826,7 +807,12 @@ void WebContents::ShowWidget(int route_id, const gfx::Rect& initial_pos) {
// The view has gone away or the renderer crashed. Nothing to do.
return;
}
- widget_view->Create(GetHWND(), NULL, NULL, WS_POPUP, WS_EX_TOOLWINDOW);
+
+ // This logic should be implemented by RenderWidgetHostHWND (as mentioned
+ // above) in the ::Init function, which should take a parent and some initial
+ // bounds.
+ widget_view->Create(view_->GetContainerHWND(), NULL, NULL,
+ WS_POPUP, WS_EX_TOOLWINDOW);
widget_view->MoveWindow(initial_pos.x(), initial_pos.y(), initial_pos.width(),
initial_pos.height(), TRUE);
widget_view->ShowWindow(SW_SHOW);
@@ -860,11 +846,13 @@ void WebContents::RendererGone(RenderViewHost* rvh) {
return;
}
+ // TODO(brettw) move the platform-specific view stuff here to the view.
+
// Force an invalidation here to render sad tab. however, it is possible for
// our window to have already gone away (since we may be in the process of
// closing this render view).
- if (::IsWindow(GetHWND()))
- InvalidateRect(GetHWND(), NULL, FALSE);
+ if (::IsWindow(view_->GetContainerHWND()))
+ InvalidateRect(view_->GetContainerHWND(), NULL, FALSE);
SetIsLoading(false, NULL);
@@ -872,7 +860,7 @@ void WebContents::RendererGone(RenderViewHost* rvh) {
// a renderer crashed while showing a modal dialog. We're assuming that the
// browser code will never show a modal dialog, so we could only be disabled
// by something the renderer (or some plug-in) did.
- HWND root_window = ::GetAncestor(GetHWND(), GA_ROOT);
+ HWND root_window = ::GetAncestor(view_->GetContainerHWND(), GA_ROOT);
if (!::IsWindowEnabled(root_window))
::EnableWindow(root_window, TRUE);
@@ -988,9 +976,10 @@ void WebContents::UpdateState(RenderViewHost* rvh,
hs->SetPageTitle(entry->display_url(), final_title);
}
}
- if (GetHWND()) {
+ // TODO(brettw) move this to the view.
+ if (view_->GetContainerHWND()) {
// It's possible to get this after the hwnd has been destroyed.
- ::SetWindowText(GetHWND(), title.c_str());
+ ::SetWindowText(view_->GetContainerHWND(), title.c_str());
::SetWindowText(view()->GetPluginHWND(), title.c_str());
}
@@ -1234,16 +1223,17 @@ void WebContents::DidDownloadImage(
void WebContents::ShowContextMenu(
const ViewHostMsg_ContextMenu_Params& params) {
+ // TODO(brettw) move this to the view.
RenderViewContextMenuController menu_controller(this, params);
RenderViewContextMenu menu(&menu_controller,
- GetHWND(),
+ view_->GetContainerHWND(),
params.type,
params.misspelled_word,
params.dictionary_suggestions,
profile());
POINT screen_pt = { params.x, params.y };
- MapWindowPoints(GetHWND(), HWND_DESKTOP, &screen_pt, 1);
+ MapWindowPoints(view_->GetContainerHWND(), HWND_DESKTOP, &screen_pt, 1);
// Enable recursive tasks on the message loop so we can get updates while
// the context menu is being displayed.
@@ -1254,42 +1244,11 @@ void WebContents::ShowContextMenu(
}
void WebContents::StartDragging(const WebDropData& drop_data) {
- scoped_refptr<OSExchangeData> data(new OSExchangeData);
-
- // TODO(tc): Generate an appropriate drag image.
-
- // We set the file contents before the URL because the URL also sets file
- // contents (to a .URL shortcut). We want to prefer file content data over a
- // shortcut.
- if (!drop_data.file_contents.empty()) {
- data->SetFileContents(drop_data.file_description_filename,
- drop_data.file_contents);
- }
- if (!drop_data.cf_html.empty())
- data->SetCFHtml(drop_data.cf_html);
- if (drop_data.url.is_valid())
- data->SetURL(drop_data.url, drop_data.url_title);
- if (!drop_data.plain_text.empty())
- data->SetString(drop_data.plain_text);
-
- scoped_refptr<WebDragSource> drag_source(
- new WebDragSource(GetHWND(), render_view_host()));
-
- DWORD effects;
-
- // We need to enable recursive tasks on the message loop so we can get
- // updates while in the system DoDragDrop loop.
- bool old_state = MessageLoop::current()->NestableTasksAllowed();
- MessageLoop::current()->SetNestableTasksAllowed(true);
- DoDragDrop(data, drag_source, DROPEFFECT_COPY | DROPEFFECT_LINK, &effects);
- MessageLoop::current()->SetNestableTasksAllowed(old_state);
-
- if (render_view_host())
- render_view_host()->DragSourceSystemDragEnded();
+ view_->StartDragging(drop_data);
}
void WebContents::UpdateDragCursor(bool is_drop_target) {
- drop_target_->set_is_drop_target(is_drop_target);
+ view_->UpdateDragCursor(is_drop_target);
}
void WebContents::RequestOpenURL(const GURL& url,
@@ -1395,8 +1354,9 @@ void WebContents::PasswordFormsSeen(
}
void WebContents::TakeFocus(bool reverse) {
+ // TODO(brettw) move this to the view.
ChromeViews::FocusManager* focus_manager =
- ChromeViews::FocusManager::GetFocusManager(GetHWND());
+ ChromeViews::FocusManager::GetFocusManager(view_->GetContainerHWND());
// We may not have a focus manager if the tab has been switched before this
// message arrived.
@@ -1470,7 +1430,7 @@ void WebContents::PageHasOSDD(RenderViewHost* render_view_host,
keyword,
url,
base_entry->favicon().url(),
- GetAncestor(GetHWND(), GA_ROOT),
+ GetAncestor(view_->GetContainerHWND(), GA_ROOT),
autodetected);
}
@@ -1492,11 +1452,13 @@ void WebContents::DidPrintPage(const ViewHostMsg_DidPrintPage_Params& params) {
// The renderer sends back to the browser the key events it did not process.
void WebContents::HandleKeyboardEvent(const WebKeyboardEvent& event) {
+ // TODO(brettw) move this to the view.
+
// The renderer returned a keyboard event it did not process. This may be
// a keyboard shortcut that we have to process.
if (event.type == WebInputEvent::KEY_DOWN) {
ChromeViews::FocusManager* focus_manager =
- ChromeViews::FocusManager::GetFocusManager(GetHWND());
+ ChromeViews::FocusManager::GetFocusManager(view_->GetContainerHWND());
// We may not have a focus_manager at this point (if the tab has been
// switched by the time this message returned).
if (focus_manager) {
@@ -1707,21 +1669,19 @@ void WebContents::BeforeUnloadFiredFromRenderManager(
void WebContents::UpdateRenderViewSizeForRenderManager() {
// Using same technique as OnPaint, which sets size of SadTab.
- CRect cr;
- GetClientRect(&cr);
- gfx::Size new_size(cr.Width(), cr.Height());
- SizeContents(new_size);
+ SizeContents(view_->GetContainerSize());
}
bool WebContents::CreateRenderViewForRenderManager(
RenderViewHost* render_view_host) {
- RenderWidgetHostHWND* view = CreatePageView(render_view_host);
+ // TODO(brettw) move this to the view. Probably the RenderWidgetHostHWNDs
+ // should be created by a factory somewhere that just returns a
+ // RenderWidgetHostView*.
+ RenderWidgetHostHWND* rvh_view = view_->CreatePageView(render_view_host);
bool ok = render_view_host->CreateRenderView();
if (ok) {
- CRect client_rect;
- ::GetClientRect(GetHWND(), &client_rect);
- view->SetSize(gfx::Size(client_rect.Width(), client_rect.Height()));
+ rvh_view->SetSize(view_->GetContainerSize());
UpdateMaxPageIDIfNecessary(render_view_host->site_instance(),
render_view_host);
}
@@ -1764,210 +1724,6 @@ void WebContents::Observe(NotificationType type,
}
}
-void WebContents::OnDestroy() {
- if (drop_target_.get()) {
- RevokeDragDrop(GetHWND());
- drop_target_ = NULL;
- }
-}
-
-void WebContents::OnHScroll(int scroll_type, short position, HWND scrollbar) {
- ScrollCommon(WM_HSCROLL, scroll_type, position, scrollbar);
-}
-
-void WebContents::OnMouseLeave() {
- // Let our delegate know that the mouse moved (useful for resetting status
- // bubble state).
- if (delegate())
- delegate()->ContentsMouseEvent(this, WM_MOUSELEAVE);
- SetMsgHandled(FALSE);
-}
-
-LRESULT WebContents::OnMouseRange(UINT msg, WPARAM w_param, LPARAM l_param) {
- switch (msg) {
- case WM_LBUTTONDOWN:
- case WM_MBUTTONDOWN:
- case WM_RBUTTONDOWN:
- // Make sure this TabContents is activated when it is clicked on.
- if (delegate())
- delegate()->ActivateContents(this);
- break;
- case WM_MOUSEMOVE:
- // Let our delegate know that the mouse moved (useful for resetting status
- // bubble state).
- if (delegate())
- delegate()->ContentsMouseEvent(this, WM_MOUSEMOVE);
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-void WebContents::OnPaint(HDC junk_dc) {
- if (render_view_host() && !render_view_host()->IsRenderViewLive()) {
- if (!sad_tab_.get())
- sad_tab_.reset(new SadTabView);
- CRect cr;
- GetClientRect(&cr);
- sad_tab_->SetBounds(cr);
- ChromeCanvasPaint canvas(GetHWND(), true);
- sad_tab_->ProcessPaint(&canvas);
- return;
- }
-
- // We need to do this to validate the dirty area so we don't end up in a
- // WM_PAINTstorm that causes other mysterious bugs (such as WM_TIMERs not
- // firing etc). It doesn't matter that we don't have any non-clipped area.
- CPaintDC dc(GetHWND());
- SetMsgHandled(FALSE);
-}
-
-// A message is reflected here from view().
-// Return non-zero to indicate that it is handled here.
-// Return 0 to allow view() to further process it.
-LRESULT WebContents::OnReflectedMessage(UINT msg, WPARAM w_param,
- LPARAM l_param) {
- MSG* message = reinterpret_cast<MSG*>(l_param);
- switch (message->message) {
- case WM_MOUSEWHEEL:
- // This message is reflected from the view() to this window.
- if (GET_KEYSTATE_WPARAM(message->wParam) & MK_CONTROL) {
- WheelZoom(GET_WHEEL_DELTA_WPARAM(message->wParam));
- return 1;
- }
- break;
- case WM_HSCROLL:
- case WM_VSCROLL:
- if (ScrollZoom(LOWORD(message->wParam)))
- return 1;
- default:
- break;
- }
-
- return 0;
-}
-
-void WebContents::OnSetFocus(HWND window) {
- // TODO(jcampan): figure out why removing this prevents tabs opened in the
- // background from properly taking focus.
- // We NULL-check the render_view_host_ here because Windows can send us
- // messages during the destruction process after it has been destroyed.
- if (view()) {
- HWND inner_hwnd = view()->GetPluginHWND();
- if (::IsWindow(inner_hwnd))
- ::SetFocus(inner_hwnd);
- }
-}
-
-void WebContents::OnVScroll(int scroll_type, short position, HWND scrollbar) {
- ScrollCommon(WM_VSCROLL, scroll_type, position, scrollbar);
-}
-
-void WebContents::OnWindowPosChanged(WINDOWPOS* window_pos) {
- if (window_pos->flags & SWP_HIDEWINDOW) {
- HideContents();
- } else {
- // The WebContents was shown by a means other than the user selecting a
- // Tab, e.g. the window was minimized then restored.
- if (window_pos->flags & SWP_SHOWWINDOW)
- ShowContents();
- // Unless we were specifically told not to size, cause the renderer to be
- // sized to the new bounds, which forces a repaint. Not required for the
- // simple minimize-restore case described above, for example, since the
- // size hasn't changed.
- if (!(window_pos->flags & SWP_NOSIZE)) {
- gfx::Size size(window_pos->cx, window_pos->cy);
- SizeContents(size);
- }
-
- // If we have a FindInPage dialog, notify it that the window changed.
- if (find_in_page_controller_.get() && find_in_page_controller_->IsVisible())
- find_in_page_controller_->MoveWindowIfNecessary(gfx::Rect());
- }
-}
-
-void WebContents::OnSize(UINT param, const CSize& size) {
- HWNDViewContainer::OnSize(param, size);
-
- // Hack for thinkpad touchpad driver.
- // Set fake scrollbars so that we can get scroll messages,
- SCROLLINFO si = {0};
- si.cbSize = sizeof(si);
- si.fMask = SIF_ALL;
-
- si.nMin = 1;
- si.nMax = 100;
- si.nPage = 10;
- si.nTrackPos = 50;
-
- ::SetScrollInfo(GetHWND(), SB_HORZ, &si, FALSE);
- ::SetScrollInfo(GetHWND(), SB_VERT, &si, FALSE);
-}
-
-LRESULT WebContents::OnNCCalcSize(BOOL w_param, LPARAM l_param) {
- // Hack for thinkpad mouse wheel driver. We have set the fake scroll bars
- // to receive scroll messages from thinkpad touchpad driver. Suppress
- // painting of scrollbars by returning 0 size for them.
- return 0;
-}
-
-void WebContents::OnNCPaint(HRGN rgn) {
- // Suppress default WM_NCPAINT handling. We don't need to do anything
- // here since the view will draw everything correctly.
-}
-
-void WebContents::ScrollCommon(UINT message, int scroll_type, short position,
- HWND scrollbar) {
- // This window can receive scroll events as a result of the ThinkPad's
- // Trackpad scroll wheel emulation.
- if (!ScrollZoom(scroll_type)) {
- // Reflect scroll message to the view() to give it a chance
- // to process scrolling.
- SendMessage(GetContentHWND(), message, MAKELONG(scroll_type, position),
- (LPARAM) scrollbar);
- }
-}
-
-bool WebContents::ScrollZoom(int scroll_type) {
- // If ctrl is held, zoom the UI. There are three issues with this:
- // 1) Should the event be eaten or forwarded to content? We eat the event,
- // which is like Firefox and unlike IE.
- // 2) Should wheel up zoom in or out? We zoom in (increase font size), which
- // is like IE and Google maps, but unlike Firefox.
- // 3) Should the mouse have to be over the content area? We zoom as long as
- // content has focus, although FF and IE require that the mouse is over
- // content. This is because all events get forwarded when content has
- // focus.
- if (GetAsyncKeyState(VK_CONTROL) & 0x8000) {
- int distance = 0;
- switch (scroll_type) {
- case SB_LINEUP:
- distance = WHEEL_DELTA;
- break;
- case SB_LINEDOWN:
- distance = -WHEEL_DELTA;
- break;
- // TODO(joshia): Handle SB_PAGEUP, SB_PAGEDOWN, SB_THUMBPOSITION,
- // and SB_THUMBTRACK for completeness
- default:
- break;
- }
-
- WheelZoom(distance);
- return true;
- }
- return false;
-}
-
-void WebContents::WheelZoom(int distance) {
- if (delegate()) {
- bool zoom_in = distance > 0;
- delegate()->ContentsZoomChange(zoom_in);
- }
-}
-
void WebContents::DidNavigateMainFramePostCommit(
const NavigationController::LoadCommittedDetails& details,
const ViewHostMsg_FrameNavigate_Params& params) {
@@ -2188,30 +1944,6 @@ void WebContents::UpdateHistoryForNavigation(const GURL& display_url,
}
}
-RenderWidgetHostHWND* WebContents::CreatePageView(
- RenderViewHost* render_view_host) {
- // Create the View as well. Its lifetime matches the child process'.
- DCHECK(!render_view_host->view());
- RenderWidgetHostHWND* view = new RenderWidgetHostHWND(render_view_host);
- render_view_host->set_view(view);
- view->Create(GetHWND());
- view->ShowWindow(SW_SHOW);
- return view;
-}
-
-void WebContents::DetachPluginWindows() {
- EnumChildWindows(GetHWND(), WebContents::EnumPluginWindowsCallback, NULL);
-}
-
-BOOL WebContents::EnumPluginWindowsCallback(HWND window, LPARAM) {
- if (WebPluginDelegateImpl::IsPluginDelegateWindow(window)) {
- ::ShowWindow(window, SW_HIDE);
- SetParent(window, NULL);
- }
-
- return TRUE;
-}
-
void WebContents::NotifySwapped() {
// After sending out a swap notification, we need to send a disconnect
// notification so that clients that pick up a pointer to |this| can NULL the
diff --git a/chrome/browser/web_contents.h b/chrome/browser/web_contents.h
index 780b34a..3fd2237 100644
--- a/chrome/browser/web_contents.h
+++ b/chrome/browser/web_contents.h
@@ -14,7 +14,6 @@
#include "chrome/browser/shell_dialogs.h"
#include "chrome/browser/tab_contents.h"
#include "chrome/browser/web_app.h"
-#include "chrome/views/hwnd_view_container.h"
class FindInPageController;
class InterstitialPageDelegate;
@@ -25,15 +24,13 @@ class RenderViewHostFactory;
class RenderWidgetHost;
class RenderWidgetHostHWND;
class SadTabView;
-struct WebDropData;
-class WebDropTarget;
+class WebContentsView;
// WebContents represents the contents of a tab that shows web pages. It embeds
// a RenderViewHost (via RenderViewHostManager) to actually display the page.
class WebContents : public TabContents,
public RenderViewHostDelegate,
public RenderViewHostManager::Delegate,
- public ChromeViews::HWNDViewContainer,
public SelectFileDialog::Listener,
public NotificationObserver,
public WebApp::Observer {
@@ -73,6 +70,8 @@ class WebContents : public TabContents,
RenderViewHost* render_view_host() const {
return render_manager_.current_host();
}
+ // TODO(brettw) rename this to render_widget_host_view soon, and make this go
+ // away entirely in the long run.
RenderWidgetHostView* view() const {
return render_manager_.current_view();
}
@@ -102,15 +101,17 @@ class WebContents : public TabContents,
virtual void ShowContents();
virtual void HideContents();
virtual void SizeContents(const gfx::Size& size);
- virtual HWND GetContentHWND();
+ virtual void SetDownloadShelfVisible(bool visible);
+
+ // Retarded pass-throughs to the view. See also below under misc state.
+ // TODO(brettw) fix this, tab contents shouldn't have these methods, probably
+ // it should be killed altogether.
virtual void CreateView(HWND parent_hwnd, const gfx::Rect& initial_bounds);
- virtual HWND GetContainerHWND() const { return GetHWND(); }
- virtual void GetContainerBounds(gfx::Rect *out) const;
- // Create the InfoBarView and returns it if none has been created.
- // Just returns existing InfoBarView if it is already created.
+ virtual HWND GetContainerHWND() const;
+ virtual HWND GetContentHWND();
+ virtual bool IsInfoBarVisible();
virtual InfoBarView* GetInfoBarView();
- virtual bool IsInfoBarVisible() { return info_bar_visible_; }
- virtual void SetDownloadShelfVisible(bool visible);
+ virtual void GetContainerBounds(gfx::Rect *out) const;
// Find in page --------------------------------------------------------------
@@ -175,6 +176,9 @@ class WebContents : public TabContents,
// Misc state & callbacks ----------------------------------------------------
+ // More retarded pass-throughs (see also above under TabContents overrides).
+ void SetInfoBarVisible(bool visible);
+
// Set whether the contents should block javascript message boxes or not.
// Default is not to block any message boxes.
void set_suppress_javascript_messages(
@@ -187,11 +191,6 @@ class WebContents : public TabContents,
bool success,
const std::wstring& prompt);
- // Whether or not the info bar is visible. This delegates to
- // the ChromeFrame method InfoBarVisibilityChanged. See also IsInfoBarVisible
- // (a TabContents override).
- void SetInfoBarVisible(bool visible);
-
// Prepare for saving page.
void OnSavePage();
@@ -384,6 +383,9 @@ class WebContents : public TabContents,
FRIEND_TEST(WebContentsTest, UpdateTitle);
friend class TestWebContents;
+ // Temporary until the view/contents separation is complete.
+ friend class WebContentsViewWin;
+
// When CreateShortcut is invoked RenderViewHost::GetApplicationInfo is
// invoked. CreateShortcut caches the state of the page needed to create the
// shortcut in PendingInstall. When OnDidGetApplicationInfo is invoked, it
@@ -406,30 +408,6 @@ class WebContents : public TabContents,
const NotificationSource& source,
const NotificationDetails& details);
- // Windows events ------------------------------------------------------------
-
- virtual void OnDestroy();
- virtual void OnHScroll(int scroll_type, short position, HWND scrollbar);
- virtual void OnMouseLeave();
- virtual LRESULT OnMouseRange(UINT msg, WPARAM w_param, LPARAM l_param);
- virtual void OnPaint(HDC junk_dc);
- virtual LRESULT OnReflectedMessage(UINT msg, WPARAM w_param, LPARAM l_param);
- virtual void OnSetFocus(HWND window);
- virtual void OnVScroll(int scroll_type, short position, HWND scrollbar);
- virtual void OnWindowPosChanged(WINDOWPOS* window_pos);
- virtual void OnSize(UINT param, const CSize& size);
- virtual LRESULT OnNCCalcSize(BOOL w_param, LPARAM l_param);
- virtual void OnNCPaint(HRGN rgn);
-
- // Backend for all scroll messages, the |message| parameter indicates which
- // one it is.
- void ScrollCommon(UINT message, int scroll_type, short position,
- HWND scrollbar);
-
- // TODO(brettw) comment these. They're confusing.
- bool ScrollZoom(int scroll_type);
- void WheelZoom(int distance);
-
// Navigation helpers --------------------------------------------------------
//
// These functions are helpers for Navigate() and DidNavigate().
@@ -488,17 +466,6 @@ class WebContents : public TabContents,
virtual void UpdateHistoryForNavigation(const GURL& display_url,
const ViewHostMsg_FrameNavigate_Params& params);
- // Misc view stuff -----------------------------------------------------------
-
- // Sets up the View that holds the rendered web page, receives messages for
- // it and contains page plugins.
- RenderWidgetHostHWND* CreatePageView(RenderViewHost* render_view_host);
-
- // Enumerate and 'un-parent' any plugin windows that are children
- // of this web contents.
- void DetachPluginWindows();
- static BOOL CALLBACK EnumPluginWindowsCallback(HWND window, LPARAM param);
-
// Misc non-view stuff -------------------------------------------------------
// Helper functions for sending notifications.
@@ -512,6 +479,9 @@ class WebContents : public TabContents,
// Data ----------------------------------------------------------------------
+ // The corresponding view.
+ scoped_ptr<WebContentsView> view_;
+
// Manages creation and swapping of render views.
RenderViewHostManager render_manager_;
@@ -545,12 +515,6 @@ class WebContents : public TabContents,
// SavePackage, lazily created.
scoped_refptr<SavePackage> save_package_;
- // InfoBarView, lazily created.
- scoped_ptr<InfoBarView> info_bar_view_;
-
- // Whether the info bar view is visible.
- bool info_bar_visible_;
-
// Handles communication with the FindInPage popup.
scoped_ptr<FindInPageController> find_in_page_controller_;
@@ -573,10 +537,8 @@ class WebContents : public TabContents,
// PluginInstaller, lazily created.
scoped_ptr<PluginInstaller> plugin_installer_;
- // A drop target object that handles drags over this WebContents.
- scoped_refptr<WebDropTarget> drop_target_;
-
// The SadTab renderer.
+ // TODO(brettw) move into WebContentsView*.
scoped_ptr<SadTabView> sad_tab_;
// Handles downloading favicons.
diff --git a/chrome/browser/web_contents_view.h b/chrome/browser/web_contents_view.h
new file mode 100644
index 0000000..bb28438
--- /dev/null
+++ b/chrome/browser/web_contents_view.h
@@ -0,0 +1,84 @@
+// 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_WEB_CONTENTS_VIEW_H_
+#define CHROME_BROWSER_WEB_CONTENTS_VIEW_H_
+
+#include <windows.h>
+
+#include "base/basictypes.h"
+#include "base/gfx/rect.h"
+#include "base/gfx/size.h"
+
+class InfoBarView;
+class RenderViewHost;
+class RenderWidgetHostHWND;
+class WebContents;
+struct WebDropData;
+
+// The WebContentsView is an interface that is implemented by the platform-
+// dependent web contents views. The WebContents uses this interface to talk to
+// them.
+class WebContentsView {
+ public:
+ virtual ~WebContentsView() {}
+
+ virtual void CreateView(HWND parent_hwnd,
+ const gfx::Rect& initial_bounds) = 0;
+
+ // Sets up the View that holds the rendered web page, receives messages for
+ // it and contains page plugins.
+ virtual RenderWidgetHostHWND* CreatePageView(
+ RenderViewHost* render_view_host) = 0;
+
+ // Returns the HWND that contains the contents of the tab.
+ // TODO(brettw) this should not be necessary in this cross-platform interface.
+ virtual HWND GetContainerHWND() const = 0;
+
+ // Returns the HWND with the main content of the tab (i.e. the main render
+ // view host, though there may be many popups in the tab as children of the
+ // container HWND).
+ // TODO(brettw) this should not be necessary in this cross-platform interface.
+ virtual HWND GetContentHWND() const = 0;
+
+ // Computes the rectangle for the native widget that contains the contents of
+ // the tab relative to its parent.
+ virtual void GetContainerBounds(gfx::Rect *out) const = 0;
+
+ // Helper function for GetContainerBounds. Most callers just want to know the
+ // size, and this makes it more clear.
+ gfx::Size GetContainerSize() const {
+ gfx::Rect rc;
+ GetContainerBounds(&rc);
+ return gfx::Size(rc.width(), rc.height());
+ }
+
+ // The user started dragging content of the specified type within the tab.
+ // Contextual information about the dragged content is supplied by drop_data.
+ virtual void StartDragging(const WebDropData& drop_data) = 0;
+
+ // Enumerate and 'un-parent' any plugin windows that are children of us.
+ virtual void DetachPluginWindows() = 0;
+
+ // Set/get whether or not the info bar is visible. See also the ChromeFrame
+ // method InfoBarVisibilityChanged and TabContents::IsInfoBarVisible.
+ virtual void SetInfoBarVisible(bool visible) = 0;
+ virtual bool IsInfoBarVisible() const = 0;
+
+ // Create the InfoBarView and returns it if none has been created.
+ // Just returns existing InfoBarView if it is already created.
+ virtual InfoBarView* GetInfoBarView() = 0;
+
+ // The page wants to update the mouse cursor during a drag & drop operation.
+ // |is_drop_target| is true if the mouse is over a valid drop target.
+ virtual void UpdateDragCursor(bool is_drop_target) = 0;
+
+ protected:
+ WebContentsView() {} // Abstract interface.
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(WebContentsView);
+};
+
+#endif // CHROME_BROWSER_WEB_CONTENTS_VIEW_H_
diff --git a/chrome/browser/web_contents_view_win.cc b/chrome/browser/web_contents_view_win.cc
new file mode 100644
index 0000000..6078b94
--- /dev/null
+++ b/chrome/browser/web_contents_view_win.cc
@@ -0,0 +1,351 @@
+// 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/web_contents_view_win.h"
+
+#include <windows.h>
+
+#include "chrome/browser/find_in_page_controller.h"
+#include "chrome/browser/render_view_host.h"
+#include "chrome/browser/render_widget_host_hwnd.h"
+#include "chrome/browser/tab_contents_delegate.h"
+#include "chrome/browser/views/sad_tab_view.h"
+#include "chrome/browser/web_contents.h"
+#include "chrome/browser/web_drag_source.h"
+#include "chrome/browser/web_drop_target.h"
+#include "chrome/common/gfx/chrome_canvas.h"
+#include "chrome/common/os_exchange_data.h"
+#include "webkit/glue/plugins/webplugin_delegate_impl.h"
+
+namespace {
+
+// Windows callback for DetachPluginWindows.
+BOOL CALLBACK EnumPluginWindowsCallback(HWND window, LPARAM param) {
+ if (WebPluginDelegateImpl::IsPluginDelegateWindow(window)) {
+ ::ShowWindow(window, SW_HIDE);
+ SetParent(window, NULL);
+ }
+ return TRUE;
+}
+
+} // namespace
+
+WebContentsViewWin::WebContentsViewWin(WebContents* web_contents)
+ : web_contents_(web_contents),
+ info_bar_visible_(false) {
+}
+
+WebContentsViewWin::~WebContentsViewWin() {
+}
+
+void WebContentsViewWin::CreateView(HWND parent_hwnd,
+ const gfx::Rect& initial_bounds) {
+ set_delete_on_destroy(false);
+ HWNDViewContainer::Init(parent_hwnd, initial_bounds, false);
+
+ // Remove the root view drop target so we can register our own.
+ RevokeDragDrop(GetHWND());
+ drop_target_ = new WebDropTarget(GetHWND(), web_contents_);
+}
+
+RenderWidgetHostHWND* WebContentsViewWin::CreatePageView(
+ RenderViewHost* render_view_host) {
+ // Create the View as well. Its lifetime matches the child process'.
+ DCHECK(!render_view_host->view());
+ RenderWidgetHostHWND* view = new RenderWidgetHostHWND(render_view_host);
+ render_view_host->set_view(view);
+ view->Create(GetHWND());
+ view->ShowWindow(SW_SHOW);
+ return view;
+}
+
+HWND WebContentsViewWin::GetContainerHWND() const {
+ return GetHWND();
+}
+
+HWND WebContentsViewWin::GetContentHWND() const {
+ if (!web_contents_->view())
+ return NULL;
+ return web_contents_->view()->GetPluginHWND();
+}
+
+void WebContentsViewWin::GetContainerBounds(gfx::Rect *out) const {
+ CRect r;
+ GetBounds(&r, false);
+ *out = r;
+}
+
+void WebContentsViewWin::StartDragging(const WebDropData& drop_data) {
+ scoped_refptr<OSExchangeData> data(new OSExchangeData);
+
+ // TODO(tc): Generate an appropriate drag image.
+
+ // We set the file contents before the URL because the URL also sets file
+ // contents (to a .URL shortcut). We want to prefer file content data over a
+ // shortcut.
+ if (!drop_data.file_contents.empty()) {
+ data->SetFileContents(drop_data.file_description_filename,
+ drop_data.file_contents);
+ }
+ if (!drop_data.cf_html.empty())
+ data->SetCFHtml(drop_data.cf_html);
+ if (drop_data.url.is_valid())
+ data->SetURL(drop_data.url, drop_data.url_title);
+ if (!drop_data.plain_text.empty())
+ data->SetString(drop_data.plain_text);
+
+ scoped_refptr<WebDragSource> drag_source(
+ new WebDragSource(GetHWND(), web_contents_->render_view_host()));
+
+ DWORD effects;
+
+ // We need to enable recursive tasks on the message loop so we can get
+ // updates while in the system DoDragDrop loop.
+ bool old_state = MessageLoop::current()->NestableTasksAllowed();
+ MessageLoop::current()->SetNestableTasksAllowed(true);
+ DoDragDrop(data, drag_source, DROPEFFECT_COPY | DROPEFFECT_LINK, &effects);
+ MessageLoop::current()->SetNestableTasksAllowed(old_state);
+
+ if (web_contents_->render_view_host())
+ web_contents_->render_view_host()->DragSourceSystemDragEnded();
+}
+
+void WebContentsViewWin::DetachPluginWindows() {
+ EnumChildWindows(GetHWND(), EnumPluginWindowsCallback, NULL);
+}
+
+void WebContentsViewWin::OnDestroy() {
+ if (drop_target_.get()) {
+ RevokeDragDrop(GetHWND());
+ drop_target_ = NULL;
+ }
+}
+
+void WebContentsViewWin::SetInfoBarVisible(bool visible) {
+ if (info_bar_visible_ != visible) {
+ info_bar_visible_ = visible;
+ if (info_bar_visible_) {
+ // Invoke GetInfoBarView to force the info bar to be created.
+ GetInfoBarView();
+ }
+ web_contents_->ToolbarSizeChanged(false);
+ }
+}
+
+bool WebContentsViewWin::IsInfoBarVisible() const {
+ return info_bar_visible_;
+}
+
+InfoBarView* WebContentsViewWin::GetInfoBarView() {
+ if (info_bar_view_.get() == NULL) {
+ info_bar_view_.reset(new InfoBarView(web_contents_));
+ // The WebContents owns the info-bar.
+ info_bar_view_->SetParentOwned(false);
+ }
+ return info_bar_view_.get();
+}
+
+void WebContentsViewWin::UpdateDragCursor(bool is_drop_target) {
+ drop_target_->set_is_drop_target(is_drop_target);
+}
+
+void WebContentsViewWin::OnHScroll(int scroll_type, short position, HWND scrollbar) {
+ ScrollCommon(WM_HSCROLL, scroll_type, position, scrollbar);
+}
+
+void WebContentsViewWin::OnMouseLeave() {
+ // Let our delegate know that the mouse moved (useful for resetting status
+ // bubble state).
+ if (web_contents_->delegate())
+ web_contents_->delegate()->ContentsMouseEvent(web_contents_, WM_MOUSELEAVE);
+ SetMsgHandled(FALSE);
+}
+
+LRESULT WebContentsViewWin::OnMouseRange(UINT msg, WPARAM w_param, LPARAM l_param) {
+ switch (msg) {
+ case WM_LBUTTONDOWN:
+ case WM_MBUTTONDOWN:
+ case WM_RBUTTONDOWN:
+ // Make sure this TabContents is activated when it is clicked on.
+ if (web_contents_->delegate())
+ web_contents_->delegate()->ActivateContents(web_contents_);
+ break;
+ case WM_MOUSEMOVE:
+ // Let our delegate know that the mouse moved (useful for resetting status
+ // bubble state).
+ if (web_contents_->delegate())
+ web_contents_->delegate()->ContentsMouseEvent(web_contents_, WM_MOUSEMOVE);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+void WebContentsViewWin::OnPaint(HDC junk_dc) {
+ if (web_contents_->render_view_host() &&
+ !web_contents_->render_view_host()->IsRenderViewLive()) {
+ if (!web_contents_->sad_tab_.get())
+ web_contents_->sad_tab_.reset(new SadTabView);
+ CRect cr;
+ GetClientRect(&cr);
+ web_contents_->sad_tab_->SetBounds(cr);
+ ChromeCanvasPaint canvas(GetHWND(), true);
+ web_contents_->sad_tab_->ProcessPaint(&canvas);
+ return;
+ }
+
+ // We need to do this to validate the dirty area so we don't end up in a
+ // WM_PAINTstorm that causes other mysterious bugs (such as WM_TIMERs not
+ // firing etc). It doesn't matter that we don't have any non-clipped area.
+ CPaintDC dc(GetHWND());
+ SetMsgHandled(FALSE);
+}
+
+// A message is reflected here from view().
+// Return non-zero to indicate that it is handled here.
+// Return 0 to allow view() to further process it.
+LRESULT WebContentsViewWin::OnReflectedMessage(UINT msg, WPARAM w_param,
+ LPARAM l_param) {
+ MSG* message = reinterpret_cast<MSG*>(l_param);
+ switch (message->message) {
+ case WM_MOUSEWHEEL:
+ // This message is reflected from the view() to this window.
+ if (GET_KEYSTATE_WPARAM(message->wParam) & MK_CONTROL) {
+ WheelZoom(GET_WHEEL_DELTA_WPARAM(message->wParam));
+ return 1;
+ }
+ break;
+ case WM_HSCROLL:
+ case WM_VSCROLL:
+ if (ScrollZoom(LOWORD(message->wParam)))
+ return 1;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+void WebContentsViewWin::OnSetFocus(HWND window) {
+ // TODO(jcampan): figure out why removing this prevents tabs opened in the
+ // background from properly taking focus.
+ // We NULL-check the render_view_host_ here because Windows can send us
+ // messages during the destruction process after it has been destroyed.
+ if (web_contents_->view()) {
+ HWND inner_hwnd = web_contents_->view()->GetPluginHWND();
+ if (::IsWindow(inner_hwnd))
+ ::SetFocus(inner_hwnd);
+ }
+}
+
+void WebContentsViewWin::OnVScroll(int scroll_type, short position, HWND scrollbar) {
+ ScrollCommon(WM_VSCROLL, scroll_type, position, scrollbar);
+}
+
+void WebContentsViewWin::OnWindowPosChanged(WINDOWPOS* window_pos) {
+ if (window_pos->flags & SWP_HIDEWINDOW) {
+ web_contents_->HideContents();
+ } else {
+ // The WebContents was shown by a means other than the user selecting a
+ // Tab, e.g. the window was minimized then restored.
+ if (window_pos->flags & SWP_SHOWWINDOW)
+ web_contents_->ShowContents();
+ // Unless we were specifically told not to size, cause the renderer to be
+ // sized to the new bounds, which forces a repaint. Not required for the
+ // simple minimize-restore case described above, for example, since the
+ // size hasn't changed.
+ if (!(window_pos->flags & SWP_NOSIZE)) {
+ gfx::Size size(window_pos->cx, window_pos->cy);
+ web_contents_->SizeContents(size); // FIXME(brettw) should this be on this class?
+ }
+
+ // If we have a FindInPage dialog, notify it that the window changed.
+ if (web_contents_->find_in_page_controller_.get() &&
+ web_contents_->find_in_page_controller_->IsVisible())
+ web_contents_->find_in_page_controller_->MoveWindowIfNecessary(gfx::Rect());
+ }
+}
+
+void WebContentsViewWin::OnSize(UINT param, const CSize& size) {
+ HWNDViewContainer::OnSize(param, size);
+
+ // Hack for thinkpad touchpad driver.
+ // Set fake scrollbars so that we can get scroll messages,
+ SCROLLINFO si = {0};
+ si.cbSize = sizeof(si);
+ si.fMask = SIF_ALL;
+
+ si.nMin = 1;
+ si.nMax = 100;
+ si.nPage = 10;
+ si.nTrackPos = 50;
+
+ ::SetScrollInfo(GetHWND(), SB_HORZ, &si, FALSE);
+ ::SetScrollInfo(GetHWND(), SB_VERT, &si, FALSE);
+}
+
+LRESULT WebContentsViewWin::OnNCCalcSize(BOOL w_param, LPARAM l_param) {
+ // Hack for thinkpad mouse wheel driver. We have set the fake scroll bars
+ // to receive scroll messages from thinkpad touchpad driver. Suppress
+ // painting of scrollbars by returning 0 size for them.
+ return 0;
+}
+
+void WebContentsViewWin::OnNCPaint(HRGN rgn) {
+ // Suppress default WM_NCPAINT handling. We don't need to do anything
+ // here since the view will draw everything correctly.
+}
+
+void WebContentsViewWin::ScrollCommon(UINT message, int scroll_type, short position,
+ HWND scrollbar) {
+ // This window can receive scroll events as a result of the ThinkPad's
+ // Trackpad scroll wheel emulation.
+ if (!ScrollZoom(scroll_type)) {
+ // Reflect scroll message to the view() to give it a chance
+ // to process scrolling.
+ SendMessage(GetContentHWND(), message, MAKELONG(scroll_type, position),
+ (LPARAM) scrollbar);
+ }
+}
+
+bool WebContentsViewWin::ScrollZoom(int scroll_type) {
+ // If ctrl is held, zoom the UI. There are three issues with this:
+ // 1) Should the event be eaten or forwarded to content? We eat the event,
+ // which is like Firefox and unlike IE.
+ // 2) Should wheel up zoom in or out? We zoom in (increase font size), which
+ // is like IE and Google maps, but unlike Firefox.
+ // 3) Should the mouse have to be over the content area? We zoom as long as
+ // content has focus, although FF and IE require that the mouse is over
+ // content. This is because all events get forwarded when content has
+ // focus.
+ if (GetAsyncKeyState(VK_CONTROL) & 0x8000) {
+ int distance = 0;
+ switch (scroll_type) {
+ case SB_LINEUP:
+ distance = WHEEL_DELTA;
+ break;
+ case SB_LINEDOWN:
+ distance = -WHEEL_DELTA;
+ break;
+ // TODO(joshia): Handle SB_PAGEUP, SB_PAGEDOWN, SB_THUMBPOSITION,
+ // and SB_THUMBTRACK for completeness
+ default:
+ break;
+ }
+
+ WheelZoom(distance);
+ return true;
+ }
+ return false;
+}
+
+void WebContentsViewWin::WheelZoom(int distance) {
+ if (web_contents_->delegate()) {
+ bool zoom_in = distance > 0;
+ web_contents_->delegate()->ContentsZoomChange(zoom_in);
+ }
+}
+
diff --git a/chrome/browser/web_contents_view_win.h b/chrome/browser/web_contents_view_win.h
new file mode 100644
index 0000000..09e80ff
--- /dev/null
+++ b/chrome/browser/web_contents_view_win.h
@@ -0,0 +1,86 @@
+// 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_WEB_CONTENTS_VIEW_WIN_H_
+#define CHROME_BROWSER_WEB_CONTENTS_VIEW_WIN_H_
+
+#include "chrome/browser/web_contents_view.h"
+#include "chrome/views/hwnd_view_container.h"
+
+struct WebDropData;
+class WebDropTarget;
+
+// Windows-specific implementation of the WebContentsView. It is a HWND that
+// contains all of the contents of the tab and associated child views.
+class WebContentsViewWin : public WebContentsView,
+ public ChromeViews::HWNDViewContainer {
+ public:
+ // The corresponding WebContents is passed in the constructor, and manages our
+ // lifetime. This doesn't need to be the case, but is this way currently
+ // because that's what was easiest when they were split.
+ explicit WebContentsViewWin(WebContents* web_contents);
+ virtual ~WebContentsViewWin();
+
+ // WebContentsView implementation --------------------------------------------
+
+ // TODO(brettw) what on earth is the difference between this and
+ // CreatePageView. Do we really need both?
+ virtual void CreateView(HWND parent_hwnd,
+ const gfx::Rect& initial_bounds);
+ virtual RenderWidgetHostHWND* CreatePageView(
+ RenderViewHost* render_view_host);
+ virtual HWND GetContainerHWND() const;
+ virtual HWND GetContentHWND() const;
+ virtual void GetContainerBounds(gfx::Rect* out) const;
+ virtual void StartDragging(const WebDropData& drop_data);
+ virtual void DetachPluginWindows();
+ virtual void SetInfoBarVisible(bool visible);
+ virtual bool IsInfoBarVisible() const;
+ virtual InfoBarView* GetInfoBarView();
+ virtual void UpdateDragCursor(bool is_drop_target);
+
+ private:
+ // Windows events ------------------------------------------------------------
+
+ // Overrides from HWNDViewContainer.
+ virtual void OnDestroy();
+ virtual void OnHScroll(int scroll_type, short position, HWND scrollbar);
+ virtual void OnMouseLeave();
+ virtual LRESULT OnMouseRange(UINT msg, WPARAM w_param, LPARAM l_param);
+ virtual void OnPaint(HDC junk_dc);
+ virtual LRESULT OnReflectedMessage(UINT msg, WPARAM w_param, LPARAM l_param);
+ virtual void OnSetFocus(HWND window);
+ virtual void OnVScroll(int scroll_type, short position, HWND scrollbar);
+ virtual void OnWindowPosChanged(WINDOWPOS* window_pos);
+ virtual void OnSize(UINT param, const CSize& size);
+ virtual LRESULT OnNCCalcSize(BOOL w_param, LPARAM l_param);
+ virtual void OnNCPaint(HRGN rgn);
+
+ // Backend for all scroll messages, the |message| parameter indicates which
+ // one it is.
+ void ScrollCommon(UINT message, int scroll_type, short position,
+ HWND scrollbar);
+
+ // TODO(brettw) comment these. They're confusing.
+ bool ScrollZoom(int scroll_type);
+ void WheelZoom(int distance);
+
+ // ---------------------------------------------------------------------------
+
+ // TODO(brettw) when this class is separated from WebContents, we should own
+ WebContents* web_contents_;
+
+ // A drop target object that handles drags over this WebContents.
+ scoped_refptr<WebDropTarget> drop_target_;
+
+ // InfoBarView, lazily created.
+ scoped_ptr<InfoBarView> info_bar_view_;
+
+ // Whether the info bar view is visible.
+ bool info_bar_visible_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebContentsViewWin);
+};
+
+#endif // CHROME_BROWSER_WEB_CONTENTS_VIEW_WIN_H_