]> Pileus Git - ~andy/gtk/blobdiff - gtk/tests/filechooser.c
filechooserbutton: Duh, remove all the timeouts after tests
[~andy/gtk] / gtk / tests / filechooser.c
index db606d21af879ef85b178ab80f4e01efd5f74d94..2ca7660bb28635e22e00d42e30bae7f21775eba6 100644 (file)
 #include "gtk/gtkfilechooserdefault.h"
 #include "gtk/gtkfilechooserentry.h"
 
+#if 0
+static const char *
+get_action_name (GtkFileChooserAction action)
+{
+  switch (action)
+    {
+    case GTK_FILE_CHOOSER_ACTION_OPEN:          return "OPEN";
+    case GTK_FILE_CHOOSER_ACTION_SAVE:          return "SAVE";
+    case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER: return "SELECT_FOLDER";
+    case GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER: return "CREATE_FOLDER";
+
+    default:
+      g_assert_not_reached ();
+      return NULL;
+    }
+}
+#endif
+
+#ifdef BROKEN_TESTS
 static void
 log_test (gboolean passed, const char *test_name, ...)
 {
@@ -52,8 +71,6 @@ log_test (gboolean passed, const char *test_name, ...)
   g_free (str);
 }
 
-static const char *get_action_name (GtkFileChooserAction action);
-
 typedef void (* SetFilenameFn) (GtkFileChooser *chooser, gpointer data);
 typedef void (* CompareFilenameFn) (GtkFileChooser *chooser, gpointer data);
 
@@ -77,6 +94,7 @@ set_filename_timeout_cb (gpointer data)
 
   return FALSE;
 }
+#endif
 
 
 static guint wait_for_idle_id = 0;
@@ -100,6 +118,7 @@ wait_for_idle (void)
     gtk_main_iteration ();
 }
 
