/*
 * Copyright (C) 2010 Apple Inc. All rights reserved.
 * Portions Copyright (c) 2010 Motorola Mobility, Inc.  All rights reserved.
 * Copyright (C) 2013 Gustavo Noronha Silva <gns@gnome.org>.
 * Copyright (C) 2011, 2020 Igalia S.L.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "WebKitWebViewBase.h"

#include "APIPageConfiguration.h"
#include "AcceleratedBackingStore.h"
#include "DragSource.h"
#include "DrawingAreaProxyCoordinatedGraphics.h"
#include "DropTarget.h"
#include "InputMethodFilter.h"
#include "KeyBindingTranslator.h"
#include "NativeWebKeyboardEvent.h"
#include "NativeWebMouseEvent.h"
#include "NativeWebWheelEvent.h"
#include "PageClientImpl.h"
#include "PointerLockManager.h"
#include "ViewGestureController.h"
#include "WebEventFactory.h"
#include "WebInspectorUIProxy.h"
#include "WebKit2Initialize.h"
#include "WebKitEmojiChooser.h"
#include "WebKitInitialize.h"
#include "WebKitInputMethodContextImplGtk.h"
#include "WebKitWebViewAccessible.h"
#include "WebKitWebViewBaseInternal.h"
#include "WebKitWebViewBasePrivate.h"
#include "WebPageGroup.h"
#include "WebPageProxy.h"
#include "WebPopupMenuProxyGtk.h"
#include "WebPreferences.h"
#include "WebProcessPool.h"
#include "WebUserContentControllerProxy.h"
#include <WebCore/ActivityState.h>
#include <WebCore/CairoUtilities.h>
#include <WebCore/GUniquePtrGtk.h>
#include <WebCore/GtkUtilities.h>
#include <WebCore/GtkVersioning.h>
#include <WebCore/NotImplemented.h>
#include <WebCore/PlatformDisplay.h>
#include <WebCore/PlatformKeyboardEvent.h>
#include <WebCore/PointerEvent.h>
#include <WebCore/RefPtrCairo.h>
#include <WebCore/Region.h>
#include <gdk/gdk.h>
#include <gdk/gdkkeysyms.h>
#include <glib/gi18n-lib.h>
#include <memory>
#include <pal/system/SleepDisabler.h>
#include <wtf/Compiler.h>
#include <wtf/HashMap.h>
#include <wtf/MathExtras.h>
#include <wtf/glib/GRefPtr.h>
#include <wtf/glib/RunLoopSourcePriority.h>
#include <wtf/glib/WTFGType.h>
#include <wtf/text/CString.h>

#if ENABLE(FULLSCREEN_API)
#include "WebFullScreenManagerProxy.h"
#endif

using namespace WebKit;
using namespace WebCore;

#if !USE(GTK4)
struct ClickCounter {
public:
    void reset()
    {
        currentClickCount = 0;
        previousClickPoint = IntPoint();
        previousClickTime = 0;
        previousClickButton = 0;
    }

    int currentClickCountForGdkButtonEvent(GdkEvent* event)
    {
        int doubleClickDistance = 250;
        int doubleClickTime = 5;
        g_object_get(gtk_settings_get_for_screen(gdk_event_get_screen(event)),
            "gtk-double-click-distance", &doubleClickDistance, "gtk-double-click-time", &doubleClickTime, nullptr);

        // GTK+ only counts up to triple clicks, but WebCore wants to know about
        // quadruple clicks, quintuple clicks, ad infinitum. Here, we replicate the
        // GDK logic for counting clicks.
        guint32 eventTime = gdk_event_get_time(event);
        if (!eventTime) {
            // Real events always have a non-zero time, but events synthesized
            // by the WTR do not and we must calculate a time manually. This time
            // is not calculated in the WTR, because GTK+ does not work well with
            // anything other than GDK_CURRENT_TIME on synthesized events.
            eventTime = g_get_monotonic_time() / 1000;
        }

        GdkEventType type;
        guint button;
        double x, y;
        gdk_event_get_coords(event, &x, &y);
        gdk_event_get_button(event, &button);
        type = gdk_event_get_event_type(event);

        if ((type == GDK_2BUTTON_PRESS || type == GDK_3BUTTON_PRESS)
            || ((std::abs(x - previousClickPoint.x()) < doubleClickDistance)
                && (std::abs(y - previousClickPoint.y()) < doubleClickDistance)
                && (eventTime - previousClickTime < static_cast<unsigned>(doubleClickTime))
                && (button == previousClickButton)))
            currentClickCount++;
        else
            currentClickCount = 1;

        previousClickPoint = IntPoint(x, y);
        previousClickButton = button;
        previousClickTime = eventTime;

        return currentClickCount;
    }

private:
    int currentClickCount;
    IntPoint previousClickPoint;
    unsigned previousClickButton;
    int previousClickTime;
};
#endif

struct MotionEvent {
    MotionEvent(const FloatPoint& position, const FloatPoint& globalPosition, WebMouseEvent::Button button, unsigned short buttons, OptionSet<WebEvent::Modifier> modifiers)
        : position(position)
        , globalPosition(globalPosition)
        , button(button)
        , buttons(buttons)
        , modifiers(modifiers)
    {
    }

    MotionEvent(GtkWidget* widget, GdkEvent* event)
    {
        double x, y, xRoot, yRoot;
        GdkModifierType state;
        if (event) {
            gdk_event_get_coords(event, &x, &y);
            gdk_event_get_root_coords(event, &xRoot, &yRoot);
            gdk_event_get_state(event, &state);
        } else {
            auto* device = gdk_seat_get_pointer(gdk_display_get_default_seat(gtk_widget_get_display(widget)));
            widgetDevicePosition(widget, device, &x, &y, &state);
            auto rootPoint = widgetRootCoords(widget, x, y);
            xRoot = rootPoint.x();
            yRoot = rootPoint.y();
        }

        MotionEvent(FloatPoint(x, y), FloatPoint(xRoot, yRoot), state);
    }

    MotionEvent(FloatPoint&& position, FloatPoint&& globalPosition, GdkModifierType state)
        : position(WTFMove(position))
        , globalPosition(WTFMove(globalPosition))
    {
        if (state & GDK_CONTROL_MASK)
            modifiers.add(WebEvent::Modifier::ControlKey);
        if (state & GDK_SHIFT_MASK)
            modifiers.add(WebEvent::Modifier::ShiftKey);
        if (state & GDK_MOD1_MASK)
            modifiers.add(WebEvent::Modifier::AltKey);
        if (state & GDK_META_MASK)
            modifiers.add(WebEvent::Modifier::MetaKey);

        if (state & GDK_BUTTON1_MASK) {
            button = WebMouseEvent::LeftButton;
            buttons |= 1;
        }
        if (state & GDK_BUTTON2_MASK) {
            button = WebMouseEvent::MiddleButton;
            buttons |= 4;
        }
        if (state & GDK_BUTTON3_MASK) {
            button = WebMouseEvent::RightButton;
            buttons |= 2;
        }
    }

    FloatSize delta(GdkEvent* event)
    {
        double x, y;
        gdk_event_get_root_coords(event, &x, &y);
        return FloatPoint(x, y) - globalPosition;
    }

    FloatPoint position;
    FloatPoint globalPosition;
    WebMouseEvent::Button button { WebMouseEvent::NoButton };
    unsigned short buttons { 0 };
    OptionSet<WebEvent::Modifier> modifiers;
};

#if !USE(GTK4)
typedef HashMap<GtkWidget*, IntRect> WebKitWebViewChildrenMap;
#endif
typedef HashMap<uint32_t, GUniquePtr<GdkEvent>> TouchEventsMap;

struct _WebKitWebViewBasePrivate {
    _WebKitWebViewBasePrivate()
        : updateActivityStateTimer(RunLoop::main(), this, &_WebKitWebViewBasePrivate::updateActivityStateTimerFired)
#if GTK_CHECK_VERSION(3, 24, 0)
        , releaseEmojiChooserTimer(RunLoop::main(), this, &_WebKitWebViewBasePrivate::releaseEmojiChooserTimerFired)
#endif
    {
#if GTK_CHECK_VERSION(3, 24, 0)
        releaseEmojiChooserTimer.setPriority(RunLoopSourcePriority::ReleaseUnusedResourcesTimer);
#endif
    }

    void updateActivityStateTimerFired()
    {
        if (!pageProxy)
            return;
        pageProxy->activityStateDidChange(activityStateFlagsToUpdate);
        activityStateFlagsToUpdate = { };
    }

#if GTK_CHECK_VERSION(3, 24, 0)
    void releaseEmojiChooserTimerFired()
    {
#if USE(GTK4)
        g_clear_pointer(&emojiChooser, gtk_widget_unparent);
#else
        if (emojiChooser) {
            gtk_widget_destroy(emojiChooser);
            emojiChooser = nullptr;
        }
#endif
    }
#endif

#if !USE(GTK4)
    WebKitWebViewChildrenMap children;
#endif
    std::unique_ptr<PageClientImpl> pageClient;
    RefPtr<WebPageProxy> pageProxy;
    IntSize viewSize { };
    bool shouldForwardNextKeyEvent { false };
    bool shouldForwardNextWheelEvent { false };
#if !USE(GTK4)
    ClickCounter clickCounter;
#endif
    CString tooltipText;
    IntRect tooltipArea;
    WebHitTestResultData::IsScrollbar mouseIsOverScrollbar;
    GRefPtr<AtkObject> accessible;
    GtkWidget* dialog { nullptr };
    GtkWidget* inspectorView { nullptr };
    AttachmentSide inspectorAttachmentSide { AttachmentSide::Bottom };
    unsigned inspectorViewSize { 0 };
    GUniquePtr<GdkEvent> contextMenuEvent;
    WebContextMenuProxyGtk* activeContextMenuProxy { nullptr };
    InputMethodFilter inputMethodFilter;
    KeyBindingTranslator keyBindingTranslator;
    TouchEventsMap touchEvents;
    IntSize contentsSize;
    std::optional<MotionEvent> lastMotionEvent;
    bool isBlank;
    bool shouldNotifyFocusEvents { true };

    GtkWindow* toplevelOnScreenWindow { nullptr };
#if USE(GTK4)
    unsigned long toplevelIsActiveID { 0 };
    unsigned long toplevelWindowStateChangedID { 0 };
    unsigned long toplevelWindowUnrealizedID { 0 };
#else
    unsigned long toplevelFocusInEventID { 0 };
    unsigned long toplevelFocusOutEventID { 0 };
    unsigned long toplevelWindowStateEventID { 0 };
#endif
    unsigned long toplevelWindowRealizedID { 0 };

    // View State.
    OptionSet<ActivityState::Flag> activityState;
    OptionSet<ActivityState::Flag> activityStateFlagsToUpdate;
    RunLoop::Timer<WebKitWebViewBasePrivate> updateActivityStateTimer;

#if ENABLE(FULLSCREEN_API)
    bool fullScreenModeActive { false };
    std::unique_ptr<PAL::SleepDisabler> sleepDisabler;
#endif

    std::unique_ptr<AcceleratedBackingStore> acceleratedBackingStore;

#if ENABLE(DRAG_SUPPORT)
    std::unique_ptr<DragSource> dragSource;
    std::unique_ptr<DropTarget> dropTarget;
#endif

    GtkGesture* touchGestureGroup;
    std::unique_ptr<ViewGestureController> viewGestureController;
    bool isBackForwardNavigationGestureEnabled { false };

#if GTK_CHECK_VERSION(3, 24, 0)
    GtkWidget* emojiChooser;
    CompletionHandler<void(String)> emojiChooserCompletionHandler;
    RunLoop::Timer<WebKitWebViewBasePrivate> releaseEmojiChooserTimer;
#endif

    // Touch gestures state
    FloatPoint dragOffset;
    bool isLongPressed;
    bool isBeingDragged;
    bool pageGrabbedTouch;

    std::unique_ptr<PointerLockManager> pointerLockManager;
};

#if USE(GTK4)
WEBKIT_DEFINE_TYPE(WebKitWebViewBase, webkit_web_view_base, GTK_TYPE_WIDGET)
#else
WEBKIT_DEFINE_TYPE(WebKitWebViewBase, webkit_web_view_base, GTK_TYPE_CONTAINER)
#endif

static void webkitWebViewBaseScheduleUpdateActivityState(WebKitWebViewBase* webViewBase, OptionSet<ActivityState::Flag> flagsToUpdate)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    priv->activityStateFlagsToUpdate.add(flagsToUpdate);
    if (priv->updateActivityStateTimer.isActive())
        return;

    priv->updateActivityStateTimer.startOneShot(0_s);
}

#if !USE(GTK4)
static gboolean toplevelWindowFocusInEvent(GtkWidget* widget, GdkEventFocus*, WebKitWebViewBase* webViewBase)
{
    // Spurious focus in events can occur when the window is hidden.
    if (!gtk_widget_get_visible(widget))
        return FALSE;

    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    if (priv->activityState & ActivityState::WindowIsActive)
        return FALSE;

    priv->activityState.add(ActivityState::WindowIsActive);
    webkitWebViewBaseScheduleUpdateActivityState(webViewBase, ActivityState::WindowIsActive);

    return FALSE;
}

static gboolean toplevelWindowFocusOutEvent(GtkWidget*, GdkEventFocus*, WebKitWebViewBase* webViewBase)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    if (!(priv->activityState & ActivityState::WindowIsActive))
        return FALSE;

    priv->activityState.remove(ActivityState::WindowIsActive);
    webkitWebViewBaseScheduleUpdateActivityState(webViewBase, ActivityState::WindowIsActive);

    return FALSE;
}

static gboolean toplevelWindowStateEvent(GtkWidget*, GdkEventWindowState* event, WebKitWebViewBase* webViewBase)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    if (!(event->changed_mask & GDK_WINDOW_STATE_ICONIFIED))
        return FALSE;

    bool visible = !(event->new_window_state & GDK_WINDOW_STATE_ICONIFIED);
    if ((visible && priv->activityState & ActivityState::IsVisible) || (!visible && !(priv->activityState & ActivityState::IsVisible)))
        return FALSE;

    if (visible)
        priv->activityState.add(ActivityState::IsVisible);
    else
        priv->activityState.remove(ActivityState::IsVisible);
    webkitWebViewBaseScheduleUpdateActivityState(webViewBase, ActivityState::IsVisible);

    return FALSE;
}

static void toplevelWindowRealized(WebKitWebViewBase* webViewBase)
{
    gtk_widget_realize(GTK_WIDGET(webViewBase));

    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    if (priv->toplevelWindowRealizedID) {
        g_signal_handler_disconnect(priv->toplevelOnScreenWindow, priv->toplevelWindowRealizedID);
        priv->toplevelWindowRealizedID = 0;
    }
}

static void webkitWebViewBaseSetToplevelOnScreenWindow(WebKitWebViewBase* webViewBase, GtkWindow* window)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    if (priv->toplevelOnScreenWindow == window)
        return;

    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;
    }
    if (priv->toplevelWindowStateEventID) {
        g_signal_handler_disconnect(priv->toplevelOnScreenWindow, priv->toplevelWindowStateEventID);
        priv->toplevelWindowStateEventID = 0;
    }
    if (priv->toplevelWindowRealizedID) {
        g_signal_handler_disconnect(priv->toplevelOnScreenWindow, priv->toplevelWindowRealizedID);
        priv->toplevelWindowRealizedID = 0;
    }

    priv->toplevelOnScreenWindow = window;

    if (!priv->toplevelOnScreenWindow) {
        OptionSet<ActivityState::Flag> flagsToUpdate;
        if (priv->activityState & ActivityState::IsInWindow) {
            priv->activityState.remove(ActivityState::IsInWindow);
            flagsToUpdate.add(ActivityState::IsInWindow);
        }
        if (priv->activityState & ActivityState::WindowIsActive) {
            priv->activityState.remove(ActivityState::WindowIsActive);
            flagsToUpdate.add(ActivityState::IsInWindow);
        }
        if (flagsToUpdate)
            webkitWebViewBaseScheduleUpdateActivityState(webViewBase, flagsToUpdate);

        return;
    }

    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);
    priv->toplevelWindowStateEventID =
        g_signal_connect(priv->toplevelOnScreenWindow, "window-state-event", G_CALLBACK(toplevelWindowStateEvent), webViewBase);

    if (gtk_widget_get_realized(GTK_WIDGET(window)))
        gtk_widget_realize(GTK_WIDGET(webViewBase));
    else
        priv->toplevelWindowRealizedID = g_signal_connect_swapped(window, "realize", G_CALLBACK(toplevelWindowRealized), webViewBase);
}
#endif

static void webkitWebViewBaseRealize(GtkWidget* widget)
{
    WebKitWebViewBase* webView = WEBKIT_WEB_VIEW_BASE(widget);
    WebKitWebViewBasePrivate* priv = webView->priv;

#if USE(GTK4)
    GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->realize(widget);
#else
    gtk_widget_set_realized(widget, TRUE);

    GtkAllocation allocation;
    gtk_widget_get_allocation(widget, &allocation);

    GdkWindowAttr attributes;
    attributes.window_type = GDK_WINDOW_CHILD;
    attributes.x = allocation.x;
    attributes.y = allocation.y;
    attributes.width = allocation.width;
    attributes.height = allocation.height;
    attributes.wclass = GDK_INPUT_OUTPUT;
    attributes.visual = gtk_widget_get_visual(widget);
    attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK
        | GDK_EXPOSURE_MASK
        | GDK_BUTTON_PRESS_MASK
        | GDK_BUTTON_RELEASE_MASK
        | GDK_SCROLL_MASK
        | GDK_SMOOTH_SCROLL_MASK
        | GDK_POINTER_MOTION_MASK
        | GDK_ENTER_NOTIFY_MASK
        | GDK_LEAVE_NOTIFY_MASK
        | GDK_KEY_PRESS_MASK
        | GDK_KEY_RELEASE_MASK
        | GDK_BUTTON_MOTION_MASK
        | GDK_BUTTON1_MOTION_MASK
        | GDK_BUTTON2_MOTION_MASK
        | GDK_BUTTON3_MOTION_MASK
        | GDK_TOUCH_MASK;
    attributes.event_mask |= GDK_TOUCHPAD_GESTURE_MASK;

    gint attributesMask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;

    GdkWindow* window = gdk_window_new(gtk_widget_get_parent_window(widget), &attributes, attributesMask);
    gtk_widget_set_window(widget, window);
    gdk_window_set_user_data(window, widget);
#endif

    auto* imContext = priv->inputMethodFilter.context();
    if (WEBKIT_IS_INPUT_METHOD_CONTEXT_IMPL_GTK(imContext))
        webkitInputMethodContextImplGtkSetClientWidget(WEBKIT_INPUT_METHOD_CONTEXT_IMPL_GTK(imContext), widget);

    if (priv->acceleratedBackingStore)
        priv->acceleratedBackingStore->realize();
}

static void webkitWebViewBaseUnrealize(GtkWidget* widget)
{
    WebKitWebViewBase* webView = WEBKIT_WEB_VIEW_BASE(widget);

    auto* imContext = webView->priv->inputMethodFilter.context();
    if (WEBKIT_IS_INPUT_METHOD_CONTEXT_IMPL_GTK(imContext))
        webkitInputMethodContextImplGtkSetClientWidget(WEBKIT_INPUT_METHOD_CONTEXT_IMPL_GTK(imContext), nullptr);

    if (webView->priv->acceleratedBackingStore)
        webView->priv->acceleratedBackingStore->unrealize();

    GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->unrealize(widget);
}

#if !USE(GTK4)
static bool webkitWebViewChildIsInternalWidget(WebKitWebViewBase* webViewBase, GtkWidget* widget)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    return widget == priv->inspectorView || widget == priv->dialog || widget == priv->keyBindingTranslator.widget();
}

static void webkitWebViewBaseContainerAdd(GtkContainer* container, GtkWidget* widget)
{
    WebKitWebViewBase* webView = WEBKIT_WEB_VIEW_BASE(container);
    WebKitWebViewBasePrivate* priv = webView->priv;

    // Internal widgets like the web inspector and authentication dialog have custom
    // allocations so we don't need to add them to our list of children.
    if (!webkitWebViewChildIsInternalWidget(webView, widget)) {
        GtkAllocation childAllocation;
        gtk_widget_get_allocation(widget, &childAllocation);
        priv->children.set(widget, childAllocation);
    }

    gtk_widget_set_parent(widget, GTK_WIDGET(container));
}
#endif

void webkitWebViewBaseAddDialog(WebKitWebViewBase* webViewBase, GtkWidget* dialog)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    priv->dialog = dialog;
#if USE(GTK4)
    g_object_add_weak_pointer(G_OBJECT(dialog), reinterpret_cast<void**>(&priv->dialog));
#endif
    gtk_widget_set_parent(dialog, GTK_WIDGET(webViewBase));
    gtk_widget_show(dialog);

    // We need to draw the shadow over the widget.
    gtk_widget_queue_draw(GTK_WIDGET(webViewBase));
}

#if USE(GTK4)
static void webkitWebViewBaseRemoveDialog(WebKitWebViewBase* webViewBase, GtkWidget* dialog)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    if (!priv->dialog)
        return;

    g_object_remove_weak_pointer(G_OBJECT(dialog), reinterpret_cast<void**>(&priv->dialog));
    g_clear_pointer(&priv->dialog, gtk_widget_unparent);
}
#endif

#if !USE(GTK4)
static void webkitWebViewBaseContainerRemove(GtkContainer* container, GtkWidget* widget)
{
    WebKitWebViewBase* webView = WEBKIT_WEB_VIEW_BASE(container);
    WebKitWebViewBasePrivate* priv = webView->priv;
    GtkWidget* widgetContainer = GTK_WIDGET(container);

    gboolean wasVisible = gtk_widget_get_visible(widget);
    gtk_widget_unparent(widget);

    if (priv->inspectorView == widget) {
        priv->inspectorView = 0;
        priv->inspectorViewSize = 0;
    } else if (priv->dialog == widget) {
        priv->dialog = nullptr;
        if (gtk_widget_get_visible(widgetContainer))
            gtk_widget_grab_focus(widgetContainer);
    } else if (priv->keyBindingTranslator.widget() == widget)
        priv->keyBindingTranslator.invalidate();
    else {
        ASSERT(priv->children.contains(widget));
        priv->children.remove(widget);
    }
    if (wasVisible && gtk_widget_get_visible(widgetContainer))
        gtk_widget_queue_resize(widgetContainer);
}

static void webkitWebViewBaseContainerForall(GtkContainer* container, gboolean includeInternals, GtkCallback callback, gpointer callbackData)
{
    WebKitWebViewBase* webView = WEBKIT_WEB_VIEW_BASE(container);
    WebKitWebViewBasePrivate* priv = webView->priv;

    for (const auto& child : copyToVector(priv->children.keys())) {
        if (priv->children.contains(child))
            (*callback)(child, callbackData);
    }

    if (includeInternals && priv->keyBindingTranslator.widget())
        (*callback)(priv->keyBindingTranslator.widget(), callbackData);

    if (includeInternals && priv->inspectorView)
        (*callback)(priv->inspectorView, callbackData);

    if (includeInternals && priv->dialog)
        (*callback)(priv->dialog, callbackData);
}

void webkitWebViewBaseChildMoveResize(WebKitWebViewBase* webView, GtkWidget* child, const IntRect& childRect)
{
    const IntRect& geometry = webView->priv->children.get(child);
    if (geometry == childRect)
        return;

    webView->priv->children.set(child, childRect);
    gtk_widget_queue_resize_no_redraw(GTK_WIDGET(webView));
}
#endif

void webkitWebViewBaseAddWebInspector(WebKitWebViewBase* webViewBase, GtkWidget* inspector, AttachmentSide attachmentSide)
{
    if (webViewBase->priv->inspectorView == inspector && webViewBase->priv->inspectorAttachmentSide == attachmentSide)
        return;

    webViewBase->priv->inspectorAttachmentSide = attachmentSide;

    if (webViewBase->priv->inspectorView == inspector) {
        gtk_widget_queue_resize(GTK_WIDGET(webViewBase));
        return;
    }

    webViewBase->priv->inspectorView = inspector;
    gtk_widget_set_parent(inspector, GTK_WIDGET(webViewBase));
}

void webkitWebViewBaseRemoveWebInspector(WebKitWebViewBase* webViewBase, GtkWidget* inspector)
{
    if (webViewBase->priv->inspectorView != inspector)
        return;

#if USE(GTK4)
    g_clear_pointer(&webViewBase->priv->inspectorView, gtk_widget_unparent);
#else
    gtk_container_remove(GTK_CONTAINER(webViewBase), inspector);
#endif
}

#if GTK_CHECK_VERSION(3, 24, 0)
static void webkitWebViewBaseCompleteEmojiChooserRequest(WebKitWebViewBase* webView, const String& text)
{
    if (auto completionHandler = std::exchange(webView->priv->emojiChooserCompletionHandler, nullptr))
        completionHandler(text);
}
#endif

static void webkitWebViewBaseDispose(GObject* gobject)
{
    WebKitWebViewBase* webView = WEBKIT_WEB_VIEW_BASE(gobject);
#if USE(GTK4)
    webkitWebViewBaseRemoveDialog(webView, webView->priv->dialog);
    webkitWebViewBaseRemoveWebInspector(webView, webView->priv->inspectorView);
    if (auto* widget = webView->priv->keyBindingTranslator.widget())
        gtk_widget_unparent(widget);
    g_clear_pointer(&webView->priv->emojiChooser, gtk_widget_unparent);
#else
    g_clear_pointer(&webView->priv->dialog, gtk_widget_destroy);
    webkitWebViewBaseSetToplevelOnScreenWindow(webView, nullptr);
#endif
    if (webView->priv->accessible)
        webkitWebViewAccessibleSetWebView(WEBKIT_WEB_VIEW_ACCESSIBLE(webView->priv->accessible.get()), nullptr);
#if GTK_CHECK_VERSION(3, 24, 0)
    webkitWebViewBaseCompleteEmojiChooserRequest(webView, emptyString());
#endif
    if (webView->priv->pointerLockManager) {
        webView->priv->pointerLockManager->unlock();
        webView->priv->pointerLockManager = nullptr;
    }
    webView->priv->inputMethodFilter.setContext(nullptr);
    webView->priv->pageProxy->close();
    webView->priv->acceleratedBackingStore = nullptr;
    webView->priv->sleepDisabler = nullptr;
    webView->priv->keyBindingTranslator.invalidate();
    G_OBJECT_CLASS(webkit_web_view_base_parent_class)->dispose(gobject);
}

#if USE(GTK4)
static void webkitWebViewBaseSnapshot(GtkWidget* widget, GtkSnapshot* snapshot)
{
    int scaleFactor = gtk_widget_get_scale_factor(widget);
    int width = gtk_widget_get_width(widget) * scaleFactor;
    int height = gtk_widget_get_height(widget) * scaleFactor;
    if (!width || !height)
        return;

    WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget);
    auto* drawingArea = static_cast<DrawingAreaProxyCoordinatedGraphics*>(webViewBase->priv->pageProxy->drawingArea());
    if (!drawingArea)
        return;

    auto* pageSnapshot = gtk_snapshot_new();
    if (!webViewBase->priv->isBlank) {
        ASSERT(drawingArea->isInAcceleratedCompositingMode());
        webViewBase->priv->acceleratedBackingStore->snapshot(pageSnapshot);
    }

    if (auto* pageRenderNode = gtk_snapshot_free_to_node(pageSnapshot)) {
        bool showingNavigationSnapshot = webViewBase->priv->pageProxy->isShowingNavigationGestureSnapshot();
        auto* controller = webkitWebViewBaseViewGestureController(webViewBase);
        if (showingNavigationSnapshot && controller)
            controller->snapshot(snapshot, pageRenderNode);
        else
            gtk_snapshot_append_node(snapshot, pageRenderNode);

        gsk_render_node_unref(pageRenderNode);
    }

    if (webViewBase->priv->inspectorView)
        gtk_widget_snapshot_child(widget, webViewBase->priv->inspectorView, snapshot);

    if (webViewBase->priv->dialog)
        gtk_widget_snapshot_child(widget, webViewBase->priv->dialog, snapshot);
}
#else
static gboolean webkitWebViewBaseDraw(GtkWidget* widget, cairo_t* cr)
{
    WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget);
    auto* drawingArea = static_cast<DrawingAreaProxyCoordinatedGraphics*>(webViewBase->priv->pageProxy->drawingArea());
    if (!drawingArea)
        return FALSE;

    GdkRectangle clipRect;
    if (!gdk_cairo_get_clip_rectangle(cr, &clipRect))
        return FALSE;

    if (!webViewBase->priv->isBlank) {
        bool showingNavigationSnapshot = webViewBase->priv->pageProxy->isShowingNavigationGestureSnapshot();
        if (showingNavigationSnapshot)
            cairo_push_group(cr);

        if (drawingArea->isInAcceleratedCompositingMode()) {
            ASSERT(webViewBase->priv->acceleratedBackingStore);
            webViewBase->priv->acceleratedBackingStore->paint(cr, clipRect);
        } else {
            WebCore::Region unpaintedRegion; // This is simply unused.
            drawingArea->paint(cr, clipRect, unpaintedRegion);
        }

        if (showingNavigationSnapshot) {
            RefPtr<cairo_pattern_t> group = adoptRef(cairo_pop_group(cr));
            if (auto* controller = webkitWebViewBaseViewGestureController(webViewBase))
                controller->draw(cr, group.get());
        }
    }

    GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->draw(widget, cr);

    return FALSE;
}
#endif

#if !USE(GTK4)
static void webkitWebViewBaseChildAllocate(GtkWidget* child, gpointer userData)
{
    if (!gtk_widget_get_visible(child))
        return;

    WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(userData);
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    const IntRect& geometry = priv->children.get(child);
    if (geometry.isEmpty())
        return;

    GtkAllocation childAllocation = geometry;
    gtk_widget_size_allocate(child, &childAllocation);
    priv->children.set(child, IntRect());
}
#endif

#if USE(GTK4)
static void webkitWebViewBaseSizeAllocate(GtkWidget* widget, int width, int height, int baseline)
#else
static void webkitWebViewBaseSizeAllocate(GtkWidget* widget, GtkAllocation* allocation)
#endif
{
#if USE(GTK4)
    GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->size_allocate(widget, width, height, baseline);
    GtkAllocation allocationStack = { 0, 0, width, height };
    GtkAllocation* allocation = &allocationStack;
#else
    GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->size_allocate(widget, allocation);
#endif

    WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget);
#if !USE(GTK4)
    gtk_container_foreach(GTK_CONTAINER(webViewBase), webkitWebViewBaseChildAllocate, webViewBase);
#endif

    IntRect viewRect(allocation->x, allocation->y, allocation->width, allocation->height);
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    if (priv->inspectorView) {
        GtkAllocation childAllocation = viewRect;

        if (priv->inspectorAttachmentSide == AttachmentSide::Bottom) {
            int inspectorViewHeight = std::min(static_cast<int>(priv->inspectorViewSize), allocation->height);
            childAllocation.x = 0;
            childAllocation.y = allocation->height - inspectorViewHeight;
            childAllocation.height = inspectorViewHeight;
            viewRect.setHeight(std::max(allocation->height - inspectorViewHeight, 1));
        } else {
            int inspectorViewWidth = std::min(static_cast<int>(priv->inspectorViewSize), allocation->width);
            childAllocation.y = 0;
            childAllocation.x = allocation->width - inspectorViewWidth;
            childAllocation.width = inspectorViewWidth;
            viewRect.setWidth(std::max(allocation->width - inspectorViewWidth, 1));
        }

        gtk_widget_size_allocate(priv->inspectorView, &childAllocation);
    }

    // The dialogs are centered in the view rect, which means that it
    // never overlaps the web inspector. Thus, we need to calculate the allocation here
    // after calculating the inspector allocation.
    if (priv->dialog) {
        GtkRequisition minimumSize;
        gtk_widget_get_preferred_size(priv->dialog, &minimumSize, nullptr);

        GtkAllocation childAllocation = { 0, 0, std::max(minimumSize.width, viewRect.width()), std::max(minimumSize.height, viewRect.height()) };
        gtk_widget_size_allocate(priv->dialog, &childAllocation);
    }

#if USE(GTK4)
    for (auto* child = gtk_widget_get_first_child(widget); child; child = gtk_widget_get_next_sibling(child)) {
        if (GTK_IS_POPOVER(child))
            gtk_popover_present(GTK_POPOVER(child));
    }
#endif

    priv->viewSize = viewRect.size();

    if (auto* drawingArea = static_cast<DrawingAreaProxyCoordinatedGraphics*>(priv->pageProxy->drawingArea()))
        drawingArea->setSize(priv->viewSize);
}

#if USE(GTK4)
static void webkitWebViewBaseMeasure(GtkWidget* widget, GtkOrientation orientation, int, int* minimumSize, int* naturalSize, int*, int*)
{
    WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv;
    switch (orientation) {
    case GTK_ORIENTATION_HORIZONTAL:
        *naturalSize = priv->contentsSize.width();
        break;
    case GTK_ORIENTATION_VERTICAL:
        *naturalSize = priv->contentsSize.height();
        break;
    }

    *minimumSize = 0;
}
#else
static void webkitWebViewBaseGetPreferredWidth(GtkWidget* widget, gint* minimumSize, gint* naturalSize)
{
    WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv;
    *minimumSize = 0;
    *naturalSize = priv->contentsSize.width();
}

static void webkitWebViewBaseGetPreferredHeight(GtkWidget* widget, gint* minimumSize, gint* naturalSize)
{
    WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv;
    *minimumSize = 0;
    *naturalSize = priv->contentsSize.height();
}
#endif

static void webkitWebViewBaseMap(GtkWidget* widget)
{
    GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->map(widget);

    WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget);
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    OptionSet<ActivityState::Flag> flagsToUpdate;
    if (!(priv->activityState & ActivityState::IsVisible))
        flagsToUpdate.add(ActivityState::IsVisible);
    if (priv->toplevelOnScreenWindow) {
        if (!(priv->activityState & ActivityState::IsInWindow))
            flagsToUpdate.add(ActivityState::IsInWindow);

#if ENABLE(DEVELOPER_MODE)
        // Xvfb doesn't support toplevel focus, so gtk_window_is_active() always returns false. We consider
        // toplevel window to be always active since it's the only one.
        if (WebCore::PlatformDisplay::sharedDisplay().type() == WebCore::PlatformDisplay::Type::X11) {
            if (!g_strcmp0(g_getenv("UNDER_XVFB"), "yes"))
                flagsToUpdate.add(ActivityState::WindowIsActive);
        }
#endif

        if (gtk_window_is_active(GTK_WINDOW(priv->toplevelOnScreenWindow)) && !(priv->activityState & ActivityState::WindowIsActive))
            flagsToUpdate.add(ActivityState::WindowIsActive);
    }
    if (!flagsToUpdate)
        return;

    priv->activityState.add(flagsToUpdate);
    webkitWebViewBaseScheduleUpdateActivityState(webViewBase, flagsToUpdate);
}

static void webkitWebViewBaseUnmap(GtkWidget* widget)
{
    GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->unmap(widget);

    WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget);
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    if (!(priv->activityState & ActivityState::IsVisible))
        return;

    priv->activityState.remove(ActivityState::IsVisible);
    webkitWebViewBaseScheduleUpdateActivityState(webViewBase, ActivityState::IsVisible);
}

#if !USE(GTK4)
static gboolean webkitWebViewBaseFocusInEvent(GtkWidget* widget, GdkEventFocus* event)
{
    WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget);
    webkitWebViewBaseSetFocus(webViewBase, true);
    webViewBase->priv->inputMethodFilter.notifyFocusedIn();

    return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->focus_in_event(widget, event);
}

static gboolean webkitWebViewBaseFocusOutEvent(GtkWidget* widget, GdkEventFocus* event)
{
    WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget);
    webkitWebViewBaseSetFocus(webViewBase, false);
    webViewBase->priv->inputMethodFilter.notifyFocusedOut();

    return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->focus_out_event(widget, event);
}

static gboolean webkitWebViewBaseKeyPressEvent(GtkWidget* widget, GdkEventKey* keyEvent)
{
    WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget);
    WebKitWebViewBasePrivate* priv = webViewBase->priv;

    // Since WebProcess key event handling is not synchronous, handle the event in two passes.
    // When WebProcess processes the input event, it will call PageClientImpl::doneWithKeyEvent
    // with event handled status which determines whether to pass the input event to parent or not
    // using gtk_main_do_event().
    if (priv->shouldForwardNextKeyEvent) {
        priv->shouldForwardNextKeyEvent = false;
        return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->key_press_event(widget, keyEvent);
    }

    GdkModifierType state;
    guint keyval;
    gdk_event_get_state(reinterpret_cast<GdkEvent*>(keyEvent), &state);
    gdk_event_get_keyval(reinterpret_cast<GdkEvent*>(keyEvent), &keyval);

#if ENABLE(DEVELOPER_MODE) && OS(LINUX)
    if ((state & GDK_CONTROL_MASK) && (state & GDK_SHIFT_MASK) && keyval == GDK_KEY_G) {
        auto& preferences = priv->pageProxy->preferences();
        preferences.setResourceUsageOverlayVisible(!preferences.resourceUsageOverlayVisible());
        return GDK_EVENT_STOP;
    }
#endif

    if (priv->dialog)
        return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->key_press_event(widget, keyEvent);

#if ENABLE(FULLSCREEN_API)
    if (priv->fullScreenModeActive) {
        switch (keyval) {
        case GDK_KEY_Escape:
        case GDK_KEY_f:
        case GDK_KEY_F:
            priv->pageProxy->fullScreenManager()->requestExitFullScreen();
            return GDK_EVENT_STOP;
        default:
            break;
        }
    }
#endif

    auto filterResult = priv->inputMethodFilter.filterKeyEvent(reinterpret_cast<GdkEvent*>(keyEvent));
    if (!filterResult.handled) {
        priv->pageProxy->handleKeyboardEvent(NativeWebKeyboardEvent(reinterpret_cast<GdkEvent*>(keyEvent), filterResult.keyText,
            priv->keyBindingTranslator.commandsForKeyEvent(keyEvent)));
    }

    return GDK_EVENT_STOP;
}

static gboolean webkitWebViewBaseKeyReleaseEvent(GtkWidget* widget, GdkEventKey* keyEvent)
{
    WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget);
    WebKitWebViewBasePrivate* priv = webViewBase->priv;

    if (!priv->inputMethodFilter.filterKeyEvent(reinterpret_cast<GdkEvent*>(keyEvent)).handled)
        priv->pageProxy->handleKeyboardEvent(NativeWebKeyboardEvent(reinterpret_cast<GdkEvent*>(keyEvent), { }, { }));

    return GDK_EVENT_STOP;
}
#endif

#if USE(GTK4)
static void webkitWebViewBaseFocusEnter(WebKitWebViewBase* webViewBase, GtkEventController*)
{
    webkitWebViewBaseSetFocus(webViewBase, true);
    webViewBase->priv->inputMethodFilter.notifyFocusedIn();
}

static void webkitWebViewBaseFocusLeave(WebKitWebViewBase* webViewBase, GtkEventController*)
{
    webkitWebViewBaseSetFocus(webViewBase, false);
    webViewBase->priv->inputMethodFilter.notifyFocusedOut();
}

static gboolean webkitWebViewBaseKeyPressed(WebKitWebViewBase* webViewBase, unsigned keyval, unsigned, GdkModifierType state, GtkEventController* controller)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;

    // Since WebProcess key event handling is not synchronous, handle the event in two passes.
    // When WebProcess processes the input event, it will call PageClientImpl::doneWithKeyEvent
    // with event handled status which determines whether to pass the input event to parent or not
    // using gdk_display_put_event().
    if (priv->shouldForwardNextKeyEvent) {
        priv->shouldForwardNextKeyEvent = false;
        return GDK_EVENT_PROPAGATE;
    }

#if ENABLE(DEVELOPER_MODE) && OS(LINUX)
    if ((state & GDK_CONTROL_MASK) && (state & GDK_SHIFT_MASK) && keyval == GDK_KEY_G) {
        auto& preferences = priv->pageProxy->preferences();
        preferences.setResourceUsageOverlayVisible(!preferences.resourceUsageOverlayVisible());
        return GDK_EVENT_STOP;
    }
#endif

    if (priv->dialog)
        return gtk_event_controller_key_forward(GTK_EVENT_CONTROLLER_KEY(controller), priv->dialog);

#if ENABLE(FULLSCREEN_API)
    if (priv->fullScreenModeActive) {
        switch (keyval) {
        case GDK_KEY_Escape:
        case GDK_KEY_f:
        case GDK_KEY_F:
            priv->pageProxy->fullScreenManager()->requestExitFullScreen();
            return GDK_EVENT_STOP;
        default:
            break;
        }
    }
#endif

    auto* event = gtk_event_controller_get_current_event(controller);
    auto filterResult = priv->inputMethodFilter.filterKeyEvent(event);
    if (!filterResult.handled) {
        priv->pageProxy->handleKeyboardEvent(NativeWebKeyboardEvent(event, filterResult.keyText,
            priv->keyBindingTranslator.commandsForKeyEvent(GTK_EVENT_CONTROLLER_KEY(controller))));
    }

    return GDK_EVENT_STOP;
}

static void webkitWebViewBaseKeyReleased(WebKitWebViewBase* webViewBase, unsigned, unsigned, GdkModifierType, GtkEventController* controller)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;

    auto* event = gtk_event_controller_get_current_event(controller);
    if (!priv->inputMethodFilter.filterKeyEvent(event).handled)
        priv->pageProxy->handleKeyboardEvent(NativeWebKeyboardEvent(event, { }, { }));
}
#endif

#if !USE(GTK4)
static void webkitWebViewBaseHandleMouseEvent(WebKitWebViewBase* webViewBase, GdkEvent* event)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    ASSERT(!priv->dialog);

    int clickCount = 0;
    std::optional<FloatSize> movementDelta;
    GdkEventType eventType = gdk_event_get_event_type(event);
    switch (eventType) {
    case GDK_BUTTON_PRESS:
    case GDK_2BUTTON_PRESS:
    case GDK_3BUTTON_PRESS: {
        // For double and triple clicks GDK sends both a normal button press event
        // and a specific type (like GDK_2BUTTON_PRESS). If we detect a special press
        // coming up, ignore this event as it certainly generated the double or triple
        // click. The consequence of not eating this event is two DOM button press events
        // are generated.
        GUniquePtr<GdkEvent> nextEvent(gdk_event_peek());
        if (nextEvent && (nextEvent->any.type == GDK_2BUTTON_PRESS || nextEvent->any.type == GDK_3BUTTON_PRESS))
            return;

        priv->inputMethodFilter.cancelComposition();

        guint button;
        gdk_event_get_button(event, &button);
        // If it's a right click event save it as a possible context menu event.
        if (button == GDK_BUTTON_SECONDARY)
            priv->contextMenuEvent.reset(gdk_event_copy(event));

        clickCount = priv->clickCounter.currentClickCountForGdkButtonEvent(event);
    }
        FALLTHROUGH;
    case GDK_BUTTON_RELEASE:
        gtk_widget_grab_focus(GTK_WIDGET(webViewBase));
        break;
    case GDK_MOTION_NOTIFY:
        // Pointer Lock. 7.1 Attributes: movementX/Y must be updated regardless of pointer lock state.
        if (priv->lastMotionEvent)
            movementDelta = priv->lastMotionEvent->delta(event);
        priv->lastMotionEvent = MotionEvent(GTK_WIDGET(webViewBase), event);
        break;
    case GDK_ENTER_NOTIFY:
    case GDK_LEAVE_NOTIFY:
        break;
    default:
        ASSERT_NOT_REACHED();
    }

    priv->pageProxy->handleMouseEvent(NativeWebMouseEvent(event, clickCount, movementDelta));
}

static gboolean webkitWebViewBaseButtonPressEvent(GtkWidget* widget, GdkEventButton* event)
{
    WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget);
    WebKitWebViewBasePrivate* priv = webViewBase->priv;

    if (priv->dialog)
        return GDK_EVENT_STOP;

    if (gdk_device_get_source(gdk_event_get_source_device(reinterpret_cast<GdkEvent*>(event))) == GDK_SOURCE_TOUCHSCREEN)
        return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->button_press_event(widget, event);

    webkitWebViewBaseHandleMouseEvent(webViewBase, reinterpret_cast<GdkEvent*>(event));

    return GDK_EVENT_STOP;
}

static gboolean webkitWebViewBaseButtonReleaseEvent(GtkWidget* widget, GdkEventButton* event)
{
    WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget);
    WebKitWebViewBasePrivate* priv = webViewBase->priv;

    if (priv->dialog)
        return GDK_EVENT_STOP;
    if (gdk_device_get_source(gdk_event_get_source_device(reinterpret_cast<GdkEvent*>(event))) == GDK_SOURCE_TOUCHSCREEN)
        return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->button_release_event(widget, event);

    webkitWebViewBaseHandleMouseEvent(webViewBase, reinterpret_cast<GdkEvent*>(event));

    return GDK_EVENT_STOP;
}
#endif

#if USE(GTK4)
static void webkitWebViewBaseButtonPressed(WebKitWebViewBase* webViewBase, int clickCount, double x, double y, GtkGesture* gesture)
{
    if (gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture)))
        return;
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    if (priv->dialog)
        return;

    if (clickCount == 1)
        priv->inputMethodFilter.cancelComposition();
    gtk_widget_grab_focus(GTK_WIDGET(webViewBase));

    auto* sequence = gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture));
    gtk_gesture_set_sequence_state(gesture, sequence, GTK_EVENT_SEQUENCE_CLAIMED);

    auto button = gtk_gesture_single_get_current_button(GTK_GESTURE_SINGLE(gesture));
    auto* event = gtk_gesture_get_last_event(gesture, sequence);

    // If it's a right click event save it as a possible context menu event.
    if (button == GDK_BUTTON_SECONDARY)
        priv->contextMenuEvent.reset(gdk_event_copy(event));

    priv->pageProxy->handleMouseEvent(NativeWebMouseEvent(event, { clampToInteger(x), clampToInteger(y) }, clickCount, std::nullopt));
}

static void webkitWebViewBaseButtonReleased(WebKitWebViewBase* webViewBase, int clickCount, double x, double y, GtkGesture* gesture)
{
    if (gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture)))
        return;
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    if (priv->dialog)
        return;

    gtk_widget_grab_focus(GTK_WIDGET(webViewBase));

    auto* sequence = gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture));
    gtk_gesture_set_sequence_state(gesture, sequence, GTK_EVENT_SEQUENCE_CLAIMED);

    priv->pageProxy->handleMouseEvent(NativeWebMouseEvent(gtk_gesture_get_last_event(gesture, sequence), { clampToInteger(x), clampToInteger(y) }, clickCount, std::nullopt));
}
#endif

static bool shouldInvertDirectionForScrollEvent(WebHitTestResultData::IsScrollbar isScrollbar, bool isShiftPressed)
{
    // Shift+Wheel scrolls in the perpendicular direction, unless we are over a scrollbar
    // in which case we always want to follow the scrollbar direction.
    switch (isScrollbar) {
    case WebHitTestResultData::IsScrollbar::No:
        return isShiftPressed;
    case WebHitTestResultData::IsScrollbar::Horizontal:
        return true;
    case WebHitTestResultData::IsScrollbar::Vertical:
        return false;
    }
    RELEASE_ASSERT_NOT_REACHED();
}

#if !USE(GTK4)
static void webkitWebViewBaseHandleWheelEvent(WebKitWebViewBase* webViewBase, GdkEvent* event, std::optional<WebWheelEvent::Phase> phase = std::nullopt, std::optional<WebWheelEvent::Phase> momentum = std::nullopt)
{
    ViewGestureController* controller = webkitWebViewBaseViewGestureController(webViewBase);
    if (controller && controller->isSwipeGestureEnabled()) {
        double deltaX, deltaY;
        gdk_event_get_scroll_deltas(event, &deltaX, &deltaY);
        FloatSize delta(deltaX, deltaY);

        int32_t eventTime = static_cast<int32_t>(gdk_event_get_time(event));

        GdkDevice* device = gdk_event_get_source_device(event);
        GdkInputSource source = gdk_device_get_source(device);

        bool isEnd = gdk_event_is_scroll_stop_event(event) ? true : false;

        PlatformGtkScrollData scrollData = { .delta = delta, .eventTime = eventTime, .source = source, .isEnd = isEnd };
        if (controller->handleScrollWheelEvent(&scrollData))
            return;
    }

    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    ASSERT(!priv->dialog);
    if (phase)
        priv->pageProxy->handleWheelEvent(NativeWebWheelEvent(event, phase.value(), momentum.value_or(WebWheelEvent::Phase::PhaseNone)));
    else
        priv->pageProxy->handleWheelEvent(NativeWebWheelEvent(event));
}

static gboolean webkitWebViewBaseScrollEvent(GtkWidget* widget, GdkEventScroll* event)
{
    WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget);
    WebKitWebViewBasePrivate* priv = webViewBase->priv;

    if (std::exchange(priv->shouldForwardNextWheelEvent, false))
        return GDK_EVENT_PROPAGATE;

    if (priv->dialog)
        return GDK_EVENT_PROPAGATE;

    if (shouldInvertDirectionForScrollEvent(priv->mouseIsOverScrollbar, event->state & GDK_SHIFT_MASK)) {
        switch (event->direction) {
        case GDK_SCROLL_UP:
            event->direction = GDK_SCROLL_LEFT;
            break;
        case GDK_SCROLL_LEFT:
            event->direction = GDK_SCROLL_UP;
            break;
        case GDK_SCROLL_DOWN:
            event->direction = GDK_SCROLL_RIGHT;
            break;
        case GDK_SCROLL_RIGHT:
            event->direction = GDK_SCROLL_DOWN;
            break;
        case GDK_SCROLL_SMOOTH:
            std::swap(event->delta_x, event->delta_y);
            break;
        }
    }

    webkitWebViewBaseHandleWheelEvent(webViewBase, reinterpret_cast<GdkEvent*>(event));

    return GDK_EVENT_STOP;
}
#endif

#if USE(GTK4)
static gboolean webkitWebViewBaseScroll(WebKitWebViewBase* webViewBase, double deltaX, double deltaY, GtkEventController* eventController)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    if (priv->dialog)
        return GDK_EVENT_PROPAGATE;

    auto* event = gtk_event_controller_get_current_event(eventController);

    ViewGestureController* controller = webkitWebViewBaseViewGestureController(webViewBase);
    if (controller && controller->isSwipeGestureEnabled()) {
        FloatSize delta(deltaX, deltaY);

        int32_t eventTime = static_cast<int32_t>(gtk_event_controller_get_current_event_time(eventController));

        GdkDevice* device = gdk_event_get_device(event);
        GdkInputSource source = gdk_device_get_source(device);

        bool isEnd = gdk_scroll_event_is_stop(event) ? true : false;

        PlatformGtkScrollData scrollData = { .delta = delta, .eventTime = eventTime, .source = source, .isEnd = isEnd };
        if (controller->handleScrollWheelEvent(&scrollData))
            return GDK_EVENT_STOP;
    }

    if (shouldInvertDirectionForScrollEvent(priv->mouseIsOverScrollbar, gdk_event_get_modifier_state(event) & GDK_SHIFT_MASK))
        std::swap(deltaX, deltaY);

    priv->pageProxy->handleWheelEvent(NativeWebWheelEvent(event, priv->lastMotionEvent ? IntPoint(priv->lastMotionEvent->position) : IntPoint(), FloatSize(-deltaX, -deltaY)));

    return GDK_EVENT_STOP;
}

static void webkitWebViewBaseScrollEnd(WebKitWebViewBase* webViewBase, GtkEventController* controller)
{
    webkitWebViewBaseScroll(webViewBase, 0, 0, controller);
}
#endif

#if !USE(GTK4)
static gboolean webkitWebViewBasePopupMenu(GtkWidget* widget)
{
    WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget);
    WebKitWebViewBasePrivate* priv = webViewBase->priv;

    GdkEvent* currentEvent = gtk_get_current_event();
    if (!currentEvent)
        currentEvent = gdk_event_new(GDK_NOTHING);
    priv->contextMenuEvent.reset(currentEvent);
    priv->pageProxy->handleContextMenuKeyEvent();

    return TRUE;
}

static gboolean webkitWebViewBaseMotionNotifyEvent(GtkWidget* widget, GdkEventMotion* event)
{
    WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget);
    WebKitWebViewBasePrivate* priv = webViewBase->priv;

    if (priv->dialog) {
        auto* widgetClass = GTK_WIDGET_CLASS(webkit_web_view_base_parent_class);
        return widgetClass->motion_notify_event ? widgetClass->motion_notify_event(widget, event) : GDK_EVENT_PROPAGATE;
    }

    if (gdk_device_get_source(gdk_event_get_source_device(reinterpret_cast<GdkEvent*>(event))) == GDK_SOURCE_TOUCHSCREEN)
        return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->motion_notify_event(widget, event);

    if (priv->pointerLockManager) {
        double x, y;
        gdk_event_get_root_coords(reinterpret_cast<GdkEvent*>(event), &x, &y);
        priv->pointerLockManager->didReceiveMotionEvent(FloatPoint(x, y));
        return GDK_EVENT_STOP;
    }

    webkitWebViewBaseHandleMouseEvent(webViewBase, reinterpret_cast<GdkEvent*>(event));

    return GDK_EVENT_PROPAGATE;
}

static gboolean webkitWebViewBaseCrossingNotifyEvent(GtkWidget* widget, GdkEventCrossing* crossingEvent)
{
    WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget);
    WebKitWebViewBasePrivate* priv = webViewBase->priv;

    if (priv->dialog)
        return GDK_EVENT_PROPAGATE;

#if ENABLE(DEVELOPER_MODE)
    // Do not send mouse move events to the WebProcess for crossing events during testing.
    // WTR never generates crossing events and they can confuse tests.
    // https://bugs.webkit.org/show_bug.cgi?id=185072.
    if (UNLIKELY(priv->pageProxy->process().processPool().configuration().fullySynchronousModeIsAllowedForTesting()))
        return GDK_EVENT_PROPAGATE;
#endif

    // In the case of crossing events, it's very important the actual coordinates the WebProcess receives, because once the mouse leaves
    // the web view, the WebProcess won't receive more events until the mouse enters again in the web view. So, if the coordinates of the leave
    // event are not accurate, the WebProcess might not know the mouse left the view. This can happen because of double to integer conversion,
    // if the coordinates of the leave event are for example (25.2, -0.9), the WebProcess will receive (25, 0) and any hit test will succeed
    // because those coordinates are inside the web view.
    GtkAllocation allocation;
    gtk_widget_get_allocation(widget, &allocation);
    double xEvent, yEvent;
    gdk_event_get_coords(reinterpret_cast<GdkEvent*>(crossingEvent), &xEvent, &yEvent);
    double width = allocation.width;
    double height = allocation.height;
    double x = xEvent;
    double y = yEvent;
    if (x < 0 && x > -1)
        x = -1;
    else if (x >= width && x < width + 1)
        x = width + 1;
    if (y < 0 && y > -1)
        y = -1;
    else if (y >= height && y < height + 1)
        y = height + 1;

    GdkEvent* event = reinterpret_cast<GdkEvent*>(crossingEvent);
    GUniquePtr<GdkEvent> copiedEvent;
    if (x != xEvent || y != yEvent) {
        copiedEvent.reset(gdk_event_copy(event));
        copiedEvent->crossing.x = x;
        copiedEvent->crossing.y = y;
    }

    webkitWebViewBaseHandleMouseEvent(webViewBase, copiedEvent ? copiedEvent.get() : event);

    return GDK_EVENT_PROPAGATE;
}
#endif

#if USE(GTK4)
static void webkitWebViewBaseEnter(WebKitWebViewBase* webViewBase, double x, double y, GdkCrossingMode, GtkEventController*)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    if (priv->dialog)
        return;

#if ENABLE(DEVELOPER_MODE)
    // Do not send mouse move events to the WebProcess for crossing events during testing.
    // WTR never generates crossing events and they can confuse tests.
    // https://bugs.webkit.org/show_bug.cgi?id=185072.
    if (UNLIKELY(priv->pageProxy->process().processPool().configuration().fullySynchronousModeIsAllowedForTesting()))
        return;
#endif

    priv->pageProxy->handleMouseEvent(NativeWebMouseEvent({ clampToInteger(x), clampToInteger(y) }));
}

static gboolean webkitWebViewBaseMotion(WebKitWebViewBase* webViewBase, double x, double y, GtkEventController* controller)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    if (priv->dialog)
        return GDK_EVENT_PROPAGATE;

    if (priv->pointerLockManager) {
        priv->pointerLockManager->didReceiveMotionEvent(FloatPoint(x, y));
        return GDK_EVENT_STOP;
    }

    auto* event = gtk_event_controller_get_current_event(controller);
    std::optional<FloatSize> movementDelta;
    MotionEvent motionEvent(FloatPoint(x, y), FloatPoint(x, y), gdk_event_get_modifier_state(event));
    if (priv->lastMotionEvent)
        movementDelta = motionEvent.position - priv->lastMotionEvent->position;
    priv->lastMotionEvent = WTFMove(motionEvent);

    webViewBase->priv->pageProxy->handleMouseEvent(NativeWebMouseEvent(event, { clampToInteger(x), clampToInteger(y) }, 0, movementDelta));

    return GDK_EVENT_PROPAGATE;
}

static void webkitWebViewBaseLeave(WebKitWebViewBase* webViewBase, GdkCrossingMode, GtkEventController*)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    if (priv->dialog)
        return;

#if ENABLE(DEVELOPER_MODE)
    // Do not send mouse move events to the WebProcess for crossing events during testing.
    // WTR never generates crossing events and they can confuse tests.
    // https://bugs.webkit.org/show_bug.cgi?id=185072.
    if (UNLIKELY(priv->pageProxy->process().processPool().configuration().fullySynchronousModeIsAllowedForTesting()))
        return;
#endif

    priv->pageProxy->handleMouseEvent(NativeWebMouseEvent({ -1, -1 }));
}
#endif

#if ENABLE(TOUCH_EVENTS)
static void appendTouchEvent(GtkWidget* webViewBase, Vector<WebPlatformTouchPoint>& touchPoints, GdkEvent* event, WebPlatformTouchPoint::TouchPointState state)
{
    gdouble x, y;
    gdk_event_get_coords(event, &x, &y);
#if USE(GTK4)
    // Events in GTK4 are given in native surface coordinates
    gtk_widget_translate_coordinates(GTK_WIDGET(gtk_widget_get_native(webViewBase)),
        webViewBase, x, y, &x, &y);
#endif

    gdouble xRoot, yRoot;
    gdk_event_get_root_coords(event, &xRoot, &yRoot);

    uint32_t identifier = GPOINTER_TO_UINT(gdk_event_get_event_sequence(event));
    touchPoints.uncheckedAppend(WebPlatformTouchPoint(identifier, state, IntPoint(xRoot, yRoot), IntPoint(x, y)));
}

static inline WebPlatformTouchPoint::TouchPointState touchPointStateForEvents(GdkEvent* current, GdkEvent* event)
{
    if (gdk_event_get_event_sequence(current) != gdk_event_get_event_sequence(event))
        return WebPlatformTouchPoint::TouchStationary;

    switch (gdk_event_get_event_type(event)) {
    case GDK_TOUCH_UPDATE:
        return WebPlatformTouchPoint::TouchMoved;
    case GDK_TOUCH_BEGIN:
        return WebPlatformTouchPoint::TouchPressed;
    case GDK_TOUCH_END:
        return WebPlatformTouchPoint::TouchReleased;
    case GDK_TOUCH_CANCEL:
        return WebPlatformTouchPoint::TouchCancelled;
    default:
        return WebPlatformTouchPoint::TouchStationary;
    }
}

static void webkitWebViewBaseGetTouchPointsForEvent(WebKitWebViewBase* webViewBase, GdkEvent* event, Vector<WebPlatformTouchPoint>& touchPoints)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    GdkEventType type = gdk_event_get_event_type(event);
    bool touchEnd = (type == GDK_TOUCH_END) || (type == GDK_TOUCH_CANCEL);
    touchPoints.reserveInitialCapacity(touchEnd ? priv->touchEvents.size() + 1 : priv->touchEvents.size());

    GtkWidget* widget = GTK_WIDGET(webViewBase);
    for (const auto& it : priv->touchEvents)
        appendTouchEvent(widget, touchPoints, it.value.get(), touchPointStateForEvents(it.value.get(), event));

    // Touch was already removed from the TouchEventsMap, add it here.
    if (touchEnd)
        appendTouchEvent(widget, touchPoints, event, WebPlatformTouchPoint::TouchReleased);
}

#if USE(GTK4)
static gboolean webkitWebViewBaseTouchEvent(GtkWidget* widget, GdkEvent* event)
#else
static gboolean webkitWebViewBaseTouchEvent(GtkWidget* widget, GdkEventTouch* event)
#endif
{
    WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget);
    WebKitWebViewBasePrivate* priv = webViewBase->priv;

    if (priv->dialog)
        return GDK_EVENT_STOP;

    GdkEvent* touchEvent = reinterpret_cast<GdkEvent*>(event);
    uint32_t sequence = GPOINTER_TO_UINT(gdk_event_get_event_sequence(touchEvent));

    GdkEventType type = gdk_event_get_event_type(touchEvent);
    switch (type) {
    case GDK_TOUCH_BEGIN: {
        if (priv->touchEvents.isEmpty())
            priv->pageGrabbedTouch = false;
        ASSERT(!priv->touchEvents.contains(sequence));
        GUniquePtr<GdkEvent> event(gdk_event_copy(touchEvent));
        priv->touchEvents.add(sequence, WTFMove(event));
        break;
    }
    case GDK_TOUCH_UPDATE: {
        auto it = priv->touchEvents.find(sequence);
        ASSERT(it != priv->touchEvents.end());
        it->value.reset(gdk_event_copy(touchEvent));
        break;
    }
    case GDK_TOUCH_CANCEL:
        FALLTHROUGH;
    case GDK_TOUCH_END:
        ASSERT(priv->touchEvents.contains(sequence));
        priv->touchEvents.remove(sequence);
        break;
    default:
#if !USE(GTK4)
        ASSERT_NOT_REACHED();
#endif
        return GDK_EVENT_PROPAGATE;
    }

    Vector<WebPlatformTouchPoint> touchPoints;
    webkitWebViewBaseGetTouchPointsForEvent(webViewBase, touchEvent, touchPoints);
    priv->pageProxy->handleTouchEvent(NativeWebTouchEvent(reinterpret_cast<GdkEvent*>(event), WTFMove(touchPoints)));

#if USE(GTK4)
    return GDK_EVENT_PROPAGATE;
#else
    return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->touch_event(widget, event);
#endif
}
#endif // ENABLE(TOUCH_EVENTS)

void webkitWebViewBaseSetEnableBackForwardNavigationGesture(WebKitWebViewBase* webViewBase, bool enabled)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    priv->isBackForwardNavigationGestureEnabled = enabled;

    if (auto* controller = webkitWebViewBaseViewGestureController(webViewBase))
        controller->setSwipeGestureEnabled(enabled);

    priv->pageProxy->setShouldRecordNavigationSnapshots(enabled);
}

ViewGestureController* webkitWebViewBaseViewGestureController(WebKitWebViewBase* webViewBase)
{
    return webViewBase->priv->viewGestureController.get();
}

bool webkitWebViewBaseBeginBackSwipeForTesting(WebKitWebViewBase* webViewBase)
{
    if (auto* gestureController = webkitWebViewBaseViewGestureController(webViewBase))
        return gestureController->beginSimulatedSwipeInDirectionForTesting(ViewGestureController::SwipeDirection::Back);

    return FALSE;
}

bool webkitWebViewBaseCompleteBackSwipeForTesting(WebKitWebViewBase* webViewBase)
{
    if (auto* gestureController = webkitWebViewBaseViewGestureController(webViewBase))
        return gestureController->completeSimulatedSwipeInDirectionForTesting(ViewGestureController::SwipeDirection::Back);

    return FALSE;
}

static gboolean webkitWebViewBaseQueryTooltip(GtkWidget* widget, gint /* x */, gint /* y */, gboolean keyboardMode, GtkTooltip* tooltip)
{
    WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv;

    if (keyboardMode) {
        // TODO: https://bugs.webkit.org/show_bug.cgi?id=61732.
        notImplemented();
        return FALSE;
    }

    if (priv->tooltipText.length() <= 0)
        return FALSE;

    if (!priv->tooltipArea.isEmpty()) {
        GdkRectangle area = priv->tooltipArea;
        gtk_tooltip_set_tip_area(tooltip, &area);
    } else
        gtk_tooltip_set_tip_area(tooltip, 0);
    gtk_tooltip_set_text(tooltip, priv->tooltipText.data());

    return TRUE;
}

