Compare commits
	
		
			17 Commits
		
	
	
		
			3.34.1
			...
			wip/carlos
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					8aeec308fb | ||
| 
						 | 
					252fd771b1 | ||
| 
						 | 
					41bff1e997 | ||
| 
						 | 
					323742e736 | ||
| 
						 | 
					14f41f3130 | ||
| 
						 | 
					21b4cf8a50 | ||
| 
						 | 
					a4f47820c3 | ||
| 
						 | 
					471eca3745 | ||
| 
						 | 
					c1f39514ca | ||
| 
						 | 
					038720fecc | ||
| 
						 | 
					d367d97364 | ||
| 
						 | 
					885f89a217 | ||
| 
						 | 
					21411faeb1 | ||
| 
						 | 
					cf4a9b3f6a | ||
| 
						 | 
					1226c599c9 | ||
| 
						 | 
					c9459fa096 | ||
| 
						 | 
					d31fb640d5 | 
@@ -124,6 +124,8 @@
 | 
			
		||||
                                        real-time scheduling. The executable
 | 
			
		||||
                                        or user must have CAP_SYS_NICE.
 | 
			
		||||
                                        Requires a restart.
 | 
			
		||||
        • “autostart-xwayland”        — initializes Xwayland lazily if there are
 | 
			
		||||
                                        X11 clients. Requires restart.
 | 
			
		||||
      </description>
 | 
			
		||||
    </key>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -34,6 +34,7 @@ typedef enum _MetaExperimentalFeature
 | 
			
		||||
  META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER = (1 << 0),
 | 
			
		||||
  META_EXPERIMENTAL_FEATURE_KMS_MODIFIERS  = (1 << 1),
 | 
			
		||||
  META_EXPERIMENTAL_FEATURE_RT_SCHEDULER = (1 << 2),
 | 
			
		||||
  META_EXPERIMENTAL_FEATURE_AUTOSTART_XWAYLAND  = (1 << 3),
 | 
			
		||||
} MetaExperimentalFeature;
 | 
			
		||||
 | 
			
		||||
#define META_TYPE_SETTINGS (meta_settings_get_type ())
 | 
			
		||||
 
 | 
			
		||||
