/* * gcc -o kill-weston -g -O0 kill-weston.c `pkg-config --libs --cflags gtk+-3.0` */ #include static void destroy (GtkWidget *widget, gpointer data) { gtk_main_quit (); } static gboolean popup_grab_on_window (GdkWindow *window, GdkDevice *keyboard, GdkDevice *pointer, guint32 activate_time) { if (keyboard && gdk_device_grab (keyboard, window, GDK_OWNERSHIP_WINDOW, TRUE, GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK, NULL, activate_time) != GDK_GRAB_SUCCESS) { return FALSE; } if (pointer && gdk_device_grab (pointer, window, GDK_OWNERSHIP_WINDOW, TRUE, GDK_SMOOTH_SCROLL_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_POINTER_MOTION_MASK, NULL, activate_time) != GDK_GRAB_SUCCESS) { if (keyboard) gdk_device_ungrab (keyboard, activate_time); return FALSE; } return TRUE; } static GdkDevice * grab_device (GtkWidget *widget) { GdkDevice *keyboard, *pointer, *device; GdkDisplay *display; display = gtk_widget_get_display (widget); device = gtk_get_current_event_device (); if (device && gdk_device_get_display (device) != display) device = NULL; if (device == NULL) { GdkDeviceManager *device_manager; GList *devices; device_manager = gdk_display_get_device_manager (display); devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER); device = devices->data; g_list_free (devices); } if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD) { keyboard = device; pointer = gdk_device_get_associated_device (device); } else { pointer = device; keyboard = gdk_device_get_associated_device (device); } if (popup_grab_on_window (gtk_widget_get_window (widget), keyboard, pointer, gtk_get_current_event_time ())) return pointer; else g_warning ("Failed to grab device!"); return NULL; } static void ungrab_device (GdkDevice *pointer) { GdkDevice *keyboard; gdk_device_ungrab (pointer, GDK_CURRENT_TIME); keyboard = gdk_device_get_associated_device (pointer); if (keyboard) gdk_device_ungrab (keyboard, GDK_CURRENT_TIME); } static void show_popup (GtkWidget *parent) { GtkWidget *popup; GdkDevice *pointer; gtk_widget_realize (parent); popup = gtk_window_new (GTK_WINDOW_POPUP); gtk_window_group_add_window (gtk_window_get_group (GTK_WINDOW (parent)), GTK_WINDOW (popup)); gtk_window_set_transient_for (GTK_WINDOW (popup), GTK_WINDOW (parent)); gtk_widget_realize (popup); gtk_window_set_type_hint (GTK_WINDOW (popup), GDK_WINDOW_TYPE_HINT_POPUP_MENU); pointer = grab_device (GTK_WIDGET (popup)); if (pointer) gtk_device_grab_add (GTK_WIDGET (popup), pointer, TRUE); gtk_window_move (GTK_WINDOW (popup), 200, 200); gtk_window_resize (GTK_WINDOW (popup), 25, 25); gtk_widget_show (GTK_WIDGET (popup)); if (pointer) { ungrab_device (pointer); gtk_device_grab_remove (GTK_WIDGET (popup), pointer); } } int main (int argc, char *argv[]) { GtkWidget *window; gtk_init (&argc, &argv); /* create a new window */ window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_resize (GTK_WINDOW (window), 200, 200); g_signal_connect (window, "destroy", G_CALLBACK (destroy), NULL); show_popup (window); gtk_widget_show_all (GTK_WIDGET (window)); gtk_main (); return 0; }