Unable to get device state during a DnD operation on Wayland
The following code demonstrates that the state reported is always 0, even when pressing down a modifier (it works on Xorg and Xwayland):
#include <stdlib.h>
#include <gtk/gtk.h>
static void
log_device_state_for_drop (GdkDrop *drop)
{
GdkDevice *device;
GdkSurface *surface;
GdkModifierType state;
device = gdk_drop_get_device (drop);
surface = gdk_drop_get_surface (drop);
gdk_device_get_state (device, surface, NULL, &state);
state &= gtk_accelerator_get_default_mod_mask ();
g_message ("%s(): device state: %u", __func__, state);
}
static void
on_drag_motion (GtkWidget *widget,
GdkDrop *drop,
int x,
int y,
gpointer user_data)
{
g_message ("%s()", __func__);
log_device_state_for_drop (drop);
}
static void
on_drag_data_received (GtkWidget *widget,
GdkDrop *drop,
GtkSelectionData *data,
gpointer user_data)
{
g_message ("%s()", __func__);
log_device_state_for_drop (drop);
}
int
main (int argc,
char **argv)
{
GtkWidget *window;
GtkWidget *grid;
g_autoptr (GdkContentFormats) formats;
GtkWidget *source;
GtkWidget *separator;
GtkWidget *destination;
gtk_init ();
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
grid = gtk_grid_new ();
formats = gdk_content_formats_new (NULL, 0);
formats = gtk_content_formats_add_text_targets (formats);
source = gtk_label_new ("Source");
separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
destination = gtk_label_new ("Destination");
g_signal_connect (window, "close-request", G_CALLBACK (gtk_main_quit), NULL);
gtk_container_add (GTK_CONTAINER (window), grid);
gtk_widget_show (window);
gtk_orientable_set_orientation (GTK_ORIENTABLE (grid), GTK_ORIENTATION_VERTICAL);
gtk_container_add (GTK_CONTAINER (grid), source);
gtk_container_add (GTK_CONTAINER (grid), separator);
gtk_container_add (GTK_CONTAINER (grid), destination);
g_object_set (source, "expand", TRUE, NULL);
gtk_drag_source_set (source, GDK_BUTTON1_MASK, formats, GDK_ACTION_ALL);
g_object_set (destination, "expand", TRUE, NULL);
g_signal_connect (destination, "drag-motion", G_CALLBACK (on_drag_motion), NULL);
g_signal_connect (destination, "drag-data-received", G_CALLBACK (on_drag_data_received), NULL);
gtk_drag_dest_set (destination, GTK_DEST_DEFAULT_ALL, formats, GDK_ACTION_ALL);
gtk_main ();
return EXIT_SUCCESS;
}