summaryrefslogtreecommitdiff
path: root/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2012-09-24 13:09:44 +0200
committerSimon Hausmann <simon.hausmann@digia.com>2012-09-24 13:09:44 +0200
commitdc6262b587c71c14e30d93e57ed812e36a79a33e (patch)
tree03ff986e7aa38bba0c0ef374f44fda52aff93f01 /Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp
parent02e1fbbefd49229b102ef107bd70ce974a2d85fb (diff)
downloadqtwebkit-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.cpp200
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;
+}