+#ifdef BROKEN_TESTS
 static void
 test_set_filename (GtkFileChooserAction action,
                   gboolean focus_button,
@@ -109,6 +128,7 @@ test_set_filename (GtkFileChooserAction action,
 {
   GtkWidget *chooser;
   struct test_set_filename_closure closure;
+  guint timeout_id;
 
   chooser = gtk_file_chooser_dialog_new ("hello", NULL, action,
                                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
@@ -122,8 +142,9 @@ test_set_filename (GtkFileChooserAction action,
 
   (* set_filename_fn) (GTK_FILE_CHOOSER (chooser), data);
 
-  gdk_threads_add_timeout_full (G_MAXINT, SLEEP_DURATION, set_filename_timeout_cb, &closure, NULL);
+  timeout_id = gdk_threads_add_timeout_full (G_MAXINT, SLEEP_DURATION, set_filename_timeout_cb, &closure, NULL);
   gtk_dialog_run (GTK_DIALOG (chooser));
+  g_source_remove (timeout_id);
 
   (* compare_filename_fn) (GTK_FILE_CHOOSER (chooser), data);
 
@@ -230,6 +251,7 @@ test_black_box_set_current_name (gconstpointer data)
 
   g_free (cwd);
 }
+#endif
 
 /* FIXME: fails in CREATE_FOLDER mode when FOLDER_NAME == "/" */
 
@@ -253,6 +275,7 @@ test_black_box_set_current_name (gconstpointer data)
  * http://bugzilla.gnome.org/show_bug.cgi?id=346058
  */
 
+#ifdef BROKEN_TESTS
 static void
 setup_set_filename_tests (void)
 {
@@ -288,6 +311,7 @@ setup_set_current_name_tests (void)
   for (i = 0; i < G_N_ELEMENTS (tests); i++)
     g_test_add_data_func (tests[i].test_name, &tests[i], test_black_box_set_current_name);
 }
+#endif
 
 typedef struct
 {
@@ -296,9 +320,14 @@ typedef struct
   const char *initial_current_folder;
   const char *initial_filename;
   gboolean open_dialog;
+  enum {
+    BUTTON,
+    DIALOG
+  } what_to_tweak;
   const char *tweak_current_folder;
   const char *tweak_filename;
   gint dialog_response;
+  gboolean unselect_all;
   const char *final_current_folder;
   const char *final_filename;
 } FileChooserButtonTest;
@@ -336,18 +365,6 @@ make_button_test_name (FileChooserButtonTest *t)
 #endif
 }
 
-/* Copied from gtkfilechooserutils.c:_gtk_file_chooser_delegate_get_quark() */
-static GQuark
-delegate_get_quark (void)
-{
-  static GQuark quark = 0;
-
-  if (G_UNLIKELY (quark == 0))
-    quark = g_quark_from_static_string ("gtk-file-chooser-delegate");
-
-  return quark;
-}
-
 static gboolean
 sleep_timeout_cb (gpointer data)
 {
@@ -358,91 +375,527 @@ sleep_timeout_cb (gpointer data)
 static void
 sleep_in_main_loop (void)
 {
-  /* process all pending idles and events */
-  while (g_main_context_pending (NULL))
-    g_main_context_iteration (NULL, FALSE);
-  /* sleeping probably isn't strictly necessary here */
-  gdk_threads_add_timeout_full (G_MAXINT, 250, sleep_timeout_cb, NULL, NULL);
+  guint timeout_id;
+
+  timeout_id = gdk_threads_add_timeout_full (G_MAXINT, 250, sleep_timeout_cb, NULL, NULL);
   gtk_main ();
-  /* process any pending idles or events that arrived during sleep */
-  while (g_main_context_pending (NULL))
-    g_main_context_iteration (NULL, FALSE);
+  g_source_remove (timeout_id);
 }
 
 static void
-test_file_chooser_button (gconstpointer data)
+build_children_list (GtkWidget *widget, gpointer data)
 {
-  const FileChooserButtonTest *setup = data;
+  GList **list;
+
+  list = data;
+  *list = g_list_prepend (*list, widget);
+}
+
+static GtkWidget *
+find_child_widget_with_atk_role (GtkWidget *widget, AtkRole role)
+{
+  AtkObject *accessible;
+  AtkRole a_role;
+
+  accessible = gtk_widget_get_accessible (widget);
+  a_role = atk_object_get_role (accessible);
+
+  if (a_role == role)
+    return widget;
+  else
+    {
+      GtkWidget *found_child;
+
+      found_child = NULL;
+
+      if (GTK_IS_CONTAINER (widget))
+       {
+         GList *children;
+         GList *l;
+
+         children = NULL;
+         gtk_container_forall (GTK_CONTAINER (widget), build_children_list, &children);
+
+         l = children;
+
+         while (l && !found_child)
+           {
+             GtkWidget *child;
+
+             child = GTK_WIDGET (l->data);
+
+             found_child = find_child_widget_with_atk_role (child, role);
+
+             l = l->next;
+           }
+
+         g_list_free (children);
+       }
+
+      return found_child;
+    }
+}
+
+static const char *
+get_atk_name_for_filechooser_button (GtkFileChooserButton *button)
+{
+  GtkFileChooserAction action;
+  GtkWidget *widget;
+  AtkObject *accessible;
+
+  action = gtk_file_chooser_get_action (GTK_FILE_CHOOSER (button));
+  g_assert (action == GTK_FILE_CHOOSER_ACTION_OPEN || action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
+
+  if (action == GTK_FILE_CHOOSER_ACTION_OPEN)
+    widget = find_child_widget_with_atk_role (GTK_WIDGET (button), ATK_ROLE_PUSH_BUTTON);
+  else
+    widget = find_child_widget_with_atk_role (GTK_WIDGET (button), ATK_ROLE_COMBO_BOX);
+
+  accessible = gtk_widget_get_accessible (widget);
+  return atk_object_get_name (accessible);
+}
+
+static void
+check_that_basename_is_shown (GtkFileChooserButton *button, const char *expected_filename)
+{
+  GtkFileChooserAction action;
+  const char *name_on_button;
+  char *expected_basename;
+
+  name_on_button = get_atk_name_for_filechooser_button (button);
+
+  action = gtk_file_chooser_get_action (GTK_FILE_CHOOSER (button));
+  g_assert (action == GTK_FILE_CHOOSER_ACTION_OPEN || action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
+
+  if (expected_filename)
+    expected_basename = g_path_get_basename (expected_filename);
+  else
+    expected_basename = NULL;
+
+  if (expected_basename)
+    g_assert_cmpstr (expected_basename, ==, name_on_button);
+  else
+    g_assert_cmpstr (name_on_button, ==, "(None)"); /* see gtkfilechooserbutton.c:FALLBACK_DISPLAY_NAME */ /* FIXME: how do we translate this? */
+
+  g_free (expected_basename);
+}
+
+static const char *
+get_expected_shown_filename (GtkFileChooserAction action, const char *folder_name, const char *filename)
+{
+  if (action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
+    {
+      if (filename)
+       return filename;
+      else
+       return folder_name;
+    }
+  else
+    return filename;
+}
+
+static GtkWidget *
+get_file_chooser_dialog_from_button (GtkFileChooserButton *button)
+{
+  GtkWidget *fc_dialog;
+
+  /* Give me the internal dialog, damnit */
+  fc_dialog = g_object_get_qdata (G_OBJECT (button), g_quark_from_static_string ("gtk-file-chooser-delegate"));
+  g_assert (GTK_IS_FILE_CHOOSER (fc_dialog));
+  g_assert (GTK_IS_DIALOG (fc_dialog));
+
+  return fc_dialog;
+}
+
+typedef struct {
   GtkWidget *window;
   GtkWidget *fc_button;
+} WindowAndButton;
+
+static WindowAndButton
+create_window_and_file_chooser_button (GtkFileChooserAction action)
+{
+  WindowAndButton w;
+
+  w.window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+  w.fc_button = gtk_file_chooser_button_new (action == GTK_FILE_CHOOSER_ACTION_OPEN ? "Select a file" : "Select a folder",
+                                            action);
+  gtk_container_add (GTK_CONTAINER (w.window), w.fc_button);
+
+  return w;
+}
+
+typedef struct
+{
+  GObject *object;
+  GHashTable *signals;
+  gboolean in_main_loop;
+} SignalWatcher;
+
+typedef struct
+{
+  SignalWatcher *watcher;
+  char *signal_name;
+  gulong id;
+  gboolean emitted;
+} SignalConnection;
+
+static SignalWatcher *
+signal_watcher_new (GObject *object)
+{
+  SignalWatcher *watcher = g_new0 (SignalWatcher, 1);
+
+  watcher->object = g_object_ref (object);
+  watcher->signals = g_hash_table_new (g_str_hash, g_str_equal);
+
+  return watcher;
+}
+
+static void
+dummy_callback (GObject *object)
+{
+  /* nothing */
+}
+
+static void
+marshal_notify_cb (gpointer data, GClosure *closure)
+{
+  if (data)
+    {
+      SignalConnection *conn;
+
+      conn = data;
+      conn->emitted = TRUE;
+
+      if (conn->watcher->in_main_loop)
+       {
+         gtk_main_quit ();
+         conn->watcher->in_main_loop = FALSE;
+       }
+    }
+}
+
+static void
+signal_watcher_watch_signal (SignalWatcher *watcher, const char *signal_name)
+{
+  SignalConnection *conn;
+
+  conn = g_hash_table_lookup (watcher->signals, signal_name);
+  if (!conn)
+    {
+      GClosure *closure;
+
+      conn = g_new0 (SignalConnection, 1);
+      conn->watcher = watcher;
+      conn->signal_name = g_strdup (signal_name);
+
+      closure = g_cclosure_new (G_CALLBACK (dummy_callback), NULL, NULL);
+      g_closure_add_marshal_guards (closure, conn, marshal_notify_cb, NULL, marshal_notify_cb);
+      conn->id = g_signal_connect_closure (watcher->object, signal_name, closure, FALSE);
+      conn->emitted = FALSE;
+
+      g_hash_table_insert (watcher->signals, conn->signal_name, conn);
+    }
+  else
+    conn->emitted = FALSE;
+}
+
+static gboolean
+signal_watcher_expect (SignalWatcher *watcher, const char *signal_name, char *unused_description)
+{
+  SignalConnection *conn;
+  gboolean emitted;
+
+  conn = g_hash_table_lookup (watcher->signals, signal_name);
+  g_assert (conn != NULL);
+
+  if (!conn->emitted)
+    {
+      guint timeout_id;
+      
+      timeout_id = gdk_threads_add_timeout_full (G_MAXINT, 1000, sleep_timeout_cb, NULL, NULL);
+
+      watcher->in_main_loop = TRUE;
+      gtk_main ();
+      watcher->in_main_loop = FALSE;
+
+      g_source_remove (timeout_id);
+    }
+
+  emitted = conn->emitted;
+  conn->emitted = FALSE;
+
+  return emitted;
+}
+
+static void
+destroy_connection (gpointer key, gpointer value, gpointer user_data)
+{
+  SignalConnection *conn;
+
+  conn = value;
+  g_signal_handler_disconnect (conn->watcher->object, conn->id);
+  g_free (conn->signal_name);
+  g_free (conn);
+}
+
+static void
+signal_watcher_destroy (SignalWatcher *watcher)
+{
+  g_hash_table_foreach (watcher->signals, destroy_connection, NULL);
+  g_hash_table_destroy (watcher->signals);
+  g_object_unref (watcher->object);
+  g_free (watcher);
+}
+
+static void
+test_file_chooser_button_with_response (const FileChooserButtonTest *setup, gint dialog_response)
+{
+  WindowAndButton w;
+  SignalWatcher *watcher;
   GtkWidget *fc_dialog;
+  int iterations;
+  int i;
 
-  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  w = create_window_and_file_chooser_button (setup->action);
 
-  fc_button = gtk_file_chooser_button_new (setup->action == GTK_FILE_CHOOSER_ACTION_OPEN ? "Select a file" : "Select a folder",
-                                          setup->action);
-  gtk_container_add (GTK_CONTAINER (window), fc_button);
+  watcher = signal_watcher_new (G_OBJECT (w.fc_button));
+  signal_watcher_watch_signal (watcher, "current-folder-changed");
+  signal_watcher_watch_signal (watcher, "selection-changed");
 
   if (setup->initial_current_folder)
-    gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (fc_button), setup->initial_current_folder);
+    gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (w.fc_button), setup->initial_current_folder);
 
   if (setup->initial_filename)
-    gtk_file_chooser_select_filename (GTK_FILE_CHOOSER (fc_button), setup->initial_filename);
+    gtk_file_chooser_select_filename (GTK_FILE_CHOOSER (w.fc_button), setup->initial_filename);
 
-  gtk_widget_show_all (window);
+  gtk_widget_show_all (w.window);
   wait_for_idle ();
 
+  if (setup->initial_current_folder)
+    g_assert (signal_watcher_expect (watcher, "current-folder-changed", "initial current folder"));
+
+  if (setup->initial_filename)
+    g_assert (signal_watcher_expect (watcher, "selection-changed", "initial filename"));
+
+  check_that_basename_is_shown (GTK_FILE_CHOOSER_BUTTON (w.fc_button),
+                               get_expected_shown_filename (setup->action, setup->initial_current_folder, setup->initial_filename));
+
+  /* If there is a dialog to be opened, we actually test going through it a
+   * couple of times.  This ensures that any state that the button frobs for
+   * each appearance of the dialog will make sense.
+   */
   if (setup->open_dialog)
+    iterations = 2;
+  else
+    iterations = 1;
+
+  for (i = 0; i < iterations; i++)
     {
-      GList *children;
+      GtkFileChooser *chooser_to_tweak;
 
-      /* Hack our way into the file chooser button; get its GtkButton child and click it */
-      children = gtk_container_get_children (GTK_CONTAINER (fc_button));
-      g_assert (children && GTK_IS_BUTTON (children->data));
-      gtk_button_clicked (GTK_BUTTON (children->data));
-      g_list_free (children);
+      if (setup->open_dialog)
+       {
+         GList *children;
 
-      wait_for_idle ();
+         /* Hack our way into the file chooser button; get its GtkButton child and click it */
+         children = gtk_container_get_children (GTK_CONTAINER (w.fc_button));
+         g_assert (children && GTK_IS_BUTTON (children->data));
+         gtk_button_clicked (GTK_BUTTON (children->data));
+         g_list_free (children);
 
-      /* Give me the internal dialog, damnit */
-      fc_dialog = g_object_get_qdata (G_OBJECT (fc_button), delegate_get_quark ());
-      g_assert (GTK_IS_FILE_CHOOSER (fc_dialog));
-      g_assert (GTK_IS_DIALOG (fc_dialog));
-    }
+         wait_for_idle ();
 
-  /* Okay, now frob the button and its optional dialog */
+         fc_dialog = get_file_chooser_dialog_from_button (GTK_FILE_CHOOSER_BUTTON (w.fc_button));
+       }
 
-  if (setup->tweak_current_folder)
-    gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (fc_button), setup->tweak_current_folder);
+      if (setup->what_to_tweak == BUTTON)
+       chooser_to_tweak = GTK_FILE_CHOOSER (w.fc_button);
+      else if (setup->what_to_tweak == DIALOG)
+       chooser_to_tweak = GTK_FILE_CHOOSER (fc_dialog);
+      else
+       g_assert_not_reached ();
 
-  if (setup->tweak_filename)
-    gtk_file_chooser_select_filename (GTK_FILE_CHOOSER (fc_button), setup->tweak_filename);
+      /* Okay, now frob the button or its optional dialog */
 
-  sleep_in_main_loop ();
+      if (setup->tweak_current_folder)
+       {
+         if (setup->what_to_tweak == BUTTON)
+           signal_watcher_watch_signal (watcher, "current-folder-changed");
+
+         gtk_file_chooser_set_current_folder (chooser_to_tweak, setup->tweak_current_folder);
+
+         if (setup->what_to_tweak == BUTTON)
+           g_assert (signal_watcher_expect (watcher, "current-folder-changed", "tweak current folder in button"));
+       }
+
+      if (setup->tweak_filename)
+       {
+         if (setup->what_to_tweak == BUTTON)
+           signal_watcher_watch_signal (watcher, "selection-changed");
+
+         gtk_file_chooser_select_filename (chooser_to_tweak, setup->tweak_filename);
+
+         if (setup->what_to_tweak == BUTTON)
+           g_assert (signal_watcher_expect (watcher, "selection-changed", "tweak filename in button"));
+       }
+
+      if (setup->unselect_all)
+       {
+         if (setup->what_to_tweak == BUTTON)
+           signal_watcher_watch_signal (watcher, "selection-changed");
+
+         gtk_file_chooser_unselect_all (chooser_to_tweak);
+
+         if (setup->what_to_tweak == BUTTON)
+           g_assert (signal_watcher_expect (watcher, "selection-changed", "tweak unselect_all in button"));
+       }
 
-  if (setup->open_dialog)
-    {
-      gtk_dialog_response (GTK_DIALOG (fc_dialog), setup->dialog_response);
       wait_for_idle ();
-    }
 
-  if (setup->final_current_folder)
-    {
-      char *folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (fc_button));
+      if (setup->open_dialog)
+       {
+         gtk_dialog_response (GTK_DIALOG (fc_dialog), dialog_response);
+         wait_for_idle ();
 
-      g_assert_cmpstr (folder, ==, setup->final_current_folder);
-      g_free (folder);
+         gtk_window_resize (GTK_WINDOW (fc_dialog), 500, 500);
+       }
+
+      if (setup->final_current_folder)
+       {
+         char *folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (w.fc_button));
+
+         g_assert_cmpstr (folder, ==, setup->final_current_folder);
+         g_free (folder);
+       }
+
+      if (setup->final_filename)
+       {
+         char *filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (w.fc_button));
+
+         g_assert_cmpstr (filename, ==, setup->final_filename);
+         g_free (filename);
+       }
+
+      check_that_basename_is_shown (GTK_FILE_CHOOSER_BUTTON (w.fc_button),
+                                   get_expected_shown_filename (setup->action, setup->final_current_folder, setup->final_filename));
     }
 
-  if (setup->final_filename)
-    {
-      char *filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (fc_button));
+  signal_watcher_destroy (watcher);
+  gtk_widget_destroy (w.window);
+}
 
-      g_assert_cmpstr (filename, ==, setup->final_filename);
-      g_free (filename);
+static void
+test_file_chooser_button (gconstpointer data)
+{
+  const FileChooserButtonTest *setup = data;
+
+  test_file_chooser_button_with_response (setup, setup->dialog_response);
+
+  if (setup->open_dialog && setup->dialog_response == GTK_RESPONSE_CANCEL)
+    {
+      /* Runs the test again, with DELETE_EVENT (as if the user closed the
+       * dialog instead of using the Cancel button), since the button misbehaved
+       * in that case sometimes.
+       */
+      test_file_chooser_button_with_response (setup, GTK_RESPONSE_DELETE_EVENT);
     }
+}
 
-  gtk_widget_destroy (window);
+static int
+find_accessible_action_num (AtkObject *object, const char *action_name)
+{
+  AtkAction *action_a;
+  int num_actions;
+  int i;
+
+  action_a = ATK_ACTION (object);
+
+  num_actions = atk_action_get_n_actions (action_a);
+
+  for (i = 0; i < num_actions; i++)
+    if (strcmp (atk_action_get_name (action_a, i), action_name) == 0)
+      return i;
+
+  return -1;
+}
+
+static void
+do_accessible_action (AtkObject *object, const char *action_name)
+{
+  int action_num;
+
+  action_num = find_accessible_action_num (object, action_name);
+  g_assert (action_num != -1);
+
+  atk_action_do_action (ATK_ACTION (object), action_num);
+}
+
+static void
+test_file_chooser_button_combo_box_1 (void)
+{
+  WindowAndButton w;
+  GtkWidget *combo_box;
+  AtkObject *combo_box_a;
+  AtkObject *menu_a;
+  int num_items;
+  int other_index;
+  AtkObject *item_a;
+  GtkWidget *fc_dialog;
+
+  w = create_window_and_file_chooser_button (GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
+
+  gtk_file_chooser_select_filename (GTK_FILE_CHOOSER (w.fc_button), FOLDER_NAME);
+
+  gtk_widget_show_all (w.window);
+
+  /* Get the accessible for the combo box */
+
+  combo_box = find_child_widget_with_atk_role (GTK_WIDGET (w.fc_button), ATK_ROLE_COMBO_BOX);
+  combo_box_a = gtk_widget_get_accessible (combo_box);
+
+  /* Press the combo box to bring up the menu */
+
+  do_accessible_action (combo_box_a, "press");
+  sleep_in_main_loop (); /* have to wait because bringing up the menu is asynchronous... */
+
+  /* Get the menu from the combo box; it's the first child */
+
+  menu_a = atk_object_ref_accessible_child (combo_box_a, 0);
+  g_assert (atk_object_get_role (menu_a) == ATK_ROLE_MENU);
+
+  /* Check that the last item in the menu is the "Other…" one */
+
+  num_items = atk_object_get_n_accessible_children (menu_a);
+  g_assert (num_items > 0);
+
+  other_index = num_items - 1;
+
+  item_a = atk_object_ref_accessible_child (menu_a, other_index);
+  g_assert_cmpstr (atk_object_get_name (item_a), ==, "Other…");  /* FIXME: how do we translate this? */
+
+  /* Activate the item */
+
+  do_accessible_action (item_a, "click");
+
+  /* Cancel the dialog */
+
+  sleep_in_main_loop ();
+  fc_dialog = get_file_chooser_dialog_from_button (GTK_FILE_CHOOSER_BUTTON (w.fc_button));
+
+  gtk_dialog_response (GTK_DIALOG (fc_dialog), GTK_RESPONSE_CANCEL);
+
+  /* Now check the selection in the combo box */
+  check_that_basename_is_shown (GTK_FILE_CHOOSER_BUTTON (w.fc_button), FOLDER_NAME);
+
+  gtk_widget_destroy (w.window);
+}
+
+static void
+setup_file_chooser_button_combo_box_tests (void)
+{
+  g_test_add_func ("/GtkFileChooserButton/combo_box-1", test_file_chooser_button_combo_box_1);
 }
 
 static FileChooserButtonTest button_tests[] =
@@ -455,9 +908,11 @@ static FileChooserButtonTest button_tests[] =
       NULL,                    /* initial_current_folder */
       NULL,                    /* initial_filename */
       FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
       NULL,                    /* tweak_current_folder */
       NULL,                    /* tweak_filename */
       0,                       /* dialog_response */
+      FALSE,                   /* unselect_all */
       NULL,                    /* final_current_folder */
       NULL                     /* final_filename */
     },
@@ -467,9 +922,11 @@ static FileChooserButtonTest button_tests[] =
       NULL,                    /* initial_current_folder */
       FILE_NAME,               /* initial_filename */
       FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
       NULL,                    /* tweak_current_folder */
       NULL,                    /* tweak_filename */
       0,                       /* dialog_response */
+      FALSE,                   /* unselect_all */
       NULL,                    /* final_current_folder */
       FILE_NAME                        /* final_filename */
     },
@@ -479,9 +936,11 @@ static FileChooserButtonTest button_tests[] =
       NULL,                    /* initial_current_folder */
       NULL,                    /* initial_filename */
       FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
       NULL,                    /* tweak_current_folder */
       FILE_NAME,               /* tweak_filename */
       0,                       /* dialog_response */
+      FALSE,                   /* unselect_all */
       NULL,                    /* final_current_folder */
       FILE_NAME                        /* final_filename */
     },
@@ -491,9 +950,11 @@ static FileChooserButtonTest button_tests[] =
       NULL,                    /* initial_current_folder */
       FILE_NAME,               /* initial_filename */
       FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
       NULL,                    /* tweak_current_folder */
       FILE_NAME_2,             /* tweak_filename */
       0,                       /* dialog_response */
+      FALSE,                   /* unselect_all */
       NULL,                    /* final_current_folder */
       FILE_NAME_2              /* final_filename */
     },
@@ -503,9 +964,11 @@ static FileChooserButtonTest button_tests[] =
       FOLDER_NAME,             /* initial_current_folder */
       NULL,                    /* initial_filename */
       FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
       NULL,                    /* tweak_current_folder */
       NULL,                    /* tweak_filename */
       0,                       /* dialog_response */
+      FALSE,                   /* unselect_all */
       FOLDER_NAME,             /* final_current_folder */
       NULL                     /* final_filename */
     },
