static gboolean maybe_open_with_existing_workspace (IdeApplication *self, GFile *file, const gchar *hint, GCancellable *cancellable) { GList *windows; GList *iter; g_assert (IDE_IS_APPLICATION (self)); g_assert (G_IS_FILE (file)); windows = gtk_application_get_windows (GTK_APPLICATION (self)); for (iter = windows; iter != NULL; iter = iter->next) { GtkWindow *window = iter->data; if (IDE_IS_WORKBENCH (window) && workbench_manages_file (IDE_WORKBENCH (window), file)) { ide_workbench_open_files_async (IDE_WORKBENCH (window), &file, 1, hint, 0, cancellable, NULL, NULL); return TRUE; } } return FALSE; }
static void gb_vim_command_vsplit_cb (GObject *object, GAsyncResult *result, gpointer user_data) { SplitCallbackData *split_callback_data = (SplitCallbackData *)user_data; IdeWorkbench *workbench; GtkWidget *active_widget; const gchar *file_path; GVariant *variant; g_autoptr(GError) error = NULL; workbench = IDE_WORKBENCH (object); if (ide_workbench_open_files_finish (workbench,result, &error)) { active_widget = split_callback_data->active_widget; file_path = split_callback_data->file_path; variant = g_variant_new_string (file_path); dzl_gtk_widget_action (GTK_WIDGET (active_widget), "layoutstack", "open-in-new-frame", variant); } g_object_unref (split_callback_data->active_widget); g_free (split_callback_data->file_path); g_slice_free (SplitCallbackData, split_callback_data); }
static void ide_workbench_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { IdeWorkbench *self = IDE_WORKBENCH (object); switch (prop_id) { case PROP_DISABLE_GREETER: self->disable_greeter = g_value_get_boolean (value); break; case PROP_VISIBLE_PERSPECTIVE: ide_workbench_set_visible_perspective (self, g_value_get_object (value)); break; case PROP_VISIBLE_PERSPECTIVE_NAME: ide_workbench_set_visible_perspective_name (self, g_value_get_string (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } }
void ide_application_actions_update (IdeApplication *self) { GList *windows; GAction *action; gboolean enabled; g_assert (IDE_IS_APPLICATION (self)); /* * We only enable the preferences action if we have a workbench open * that is past the greeter. */ action = g_action_map_lookup_action (G_ACTION_MAP (self), "preferences"); enabled = FALSE; for (windows = gtk_application_get_windows (GTK_APPLICATION (self)); windows != NULL; windows = windows->next) { GtkWindow *window = windows->data; if (IDE_IS_WORKBENCH (window) && !ide_str_equal0 ("greeter", ide_workbench_get_visible_perspective_name (IDE_WORKBENCH (window)))) { enabled = TRUE; break; } } g_simple_action_set_enabled (G_SIMPLE_ACTION (action), enabled); }
static void ide_workbench_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { IdeWorkbench *self = IDE_WORKBENCH (object); switch (prop_id) { case PROP_CONTEXT: g_value_set_object (value, ide_workbench_get_context (self)); break; case PROP_VISIBLE_PERSPECTIVE: g_value_set_object (value, ide_workbench_get_visible_perspective (self)); break; case PROP_VISIBLE_PERSPECTIVE_NAME: g_value_set_string (value, ide_workbench_get_visible_perspective_name (self)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } }
static void gb_terminal_respawn (GbTerminalView *self, VteTerminal *terminal) { g_autoptr(GPtrArray) args = NULL; g_autofree gchar *workpath = NULL; GtkWidget *toplevel; GError *error = NULL; IdeContext *context; IdeVcs *vcs; GFile *workdir; GPid child_pid; gint64 now; g_assert (GB_IS_TERMINAL_VIEW (self)); vte_terminal_reset (terminal, TRUE, TRUE); toplevel = gtk_widget_get_toplevel (GTK_WIDGET (self)); if (!IDE_IS_WORKBENCH (toplevel)) return; /* Prevent flapping */ now = g_get_monotonic_time (); if ((now - self->last_respawn) < (G_USEC_PER_SEC / 10)) return; self->last_respawn = now; context = ide_workbench_get_context (IDE_WORKBENCH (toplevel)); vcs = ide_context_get_vcs (context); workdir = ide_vcs_get_working_directory (vcs); workpath = g_file_get_path (workdir); args = g_ptr_array_new_with_free_func (g_free); g_ptr_array_add (args, vte_get_user_shell ()); g_ptr_array_add (args, NULL); vte_terminal_spawn_sync (terminal, VTE_PTY_DEFAULT | VTE_PTY_NO_LASTLOG | VTE_PTY_NO_UTMP | VTE_PTY_NO_WTMP, workpath, (gchar **)args->pdata, NULL, G_SPAWN_DEFAULT, NULL, NULL, &child_pid, NULL, &error); if (error != NULL) { g_warning ("%s", error->message); g_clear_error (&error); return; } vte_terminal_watch_child (terminal, child_pid); }
static void ide_application_actions_load_workbench_view (IdeApplication *self, const char *genesis_view, const char *manifest) { IdeWorkbench *workbench = NULL; IdePerspective *greeter; const GList *list; list = gtk_application_get_windows (GTK_APPLICATION (self)); for (; list != NULL; list = list->next) { GtkWindow *window = list->data; if (IDE_IS_WORKBENCH (window)) { if (ide_workbench_get_context (IDE_WORKBENCH (window)) == NULL) { workbench = IDE_WORKBENCH (window); break; } } } if (workbench == NULL) { workbench = g_object_new (IDE_TYPE_WORKBENCH, "application", self, NULL); } greeter = ide_workbench_get_perspective_by_name (workbench, "greeter"); if (greeter) { ide_greeter_perspective_show_genesis_view (IDE_GREETER_PERSPECTIVE (greeter), genesis_view, manifest); } gtk_window_present (GTK_WINDOW (workbench)); }
static void ide_application_actions_preferences (GSimpleAction *action, GVariant *parameter, gpointer user_data) { IdeApplication *self = user_data; GList *windows; IDE_ENTRY; g_assert (IDE_IS_APPLICATION (self)); /* * TODO: Make this work at the greeter screen too. */ windows = gtk_application_get_windows (GTK_APPLICATION (self)); for (; windows; windows = windows->next) { GtkWindow *window = windows->data; const gchar *name; if (!IDE_IS_WORKBENCH (window)) continue; name = ide_workbench_get_visible_perspective_name (IDE_WORKBENCH (window)); if (!ide_str_equal0 (name, "greeter") && !ide_str_equal0 (name, "genesis")) { ide_workbench_set_visible_perspective_name (IDE_WORKBENCH (window), "preferences"); IDE_EXIT; } } IDE_EXIT; }
IdeWorkbench * ide_widget_get_workbench (GtkWidget *widget) { GtkWidget *ancestor; g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); ancestor = gtk_widget_get_ancestor (widget, IDE_TYPE_WORKBENCH); if (IDE_IS_WORKBENCH (ancestor)) return IDE_WORKBENCH (ancestor); /* * TODO: Add "IDE_WORKBENCH" gdata for popout windows. */ return NULL; }
static gboolean gb_project_tree_builder_node_activated (IdeTreeBuilder *builder, IdeTreeNode *node) { GObject *item; g_assert (GB_IS_PROJECT_TREE_BUILDER (builder)); item = ide_tree_node_get_item (node); if (GB_IS_PROJECT_FILE (item)) { GtkWidget *workbench; IdeTree *tree; GFile *file; if (gb_project_file_get_is_directory (GB_PROJECT_FILE (item))) goto failure; file = gb_project_file_get_file (GB_PROJECT_FILE (item)); if (!file) goto failure; tree = ide_tree_node_get_tree (node); if (!tree) goto failure; workbench = gtk_widget_get_ancestor (GTK_WIDGET (tree), IDE_TYPE_WORKBENCH); ide_workbench_open_files_async (IDE_WORKBENCH (workbench), &file, 1, NULL, IDE_WORKBENCH_OPEN_FLAGS_NONE, NULL, NULL, NULL); return TRUE; } failure: return FALSE; }
static void gb_terminal_respawn (GbTerminalView *self, VteTerminal *terminal) { g_autoptr(GPtrArray) args = NULL; g_autoptr(IdeSubprocess) subprocess = NULL; g_autoptr(IdeSubprocessLauncher) launcher = NULL; g_autofree gchar *workpath = NULL; g_autofree gchar *shell = NULL; GtkWidget *toplevel; GError *error = NULL; IdeContext *context; IdeVcs *vcs; VtePty *pty = NULL; GFile *workdir; gint64 now; int tty_fd = -1; gint stdout_fd = -1; gint stderr_fd = -1; IDE_ENTRY; g_assert (GB_IS_TERMINAL_VIEW (self)); vte_terminal_reset (terminal, TRUE, TRUE); toplevel = gtk_widget_get_toplevel (GTK_WIDGET (self)); if (!IDE_IS_WORKBENCH (toplevel)) IDE_EXIT; /* Prevent flapping */ now = g_get_monotonic_time (); if ((now - self->last_respawn) < (G_USEC_PER_SEC / 10)) IDE_EXIT; self->last_respawn = now; context = ide_workbench_get_context (IDE_WORKBENCH (toplevel)); vcs = ide_context_get_vcs (context); workdir = ide_vcs_get_working_directory (vcs); workpath = g_file_get_path (workdir); shell = gb_terminal_view_discover_shell (NULL, &error); if (shell == NULL) { g_warning ("Failed to discover user shell: %s", error->message); /* We prefer bash in flatpak over sh */ if (ide_is_flatpak ()) shell = g_strdup ("/bin/bash"); else shell = vte_get_user_shell (); g_clear_error (&error); } args = g_ptr_array_new (); g_ptr_array_add (args, (gchar *)shell); g_ptr_array_add (args, NULL); pty = vte_terminal_pty_new_sync (terminal, VTE_PTY_DEFAULT | VTE_PTY_NO_LASTLOG | VTE_PTY_NO_UTMP | VTE_PTY_NO_WTMP, NULL, &error); if (pty == NULL) IDE_GOTO (failure); vte_terminal_set_pty (terminal, pty); if (-1 == (tty_fd = gb_vte_pty_create_slave (pty))) IDE_GOTO (failure); /* dup() is safe as it will inherit O_CLOEXEC */ if (-1 == (stdout_fd = dup (tty_fd)) || -1 == (stderr_fd = dup (tty_fd))) IDE_GOTO (failure); /* XXX: It would be nice to allow using the runtimes launcher */ launcher = ide_subprocess_launcher_new (0); ide_subprocess_launcher_set_run_on_host (launcher, TRUE); ide_subprocess_launcher_set_clear_env (launcher, FALSE); ide_subprocess_launcher_set_cwd (launcher, workpath); ide_subprocess_launcher_push_args (launcher, (const gchar * const *)args->pdata); ide_subprocess_launcher_take_stdin_fd (launcher, tty_fd); ide_subprocess_launcher_take_stdout_fd (launcher, stdout_fd); ide_subprocess_launcher_take_stderr_fd (launcher, stderr_fd); ide_subprocess_launcher_setenv (launcher, "TERM", "xterm-256color", TRUE); ide_subprocess_launcher_setenv (launcher, "INSIDE_GNOME_BUILDER", PACKAGE_VERSION, TRUE); ide_subprocess_launcher_setenv (launcher, "SHELL", shell, TRUE); tty_fd = -1; stdout_fd = -1; stderr_fd = -1; if (NULL == (subprocess = ide_subprocess_launcher_spawn (launcher, NULL, &error))) IDE_GOTO (failure); ide_subprocess_wait_async (subprocess, NULL, gb_terminal_view_wait_cb, g_object_ref (terminal)); failure: if (tty_fd != -1) close (tty_fd); if (stdout_fd != -1) close (stdout_fd); g_clear_object (&pty); if (error != NULL) { g_warning ("%s", error->message); g_clear_error (&error); } IDE_EXIT; }