#if !USE(GTK4)
static AtkObject* webkitWebViewBaseGetAccessible(GtkWidget* widget)
{
    WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv;
    if (!priv->accessible) {
        // Create the accessible object and associate it to the widget.
        priv->accessible = adoptGRef(ATK_OBJECT(webkitWebViewAccessibleNew(widget)));

        // Set the parent to not break bottom-up navigation.
        if (auto* parentWidget = gtk_widget_get_parent(widget)) {
            if (auto* axParent = gtk_widget_get_accessible(parentWidget))
                atk_object_set_parent(priv->accessible.get(), axParent);
        }
    }

    return priv->accessible.get();
}
#endif

#if USE(GTK4)
static void toplevelWindowIsActiveChanged(GtkWindow* window, GParamSpec*, WebKitWebViewBase* webViewBase)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    if (gtk_window_is_active(window)) {
        if (priv->activityState & ActivityState::WindowIsActive)
            return;
        priv->activityState.add(ActivityState::WindowIsActive);
        if (priv->activityState & ActivityState::IsFocused)
            priv->inputMethodFilter.notifyFocusedIn();
    } else {
        if (!(priv->activityState & ActivityState::WindowIsActive))
            return;
        priv->activityState.remove(ActivityState::WindowIsActive);
        if (priv->activityState & ActivityState::IsFocused)
            priv->inputMethodFilter.notifyFocusedOut();
    }

    webkitWebViewBaseScheduleUpdateActivityState(webViewBase, ActivityState::WindowIsActive);
}