@@ -515,9 +978,11 @@ static FileChooserButtonTest button_tests[] =
       FOLDER_NAME,             /* initial_current_folder */
       NULL,                    /* initial_filename */
       FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
       FOLDER_NAME_2,           /* tweak_current_folder */
       NULL,                    /* tweak_filename */
       0,                       /* dialog_response */
+      FALSE,                   /* unselect_all */
       FOLDER_NAME_2,           /* final_current_folder */
       NULL                     /* final_filename */
     },
@@ -530,9 +995,11 @@ static FileChooserButtonTest button_tests[] =
       NULL,                    /* initial_current_folder */
       NULL,                    /* initial_filename */
       FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
       NULL,                    /* tweak_current_folder */
       NULL,                    /* tweak_filename */
       0,                       /* dialog_response */
+      FALSE,                   /* unselect_all */
       NULL,                    /* final_current_folder */
       NULL                     /* final_filename */
     },
@@ -542,9 +1009,11 @@ static FileChooserButtonTest button_tests[] =
       NULL,                    /* initial_current_folder */
       FOLDER_NAME,             /* initial_filename */
       FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
       NULL,                    /* tweak_current_folder */
       NULL,                    /* tweak_filename */
       0,                       /* dialog_response */
+      FALSE,                   /* unselect_all */
       NULL,                    /* final_current_folder */
       FOLDER_NAME              /* final_filename */
     },
@@ -554,9 +1023,11 @@ static FileChooserButtonTest button_tests[] =
       NULL,                    /* initial_current_folder */
       FOLDER_NAME,             /* initial_filename */
       FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
       NULL,                    /* tweak_current_folder */
       FOLDER_NAME_2,           /* tweak_filename */
       0,                       /* dialog_response */
+      FALSE,                   /* unselect_all */
       NULL,                    /* final_current_folder */
       FOLDER_NAME_2            /* final_filename */
     },
@@ -566,9 +1037,11 @@ static FileChooserButtonTest button_tests[] =
       FOLDER_NAME,             /* initial_current_folder */
       NULL,                    /* initial_filename */
       FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
       NULL,                    /* tweak_current_folder */
       NULL,                    /* tweak_filename */
       0,                       /* dialog_response */
+      FALSE,                   /* unselect_all */
       NULL,                    /* final_current_folder */
       FOLDER_NAME              /* final_filename */
     },
@@ -578,9 +1051,11 @@ static FileChooserButtonTest button_tests[] =
       FOLDER_NAME,             /* initial_current_folder */
       NULL,                    /* initial_filename */
       FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
       NULL,                    /* tweak_current_folder */
       NULL,                    /* tweak_filename */
       0,                       /* dialog_response */
+      FALSE,                   /* unselect_all */
       FOLDER_NAME,             /* final_current_folder */
       NULL                     /* final_filename */
     },
@@ -590,209 +1065,439 @@ static FileChooserButtonTest button_tests[] =
       FOLDER_NAME,             /* initial_current_folder */
       NULL,                    /* initial_filename */
       FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
       FOLDER_NAME_2,           /* tweak_current_folder */
       NULL,                    /* tweak_filename */
       0,                       /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FOLDER_NAME_2            /* final_filename */
+    },
+    {
+      "select-folder-7",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      FOLDER_NAME,             /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      FOLDER_NAME_2,           /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      0,                       /* dialog_response */
+      FALSE,                   /* unselect_all */
+      FOLDER_NAME_2,           /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "select-folder-8",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      FOLDER_NAME,             /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      FOLDER_NAME_2,           /* tweak_filename */
+      0,                       /* dialog_response */
+      FALSE,                   /* unselect_all */
       NULL,                    /* final_current_folder */
       FOLDER_NAME_2            /* final_filename */
     },
+
+    /* OPEN tests with dialog, cancelled
+     *
+     * Test names are "open-dialog-cancel-A-B", where A and B can be:
+     *
+     *   A:
+     *      ni - no initial filename
+     *       i - initial filename
+     *      nf - no initial folder
+     *       f - initial folder
+     *
+     *   B:
+     *      nt - no tweaks
+     *       b - tweak button
+     *       d - tweak dialog
+     */
+
+    {
+      "open-dialog-cancel-ni-nt",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      NULL,                    /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "open-dialog-cancel-ni-b",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      NULL,                    /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      FILE_NAME,               /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FILE_NAME                        /* final_filename */
+    },
+    {
+      "open-dialog-cancel-ni-d",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      NULL,                    /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      DIALOG,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      FILE_NAME,               /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "open-dialog-cancel-i-nt",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      NULL,                    /* initial_current_folder */
+      FILE_NAME,               /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FILE_NAME                        /* final_filename */
+    },
+    {
+      "open-dialog-cancel-i-b",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      NULL,                    /* initial_current_folder */
+      FILE_NAME,               /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      FILE_NAME_2,             /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FILE_NAME_2              /* final_filename */
+    },
+    {
+      "open-dialog-cancel-i-d",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      NULL,                    /* initial_current_folder */
+      FILE_NAME,               /* initial_filename */
+      TRUE,                    /* open_dialog */
+      DIALOG,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      FILE_NAME_2,             /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FILE_NAME                        /* final_filename */
+    },
+    {
+      "open-dialog-cancel-nf-nt",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      NULL,                    /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "open-dialog-cancel-nf-b",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      NULL,                    /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      FOLDER_NAME,             /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      FOLDER_NAME,             /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "open-dialog-cancel-nf-d",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      NULL,                    /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      DIALOG,                  /* what_to_tweak */
+      FOLDER_NAME,             /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "open-dialog-cancel-f-nt",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      FOLDER_NAME,             /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      FOLDER_NAME,             /* final_current_folder */
+      NULL                     /* final_filename */
+    },
     {
-      "select-folder-7",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      "open-dialog-cancel-f-b",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
       FOLDER_NAME,             /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      FALSE,                   /* open_dialog */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
       FOLDER_NAME_2,           /* tweak_current_folder */
       NULL,                    /* tweak_filename */
-      0,                       /* dialog_response */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
       FOLDER_NAME_2,           /* final_current_folder */
       NULL                     /* final_filename */
     },
     {
-      "select-folder-8",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      "open-dialog-cancel-f-d",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
       FOLDER_NAME,             /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      FALSE,                   /* open_dialog */
-      NULL,                    /* tweak_current_folder */
-      FOLDER_NAME_2,           /* tweak_filename */
-      0,                       /* dialog_response */
-      NULL,                    /* final_current_folder */
-      FOLDER_NAME_2            /* final_filename */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      DIALOG,                  /* what_to_tweak */
+      FOLDER_NAME_2,           /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      FOLDER_NAME,             /* final_current_folder */
+      NULL                     /* final_filename */
     },
 
-    /* OPEN tests with dialog, cancelled */
+    /* SELECT_FOLDER tests with dialog, cancelled */
 
     {
-      "open-dialog-cancel-1",
-      GTK_FILE_CHOOSER_ACTION_OPEN,
+      "select-folder-dialog-cancel-ni-nt",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
       NULL,                    /* initial_current_folder */
       NULL,                    /* initial_filename */
       TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
       NULL,                    /* tweak_current_folder */
       NULL,                    /* tweak_filename */
       GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
       NULL,                    /* final_current_folder */
       NULL                     /* final_filename */
     },
     {
-      "open-dialog-cancel-2",
-      GTK_FILE_CHOOSER_ACTION_OPEN,
+      "select-folder-dialog-cancel-ni-b",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
       NULL,                    /* initial_current_folder */
-      FILE_NAME,               /* initial_filename */
+      NULL,                    /* initial_filename */
       TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
       NULL,                    /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
+      FOLDER_NAME,             /* tweak_filename */
       GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
       NULL,                    /* final_current_folder */
-      FILE_NAME                        /* final_filename */
+      FOLDER_NAME              /* final_filename */
     },
     {
-      "open-dialog-cancel-3",
-      GTK_FILE_CHOOSER_ACTION_OPEN,
-      FOLDER_NAME,             /* initial_current_folder */
-      NULL,                    /* initial_filename */
+      "select-folder-dialog-cancel-ni-d",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      NULL,                    /* initial_current_folder */
+      NULL,                    /* initial_filename */
       TRUE,                    /* open_dialog */
+      DIALOG,                  /* what_to_tweak */
       NULL,                    /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
+      FOLDER_NAME,             /* tweak_filename */
       GTK_RESPONSE_CANCEL,     /* dialog_response */
-      FOLDER_NAME,             /* final_current_folder */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
       NULL                     /* final_filename */
     },
     {
-      "open-dialog-cancel-4",
-      GTK_FILE_CHOOSER_ACTION_OPEN,
+      "select-folder-dialog-cancel-i-nt",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
       NULL,                    /* initial_current_folder */
-      NULL,                    /* initial_filename */
+      FOLDER_NAME,             /* initial_filename */
       TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
       NULL,                    /* tweak_current_folder */
-      FILE_NAME,               /* tweak_filename */
+      NULL,                    /* tweak_filename */
       GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
       NULL,                    /* final_current_folder */
-      NULL                     /* final_filename */
+      FOLDER_NAME              /* final_filename */
     },
     {
-      "open-dialog-cancel-5",
-      GTK_FILE_CHOOSER_ACTION_OPEN,
+      "select-folder-dialog-cancel-i-b",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
       NULL,                    /* initial_current_folder */
-      FILE_NAME,               /* initial_filename */
+      FOLDER_NAME,             /* initial_filename */
       TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
       NULL,                    /* tweak_current_folder */
-      FILE_NAME_2,             /* tweak_filename */
+      FOLDER_NAME_2,           /* tweak_filename */
       GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
       NULL,                    /* final_current_folder */
-      FILE_NAME                        /* final_filename */
+      FOLDER_NAME_2            /* final_filename */
     },
     {
-      "open-dialog-cancel-6",
-      GTK_FILE_CHOOSER_ACTION_OPEN,
-      FOLDER_NAME,             /* initial_current_folder */
-      NULL,                    /* initial_filename */
+      "select-folder-dialog-cancel-i-d",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      NULL,                    /* initial_current_folder */
+      FOLDER_NAME,             /* initial_filename */
       TRUE,                    /* open_dialog */
+      DIALOG,                  /* what_to_tweak */
       NULL,                    /* tweak_current_folder */
-      FILE_NAME_2,             /* tweak_filename */
+      FOLDER_NAME_2,           /* tweak_filename */
       GTK_RESPONSE_CANCEL,     /* dialog_response */
-      FOLDER_NAME,             /* final_current_folder */
-      NULL                     /* final_filename */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FOLDER_NAME              /* final_filename */
     },
-
-    /* SELECT_FOLDER tests with dialog, cancelled */
-
     {
-      "select-folder-dialog-cancel-1",
+      "select-folder-dialog-cancel-nf-nt",
       GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
       NULL,                    /* initial_current_folder */
       NULL,                    /* initial_filename */
       TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
       NULL,                    /* tweak_current_folder */
       NULL,                    /* tweak_filename */
       GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
       NULL,                    /* final_current_folder */
       NULL                     /* final_filename */
     },
     {
-      "select-folder-dialog-cancel-2",
+      "select-folder-dialog-cancel-nf-b",
       GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
       NULL,                    /* initial_current_folder */
-      FOLDER_NAME,             /* initial_filename */
+      NULL,                    /* initial_filename */
       TRUE,                    /* open_dialog */
-      NULL,                    /* tweak_current_folder */
+      BUTTON,                  /* what_to_tweak */
+      FOLDER_NAME,             /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      FOLDER_NAME,             /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "select-folder-dialog-cancel-nf-d",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      NULL,                    /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      DIALOG,                  /* what_to_tweak */
+      FOLDER_NAME,             /* tweak_current_folder */
       NULL,                    /* tweak_filename */
       GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
       NULL,                    /* final_current_folder */
-      FOLDER_NAME              /* final_filename */
+      NULL                     /* final_filename */
     },
     {
-      "select-folder-dialog-cancel-3",
+      "select-folder-dialog-cancel-f-nt",
       GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
       FOLDER_NAME,             /* initial_current_folder */
       NULL,                    /* initial_filename */
       TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
       NULL,                    /* tweak_current_folder */
       NULL,                    /* tweak_filename */
       GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
       FOLDER_NAME,             /* final_current_folder */
       NULL                     /* final_filename */
     },
     {
-      "select-folder-dialog-cancel-4",
+      "select-folder-dialog-cancel-f-nt-2",
       GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
       FOLDER_NAME,             /* initial_current_folder */
       NULL,                    /* initial_filename */
       TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
       NULL,                    /* tweak_current_folder */
       NULL,                    /* tweak_filename */
       GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
       NULL,                    /* final_current_folder */
       FOLDER_NAME              /* final_filename */
     },
     {
-      "select-folder-dialog-cancel-5",
+      "select-folder-dialog-cancel-f-b",
       GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      NULL,                    /* initial_current_folder */
+      FOLDER_NAME,             /* initial_current_folder */
       NULL,                    /* initial_filename */
       TRUE,                    /* open_dialog */
-      NULL,                    /* tweak_current_folder */
-      FOLDER_NAME,             /* tweak_filename */
+      BUTTON,                  /* what_to_tweak */
+      FOLDER_NAME_2,           /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
       GTK_RESPONSE_CANCEL,     /* dialog_response */
-      NULL,                    /* final_current_folder */
+      FALSE,                   /* unselect_all */
+      FOLDER_NAME_2,           /* final_current_folder */
       NULL                     /* final_filename */
     },
     {
-      "select-folder-dialog-cancel-6",
+      "select-folder-dialog-cancel-f-b-2",
       GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      NULL,                    /* initial_current_folder */
-      FOLDER_NAME,             /* initial_filename */
+      FOLDER_NAME,             /* initial_current_folder */
+      NULL,                    /* initial_filename */
       TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
       NULL,                    /* tweak_current_folder */
       FOLDER_NAME_2,           /* tweak_filename */
       GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
       NULL,                    /* final_current_folder */
-      FOLDER_NAME                      /* final_filename */
+      FOLDER_NAME_2            /* final_filename */
     },
     {
-      "select-folder-dialog-cancel-7",
+      "select-folder-dialog-cancel-f-d",
       GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
       FOLDER_NAME,             /* initial_current_folder */
       NULL,                    /* initial_filename */
       TRUE,                    /* open_dialog */
-      NULL,                    /* tweak_current_folder */
-      FOLDER_NAME_2,           /* tweak_filename */
+      DIALOG,                  /* what_to_tweak */
+      FOLDER_NAME_2,           /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
       GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
       FOLDER_NAME,             /* final_current_folder */
       NULL                     /* final_filename */
     },
     {
-      "select-folder-dialog-cancel-8",
+      "select-folder-dialog-cancel-f-d-2",
       GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
       FOLDER_NAME,             /* initial_current_folder */
       NULL,                    /* initial_filename */
       TRUE,                    /* open_dialog */
+      DIALOG,                  /* what_to_tweak */
       NULL,                    /* tweak_current_folder */
       FOLDER_NAME_2,           /* tweak_filename */
       GTK_RESPONSE_CANCEL,     /* dialog_response */
-      NULL,                    /* final_current_folder */
-      FOLDER_NAME              /* final_filename */
+      FALSE,                   /* unselect_all */
+      FOLDER_NAME,             /* final_current_folder */
+      NULL                     /* final_filename */
     },
 
     /* OPEN tests with dialog */
@@ -803,9 +1508,11 @@ static FileChooserButtonTest button_tests[] =
       NULL,                    /* initial_current_folder */
       NULL,                    /* initial_filename */
       TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
       NULL,                    /* tweak_current_folder */
       FILE_NAME,               /* tweak_filename */
       GTK_RESPONSE_ACCEPT,     /* dialog_response */
+      FALSE,                   /* unselect_all */
       NULL,                    /* final_current_folder */
       FILE_NAME                        /* final_filename */
     },
@@ -815,9 +1522,11 @@ static FileChooserButtonTest button_tests[] =
       NULL,                    /* initial_current_folder */
       FILE_NAME,               /* initial_filename */
       TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
       NULL,                    /* tweak_current_folder */
       NULL,                    /* tweak_filename */
       GTK_RESPONSE_ACCEPT,     /* dialog_response */
+      FALSE,                   /* unselect_all */
       NULL,                    /* final_current_folder */
       FILE_NAME                        /* final_filename */
     },
@@ -827,9 +1536,11 @@ static FileChooserButtonTest button_tests[] =
       NULL,                    /* initial_current_folder */
       FILE_NAME,               /* initial_filename */
       TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
       NULL,                    /* tweak_current_folder */
       FILE_NAME_2,             /* tweak_filename */
       GTK_RESPONSE_ACCEPT,     /* dialog_response */
+      FALSE,                   /* unselect_all */
       NULL,                    /* final_current_folder */
       FILE_NAME_2              /* final_filename */
     },
@@ -839,13 +1550,160 @@ static FileChooserButtonTest button_tests[] =
       FOLDER_NAME,             /* initial_current_folder */
       NULL,                    /* initial_filename */
       TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
       NULL,                    /* tweak_current_folder */
       FILE_NAME,               /* tweak_filename */
       GTK_RESPONSE_ACCEPT,     /* dialog_response */
+      FALSE,                   /* unselect_all */
       NULL,                    /* final_current_folder */
       FILE_NAME                        /* final_filename */
     },
 
+    /* SELECT_FOLDER tests with dialog */
+
+    {
+      "select-folder-dialog-1",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      NULL,                    /* initial_current_folder */
+      FOLDER_NAME,             /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      GTK_RESPONSE_ACCEPT,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FOLDER_NAME              /* final_filename */
+    },
+    {
+      "select-folder-dialog-2",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      FOLDER_NAME,             /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      GTK_RESPONSE_ACCEPT,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FOLDER_NAME              /* final_filename */
+    },
+    {
+      "select-folder-dialog-3",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      NULL,                    /* initial_current_folder */
+      FOLDER_NAME,             /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      FOLDER_NAME_2,           /* tweak_filename */
+      GTK_RESPONSE_ACCEPT,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FOLDER_NAME_2            /* final_filename */
+    },
+    {
+      "select-folder-dialog-4",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      FOLDER_NAME,             /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      FOLDER_NAME_2,           /* tweak_filename */
+      GTK_RESPONSE_ACCEPT,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FOLDER_NAME_2            /* final_filename */
+    },
+
+    /* Unselection tests */
+    {
+      "unselect-all-1",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      NULL,                    /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      0,                       /* dialog_response */
+      TRUE,                    /* unselect_all */
+      NULL,                    /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "unselect-all-2",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      NULL,                    /* initial_current_folder */
+      FILE_NAME,               /* initial_filename */
+      FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      0,                       /* dialog_response */
+      TRUE,                    /* unselect_all */
+      NULL,                    /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "unselect-all-3",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      NULL,                    /* initial_current_folder */
+      FILE_NAME,               /* initial_filename */
+      FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      FILE_NAME_2,             /* tweak_filename */
+      0,                       /* dialog_response */
+      TRUE,                    /* unselect_all */
+      NULL,                    /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "unselect-all-4",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      NULL,                    /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      0,                       /* dialog_response */
+      TRUE,                    /* unselect_all */
+      NULL,                    /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "unselect-all-5",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      NULL,                    /* initial_current_folder */
+      FOLDER_NAME,             /* initial_filename */
+      FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      0,                       /* dialog_response */
+      TRUE,                    /* unselect_all */
+      NULL,                    /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "unselect-all-6",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      NULL,                    /* initial_current_folder */
+      FOLDER_NAME,             /* initial_filename */
+      FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      FOLDER_NAME_2,           /* tweak_filename */
+      0,                       /* dialog_response */
+      TRUE,                    /* unselect_all */
+      NULL,                    /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+
   };
 
 static void
@@ -861,8 +1719,11 @@ setup_file_chooser_button_tests (void)
       g_test_add_data_func (test_name, &button_tests[i], test_file_chooser_button);
       g_free (test_name);
     }
+
+  setup_file_chooser_button_combo_box_tests ();
 }
 
+#ifdef BROKEN_TESTS
 struct confirm_overwrite_closure {
   GtkWidget *chooser;
   GtkWidget *accept_button;
@@ -929,6 +1790,7 @@ test_confirm_overwrite_for_path (const char *path, gboolean append_extension)
   gboolean passed;
   struct confirm_overwrite_closure closure;
   char *filename;
+  guint timeout_id;
 
   passed = TRUE;
 
@@ -974,13 +1836,14 @@ test_confirm_overwrite_for_path (const char *path, gboolean append_extension)
       gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (closure.chooser), path);
     }
 
-  gdk_threads_add_timeout_full (G_MAXINT, SLEEP_DURATION, confirm_overwrite_timeout_cb, &closure, NULL);
+  timeout_id = gdk_threads_add_timeout_full (G_MAXINT, SLEEP_DURATION, confirm_overwrite_timeout_cb, &closure, NULL);
   gtk_dialog_run (GTK_DIALOG (closure.chooser));
+  g_source_remove (timeout_id);
 
   filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (closure.chooser));
   passed = passed && filename && (strcmp (filename, path) == 0);
   g_free (filename);
-  
+
   gtk_widget_destroy (closure.chooser);
 
   passed = passed && (1 == closure.confirm_overwrite_signal_emitted);
@@ -996,11 +1859,12 @@ test_confirm_overwrite (void)
   gboolean passed = TRUE;
 
   /* first test for a file we know will always exist */
-  passed = passed && test_confirm_overwrite_for_path ("/etc/passwd", FALSE); 
+  passed = passed && test_confirm_overwrite_for_path ("/etc/passwd", FALSE);
   g_assert (passed);
-  passed = passed && test_confirm_overwrite_for_path ("/etc/resolv.conf", TRUE); 
+  passed = passed && test_confirm_overwrite_for_path ("/etc/resolv.conf", TRUE);
   g_assert (passed);
 }
+#endif
 
 static const GtkFileChooserAction open_actions[] = {
   GTK_FILE_CHOOSER_ACTION_OPEN,
@@ -1013,6 +1877,7 @@ static const GtkFileChooserAction save_actions[] = {
 };
 
 
+#ifdef BROKEN_TESTS
 static gboolean
 has_action (const GtkFileChooserAction *actions,
            int n_actions,
@@ -1027,22 +1892,6 @@ has_action (const GtkFileChooserAction *actions,
   return FALSE;
 }
 
-static const char *
-get_action_name (GtkFileChooserAction action)
-{
-  switch (action)
-    {
-    case GTK_FILE_CHOOSER_ACTION_OPEN:          return "OPEN";
-    case GTK_FILE_CHOOSER_ACTION_SAVE:          return "SAVE";
-    case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER: return "SELECT_FOLDER";
-    case GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER: return "CREATE_FOLDER";
-
-    default:
-      g_assert_not_reached ();
-      return NULL;
-    }
-}
-
 static GtkFileChooserDefault *
 get_impl_from_dialog (GtkWidget *dialog)
 {
@@ -1065,7 +1914,7 @@ get_impl_from_dialog (GtkWidget *dialog)
 
   return impl;
 }
-#ifdef BROKEN_TESTS
+
 static gboolean
 test_widgets_for_current_action (GtkFileChooserDialog *dialog,
                                 GtkFileChooserAction  expected_action)
@@ -1388,7 +2237,6 @@ test_reload (void)
   log_test (passed, "test_reload(): set a folder explicitly before mapping");
   g_assert (passed);
 }
-#endif
 
 static gboolean
 test_button_folder_states_for_action (GtkFileChooserAction action, gboolean use_dialog, gboolean set_folder_on_dialog)
@@ -1617,6 +2465,7 @@ test_folder_switch_and_filters (void)
 
   log_test (passed, "test_folder_switch_and_filters(): all filter tests");
 }
+#endif
 
 int
 main (int    argc,