[GTK] FullScreen signals
authorphiln@webkit.org <philn@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 22 Feb 2012 18:56:25 +0000 (18:56 +0000)
committerphiln@webkit.org <philn@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 22 Feb 2012 18:56:25 +0000 (18:56 +0000)
https://bugs.webkit.org/show_bug.cgi?id=76181

Reviewed by Martin Robinson.

Source/WebKit/gtk:

Added entering-fullscreen and leaving-fullscreen signals, meant to
be used by the user agent to be notified when an element requests
full screen display and when the full screen display is to be
disabled.

* WebCoreSupport/ChromeClientGtk.cpp:
(WebKit::ChromeClient::supportsFullScreenForElement):
(WebKit::onFullscreenGtkKeyPressEvent):
(WebKit::ChromeClient::cancelFullScreen):
(WebKit::ChromeClient::enterFullScreenForElement):
(WebKit::ChromeClient::exitFullScreenForElement):
* WebCoreSupport/ChromeClientGtk.h:
* tests/testwebview.c:
* webkit/webkitwebview.cpp:
(webkit_web_view_real_entering_fullscreen):
(webkit_web_view_real_leaving_fullscreen):
(webkit_web_view_class_init):
* webkit/webkitwebview.h:

Tools:

Use the two new entering/leaving fullscreen signals to hide/show
the tool bar, the status bar and ask the user's permission before
entering fullscreen.

* GtkLauncher/main.c:
(webViewFullscreenMessageWindowClose):
(webViewWindowStateEvent):
(hide_widget):
(show_widget):
(webViewEnteringFullScreen):
(webViewLeavingFullScreen):
(createBrowser):
(createWindow):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@108522 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit/gtk/ChangeLog
Source/WebKit/gtk/WebCoreSupport/ChromeClientGtk.cpp
Source/WebKit/gtk/WebCoreSupport/ChromeClientGtk.h
Source/WebKit/gtk/tests/testwebview.c
Source/WebKit/gtk/webkit/webkitwebview.cpp
Source/WebKit/gtk/webkit/webkitwebview.h
Tools/ChangeLog
Tools/GtkLauncher/main.c

index 6ae98e62f2b02de3497105a04af00d97d82006b6..477f024ac4ab6c5c7b47cbc1669abf6e1df89c6b 100644 (file)
@@ -1,3 +1,29 @@
+2012-02-20  Philippe Normand  <pnormand@igalia.com>
+
+        [GTK] FullScreen signals
+        https://bugs.webkit.org/show_bug.cgi?id=76181
+
+        Reviewed by Martin Robinson.
+
+        Added entering-fullscreen and leaving-fullscreen signals, meant to
+        be used by the user agent to be notified when an element requests
+        full screen display and when the full screen display is to be
+        disabled.
+
+        * WebCoreSupport/ChromeClientGtk.cpp:
+        (WebKit::ChromeClient::supportsFullScreenForElement):
+        (WebKit::onFullscreenGtkKeyPressEvent):
+        (WebKit::ChromeClient::cancelFullScreen):
+        (WebKit::ChromeClient::enterFullScreenForElement):
+        (WebKit::ChromeClient::exitFullScreenForElement):
+        * WebCoreSupport/ChromeClientGtk.h:
+        * tests/testwebview.c:
+        * webkit/webkitwebview.cpp:
+        (webkit_web_view_real_entering_fullscreen):
+        (webkit_web_view_real_leaving_fullscreen):
+        (webkit_web_view_class_init):
+        * webkit/webkitwebview.h:
+
 2012-02-22  Ryosuke Niwa  <rniwa@webkit.org>
 
         Remove the remaining uses of CSSStyleDeclaration in Editor
index 591a0928db47d2198fbdd17f7a817f6c44c0bfc6..adb238d7b1bbf9a3f56149af92ff963834693281 100644 (file)
@@ -51,6 +51,8 @@
 #include "RefPtrCairo.h"
 #include "SearchPopupMenuGtk.h"
 #include "SecurityOrigin.h"
+#include "WebKitDOMBinding.h"
+#include "WebKitDOMHTMLElementPrivate.h"
 #include "WindowFeatures.h"
 #include "webkitgeolocationpolicydecision.h"
 #include "webkitgeolocationpolicydecisionprivate.h"