static void toplevelWindowStateChanged(GdkSurface* surface, GParamSpec*, WebKitWebViewBase* webViewBase)
{
    auto state = gdk_toplevel_get_state(GDK_TOPLEVEL(surface));
    bool visible = !(state & GDK_TOPLEVEL_STATE_MINIMIZED);
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    if (visible) {
        if (priv->activityState & ActivityState::IsVisible)
            return;
        priv->activityState.add(ActivityState::IsVisible);
    } else {
        if (!(priv->activityState & ActivityState::IsVisible))
            return;
        priv->activityState.remove(ActivityState::IsVisible);
    }
    webkitWebViewBaseScheduleUpdateActivityState(webViewBase, ActivityState::IsVisible);
}

static void toplevelWindowRealized(WebKitWebViewBase* webViewBase)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    g_clear_signal_handler(&priv->toplevelWindowRealizedID, priv->toplevelOnScreenWindow);
    priv->toplevelWindowStateChangedID =
        g_signal_connect(gtk_native_get_surface(GTK_NATIVE(priv->toplevelOnScreenWindow)), "notify::state", G_CALLBACK(toplevelWindowStateChanged), webViewBase);
}

static void toplevelWindowUnrealized(WebKitWebViewBase* webViewBase)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    g_clear_signal_handler(&priv->toplevelWindowUnrealizedID, priv->toplevelOnScreenWindow);
    g_clear_signal_handler(&priv->toplevelWindowStateChangedID, gtk_native_get_surface(GTK_NATIVE(priv->toplevelOnScreenWindow)));
}

