Hi Jonas,

> > [...]
> > For that last point, I'd rather use:
> > 
> >     * does not guarantee that events sent to this client are continuous,
> >       a compositor may change and reroute keyboard events while the grab
> >       is nominally active.
> > 
> > > hmm, and thinking about the last point: do we need to specify what the
> > > focus
> > > behaviour is if a grab is active? I'm assuming 'no' because there is no
> > > notification whatsoever whether it ever activates anyway, but...
> > 
> > No, indeed, that's precisely the main difference with the shortcuts
> > inhibitor logic for the wayland native apps.
> > 
> > Here, keyboards events are routed to the surface regardless of the focus,
> > just like an X11 grab.
> 
> Should this part really be respected though? In what circumstances does
> it make sense to route input events to Xwayland when a Wayland client is
> the one focused?

Yes, that's precisely the whole point of this protocol (and grabs in general) :)

Take the attached sample code for example, it maps a single override redirect 
window (one that no X11 window manager would focus, because it's an O-R) and 
issues an active keyboard grab to get all keyboard events.


While that works fine in X11 native, that won't work in Wayland/Xwayland 
without this protocol and the ability to route keyboard events even when the 
surface is not focused.

> > > Last question: how will you deal with XGrabKeyboard() requests on already
> > > grabbed keyboards? I can send that request twice with different grab
> > > windows
> > > and it'll change the grab over (iirc). Xwayland will destroy the current
> > > grab and request a new one?
> > 
> > Yeap, good point, "XGrabKeyboard overrides any active keyboard grab by the
> > client" so Xwayland needs to destroy any current grab before setting a new
> > one in this case.
> >  
> 
> FWIW, this will create a minor race, where any key presses between the
> .destroy and .grab requests will be ungrabbed.

Yeah, you're right, but I reckon it's acceptable.

Cheers,
Olivier

/*
 * Compile with :
 *
 * gcc -Wall -g grab.c -o grab `pkg-config --cflags gtk+-2.0` `pkg-config --libs gtk+-2.0`
 * 
 */
#include <gtk/gtk.h>


static gboolean
on_map_event_cb (GtkWidget *widget,
                 GdkEvent  *event,
                 gpointer   user_data)
{
    GdkWindow *gdk_window = gtk_widget_get_window (widget);

    gdk_keyboard_grab (gdk_window, TRUE, GDK_CURRENT_TIME);
    g_message ("Widget %p is mapped!", widget);

    return FALSE;
}

static void
destroy (GtkWidget *widget, gpointer data)
{
    gtk_main_quit ();
}

static gboolean
on_key_press_event (GtkWidget *widget, GdkEventKey *event, gpointer data)
{
    g_message ("Key 0x%x pressed, widget %p", event->keyval, widget);

    return FALSE;
}

static gboolean
on_key_release_event (GtkWidget *widget, GdkEventKey *event, gpointer data)
{
    g_message ("Key 0x%x released, widget %p", event->keyval, widget);

    return FALSE;
}

int
main (int argc, char *argv[])
{
    GtkWidget *window1;
    GtkWidget *button;
    GtkWidget *vbox;
    GtkWidget *label;
    GtkWidget *entry;
    gchar* str;

    gtk_init (&argc, &argv);

    /* Popup window (override redirect on X11) */
    window1 = gtk_window_new (GTK_WINDOW_POPUP);
    gtk_window_set_keep_above (GTK_WINDOW (window1), TRUE);
    gtk_window_set_position (GTK_WINDOW (window1), GTK_WIN_POS_CENTER_ALWAYS);
    gtk_container_set_border_width (GTK_CONTAINER (window1), 25);
    g_signal_connect (G_OBJECT (window1), "destroy", G_CALLBACK (destroy), NULL);
    g_signal_connect_after (G_OBJECT (window1), "map-event", G_CALLBACK (on_map_event_cb), NULL);

    vbox = gtk_vbox_new (FALSE, 10);
    gtk_container_add (GTK_CONTAINER (window1), vbox);

    label = gtk_label_new (NULL);
    gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
    str = g_markup_printf_escaped ("<big>This is widget <b><tt>%p</tt></b></big>", window1);
    gtk_label_set_markup (GTK_LABEL (label), str);
    g_free (str);
    gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);

    entry = gtk_entry_new ();
    gtk_entry_set_text (GTK_ENTRY (entry), "Enter some text here...");
    gtk_box_pack_start (GTK_BOX (vbox), entry, TRUE, TRUE, 0);

    button = gtk_toggle_button_new_with_label ("Done");
    gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
    g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (gtk_main_quit), NULL);

    g_signal_connect (G_OBJECT (window1), "key-press-event", G_CALLBACK(on_key_press_event), NULL);
    g_signal_connect (G_OBJECT (window1), "key-release-event", G_CALLBACK(on_key_release_event), NULL);

    gtk_widget_show_all (window1);

    gtk_main ();

    return 0;
}
_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to