diff options
author | brettw@google.com <brettw@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-10 20:34:35 +0000 |
---|---|---|
committer | brettw@google.com <brettw@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-10 20:34:35 +0000 |
commit | c80c563f3f32e49ce0087d899accf6a77de09ba6 (patch) | |
tree | 17f56be64796b691c7d323e08120acdac0e43d9f /chrome | |
parent | b5108d1892eeb184b2679ce0658f5fe708e22016 (diff) | |
download | chromium_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.vcproj | 12 | ||||
-rw-r--r-- | chrome/browser/dom_ui/new_tab_ui.cc | 2 | ||||
-rw-r--r-- | chrome/browser/jsmessage_box_handler.cc | 2 | ||||
-rw-r--r-- | chrome/browser/tab_contents.cc | 2 | ||||
-rw-r--r-- | chrome/browser/views/dom_view.cc | 1 | ||||
-rw-r--r-- | chrome/browser/views/tab_contents_container_view.cc | 1 | ||||
-rw-r--r-- | chrome/browser/web_contents.cc | 390 | ||||
-rw-r--r-- | chrome/browser/web_contents.h | 82 | ||||
-rw-r--r-- | chrome/browser/web_contents_view.h | 84 | ||||
-rw-r--r-- | chrome/browser/web_contents_view_win.cc | 351 | ||||
-rw-r--r-- | chrome/browser/web_contents_view_win.h | 86 |
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_ |