static void webkitWebViewBaseRoot(GtkWidget* widget)
{
    GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->root(widget);

    WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget);
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    priv->toplevelOnScreenWindow = GTK_WINDOW(gtk_widget_get_root(widget));

    OptionSet<ActivityState::Flag> flagsToUpdate;
    if (!(priv->activityState & ActivityState::IsInWindow)) {
        priv->activityState.add(ActivityState::IsInWindow);
        flagsToUpdate.add(ActivityState::IsInWindow);
    }
    if (gtk_widget_get_visible(GTK_WIDGET(priv->toplevelOnScreenWindow)) && gtk_window_is_active(priv->toplevelOnScreenWindow)) {
        priv->activityState.add(ActivityState::WindowIsActive);
        flagsToUpdate.add(ActivityState::IsInWindow);
    }
    if (flagsToUpdate)
        webkitWebViewBaseScheduleUpdateActivityState(webViewBase, flagsToUpdate);

    priv->toplevelIsActiveID =
        g_signal_connect(priv->toplevelOnScreenWindow, "notify::is-active", G_CALLBACK(toplevelWindowIsActiveChanged), widget);
    if (gtk_widget_get_realized(GTK_WIDGET(priv->toplevelOnScreenWindow))) {
        priv->toplevelWindowStateChangedID =
            g_signal_connect(gtk_native_get_surface(GTK_NATIVE(priv->toplevelOnScreenWindow)), "notify::state", G_CALLBACK(toplevelWindowStateChanged), widget);
    } else {
        priv->toplevelWindowRealizedID =
            g_signal_connect_swapped(priv->toplevelOnScreenWindow, "realize", G_CALLBACK(toplevelWindowRealized), widget);
    }
    priv->toplevelWindowUnrealizedID =
        g_signal_connect_swapped(priv->toplevelOnScreenWindow, "unrealize", G_CALLBACK(toplevelWindowUnrealized), widget);
}

static void webkitWebViewBaseUnroot(GtkWidget* widget)
{
    GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->unroot(widget);

    WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget);
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    g_clear_signal_handler(&priv->toplevelIsActiveID, priv->toplevelOnScreenWindow);
    g_clear_signal_handler(&priv->toplevelWindowRealizedID, priv->toplevelOnScreenWindow);
    g_clear_signal_handler(&priv->toplevelWindowUnrealizedID, priv->toplevelOnScreenWindow);
    if (gtk_widget_get_realized(GTK_WIDGET(priv->toplevelOnScreenWindow)))
        g_clear_signal_handler(&priv->toplevelWindowStateChangedID, gtk_native_get_surface(GTK_NATIVE(priv->toplevelOnScreenWindow)));
    priv->toplevelOnScreenWindow = nullptr;

    OptionSet<ActivityState::Flag> flagsToUpdate;
    if (priv->activityState & ActivityState::IsInWindow) {
        priv->activityState.remove(ActivityState::IsInWindow);
        flagsToUpdate.add(ActivityState::IsInWindow);
    }
    if (priv->activityState & ActivityState::WindowIsActive) {
        priv->activityState.remove(ActivityState::WindowIsActive);
        flagsToUpdate.add(ActivityState::IsInWindow);
    }
    if (flagsToUpdate)
        webkitWebViewBaseScheduleUpdateActivityState(webViewBase, flagsToUpdate);
}
#else
static void webkitWebViewBaseHierarchyChanged(GtkWidget* widget, GtkWidget* oldToplevel)
{
    WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv;
    if (widgetIsOnscreenToplevelWindow(oldToplevel) && GTK_WINDOW(oldToplevel) == priv->toplevelOnScreenWindow) {
        webkitWebViewBaseSetToplevelOnScreenWindow(WEBKIT_WEB_VIEW_BASE(widget), nullptr);
        return;
    }

    if (!oldToplevel) {
        GtkWidget* toplevel = gtk_widget_get_toplevel(widget);
        if (widgetIsOnscreenToplevelWindow(toplevel))
            webkitWebViewBaseSetToplevelOnScreenWindow(WEBKIT_WEB_VIEW_BASE(widget), GTK_WINDOW(toplevel));
    }
}
#endif

#if USE(GTK4)
static gboolean webkitWebViewBaseGrabFocus(GtkWidget* widget)
{
    gtk_root_set_focus(gtk_widget_get_root(widget), widget);
    return TRUE;
}
#endif

static gboolean webkitWebViewBaseFocus(GtkWidget* widget, GtkDirectionType direction)
{
    // If a dialog is active, we need to forward focus events there. This
    // ensures that you can tab between elements in the box.
    WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv;
    if (priv->dialog) {
        gboolean returnValue;
        g_signal_emit_by_name(priv->dialog, "focus", direction, &returnValue);
        return returnValue;
    }

    return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->focus(widget, direction);
}


static void webkitWebViewBaseZoomBegin(WebKitWebViewBase* webViewBase, GdkEventSequence* sequence, GtkGesture* gesture)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    if (priv->pageGrabbedTouch)
        return;

    double x, y;
    gtk_gesture_get_bounding_box_center(gesture, &x, &y);

    auto* event = gtk_gesture_get_last_event(gesture, sequence);

    webkitWebViewBaseSynthesizeWheelEvent(webViewBase, event, 0, 0, x, y, WheelEventPhase::Began, WheelEventPhase::NoPhase, true);

    GtkGesture* click = GTK_GESTURE(g_object_get_data(G_OBJECT(webViewBase), "wk-view-multi-press-gesture"));
    gtk_gesture_set_state(click, GTK_EVENT_SEQUENCE_DENIED);
}

static void webkitWebViewBaseZoomChanged(WebKitWebViewBase* webViewBase, gdouble scale, GtkGesture* gesture)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    if (priv->pageGrabbedTouch)
        return;

    gtk_gesture_set_state(gesture, GTK_EVENT_SEQUENCE_CLAIMED);

    ViewGestureController* controller = webkitWebViewBaseViewGestureController(webViewBase);
    if (!controller)
        return;

    double x, y;
    gtk_gesture_get_bounding_box_center(gesture, &x, &y);
    FloatPoint origin = FloatPoint(x, y);

    controller->setMagnification(scale, origin);
}

static void webkitWebViewBaseZoomEnd(WebKitWebViewBase* webViewBase, GdkEventSequence* sequence, GtkGesture* gesture)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    if (priv->pageGrabbedTouch)
        return;

    gtk_gesture_set_state(gesture, GTK_EVENT_SEQUENCE_CLAIMED);

    ViewGestureController* controller = webkitWebViewBaseViewGestureController(webViewBase);
    if (!controller)
        return;

    controller->endMagnification();
}

static void webkitWebViewBaseTouchLongPress(WebKitWebViewBase* webViewBase, gdouble x, gdouble y, GtkGesture*)
{
    webViewBase->priv->isLongPressed = true;
}

static void webkitWebViewBaseTouchPress(WebKitWebViewBase* webViewBase, int nPress, double x, double y, GtkGesture*)
{
    webViewBase->priv->isLongPressed = false;
}

static void webkitWebViewBaseTouchRelease(WebKitWebViewBase* webViewBase, int nPress, double x, double y, GtkGesture* gesture)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    if (priv->pageGrabbedTouch)
        return;
    if (priv->isBeingDragged)
        return;

    unsigned button;
    unsigned buttons;
    if (priv->isLongPressed) {
        button = GDK_BUTTON_SECONDARY;
        buttons = GDK_BUTTON3_MASK;
    } else {
        button = GDK_BUTTON_PRIMARY;
        buttons = GDK_BUTTON1_MASK;
    }

    unsigned modifiers = gtk_event_controller_get_current_event_state(GTK_EVENT_CONTROLLER(gesture));
    webkitWebViewBaseSynthesizeMouseEvent(webViewBase, MouseEventType::Motion, 0, 0, x, y, modifiers, nPress, mousePointerEventType());
    webkitWebViewBaseSynthesizeMouseEvent(webViewBase, MouseEventType::Press, button, 0, x, y, modifiers, nPress, mousePointerEventType());
    webkitWebViewBaseSynthesizeMouseEvent(webViewBase, MouseEventType::Release, button, buttons, x, y, modifiers, nPress, mousePointerEventType());
}

static void webkitWebViewBaseTouchDragBegin(WebKitWebViewBase* webViewBase, gdouble startX, gdouble startY, GtkGesture* gesture)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    priv->dragOffset.set(0, 0);
    priv->isBeingDragged = false;

    auto* sequence = gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture));
    auto* event = gtk_gesture_get_last_event(gesture, sequence);

    webkitWebViewBaseSynthesizeWheelEvent(webViewBase, event, 0, 0, startX, startY, WheelEventPhase::Began, WheelEventPhase::NoPhase, true);
}

static void webkitWebViewBaseTouchDragUpdate(WebKitWebViewBase* webViewBase, double offsetX, double offsetY, GtkGesture* gesture)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    if (priv->pageGrabbedTouch)
        return;

    double x, y;
    gtk_gesture_drag_get_start_point(GTK_GESTURE_DRAG(gesture), &x, &y);

    auto* sequence = gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture));
    auto* event = gtk_gesture_get_last_event(gesture, sequence);

    unsigned modifiers = gtk_event_controller_get_current_event_state(GTK_EVENT_CONTROLLER(gesture));
    if (!priv->isBeingDragged) {
        if (!gtk_drag_check_threshold(GTK_WIDGET(webViewBase), 0, 0, static_cast<int>(offsetX), static_cast<int>(offsetY)))
            return;
        priv->isBeingDragged = true;
        gtk_gesture_set_state(gesture, GTK_EVENT_SEQUENCE_CLAIMED);

        if (priv->isLongPressed) {
            // Drag after long press forwards emulated mouse events (for e.g. text selection)
            webkitWebViewBaseSynthesizeMouseEvent(webViewBase, MouseEventType::Motion, 0, 0, x, y, modifiers, 1, mousePointerEventType());
            webkitWebViewBaseSynthesizeMouseEvent(webViewBase, MouseEventType::Press, GDK_BUTTON_PRIMARY, 0, x, y, modifiers, 0, mousePointerEventType());
        } else
            webkitWebViewBaseSynthesizeWheelEvent(webViewBase, event, 0, 0, x, y, WheelEventPhase::Began, WheelEventPhase::NoPhase, true);
    }

    if (priv->isLongPressed)
        webkitWebViewBaseSynthesizeMouseEvent(webViewBase, MouseEventType::Motion, GDK_BUTTON_PRIMARY, GDK_BUTTON1_MASK, x + offsetX, y + offsetY, modifiers, 0, mousePointerEventType());
    else {
        double deltaX = priv->dragOffset.x() - offsetX;
        double deltaY = priv->dragOffset.y() - offsetY;
        priv->dragOffset.set(offsetX, offsetY);

        ViewGestureController* controller = webkitWebViewBaseViewGestureController(webViewBase);
        if (controller && controller->isSwipeGestureEnabled()) {
            FloatSize delta(deltaX / Scrollbar::pixelsPerLineStep(), deltaY / Scrollbar::pixelsPerLineStep());
            int32_t eventTime = static_cast<int32_t>(gtk_event_controller_get_current_event_time(GTK_EVENT_CONTROLLER(gesture)));
            PlatformGtkScrollData scrollData = { .delta = delta, .eventTime = eventTime, .source = GDK_SOURCE_TOUCHSCREEN, .isEnd = false };
            if (controller->handleScrollWheelEvent(&scrollData))
                return;
        }

        webkitWebViewBaseSynthesizeWheelEvent(webViewBase, event, -deltaX, -deltaY, x, y, WheelEventPhase::Changed, WheelEventPhase::NoPhase, true);
    }
}

static void webkitWebViewBaseTouchDragEnd(WebKitWebViewBase* webViewBase, gdouble offsetX, gdouble offsetY, GtkGesture* gesture)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    if (priv->pageGrabbedTouch)
        return;

    if (priv->isLongPressed) {
        double x, y;
        gtk_gesture_drag_get_start_point(GTK_GESTURE_DRAG(gesture), &x, &y);
        unsigned modifiers = gtk_event_controller_get_current_event_state(GTK_EVENT_CONTROLLER(gesture));
        webkitWebViewBaseSynthesizeMouseEvent(webViewBase, MouseEventType::Release, GDK_BUTTON_PRIMARY, GDK_BUTTON1_MASK, x + offsetX, y + offsetY, modifiers, 0, mousePointerEventType());
    }
}

static void webkitWebViewBaseTouchDragCancel(WebKitWebViewBase* webViewBase, GdkEventSequence*, GtkGesture*)
{
    if (auto* controller = webkitWebViewBaseViewGestureController(webViewBase))
        controller->cancelSwipe();
}

static void webkitWebViewBaseTouchSwipe(WebKitWebViewBase* webViewBase, gdouble velocityX, gdouble velocityY, GtkGesture* gesture)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    if (priv->pageGrabbedTouch || !priv->isBeingDragged || priv->isLongPressed)
        return;

    double x, y;
    if (gtk_gesture_get_point(gesture, gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture)), &x, &y)) {
        auto* sequence = gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture));
        auto* event = gtk_gesture_get_last_event(gesture, sequence);

        ViewGestureController* controller = webkitWebViewBaseViewGestureController(webViewBase);
        if (controller && controller->isSwipeGestureEnabled()) {
            int32_t eventTime = static_cast<int32_t>(gtk_event_controller_get_current_event_time(GTK_EVENT_CONTROLLER(gesture)));
            PlatformGtkScrollData scrollData = { .delta = FloatSize(), .eventTime = eventTime, .source = GDK_SOURCE_TOUCHSCREEN, .isEnd = true };
            if (controller->handleScrollWheelEvent(&scrollData))
                return;
        }

        webkitWebViewBaseSynthesizeWheelEvent(webViewBase, event, -velocityX, -velocityY, x, y, WheelEventPhase::NoPhase, WheelEventPhase::Began, true);
    }
}