@@ -61,6 +63,8 @@
 #include "webkitwebview.h"
 #include "webkitwebviewprivate.h"
 #include "webkitwebwindowfeaturesprivate.h"
+#include <gdk/gdk.h>
+#include <gdk/gdkkeysyms.h>
 #include <glib.h>
 #include <glib/gi18n-lib.h>
 #include <gtk/gtk.h>
@@ -921,29 +925,69 @@ void ChromeClient::exitFullscreenForNode(Node* node)
 #if ENABLE(FULLSCREEN_API)
 bool ChromeClient::supportsFullScreenForElement(const WebCore::Element* element, bool withKeyboard)
 {
-    return true;
+    return !withKeyboard;
+}
+
+static gboolean onFullscreenGtkKeyPressEvent(GtkWidget* widget, GdkEventKey* event, ChromeClient* chromeClient)
+{
+    switch (event->keyval) {
+    case GDK_KEY_Escape:
+    case GDK_KEY_f:
+    case GDK_KEY_F:
+        chromeClient->cancelFullScreen();
+        return TRUE;
+    default:
+        break;
+    }
+
+    return FALSE;
+}
+
+void ChromeClient::cancelFullScreen()
+{
+    ASSERT(m_fullScreenElement);
+    m_fullScreenElement->document()->webkitCancelFullScreen();
 }
 
 void ChromeClient::enterFullScreenForElement(WebCore::Element* element)
 {
+    gboolean returnValue;
+    GRefPtr<WebKitDOMHTMLElement> kitElement(adoptGRef(kit(reinterpret_cast<HTMLElement*>(element))));
+    g_signal_emit_by_name(m_webView, "entering-fullscreen", kitElement.get(), &returnValue);
+    if (returnValue)
+        return;
+
+    GtkWidget* window = gtk_widget_get_toplevel(GTK_WIDGET(m_webView));
+    if (!widgetIsOnscreenToplevelWindow(window))
+        return;
+
+    g_signal_connect(window, "key-press-event", G_CALLBACK(onFullscreenGtkKeyPressEvent), this);
+
+    m_fullScreenElement = adoptRef(element);
+
     element->document()->webkitWillEnterFullScreenForElement(element);
     m_adjustmentWatcher.disableAllScrollbars();
-#if ENABLE(VIDEO)
-    if (element->tagName() == "VIDEO")
-        enterFullscreenForNode(static_cast<Node*>(element));
-#endif
+    gtk_window_fullscreen(GTK_WINDOW(window));
     element->document()->webkitDidEnterFullScreenForElement(element);
 }
 
 void ChromeClient::exitFullScreenForElement(WebCore::Element* element)
 {
+    gboolean returnValue;
+    GRefPtr<WebKitDOMHTMLElement> kitElement(adoptGRef(kit(reinterpret_cast<HTMLElement*>(element))));
+    g_signal_emit_by_name(m_webView, "leaving-fullscreen", kitElement.get(), &returnValue);
+    if (returnValue)
+        return;
+
+    GtkWidget* window = gtk_widget_get_toplevel(GTK_WIDGET(m_webView));
+    ASSERT(widgetIsOnscreenToplevelWindow(window));
+    g_signal_handlers_disconnect_by_func(window, reinterpret_cast<void*>(onFullscreenGtkKeyPressEvent), this);
+
     element->document()->webkitWillExitFullScreenForElement(element);
+    gtk_window_unfullscreen(GTK_WINDOW(window));
     m_adjustmentWatcher.enableAllScrollbars();
-#if ENABLE(VIDEO)
-    if (element->tagName() == "VIDEO")
-        webViewExitFullscreen(m_webView);
-#endif
     element->document()->webkitDidExitFullScreenForElement(element);
+    m_fullScreenElement.clear();
 }
 #endif
 
index e4239e34a6a8b5102436c8e14d4b51c4c5d5724d..5905f567959316b915648e38d165c294cedd9706 100644 (file)
@@ -155,6 +155,7 @@ namespace WebKit {
         virtual bool supportsFullScreenForElement(const Element*, bool withKeyboard);
         virtual void enterFullScreenForElement(Element*);
         virtual void exitFullScreenForElement(Element*);
+        void cancelFullScreen();
 #endif
 
         virtual bool shouldRubberBandInDirection(ScrollDirection) const { return true; }
@@ -186,6 +187,9 @@ namespace WebKit {
         unsigned int m_repaintSoonSourceId;
 
         void invalidateWidgetRect(const IntRect&);
+#if ENABLE(FULLSCREEN_API)
+        RefPtr<Element> m_fullScreenElement;
+#endif
     };
 }
 
