IME client widget when using GTK4 and/or Wayland

I’m working on Chromium’s IME support, and currently the only fully supported platform is GTK3 / GDK3 on X11. An important part plays the gdk_x11_window_lookup_for_display() function. Its return value is used as the argument to gtk_im_context_set_client_window().

However, as this is not available when using GTK4 / GDK4 and/or Wayland, the client window (or client widget in GTK4) cannot be correctly set on these platforms. Is there an alternative to this function? Or maybe another workaround for the client widget?

Currently, if gdk_x11_window_lookup_for_display() is not available, a dummy window that is never shown is used as the client widget. On X11, this makes IME popups have an incorrect position, and on Wayland, some popups don’t show up at all.

Hi Max,

The first thing to note here, a big difference of GTK4 is that GdkWindow (now GdkSurface) has a much more constrained role, being reserved now for windows, popups, and other toplevel surfaces.

Most notably, GtkWidgets no longer use nor require child GdkWindows to paint themselves, handle input, nor function normally. You can see some details about that in the migration docs.

The moral equivalent of that function is gtk_im_context_set_client_widget(), from there things should be worked out in widget-local coordinates (e.g. text extents and positions).

Hi Carlos,

Thank you for your quick response!

I’m aware of gtk_im_context_set_client_widget() and Chromium already uses that with GDK4. The problem is that currently we don’t set a real widget, but instead the already mentioned dummy window. I could have been more clear about that, my bad.

So the question is: what can we use as the argument to gtk_im_context_set_client_widget()? A function similar to gdk_x11_window_lookup_for_display()would be super useful – for example, is it possible to obtain a GdkSurface from Wayland’s wl_surface and create a widget containing that surface? Then maybe that could be used with gtk_im_context_set_client_widget().

Hmm, I am afraid I don’t see what role does this GdkWindow have, nor why does the code require it to be looked up from a X11 Window. In GTK4 IM context are inextricably attached to a GtkWidget, it is used to determine the focus position within the toplevel, whether it has focus or not, and many other details. That can no longer be exposed to other random processes as a handle.

Is it the case that IM interaction is done from the web process? If this is what is happening, GTK4 and Wayland will require that it is the browser process (i.e. the one creating the toplevel surface that everything gets drawn to) that does the communication with the compositor, it cannot be delegated to a third process. That requires communication between web and browser processes, so the latter can do the interfacing between the compositor and the web process through a WebView GTK4 widget.

So the question is: what can we use as the argument to gtk_im_context_set_client_widget() ? A function similar to gdk_x11_window_lookup_for_display() would be super useful – for example, is it possible to obtain a GdkSurface from Wayland’s wl_surface and create a widget containing that surface? Then maybe that could be used with gtk_im_context_set_client_widget() .

I have the feeling you’re not just fighting against changed GTK semantics, but also against Wayland ones :). This cannot be done, for 2 reasons:

  • wl_surface is just something shared between one client and the compositor, there is no global registry of surfaces, nor clients can peek/borrow surfaces made by others.
  • GtkWidget is 100% a client side abstract construct. It’s again not something you can export and let other processes operate with it as an entity onscreen.

X11 is an IPC that relies on Windows being a global shared resource, Wayland no longer works that way.

I know there is a lot of custom stuff going on but doesn’t Chromium have a GtkWindow-per-window? I’d have thought you can use that

IM interaction is done from the browser process, so there should be no IPC required :slight_smile:

And you’re right, Wayland imposes additional limitations. I forgot how Wayland works for a moment :sweat_smile:

As far as I can tell from patching GTK and printing whenever gtk_window_init() is called (for reasons :tm: this is probably the simplest way to do this), this is sadly not the case. I only see one call to this method at Chromium’s start up, regardless of how many new windows I open afterwards.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.