Blame SOURCES/support-headless-mode.patch

db633a
From 0826616da1dacf29e3e08dae6d2ffe4116e5bdff Mon Sep 17 00:00:00 2001
db633a
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
db633a
Date: Thu, 16 Jul 2015 15:07:38 +0200
db633a
Subject: [PATCH 1/2] barrier: Guard against X errors
db633a
db633a
---
db633a
 src/backends/x11/meta-barrier-x11.c | 22 +++++++++++++++-------
db633a
 1 file changed, 15 insertions(+), 7 deletions(-)
db633a
db633a
diff --git a/src/backends/x11/meta-barrier-x11.c b/src/backends/x11/meta-barrier-x11.c
db633a
index 054e5cdc6..1fc3fd8cc 100644
db633a
--- a/src/backends/x11/meta-barrier-x11.c
db633a
+++ b/src/backends/x11/meta-barrier-x11.c
db633a
@@ -38,6 +38,7 @@
db633a
 #include <X11/extensions/XInput2.h>
db633a
 #include <X11/extensions/Xfixes.h>
db633a
 #include <meta/barrier.h>
db633a
+#include <meta/errors.h>
db633a
 #include "backends/x11/meta-barrier-x11.h"
db633a
 #include "display-private.h"
db633a
 
db633a
@@ -107,6 +108,7 @@ meta_barrier_impl_x11_new (MetaBarrier *barrier)
db633a
   MetaDisplay *display = barrier->priv->display;
db633a
   Display *dpy;
db633a
   Window root;
db633a
+  PointerBarrier xbarrier;
db633a
   unsigned int allowed_motion_dirs;
db633a
 
db633a
   if (display == NULL)
db633a
@@ -119,18 +121,24 @@ meta_barrier_impl_x11_new (MetaBarrier *barrier)
db633a
   priv = meta_barrier_impl_x11_get_instance_private (self);
db633a
   priv->barrier = barrier;
db633a
 
db633a
+  meta_error_trap_push (display);
db633a
   dpy = display->xdisplay;
db633a
   root = DefaultRootWindow (dpy);
db633a
 
db633a
   allowed_motion_dirs =
db633a
     meta_border_get_allows_directions (&barrier->priv->border);
db633a
-  priv->xbarrier = XFixesCreatePointerBarrier (dpy, root,
db633a
-                                               barrier->priv->border.line.a.x,
db633a
-                                               barrier->priv->border.line.a.y,
db633a
-                                               barrier->priv->border.line.b.x,
db633a
-                                               barrier->priv->border.line.b.y,
db633a
-                                               allowed_motion_dirs,
db633a
-                                               0, NULL);
db633a
+  xbarrier = XFixesCreatePointerBarrier (dpy, root,
db633a
+                                         barrier->priv->border.line.a.x,
db633a
+                                         barrier->priv->border.line.a.y,
db633a
+                                         barrier->priv->border.line.b.x,
db633a
+                                         barrier->priv->border.line.b.y,
db633a
+                                         allowed_motion_dirs,
db633a
+                                         0, NULL);
db633a
+
db633a
+  if (meta_error_trap_pop_with_return (display) != Success)
db633a
+    return NULL;
db633a
+
db633a
+  priv->xbarrier = xbarrier;
db633a
 
db633a
   g_hash_table_insert (display->xids, &priv->xbarrier, barrier);
db633a
 
db633a
-- 
db633a
2.12.0
db633a
db633a
db633a
From 2da829399dc79b5c51ca55ab6e633c4a4769c15a Mon Sep 17 00:00:00 2001
db633a
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
db633a
Date: Thu, 16 Jul 2015 15:12:55 +0200
db633a
Subject: [PATCH 2/2] Do not crash when starting up with no monitor connected
db633a
db633a
Some parts of Mutter currently assume there's always a monitor connected
db633a
to the screen. This assumption can be incorrect - e.g. a desktop
db633a
computer can be powered on and a monitor only plugged in after the
db633a
desktop session - or the GDM login - has already been reached.
db633a
db633a
Fix the various places that assume so, making the code robust to the
db633a
above use case.
db633a
db633a
Based on an initial patch by Cosimo Cecchi.
db633a
---
db633a
 src/backends/x11/meta-monitor-manager-xrandr.c |  4 +-
