TerminalScreen * terminal_app_new_terminal (TerminalApp *app, TerminalWindow *window, GSettings *profile, char **override_command, const char *working_dir, char **child_env, double zoom) { TerminalScreen *screen; g_return_val_if_fail (TERMINAL_IS_APP (app), NULL); g_return_val_if_fail (TERMINAL_IS_WINDOW (window), NULL); screen = terminal_screen_new (profile, override_command, working_dir, child_env, zoom); terminal_window_add_screen (window, screen, -1); terminal_window_switch_screen (window, screen); gtk_widget_grab_focus (GTK_WIDGET (screen)); /* Launch the child on idle */ _terminal_screen_launch_child_on_idle (screen); return screen; }
static gboolean terminal_factory_impl_create_instance (TerminalFactory *factory, GDBusMethodInvocation *invocation, GVariant *options) { TerminalApp *app = terminal_app_get (); TerminalSettingsList *profiles_list; GDBusObjectManagerServer *object_manager; TerminalWindow *window; TerminalScreen *screen; TerminalReceiverImpl *impl; TerminalObjectSkeleton *skeleton; char *object_path; GSettings *profile = NULL; const char *profile_uuid, *title, *encoding; gboolean zoom_set = FALSE; gdouble zoom = 1.0; guint window_id; gboolean show_menubar; gboolean active; gboolean have_new_window, present_window, present_window_set; GError *err = NULL; /* Look up the profile */ if (!g_variant_lookup (options, "profile", "&s", &profile_uuid)) profile_uuid = NULL; if (!g_variant_lookup (options, "encoding", "&s", &encoding)) encoding = NULL; /* use profile encoding */ profiles_list = terminal_app_get_profiles_list (app); profile = terminal_profiles_list_ref_profile_by_uuid (profiles_list, profile_uuid, &err); if (profile == NULL) { g_dbus_method_invocation_return_gerror (invocation, err); g_error_free (err); goto out; } if (g_variant_lookup (options, "window-id", "u", &window_id)) { GtkWindow *win; win = gtk_application_get_window_by_id (GTK_APPLICATION (app), window_id); if (!TERMINAL_IS_WINDOW (win)) { g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "Nonexisting window %u referenced", window_id); goto out; } window = TERMINAL_WINDOW (win); have_new_window = FALSE; } else { const char *startup_id, *display_name, *role; gboolean start_maximized, start_fullscreen; int screen_number; GdkScreen *gdk_screen; /* Create a new window */ if (!g_variant_lookup (options, "display", "^&ay", &display_name)) { g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No display specified"); goto out; } screen_number = 0; gdk_screen = terminal_util_get_screen_by_display_name (display_name, screen_number); if (gdk_screen == NULL) { g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No screen %d on display \"%s\"", screen_number, display_name); goto out; } window = terminal_app_new_window (app, gdk_screen); if (g_variant_lookup (options, "desktop-startup-id", "^&ay", &startup_id)) gtk_window_set_startup_id (GTK_WINDOW (window), startup_id); /* Overwrite the default, unique window role set in terminal_window_init */ if (g_variant_lookup (options, "role", "&s", &role)) gtk_window_set_role (GTK_WINDOW (window), role); if (g_variant_lookup (options, "show-menubar", "b", &show_menubar)) terminal_window_set_menubar_visible (window, show_menubar); if (g_variant_lookup (options, "fullscreen-window", "b", &start_fullscreen) && start_fullscreen) { gtk_window_fullscreen (GTK_WINDOW (window)); } if (g_variant_lookup (options, "maximize-window", "b", &start_maximized) && start_maximized) { gtk_window_maximize (GTK_WINDOW (window)); } have_new_window = TRUE; } g_assert (window != NULL); if (!g_variant_lookup (options, "title", "&s", &title)) title = NULL; if (g_variant_lookup (options, "zoom", "d", &zoom)) zoom_set = TRUE; screen = terminal_screen_new (profile, encoding, NULL, title, NULL, NULL, zoom_set ? zoom : 1.0); terminal_window_add_screen (window, screen, -1); object_path = get_object_path_for_screen (window, screen); g_assert (g_variant_is_object_path (object_path)); skeleton = terminal_object_skeleton_new (object_path); impl = terminal_receiver_impl_new (screen); terminal_object_skeleton_set_receiver (skeleton, TERMINAL_RECEIVER (impl)); g_object_unref (impl); object_manager = terminal_app_get_object_manager (app); g_dbus_object_manager_server_export (object_manager, G_DBUS_OBJECT_SKELETON (skeleton)); g_object_set_data_full (G_OBJECT (screen), RECEIVER_IMPL_SKELETON_DATA_KEY, skeleton, (GDestroyNotify) g_object_unref); g_signal_connect (screen, "destroy", G_CALLBACK (screen_destroy_cb), app); if (g_variant_lookup (options, "active", "b", &active) && active) { terminal_window_switch_screen (window, screen); gtk_widget_grab_focus (GTK_WIDGET (screen)); } if (g_variant_lookup (options, "present-window", "b", &present_window)) present_window_set = TRUE; else present_window_set = FALSE; if (have_new_window) { const char *geometry; if (g_variant_lookup (options, "geometry", "&s", &geometry) && !terminal_window_parse_geometry (window, geometry)) _terminal_debug_print (TERMINAL_DEBUG_GEOMETRY, "Invalid geometry string \"%s\"", geometry); } if (have_new_window || (present_window_set && present_window)) gtk_window_present (GTK_WINDOW (window)); terminal_factory_complete_create_instance (factory, invocation, object_path); g_free (object_path); out: if (profile) g_object_unref (profile); return TRUE; /* handled */ }
/** * handle_options: * @app: * @options: a #TerminalOptions * @allow_resume: whether to merge the terminal configuration from the * saved session on resume * @error: a #GError to fill in * * Processes @options. It loads or saves the terminal configuration, or * opens the specified windows and tabs. * * Returns: %TRUE if @options could be successfully handled, or %FALSE on * error */ static gboolean handle_options (TerminalFactory *factory, TerminalOptions *options, GError **error) { GList *lw; GError *err; #if 0 gdk_screen = terminal_app_get_screen_by_display_name (options->display_name, options->screen_number); #endif /* Make sure we open at least one window */ terminal_options_ensure_window (options); for (lw = options->initial_windows; lw != NULL; lw = lw->next) { InitialWindow *iw = lw->data; GList *lt; guint window_id; g_assert (iw->tabs); window_id = 0; /* Now add the tabs */ for (lt = iw->tabs; lt != NULL; lt = lt->next) { InitialTab *it = lt->data; GVariantBuilder builder; char *object_path, *p; TerminalReceiver *receiver; char **argv; int argc; err = NULL; g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); terminal_client_append_create_instance_options (&builder, options->display_name, options->startup_id, iw->geometry, iw->role, it->profile ? it->profile : options->default_profile, it->title ? it->title : options->default_title, iw->start_maximized, iw->start_fullscreen); if (window_id) g_variant_builder_add (&builder, "{sv}", "window-id", g_variant_new_uint32 (window_id)); /* Restored windows shouldn't demand attention; see bug #586308. */ if (iw->source_tag == SOURCE_SESSION) g_variant_builder_add (&builder, "{sv}", "present-window", g_variant_new_boolean (FALSE)); if (options->zoom_set || it->zoom_set) g_variant_builder_add (&builder, "{sv}", "zoom", g_variant_new_double (it->zoom_set ? it->zoom : options->zoom)); if (iw->force_menubar_state) g_variant_builder_add (&builder, "{sv}", "show-menubar", g_variant_new_boolean (iw->menubar_state)); #if 0 if (it->active) terminal_window_switch_screen (window, screen); #endif if (!terminal_factory_call_create_instance_sync (factory, g_variant_builder_end (&builder), &object_path, NULL /* cancellable */, &err)) { g_dbus_error_strip_remote_error (err); g_printerr ("Error creating terminal: %s\n", err->message); g_error_free (err); /* Continue processing the remaining options! */ continue; } p = strstr (object_path, "/window/"); if (p) { char *end = NULL; guint64 value; errno = 0; p += strlen ("/window/"); value = g_ascii_strtoull (p, &end, 10); if (errno == 0 && end != p && *end == '/') window_id = (guint) value; } receiver = terminal_receiver_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, options->server_app_id ? options->server_app_id : TERMINAL_APPLICATION_ID, object_path, NULL /* cancellable */, &err); if (receiver == NULL) { g_dbus_error_strip_remote_error (err); g_printerr ("Failed to create proxy for terminal: %s\n", err->message); g_error_free (err); g_free (object_path); /* Continue processing the remaining options! */ continue; } g_free (object_path); g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); argv = it->exec_argv ? it->exec_argv : options->exec_argv, argc = argv ? g_strv_length (argv) : 0; terminal_client_append_exec_options (&builder, it->working_dir ? it->working_dir : options->default_working_dir, argc == 0); if (!terminal_receiver_call_exec_sync (receiver, g_variant_builder_end (&builder), g_variant_new_bytestring_array ((const char * const *) argv, argc), NULL /* infdlist */, NULL /* outfdlist */, NULL /* cancellable */, &err)) { g_dbus_error_strip_remote_error (err); g_printerr ("Error: %s\n", err->message); g_error_free (err); } g_object_unref (receiver); } } return TRUE; }