@@ -266,6 +266,8 @@ experimental_features_handler (GVariant *features_variant,
 | 
			
		||||
        features |= META_EXPERIMENTAL_FEATURE_KMS_MODIFIERS;
 | 
			
		||||
      else if (g_str_equal (feature, "rt-scheduler"))
 | 
			
		||||
        features |= META_EXPERIMENTAL_FEATURE_RT_SCHEDULER;
 | 
			
		||||
      else if (g_str_equal (feature, "autostart-xwayland"))
 | 
			
		||||
        features |= META_EXPERIMENTAL_FEATURE_AUTOSTART_XWAYLAND;
 | 
			
		||||
      else
 | 
			
		||||
        g_info ("Unknown experimental feature '%s'\n", feature);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -74,4 +74,6 @@ MetaInhibitShortcutsDialog * meta_compositor_create_inhibit_shortcuts_dialog (Me
 | 
			
		||||
 | 
			
		||||
void meta_compositor_locate_pointer (MetaCompositor *compositor);
 | 
			
		||||
 | 
			
		||||
void meta_compositor_redirect_x11_windows (MetaCompositor *compositor);
 | 
			
		||||
 | 
			
		||||
#endif /* META_COMPOSITOR_PRIVATE_H */
 | 
			
		||||
 
 | 
			
		||||
@@ -516,6 +516,15 @@ redirect_windows (MetaX11Display *x11_display)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_compositor_redirect_x11_windows (MetaCompositor *compositor)
 | 
			
		||||
{
 | 
			
		||||
  MetaDisplay *display = compositor->display;
 | 
			
		||||
 | 
			
		||||
  if (display->x11_display)
 | 
			
		||||
    redirect_windows (display->x11_display);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_compositor_manage (MetaCompositor *compositor)
 | 
			
		||||
{
 | 
			
		||||
@@ -595,8 +604,7 @@ meta_compositor_manage (MetaCompositor *compositor)
 | 
			
		||||
      compositor->have_x11_sync_object = meta_sync_ring_init (xdisplay);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (display->x11_display)
 | 
			
		||||
    redirect_windows (display->x11_display);
 | 
			
		||||
  meta_compositor_redirect_x11_windows (compositor);
 | 
			
		||||
 | 
			
		||||
  compositor->plugin_mgr = meta_plugin_manager_new (compositor);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -264,7 +264,7 @@ struct _MetaDisplayClass
 | 
			
		||||
 | 
			
		||||
gboolean      meta_display_open                (void);
 | 
			
		||||
 | 
			
		||||
void meta_display_manage_all_windows (MetaDisplay *display);
 | 
			
		||||
void meta_display_manage_all_xwindows (MetaDisplay *display);
 | 
			
		||||
void meta_display_unmanage_windows   (MetaDisplay *display,
 | 
			
		||||
                                      guint32      timestamp);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -49,6 +49,7 @@
 | 
			
		||||
#include "backends/x11/meta-backend-x11.h"
 | 
			
		||||
#include "backends/x11/cm/meta-backend-x11-cm.h"
 | 
			
		||||
#include "clutter/x11/clutter-x11.h"
 | 
			
		||||
#include "compositor/compositor-private.h"
 | 
			
		||||
#include "core/bell.h"
 | 
			
		||||
#include "core/boxes-private.h"
 | 
			
		||||
#include "core/display-private.h"
 | 
			
		||||
@@ -149,6 +150,7 @@ enum
 | 
			
		||||
  SHOWING_DESKTOP_CHANGED,
 | 
			
		||||
  RESTACKED,
 | 
			
		||||
  WORKAREAS_CHANGED,
 | 
			
		||||
  INIT_XSERVER,
 | 
			
		||||
  LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -479,6 +481,13 @@ meta_display_class_init (MetaDisplayClass *klass)
 | 
			
		||||
                  0, NULL, NULL, NULL,
 | 
			
		||||
                  G_TYPE_NONE, 0);
 | 
			
		||||
 | 
			
		||||
  display_signals[INIT_XSERVER] =
 | 
			
		||||
    g_signal_new ("init-xserver",
 | 
			
		||||
                  G_TYPE_FROM_CLASS (klass),
 | 
			
		||||
                  G_SIGNAL_RUN_LAST,
 | 
			
		||||
                  0, NULL, NULL, NULL,
 | 
			
		||||
                  G_TYPE_NONE, 1, G_TYPE_INT);
 | 
			
		||||
 | 
			
		||||
  g_object_class_install_property (object_class,
 | 
			
		||||
                                   PROP_FOCUS_WINDOW,
 | 
			
		||||
                                   g_param_spec_object ("focus-window",
 | 
			
		||||
@@ -643,10 +652,15 @@ meta_display_init_x11 (MetaDisplay  *display,
 | 
			
		||||
 | 
			
		||||
  display->x11_display = x11_display;
 | 
			
		||||
  g_signal_emit (display, display_signals[X11_DISPLAY_OPENED], 0);
 | 
			
		||||
  meta_x11_display_create_guard_window (x11_display);
 | 
			
		||||
 | 
			
		||||
  if (!display->display_opening)
 | 
			
		||||
    meta_display_manage_all_windows (display);
 | 
			
		||||
  if (meta_get_x11_display_policy () == META_DISPLAY_POLICY_ON_DEMAND)
 | 
			
		||||
    {
 | 
			
		||||
      meta_x11_display_create_guard_window (x11_display);
 | 
			
		||||
      if (!display->display_opening)
 | 
			
		||||
        meta_display_manage_all_xwindows (display);
 | 
			
		||||
 | 
			
		||||
      meta_compositor_redirect_x11_windows (display->compositor);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
@@ -758,7 +772,7 @@ meta_display_open (void)
 | 
			
		||||
  display->selection = meta_selection_new (display);
 | 
			
		||||
  meta_clipboard_manager_init (display);
 | 
			
		||||
 | 
			
		||||
  if (meta_should_autostart_x11_display ())
 | 
			
		||||
  if (meta_get_x11_display_policy () == META_DISPLAY_POLICY_MANDATORY)
 | 
			
		||||
    {
 | 
			
		||||
      if (!meta_display_init_x11 (display, &error))
 | 
			
		||||
        g_error ("Failed to start Xwayland: %s", error->message);
 | 
			
		||||
@@ -797,7 +811,7 @@ meta_display_open (void)
 | 
			
		||||
   * we start out with no windows.
 | 
			
		||||
   */
 | 
			
		||||
  if (!meta_is_wayland_compositor ())
 | 
			
		||||
    meta_display_manage_all_windows (display);
 | 
			
		||||
    meta_display_manage_all_xwindows (display);
 | 
			
		||||
 | 
			
		||||
  if (old_active_xwindow != None)
 | 
			
		||||
    {
 | 
			
		||||
@@ -2448,7 +2462,7 @@ meta_resize_gravity_from_grab_op (MetaGrabOp op)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_display_manage_all_windows (MetaDisplay *display)
 | 
			
		||||
meta_display_manage_all_xwindows (MetaDisplay *display)
 | 
			
		||||
{
 | 
			
		||||
  guint64 *_children;
 | 
			
		||||
  guint64 *children;
 | 
			
		||||
@@ -2462,7 +2476,8 @@ meta_display_manage_all_windows (MetaDisplay *display)
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < n_children; ++i)
 | 
			
		||||
    {
 | 
			
		||||
      g_assert (META_STACK_ID_IS_X11 (children[i]));
 | 
			
		||||
      if (!META_STACK_ID_IS_X11 (children[i]))
 | 
			
		||||
        continue;
 | 
			
		||||
      meta_window_x11_new (display, children[i], TRUE,
 | 
			
		||||
                           META_COMP_EFFECT_NONE);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -190,9 +190,14 @@ meta_window_destroy_frame (MetaWindow *window)
 | 
			
		||||
                  "Incrementing unmaps_pending on %s for reparent back to root\n", window->desc);
 | 
			
		||||
      window->unmaps_pending += 1;
 | 
			
		||||
    }
 | 
			
		||||
  meta_stack_tracker_record_add (window->display->stack_tracker,
 | 
			
		||||
                                 window->xwindow,
 | 
			
		||||
                                 XNextRequest (x11_display->xdisplay));
 | 
			
		||||
 | 
			
		||||
  if (!x11_display->closing)
 | 
			
		||||
    {
 | 
			
		||||
      meta_stack_tracker_record_add (window->display->stack_tracker,
 | 
			
		||||
                                     window->xwindow,
 | 
			
		||||
                                     XNextRequest (x11_display->xdisplay));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  XReparentWindow (x11_display->xdisplay,
 | 
			
		||||
                   window->xwindow,
 | 
			
		||||
                   x11_display->xroot,
 | 
			
		||||
 
 | 
			
		||||
@@ -1570,6 +1570,8 @@ meta_window_grab_keys (MetaWindow  *window)
 | 
			
		||||
  MetaDisplay *display = window->display;
 | 
			
		||||
  MetaKeyBindingManager *keys = &display->key_binding_manager;
 | 
			
		||||
 | 
			
		||||
  if (!meta_is_wayland_compositor ())
 | 
			
		||||
    return;
 | 
			
		||||
  if (window->all_keys_grabbed)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
@@ -1604,7 +1606,7 @@ meta_window_grab_keys (MetaWindow  *window)
 | 
			
		||||
void
 | 
			
		||||
meta_window_ungrab_keys (MetaWindow  *window)
 | 
			
		||||
{
 | 
			
		||||
  if (window->keys_grabbed)
 | 
			
		||||
  if (!meta_is_wayland_compositor () && window->keys_grabbed)
 | 
			
		||||
    {
 | 
			
		||||
      MetaDisplay *display = window->display;
 | 
			
		||||
      MetaKeyBindingManager *keys = &display->key_binding_manager;
 | 
			
		||||
@@ -1663,7 +1665,11 @@ meta_display_grab_accelerator (MetaDisplay         *display,
 | 
			
		||||
      return META_KEYBINDING_ACTION_NONE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_change_keygrab (keys, display->x11_display->xroot, TRUE, &resolved_combo);
 | 
			
		||||
  if (!meta_is_wayland_compositor ())
 | 
			
		||||
    {
 | 
			
		||||
      meta_change_keygrab (keys, display->x11_display->xroot,
 | 
			
		||||
                           TRUE, &resolved_combo);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  grab = g_new0 (MetaKeyGrab, 1);
 | 
			
		||||
  grab->action = next_dynamic_keybinding_action ();
 | 
			
		||||
@@ -1709,8 +1715,11 @@ meta_display_ungrab_accelerator (MetaDisplay *display,
 | 
			
		||||
    {
 | 
			
		||||
      int i;
 | 
			
		||||
 | 
			
		||||
      meta_change_keygrab (keys, display->x11_display->xroot,
 | 
			
		||||
                           FALSE, &binding->resolved_combo);
 | 
			
		||||
      if (!meta_is_wayland_compositor ())
 | 
			
		||||
        {
 | 
			
		||||
          meta_change_keygrab (keys, display->x11_display->xroot,
 | 
			
		||||
                               FALSE, &binding->resolved_combo);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      for (i = 0; i < binding->resolved_combo.len; i++)
 | 
			
		||||
        {
 | 
			
		||||
@@ -1788,7 +1797,7 @@ meta_window_grab_all_keys (MetaWindow  *window,
 | 
			
		||||
                           guint32      timestamp)
 | 
			
		||||
{
 | 
			
		||||
  Window grabwindow;
 | 
			
		||||
  gboolean retval;
 | 
			
		||||
  gboolean retval = TRUE;
 | 
			
		||||
 | 
			
		||||
  if (window->all_keys_grabbed)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
@@ -1804,25 +1813,29 @@ meta_window_grab_all_keys (MetaWindow  *window,
 | 
			
		||||
              window->desc);
 | 
			
		||||
  meta_window_focus (window, timestamp);
 | 
			
		||||
 | 
			
		||||
  grabwindow = meta_window_x11_get_toplevel_xwindow (window);
 | 
			
		||||
 | 
			
		||||
  meta_topic (META_DEBUG_KEYBINDINGS,
 | 
			
		||||
              "Grabbing all keys on window %s\n", window->desc);
 | 
			
		||||
  retval = grab_keyboard (grabwindow, timestamp, XIGrabModeAsync);
 | 
			
		||||
  if (retval)
 | 
			
		||||
  if (!meta_is_wayland_compositor ())
 | 
			
		||||
    {
 | 
			
		||||
      window->keys_grabbed = FALSE;
 | 
			
		||||
      window->all_keys_grabbed = TRUE;
 | 
			
		||||
      window->grab_on_frame = window->frame != NULL;
 | 
			
		||||
      grabwindow = meta_window_x11_get_toplevel_xwindow (window);
 | 
			
		||||
 | 
			
		||||
      meta_topic (META_DEBUG_KEYBINDINGS,
 | 
			
		||||
                  "Grabbing all keys on window %s\n", window->desc);
 | 
			
		||||
      retval = grab_keyboard (grabwindow, timestamp, XIGrabModeAsync);
 | 
			
		||||
      if (retval)
 | 
			
		||||
        {
 | 
			
		||||
          window->keys_grabbed = FALSE;
 | 
			
		||||
          window->all_keys_grabbed = TRUE;
 | 
			
		||||
          window->grab_on_frame = window->frame != NULL;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_window_ungrab_all_keys (MetaWindow *window, guint32 timestamp)
 | 
			
		||||
meta_window_ungrab_all_keys (MetaWindow *window,
 | 
			
		||||
                             guint32     timestamp)
 | 
			
		||||
{
 | 
			
		||||
  if (window->all_keys_grabbed)
 | 
			
		||||
  if (!meta_is_wayland_compositor () && window->all_keys_grabbed)
 | 
			
		||||
    {
 | 
			
		||||
      ungrab_keyboard (timestamp);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -30,10 +30,17 @@ typedef enum _MetaCompositorType
 | 
			
		||||
  META_COMPOSITOR_TYPE_X11,
 | 
			
		||||
} MetaCompositorType;
 | 
			
		||||
 | 
			
		||||
typedef enum _MetaDisplayPolicy
 | 
			
		||||
{
 | 
			
		||||
  META_DISPLAY_POLICY_MANDATORY,
 | 
			
		||||
  META_DISPLAY_POLICY_ON_DEMAND,
 | 
			
		||||
  META_DISPLAY_POLICY_DISABLED,
 | 
			
		||||
} MetaDisplayPolicy;
 | 
			
		||||
 | 
			
		||||
META_EXPORT_TEST
 | 
			
		||||
void meta_override_compositor_configuration (MetaCompositorType compositor_type,
 | 
			
		||||
                                             GType              backend_gtype);
 | 
			
		||||
 | 
			
		||||
gboolean meta_should_autostart_x11_display (void);
 | 
			
		||||
MetaDisplayPolicy meta_get_x11_display_policy (void);
 | 
			
		||||
 | 
			
		||||
#endif /* META_MAIN_PRIVATE_H */
 | 
			
		||||
 
 | 
			
		||||
@@ -717,15 +717,27 @@ prefs_changed_callback (MetaPreference pref,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_should_autostart_x11_display (void)
 | 
			
		||||
MetaDisplayPolicy
 | 
			
		||||
meta_get_x11_display_policy (void)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackend *backend = meta_get_backend ();
 | 
			
		||||
  gboolean wants_x11 = TRUE;
 | 
			
		||||
 | 
			
		||||
  if (META_IS_BACKEND_X11_CM (backend))
 | 
			
		||||
    return META_DISPLAY_POLICY_MANDATORY;
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_WAYLAND
 | 
			
		||||
  wants_x11 = !opt_no_x11;
 | 
			
		||||
  if (meta_is_wayland_compositor ())
 | 
			
		||||
    {
 | 
			
		||||
      MetaSettings *settings = meta_backend_get_settings (backend);
 | 
			
		||||
 | 
			
		||||
      if (opt_no_x11)
 | 
			
		||||
        return META_DISPLAY_POLICY_DISABLED;
 | 
			
		||||
 | 
			
		||||
      if (meta_settings_is_experimental_feature_enabled (settings,
 | 
			
		||||
                                                         META_EXPERIMENTAL_FEATURE_AUTOSTART_XWAYLAND))
 | 
			
		||||
        return META_DISPLAY_POLICY_ON_DEMAND;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  return META_IS_BACKEND_X11_CM (backend) || wants_x11;
 | 
			
		||||
  return META_DISPLAY_POLICY_MANDATORY;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -114,7 +114,7 @@ meta_launch_context_constructed (GObject *object)
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (meta_launch_context_parent_class)->constructed (object);
 | 
			
		||||
 | 
			
		||||
  x11_display = getenv ("DISPLAY");
 | 
			
		||||
  x11_display = meta_x11_get_display_name ();
 | 
			
		||||
  wayland_display = getenv ("WAYLAND_DISPLAY");
 | 
			
		||||
 | 
			
		||||
  if (x11_display)
 | 
			
		||||
 
 | 
			
		||||
@@ -508,6 +508,42 @@ query_xserver_stack (MetaDisplay      *display,
 | 
			
		||||
  XFree (children);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
drop_x11_windows (MetaDisplay      *display,
 | 
			
		||||
                  MetaStackTracker *tracker)
 | 
			
		||||
{
 | 
			
		||||
  GArray *new_stack;
 | 
			
		||||
  GList *l;
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  tracker->xserver_serial = 0;
 | 
			
		||||
 | 
			
		||||
  new_stack = g_array_new (FALSE, FALSE, sizeof (guint64));
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < tracker->verified_stack->len; i++)
 | 
			
		||||
    {
 | 
			
		||||
      guint64 window = g_array_index (tracker->verified_stack, guint64, i);
 | 
			
		||||
 | 
			
		||||
      if (!META_STACK_ID_IS_X11 (window))
 | 
			
		||||
        g_array_append_val (new_stack, window);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_array_unref (tracker->verified_stack);
 | 
			
		||||
  tracker->verified_stack = new_stack;
 | 
			
		||||
  l = tracker->unverified_predictions->head;
 | 
			
		||||
 | 
			
		||||
  while (l)
 | 
			
		||||
    {
 | 
			
		||||
      MetaStackOp *op = l->data;
 | 
			
		||||
      GList *next = l->next;
 | 
			
		||||
 | 
			
		||||
      if (META_STACK_ID_IS_X11 (op->any.window))
 | 
			
		||||
        g_queue_remove (tracker->unverified_predictions, op);
 | 
			
		||||
 | 
			
		||||
      l = next;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaStackTracker *
 | 
			
		||||
meta_stack_tracker_new (MetaDisplay *display)
 | 
			
		||||
{
 | 
			
		||||
@@ -523,6 +559,10 @@ meta_stack_tracker_new (MetaDisplay *display)
 | 
			
		||||
                    "x11-display-opened",
 | 
			
		||||
                    G_CALLBACK (query_xserver_stack),
 | 
			
		||||
                    tracker);
 | 
			
		||||
  g_signal_connect (display,
 | 
			
		||||
                    "x11-display-closing",
 | 
			
		||||
                    G_CALLBACK (drop_x11_windows),
 | 
			
		||||
                    tracker);
 | 
			
		||||
 | 
			
		||||
  meta_stack_tracker_dump (tracker);
 | 
			
		||||
 | 
			
		||||
@@ -546,6 +586,9 @@ meta_stack_tracker_free (MetaStackTracker *tracker)
 | 
			
		||||
  g_signal_handlers_disconnect_by_func (tracker->display,
 | 
			
		||||
                                        (gpointer)query_xserver_stack,
 | 
			
		||||
                                        tracker);
 | 
			
		||||
  g_signal_handlers_disconnect_by_func (tracker->display,
 | 
			
		||||
                                        drop_x11_windows,
 | 
			
		||||
                                        tracker);
 | 
			
		||||
 | 
			
		||||
  g_free (tracker);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -48,16 +48,26 @@ typedef struct
 | 
			
		||||
  char *lock_file;
 | 
			
		||||
  int abstract_fd;
 | 
			
		||||
  int unix_fd;
 | 
			
		||||
  char *name;
 | 
			
		||||
} MetaXWaylandConnection;
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  MetaXWaylandConnection private_connection;
 | 
			
		||||
  MetaXWaylandConnection public_connection;
 | 
			
		||||
 | 
			
		||||
  guint xserver_grace_period_id;
 | 
			
		||||
  struct wl_display *wayland_display;
 | 
			
		||||
  struct wl_client *client;
 | 
			
		||||
  struct wl_resource *xserver_resource;
 | 
			
		||||
  char *display_name;
 | 
			
		||||
  char *auth_file;
 | 
			
		||||
 | 
			
		||||
  GCancellable *xserver_died_cancellable;
 | 
			
		||||
  GSubprocess *proc;
 | 
			
		||||
  GMainLoop *init_loop;
 | 
			
		||||
 | 
			
		||||
  GList *x11_windows;
 | 
			
		||||
 | 
			
		||||
  MetaXWaylandDnd *dnd;
 | 
			
		||||
} MetaXWaylandManager;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -418,9 +418,9 @@ meta_wayland_init (void)
 | 
			
		||||
  meta_wayland_eglstream_controller_init (compositor);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  if (meta_should_autostart_x11_display ())
 | 
			
		||||
  if (meta_get_x11_display_policy () != META_DISPLAY_POLICY_DISABLED)
 | 
			
		||||
    {
 | 
			
		||||
      if (!meta_xwayland_start (&compositor->xwayland_manager, compositor->wayland_display))
 | 
			
		||||
      if (!meta_xwayland_init (&compositor->xwayland_manager, compositor->wayland_display))
 | 
			
		||||
        g_error ("Failed to start X Wayland");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -443,9 +443,9 @@ meta_wayland_init (void)
 | 
			
		||||
      compositor->display_name = g_strdup (display_name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (meta_should_autostart_x11_display ())
 | 
			
		||||
  if (meta_get_x11_display_policy () != META_DISPLAY_POLICY_DISABLED)
 | 
			
		||||
    {
 | 
			
		||||
      set_gnome_env ("DISPLAY", meta_wayland_get_xwayland_display_name (compositor));
 | 
			
		||||
      set_gnome_env ("DISPLAY", compositor->xwayland_manager.public_connection.name);
 | 
			
		||||
      set_gnome_env ("XAUTHORITY", meta_wayland_get_xwayland_auth_file (compositor));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -461,7 +461,7 @@ meta_wayland_get_wayland_display_name (MetaWaylandCompositor *compositor)
 | 
			
		||||
const char *
 | 
			
		||||
meta_wayland_get_xwayland_display_name (MetaWaylandCompositor *compositor)
 | 
			
		||||
{
 | 
			
		||||
  return compositor->xwayland_manager.display_name;
 | 
			
		||||
  return compositor->xwayland_manager.private_connection.name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -471,7 +471,7 @@ meta_wayland_finalize (void)
 | 
			
		||||
 | 
			
		||||
  compositor = meta_wayland_compositor_get_default ();
 | 
			
		||||
 | 
			
		||||
  meta_xwayland_stop (&compositor->xwayland_manager);
 | 
			
		||||
  meta_xwayland_shutdown (&compositor->xwayland_manager);
 | 
			
		||||
  g_clear_pointer (&compositor->display_name, g_free);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -25,14 +25,14 @@
 | 
			
		||||
#include "wayland/meta-wayland-private.h"
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_xwayland_start (MetaXWaylandManager *manager,
 | 
			
		||||
                     struct wl_display   *display);
 | 
			
		||||
meta_xwayland_init (MetaXWaylandManager *manager,
 | 
			
		||||
		    struct wl_display   *display);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_xwayland_complete_init (MetaDisplay *display);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_xwayland_stop (MetaXWaylandManager *manager);
 | 
			
		||||
meta_xwayland_shutdown (MetaXWaylandManager *manager);
 | 
			
		||||
 | 
			
		||||
/* wl_data_device/X11 selection interoperation */
 | 
			
		||||
void     meta_xwayland_init_dnd         (void);
 | 
			
		||||
 
 | 
			
		||||
@@ -41,6 +41,7 @@
 | 
			
		||||
 | 
			
		||||
#include "compositor/meta-surface-actor-wayland.h"
 | 
			
		||||
#include "compositor/meta-window-actor-private.h"
 | 
			
		||||
#include "core/main-private.h"
 | 
			
		||||
#include "meta/main.h"
 | 
			
		||||
#include "wayland/meta-wayland-actor-surface.h"
 | 
			
		||||
 | 
			
		||||
@@ -70,6 +71,8 @@ G_DEFINE_TYPE (MetaWaylandSurfaceRoleXWayland,
 | 
			
		||||
 | 
			
		||||
static int display_number_override = -1;
 | 
			
		||||
 | 
			
		||||
static void meta_xwayland_stop_xserver (MetaXWaylandManager *manager);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_xwayland_associate_window_with_surface (MetaWindow          *window,
 | 
			
		||||
                                             MetaWaylandSurface  *surface)
 | 
			
		||||
@@ -368,24 +371,45 @@ xserver_died (GObject      *source,
 | 
			
		||||
      g_warning ("Failed to finish waiting for Xwayland: %s", error->message);
 | 
			
		||||
    }
 | 
			
		||||
  else if (!g_subprocess_get_successful (proc))
 | 
			
		||||
    g_warning ("X Wayland crashed; exiting");
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      /* For now we simply abort if we see the server exit.
 | 
			
		||||
       *
 | 
			
		||||
       * In the future X will only be loaded lazily for legacy X support
 | 
			
		||||
       * but for now it's a hard requirement. */
 | 
			
		||||
      g_warning ("Spurious exit of X Wayland server");
 | 
			
		||||
    }
 | 
			
		||||
    g_warning ("X Wayland process exited");
 | 
			
		||||
 | 
			
		||||
  meta_exit (META_EXIT_ERROR);
 | 
			
		||||
  if (meta_get_x11_display_policy () == META_DISPLAY_POLICY_MANDATORY)
 | 
			
		||||
    {
 | 
			
		||||
      meta_exit (META_EXIT_ERROR);
 | 
			
		||||
    }
 | 
			
		||||
  else if (meta_get_x11_display_policy () == META_DISPLAY_POLICY_ON_DEMAND)
 | 
			
		||||
    {
 | 
			
		||||
      MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
 | 
			
		||||
      MetaDisplay *display = meta_get_display ();
 | 
			
		||||
 | 
			
		||||
      if (display->x11_display)
 | 
			
		||||
        meta_display_shutdown_x11 (display);
 | 
			
		||||
 | 
			
		||||
      if (!meta_xwayland_init (&compositor->xwayland_manager,
 | 
			
		||||
                               compositor->wayland_display))
 | 
			
		||||
        g_warning ("Failed to init X sockets");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
shutdown_xwayland_cb (gpointer data)
 | 
			
		||||
{
 | 
			
		||||
  MetaXWaylandManager *manager = data;
 | 
			
		||||
 | 
			
		||||
  g_debug ("Shutting down Xwayland");
 | 
			
		||||
  manager->xserver_grace_period_id = 0;
 | 
			
		||||
  meta_display_shutdown_x11 (meta_get_display ());
 | 
			
		||||
  meta_xwayland_stop_xserver (manager);
 | 
			
		||||
  return G_SOURCE_REMOVE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
x_io_error (Display *display)
 | 
			
		||||
{
 | 
			
		||||
  g_warning ("Connection to xwayland lost");
 | 
			
		||||
  meta_exit (META_EXIT_ERROR);
 | 
			
		||||
 | 
			
		||||
  if (meta_get_x11_display_policy () == META_DISPLAY_POLICY_MANDATORY)
 | 
			
		||||
    meta_exit (META_EXIT_ERROR);
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -397,7 +421,36 @@ meta_xwayland_override_display_number (int number)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
choose_xdisplay (MetaXWaylandManager *manager)
 | 
			
		||||
open_display_sockets (MetaXWaylandManager *manager,
 | 
			
		||||
                      int                  display_index,
 | 
			
		||||
                      int                 *abstract_fd_out,
 | 
			
		||||
                      int                 *unix_fd_out,
 | 
			
		||||
                      gboolean            *fatal)
 | 
			
		||||
{
 | 
			
		||||
  int abstract_fd, unix_fd;
 | 
			
		||||
 | 
			
		||||
  abstract_fd = bind_to_abstract_socket (display_index,
 | 
			
		||||
                                         fatal);
 | 
			
		||||
  if (abstract_fd < 0)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  unix_fd = bind_to_unix_socket (display_index);
 | 
			
		||||
  if (unix_fd < 0)
 | 
			
		||||
    {
 | 
			
		||||
      *fatal = FALSE;
 | 
			
		||||
      close (abstract_fd);
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  *abstract_fd_out = abstract_fd;
 | 
			
		||||
  *unix_fd_out = unix_fd;
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
choose_xdisplay (MetaXWaylandManager    *manager,
 | 
			
		||||
                 MetaXWaylandConnection *connection)
 | 
			
		||||
{
 | 
			
		||||
  int display = 0;
 | 
			
		||||
  char *lock_file = NULL;
 | 
			
		||||
@@ -417,8 +470,10 @@ choose_xdisplay (MetaXWaylandManager *manager)
 | 
			
		||||
          return FALSE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      manager->abstract_fd = bind_to_abstract_socket (display, &fatal);
 | 
			
		||||
      if (manager->abstract_fd < 0)
 | 
			
		||||
      if (!open_display_sockets (manager, display,
 | 
			
		||||
                                 &connection->abstract_fd,
 | 
			
		||||
                                 &connection->unix_fd,
 | 
			
		||||
                                 &fatal))
 | 
			
		||||
        {
 | 
			
		||||
          unlink (lock_file);
 | 
			
		||||
 | 
			
		||||
@@ -429,27 +484,18 @@ choose_xdisplay (MetaXWaylandManager *manager)
 | 
			
		||||
            }
 | 
			
		||||
          else
 | 
			
		||||
            {
 | 
			
		||||
              g_warning ("Failed to bind abstract socket");
 | 
			
		||||
              g_warning ("Failed to bind X11 socket");
 | 
			
		||||
              return FALSE;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      manager->unix_fd = bind_to_unix_socket (display);
 | 
			
		||||
      if (manager->unix_fd < 0)
 | 
			
		||||
        {
 | 
			
		||||
          unlink (lock_file);
 | 
			
		||||
          close (manager->abstract_fd);
 | 
			
		||||
          display++;
 | 
			
		||||
          continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  while (1);
 | 
			
		||||
 | 
			
		||||
  manager->display_index = display;
 | 
			
		||||
  manager->display_name = g_strdup_printf (":%d", manager->display_index);
 | 
			
		||||
  manager->lock_file = lock_file;
 | 
			
		||||
  connection->display_index = display;
 | 
			
		||||
  connection->name = g_strdup_printf (":%d", connection->display_index);
 | 
			
		||||
  connection->lock_file = lock_file;
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
@@ -536,6 +582,7 @@ on_displayfd_ready (int          fd,
 | 
			
		||||
                    gpointer     user_data)
 | 
			
		||||
{
 | 
			
		||||
  MetaXWaylandManager *manager = user_data;
 | 
			
		||||
  MetaDisplay *display = meta_get_display ();
 | 
			
		||||
 | 
			
		||||
  /* The server writes its display name to the displayfd
 | 
			
		||||
   * socket when it's ready. We don't care about the data
 | 
			
		||||
@@ -543,11 +590,17 @@ on_displayfd_ready (int          fd,
 | 
			
		||||
   * that means it's ready. */
 | 
			
		||||
  xserver_finished_init (manager);
 | 
			
		||||
 | 
			
		||||
  g_signal_emit_by_name (display, "init-xserver",
 | 
			
		||||
                         manager->private_connection.display_index);
 | 
			
		||||
 | 
			
		||||
  if (meta_get_x11_display_policy () == META_DISPLAY_POLICY_ON_DEMAND)
 | 
			
		||||
    meta_display_init_x11 (display, NULL);
 | 
			
		||||
 | 
			
		||||
  return G_SOURCE_REMOVE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
meta_xwayland_init_xserver (MetaXWaylandManager *manager)
 | 
			
		||||
meta_xwayland_start_xserver (MetaXWaylandManager *manager)
 | 
			
		||||
{
 | 
			
		||||
  int xwayland_client_fd[2];
 | 
			
		||||
  int displayfd[2];
 | 
			
		||||
@@ -581,14 +634,15 @@ meta_xwayland_init_xserver (MetaXWaylandManager *manager)
 | 
			
		||||
  launcher = g_subprocess_launcher_new (flags);
 | 
			
		||||
 | 
			
		||||
  g_subprocess_launcher_take_fd (launcher, xwayland_client_fd[1], 3);
 | 
			
		||||
  g_subprocess_launcher_take_fd (launcher, manager->abstract_fd, 4);
 | 
			
		||||
  g_subprocess_launcher_take_fd (launcher, manager->unix_fd, 5);
 | 
			
		||||
  g_subprocess_launcher_take_fd (launcher, manager->public_connection.abstract_fd, 4);
 | 
			
		||||
  g_subprocess_launcher_take_fd (launcher, manager->public_connection.unix_fd, 5);
 | 
			
		||||
  g_subprocess_launcher_take_fd (launcher, displayfd[1], 6);
 | 
			
		||||
  g_subprocess_launcher_take_fd (launcher, manager->private_connection.abstract_fd, 7);
 | 
			
		||||
 | 
			
		||||
  g_subprocess_launcher_setenv (launcher, "WAYLAND_SOCKET", "3", TRUE);
 | 
			
		||||
 | 
			
		||||
  manager->proc = g_subprocess_launcher_spawn (launcher, &error,
 | 
			
		||||
                                               XWAYLAND_PATH, manager->display_name,
 | 
			
		||||
                                               XWAYLAND_PATH, manager->public_connection.name,
 | 
			
		||||
                                               "-rootless",
 | 
			
		||||
                                               "-noreset",
 | 
			
		||||
                                               "-accessx",
 | 
			
		||||
@@ -597,6 +651,7 @@ meta_xwayland_init_xserver (MetaXWaylandManager *manager)
 | 
			
		||||
                                               "-listen", "4",
 | 
			
		||||
                                               "-listen", "5",
 | 
			
		||||
                                               "-displayfd", "6",
 | 
			
		||||
                                               "-initfd", "7",
 | 
			
		||||
                                               NULL);
 | 
			
		||||
  if (!manager->proc)
 | 
			
		||||
    {
 | 
			
		||||
@@ -620,30 +675,133 @@ meta_xwayland_init_xserver (MetaXWaylandManager *manager)
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_xwayland_start (MetaXWaylandManager *manager,
 | 
			
		||||
                     struct wl_display   *wl_display)
 | 
			
		||||
static gboolean
 | 
			
		||||
xdisplay_connection_activity_cb (gint         fd,
 | 
			
		||||
                                 GIOCondition cond,
 | 
			
		||||
                                 gpointer     user_data)
 | 
			
		||||
{
 | 
			
		||||
  if (!choose_xdisplay (manager))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
  MetaXWaylandManager *manager = user_data;
 | 
			
		||||
 | 
			
		||||
  if (!meta_xwayland_start_xserver (manager))
 | 
			
		||||
    g_critical ("Could not start Xserver");
 | 
			
		||||
 | 
			
		||||
  return G_SOURCE_REMOVE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
window_unmanaged_cb (MetaWindow          *window,
 | 
			
		||||
                     MetaXWaylandManager *manager)
 | 
			
		||||
{
 | 
			
		||||
  manager->x11_windows = g_list_remove (manager->x11_windows, window);
 | 
			
		||||
  g_signal_handlers_disconnect_by_func (window,
 | 
			
		||||
                                        window_unmanaged_cb,
 | 
			
		||||
                                        manager);
 | 
			
		||||
  if (!manager->x11_windows)
 | 
			
		||||
    {
 | 
			
		||||
      g_debug ("All X11 windows gone, setting shutdown timeout");
 | 
			
		||||
      manager->xserver_grace_period_id =
 | 
			
		||||
        g_timeout_add_seconds (10, shutdown_xwayland_cb, manager);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
window_created_cb (MetaDisplay         *display,
 | 
			
		||||
                   MetaWindow          *window,
 | 
			
		||||
                   MetaXWaylandManager *manager)
 | 
			
		||||
{
 | 
			
		||||
  if (window->xwindow &&
 | 
			
		||||
      meta_window_get_client_pid (window) != getpid ())
 | 
			
		||||
    {
 | 
			
		||||
      manager->x11_windows = g_list_prepend (manager->x11_windows, window);
 | 
			
		||||
      g_signal_connect (window, "unmanaged",
 | 
			
		||||
                        G_CALLBACK (window_unmanaged_cb), manager);
 | 
			
		||||
      if (manager->xserver_grace_period_id)
 | 
			
		||||
        {
 | 
			
		||||
          g_source_remove (manager->xserver_grace_period_id);
 | 
			
		||||
          manager->xserver_grace_period_id = 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_xwayland_stop_xserver (MetaXWaylandManager *manager)
 | 
			
		||||
{
 | 
			
		||||
  if (manager->proc)
 | 
			
		||||
    g_subprocess_send_signal (manager->proc, SIGTERM);
 | 
			
		||||
  g_signal_handlers_disconnect_by_func (meta_get_display (),
 | 
			
		||||
                                        window_created_cb,
 | 
			
		||||
                                        manager);
 | 
			
		||||
  g_clear_object (&manager->xserver_died_cancellable);
 | 
			
		||||
  g_clear_object (&manager->proc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_xwayland_init (MetaXWaylandManager *manager,
 | 
			
		||||
                    struct wl_display   *wl_display)
 | 
			
		||||
{
 | 
			
		||||
  MetaDisplayPolicy policy;
 | 
			
		||||
  gboolean fatal;
 | 
			
		||||
 | 
			
		||||
  if (!manager->public_connection.name)
 | 
			
		||||
    {
 | 
			
		||||
      if (!choose_xdisplay (manager, &manager->public_connection))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
      if (!choose_xdisplay (manager, &manager->private_connection))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      if (!open_display_sockets (manager,
 | 
			
		||||
                                 manager->public_connection.display_index,
 | 
			
		||||
                                 &manager->public_connection.abstract_fd,
 | 
			
		||||
                                 &manager->public_connection.unix_fd,
 | 
			
		||||
                                 &fatal))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
 | 
			
		||||
      if (!open_display_sockets (manager,
 | 
			
		||||
                                 manager->private_connection.display_index,
 | 
			
		||||
                                 &manager->private_connection.abstract_fd,
 | 
			
		||||
                                 &manager->private_connection.unix_fd,
 | 
			
		||||
                                 &fatal))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (!prepare_auth_file (manager))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  manager->wayland_display = wl_display;
 | 
			
		||||
  return meta_xwayland_init_xserver (manager);
 | 
			
		||||
  policy = meta_get_x11_display_policy ();
 | 
			
		||||
 | 
			
		||||
  if (policy == META_DISPLAY_POLICY_MANDATORY)
 | 
			
		||||
    {
 | 
			
		||||
      return meta_xwayland_start_xserver (manager);
 | 
			
		||||
    }
 | 
			
		||||
  else if (policy == META_DISPLAY_POLICY_ON_DEMAND)
 | 
			
		||||
    {
 | 
			
		||||
      g_unix_fd_add (manager->public_connection.abstract_fd, G_IO_IN,
 | 
			
		||||
                     xdisplay_connection_activity_cb, manager);
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_x11_display_closing (MetaDisplay *display)
 | 
			
		||||
{
 | 
			
		||||
  meta_xwayland_shutdown_dnd ();
 | 
			
		||||
  g_signal_handlers_disconnect_by_func (display,
 | 
			
		||||
                                        on_x11_display_closing,
 | 
			
		||||
                                        NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* To be called right after connecting */
 | 
			
		||||
void
 | 
			
		||||
meta_xwayland_complete_init (MetaDisplay *display)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
 | 
			
		||||
  MetaXWaylandManager *manager = &compositor->xwayland_manager;
 | 
			
		||||
 | 
			
		||||
  /* We install an X IO error handler in addition to the child watch,
 | 
			
		||||
     because after Xlib connects our child watch may not be called soon
 | 
			
		||||
     enough, and therefore we won't crash when X exits (and most important
 | 
			
		||||
@@ -654,31 +812,41 @@ meta_xwayland_complete_init (MetaDisplay *display)
 | 
			
		||||
  g_signal_connect (display, "x11-display-closing",
 | 
			
		||||
                    G_CALLBACK (on_x11_display_closing), NULL);
 | 
			
		||||
  meta_xwayland_init_dnd ();
 | 
			
		||||
 | 
			
		||||
  g_signal_connect (meta_get_display (), "window-created",
 | 
			
		||||
                    G_CALLBACK (window_created_cb), manager);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_xwayland_stop (MetaXWaylandManager *manager)
 | 
			
		||||
meta_xwayland_shutdown (MetaXWaylandManager *manager)
 | 
			
		||||
{
 | 
			
		||||
  char path[256];
 | 
			
		||||
 | 
			
		||||
  g_cancellable_cancel (manager->xserver_died_cancellable);
 | 
			
		||||
  g_clear_object (&manager->proc);
 | 
			
		||||
  g_clear_object (&manager->xserver_died_cancellable);
 | 
			
		||||
 | 
			
		||||
  snprintf (path, sizeof path, "/tmp/.X11-unix/X%d", manager->display_index);
 | 
			
		||||
  snprintf (path, sizeof path, "/tmp/.X11-unix/X%d", manager->public_connection.display_index);
 | 
			
		||||
  unlink (path);
 | 
			
		||||
 | 
			
		||||
  g_clear_pointer (&manager->display_name, g_free);
 | 
			
		||||
  snprintf (path, sizeof path, "/tmp/.X11-unix/X%d", manager->private_connection.display_index);
 | 
			
		||||
  unlink (path);
 | 
			
		||||
 | 
			
		||||
  g_clear_pointer (&manager->public_connection.name, g_free);
 | 
			
		||||
  g_clear_pointer (&manager->private_connection.name, g_free);
 | 
			
		||||
  if (manager->public_connection.lock_file)
 | 
			
		||||
    {
 | 
			
		||||
      unlink (manager->public_connection.lock_file);
 | 
			
		||||
      g_clear_pointer (&manager->public_connection.lock_file, g_free);
 | 
			
		||||
    }
 | 
			
		||||
  if (manager->private_connection.lock_file)
 | 
			
		||||
    {
 | 
			
		||||
      unlink (manager->private_connection.lock_file);
 | 
			
		||||
      g_clear_pointer (&manager->private_connection.lock_file, g_free);
 | 
			
		||||
    }
 | 
			
		||||
  if (manager->auth_file)
 | 
			
		||||
    {
 | 
			
		||||
      unlink (manager->auth_file);
 | 
			
		||||
      g_clear_pointer (&manager->auth_file, g_free);
 | 
			
		||||
    }
 | 
			
		||||
  if (manager->lock_file)
 | 
			
		||||
    {
 | 
			
		||||
      unlink (manager->lock_file);
 | 
			
		||||
      g_clear_pointer (&manager->lock_file, g_free);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
 
 | 
			
		||||
@@ -144,6 +144,8 @@ struct _MetaX11Display
 | 
			
		||||
 | 
			
		||||
  guint keys_grabbed : 1;
 | 
			
		||||
 | 
			
		||||
  guint closing : 1;
 | 
			
		||||
 | 
			
		||||
  /* we use property updates as sentinels for certain window focus events
 | 
			
		||||
   * to avoid some race conditions on EnterNotify events
 | 
			
		||||
   */
 | 
			
		||||
@@ -249,4 +251,6 @@ void meta_x11_display_set_input_focus (MetaX11Display *x11_display,
 | 
			
		||||
                                       Window          xwindow,
 | 
			
		||||
                                       guint32         timestamp);
 | 
			
		||||
 | 
			
		||||
const gchar * meta_x11_get_display_name (void);
 | 
			
		||||
 | 
			
		||||
#endif /* META_X11_DISPLAY_PRIVATE_H */
 | 
			
		||||
 
 | 
			
		||||
@@ -129,17 +129,19 @@ meta_x11_display_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  MetaX11Display *x11_display = META_X11_DISPLAY (object);
 | 
			
		||||
 | 
			
		||||
  x11_display->closing = TRUE;
 | 
			
		||||
 | 
			
		||||
  meta_x11_startup_notification_release (x11_display);
 | 
			
		||||
 | 
			
		||||
  meta_prefs_remove_listener (prefs_changed_callback, x11_display);
 | 
			
		||||
 | 
			
		||||
  meta_x11_display_ungrab_keys (x11_display);
 | 
			
		||||
 | 
			
		||||
  g_clear_object (&x11_display->x11_stack);
 | 
			
		||||
 | 
			
		||||
  meta_x11_selection_shutdown (x11_display);
 | 
			
		||||
  meta_x11_display_unmanage_windows (x11_display);
 | 
			
		||||
 | 
			
		||||
  g_clear_object (&x11_display->x11_stack);
 | 
			
		||||
 | 
			
		||||
  if (x11_display->ui)
 | 
			
		||||
    {
 | 
			
		||||
      meta_ui_free (x11_display->ui);
 | 
			
		||||
@@ -182,21 +184,8 @@ meta_x11_display_dispose (GObject *object)
 | 
			
		||||
 | 
			
		||||
  if (x11_display->guard_window != None)
 | 
			
		||||
    {
 | 
			
		||||
      MetaStackTracker *stack_tracker = x11_display->display->stack_tracker;
 | 
			
		||||
 | 
			
		||||
      if (stack_tracker)
 | 
			
		||||
        {
 | 
			
		||||
          unsigned long serial;
 | 
			
		||||
 | 
			
		||||
          serial = XNextRequest (x11_display->xdisplay);
 | 
			
		||||
          meta_stack_tracker_record_remove (stack_tracker,
 | 
			
		||||
                                            x11_display->guard_window,
 | 
			
		||||
                                            serial);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      XUnmapWindow (x11_display->xdisplay, x11_display->guard_window);
 | 
			
		||||
      XDestroyWindow (x11_display->xdisplay, x11_display->guard_window);
 | 
			
		||||
 | 
			
		||||
      x11_display->guard_window = None;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -988,6 +977,25 @@ meta_set_gnome_wm_keybindings (const char *wm_keybindings)
 | 
			
		||||
  gnome_wm_keybindings = wm_keybindings;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const gchar *
 | 
			
		||||
meta_x11_get_display_name (void)
 | 
			
		||||
{
 | 
			
		||||
#ifdef HAVE_WAYLAND
 | 
			
		||||
  if (meta_is_wayland_compositor ())
 | 
			
		||||
    {
 | 
			
		||||
      MetaWaylandCompositor *compositor;
 | 
			
		||||
 | 
			
		||||
      compositor = meta_wayland_compositor_get_default ();
 | 
			
		||||
 | 
			
		||||
      return meta_wayland_get_xwayland_display_name (compositor);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
      return g_getenv ("DISPLAY");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_x11_init_gdk_display (GError **error)
 | 
			
		||||
{
 | 
			
		||||
@@ -996,7 +1004,7 @@ meta_x11_init_gdk_display (GError **error)
 | 
			
		||||
  const char *gdk_gl_env = NULL;
 | 
			
		||||
  Display *xdisplay;
 | 
			
		||||
 | 
			
		||||
  xdisplay_name = g_getenv ("DISPLAY");
 | 
			
		||||
  xdisplay_name = meta_x11_get_display_name ();
 | 
			
		||||
  if (!xdisplay_name)
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user