summaryrefslogtreecommitdiffstats
path: root/chrome/browser/render_widget_host_hwnd.cc
diff options
context:
space:
mode:
authorbrettw@google.com <brettw@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-10-14 22:56:54 +0000
committerbrettw@google.com <brettw@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-10-14 22:56:54 +0000
commite80eb5d77db328a9270a0c8caac467ab2345b914 (patch)
tree76aa032117b6d55c2c5a3e974f84aadb2dc7e4fa /chrome/browser/render_widget_host_hwnd.cc
parentddece899b99061860b28399b91dd6545d15ceecf (diff)
downloadchromium_src-e80eb5d77db328a9270a0c8caac467ab2345b914.zip
chromium_src-e80eb5d77db328a9270a0c8caac467ab2345b914.tar.gz
chromium_src-e80eb5d77db328a9270a0c8caac467ab2345b914.tar.bz2
Rename RenderWidgetHostHWND to RenderWidgetHostViewWin for consistency with other view-related classes.
No logic change. Review URL: http://codereview.chromium.org/7310 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@3379 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/render_widget_host_hwnd.cc')
-rw-r--r--chrome/browser/render_widget_host_hwnd.cc875
1 files changed, 0 insertions, 875 deletions
diff --git a/chrome/browser/render_widget_host_hwnd.cc b/chrome/browser/render_widget_host_hwnd.cc
deleted file mode 100644
index bc49e62..0000000
--- a/chrome/browser/render_widget_host_hwnd.cc
+++ /dev/null
@@ -1,875 +0,0 @@
-// 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/render_widget_host_hwnd.h"
-
-#include "base/command_line.h"
-#include "base/gfx/gdi_util.h"
-#include "base/gfx/rect.h"
-#include "base/histogram.h"
-#include "base/win_util.h"
-#include "chrome/browser/browser_accessibility.h"
-#include "chrome/browser/browser_accessibility_manager.h"
-#include "chrome/browser/render_process_host.h"
-// TODO(beng): (Cleanup) we should not need to include this file... see comment
-// in |DidBecomeSelected|.
-#include "chrome/browser/render_view_host.h"
-#include "chrome/browser/render_widget_host.h"
-#include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_switches.h"
-#include "chrome/common/l10n_util.h"
-#include "chrome/common/plugin_messages.h"
-#include "chrome/common/win_util.h"
-#include "chrome/views/hwnd_view_container.h"
-#include "webkit/glue/webcursor.h"
-
-// Tooltips will wrap after this width. Yes, wrap. Imagine that!
-static const int kTooltipMaxWidthPixels = 300;
-
-// Maximum number of characters we allow in a tooltip.
-static const int kMaxTooltipLength = 1024;
-
-///////////////////////////////////////////////////////////////////////////////
-// RenderWidgetHostHWND, public:
-
-RenderWidgetHostHWND::RenderWidgetHostHWND(
- RenderWidgetHost* render_widget_host)
- : RenderWidgetHostView(),
- render_widget_host_(render_widget_host),
- real_cursor_(LoadCursor(NULL, IDC_ARROW)),
- real_cursor_type_(WebCursor::ARROW),
- track_mouse_leave_(false),
- ime_notification_(false),
- is_hidden_(false),
- close_on_deactivate_(false),
- tooltip_hwnd_(NULL),
- tooltip_showing_(false),
- shutdown_factory_(this),
- parent_hwnd_(NULL),
- is_loading_(false) {
-}
-
-RenderWidgetHostHWND::~RenderWidgetHostHWND() {
- if (real_cursor_type_ == WebCursor::CUSTOM)
- DestroyIcon(real_cursor_);
- ResetTooltip();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// RenderWidgetHostHWND, RenderWidgetHostView implementation:
-
-void RenderWidgetHostHWND::DidBecomeSelected() {
- if (!is_hidden_)
- return;
-
- is_hidden_ = false;
- EnsureTooltip();
- render_widget_host_->WasRestored();
-}
-
-void RenderWidgetHostHWND::WasHidden() {
- if (is_hidden_)
- return;
-
- // If we receive any more paint messages while we are hidden, we want to
- // ignore them so we don't re-allocate the backing store. We will paint
- // everything again when we become selected again.
- is_hidden_ = true;
-
- ResetTooltip();
-
- // If we have a renderer, then inform it that we are being hidden so it can
- // reduce its resource utilization.
- render_widget_host_->WasHidden();
-
- // TODO(darin): what about constrained windows? it doesn't look like they
- // see a message when their parent is hidden. maybe there is something more
- // generic we can do at the TabContents API level instead of relying on
- // Windows messages.
-}
-
-void RenderWidgetHostHWND::SetSize(const gfx::Size& size) {
- if (is_hidden_)
- return;
-
- UINT swp_flags = SWP_NOSENDCHANGING | SWP_NOOWNERZORDER | SWP_NOCOPYBITS |
- SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE |
- SWP_DEFERERASE;
- SetWindowPos(NULL, 0, 0, size.width(), size.height(), swp_flags);
- render_widget_host_->WasResized();
- EnsureTooltip();
-}
-
-HWND RenderWidgetHostHWND::GetPluginHWND() {
- return m_hWnd;
-}
-
-void RenderWidgetHostHWND::ForwardMouseEventToRenderer(UINT message,
- WPARAM wparam,
- LPARAM lparam) {
- WebMouseEvent event(m_hWnd, message, wparam, lparam);
- switch (event.type) {
- case WebInputEvent::MOUSE_MOVE:
- TrackMouseLeave(true);
- break;
- case WebInputEvent::MOUSE_LEAVE:
- TrackMouseLeave(false);
- break;
- case WebInputEvent::MOUSE_DOWN:
- SetCapture();
- break;
- case WebInputEvent::MOUSE_UP:
- if (GetCapture() == m_hWnd)
- ReleaseCapture();
- break;
- }
-
- render_widget_host_->ForwardMouseEvent(event);
-
- if (event.type == WebInputEvent::MOUSE_DOWN) {
- // This is a temporary workaround for bug 765011 to get focus when the
- // mouse is clicked. This happens after the mouse down event is sent to
- // the renderer because normally Windows does a WM_SETFOCUS after
- // WM_LBUTTONDOWN.
- SetFocus();
- }
-}
-
-void RenderWidgetHostHWND::Focus() {
- if (IsWindow())
- SetFocus();
-}
-
-void RenderWidgetHostHWND::Blur() {
- ChromeViews::FocusManager* focus_manager =
- ChromeViews::FocusManager::GetFocusManager(GetParent());
- // We don't have a FocusManager if we are hidden.
- if (focus_manager && render_widget_host_->CanBlur())
- focus_manager->ClearFocus();
-}
-
-bool RenderWidgetHostHWND::HasFocus() {
- return ::GetFocus() == m_hWnd;
-}
-
-void RenderWidgetHostHWND::Show() {
- DCHECK(parent_hwnd_);
- SetParent(parent_hwnd_);
- ShowWindow(SW_SHOW);
-
- DidBecomeSelected();
-}
-
-void RenderWidgetHostHWND::Hide() {
- if (::GetFocus() == m_hWnd)
- ::SetFocus(NULL);
- ShowWindow(SW_HIDE);
- parent_hwnd_ = GetParent();
- // Orphan the window so we stop receiving messages.
- SetParent(NULL);
-
- WasHidden();
-}
-
-gfx::Rect RenderWidgetHostHWND::GetViewBounds() const {
- CRect window_rect;
- GetWindowRect(&window_rect);
- return gfx::Rect(window_rect);
-}
-
-void RenderWidgetHostHWND::UpdateCursor(const WebCursor& cursor) {
- static HINSTANCE module_handle =
- GetModuleHandle(chrome::kBrowserResourcesDll);
-
- // If the last active cursor was a custom cursor, we need to destroy
- // it before setting the new one.
- if (real_cursor_type_ == WebCursor::CUSTOM)
- DestroyIcon(real_cursor_);
-
- real_cursor_type_ = cursor.type();
- if (real_cursor_type_ == cursor.WebCursor::CUSTOM) {
- real_cursor_ = cursor.GetCustomCursor();
- } else {
- // We cannot pass in NULL as the module handle as this would only
- // work for standard win32 cursors. We can also receive cursor
- // types which are defined as webkit resources. We need to specify
- // the module handle of chrome.dll while loading these cursors.
- real_cursor_ = cursor.GetCursor(module_handle);
- }
-
- UpdateCursorIfOverSelf();
-}
-
-void RenderWidgetHostHWND::UpdateCursorIfOverSelf() {
- static HINSTANCE module_handle =
- GetModuleHandle(chrome::kBrowserResourcesDll);
-
- HCURSOR display_cursor = real_cursor_;
- // If a page is in the loading state, we want to show the Arrow+Hourglass
- // cursor only when the current cursor is the ARROW cursor. In all other
- // cases we should continue to display the current cursor.
- if (is_loading_ && (real_cursor_type_ == WebCursor::ARROW)) {
- WebCursor page_loading_cursor(WebCursor::APPSTARTING);
- display_cursor = page_loading_cursor.GetCursor(module_handle);
- }
-
- // If the mouse is over our HWND, then update the cursor state immediately.
- CPoint pt;
- GetCursorPos(&pt);
- if (WindowFromPoint(pt) == m_hWnd)
- SetCursor(display_cursor);
-}
-
-void RenderWidgetHostHWND::SetIsLoading(bool is_loading) {
- is_loading_ = is_loading;
- UpdateCursorIfOverSelf();
-}
-
-void RenderWidgetHostHWND::IMEUpdateStatus(ViewHostMsg_ImeControl control,
- int x, int y) {
- if (control == IME_DISABLE) {
- ime_input_.DisableIME(m_hWnd);
- } else {
- ime_input_.EnableIME(m_hWnd, x, y, control == IME_COMPLETE_COMPOSITION);
- }
-}
-
-void RenderWidgetHostHWND::DidPaintRect(const gfx::Rect& rect) {
- if (is_hidden_)
- return;
-
- RECT invalid_rect = rect.ToRECT();
-
- // Paint the invalid region synchronously. Our caller will not paint again
- // until we return, so by painting to the screen here, we ensure effective
- // rate-limiting of backing store updates. This helps a lot on pages that
- // have animations or fairly expensive layout (e.g., google maps).
- //
- // Please refer to the RenderWidgetHostHWND::DidScrollRect function for the
- // reasoning behind the combination of flags passed to RedrawWindow.
- //
- RedrawWindow(&invalid_rect, NULL,
- RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN | RDW_FRAME);
-}
-
-void RenderWidgetHostHWND::DidScrollRect(
- const gfx::Rect& rect, int dx, int dy) {
- if (is_hidden_)
- return;
-
- // We need to pass in SW_INVALIDATE to ScrollWindowEx. The MSDN
- // documentation states that it only applies to the HRGN argument, which is
- // wrong. Not passing in this flag does not invalidate the region which was
- // scrolled from, thus causing painting issues.
- RECT clip_rect = rect.ToRECT();
- ScrollWindowEx(dx, dy, NULL, &clip_rect, NULL, NULL, SW_INVALIDATE);
-
- RECT invalid_rect = {0};
- GetUpdateRect(&invalid_rect);
-
- // Paint the invalid region synchronously. Our caller will not paint again
- // until we return, so by painting to the screen here, we ensure effective
- // rate-limiting of backing store updates. This helps a lot on pages that
- // have animations or fairly expensive layout (e.g., google maps).
- //
- // Our RenderWidgetHostHWND does not have a non-client area, whereas the
- // children (plugin windows) may. If we don't pass in RDW_FRAME then the
- // children don't receive WM_NCPAINT messages while scrolling, which causes
- // painting problems (http://b/issue?id=923945). We need to pass
- // RDW_INVALIDATE as it is required for RDW_FRAME to work.
- //
- RedrawWindow(&invalid_rect, NULL,
- RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN | RDW_FRAME);
-}
-
-void RenderWidgetHostHWND::RendererGone() {
- // TODO(darin): keep this around, and draw sad-tab into it.
- UpdateCursorIfOverSelf();
- DestroyWindow();
-}
-
-void RenderWidgetHostHWND::Destroy() {
- // We've been told to destroy.
- // By clearing close_on_deactivate_, we prevent further deactivations
- // (caused by windows messages resulting from the DestroyWindow) from
- // triggering further destructions. The deletion of this is handled by
- // OnFinalMessage();
- close_on_deactivate_ = false;
- DestroyWindow();
-}
-
-void RenderWidgetHostHWND::SetTooltipText(const std::wstring& tooltip_text) {
- if (tooltip_text != tooltip_text_) {
- tooltip_text_ = tooltip_text;
-
- // Clamp the tooltip length to kMaxTooltipLength so that we don't
- // accidentally DOS the user with a mega tooltip (since Windows doesn't seem
- // to do this itself).
- if (tooltip_text_.length() > kMaxTooltipLength)
- tooltip_text_ = tooltip_text_.substr(0, kMaxTooltipLength);
-
- // Need to check if the tooltip is already showing so that we don't
- // immediately show the tooltip with no delay when we move the mouse from
- // a region with no tooltip to a region with a tooltip.
- if (::IsWindow(tooltip_hwnd_) && tooltip_showing_) {
- ::SendMessage(tooltip_hwnd_, TTM_POP, 0, 0);
- ::SendMessage(tooltip_hwnd_, TTM_POPUP, 0, 0);
- }
- } else {
- // Make sure the tooltip gets closed after TTN_POP gets sent. For some
- // reason this doesn't happen automatically, so moving the mouse around
- // within the same link/image/etc doesn't cause the tooltip to re-appear.
- if (!tooltip_showing_) {
- if (::IsWindow(tooltip_hwnd_))
- ::SendMessage(tooltip_hwnd_, TTM_POP, 0, 0);
- }
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// RenderWidgetHostHWND, private:
-
-LRESULT RenderWidgetHostHWND::OnCreate(CREATESTRUCT* create_struct) {
- // Call the WM_INPUTLANGCHANGE message handler to initialize the input locale
- // of a browser process.
- OnInputLangChange(0, 0);
- return 0;
-}
-
-void RenderWidgetHostHWND::OnActivate(UINT action, BOOL minimized,
- HWND window) {
- // If the container is a popup, clicking elsewhere on screen should close the
- // popup.
- if (close_on_deactivate_ && action == WA_INACTIVE) {
- // Send a windows message so that any derived classes
- // will get a change to override the default handling
- SendMessage(WM_CANCELMODE);
- }
-}
-
-void RenderWidgetHostHWND::OnDestroy() {
- ResetTooltip();
- TrackMouseLeave(false);
-}
-
-void RenderWidgetHostHWND::OnPaint(HDC dc) {
- DCHECK(render_widget_host_->process()->channel());
-
- CPaintDC paint_dc(m_hWnd);
- HBRUSH white_brush = reinterpret_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));
-
- RenderWidgetHost::BackingStore* backing_store =
- render_widget_host_->GetBackingStore();
-
- if (backing_store) {
- gfx::Rect damaged_rect(paint_dc.m_ps.rcPaint);
-
- gfx::Rect bitmap_rect(
- 0, 0, backing_store->size().width(), backing_store->size().height());
-
- gfx::Rect paint_rect = bitmap_rect.Intersect(damaged_rect);
- if (!paint_rect.IsEmpty()) {
- BitBlt(paint_dc.m_hDC,
- paint_rect.x(),
- paint_rect.y(),
- paint_rect.width(),
- paint_rect.height(),
- backing_store->dc(),
- paint_rect.x(),
- paint_rect.y(),
- SRCCOPY);
- }
-
- // Fill the remaining portion of the damaged_rect with white
- if (damaged_rect.right() > bitmap_rect.right()) {
- RECT r;
- r.left = std::max(bitmap_rect.right(), damaged_rect.x());
- r.right = damaged_rect.right();
- r.top = damaged_rect.y();
- r.bottom = std::min(bitmap_rect.bottom(), damaged_rect.bottom());
- paint_dc.FillRect(&r, white_brush);
- }
- if (damaged_rect.bottom() > bitmap_rect.bottom()) {
- RECT r;
- r.left = damaged_rect.x();
- r.right = damaged_rect.right();
- r.top = std::max(bitmap_rect.bottom(), damaged_rect.y());
- r.bottom = damaged_rect.bottom();
- paint_dc.FillRect(&r, white_brush);
- }
- if (!whiteout_start_time_.is_null()) {
- TimeDelta whiteout_duration = TimeTicks::Now() - whiteout_start_time_;
- UMA_HISTOGRAM_TIMES(L"MPArch.RWHH_WhiteoutDuration", whiteout_duration);
- // Reset the start time to 0 so that we start recording again the next
- // time the backing store is NULL...
- whiteout_start_time_ = TimeTicks();
- }
- } else {
- paint_dc.FillRect(&paint_dc.m_ps.rcPaint, white_brush);
- if (whiteout_start_time_.is_null())
- whiteout_start_time_ = TimeTicks::Now();
- }
-}
-
-void RenderWidgetHostHWND::OnNCPaint(HRGN update_region) {
- // Do nothing. This suppresses the resize corner that Windows would
- // otherwise draw for us.
-}
-
-LRESULT RenderWidgetHostHWND::OnEraseBkgnd(HDC dc) {
- return 1;
-}
-
-LRESULT RenderWidgetHostHWND::OnSetCursor(HWND window, UINT hittest_code,
- UINT mouse_message_id) {
- UpdateCursorIfOverSelf();
- return 0;
-}
-
-void RenderWidgetHostHWND::OnSetFocus(HWND window) {
- render_widget_host_->Focus();
-}
-
-void RenderWidgetHostHWND::OnKillFocus(HWND window) {
- render_widget_host_->Blur();
-}
-
-void RenderWidgetHostHWND::OnCaptureChanged(HWND window) {
- render_widget_host_->LostCapture();
-}
-
-void RenderWidgetHostHWND::OnCancelMode() {
- render_widget_host_->LostCapture();
-
- if (close_on_deactivate_ && shutdown_factory_.empty()) {
- // Dismiss popups and menus. We do this asynchronously to avoid changing
- // activation within this callstack, which may interfere with another window
- // being activated. We can synchronously hide the window, but we need to
- // not change activation while doing so.
- SetWindowPos(NULL, 0, 0, 0, 0,
- SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOMOVE |
- SWP_NOREPOSITION | SWP_NOSIZE | SWP_NOZORDER);
- MessageLoop::current()->PostTask(FROM_HERE,
- shutdown_factory_.NewRunnableMethod(
- &RenderWidgetHostHWND::ShutdownHost));
- }
-}
-
-void RenderWidgetHostHWND::OnInputLangChange(DWORD character_set,
- HKL input_language_id) {
- // Send the given Locale ID to the ImeInput object and retrieves whether
- // or not the current input context has IMEs.
- // If the current input context has IMEs, a browser process has to send a
- // request to a renderer process that it needs status messages about
- // the focused edit control from the renderer process.
- // On the other hand, if the current input context does not have IMEs, the
- // browser process also has to send a request to the renderer process that
- // it does not need the status messages any longer.
- // To minimize the number of this notification request, we should check if
- // the browser process is actually retrieving the status messages (this
- // state is stored in ime_notification_) and send a request only if the
- // browser process has to update this status, its details are listed below:
- // * If a browser process is not retrieving the status messages,
- // (i.e. ime_notification_ == false),
- // send this request only if the input context does have IMEs,
- // (i.e. ime_status == true);
- // When it successfully sends the request, toggle its notification status,
- // (i.e.ime_notification_ = !ime_notification_ = true).
- // * If a browser process is retrieving the status messages
- // (i.e. ime_notification_ == true),
- // send this request only if the input context does not have IMEs,
- // (i.e. ime_status == false).
- // When it successfully sends the request, toggle its notification status,
- // (i.e.ime_notification_ = !ime_notification_ = false).
- // To analyze the above actions, we can optimize them into the ones
- // listed below:
- // 1 Sending a request only if ime_status_ != ime_notification_, and;
- // 2 Copying ime_status to ime_notification_ if it sends the request
- // successfully (because Action 1 shows ime_status = !ime_notification_.)
- bool ime_status = ime_input_.SetInputLanguage();
- if (ime_status != ime_notification_) {
- if (Send(new ViewMsg_ImeSetInputMode(render_widget_host_->routing_id(),
- ime_status))) {
- ime_notification_ = ime_status;
- }
- }
-}
-
-void RenderWidgetHostHWND::OnThemeChanged() {
- render_widget_host_->SystemThemeChanged();
-}
-
-LRESULT RenderWidgetHostHWND::OnNotify(int w_param, NMHDR* header) {
- if (tooltip_hwnd_ == NULL)
- return 0;
-
- switch (header->code) {
- case TTN_GETDISPINFO: {
- NMTTDISPINFOW* tooltip_info = reinterpret_cast<NMTTDISPINFOW*>(header);
- tooltip_info->szText[0] = L'\0';
- tooltip_info->lpszText = const_cast<wchar_t*>(tooltip_text_.c_str());
- ::SendMessage(
- tooltip_hwnd_, TTM_SETMAXTIPWIDTH, 0, kTooltipMaxWidthPixels);
- SetMsgHandled(TRUE);
- break;
- }
- case TTN_POP:
- tooltip_showing_ = false;
- SetMsgHandled(TRUE);
- break;
- case TTN_SHOW:
- tooltip_showing_ = true;
- SetMsgHandled(TRUE);
- break;
- }
- return 0;
-}
-
-LRESULT RenderWidgetHostHWND::OnImeSetContext(
- UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled) {
- // We need status messages about the focused input control from a
- // renderer process when:
- // * the current input context has IMEs, and;
- // * an application is activated.
- // This seems to tell we should also check if the current input context has
- // IMEs before sending a request, however, this WM_IME_SETCONTEXT is
- // fortunately sent to an application only while the input context has IMEs.
- // Therefore, we just start/stop status messages according to the activation
- // status of this application without checks.
- bool activated = (wparam == TRUE);
- if (Send(new ViewMsg_ImeSetInputMode(
- render_widget_host_->routing_id(), activated))) {
- ime_notification_ = activated;
- }
-
- if (ime_notification_)
- ime_input_.CreateImeWindow(m_hWnd);
-
- ime_input_.CleanupComposition(m_hWnd);
- ime_input_.SetImeWindowStyle(m_hWnd, message, wparam, lparam, &handled);
- return 0;
-}
-
-LRESULT RenderWidgetHostHWND::OnImeStartComposition(
- UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled) {
- // Reset the composition status and create IME windows.
- ime_input_.CreateImeWindow(m_hWnd);
- ime_input_.ResetComposition(m_hWnd);
- // We have to prevent WTL from calling ::DefWindowProc() because the function
- // calls ::ImmSetCompositionWindow() and ::ImmSetCandidateWindow() to
- // over-write the position of IME windows.
- handled = TRUE;
- return 0;
-}
-
-LRESULT RenderWidgetHostHWND::OnImeComposition(
- UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled) {
- // At first, update the position of the IME window.
- ime_input_.UpdateImeWindow(m_hWnd);
-
- // Retrieve the result string and its attributes of the ongoing composition
- // and send it to a renderer process.
- ImeComposition composition;
- if (ime_input_.GetResult(m_hWnd, lparam, &composition)) {
- Send(new ViewMsg_ImeSetComposition(render_widget_host_->routing_id(),
- composition.string_type,
- composition.cursor_position,
- composition.target_start,
- composition.target_end,
- composition.ime_string));
- ime_input_.ResetComposition(m_hWnd);
- // Fall though and try reading the composition string.
- // Japanese IMEs send a message containing both GCS_RESULTSTR and
- // GCS_COMPSTR, which means an ongoing composition has been finished
- // by the start of another composition.
- }
- // Retrieve the composition string and its attributes of the ongoing
- // composition and send it to a renderer process.
- if (ime_input_.GetComposition(m_hWnd, lparam, &composition)) {
- Send(new ViewMsg_ImeSetComposition(render_widget_host_->routing_id(),
- composition.string_type,
- composition.cursor_position,
- composition.target_start,
- composition.target_end,
- composition.ime_string));
- }
- // We have to prevent WTL from calling ::DefWindowProc() because we do not
- // want for the IMM (Input Method Manager) to send WM_IME_CHAR messages.
- handled = TRUE;
- return 0;
-}
-
-LRESULT RenderWidgetHostHWND::OnImeEndComposition(
- UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled) {
- if (ime_input_.is_composing()) {
- // A composition has been ended while there is an ongoing composition,
- // i.e. the ongoing composition has been canceled.
- // We need to reset the composition status both of the ImeInput object and
- // of the renderer process.
- std::wstring empty_string;
- Send(new ViewMsg_ImeSetComposition(render_widget_host_->routing_id(),
- 0, -1, -1, -1, empty_string));
- ime_input_.ResetComposition(m_hWnd);
- }
- ime_input_.DestroyImeWindow(m_hWnd);
- // Let WTL call ::DefWindowProc() and release its resources.
- handled = FALSE;
- return 0;
-}
-
-LRESULT RenderWidgetHostHWND::OnMouseEvent(UINT message, WPARAM wparam,
- LPARAM lparam, BOOL& handled) {
- handled = TRUE;
-
- if (::IsWindow(tooltip_hwnd_)) {
- // Forward mouse events through to the tooltip window
- MSG msg;
- msg.hwnd = m_hWnd;
- msg.message = message;
- msg.wParam = wparam;
- msg.lParam = lparam;
- SendMessage(tooltip_hwnd_, TTM_RELAYEVENT, NULL,
- reinterpret_cast<LPARAM>(&msg));
- }
-
- // TODO(jcampan): I am not sure if we should forward the message to the
- // WebContents first in the case of popups. If we do, we would need to
- // convert the click from the popup window coordinates to the WebContents'
- // window coordinates. For now we don't forward the message in that case to
- // address bug #907474.
- // Note: GetParent() on popup windows returns the top window and not the
- // parent the window was created with (the parent and the owner of the popup
- // is the first non-child view of the view that was specified to the create
- // call). So the WebContents window would have to be specified to the
- // RenderViewHostHWND as there is no way to retrieve it from the HWND.
- if (!close_on_deactivate_) { // Don't forward if the container is a popup.
- switch (message) {
- case WM_LBUTTONDOWN:
- case WM_MBUTTONDOWN:
- case WM_MOUSEMOVE:
- case WM_MOUSELEAVE:
- case WM_RBUTTONDOWN: {
- // Give the WebContents first crack at the message. It may want to
- // prevent forwarding to the renderer if some higher level browser
- // functionality is invoked.
- if (SendMessage(GetParent(), message, wparam, lparam) != 0)
- return 1;
- }
- }
- }
-
- ForwardMouseEventToRenderer(message, wparam, lparam);
- return 0;
-}
-
-LRESULT RenderWidgetHostHWND::OnKeyEvent(UINT message, WPARAM wparam,
- LPARAM lparam, BOOL& handled) {
- handled = TRUE;
-
- // If we are a pop-up, forward tab related messages to our parent HWND, so
- // that we are dismissed appropriately and so that the focus advance in our
- // parent.
- // TODO(jcampan): http://b/issue?id=1192881 Could be abstracted in the
- // FocusManager.
- if (close_on_deactivate_ &&
- (((message == WM_KEYDOWN || message == WM_KEYUP) && (wparam == VK_TAB)) ||
- (message == WM_CHAR && wparam == L'\t'))) {
- DCHECK(parent_hwnd_);
- // First close the pop-up.
- SendMessage(WM_CANCELMODE);
- // Then move the focus by forwarding the tab key to the parent.
- return ::SendMessage(parent_hwnd_, message, wparam, lparam);
- }
-
- render_widget_host_->ForwardKeyboardEvent(
- WebKeyboardEvent(m_hWnd, message, wparam, lparam));
- return 0;
-}
-
-LRESULT RenderWidgetHostHWND::OnWheelEvent(UINT message, WPARAM wparam,
- LPARAM lparam, BOOL& handled) {
- // Workaround for Thinkpad mousewheel driver. We get mouse wheel/scroll
- // messages even if we are not in the foreground. So here we check if
- // we have any owned popup windows in the foreground and dismiss them.
- if (m_hWnd != GetForegroundWindow()) {
- HWND toplevel_hwnd = ::GetAncestor(m_hWnd, GA_ROOT);
- EnumThreadWindows(
- GetCurrentThreadId(),
- DismissOwnedPopups,
- reinterpret_cast<LPARAM>(toplevel_hwnd));
- }
-
- // This is a bit of a hack, but will work for now since we don't want to
- // pollute this object with WebContents-specific functionality...
- bool handled_by_webcontents = false;
- if (GetParent()) {
- // Use a special reflected message to break recursion. If we send
- // WM_MOUSEWHEEL, the focus manager subclass of web contents will
- // route it back here.
- MSG new_message = {0};
- new_message.hwnd = m_hWnd;
- new_message.message = message;
- new_message.wParam = wparam;
- new_message.lParam = lparam;
-
- handled_by_webcontents =
- !!::SendMessage(GetParent(), ChromeViews::kReflectedMessage, 0,
- reinterpret_cast<LPARAM>(&new_message));
- }
-
- if (!handled_by_webcontents) {
- render_widget_host_->ForwardWheelEvent(
- WebMouseWheelEvent(m_hWnd, message, wparam, lparam));
- }
- handled = TRUE;
- return 0;
-}
-
-LRESULT RenderWidgetHostHWND::OnMouseActivate(UINT, WPARAM, LPARAM,
- BOOL& handled) {
- // We handle WM_MOUSEACTIVATE to set focus to the underlying plugin
- // child window. This is to ensure that keyboard events are received
- // by the plugin. The correct way to fix this would be send over
- // an event to the renderer which would then eventually send over
- // a setFocus call to the plugin widget. This would ensure that
- // the renderer (webkit) knows about the plugin widget receiving
- // focus.
- // TODO(iyengar) Do the right thing as per the above comment.
- POINT cursor_pos = {0};
- ::GetCursorPos(&cursor_pos);
- MapWindowPoints(m_hWnd, &cursor_pos, 1);
- HWND child_window = ::RealChildWindowFromPoint(m_hWnd, cursor_pos);
- if (::IsWindow(child_window)) {
- ::SetFocus(child_window);
- return MA_NOACTIVATE;
- } else {
- handled = FALSE;
- return MA_ACTIVATE;
- }
-}
-
-LRESULT RenderWidgetHostHWND::OnGetObject(UINT message, WPARAM wparam,
- LPARAM lparam, BOOL& handled) {
- LRESULT reference_result = static_cast<LRESULT>(0L);
-
- // Accessibility readers will send an OBJID_CLIENT message.
- if (OBJID_CLIENT == lparam) {
- // If our MSAA DOM root is already created, reuse that pointer. Otherwise,
- // create a new one.
- if (!browser_accessibility_root_) {
- CComObject<BrowserAccessibility>* accessibility = NULL;
-
- if (!SUCCEEDED(CComObject<BrowserAccessibility>::CreateInstance(
- &accessibility)) || !accessibility) {
- // Return with failure.
- return static_cast<LRESULT>(0L);
- }
-
- CComPtr<IAccessible> accessibility_comptr(accessibility);
-
- // Root id is always 0, to distinguish this particular instance when
- // mapping to the render-side IAccessible.
- accessibility->set_iaccessible_id(0);
-
- // Set the unique member variables of this particular process.
- accessibility->set_instance_id(
- BrowserAccessibilityManager::GetInstance()->
- SetMembers(accessibility, m_hWnd, render_widget_host_));
-
- // All is well, assign the temp instance to the class smart pointer.
- browser_accessibility_root_.Attach(accessibility_comptr.Detach());
-
- if (!browser_accessibility_root_) {
- // Paranoia check. Return with failure.
- NOTREACHED();
- return static_cast<LRESULT>(0L);
- }
-
- // Notify that an instance of IAccessible was allocated for m_hWnd.
- ::NotifyWinEvent(EVENT_OBJECT_CREATE, m_hWnd, OBJID_CLIENT,
- CHILDID_SELF);
- }
-
- // Create a reference to ViewAccessibility that MSAA will marshall
- // to the client.
- reference_result = LresultFromObject(IID_IAccessible, wparam,
- static_cast<IAccessible*>(browser_accessibility_root_));
- }
- return reference_result;
-}
-
-void RenderWidgetHostHWND::OnFinalMessage(HWND window) {
- render_widget_host_->ViewDestroyed();
- delete this;
-}
-
-void RenderWidgetHostHWND::TrackMouseLeave(bool track) {
- if (track == track_mouse_leave_)
- return;
- track_mouse_leave_ = track;
-
- DCHECK(m_hWnd);
-
- TRACKMOUSEEVENT tme;
- tme.cbSize = sizeof(TRACKMOUSEEVENT);
- tme.dwFlags = TME_LEAVE;
- if (!track_mouse_leave_)
- tme.dwFlags |= TME_CANCEL;
- tme.hwndTrack = m_hWnd;
-
- TrackMouseEvent(&tme);
-}
-
-bool RenderWidgetHostHWND::Send(IPC::Message* message) {
- return render_widget_host_->Send(message);
-}
-
-void RenderWidgetHostHWND::EnsureTooltip() {
- UINT message = TTM_NEWTOOLRECT;
-
- TOOLINFO ti;
- ti.cbSize = sizeof(ti);
- ti.hwnd = m_hWnd;
- ti.uId = 0;
- if (!::IsWindow(tooltip_hwnd_)) {
- message = TTM_ADDTOOL;
- tooltip_hwnd_ = CreateWindowEx(
- WS_EX_TRANSPARENT | l10n_util::GetExtendedTooltipStyles(),
- TOOLTIPS_CLASS, NULL, TTS_NOPREFIX, 0, 0, 0, 0, m_hWnd, NULL,
- NULL, NULL);
- ti.uFlags = TTF_TRANSPARENT;
- ti.lpszText = LPSTR_TEXTCALLBACK;
- }
-
- CRect cr;
- GetClientRect(&ti.rect);
- SendMessage(tooltip_hwnd_, message, NULL, reinterpret_cast<LPARAM>(&ti));
-}
-
-void RenderWidgetHostHWND::ResetTooltip() {
- if (::IsWindow(tooltip_hwnd_))
- ::DestroyWindow(tooltip_hwnd_);
- tooltip_hwnd_ = NULL;
-}
-
-BOOL CALLBACK RenderWidgetHostHWND::DismissOwnedPopups(HWND window,
- LPARAM arg) {
- const HWND toplevel_hwnd = reinterpret_cast<HWND>(arg);
-
- if (::IsWindowVisible(window)) {
- const HWND owner = ::GetWindow(window, GW_OWNER);
- if (toplevel_hwnd == owner) {
- ::PostMessage(window, WM_CANCELMODE, 0, 0);
- }
- }
-
- return TRUE;
-}
-
-void RenderWidgetHostHWND::ShutdownHost() {
- shutdown_factory_.RevokeAll();
- render_widget_host_->Shutdown();
- // Do not touch any members at this point, |this| has been deleted.
-}
-