[gnome-control-center] display: initial implementation of the new design



commit b4a16be646b3c2f7b5b2eb8c4ceeed9dc84d7c8e
Author: Thomas Wood <thomas wood intel com>
Date:   Tue Aug 20 14:48:04 2013 +0100

    display: initial implementation of the new design
    
    Add an initial implementation of the new design for the display panel. The
    display previews and presentation mode are not yet fully implemented.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=706115

 configure.ac                      |    2 +-
 panels/display/cc-display-panel.c | 2442 +++++++++++++++----------------------
 panels/display/cc-display-panel.h |    3 +
 panels/display/cc-rr-labeler.c    |  152 +--
 panels/display/cc-rr-labeler.h    |    2 -
 panels/display/display-capplet.ui |  578 ++++++---
 6 files changed, 1393 insertions(+), 1786 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 799df81..6a04dba 100644
--- a/configure.ac
+++ b/configure.ac
@@ -94,7 +94,7 @@ NETWORK_MANAGER_REQUIRED_VERSION=0.9.8
 NETWORK_MANAGER_APPLET_REQUIRED_VERSION=0.9.7.995
 MODEM_MANAGER_REQUIRED_VERSION=0.7
 LIBNOTIFY_REQUIRED_VERSION=0.7.3
-GNOME_DESKTOP_REQUIRED_VERSION=3.9.0
+GNOME_DESKTOP_REQUIRED_VERSION=3.9.90
 SCHEMAS_REQUIRED_VERSION=3.7.2.2
 LIBWACOM_REQUIRED_VERSION=0.7
 CLUTTER_REQUIRED_VERSION=1.11.3
diff --git a/panels/display/cc-display-panel.c b/panels/display/cc-display-panel.c
index ff585e2..2424037 100644
--- a/panels/display/cc-display-panel.c
+++ b/panels/display/cc-display-panel.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2007, 2008  Red Hat, Inc.
+ * Copyright (C) 2013 Intel, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -13,17 +14,10 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Author: Soren Sandmann <sandmann redhat com>
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  */
 
-#include <config.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/wait.h>
-
 #include "cc-display-panel.h"
 #include "cc-display-resources.h"
 
@@ -32,10 +26,10 @@
 #define GNOME_DESKTOP_USE_UNSTABLE_API
 #include <libgnome-desktop/gnome-rr.h>
 #include <libgnome-desktop/gnome-rr-config.h>
-#include <gdk/gdkx.h>
-#include <X11/Xlib.h>
 #include <glib/gi18n.h>
+#include <stdlib.h>
 #include <gdesktop-enums.h>
+#include <math.h>
 
 #include "cc-rr-labeler.h"
 #include <libupower-glib/upower.h>
@@ -49,52 +43,38 @@ CC_PANEL_REGISTER (CcDisplayPanel, cc_display_panel)
 
 #define TOP_BAR_HEIGHT 10
 
-#define CLOCK_SCHEMA "org.gnome.desktop.interface"
-#define CLOCK_FORMAT_KEY "clock-format"
-
 /* The minimum supported size for the panel, see:
  * http://live.gnome.org/Design/SystemSettings */
 #define MINIMUM_WIDTH 675
 #define MINIMUM_HEIGHT 530
 
-enum {
-  TEXT_COL,
-  WIDTH_COL,
-  HEIGHT_COL,
-  RATE_COL,
-  SORT_COL,
-  ROTATION_COL,
-  NUM_COLS
+
+#define DISPLAY_PREVIEW_SETUP_HEIGHT 140
+#define DISPLAY_PREVIEW_LIST_HEIGHT  55
+
+enum
+{
+  DISPLAY_MODE_PRIMARY,
+  DISPLAY_MODE_SECONDARY,
+  /* DISPLAY_MODE_PRESENTATION, */
+  DISPLAY_MODE_MIRROR
 };
 
 struct _CcDisplayPanelPrivate
 {
-  GnomeRRScreen       *screen;
-  GnomeRRConfig  *current_configuration;
-  CcRRLabeler *labeler;
-  GnomeRROutputInfo         *current_output;
+  GnomeRRScreen     *screen;
+  GnomeRRConfig     *current_configuration;
+  CcRRLabeler       *labeler;
+  GnomeRROutputInfo *current_output;
 
-  GSettings      *clock_settings;
-  GtkBuilder     *builder;
   guint           focus_id;
+  guint           screen_changed_handler_id;
 
-  GtkWidget      *panel;
-  GtkWidget      *current_monitor_event_box;
-  GtkWidget      *current_monitor_label;
-  GtkWidget      *monitor_switch;
-  GtkListStore   *resolution_store;
-  GtkWidget      *resolution_combo;
-  GtkWidget      *rotation_combo;
-  GtkWidget      *clone_checkbox;
-  GtkWidget      *clone_label;
-  GtkWidget      *show_icon_checkbox;
-
-  /* We store the event timestamp when the Apply button is clicked */
-  guint32         apply_button_clicked_timestamp;
-
-  GtkWidget      *area;
-  gboolean        ignore_gui_changes;
-  gboolean        dragging_top_bar;
+  GtkWidget *displays_listbox;
+  GtkWidget *arrange_button;
+  GtkWidget *res_combo;
+  GtkWidget *rotate_left_button;
+  GtkWidget *rotate_right_button;
 
   UpClient *up_client;
   gboolean lid_is_closed;
@@ -108,85 +88,52 @@ typedef struct
   int output_y;
 } GrabInfo;
 
-static void rebuild_gui (CcDisplayPanel *self);
-static void on_clone_changed (GtkWidget *box, gpointer data);
-static gboolean output_overlaps (GnomeRROutputInfo *output, GnomeRRConfig *config);
-static void select_current_output_from_dialog_position (CcDisplayPanel *self);
-static void monitor_switch_active_cb (GObject *object, GParamSpec *pspec, gpointer data);
-static void get_geometry (GnomeRROutputInfo *output, int *w, int *h);
-static gboolean get_clone_size (GnomeRRScreen *screen, int *width, int *height);
-static gboolean output_info_supports_mode (CcDisplayPanel *self, GnomeRROutputInfo *info, int width, int 
height);
-static char *make_resolution_string (int width, int height);
-static GObject *cc_display_panel_constructor (GType                  gtype,
-                                             guint                  n_properties,
-                                             GObjectConstructParam *properties);
-static void on_screen_changed (GnomeRRScreen *scr, gpointer data);
-
-static void
-cc_display_panel_get_property (GObject    *object,
-                               guint       property_id,
-                               GValue     *value,
-                               GParamSpec *pspec)
-{
-  switch (property_id)
-    {
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-    }
-}
+static GHashTable *output_ids;
 
-static void
-cc_display_panel_set_property (GObject      *object,
-                               guint         property_id,
-                               const GValue *value,
-                               GParamSpec   *pspec)
+gint
+cc_display_panel_get_output_id (GnomeRROutputInfo *output)
 {
-  switch (property_id)
-    {
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-    }
+  if (output_ids)
+    return GPOINTER_TO_INT (g_hash_table_lookup (output_ids, output));
+  else
+    return 0;
 }
 
 static void
 cc_display_panel_dispose (GObject *object)
 {
   CcDisplayPanelPrivate *priv = CC_DISPLAY_PANEL (object)->priv;
-
-  g_clear_object (&priv->up_client);
-
-  G_OBJECT_CLASS (cc_display_panel_parent_class)->dispose (object);
-}
-
-static void
-cc_display_panel_finalize (GObject *object)
-{
-  CcDisplayPanel *self;
   CcShell *shell;
   GtkWidget *toplevel;
 
-  self = CC_DISPLAY_PANEL (object);
-
-  g_signal_handlers_disconnect_by_func (self->priv->screen, on_screen_changed, self);
-  g_object_unref (self->priv->screen);
-  g_object_unref (self->priv->builder);
-
-  if (self->priv->clock_settings != NULL)
-    g_object_unref (self->priv->clock_settings);
+  if (output_ids)
+    {
+      g_hash_table_destroy (output_ids);
+      output_ids = NULL;
+    }
 
-  shell = cc_panel_get_shell (CC_PANEL (self));
-  if (shell != NULL)
+  if (priv->focus_id)
     {
+      shell = cc_panel_get_shell (CC_PANEL (object));
       toplevel = cc_shell_get_toplevel (shell);
       if (toplevel != NULL)
         g_signal_handler_disconnect (G_OBJECT (toplevel),
-                                     self->priv->focus_id);
+                                     priv->focus_id);
+      cc_rr_labeler_hide (priv->labeler);
+      priv->focus_id = 0;
     }
+  g_clear_object (&priv->labeler);
 
-  cc_rr_labeler_hide (self->priv->labeler);
-  g_object_unref (self->priv->labeler);
+  if (priv->screen_changed_handler_id)
+    {
+      g_signal_handler_disconnect (priv->screen, priv->screen_changed_handler_id);
+      priv->screen_changed_handler_id = 0;
+    }
+
+  g_clear_object (&priv->screen);
+  g_clear_object (&priv->up_client);
 
-  G_OBJECT_CLASS (cc_display_panel_parent_class)->finalize (object);
+  G_OBJECT_CLASS (cc_display_panel_parent_class)->dispose (object);
 }
 
 static const char *
@@ -205,35 +152,7 @@ cc_display_panel_class_init (CcDisplayPanelClass *klass)
 
   panel_class->get_help_uri = cc_display_panel_get_help_uri;
 
-  object_class->constructor = cc_display_panel_constructor;
-  object_class->get_property = cc_display_panel_get_property;
-  object_class->set_property = cc_display_panel_set_property;
   object_class->dispose = cc_display_panel_dispose;
-  object_class->finalize = cc_display_panel_finalize;
-}
-
-static void
-error_message (CcDisplayPanel *self, const char *primary_text, const char *secondary_text)
-{
-  GtkWidget *toplevel;
-  GtkWidget *dialog;
-
-  if (self && self->priv->panel)
-    toplevel = gtk_widget_get_toplevel (self->priv->panel);
-  else
-    toplevel = NULL;
-
-  dialog = gtk_message_dialog_new (GTK_WINDOW (toplevel),
-                                   GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
-                                   GTK_MESSAGE_ERROR,
-                                   GTK_BUTTONS_CLOSE,
-                                   "%s", primary_text);
-
-  if (secondary_text)
-    gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", secondary_text);
-
-  gtk_dialog_run (GTK_DIALOG (dialog));
-  gtk_widget_destroy (dialog);
 }
 
 static gboolean
@@ -250,33 +169,6 @@ should_show_resolution (gint output_width,
   return FALSE;
 }
 
-static void
-on_screen_changed (GnomeRRScreen *scr,
-                   gpointer data)
-{
-  GnomeRRConfig *current;
-  CcDisplayPanel *self = data;
-
-  current = gnome_rr_config_new_current (self->priv->screen, NULL);
-  gnome_rr_config_ensure_primary (current);
-
-  if (self->priv->current_configuration)
-    g_object_unref (self->priv->current_configuration);
-
-  self->priv->current_configuration = current;
-  self->priv->current_output = NULL;
-
-  if (self->priv->labeler) {
-    cc_rr_labeler_hide (self->priv->labeler);
-    g_object_unref (self->priv->labeler);
-  }
-
-  self->priv->labeler = cc_rr_labeler_new (self->priv->current_configuration);
-  if (gtk_widget_has_focus (self->priv->panel))
-     cc_rr_labeler_show (self->priv->labeler);
-
-  select_current_output_from_dialog_position (self);
-}
 
 static void
 on_viewport_changed (FooScrollArea *scroll_area,
@@ -291,693 +183,274 @@ on_viewport_changed (FooScrollArea *scroll_area,
 }
 
 static void
-layout_set_font (PangoLayout *layout, const char *font)
+paint_output (cairo_t           *cr,
+              GnomeRRConfig     *configuration,
+              GnomeRROutputInfo *output,
+              gint               num,
+              gint               allocated_width,
+              gint               allocated_height)
 {
-  PangoFontDescription *desc =
-    pango_font_description_from_string (font);
-
-  if (desc)
+  GnomeRRRotation rotation;
+  cairo_text_extents_t extents;
+  gint x, y, width, height;
+  gint max_extent;
+  gboolean active;
+
+  active = gnome_rr_output_info_is_active (output);
+  if (active)
+    gnome_rr_output_info_get_geometry (output, NULL, NULL, &width, &height);
+  else
     {
-      pango_layout_set_font_description (layout, desc);
-
-      pango_font_description_free (desc);
+      width = gnome_rr_output_info_get_preferred_width (output);
+      height = gnome_rr_output_info_get_preferred_height (output);
     }
-}
-
-static void
-clear_combo (GtkWidget *widget)
-{
-  GtkComboBox *box = GTK_COMBO_BOX (widget);
-  GtkTreeModel *model = gtk_combo_box_get_model (box);
-  GtkListStore *store = GTK_LIST_STORE (model);
-
-  gtk_list_store_clear (store);
-}
 
-typedef struct
-{
-  const char *text;
-  gboolean found;
-  GtkTreeIter iter;
-} ForeachInfo;
+  rotation = gnome_rr_output_info_get_rotation (output);
 
-static gboolean
-foreach (GtkTreeModel *model,
-         GtkTreePath *path,
-         GtkTreeIter *iter,
-         gpointer data)
-{
-  ForeachInfo *info = data;
-  char *text = NULL;
+  x = y = 0;
 
-  gtk_tree_model_get (model, iter, TEXT_COL, &text, -1);
+  if ((rotation & GNOME_RR_ROTATION_90) || (rotation & GNOME_RR_ROTATION_270))
+    {
+      gint tmp;
 
-  g_assert (text != NULL);
+      /* swap width and height */
+      tmp = width;
+      width = height;
+      height = tmp;
+    }
 
-  if (strcmp (info->text, text) == 0)
+  /* scale to fit allocation */
+  if (width / (double) height < allocated_width / (double) allocated_height)
     {
-      info->found = TRUE;
-      info->iter = *iter;
-      return TRUE;
+      width = allocated_height * (width / (double) height);
+      height = allocated_height;
+    }
+  else
+    {
+      height = allocated_width * (height / (double) width);
+      width = allocated_width;
     }
 
-  return FALSE;
-}
-
-static void
-add_key (GtkTreeModel *model,
-         const char *text,
-         gboolean preferred,
-         int width, int height, int rate,
-         GnomeRRRotation rotation)
-{
-  ForeachInfo info;
-
-  info.text = text;
-  info.found = FALSE;
 
-  gtk_tree_model_foreach (model, foreach, &info);
+  x = (allocated_width / 2.0) - (width / 2.0);
+  cairo_set_source_rgb (cr, 0, 0, 0);
+  cairo_rectangle (cr, x, y, width, height);
+  cairo_fill (cr);
 
-  if (!info.found)
+  if (gnome_rr_output_info_get_primary (output)
+      || gnome_rr_config_get_clone (configuration))
     {
-      GtkTreeIter iter;
-      g_debug ("adding %s with rate %d Hz", text, rate);
-      gtk_list_store_insert_with_values (GTK_LIST_STORE (model), &iter, -1,
-                                         TEXT_COL, text,
-                                         WIDTH_COL, width,
-                                         HEIGHT_COL, height,
-                                         RATE_COL, rate,
-                                         SORT_COL, width * 10000 + height,
-                                         ROTATION_COL, rotation,
-                                         -1);
-      return;
-    }
+      gint top_bar_height;
 
-  /* Look, the preferred output, replace the old one */
-  if (preferred)
-    {
-      g_debug ("replacing %s with rate %d Hz (preferred mode)", text, rate);
-      gtk_list_store_set (GTK_LIST_STORE (model), &info.iter,
-                          RATE_COL, rate,
-                          -1);
-      return;
-    }
+      top_bar_height = height / 12;
 
-  {
-    int old_rate;
+      y += top_bar_height;
+      height -= top_bar_height;
+    }
 
-    gtk_tree_model_get (model, &info.iter,
-                        RATE_COL, &old_rate,
-                        -1);
+  cairo_set_source_rgb (cr, 0.7, 0.7, 0.7);
+  cairo_rectangle (cr, x + 1, y + 1, width - 2, height - 2);
+  cairo_fill (cr);
 
-    /* Higher refresh rate */
-    if (rate > old_rate)
+  if (num > 0)
     {
-      g_debug ("replacing %s with rate %d Hz (old rate: %d)", text, rate, old_rate);
-      gtk_list_store_set (GTK_LIST_STORE (model), &info.iter,
-                          RATE_COL, rate,
-                          -1);
-      return;
-    }
-  }
+      gchar *number_str;
 
-  g_debug ("not adding %s with rate %d Hz (higher rate already there)", text, rate);
-}
+      number_str = g_strdup_printf ("%d", num);
+      cairo_text_extents (cr, number_str, &extents);
 
