/*
 * Build with:
 *
 *  gcc -std=gnu99 -o test test.c `pkg-config webkit2gtk-4.0 --cflags --libs`   
 *
 */

#include <glib-object.h>
#include <webkit2/webkit2.h>
#include <gtk/gtk.h>

#define EPHY_TYPE_WINDOW (ephy_window_get_type ())

G_DECLARE_FINAL_TYPE (EphyWindow, ephy_window, EPHY, WINDOW, GtkApplicationWindow)

struct _EphyWindow {
    GtkApplicationWindow parent_instance;
};

G_DEFINE_TYPE (EphyWindow, ephy_window, GTK_TYPE_APPLICATION_WINDOW)


static gboolean
ephy_window_key_press_event (GtkWidget   *widget,
                             GdkEventKey *event)
{
  GtkWindow *window = GTK_WINDOW (widget);
  GtkWidget *focus_widget;
  gboolean shortcircuit = FALSE, force_chain = FALSE, handled = FALSE;
  guint modifier = event->state & gtk_accelerator_get_default_mod_mask ();

  /* In an attempt to get the mozembed playing nice with things like emacs keybindings
   * we are passing important events to the focused child widget before letting the window's
   * base handler see them. This is *completely against* stated gtk2 policy but the
   * 'correct' behaviour is exceptionally useless. We need to keep an eye out for
   * unexpected consequences of this decision. IME's should be a high concern, but
   * considering that the IME folks complained about the upside-down event propagation
   * rules, we might be doing them a favour.
   *
   * We achieve this by first evaluating the event to see if it's important, and if
   * so, we get the focus widget and attempt to get the widget to handle that event.
   * If the widget does handle it, we're done (unless force_chain is true, in which
   * case the event is handled as normal in addition to being sent to the focus
   * widget), otherwise the event follows the normal handling path.
   */

  if ((event->state & GDK_CONTROL_MASK ||
       event->state & GDK_MOD1_MASK ||
       event->state & GDK_SHIFT_MASK) &&
      event->length > 0) {
    /* Pass (CTRL|ALT|SHIFT)+letter characters to the widget */
    shortcircuit = TRUE;
  } else if (event->keyval == GDK_KEY_Escape && modifier == 0) {
    /* Always pass Escape to both the widget, and the parent */
    shortcircuit = TRUE;
    force_chain = TRUE;
#if 0
  } else if (window->key_theme_is_emacs &&
             (modifier == GDK_CONTROL_MASK) &&
             event->length > 0 &&
             /* But don't pass Ctrl+Enter twice */
             event->keyval != GDK_KEY_Return &&
             event->keyval != GDK_KEY_KP_Enter &&
             event->keyval != GDK_KEY_ISO_Enter) {
    /* Pass CTRL+letter characters to the widget */
    shortcircuit = TRUE;
#endif
  }

  if (shortcircuit) {
    focus_widget = gtk_window_get_focus (GTK_WINDOW (window));

    if (GTK_IS_WIDGET (focus_widget)) {
      handled = gtk_widget_event (focus_widget,
                                  (GdkEvent *)event);
    }

    if (handled && !force_chain) {
      return handled;
    }
  }

  return GTK_WIDGET_CLASS (ephy_window_parent_class)->key_press_event (widget, event);
}


static void
ephy_window_init (EphyWindow *window)
{
}


static void
ephy_window_class_init (EphyWindowClass *klass)
{
    GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
    widget_class->key_press_event = ephy_window_key_press_event;
}


int
main (int argc, char **argv)
{
    gtk_init (&argc, &argv);

    GtkWidget *window = g_object_new (EPHY_TYPE_WINDOW, NULL);
    GtkWidget *webview = webkit_web_view_new ();

    gtk_container_add (GTK_CONTAINER (window), webview);
    gtk_widget_show_all (window);
    webkit_web_view_load_uri (WEBKIT_WEB_VIEW (webview), argv[1]);

    gtk_main ();
    return 0;
}


