9719eddd4e210b19ece2b26a4e81edcb9bf880ed
[WebKit-https.git] / Source / WebKit2 / UIProcess / API / gtk / PageClientImpl.cpp
1 /*
2  * Copyright (C) 2010 Apple Inc. All rights reserved.
3  * Portions Copyright (c) 2010 Motorola Mobility, Inc.  All rights reserved.
4  * Copyright (C) 2011 Igalia S.L.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
19  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
25  * THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include "config.h"
29 #include "PageClientImpl.h"
30
31 #include "DrawingAreaProxyImpl.h"
32 #include "NativeWebKeyboardEvent.h"
33 #include "NativeWebMouseEvent.h"
34 #include "NotImplemented.h"
35 #include "WebContext.h"
36 #include "WebContextMenuProxyGtk.h"
37 #include "WebEventFactory.h"
38 #include "WebKitWebViewBasePrivate.h"
39 #include "WebPageProxy.h"
40 #include "WebPopupMenuProxyGtk.h"
41 #include <WebCore/Cursor.h>
42 #include <WebCore/EventNames.h>
43 #include <WebCore/GtkUtilities.h>
44 #include <wtf/text/CString.h>
45 #include <wtf/text/WTFString.h>
46
47 using namespace WebCore;
48
49 namespace WebKit {
50
51 PageClientImpl::PageClientImpl(GtkWidget* viewWidget)
52     : m_viewWidget(viewWidget)
53 {
54 }
55
56 void PageClientImpl::getEditorCommandsForKeyEvent(const NativeWebKeyboardEvent& event, const AtomicString& eventType, Vector<WTF::String>& commandList)
57 {
58     ASSERT(eventType == eventNames().keydownEvent || eventType == eventNames().keypressEvent);
59
60     KeyBindingTranslator::EventType type = eventType == eventNames().keydownEvent ?
61         KeyBindingTranslator::KeyDown : KeyBindingTranslator::KeyPress;
62     m_keyBindingTranslator.getEditorCommandsForKeyEvent(const_cast<GdkEventKey*>(&event.nativeEvent()->key), type, commandList);
63 }
64
65 // PageClient's pure virtual functions
66 std::unique_ptr<DrawingAreaProxy> PageClientImpl::createDrawingAreaProxy()
67 {
68     return std::make_unique<DrawingAreaProxyImpl>(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(m_viewWidget)));
69 }
70
71 void PageClientImpl::setViewNeedsDisplay(const WebCore::IntRect& rect)
72 {
73     gtk_widget_queue_draw_area(m_viewWidget, rect.x(), rect.y(), rect.width(), rect.height());
74 }
75
76 void PageClientImpl::displayView()
77 {
78     notImplemented();
79 }
80
81 void PageClientImpl::scrollView(const WebCore::IntRect& scrollRect, const WebCore::IntSize& /* scrollOffset */)
82 {
83     setViewNeedsDisplay(scrollRect);
84 }
85
86 void PageClientImpl::requestScroll(const WebCore::FloatPoint&, bool)
87 {
88     notImplemented();
89 }
90
91 WebCore::IntSize PageClientImpl::viewSize()
92 {
93     if (!gtk_widget_get_realized(m_viewWidget))
94         return IntSize();
95     GtkAllocation allocation;
96     gtk_widget_get_allocation(m_viewWidget, &allocation);
97     return IntSize(allocation.width, allocation.height);
98 }
99
100 bool PageClientImpl::isViewWindowActive()
101 {
102     return webkitWebViewBaseIsInWindowActive(WEBKIT_WEB_VIEW_BASE(m_viewWidget));
103 }
104
105 bool PageClientImpl::isViewFocused()
106 {
107     return webkitWebViewBaseIsFocused(WEBKIT_WEB_VIEW_BASE(m_viewWidget));
108 }
109
110 bool PageClientImpl::isViewVisible()
111 {
112     return webkitWebViewBaseIsVisible(WEBKIT_WEB_VIEW_BASE(m_viewWidget));
113 }
114
115 bool PageClientImpl::isViewInWindow()
116 {
117     return webkitWebViewBaseIsInWindow(WEBKIT_WEB_VIEW_BASE(m_viewWidget));
118 }
119
120 void PageClientImpl::PageClientImpl::processDidExit()
121 {
122     notImplemented();
123 }
124
125 void PageClientImpl::didRelaunchProcess()
126 {
127     notImplemented();
128 }
129
130 void PageClientImpl::toolTipChanged(const String&, const String& newToolTip)
131 {
132     webkitWebViewBaseSetTooltipText(WEBKIT_WEB_VIEW_BASE(m_viewWidget), newToolTip.utf8().data());
133 }
134
135 void PageClientImpl::setCursor(const Cursor& cursor)
136 {
137     if (!gtk_widget_get_realized(m_viewWidget))
138         return;
139
140     // [GTK] Widget::setCursor() gets called frequently
141     // http://bugs.webkit.org/show_bug.cgi?id=16388
142     // Setting the cursor may be an expensive operation in some backends,
143     // so don't re-set the cursor if it's already set to the target value.
144     GdkWindow* window = gtk_widget_get_window(m_viewWidget);
145     GdkCursor* currentCursor = gdk_window_get_cursor(window);
146     GdkCursor* newCursor = cursor.platformCursor().get();
147     if (currentCursor != newCursor)
148         gdk_window_set_cursor(window, newCursor);
149 }
150
151 void PageClientImpl::setCursorHiddenUntilMouseMoves(bool /* hiddenUntilMouseMoves */)
152 {
153     notImplemented();
154 }
155
156 void PageClientImpl::didChangeViewportProperties(const WebCore::ViewportAttributes&)
157 {
158     notImplemented();
159 }
160
161 void PageClientImpl::registerEditCommand(PassRefPtr<WebEditCommandProxy> command, WebPageProxy::UndoOrRedo undoOrRedo)
162 {
163     m_undoController.registerEditCommand(command, undoOrRedo);
164 }
165
166 void PageClientImpl::clearAllEditCommands()
167 {
168     m_undoController.clearAllEditCommands();
169 }
170
171 bool PageClientImpl::canUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo)
172 {
173     return m_undoController.canUndoRedo(undoOrRedo);
174 }
175
176 void PageClientImpl::executeUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo)
177 {
178     m_undoController.executeUndoRedo(undoOrRedo);
179 }
180
181 FloatRect PageClientImpl::convertToDeviceSpace(const FloatRect& viewRect)
182 {
183     notImplemented();
184     return viewRect;
185 }
186
187 FloatRect PageClientImpl::convertToUserSpace(const FloatRect& viewRect)
188 {
189     notImplemented();
190     return viewRect;
191 }
192
193 IntPoint PageClientImpl::screenToRootView(const IntPoint& point)
194 {
195     IntPoint widgetPositionOnScreen = convertWidgetPointToScreenPoint(m_viewWidget, IntPoint());
196     IntPoint result(point);
197     result.move(-widgetPositionOnScreen.x(), -widgetPositionOnScreen.y());
198     return result;
199 }
200
201 IntRect PageClientImpl::rootViewToScreen(const IntRect& rect)
202 {
203     return IntRect(convertWidgetPointToScreenPoint(m_viewWidget, rect.location()), rect.size());
204 }
205
206 void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool wasEventHandled)
207 {
208     if (wasEventHandled)
209         return;
210     if (event.isFakeEventForComposition())
211         return;
212
213     WebKitWebViewBase* webkitWebViewBase = WEBKIT_WEB_VIEW_BASE(m_viewWidget);
214     webkitWebViewBaseForwardNextKeyEvent(webkitWebViewBase);
215     gtk_main_do_event(event.nativeEvent());
216 }
217
218 PassRefPtr<WebPopupMenuProxy> PageClientImpl::createPopupMenuProxy(WebPageProxy* page)
219 {
220     return WebPopupMenuProxyGtk::create(m_viewWidget, page);
221 }
222
223 PassRefPtr<WebContextMenuProxy> PageClientImpl::createContextMenuProxy(WebPageProxy* page)
224 {
225     return WebContextMenuProxyGtk::create(m_viewWidget, page);
226 }
227
228 #if ENABLE(INPUT_TYPE_COLOR)
229 PassRefPtr<WebColorPicker> PageClientImpl::createColorPicker(WebPageProxy*, const WebCore::Color&, const WebCore::IntRect&)
230 {
231     notImplemented();
232     return 0;
233 }
234 #endif
235
236 void PageClientImpl::setFindIndicator(PassRefPtr<FindIndicator>, bool /* fadeOut */, bool /* animate */)
237 {
238     notImplemented();
239 }
240
241 void PageClientImpl::enterAcceleratedCompositingMode(const LayerTreeContext&)
242 {
243     notImplemented();
244 }
245
246 void PageClientImpl::exitAcceleratedCompositingMode()
247 {
248     notImplemented();
249 }
250
251 void PageClientImpl::updateAcceleratedCompositingMode(const LayerTreeContext&)
252 {
253     notImplemented();
254 }
255
256 void PageClientImpl::pageClosed()
257 {
258     notImplemented();
259 }
260
261 void PageClientImpl::preferencesDidChange()
262 {
263     notImplemented();
264 }
265
266 void PageClientImpl::updateTextInputState()
267 {
268     webkitWebViewBaseUpdateTextInputState(WEBKIT_WEB_VIEW_BASE(m_viewWidget));
269 }
270
271 void PageClientImpl::startDrag(const WebCore::DragData& dragData, PassRefPtr<ShareableBitmap> dragImage)
272 {
273     webkitWebViewBaseStartDrag(WEBKIT_WEB_VIEW_BASE(m_viewWidget), dragData, dragImage);
274 }
275
276 void PageClientImpl::handleDownloadRequest(DownloadProxy* download)
277 {
278     webkitWebViewBaseHandleDownloadRequest(WEBKIT_WEB_VIEW_BASE(m_viewWidget), download);
279 }
280
281 void PageClientImpl::didCommitLoadForMainFrame(const String& /* mimeType */, bool /* useCustomContentProvider */ )
282 {
283     webkitWebViewBaseResetClickCounter(WEBKIT_WEB_VIEW_BASE(m_viewWidget));
284 }
285
286 #if ENABLE(FULLSCREEN_API)
287 WebFullScreenManagerProxyClient& PageClientImpl::fullScreenManagerProxyClient()
288 {
289     return *this;
290 }
291
292 void PageClientImpl::closeFullScreenManager()
293 {
294     notImplemented();
295 }
296
297 bool PageClientImpl::isFullScreen()
298 {
299     notImplemented();
300     return false;
301 }
302
303 void PageClientImpl::enterFullScreen()
304 {
305     if (!m_viewWidget)
306         return;
307
308     webkitWebViewBaseEnterFullScreen(WEBKIT_WEB_VIEW_BASE(m_viewWidget));
309 }
310
311 void PageClientImpl::exitFullScreen()
312 {
313     if (!m_viewWidget)
314         return;
315
316     webkitWebViewBaseExitFullScreen(WEBKIT_WEB_VIEW_BASE(m_viewWidget));
317 }
318
319 void PageClientImpl::beganEnterFullScreen(const IntRect& /* initialFrame */, const IntRect& /* finalFrame */)
320 {
321     notImplemented();
322 }
323
324 void PageClientImpl::beganExitFullScreen(const IntRect& /* initialFrame */, const IntRect& /* finalFrame */)
325 {
326     notImplemented();
327 }
328
329 #endif // ENABLE(FULLSCREEN_API)
330
331 void PageClientImpl::doneWithTouchEvent(const NativeWebTouchEvent& event, bool wasEventHandled)
332 {
333     if (wasEventHandled)
334         return;
335
336     // Emulate pointer events if unhandled.
337     const GdkEvent* touchEvent = event.nativeEvent();
338
339     if (!touchEvent->touch.emulating_pointer)
340         return;
341
342     GUniquePtr<GdkEvent> pointerEvent;
343
344     if (touchEvent->type == GDK_TOUCH_UPDATE) {
345         pointerEvent.reset(gdk_event_new(GDK_MOTION_NOTIFY));
346         pointerEvent->motion.time = touchEvent->touch.time;
347         pointerEvent->motion.x = touchEvent->touch.x;
348         pointerEvent->motion.y = touchEvent->touch.y;
349         pointerEvent->motion.x_root = touchEvent->touch.x_root;
350         pointerEvent->motion.y_root = touchEvent->touch.y_root;
351         pointerEvent->motion.state = touchEvent->touch.state | GDK_BUTTON1_MASK;
352     } else {
353         switch (touchEvent->type) {
354         case GDK_TOUCH_END:
355             pointerEvent.reset(gdk_event_new(GDK_BUTTON_RELEASE));
356             pointerEvent->button.state = touchEvent->touch.state | GDK_BUTTON1_MASK;
357             break;
358         case GDK_TOUCH_BEGIN:
359             pointerEvent.reset(gdk_event_new(GDK_BUTTON_PRESS));
360             break;
361         default:
362             ASSERT_NOT_REACHED();
363         }
364
365         pointerEvent->button.button = 1;
366         pointerEvent->button.time = touchEvent->touch.time;
367         pointerEvent->button.x = touchEvent->touch.x;
368         pointerEvent->button.y = touchEvent->touch.y;
369         pointerEvent->button.x_root = touchEvent->touch.x_root;
370         pointerEvent->button.y_root = touchEvent->touch.y_root;
371     }
372
373     gdk_event_set_device(pointerEvent.get(), gdk_event_get_device(touchEvent));
374     gdk_event_set_source_device(pointerEvent.get(), gdk_event_get_source_device(touchEvent));
375     pointerEvent->any.window = GDK_WINDOW(g_object_ref(touchEvent->any.window));
376     pointerEvent->any.send_event = TRUE;
377
378     gtk_widget_event(m_viewWidget, pointerEvent.get());
379 }
380
381 void PageClientImpl::didFinishLoadingDataForCustomContentProvider(const String&, const IPC::DataReference&)
382 {
383 }
384
385 void PageClientImpl::navigationGestureDidBegin()
386 {
387 }
388
389 void PageClientImpl::navigationGestureWillEnd(bool, WebBackForwardListItem&)
390 {
391 }
392
393 void PageClientImpl::navigationGestureDidEnd(bool, WebBackForwardListItem&)
394 {
395 }
396
397 } // namespace WebKit