static void webkitWebViewBaseConstructed(GObject* object)
{
    G_OBJECT_CLASS(webkit_web_view_base_parent_class)->constructed(object);

    GtkWidget* viewWidget = GTK_WIDGET(object);
    gtk_widget_set_can_focus(viewWidget, TRUE);

    WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(object)->priv;
    priv->pageClient = makeUnique<PageClientImpl>(viewWidget);
    gtk_widget_set_parent(priv->keyBindingTranslator.widget(), viewWidget);

#if ENABLE(DRAG_SUPPORT)
    priv->dropTarget = makeUnique<DropTarget>(viewWidget);
#endif

#if USE(GTK4)
    auto* controller = gtk_event_controller_scroll_new(GTK_EVENT_CONTROLLER_SCROLL_BOTH_AXES);
    g_signal_connect_object(controller, "scroll", G_CALLBACK(webkitWebViewBaseScroll), viewWidget, G_CONNECT_SWAPPED);
    g_signal_connect_object(controller, "scroll-end", G_CALLBACK(webkitWebViewBaseScrollEnd), viewWidget, G_CONNECT_SWAPPED);
    gtk_widget_add_controller(viewWidget, controller);

    controller = gtk_event_controller_motion_new();
    g_signal_connect_object(controller, "enter", G_CALLBACK(webkitWebViewBaseEnter), viewWidget, G_CONNECT_SWAPPED);
    g_signal_connect_object(controller, "motion", G_CALLBACK(webkitWebViewBaseMotion), viewWidget, G_CONNECT_SWAPPED);
    g_signal_connect_object(controller, "leave", G_CALLBACK(webkitWebViewBaseLeave), viewWidget, G_CONNECT_SWAPPED);
    gtk_widget_add_controller(viewWidget, controller);

    controller = gtk_event_controller_focus_new();
    g_signal_connect_object(controller, "enter", G_CALLBACK(webkitWebViewBaseFocusEnter), viewWidget, G_CONNECT_SWAPPED);
    g_signal_connect_object(controller, "leave", G_CALLBACK(webkitWebViewBaseFocusLeave), viewWidget, G_CONNECT_SWAPPED);
    gtk_widget_add_controller(viewWidget, controller);

    controller = gtk_event_controller_key_new();
    g_signal_connect_object(controller, "key-pressed", G_CALLBACK(webkitWebViewBaseKeyPressed), viewWidget, G_CONNECT_SWAPPED);
    g_signal_connect_object(controller, "key-released", G_CALLBACK(webkitWebViewBaseKeyReleased), viewWidget, G_CONNECT_SWAPPED);
    gtk_widget_add_controller(viewWidget, controller);

    controller = gtk_event_controller_legacy_new();
    gtk_event_controller_set_propagation_phase(GTK_EVENT_CONTROLLER(controller), GTK_PHASE_TARGET);
    g_signal_connect_object(controller, "event", G_CALLBACK(webkitWebViewBaseTouchEvent), viewWidget, G_CONNECT_SWAPPED);
    gtk_widget_add_controller(viewWidget, GTK_EVENT_CONTROLLER(controller));

    auto* gesture = gtk_gesture_click_new();
    gtk_gesture_single_set_button(GTK_GESTURE_SINGLE(gesture), 0);
    gtk_gesture_single_set_exclusive(GTK_GESTURE_SINGLE(gesture), TRUE);
    g_signal_connect_object(gesture, "pressed", G_CALLBACK(webkitWebViewBaseButtonPressed), viewWidget, G_CONNECT_SWAPPED);
    g_signal_connect_object(gesture, "released", G_CALLBACK(webkitWebViewBaseButtonReleased), viewWidget, G_CONNECT_SWAPPED);
    gtk_widget_add_controller(viewWidget, GTK_EVENT_CONTROLLER(gesture));
#endif

#if USE(GTK4)
    gesture = gtk_gesture_click_new();
    gtk_widget_add_controller(viewWidget, GTK_EVENT_CONTROLLER(gesture));
#else
    auto* gesture = gtk_gesture_multi_press_new(viewWidget);
    g_object_set_data_full(G_OBJECT(viewWidget), "wk-view-multi-press-gesture", gesture, g_object_unref);
#endif
    gtk_gesture_single_set_touch_only(GTK_GESTURE_SINGLE(gesture), TRUE);
    g_signal_connect_object(gesture, "pressed", G_CALLBACK(webkitWebViewBaseTouchPress), viewWidget, G_CONNECT_SWAPPED);
    g_signal_connect_object(gesture, "released", G_CALLBACK(webkitWebViewBaseTouchRelease), viewWidget, G_CONNECT_SWAPPED);

    // Touch gestures
#if USE(GTK4)
    priv->touchGestureGroup = gtk_gesture_zoom_new();
    gtk_widget_add_controller(viewWidget, GTK_EVENT_CONTROLLER(priv->touchGestureGroup));
#else
    priv->touchGestureGroup = gtk_gesture_zoom_new(viewWidget);
    g_object_set_data_full(G_OBJECT(viewWidget), "wk-view-zoom-gesture", priv->touchGestureGroup, g_object_unref);
#endif
    g_signal_connect_object(priv->touchGestureGroup, "begin", G_CALLBACK(webkitWebViewBaseZoomBegin), viewWidget, G_CONNECT_SWAPPED);
    g_signal_connect_object(priv->touchGestureGroup, "scale-changed", G_CALLBACK(webkitWebViewBaseZoomChanged), viewWidget, G_CONNECT_SWAPPED);
    g_signal_connect_object(priv->touchGestureGroup, "end", G_CALLBACK(webkitWebViewBaseZoomEnd), viewWidget, G_CONNECT_SWAPPED);

#if USE(GTK4)
    gesture = gtk_gesture_long_press_new();
    gtk_widget_add_controller(viewWidget, GTK_EVENT_CONTROLLER(gesture));
#else
    gesture = gtk_gesture_long_press_new(viewWidget);
    g_object_set_data_full(G_OBJECT(viewWidget), "wk-view-long-press-gesture", gesture, g_object_unref);
#endif
    gtk_gesture_group(gesture, priv->touchGestureGroup);
    gtk_gesture_single_set_touch_only(GTK_GESTURE_SINGLE(gesture), TRUE);
    g_signal_connect_object(gesture, "pressed", G_CALLBACK(webkitWebViewBaseTouchLongPress), viewWidget, G_CONNECT_SWAPPED);

#if USE(GTK4)
    gesture = gtk_gesture_drag_new();
    gtk_widget_add_controller(viewWidget, GTK_EVENT_CONTROLLER(gesture));
#else
    gesture = gtk_gesture_drag_new(viewWidget);
    g_object_set_data_full(G_OBJECT(viewWidget), "wk-view-drag-gesture", gesture, g_object_unref);
#endif
    gtk_gesture_group(gesture, priv->touchGestureGroup);
    gtk_gesture_single_set_touch_only(GTK_GESTURE_SINGLE(gesture), TRUE);
    g_signal_connect_object(gesture, "drag-begin", G_CALLBACK(webkitWebViewBaseTouchDragBegin), viewWidget, G_CONNECT_SWAPPED);
    g_signal_connect_object(gesture, "drag-update", G_CALLBACK(webkitWebViewBaseTouchDragUpdate), viewWidget, G_CONNECT_SWAPPED);
    g_signal_connect_object(gesture, "drag-end", G_CALLBACK(webkitWebViewBaseTouchDragEnd), viewWidget, G_CONNECT_SWAPPED);
    g_signal_connect_object(gesture, "cancel", G_CALLBACK(webkitWebViewBaseTouchDragCancel), viewWidget, G_CONNECT_SWAPPED);

#if USE(GTK4)
    gesture = gtk_gesture_swipe_new();
    gtk_widget_add_controller(viewWidget, GTK_EVENT_CONTROLLER(gesture));
#else
    gesture = gtk_gesture_swipe_new(viewWidget);
    g_object_set_data_full(G_OBJECT(viewWidget), "wk-view-swipe-gesture", gesture, g_object_unref);
#endif
    gtk_gesture_group(gesture, priv->touchGestureGroup);
    gtk_gesture_single_set_touch_only(GTK_GESTURE_SINGLE(gesture), TRUE);
    g_signal_connect_object(gesture, "swipe", G_CALLBACK(webkitWebViewBaseTouchSwipe), viewWidget, G_CONNECT_SWAPPED);

    auto* settings = gtk_settings_get_default();
    auto callback = +[](WebKitWebViewBase* webViewBase) {
        webViewBase->priv->pageProxy->effectiveAppearanceDidChange();
    };
    g_signal_connect_object(settings, "notify::gtk-theme-name", G_CALLBACK(callback), viewWidget, G_CONNECT_SWAPPED);
    g_signal_connect_object(settings, "notify::gtk-application-prefer-dark-theme", G_CALLBACK(callback), viewWidget, G_CONNECT_SWAPPED);
}

static void webkit_web_view_base_class_init(WebKitWebViewBaseClass* webkitWebViewBaseClass)
{
    GtkWidgetClass* widgetClass = GTK_WIDGET_CLASS(webkitWebViewBaseClass);
    widgetClass->realize = webkitWebViewBaseRealize;
    widgetClass->unrealize = webkitWebViewBaseUnrealize;
#if USE(GTK4)
    widgetClass->snapshot = webkitWebViewBaseSnapshot;
#else
    widgetClass->draw = webkitWebViewBaseDraw;
#endif
    widgetClass->size_allocate = webkitWebViewBaseSizeAllocate;
#if USE(GTK4)
    widgetClass->measure = webkitWebViewBaseMeasure;
#else
    widgetClass->get_preferred_width = webkitWebViewBaseGetPreferredWidth;
    widgetClass->get_preferred_height = webkitWebViewBaseGetPreferredHeight;
#endif
    widgetClass->map = webkitWebViewBaseMap;
    widgetClass->unmap = webkitWebViewBaseUnmap;
    widgetClass->focus = webkitWebViewBaseFocus;
#if USE(GTK4)
    widgetClass->grab_focus = webkitWebViewBaseGrabFocus;
#else
    widgetClass->focus_in_event = webkitWebViewBaseFocusInEvent;
    widgetClass->focus_out_event = webkitWebViewBaseFocusOutEvent;
    widgetClass->key_press_event = webkitWebViewBaseKeyPressEvent;
    widgetClass->key_release_event = webkitWebViewBaseKeyReleaseEvent;
    widgetClass->button_press_event = webkitWebViewBaseButtonPressEvent;
    widgetClass->button_release_event = webkitWebViewBaseButtonReleaseEvent;
    widgetClass->scroll_event = webkitWebViewBaseScrollEvent;
    widgetClass->popup_menu = webkitWebViewBasePopupMenu;
    widgetClass->motion_notify_event = webkitWebViewBaseMotionNotifyEvent;
    widgetClass->enter_notify_event = webkitWebViewBaseCrossingNotifyEvent;
    widgetClass->leave_notify_event = webkitWebViewBaseCrossingNotifyEvent;
#endif
#if ENABLE(TOUCH_EVENTS) && !USE(GTK4)
    widgetClass->touch_event = webkitWebViewBaseTouchEvent;
#endif
    widgetClass->query_tooltip = webkitWebViewBaseQueryTooltip;
#if !USE(GTK4)
    widgetClass->get_accessible = webkitWebViewBaseGetAccessible;
#endif
#if USE(GTK4)
    widgetClass->root = webkitWebViewBaseRoot;
    widgetClass->unroot = webkitWebViewBaseUnroot;
#else
    widgetClass->hierarchy_changed = webkitWebViewBaseHierarchyChanged;
#endif

    GObjectClass* gobjectClass = G_OBJECT_CLASS(webkitWebViewBaseClass);
    gobjectClass->constructed = webkitWebViewBaseConstructed;
    gobjectClass->dispose = webkitWebViewBaseDispose;

#if !USE(GTK4)
    GtkContainerClass* containerClass = GTK_CONTAINER_CLASS(webkitWebViewBaseClass);
    containerClass->add = webkitWebViewBaseContainerAdd;
    containerClass->remove = webkitWebViewBaseContainerRemove;
    containerClass->forall = webkitWebViewBaseContainerForall;
#endif

    // Before creating a WebKitWebViewBasePriv we need to be sure that WebKit is started.
    // Usually starting a context triggers webkitInitialize, but in case
    // we create a view without asking before for a default_context we get a crash.
    WebKit::webkitInitialize();

    gtk_widget_class_set_css_name(widgetClass, "webkitwebview");
}

WebKitWebViewBase* webkitWebViewBaseCreate(const API::PageConfiguration& configuration)
{
    WebKitWebViewBase* webkitWebViewBase = WEBKIT_WEB_VIEW_BASE(g_object_new(WEBKIT_TYPE_WEB_VIEW_BASE, nullptr));
    webkitWebViewBaseCreateWebPage(webkitWebViewBase, configuration.copy());
    return webkitWebViewBase;
}

WebPageProxy* webkitWebViewBaseGetPage(WebKitWebViewBase* webkitWebViewBase)
{
    return webkitWebViewBase->priv->pageProxy.get();
}

static void deviceScaleFactorChanged(WebKitWebViewBase* webkitWebViewBase)
{
    webkitWebViewBase->priv->pageProxy->setIntrinsicDeviceScaleFactor(gtk_widget_get_scale_factor(GTK_WIDGET(webkitWebViewBase)));
}

void webkitWebViewBaseCreateWebPage(WebKitWebViewBase* webkitWebViewBase, Ref<API::PageConfiguration>&& configuration)
{
    WebKitWebViewBasePrivate* priv = webkitWebViewBase->priv;
    WebProcessPool* processPool = configuration->processPool();
    priv->pageProxy = processPool->createWebPage(*priv->pageClient, WTFMove(configuration));
    priv->acceleratedBackingStore = AcceleratedBackingStore::create(*priv->pageProxy);
    priv->pageProxy->initializeWebPage();

    // We attach this here, because changes in scale factor are passed directly to the page proxy.
    priv->pageProxy->setIntrinsicDeviceScaleFactor(gtk_widget_get_scale_factor(GTK_WIDGET(webkitWebViewBase)));
    g_signal_connect(webkitWebViewBase, "notify::scale-factor", G_CALLBACK(deviceScaleFactorChanged), nullptr);
}

void webkitWebViewBaseSetTooltipText(WebKitWebViewBase* webViewBase, const char* tooltip)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    if (tooltip && tooltip[0] != '\0') {
        priv->tooltipText = tooltip;
        gtk_widget_set_has_tooltip(GTK_WIDGET(webViewBase), TRUE);
    } else {
        priv->tooltipText = "";
        gtk_widget_set_has_tooltip(GTK_WIDGET(webViewBase), FALSE);
    }

    gtk_widget_trigger_tooltip_query(GTK_WIDGET(webViewBase));
}

void webkitWebViewBaseSetTooltipArea(WebKitWebViewBase* webViewBase, const IntRect& tooltipArea)
{
    webViewBase->priv->tooltipArea = tooltipArea;
}

void webkitWebViewBaseSetMouseIsOverScrollbar(WebKitWebViewBase* webViewBase, WebHitTestResultData::IsScrollbar isScrollbar)
{
    webViewBase->priv->mouseIsOverScrollbar = isScrollbar;
}

#if ENABLE(DRAG_SUPPORT)
void webkitWebViewBaseStartDrag(WebKitWebViewBase* webViewBase, SelectionData&& selectionData, OptionSet<DragOperation> dragOperationMask, RefPtr<ShareableBitmap>&& image)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    if (!priv->dragSource)
        priv->dragSource = makeUnique<DragSource>(GTK_WIDGET(webViewBase));

    priv->dragSource->begin(WTFMove(selectionData), dragOperationMask, WTFMove(image));

#if !USE(GTK4)
    // A drag starting should prevent a double-click from happening. This might
    // happen if a drag is followed very quickly by another click (like in the WTR).
    priv->clickCounter.reset();
#endif
}

void webkitWebViewBaseDidPerformDragControllerAction(WebKitWebViewBase* webViewBase)
{
    webViewBase->priv->dropTarget->didPerformAction();
}
#endif // ENABLE(DRAG_SUPPORT)

void webkitWebViewBaseForwardNextKeyEvent(WebKitWebViewBase* webkitWebViewBase)
{
    webkitWebViewBase->priv->shouldForwardNextKeyEvent = TRUE;
}

void webkitWebViewBaseForwardNextWheelEvent(WebKitWebViewBase* webkitWebViewBase)
{
    webkitWebViewBase->priv->shouldForwardNextWheelEvent = true;
}

void webkitWebViewBaseEnterFullScreen(WebKitWebViewBase* webkitWebViewBase)
{
#if ENABLE(FULLSCREEN_API)
    WebKitWebViewBasePrivate* priv = webkitWebViewBase->priv;
    ASSERT(!priv->fullScreenModeActive);

    WebFullScreenManagerProxy* fullScreenManagerProxy = priv->pageProxy->fullScreenManager();
    fullScreenManagerProxy->willEnterFullScreen();

    GtkWidget* topLevelWindow = gtk_widget_get_toplevel(GTK_WIDGET(webkitWebViewBase));
    if (gtk_widget_is_toplevel(topLevelWindow))
        gtk_window_fullscreen(GTK_WINDOW(topLevelWindow));
    fullScreenManagerProxy->didEnterFullScreen();
    priv->fullScreenModeActive = true;
    priv->sleepDisabler = PAL::SleepDisabler::create(_("Website running in fullscreen mode"), PAL::SleepDisabler::Type::Display);
#endif
}

