diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2012-09-24 13:09:44 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2012-09-24 13:09:44 +0200 |
commit | dc6262b587c71c14e30d93e57ed812e36a79a33e (patch) | |
tree | 03ff986e7aa38bba0c0ef374f44fda52aff93f01 /Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp | |
parent | 02e1fbbefd49229b102ef107bd70ce974a2d85fb (diff) | |
download | qtwebkit-dc6262b587c71c14e30d93e57ed812e36a79a33e.tar.gz |
Imported WebKit commit 6339232fec7f5d9984a33388aecfd2cbc7832053 (http://svn.webkit.org/repository/webkit/trunk@129343)
New snapshot with build fixes for latest qtbase
Diffstat (limited to 'Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp')
-rw-r--r-- | Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp | 200 |
1 files changed, 162 insertions, 38 deletions
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp index 23b02f649..5338e2bd3 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp @@ -79,7 +79,6 @@ struct _WebKitWebViewBasePrivate { WebKitWebViewChildrenMap children; OwnPtr<PageClientImpl> pageClient; RefPtr<WebPageProxy> pageProxy; - bool isPageActive; bool shouldForwardNextKeyEvent; GRefPtr<GtkIMContext> imContext; GtkClickCounter clickCounter; @@ -95,6 +94,16 @@ struct _WebKitWebViewBasePrivate { GOwnPtr<GdkEvent> contextMenuEvent; WebContextMenuProxyGtk* activeContextMenuProxy; + GtkWindow* toplevelOnScreenWindow; + unsigned long toplevelResizeGripVisibilityID; + unsigned long toplevelFocusInEventID; + unsigned long toplevelFocusOutEventID; + + // View State. + bool isInWindowActive : 1; + bool isFocused : 1; + bool isVisible : 1; + #if ENABLE(FULLSCREEN_API) bool fullScreenModeActive; WebFullScreenClientGtk fullScreenClient; @@ -108,30 +117,93 @@ struct _WebKitWebViewBasePrivate { G_DEFINE_TYPE(WebKitWebViewBase, webkit_web_view_base, GTK_TYPE_CONTAINER) -static void webkitWebViewBaseNotifyResizerSizeForWindow(WebKitWebViewBase* webViewBase, GtkWindow* window) +static void webkitWebViewBaseNotifyResizerSize(WebKitWebViewBase* webViewBase) { + WebKitWebViewBasePrivate* priv = webViewBase->priv; + if (!priv->toplevelOnScreenWindow) + return; + gboolean resizerVisible; - g_object_get(G_OBJECT(window), "resize-grip-visible", &resizerVisible, NULL); + g_object_get(G_OBJECT(priv->toplevelOnScreenWindow), "resize-grip-visible", &resizerVisible, NULL); IntSize resizerSize; if (resizerVisible) { GdkRectangle resizerRect; - gtk_window_get_resize_grip_area(window, &resizerRect); + gtk_window_get_resize_grip_area(priv->toplevelOnScreenWindow, &resizerRect); GdkRectangle allocation; gtk_widget_get_allocation(GTK_WIDGET(webViewBase), &allocation); if (gdk_rectangle_intersect(&resizerRect, &allocation, 0)) resizerSize = IntSize(resizerRect.width, resizerRect.height); } - if (resizerSize != webViewBase->priv->resizerSize) { - webViewBase->priv->resizerSize = resizerSize; - webViewBase->priv->pageProxy->setWindowResizerSize(resizerSize); + if (resizerSize != priv->resizerSize) { + priv->resizerSize = resizerSize; + priv->pageProxy->setWindowResizerSize(resizerSize); + } +} + +static void toplevelWindowResizeGripVisibilityChanged(GObject*, GParamSpec*, WebKitWebViewBase* webViewBase) +{ + webkitWebViewBaseNotifyResizerSize(webViewBase); +} + +static gboolean toplevelWindowFocusInEvent(GtkWidget* widget, GdkEventFocus*, WebKitWebViewBase* webViewBase) +{ + WebKitWebViewBasePrivate* priv = webViewBase->priv; + if (!priv->isInWindowActive) { + priv->isInWindowActive = true; + priv->pageProxy->viewStateDidChange(WebPageProxy::ViewWindowIsActive); + } + + return FALSE; +} + +static gboolean toplevelWindowFocusOutEvent(GtkWidget* widget, GdkEventFocus*, WebKitWebViewBase* webViewBase) +{ + WebKitWebViewBasePrivate* priv = webViewBase->priv; + if (priv->isInWindowActive) { + priv->isInWindowActive = false; + priv->pageProxy->viewStateDidChange(WebPageProxy::ViewWindowIsActive); } + + return FALSE; } -static void toplevelWindowResizeGripVisibilityChanged(GObject* object, GParamSpec*, WebKitWebViewBase* webViewBase) +static void webkitWebViewBaseSetToplevelOnScreenWindow(WebKitWebViewBase* webViewBase, GtkWindow* window) { - webkitWebViewBaseNotifyResizerSizeForWindow(webViewBase, GTK_WINDOW(object)); + WebKitWebViewBasePrivate* priv = webViewBase->priv; + if (priv->toplevelOnScreenWindow == window) + return; + + if (priv->toplevelResizeGripVisibilityID) { + g_signal_handler_disconnect(priv->toplevelOnScreenWindow, priv->toplevelResizeGripVisibilityID); + priv->toplevelResizeGripVisibilityID = 0; + } + if (priv->toplevelFocusInEventID) { + g_signal_handler_disconnect(priv->toplevelOnScreenWindow, priv->toplevelFocusInEventID); + priv->toplevelFocusInEventID = 0; + } + if (priv->toplevelFocusOutEventID) { + g_signal_handler_disconnect(priv->toplevelOnScreenWindow, priv->toplevelFocusOutEventID); + priv->toplevelFocusOutEventID = 0; + } + + priv->toplevelOnScreenWindow = window; + priv->pageProxy->viewStateDidChange(WebPageProxy::ViewIsInWindow); + if (!priv->toplevelOnScreenWindow) + return; + + webkitWebViewBaseNotifyResizerSize(webViewBase); + + priv->toplevelResizeGripVisibilityID = + g_signal_connect(priv->toplevelOnScreenWindow, "notify::resize-grip-visible", + G_CALLBACK(toplevelWindowResizeGripVisibilityChanged), webViewBase); + priv->toplevelFocusInEventID = + g_signal_connect(priv->toplevelOnScreenWindow, "focus-in-event", + G_CALLBACK(toplevelWindowFocusInEvent), webViewBase); + priv->toplevelFocusOutEventID = + g_signal_connect(priv->toplevelOnScreenWindow, "focus-out-event", + G_CALLBACK(toplevelWindowFocusOutEvent), webViewBase); } static void webkitWebViewBaseRealize(GtkWidget* widget) @@ -178,11 +250,8 @@ static void webkitWebViewBaseRealize(GtkWidget* widget) gtk_im_context_set_client_window(priv->imContext.get(), window); GtkWidget* toplevel = gtk_widget_get_toplevel(widget); - if (widgetIsOnscreenToplevelWindow(toplevel)) { - webkitWebViewBaseNotifyResizerSizeForWindow(webView, GTK_WINDOW(toplevel)); - g_signal_connect(toplevel, "notify::resize-grip-visible", - G_CALLBACK(toplevelWindowResizeGripVisibilityChanged), webView); - } + if (widgetIsOnscreenToplevelWindow(toplevel)) + webkitWebViewBaseSetToplevelOnScreenWindow(webView, GTK_WINDOW(toplevel)); } static void webkitWebViewBaseContainerAdd(GtkContainer* container, GtkWidget* widget) @@ -251,9 +320,12 @@ void webkitWebViewBaseChildMoveResize(WebKitWebViewBase* webView, GtkWidget* chi static void webkitWebViewBaseFinalize(GObject* gobject) { WebKitWebViewBase* webkitWebViewBase = WEBKIT_WEB_VIEW_BASE(gobject); - webkitWebViewBase->priv->pageProxy->close(); + WebKitWebViewBasePrivate* priv = webkitWebViewBase->priv; + priv->pageProxy->close(); + + webkitWebViewBaseSetToplevelOnScreenWindow(webkitWebViewBase, 0); - webkitWebViewBase->priv->~WebKitWebViewBasePrivate(); + priv->~WebKitWebViewBasePrivate(); G_OBJECT_CLASS(webkit_web_view_base_parent_class)->finalize(gobject); } @@ -263,7 +335,6 @@ static void webkit_web_view_base_init(WebKitWebViewBase* webkitWebViewBase) webkitWebViewBase->priv = priv; new (priv) WebKitWebViewBasePrivate(); - priv->isPageActive = TRUE; priv->shouldForwardNextKeyEvent = FALSE; GtkWidget* viewWidget = GTK_WIDGET(webkitWebViewBase); @@ -366,9 +437,7 @@ static void resizeWebKitWebViewBaseFromAllocation(WebKitWebViewBase* webViewBase if (priv->pageProxy->drawingArea()) priv->pageProxy->drawingArea()->setSize(viewRect.size(), IntSize()); - GtkWidget* toplevel = gtk_widget_get_toplevel(GTK_WIDGET(webViewBase)); - if (widgetIsOnscreenToplevelWindow(toplevel)) - webkitWebViewBaseNotifyResizerSizeForWindow(webViewBase, GTK_WINDOW(toplevel)); + webkitWebViewBaseNotifyResizerSize(webViewBase); } static void webkitWebViewBaseSizeAllocate(GtkWidget* widget, GtkAllocation* allocation) @@ -392,28 +461,37 @@ static void webkitWebViewBaseMap(GtkWidget* widget) GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->map(widget); WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); - if (!webViewBase->priv->needsResizeOnMap) + WebKitWebViewBasePrivate* priv = webViewBase->priv; + if (!priv->isVisible) { + priv->isVisible = true; + priv->pageProxy->viewStateDidChange(WebPageProxy::ViewIsVisible); + } + + if (!priv->needsResizeOnMap) return; GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); resizeWebKitWebViewBaseFromAllocation(webViewBase, &allocation, true /* sizeChanged */); - webViewBase->priv->needsResizeOnMap = false; + priv->needsResizeOnMap = false; } -static gboolean webkitWebViewBaseFocusInEvent(GtkWidget* widget, GdkEventFocus* event) +static void webkitWebViewBaseUnmap(GtkWidget* widget) { - WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); - WebKitWebViewBasePrivate* priv = webViewBase->priv; + GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->unmap(widget); - GtkWidget* toplevel = gtk_widget_get_toplevel(widget); - if (widgetIsOnscreenToplevelWindow(toplevel) && gtk_window_has_toplevel_focus(GTK_WINDOW(toplevel))) { - gtk_im_context_focus_in(priv->imContext.get()); - if (!priv->isPageActive) { - priv->isPageActive = TRUE; - priv->pageProxy->viewStateDidChange(WebPageProxy::ViewWindowIsActive); - } + WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv; + if (priv->isVisible) { + priv->isVisible = false; + priv->pageProxy->viewStateDidChange(WebPageProxy::ViewIsVisible); } +} + +static gboolean webkitWebViewBaseFocusInEvent(GtkWidget* widget, GdkEventFocus* event) +{ + WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); + webkitWebViewBaseSetFocus(webViewBase, true); + gtk_im_context_focus_in(webViewBase->priv->imContext.get()); return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->focus_in_event(widget, event); } @@ -421,12 +499,8 @@ static gboolean webkitWebViewBaseFocusInEvent(GtkWidget* widget, GdkEventFocus* static gboolean webkitWebViewBaseFocusOutEvent(GtkWidget* widget, GdkEventFocus* event) { WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); - WebKitWebViewBasePrivate* priv = webViewBase->priv; - - priv->isPageActive = FALSE; - priv->pageProxy->viewStateDidChange(WebPageProxy::ViewWindowIsActive); - if (priv->imContext) - gtk_im_context_focus_out(priv->imContext.get()); + webkitWebViewBaseSetFocus(webViewBase, false); + gtk_im_context_focus_out(webViewBase->priv->imContext.get()); return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->focus_out_event(widget, event); } @@ -654,6 +728,13 @@ static gboolean webkitWebViewBaseDragDrop(GtkWidget* widget, GdkDragContext* con return TRUE; } +static void webkitWebViewBaseParentSet(GtkWidget* widget, GtkWidget* oldParent) +{ + if (!gtk_widget_get_parent(widget)) + webkitWebViewBaseSetToplevelOnScreenWindow(WEBKIT_WEB_VIEW_BASE(widget), 0); + +} + static void webkit_web_view_base_class_init(WebKitWebViewBaseClass* webkitWebViewBaseClass) { GtkWidgetClass* widgetClass = GTK_WIDGET_CLASS(webkitWebViewBaseClass); @@ -661,6 +742,7 @@ static void webkit_web_view_base_class_init(WebKitWebViewBaseClass* webkitWebVie widgetClass->draw = webkitWebViewBaseDraw; widgetClass->size_allocate = webkitWebViewBaseSizeAllocate; widgetClass->map = webkitWebViewBaseMap; + widgetClass->unmap = webkitWebViewBaseUnmap; widgetClass->focus_in_event = webkitWebViewBaseFocusInEvent; widgetClass->focus_out_event = webkitWebViewBaseFocusOutEvent; widgetClass->key_press_event = webkitWebViewBaseKeyPressEvent; @@ -677,6 +759,7 @@ static void webkit_web_view_base_class_init(WebKitWebViewBaseClass* webkitWebVie widgetClass->drag_drop = webkitWebViewBaseDragDrop; widgetClass->drag_data_received = webkitWebViewBaseDragDataReceived; widgetClass->get_accessible = webkitWebViewBaseGetAccessible; + widgetClass->parent_set = webkitWebViewBaseParentSet; GObjectClass* gobjectClass = G_OBJECT_CLASS(webkitWebViewBaseClass); gobjectClass->finalize = webkitWebViewBaseFinalize; @@ -878,3 +961,44 @@ void webkitWebViewBaseQueueDrawOfAcceleratedCompositingResults(WebKitWebViewBase g_timeout_add(1000 / 60, reinterpret_cast<GSourceFunc>(queueAnotherDrawOfAcceleratedCompositingResults), webViewBasePointer); } #endif + +void webkitWebViewBaseSetFocus(WebKitWebViewBase* webViewBase, bool focused) +{ + WebKitWebViewBasePrivate* priv = webViewBase->priv; + if (priv->isFocused == focused) + return; + + unsigned viewStateFlags = WebPageProxy::ViewIsFocused; + priv->isFocused = focused; + + // If the view has received the focus and the window is not active + // mark the current window as active now. This can happen if the + // toplevel window is a GTK_WINDOW_POPUP and the focus has been + // set programatically like WebKitTestRunner does, because POPUP + // can't be focused. + if (priv->isFocused && !priv->isInWindowActive) { + priv->isInWindowActive = true; + viewStateFlags |= WebPageProxy::ViewWindowIsActive; + } + priv->pageProxy->viewStateDidChange(viewStateFlags); +} + +bool webkitWebViewBaseIsInWindowActive(WebKitWebViewBase* webViewBase) +{ + return webViewBase->priv->isInWindowActive; +} + +bool webkitWebViewBaseIsFocused(WebKitWebViewBase* webViewBase) +{ + return webViewBase->priv->isFocused; +} + +bool webkitWebViewBaseIsVisible(WebKitWebViewBase* webViewBase) +{ + return webViewBase->priv->isVisible; +} + +bool webkitWebViewBaseIsInWindow(WebKitWebViewBase* webViewBase) +{ + return webViewBase->priv->toplevelOnScreenWindow; +} |