-static void
-add_mode (CcDisplayPanel *self,
-         GnomeRRMode *mode,
-         gint  output_width,
-         gint  output_height,
-         guint preferred_id)
-{
-  int width, height, rate;
+      cairo_set_source_rgb (cr, 0, 0, 0);
+      max_extent = MAX (extents.width, extents.height);
+      cairo_rectangle (cr, x + 5, y + 5, max_extent + 10, max_extent + 10);
+      cairo_fill (cr);
 
-  width = gnome_rr_mode_get_width (mode);
-  height = gnome_rr_mode_get_height (mode);
-  rate = gnome_rr_mode_get_freq (mode);
+      cairo_set_source_rgb (cr, 1, 1, 1);
+      cairo_move_to (cr, x + 10, y + 10 + extents.height);
+      cairo_show_text (cr, number_str);
 
-  if (should_show_resolution (output_width, output_height, width, height))
-    {
-      char *text;
-      gboolean preferred;
-
-      preferred = (gnome_rr_mode_get_id (mode) == preferred_id);
-      text = make_resolution_string (width, height);
-      add_key (gtk_combo_box_get_model (GTK_COMBO_BOX (self->priv->resolution_combo)),
-               text, preferred, width, height, rate, -1);
-      g_free (text);
+      g_free (number_str);
     }
 }
 
-
-
 static gboolean
-combo_select (GtkWidget *widget, const char *text)
+display_preview_draw (GtkWidget      *widget,
+                      cairo_t        *cr,
+                      gpointer        data)
 {
-  GtkComboBox *box = GTK_COMBO_BOX (widget);
-  GtkTreeModel *model = gtk_combo_box_get_model (box);
-  ForeachInfo info;
+  GnomeRROutputInfo *output;
+  GnomeRRConfig *config;
+  gint num, width, height;
 
-  info.text = text;
-  info.found = FALSE;
+  output = g_object_get_data (G_OBJECT (widget), "output");
+  config = g_object_get_data (G_OBJECT (widget), "config");
+  num = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "number"));
 
-  gtk_tree_model_foreach (model, foreach, &info);
+  width = gtk_widget_get_allocated_width (widget);
+  height = gtk_widget_get_allocated_height (widget);
 
-  if (!info.found)
-    return FALSE;
+  paint_output (cr, config, output, num, width, height);
 
-  gtk_combo_box_set_active_iter (box, &info.iter);
   return TRUE;
 }
 
-static GnomeRRMode **
-get_current_modes (CcDisplayPanel *self)
+static GtkWidget*
+display_preview_new (GnomeRROutputInfo *output,
+                     GnomeRRConfig     *config,
+                     gint               num,
+                     gint               base_height)
 {
-  GnomeRROutput *output;
+  GtkWidget *area;
+  gint width, height, x, y;
+  gboolean active;
 
-  if (gnome_rr_config_get_clone (self->priv->current_configuration))
-    {
-      return gnome_rr_screen_list_clone_modes (self->priv->screen);
-    }
+  active = gnome_rr_output_info_is_active (output);
+  if (active)
+    gnome_rr_output_info_get_geometry (output, &x, &y, &width, &height);
   else
     {
-      if (!self->priv->current_output)
-        return NULL;
-
-      output = gnome_rr_screen_get_output_by_name (self->priv->screen,
-                                                   gnome_rr_output_info_get_name 
(self->priv->current_output));
-
-      if (!output)
-        return NULL;
-
-      return gnome_rr_output_list_modes (output);
-    }
-}
-
-static void
-rebuild_rotation_combo (CcDisplayPanel *self)
-{
-  typedef struct
-  {
-    GnomeRRRotation    rotation;
-    const char *       name;
-  } RotationInfo;
-  static const RotationInfo rotations[] = {
-    { GNOME_RR_ROTATION_0, NC_("display panel, rotation", "Normal") },
-    { GNOME_RR_ROTATION_90, NC_("display panel, rotation", "Counterclockwise") },
-    { GNOME_RR_ROTATION_270, NC_("display panel, rotation", "Clockwise") },
-    { GNOME_RR_ROTATION_180, NC_("display panel, rotation", "180 Degrees") },
-  };
-  const char *selection;
-  GnomeRRRotation current;
-  int i;
-
-  clear_combo (self->priv->rotation_combo);
-
-  gtk_widget_set_sensitive (self->priv->rotation_combo,
-                            self->priv->current_output && gnome_rr_output_info_is_active 
(self->priv->current_output));
-
-  if (!self->priv->current_output)
-    return;
-
-  current = gnome_rr_output_info_get_rotation (self->priv->current_output);
-
-  selection = NULL;
-  for (i = 0; i < G_N_ELEMENTS (rotations); ++i)
-    {
-      const RotationInfo *info = &(rotations[i]);
-
-      gnome_rr_output_info_set_rotation (self->priv->current_output, info->rotation);
-
-      /* NULL-GError --- FIXME: we should say why this rotation is not available! */
-      if (gnome_rr_config_applicable (self->priv->current_configuration, self->priv->screen, NULL))
-        {
-          add_key (gtk_combo_box_get_model (GTK_COMBO_BOX (self->priv->rotation_combo)), g_dpgettext2 (NULL, 
"display panel, rotation", info->name), FALSE, 0, 0, 0, info->rotation);
-
-          if (info->rotation == current)
-            selection = g_dpgettext2 (NULL, "display panel, rotation", info->name);
-        }
-    }
-
-  gnome_rr_output_info_set_rotation (self->priv->current_output, current);
-
-  if (!(selection && combo_select (self->priv->rotation_combo, selection)))
-    gtk_combo_box_set_active (GTK_COMBO_BOX (self->priv->rotation_combo), 0);
-}
-
-static int
-count_active_outputs (CcDisplayPanel *self)
-{
-  int i, count = 0;
-  GnomeRROutputInfo **outputs = gnome_rr_config_get_outputs (self->priv->current_configuration);
-
-  for (i = 0; outputs[i] != NULL; ++i)
-    {
-      if (gnome_rr_output_info_is_active (outputs[i]))
-        count++;
+      width = gnome_rr_output_info_get_preferred_width (output);
+      height = gnome_rr_output_info_get_preferred_height (output);
     }
 
-  return count;
-}
-
-#if 0
-static int
-count_all_outputs (GnomeRRConfig *config)
-{
-  int i;
-  GnomeRROutputInfo **outputs = gnome_rr_config_get_outputs (config);
-
-  for (i = 0; outputs[i] != NULL; i++)
-    ;
-
-  return i;
-}
-#endif
+  area = gtk_drawing_area_new ();
+  g_signal_connect (area, "draw", G_CALLBACK (display_preview_draw), NULL);
 
-/* Computes whether "Mirror displays" (clone mode) is supported based on these criteria:
- *
- * 1. There is an available size for cloning.
- *
- * 2. There are 2 or more connected outputs that support that size.
- */
-static gboolean
-mirror_screens_is_supported (CcDisplayPanel *self)
-{
-  int clone_width, clone_height;
-  gboolean have_clone_size;
-  gboolean mirror_is_supported;
+  gtk_widget_set_size_request (area, base_height * (width / (gdouble) height), base_height);
 
-  mirror_is_supported = FALSE;
+  gtk_widget_set_valign (area, GTK_ALIGN_CENTER);
+  gtk_widget_set_halign (area, GTK_ALIGN_CENTER);
 
-  have_clone_size = get_clone_size (self->priv->screen, &clone_width, &clone_height);
+  g_object_set_data (G_OBJECT (area), "output", output);
+  g_object_set_data (G_OBJECT (area), "config", config);
+  g_object_set_data (G_OBJECT (area), "number", GINT_TO_POINTER (num));
 
-  if (have_clone_size) {
-    int i;
-    int num_outputs_with_clone_size;
-    GnomeRROutputInfo **outputs = gnome_rr_config_get_outputs (self->priv->current_configuration);
-
-    num_outputs_with_clone_size = 0;
-
-    for (i = 0; outputs[i] != NULL; i++)
-      {
-         /* We count the connected outputs that support the clone size.  It
-          * doesn't matter if those outputs aren't actually On currently; we
-          * will turn them on in on_clone_changed().
-          */
-         if (gnome_rr_output_info_is_connected (outputs[i]) && output_info_supports_mode (self, outputs[i], 
clone_width, clone_height))
-           num_outputs_with_clone_size++;
-      }
-
-    if (num_outputs_with_clone_size >= 2)
-      mirror_is_supported = TRUE;
-  }
-
-  return mirror_is_supported;
+  return area;
 }
 
 static void
-rebuild_mirror_screens (CcDisplayPanel *self)
+on_screen_changed (CcDisplayPanel *panel)
 {
-  gboolean mirror_is_active;
-  gboolean mirror_is_supported;
-
-  g_signal_handlers_block_by_func (self->priv->clone_checkbox, G_CALLBACK (on_clone_changed), self);
-
-  mirror_is_active = self->priv->current_configuration && gnome_rr_config_get_clone 
(self->priv->current_configuration);
-
-  /* If mirror_is_active, then it *must* be possible to turn mirroring off */
-  mirror_is_supported = mirror_is_active || mirror_screens_is_supported (self);
-
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->priv->clone_checkbox), mirror_is_active);
-  gtk_widget_set_sensitive (self->priv->clone_checkbox, mirror_is_supported);
-  gtk_widget_set_sensitive (self->priv->clone_label, mirror_is_supported);
-
-  g_signal_handlers_unblock_by_func (self->priv->clone_checkbox, G_CALLBACK (on_clone_changed), self);
-}
+  GnomeRRConfig *current;
+  CcDisplayPanelPrivate *priv = panel->priv;
+  GnomeRROutputInfo **outputs;
+  gint i, num_active_outputs = 0, num_connected_outputs = 0, number = 0;
+  gboolean clone, combined = FALSE;
+  GtkSizeGroup *sizegroup;
 
-static char *
-mirror_monitor_name (void)
-{
-  /* Keep this string in sync with gnome-desktop/libgnome-desktop/gnome-rr-labeler.c */
+  gnome_rr_screen_refresh (priv->screen, NULL);
 
-  /* Translators:  this is the feature where what you see on your laptop's
-   * screen is the same as your external projector.  Here, "Mirrored" is being
-   * used as an adjective.  For example, the Spanish translation could be
-   * "Pantallas en Espejo".
-   */
-  return g_strdup (_("Mirrored Displays"));
-}
+  current = gnome_rr_config_new_current (priv->screen, NULL);
+  gnome_rr_config_ensure_primary (current);
 
-static void
-rebuild_current_monitor_label (CcDisplayPanel *self)
-{
-  char *str, *tmp;
-  GdkRGBA color;
-  gboolean use_color;
+  gtk_container_foreach (GTK_CONTAINER (priv->displays_listbox),
+                         (GtkCallback) gtk_widget_destroy, NULL);
 
-  if (self->priv->current_output)
-    {
-      if (gnome_rr_config_get_clone (self->priv->current_configuration))
-        tmp = mirror_monitor_name ();
-      else
-        tmp = g_strdup (gnome_rr_output_info_get_display_name (self->priv->current_output));
+  if (priv->current_configuration)
+    g_object_unref (priv->current_configuration);
 
-      str = g_strdup_printf ("<b>%s</b>", tmp);
-      cc_rr_labeler_get_rgba_for_output (self->priv->labeler, self->priv->current_output, &color);
-      use_color = TRUE;
-      g_free (tmp);
-    }
-  else
-    {
-      str = g_strdup_printf ("<b>%s</b>", _("Monitor"));
-      use_color = FALSE;
-    }
+  priv->current_configuration = current;
 
-  gtk_label_set_markup (GTK_LABEL (self->priv->current_monitor_label), str);
-  g_free (str);
+  clone = gnome_rr_config_get_clone (current);
 
-  if (use_color)
-    {
-      GdkRGBA black = { 0, 0, 0, 1.0 };
+  outputs = gnome_rr_config_get_outputs (current);
 
-      gtk_widget_override_background_color (self->priv->current_monitor_event_box,
-                                            gtk_widget_get_state_flags 
(self->priv->current_monitor_event_box),
-                                            &color);
+  g_hash_table_remove_all (output_ids);
 
-      /* Make the label explicitly black.  We don't want it to follow the
-       * theme's colors, since the label is always shown against a light
-       * pastel background.  See bgo#556050
-       */
-      gtk_widget_override_color (self->priv->current_monitor_label,
-                                 gtk_widget_get_state_flags (self->priv->current_monitor_label),
-                                 &black);
-    }
-  else
+  /* count the number of active and connected outputs */
+  for (i = 0; outputs[i]; i++)
     {
-      /* Remove any modifications we did on the label's color */
-      gtk_widget_override_color (self->priv->current_monitor_label,
-                                 gtk_widget_get_state_flags (self->priv->current_monitor_label),
-                                 NULL);
+      if (gnome_rr_output_info_is_active (outputs[i]))
+        num_active_outputs++;
+      num_connected_outputs++;
     }
 
-    gtk_event_box_set_visible_window (GTK_EVENT_BOX (self->priv->current_monitor_event_box), use_color);
-}
-
-static void
-rebuild_on_off_radios (CcDisplayPanel *self)
-{
-  gboolean sensitive;
-  gboolean on_active;
-
-  g_signal_handlers_block_by_func (self->priv->monitor_switch, G_CALLBACK (monitor_switch_active_cb), self);
+  sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
 
-  sensitive = FALSE;
-  on_active = FALSE;
-
-  if (!gnome_rr_config_get_clone (self->priv->current_configuration) && self->priv->current_output)
+  for (i = 0; outputs[i]; i++)
     {
+      GtkWidget *row, *item, *preview, *label;
+      gboolean primary, active;
+      gint x, y, width, height;
+      const gchar *status;
       gboolean display_closed = FALSE;
 
-      if (self->priv->lid_is_closed)
+      if (priv->lid_is_closed)
         {
           GnomeRROutput *output;
 
-          output = gnome_rr_screen_get_output_by_name (self->priv->screen,
-                                                       gnome_rr_output_info_get_name 
(self->priv->current_output));
+          output = gnome_rr_screen_get_output_by_name (priv->screen,
+                                                       gnome_rr_output_info_get_name (outputs[i]));
 
           display_closed = gnome_rr_output_is_builtin_display (output);
         }
 
-      if ((count_active_outputs (self) > 1 || !gnome_rr_output_info_is_active (self->priv->current_output))
-          && !display_closed)
-        sensitive = TRUE;
-      else
-        sensitive = FALSE;
-
-      on_active = gnome_rr_output_info_is_active (self->priv->current_output);
-    }
-
-  gtk_widget_set_sensitive (self->priv->monitor_switch, sensitive);
-
-  gtk_switch_set_active (GTK_SWITCH (self->priv->monitor_switch), on_active);
-
-  g_signal_handlers_unblock_by_func (self->priv->monitor_switch, G_CALLBACK (monitor_switch_active_cb), 
self);
-}
-
-static char *
-make_resolution_string (int width, int height)
-{
-  int ratio;
-  const char *aspect = NULL;
-
-    /* We use a number of Unicode characters below:
-     * ∶ is U+2236 RATIO
-     *   is U+2009 THIN SPACE,
-     * × is U+00D7 MULTIPLICATION SIGN
-     */
-  if (width && height) {
-    if (width > height)
-      ratio = width * 10 / height;
-    else
-      ratio = height * 10 / width;
-
-    switch (ratio) {
-    case 13:
-      aspect = "4∶3";
-      break;
-    case 16:
-      aspect = "16∶10";
-      break;
-    case 17:
-      aspect = "16∶9";
-      break;
-    case 23:
-      aspect = "21∶9";
-      break;
-    case 12:
-      aspect = "5∶4";
-      break;
-      /* This catches 1.5625 as well (1600x1024) when maybe it shouldn't. */
-    case 15:
-      aspect = "3∶2";
-      break;
-    case 18:
-      aspect = "9∶5";
-      break;
-    case 10:
-      aspect = "1∶1";
-      break;
-    }
-  }
-
-  if (aspect != NULL)
-    return g_strdup_printf ("%d × %d (%s)", width, height, aspect);
-  else
-    return g_strdup_printf ("%d × %d", width, height);
-}
-
-static void
-find_best_mode (GnomeRRMode **modes, int *out_width, int *out_height)
-{
-  int i;
+      row = gtk_list_box_row_new ();
+      item = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
+      gtk_container_set_border_width (GTK_CONTAINER (item), 12);
 
-  *out_width = 0;
-  *out_height = 0;
+      active = gnome_rr_output_info_is_active (outputs[i]);
 
-  for (i = 0; modes[i] != NULL; i++)
-    {
-      int w, h;
+      gnome_rr_output_info_get_geometry (outputs[i], &x, &y, &width, &height);
 
-      w = gnome_rr_mode_get_width (modes[i]);
-      h = gnome_rr_mode_get_height (modes[i]);
-
-      if (w * h > *out_width * *out_height)
+      if (!active)
         {
-          *out_width = w;
-          *out_height = h;
+          width = gnome_rr_output_info_get_preferred_width (outputs[i]);
+          height = gnome_rr_output_info_get_preferred_height (outputs[i]);
         }
-    }
-}
-
-static void
-rebuild_resolution_combo (CcDisplayPanel *self)
-{
-  int i;
-  GnomeRRMode **modes;
-  GnomeRRMode *mode;
-  char *current;
-  int output_width, output_height;
-  guint32 preferred_id;
-  GnomeRROutput *output;
-
-  clear_combo (self->priv->resolution_combo);
-
-  if (!(modes = get_current_modes (self))
-      || !self->priv->current_output
-      || !gnome_rr_output_info_is_active (self->priv->current_output))
-    {
-      gtk_widget_set_sensitive (self->priv->resolution_combo, FALSE);
-      return;
-    }
-
-  g_assert (self->priv->current_output != NULL);
-
-  gnome_rr_output_info_get_geometry (self->priv->current_output, NULL, NULL, &output_width, &output_height);
-  g_assert (output_width != 0 && output_height != 0);
-
-  gtk_widget_set_sensitive (self->priv->resolution_combo, TRUE);
-
-  output = gnome_rr_screen_get_output_by_name (self->priv->screen,
-                                               gnome_rr_output_info_get_name (self->priv->current_output));
-  mode = gnome_rr_output_get_preferred_mode (output);
-  preferred_id = gnome_rr_mode_get_id (mode);
-
-  for (i = 0; modes[i] != NULL; ++i)
-    add_mode (self, modes[i], output_width, output_height, preferred_id);
-
-  /* And force the preferred mode in the drop-down (when not in clone mode)
-   * https://bugzilla.gnome.org/show_bug.cgi?id=680969 */
-  if (!gnome_rr_config_get_clone (self->priv->current_configuration))
-   add_mode (self, mode, output_width, output_height, preferred_id);
-
-  current = make_resolution_string (output_width, output_height);
 
-  if (!combo_select (self->priv->resolution_combo, current))
-    {
-      int best_w, best_h;
-      char *str;
-
-      find_best_mode (modes, &best_w, &best_h);
-      str = make_resolution_string (best_w, best_h);
-      combo_select (self->priv->resolution_combo, str);
-      g_free (str);
-    }
-
-  g_free (current);
-}
-
-static void
-rebuild_gui (CcDisplayPanel *self)
-{
-  /* We would break spectacularly if we recursed, so
-   * just assert if that happens
-   */
-  g_assert (self->priv->ignore_gui_changes == FALSE);
-
-  self->priv->ignore_gui_changes = TRUE;
-
-  rebuild_mirror_screens (self);
-  rebuild_current_monitor_label (self);
-  rebuild_on_off_radios (self);
-  rebuild_resolution_combo (self);
-  rebuild_rotation_combo (self);
-
-  self->priv->ignore_gui_changes = FALSE;
-}
-
-static gboolean
-get_mode (GtkWidget *widget, int *width, int *height, int *rate, GnomeRRRotation *rot)
-{
-  GtkTreeIter iter;
-  GtkTreeModel *model;
-  GtkComboBox *box = GTK_COMBO_BOX (widget);
-  int dummy;
-
-  if (!gtk_combo_box_get_active_iter (box, &iter))
-    return FALSE;
-
-  if (!width)
-    width = &dummy;
-
-  if (!height)
-    height = &dummy;
-
-  if (!rate)
-    rate = &dummy;
-
-  if (!rot)
-    rot = (GnomeRRRotation *)&dummy;
-
-  model = gtk_combo_box_get_model (box);
-  gtk_tree_model_get (model, &iter,
-                      WIDTH_COL, width,
-                      HEIGHT_COL, height,
-                      RATE_COL, rate,
-                      ROTATION_COL, rot,
-                      -1);
-
-  return TRUE;
+      preview = display_preview_new (outputs[i], current, ++number,
+                                     DISPLAY_PREVIEW_LIST_HEIGHT);
+      gtk_size_group_add_widget (sizegroup, preview);
 
-}
+      if (display_closed)
+        gtk_widget_set_sensitive (row, FALSE);
 
-static void
-on_rotation_changed (GtkComboBox *box, gpointer data)
-{
-  CcDisplayPanel *self = data;
-  GnomeRRRotation rotation;
+      g_hash_table_insert (output_ids, outputs[i], GINT_TO_POINTER (number));
 
-  if (!self->priv->current_output)
-    return;
+      gtk_container_add (GTK_CONTAINER (item), preview);
 
-  if (get_mode (self->priv->rotation_combo, NULL, NULL, NULL, &rotation))
-    gnome_rr_output_info_set_rotation (self->priv->current_output, rotation);
+      label = gtk_label_new (gnome_rr_output_info_get_display_name (outputs[i]));
+      gtk_container_add (GTK_CONTAINER (item), label);
 
-  foo_scroll_area_invalidate (FOO_SCROLL_AREA (self->priv->area));
-}
+      primary = gnome_rr_output_info_get_primary (outputs[i]);
+      active = gnome_rr_output_info_is_active (outputs[i]);
 
-static void
-select_resolution_for_current_output (CcDisplayPanel *self)
-{
-  GnomeRRMode **modes;
-  int width, height;
-  int x,y;
-  gnome_rr_output_info_get_geometry (self->priv->current_output, &x, &y, NULL, NULL);
+      if (num_connected_outputs > 1)
+        {
+          if (display_closed)
+            status = _("Lid Closed");
+          else if (clone)
+            /* translators: "Mirrored" describes when both displays show the same view */
+            status = _("Mirrored");
+          else if (primary)
+            status = _("Primary");
+          else if (!active)
+            status = _("Off");
+          else
+            {
+              status = _("Secondary");
+              combined = TRUE;
+            }
 
-  width = gnome_rr_output_info_get_preferred_width (self->priv->current_output);
-  height = gnome_rr_output_info_get_preferred_height (self->priv->current_output);
+          label = gtk_label_new (status);
+          gtk_widget_set_hexpand (label, TRUE);
+          gtk_widget_set_halign (label, GTK_ALIGN_END);
+          gtk_container_add (GTK_CONTAINER (item), label);
+        }
 
-  if (width != 0 && height != 0)
-    {
-      gnome_rr_output_info_set_geometry (self->priv->current_output, x, y, width, height);
-      return;
+      g_object_set_data (G_OBJECT (row), "gnome-rr-output", outputs[i]);
+      gtk_container_add (GTK_CONTAINER (row), item);
+      gtk_container_add (GTK_CONTAINER (priv->displays_listbox), row);
+      gtk_widget_show_all (row);
     }
 
-  modes = get_current_modes (self);
-  if (!modes)
-    return;
-
-  find_best_mode (modes, &width, &height);
-
-  gnome_rr_output_info_set_geometry (self->priv->current_output, x, y, width, height);
-}
-
-static void
-monitor_switch_active_cb (GObject    *object,
-                          GParamSpec *pspec,
-                          gpointer    data)
-{
-  CcDisplayPanel *self = data;
-  gboolean value;
-
-  if (!self->priv->current_output)
-    return;
-
-  value = gtk_switch_get_active (GTK_SWITCH (object));
-
-  if (value)
-    {
-      gnome_rr_output_info_set_active (self->priv->current_output, TRUE);
-      select_resolution_for_current_output (self);
-    }
+  if (combined)
+    gtk_widget_show (priv->arrange_button);
   else
-    {
-      gnome_rr_output_info_set_active (self->priv->current_output, FALSE);
-      gnome_rr_config_ensure_primary (self->priv->current_configuration);
-    }
+    gtk_widget_hide (priv->arrange_button);
 
-  rebuild_gui (self);
-  foo_scroll_area_invalidate (FOO_SCROLL_AREA (self->priv->area));
+  g_clear_object (&priv->labeler);
+  priv->labeler = cc_rr_labeler_new (priv->current_configuration);
 }
 
 static void
@@ -1035,37 +508,6 @@ realign_outputs_after_resolution_change (CcDisplayPanel *self, GnomeRROutputInfo
 }
 
 static void
-on_resolution_changed (GtkComboBox *box, gpointer data)
-{
-  CcDisplayPanel *self = data;
-  int old_width, old_height;
-  int x,y;
-  int width;
-  int height;
-
-  if (!self->priv->current_output)
-    return;
-
-  gnome_rr_output_info_get_geometry (self->priv->current_output, &x, &y, &old_width, &old_height);
-
-  if (get_mode (self->priv->resolution_combo, &width, &height, NULL, NULL))
-    {
-      gnome_rr_output_info_set_geometry (self->priv->current_output, x, y, width, height);
-
-      if (width == 0 || height == 0)
-        gnome_rr_output_info_set_active (self->priv->current_output, FALSE);
-      else
-        gnome_rr_output_info_set_active (self->priv->current_output, TRUE);
-    }
-
-  realign_outputs_after_resolution_change (self, self->priv->current_output, old_width, old_height);
-
-  rebuild_rotation_combo (self);
-
-  foo_scroll_area_invalidate (FOO_SCROLL_AREA (self->priv->area));
-}
-
-static void
 lay_out_outputs_horizontally (CcDisplayPanel *self)
 {
   int i;
@@ -1108,116 +550,6 @@ lay_out_outputs_horizontally (CcDisplayPanel *self)
 
 }
 
-/* FIXME: this function is copied from gnome-settings-daemon/plugins/xrandr/gsd-xrandr-manager.c.
- * Do we need to put this function in gnome-desktop for public use?
- */
-static gboolean
-get_clone_size (GnomeRRScreen *screen, int *width, int *height)
-{
-  GnomeRRMode **modes = gnome_rr_screen_list_clone_modes (screen);
-  int best_w, best_h;
-  int i;
-
-  best_w = 0;
-  best_h = 0;
-
-  for (i = 0; modes[i] != NULL; ++i) {
-    GnomeRRMode *mode = modes[i];
-    int w, h;
-
-    w = gnome_rr_mode_get_width (mode);
-    h = gnome_rr_mode_get_height (mode);
-
-    if (w * h > best_w * best_h) {
-      best_w = w;
-      best_h = h;
-    }
-  }
-
-  if (best_w > 0 && best_h > 0) {
-    if (width)
-      *width = best_w;
-    if (height)
-      *height = best_h;
-
-    return TRUE;
-  }
-
-  return FALSE;
-}
-
-static gboolean
-output_info_supports_mode (CcDisplayPanel *self, GnomeRROutputInfo *info, int width, int height)
-{
-  GnomeRROutput *output;
-  GnomeRRMode **modes;
-  int i;
-
-  if (!gnome_rr_output_info_is_connected (info))
-    return FALSE;
-
-  output = gnome_rr_screen_get_output_by_name (self->priv->screen, gnome_rr_output_info_get_name (info));
-  if (!output)
-    return FALSE;
-
-  modes = gnome_rr_output_list_modes (output);
-
-  for (i = 0; modes[i]; i++) {
-    if (gnome_rr_mode_get_width (modes[i]) == width
-        && gnome_rr_mode_get_height (modes[i]) == height)
-      return TRUE;
-  }
-
-  return FALSE;
-}
-
-static void
-on_clone_changed (GtkWidget *box, gpointer data)
-{
-  CcDisplayPanel *self = data;
-
-  gnome_rr_config_set_clone (self->priv->current_configuration, gtk_toggle_button_get_active 
(GTK_TOGGLE_BUTTON (self->priv->clone_checkbox)));
-
-  if (gnome_rr_config_get_clone (self->priv->current_configuration))
-    {
-      int i;
-      int width, height;
-      GnomeRROutputInfo **outputs = gnome_rr_config_get_outputs (self->priv->current_configuration);
-
-      for (i = 0; outputs[i]; ++i)
-       {
-         if (gnome_rr_output_info_is_connected (outputs[i]))
-           {
-             self->priv->current_output = outputs[i];
-             break;
-           }
-       }
-
-      /* Turn on all the connected screens that support the best clone mode.
-       * The user may hit "Mirror displays", but he shouldn't have to turn on
-       * all the required outputs as well.
-       */
-
-      get_clone_size (self->priv->screen, &width, &height);
-
-      for (i = 0; outputs[i]; i++) {
-       int x, y;
-       if (output_info_supports_mode (self, outputs[i], width, height)) {
-         gnome_rr_output_info_set_active (outputs[i], TRUE);
-         gnome_rr_output_info_get_geometry (outputs[i], &x, &y, NULL, NULL);
-         gnome_rr_output_info_set_geometry (outputs[i], x, y, width, height);
-       }
-      }
-    }
-  else
-    {
-      if (output_overlaps (self->priv->current_output, self->priv->current_configuration))
-        lay_out_outputs_horizontally (self);
-    }
-
-  rebuild_gui (self);
-}
-
 static void
 apply_rotation_to_geometry (GnomeRROutputInfo *output, int *w, int *h)
 {
@@ -1298,7 +630,7 @@ get_n_connected (CcDisplayPanel *self)
 }
 
 static double
-compute_scale (CcDisplayPanel *self)
+compute_scale (CcDisplayPanel *self, FooScrollArea *area)
 {
   int available_w, available_h;
   int total_w, total_h;
@@ -1306,7 +638,7 @@ compute_scale (CcDisplayPanel *self)
   GdkRectangle viewport;
   GList *connected_outputs;
 
-  foo_scroll_area_get_viewport (FOO_SCROLL_AREA (self->priv->area), &viewport);
+  foo_scroll_area_get_viewport (area, &viewport);
 
   connected_outputs = list_connected_outputs (self, &total_w, &total_h);
 
@@ -1688,89 +1020,6 @@ set_cursor (GtkWidget *widget, GdkCursorType type)
 }
 
 static void
-set_top_bar_tooltip (CcDisplayPanel *self, gboolean is_dragging)
-{
-  const char *text;
-
-  if (is_dragging)
-    text = NULL;
-  else
-    text = _("Drag to change primary display.");
-
-  gtk_widget_set_tooltip_text (self->priv->area, text);
-}
-
-static void
-on_top_bar_event (FooScrollArea *area,
-                  FooScrollAreaEvent *event,
-                  CcDisplayPanel *self)
-{
-  /* Ignore drops */
-  if (event->type == FOO_DROP)
-    return;
-
-  /* If the mouse is inside the top bar, set the cursor to "you can move me".  See
-   * on_canvas_event() for where we reset the cursor to the default if it
-   * exits the outputs' area.
-   */
-  if (!gnome_rr_config_get_clone (self->priv->current_configuration) && get_n_connected (self) > 1)
-    set_cursor (GTK_WIDGET (area), GDK_HAND1);
-
-  if (event->type == FOO_BUTTON_PRESS)
-    {
-      rebuild_gui (self);
-      set_top_bar_tooltip (self, TRUE);
-
-      if (!gnome_rr_config_get_clone (self->priv->current_configuration) && get_n_connected (self) > 1)
-        {
-          self->priv->dragging_top_bar = TRUE;
-          foo_scroll_area_begin_grab (area, (FooScrollAreaEventFunc) on_top_bar_event, self);
-        }
-
-      foo_scroll_area_invalidate (area);
-    }
-  else
-    {
-      if (foo_scroll_area_is_grabbed (area))
-        {
-          if (event->type == FOO_BUTTON_RELEASE)
-            {
-              foo_scroll_area_end_grab (area, event);
-              self->priv->dragging_top_bar = FALSE;
-              set_top_bar_tooltip (self, FALSE);
-            }
-
-          foo_scroll_area_invalidate (area);
-        }
-    }
-}
-
-static void
-set_monitors_tooltip (CcDisplayPanel *self, gboolean is_dragging)
-{
-  const char *text;
-
-  if (is_dragging)
-    text = NULL;
-  else
-    text = _("Select a monitor to change its properties; drag it to rearrange its placement.");
-
-  gtk_widget_set_tooltip_text (self->priv->area, text);
-}
-
-static void
-set_primary_output (CcDisplayPanel *self,
-                    GnomeRROutputInfo *output)
-{
-  int i;
-  GnomeRROutputInfo **outputs;
-
-  outputs = gnome_rr_config_get_outputs (self->priv->current_configuration);
-  for (i = 0; outputs[i] != NULL; ++i)
-    gnome_rr_output_info_set_primary (outputs[i], outputs[i] == output);
-}
-
-static void
 grab_weak_ref_notify (gpointer  area,
                       GObject  *object)
 {
@@ -1787,8 +1036,6 @@ on_output_event (FooScrollArea *area,
 
   if (event->type == FOO_DRAG_HOVER)
     {
-      if (gnome_rr_output_info_is_active (output) && self->priv->dragging_top_bar)
-        set_primary_output (self, output);
       return;
     }
   if (event->type == FOO_DROP)
@@ -1810,8 +1057,6 @@ on_output_event (FooScrollArea *area,
 
       self->priv->current_output = output;
 
-      rebuild_gui (self);
-      set_monitors_tooltip (self, TRUE);
 
       if (!gnome_rr_config_get_clone (self->priv->current_configuration) && get_n_connected (self) > 1)
        {
@@ -1836,7 +1081,7 @@ on_output_event (FooScrollArea *area,
       if (foo_scroll_area_is_grabbed (area))
        {
          GrabInfo *info = g_object_get_data (G_OBJECT (output), "grab-info");
-         double scale = compute_scale (self);
+         double scale = compute_scale (self, area);
          int old_x, old_y;
          int width, height;
          int new_x, new_y;
@@ -1888,7 +1133,6 @@ on_output_event (FooScrollArea *area,
          if (event->type == FOO_BUTTON_RELEASE)
            {
              foo_scroll_area_end_grab (area, event);
-             set_monitors_tooltip (self, FALSE);
 
              g_free (g_object_get_data (G_OBJECT (output), "grab-info"));
              g_object_set_data (G_OBJECT (output), "grab-info", NULL);
@@ -1916,25 +1160,6 @@ on_canvas_event (FooScrollArea *area,
   set_cursor (GTK_WIDGET (area), GDK_BLANK_CURSOR);
 }
 
-static PangoLayout *
-get_display_name (CcDisplayPanel *self,
-                 GnomeRROutputInfo *output)
-{
-  PangoLayout *layout;
-  char *text;
-
-  if (gnome_rr_config_get_clone (self->priv->current_configuration))
-    text = mirror_monitor_name ();
-  else
-    text = g_strdup (gnome_rr_output_info_get_display_name (output));
-
-  layout = gtk_widget_create_pango_layout (GTK_WIDGET (self->priv->area), text);
-  g_free (text);
-  pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
-
-  return layout;
-}
-
 static void
 paint_background (FooScrollArea *area,
                   cairo_t       *cr)
@@ -1975,217 +1200,6 @@ paint_background (FooScrollArea *area,
 }
 
 static void
-color_shade (double *r,
-             double *g,
-             double *b,
-             double  k)
-{
-  double h, s, v;
-
-  gtk_rgb_to_hsv (*r, *g, *b, &h, &s, &v);
-
-  s *= k;
-  if (s > 1.0)
-    s = 1.0;
-  else if (s < 0.0)
-    s = 0.0;
-
-  v *= k;
-  if (v > 1.0)
-    v = 1.0;
-  else if (v < 0.0)
-    v = 0.0;
-
-  gtk_hsv_to_rgb (h, s, v, r, g, b);
-}
-
-static void
-paint_output (CcDisplayPanel *self, cairo_t *cr, int i)
-{
-  int w, h;
-  double scale = compute_scale (self);
-  double x, y;
-  int output_x, output_y;
-  GnomeRRRotation rotation;
-  int total_w, total_h;
-  GList *connected_outputs = list_connected_outputs (self, &total_w, &total_h);
-  GnomeRROutputInfo *output = g_list_nth (connected_outputs, i)->data;
-  PangoLayout *layout = get_display_name (self, output);
-  PangoRectangle ink_extent, log_extent;
-  GdkRectangle viewport;
-  GdkRGBA output_color;
-  double r, g, b;
-  double available_w;
-  double factor;
-
-  cairo_save (cr);
-
-  foo_scroll_area_get_viewport (FOO_SCROLL_AREA (self->priv->area), &viewport);
-  get_geometry (output, &w, &h);
-
-#if 0
-  g_debug ("%s (%p) geometry %d %d %d primary=%d", output->name, output->name,
-           w, h, output->rate, output->primary);
-#endif
-
-  viewport.height -= 2 * MARGIN;
-  viewport.width -= 2 * MARGIN;
-
-  gnome_rr_output_info_get_geometry (output, &output_x, &output_y, NULL, NULL);
-  x = output_x * scale + MARGIN + (viewport.width - total_w * scale) / 2.0;
-  y = output_y * scale + MARGIN + (viewport.height - total_h * scale) / 2.0;
-
-#if 0
-  g_debug ("scaled: %f %f", x, y);
-
-  g_debug ("scale: %f", scale);
-
-  g_debug ("%f %f %f %f", x, y, w * scale + 0.5, h * scale + 0.5);
-#endif
-
-  cairo_translate (cr,
-                   x + (w * scale + 0.5) / 2,
-                   y + (h * scale + 0.5) / 2);
-
-  /* rotation is already applied in get_geometry */
-
-  rotation = gnome_rr_output_info_get_rotation (output);
-  if (rotation & GNOME_RR_REFLECT_X)
-    cairo_scale (cr, -1, 1);
-
-  if (rotation & GNOME_RR_REFLECT_Y)
-    cairo_scale (cr, 1, -1);
-
-  cairo_translate (cr,
-                   - x - (w * scale + 0.5) / 2,
-                   - y - (h * scale + 0.5) / 2);
-
-  if (output == self->priv->current_output)
-    {
-      GtkStyleContext *context;
-      GdkRGBA color;
-
-      context = gtk_widget_get_style_context (self->priv->area);
-      gtk_style_context_get_background_color (context, GTK_STATE_FLAG_SELECTED, &color);
-
-      cairo_rectangle (cr, x - 2, y - 2, w * scale + 0.5 + 4, h * scale + 0.5 + 4);
-
-      cairo_set_line_width (cr, 4);
-      cairo_set_source_rgba (cr, color.red, color.green, color.blue, 0.5);
-      cairo_stroke (cr);
-    }
-
-  cairo_rectangle (cr, x, y, w * scale + 0.5, h * scale + 0.5);
-  cairo_clip_preserve (cr);
-
-  cc_rr_labeler_get_rgba_for_output (self->priv->labeler, output, &output_color);
-  r = output_color.red;
-  g = output_color.green;
-  b = output_color.blue;
-
-  if (!gnome_rr_output_info_is_active (output))
-    {
-      /* If the output is turned off, just darken the selected color */
-      color_shade (&r, &g, &b, 0.4);
-    }
-
-  cairo_set_source_rgba (cr, r, g, b, 1.0);
-
-  foo_scroll_area_add_input_from_fill (FOO_SCROLL_AREA (self->priv->area),
-                                       cr, on_output_event, output);
-  cairo_fill (cr);
-
-  cairo_rectangle (cr, x + 0.5, y + 0.5, w * scale + 0.5 - 1, h * scale + 0.5 - 1);
-
-  cairo_set_line_width (cr, 1);
-  cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0);
-
-  cairo_stroke (cr);
-  cairo_set_line_width (cr, 2);
-
-  cairo_save (cr);
-
-  layout_set_font (layout, "Sans 10");
-  pango_layout_get_pixel_extents (layout, &ink_extent, &log_extent);
-
-  available_w = w * scale + 0.5 - 6; /* Same as the inner rectangle's width, minus 1 pixel of padding on 
each side */
-  if (available_w < ink_extent.width)
-    factor = available_w / ink_extent.width;
-  else
-    factor = 1.0;
-
-  cairo_move_to (cr,
-                 x + ((w * scale + 0.5) - factor * log_extent.width) / 2,
-                 y + ((h * scale + 0.5) - factor * log_extent.height) / 2);
-
-  cairo_scale (cr, factor, factor);
-  if (gnome_rr_output_info_is_active (output))
-    cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
-  else
-    cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
-
-  pango_cairo_show_layout (cr, layout);
-  g_object_unref (layout);
-  cairo_restore (cr);
-
-  if (gnome_rr_output_info_get_primary (output))
-    {
-      const char *clock_format;
-      char *text;
-      gboolean use_24;
-      GDateTime *dt;
-      GDesktopClockFormat value;
-
-      /* top bar */
-      cairo_rectangle (cr, x, y, w * scale + 0.5, TOP_BAR_HEIGHT);
-      cairo_set_source_rgb (cr, 0, 0, 0);
-      foo_scroll_area_add_input_from_fill (FOO_SCROLL_AREA (self->priv->area),
-                                           cr,
-                                           (FooScrollAreaEventFunc) on_top_bar_event,
-                                           self);
-
-      cairo_fill (cr);
-
-      /* clock */
-      value = g_settings_get_enum (self->priv->clock_settings, CLOCK_FORMAT_KEY);
-      use_24 = value == G_DESKTOP_CLOCK_FORMAT_24H;
-      if (use_24)
-        clock_format = _("%a %R");
-      else
-        clock_format = _("%a %l:%M %p");
-
-      dt = g_date_time_new_now_local ();
-      text = g_date_time_format (dt, clock_format);
-      g_date_time_unref (dt);
-
-      layout = gtk_widget_create_pango_layout (GTK_WIDGET (self->priv->area), text);
-      g_free (text);
-      pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
-
-      layout_set_font (layout, "Sans 4");
-      pango_layout_get_pixel_extents (layout, &ink_extent, &log_extent);
-
-      if (available_w < ink_extent.width)
-        factor = available_w / ink_extent.width;
-      else
-        factor = 1.0;
-
-      cairo_move_to (cr,
-                     x + ((w * scale + 0.5) - factor * log_extent.width) / 2,
-                     y + (TOP_BAR_HEIGHT - factor * log_extent.height) / 2);
-
-      cairo_scale (cr, factor, factor);
-
-      cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
-
-      pango_cairo_show_layout (cr, layout);
-      g_object_unref (layout);
-    }
-
-  cairo_restore (cr);
-}
-
-static void
 on_area_paint (FooScrollArea  *area,
                cairo_t        *cr,
                gpointer        data)
@@ -2203,43 +1217,45 @@ on_area_paint (FooScrollArea  *area,
 
   for (list = connected_outputs; list != NULL; list = list->next)
     {
-      paint_output (self, cr, g_list_position (connected_outputs, list));
+      int w, h;
+      double scale = compute_scale (self, area);
+      double x, y;
+      int output_x, output_y;
+      int total_w, total_h;
+      GList *connected_outputs;
+      GnomeRROutputInfo *output = list->data;
+      GdkRectangle viewport;
 
-      if (gnome_rr_config_get_clone (self->priv->current_configuration))
-       break;
-    }
-}
+      cairo_save (cr);
 
-static void
-make_text_combo (GtkWidget *widget, int sort_column)
-{
-  GtkComboBox *box = GTK_COMBO_BOX (widget);
-  GtkListStore *store = gtk_list_store_new (
-                                            NUM_COLS,
-                                            G_TYPE_STRING,          /* Text */
-                                            G_TYPE_INT,             /* Width */
-                                            G_TYPE_INT,             /* Height */
-                                            G_TYPE_INT,             /* Frequency */
-                                            G_TYPE_INT,             /* Width * Height */
-                                            G_TYPE_INT);            /* Rotation */
+      connected_outputs = list_connected_outputs (self, &total_w, &total_h);
+      g_list_free (connected_outputs);
 
-  GtkCellRenderer *cell;
+      foo_scroll_area_get_viewport (area, &viewport);
+      get_geometry (output, &w, &h);
 
-  gtk_cell_layout_clear (GTK_CELL_LAYOUT (widget));
+      viewport.height -= 2 * MARGIN;
+      viewport.width -= 2 * MARGIN;
 
-  gtk_combo_box_set_model (box, GTK_TREE_MODEL (store));
+      gnome_rr_output_info_get_geometry (output, &output_x, &output_y, NULL, NULL);
+      x = output_x * scale + MARGIN + (viewport.width - total_w * scale) / 2.0;
+      y = output_y * scale + MARGIN + (viewport.height - total_h * scale) / 2.0;
 
-  cell = gtk_cell_renderer_text_new ();
-  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (box), cell, TRUE);
-  gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (box), cell,
-                                  "text", 0,
-                                  NULL);
 
-  if (sort_column != -1)
-    {
-      gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
-                                            sort_column,
-                                            GTK_SORT_DESCENDING);
+      cairo_set_source_rgba (cr, 0, 0, 0, 0);
+      cairo_rectangle (cr, x, y, w * scale + 0.5, h * scale + 0.5);
+      foo_scroll_area_add_input_from_fill (area, cr, on_output_event, output);
+      cairo_fill (cr);
+
+      cairo_translate (cr, x, y);
+      paint_output (cr, self->priv->current_configuration, list->data,
+                    cc_display_panel_get_output_id (list->data),
+                    w * scale, h * scale);
+
+      cairo_restore (cr);
+
+      if (gnome_rr_config_get_clone (self->priv->current_configuration))
+        break;
     }
 }
 
@@ -2298,166 +1314,288 @@ check_required_virtual_size (CcDisplayPanel *self)
 }
 
 static void
-sanitize_configuration (CcDisplayPanel *self)
+apply_current_configuration (CcDisplayPanel *self)
 {
+  GError *error = NULL;
+
   gnome_rr_config_sanitize (self->priv->current_configuration);
   gnome_rr_config_ensure_primary (self->priv->current_configuration);
 
   check_required_virtual_size (self);
 
-  foo_scroll_area_invalidate (FOO_SCROLL_AREA (self->priv->area));
+  gnome_rr_config_apply_persistent (self->priv->current_configuration,
+                                    self->priv->screen, &error);
+
+  /* re-read the configuration */
+  on_screen_changed (self);
+
+  if (error)
+    {
+      g_warning ("Error applying configuration: %s", error->message);
+      g_clear_error (&error);
+    }
 }
 
 static void
-apply (CcDisplayPanel *self)
+show_arrange_displays_dialog (GtkButton      *button,
+                              CcDisplayPanel *panel)
+{
+  GtkWidget *dialog, *content_area, *area, *vbox, *label;
+
+  dialog = gtk_dialog_new_with_buttons (_("Arrange Combined Displays"),
+                                        GTK_WINDOW (cc_shell_get_toplevel (cc_panel_get_shell (CC_PANEL 
(panel)))),
+                                        GTK_DIALOG_MODAL,
+                                        _("_Cancel"), GTK_RESPONSE_REJECT,
+                                        _("_Apply"), GTK_RESPONSE_ACCEPT,
+                                        NULL);
+
+  content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+
+  area = (GtkWidget *) foo_scroll_area_new ();
+  g_object_set_data (G_OBJECT (area), "panel", panel);
+
+  foo_scroll_area_set_min_size (FOO_SCROLL_AREA (area), 520, 290);
+  gtk_widget_set_margin_right (area, 12);
+  gtk_widget_set_margin_left (area, 12);
+  gtk_widget_set_size_request (area, 520, 290);
+  g_signal_connect (area, "paint",
+                    G_CALLBACK (on_area_paint), panel);
+  g_signal_connect (area, "viewport_changed",
+                    G_CALLBACK (on_viewport_changed), panel);
+
+  vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+  gtk_container_add (GTK_CONTAINER (vbox), area);
+
+  label = gtk_label_new (_("Drag displays to rearrange them"));
+  gtk_widget_set_margin_top (label, 12);
+  gtk_widget_set_margin_bottom (label, 12);
+  gtk_container_add (GTK_CONTAINER (vbox), label);
+  gtk_style_context_add_class (gtk_widget_get_style_context (label), GTK_STYLE_CLASS_DIM_LABEL);
+
+  gtk_widget_show_all (vbox);
+  gtk_container_add (GTK_CONTAINER (content_area), vbox);
+
+  if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
+    apply_current_configuration (panel);
+  else
+    {
+      /* re-read the previous configuration */
+      on_screen_changed (panel);
+    }
+
+  gtk_widget_destroy (dialog);
+}
+
+static const gchar *
+make_aspect_string (gint width,
+                    gint height)
 {
-  GError *error;
-  gboolean ok;
+  int ratio;
+  const gchar *aspect = NULL;
+
+    /* We use a number of Unicode characters below:
+     * ∶ is U+2236 RATIO
+     *   is U+2009 THIN SPACE,
+     * × is U+00D7 MULTIPLICATION SIGN
+     */
+  if (width && height) {
+    if (width > height)
+      ratio = width * 10 / height;
+    else
+      ratio = height * 10 / width;
 
-  self->priv->apply_button_clicked_timestamp = gtk_get_current_event_time ();
+    switch (ratio) {
+    case 13:
+      aspect = "4∶3";
+      break;
+    case 16:
+      aspect = "16∶10";
+      break;
+    case 17:
+      aspect = "16∶9";
+      break;
+    case 23:
+      aspect = "21∶9";
+      break;
+    case 12:
+      aspect = "5∶4";
+      break;
+      /* This catches 1.5625 as well (1600x1024) when maybe it shouldn't. */
+    case 15:
+      aspect = "3∶2";
+      break;
+    case 18:
+      aspect = "9∶5";
+      break;
+    case 10:
+      aspect = "1∶1";
+      break;
+    }
+  }
 
-  sanitize_configuration (self);
+  return aspect;
+}
 
-  error = NULL;
-  ok = gnome_rr_config_apply_persistent (self->priv->current_configuration,
-                                         self->priv->screen, &error);
+static char *
+make_resolution_string (gint width,
+                        gint height)
+{
+  const char *aspect = make_aspect_string (width, height);
 
-  if (!ok)
-      error_message (self, _("Failed to apply configuration"), error->message);
-  g_clear_error (&error);  
+  if (aspect != NULL)
+    return g_strdup_printf ("%d × %d (%s)", width, height, aspect);
+  else
+    return g_strdup_printf ("%d × %d", width, height);
 }
 
-#if 0
-/* Returns whether the graphics driver doesn't advertise RANDR 1.2 features, and just 1.0 */
-static gboolean
-driver_is_randr_10 (GnomeRRConfig *config)
-{
-  /* In the Xorg code, see xserver/randr/rrinfo.c:RRScanOldConfig().  It gets
-   * called when the graphics driver doesn't support RANDR 1.2 yet, just 1.0.
-   * In that case, the X server's base code (which supports RANDR 1.2) will
-   * simulate having a single output called "default".  For drivers that *do*
-   * support RANDR 1.2, the separate outputs will be named differently, we
-   * hope.
-   *
-   * This heuristic is courtesy of Dirk Mueller <dmueller suse de>
-   *
-   * FIXME: however, we don't even check for XRRQueryVersion() returning 1.2, neither
-   * here nor in gnome-desktop/libgnomedesktop*.c.  Do we need to check for that,
-   * or is gnome_rr_screen_new()'s return value sufficient?
-   */
+static GtkWidget *
+list_box_item (const gchar *title,
+               const gchar *subtitle)
+{
+  GtkWidget *item, *label, *row;
+
+  row = gtk_list_box_row_new ();
+
+  item = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+  gtk_container_set_border_width (GTK_CONTAINER (item), 12);
+
+  label = gtk_label_new (title);
+  gtk_container_add (GTK_CONTAINER (item), label);
+  gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
+  gtk_widget_set_size_request (label, 230, -1);
+  gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+
+  label = gtk_label_new (subtitle);
+  gtk_container_add (GTK_CONTAINER (item), label);
+  gtk_style_context_add_class (gtk_widget_get_style_context (label), GTK_STYLE_CLASS_DIM_LABEL);
+  gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
+  gtk_widget_set_size_request (label, 230, -1);
+  gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
 
-  return (count_all_outputs (config) == 1 && strcmp (gnome_rr_output_info_get_name 
(gnome_rr_config_get_outputs (config)[0]), "default") == 0);
+  gtk_container_add (GTK_CONTAINER (row), item);
+
+  return row;
 }
-#endif
 
 static void
-on_detect_displays (GtkWidget *widget, gpointer data)
+cc_display_panel_list_box_update_header (GtkListBoxRow *row,
+                                         GtkListBoxRow *before,
+                                         gpointer       user_data)
 {
-  CcDisplayPanel *self = data;
-  GError *error;
+  GtkWidget *current;
 
-  error = NULL;
-  if (!gnome_rr_screen_refresh (self->priv->screen, &error)) {
-    if (error) {
-      error_message (self, _("Could not detect displays"), error->message);
-      g_error_free (error);
+  if (before == NULL)
+    return;
+
+  current = gtk_list_box_row_get_header (row);
+  if (current == NULL)
+    {
+      current = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
+      gtk_widget_show (current);
+      gtk_list_box_row_set_header (row, current);
     }
-  }
 }
 
-static GnomeRROutputInfo *
-get_nearest_output (GnomeRRConfig *configuration, int x, int y)
+static void
+setup_resolution_combo_box (CcDisplayPanel  *panel,
+                            GnomeRRMode    **modes,
+                            GnomeRRMode     *current_mode)
 {
-  int i;
-  int nearest_index;
-  int nearest_dist;
-  GnomeRROutputInfo **outputs;
+  CcDisplayPanelPrivate *priv = panel->priv;
+  GtkTreeModel *res_model;
+  GHashTable *resolutions;
+  gint i;
 
-  nearest_index = -1;
-  nearest_dist = G_MAXINT;
+  res_model = gtk_combo_box_get_model (GTK_COMBO_BOX (priv->res_combo));
+  gtk_list_store_clear (GTK_LIST_STORE (res_model));
 
-  outputs = gnome_rr_config_get_outputs (configuration);
-  for (i = 0; outputs[i] != NULL; i++)
+  resolutions = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+  for (i = 0; modes[i] != NULL; i++)
     {
-      int dist_x, dist_y;
-      int output_x, output_y, output_width, output_height;
+      gchar *res;
+      gboolean present;
+      gint output_width, output_height, mode_width, mode_height;
 
-      if (!(gnome_rr_output_info_is_connected (outputs[i]) && gnome_rr_output_info_is_active (outputs[i])))
-       continue;
+      if (!current_mode)
+        current_mode = modes[i];
 
-      gnome_rr_output_info_get_geometry (outputs[i], &output_x, &output_y, &output_width, &output_height);
+      mode_width = gnome_rr_mode_get_width (modes[i]);
+      mode_height = gnome_rr_mode_get_height (modes[i]);
 
-      if (x < output_x)
-       dist_x = output_x - x;
-      else if (x >= output_x + output_width)
-       dist_x = x - (output_x + output_width) + 1;
-      else
-       dist_x = 0;
+      output_width = gnome_rr_output_info_get_preferred_width (priv->current_output);
+      output_height = gnome_rr_output_info_get_preferred_height (priv->current_output);
 
-      if (y < output_y)
-       dist_y = output_y - y;
-      else if (y >= output_y + output_height)
-       dist_y = y - (output_y + output_height) + 1;
-      else
-       dist_y = 0;
+      if (!should_show_resolution (output_width, output_height, mode_width,
+                                   mode_height))
+        continue;
 
-      if (MIN (dist_x, dist_y) < nearest_dist)
-       {
-         nearest_dist = MIN (dist_x, dist_y);
-         nearest_index = i;
-       }
+      res = make_resolution_string (gnome_rr_mode_get_width (modes[i]),
+                                    gnome_rr_mode_get_height (modes[i]));
+      present = GPOINTER_TO_INT (g_hash_table_lookup (resolutions, res));
+      if (!present)
+        {
+          GtkTreeIter iter;
+
+          g_hash_table_insert (resolutions, g_strdup (res),
+                               GINT_TO_POINTER (TRUE));
+
+          gtk_list_store_insert_with_values (GTK_LIST_STORE (res_model), &iter,
+                                             -1, 0, res, 1, modes[i], -1);
+
+          /* select the current mode in the combo box */
+          if (gnome_rr_mode_get_width (modes[i]) == gnome_rr_mode_get_width (current_mode)
+              && gnome_rr_mode_get_height (modes[i]) == gnome_rr_mode_get_height (current_mode))
+            {
+              gtk_combo_box_set_active_iter (GTK_COMBO_BOX (priv->res_combo),
+                                             &iter);
+            }
+        }
+      g_free (res);
     }
 
-  if (nearest_index != -1)
-    return outputs[nearest_index];
-  else
-    return NULL;
+  /* ensure a resolution is selected by default */
+  if (gtk_combo_box_get_active (GTK_COMBO_BOX (priv->res_combo)) == -1)
+    gtk_combo_box_set_active (GTK_COMBO_BOX (priv->res_combo), 0);
+
+  g_hash_table_destroy (resolutions);
 }
 
-/* Gets the output that contains the largest intersection with the window.
- * Logic stolen from gdk_screen_get_monitor_at_window().
- */
-static GnomeRROutputInfo *
-get_output_for_window (GnomeRRConfig *configuration, GdkWindow *window)
-{
-  GdkRectangle win_rect;
-  int i;
-  int largest_area;
-  int largest_index;
-  GnomeRROutputInfo **outputs;
 
-  gdk_window_get_geometry (window, &win_rect.x, &win_rect.y, &win_rect.width, &win_rect.height);
-  gdk_window_get_origin (window, &win_rect.x, &win_rect.y);
+static void
+setup_listbox_row_activated (GtkListBox     *list_box,
+                             GtkListBoxRow  *row,
+                             CcDisplayPanel *panel)
+{
+  CcDisplayPanelPrivate *priv = panel->priv;
+  GnomeRRMode **modes;
+  gint index;
+  GnomeRROutput *output;
 
-  largest_area = 0;
-  largest_index = -1;
+  if (!row)
+    return;
 
-  outputs = gnome_rr_config_get_outputs (configuration);
-  for (i = 0; outputs[i] != NULL; i++)
-    {
-      GdkRectangle output_rect, intersection;
+  index = gtk_list_box_row_get_index (row);
 
-      gnome_rr_output_info_get_geometry (outputs[i], &output_rect.x, &output_rect.y, &output_rect.width, 
&output_rect.height);
+  output = gnome_rr_screen_get_output_by_name (priv->screen,
+                                               gnome_rr_output_info_get_name (priv->current_output));
 
-      if (gnome_rr_output_info_is_connected (outputs[i]) && gdk_rectangle_intersect (&win_rect, 
&output_rect, &intersection))
-       {
-         int area;
+  if (index == DISPLAY_MODE_MIRROR)
+    {
+      modes = gnome_rr_screen_list_clone_modes (priv->screen);
+      gnome_rr_config_set_clone (priv->current_configuration, TRUE);
+    }
+  else
+    {
+      gnome_rr_output_info_set_primary (priv->current_output,
+                                        (index == DISPLAY_MODE_PRIMARY));
+      gnome_rr_config_set_clone (priv->current_configuration, FALSE);
 
-         area = intersection.width * intersection.height;
-         if (area > largest_area)
-           {
-             largest_area = area;
-             largest_index = i;
-           }
-       }
+      modes = gnome_rr_output_list_modes (output);
     }
 
-  if (largest_index != -1)
-    return outputs[largest_index];
-  else
-    return get_nearest_output (configuration,
-                              win_rect.x + win_rect.width / 2,
-                              win_rect.y + win_rect.height / 2);
+  setup_resolution_combo_box (panel, modes,
+                              gnome_rr_output_get_current_mode (output));
 }
 
 static void
@@ -2473,174 +1611,528 @@ dialog_toplevel_focus_changed (GtkWindow      *window,
     cc_rr_labeler_hide (self->priv->labeler);
 }
 
+
 static void
-on_toplevel_realized (GtkWidget     *widget,
-                      CcDisplayPanel *self)
+rotate_left_clicked (GtkButton      *button,
+                     CcDisplayPanel *panel)
 {
-  self->priv->current_output = get_output_for_window (self->priv->current_configuration,
-                                               gtk_widget_get_window (widget));
-  rebuild_gui (self);
+  CcDisplayPanelPrivate *priv = panel->priv;
+  GnomeRRRotation rotation;
+
+  rotation = gnome_rr_output_info_get_rotation (priv->current_output);
+
+  if (rotation & GNOME_RR_ROTATION_0)
+    {
+      rotation = GNOME_RR_ROTATION_90;
+      gtk_widget_set_sensitive (priv->rotate_left_button, FALSE);
+    }
+  else
+    {
+      rotation = GNOME_RR_ROTATION_0;
+      gtk_widget_set_sensitive (priv->rotate_right_button, TRUE);
+    }
+
+  gnome_rr_output_info_set_rotation (priv->current_output, rotation);
 }
 
-/* We select the current output, i.e. select the one being edited, based on
- * which output is showing the configuration dialog.
- */
 static void
-select_current_output_from_dialog_position (CcDisplayPanel *self)
+rotate_right_clicked (GtkButton      *button,
+                      CcDisplayPanel *panel)
 {
-  GtkWidget *toplevel;
+  CcDisplayPanelPrivate *priv = panel->priv;
+  GnomeRRRotation rotation;
 
-  toplevel = gtk_widget_get_toplevel (self->priv->panel);
+  rotation = gnome_rr_output_info_get_rotation (priv->current_output);
 
-  if (gtk_widget_get_realized (toplevel)) {
-    self->priv->current_output = get_output_for_window (self->priv->current_configuration,
-                                                 gtk_widget_get_window (toplevel));
-    rebuild_gui (self);
-  } else {
-    g_signal_connect (toplevel, "realize", G_CALLBACK (on_toplevel_realized), self);
-    self->priv->current_output = NULL;
-  }
+  if (rotation & GNOME_RR_ROTATION_0)
+    {
+      rotation = GNOME_RR_ROTATION_270;
+      gtk_widget_set_sensitive (priv->rotate_right_button, FALSE);
+    }
+  else
+    {
+      rotation = GNOME_RR_ROTATION_0;
+      gtk_widget_set_sensitive (priv->rotate_left_button, TRUE);
+    }
+
+  gnome_rr_output_info_set_rotation (priv->current_output, rotation);
 }
 
-/* This is a GtkWidget::map-event handler.  We wait for the display-properties
- * dialog to be mapped, and then we select the output which corresponds to the
- * monitor on which the dialog is being shown.
- */
-static gboolean
-dialog_map_event_cb (GtkWidget *widget, GdkEventAny *event, gpointer data)
+static const double known_diagonals[] = {
+    12.1,
+    13.3,
+    15.6
+};
+
+static char *
+diagonal_to_str (double d)
 {
-  CcDisplayPanel *self = data;
+    int i;
 
-  select_current_output_from_dialog_position (self);
-  return FALSE;
+    for (i = 0; i < G_N_ELEMENTS (known_diagonals); i++)
+    {
+        double delta;
+
+        delta = fabs(known_diagonals[i] - d);
+        if (delta < 0.1)
+            return g_strdup_printf ("%0.1lf\"", known_diagonals[i]);
+    }
+
+    return g_strdup_printf ("%d\"", (int) (d + 0.5));
 }
 
-static void
-cc_display_panel_init (CcDisplayPanel *self)
+static char *
+make_display_size_string (int width_mm,
+                          int height_mm)
 {
-  g_resources_register (cc_display_get_resource ());
+  char *inches = NULL;
+
+  if (width_mm > 0 && height_mm > 0)
+    {
+      double d = sqrt (width_mm * width_mm + height_mm * height_mm);
+
+      inches = diagonal_to_str (d / 25.4);
+    }
+
+  return inches;
 }
 
 static void
-cc_display_panel_up_client_changed (UpClient       *client,
-                                    CcDisplayPanel *self)
+res_combo_changed (GtkComboBox    *combo,
+                   CcDisplayPanel *panel)
 {
-  CcDisplayPanelPrivate *priv = self->priv;
-  gboolean lid_is_closed;
+  CcDisplayPanelPrivate *priv = panel->priv;
+  GtkTreeModel *res_model;
+  GtkTreeIter iter;
+  GnomeRRMode *mode;
+  gint x, y, width, height;
 
-  lid_is_closed = up_client_get_lid_is_closed (client);
+  res_model = gtk_combo_box_get_model (combo);
 
-  if (lid_is_closed != priv->lid_is_closed)
+  if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter))
     {
-      priv->lid_is_closed = lid_is_closed;
+      gtk_tree_model_get (GTK_TREE_MODEL (res_model), &iter, 1, &mode, -1);
+
+      gnome_rr_output_info_get_geometry (priv->current_output, &x, &y, NULL, NULL);
 
-      rebuild_on_off_radios (self);
+      width = gnome_rr_mode_get_width (mode);
+      height = gnome_rr_mode_get_height (mode);
+
+      gnome_rr_output_info_set_geometry (priv->current_output, x, y, width, height);
     }
 }
 
-static GObject *
-cc_display_panel_constructor (GType                  gtype,
-                              guint                  n_properties,
-                              GObjectConstructParam *properties)
+static void
+show_setup_dialog (CcDisplayPanel *panel)
 {
-  GtkBuilder *builder;
-  GtkWidget *align;
-  GError *error;
-  GObject *obj;
-  CcDisplayPanel *self;
-  CcShell *shell;
-  GtkWidget *toplevel;
-  gchar *objects[] = {"display-panel", NULL};
+  CcDisplayPanelPrivate *priv = panel->priv;
+  GtkWidget *dialog, *listbox, *content_area, *item, *box, *frame, *preview;
+  GtkWidget *label, *rotate_box, *grid;
+  gint i, width_mm, height_mm, old_width, old_height;
+  GnomeRROutput *output;
+  gchar *str;
+  gboolean clone, was_clone, primary, was_primary, active;
+  GtkListStore *res_model;
+  GtkCellRenderer *renderer;
+  GnomeRRRotation rotation;
 
-  obj = G_OBJECT_CLASS (cc_display_panel_parent_class)->constructor (gtype, n_properties, properties);
-  self = CC_DISPLAY_PANEL (obj);
-  self->priv = DISPLAY_PANEL_PRIVATE (self);
+  output = gnome_rr_screen_get_output_by_name (priv->screen,
+                                               gnome_rr_output_info_get_name (priv->current_output));
+
+
+  dialog = gtk_dialog_new_with_buttons (gnome_rr_output_info_get_display_name (priv->current_output),
+                                        GTK_WINDOW (cc_shell_get_toplevel (cc_panel_get_shell (CC_PANEL 
(panel)))),
+                                        GTK_DIALOG_MODAL,
+                                        _("_Cancel"), GTK_RESPONSE_REJECT,
+                                        _("_Apply"), GTK_RESPONSE_ACCEPT,
+                                        NULL);
+  gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
+
+  content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+
+  box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
+  gtk_widget_set_margin_left (box, 12);
+  gtk_widget_set_margin_right (box, 12);
+  gtk_widget_set_margin_top (box, 6);
+  gtk_widget_set_margin_bottom (box, 12);
+  gtk_container_add (GTK_CONTAINER (content_area), box);
+
+  /* configuration grid */
+  grid = gtk_grid_new ();
+  gtk_widget_set_margin_left (grid, 36);
+  gtk_widget_set_margin_right (grid, 36);
+  gtk_widget_set_margin_bottom (grid, 6);
+  gtk_grid_set_column_spacing (GTK_GRID (grid), 12);
+  gtk_grid_set_row_spacing (GTK_GRID (grid), 12);
+
+  /* preview */
+  preview = display_preview_new (priv->current_output,
+                                 priv->current_configuration,
+                                 cc_display_panel_get_output_id (priv->current_output),
+                                 DISPLAY_PREVIEW_SETUP_HEIGHT);
+  gtk_grid_attach (GTK_GRID (grid), preview, 0, 0, 2, 1);
+
+  /* rotation */
+  rotation = gnome_rr_output_info_get_rotation (priv->current_output);
+  rotate_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+  gtk_widget_set_margin_bottom (rotate_box, 12);
+  gtk_style_context_add_class (gtk_widget_get_style_context (rotate_box),
+                               GTK_STYLE_CLASS_LINKED);
+  gtk_grid_attach (GTK_GRID (grid), rotate_box, 0, 1, 2, 1);
+  gtk_widget_set_halign (rotate_box, GTK_ALIGN_CENTER);
+
+  priv->rotate_left_button = gtk_button_new ();
+  if (rotation == GNOME_RR_ROTATION_90)
+    gtk_widget_set_sensitive (priv->rotate_left_button, FALSE);
+  g_signal_connect (priv->rotate_left_button, "clicked",
+                    G_CALLBACK (rotate_left_clicked), panel);
+  g_signal_connect_swapped (priv->rotate_left_button, "clicked",
+                            G_CALLBACK (gtk_widget_queue_draw), preview);
+  gtk_container_add (GTK_CONTAINER (priv->rotate_left_button),
+                     gtk_image_new_from_icon_name ("object-rotate-left-symbolic",
+                                                   GTK_ICON_SIZE_BUTTON));
+  gtk_widget_set_halign (priv->rotate_left_button, GTK_ALIGN_END);
+  gtk_container_add (GTK_CONTAINER (rotate_box), priv->rotate_left_button);
+
+  priv->rotate_right_button = gtk_button_new ();
+  if (rotation == GNOME_RR_ROTATION_270)
+    gtk_widget_set_sensitive (priv->rotate_right_button, FALSE);
+  g_signal_connect (priv->rotate_right_button, "clicked",
+                    G_CALLBACK (rotate_right_clicked), panel);
+  g_signal_connect_swapped (priv->rotate_right_button, "clicked",
+                            G_CALLBACK (gtk_widget_queue_draw), preview);
+  gtk_container_add (GTK_CONTAINER (priv->rotate_right_button),
+                     gtk_image_new_from_icon_name ("object-rotate-right-symbolic",
+                                                   GTK_ICON_SIZE_BUTTON));
+  gtk_widget_set_halign (priv->rotate_right_button, GTK_ALIGN_START);
+  gtk_container_add (GTK_CONTAINER (rotate_box), priv->rotate_right_button);
+
+  /* size */
+  label = gtk_label_new (_("Size"));
+  gtk_style_context_add_class (gtk_widget_get_style_context (label),
+                               GTK_STYLE_CLASS_DIM_LABEL);
+  gtk_grid_attach (GTK_GRID (grid), label, 0, 2, 1, 1);
+  gtk_widget_set_halign (label, GTK_ALIGN_END);
+
+
+  gnome_rr_output_get_physical_size (output, &width_mm, &height_mm);
+  str = make_display_size_string (width_mm, height_mm);
+  label = gtk_label_new (str);
+  gtk_grid_attach (GTK_GRID (grid), label, 1, 2, 1, 1);
+  gtk_widget_set_halign (label, GTK_ALIGN_START);
+  g_free (str);
+
+  /* aspect ratio */
+  label = gtk_label_new (_("Aspect Ratio"));
+  gtk_style_context_add_class (gtk_widget_get_style_context (label),
+                               GTK_STYLE_CLASS_DIM_LABEL);
+  gtk_grid_attach (GTK_GRID (grid), label, 0, 3, 1, 1);
+  gtk_widget_set_halign (label, GTK_ALIGN_END);
+  label = gtk_label_new (make_aspect_string (gnome_rr_output_info_get_preferred_width (priv->current_output),
+                                             gnome_rr_output_info_get_preferred_height 
(priv->current_output)));
+  gtk_grid_attach (GTK_GRID (grid), label, 1, 3, 1, 1);
+  gtk_widget_set_halign (label, GTK_ALIGN_START);
+
+  /* resolution combo box */
+  res_model = gtk_list_store_new (2, G_TYPE_STRING, GNOME_TYPE_RR_MODE);
+  renderer = gtk_cell_renderer_text_new ();
+  priv->res_combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (res_model));
+  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (priv->res_combo), renderer, TRUE);
+  gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (priv->res_combo), renderer, "text", 0);
+  g_signal_connect (priv->res_combo, "changed", G_CALLBACK (res_combo_changed),
+                    panel);
+  g_signal_connect_swapped (priv->res_combo, "changed",
+                            G_CALLBACK (gtk_widget_queue_draw), preview);
+
+  label = gtk_label_new (_("Resolution"));
+  gtk_style_context_add_class (gtk_widget_get_style_context (label),
+                               GTK_STYLE_CLASS_DIM_LABEL);
+  gtk_grid_attach (GTK_GRID (grid), label, 0, 4, 1, 1);
+  gtk_grid_attach (GTK_GRID (grid), priv->res_combo, 1, 4, 1, 1);
+
+  gtk_widget_set_halign (label, GTK_ALIGN_END);
+  gtk_widget_set_halign (priv->res_combo, GTK_ALIGN_START);
+
+  was_clone = clone = gnome_rr_config_get_clone (priv->current_configuration);
+  was_primary = primary = gnome_rr_output_info_get_primary (priv->current_output);
+  active = gnome_rr_output_info_is_active (priv->current_output);
+
+  if (g_hash_table_size (output_ids) > 1)
+    {
+      frame = gtk_frame_new (NULL);
+      gtk_container_add (GTK_CONTAINER (box), frame);
+      gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
+
+      listbox = gtk_list_box_new ();
+      gtk_container_add (GTK_CONTAINER (frame), listbox);
+      gtk_list_box_set_header_func (GTK_LIST_BOX (listbox),
+                                    cc_display_panel_list_box_update_header,
+                                    NULL, NULL);
+      g_signal_connect (listbox, "row-selected",
+                        G_CALLBACK (setup_listbox_row_activated), panel);
+      g_signal_connect_swapped (listbox, "row-selected",
+                                G_CALLBACK (gtk_widget_queue_draw), preview);
+      gtk_widget_show (listbox);
+
+      item = list_box_item (_("Primary"),
+                            _("Show the top bar and Activities Overview on this display"));
+      gtk_container_add (GTK_CONTAINER (listbox), item);
+      if (primary)
+        gtk_list_box_select_row (GTK_LIST_BOX (listbox),
+                                 GTK_LIST_BOX_ROW (item));
+
+      item = list_box_item (_("Secondary Display"),
+                            _("Join this display with another to create an extra workspace"));
+      gtk_container_add (GTK_CONTAINER (listbox), item);
+      if (!primary && !clone)
+        gtk_list_box_select_row (GTK_LIST_BOX (listbox),
+                                 GTK_LIST_BOX_ROW (item));
 
-  error = NULL;
-  self->priv->builder = builder = gtk_builder_new ();
+#if 0
+      item = list_box_item (_("Presentation"),
+                            _("Show slideshows and media only"));
+      gtk_container_add (GTK_CONTAINER (listbox), item);
+#endif
 
-  if (!gtk_builder_add_objects_from_resource (builder, 
"/org/gnome/control-center/display/display-capplet.ui", objects, &error))
+      /* translators: "Mirror" describes when both displays show the same view */
+      item = list_box_item (_("Mirror"),
+                            _("Show your existing view on both displays"));
+      gtk_container_add (GTK_CONTAINER (listbox), item);
+      if (clone && active)
+        gtk_list_box_select_row (GTK_LIST_BOX (listbox),
+                                 GTK_LIST_BOX_ROW (item));
+    }
+  else
     {
-      g_warning ("Could not parse UI definition: %s", error->message);
-      g_error_free (error);
-      g_object_unref (builder);
-      return obj;
+      GnomeRRMode **modes;
+
+      modes = gnome_rr_output_list_modes (output);
+      setup_resolution_combo_box (panel, modes,
+                                  gnome_rr_output_get_current_mode (output));
     }
 
-  self->priv->screen = gnome_rr_screen_new (gdk_screen_get_default (), &error);
-  g_signal_connect (self->priv->screen, "changed", G_CALLBACK (on_screen_changed), self);
-  if (!self->priv->screen)
+  content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+  gtk_container_add (GTK_CONTAINER (box), grid);
+  gtk_widget_show_all (box);
+
+  gnome_rr_output_info_get_geometry (priv->current_output, NULL, NULL,
+                                     &old_width, &old_height);
+
+  if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
     {
-      error_message (NULL, _("Could not get screen information"), error->message);
-      g_error_free (error);
-      g_object_unref (builder);
-      return obj;
+      GnomeRROutputInfo **outputs;
+      GtkListBoxRow *row;
+      GnomeRRRotation rotation;
+
+      if (g_hash_table_size (output_ids) > 1)
+        {
+          gint new_width, new_height;
+
+          outputs = gnome_rr_config_get_outputs (priv->current_configuration);
+
+          gnome_rr_output_info_get_geometry (priv->current_output, NULL, NULL,
+                                             &new_width, &new_height);
+
+          row = gtk_list_box_get_selected_row (GTK_LIST_BOX (listbox));
+
+          switch (gtk_list_box_row_get_index (row))
+            {
+            case DISPLAY_MODE_PRIMARY:
+              primary = TRUE;
+              clone = FALSE;
+              break;
+
+#if 0
+            case DISPLAY_MODE_PRESENTATION:
+              gnome_rr_config_set_clone (priv->current_configuration, FALSE);
+              primary = FALSE;
+              clone = FALSE;
+              break;
+#endif
+
+            case DISPLAY_MODE_MIRROR:
+              clone = TRUE;
+              break;
+
+            case DISPLAY_MODE_SECONDARY:
+              primary = FALSE;
+              clone = FALSE;
+              break;
+            }
+
+          gnome_rr_output_info_set_active (priv->current_output, TRUE);
+          gnome_rr_output_info_set_primary (priv->current_output, primary);
+          gnome_rr_config_set_clone (priv->current_configuration, clone);
+
+          for (i = 0; outputs[i]; i++)
+            {
+              if (!gnome_rr_output_info_is_active (outputs[i]))
+                continue;
+
+              if (clone)
+                {
+                  /* set all active outputs to the same size and position when
+                   * cloning */
+                  gnome_rr_output_info_set_geometry (outputs[i], 0, 0,
+                                                     new_width, new_height);
+                }
+              else if (outputs[i] != priv->current_output)
+                {
+                  /* ensure no other outputs are primary if this output is now
+                   * primary, or find another output to set as primary if this
+                   * output is no longer primary */
+
+                  gnome_rr_output_info_set_primary (outputs[i], !primary);
+                  if (!was_primary)
+                    break;
+                }
+            }
+
+          /* if the display was previously in clone mode, ensure the outputs
+           * are arranged correctly */
+          if ((was_clone && !clone))
+            lay_out_outputs_horizontally (panel);
+
+          if (!clone)
+            realign_outputs_after_resolution_change (panel,
+                                                     priv->current_output,
+                                                     old_width, old_height);
+        }
+
+      /* check rotation */
+      rotation = gnome_rr_output_info_get_rotation (priv->current_output);
+
+      /* other options such as reflection are not supported */
+      rotation &= (GNOME_RR_ROTATION_0 | GNOME_RR_ROTATION_90
+                   | GNOME_RR_ROTATION_180 | GNOME_RR_ROTATION_270);
+      if (rotation == 0)
+        rotation = GNOME_RR_ROTATION_0;
+      gnome_rr_output_info_set_rotation (priv->current_output, rotation);
+
+      apply_current_configuration (panel);
+    }
+  else
+    {
+      /* changes cancelled, so re-read the current configuration */
+      on_screen_changed (panel);
     }
 
-  self->priv->clock_settings = g_settings_new (CLOCK_SCHEMA);
+  priv->rotate_left_button = NULL;
+  priv->rotate_right_button = NULL;
+  priv->res_combo = NULL;
+  gtk_widget_destroy (dialog);
+}
+
+static void
+cc_display_panel_box_row_activated (GtkListBox     *listbox,
+                                    GtkWidget      *row,
+                                    CcDisplayPanel *panel)
+{
+  CcDisplayPanelPrivate *priv = panel->priv;
+  GnomeRROutputInfo *output_info;
+
+  gtk_list_box_select_row (listbox, NULL);
+
+  output_info = g_object_get_data (G_OBJECT (row), "gnome-rr-output");
+
+  if (!output_info)
+    return;
+
+  priv->current_output = output_info;
+
+  show_setup_dialog (panel);
+}
+
+static void
+mapped_cb (CcDisplayPanel *panel)
+{
+  CcDisplayPanelPrivate *priv = panel->priv;
+  CcShell *shell;
+  GtkWidget *toplevel;
 
-  shell = cc_panel_get_shell (CC_PANEL (self));
+  shell = cc_panel_get_shell (CC_PANEL (panel));
   toplevel = cc_shell_get_toplevel (shell);
-  self->priv->focus_id = g_signal_connect (toplevel, "notify::has-toplevel-focus",
-                                           G_CALLBACK (dialog_toplevel_focus_changed), self);
+  if (toplevel)
+    priv->focus_id = g_signal_connect (toplevel, "notify::has-toplevel-focus",
+                                       G_CALLBACK (dialog_toplevel_focus_changed), panel);
+}
 
-  self->priv->panel = WID ("display-panel");
-  g_signal_connect_after (self->priv->panel, "show",
-                          G_CALLBACK (dialog_map_event_cb), self);
+static void
+cc_display_panel_up_client_changed (UpClient       *client,
+                                    CcDisplayPanel *self)
+{
+  CcDisplayPanelPrivate *priv = self->priv;
+  gboolean lid_is_closed;
 
-  self->priv->current_monitor_event_box = WID ("current_monitor_event_box");
-  self->priv->current_monitor_label = WID ("current_monitor_label");
+  lid_is_closed = up_client_get_lid_is_closed (client);
 
-  self->priv->monitor_switch = WID ("monitor_switch");
-  g_signal_connect (self->priv->monitor_switch, "notify::active",
-                    G_CALLBACK (monitor_switch_active_cb), self);
+  if (lid_is_closed != priv->lid_is_closed)
+    {
+      priv->lid_is_closed = lid_is_closed;
 
-  self->priv->resolution_combo = WID ("resolution_combo");
-  g_signal_connect (self->priv->resolution_combo, "changed",
-                    G_CALLBACK (on_resolution_changed), self);
+      on_screen_changed (self);
+    }
+}
 
-  self->priv->rotation_combo = WID ("rotation_combo");
-  g_signal_connect (self->priv->rotation_combo, "changed",
-                    G_CALLBACK (on_rotation_changed), self);
+static void
+cc_display_panel_init (CcDisplayPanel *self)
+{
+  CcDisplayPanelPrivate *priv;
+  GtkWidget *frame, *vbox;
+  GError *error = NULL;
 
-  self->priv->clone_checkbox = WID ("clone_checkbox");
-  g_signal_connect (self->priv->clone_checkbox, "toggled",
-                    G_CALLBACK (on_clone_changed), self);
+  g_resources_register (cc_display_get_resource ());
 
-  self->priv->clone_label    = WID ("clone_resolution_warning_label");
+  priv = self->priv = DISPLAY_PANEL_PRIVATE (self);
 
-  g_signal_connect (WID ("detect_displays_button"),
-                    "clicked", G_CALLBACK (on_detect_displays), self);
+  priv->screen = gnome_rr_screen_new (gdk_screen_get_default (), &error);
+  if (!priv->screen)
+    {
+      gtk_container_add (GTK_CONTAINER (self),
+                         gtk_label_new (_("Could not get screen information")));
+      g_error_free (error);
 
-  make_text_combo (self->priv->resolution_combo, 4);
-  make_text_combo (self->priv->rotation_combo, -1);
+      gtk_widget_show_all (GTK_WIDGET (self));
 
-  /* Scroll Area */
-  self->priv->area = (GtkWidget *)foo_scroll_area_new ();
+      return;
+    }
 
-  g_object_set_data (G_OBJECT (self->priv->area), "panel", self);
+  output_ids = g_hash_table_new (g_direct_hash, g_direct_equal);
 
-  set_monitors_tooltip (self, FALSE);
+  vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
+  gtk_container_add (GTK_CONTAINER (self), vbox);
 
-  /* FIXME: this should be computed dynamically */
-  foo_scroll_area_set_min_size (FOO_SCROLL_AREA (self->priv->area), 0, 200);
-  gtk_widget_show (self->priv->area);
-  g_signal_connect (self->priv->area, "paint",
-                    G_CALLBACK (on_area_paint), self);
-  g_signal_connect (self->priv->area, "viewport_changed",
-                    G_CALLBACK (on_viewport_changed), self);
+  frame = gtk_frame_new (NULL);
+  gtk_widget_set_margin_left (vbox, 134);
+  gtk_widget_set_margin_right (vbox, 134);
+  gtk_widget_set_margin_top (vbox, 22);
+  gtk_widget_set_margin_bottom (vbox, 22);
+  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
+  gtk_container_add (GTK_CONTAINER (vbox), frame);
 
-  align = WID ("align");
+  priv->displays_listbox = gtk_list_box_new ();
+  gtk_list_box_set_header_func (GTK_LIST_BOX (priv->displays_listbox),
+                                cc_display_panel_list_box_update_header, NULL,
+                                NULL);
+  g_signal_connect (priv->displays_listbox, "row-activated",
+                    G_CALLBACK (cc_display_panel_box_row_activated),
+                    self);
+  gtk_container_add (GTK_CONTAINER (frame), priv->displays_listbox);
 
-  gtk_container_add (GTK_CONTAINER (align), self->priv->area);
 
-  on_screen_changed (self->priv->screen, self);
+  priv->arrange_button = gtk_button_new_with_mnemonic (_("_Arrange Combined Displays"));
+  g_signal_connect (priv->arrange_button, "clicked",
+                    G_CALLBACK (show_arrange_displays_dialog), self);
+  gtk_widget_set_halign (priv->arrange_button, GTK_ALIGN_CENTER);
 
-  g_signal_connect_swapped (WID ("apply_button"),
-                            "clicked", G_CALLBACK (apply), self);
+  gtk_container_add (GTK_CONTAINER (vbox), priv->arrange_button);
+  gtk_widget_show_all (vbox);
 
-  gtk_widget_show (self->priv->panel);
-  gtk_container_add (GTK_CONTAINER (self), self->priv->panel);
+  on_screen_changed (self);
+  priv->screen_changed_handler_id = g_signal_connect_swapped (priv->screen,
+                                                              "changed",
+                                                              G_CALLBACK (on_screen_changed),
+                                                              self);
 
   self->priv->up_client = up_client_new ();
   if (up_client_get_lid_is_present (self->priv->up_client))
@@ -2658,5 +2150,5 @@ cc_display_panel_constructor (GType                  gtype,
   else
     g_clear_object (&self->priv->up_client);
 
-  return obj;
+  g_signal_connect (self, "map", G_CALLBACK (mapped_cb), NULL);
 }
diff --git a/panels/display/cc-display-panel.h b/panels/display/cc-display-panel.h
index dd02c2b..881d203 100644
--- a/panels/display/cc-display-panel.h
+++ b/panels/display/cc-display-panel.h
@@ -24,6 +24,8 @@
 #define _CC_DISPLAY_PANEL_H
 
 #include <shell/cc-panel.h>
+#define GNOME_DESKTOP_USE_UNSTABLE_API
+#include <libgnome-desktop/gnome-rr-config.h>
 
 G_BEGIN_DECLS
 
@@ -66,6 +68,7 @@ struct _CcDisplayPanelClass
 };
 
 GType cc_display_panel_get_type (void) G_GNUC_CONST;
+gint cc_display_panel_get_output_id (GnomeRROutputInfo *output);
 
 G_END_DECLS
 
diff --git a/panels/display/cc-rr-labeler.c b/panels/display/cc-rr-labeler.c
index ea8a7fd..646b112 100644
--- a/panels/display/cc-rr-labeler.c
+++ b/panels/display/cc-rr-labeler.c
@@ -38,13 +38,13 @@
 #endif
 
 #include "cc-rr-labeler.h"
+#include "cc-display-panel.h"
 
 struct _CcRRLabelerPrivate {
        GnomeRRConfig *config;
 
        int num_outputs;
 
-       GdkRGBA *palette;
        GtkWidget **windows;
 
        GdkScreen  *screen;
@@ -179,8 +179,6 @@ cc_rr_labeler_finalize (GObject *object)
                g_free (labeler->priv->windows);
        }
 
-       g_free (labeler->priv->palette);
-
        G_OBJECT_CLASS (cc_rr_labeler_parent_class)->finalize (object);
 }
 
@@ -197,45 +195,6 @@ count_outputs (GnomeRRConfig *config)
 }
 
 static void
-make_palette (CcRRLabeler *labeler)
-{
-       /* The idea is that we go around an hue color wheel.  We want to start
-        * at red, go around to green/etc. and stop at blue --- because magenta
-        * is evil.  Eeeeek, no magenta, please!
-        *
-        * Purple would be nice, though.  Remember that we are watered down
-        * (i.e. low saturation), so that would be like Like berries with cream.
-        * Mmmmm, berries.
-        */
-       double start_hue;
-       double end_hue;
-       int i;
-
-       g_assert (labeler->priv->num_outputs > 0);
-
-       labeler->priv->palette = g_new (GdkRGBA, labeler->priv->num_outputs);
-
-       start_hue = 0.0; /* red */
-       end_hue   = 2.0/3; /* blue */
-
-       for (i = 0; i < labeler->priv->num_outputs; i++) {
-               double h, s, v;
-               double r, g, b;
-
-               h = start_hue + (end_hue - start_hue) / labeler->priv->num_outputs * i;
-               s = 1.0 / 3;
-               v = 1.0;
-
-               gtk_hsv_to_rgb (h, s, v, &r, &g, &b);
-
-               labeler->priv->palette[i].red   = r;
-               labeler->priv->palette[i].green = g;
-               labeler->priv->palette[i].blue  = b;
-               labeler->priv->palette[i].alpha  = 1.0;
-       }
-}
-
-static void
 rounded_rectangle (cairo_t *cr,
                    gint     x,
                    gint     y,
@@ -274,7 +233,9 @@ rounded_rectangle (cairo_t *cr,
        cairo_close_path (cr);
 }
 
-#define LABEL_WINDOW_EDGE_THICKNESS 2
+#define LABEL_WINDOW_SIZE 80
+#define LABEL_WINDOW_MARGIN 14
+#define LABEL_WINDOW_EDGE_THICKNESS 1
 #define LABEL_WINDOW_PADDING 12
 /* Look for panel-corner in:
  * http://git.gnome.org/browse/gnome-shell/tree/data/theme/gnome-shell.css
@@ -285,10 +246,9 @@ static void
 label_draw_background_and_frame (GtkWidget *widget, cairo_t *cr, gboolean for_shape)
 {
        GdkRGBA shape_color = { 0, 0, 0, 1 };
-       GdkRGBA *rgba;
+        GdkRGBA black = { 0, 0, 0, 0.75 };
        GtkAllocation allocation;
 
-       rgba = g_object_get_data (G_OBJECT (widget), "rgba");
        gtk_widget_get_allocation (widget, &allocation);
 
        cairo_save (cr);
@@ -298,7 +258,7 @@ label_draw_background_and_frame (GtkWidget *widget, cairo_t *cr, gboolean for_sh
        if (for_shape)
                gdk_cairo_set_source_rgba (cr, &shape_color);
        else
-               cairo_set_source_rgba (cr, 0, 0, 0, 0.5);
+               cairo_set_source_rgba (cr, 0.75, 0.75, 0.75, 0.75);
 
        rounded_rectangle (cr,
                           LABEL_WINDOW_EDGE_THICKNESS / 2.0,
@@ -313,8 +273,7 @@ label_draw_background_and_frame (GtkWidget *widget, cairo_t *cr, gboolean for_sh
        if (for_shape) {
                gdk_cairo_set_source_rgba (cr, &shape_color);
        } else {
-               rgba->alpha = 0.75;
-               gdk_cairo_set_source_rgba (cr, rgba);
+               gdk_cairo_set_source_rgba (cr, &black);
        }
 
        rounded_rectangle (cr,
@@ -362,7 +321,8 @@ position_window (CcRRLabeler  *labeler,
                                          &monitor);
        gdk_rectangle_intersect (&monitor, &workarea, &workarea);
 
-       gtk_window_move (GTK_WINDOW (window), workarea.x, workarea.y);
+       gtk_window_move (GTK_WINDOW (window), workarea.x + LABEL_WINDOW_MARGIN,
+                        workarea.y + LABEL_WINDOW_MARGIN);
 }
 
 static void
@@ -386,17 +346,21 @@ label_window_composited_changed_cb (GtkWidget *widget, CcRRLabeler *labeler)
 }
 
 static GtkWidget *
-create_label_window (CcRRLabeler *labeler, GnomeRROutputInfo *output, GdkRGBA *rgba)
+create_label_window (CcRRLabeler *labeler, GnomeRROutputInfo *output)
 {
        GtkWidget *window;
        GtkWidget *widget;
        char *str;
-       const char *display_name;
-       GdkRGBA black = { 0, 0, 0, 1.0 };
-       int x, y;
+       GdkRGBA white = { 1, 1, 1, 1 };
+       int x, y, display_num;
        GdkScreen *screen;
        GdkVisual *visual;
 
+       display_num = cc_display_panel_get_output_id (output);
+
+       if (display_num == 0)
+         return NULL;
+
        window = gtk_window_new (GTK_WINDOW_POPUP);
        gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_TOOLTIP);
        gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
@@ -407,13 +371,8 @@ create_label_window (CcRRLabeler *labeler, GnomeRROutputInfo *output, GdkRGBA *r
        if (visual != NULL)
                gtk_widget_set_visual (window, visual);
 
-       gtk_container_set_border_width (GTK_CONTAINER (window), LABEL_WINDOW_PADDING + 
LABEL_WINDOW_EDGE_THICKNESS);
-
-       /* This is semi-dangerous.  The color is part of the labeler->palette
-        * array.  Note that in cc_rr_labeler_finalize(), we are careful to
-        * free the palette only after we free the windows.
-        */
-       g_object_set_data (G_OBJECT (window), "rgba", rgba);
+       gtk_widget_set_size_request (window, LABEL_WINDOW_SIZE,
+                                    LABEL_WINDOW_SIZE);
 
        g_signal_connect (window, "draw",
                          G_CALLBACK (label_window_draw_event_cb), labeler);
@@ -422,30 +381,18 @@ create_label_window (CcRRLabeler *labeler, GnomeRROutputInfo *output, GdkRGBA *r
        g_signal_connect (window, "composited-changed",
                          G_CALLBACK (label_window_composited_changed_cb), labeler);
 
-       if (gnome_rr_config_get_clone (labeler->priv->config)) {
-               /* Keep this string in sync with 
gnome-control-center/capplets/display/xrandr-capplet.c:get_display_name() */
-
-               /* Translators:  this is the feature where what you see on your
-                * laptop's screen is the same as your external projector.
-                * Here, "Mirrored" is being used as an adjective.  For example,
-                * the Spanish translation could be "Pantallas en Espejo".
-                */
-               display_name = _("Mirrored Displays");
-       } else
-               display_name = gnome_rr_output_info_get_display_name (output);
-
-       str = g_strdup_printf ("<b>%s</b>", display_name);
+       str = g_strdup_printf ("<span size='xx-large' font-weight='bold'>%d</span>", display_num);
        widget = gtk_label_new (NULL);
        gtk_label_set_markup (GTK_LABEL (widget), str);
        g_free (str);
 
-       /* Make the label explicitly black.  We don't want it to follow the
-        * theme's colors, since the label is always shown against a light
-        * pastel background.  See bgo#556050
+       /* Make the label explicitly white.  We don't want it to follow the
+        * theme's colors, since the label is always shown against a black
+         * background.  See bgo#556050
         */
        gtk_widget_override_color (widget,
                                   gtk_widget_get_state_flags (widget),
-                                  &black);
+                                  &white);
 
        gtk_container_add (GTK_CONTAINER (window), widget);
 
@@ -463,8 +410,6 @@ setup_from_config (CcRRLabeler *labeler)
 {
        labeler->priv->num_outputs = count_outputs (labeler->priv->config);
 
-       make_palette (labeler);
-
        cc_rr_labeler_show (labeler);
 }
 
@@ -497,7 +442,6 @@ void
 cc_rr_labeler_show (CcRRLabeler *labeler)
 {
        int i;
-       gboolean created_window_for_clone;
        GnomeRROutputInfo **outputs;
 
        g_return_if_fail (GNOME_IS_RR_LABELER (labeler));
@@ -505,18 +449,16 @@ cc_rr_labeler_show (CcRRLabeler *labeler)
        if (labeler->priv->windows != NULL)
                return;
 
-       labeler->priv->windows = g_new (GtkWidget *, labeler->priv->num_outputs);
-
-       created_window_for_clone = FALSE;
+       if (gnome_rr_config_get_clone (labeler->priv->config))
+               return;
 
        outputs = gnome_rr_config_get_outputs (labeler->priv->config);
 
-       for (i = 0; i < labeler->priv->num_outputs; i++) {
-               if (!created_window_for_clone && gnome_rr_output_info_is_active (outputs[i])) {
-                       labeler->priv->windows[i] = create_label_window (labeler, outputs[i], 
labeler->priv->palette + i);
+       labeler->priv->windows = g_new (GtkWidget *, labeler->priv->num_outputs);
 
-                       if (gnome_rr_config_get_clone (labeler->priv->config))
-                               created_window_for_clone = TRUE;
+       for (i = 0; i < labeler->priv->num_outputs; i++) {
+               if (gnome_rr_output_info_is_active (outputs[i])) {
+                       labeler->priv->windows[i] = create_label_window (labeler, outputs[i]);
                } else
                        labeler->priv->windows[i] = NULL;
        }
@@ -549,37 +491,3 @@ cc_rr_labeler_hide (CcRRLabeler *labeler)
        g_free (priv->windows);
        priv->windows = NULL;
 }
-
-/**
- * cc_rr_labeler_get_rgba_for_output:
- * @labeler: A #CcRRLabeler
- * @output: Output device (i.e. monitor) to query
- * @rgba_out: (out): Color of selected monitor.
- *
- * Get the color used for the label on a given output (monitor).
- */
-void
-cc_rr_labeler_get_rgba_for_output (CcRRLabeler *labeler, GnomeRROutputInfo *output, GdkRGBA *rgba_out)
-{
-       int i;
-       GnomeRROutputInfo **outputs;
-
-       g_return_if_fail (GNOME_IS_RR_LABELER (labeler));
-       g_return_if_fail (GNOME_IS_RR_OUTPUT_INFO (output));
-       g_return_if_fail (rgba_out != NULL);
-
-       outputs = gnome_rr_config_get_outputs (labeler->priv->config);
-
-       for (i = 0; i < labeler->priv->num_outputs; i++)
-               if (outputs[i] == output) {
-                       *rgba_out = labeler->priv->palette[i];
-                       return;
-               }
-
-       g_warning ("trying to get the color for unknown GnomeOutputInfo %p; returning magenta!", output);
-
-       rgba_out->red   = 1.0;
-       rgba_out->green = 0;
-       rgba_out->blue  = 1.0;
-       rgba_out->alpha  = 1.0;
-}
diff --git a/panels/display/cc-rr-labeler.h b/panels/display/cc-rr-labeler.h
index fdecf29..860accf 100644
--- a/panels/display/cc-rr-labeler.h
+++ b/panels/display/cc-rr-labeler.h
@@ -59,6 +59,4 @@ void cc_rr_labeler_show (CcRRLabeler *labeler);
 
 void cc_rr_labeler_hide (CcRRLabeler *labeler);
 
-void cc_rr_labeler_get_rgba_for_output (CcRRLabeler *labeler, GnomeRROutputInfo *output, GdkRGBA *rgba_out);
-
 #endif
diff --git a/panels/display/display-capplet.ui b/panels/display/display-capplet.ui
index 6906e5d..386bd3b 100644
--- a/panels/display/display-capplet.ui
+++ b/panels/display/display-capplet.ui
@@ -1,312 +1,518 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
 <interface>
-  <requires lib="gtk+" version="2.16"/>
-  <!-- interface-naming-policy toplevel-contextual -->
+  <!-- interface-requires gtk+ 3.10 -->
   <object class="GtkWindow" id="window1">
+    <property name="can_focus">False</property>
     <child>
-      <object class="GtkVBox" id="display-panel">
+      <object class="GtkFrame" id="frame1">
         <property name="visible">True</property>
-        <property name="border_width">10</property>
-        <property name="orientation">vertical</property>
-        <property name="spacing">12</property>
-        <property name="margin-left">6</property>
-        <property name="margin-right">6</property>
-        <property name="margin-top">6</property>
-        <property name="margin-bottom">6</property>
+        <property name="can_focus">False</property>
+        <property name="margin_left">134</property>
+        <property name="margin_right">134</property>
+        <property name="margin_top">22</property>
+        <property name="margin_bottom">22</property>
+        <property name="label_xalign">0</property>
+        <property name="shadow_type">in</property>
         <child>
-          <object class="GtkAlignment" id="align">
+          <object class="GtkListBox" id="listbox1">
             <property name="visible">True</property>
+            <property name="can_focus">False</property>
             <child>
-              <placeholder/>
+              <object class="GtkListBoxRow" id="listboxrow1">
+                <property name="can_focus">False</property>
+                <property name="margin_bottom">67</property>
+              </object>
             </child>
           </object>
-          <packing>
-            <property name="position">0</property>
-          </packing>
         </child>
+      </object>
+    </child>
+  </object>
+  <object class="GtkWindow" id="window2">
+    <property name="can_focus">False</property>
+    <child>
+      <object class="GtkBox" id="box1">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
         <child>
-          <object class="GtkHBox" id="hbox1">
+          <object class="GtkFrame" id="frame2">
             <property name="visible">True</property>
-            <property name="spacing">12</property>
+            <property name="can_focus">False</property>
+            <property name="margin_left">39</property>
+            <property name="margin_right">39</property>
+            <property name="margin_top">22</property>
+            <property name="margin_bottom">22</property>
+            <property name="label_xalign">0</property>
+            <property name="shadow_type">in</property>
             <child>
-              <object class="GtkVBox" id="vbox1">
+              <object class="GtkListBox" id="listbox2">
                 <property name="visible">True</property>
-                <property name="orientation">vertical</property>
-                <property name="spacing">12</property>
+                <property name="can_focus">False</property>
                 <child>
-                  <object class="GtkHBox" id="hbox3">
+                  <object class="GtkListBoxRow" id="listboxrow3">
+                    <property name="width_request">100</property>
+                    <property name="height_request">80</property>
                     <property name="visible">True</property>
-                    <property name="spacing">12</property>
+                    <property name="can_focus">True</property>
                     <child>
-                      <object class="GtkEventBox" id="current_monitor_event_box">
+                      <object class="GtkBox" id="box2">
                         <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="border_width">12</property>
+                        <property name="orientation">vertical</property>
                         <child>
-                          <object class="GtkLabel" id="current_monitor_label">
+                          <object class="GtkLabel" id="label3">
                             <property name="visible">True</property>
-                            <property name="xalign">0</property>
-                            <property name="xpad">10</property>
-                            <property name="ypad">5</property>
-                            <property name="label" translatable="yes">Monitor</property>
+                            <property name="can_focus">False</property>
+                            <property name="halign">start</property>
+                            <property name="label" translatable="yes">Primary</property>
                             <attributes>
                               <attribute name="weight" value="bold"/>
                             </attributes>
                           </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label4">
+                            <property name="width_request">260</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="halign">start</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">Show the top bar and Activities 
Overview on this display</property>
+                            <property name="wrap">True</property>
+                            <style>
+                              <class name="dim-label"/>
+                            </style>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">1</property>
+                          </packing>
                         </child>
                       </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">0</property>
-                      </packing>
                     </child>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkListBoxRow" id="listboxrow2">
+                    <property name="width_request">100</property>
+                    <property name="height_request">80</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
                     <child>
-                      <object class="GtkHBox" id="hbox2">
+                      <object class="GtkBox" id="box3">
                         <property name="visible">True</property>
-                        <property name="spacing">12</property>
+                        <property name="can_focus">False</property>
+                        <property name="border_width">12</property>
+                        <property name="orientation">vertical</property>
                         <child>
-                          <object class="GtkSwitch" id="monitor_switch">
+                          <object class="GtkLabel" id="label5">
                             <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="receives_default">False</property>
-                            <property name="active">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="halign">start</property>
+                            <property name="label" translatable="yes">Presentation</property>
+                            <attributes>
+                              <attribute name="weight" value="bold"/>
+                            </attributes>
                           </object>
                           <packing>
                             <property name="expand">False</property>
-                            <property name="fill">False</property>
+                            <property name="fill">True</property>
                             <property name="position">0</property>
                           </packing>
                         </child>
+                        <child>
+                          <object class="GtkLabel" id="label6">
+                            <property name="width_request">260</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="halign">start</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">Show slideshows and media 
only</property>
+                            <property name="wrap">True</property>
+                            <style>
+                              <class name="dim-label"/>
+                            </style>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
                       </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="pack_type">end</property>
-                        <property name="position">1</property>
-                      </packing>
                     </child>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">0</property>
-                  </packing>
                 </child>
                 <child>
-                  <object class="GtkAlignment" id="alignment1">
+                  <object class="GtkListBoxRow" id="listboxrow4">
+                    <property name="width_request">100</property>
+                    <property name="height_request">80</property>
                     <property name="visible">True</property>
-                    <property name="xalign">0</property>
-                    <property name="yalign">0</property>
-                    <property name="left_padding">12</property>
+                    <property name="can_focus">True</property>
                     <child>
-                      <object class="GtkTable" id="table1">
+                      <object class="GtkBox" id="box4">
                         <property name="visible">True</property>
-                        <property name="n_rows">3</property>
-                        <property name="n_columns">2</property>
-                        <property name="column_spacing">12</property>
-                        <property name="row_spacing">6</property>
+                        <property name="can_focus">False</property>
+                        <property name="border_width">12</property>
+                        <property name="orientation">vertical</property>
                         <child>
-                          <object class="GtkAlignment" id="alignment4">
+                          <object class="GtkLabel" id="label7">
                             <property name="visible">True</property>
-                            <child>
-                              <placeholder/>
-                            </child>
+                            <property name="can_focus">False</property>
+                            <property name="halign">start</property>
+                            <property name="label" translatable="yes">Mirror</property>
+                            <attributes>
+                              <attribute name="weight" value="bold"/>
+                            </attributes>
                           </object>
                           <packing>
-                            <property name="left_attach">1</property>
-                            <property name="right_attach">2</property>
-                            <property name="top_attach">2</property>
-                            <property name="bottom_attach">3</property>
-                            <property name="x_options"></property>
-                            <property name="y_options"></property>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">0</property>
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkLabel" id="label2">
+                          <object class="GtkLabel" id="label8">
+                            <property name="width_request">260</property>
                             <property name="visible">True</property>
-                            <property name="xalign">1</property>
-                            <property name="label" translatable="yes">_Resolution</property>
-                            <property name="use_underline">True</property>
-                            <property name="mnemonic_widget">resolution_combo</property>
+                            <property name="can_focus">False</property>
+                            <property name="halign">start</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">Show your primary display on this 
screen also</property>
+                            <property name="wrap">True</property>
                             <style>
                               <class name="dim-label"/>
                             </style>
                           </object>
                           <packing>
-                            <property name="x_options">GTK_FILL</property>
-                            <property name="y_options"></property>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">1</property>
                           </packing>
                         </child>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkListBoxRow" id="listboxrow5">
+                    <property name="width_request">100</property>
+                    <property name="height_request">80</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <child>
+                      <object class="GtkBox" id="box5">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="border_width">12</property>
+                        <property name="orientation">vertical</property>
                         <child>
-                          <object class="GtkLabel" id="label5">
+                          <object class="GtkLabel" id="label9">
                             <property name="visible">True</property>
-                            <property name="xalign">1</property>
-                            <property name="label" translatable="yes">R_otation</property>
-                            <property name="mnemonic_widget">rotation_combo</property>
-                            <property name="use_underline">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="halign">start</property>
+                            <property name="label" translatable="yes">Combine</property>
+                            <attributes>
+                              <attribute name="weight" value="bold"/>
+                            </attributes>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label10">
+                            <property name="width_request">260</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="halign">start</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">Join with the primary display to 
create an extra space</property>
+                            <property name="wrap">True</property>
                             <style>
                               <class name="dim-label"/>
                             </style>
                           </object>
                           <packing>
-                            <property name="top_attach">1</property>
-                            <property name="bottom_attach">2</property>
-                            <property name="x_options">GTK_FILL</property>
-                            <property name="y_options"></property>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">1</property>
                           </packing>
                         </child>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkListBoxRow" id="listboxrow6">
+                    <property name="width_request">100</property>
+                    <property name="height_request">80</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <child>
+                      <object class="GtkBox" id="box6">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="border_width">12</property>
+                        <property name="orientation">vertical</property>
                         <child>
-                          <object class="GtkComboBox" id="resolution_combo">
+                          <object class="GtkLabel" id="label11">
                             <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="halign">start</property>
+                            <property name="label" translatable="yes">Turn Off</property>
+                            <attributes>
+                              <attribute name="weight" value="bold"/>
+                            </attributes>
                           </object>
                           <packing>
-                            <property name="left_attach">1</property>
-                            <property name="right_attach">2</property>
-                            <property name="y_options"></property>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">0</property>
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkComboBox" id="rotation_combo">
+                          <object class="GtkLabel" id="label12">
+                            <property name="width_request">260</property>
                             <property name="visible">True</property>
-                            <child>
-                              <object class="GtkCellRendererText" id="cellrenderertext1"/>
-                              <attributes>
-                                <attribute name="text">0</attribute>
-                              </attributes>
-                            </child>
+                            <property name="can_focus">False</property>
+                            <property name="halign">start</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">Don't use the display</property>
+                            <property name="wrap">True</property>
+                            <style>
+                              <class name="dim-label"/>
+                            </style>
                           </object>
                           <packing>
-                            <property name="left_attach">1</property>
-                            <property name="right_attach">2</property>
-                            <property name="top_attach">1</property>
-                            <property name="bottom_attach">2</property>
-                            <property name="y_options"></property>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">1</property>
                           </packing>
                         </child>
-                        <child>
-                          <placeholder/>
-                        </child>
                       </object>
                     </child>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="position">1</property>
-                  </packing>
                 </child>
               </object>
-              <packing>
-                <property name="position">0</property>
-              </packing>
             </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkGrid" id="grid1">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="margin_left">67</property>
+            <property name="margin_right">67</property>
+            <property name="margin_top">22</property>
+            <property name="margin_bottom">22</property>
+            <property name="row_spacing">12</property>
+            <property name="column_spacing">12</property>
             <child>
-              <object class="GtkAlignment" id="alignment2">
+              <object class="GtkDrawingArea" id="drawingarea1">
+                <property name="height_request">100</property>
                 <property name="visible">True</property>
-                <child>
-                  <placeholder/>
-                </child>
+                <property name="can_focus">False</property>
               </object>
               <packing>
-                <property name="position">1</property>
+                <property name="left_attach">0</property>
+                <property name="top_attach">0</property>
+                <property name="width">2</property>
+                <property name="height">1</property>
               </packing>
             </child>
             <child>
-              <object class="GtkVBox" id="vbox2">
+              <object class="GtkBox" id="box8">
                 <property name="visible">True</property>
-                <property name="orientation">vertical</property>
+                <property name="can_focus">False</property>
+                <style>
+                  <class name="linked"/>
+                </style>
                 <child>
-                  <object class="GtkCheckButton" id="clone_checkbox">
-                    <property name="label" translatable="yes" comments="Note that mirror is a verb in this 
string">_Mirror displays</property>
+                  <object class="GtkButton" id="button2">
+                    <property name="name">rotate-left-button</property>
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
-                    <property name="receives_default">False</property>
-                    <property name="use_underline">True</property>
-                    <property name="draw_indicator">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="halign">end</property>
+                    <child>
+                      <object class="GtkImage" id="image1">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="icon_name">object-rotate-left-symbolic</property>
+                      </object>
+                    </child>
                   </object>
                   <packing>
                     <property name="expand">False</property>
-                    <property name="fill">False</property>
+                    <property name="fill">True</property>
                     <property name="position">0</property>
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkLabel" id="clone_resolution_warning_label">
+                  <object class="GtkButton" id="button3">
+                    <property name="name">rotate-right-button</property>
                     <property name="visible">True</property>
-                    <property name="xalign">0</property>
-                    <property name="label" translatable="yes">Note: may limit resolution options</property>
-                    <attributes>
-                      <attribute name="style" value="italic"/>
-                    </attributes>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="halign">start</property>
+                    <child>
+                      <object class="GtkImage" id="image2">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="icon_name">object-rotate-right-symbolic</property>
+                      </object>
+                    </child>
                   </object>
                   <packing>
                     <property name="expand">False</property>
-                    <property name="fill">False</property>
+                    <property name="fill">True</property>
                     <property name="position">1</property>
                   </packing>
                 </child>
-                <child>
-                  <placeholder/>
-                </child>
-                <child>
-                  <placeholder/>
-                </child>
               </object>
               <packing>
-                <property name="expand">False</property>
-                <property name="position">2</property>
+                <property name="left_attach">0</property>
+                <property name="top_attach">1</property>
+                <property name="width">2</property>
+                <property name="height">1</property>
               </packing>
             </child>
-          </object>
-          <packing>
-            <property name="position">1</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkAlignment" id="alignment3">
-            <property name="visible">True</property>
-            <property name="top_padding">10</property>
             <child>
-              <object class="GtkHButtonBox" id="hbuttonbox1">
+              <object class="GtkLabel" id="label13">
                 <property name="visible">True</property>
-                <property name="spacing">6</property>
-                <property name="layout_style">end</property>
-                <child>
-                  <object class="GtkButton" id="apply_button">
-                    <property name="label">gtk-apply</property>
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="can_default">True</property>
-                    <property name="receives_default">True</property>
-                    <property name="use_stock">True</property>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkButton" id="detect_displays_button">
-                    <property name="label" translatable="yes">_Detect Displays</property>
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">True</property>
-                    <property name="use_underline">True</property>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="pack_type">end</property>
-                    <property name="position">0</property>
-                    <property name="secondary">True</property>
-                  </packing>
-                </child>
+                <property name="can_focus">False</property>
+                <property name="halign">end</property>
+                <property name="label" translatable="yes">Model</property>
+                <style>
+                  <class name="dim-label"/>
+                </style>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">2</property>
+                <property name="width">1</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="label14">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="halign">end</property>
+                <property name="label" translatable="yes">Aspect Ratio</property>
+                <style>
+                  <class name="dim-label"/>
+                </style>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">3</property>
+                <property name="width">1</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="label15">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="halign">end</property>
+                <property name="label" translatable="yes">Resolution</property>
+                <style>
+                  <class name="dim-label"/>
+                </style>
               </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">4</property>
+                <property name="width">1</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="label16">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="halign">end</property>
+                <property name="label" translatable="yes">Refresh Rate</property>
+                <style>
+                  <class name="dim-label"/>
+                </style>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">5</property>
+                <property name="width">1</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="model-label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">2</property>
+                <property name="width">1</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="aspect-ratio-label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">3</property>
+                <property name="width">1</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkComboBox" id="resolution-combobox">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">4</property>
+                <property name="width">1</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkComboBoxText" id="refresh-rate-comboboxtext">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">5</property>
+                <property name="width">1</property>
+                <property name="height">1</property>
+              </packing>
             </child>
           </object>
           <packing>
             <property name="expand">False</property>
-            <property name="fill">False</property>
-            <property name="position">2</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
           </packing>
         </child>
       </object>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]