index ed6fec6ae9f9c51867bcef1152d0560b7f09f49e..ab3bd557632f7fa0cfbe103a2ca1684bc4a25242 100644 (file)
@@ -416,6 +416,87 @@ static void test_webkit_web_view_does_not_steal_focus()
     g_main_loop_unref(loop);
 }
 
+static gboolean emitKeyStroke(WebKitWebView* webView)
+{
+    GdkEvent* pressEvent = gdk_event_new(GDK_KEY_PRESS);
+    pressEvent->key.keyval = GDK_KEY_f;
+    GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(webView));
+    pressEvent->key.window = window;
+    g_object_ref(pressEvent->key.window);
+
+    GdkDeviceManager* manager = gdk_display_get_device_manager(gdk_window_get_display(window));
+    gdk_event_set_device(pressEvent, gdk_device_manager_get_client_pointer(manager));
+
+    // When synthesizing an event, an invalid hardware_keycode value
+    // can cause it to be badly processed by Gtk+.
+    GdkKeymapKey* keys;
+    gint n_keys;
+    if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), GDK_KEY_f, &keys, &n_keys)) {
+        pressEvent->key.hardware_keycode = keys[0].keycode;
+        g_free(keys);
+    }
+
+    GdkEvent* releaseEvent = gdk_event_copy(pressEvent);
+    gtk_main_do_event(pressEvent);
+    gdk_event_free(pressEvent);
+    releaseEvent->key.type = GDK_KEY_RELEASE;
+    gtk_main_do_event(releaseEvent);
+    gdk_event_free(releaseEvent);
+
+    return FALSE;
+}
+
+static gboolean entering_fullscreen_cb(WebKitWebView* webView, GObject* element, gboolean blocked)
+{
+    if (blocked)
+        g_main_loop_quit(loop);
+    else
+        g_timeout_add(200, (GSourceFunc) emitKeyStroke, webView);
+    return blocked;
+}
+
+static gboolean leaving_fullscreen_cb(WebKitWebView* webView, GObject* element, gpointer data)
+{
+    g_main_loop_quit(loop);
+    return FALSE;
+}
+
+static void test_webkit_web_view_fullscreen(gconstpointer blocked)
+{
+    GtkWidget* window;
+    GtkWidget* web_view;
+    WebKitWebSettings *settings;
+
+    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+    web_view = webkit_web_view_new();
+
+    settings = webkit_web_view_get_settings(WEBKIT_WEB_VIEW(web_view));
+    g_object_set(settings, "enable-fullscreen", TRUE, NULL);
+    webkit_web_view_set_settings(WEBKIT_WEB_VIEW(web_view), settings);
+
+    gtk_container_add(GTK_CONTAINER(window), web_view);
+
+    gtk_widget_show_all(window);
+
+    loop = g_main_loop_new(NULL, TRUE);
+
+    g_signal_connect(web_view, "entering-fullscreen", G_CALLBACK(entering_fullscreen_cb), (gpointer) blocked);
+    g_signal_connect(web_view, "leaving-fullscreen", G_CALLBACK(leaving_fullscreen_cb), NULL);
+
+    webkit_web_view_load_string(WEBKIT_WEB_VIEW(web_view), "<html><body>"
+                   "<script>"
+                   "var eventName = 'keypress';"
+                   "document.addEventListener(eventName, function () {"
+                   "    document.documentElement.webkitRequestFullScreen();"
+                   "}, false);"
+                   "</script></body></html>", NULL, NULL, NULL);
+
+    g_timeout_add(100, (GSourceFunc) emitKeyStroke, WEBKIT_WEB_VIEW(web_view));
+    g_main_loop_run(loop);
+
+    gtk_widget_destroy(window);
+}
+
 int main(int argc, char** argv)
 {
     SoupServer* server;
@@ -445,6 +526,8 @@ int main(int argc, char** argv)
     g_test_add_func("/webkit/webview/window-features", test_webkit_web_view_window_features);
     g_test_add_func("/webkit/webview/webview-in-offscreen-window-does-not-crash", test_webkit_web_view_in_offscreen_window_does_not_crash);
     g_test_add_func("/webkit/webview/webview-does-not-steal-focus", test_webkit_web_view_does_not_steal_focus);
+    g_test_add_data_func("/webkit/webview/fullscreen", GINT_TO_POINTER(FALSE), test_webkit_web_view_fullscreen);
+    g_test_add_data_func("/webkit/webview/fullscreen-blocked", GINT_TO_POINTER(TRUE), test_webkit_web_view_fullscreen);
 
     return g_test_run ();
 }