void webkitWebViewBaseExitFullScreen(WebKitWebViewBase* webkitWebViewBase)
{
#if ENABLE(FULLSCREEN_API)
    WebKitWebViewBasePrivate* priv = webkitWebViewBase->priv;
    ASSERT(priv->fullScreenModeActive);

    WebFullScreenManagerProxy* fullScreenManagerProxy = priv->pageProxy->fullScreenManager();
    fullScreenManagerProxy->willExitFullScreen();

    GtkWidget* topLevelWindow = gtk_widget_get_toplevel(GTK_WIDGET(webkitWebViewBase));
    if (gtk_widget_is_toplevel(topLevelWindow))
        gtk_window_unfullscreen(GTK_WINDOW(topLevelWindow));
    fullScreenManagerProxy->didExitFullScreen();
    priv->fullScreenModeActive = false;
    priv->sleepDisabler = nullptr;
#endif
}

bool webkitWebViewBaseIsFullScreen(WebKitWebViewBase* webkitWebViewBase)
{
#if ENABLE(FULLSCREEN_API)
    return webkitWebViewBase->priv->fullScreenModeActive;
#else
    return false;
#endif
}

void webkitWebViewBaseSetInspectorViewSize(WebKitWebViewBase* webkitWebViewBase, unsigned size)
{
    if (webkitWebViewBase->priv->inspectorViewSize == size)
        return;
    webkitWebViewBase->priv->inspectorViewSize = size;
    if (webkitWebViewBase->priv->inspectorView)
        gtk_widget_queue_resize_no_redraw(GTK_WIDGET(webkitWebViewBase));
}

void webkitWebViewBaseSetActiveContextMenuProxy(WebKitWebViewBase* webkitWebViewBase, WebContextMenuProxyGtk* contextMenuProxy)
{
    webkitWebViewBase->priv->activeContextMenuProxy = contextMenuProxy;
    g_signal_connect(contextMenuProxy->gtkWidget(), WebContextMenuProxyGtk::widgetDismissedSignal, G_CALLBACK(+[](GtkWidget* widget, WebKitWebViewBase* webViewBase) {
        if (webViewBase->priv->activeContextMenuProxy && webViewBase->priv->activeContextMenuProxy->gtkWidget() == widget)
            webViewBase->priv->activeContextMenuProxy = nullptr;
    }), webkitWebViewBase);
}

WebContextMenuProxyGtk* webkitWebViewBaseGetActiveContextMenuProxy(WebKitWebViewBase* webkitWebViewBase)
{
    return webkitWebViewBase->priv->activeContextMenuProxy;
}

GdkEvent* webkitWebViewBaseTakeContextMenuEvent(WebKitWebViewBase* webkitWebViewBase)
{
    return webkitWebViewBase->priv->contextMenuEvent.release();
}

void webkitWebViewBaseSetFocus(WebKitWebViewBase* webViewBase, bool focused)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    if (!priv->shouldNotifyFocusEvents)
        return;
    if ((focused && priv->activityState & ActivityState::IsFocused) || (!focused && !(priv->activityState & ActivityState::IsFocused)))
        return;

    OptionSet<ActivityState::Flag> flagsToUpdate { ActivityState::IsFocused };
    if (focused) {
        priv->activityState.add(ActivityState::IsFocused);

        // 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->activityState & ActivityState::WindowIsActive)) {
            priv->activityState.add(ActivityState::WindowIsActive);
            flagsToUpdate.add(ActivityState::WindowIsActive);
        }
    } else
        priv->activityState.remove(ActivityState::IsFocused);

    webkitWebViewBaseScheduleUpdateActivityState(webViewBase, flagsToUpdate);
}

IntSize webkitWebViewBaseGetViewSize(WebKitWebViewBase* webViewBase)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    int width = priv->viewSize.width();
    int height = priv->viewSize.height();

    // First try the widget's own size. If it's already allocated,
    // everything is fine and we'll just use that.
    if (width > 0 || height > 0)
        return IntSize(width, height);

    GtkWidget* parent = gtk_widget_get_parent(GTK_WIDGET(webViewBase));

    // If it's not allocated, then its size will be 0. This can be a problem
    // if the web view is loaded in background and the container doesn't
    // allocate non-visible children: e.g. GtkNotebook in GTK3 does allocate
    // them, but GtkStack, and so GtkNotebook in GTK4 and HdyTabView don't.
    // See https://gitlab.gnome.org/GNOME/epiphany/-/issues/1532
    // In that case we go up through the hierarchy and try to find a parent
    // with non-0 size.
    while (parent) {
#if USE(GTK4)
        width = gtk_widget_get_width(parent);
        height = gtk_widget_get_height(parent);

        if (width > 0 || height > 0)
#else
        width = gtk_widget_get_allocated_width(parent);
        height = gtk_widget_get_allocated_height(parent);

        // The default widget size in GTK3 is 1x1, not 0x0.
        if (width > 1 || height > 1)
#endif
            return IntSize(width, height);

        parent = gtk_widget_get_parent(parent);
    }

    // If there was no such a parent, it's likely the widget widget isn't
    // in a window, or the whole window isn't mapped. No point in trying
    // in this case.

    return IntSize();
}

bool webkitWebViewBaseIsInWindowActive(WebKitWebViewBase* webViewBase)
{
    return webViewBase->priv->activityState.contains(ActivityState::WindowIsActive);
}

bool webkitWebViewBaseIsFocused(WebKitWebViewBase* webViewBase)
{
#if ENABLE(DEVELOPER_MODE)
    // Xvfb doesn't support toplevel focus, so the view is never focused. We consider it to tbe focused when
    // its window is marked as active.
    if (WebCore::PlatformDisplay::sharedDisplay().type() == WebCore::PlatformDisplay::Type::X11) {
        if (!g_strcmp0(g_getenv("UNDER_XVFB"), "yes") && webViewBase->priv->activityState.contains(ActivityState::WindowIsActive))
            return true;
    }
#endif
    return webViewBase->priv->activityState.contains(ActivityState::IsFocused);
}

bool webkitWebViewBaseIsVisible(WebKitWebViewBase* webViewBase)
{
    return webViewBase->priv->activityState.contains(ActivityState::IsVisible);
}

bool webkitWebViewBaseIsInWindow(WebKitWebViewBase* webViewBase)
{
    return webViewBase->priv->activityState.contains(ActivityState::IsInWindow);
}

void webkitWebViewBaseSetInputMethodState(WebKitWebViewBase* webkitWebViewBase, std::optional<InputMethodState>&& state)
{
    webkitWebViewBase->priv->inputMethodFilter.setState(WTFMove(state));
}

void webkitWebViewBaseUpdateTextInputState(WebKitWebViewBase* webkitWebViewBase)
{
    const auto& editorState = webkitWebViewBase->priv->pageProxy->editorState();
    if (!editorState.isMissingPostLayoutData) {
        webkitWebViewBase->priv->inputMethodFilter.notifyCursorRect(editorState.postLayoutData().caretRectAtStart);
        webkitWebViewBase->priv->inputMethodFilter.notifySurrounding(editorState.postLayoutData().surroundingContext, editorState.postLayoutData().surroundingContextCursorPosition,
            editorState.postLayoutData().surroundingContextSelectionPosition);
    }
}

void webkitWebViewBaseSetContentsSize(WebKitWebViewBase* webkitWebViewBase, const IntSize& contentsSize)
{
    WebKitWebViewBasePrivate* priv = webkitWebViewBase->priv;
    if (priv->contentsSize == contentsSize)
        return;
    priv->contentsSize = contentsSize;
}

void webkitWebViewBaseResetClickCounter(WebKitWebViewBase* webkitWebViewBase)
{
#if !USE(GTK4)
    webkitWebViewBase->priv->clickCounter.reset();
#endif
}

void webkitWebViewBaseEnterAcceleratedCompositingMode(WebKitWebViewBase* webkitWebViewBase, const LayerTreeContext& layerTreeContext)
{
    ASSERT(webkitWebViewBase->priv->acceleratedBackingStore);
    webkitWebViewBase->priv->acceleratedBackingStore->update(layerTreeContext);
}

void webkitWebViewBaseUpdateAcceleratedCompositingMode(WebKitWebViewBase* webkitWebViewBase, const LayerTreeContext& layerTreeContext)
{
    ASSERT(webkitWebViewBase->priv->acceleratedBackingStore);
    webkitWebViewBase->priv->acceleratedBackingStore->update(layerTreeContext);
}

void webkitWebViewBaseExitAcceleratedCompositingMode(WebKitWebViewBase* webkitWebViewBase)
{
    ASSERT(webkitWebViewBase->priv->acceleratedBackingStore);
    webkitWebViewBase->priv->acceleratedBackingStore->update(LayerTreeContext());
}

bool webkitWebViewBaseMakeGLContextCurrent(WebKitWebViewBase* webkitWebViewBase)
{
    ASSERT(webkitWebViewBase->priv->acceleratedBackingStore);
    return webkitWebViewBase->priv->acceleratedBackingStore->makeContextCurrent();
}

void webkitWebViewBaseWillSwapWebProcess(WebKitWebViewBase* webkitWebViewBase)
{
    WebKitWebViewBasePrivate* priv = webkitWebViewBase->priv;
    if (priv->viewGestureController)
        priv->viewGestureController->disconnectFromProcess();
}

void webkitWebViewBaseDidExitWebProcess(WebKitWebViewBase* webkitWebViewBase)
{
    webkitWebViewBase->priv->viewGestureController = nullptr;
}

void webkitWebViewBaseDidRelaunchWebProcess(WebKitWebViewBase* webkitWebViewBase)
{
    // Queue a resize to ensure the new DrawingAreaProxy is resized.
    gtk_widget_queue_resize_no_redraw(GTK_WIDGET(webkitWebViewBase));

    WebKitWebViewBasePrivate* priv = webkitWebViewBase->priv;
    if (priv->acceleratedBackingStore) {
        auto* drawingArea = static_cast<DrawingAreaProxyCoordinatedGraphics*>(priv->pageProxy->drawingArea());
        priv->acceleratedBackingStore->update(drawingArea->layerTreeContext());
    }
    if (priv->viewGestureController)
        priv->viewGestureController->connectToProcess();
    else {
        priv->viewGestureController = makeUnique<WebKit::ViewGestureController>(*priv->pageProxy);
        priv->viewGestureController->setSwipeGestureEnabled(priv->isBackForwardNavigationGestureEnabled);
    }
}

void webkitWebViewBasePageClosed(WebKitWebViewBase* webkitWebViewBase)
{
    if (webkitWebViewBase->priv->acceleratedBackingStore)
        webkitWebViewBase->priv->acceleratedBackingStore->update({ });
}

RefPtr<WebKit::ViewSnapshot> webkitWebViewBaseTakeViewSnapshot(WebKitWebViewBase* webkitWebViewBase, std::optional<IntRect>&& clipRect)
{
    WebPageProxy* page = webkitWebViewBase->priv->pageProxy.get();

    IntSize size = clipRect ? clipRect->size() : page->viewSize();
    float deviceScale = page->deviceScaleFactor();
    size.scale(deviceScale);

#if !USE(GTK4)
    RefPtr<cairo_surface_t> surface = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_RGB24, size.width(), size.height()));
    cairo_surface_set_device_scale(surface.get(), deviceScale, deviceScale);

    RefPtr<cairo_t> cr = adoptRef(cairo_create(surface.get()));
    if (clipRect) {
        cairo_translate(cr.get(), -clipRect->x(), -clipRect->y());
        cairo_rectangle(cr.get(), clipRect->x(), clipRect->y(), clipRect->width(), clipRect->height());
        cairo_clip(cr.get());
    }
    webkitWebViewBaseDraw(GTK_WIDGET(webkitWebViewBase), cr.get());

    return ViewSnapshot::create(WTFMove(surface));
#else
    WebKitWebViewBasePrivate* priv = webkitWebViewBase->priv;
    auto* renderer = gtk_native_get_renderer(GTK_NATIVE(priv->toplevelOnScreenWindow));

    GRefPtr<GtkSnapshot> snapshot = adoptGRef(gtk_snapshot_new());

    if (clipRect) {
        graphene_point_t point = { -static_cast<float>(clipRect->x()), -static_cast<float>(clipRect->y()) };
        graphene_rect_t rect = {
            { static_cast<float>(clipRect->x()), static_cast<float>(clipRect->y()) },
            { static_cast<float>(clipRect->width()), static_cast<float>(clipRect->height()) }
        };

        gtk_snapshot_translate(snapshot.get(), &point);
        gtk_snapshot_push_clip(snapshot.get(), &rect);
    }

    gtk_snapshot_scale(snapshot.get(), deviceScale, deviceScale);
    webkitWebViewBaseSnapshot(GTK_WIDGET(webkitWebViewBase), snapshot.get());

    if (clipRect)
        gtk_snapshot_pop(snapshot.get());

    GRefPtr<GskRenderNode> renderNode = adoptGRef(gtk_snapshot_to_node(snapshot.get()));

    graphene_rect_t viewport = { 0, 0, static_cast<float>(size.width()), static_cast<float>(size.height()) };
    GdkTexture* texture = gsk_renderer_render_texture(renderer, renderNode.get(), &viewport);

    return ViewSnapshot::create(WTFMove(texture));
#endif
}

void webkitWebViewBaseDidStartProvisionalLoadForMainFrame(WebKitWebViewBase* webkitWebViewBase)
{
    ViewGestureController* controller = webkitWebViewBaseViewGestureController(webkitWebViewBase);
    if (controller && controller->isSwipeGestureEnabled())
        controller->didStartProvisionalLoadForMainFrame();
}

void webkitWebViewBaseDidFirstVisuallyNonEmptyLayoutForMainFrame(WebKitWebViewBase* webkitWebViewBase)
{
    ViewGestureController* controller = webkitWebViewBaseViewGestureController(webkitWebViewBase);
    if (controller && controller->isSwipeGestureEnabled())
        controller->didFirstVisuallyNonEmptyLayoutForMainFrame();
}

void webkitWebViewBaseDidFinishNavigation(WebKitWebViewBase* webkitWebViewBase, API::Navigation* navigation)
{
    ViewGestureController* controller = webkitWebViewBaseViewGestureController(webkitWebViewBase);
    if (controller && controller->isSwipeGestureEnabled())
        controller->didFinishNavigation(navigation);
}

void webkitWebViewBaseDidFailNavigation(WebKitWebViewBase* webkitWebViewBase, API::Navigation* navigation)
{
    ViewGestureController* controller = webkitWebViewBaseViewGestureController(webkitWebViewBase);
    if (controller && controller->isSwipeGestureEnabled())
        controller->didFailNavigation(navigation);
}

void webkitWebViewBaseDidSameDocumentNavigationForMainFrame(WebKitWebViewBase* webkitWebViewBase, SameDocumentNavigationType type)
{
    ViewGestureController* controller = webkitWebViewBaseViewGestureController(webkitWebViewBase);
    if (controller && controller->isSwipeGestureEnabled())
        controller->didSameDocumentNavigationForMainFrame(type);
}

void webkitWebViewBaseDidRestoreScrollPosition(WebKitWebViewBase* webkitWebViewBase)
{
    ViewGestureController* controller = webkitWebViewBaseViewGestureController(webkitWebViewBase);
    if (controller && controller->isSwipeGestureEnabled())
        webkitWebViewBase->priv->viewGestureController->didRestoreScrollPosition();
}

#if GTK_CHECK_VERSION(3, 24, 0)
static void emojiChooserEmojiPicked(WebKitWebViewBase* webkitWebViewBase, const char* text)
{
    webkitWebViewBaseCompleteEmojiChooserRequest(webkitWebViewBase, String::fromUTF8(text));
}

static void emojiChooserClosed(WebKitWebViewBase* webkitWebViewBase)
{
    // The emoji chooser first closes the popover and then emits emoji-picked signal, so complete
    // the request if the emoji isn't picked before the next run loop iteration.
    RunLoop::main().dispatch([webViewBase = GRefPtr<WebKitWebViewBase>(webkitWebViewBase)] {
        webkitWebViewBaseCompleteEmojiChooserRequest(webViewBase.get(), emptyString());
    });
    webkitWebViewBase->priv->releaseEmojiChooserTimer.startOneShot(2_min);
}
#endif

