diff --git a/libweston-desktop/internal.h b/libweston-desktop/internal.h index a9c974b0..763355bf 100644 --- a/libweston-desktop/internal.h +++ b/libweston-desktop/internal.h @@ -81,6 +81,11 @@ void weston_desktop_api_minimized_requested(struct weston_desktop *desktop, struct weston_desktop_surface *surface); +void +weston_desktop_api_set_xwayland_position(struct weston_desktop *desktop, + struct weston_desktop_surface *surface, + int32_t x, int32_t y); + struct weston_desktop_seat * weston_desktop_seat_from_seat(struct weston_seat *wseat); diff --git a/libweston-desktop/libweston-desktop.c b/libweston-desktop/libweston-desktop.c index 0ee11393..48e90009 100644 --- a/libweston-desktop/libweston-desktop.c +++ b/libweston-desktop/libweston-desktop.c @@ -242,3 +242,13 @@ weston_desktop_api_minimized_requested(struct weston_desktop *desktop, if (desktop->api.minimized_requested != NULL) desktop->api.minimized_requested(surface, desktop->user_data); } + +void +weston_desktop_api_set_xwayland_position(struct weston_desktop *desktop, + struct weston_desktop_surface *surface, + int32_t x, int32_t y) +{ + if (desktop->api.set_xwayland_position != NULL) + desktop->api.set_xwayland_position(surface, x, y, + desktop->user_data); +} diff --git a/libweston-desktop/libweston-desktop.h b/libweston-desktop/libweston-desktop.h index f77ab55b..03b04c7b 100644 --- a/libweston-desktop/libweston-desktop.h +++ b/libweston-desktop/libweston-desktop.h @@ -80,6 +80,39 @@ struct weston_desktop_api { bool maximized, void *user_data); void (*minimized_requested)(struct weston_desktop_surface *surface, void *user_data); + + /** Position suggestion for an Xwayland window + * + * X11 applications assume they can position their windows as necessary, + * which is not possible in Wayland where positioning is driven by the + * shell alone. This function is used to relay absolute position wishes + * from Xwayland clients to the shell. + * + * This is particularly used for mapping windows at specified locations, + * e.g. via the commonly used '-geometry' command line option. In such + * case, a call to surface_added() is immediately followed by + * xwayland_position() if the X11 application specified a position. + * The committed() call that will map the window occurs later, so it + * is recommended to usually store and honour the given position for + * windows that are not yet mapped. + * + * Calls to this function may happen also at other times. + * + * The given coordinates are in the X11 window system coordinate frame + * relative to the X11 root window. Care should be taken to ensure the + * window gets mapped to coordinates that correspond to the proposed + * position from the X11 client perspective. + * + * \param surface The surface in question. + * \param x The absolute X11 coordinate for x. + * \param y The absolute X11 coordinate for y. + * \param user_data The user_data argument passed in to + * weston_desktop_create(). + * + * This callback can be NULL. + */ + void (*set_xwayland_position)(struct weston_desktop_surface *surface, + int32_t x, int32_t y, void *user_data); }; void diff --git a/libweston-desktop/xwayland.c b/libweston-desktop/xwayland.c index 1b19e224..b9843853 100644 --- a/libweston-desktop/xwayland.c +++ b/libweston-desktop/xwayland.c @@ -257,6 +257,16 @@ set_toplevel(struct weston_desktop_xwayland_surface *surface) 0, 0); } +static void +set_toplevel_with_position(struct weston_desktop_xwayland_surface *surface, + int32_t x, int32_t y) +{ + weston_desktop_xwayland_surface_change_state(surface, TOPLEVEL, NULL, + 0, 0); + weston_desktop_api_set_xwayland_position(surface->desktop, + surface->surface, x, y); +} + static void set_parent(struct weston_desktop_xwayland_surface *surface, struct weston_surface *wparent) @@ -361,6 +371,7 @@ set_pid(struct weston_desktop_xwayland_surface *surface, pid_t pid) static const struct weston_desktop_xwayland_interface weston_desktop_xwayland_interface = { .create_surface = create_surface, .set_toplevel = set_toplevel, + .set_toplevel_with_position = set_toplevel_with_position, .set_parent = set_parent, .set_transient = set_transient, .set_fullscreen = set_fullscreen,