index 3cd3abff31a65b47a794bb3bd717cd14c21c7863..89b9c228fb93ca6b21160a6e9e795e4e48ea9a0b 100644 (file)
@@ -212,6 +212,8 @@ enum {
     RESOURCE_LOAD_FINISHED,
     RESOURCE_CONTENT_LENGTH_RECEIVED,
     RESOURCE_LOAD_FAILED,
+    ENTERING_FULLSCREEN,
+    LEAVING_FULLSCREEN,
 
     LAST_SIGNAL
 };
@@ -1300,6 +1302,16 @@ static gboolean webkit_web_view_real_should_allow_editing_action(WebKitWebView*)
     return TRUE;
 }
 
+static gboolean webkit_web_view_real_entering_fullscreen(WebKitWebView* webView)
+{
+    return FALSE;
+}
+
+static gboolean webkit_web_view_real_leaving_fullscreen(WebKitWebView* webView)
+{
+    return FALSE;
+}
+
 static void webkit_web_view_dispose(GObject* object)
 {
     WebKitWebView* webView = WEBKIT_WEB_VIEW(object);
@@ -2655,6 +2667,59 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
             G_TYPE_NONE, 1,
             WEBKIT_TYPE_VIEWPORT_ATTRIBUTES);
 
+    /**
+     * WebKitWebView::entering-fullscreen:
+     * @web_view: the #WebKitWebView on which the signal is emitted.
+     * @element: the #WebKitDOMHTMLElement which has requested full screen display.
+     *
+     * Emitted when JavaScript code calls
+     * <function>element.webkitRequestFullScreen</function>. If the
+     * signal is not handled the WebView will proceed to full screen
+     * its top level window. This signal can be used by client code to
+     * request permission to the user prior doing the full screen
+     * transition and eventually prepare the top-level window
+     * (e.g. hide some widgets that would otherwise be part of the
+     * full screen window).
+     *
+     * Returns: %TRUE to stop other handlers from being invoked for the event.
+     *    %FALSE to continue emission of the event.
+     *
+     * Since: 1.9.0
+     */
+    webkit_web_view_signals[ENTERING_FULLSCREEN] =
+            g_signal_new("entering-fullscreen",
+                         G_TYPE_FROM_CLASS(webViewClass),
+                         G_SIGNAL_RUN_LAST,
+                         G_STRUCT_OFFSET(WebKitWebViewClass, entering_fullscreen),
+                         g_signal_accumulator_true_handled, 0,
+                         webkit_marshal_BOOLEAN__OBJECT,
+                         G_TYPE_BOOLEAN, 1, WEBKIT_TYPE_DOM_HTML_ELEMENT);
+
+
+    /**
+     * WebKitWebView::leaving-fullscreen:
+     * @web_view: the #WebKitWebView on which the signal is emitted.
+     * @element: the #WebKitDOMHTMLElement which is currently displayed full screen.
+     *
+     * Emitted when the WebView is about to restore its top level
+     * window out of its full screen state. This signal can be used by
+     * client code to restore widgets hidden during the
+     * entering-fullscreen stage for instance.
+     *
+     * Returns: %TRUE to stop other handlers from being invoked for the event.
+     *    %FALSE to continue emission of the event.
+     *
+     * Since: 1.9.0
+     */
+    webkit_web_view_signals[LEAVING_FULLSCREEN] =
+            g_signal_new("leaving-fullscreen",
+                         G_TYPE_FROM_CLASS(webViewClass),
+                         G_SIGNAL_RUN_LAST,
+                         G_STRUCT_OFFSET(WebKitWebViewClass, leaving_fullscreen),
+                         g_signal_accumulator_true_handled, 0,
+                         webkit_marshal_BOOLEAN__OBJECT,
+                         G_TYPE_BOOLEAN, 1, WEBKIT_TYPE_DOM_HTML_ELEMENT);
+
     /*
      * WebKitWebView::resource-response-received
      * @webView: the object which received the signal
@@ -2763,6 +2828,8 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
     webViewClass->redo = webkit_web_view_real_redo;
     webViewClass->move_cursor = webkit_web_view_real_move_cursor;
     webViewClass->should_allow_editing_action = webkit_web_view_real_should_allow_editing_action;
+    webViewClass->entering_fullscreen = webkit_web_view_real_entering_fullscreen;
+    webViewClass->leaving_fullscreen = webkit_web_view_real_leaving_fullscreen;
 
     GObjectClass* objectClass = G_OBJECT_CLASS(webViewClass);
     objectClass->dispose = webkit_web_view_dispose;
index 678e3296622e2d0516ec6cc65e2031fc2b624dd6..2a15b53c67689cf6e7031ec8d93d45be612d44f4 100644 (file)
@@ -176,11 +176,11 @@ struct _WebKitWebViewClass {
     void                       (* undo)                   (WebKitWebView        *web_view);
     void                       (* redo)                   (WebKitWebView        *web_view);
     gboolean                   (* should_allow_editing_action) (WebKitWebView   *web_view);
+    gboolean                   (* entering_fullscreen) (WebKitWebView   *web_view);
+    gboolean                   (* leaving_fullscreen) (WebKitWebView   *web_view);
 
     /* Padding for future expansion */
     void (*_webkit_reserved0) (void);
