public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Nirbheek Chauhan" <nirbheek@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/gnome:master commit in: x11-wm/mutter/, x11-wm/mutter/files/
Date: Thu,  2 Jun 2011 14:43:07 +0000 (UTC)	[thread overview]
Message-ID: <ca057bf0f0093407f21c039ab440bf63bd31098d.nirbheek@gentoo> (raw)

commit:     ca057bf0f0093407f21c039ab440bf63bd31098d
Author:     Alexandre Rostovtsev <tetromino <AT> gmail <DOT> com>
AuthorDate: Sun May 29 23:54:29 2011 +0000
Commit:     Nirbheek Chauhan <nirbheek <AT> gentoo <DOT> org>
CommitDate: Thu Jun  2 14:07:45 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/gnome.git;a=commit;h=ca057bf0

x11-wm/mutter: 3.0.1-r1 → 3.0.2.1 + argb windows patches

Version bump, remove session saving patch (was applied upstream), add
patches for properly handling argb windows such as transparent terminals
(see gnome bug 635268 and gentoo bug 367139).

Signed-off-by: Nirbheek Chauhan <nirbheek <AT> gentoo.org>

---
 .../files/mutter-3.0.1-fix-session-saving.patch    |   69 --
 .../files/mutter-3.0.2-argb-windows-shadow.patch   |  764 ++++++++++++++++++++
 x11-wm/mutter/files/mutter-3.0.2-fix-xshape.patch  |   30 +
 .../mutter-3.0.2-frame-region-cairo-region.patch   |  234 ++++++
 ...utter-3.0.1-r1.ebuild => mutter-3.0.2.1.ebuild} |   13 +-
 5 files changed, 1037 insertions(+), 73 deletions(-)