db633a
 src/compositor/meta-window-actor.c             |  2 +-
db633a
 src/core/constraints.c                         | 71 +++++++++++++++-----------
db633a
 src/core/place.c                               |  4 ++
db633a
 src/core/screen.c                              | 10 +++-
db633a
 src/core/window.c                              | 57 ++++++++++++++-------
db633a
 src/core/workspace.c                           |  3 ++
db633a
 src/x11/window-x11.c                           |  3 +-
db633a
 8 files changed, 100 insertions(+), 54 deletions(-)
db633a
db633a
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
db633a
index b0a77dadb..b82120af9 100644
db633a
--- a/src/backends/x11/meta-monitor-manager-xrandr.c
db633a
+++ b/src/backends/x11/meta-monitor-manager-xrandr.c
db633a
@@ -1141,7 +1141,9 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
db633a
       crtc->current_mode = NULL;
db633a
     }
db633a
 
db633a
-  g_assert (width > 0 && height > 0);
db633a
+  if (width == 0 || height == 0)
db633a
+    return;
db633a
+
db633a
   /* The 'physical size' of an X screen is meaningless if that screen
db633a
    * can consist of many monitors. So just pick a size that make the
db633a
    * dpi 96.
db633a
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
db633a
index 9395caac5..fb29ca1c9 100644
db633a
--- a/src/compositor/meta-window-actor.c
db633a
+++ b/src/compositor/meta-window-actor.c
db633a
@@ -959,7 +959,7 @@ queue_send_frame_messages_timeout (MetaWindowActor *self)
db633a
   outputs = meta_monitor_manager_get_outputs (monitor_manager, &n_outputs);
db633a
   for (i = 0; i < n_outputs; i++)
db633a
     {
db633a
-      if (outputs[i].winsys_id == window->monitor->winsys_id && outputs[i].crtc)
db633a
+      if (window->monitor && outputs[i].winsys_id == window->monitor->winsys_id && outputs[i].crtc)
db633a
         {
db633a
           refresh_rate = outputs[i].crtc->current_mode->refresh_rate;
db633a
           break;
db633a
diff --git a/src/core/constraints.c b/src/core/constraints.c
db633a
index 67b52c994..3d1701e88 100644
db633a
--- a/src/core/constraints.c
db633a
+++ b/src/core/constraints.c
db633a
@@ -29,6 +29,7 @@
db633a
 #include <meta/prefs.h>
db633a
 
db633a
 #include <stdlib.h>
db633a
+#include <string.h>
db633a
 #include <math.h>
db633a
 
db633a
 #if 0
db633a
@@ -337,6 +338,8 @@ setup_constraint_info (ConstraintInfo      *info,
db633a
   const MetaMonitorInfo *monitor_info;
db633a
   MetaWorkspace *cur_workspace;
db633a
 
db633a
+  memset (info, 0, sizeof (ConstraintInfo));
db633a
+
db633a
   info->orig    = *orig;
db633a
   info->current = *new;
db633a
 
db633a
@@ -382,40 +385,43 @@ setup_constraint_info (ConstraintInfo      *info,
db633a
   if (!info->is_user_action)
db633a
     info->fixed_directions = FIXED_DIRECTION_NONE;
db633a
 
db633a
+  cur_workspace = window->screen->active_workspace;
db633a
   monitor_info =
db633a
     meta_screen_get_monitor_for_rect (window->screen, &info->current);
db633a
-  meta_window_get_work_area_for_monitor (window,
db633a
-                                         monitor_info->number,
db633a
-                                         &info->work_area_monitor);
db633a
 
db633a
-  if (!window->fullscreen || window->fullscreen_monitors[0] == -1)
db633a
+  if (monitor_info)
db633a
     {
db633a
-      info->entire_monitor = monitor_info->rect;
db633a
-    }
db633a
-  else
db633a
-    {
db633a
-      int i = 0;
db633a
-      long monitor;
db633a
+      meta_window_get_work_area_for_monitor (window,
db633a
+                                             monitor_info->number,
db633a
+                                             &info->work_area_monitor);
db633a
 
db633a
-      monitor = window->fullscreen_monitors[i];
db633a
-      info->entire_monitor =
db633a
-        window->screen->monitor_infos[monitor].rect;
db633a
-      for (i = 1; i <= 3; i++)
db633a
+      if (!window->fullscreen || window->fullscreen_monitors[0] == -1)
db633a
+        {
db633a
+          info->entire_monitor = monitor_info->rect;
db633a
+        }
db633a
+      else
db633a
         {
db633a
+          int i = 0;
db633a
+          long monitor;
db633a
+
db633a
           monitor = window->fullscreen_monitors[i];
db633a
-          meta_rectangle_union (&info->entire_monitor,
db633a
-                                &window->screen->monitor_infos[monitor].rect,
db633a
-                                &info->entire_monitor);
db633a
+          info->entire_monitor =
db633a
+            window->screen->monitor_infos[monitor].rect;
db633a
+          for (i = 1; i <= 3; i++)
db633a
+            {
db633a
+              monitor = window->fullscreen_monitors[i];
db633a
+              meta_rectangle_union (&info->entire_monitor,
db633a
+                                    &window->screen->monitor_infos[monitor].rect,
db633a
+                                    &info->entire_monitor);
db633a
+            }
db633a
         }
db633a
+      info->usable_screen_region  =
db633a
+        meta_workspace_get_onscreen_region (cur_workspace);
db633a
+      info->usable_monitor_region =
db633a
+        meta_workspace_get_onmonitor_region (cur_workspace,
db633a
+                                             monitor_info->number);
db633a
     }
db633a
 
db633a
-  cur_workspace = window->screen->active_workspace;
db633a
-  info->usable_screen_region   =
db633a
-    meta_workspace_get_onscreen_region (cur_workspace);
db633a
-  info->usable_monitor_region =
db633a
-    meta_workspace_get_onmonitor_region (cur_workspace,
db633a
-                                         monitor_info->number);
db633a
-
db633a
   /* Log all this information for debugging */