-    void (*_webkit_reserved1) (void);
-    void (*_webkit_reserved2) (void);
 };
 
 WEBKIT_API GType
index ff2c57a16d414adbb9249a3bc94fed869ca646ff..5582eff020113de0fda8a17ca559668c9a2c5184 100644 (file)
@@ -1,3 +1,24 @@
+2012-02-20  Philippe Normand  <pnormand@igalia.com>
+
+        [GTK] FullScreen signals
+        https://bugs.webkit.org/show_bug.cgi?id=76181
+
+        Reviewed by Martin Robinson.
+
+        Use the two new entering/leaving fullscreen signals to hide/show
+        the tool bar, the status bar and ask the user's permission before
+        entering fullscreen.
+
+        * GtkLauncher/main.c:
+        (webViewFullscreenMessageWindowClose):
+        (webViewWindowStateEvent):
+        (hide_widget):
+        (show_widget):
+        (webViewEnteringFullScreen):
+        (webViewLeavingFullScreen):
+        (createBrowser):
+        (createWindow):
+
 2012-02-22  Rob Flack  <flackr@chromium.org>
 
         Update Linux ChromiumOS builders in flakiness dashboard.
index e3a66b03e923e1e1841cd6b8a8c2992ce12a16a1..587405fc4234f1d7be8a73c913ede2bdbce4b711 100644 (file)
@@ -123,7 +123,79 @@ static gboolean closeWebViewCb(WebKitWebView* webView, GtkWidget* window)
     return TRUE;
 }
 
