2
* Copyright (C) 2010 Apple Inc. All rights reserved.
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
7
* 1. Redistributions of source code must retain the above copyright
8
* notice, this list of conditions and the following disclaimer.
9
* 2. Redistributions in binary form must reproduce the above copyright
10
* notice, this list of conditions and the following disclaimer in the
11
* documentation and/or other materials provided with the distribution.
13
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23
* THE POSSIBILITY OF SUCH DAMAGE.
29
#include "DrawingAreaProxyImpl.h"
30
#include "FindIndicator.h"
32
#include "NativeWebKeyboardEvent.h"
33
#include "NativeWebMouseEvent.h"
34
#include "NativeWebWheelEvent.h"
35
#include "WKAPICast.h"
36
#include "WebContext.h"
37
#include "WebContextMenuProxyWin.h"
38
#include "WebEditCommandProxy.h"
39
#include "WebEventFactory.h"
40
#include "WebPageProxy.h"
41
#include "WebPopupMenuProxyWin.h"
43
#include <WebCore/BitmapInfo.h>
44
#include <WebCore/Cursor.h>
45
#include <WebCore/DragSession.h>
46
#include <WebCore/Editor.h>
47
#include <WebCore/FileSystem.h>
48
#include <WebCore/FloatRect.h>
49
#include <WebCore/HWndDC.h>
50
#include <WebCore/IntRect.h>
51
#include <WebCore/NotImplemented.h>
52
#include <WebCore/Region.h>
53
#include <WebCore/RunLoop.h>
54
#include <WebCore/SoftLinking.h>
55
#include <WebCore/WebCoreInstanceHandle.h>
56
#include <WebCore/WindowMessageBroadcaster.h>
57
#include <WebCore/WindowsTouch.h>
58
#include <wtf/text/StringBuilder.h>
59
#include <wtf/text/WTFString.h>
62
#include "WKCACFViewWindow.h"
63
#include <WebCore/GraphicsContextCG.h>
66
#if ENABLE(FULLSCREEN_API)
67
#include "WebFullScreenManagerProxy.h"
68
#include <WebCore/FullScreenController.h>
72
// We need these functions in a separate namespace, because in the global namespace they conflict
73
// with the definitions in imm.h only by the type modifier (the macro defines them as static) and
74
// imm.h is included by windows.h
75
SOFT_LINK_LIBRARY(IMM32)
76
SOFT_LINK(IMM32, ImmGetContext, HIMC, WINAPI, (HWND hwnd), (hwnd))
77
SOFT_LINK(IMM32, ImmReleaseContext, BOOL, WINAPI, (HWND hWnd, HIMC hIMC), (hWnd, hIMC))
78
SOFT_LINK(IMM32, ImmGetCompositionStringW, LONG, WINAPI, (HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen), (hIMC, dwIndex, lpBuf, dwBufLen))
79
SOFT_LINK(IMM32, ImmSetCandidateWindow, BOOL, WINAPI, (HIMC hIMC, LPCANDIDATEFORM lpCandidate), (hIMC, lpCandidate))
80
SOFT_LINK(IMM32, ImmSetOpenStatus, BOOL, WINAPI, (HIMC hIMC, BOOL fOpen), (hIMC, fOpen))
81
SOFT_LINK(IMM32, ImmNotifyIME, BOOL, WINAPI, (HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue), (hIMC, dwAction, dwIndex, dwValue))
82
SOFT_LINK(IMM32, ImmAssociateContextEx, BOOL, WINAPI, (HWND hWnd, HIMC hIMC, DWORD dwFlags), (hWnd, hIMC, dwFlags))
85
// Soft link functions for gestures and panning.
86
SOFT_LINK_LIBRARY(USER32);
87
SOFT_LINK_OPTIONAL(USER32, GetGestureInfo, BOOL, WINAPI, (HGESTUREINFO, PGESTUREINFO));
88
SOFT_LINK_OPTIONAL(USER32, SetGestureConfig, BOOL, WINAPI, (HWND, DWORD, UINT, PGESTURECONFIG, UINT));
89
SOFT_LINK_OPTIONAL(USER32, CloseGestureInfoHandle, BOOL, WINAPI, (HGESTUREINFO));
91
SOFT_LINK_LIBRARY(Uxtheme);
92
SOFT_LINK_OPTIONAL(Uxtheme, BeginPanningFeedback, BOOL, WINAPI, (HWND));
93
SOFT_LINK_OPTIONAL(Uxtheme, EndPanningFeedback, BOOL, WINAPI, (HWND, BOOL));
94
SOFT_LINK_OPTIONAL(Uxtheme, UpdatePanningFeedback, BOOL, WINAPI, (HWND, LONG, LONG, BOOL));
96
using namespace WebCore;
100
static const LPCWSTR kWebKit2WebViewWindowClassName = L"WebKit2WebViewWindowClass";
102
// Constants not available on all platforms.
103
const int WM_XP_THEMECHANGED = 0x031A;
104
const int WM_VISTA_MOUSEHWHEEL = 0x020E;
106
static const int kMaxToolTipWidth = 250;
109
UpdateActiveStateTimer = 1,
112
LRESULT CALLBACK WebView::WebViewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
114
LONG_PTR longPtr = ::GetWindowLongPtr(hWnd, 0);
116
if (WebView* webView = reinterpret_cast<WebView*>(longPtr))
117
return webView->wndProc(hWnd, message, wParam, lParam);
119
if (message == WM_CREATE) {
120
LPCREATESTRUCT createStruct = reinterpret_cast<LPCREATESTRUCT>(lParam);
122
// Associate the WebView with the window.
123
::SetWindowLongPtr(hWnd, 0, (LONG_PTR)createStruct->lpCreateParams);
127
return ::DefWindowProc(hWnd, message, wParam, lParam);
130
LRESULT WebView::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
140
m_isBeingDestroyed = true;
147
lResult = onPaintEvent(hWnd, message, wParam, lParam, handled);
150
lResult = onPrintClientEvent(hWnd, message, wParam, lParam, handled);
152
case WM_MOUSEACTIVATE:
153
setWasActivatedByMouseEvent(true);
160
case WM_LBUTTONDBLCLK:
161
case WM_MBUTTONDBLCLK:
162
case WM_RBUTTONDBLCLK:
167
lResult = onMouseEvent(hWnd, message, wParam, lParam, handled);
170
case WM_VISTA_MOUSEHWHEEL:
171
lResult = onWheelEvent(hWnd, message, wParam, lParam, handled);
174
lResult = onHorizontalScroll(hWnd, message, wParam, lParam, handled);
177
lResult = onVerticalScroll(hWnd, message, wParam, lParam, handled);
179
case WM_GESTURENOTIFY:
180
lResult = onGestureNotify(hWnd, message, wParam, lParam, handled);
183
lResult = onGesture(hWnd, message, wParam, lParam, handled);
191
lResult = onKeyEvent(hWnd, message, wParam, lParam, handled);
194
lResult = onSizeEvent(hWnd, message, wParam, lParam, handled);
196
case WM_WINDOWPOSCHANGED:
197
lResult = onWindowPositionChangedEvent(hWnd, message, wParam, lParam, handled);
200
lResult = onSetFocusEvent(hWnd, message, wParam, lParam, handled);
203
lResult = onKillFocusEvent(hWnd, message, wParam, lParam, handled);
206
lResult = onTimerEvent(hWnd, message, wParam, lParam, handled);
209
lResult = onShowWindowEvent(hWnd, message, wParam, lParam, handled);
212
lResult = onSetCursor(hWnd, message, wParam, lParam, handled);
214
case WM_IME_STARTCOMPOSITION:
215
handled = onIMEStartComposition();
218
lResult = onIMERequest(wParam, lParam);
220
case WM_IME_COMPOSITION:
221
handled = onIMEComposition(lParam);
223
case WM_IME_ENDCOMPOSITION:
224
handled = onIMEEndComposition();
227
handled = onIMESelect(wParam, lParam);
229
case WM_IME_SETCONTEXT:
230
handled = onIMESetContext(wParam, lParam);
238
lResult = ::DefWindowProc(hWnd, message, wParam, lParam);
243
bool WebView::registerWebViewWindowClass()
245
static bool haveRegisteredWindowClass = false;
246
if (haveRegisteredWindowClass)
248
haveRegisteredWindowClass = true;
252
wcex.cbSize = sizeof(WNDCLASSEX);
253
wcex.style = CS_DBLCLKS;
254
wcex.lpfnWndProc = WebView::WebViewWndProc;
256
wcex.cbWndExtra = sizeof(WebView*);
257
wcex.hInstance = instanceHandle();
259
wcex.hCursor = ::LoadCursor(0, IDC_ARROW);
260
wcex.hbrBackground = 0;
261
wcex.lpszMenuName = 0;
262
wcex.lpszClassName = kWebKit2WebViewWindowClassName;
265
return !!::RegisterClassEx(&wcex);
268
WebView::WebView(RECT rect, WebContext* context, WebPageGroup* pageGroup, HWND parentWindow)
269
: m_topLevelParentWindow(0)
273
, m_overrideCursor(0)
274
, m_trackingMouseLeave(false)
275
, m_isInWindow(false)
277
, m_wasActivatedByMouseEvent(false)
278
, m_isBeingDestroyed(false)
279
, m_inIMEComposition(0)
280
, m_findIndicatorCallback(0)
281
, m_findIndicatorCallbackContext(0)
282
, m_pageOverlayInstalled(false)
286
, m_gestureReachedScrollingLimit(false)
287
#if USE(ACCELERATED_COMPOSITING)
288
, m_layerHostWindow(0)
291
registerWebViewWindowClass();
293
m_window = ::CreateWindowExW(0, kWebKit2WebViewWindowClassName, 0, WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE,
294
rect.top, rect.left, rect.right - rect.left, rect.bottom - rect.top, parentWindow ? parentWindow : HWND_MESSAGE, 0, instanceHandle(), this);
295
ASSERT(::IsWindow(m_window));
296
// We only check our window style, and not ::IsWindowVisible, because m_isVisible only tracks
297
// this window's visibility status, while ::IsWindowVisible takes our ancestors' visibility
298
// status into account. <http://webkit.org/b/54104>
299
ASSERT(m_isVisible == static_cast<bool>(::GetWindowLong(m_window, GWL_STYLE) & WS_VISIBLE));
301
m_page = context->createWebPage(this, pageGroup);
302
m_page->initializeWebPage();
304
CoCreateInstance(CLSID_DragDropHelper, 0, CLSCTX_INPROC_SERVER, IID_IDropTargetHelper, (void**)&m_dropTargetHelper);
306
// FIXME: Initializing the tooltip window here matches WebKit win, but seems like something
307
// we could do on demand to save resources.
308
initializeToolTipWindow();
310
// Initialize the top level parent window and register it with the WindowMessageBroadcaster.
311
windowAncestryDidChange();
313
#if ENABLE(FULLSCREEN_API)
314
m_page->fullScreenManager()->setWebView(this);
320
// Tooltip window needs to be explicitly destroyed since it isn't a WS_CHILD.
321
if (::IsWindow(m_toolTipWindow))
322
::DestroyWindow(m_toolTipWindow);
325
void WebView::initialize()
327
::RegisterDragDrop(m_window, this);
329
if (shouldInitializeTrackPointHack()) {
330
// If we detected a registry key belonging to a TrackPoint driver, then create fake
331
// scrollbars, so the WebView will receive WM_VSCROLL and WM_HSCROLL messages.
332
// We create an invisible vertical scrollbar and an invisible horizontal scrollbar to allow
333
// for receiving both types of messages.
334
::CreateWindow(TEXT("SCROLLBAR"), TEXT("FAKETRACKPOINTHSCROLLBAR"), WS_CHILD | WS_VISIBLE | SBS_HORZ, 0, 0, 0, 0, m_window, 0, instanceHandle(), 0);
335
::CreateWindow(TEXT("SCROLLBAR"), TEXT("FAKETRACKPOINTVSCROLLBAR"), WS_CHILD | WS_VISIBLE | SBS_VERT, 0, 0, 0, 0, m_window, 0, instanceHandle(), 0);
339
void WebView::initializeUndoClient(const WKViewUndoClient* client)
341
m_undoClient.initialize(client);
344
void WebView::setParentWindow(HWND parentWindow)
347
// If the host window hasn't changed, bail.
348
if (::GetParent(m_window) == parentWindow)
351
::SetParent(m_window, parentWindow);
352
else if (!m_isBeingDestroyed) {
353
// Turn the WebView into a message-only window so it will no longer be a child of the
354
// old parent window and will be hidden from screen. We only do this when
355
// isBeingDestroyed() is false because doing this while handling WM_DESTROY can leave
356
// m_window in a weird state (see <http://webkit.org/b/29337>).
357
::SetParent(m_window, HWND_MESSAGE);
361
windowAncestryDidChange();
364
static HWND findTopLevelParentWindow(HWND window)
369
HWND current = window;
370
for (HWND parent = GetParent(current); current; current = parent, parent = GetParent(parent)) {
371
if (!parent || !(GetWindowLongPtr(current, GWL_STYLE) & (WS_POPUP | WS_CHILD)))
374
ASSERT_NOT_REACHED();
378
void WebView::windowAncestryDidChange()
380
HWND newTopLevelParentWindow;
382
newTopLevelParentWindow = findTopLevelParentWindow(m_window);
384
// There's no point in tracking active state changes of our parent window if we don't have
385
// a window ourselves.
386
newTopLevelParentWindow = 0;
389
if (newTopLevelParentWindow == m_topLevelParentWindow)
392
if (m_topLevelParentWindow)
393
WindowMessageBroadcaster::removeListener(m_topLevelParentWindow, this);
395
m_topLevelParentWindow = newTopLevelParentWindow;
397
if (m_topLevelParentWindow)
398
WindowMessageBroadcaster::addListener(m_topLevelParentWindow, this);
403
LRESULT WebView::onMouseEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled)
405
NativeWebMouseEvent mouseEvent = NativeWebMouseEvent(hWnd, message, wParam, lParam, m_wasActivatedByMouseEvent);
406
setWasActivatedByMouseEvent(false);
412
::SetFocus(m_window);
413
::SetCapture(m_window);
421
startTrackingMouseLeave();
424
stopTrackingMouseLeave();
426
case WM_LBUTTONDBLCLK:
427
case WM_MBUTTONDBLCLK:
428
case WM_RBUTTONDBLCLK:
431
ASSERT_NOT_REACHED();
434
m_page->handleMouseEvent(mouseEvent);
440
LRESULT WebView::onWheelEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled)
442
NativeWebWheelEvent wheelEvent(hWnd, message, wParam, lParam);
443
if (wheelEvent.controlKey()) {
444
// We do not want WebKit to handle Control + Wheel, this should be handled by the client application
450
m_page->handleWheelEvent(wheelEvent);
456
LRESULT WebView::onHorizontalScroll(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled)
458
ScrollDirection direction;
459
ScrollGranularity granularity;
460
switch (LOWORD(wParam)) {
462
granularity = ScrollByLine;
463
direction = ScrollLeft;
466
granularity = ScrollByLine;
467
direction = ScrollRight;
470
granularity = ScrollByDocument;
471
direction = ScrollLeft;
474
granularity = ScrollByDocument;
475
direction = ScrollRight;
482
m_page->scrollBy(direction, granularity);
488
LRESULT WebView::onVerticalScroll(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled)
490
ScrollDirection direction;
491
ScrollGranularity granularity;
492
switch (LOWORD(wParam)) {
494
granularity = ScrollByLine;
495
direction = ScrollDown;
498
granularity = ScrollByLine;
499
direction = ScrollUp;
502
granularity = ScrollByDocument;
503
direction = ScrollDown;
506
granularity = ScrollByDocument;
507
direction = ScrollUp;
514
m_page->scrollBy(direction, granularity);
520
LRESULT WebView::onGestureNotify(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled)
522
// We shouldn't be getting any gesture messages without SetGestureConfig soft-linking correctly.
523
ASSERT(SetGestureConfigPtr());
525
GESTURENOTIFYSTRUCT* gn = reinterpret_cast<GESTURENOTIFYSTRUCT*>(lParam);
527
POINT localPoint = { gn->ptsLocation.x, gn->ptsLocation.y };
528
::ScreenToClient(m_window, &localPoint);
530
bool canPan = m_page->gestureWillBegin(localPoint);
532
DWORD dwPanWant = GC_PAN | GC_PAN_WITH_INERTIA | GC_PAN_WITH_GUTTER;
533
DWORD dwPanBlock = GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY;
535
dwPanWant |= GC_PAN_WITH_SINGLE_FINGER_VERTICALLY;
537
dwPanBlock |= GC_PAN_WITH_SINGLE_FINGER_VERTICALLY;
539
GESTURECONFIG gc = { GID_PAN, dwPanWant, dwPanBlock };
540
return SetGestureConfigPtr()(m_window, 0, 1, &gc, sizeof(gc));
543
LRESULT WebView::onGesture(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled)
545
ASSERT(GetGestureInfoPtr());
546
ASSERT(CloseGestureInfoHandlePtr());
547
ASSERT(UpdatePanningFeedbackPtr());
548
ASSERT(BeginPanningFeedbackPtr());
549
ASSERT(EndPanningFeedbackPtr());
551
if (!GetGestureInfoPtr() || !CloseGestureInfoHandlePtr() || !UpdatePanningFeedbackPtr() || !BeginPanningFeedbackPtr() || !EndPanningFeedbackPtr()) {
556
HGESTUREINFO gestureHandle = reinterpret_cast<HGESTUREINFO>(lParam);
557
GESTUREINFO gi = {0};
558
gi.cbSize = sizeof(GESTUREINFO);
560
if (!GetGestureInfoPtr()(gestureHandle, &gi)) {
567
m_lastPanX = gi.ptsLocation.x;
568
m_lastPanY = gi.ptsLocation.y;
571
m_page->gestureDidEnd();
574
int currentX = gi.ptsLocation.x;
575
int currentY = gi.ptsLocation.y;
577
// Reverse the calculations because moving your fingers up should move the screen down, and
579
int deltaX = m_lastPanX - currentX;
580
int deltaY = m_lastPanY - currentY;
582
m_lastPanX = currentX;
583
m_lastPanY = currentY;
585
// Calculate the overpan for window bounce.
586
m_overPanY -= deltaY;
588
if (deltaX || deltaY)
589
m_page->gestureDidScroll(IntSize(deltaX, deltaY));
591
if (gi.dwFlags & GF_BEGIN) {
592
BeginPanningFeedbackPtr()(m_window);
593
m_gestureReachedScrollingLimit = false;
595
} else if (gi.dwFlags & GF_END) {
596
EndPanningFeedbackPtr()(m_window, true);
600
// FIXME: Support horizontal window bounce - <http://webkit.org/b/58068>.
601
// FIXME: Window Bounce doesn't undo until user releases their finger - <http://webkit.org/b/58069>.
603
if (m_gestureReachedScrollingLimit)
604
UpdatePanningFeedbackPtr()(m_window, 0, m_overPanY, gi.dwFlags & GF_INERTIA);
606
CloseGestureInfoHandlePtr()(gestureHandle);
615
// If we get to this point, the gesture has not been handled. We forward
616
// the call to DefWindowProc by returning false, and we don't need to
617
// to call CloseGestureInfoHandle.
618
// http://msdn.microsoft.com/en-us/library/dd353228(VS.85).aspx
623
LRESULT WebView::onKeyEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled)
625
#if ENABLE(FULLSCREEN_API)
626
// Trap the ESC key when in full screen mode.
627
if (message == WM_KEYDOWN && wParam == VK_ESCAPE && m_fullScreenController && m_fullScreenController->isFullScreen()) {
628
m_fullScreenController->exitFullScreen();
633
m_page->handleKeyboardEvent(NativeWebKeyboardEvent(hWnd, message, wParam, lParam));
635
// We claim here to always have handled the event. If the event is not in fact handled, we will
636
// find out later in didNotHandleKeyEvent.
641
static void drawPageBackground(HDC dc, const WebPageProxy* page, const RECT& rect)
643
if (!page->drawsBackground() || page->drawsTransparentBackground())
646
::FillRect(dc, &rect, reinterpret_cast<HBRUSH>(COLOR_WINDOW + 1));
649
void WebView::paint(HDC hdc, const IntRect& dirtyRect)
651
m_page->endPrinting();
652
if (DrawingAreaProxyImpl* drawingArea = static_cast<DrawingAreaProxyImpl*>(m_page->drawingArea())) {
653
// FIXME: We should port WebKit1's rect coalescing logic here.
654
Region unpaintedRegion;
655
drawingArea->paint(hdc, dirtyRect, unpaintedRegion);
657
Vector<IntRect> unpaintedRects = unpaintedRegion.rects();
658
for (size_t i = 0; i < unpaintedRects.size(); ++i) {
659
RECT winRect = unpaintedRects[i];
660
drawPageBackground(hdc, m_page.get(), unpaintedRects[i]);
663
drawPageBackground(hdc, m_page.get(), dirtyRect);
668
static void flashRects(HDC dc, const IntRect rects[], size_t rectCount, HBRUSH brush)
670
for (size_t i = 0; i < rectCount; ++i) {
671
RECT winRect = rects[i];
672
::FillRect(dc, &winRect, brush);
679
static OwnPtr<HBRUSH> createBrush(const Color& color)
681
return adoptPtr(::CreateSolidBrush(RGB(color.red(), color.green(), color.blue())));
684
LRESULT WebView::onPaintEvent(HWND hWnd, UINT message, WPARAM, LPARAM, bool& handled)
686
// Update child windows now so that any areas of our window they reveal will be included in the
687
// invalid region that ::BeginPaint sees.
688
updateChildWindowGeometries();
690
PAINTSTRUCT paintStruct;
691
HDC hdc = ::BeginPaint(m_window, &paintStruct);
693
if (WebPageProxy::debugPaintFlags() & kWKDebugFlashViewUpdates) {
694
static HBRUSH brush = createBrush(WebPageProxy::viewUpdatesFlashColor().rgb()).leakPtr();
695
IntRect rect = paintStruct.rcPaint;
696
flashRects(hdc, &rect, 1, brush);
699
paint(hdc, paintStruct.rcPaint);
701
::EndPaint(m_window, &paintStruct);
707
LRESULT WebView::onPrintClientEvent(HWND hWnd, UINT, WPARAM wParam, LPARAM, bool& handled)
709
HDC hdc = reinterpret_cast<HDC>(wParam);
711
::GetClientRect(hWnd, &winRect);
713
// Twidding the visibility flags tells the DrawingArea to resume painting. Right now, the
714
// the visible state of the view only affects whether or not painting happens, but in the
715
// future it could affect more, which we wouldn't want to touch here.
717
// FIXME: We should have a better way of telling the WebProcess to draw even if we're
718
// invisible than twiddling the visibility flag.
720
bool wasVisible = isViewVisible();
733
LRESULT WebView::onSizeEvent(HWND, UINT, WPARAM, LPARAM lParam, bool& handled)
735
int width = LOWORD(lParam);
736
int height = HIWORD(lParam);
738
if (m_page && m_page->drawingArea()) {
739
m_page->drawingArea()->setSize(IntSize(width, height), m_nextResizeScrollOffset);
740
m_nextResizeScrollOffset = IntSize();
743
#if USE(ACCELERATED_COMPOSITING)
744
if (m_layerHostWindow)
745
::MoveWindow(m_layerHostWindow, 0, 0, width, height, FALSE);
752
LRESULT WebView::onWindowPositionChangedEvent(HWND, UINT, WPARAM, LPARAM lParam, bool& handled)
754
if (reinterpret_cast<WINDOWPOS*>(lParam)->flags & SWP_SHOWWINDOW)
755
updateActiveStateSoon();
761
LRESULT WebView::onSetFocusEvent(HWND, UINT, WPARAM, LPARAM lParam, bool& handled)
763
m_page->viewStateDidChange(WebPageProxy::ViewIsFocused);
768
LRESULT WebView::onKillFocusEvent(HWND, UINT, WPARAM, LPARAM lParam, bool& handled)
770
m_page->viewStateDidChange(WebPageProxy::ViewIsFocused);
775
LRESULT WebView::onTimerEvent(HWND hWnd, UINT, WPARAM wParam, LPARAM, bool& handled)
778
case UpdateActiveStateTimer:
779
::KillTimer(hWnd, UpdateActiveStateTimer);
788
LRESULT WebView::onShowWindowEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled)
790
// lParam is 0 when the message is sent because of a ShowWindow call.
791
// FIXME: Since we don't get notified when an ancestor window is hidden or shown, we will keep
792
// painting even when we have a hidden ancestor. <http://webkit.org/b/54104>
794
setIsVisible(wParam);
800
LRESULT WebView::onSetCursor(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled)
802
if (!m_lastCursorSet) {
807
::SetCursor(m_lastCursorSet);
811
void WebView::updateActiveState()
813
m_page->viewStateDidChange(WebPageProxy::ViewWindowIsActive);
816
void WebView::updateActiveStateSoon()
818
// This function is called while processing the WM_NCACTIVATE message.
819
// While processing WM_NCACTIVATE when we are being deactivated, GetActiveWindow() will
820
// still return our window. If we were to call updateActiveState() in that case, we would
821
// wrongly think that we are still the active window. To work around this, we update our
822
// active state after a 0-delay timer fires, at which point GetActiveWindow() will return
823
// the newly-activated window.
825
::SetTimer(m_window, UpdateActiveStateTimer, 0, 0);
828
static bool initCommonControls()
830
static bool haveInitialized = false;
834
INITCOMMONCONTROLSEX init;
835
init.dwSize = sizeof(init);
836
init.dwICC = ICC_TREEVIEW_CLASSES;
837
haveInitialized = !!::InitCommonControlsEx(&init);
838
return haveInitialized;
841
void WebView::initializeToolTipWindow()
843
if (!initCommonControls())
846
m_toolTipWindow = ::CreateWindowEx(WS_EX_TRANSPARENT, TOOLTIPS_CLASS, 0, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
847
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
849
if (!m_toolTipWindow)
853
info.cbSize = sizeof(info);
854
info.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
855
info.uId = reinterpret_cast<UINT_PTR>(m_window);
857
::SendMessage(m_toolTipWindow, TTM_ADDTOOL, 0, reinterpret_cast<LPARAM>(&info));
858
::SendMessage(m_toolTipWindow, TTM_SETMAXTIPWIDTH, 0, kMaxToolTipWidth);
859
::SetWindowPos(m_toolTipWindow, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
862
void WebView::startTrackingMouseLeave()
864
if (m_trackingMouseLeave)
866
m_trackingMouseLeave = true;
868
TRACKMOUSEEVENT trackMouseEvent;
869
trackMouseEvent.cbSize = sizeof(TRACKMOUSEEVENT);
870
trackMouseEvent.dwFlags = TME_LEAVE;
871
trackMouseEvent.hwndTrack = m_window;
873
::TrackMouseEvent(&trackMouseEvent);
876
void WebView::stopTrackingMouseLeave()
878
if (!m_trackingMouseLeave)
880
m_trackingMouseLeave = false;
882
TRACKMOUSEEVENT trackMouseEvent;
883
trackMouseEvent.cbSize = sizeof(TRACKMOUSEEVENT);
884
trackMouseEvent.dwFlags = TME_LEAVE | TME_CANCEL;
885
trackMouseEvent.hwndTrack = m_window;
887
::TrackMouseEvent(&trackMouseEvent);
890
bool WebView::shouldInitializeTrackPointHack()
892
static bool shouldCreateScrollbars;
893
static bool hasRunTrackPointCheck;
895
if (hasRunTrackPointCheck)
896
return shouldCreateScrollbars;
898
hasRunTrackPointCheck = true;
899
const wchar_t* trackPointKeys[] = {
900
L"Software\\Lenovo\\TrackPoint",
901
L"Software\\Lenovo\\UltraNav",
902
L"Software\\Alps\\Apoint\\TrackPoint",
903
L"Software\\Synaptics\\SynTPEnh\\UltraNavUSB",
904
L"Software\\Synaptics\\SynTPEnh\\UltraNavPS2"
907
for (size_t i = 0; i < WTF_ARRAY_LENGTH(trackPointKeys); ++i) {
909
int readKeyResult = ::RegOpenKeyExW(HKEY_CURRENT_USER, trackPointKeys[i], 0, KEY_READ, &trackPointKey);
910
::RegCloseKey(trackPointKey);
911
if (readKeyResult == ERROR_SUCCESS) {
912
shouldCreateScrollbars = true;
913
return shouldCreateScrollbars;
917
return shouldCreateScrollbars;
920
void WebView::close()
922
m_undoClient.initialize(0);
923
::RevokeDragDrop(m_window);
925
// We can't check IsWindow(m_window) here, because that will return true even while
926
// we're already handling WM_DESTROY. So we check !m_isBeingDestroyed instead.
927
if (!m_isBeingDestroyed)
928
DestroyWindow(m_window);
929
// Either we just destroyed m_window, or it's in the process of being destroyed. Either
930
// way, we clear it out to make sure we don't try to use it later.
939
PassOwnPtr<DrawingAreaProxy> WebView::createDrawingAreaProxy()
941
return DrawingAreaProxyImpl::create(m_page.get());
944
void WebView::setViewNeedsDisplay(const WebCore::IntRect& rect)
947
::InvalidateRect(m_window, &r, false);
950
void WebView::displayView()
952
::UpdateWindow(m_window);
955
void WebView::scrollView(const IntRect& scrollRect, const IntSize& scrollOffset)
957
// FIXME: Actually scroll the view contents.
958
setViewNeedsDisplay(scrollRect);
961
void WebView::flashBackingStoreUpdates(const Vector<IntRect>& updateRects)
963
static HBRUSH brush = createBrush(WebPageProxy::backingStoreUpdatesFlashColor().rgb()).leakPtr();
965
flashRects(dc, updateRects.data(), updateRects.size(), brush);
968
WebCore::IntSize WebView::viewSize()
971
GetClientRect(m_window, &clientRect);
973
return IntRect(clientRect).size();
976
bool WebView::isViewWindowActive()
978
HWND activeWindow = ::GetActiveWindow();
979
return (activeWindow && m_topLevelParentWindow == findTopLevelParentWindow(activeWindow));
982
bool WebView::isViewFocused()
984
return ::GetFocus() == m_window;
987
bool WebView::isViewVisible()
992
bool WebView::isViewInWindow()
997
void WebView::pageClosed()
1001
void WebView::processDidCrash()
1003
updateNativeCursor();
1004
::InvalidateRect(m_window, 0, TRUE);
1007
void WebView::didRelaunchProcess()
1009
updateNativeCursor();
1010
::InvalidateRect(m_window, 0, TRUE);
1013
void WebView::toolTipChanged(const String&, const String& newToolTip)
1015
if (!m_toolTipWindow)
1018
if (!newToolTip.isEmpty()) {
1019
// This is necessary because String::charactersWithNullTermination() is not const.
1020
String toolTip = newToolTip;
1022
TOOLINFO info = {0};
1023
info.cbSize = sizeof(info);
1024
info.uFlags = TTF_IDISHWND;
1025
info.uId = reinterpret_cast<UINT_PTR>(m_window);
1026
info.lpszText = const_cast<UChar*>(toolTip.charactersWithNullTermination());
1027
::SendMessage(m_toolTipWindow, TTM_UPDATETIPTEXT, 0, reinterpret_cast<LPARAM>(&info));
1030
::SendMessage(m_toolTipWindow, TTM_ACTIVATE, !newToolTip.isEmpty(), 0);
1033
HCURSOR WebView::cursorToShow() const
1035
if (!m_page->isValid())
1038
// We only show the override cursor if the default (arrow) cursor is showing.
1039
static HCURSOR arrowCursor = ::LoadCursor(0, IDC_ARROW);
1040
if (m_overrideCursor && m_webCoreCursor == arrowCursor)
1041
return m_overrideCursor;
1043
return m_webCoreCursor;
1046
void WebView::updateNativeCursor()
1048
m_lastCursorSet = cursorToShow();
1049
if (!m_lastCursorSet)
1051
::SetCursor(m_lastCursorSet);
1054
void WebView::setCursor(const WebCore::Cursor& cursor)
1056
if (!cursor.platformCursor()->nativeCursor())
1058
m_webCoreCursor = cursor.platformCursor()->nativeCursor();
1059
updateNativeCursor();
1062
void WebView::setCursorHiddenUntilMouseMoves(bool)
1067
void WebView::setOverrideCursor(HCURSOR overrideCursor)
1069
m_overrideCursor = overrideCursor;
1070
updateNativeCursor();
1073
void WebView::setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent& event)
1075
m_page->setInitialFocus(forward, isKeyboardEventValid, event);
1078
void WebView::setScrollOffsetOnNextResize(const IntSize& scrollOffset)
1080
// The next time we get a WM_SIZE message, scroll by the specified amount in onSizeEvent().
1081
m_nextResizeScrollOffset = scrollOffset;
1084
void WebView::didChangeViewportProperties(const WebCore::ViewportAttributes&)
1088
void WebView::registerEditCommand(PassRefPtr<WebEditCommandProxy> prpCommand, WebPageProxy::UndoOrRedo undoOrRedo)
1090
RefPtr<WebEditCommandProxy> command = prpCommand;
1091
m_undoClient.registerEditCommand(this, command, undoOrRedo);
1094
void WebView::clearAllEditCommands()
1096
m_undoClient.clearAllEditCommands(this);
1099
bool WebView::canUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo)
1101
return m_undoClient.canUndoRedo(this, undoOrRedo);
1104
void WebView::executeUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo)
1106
m_undoClient.executeUndoRedo(this, undoOrRedo);
1109
void WebView::reapplyEditCommand(WebEditCommandProxy* command)
1111
if (!m_page->isValid() || !m_page->isValidEditCommand(command))
1117
void WebView::unapplyEditCommand(WebEditCommandProxy* command)
1119
if (!m_page->isValid() || !m_page->isValidEditCommand(command))
1125
void WebView::setCustomDropTarget(IDropTarget* dropTarget)
1127
if (!m_page->isValid() || !m_window)
1130
::RevokeDragDrop(m_window);
1133
::RegisterDragDrop(m_window, dropTarget);
1135
::RegisterDragDrop(m_window, this);
1138
FloatRect WebView::convertToDeviceSpace(const FloatRect& rect)
1143
IntPoint WebView::screenToWindow(const IntPoint& point)
1148
IntRect WebView::windowToScreen(const IntRect& rect)
1153
FloatRect WebView::convertToUserSpace(const FloatRect& rect)
1158
HIMC WebView::getIMMContext()
1160
return Ime::ImmGetContext(m_window);
1163
void WebView::prepareCandidateWindow(HIMC hInputContext)
1165
IntRect caret = m_page->firstRectForCharacterInSelectedRange(0);
1168
form.dwStyle = CFS_EXCLUDE;
1169
form.ptCurrentPos.x = caret.x();
1170
form.ptCurrentPos.y = caret.maxY();
1171
form.rcArea.top = caret.y();
1172
form.rcArea.bottom = caret.maxY();
1173
form.rcArea.left = caret.x();
1174
form.rcArea.right = caret.maxX();
1175
Ime::ImmSetCandidateWindow(hInputContext, &form);
1178
void WebView::resetIME()
1180
HIMC hInputContext = getIMMContext();
1183
Ime::ImmNotifyIME(hInputContext, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
1184
Ime::ImmReleaseContext(m_window, hInputContext);
1187
void WebView::setInputMethodState(bool enabled)
1189
Ime::ImmAssociateContextEx(m_window, 0, enabled ? IACE_DEFAULT : 0);
1192
void WebView::compositionSelectionChanged(bool hasChanged)
1194
if (m_page->editorState().hasComposition && !hasChanged)
1198
bool WebView::onIMEStartComposition()
1200
LOG(TextInput, "onIMEStartComposition");
1201
m_inIMEComposition++;
1203
HIMC hInputContext = getIMMContext();
1206
prepareCandidateWindow(hInputContext);
1207
Ime::ImmReleaseContext(m_window, hInputContext);
1211
static bool getCompositionString(HIMC hInputContext, DWORD type, String& result)
1213
LONG compositionLength = Ime::ImmGetCompositionStringW(hInputContext, type, 0, 0);
1214
if (compositionLength <= 0)
1216
Vector<UChar> compositionBuffer(compositionLength / 2);
1217
compositionLength = Ime::ImmGetCompositionStringW(hInputContext, type, compositionBuffer.data(), compositionLength);
1218
result = String::adopt(compositionBuffer);
1222
static void compositionToUnderlines(const Vector<DWORD>& clauses, const Vector<BYTE>& attributes, Vector<CompositionUnderline>& underlines)
1224
if (clauses.isEmpty()) {
1229
size_t numBoundaries = clauses.size() - 1;
1230
underlines.resize(numBoundaries);
1231
for (unsigned i = 0; i < numBoundaries; ++i) {
1232
underlines[i].startOffset = clauses[i];
1233
underlines[i].endOffset = clauses[i + 1];
1234
BYTE attribute = attributes[clauses[i]];
1235
underlines[i].thick = attribute == ATTR_TARGET_CONVERTED || attribute == ATTR_TARGET_NOTCONVERTED;
1236
underlines[i].color = Color::black;
1241
#define APPEND_ARGUMENT_NAME(name) \
1242
if (lparam & name) { \
1244
result.appendLiteral(", "); \
1245
result.appendLiteral(#name); \
1246
needsComma = true; \
1249
static String imeCompositionArgumentNames(LPARAM lparam)
1251
StringBuilder result;
1252
bool needsComma = false;
1254
APPEND_ARGUMENT_NAME(GCS_COMPATTR);
1255
APPEND_ARGUMENT_NAME(GCS_COMPCLAUSE);
1256
APPEND_ARGUMENT_NAME(GCS_COMPREADSTR);
1257
APPEND_ARGUMENT_NAME(GCS_COMPREADATTR);
1258
APPEND_ARGUMENT_NAME(GCS_COMPREADCLAUSE);
1259
APPEND_ARGUMENT_NAME(GCS_COMPSTR);
1260
APPEND_ARGUMENT_NAME(GCS_CURSORPOS);
1261
APPEND_ARGUMENT_NAME(GCS_DELTASTART);
1262
APPEND_ARGUMENT_NAME(GCS_RESULTCLAUSE);
1263
APPEND_ARGUMENT_NAME(GCS_RESULTREADCLAUSE);
1264
APPEND_ARGUMENT_NAME(GCS_RESULTREADSTR);
1265
APPEND_ARGUMENT_NAME(GCS_RESULTSTR);
1266
APPEND_ARGUMENT_NAME(CS_INSERTCHAR);
1267
APPEND_ARGUMENT_NAME(CS_NOMOVECARET);
1269
return result.toString();
1272
static String imeRequestName(WPARAM wparam)
1275
case IMR_CANDIDATEWINDOW:
1276
return "IMR_CANDIDATEWINDOW";
1277
case IMR_COMPOSITIONFONT:
1278
return "IMR_COMPOSITIONFONT";
1279
case IMR_COMPOSITIONWINDOW:
1280
return "IMR_COMPOSITIONWINDOW";
1281
case IMR_CONFIRMRECONVERTSTRING:
1282
return "IMR_CONFIRMRECONVERTSTRING";
1283
case IMR_DOCUMENTFEED:
1284
return "IMR_DOCUMENTFEED";
1285
case IMR_QUERYCHARPOSITION:
1286
return "IMR_QUERYCHARPOSITION";
1287
case IMR_RECONVERTSTRING:
1288
return "IMR_RECONVERTSTRING";
1290
return "Unknown (" + String::number(wparam) + ")";
1295
bool WebView::onIMEComposition(LPARAM lparam)
1297
LOG(TextInput, "onIMEComposition %s", imeCompositionArgumentNames(lparam).latin1().data());
1298
HIMC hInputContext = getIMMContext();
1302
if (!m_page->editorState().isContentEditable)
1305
prepareCandidateWindow(hInputContext);
1307
if (lparam & GCS_RESULTSTR || !lparam) {
1308
String compositionString;
1309
if (!getCompositionString(hInputContext, GCS_RESULTSTR, compositionString) && lparam)
1312
m_page->confirmComposition(compositionString);
1316
String compositionString;
1317
if (!getCompositionString(hInputContext, GCS_COMPSTR, compositionString))
1320
// Composition string attributes
1321
int numAttributes = Ime::ImmGetCompositionStringW(hInputContext, GCS_COMPATTR, 0, 0);
1322
Vector<BYTE> attributes(numAttributes);
1323
Ime::ImmGetCompositionStringW(hInputContext, GCS_COMPATTR, attributes.data(), numAttributes);
1326
int numBytes = Ime::ImmGetCompositionStringW(hInputContext, GCS_COMPCLAUSE, 0, 0);
1327
Vector<DWORD> clauses(numBytes / sizeof(DWORD));
1328
Ime::ImmGetCompositionStringW(hInputContext, GCS_COMPCLAUSE, clauses.data(), numBytes);
1330
Vector<CompositionUnderline> underlines;
1331
compositionToUnderlines(clauses, attributes, underlines);
1333
int cursorPosition = LOWORD(Ime::ImmGetCompositionStringW(hInputContext, GCS_CURSORPOS, 0, 0));
1335
m_page->setComposition(compositionString, underlines, cursorPosition);
1340
bool WebView::onIMEEndComposition()
1342
LOG(TextInput, "onIMEEndComposition");
1343
// If the composition hasn't been confirmed yet, it needs to be cancelled.
1344
// This happens after deleting the last character from inline input hole.
1345
if (m_page->editorState().hasComposition)
1346
m_page->confirmComposition(String());
1348
if (m_inIMEComposition)
1349
m_inIMEComposition--;
1354
LRESULT WebView::onIMERequestCharPosition(IMECHARPOSITION* charPos)
1356
if (charPos->dwCharPos && !m_page->editorState().hasComposition)
1358
IntRect caret = m_page->firstRectForCharacterInSelectedRange(charPos->dwCharPos);
1359
charPos->pt.x = caret.x();
1360
charPos->pt.y = caret.y();
1361
::ClientToScreen(m_window, &charPos->pt);
1362
charPos->cLineHeight = caret.height();
1363
::GetWindowRect(m_window, &charPos->rcDocument);
1367
LRESULT WebView::onIMERequestReconvertString(RECONVERTSTRING* reconvertString)
1369
String text = m_page->getSelectedText();
1370
unsigned totalSize = sizeof(RECONVERTSTRING) + text.length() * sizeof(UChar);
1372
if (!reconvertString)
1375
if (totalSize > reconvertString->dwSize)
1377
reconvertString->dwCompStrLen = text.length();
1378
reconvertString->dwStrLen = text.length();
1379
reconvertString->dwTargetStrLen = text.length();
1380
reconvertString->dwStrOffset = sizeof(RECONVERTSTRING);
1381
memcpy(reconvertString + 1, text.characters(), text.length() * sizeof(UChar));
1385
LRESULT WebView::onIMERequest(WPARAM request, LPARAM data)
1387
LOG(TextInput, "onIMERequest %s", imeRequestName(request).latin1().data());
1388
if (!m_page->editorState().isContentEditable)
1392
case IMR_RECONVERTSTRING:
1393
return onIMERequestReconvertString(reinterpret_cast<RECONVERTSTRING*>(data));
1395
case IMR_QUERYCHARPOSITION:
1396
return onIMERequestCharPosition(reinterpret_cast<IMECHARPOSITION*>(data));
1401
bool WebView::onIMESelect(WPARAM wparam, LPARAM lparam)
1403
UNUSED_PARAM(wparam);
1404
UNUSED_PARAM(lparam);
1405
LOG(TextInput, "onIMESelect locale %ld %s", lparam, wparam ? "select" : "deselect");
1409
bool WebView::onIMESetContext(WPARAM wparam, LPARAM)
1411
LOG(TextInput, "onIMESetContext %s", wparam ? "active" : "inactive");
1415
void WebView::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool wasEventHandled)
1417
// Calling ::DefWindowProcW will ensure that pressing the Alt key will generate a WM_SYSCOMMAND
1418
// event, e.g. See <http://webkit.org/b/47671>.
1419
if (!wasEventHandled)
1420
::DefWindowProcW(event.nativeEvent()->hwnd, event.nativeEvent()->message, event.nativeEvent()->wParam, event.nativeEvent()->lParam);
1423
PassRefPtr<WebPopupMenuProxy> WebView::createPopupMenuProxy(WebPageProxy* page)
1425
return WebPopupMenuProxyWin::create(this, page);
1428
PassRefPtr<WebContextMenuProxy> WebView::createContextMenuProxy(WebPageProxy* page)
1430
return WebContextMenuProxyWin::create(m_window, page);
1433
#if ENABLE(INPUT_TYPE_COLOR)
1434
PassRefPtr<WebColorChooserProxy> WebView::createColorChooserProxy(WebPageProxy*, const WebCore::Color&, const WebCore::IntRect&)
1441
void WebView::setFindIndicator(PassRefPtr<FindIndicator> prpFindIndicator, bool fadeOut, bool animate)
1443
UNUSED_PARAM(animate);
1445
if (!m_findIndicatorCallback)
1449
IntRect selectionRect;
1451
if (RefPtr<FindIndicator> findIndicator = prpFindIndicator) {
1452
if (ShareableBitmap* contentImage = findIndicator->contentImage()) {
1453
// Render the contentImage to an HBITMAP.
1455
HDC hdc = ::CreateCompatibleDC(0);
1456
int width = contentImage->bounds().width();
1457
int height = contentImage->bounds().height();
1458
BitmapInfo bitmapInfo = BitmapInfo::create(contentImage->size());
1460
hbmp = CreateDIBSection(0, &bitmapInfo, DIB_RGB_COLORS, static_cast<void**>(&bits), 0, 0);
1461
HBITMAP hbmpOld = static_cast<HBITMAP>(SelectObject(hdc, hbmp));
1463
RetainPtr<CGContextRef> context(AdoptCF, CGBitmapContextCreate(bits, width, height,
1464
8, width * sizeof(RGBQUAD), deviceRGBColorSpaceRef(), kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst));
1466
GraphicsContext graphicsContext(context.get());
1467
contentImage->paint(graphicsContext, IntPoint(), contentImage->bounds());
1469
// FIXME: Implement!
1472
::SelectObject(hdc, hbmpOld);
1476
selectionRect = IntRect(findIndicator->selectionRectInWindowCoordinates());
1479
// The callback is responsible for calling ::DeleteObject(hbmp).
1480
(*m_findIndicatorCallback)(toAPI(this), hbmp, selectionRect, fadeOut, m_findIndicatorCallbackContext);
1483
void WebView::setFindIndicatorCallback(WKViewFindIndicatorCallback callback, void* context)
1485
m_findIndicatorCallback = callback;
1486
m_findIndicatorCallbackContext = context;
1489
WKViewFindIndicatorCallback WebView::getFindIndicatorCallback(void** context)
1492
*context = m_findIndicatorCallbackContext;
1494
return m_findIndicatorCallback;
1497
void WebView::didInstallOrUninstallPageOverlay(bool didInstall)
1499
m_pageOverlayInstalled = didInstall;
1502
void WebView::didCommitLoadForMainFrame(bool useCustomRepresentation)
1506
void WebView::didFinishLoadingDataForCustomRepresentation(const String& suggestedFilename, const CoreIPC::DataReference&)
1510
double WebView::customRepresentationZoomFactor()
1515
void WebView::setCustomRepresentationZoomFactor(double)
1519
void WebView::didChangeScrollbarsForMainFrame() const
1523
void WebView::findStringInCustomRepresentation(const String&, FindOptions, unsigned)
1527
void WebView::countStringMatchesInCustomRepresentation(const String&, FindOptions, unsigned)
1531
void WebView::setIsInWindow(bool isInWindow)
1533
m_isInWindow = isInWindow;
1534
m_page->viewStateDidChange(WebPageProxy::ViewIsInWindow);
1537
void WebView::setIsVisible(bool isVisible)
1539
m_isVisible = isVisible;
1542
m_page->viewStateDidChange(WebPageProxy::ViewIsVisible);
1545
#if USE(ACCELERATED_COMPOSITING)
1547
void WebView::enterAcceleratedCompositingMode(const LayerTreeContext& context)
1550
ASSERT(!context.isEmpty());
1552
m_layerHostWindow = context.window;
1554
IntSize size = viewSize();
1555
// Ensure the layer host window is behind all other child windows (since otherwise it would obscure them).
1556
::SetWindowPos(m_layerHostWindow, HWND_BOTTOM, 0, 0, size.width(), size.height(), SWP_SHOWWINDOW | SWP_NOACTIVATE);
1558
ASSERT_NOT_REACHED();
1562
void WebView::exitAcceleratedCompositingMode()
1565
ASSERT(m_layerHostWindow);
1567
// Tell the WKCACFViewWindow to destroy itself. We can't call ::DestroyWindow directly because
1568
// the window is owned by another thread.
1569
::PostMessageW(m_layerHostWindow, WKCACFViewWindow::customDestroyMessage, 0, 0);
1570
m_layerHostWindow = 0;
1572
ASSERT_NOT_REACHED();
1576
void WebView::updateAcceleratedCompositingMode(const LayerTreeContext&)
1579
#endif // USE(ACCELERATED_COMPOSITING)
1581
HWND WebView::nativeWindow()
1586
void WebView::scheduleChildWindowGeometryUpdate(const WindowGeometry& geometry)
1588
m_geometriesUpdater.addPendingUpdate(geometry);
1591
void WebView::updateChildWindowGeometries()
1593
m_geometriesUpdater.updateGeometries(DoNotBringToTop);
1596
// WebCore::WindowMessageListener
1598
void WebView::windowReceivedMessage(HWND, UINT message, WPARAM wParam, LPARAM)
1602
updateActiveStateSoon();
1604
case WM_SETTINGCHANGE:
1605
// systemParameterChanged(wParam);
1610
HRESULT STDMETHODCALLTYPE WebView::QueryInterface(REFIID riid, void** ppvObject)
1613
if (IsEqualGUID(riid, IID_IUnknown))
1614
*ppvObject = static_cast<IUnknown*>(this);
1615
else if (IsEqualGUID(riid, IID_IDropTarget))
1616
*ppvObject = static_cast<IDropTarget*>(this);
1618
return E_NOINTERFACE;
1624
ULONG STDMETHODCALLTYPE WebView::AddRef(void)
1630
ULONG STDMETHODCALLTYPE WebView::Release(void)
1636
static DWORD dragOperationToDragCursor(DragOperation op)
1638
DWORD res = DROPEFFECT_NONE;
1639
if (op & DragOperationCopy)
1640
res = DROPEFFECT_COPY;
1641
else if (op & DragOperationLink)
1642
res = DROPEFFECT_LINK;
1643
else if (op & DragOperationMove)
1644
res = DROPEFFECT_MOVE;
1645
else if (op & DragOperationGeneric)
1646
res = DROPEFFECT_MOVE; // This appears to be the Firefox behaviour
1650
WebCore::DragOperation WebView::keyStateToDragOperation(DWORD grfKeyState) const
1653
return DragOperationNone;
1655
// Conforms to Microsoft's key combinations as documented for
1656
// IDropTarget::DragOver. Note, grfKeyState is the current
1657
// state of the keyboard modifier keys on the keyboard. See:
1658
// <http://msdn.microsoft.com/en-us/library/ms680129(VS.85).aspx>.
1659
DragOperation operation = m_page->dragSession().operation;
1661
if ((grfKeyState & (MK_CONTROL | MK_SHIFT)) == (MK_CONTROL | MK_SHIFT))
1662
operation = DragOperationLink;
1663
else if ((grfKeyState & MK_CONTROL) == MK_CONTROL)
1664
operation = DragOperationCopy;
1665
else if ((grfKeyState & MK_SHIFT) == MK_SHIFT)
1666
operation = DragOperationGeneric;
1671
HRESULT STDMETHODCALLTYPE WebView::DragEnter(IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect)
1674
m_page->resetDragOperation();
1676
if (m_dropTargetHelper)
1677
m_dropTargetHelper->DragEnter(m_window, pDataObject, (POINT*)&pt, *pdwEffect);
1679
POINTL localpt = pt;
1680
::ScreenToClient(m_window, (LPPOINT)&localpt);
1681
DragData data(pDataObject, IntPoint(localpt.x, localpt.y), IntPoint(pt.x, pt.y), keyStateToDragOperation(grfKeyState));
1682
m_page->dragEntered(&data);
1683
*pdwEffect = dragOperationToDragCursor(m_page->dragSession().operation);
1685
m_lastDropEffect = *pdwEffect;
1686
m_dragData = pDataObject;
1691
HRESULT STDMETHODCALLTYPE WebView::DragOver(DWORD grfKeyState, POINTL pt, DWORD* pdwEffect)
1693
if (m_dropTargetHelper)
1694
m_dropTargetHelper->DragOver((POINT*)&pt, *pdwEffect);
1697
POINTL localpt = pt;
1698
::ScreenToClient(m_window, (LPPOINT)&localpt);
1699
DragData data(m_dragData.get(), IntPoint(localpt.x, localpt.y), IntPoint(pt.x, pt.y), keyStateToDragOperation(grfKeyState));
1700
m_page->dragUpdated(&data);
1701
*pdwEffect = dragOperationToDragCursor(m_page->dragSession().operation);
1703
*pdwEffect = DROPEFFECT_NONE;
1705
m_lastDropEffect = *pdwEffect;
1709
HRESULT STDMETHODCALLTYPE WebView::DragLeave()
1711
if (m_dropTargetHelper)
1712
m_dropTargetHelper->DragLeave();
1715
DragData data(m_dragData.get(), IntPoint(), IntPoint(), DragOperationNone);
1716
m_page->dragExited(&data);
1718
m_page->resetDragOperation();
1723
static bool maybeCreateSandboxExtensionFromDragData(const DragData& dragData, SandboxExtension::Handle& sandboxExtensionHandle)
1725
if (!dragData.containsFiles())
1728
// Unlike on Mac, we allow multiple files and directories, since on Windows
1729
// we have actions for those (open the first file, open a Windows Explorer window).
1731
SandboxExtension::createHandle("\\", SandboxExtension::ReadOnly, sandboxExtensionHandle);
1735
HRESULT STDMETHODCALLTYPE WebView::Drop(IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect)
1737
if (m_dropTargetHelper)
1738
m_dropTargetHelper->Drop(pDataObject, (POINT*)&pt, *pdwEffect);
1741
*pdwEffect = m_lastDropEffect;
1742
POINTL localpt = pt;
1743
::ScreenToClient(m_window, (LPPOINT)&localpt);
1744
DragData data(pDataObject, IntPoint(localpt.x, localpt.y), IntPoint(pt.x, pt.y), keyStateToDragOperation(grfKeyState));
1746
SandboxExtension::Handle sandboxExtensionHandle;
1747
bool createdExtension = maybeCreateSandboxExtensionFromDragData(data, sandboxExtensionHandle);
1748
if (createdExtension)
1749
m_page->process()->willAcquireUniversalFileReadSandboxExtension();
1750
SandboxExtension::HandleArray sandboxExtensionForUpload;
1751
m_page->performDrag(&data, String(), sandboxExtensionHandle, sandboxExtensionForUpload);
1755
#if ENABLE(FULLSCREEN_API)
1756
FullScreenController* WebView::fullScreenController()
1758
if (!m_fullScreenController)
1759
m_fullScreenController = adoptPtr(new FullScreenController(this));
1760
return m_fullScreenController.get();
1763
HWND WebView::fullScreenClientWindow() const
1768
HWND WebView::fullScreenClientParentWindow() const
1770
return ::GetParent(m_window);
1773
void WebView::fullScreenClientSetParentWindow(HWND hostWindow)
1775
setParentWindow(hostWindow);
1778
void WebView::fullScreenClientWillEnterFullScreen()
1780
page()->fullScreenManager()->willEnterFullScreen();
1783
void WebView::fullScreenClientDidEnterFullScreen()
1785
page()->fullScreenManager()->didEnterFullScreen();
1788
void WebView::fullScreenClientWillExitFullScreen()
1790
page()->fullScreenManager()->willExitFullScreen();
1793
void WebView::fullScreenClientDidExitFullScreen()
1795
page()->fullScreenManager()->didExitFullScreen();
1798
static void fullScreenClientForceRepaintCompleted(WKErrorRef, void* context)
1801
static_cast<WebView*>(context)->fullScreenController()->repaintCompleted();
1804
void WebView::fullScreenClientForceRepaint()
1806
page()->forceRepaint(VoidCallback::create(this, &fullScreenClientForceRepaintCompleted));
1810
} // namespace WebKit