#include <gtk/gtk.h>

static gboolean
close_popup (GtkWidget *widget,
             GdkEvent  *event,
             gpointer   data)
{
  gtk_grab_remove (widget);
  gdk_seat_ungrab (gdk_event_get_seat (event));
  gtk_widget_destroy (widget);

  return TRUE;
}


static void
prepare_popup(GdkSeat *seat, GdkWindow *window, gpointer user_data)
{
  GtkWidget *popup = (GtkWidget *) user_data;

  gtk_widget_show_all (popup);
}

static gboolean
open_popup (GtkWidget *parent,
            GdkEvent  *event,
            gpointer   data)
{
  GdkEventButton *ev_button = (GdkEventButton *) event;
  GdkSeat *seat;
  GtkWidget *popup;
  GtkWidget *vbox;
  GtkWidget *entry;
  GtkEntryBuffer *buffer;
  GdkGrabStatus status;

  popup = gtk_window_new (GTK_WINDOW_POPUP);

  gtk_widget_set_size_request (GTK_WIDGET (popup), 200, 20);
  gtk_window_set_transient_for (GTK_WINDOW (popup), GTK_WINDOW (parent));

  vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
  gtk_container_add (GTK_CONTAINER (popup), vbox);
  gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);

  buffer = gtk_entry_buffer_new (NULL, 0);
  entry = gtk_entry_new_with_buffer (buffer);
  gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
  g_object_unref (buffer);

  g_signal_connect (popup, "button-press-event", G_CALLBACK (close_popup), NULL);

  gtk_window_move (GTK_WINDOW (popup),
                   (int) ev_button->x_root - 10,
                   (int) ev_button->y_root - 10);

  gtk_widget_realize (popup);

  gtk_grab_add (popup);
  seat = gdk_event_get_seat (event);
  status = gdk_seat_grab (seat, gtk_widget_get_window (popup),
                          GDK_SEAT_CAPABILITY_ALL_POINTING, TRUE,
                          NULL, event, prepare_popup, popup);

  return (status == GDK_GRAB_SUCCESS);
}

static void
activate (GtkApplication *app,
          gpointer        user_data)
{
  GtkWidget *window;

  window = gtk_application_window_new (app);
  gtk_window_set_title (GTK_WINDOW (window), "Window");
  gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);

  g_signal_connect (window, "button-press-event", G_CALLBACK (open_popup), NULL);

  gtk_widget_show_all (window);
}

int
main (int    argc,
      char **argv)
{
  GtkApplication *app;
  int status;

  app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
  g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
  status = g_application_run (G_APPLICATION (app), argc, argv);
  g_object_unref (app);

  return status;
}