db633a
   meta_topic (META_DEBUG_GEOMETRY,
db633a
               "Setting up constraint info:\n"
db633a
@@ -489,14 +495,17 @@ place_window_if_needed(MetaWindow     *window,
db633a
        */
db633a
       monitor_info =
db633a
         meta_screen_get_monitor_for_rect (window->screen, &placed_rect);
db633a
-      info->entire_monitor = monitor_info->rect;
db633a
-      meta_window_get_work_area_for_monitor (window,
db633a
-                                             monitor_info->number,
db633a
-                                             &info->work_area_monitor);
db633a
       cur_workspace = window->screen->active_workspace;
db633a
-      info->usable_monitor_region =
db633a
-        meta_workspace_get_onmonitor_region (cur_workspace,
db633a
-                                             monitor_info->number);
db633a
+      if (monitor_info)
db633a
+        {
db633a
+          info->entire_monitor = monitor_info->rect;
db633a
+          meta_window_get_work_area_for_monitor (window,
db633a
+                                                 monitor_info->number,
db633a
+                                                 &info->work_area_monitor);
db633a
+          info->usable_monitor_region =
db633a
+            meta_workspace_get_onmonitor_region (cur_workspace,
db633a
+                                                 monitor_info->number);
db633a
+        }
db633a
 
db633a
       info->current.x = placed_rect.x;
db633a
       info->current.y = placed_rect.y;
db633a
diff --git a/src/core/place.c b/src/core/place.c
db633a
index db71b83ce..0f046f046 100644
db633a
--- a/src/core/place.c
db633a
+++ b/src/core/place.c
db633a
@@ -811,6 +811,8 @@ meta_window_place (MetaWindow        *window,
db633a
 
db633a
       /* Warning, this function is a round trip! */
db633a
       xi = meta_screen_get_current_monitor_info (window->screen);
db633a
+      if (!xi)
db633a
+        goto done;
db633a
 
db633a
       w = xi->rect.width;
db633a
       h = xi->rect.height;
db633a
@@ -856,6 +858,8 @@ meta_window_place (MetaWindow        *window,
db633a
 
db633a
   /* Warning, this is a round trip! */
db633a
   xi = meta_screen_get_current_monitor_info (window->screen);
db633a
+  if (!xi)
db633a
+    goto done;
db633a
 
db633a
   /* Maximize windows if they are too big for their work area (bit of
db633a
    * a hack here). Assume undecorated windows probably don't intend to
db633a
diff --git a/src/core/screen.c b/src/core/screen.c
db633a
index b8ac22f76..54a0b0aba 100644
db633a
--- a/src/core/screen.c
db633a
+++ b/src/core/screen.c
db633a
@@ -381,7 +381,10 @@ meta_screen_monitor_index_to_xinerama_index (MetaScreen *screen,
db633a
 
db633a
   meta_screen_ensure_xinerama_indices (screen);
db633a
 
db633a
-  return screen->monitor_infos[index].xinerama_index;
db633a
+  if (index >= 0 && index < screen->n_monitor_infos)
db633a
+    return screen->monitor_infos[index].xinerama_index;
db633a
+
db633a
+  return -1;
db633a
 }
db633a
 
db633a
 int
db633a
@@ -1395,6 +1398,9 @@ meta_screen_get_monitor_for_rect (MetaScreen    *screen,
db633a
   int i;
db633a
   int best_monitor, monitor_score, rect_area;
db633a
 
db633a
+  if (screen->n_monitor_infos == 0)
db633a
+    return NULL;
db633a
+
db633a
   if (screen->n_monitor_infos == 1)
db633a
     return &screen->monitor_infos[0];
db633a
 
db633a
@@ -1448,7 +1454,7 @@ meta_screen_get_monitor_index_for_rect (MetaScreen    *screen,
db633a
                                         MetaRectangle *rect)
db633a
 {
db633a
   const MetaMonitorInfo *monitor = meta_screen_get_monitor_for_rect (screen, rect);
db633a
-  return monitor->number;
db633a
+  return monitor ? monitor->number : -1;
db633a
 }
db633a
 
db633a
 const MetaMonitorInfo *
db633a
diff --git a/src/core/window.c b/src/core/window.c
db633a
index e3e15cf26..9745b42e0 100644
db633a
--- a/src/core/window.c
db633a
+++ b/src/core/window.c
db633a
@@ -1029,7 +1029,8 @@ _meta_window_shared_new (MetaDisplay         *display,
db633a
 
db633a
   window->monitor = meta_screen_calculate_monitor_for_window (window->screen,
db633a
                                                               window);
db633a
-  window->preferred_output_winsys_id = window->monitor->winsys_id;
db633a
+  window->preferred_output_winsys_id = window->monitor ? window->monitor->winsys_id
db633a
+                                                       : -1;
db633a
 
db633a
   window->tile_match = NULL;
db633a
 
db633a
@@ -2280,7 +2281,10 @@ meta_window_show (MetaWindow *window)
db633a
       if (meta_prefs_get_auto_maximize() && window->showing_for_first_time && window->has_maximize_func)
db633a
         {
db633a
           MetaRectangle work_area;
db633a
-          meta_window_get_work_area_for_monitor (window, window->monitor->number, &work_area);
db633a
+          if (window->monitor)
db633a
+            meta_window_get_work_area_for_monitor (window, window->monitor->number, &work_area);
db633a
+          else
db633a
+            meta_window_get_work_area_current_monitor (window, &work_area);
db633a
           /* Automaximize windows that map with a size > MAX_UNMAXIMIZED_WINDOW_AREA of the work area */
db633a
           if (window->rect.width * window->rect.height > work_area.width * work_area.height * MAX_UNMAXIMIZED_WINDOW_AREA)
db633a
             {
db633a
@@ -2677,7 +2681,7 @@ meta_window_maximize_internal (MetaWindow        *window,
db633a
   meta_window_recalc_features (window);
db633a
   set_net_wm_state (window);
db633a
 
db633a
-  if (window->monitor->in_fullscreen)
db633a
+  if (window->monitor && window->monitor->in_fullscreen)
db633a
     meta_screen_queue_check_fullscreen (window->screen);
db633a
 
db633a
   g_object_freeze_notify (G_OBJECT (window));
db633a
@@ -2863,6 +2867,9 @@ meta_window_is_monitor_sized (MetaWindow *window)
db633a
   if (meta_window_is_screen_sized (window))
db633a
     return TRUE;
db633a
 
db633a
+  if (!window->monitor)
db633a
+    return FALSE;
db633a
+
db633a
   if (window->override_redirect)
db633a
     {
db633a
       MetaRectangle window_rect, monitor_rect;
db633a
@@ -2886,7 +2893,7 @@ meta_window_is_monitor_sized (MetaWindow *window)
db633a
 gboolean
db633a
 meta_window_is_on_primary_monitor (MetaWindow *window)
db633a
 {
db633a
-  return window->monitor->is_primary;
db633a
+  return window->monitor ? window->monitor->is_primary : FALSE;
db633a
 }
db633a
 
db633a
 /**
db633a
@@ -3027,7 +3034,10 @@ meta_window_unmaximize (MetaWindow        *window,
db633a
       MetaRectangle work_area;
db633a
       MetaRectangle old_frame_rect, old_buffer_rect;
db633a
 
db633a
-      meta_window_get_work_area_for_monitor (window, window->monitor->number, &work_area);
db633a
+      if (window->monitor)
db633a
+        meta_window_get_work_area_for_monitor (window, window->monitor->number, &work_area);
db633a
+      else
db633a
+        meta_window_get_work_area_current_monitor (window, &work_area);
db633a
       meta_window_get_frame_rect (window, &old_frame_rect);
db633a
       meta_window_get_buffer_rect (window, &old_buffer_rect);
db633a
 
db633a
@@ -3123,7 +3133,7 @@ meta_window_unmaximize (MetaWindow        *window,
db633a
 
db633a
       meta_window_recalc_features (window);
db633a
       set_net_wm_state (window);
db633a
-      if (!window->monitor->in_fullscreen)
db633a
+      if (window->monitor && !window->monitor->in_fullscreen)
db633a
         meta_screen_queue_check_fullscreen (window->screen);
db633a
     }
db633a
 
db633a
@@ -3522,7 +3532,7 @@ maybe_move_attached_dialog (MetaWindow *window,
db633a
 int
db633a
 meta_window_get_monitor (MetaWindow *window)
db633a
 {
db633a
-  return window->monitor->number;
db633a
+  return window->monitor ? window->monitor->number : -1;
db633a
 }
db633a
 
db633a
 static MetaMonitorInfo *
db633a
@@ -3549,14 +3559,15 @@ meta_window_update_for_monitors_changed (MetaWindow *window)
db633a
 {
db633a
   const MetaMonitorInfo *old, *new;
db633a
 
db633a
-  if (window->override_redirect || window->type == META_WINDOW_DESKTOP)
db633a
+  old = window->monitor;
db633a
+
db633a
+  if (!old || window->screen->n_monitor_infos == 0 ||
db633a
+      window->override_redirect || window->type == META_WINDOW_DESKTOP)
db633a
     {
db633a
       meta_window_update_monitor (window, FALSE);
db633a
       return;
db633a
     }
db633a
 
db633a
-  old = window->monitor;
db633a
-
db633a
   /* Try the preferred output first */
db633a
   new = find_monitor_by_winsys_id (window, window->preferred_output_winsys_id);
db633a
 
db633a
@@ -3643,7 +3654,7 @@ meta_window_move_resize_internal (MetaWindow          *window,
db633a
    */
db633a
 
db633a
   gboolean did_placement;
db633a
-  guint old_output_winsys_id;
db633a
+  guint old_output_winsys_id, new_output_winsys_id;
db633a
   MetaRectangle unconstrained_rect;
db633a
   MetaRectangle constrained_rect;
db633a
   MetaMoveResizeResultFlags result = 0;
db633a
@@ -3737,13 +3748,15 @@ meta_window_move_resize_internal (MetaWindow          *window,
db633a
                                               did_placement);
db633a
     }
db633a
 
db633a
-  old_output_winsys_id = window->monitor->winsys_id;
db633a
+  old_output_winsys_id = window->monitor ? window->monitor->winsys_id : -1;
db633a
 
db633a
   meta_window_update_monitor (window, flags & META_MOVE_RESIZE_USER_ACTION);
db633a
 
db633a
-  if (old_output_winsys_id != window->monitor->winsys_id &&
db633a
+  new_output_winsys_id = window->monitor ? window->monitor->winsys_id : -1;
db633a
+
db633a
+  if (old_output_winsys_id != new_output_winsys_id &&
db633a
       flags & META_MOVE_RESIZE_MOVE_ACTION && flags & META_MOVE_RESIZE_USER_ACTION)
db633a
-    window->preferred_output_winsys_id = window->monitor->winsys_id;
db633a
+    window->preferred_output_winsys_id = new_output_winsys_id;
db633a
 
db633a
   if ((result & META_MOVE_RESIZE_RESULT_FRAME_SHAPE_CHANGED) && window->frame_bounds)
db633a
     {
db633a
@@ -3849,7 +3862,7 @@ meta_window_move_to_monitor (MetaWindow  *window,
db633a
 {
db633a
   MetaRectangle old_area, new_area;
db633a
 
db633a
-  if (monitor == window->monitor->number)
db633a
+  if (!window->monitor || monitor == window->monitor->number)
db633a
     return;
db633a
 
db633a
   meta_window_get_work_area_for_monitor (window,
db633a
@@ -6104,9 +6117,17 @@ void
db633a
 meta_window_get_work_area_current_monitor (MetaWindow    *window,
db633a
                                            MetaRectangle *area)
db633a
 {
db633a
-  meta_window_get_work_area_for_monitor (window,
db633a
-                                         window->monitor->number,
db633a
-                                         area);
db633a
+  if (window->monitor)
db633a
+    {
db633a
+      meta_window_get_work_area_for_monitor (window,
db633a
+                                             window->monitor->number,
db633a
+                                             area);
db633a
+    }
db633a
+  else if (area)
db633a
+    {
db633a
+      MetaRectangle empty = { 0, 0, 0, 0 };
db633a
+      *area = empty;
db633a
+    }
db633a
 }
db633a
 
db633a
 /**
db633a
diff --git a/src/core/workspace.c b/src/core/workspace.c
db633a
index cfac7dc48..a73ac6bb7 100644
db633a
--- a/src/core/workspace.c
db633a
+++ b/src/core/workspace.c
db633a
@@ -765,6 +765,9 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
db633a
   g_assert (workspace->screen_edges == NULL);
db633a
   g_assert (workspace->monitor_edges == NULL);
db633a
 
db633a
+  if (workspace->screen->n_monitor_infos == 0)
db633a
+    return;
db633a
+
db633a
   /* STEP 1: Get the list of struts */
db633a
 
db633a
   workspace->all_struts = copy_strut_list (workspace->builtin_struts);
db633a
diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c
db633a
index 376d73c78..9b102e589 100644
db633a
--- a/src/x11/window-x11.c
db633a
+++ b/src/x11/window-x11.c
db633a
@@ -2032,7 +2032,8 @@ meta_window_move_resize_request (MetaWindow *window,
db633a
       rect.width = width;
db633a
       rect.height = height;
db633a
 
db633a
-      meta_screen_get_monitor_geometry (window->screen, window->monitor->number, &monitor_rect);
db633a
+      if (window->monitor)
db633a
+        meta_screen_get_monitor_geometry (window->screen, window->monitor->number, &monitor_rect);
db633a
 
db633a
       /* Workaround braindead legacy apps that don't know how to
db633a
        * fullscreen themselves properly - don't get fooled by
db633a
-- 
db633a
2.12.0
db633a