Hi
> I cannot see why this api cannot be correctly emulated using some
> wayland api that normal wayland clients can also use. Allowing X
> clients to have more rights and abilities than Wayland clients seems
> horrendously wrong.
>
> The X emulation does not have to do 1:1 translation of X11 calls into
> Wayland requests.
>
> In this case I would think an attempt to grab the keyboard would
> instead send an "activate" or "raise" or "needs attention" (that seems
> to be a popular name) request. The X client would then get keystrokes
> (possibly after some more user interaction such as clicking or of
> de-iconizing the client). Because the X11 app may not expect to lose
> the focus until the grab is lost, the X emulator would also re-request
> the focus if it is lost at any time it could, such as on mouse clicks
> or mouse enter events.
>
> I suppose the plan is that this does not actually do something that
> Wayland clients can't do, but in that case you are just moving "how to
> replicate what X does" from the X emulator into the compositor. That
> still seems wrong, since compositors may differ, making it impossible
> for the client to be rewritten to not use the X emulator but still
> have the same behavior. I would much rather see this done by the X
> emulator.
Again, even though the protocol does not specifically target override-redirect
windows, those are the main problem here, sensible X11 window managers do not
"manage" those, so setting EWMH properties such as "activate" or "demand
attention" will be ignored by most X11 window managers on O-R windows.
I have attached a simple code sample to demonstrate this - And this is not an
hypothetical issue, this is https://bugs.freedesktop.org/show_bug.cgi?id=96547
- This works fine on X11 thanks to the Xserver issuing the requested grab, it
cannot work on Xwayland because Wayland has no similar mechanism.
But if you can solve this issue reliably for all X11 window managers/Wayland
compositors in Xwayland alone without the help of any additional protocol, best
would be to send your patches for Xwayland to xorg-devel.
Cheers,
Olivier
/*
* Copyright (C) 2017 Red Hat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Written by:
* Olivier Fourdan <[email protected]>
*
* Compile with :
*
* for gtk2:
* gcc -Wall -g grab.c -o grab `pkg-config --cflags gtk+-2.0` `pkg-config --libs gtk+-2.0`
*
* for gtk3:
* gcc -Wall -g grab.c -o grab `pkg-config --cflags gtk+-3.0` `pkg-config --libs gtk+-3.0`
*
* To exercise Xwayland grabs, make sure to either build with gtk2 (which doesn't have a
* Wayland backend) or force the X11 backend if built with gtk3 (GDK_BACKEND=x11 ...)
*/
#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 (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