-static GtkWidget* createBrowser(GtkWidget* window, GtkWidget* uriEntry, GtkWidget* statusbar, WebKitWebView* webView)
+static gboolean webViewFullscreenMessageWindowClose(GtkWidget *dialog)
+{
+    if (GTK_IS_WIDGET(dialog))
+        gtk_widget_destroy(dialog);
+    return FALSE;
+}
+
+static gboolean webViewWindowStateEvent(GtkWidget *widget, GdkEventWindowState *event, WebKitWebView *webView)
+{
+    if (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN) {
+        WebKitWebFrame *frame = webkit_web_view_get_main_frame(webView);
+        const gchar *uri = webkit_web_frame_get_uri(frame);
+        GtkWidget *window = gtk_widget_get_toplevel(GTK_WIDGET(webView));
+        if (!gtk_widget_is_toplevel(window) || !GTK_IS_WINDOW(window) || GTK_IS_OFFSCREEN_WINDOW(window))
+            window = 0;
+
+        GtkWidget *dialog = gtk_message_dialog_new(window ? GTK_WINDOW(window) : 0,
+                                                    GTK_DIALOG_MODAL,
+                                                    GTK_MESSAGE_INFO,
+                                                    GTK_BUTTONS_CLOSE,
+                                                    "%s is now full screen. Press ESC or f to exit.", uri);
+        g_signal_connect_swapped(dialog, "response", G_CALLBACK(gtk_widget_destroy), dialog);
+        g_timeout_add(1500, (GSourceFunc) webViewFullscreenMessageWindowClose, dialog);
+        gtk_dialog_run(GTK_DIALOG(dialog));
+    }
+    return TRUE;
+}
+
+static void hideWidget(GtkWidget* widget, gpointer data)
+{
+    if (!GTK_IS_SCROLLED_WINDOW(widget))
+        gtk_widget_hide(widget);
+}
+
+static void showWidget(GtkWidget* widget, gpointer data)
+{
+    if (!GTK_IS_SCROLLED_WINDOW(widget))
+        gtk_widget_show(widget);
+}
+
+static gboolean webViewEnteringFullScreen(WebKitWebView *webView, GObject *element, GtkWidget* vbox)
+{
+    WebKitWebFrame *frame = webkit_web_view_get_main_frame(webView);
+    const gchar *uri = webkit_web_frame_get_uri(frame);
+    GtkWidget *window = gtk_widget_get_toplevel(GTK_WIDGET(webView));
+    if (!gtk_widget_is_toplevel(window) || !GTK_IS_WINDOW(window) || GTK_IS_OFFSCREEN_WINDOW(window))
+        window = 0;
+
+    GtkWidget *dialog = gtk_message_dialog_new(window ? GTK_WINDOW(window) : 0,
+                                               GTK_DIALOG_MODAL,
+                                               GTK_MESSAGE_INFO,
+                                               GTK_BUTTONS_YES_NO,
+                                               "Allow full screen display of %s ?", uri);
+    gint result = gtk_dialog_run(GTK_DIALOG(dialog));
+    if (result == GTK_RESPONSE_YES) {
+        gtk_container_foreach(GTK_CONTAINER(vbox), (GtkCallback) hideWidget, NULL);
+        gtk_widget_destroy(GTK_WIDGET(dialog));
+        return FALSE;
+    }
+    gtk_widget_destroy(GTK_WIDGET(dialog));
+    return TRUE;
+}
+
+static gboolean webViewLeavingFullScreen(WebKitWebView *webView, GObject *element, GtkWidget* vbox)
+{
+    GtkWidget *window = gtk_widget_get_toplevel(GTK_WIDGET(webView));
+    if (gtk_widget_is_toplevel(window) && GTK_IS_WINDOW(window) && !GTK_IS_OFFSCREEN_WINDOW(window))
+        g_signal_handlers_disconnect_by_func(window, G_CALLBACK(webViewWindowStateEvent), webView);
+    gtk_container_foreach(GTK_CONTAINER(vbox), (GtkCallback) showWidget, NULL);
+    return FALSE;
+}
+
+static GtkWidget* createBrowser(GtkWidget* window, GtkWidget* uriEntry, GtkWidget* statusbar, WebKitWebView* webView, GtkWidget* vbox)
 {
     GtkWidget *scrolledWindow = gtk_scrolled_window_new(NULL, NULL);
     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledWindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
@@ -137,6 +209,8 @@ static GtkWidget* createBrowser(GtkWidget* window, GtkWidget* uriEntry, GtkWidge
     g_signal_connect(webView, "create-web-view", G_CALLBACK(createWebViewCb), window);
     g_signal_connect(webView, "web-view-ready", G_CALLBACK(webViewReadyCb), window);
     g_signal_connect(webView, "close-web-view", G_CALLBACK(closeWebViewCb), window);
+    g_signal_connect(webView, "entering-fullscreen", G_CALLBACK(webViewEnteringFullScreen), vbox);
+    g_signal_connect(webView, "leaving-fullscreen", G_CALLBACK(webViewLeavingFullScreen), vbox);
 
     return scrolledWindow;
 }
@@ -214,7 +288,7 @@ static GtkWidget* createWindow(WebKitWebView** outWebView)
 #endif
     statusbar = createStatusbar(webView);
     gtk_box_pack_start(GTK_BOX(vbox), createToolbar(uriEntry, webView), FALSE, FALSE, 0);
-    gtk_box_pack_start(GTK_BOX(vbox), createBrowser(window, uriEntry, statusbar, webView), TRUE, TRUE, 0);
+    gtk_box_pack_start(GTK_BOX(vbox), createBrowser(window, uriEntry, statusbar, webView, vbox), TRUE, TRUE, 0);
     gtk_box_pack_start(GTK_BOX(vbox), statusbar, FALSE, FALSE, 0);
 
     gtk_container_add(GTK_CONTAINER(window), vbox);