static gboolean
open_after_timeout (gpointer user_data)
{
  IdeGitCloneWidget *self;
  IdeWorkbench *workbench;
  g_autoptr(GTask) task = user_data;
  g_autoptr(GError) error = NULL;
  CloneRequest *req;

  IDE_ENTRY;

  g_assert (G_IS_TASK (task));

  self = g_task_get_source_object (task);
  req = g_task_get_task_data (task);
  workbench = ide_widget_get_workbench (GTK_WIDGET (self));

  g_assert (req != NULL);
  g_assert (IDE_IS_GIT_CLONE_WIDGET (self));
  g_assert (IDE_IS_WORKBENCH (workbench));

  if (error)
    {
      g_warning ("%s", error->message);
      gtk_label_set_label (self->clone_error_label, error->message);
      gtk_widget_show (GTK_WIDGET (self->clone_error_label));
    }
  else
    {
      ide_workbench_open_project_async (workbench, req->project_file, NULL, NULL, NULL);
    }

  g_task_return_boolean (task, TRUE);

  IDE_RETURN (G_SOURCE_REMOVE);
}
static void
ide_application_open_tick (GTask *task)
{
  IdeApplication *self;
  IdeApplicationOpen *state;
  IdeWorkbench *workbench;
  GCancellable *cancellable;
  GFile *next;
  guint i;

  g_assert (G_IS_TASK (task));

  self = g_task_get_source_object (task);
  state = g_task_get_task_data (task);
  cancellable = g_task_get_cancellable (task);

  g_assert (IDE_IS_APPLICATION (self));
  g_assert (state != NULL);
  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));

  /*
   * Try to open each of our available files with an existing workspace
   * since we could have gotten a new workspace since the last file
   * we opened.
   */

  for (i = state->files->len; i > 0; i--)
    {
      GFile *file = g_ptr_array_index (state->files, i - 1);

      /*
       * We walk backwards via the array so we can safely remove
       * items as we go. We could do remove_index_fast(), but it
       * seems worthwhile to preserve the stack ordering as much
       * as possible. This way, the files are shown in the editor
       * with a similar stacking to the request.
       */
      if (maybe_open_with_existing_workspace (self, file, state->hint, cancellable))
        g_ptr_array_remove_index (state->files, i - 1);
    }

  /*
   * If we have no files left, we can complete the task now.
   */
  if (state->files->len == 0)
    {
      g_task_return_boolean (task, TRUE);
      return;
    }

  /*
   * Try to open the next file in the list, which will result in a
   * new workbench being loaded (and therefore might allow us to
   * open further files in that workbench).
   */

  next = g_ptr_array_index (state->files, state->files->len - 1);

  workbench = g_object_new (IDE_TYPE_WORKBENCH,
                            "application", self,
                            "disable-greeter", TRUE,
                            NULL);

  ide_workbench_open_project_async (workbench,
                                    next,
                                    cancellable,
                                    ide_application_open_project_cb,
                                    g_object_ref (task));
}