Commit 2732dbf7 authored by Brian Tarricone's avatar Brian Tarricone
Browse files

Retrieve wl_seat instance from compositor

It turns out that activating a toplevel with a NULL wl_seat parameter
causes a protocol error, which crashes the calling app.  So make sure
we've fetched a wl_seat from the server before trying to activate a
window.
parent cd9a664b
......@@ -21,7 +21,7 @@
#include <gdk/gdkwayland.h>
#include <string.h>
#include <wayland-client-protocol.h>
#include <wayland-client.h>
#include "protocols/wlr-foreign-toplevel-management-unstable-v1-client.h"
......@@ -37,6 +37,7 @@ struct _XfwScreenWaylandPrivate {
GdkScreen *gdk_screen;
struct wl_registry *wl_registry;
struct zwlr_foreign_toplevel_manager_v1 *toplevel_manager;
struct wl_seat *wl_seat;
XfwWorkspaceManager *workspace_manager;
GList *windows;
GList *windows_stacked;
......@@ -92,7 +93,8 @@ xfw_screen_wayland_init(XfwScreenWayland *screen) {
screen->priv = xfw_screen_wayland_get_instance_private(screen);
}
static void xfw_screen_wayland_constructed(GObject *obj) {
static void
xfw_screen_wayland_constructed(GObject *obj) {
XfwScreenWayland *screen = XFW_SCREEN_WAYLAND(obj);
GdkDisplay *gdk_display;
struct wl_display *wl_display;
......@@ -165,6 +167,9 @@ xfw_screen_wayland_finalize(GObject *obj) {
if (screen->priv->toplevel_manager != NULL) {
zwlr_foreign_toplevel_manager_v1_destroy(screen->priv->toplevel_manager);
}
if (screen->priv->wl_seat != NULL) {
wl_seat_release(screen->priv->wl_seat);
}
if (screen->priv->wl_registry != NULL) {
wl_registry_destroy(screen->priv->wl_registry);
}
......@@ -216,6 +221,15 @@ registry_global(void *data, struct wl_registry *registry, uint32_t id, const cha
id,
&zwlr_foreign_toplevel_manager_v1_interface,
MIN((uint32_t)zwlr_foreign_toplevel_manager_v1_interface.version, version));
} else if (strcmp(wl_seat_interface.name, interface) == 0) {
if (screen->priv->wl_seat != NULL) {
g_debug("We already had a wl_seat, but now we're getting a new one");
wl_seat_release(screen->priv->wl_seat);
}
screen->priv->wl_seat = wl_registry_bind(screen->priv->wl_registry,
id,
&wl_seat_interface,
MIN((uint32_t)wl_seat_interface.version, version));
}
}
......@@ -260,6 +274,11 @@ _xfw_screen_wayland_get_gdk_screen(XfwScreenWayland *screen) {
return screen->priv->gdk_screen;
}
struct wl_seat *
_xfw_screen_wayland_get_wl_seat(XfwScreenWayland *screen) {
return screen->priv->wl_seat;
}
void
_xfw_screen_wayland_set_active_window(XfwScreenWayland *screen, XfwWindow *window) {
if (screen->priv->active_window != window) {
......
......@@ -25,6 +25,7 @@
#endif
#include <glib-object.h>
#include <wayland-client.h>
#include "xfw-window.h"
#include "xfw-workspace.h"
......@@ -51,7 +52,8 @@ struct _XfwScreenWaylandClass {
GType xfw_screen_wayland_get_type(void) G_GNUC_CONST;
GdkScreen * _xfw_screen_wayland_get_gdk_screen(XfwScreenWayland *screen);
GdkScreen *_xfw_screen_wayland_get_gdk_screen(XfwScreenWayland *screen);
struct wl_seat *_xfw_screen_wayland_get_wl_seat(XfwScreenWayland *screen);
void _xfw_screen_wayland_set_active_window(XfwScreenWayland *screen, XfwWindow *window);
XfwWorkspace *_xfw_screen_wayland_get_window_workspace(XfwScreenWayland *screen, XfwWindow *window);
......
......@@ -41,11 +41,13 @@ G_BEGIN_DECLS
/**
* XfwErrorCode:
* @XFW_ERROR_UNSUPPORTED: the operation attempted is not supported.
* @XFW_ERROR_INTERNAL: an internal error has occurred.
*
* An error code enum describing possible errors returned by this library.
**/
typedef enum _XfwErrorCode {
XFW_ERROR_UNSUPPORTED = 0,
XFW_ERROR_INTERNAL,
} XfwErrorCode;
/**
......
......@@ -313,9 +313,18 @@ xfw_window_wayland_get_workspace(XfwWindow *window) {
static gboolean
xfw_window_wayland_activate(XfwWindow *window, guint64 event_timestamp, GError **error) {
// FIXME: make sure NULL for seat means "compositor picks what seat", and doesn't crash or fail
zwlr_foreign_toplevel_handle_v1_activate(XFW_WINDOW_WAYLAND(window)->priv->handle, NULL);
return TRUE;
XfwWindowWayland *wwindow = XFW_WINDOW_WAYLAND(window);
struct wl_seat *wl_seat = _xfw_screen_wayland_get_wl_seat(XFW_SCREEN_WAYLAND(wwindow->priv->screen));
if (wl_seat != NULL) {
zwlr_foreign_toplevel_handle_v1_activate(wwindow->priv->handle, wl_seat);
return TRUE;
} else {
if (error != NULL) {
*error = g_error_new(XFW_ERROR, XFW_ERROR_INTERNAL, "Cannot activate window as we do not have a wl_seat");
}
return FALSE;
}
}
static gboolean
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment