diff --git a/configure.ac b/configure.ac index b5905a74a..180af409e 100644 --- a/configure.ac +++ b/configure.ac @@ -133,7 +133,7 @@ AC_ARG_WITH([wayland-protocols], AC_ARG_WITH([xwayland-path], [AS_HELP_STRING([--with-xwayland-path], [Absolute path for an X Wayland server])], [XWAYLAND_PATH="$withval"], - [XWAYLAND_PATH="$bindir/Xorg"]) + [XWAYLAND_PATH="$bindir/Xwayland"]) AM_GLIB_GNU_GETTEXT diff --git a/src/Makefile.am b/src/Makefile.am index aacec1829..61a14fe74 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -41,14 +41,11 @@ mutter_built_sources = \ gtk-shell-protocol.c \ gtk-shell-server-protocol.h \ xdg-shell-protocol.c \ - xdg-shell-server-protocol.h \ - xserver-protocol.c \ - xserver-server-protocol.h + xdg-shell-server-protocol.h wayland_protocols = \ wayland/protocol/gtk-shell.xml \ - wayland/protocol/xdg-shell.xml \ - wayland/protocol/xserver.xml + wayland/protocol/xdg-shell.xml libmutter_wayland_la_SOURCES = \ backends/meta-backend.c \ @@ -214,8 +211,9 @@ libmutter_wayland_la_SOURCES = \ wayland/meta-wayland.c \ wayland/meta-wayland.h \ wayland/meta-wayland-private.h \ - wayland/meta-xwayland-private.h \ wayland/meta-xwayland.c \ + wayland/meta-xwayland.h \ + wayland/meta-xwayland-private.h \ wayland/meta-wayland-data-device.c \ wayland/meta-wayland-data-device.h \ wayland/meta-wayland-keyboard.c \ diff --git a/src/core/events.c b/src/core/events.c index afc499997..35e397f29 100644 --- a/src/core/events.c +++ b/src/core/events.c @@ -39,6 +39,7 @@ #include "x11/window-x11.h" #include "x11/xprops.h" +#include "wayland/meta-xwayland.h" #include "wayland/meta-wayland-private.h" #include "meta-surface-actor-wayland.h" @@ -1536,7 +1537,12 @@ handle_other_xevent (MetaDisplay *display, case ClientMessage: if (window) { - if (!frame_was_receiver) + if (event->xclient.message_type == display->atom_WL_SURFACE_ID) + { + guint32 surface_id = event->xclient.data.l[0]; + meta_xwayland_handle_wl_surface_id (window, surface_id); + } + else if (!frame_was_receiver) meta_window_x11_client_message (window, event); } else diff --git a/src/meta/atomnames.h b/src/meta/atomnames.h index f93876cce..38227deaa 100644 --- a/src/meta/atomnames.h +++ b/src/meta/atomnames.h @@ -81,6 +81,7 @@ item(ATOM_PAIR) item(BACKLIGHT) item(_XKB_RULES_NAMES) item(hotplug_mode_update) +item(WL_SURFACE_ID) /* Oddities: These are used, and we need atoms for them, * but when we need all _NET_WM hints (i.e. when we're making diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index ec9f342c1..cb1f54ad1 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -23,6 +23,7 @@ #include "config.h" +#include "meta-xwayland.h" #include "meta-xwayland-private.h" #include @@ -36,9 +37,6 @@ #include #include -#include "meta-window-actor-private.h" -#include "xserver-server-protocol.h" - static void associate_window_with_surface (MetaWindow *window, MetaWaylandSurface *surface) @@ -58,53 +56,63 @@ associate_window_with_surface (MetaWindow *window, meta_compositor_window_surface_changed (display->compositor, window); } -static void -xserver_set_window_id (struct wl_client *client, - struct wl_resource *compositor_resource, - struct wl_resource *surface_resource, - guint32 xid) +static gboolean +associate_window_with_surface_id (MetaXWaylandManager *manager, + MetaWindow *window, + guint32 surface_id) { - MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); - MetaDisplay *display = meta_get_display (); - MetaWindow *window; + struct wl_resource *resource; - window = meta_display_lookup_x_window (display, xid); - if (!window) - return; - - associate_window_with_surface (window, surface); + resource = wl_client_get_object (manager->client, surface_id); + if (resource) + { + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); + associate_window_with_surface (window, surface); + return TRUE; + } + else + return FALSE; } -static const struct xserver_interface xserver_implementation = { - xserver_set_window_id -}; +typedef struct { + MetaXWaylandManager *manager; + MetaWindow *window; + guint32 surface_id; +} AssociateWindowWithSurfaceOp; -static void -bind_xserver (struct wl_client *client, - void *data, - guint32 version, - guint32 id) +static gboolean +associate_window_with_surface_idle (gpointer user_data) { - MetaXWaylandManager *manager = data; + AssociateWindowWithSurfaceOp *op = user_data; + if (!associate_window_with_surface_id (op->manager, op->window, op->surface_id)) + { + /* Not here? Oh well... nothing we can do */ + g_warning ("Unknown surface ID %d (from window %s)", op->surface_id, op->window->desc); + } + g_free (op); - /* If it's a different client than the xserver we launched, - * just freeze up... */ - if (client != manager->client) - return; + return G_SOURCE_REMOVE; +} - manager->xserver_resource = wl_resource_create (client, &xserver_interface, - MIN (META_XSERVER_VERSION, version), id); - wl_resource_set_implementation (manager->xserver_resource, - &xserver_implementation, manager, NULL); +void +meta_xwayland_handle_wl_surface_id (MetaWindow *window, + guint32 surface_id) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + MetaXWaylandManager *manager = &compositor->xwayland_manager; - xserver_send_listen_socket (manager->xserver_resource, manager->abstract_fd); - xserver_send_listen_socket (manager->xserver_resource, manager->unix_fd); - - /* Make sure xwayland will recieve the above sockets in a finite - * time before unblocking the initialization mainloop since we are - * then going to immediately try and connect to those as the window - * manager. */ - wl_client_flush (client); + if (!associate_window_with_surface_id (manager, window, surface_id)) + { + /* No surface ID yet... it should arrive after the next + * iteration through the loop, so queue an idle and see + * what happens. + */ + AssociateWindowWithSurfaceOp *op = g_new0 (AssociateWindowWithSurfaceOp, 1); + op->manager = manager; + op->window = window; + op->surface_id = surface_id; + g_idle_add (associate_window_with_surface_idle, op); + } } static char * @@ -363,10 +371,6 @@ meta_xwayland_start (MetaXWaylandManager *manager, if (!choose_xdisplay (manager)) return FALSE; - wl_global_create (wl_display, &xserver_interface, - META_XSERVER_VERSION, - manager, bind_xserver); - /* We want xwayland to be a wayland client so we make a socketpair to setup a * wayland protocol connection. */ if (socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sp) < 0) @@ -379,7 +383,7 @@ meta_xwayland_start (MetaXWaylandManager *manager, manager->pid = fork (); if (manager->pid == 0) { - char socket_fd[8]; + char socket_fd[8], unix_fd[8], abstract_fd[8]; /* We passed SOCK_CLOEXEC, so dup the FD so it isn't * closed on exec.. */ @@ -387,6 +391,12 @@ meta_xwayland_start (MetaXWaylandManager *manager, snprintf (socket_fd, sizeof (socket_fd), "%d", fd); setenv ("WAYLAND_SOCKET", socket_fd, TRUE); + fd = dup (manager->abstract_fd); + snprintf (abstract_fd, sizeof (abstract_fd), "%d", fd); + + fd = dup (manager->unix_fd); + snprintf (unix_fd, sizeof (unix_fd), "%d", fd); + /* xwayland, please. */ if (getenv ("XWAYLAND_STFU")) { @@ -403,10 +413,10 @@ meta_xwayland_start (MetaXWaylandManager *manager, if (execl (XWAYLAND_PATH, XWAYLAND_PATH, manager->display_name, - "-wayland", "-rootless", "-noreset", - "-nolisten", "all", + "-listen", abstract_fd, + "-listen", unix_fd, NULL) < 0) { g_error ("Failed to spawn XWayland: %m"); diff --git a/src/wayland/meta-xwayland.h b/src/wayland/meta-xwayland.h new file mode 100644 index 000000000..5308f2957 --- /dev/null +++ b/src/wayland/meta-xwayland.h @@ -0,0 +1,35 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 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: + * Jasper St. Pierre + */ + +#ifndef META_XWAYLAND_H +#define META_XWAYLAND_H + +#include +#include + +void +meta_xwayland_handle_wl_surface_id (MetaWindow *window, + guint32 surface_id); + +#endif /* META_XWAYLAND_H */ diff --git a/src/wayland/protocol/xserver.xml b/src/wayland/protocol/xserver.xml deleted file mode 100644 index 9e25f5c0d..000000000 --- a/src/wayland/protocol/xserver.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - -