[gnome-screenshot] Redesign Screenshot's main window



commit aab0e5dc14f3a24172467a1e10b71c38ae618a66
Author: Christopher Davis <brainblasted disroot org>
Date:   Tue Mar 10 11:39:23 2020 +0000

    Redesign Screenshot's main window
    
    The dialog-style window of Screenshot introduced some
    complications when it came to designing for the app menu
    initiative: https://gitlab.gnome.org/GNOME/Initiatives/issues/4
    
    The window was redesigned by Tobias Bernard with new icons from
    Jakub Steiner. The window effects were simplified down to a drop
    shadow.
    
    Fixes https://gitlab.gnome.org/GNOME/gnome-screenshot/issues/15

 src/display-symbolic.svg                   |   5 +
 src/gnome-screenshot.gresource.xml         |   4 +
 src/org.gnome.gnome-screenshot.gschema.xml |   8 +-
 src/screenshot-app-menu.ui                 |   6 +-
 src/screenshot-application.c               |  43 ++-
 src/screenshot-config.c                    |  24 +-
 src/screenshot-config.h                    |   5 +-
 src/screenshot-dialog.c                    |  73 +++--
 src/screenshot-dialog.ui                   | 141 +++-------
 src/screenshot-interactive-dialog.c        | 432 +++++++----------------------
 src/screenshot-interactive.ui              | 425 ++++++++++++++++++++++++++++
 src/selection-symbolic.svg                 |   6 +
 src/window-symbolic.svg                    |   3 +
 13 files changed, 660 insertions(+), 515 deletions(-)
---
diff --git a/src/display-symbolic.svg b/src/display-symbolic.svg
new file mode 100644
index 0000000..3eda6df
--- /dev/null
+++ b/src/display-symbolic.svg
@@ -0,0 +1,5 @@
+<svg xmlns="http://www.w3.org/2000/svg"; width="16" height="16">
+    <g fill="#2e3436">
+        <path d="M3 1C1.338 1 0 2.338 0 4v7c0 1.662 1.338 3 3 3h10c1.662 0 3-1.338 
3-3V4c0-1.662-1.338-3-3-3zm0 2h10c.554 0 1 .446 1 1v7c0 .554-.446 1-1 1H3c-.554 0-1-.446-1-1V4c0-.554.446-1 
1-1zM8 16c3 0 4-1 4-1H4s1 1 4 1z"/>
+    </g>
+</svg>
diff --git a/src/gnome-screenshot.gresource.xml b/src/gnome-screenshot.gresource.xml
index dbd88f8..91b4c98 100644
--- a/src/gnome-screenshot.gresource.xml
+++ b/src/gnome-screenshot.gresource.xml
@@ -1,7 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <gresources>
   <gresource prefix="/org/gnome/screenshot">
+    <file alias="icons/display-symbolic.svg">display-symbolic.svg</file>
+    <file alias="icons/selection-symbolic.svg">selection-symbolic.svg</file>
+    <file alias="icons/window-symbolic.svg">window-symbolic.svg</file>
     <file preprocess="xml-stripblanks">screenshot-app-menu.ui</file>
+    <file preprocess="xml-stripblanks">screenshot-interactive.ui</file>
     <file preprocess="xml-stripblanks">screenshot-dialog.ui</file>
   </gresource>
 </gresources>
diff --git a/src/org.gnome.gnome-screenshot.gschema.xml b/src/org.gnome.gnome-screenshot.gschema.xml
index b998853..494b28e 100644
--- a/src/org.gnome.gnome-screenshot.gschema.xml
+++ b/src/org.gnome.gnome-screenshot.gschema.xml
@@ -41,10 +41,10 @@
       <summary>Include ICC Profile</summary>
       <description>Include the ICC profile of the target in the screenshot file</description>
     </key>
-    <key name="border-effect" type="s">
-      <default>'none'</default>
-      <summary>Border Effect</summary>
-      <description>Effect to add to the outside of a border.  Possible values are “shadow”, “none”, and 
“border”.</description>
+    <key name="use-shadow" type="b">
+      <default>false</default>
+      <summary>Use Shadow</summary>
+      <description>Apply a window shadow to the screenshot</description>
     </key>
     <key name="default-file-type" enum="org.gnome.gnome-screenshot.file-types">
       <default>'png'</default>
diff --git a/src/screenshot-app-menu.ui b/src/screenshot-app-menu.ui
index f6eae19..51ca5de 100644
--- a/src/screenshot-app-menu.ui
+++ b/src/screenshot-app-menu.ui
@@ -7,11 +7,7 @@
       </item>
       <item>
         <attribute name="action">app.about</attribute>
-        <attribute name="label" translatable="yes">About</attribute>
-      </item>
-      <item>
-       <attribute name="action">app.quit</attribute>
-       <attribute name="label" translatable="yes">Quit</attribute>
+        <attribute name="label" translatable="yes">About Screenshot</attribute>
       </item>
     </section>
   </menu>
diff --git a/src/screenshot-application.c b/src/screenshot-application.c
index 92134ab..b588437 100644
--- a/src/screenshot-application.c
+++ b/src/screenshot-application.c
@@ -481,20 +481,9 @@ finish_prepare_screenshot (ScreenshotApplication *self,
 
   if (screenshot_config->take_window_shot)
     {
-      switch (screenshot_config->border_effect[0])
+      if (screenshot_config->use_shadow)
         {
-        case 's': /* shadow */
           screenshot_add_shadow (&screenshot);
-          break;
-        case 'b': /* border */
-          screenshot_add_border (&screenshot);
-          break;
-        case 'v': /* vintage */
-          screenshot_add_vintage (&screenshot);
-          break;
-        case 'n': /* none */
-        default:
-          break;
         }
     }
 
@@ -601,7 +590,7 @@ static const GOptionEntry entries[] = {
   { "remove-border", 'B', 0, G_OPTION_ARG_NONE, NULL, N_("Remove the window border from the screenshot"), 
NULL },
   { "include-pointer", 'p', 0, G_OPTION_ARG_NONE, NULL, N_("Include the pointer with the screenshot"), NULL 
},
   { "delay", 'd', 0, G_OPTION_ARG_INT, NULL, N_("Take screenshot after specified delay [in seconds]"), 
N_("seconds") },
-  { "border-effect", 'e', 0, G_OPTION_ARG_STRING, NULL, N_("Effect to add to the border (shadow, border, 
vintage or none)"), N_("effect") },
+  { "use-shadow", 'b', 0, G_OPTION_ARG_NONE, NULL, N_("Apply a window shadow to the screenshot"), NULL },
   { "interactive", 'i', 0, G_OPTION_ARG_NONE, NULL, N_("Interactively set options"), NULL },
   { "file", 'f', 0, G_OPTION_ARG_FILENAME, NULL, N_("Save screenshot directly to this file"), N_("filename") 
},
   { "version", 0, 0, G_OPTION_ARG_NONE, &version_arg, N_("Print version information and exit"), NULL },
@@ -645,7 +634,7 @@ screenshot_application_command_line (GApplication            *app,
   gboolean disable_border_arg = FALSE;
   gboolean include_pointer_arg = FALSE;
   gboolean interactive_arg = FALSE;
-  gchar *border_effect_arg = NULL;
+  gboolean use_shadow_arg = FALSE;
   guint delay_arg = 0;
   gchar *file_arg = NULL;
   GVariantDict *options;
@@ -660,7 +649,7 @@ screenshot_application_command_line (GApplication            *app,
   g_variant_dict_lookup (options, "remove-border", "b", &disable_border_arg);
   g_variant_dict_lookup (options, "include-pointer", "b", &include_pointer_arg);
   g_variant_dict_lookup (options, "interactive", "b", &interactive_arg);
-  g_variant_dict_lookup (options, "border-effect", "&s", &border_effect_arg);
+  g_variant_dict_lookup (options, "use-shadow", "b", &use_shadow_arg);
   g_variant_dict_lookup (options, "delay", "i", &delay_arg);
   g_variant_dict_lookup (options, "file", "^&ay", &file_arg);
 
@@ -670,7 +659,7 @@ screenshot_application_command_line (GApplication            *app,
                                               include_border_arg,
                                               disable_border_arg,
                                               include_pointer_arg,
-                                              border_effect_arg,
+                                              use_shadow_arg,
                                               delay_arg,
                                               interactive_arg,
                                               file_arg);
@@ -726,10 +715,17 @@ action_about (GSimpleAction *action,
     NULL
   };
 
+  const gchar *artists[] = {
+    "Tobias Bernard",
+    "Jakub Steiner",
+    NULL
+  };
+
   GList *windows = gtk_application_get_windows (GTK_APPLICATION (user_data));
   gtk_show_about_dialog (GTK_WINDOW (g_list_nth_data (windows, 0)),
                          "version", VERSION,
                          "authors", authors,
+                         "artists", artists,
                          "program-name", _("Screenshot"),
                          "comments", _("Save images of your screen or individual windows"),
                          "logo-icon-name", SCREENSHOT_ICON_NAME,
@@ -752,7 +748,7 @@ action_screen_shot (GSimpleAction *action,
                                         FALSE, /* include border */
                                         FALSE, /* disable border */
                                         FALSE, /* include pointer */
-                                        NULL,  /* border effect */
+                                        FALSE,  /* use shadow */
                                         0,     /* delay */
                                         FALSE, /* interactive */
                                         NULL); /* file */
@@ -772,7 +768,7 @@ action_window_shot (GSimpleAction *action,
                                         FALSE, /* include border */
                                         FALSE, /* disable border */
                                         FALSE, /* include pointer */
-                                        NULL,  /* border effect */
+                                        FALSE,  /* use shadow */
                                         0,     /* delay */
                                         FALSE, /* interactive */
                                         NULL); /* file */
@@ -790,9 +786,10 @@ static GActionEntry action_entries[] = {
 static void
 screenshot_application_startup (GApplication *app)
 {
-  g_autoptr(GMenuModel) menu = NULL;
-  g_autoptr(GtkBuilder) builder = NULL;
+  const gchar *help_accels[2] = { "F1", NULL };
+  const gchar *quit_accels[2] = { "<Primary>q", NULL };
   ScreenshotApplication *self = SCREENSHOT_APPLICATION (app);
+  g_application_set_resource_base_path (app, "/org/gnome/screenshot");
 
   G_APPLICATION_CLASS (screenshot_application_parent_class)->startup (app);
 
@@ -804,10 +801,8 @@ screenshot_application_startup (GApplication *app)
   g_action_map_add_action_entries (G_ACTION_MAP (self), action_entries,
                                    G_N_ELEMENTS (action_entries), self);
 
-  builder = gtk_builder_new ();
-  gtk_builder_add_from_resource (builder, "/org/gnome/screenshot/screenshot-app-menu.ui", NULL);
-  menu = G_MENU_MODEL (gtk_builder_get_object (builder, "app-menu"));
-  gtk_application_set_app_menu (GTK_APPLICATION (app), menu);
+  gtk_application_set_accels_for_action (GTK_APPLICATION (self), "app.help", help_accels);
+  gtk_application_set_accels_for_action (GTK_APPLICATION (self), "app.quit", quit_accels);
 }
 
 static void
diff --git a/src/screenshot-config.c b/src/screenshot-config.c
index c095f24..ff2b82b 100644
--- a/src/screenshot-config.c
+++ b/src/screenshot-config.c
@@ -26,7 +26,7 @@
 
 #include "screenshot-config.h"
 
-#define BORDER_EFFECT_KEY       "border-effect"
+#define USE_SHADOW_KEY          "use-shadow"
 #define DELAY_KEY               "delay"
 #define INCLUDE_BORDER_KEY      "include-border"
 #define INCLUDE_POINTER_KEY     "include-pointer"
@@ -57,9 +57,9 @@ screenshot_load_config (void)
   config->include_pointer =
     g_settings_get_boolean (config->settings,
                             INCLUDE_POINTER_KEY);
-  config->border_effect =
-    g_settings_get_string (config->settings,
-                           BORDER_EFFECT_KEY);
+  config->use_shadow =
+    g_settings_get_boolean (config->settings,
+                           USE_SHADOW_KEY);
   config->file_type =
     g_settings_get_string (config->settings,
                            DEFAULT_FILE_TYPE_KEY);
@@ -67,9 +67,6 @@ screenshot_load_config (void)
     g_settings_get_boolean (config->settings,
                             INCLUDE_ICC_PROFILE);
 
-  if (config->border_effect == NULL)
-    config->border_effect = g_strdup ("none");
-
   config->take_window_shot = FALSE;
   config->take_area_shot = FALSE;
 
@@ -93,8 +90,8 @@ screenshot_save_config (void)
                           INCLUDE_BORDER_KEY, c->include_border);
   g_settings_set_boolean (c->settings,
                           INCLUDE_POINTER_KEY, c->include_pointer);
-  g_settings_set_string (c->settings,
-                         BORDER_EFFECT_KEY, c->border_effect);
+  g_settings_set_boolean (c->settings,
+                         USE_SHADOW_KEY, c->use_shadow);
 
   if (!c->take_area_shot)
     g_settings_set_int (c->settings, DELAY_KEY, c->delay);
@@ -107,7 +104,7 @@ screenshot_config_parse_command_line (gboolean clipboard_arg,
                                       gboolean include_border_arg,
                                       gboolean disable_border_arg,
                                       gboolean include_pointer_arg,
-                                      const gchar *border_effect_arg,
+                                      gboolean use_shadow_arg,
                                       guint delay_arg,
                                       gboolean interactive_arg,
                                       const gchar *file_arg)
@@ -156,16 +153,11 @@ screenshot_config_parse_command_line (gboolean clipboard_arg,
       screenshot_config->include_border = !disable_border_arg;
       screenshot_config->include_pointer = include_pointer_arg;
       screenshot_config->copy_to_clipboard = clipboard_arg;
+      screenshot_config->use_shadow = use_shadow_arg;
       if (file_arg != NULL)
         screenshot_config->file = g_file_new_for_commandline_arg (file_arg);
     }
 
-  if (border_effect_arg != NULL)
-    {
-      g_free (screenshot_config->border_effect);
-      screenshot_config->border_effect = g_strdup (border_effect_arg);
-    }
-
   screenshot_config->take_window_shot = window_arg;
   screenshot_config->take_area_shot = area_arg;
 
diff --git a/src/screenshot-config.h b/src/screenshot-config.h
index a1989d2..fbb275d 100644
--- a/src/screenshot-config.h
+++ b/src/screenshot-config.h
@@ -41,7 +41,8 @@ typedef struct {
   gboolean include_icc_profile;
 
   gboolean include_border;
-  gchar *border_effect;
+
+  gboolean use_shadow;
 
   guint delay;
 
@@ -58,7 +59,7 @@ gboolean    screenshot_config_parse_command_line  (gboolean clipboard_arg,
                                                    gboolean include_border_arg,
                                                    gboolean disable_border_arg,
                                                    gboolean include_pointer_arg,
-                                                   const gchar *border_effect_arg,
+                                                   gboolean use_shadow_arg,
                                                    guint delay_arg,
                                                    gboolean interactive_arg,
                                                    const gchar *file_arg);
diff --git a/src/screenshot-dialog.c b/src/screenshot-dialog.c
index 40e560b..d674584 100644
--- a/src/screenshot-dialog.c
+++ b/src/screenshot-dialog.c
@@ -43,30 +43,49 @@ on_preview_draw (GtkWidget      *drawing_area,
                  gpointer        data)
 {
   ScreenshotDialog *dialog = data;
-  GtkStyleContext *context;
-  int width, height;
+  gint scale, width, height, image_width, image_height, x, y;
 
-  width = gtk_widget_get_allocated_width (drawing_area);
-  height = gtk_widget_get_allocated_height (drawing_area);
+  scale = gtk_widget_get_scale_factor (drawing_area);
+  width = gtk_widget_get_allocated_width (drawing_area) * scale;
+  height = gtk_widget_get_allocated_height (drawing_area) * scale;
+
+  image_width = gdk_pixbuf_get_width (dialog->screenshot);
+  image_height = gdk_pixbuf_get_height (dialog->screenshot);
+
+  if (image_width > width)
+    {
+      image_height = (gdouble) image_height / image_width * width;
+      image_width = width;
+
+    }
+
+  if (image_height > height)
+    {
+      image_width = (gdouble) image_width / image_height * height;
+      image_height = height;
+    }
+
+  x = (width - image_width) / 2;
+  y = (height - image_height) / 2;
 
   if (!dialog->preview_image ||
-      gdk_pixbuf_get_width (dialog->preview_image) != width ||
-      gdk_pixbuf_get_height (dialog->preview_image) != height)
+      gdk_pixbuf_get_width (dialog->preview_image) != image_width ||
+      gdk_pixbuf_get_height (dialog->preview_image) != image_height)
     {
       g_clear_object (&dialog->preview_image);
       dialog->preview_image = gdk_pixbuf_scale_simple (dialog->screenshot,
-                                                       width,
-                                                       height,
+                                                       image_width,
+                                                       image_height,
                                                        GDK_INTERP_BILINEAR);
     }
 
-  context = gtk_widget_get_style_context (drawing_area);
-  gtk_style_context_save (context);
+  cairo_save (cr);
 
-  gtk_style_context_set_state (context, gtk_widget_get_state_flags (drawing_area));
-  gtk_render_icon (context, cr, dialog->preview_image, 0, 0);
+  cairo_scale (cr, 1.0 / scale, 1.0 / scale);
+  gdk_cairo_set_source_pixbuf (cr, dialog->preview_image, x, y);
+  cairo_paint (cr);
 
-  gtk_style_context_restore (context);
+  cairo_restore (cr);
 }
 
 static gboolean
@@ -114,7 +133,7 @@ drag_begin (GtkWidget        *widget,
             GdkDragContext   *context,
             ScreenshotDialog *dialog)
 {
-  gtk_drag_set_icon_pixbuf (context, dialog->preview_image,
+  gtk_drag_set_icon_pixbuf (context, dialog->screenshot,
                             dialog->drag_x, dialog->drag_y);
 }
 
@@ -123,12 +142,6 @@ dialog_key_press_cb (GtkWidget *widget,
                      GdkEventKey *event,
                      gpointer user_data)
 {
-  if (event->keyval == GDK_KEY_F1)
-    {
-      screenshot_display_help (GTK_WINDOW (widget));
-      return TRUE;
-    }
-
   if (event->keyval == GDK_KEY_Escape)
     {
       gtk_widget_destroy (widget);
@@ -157,29 +170,9 @@ static void
 setup_drawing_area (ScreenshotDialog *dialog, GtkBuilder *ui)
 {
   GtkWidget *preview_darea;
-  GtkWidget *aspect_frame;
-  gint width, height, scale_factor;
 
-  aspect_frame = GTK_WIDGET (gtk_builder_get_object (ui, "aspect_frame"));
   preview_darea = GTK_WIDGET (gtk_builder_get_object (ui, "preview_darea"));
 
-  width = gdk_pixbuf_get_width (dialog->screenshot);
-  height = gdk_pixbuf_get_height (dialog->screenshot);
-  scale_factor = gtk_widget_get_scale_factor (dialog->dialog);
-
-  width /= 5 * scale_factor;
-  height /= 5 * scale_factor;
-
-  gtk_widget_set_size_request (preview_darea, width, height);
-  gtk_aspect_frame_set (GTK_ASPECT_FRAME (aspect_frame), 0.0, 0.5,
-                        (gfloat) width / (gfloat) height,
-                        FALSE);
-
-  if (screenshot_config->take_window_shot)
-    gtk_frame_set_shadow_type (GTK_FRAME (aspect_frame), GTK_SHADOW_NONE);
-  else
-    gtk_frame_set_shadow_type (GTK_FRAME (aspect_frame), GTK_SHADOW_IN);
-
   g_signal_connect (preview_darea, "draw", G_CALLBACK (on_preview_draw), dialog);
   g_signal_connect (preview_darea, "button_press_event", G_CALLBACK (on_preview_button_press_event), dialog);
   g_signal_connect (preview_darea, "button_release_event", G_CALLBACK (on_preview_button_release_event), 
dialog);
diff --git a/src/screenshot-dialog.ui b/src/screenshot-dialog.ui
index 3d1d5f5..455ca30 100644
--- a/src/screenshot-dialog.ui
+++ b/src/screenshot-dialog.ui
@@ -1,201 +1,146 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.0 -->
 <interface>
-  <!-- interface-requires gtk+ 3.8 -->
+  <requires lib="gtk+" version="3.22"/>
   <object class="GtkApplicationWindow" id="toplevel">
     <property name="can_focus">False</property>
-    <property name="border_width">5</property>
-    <property name="title" translatable="yes">Save Screenshot</property>
-    <property name="resizable">False</property>
     <property name="window_position">center</property>
-    <property name="modal">True</property>
     <child type="titlebar">
-      <object class="GtkHeaderBar" id="headerbar1">
+      <object class="GtkHeaderBar">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
-        <property name="show_close_button">True</property>
         <child>
           <object class="GtkButton" id="back_button">
-            <property name="tooltip_text" translatable="yes">Back</property>
+            <property name="label" translatable="yes">_Cancel</property>
             <property name="visible">True</property>
             <property name="can_focus">True</property>
             <property name="receives_default">True</property>
             <property name="use_underline">True</property>
-            <style>
-              <class name="image-button"/>
-            </style>
-            <child>
-              <object class="GtkImage">
-                <property name="visible">True</property>
-                <property name="icon_name">go-previous-symbolic</property>
-              </object>
-            </child>
           </object>
-          <packing>
-            <property name="pack-type">start</property>
-          </packing>
         </child>
         <child>
-          <object class="GtkButton" id="copy_button">
-            <property name="label" translatable="yes">C_opy to Clipboard</property>
+          <object class="GtkButton" id="save_button">
+            <property name="label" translatable="yes">_Save</property>
             <property name="visible">True</property>
             <property name="can_focus">True</property>
+            <property name="can_default">True</property>
+            <property name="has_default">True</property>
             <property name="receives_default">True</property>
             <property name="use_underline">True</property>
+            <style>
+              <class name="suggested-action"/>
+            </style>
           </object>
           <packing>
-            <property name="pack-type">start</property>
+            <property name="pack_type">end</property>
+            <property name="position">1</property>
           </packing>
         </child>
         <child>
-          <object class="GtkButton" id="save_button">
-            <property name="label" translatable="yes">_Save</property>
+          <object class="GtkButton" id="copy_button">
+            <property name="label" translatable="yes">C_opy to Clipboard</property>
             <property name="visible">True</property>
             <property name="can_focus">True</property>
-            <property name="can_default">True</property>
-            <property name="has_default">True</property>
             <property name="receives_default">True</property>
             <property name="use_underline">True</property>
-            <style>
-              <class name="suggested-action"/>
-            </style>
           </object>
           <packing>
-            <property name="pack-type">end</property>
+            <property name="pack_type">end</property>
+            <property name="position">2</property>
           </packing>
         </child>
       </object>
     </child>
     <child>
-      <object class="GtkGrid" id="grid1">
+      <object class="GtkBox">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
-        <property name="margin_left">5</property>
-        <property name="margin_right">5</property>
-        <property name="margin_top">5</property>
-        <property name="margin_bottom">5</property>
-        <property name="row_spacing">8</property>
-        <property name="column_spacing">8</property>
+        <property name="halign">fill</property>
+        <property name="valign">fill</property>
+        <property name="expand">True</property>
+        <property name="margin">24</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">24</property>
         <child>
-          <object class="GtkAlignment" id="alignment1">
+           <object class="GtkDrawingArea" id="preview_darea">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
-            <property name="vexpand">True</property>
-            <child>
-              <object class="GtkAspectFrame" id="aspect_frame">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="label_xalign">0</property>
-                <property name="shadow_type">none</property>
-                <child>
-                  <object class="GtkDrawingArea" id="preview_darea">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                  </object>
-                </child>
-              </object>
-            </child>
+            <property name="width-request">256</property>
+            <property name="height-request">256</property>
+            <property name="expand">True</property>
           </object>
           <packing>
-            <property name="left_attach">0</property>
-            <property name="top_attach">0</property>
-            <property name="width">1</property>
-            <property name="height">2</property>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
           </packing>
         </child>
         <child>
-          <object class="GtkGrid" id="grid2">
+          <object class="GtkGrid">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
-            <property name="row_spacing">8</property>
-            <property name="column_spacing">8</property>
-            <property name="valign">start</property>
+            <property name="halign">center</property>
+            <property name="row_spacing">6</property>
+            <property name="column_spacing">12</property>
             <child>
-              <object class="GtkLabel" id="label1">
+              <object class="GtkLabel">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
                 <property name="halign">end</property>
-                <property name="valign">center</property>
-                <property name="label" translatable="yes">_Name</property>
+                <property name="label" translatable="yes">_Name:</property>
                 <property name="use_underline">True</property>
                 <property name="mnemonic_widget">filename_entry</property>
-                <style>
-                  <class name="dim-label"/>
-                </style>
               </object>
               <packing>
                 <property name="left_attach">0</property>
                 <property name="top_attach">0</property>
-                <property name="width">1</property>
-                <property name="height">1</property>
               </packing>
             </child>
             <child>
-              <object class="GtkLabel" id="label2">
+              <object class="GtkLabel">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
                 <property name="halign">end</property>
-                <property name="valign">center</property>
-                <property name="label" translatable="yes">Save in _folder</property>
+                <property name="label" translatable="yes">_Folder:</property>
                 <property name="use_underline">True</property>
                 <property name="mnemonic_widget">save_widget</property>
-                <style>
-                  <class name="dim-label"/>
-                </style>
               </object>
               <packing>
                 <property name="left_attach">0</property>
                 <property name="top_attach">1</property>
-                <property name="width">1</property>
-                <property name="height">1</property>
               </packing>
             </child>
             <child>
               <object class="GtkEntry" id="filename_entry">
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
-                <property name="valign">center</property>
-                <property name="activates_default">True</property>
-                <property name="width_chars">32</property>
+                <property name="width_chars">35</property>
               </object>
               <packing>
                 <property name="left_attach">1</property>
                 <property name="top_attach">0</property>
-                <property name="width">1</property>
-                <property name="height">1</property>
               </packing>
             </child>
             <child>
               <object class="GtkFileChooserButton" id="save_widget">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="valign">center</property>
-                <property name="vexpand">True</property>
                 <property name="action">select-folder</property>
                 <property name="local_only">False</property>
               </object>
               <packing>
                 <property name="left_attach">1</property>
                 <property name="top_attach">1</property>
-                <property name="width">1</property>
-                <property name="height">1</property>
               </packing>
             </child>
           </object>
           <packing>
-            <property name="left_attach">1</property>
-            <property name="top_attach">0</property>
-            <property name="width">2</property>
-            <property name="height">1</property>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
           </packing>
         </child>
       </object>
     </child>
   </object>
-  <object class="GtkSizeGroup" id="header_bar_size_group">
-    <property name="mode">horizontal</property>
-    <widgets>
-      <widget name="copy_button"/>
-      <widget name="save_button"/>
-    </widgets>
-  </object>
 </interface>
diff --git a/src/screenshot-interactive-dialog.c b/src/screenshot-interactive-dialog.c
index e24552e..9888f90 100644
--- a/src/screenshot-interactive-dialog.c
+++ b/src/screenshot-interactive-dialog.c
@@ -25,15 +25,14 @@
 
 #include <glib/gi18n.h>
 
+#include "screenshot-application.h"
 #include "screenshot-config.h"
 #include "screenshot-interactive-dialog.h"
 #include "screenshot-utils.h"
 
-static GtkWidget *border_check = NULL;
-static GtkWidget *effect_combo = NULL;
-static GtkWidget *effect_label = NULL;
-static GtkWidget *effects_vbox = NULL;
-static GtkWidget *delay_hbox = NULL;
+static GtkWidget *pointer_row = NULL;
+static GtkWidget *shadow_row = NULL;
+static GtkWidget *delay_row = NULL;
 
 enum
 {
@@ -67,12 +66,10 @@ target_toggled_cb (GtkToggleButton *button,
       take_window_shot = (target_toggle == TARGET_TOGGLE_WINDOW);
       take_area_shot = (target_toggle == TARGET_TOGGLE_AREA);
 
-      gtk_widget_set_sensitive (border_check, take_window_shot);
-      gtk_widget_set_sensitive (effect_combo, take_window_shot);
-      gtk_widget_set_sensitive (effect_label, take_window_shot);
+      gtk_widget_set_sensitive (shadow_row, take_window_shot);
 
-      gtk_widget_set_sensitive (delay_hbox, !take_area_shot);
-      gtk_widget_set_sensitive (effects_vbox, !take_area_shot);
+      gtk_widget_set_sensitive (pointer_row, !take_area_shot);
+      gtk_widget_set_sensitive (delay_row, !take_area_shot);
 
       screenshot_config->take_window_shot = take_window_shot;
       screenshot_config->take_area_shot = take_area_shot;
@@ -86,332 +83,104 @@ delay_spin_value_changed_cb (GtkSpinButton *button)
 }
 
 static void
-include_border_toggled_cb (GtkToggleButton *button,
-                           gpointer         data)
-{
-  screenshot_config->include_border = gtk_toggle_button_get_active (button);
-}
-
-static void
-include_pointer_toggled_cb (GtkToggleButton *button,
+include_pointer_toggled_cb (GtkSwitch *toggle,
                             gpointer         data)
 {
-  screenshot_config->include_pointer = gtk_toggle_button_get_active (button);
+  screenshot_config->include_pointer = gtk_switch_get_active (toggle);
+  gtk_switch_set_state (toggle, gtk_switch_get_active (toggle));
 }
 
 static void
-effect_combo_changed_cb (GtkComboBox *combo,
+use_shadow_toggled_cb (GtkSwitch *toggle,
                          gpointer     user_data)
 {
-  GtkTreeIter iter;
-
-  if (gtk_combo_box_get_active_iter (combo, &iter))
-    {
-      GtkTreeModel *model;
-      gchar *effect;
-
-      model = gtk_combo_box_get_model (combo);
-      gtk_tree_model_get (model, &iter, COLUMN_NICK, &effect, -1);
-
-      g_assert (effect != NULL);
-
-      g_free (screenshot_config->border_effect);
-      screenshot_config->border_effect = effect; /* gets free'd later */
-    }
-}
-
-static gint
-interactive_dialog_key_press_cb (GtkWidget   *widget,
-                                 GdkEventKey *event,
-                                 gpointer    user_data)
-{
-  if (event->keyval == GDK_KEY_F1)
-    {
-      screenshot_display_help (GTK_WINDOW (widget));
-      return TRUE;
-    }
-
-  if (event->keyval == GDK_KEY_Escape)
-    {
-      gtk_widget_destroy (widget);
-      return TRUE;
-    }
-
-  return FALSE;
-}
-
-typedef struct {
-  ScreenshotEffectType id;
-  const gchar *label;
-  const gchar *nick;
-} ScreenshotEffect;
-
-static const ScreenshotEffect effects[] = {
-  /* Translators:
-   * these are the names of the effects available which will be
-   * displayed inside a combo box in interactive mode for the user
-   * to chooser.
-   */
-  { SCREENSHOT_EFFECT_NONE, N_("None"), "none" },
-  { SCREENSHOT_EFFECT_SHADOW, N_("Drop shadow"), "shadow" },
-  { SCREENSHOT_EFFECT_BORDER, N_("Border"), "border" },
-  { SCREENSHOT_EFFECT_VINTAGE, N_("Vintage"), "vintage" }
-};
-
-static guint n_effects = G_N_ELEMENTS (effects);
-
-static GtkWidget *
-create_effects_combo (void)
-{
-  g_autoptr(GtkListStore) model = NULL;
-  GtkWidget *retval;
-  GtkCellRenderer *renderer;
-  gint i;
-
-  model = gtk_list_store_new (N_COLUMNS,
-                              G_TYPE_STRING,
-                              G_TYPE_STRING,
-                              G_TYPE_UINT);
-
-  for (i = 0; i < n_effects; i++)
-    {
-      GtkTreeIter iter;
-
-      gtk_list_store_insert (model, &iter, i);
-      gtk_list_store_set (model, &iter,
-                          COLUMN_ID, effects[i].id,
-                          COLUMN_LABEL, gettext (effects[i].label),
-                          COLUMN_NICK, effects[i].nick,
-                          -1);
-    }
-
-  retval = gtk_combo_box_new ();
-  gtk_combo_box_set_model (GTK_COMBO_BOX (retval),
-                           GTK_TREE_MODEL (model));
-
-  switch (screenshot_config->border_effect[0])
-    {
-    case 's': /* shadow */
-      gtk_combo_box_set_active (GTK_COMBO_BOX (retval),
-                                SCREENSHOT_EFFECT_SHADOW);
-      break;
-    case 'b': /* border */
-      gtk_combo_box_set_active (GTK_COMBO_BOX (retval),
-                                SCREENSHOT_EFFECT_BORDER);
-      break;
-    case 'v': /* vintage */
-      gtk_combo_box_set_active (GTK_COMBO_BOX (retval),
-                                SCREENSHOT_EFFECT_VINTAGE);
-      break;
-    case 'n': /* none */
-      gtk_combo_box_set_active (GTK_COMBO_BOX (retval),
-                                SCREENSHOT_EFFECT_NONE);
-      break;
-    default:
-      break;
-    }
-
-  renderer = gtk_cell_renderer_text_new ();
-  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (retval), renderer, TRUE);
-  gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (retval), renderer,
-                                  "text", COLUMN_LABEL,
-                                  NULL);
-
-  g_signal_connect (retval, "changed",
-                    G_CALLBACK (effect_combo_changed_cb),
-                    NULL);
-
-  return retval;
+  screenshot_config->use_shadow = gtk_switch_get_active (toggle);
+  gtk_switch_set_state (toggle, gtk_switch_get_active (toggle));
 }
 
 static void
-create_effects_frame (GtkWidget   *outer_vbox,
-                      const gchar *frame_title)
+connect_effects_frame (GtkBuilder *ui)
 {
-  GtkWidget *main_vbox, *vbox, *hbox;
-  GtkWidget *label;
-  GtkWidget *check;
-  GtkWidget *combo;
-  g_autofree gchar *title = NULL;
-
-  main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
-  gtk_box_pack_start (GTK_BOX (outer_vbox), main_vbox, FALSE, FALSE, 0);
-  gtk_widget_show (main_vbox);
-  effects_vbox = main_vbox;
-
-  title = g_strconcat ("<b>", frame_title, "</b>", NULL);
-  label = gtk_label_new (title);
-  gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
-  gtk_widget_set_halign (label, GTK_ALIGN_START);
-  gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
-  gtk_box_pack_start (GTK_BOX (main_vbox), label, FALSE, FALSE, 0);
-  gtk_widget_show (label);
-
-  hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
-  gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
-  gtk_widget_show (hbox);
-
-  vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
-  gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
-  gtk_widget_set_margin_start (vbox, 12);
-  gtk_widget_show (vbox);
+  GtkWidget *pointer;
+  GtkWidget *shadow;
 
   /** Include pointer **/
-  check = gtk_check_button_new_with_mnemonic (_("Include _pointer"));
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check),
-                                screenshot_config->include_pointer);
-  g_signal_connect (check, "toggled",
+  pointer = GTK_WIDGET (gtk_builder_get_object (ui, "pointer"));
+  gtk_switch_set_active (GTK_SWITCH (pointer), screenshot_config->include_pointer);
+  g_signal_connect (pointer, "state-set",
                     G_CALLBACK (include_pointer_toggled_cb),
                     NULL);
-  gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
-  gtk_widget_show (check);
-
-  /** Include window border **/
-  check = gtk_check_button_new_with_mnemonic (_("Include the window _border"));
-  gtk_widget_set_sensitive (check,
-                            screenshot_config->take_window_shot);
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check),
-                                screenshot_config->include_border);
-  g_signal_connect (check, "toggled",
-                    G_CALLBACK (include_border_toggled_cb),
+
+  /** Use shadow **/
+  shadow = GTK_WIDGET (gtk_builder_get_object (ui, "shadow"));
+  gtk_switch_set_active (GTK_SWITCH (shadow), screenshot_config->use_shadow);
+  g_signal_connect (shadow, "state-set",
+                    G_CALLBACK (use_shadow_toggled_cb),
                     NULL);
-  gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
-  gtk_widget_show (check);
-  border_check = check;
-
-  /** Effects **/
-  hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
-  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
-  gtk_widget_show (hbox);
-
-  label = gtk_label_new_with_mnemonic (_("Apply _effect:"));
-  gtk_widget_set_sensitive (label, screenshot_config->take_window_shot);
-  gtk_widget_set_halign (label, GTK_ALIGN_START);
-  gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
-  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-  gtk_widget_show (label);
-  effect_label = label;
-
-  combo = create_effects_combo ();
-  gtk_widget_set_sensitive (combo, screenshot_config->take_window_shot);
-  gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, FALSE, 0);
-  gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo);
-  gtk_widget_show (combo);
-  effect_combo = combo;
 }
 
 static void
-create_screenshot_frame (GtkWidget   *outer_vbox,
-                         const gchar *frame_title)
+connect_screenshot_frame (GtkBuilder *ui)
 {
-  GtkWidget *main_vbox, *vbox, *hbox;
-  GtkWidget *radio;
-  GtkWidget *image;
-  GtkWidget *spin;
-  GtkWidget *label;
   GtkAdjustment *adjust;
+  GtkWidget *screen;
+  GtkWidget *selection;
+  GtkWidget *window;
+  GtkWidget *delay;
   GSList *group;
-  g_autofree gchar *title = NULL;
-
-  main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
-  gtk_box_pack_start (GTK_BOX (outer_vbox), main_vbox, FALSE, FALSE, 0);
-  gtk_widget_show (main_vbox);
-
-  title = g_strconcat ("<b>", frame_title, "</b>", NULL);
-  label = gtk_label_new (title);
-  gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
-  gtk_widget_set_halign (label, GTK_ALIGN_START);
-  gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
-  gtk_box_pack_start (GTK_BOX (main_vbox), label, FALSE, FALSE, 0);
-  gtk_widget_show (label);
-
-  hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
-  gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
-  gtk_widget_show (hbox);
-
-  image = gtk_image_new_from_icon_name (SCREENSHOT_ICON_NAME, GTK_ICON_SIZE_DIALOG);
-  gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
-  gtk_widget_show (image);
-
-  vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
-  gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
-  gtk_widget_show (vbox);
 
   /** Grab whole screen **/
   group = NULL;
-  radio = gtk_radio_button_new_with_mnemonic (group,
-                                              _("Grab the whole sc_reen"));
+  screen = GTK_WIDGET (gtk_builder_get_object (ui, "screen"));
+
   if (screenshot_config->take_window_shot ||
       screenshot_config->take_area_shot)
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), FALSE);
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (screen), FALSE);
 
-  g_signal_connect (radio, "toggled",
+  g_signal_connect (screen, "toggled",
                     G_CALLBACK (target_toggled_cb),
                     GINT_TO_POINTER (TARGET_TOGGLE_DESKTOP));
-  gtk_box_pack_start (GTK_BOX (vbox), radio, FALSE, FALSE, 0);
-  group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio));
-  gtk_widget_show (radio);
+  group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (screen));
 
   /** Grab current window **/
-  radio = gtk_radio_button_new_with_mnemonic (group,
-                                              _("Grab the current _window"));
+  window = GTK_WIDGET (gtk_builder_get_object (ui, "window"));
+  gtk_radio_button_set_group (GTK_RADIO_BUTTON (window), group);
+
   if (screenshot_config->take_window_shot)
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), TRUE);
-  g_signal_connect (radio, "toggled",
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (window), TRUE);
+  g_signal_connect (window, "toggled",
                     G_CALLBACK (target_toggled_cb),
                     GINT_TO_POINTER (TARGET_TOGGLE_WINDOW));
-  gtk_box_pack_start (GTK_BOX (vbox), radio, FALSE, FALSE, 0);
-  group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio));
-  gtk_widget_show (radio);
+  group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (window));
+
+  shadow_row = GTK_WIDGET (gtk_builder_get_object (ui, "shadowrow"));
+  gtk_widget_set_sensitive (shadow_row, screenshot_config->take_window_shot);
 
   /** Grab area of the desktop **/
-  radio = gtk_radio_button_new_with_mnemonic (group,
-                                              _("Select _area to grab"));
+  selection = GTK_WIDGET (gtk_builder_get_object (ui, "selection"));
+
   if (screenshot_config->take_area_shot)
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), TRUE);
-  g_signal_connect (radio, "toggled",
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (selection), TRUE);
+  g_signal_connect (selection, "toggled",
                     G_CALLBACK (target_toggled_cb),
                     GINT_TO_POINTER (TARGET_TOGGLE_AREA));
-  gtk_box_pack_start (GTK_BOX (vbox), radio, FALSE, FALSE, 0);
-  gtk_widget_show (radio);
+  pointer_row = GTK_WIDGET (gtk_builder_get_object (ui, "pointerrow"));
+  gtk_widget_set_sensitive (pointer_row, !screenshot_config->take_area_shot);
 
   /** Grab after delay **/
-  delay_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
-  gtk_box_pack_start (GTK_BOX (vbox), delay_hbox, FALSE, FALSE, 0);
-  gtk_widget_show (delay_hbox);
-
-  if (screenshot_config->take_area_shot)
-    gtk_widget_set_sensitive (delay_hbox, FALSE);
-
-  /* translators: this is the first part of the "grab after a
-   * delay of <spin button> seconds".
-   */
-  label = gtk_label_new_with_mnemonic (_("Grab after a _delay of"));
-  gtk_widget_set_halign (label, GTK_ALIGN_START);
-  gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
-  gtk_box_pack_start (GTK_BOX (delay_hbox), label, FALSE, FALSE, 0);
-  gtk_widget_show (label);
+  delay = GTK_WIDGET (gtk_builder_get_object (ui, "delay"));
+  delay_row = GTK_WIDGET (gtk_builder_get_object (ui, "delayrow"));
+  gtk_widget_set_sensitive (delay_row, !screenshot_config->take_area_shot);
 
   adjust = GTK_ADJUSTMENT (gtk_adjustment_new ((gdouble) screenshot_config->delay,
                                                0.0, 99.0,
                                                1.0,  1.0,
                                                0.0));
-  spin = gtk_spin_button_new (adjust, 1.0, 0);
-  g_signal_connect (spin, "value-changed",
+
+  gtk_spin_button_set_adjustment (GTK_SPIN_BUTTON (delay), adjust);
+  g_signal_connect (delay, "value-changed",
                     G_CALLBACK (delay_spin_value_changed_cb),
                     NULL);
-  gtk_box_pack_start (GTK_BOX (delay_hbox), spin, FALSE, FALSE, 0);
-  gtk_label_set_mnemonic_widget (GTK_LABEL (label), spin);
-  gtk_widget_show (spin);
-
-  /* translators: this is the last part of the "grab after a
-   * delay of <spin button> seconds".
-   */
-  label = gtk_label_new (_("seconds"));
-  gtk_widget_set_halign (label, GTK_ALIGN_START);
-  gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
-  gtk_box_pack_end (GTK_BOX (delay_hbox), label, FALSE, FALSE, 0);
-  gtk_widget_show (label);
 }
 
 typedef struct {
@@ -428,64 +197,75 @@ capture_button_clicked_cb (GtkButton *button, CaptureData *data)
   g_free (data);
 }
 
+static void
+screenshot_listbox_update_header_func (GtkListBoxRow *row,
+                                       GtkListBoxRow *before,
+                                       gpointer user_data)
+{
+  GtkWidget *current;
+
+  if (before == NULL)
+    {
+      gtk_list_box_row_set_header (row, 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);
+    }
+}
+
 GtkWidget *
 screenshot_interactive_dialog_new (CaptureClickedCallback f, gpointer user_data)
 {
+  ScreenshotApplication *self = user_data;
   GtkWidget *dialog;
-  GtkWidget *main_vbox;
-  GtkWidget *header_bar;
-  GtkWidget *button;
-  GtkStyleContext *context;
-  g_autoptr(GtkSizeGroup) size_group = NULL;
+  GtkWidget *capture_button;
+  GtkWidget *menu;
+  GtkWidget *listbox;
+  GMenuModel *app_menu;
+  GtkBuilder *ui;
   CaptureData *data;
+  guint res;
 
-  dialog = gtk_application_window_new (GTK_APPLICATION (g_application_get_default ()));
+  ui = gtk_builder_new_from_resource ("/org/gnome/screenshot/screenshot-interactive.ui");
+  res = gtk_builder_add_from_resource (ui, "/org/gnome/screenshot/screenshot-app-menu.ui", NULL);
+  g_assert (res != 0);
 
-  header_bar = gtk_header_bar_new ();
-  gtk_header_bar_set_show_close_button (GTK_HEADER_BAR (header_bar), TRUE);
-  gtk_header_bar_set_decoration_layout (GTK_HEADER_BAR (header_bar), "menu");
-  gtk_window_set_titlebar (GTK_WINDOW (dialog), header_bar);
+  dialog = GTK_WIDGET (gtk_builder_get_object (ui, "screenshot_window"));
+  gtk_window_set_application (GTK_WINDOW (dialog), GTK_APPLICATION (self));
 
-  gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
-  gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
+  capture_button = GTK_WIDGET (gtk_builder_get_object (ui, "capture_button"));
 
-  gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
+  menu = GTK_WIDGET (gtk_builder_get_object (ui, "menu"));
+  app_menu = G_MENU_MODEL (gtk_builder_get_object (ui, "app-menu"));
 
-  /* main container */
-  main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 18);
-  gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 5);
-  gtk_container_add (GTK_CONTAINER (dialog), main_vbox);
+  gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (menu), app_menu);
 
-  create_screenshot_frame (main_vbox, _("Take Screenshot"));
-  create_effects_frame (main_vbox, _("Effects"));
+  gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
 
-  size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+  listbox = GTK_WIDGET (gtk_builder_get_object (ui, "listbox"));
+  gtk_list_box_set_header_func (GTK_LIST_BOX (listbox),
+                                screenshot_listbox_update_header_func,
+                                user_data,
+                                NULL);
 
-  button = gtk_button_new_with_mnemonic (_("Take _Screenshot"));
-  gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
-  context = gtk_widget_get_style_context (button);
-  gtk_style_context_add_class (context, "suggested-action");
   data = g_new (CaptureData, 1);
   data->widget = dialog;
   data->callback = f;
   data->user_data = user_data;
-  g_signal_connect (button, "clicked", G_CALLBACK (capture_button_clicked_cb), data);
-  gtk_size_group_add_widget (size_group, button);
-  gtk_header_bar_pack_end (GTK_HEADER_BAR (header_bar), button);
-  gtk_widget_set_can_default (button, TRUE);
-  gtk_widget_grab_default (button);
-  g_signal_connect (dialog, "key-press-event",
-                    G_CALLBACK (interactive_dialog_key_press_cb),
-                    NULL);
-
-  button = gtk_button_new_with_mnemonic (_("_Cancel"));
-  gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
-  gtk_size_group_add_widget (size_group, button);
-  gtk_header_bar_pack_start (GTK_HEADER_BAR (header_bar), button);
-  g_signal_connect_swapped (button, "clicked",
-                            G_CALLBACK (gtk_widget_destroy), dialog);
+  g_signal_connect (capture_button, "clicked", G_CALLBACK (capture_button_clicked_cb), data);
+  gtk_widget_set_can_default (capture_button, TRUE);
+  gtk_widget_grab_default (capture_button);
 
   gtk_widget_show_all (dialog);
 
+  connect_screenshot_frame (ui);
+  connect_effects_frame (ui);
+
   return dialog;
 }
diff --git a/src/screenshot-interactive.ui b/src/screenshot-interactive.ui
new file mode 100644
index 0000000..ff91032
--- /dev/null
+++ b/src/screenshot-interactive.ui
@@ -0,0 +1,425 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.0 -->
+<interface>
+  <requires lib="gtk+" version="3.20"/>
+  <object class="GtkAdjustment" id="adjustment1">
+    <property name="upper">100</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">10</property>
+  </object>
+  <object class="GtkApplicationWindow" id="screenshot_window">
+    <property name="can_focus">False</property>
+    <property name="resizable">False</property>
+    <child>
+      <object class="GtkBox">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">center</property>
+        <property name="valign">center</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">24</property>
+        <property name="margin">24</property>
+        <child>
+          <object class="GtkBox">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="orientation">vertical</property>
+            <child>
+              <object class="GtkLabel">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="halign">start</property>
+                <property name="label" translatable="yes">Capture Area</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="padding">6</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkBox">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="homogeneous">True</property>
+                <child>
+                  <object class="GtkRadioButton" id="screen">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="border_width">0</property>
+                    <property name="draw_indicator">False</property>
+                    <property name="group">selection</property>
+                    <signal name="toggled" handler="on_screen" swapped="no"/>
+                    <child>
+                      <object class="GtkBox">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="border_width">12</property>
+                        <property name="orientation">vertical</property>
+                        <property name="spacing">6</property>
+                        <child>
+                          <object class="GtkImage" id="screen_img">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="icon_name">display-symbolic</property>
+                            <property name="pixel_size">32</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="valign">end</property>
+                            <property name="label" translatable="yes">_Screen</property>
+                            <property name="use_underline">True</property>
+                            <property name="mnemonic_widget">screen</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkRadioButton" id="window">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="active">True</property>
+                    <property name="draw_indicator">False</property>
+                    <property name="group">screen</property>
+                    <signal name="toggled" handler="on_window" swapped="no"/>
+                    <child>
+                      <object class="GtkBox">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="border_width">12</property>
+                        <property name="orientation">vertical</property>
+                        <property name="spacing">6</property>
+                        <child>
+                          <object class="GtkImage" id="window_img">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="icon_name">window-symbolic</property>
+                            <property name="pixel_size">32</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="valign">end</property>
+                            <property name="label" translatable="yes">_Window</property>
+                            <property name="use_underline">True</property>
+                            <property name="mnemonic_widget">window</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkRadioButton" id="selection">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="draw_indicator">False</property>
+                    <property name="group">screen</property>
+                    <signal name="toggled" handler="on_selection" swapped="no"/>
+                    <child>
+                      <object class="GtkBox">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="border_width">12</property>
+                        <property name="orientation">vertical</property>
+                        <property name="spacing">6</property>
+                        <child>
+                          <object class="GtkImage" id="selection_img">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="icon_name">selection-symbolic</property>
+                            <property name="pixel_size">32</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="valign">end</property>
+                            <property name="label" translatable="yes">Se_lection</property>
+                            <property name="use_underline">True</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
+                <style>
+                  <class name="linked"/>
+                </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">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkFrame" id="frame">
+            <property name="width_request">360</property>
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label_xalign">0</property>
+            <property name="label_yalign">0</property>
+            <property name="shadow_type">in</property>
+            <child>
+              <object class="GtkAlignment">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <child>
+                  <object class="GtkListBox" id="listbox">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="selection_mode">none</property>
+                    <property name="activate_on_single_click">False</property>
+                    <child>
+                      <object class="GtkListBoxRow" id="pointerrow">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <child>
+                          <object class="GtkBox">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="border_width">12</property>
+                            <property name="spacing">10</property>
+                            <child>
+                              <object class="GtkLabel">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="label" translatable="yes">Show _Pointer</property>
+                                <property name="use_underline">True</property>
+                                <property name="mnemonic_widget">pointer</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkSwitch" id="pointer">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="pack_type">end</property>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                          </object>
+                        </child>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkListBoxRow" id="shadowrow">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <child>
+                          <object class="GtkBox">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="border_width">12</property>
+                            <property name="spacing">10</property>
+                            <child>
+                              <object class="GtkLabel">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="label" translatable="yes">Window S_hadow</property>
+                                <property name="use_underline">True</property>
+                                <property name="mnemonic_widget">shadow</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkSwitch" id="shadow">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="active">True</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="pack_type">end</property>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                          </object>
+                        </child>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkListBoxRow" id="delayrow">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <child>
+                          <object class="GtkBox">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="margin_start">6</property>
+                            <property name="margin_end">6</property>
+                            <property name="border_width">9</property>
+                            <property name="spacing">10</property>
+                            <child>
+                              <object class="GtkLabel">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="label" translatable="yes">_Delay in Seconds</property>
+                                <property name="use_underline">True</property>
+                                <property name="mnemonic_widget">delay</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkSpinButton" id="delay">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="text" translatable="yes">0</property>
+                                <property name="input_purpose">number</property>
+                                <property name="adjustment">adjustment1</property>
+                                <property name="climb_rate">1</property>
+                                <property name="snap_to_ticks">True</property>
+                                <property name="numeric">True</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="pack_type">end</property>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                          </object>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+              </object>
+            </child>
+            <child type="label_item">
+              <placeholder/>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">2</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <child type="titlebar">
+      <object class="GtkHeaderBar">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="show_close_button">True</property>
+        <child>
+          <object class="GtkButton" id="capture_button">
+            <property name="label" translatable="yes">_Take Screenshot</property>
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">True</property>
+            <property name="action_name">app.screen-shot</property>
+            <property name="use_underline">True</property>
+            <style>
+              <class name="suggested-action"/>
+            </style>
+          </object>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkMenuButton" id="menu">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">True</property>
+            <child>
+              <object class="GtkImage">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="icon_name">open-menu-symbolic</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="pack_type">end</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </object>
+</interface>
diff --git a/src/selection-symbolic.svg b/src/selection-symbolic.svg
new file mode 100644
index 0000000..3f90112
--- /dev/null
+++ b/src/selection-symbolic.svg
@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg"; width="16" height="16">
+    <g fill="#2e3436">
+        <path d="M1.017 4.995h1v1h-1zM3.017 4.995h1v1h-1zM5.017 4.995h1v1h-1zM7.017 4.995h1v1h-1zM9.017 
4.995h1v1h-1zM11.049 4.995h1v1h-1zM11.049 6.995h1v1h-1zM11.049 8.995h1v1h-1zM11.049 10.995h1v1h-1zM11.049 
12.995h1v1h-1zM9.017 12.995h1v1h-1zM7.017 12.995h1v1h-1zM5.017 12.995h1v1h-1zM3.017 12.995h1v1h-1zM1.017 
12.995h1v1h-1zM1.017 10.995h1v1h-1zM1.017 8.995h1v1h-1zM1.017 6.995h1v1h-1z" style="marker:none"/>
+        <path d="M6.017 1.027a1 1 0 0 0-1 1v1.968h8v8h1a1 1 0 0 0 1-1V2.027a1 1 0 0 0-1-1zm-1 5.968v4a1 1 0 
0 0 1 1h4v-2h-3v-3z" 
style="line-height:normal;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000;text-transform:none;text-orientation:mixed;shape-padding:0;isolation:auto;mix-blend-mode:normal;marker:none"
 color="#000" font-weight="400" font-family="sans-serif" white-space="normal" overflow="visible"/>
+    </g>
+</svg>
diff --git a/src/window-symbolic.svg b/src/window-symbolic.svg
new file mode 100644
index 0000000..329363c
--- /dev/null
+++ b/src/window-symbolic.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg"; width="16" height="16">
+    <path d="M3.012 1.027c-1.215 0-1.994.779-1.995 1.95V14a1 1 0 0 0 1 1h12a1 1 0 0 0 
1-1V2.955c0-1.238-.8-1.928-1.972-1.928zm7.005 1.963h1v1h1v-1h1v1h-1v1h1v1h-1v-1h-1v1h-1v-1h1v-1h-1zm-7 
4.076h10v5.935h-10z" 
style="line-height:normal;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000;text-transform:none;text-orientation:mixed;shape-padding:0;isolation:auto;mix-blend-mode:normal;marker:none"
 color="#000" font-weight="400" font-family="sans-serif" white-space="normal" overflow="visible" 
fill="#2e3436"/>
+</svg>


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