diff --git a/x11-wm/mutter/files/mutter-3.0.1-fix-session-saving.patch b/x11-wm/mutter/files/mutter-3.0.1-fix-session-saving.patch
deleted file mode 100644
index 7352d2c..0000000
--- a/x11-wm/mutter/files/mutter-3.0.1-fix-session-saving.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-From c248c57b6e48b230fc80e3bd53d0d41fb713848a Mon Sep 17 00:00:00 2001
-From: Matthias Clasen <mclasen@redhat.com>
-Date: Fri, 29 Apr 2011 11:23:30 +0000
-Subject: Make session saving work a bit better
-
-Previously, the restart command hardcoded "mutter" as the binary name.
-This commit changes it to use g_get_prgname() which has a better chance
-of being correct (and it does fix session saving for gnome-shell).
-
-Now that mutter is a library, it might be more correct (but also
-much higher overhead) to add api for setting these things from
-the outside.
-
-https://bugzilla.gnome.org/show_bug.cgi?id=648828
----
-diff --git a/src/core/session.c b/src/core/session.c
-index 65542f3..c19b17c 100644
---- a/src/core/session.c
-+++ b/src/core/session.c
-@@ -308,13 +308,16 @@ meta_session_init (const char *previous_client_id,
-      */
-     char hint = SmRestartIfRunning;
-     char priority = 20; /* low to run before other apps */
--    
-+    const char *prgname;
-+
-+    prgname = g_get_prgname ();
-+
-     prop1.name = SmProgram;
-     prop1.type = SmARRAY8;
-     prop1.num_vals = 1;
-     prop1.vals = &prop1val;
--    prop1val.value = "mutter";
--    prop1val.length = strlen ("mutter");
-+    prop1val.value = (char *)prgname;
-+    prop1val.length = strlen (prgname);
- 
-     /* twm sets getuid() for this, but the SM spec plainly
-      * says pw_name, twm is on crack
-@@ -573,6 +576,9 @@ set_clone_restart_commands (void)
-   char *discardv[10];
-   int i;
-   SmProp prop1, prop2, prop3, *props[3];
-+  const char *prgname;
-+
-+  prgname = g_get_prgname ();
-   
-   /* Restart (use same client ID) */
-   
-@@ -582,7 +588,7 @@ set_clone_restart_commands (void)
-   g_return_if_fail (client_id);
-   
-   i = 0;
--  restartv[i] = "mutter";
-+  restartv[i] = (char *)prgname;
-   ++i;
-   restartv[i] = "--sm-client-id";
-   ++i;
-@@ -603,7 +609,7 @@ set_clone_restart_commands (void)
-   /* Clone (no client ID) */
-   
-   i = 0;
--  clonev[i] = "mutter";
-+  clonev[i] = (char *)prgname;
-   ++i;
-   clonev[i] = NULL;
- 
---
-cgit v0.9

diff --git a/x11-wm/mutter/files/mutter-3.0.2-argb-windows-shadow.patch b/x11-wm/mutter/files/mutter-3.0.2-argb-windows-shadow.patch
new file mode 100644
index 0000000..2ae376d
--- /dev/null
+++ b/x11-wm/mutter/files/mutter-3.0.2-argb-windows-shadow.patch
@@ -0,0 +1,764 @@
+From 67c3c93b8fd1e11716e72142ca43deb978e15c98 Mon Sep 17 00:00:00 2001
+From: Owen W. Taylor <otaylor@fishsoup.net>
+Date: Tue, 22 Mar 2011 19:36:12 +0000
+Subject: Only shadow ARGB windows with a frame outside the frame
+
+An ARGB window with a frame is likely something like a transparent
+terminal. It looks awful (and breaks transparency) to draw a big
+opaque black shadow under the window, so clip out the region under
+the terminal from the shadow we draw.
+
+Add meta_window_get_frame_bounds() to get a cairo region for the
+outer bounds of the frame of a window, and modify the frame handling
+code to notice changes to the frame shape and discard a cached
+region. meta_frames_apply_shapes() is refactored so we can extract
+meta_frames_get_frame_bounds() from it.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=635268
+---
+diff --git a/src/compositor/meta-shadow-factory-private.h b/src/compositor/meta-shadow-factory-private.h
+index 3d51cbb..e6b033e 100644
+--- a/src/compositor/meta-shadow-factory-private.h
++++ b/src/compositor/meta-shadow-factory-private.h
+@@ -47,7 +47,8 @@ void        meta_shadow_paint       (MetaShadow            *shadow,
+                                      int                    window_width,
+                                      int                    window_height,
+                                      guint8                 opacity,
+-                                     cairo_region_t        *clip);
++                                     cairo_region_t        *clip,
++                                     gboolean               clip_strictly);
+ void        meta_shadow_get_bounds  (MetaShadow            *shadow,
+                                      int                    window_x,
+                                      int                    window_y,
+diff --git a/src/compositor/meta-shadow-factory.c b/src/compositor/meta-shadow-factory.c
+index 1a9a447..f8bb1a8 100644
+--- a/src/compositor/meta-shadow-factory.c
++++ b/src/compositor/meta-shadow-factory.c
+@@ -189,8 +189,10 @@ meta_shadow_unref (MetaShadow *shadow)
+  * @window_width: actual width of the region to paint a shadow for
+  * @window_height: actual height of the region to paint a shadow for
+  * @clip: (allow-none): if non-%NULL specifies the visible portion
+- *   of the shadow. Drawing won't be strictly clipped to this region
+- *   but it will be used to optimize what is drawn.
++ *   of the shadow.
++ * @clip_strictly: if %TRUE, drawing will be clipped strictly
++ *   to @clip, otherwise, it will be only used to optimize
++ *   drawing.
+  *
+  * Paints the shadow at the given position, for the specified actual
+  * size of the region. (Since a #MetaShadow can be shared between
+@@ -204,7 +206,8 @@ meta_shadow_paint (MetaShadow     *shadow,
+                    int             window_width,
+                    int             window_height,
+                    guint8          opacity,
+-                   cairo_region_t *clip)
++                   cairo_region_t *clip,
++                   gboolean        clip_strictly)
+ {
+   float texture_width = cogl_texture_get_width (shadow->texture);
+   float texture_height = cogl_texture_get_height (shadow->texture);
+@@ -276,6 +279,9 @@ meta_shadow_paint (MetaShadow     *shadow,
+       dest_rect.y = dest_y[j];
+       dest_rect.height = dest_y[j + 1] - dest_y[j];
+ 
++      if (dest_rect.height == 0)
++        continue;
++
+       for (i = 0; i < n_x; i++)
+         {
+           cairo_region_overlap_t overlap;
+@@ -283,16 +289,64 @@ meta_shadow_paint (MetaShadow     *shadow,
+           dest_rect.x = dest_x[i];
+           dest_rect.width = dest_x[i + 1] - dest_x[i];
+ 
++          if (dest_rect.width == 0)
++            continue;
++
+           if (clip)
+             overlap = cairo_region_contains_rectangle (clip, &dest_rect);
+           else
+-            overlap = CAIRO_REGION_OVERLAP_PART;
++            overlap = CAIRO_REGION_OVERLAP_IN;
+ 
+-          if (overlap != CAIRO_REGION_OVERLAP_OUT)
+-            cogl_rectangle_with_texture_coords (dest_x[i], dest_y[j],
+-                                                dest_x[i + 1], dest_y[j + 1],
+-                                                src_x[i], src_y[j],
+-                                                src_x[i + 1], src_y[j + 1]);
++          /* There's quite a bit of overhead from allocating a new
++           * region in order to find an exact intersection and
++           * generating more geometry - we make the assumption that
++           * unless we have to clip strictly it will be cheaper to
++           * just draw the entire rectangle.
++           */
++          if (overlap == CAIRO_REGION_OVERLAP_IN ||
++              (overlap == CAIRO_REGION_OVERLAP_PART && !clip_strictly))
++            {
++              cogl_rectangle_with_texture_coords (dest_x[i], dest_y[j],
++                                                  dest_x[i + 1], dest_y[j + 1],
++                                                  src_x[i], src_y[j],
++                                                  src_x[i + 1], src_y[j + 1]);
++            }
++          else if (overlap == CAIRO_REGION_OVERLAP_PART)
++            {
++              cairo_region_t *intersection;
++              int n_rectangles, k;
++
++              intersection = cairo_region_create_rectangle (&dest_rect);
++              cairo_region_intersect (intersection, clip);
++
++              n_rectangles = cairo_region_num_rectangles (intersection);
++              for (k = 0; k < n_rectangles; k++)
++                {
++                  cairo_rectangle_int_t rect;
++                  float src_x1, src_x2, src_y1, src_y2;
++
++                  cairo_region_get_rectangle (intersection, k, &rect);
++
++                  /* Separately linear interpolate X and Y coordinates in the source
++                   * based on the destination X and Y coordinates */
++
++                  src_x1 = (src_x[i] * (dest_rect.x + dest_rect.width - rect.x) +
++                            src_x[i + 1] * (rect.x - dest_rect.x)) / dest_rect.width;
++                  src_x2 = (src_x[i] * (dest_rect.x + dest_rect.width - (rect.x + rect.width)) +
++                            src_x[i + 1] * (rect.x + rect.width - dest_rect.x)) / dest_rect.width;
++
++                  src_y1 = (src_y[j] * (dest_rect.y + dest_rect.height - rect.y) +
++                            src_y[j + 1] * (rect.y - dest_rect.y)) / dest_rect.height;
++                  src_y2 = (src_y[j] * (dest_rect.y + dest_rect.height - (rect.y + rect.height)) +
++                            src_y[j + 1] * (rect.y + rect.height - dest_rect.y)) / dest_rect.height;
++
++                  cogl_rectangle_with_texture_coords (rect.x, rect.y,
++                                                      rect.x + rect.width, rect.y + rect.height,
++                                                      src_x1, src_y1, src_x2, src_y2);
++                }
++
++              cairo_region_destroy (intersection);
++            }
+         }
+     }
+ }
+diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
+index 3be0363..4aab5c9 100644
+--- a/src/compositor/meta-window-actor.c
++++ b/src/compositor/meta-window-actor.c
+@@ -702,6 +702,26 @@ meta_window_actor_get_shadow_bounds (MetaWindowActor       *self,
+ }
+ #endif
+ 
++/* If we have an ARGB32 window that we decorate with a frame, it's
++ * probably something like a translucent terminal - something where
++ * the alpha channel represents transparency rather than a shape.  We
++ * don't want to show the shadow through the translucent areas since
++ * the shadow is wrong for translucent windows (it should be
++ * translucent itself and colored), and not only that, will /look/
++ * horribly wrong - a misplaced big black blob. As a hack, what we
++ * want to do is just draw the shadow as normal outside the frame, and
++ * inside the frame draw no shadow.  This is also not even close to
++ * the right result, but looks OK. We also apply this approach to
++ * windows set to be partially translucent with _NET_WM_WINDOW_OPACITY.
++ */
++static gboolean
++clip_shadow_under_window (MetaWindowActor *self)
++{
++  MetaWindowActorPrivate *priv = self->priv;
++
++  return (priv->argb32 || priv->opacity != 0xff) && priv->window->frame;
++}
++
+ static void
+ meta_window_actor_paint (ClutterActor *actor)
+ {
+@@ -714,17 +734,36 @@ meta_window_actor_paint (ClutterActor *actor)
+     {
+       MetaShadowParams params;
+       cairo_rectangle_int_t shape_bounds;
++      cairo_region_t *clip = priv->shadow_clip;
+ 
+       meta_window_actor_get_shape_bounds (self, &shape_bounds);
+       meta_window_actor_get_shadow_params (self, appears_focused, &params);
+ 
++      /* The frame bounds are already subtracted from priv->shadow_clip
++       * if that exists.
++       */
++      if (!clip && clip_shadow_under_window (self))
++        {
++          cairo_region_t *frame_bounds = meta_window_get_frame_bounds (priv->window);
++          cairo_rectangle_int_t bounds;
++
++          meta_window_actor_get_shadow_bounds (self, appears_focused, &bounds);
++          clip = cairo_region_create_rectangle (&bounds);
++
++          cairo_region_subtract (clip, frame_bounds);
++        }
++
+       meta_shadow_paint (shadow,
+                          params.x_offset + shape_bounds.x,
+                          params.y_offset + shape_bounds.y,
+                          shape_bounds.width,
+                          shape_bounds.height,
+                          (clutter_actor_get_paint_opacity (actor) * params.opacity * priv->opacity) / (255 * 255),
+-                         priv->shadow_clip);
++                         clip,
++                         clip_shadow_under_window (self)); /* clip_strictly - not just as an optimization */
++
++      if (clip && clip != priv->shadow_clip)
++        cairo_region_destroy (clip);
+     }
+ 
+   CLUTTER_ACTOR_CLASS (meta_window_actor_parent_class)->paint (actor);
+@@ -1787,6 +1826,12 @@ meta_window_actor_set_visible_region_beneath (MetaWindowActor *self,
+     {
+       meta_window_actor_clear_shadow_clip (self);
+       priv->shadow_clip = cairo_region_copy (beneath_region);
++
++      if (clip_shadow_under_window (self))
++        {
++          cairo_region_t *frame_bounds = meta_window_get_frame_bounds (priv->window);
++          cairo_region_subtract (priv->shadow_clip, frame_bounds);
++        }
+     }
+ }
+ 
+diff --git a/src/core/frame.c b/src/core/frame.c
+index 4db0002..155a0b8 100644
+--- a/src/core/frame.c
++++ b/src/core/frame.c
+@@ -328,7 +328,7 @@ meta_frame_calc_geometry (MetaFrame         *frame,
+   *geomp = geom;
+ }
+ 
+-static void
++static gboolean
+ update_shape (MetaFrame *frame)
+ {
+   if (frame->need_reapply_frame_shape)
+@@ -339,10 +339,14 @@ update_shape (MetaFrame *frame)
+                                  frame->rect.height,
+                                  frame->window->has_shape);
+       frame->need_reapply_frame_shape = FALSE;
++
++      return TRUE;
+     }
++  else
++    return FALSE;
+ }
+ 
+-void
++gboolean
+ meta_frame_sync_to_window (MetaFrame *frame,
+                            int        resize_gravity,
+                            gboolean   need_move,
+@@ -350,8 +354,7 @@ meta_frame_sync_to_window (MetaFrame *frame,
+ {
+   if (!(need_move || need_resize))
+     {
+-      update_shape (frame);
+-      return;
++      return update_shape (frame);
+     }
+ 
+   meta_topic (META_DEBUG_GEOMETRY,
+@@ -401,6 +404,17 @@ meta_frame_sync_to_window (MetaFrame *frame,
+         meta_ui_repaint_frame (frame->window->screen->ui,
+                                frame->xwindow);
+     }
++
++  return need_resize;
++}
++
++cairo_region_t *
++meta_frame_get_frame_bounds (MetaFrame *frame)
++{
++  return meta_ui_get_frame_bounds (frame->window->screen->ui,
++                                   frame->xwindow,
++                                   frame->rect.width,
++                                   frame->rect.height);
+ }
+ 
+ void
+diff --git a/src/core/frame.h b/src/core/frame.h
+index 019d6b3..7a637e8 100644
+--- a/src/core/frame.h
++++ b/src/core/frame.h
+@@ -73,11 +73,13 @@ Window         meta_frame_get_xwindow (MetaFrame *frame);
+ /* These should ONLY be called from meta_window_move_resize_internal */
+ void meta_frame_calc_geometry      (MetaFrame         *frame,
+                                     MetaFrameGeometry *geomp);
+-void meta_frame_sync_to_window     (MetaFrame         *frame,
++gboolean meta_frame_sync_to_window (MetaFrame         *frame,
+                                     int                gravity,
+                                     gboolean           need_move,
+                                     gboolean           need_resize);
+ 
++cairo_region_t *meta_frame_get_frame_bounds (MetaFrame *frame);
++
+ void meta_frame_set_screen_cursor (MetaFrame	*frame,
+ 				   MetaCursor	cursor);
+ 
+diff --git a/src/core/window-private.h b/src/core/window-private.h
+index cbac91d..7909943 100644
+--- a/src/core/window-private.h
++++ b/src/core/window-private.h
+@@ -42,6 +42,7 @@
+ #include "stack.h"
+ #include "iconcache.h"
+ #include <X11/Xutil.h>
++#include <cairo.h>
+ #include <gdk-pixbuf/gdk-pixbuf.h>
+ 
+ typedef struct _MetaWindowQueue MetaWindowQueue;
+@@ -316,6 +317,9 @@ struct _MetaWindow
+   /* if TRUE, application is buggy and SYNC resizing is turned off */
+   guint disable_sync : 1;
+ 
++  /* if non-NULL, the bounds of the window frame */
++  cairo_region_t *frame_bounds;
++
+   /* Note: can be NULL */
+   GSList *struts;
+ 
+diff --git a/src/core/window.c b/src/core/window.c
+index d442932..aa6d75c 100644
+--- a/src/core/window.c
++++ b/src/core/window.c
+@@ -181,6 +181,9 @@ meta_window_finalize (GObject *object)
+   if (window->mini_icon)
+     g_object_unref (G_OBJECT (window->mini_icon));
+ 
++  if (window->frame_bounds)
++    cairo_region_destroy (window->frame_bounds);
++
+   meta_icon_cache_free (&window->icon_cache);
+ 
+   g_free (window->sm_client_id);
+@@ -4295,6 +4298,7 @@ meta_window_move_resize_internal (MetaWindow          *window,
+   int frame_size_dy;
+   int size_dx;
+   int size_dy;
++  gboolean frame_shape_changed = FALSE;
+   gboolean is_configure_request;
+   gboolean do_gravity_adjust;
+   gboolean is_user_action;
+@@ -4598,9 +4602,9 @@ meta_window_move_resize_internal (MetaWindow          *window,
+     meta_window_set_gravity (window, StaticGravity);
+ 
+   if (configure_frame_first && window->frame)
+-    meta_frame_sync_to_window (window->frame,
+-                               gravity,
+-                               need_move_frame, need_resize_frame);
++    frame_shape_changed = meta_frame_sync_to_window (window->frame,
++                                                     gravity,
++                                                     need_move_frame, need_resize_frame);
+ 
+   values.border_width = 0;
+   values.x = client_move_x;
+@@ -4655,9 +4659,9 @@ meta_window_move_resize_internal (MetaWindow          *window,
+     }
+ 
+   if (!configure_frame_first && window->frame)
+-    meta_frame_sync_to_window (window->frame,
+-                               gravity,
+-                               need_move_frame, need_resize_frame);
++    frame_shape_changed = meta_frame_sync_to_window (window->frame,
++                                                     gravity,
++                                                     need_move_frame, need_resize_frame);
+ 
+   /* Put gravity back to be nice to lesser window managers */
+   if (use_static_gravity)
+@@ -4700,6 +4704,12 @@ meta_window_move_resize_internal (MetaWindow          *window,
+    *   b) all constraints are obeyed by window->rect and frame->rect
+    */
+ 
++  if (frame_shape_changed && window->frame_bounds)
++    {
++      cairo_region_destroy (window->frame_bounds);
++      window->frame_bounds = NULL;
++    }
++
+   if (meta_prefs_get_attach_modal_dialogs ())
+     meta_window_foreach_transient (window, move_attached_dialog, NULL);
+ }
+@@ -10204,3 +10214,24 @@ meta_window_get_frame_type (MetaWindow *window)
+       return base_type;
+     }
+ }
++
++/**
++ * meta_window_get_frame_bounds:
++ *
++ * Gets a region representing the outer bounds of the window's frame.
++ *
++ * Return value: (transfer none) (allow-none): a #cairo_region_t
++ *  holding the outer bounds of the window, or %NULL if the window
++ *  doesn't have a frame.
++ */
++cairo_region_t *
++meta_window_get_frame_bounds (MetaWindow *window)
++{
++  if (!window->frame_bounds)
++    {
++      if (window->frame)
++        window->frame_bounds = meta_frame_get_frame_bounds (window->frame);
++    }
++
++  return window->frame_bounds;
++}
+diff --git a/src/meta/window.h b/src/meta/window.h
+index a1c4b75..985a146 100644
+--- a/src/meta/window.h
++++ b/src/meta/window.h
+@@ -23,6 +23,7 @@
+ #define META_WINDOW_H
+ 
+ #include <glib-object.h>
++#include <cairo.h>
+ #include <X11/Xlib.h>
+ 
+ #include <meta/boxes.h>
+@@ -156,4 +157,6 @@ const char *meta_window_get_mutter_hints (MetaWindow *window);
+ 
+ MetaFrameType meta_window_get_frame_type (MetaWindow *window);
+ 
++cairo_region_t *meta_window_get_frame_bounds (MetaWindow *window);
++
+ #endif
+diff --git a/src/ui/frames.c b/src/ui/frames.c
+index 7c62898..520f29d 100644
+--- a/src/ui/frames.c
++++ b/src/ui/frames.c
+@@ -797,60 +797,22 @@ apply_cairo_region_to_window (Display        *display,
+ }
+ #endif
+ 
+-void
+-meta_frames_apply_shapes (MetaFrames *frames,
+-                          Window      xwindow,
+-                          int         new_window_width,
+-                          int         new_window_height,
+-                          gboolean    window_has_shape)
++static cairo_region_t *
++get_bounds_region (MetaFrames        *frames,
++                  MetaUIFrame       *frame,
++                  MetaFrameGeometry *fgeom,
++                  int                window_width,
++                  int                window_height)
+ {
+-#ifdef HAVE_SHAPE
+-  /* Apply shapes as if window had new_window_width, new_window_height */
+-  MetaUIFrame *frame;
+-  MetaFrameGeometry fgeom;
+-  cairo_rectangle_int_t rect;
+   cairo_region_t *corners_region;
+-  cairo_region_t *window_region;
+-  Display *display;
+-  
+-  frame = meta_frames_lookup_window (frames, xwindow);
+-  g_return_if_fail (frame != NULL);
+-
+-  display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
+-
+-  meta_frames_calc_geometry (frames, frame, &fgeom);
++  cairo_region_t *bounds_region;
++  cairo_rectangle_int_t rect;
+ 
+-  if (!(fgeom.top_left_corner_rounded_radius != 0 ||
+-        fgeom.top_right_corner_rounded_radius != 0 ||
+-        fgeom.bottom_left_corner_rounded_radius != 0 ||
+-        fgeom.bottom_right_corner_rounded_radius != 0 ||
+-        window_has_shape))
+-    {
+-      if (frame->shape_applied)
+-        {
+-          meta_topic (META_DEBUG_SHAPES,
+-                      "Unsetting shape mask on frame 0x%lx\n",
+-                      frame->xwindow);
+-          
+-          XShapeCombineMask (display, frame->xwindow,
+-                             ShapeBounding, 0, 0, None, ShapeSet);
+-          frame->shape_applied = FALSE;
+-        }
+-      else
+-        {
+-          meta_topic (META_DEBUG_SHAPES,
+-                      "Frame 0x%lx still doesn't need a shape mask\n",
+-                      frame->xwindow);
+-        }
+-      
+-      return; /* nothing to do */
+-    }
+-  
+   corners_region = cairo_region_create ();
+   
+-  if (fgeom.top_left_corner_rounded_radius != 0)
++  if (fgeom->top_left_corner_rounded_radius != 0)
+     {
+-      const int corner = fgeom.top_left_corner_rounded_radius;
++      const int corner = fgeom->top_left_corner_rounded_radius;
+       const float radius = sqrt(corner) + corner;
+       int i;
+ 
+@@ -866,16 +828,16 @@ meta_frames_apply_shapes (MetaFrames *frames,
+         }
+     }
+ 
+-  if (fgeom.top_right_corner_rounded_radius != 0)
++  if (fgeom->top_right_corner_rounded_radius != 0)
+     {
+-      const int corner = fgeom.top_right_corner_rounded_radius;
++      const int corner = fgeom->top_right_corner_rounded_radius;
+       const float radius = sqrt(corner) + corner;
+       int i;
+ 
+       for (i=0; i<corner; i++)
+         {
+           const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
+-          rect.x = new_window_width - width;
++          rect.x = window_width - width;
+           rect.y = i;
+           rect.width = width;
+           rect.height = 1;
+@@ -884,9 +846,9 @@ meta_frames_apply_shapes (MetaFrames *frames,
+         }
+     }
+ 
+-  if (fgeom.bottom_left_corner_rounded_radius != 0)
++  if (fgeom->bottom_left_corner_rounded_radius != 0)
+     {
+-      const int corner = fgeom.bottom_left_corner_rounded_radius;
++      const int corner = fgeom->bottom_left_corner_rounded_radius;
+       const float radius = sqrt(corner) + corner;
+       int i;
+ 
+@@ -894,7 +856,7 @@ meta_frames_apply_shapes (MetaFrames *frames,
+         {
+           const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
+           rect.x = 0;
+-          rect.y = new_window_height - i - 1;
++          rect.y = window_height - i - 1;
+           rect.width = width;
+           rect.height = 1;
+           
+@@ -902,17 +864,17 @@ meta_frames_apply_shapes (MetaFrames *frames,
+         }
+     }
+ 
+-  if (fgeom.bottom_right_corner_rounded_radius != 0)
++  if (fgeom->bottom_right_corner_rounded_radius != 0)
+     {
+-      const int corner = fgeom.bottom_right_corner_rounded_radius;
++      const int corner = fgeom->bottom_right_corner_rounded_radius;
+       const float radius = sqrt(corner) + corner;
+       int i;
+ 
+       for (i=0; i<corner; i++)
+         {
+           const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
+-          rect.x = new_window_width - width;
+-          rect.y = new_window_height - i - 1;
++          rect.x = window_width - width;
++          rect.y = window_height - i - 1;
+           rect.width = width;
+           rect.height = 1;
+           
+@@ -920,19 +882,88 @@ meta_frames_apply_shapes (MetaFrames *frames,
+         }
+     }
+   
+-  window_region = cairo_region_create ();
++  bounds_region = cairo_region_create ();
+   
+   rect.x = 0;
+   rect.y = 0;
+-  rect.width = new_window_width;
+-  rect.height = new_window_height;
++  rect.width = window_width;
++  rect.height = window_height;
+ 
+-  cairo_region_union_rectangle (window_region, &rect);
++  cairo_region_union_rectangle (bounds_region, &rect);
+ 
+-  cairo_region_subtract (window_region, corners_region);
++  cairo_region_subtract (bounds_region, corners_region);
+ 
+   cairo_region_destroy (corners_region);
++
++  return bounds_region;
++}
++
++static cairo_region_t *
++get_client_region (MetaFrameGeometry *fgeom,
++                   int                window_width,
++                   int                window_height)
++{
++  cairo_rectangle_int_t rect;
++
++  rect.x = fgeom->left_width;
++  rect.y = fgeom->top_height;
++  rect.width = window_width - fgeom->right_width - rect.x;
++  rect.height = window_height - fgeom->bottom_height - rect.y;
++
++  return cairo_region_create_rectangle (&rect);
++}
++
++void
++meta_frames_apply_shapes (MetaFrames *frames,
++                          Window      xwindow,
++                          int         new_window_width,
++                          int         new_window_height,
++                          gboolean    window_has_shape)
++{
++#ifdef HAVE_SHAPE
++  /* Apply shapes as if window had new_window_width, new_window_height */
++  MetaUIFrame *frame;
++  MetaFrameGeometry fgeom;
++  cairo_region_t *window_region;
++  Display *display;
+   
++  frame = meta_frames_lookup_window (frames, xwindow);
++  g_return_if_fail (frame != NULL);
++
++  display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
++
++  meta_frames_calc_geometry (frames, frame, &fgeom);
++
++  if (!(fgeom.top_left_corner_rounded_radius != 0 ||
++        fgeom.top_right_corner_rounded_radius != 0 ||
++        fgeom.bottom_left_corner_rounded_radius != 0 ||
++        fgeom.bottom_right_corner_rounded_radius != 0 ||
++        window_has_shape))
++    {
++      if (frame->shape_applied)
++        {
++          meta_topic (META_DEBUG_SHAPES,
++                      "Unsetting shape mask on frame 0x%lx\n",
++                      frame->xwindow);
++
++          XShapeCombineMask (display, frame->xwindow,
++                             ShapeBounding, 0, 0, None, ShapeSet);
++          frame->shape_applied = FALSE;
++        }
++      else
++        {
++          meta_topic (META_DEBUG_SHAPES,
++                      "Frame 0x%lx still doesn't need a shape mask\n",
++                      frame->xwindow);
++        }
++
++      return; /* nothing to do */
++    }
++
++  window_region = get_bounds_region (frames, frame,
++                                     &fgeom,
++                                     new_window_width, new_window_height);
++
+   if (window_has_shape)
+     {
+       /* The client window is oclock or something and has a shape
+@@ -984,15 +1015,10 @@ meta_frames_apply_shapes (MetaFrames *frames,
+       /* Punch the client area out of the normal frame shape,
+        * then union it with the shape_window's existing shape
+        */
+-      client_region = cairo_region_create ();
+-  
+-      rect.x = fgeom.left_width;
+-      rect.y = fgeom.top_height;
+-      rect.width = new_window_width - fgeom.right_width - rect.x;
+-      rect.height = new_window_height - fgeom.bottom_height - rect.y;
++      client_region = get_client_region (&fgeom,
++                                         new_window_width,
++                                         new_window_height);
+ 
+-      cairo_region_union_rectangle (client_region, &rect);
+-      
+       cairo_region_subtract (window_region, client_region);
+ 
+       cairo_region_destroy (client_region);
+@@ -1027,6 +1053,25 @@ meta_frames_apply_shapes (MetaFrames *frames,
+ #endif /* HAVE_SHAPE */
+ }
+ 
++cairo_region_t *
++meta_frames_get_frame_bounds (MetaFrames *frames,
++                              Window      xwindow,
++                              int         window_width,
++                              int         window_height)
++{
++  MetaUIFrame *frame;
++  MetaFrameGeometry fgeom;
++
++  frame = meta_frames_lookup_window (frames, xwindow);
++  g_return_val_if_fail (frame != NULL, NULL);
++
++  meta_frames_calc_geometry (frames, frame, &fgeom);
++
++  return get_bounds_region (frames, frame,
++                            &fgeom,
++                            window_width, window_height);
++}
++
+ void
+ meta_frames_move_resize_frame (MetaFrames *frames,
+                                Window      xwindow,
+diff --git a/src/ui/frames.h b/src/ui/frames.h
+index 5fdba63..d1807df 100644
+--- a/src/ui/frames.h
++++ b/src/ui/frames.h
+@@ -144,6 +144,10 @@ void meta_frames_apply_shapes (MetaFrames *frames,
+                                int         new_window_width,
+                                int         new_window_height,
+                                gboolean    window_has_shape);
++cairo_region_t *meta_frames_get_frame_bounds (MetaFrames *frames,
++                                              Window      xwindow,
++                                              int         window_width,
++                                              int         window_height);
+ void meta_frames_move_resize_frame (MetaFrames *frames,
+ 				    Window      xwindow,
+ 				    int         x,
+diff --git a/src/ui/ui.c b/src/ui/ui.c
+index 575f2ae..5381b8d 100644
+--- a/src/ui/ui.c
++++ b/src/ui/ui.c
+@@ -470,6 +470,16 @@ meta_ui_apply_frame_shape  (MetaUI  *ui,
+                             window_has_shape);
+ }
+ 
++cairo_region_t *
++meta_ui_get_frame_bounds (MetaUI  *ui,
++                          Window   xwindow,
++                          int      window_width,
++                          int      window_height)
++{
++  return meta_frames_get_frame_bounds (ui->frames, xwindow,
++                                       window_width, window_height);
++}
++
+ void
+ meta_ui_queue_frame_draw (MetaUI *ui,
+                           Window xwindow)
+diff --git a/src/ui/ui.h b/src/ui/ui.h
+index cc449bd..9a33d9d 100644
+--- a/src/ui/ui.h
++++ b/src/ui/ui.h
+@@ -28,6 +28,7 @@
+ #include <meta/common.h>
+ #include <X11/Xlib.h>
+ #include <X11/Xutil.h>
++#include <cairo.h>
+ #include <glib.h>
+ #include <gdk-pixbuf/gdk-pixbuf.h>
+ 
+@@ -104,6 +105,11 @@ void meta_ui_apply_frame_shape  (MetaUI  *ui,
+                                  int      new_window_height,
+                                  gboolean window_has_shape);
+ 
++cairo_region_t *meta_ui_get_frame_bounds (MetaUI  *ui,
++                                          Window   xwindow,
++                                          int      window_width,
++                                          int      window_height);
++
+ void meta_ui_queue_frame_draw (MetaUI *ui,
+                                Window xwindow);
+ 
+--
+cgit v0.9

diff --git a/x11-wm/mutter/files/mutter-3.0.2-fix-xshape.patch b/x11-wm/mutter/files/mutter-3.0.2-fix-xshape.patch
new file mode 100644
index 0000000..bc65ab2
--- /dev/null
+++ b/x11-wm/mutter/files/mutter-3.0.2-fix-xshape.patch
@@ -0,0 +1,30 @@
+From 59efae8920ff919beffa3816874c2e7cc85f3f08 Mon Sep 17 00:00:00 2001
+From: Jasper St. Pierre <jstpierre@mecheye.net>
+Date: Wed, 25 May 2011 20:47:53 -0400
+Subject: [PATCH] Fix XShape
+
+Commit c3a04bf unintentionally broke XShape handling. By studying the code
+extremely carefully, I found this inconsistency with the code that was
+there before.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=635268
+---
+ src/ui/frames.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/src/ui/frames.c b/src/ui/frames.c
+index 9f0126c..4352e38 100644
+--- a/src/ui/frames.c
++++ b/src/ui/frames.c
+@@ -880,7 +880,7 @@ apply_cairo_region_to_window (Display        *display,
+ 
+   XShapeCombineRectangles (display, xwindow,
+                            ShapeBounding, 0, 0, rects, n_rects,
+-                           ShapeSet, YXBanded);
++                           op, YXBanded);
+ 
+   g_free (rects);
+ }
+-- 
+1.7.5.1
+

diff --git a/x11-wm/mutter/files/mutter-3.0.2-frame-region-cairo-region.patch b/x11-wm/mutter/files/mutter-3.0.2-frame-region-cairo-region.patch
new file mode 100644
index 0000000..2a41fea
--- /dev/null
+++ b/x11-wm/mutter/files/mutter-3.0.2-frame-region-cairo-region.patch
@@ -0,0 +1,234 @@
+From c3a04bf3948dae31cbd64e637c290ddee7bcc73b Mon Sep 17 00:00:00 2001
+From: Owen W. Taylor <otaylor@fishsoup.net>
+Date: Sun, 20 Mar 2011 20:26:27 +0000
+Subject: Convert frame region handling to cairo regions
+
+It's useful to get frame shapes and manipulate them within Mutter, for
+example so that the compositor can use them to clip drawing.
+For this, we'll need the regions as cairo regions not X regions, so
+convert frame shaping code to work in terms of cairo_region_t.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=635268
+---
+diff --git a/src/ui/frames.c b/src/ui/frames.c
+index 9c4782e..7c62898 100644
+--- a/src/ui/frames.c
++++ b/src/ui/frames.c
+@@ -764,6 +764,39 @@ meta_frames_unflicker_bg (MetaFrames *frames,
+   set_background_none (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow);
+ }
+ 
++#ifdef HAVE_SHAPE
++static void
++apply_cairo_region_to_window (Display        *display,
++                              Window          xwindow,
++                              cairo_region_t *region,
++                              int             op)
++{
++  int n_rects, i;
++  XRectangle *rects;
++
++  n_rects = cairo_region_num_rectangles (region);
++  rects = g_new (XRectangle, n_rects);
++
++  for (i = 0; i < n_rects; i++)
++    {
++      cairo_rectangle_int_t rect;
++
++      cairo_region_get_rectangle (region, i, &rect);
++
++      rects[i].x = rect.x;
++      rects[i].y = rect.y;
++      rects[i].width = rect.width;
++      rects[i].height = rect.height;
++    }
++
++  XShapeCombineRectangles (display, xwindow,
++                           ShapeBounding, 0, 0, rects, n_rects,
++                           ShapeSet, YXBanded);
++
++  g_free (rects);
++}
++#endif
++
+ void
+ meta_frames_apply_shapes (MetaFrames *frames,
+                           Window      xwindow,
+@@ -775,9 +808,9 @@ meta_frames_apply_shapes (MetaFrames *frames,
+   /* Apply shapes as if window had new_window_width, new_window_height */
+   MetaUIFrame *frame;
+   MetaFrameGeometry fgeom;
+-  XRectangle xrect;
+-  Region corners_xregion;
+-  Region window_xregion;
++  cairo_rectangle_int_t rect;
++  cairo_region_t *corners_region;
++  cairo_region_t *window_region;
+   Display *display;
+   
+   frame = meta_frames_lookup_window (frames, xwindow);
+@@ -813,7 +846,7 @@ meta_frames_apply_shapes (MetaFrames *frames,
+       return; /* nothing to do */
+     }
+   
+-  corners_xregion = XCreateRegion ();
++  corners_region = cairo_region_create ();
+   
+   if (fgeom.top_left_corner_rounded_radius != 0)
+     {
+@@ -824,12 +857,12 @@ meta_frames_apply_shapes (MetaFrames *frames,
+       for (i=0; i<corner; i++)
+         {
+           const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
+-          xrect.x = 0;
+-          xrect.y = i;
+-          xrect.width = width;
+-          xrect.height = 1;
++          rect.x = 0;
++          rect.y = i;
++          rect.width = width;
++          rect.height = 1;
+           
+-          XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
++          cairo_region_union_rectangle (corners_region, &rect);
+         }
+     }
+ 
+@@ -842,12 +875,12 @@ meta_frames_apply_shapes (MetaFrames *frames,
+       for (i=0; i<corner; i++)
+         {
+           const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
+-          xrect.x = new_window_width - width;
+-          xrect.y = i;
+-          xrect.width = width;
+-          xrect.height = 1;
++          rect.x = new_window_width - width;
++          rect.y = i;
++          rect.width = width;
++          rect.height = 1;
+           
+-          XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
++          cairo_region_union_rectangle (corners_region, &rect);
+         }
+     }
+ 
+@@ -860,12 +893,12 @@ meta_frames_apply_shapes (MetaFrames *frames,
+       for (i=0; i<corner; i++)
+         {
+           const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
+-          xrect.x = 0;
+-          xrect.y = new_window_height - i - 1;
+-          xrect.width = width;
+-          xrect.height = 1;
++          rect.x = 0;
++          rect.y = new_window_height - i - 1;
++          rect.width = width;
++          rect.height = 1;
+           
+-          XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
++          cairo_region_union_rectangle (corners_region, &rect);
+         }
+     }
+ 
+@@ -878,27 +911,27 @@ meta_frames_apply_shapes (MetaFrames *frames,
+       for (i=0; i<corner; i++)
+         {
+           const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
+-          xrect.x = new_window_width - width;
+-          xrect.y = new_window_height - i - 1;
+-          xrect.width = width;
+-          xrect.height = 1;
++          rect.x = new_window_width - width;
++          rect.y = new_window_height - i - 1;
++          rect.width = width;
++          rect.height = 1;
+           
+-          XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
++          cairo_region_union_rectangle (corners_region, &rect);
+         }
+     }
+   
+-  window_xregion = XCreateRegion ();
++  window_region = cairo_region_create ();
+   
+-  xrect.x = 0;
+-  xrect.y = 0;
+-  xrect.width = new_window_width;
+-  xrect.height = new_window_height;
++  rect.x = 0;
++  rect.y = 0;
++  rect.width = new_window_width;
++  rect.height = new_window_height;
+ 
+-  XUnionRectWithRegion (&xrect, window_xregion, window_xregion);
++  cairo_region_union_rectangle (window_region, &rect);
+ 
+-  XSubtractRegion (window_xregion, corners_xregion, window_xregion);
++  cairo_region_subtract (window_region, corners_region);
+ 
+-  XDestroyRegion (corners_xregion);
++  cairo_region_destroy (corners_region);
+   
+   if (window_has_shape)
+     {
+@@ -911,7 +944,7 @@ meta_frames_apply_shapes (MetaFrames *frames,
+       XSetWindowAttributes attrs;      
+       Window shape_window;
+       Window client_window;
+-      Region client_xregion;
++      cairo_region_t *client_region;
+       GdkScreen *screen;
+       int screen_number;
+       
+@@ -951,21 +984,21 @@ meta_frames_apply_shapes (MetaFrames *frames,
+       /* Punch the client area out of the normal frame shape,
+        * then union it with the shape_window's existing shape
+        */
+-      client_xregion = XCreateRegion ();
++      client_region = cairo_region_create ();
+   
+-      xrect.x = fgeom.left_width;
+-      xrect.y = fgeom.top_height;
+-      xrect.width = new_window_width - fgeom.right_width - xrect.x;
+-      xrect.height = new_window_height - fgeom.bottom_height - xrect.y;
++      rect.x = fgeom.left_width;
++      rect.y = fgeom.top_height;
++      rect.width = new_window_width - fgeom.right_width - rect.x;
++      rect.height = new_window_height - fgeom.bottom_height - rect.y;
+ 
+-      XUnionRectWithRegion (&xrect, client_xregion, client_xregion);
++      cairo_region_union_rectangle (client_region, &rect);
+       
+-      XSubtractRegion (window_xregion, client_xregion, window_xregion);
++      cairo_region_subtract (window_region, client_region);
+ 
+-      XDestroyRegion (client_xregion);
+-      
+-      XShapeCombineRegion (display, shape_window,
+-                           ShapeBounding, 0, 0, window_xregion, ShapeUnion);
++      cairo_region_destroy (client_region);
++
++      apply_cairo_region_to_window (display, shape_window,
++                                    window_region, ShapeUnion);
+       
+       /* Now copy shape_window shape to the real frame */
+       XShapeCombineShape (display, frame->xwindow, ShapeBounding,
+@@ -984,13 +1017,13 @@ meta_frames_apply_shapes (MetaFrames *frames,
+                   "Frame 0x%lx has shaped corners\n",
+                   frame->xwindow);
+       
+-      XShapeCombineRegion (display, frame->xwindow,
+-                           ShapeBounding, 0, 0, window_xregion, ShapeSet);
++      apply_cairo_region_to_window (display, frame->xwindow,
++                                    window_region, ShapeSet);
+     }
+   
+   frame->shape_applied = TRUE;
+   
+-  XDestroyRegion (window_xregion);
++  cairo_region_destroy (window_region);
+ #endif /* HAVE_SHAPE */
+ }
+ 
+--
+cgit v0.9

diff --git a/x11-wm/mutter/mutter-3.0.1-r1.ebuild b/x11-wm/mutter/mutter-3.0.2.1.ebuild
similarity index 80%
rename from x11-wm/mutter/mutter-3.0.1-r1.ebuild
rename to x11-wm/mutter/mutter-3.0.2.1.ebuild
index d33255c..c5f7d14 100644
--- a/x11-wm/mutter/mutter-3.0.1-r1.ebuild
+++ b/x11-wm/mutter/mutter-3.0.2.1.ebuild
@@ -6,7 +6,7 @@ EAPI="3"
 GCONF_DEBUG="no"
 GNOME2_LA_PUNT="yes"
 
-inherit gnome2
+inherit eutils gnome2
 if [[ ${PV} = 9999 ]]; then
 	inherit gnome2-live
 fi
@@ -78,7 +78,12 @@ pkg_setup() {
 }
 
 src_prepare() {
-	# https://bugs.gentoo.org/show_bug.cgi?id=363853
-	# Taken from upstream, remove for next release
-	epatch "${FILESDIR}/${P}-fix-session-saving.patch"
+	# Fix argb window shadows: https://bugzilla.gnome.org/show_bug.cgi?id=635268
+	# The first two patches are from upstream git master branch:
+	epatch "${FILESDIR}/${PN}-3.0.2-frame-region-cairo-region.patch"
+	epatch "${FILESDIR}/${PN}-3.0.2-argb-windows-shadow.patch"
+	# The third is from comment 33 in the gnome bug and unbreaks XShape handling
+	epatch "${FILESDIR}/${PN}-3.0.2-fix-xshape.patch"
+
+	gnome2_src_prepare
 }



             reply	other threads:[~2011-06-02 14:43 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-06-02 14:43 Nirbheek Chauhan [this message]
  -- strict thread matches above, loose matches on Subject: below --
2015-04-18  9:00 [gentoo-commits] proj/gnome:master commit in: x11-wm/mutter/, x11-wm/mutter/files/ Ole Reifschneider
2012-03-26  8:20 Nirbheek Chauhan
2011-10-18  7:37 Alexandre Restovtsev
2011-04-29 19:16 Nirbheek Chauhan
2011-03-29  8:35 Nirbheek Chauhan
2011-03-09 11:34 Nirbheek Chauhan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ca057bf0f0093407f21c039ab440bf63bd31098d.nirbheek@gentoo \
    --to=nirbheek@gentoo.org \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox