Gtk4 migration - window management functions gone

As the migration guide states, window management functions are gone from Gdk and Gtk:

https://gnome.pages.gitlab.gnome.org/gtk/gtk4/migrating-3to4.html#adapt-to-gdkwindow-api-changes

The guide says to use Xlib functions. If I want to work with both Xorg and XWayland I guess I would need to check and call one or another, correct?

How would I implement a gdk_surface_move() for ex?

No: XWayland does not exist from a client perspective. A client will only ever use the X11 backend regardless of whether a real X11 server owns the display, or if an X11 server spawned by the Wayland compositor is on the other side of the connection.

If you’re using the X11 backend, then you can always use XMoveWindow() yourself—of course, you’ll need to figure out the location of the window. In practice, though, any X11 client doing that on its own is generally frowned upon: the window manager decides whether to put a window, not yourself. If you’re creating an Override-Redirect window, you’ll still need a parent window to provide a reference point for the coordinate system.

If you’re using the Wayland backend directly, then you cannot move windows anyway.

You cannot move top level windows in Wayland, because you don’t have access to the screen coordinate system; that coordinate space is the exclusive realm of the Wayland compositor, and clients have no access to it—unless the compositor exposes some sort of ad hoc interface. Each top level window exists in its own coordinate space, with the origin at the top left corner of the rectangle defined by the size of the window, and the anti-origin at the bottom right.

Only “child” windows—popups, like menus and tooltips—can be positioned relative to their parent window; for that, you already have access to the generic gdk_popup_present() API.

So, to my understanding, it’s correct to use the X11 api even if running on Wayland?

My initial thought was that X11 compatibility was a “temporary migration mechanism”.

Thanks

If, and only if, you’re using the X11 backend of GDK. If you’re using the native Wayland backend, then the windowing system surface represented by a GdkSurface will not be an X11 Window, but a Wayland object, which means you cannot use Xlib API with it.

The “X11 compatibility” only exists at the Wayland compositor level: clients either connect to the Wayland compositor using the Wayland API; or they connect to the XWayland server that is spawned by the Wayland compositor, and use the X11 API.

By default, GTK applications will try to connect to the Wayland compositor, and only fall back to checking an X11 display server if that fails. You can force them to use X11 by exporting the GDK_BACKEND=x11 variable in your environment.

As I said in my first reply, though, you should not be moving windows programmatically—unless they are “child” of top level windows, in which case you can use the GdkPopup API.

The bad thing is that I really need to control position and stacking of the Windows, so after your explanation I can’t use Wayland, unless using the X11 API and the compatibility layer.

I’m experimenting/developing a new native backend for JavaFx (https://openjfx.io/). The idea was to use Gtk4 (mainly Gdk), as it would already do the work abstracting X11, Wayland (as initially thought). But JavaFx would need to move, resize a stack windows to provide the same behavior between platforms.

Not criticizing Wayland, but not having those windowing functionality, it’s a no-go for JavaFx.

Thanks.

The focus of GTK has moved away from being a “meta toolkit” that other toolkits can use as a “backend”. We don’t have enough resources to deal with that, and such a design is inherently brittle and exposes far too many internals to ever be useful, safe, or maintainable in the long run.

The fact that you want to control position and stacking of top levels means that you’re doing the work of a window manager, which is really not where graphic stacks are going; it’s something of a legacy design. Don’t expect things to get any easier in that department.

I wish you luck in your endeavours, in any case.

1 Like

Why does JavaFX need to move/resize/stack windows? Do applications actually use this functionality or is it just a mirror of some older Win32/X11 platform APIs as it was previously with GDK? If the intent is to get JavaFX working with Wayland, it would be appropriate to stub out those functions and mark them as legacy APIs.

I think resize is a common case, because the contents of the window could change from the initial size. Thinking in a broader range of app types it supports.

Move maybe not so common, it currently uses for “consistent positioning between platforms”. There are probably more use cases.

Stacking maybe it should not do. There are some common code between the supported platforms, and it seeks to behave exactly the same between those.

There is a use case that needs all those plus “Event mock”: Automated testing. In JavaFx there’s an API for that called “Robot”. It needs to know where the window is, so it can move the mouse and click a button, etc.

One follow up question if you are willing to answer: I’ve been studying gtk4 and it seems to “prefer” decorations on the client size. Windows are now sized with decorations in total (it was not on gtk3).

So the window manager does not draw those. How GtkHeaderBar tells Wayland to move the window when dragged?

How GtkHeaderBar tells Wayland to move the window when dragged?

It uses the xdg-shell protocol to tell the wayland compositor to start a move operation. But where the window is moved (and indeed: whether it is moved at all) is entirely up to the compositor.

Resizing is still available. The only “window management” operations that are not available any more are:

  • positioning top levels in the global coordinate space
  • controlling the stacking order of top levels

UI automation and testing is a thing that should have its own API. I’m looking into adding this kind of functionality in the future, as multiple UI testing frameworks tend to use the accessibility API instead, making a mess out of it.

Injecting events into the toolkit is not supported, and won’t be, because you have no idea how the toolkit will handle the event state. Warping the pointer position is also an awful API, so we dropped that from the shared API.

On X11, applications moving their own windows is generally a bad idea, as the window manager can ignore any move requests for normal (non-override-redirect) windows. There is no guarantee that the positioning will be consistent. For automated testing, you would just use the XTest extension, there would be no need to move the windows. Of course that doesn’t apply to Wayland though.