void webkitWebViewBaseShowEmojiChooser(WebKitWebViewBase* webkitWebViewBase, const IntRect& caretRect, CompletionHandler<void(String)>&& completionHandler)
{
#if GTK_CHECK_VERSION(3, 24, 0)
    WebKitWebViewBasePrivate* priv = webkitWebViewBase->priv;
    priv->releaseEmojiChooserTimer.stop();

    if (!priv->emojiChooser) {
#if USE(GTK4)
        priv->emojiChooser = gtk_emoji_chooser_new();
        gtk_widget_set_parent(priv->emojiChooser, GTK_WIDGET(webkitWebViewBase));
#else
        priv->emojiChooser = webkitEmojiChooserNew();
        gtk_popover_set_relative_to(GTK_POPOVER(priv->emojiChooser), GTK_WIDGET(webkitWebViewBase));
#endif
        g_signal_connect_swapped(priv->emojiChooser, "emoji-picked", G_CALLBACK(emojiChooserEmojiPicked), webkitWebViewBase);
        g_signal_connect_swapped(priv->emojiChooser, "closed", G_CALLBACK(emojiChooserClosed), webkitWebViewBase);
    }

    priv->emojiChooserCompletionHandler = WTFMove(completionHandler);

    GdkRectangle gdkCaretRect = caretRect;
    gtk_popover_set_pointing_to(GTK_POPOVER(priv->emojiChooser), &gdkCaretRect);
    gtk_popover_popup(GTK_POPOVER(priv->emojiChooser));
#else
    UNUSED_PARAM(webkitWebViewBase);
    UNUSED_PARAM(caretRect);
    completionHandler(emptyString());
#endif
}

#if USE(WPE_RENDERER)
int webkitWebViewBaseRenderHostFileDescriptor(WebKitWebViewBase* webkitWebViewBase)
{
    if (!webkitWebViewBase->priv->acceleratedBackingStore)
        return -1;
    return webkitWebViewBase->priv->acceleratedBackingStore->renderHostFileDescriptor();
}
#endif

void webkitWebViewBaseRequestPointerLock(WebKitWebViewBase* webViewBase)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    ASSERT(!priv->pointerLockManager);
    if (!priv->lastMotionEvent)
        priv->lastMotionEvent = MotionEvent(GTK_WIDGET(webViewBase), nullptr);
    priv->pointerLockManager = PointerLockManager::create(*priv->pageProxy, priv->lastMotionEvent->position, priv->lastMotionEvent->globalPosition,
        priv->lastMotionEvent->button, priv->lastMotionEvent->buttons, priv->lastMotionEvent->modifiers);
    if (priv->pointerLockManager->lock()) {
        priv->pageProxy->didAllowPointerLock();
        return;
    }

    priv->pointerLockManager = nullptr;
    priv->pageProxy->didDenyPointerLock();
}

void webkitWebViewBaseDidLosePointerLock(WebKitWebViewBase* webViewBase)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    if (!priv->pointerLockManager)
        return;

    priv->pointerLockManager->unlock();
    priv->pointerLockManager = nullptr;
}

void webkitWebViewBaseSetInputMethodContext(WebKitWebViewBase* webViewBase, WebKitInputMethodContext* context)
{
    webViewBase->priv->inputMethodFilter.setContext(context);
}

WebKitInputMethodContext* webkitWebViewBaseGetInputMethodContext(WebKitWebViewBase* webViewBase)
{
    return webViewBase->priv->inputMethodFilter.context();
}

void webkitWebViewBaseSynthesizeCompositionKeyPress(WebKitWebViewBase* webViewBase, const String& text, std::optional<Vector<CompositionUnderline>>&& underlines, std::optional<EditingRange>&& selectionRange)
{
    webViewBase->priv->pageProxy->handleKeyboardEvent(NativeWebKeyboardEvent(text, WTFMove(underlines), WTFMove(selectionRange)));
}

static inline OptionSet<WebEvent::Modifier> toWebKitModifiers(unsigned modifiers)
{
    OptionSet<WebEvent::Modifier> webEventModifiers;
    if (modifiers & GDK_CONTROL_MASK)
        webEventModifiers.add(WebEvent::Modifier::ControlKey);
    if (modifiers & GDK_SHIFT_MASK)
        webEventModifiers.add(WebEvent::Modifier::ShiftKey);
    if (modifiers & GDK_MOD1_MASK)
        webEventModifiers.add(WebEvent::Modifier::AltKey);
    if (modifiers & GDK_META_MASK)
        webEventModifiers.add(WebEvent::Modifier::MetaKey);
    if (PlatformKeyboardEvent::modifiersContainCapsLock(modifiers))
        webEventModifiers.add(WebEvent::Modifier::CapsLockKey);
    return webEventModifiers;
}

static inline PointerID primaryPointerForType(const String& pointerType)
{
    if (pointerType == mousePointerEventType())
        return mousePointerID;

    if (pointerType == penPointerEventType())
        return 2;

    return mousePointerID;
}

void webkitWebViewBaseSynthesizeMouseEvent(WebKitWebViewBase* webViewBase, MouseEventType type, unsigned button, unsigned short buttons, int x, int y, unsigned modifiers, int clickCount, const String& pointerType)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    if (priv->dialog)
        return;

    if (priv->pointerLockManager) {
        priv->pointerLockManager->didReceiveMotionEvent(FloatPoint(x, y));
        return;
    }

    WebMouseEvent::Button webEventButton = WebMouseEvent::NoButton;
    switch (button) {
    case 0:
        webEventButton = WebMouseEvent::NoButton;
        break;
    case 1:
        webEventButton = WebMouseEvent::LeftButton;
        break;
    case 2:
        webEventButton = WebMouseEvent::MiddleButton;
        break;
    case 3:
        webEventButton = WebMouseEvent::RightButton;
        break;
    }

    unsigned short webEventButtons = 0;
    if (buttons & GDK_BUTTON1_MASK)
        webEventButtons |= 1;
    if (buttons & GDK_BUTTON2_MASK)
        webEventButtons |= 4;
    if (buttons & GDK_BUTTON3_MASK)
        webEventButtons |= 2;

    std::optional<FloatSize> movementDelta;
    WebEvent::Type webEventType;
    switch (type) {
    case MouseEventType::Press:
        webEventType = WebEvent::MouseDown;
        priv->inputMethodFilter.cancelComposition();
#if !USE(GTK4)
        if (webEventButton == WebMouseEvent::RightButton) {
            GUniquePtr<GdkEvent> event(gdk_event_new(GDK_BUTTON_PRESS));
            event->button.window = gtk_widget_get_window(GTK_WIDGET(webViewBase));
            g_object_ref(event->button.window);
            event->button.time = GDK_CURRENT_TIME;
            event->button.x = x;
            event->button.y = y;
            event->button.axes = 0;
            event->button.state = modifiers;
            event->button.button = button;
            event->button.device = gdk_seat_get_pointer(gdk_display_get_default_seat(gtk_widget_get_display(GTK_WIDGET(webViewBase))));
            int xRoot, yRoot;
            gdk_window_get_root_coords(event->button.window, x, y, &xRoot, &yRoot);
            event->button.x_root = xRoot;
            event->button.y_root = yRoot;
            priv->contextMenuEvent = WTFMove(event);
        }
#endif
        if (!gtk_widget_has_focus(GTK_WIDGET(webViewBase)) && gtk_widget_is_focus(GTK_WIDGET(webViewBase)))
            gtk_widget_grab_focus(GTK_WIDGET(webViewBase));
        break;
    case MouseEventType::Release:
        webEventType = WebEvent::MouseUp;
        if (!gtk_widget_has_focus(GTK_WIDGET(webViewBase)) && gtk_widget_is_focus(GTK_WIDGET(webViewBase)))
            gtk_widget_grab_focus(GTK_WIDGET(webViewBase));
        break;
    case MouseEventType::Motion:
        webEventType = WebEvent::MouseMove;
        if (buttons & GDK_BUTTON1_MASK)
            webEventButton = WebMouseEvent::LeftButton;
        else if (buttons & GDK_BUTTON2_MASK)
            webEventButton = WebMouseEvent::MiddleButton;
        else if (buttons & GDK_BUTTON3_MASK)
            webEventButton = WebMouseEvent::RightButton;

        if (priv->lastMotionEvent)
            movementDelta = FloatPoint(x, y) - priv->lastMotionEvent->globalPosition;
        priv->lastMotionEvent = MotionEvent(FloatPoint(x, y), widgetRootCoords(GTK_WIDGET(webViewBase), x, y), webEventButton, webEventButtons, toWebKitModifiers(modifiers));
        break;
    }

    priv->pageProxy->handleMouseEvent(NativeWebMouseEvent(webEventType, webEventButton, webEventButtons, { x, y },
        widgetRootCoords(GTK_WIDGET(webViewBase), x, y), clickCount, toWebKitModifiers(modifiers), movementDelta,
        primaryPointerForType(pointerType), pointerType.isNull() ? mousePointerEventType() : pointerType));
}

void webkitWebViewBaseSynthesizeKeyEvent(WebKitWebViewBase* webViewBase, KeyEventType type, unsigned keyval, unsigned modifiers, ShouldTranslateKeyboardState shouldTranslate)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    if (priv->dialog)
        return;

    if (type != KeyEventType::Release) {
        if (auto* popupMenu = priv->pageProxy->activePopupMenu()) {
            auto* gtkPopupMenu = static_cast<WebPopupMenuProxyGtk*>(popupMenu);
            if (gtkPopupMenu->handleKeyPress(keyval, GDK_CURRENT_TIME))
                return;

            if (keyval == GDK_KEY_Return) {
                gtkPopupMenu->activateSelectedItem();
                return;
            }
        }

#if ENABLE(FULLSCREEN_API)
        if (priv->fullScreenModeActive) {
            switch (keyval) {
            case GDK_KEY_Escape:
            case GDK_KEY_f:
            case GDK_KEY_F:
                priv->pageProxy->fullScreenManager()->requestExitFullScreen();
                return;
            default:
                break;
            }
        }
#endif

#if !USE(GTK4)
        if (priv->activeContextMenuProxy && keyval == GDK_KEY_Escape) {
            gtk_menu_shell_deactivate(GTK_MENU_SHELL(priv->activeContextMenuProxy->gtkWidget()));
            return;
        }

        if (keyval == GDK_KEY_Menu) {
            GUniquePtr<GdkEvent> event(gdk_event_new(GDK_KEY_PRESS));
            event->key.window = gtk_widget_get_window(GTK_WIDGET(webViewBase));
            g_object_ref(event->key.window);
            event->key.time = GDK_CURRENT_TIME;
            event->key.keyval = keyval;
            event->key.state = modifiers;
            gdk_event_set_device(event.get(), gdk_seat_get_keyboard(gdk_display_get_default_seat(gtk_widget_get_display(GTK_WIDGET(webViewBase)))));
            priv->contextMenuEvent = WTFMove(event);
            priv->pageProxy->handleContextMenuKeyEvent();
            return;
        }
#endif
    }

    auto keycode = widgetKeyvalToKeycode(GTK_WIDGET(webViewBase), keyval);
    if (modifiers && shouldTranslate == ShouldTranslateKeyboardState::Yes) {
        auto* display = gtk_widget_get_display(GTK_WIDGET(webViewBase));
#if USE(GTK4)
        gdk_display_translate_key(display, keycode, static_cast<GdkModifierType>(modifiers), 0, &keyval, nullptr, nullptr, nullptr);
#else
        gdk_keymap_translate_keyboard_state(gdk_keymap_get_for_display(display), keycode, static_cast<GdkModifierType>(modifiers), 0, &keyval, nullptr, nullptr, nullptr);
#endif
    }
    auto webEventModifiers = toWebKitModifiers(modifiers);

    if (type != KeyEventType::Release) {
        // Modifier masks are set different in X than other platforms. This code makes WebKitGTK
        // to behave similar to other platforms and other browsers under X (see http://crbug.com/127142#c8).
        switch (keyval) {
        case GDK_KEY_Control_L:
        case GDK_KEY_Control_R:
            webEventModifiers.add(WebEvent::Modifier::ControlKey);
            break;
        case GDK_KEY_Shift_L:
        case GDK_KEY_Shift_R:
            webEventModifiers.add(WebEvent::Modifier::ShiftKey);
            break;
        case GDK_KEY_Alt_L:
        case GDK_KEY_Alt_R:
            webEventModifiers.add(WebEvent::Modifier::AltKey);
            break;
        case GDK_KEY_Meta_L:
        case GDK_KEY_Meta_R:
            webEventModifiers.add(WebEvent::Modifier::MetaKey);
            break;
        case GDK_KEY_Caps_Lock:
            webEventModifiers.add(WebEvent::Modifier::CapsLockKey);
            break;
        }

        auto filterResult = priv->inputMethodFilter.filterKeyEvent(GDK_KEY_PRESS, keyval, keycode, modifiers);
        if (!filterResult.handled) {
            priv->pageProxy->handleKeyboardEvent(NativeWebKeyboardEvent(
                WebEvent::KeyDown,
                filterResult.keyText.isNull() ? PlatformKeyboardEvent::singleCharacterString(keyval) : filterResult.keyText,
                PlatformKeyboardEvent::keyValueForGdkKeyCode(keyval),
                PlatformKeyboardEvent::keyCodeForHardwareKeyCode(keycode),
                PlatformKeyboardEvent::keyIdentifierForGdkKeyCode(keyval),
                PlatformKeyboardEvent::windowsKeyCodeForGdkKeyCode(keyval),
                static_cast<int>(keyval),
                priv->keyBindingTranslator.commandsForKeyval(keyval, modifiers),
                keyval >= GDK_KEY_KP_Space && keyval <= GDK_KEY_KP_9,
                webEventModifiers));
        }
    }

    if (type != KeyEventType::Press) {
        if (!priv->inputMethodFilter.filterKeyEvent(GDK_KEY_RELEASE, keyval, keycode, modifiers).handled) {
            priv->pageProxy->handleKeyboardEvent(NativeWebKeyboardEvent(
                WebEvent::KeyUp,
                PlatformKeyboardEvent::singleCharacterString(keyval),
                PlatformKeyboardEvent::keyValueForGdkKeyCode(keyval),
                PlatformKeyboardEvent::keyCodeForHardwareKeyCode(keycode),
                PlatformKeyboardEvent::keyIdentifierForGdkKeyCode(keyval),
                PlatformKeyboardEvent::windowsKeyCodeForGdkKeyCode(keyval),
                static_cast<int>(keyval),
                { },
                keyval >= GDK_KEY_KP_Space && keyval <= GDK_KEY_KP_9,
                webEventModifiers));
        }
    }
}

static inline WebWheelEvent::Phase toWebKitWheelEventPhase(WheelEventPhase phase)
{
    switch (phase) {
    case WheelEventPhase::NoPhase:
        return WebWheelEvent::Phase::PhaseNone;
    case WheelEventPhase::Began:
        return WebWheelEvent::Phase::PhaseBegan;
    case WheelEventPhase::Changed:
        return WebWheelEvent::Phase::PhaseChanged;
    case WheelEventPhase::Ended:
        return WebWheelEvent::Phase::PhaseEnded;
    case WheelEventPhase::Cancelled:
        return WebWheelEvent::Phase::PhaseCancelled;
    case WheelEventPhase::MayBegin:
        return WebWheelEvent::Phase::PhaseMayBegin;
    }

    RELEASE_ASSERT_NOT_REACHED();
}

void webkitWebViewBaseSynthesizeWheelEvent(WebKitWebViewBase* webViewBase, double deltaX, double deltaY, int x, int y, WheelEventPhase phase, WheelEventPhase momentumPhase, bool hasPreciseDeltas)
{
    webkitWebViewBaseSynthesizeWheelEvent(webViewBase, nullptr, deltaX, deltaY, x, y, phase, momentumPhase, hasPreciseDeltas);
}

void webkitWebViewBaseSynthesizeWheelEvent(WebKitWebViewBase* webViewBase, const GdkEvent* event, double deltaX, double deltaY, int x, int y, WheelEventPhase phase, WheelEventPhase momentumPhase, bool hasPreciseDeltas)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    if (priv->dialog)
        return;

    FloatSize wheelTicks(deltaX, deltaY);
    FloatSize delta(wheelTicks);
    if (!hasPreciseDeltas)
        delta.scale(static_cast<float>(Scrollbar::pixelsPerLineStep()));

    priv->pageProxy->handleWheelEvent(NativeWebWheelEvent(const_cast<GdkEvent*>(event), { x, y }, widgetRootCoords(GTK_WIDGET(webViewBase), x, y),
        delta, wheelTicks, toWebKitWheelEventPhase(phase), toWebKitWheelEventPhase(momentumPhase), true));
}

void webkitWebViewBaseMakeBlank(WebKitWebViewBase* webViewBase, bool makeBlank)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    if (priv->isBlank == makeBlank)
        return;

    priv->isBlank = makeBlank;
    gtk_widget_queue_draw(GTK_WIDGET(webViewBase));
}

void webkitWebViewBasePageGrabbedTouch(WebKitWebViewBase* webViewBase)
{
    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    priv->pageGrabbedTouch = true;
    gtk_gesture_set_state(priv->touchGestureGroup, GTK_EVENT_SEQUENCE_DENIED);
}

void webkitWebViewBaseSetShouldNotifyFocusEvents(WebKitWebViewBase* webViewBase, bool shouldNotifyFocusEvents)
{
    webViewBase->priv->shouldNotifyFocusEvents = shouldNotifyFocusEvents;
}
