nautilus-3.6.3/src/nautilus-application.c

Location Tool Test ID Function Issue
nautilus-application.c:379:6 clang-analyzer Value stored to 'res' is never read
nautilus-application.c:1192:19 clang-analyzer Array access (from variable 'files') results in a null pointer dereference
   1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
   2 /*
   3  * nautilus-application: main Nautilus application class.
   4  *
   5  * Copyright (C) 1999, 2000 Red Hat, Inc.
   6  * Copyright (C) 2000, 2001 Eazel, Inc.
   7  * Copyright (C) 2010, Cosimo Cecchi <cosimoc@gnome.org>
   8  *
   9  * Nautilus is free software; you can redistribute it and/or
  10  * modify it under the terms of the GNU General Public License as
  11  * published by the Free Software Foundation; either version 2 of the
  12  * License, or (at your option) any later version.
  13  *
  14  * Nautilus is distributed in the hope that it will be useful,
  15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17  * General Public License for more details.
  18  *
  19  * You should have received a copy of the GNU General Public License
  20  * along with this program; if not, write to the Free Software
  21  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22  *
  23  * Authors: Elliot Lee <sopwith@redhat.com>,
  24  *          Darin Adler <darin@bentspoon.com>
  25  *          Cosimo Cecchi <cosimoc@gnome.org>
  26  *
  27  */
  28 
  29 #include <config.h>
  30 
  31 #include "nautilus-application.h"
  32 
  33 #if ENABLE_EMPTY_VIEW
  34 #include "nautilus-empty-view.h"
  35 #endif /* ENABLE_EMPTY_VIEW */
  36 
  37 #include "nautilus-bookmarks-window.h"
  38 #include "nautilus-connect-server-dialog.h"
  39 #include "nautilus-desktop-canvas-view.h"
  40 #include "nautilus-desktop-window.h"
  41 #include "nautilus-file-management-properties.h"
  42 #include "nautilus-freedesktop-dbus.h"
  43 #include "nautilus-canvas-view.h"
  44 #include "nautilus-image-properties-page.h"
  45 #include "nautilus-list-view.h"
  46 #include "nautilus-previewer.h"
  47 #include "nautilus-progress-ui-handler.h"
  48 #include "nautilus-self-check-functions.h"
  49 #include "nautilus-window.h"
  50 #include "nautilus-window-manage-views.h"
  51 #include "nautilus-window-private.h"
  52 #include "nautilus-window-slot.h"
  53 
  54 #include <libnautilus-private/nautilus-dbus-manager.h>
  55 #include <libnautilus-private/nautilus-desktop-link-monitor.h>
  56 #include <libnautilus-private/nautilus-directory-private.h>
  57 #include <libnautilus-private/nautilus-file-utilities.h>
  58 #include <libnautilus-private/nautilus-file-operations.h>
  59 #include <libnautilus-private/nautilus-global-preferences.h>
  60 #include <libnautilus-private/nautilus-lib-self-check-functions.h>
  61 #include <libnautilus-private/nautilus-module.h>
  62 #include <libnautilus-private/nautilus-profile.h>
  63 #include <libnautilus-private/nautilus-signaller.h>
  64 #include <libnautilus-private/nautilus-ui-utilities.h>
  65 #include <libnautilus-extension/nautilus-menu-provider.h>
  66 
  67 #define DEBUG_FLAG NAUTILUS_DEBUG_APPLICATION
  68 #include <libnautilus-private/nautilus-debug.h>
  69 
  70 #include <sys/types.h>
  71 #include <sys/stat.h>
  72 #include <fcntl.h>
  73 #include <glib/gstdio.h>
  74 #include <glib/gi18n.h>
  75 #include <gio/gio.h>
  76 #include <eel/eel-gtk-extensions.h>
  77 #include <eel/eel-stock-dialogs.h>
  78 #include <libnotify/notify.h>
  79 #include <gdk/gdkx.h>
  80 #include <gtk/gtk.h>
  81 
  82 /* Keep window from shrinking down ridiculously small; numbers are somewhat arbitrary */
  83 #define APPLICATION_WINDOW_MIN_WIDTH	300
  84 #define APPLICATION_WINDOW_MIN_HEIGHT	100
  85 
  86 #define START_STATE_CONFIG "start-state"
  87 
  88 #define NAUTILUS_ACCEL_MAP_SAVE_DELAY 30
  89 
  90 /* Keeps track of all the desktop windows. */
  91 static GList *nautilus_application_desktop_windows;
  92 
  93 /* The saving of the accelerator map was requested  */
  94 static gboolean save_of_accel_map_requested = FALSE;
  95 
  96 static void     desktop_changed_callback          (gpointer                  user_data);
  97 static void     mount_added_callback              (GVolumeMonitor            *monitor,
  98 						   GMount                    *mount,
  99 						   NautilusApplication       *application);
 100 
 101 G_DEFINE_TYPE (NautilusApplication, nautilus_application, GTK_TYPE_APPLICATION);
 102 
 103 struct _NautilusApplicationPriv {
 104 	GVolumeMonitor *volume_monitor;
 105 	NautilusProgressUIHandler *progress_handler;
 106 
 107 	gboolean no_desktop;
 108 	gchar *geometry;
 109 
 110 	NotifyNotification *unmount_notify;
 111 
 112 	NautilusBookmarkList *bookmark_list;
 113 
 114 	GtkWidget *connect_server_window;
 115 };
 116 
 117 NautilusBookmarkList *
 118 nautilus_application_get_bookmarks (NautilusApplication *application)
 119 {
 120 	return application->priv->bookmark_list;
 121 }
 122 
 123 void
 124 nautilus_application_edit_bookmarks (NautilusApplication *application,
 125 				     NautilusWindow      *window)
 126 {
 127 	GtkWindow *bookmarks_window;
 128 
 129 	bookmarks_window = nautilus_bookmarks_window_new (window);
 130 	gtk_window_present (bookmarks_window);
 131 }
 132 
 133 void
 134 nautilus_application_notify_unmount_done (NautilusApplication *application,
 135 					  const gchar *message)
 136 {
 137 	if (application->priv->unmount_notify) {
 138 		notify_notification_close (application->priv->unmount_notify, NULL);
 139 		g_clear_object (&application->priv->unmount_notify);
 140 	}
 141 
 142 	if (message != NULL) {
 143 		NotifyNotification *unplug;
 144 		gchar **strings;
 145 
 146 		strings = g_strsplit (message, "\n", 0);
 147 		unplug = notify_notification_new (strings[0], strings[1],
 148 						  "media-removable");
 149 
 150 		notify_notification_show (unplug, NULL);
 151 		g_object_unref (unplug);
 152 		g_strfreev (strings);
 153 	}
 154 }
 155 
 156 void
 157 nautilus_application_notify_unmount_show (NautilusApplication *application,
 158 					  const gchar *message)
 159 {
 160 	gchar **strings;
 161 
 162 	strings = g_strsplit (message, "\n", 0);
 163 
 164 	if (!application->priv->unmount_notify) {
 165 		application->priv->unmount_notify =
 166 			notify_notification_new (strings[0], strings[1],
 167 						 "media-removable");
 168 
 169 		notify_notification_set_hint (application->priv->unmount_notify,
 170 					      "transient", g_variant_new_boolean (TRUE));
 171 		notify_notification_set_urgency (application->priv->unmount_notify,
 172 						 NOTIFY_URGENCY_CRITICAL);
 173 	} else {
 174 		notify_notification_update (application->priv->unmount_notify,
 175 					    strings[0], strings[1],
 176 					    "media-removable");
 177 	}
 178 
 179 	notify_notification_show (application->priv->unmount_notify, NULL);
 180 	g_strfreev (strings);
 181 }
 182 
 183 static gboolean
 184 check_required_directories (NautilusApplication *application)
 185 {
 186 	char *user_directory;
 187 	char *desktop_directory;
 188 	GSList *directories;
 189 	gboolean ret;
 190 
 191 	g_assert (NAUTILUS_IS_APPLICATION (application));
 192 
 193 	nautilus_profile_start (NULL);
 194 
 195 	ret = TRUE;
 196 
 197 	user_directory = nautilus_get_user_directory ();
 198 	desktop_directory = nautilus_get_desktop_directory ();
 199 
 200 	directories = NULL;
 201 
 202 	if (!g_file_test (user_directory, G_FILE_TEST_IS_DIR)) {
 203 		directories = g_slist_prepend (directories, user_directory);
 204 	}
 205 
 206 	if (!g_file_test (desktop_directory, G_FILE_TEST_IS_DIR)) {
 207 		directories = g_slist_prepend (directories, desktop_directory);
 208 	}
 209 
 210 	if (directories != NULL) {
 211 		int failed_count;
 212 		GString *directories_as_string;
 213 		GSList *l;
 214 		char *error_string;
 215 		const char *detail_string;
 216 		GtkDialog *dialog;
 217 
 218 		ret = FALSE;
 219 
 220 		failed_count = g_slist_length (directories);
 221 
 222 		directories_as_string = g_string_new ((const char *)directories->data);
 223 		for (l = directories->next; l != NULL; l = l->next) {
 224 			g_string_append_printf (directories_as_string, ", %s", (const char *)l->data);
 225 		}
 226 
 227 		error_string = _("Oops! Something went wrong.");
 228 		if (failed_count == 1) {
 229 			detail_string = g_strdup_printf (_("Unable to create a required folder. "
 230 							   "Please create the following folder, or "
 231 							   "set permissions such that it can be created:\n%s"),
 232 							 directories_as_string->str);
 233 		} else {
 234 			detail_string = g_strdup_printf (_("Unable to create required folders. "
 235 							   "Please create the following folders, or "
 236 							   "set permissions such that they can be created:\n%s"),
 237 							 directories_as_string->str);
 238 		}
 239 
 240 		dialog = eel_show_error_dialog (error_string, detail_string, NULL);
 241 		/* We need the main event loop so the user has a chance to see the dialog. */
 242 		gtk_application_add_window (GTK_APPLICATION (application),
 243 					    GTK_WINDOW (dialog));
 244 
 245 		g_string_free (directories_as_string, TRUE);
 246 	}
 247 
 248 	g_slist_free (directories);
 249 	g_free (user_directory);
 250 	g_free (desktop_directory);
 251 	nautilus_profile_end (NULL);
 252 
 253 	return ret;
 254 }
 255 
 256 static void
 257 menu_provider_items_updated_handler (NautilusMenuProvider *provider, GtkWidget* parent_window, gpointer data)
 258 {
 259 
 260 	g_signal_emit_by_name (nautilus_signaller_get_current (),
 261 			       "popup_menu_changed");
 262 }
 263 
 264 static void
 265 menu_provider_init_callback (void)
 266 {
 267         GList *providers;
 268         GList *l;
 269 
 270         providers = nautilus_module_get_extensions_for_type (NAUTILUS_TYPE_MENU_PROVIDER);
 271 
 272         for (l = providers; l != NULL; l = l->next) {
 273                 NautilusMenuProvider *provider = NAUTILUS_MENU_PROVIDER (l->data);
 274 
 275 		g_signal_connect_after (G_OBJECT (provider), "items_updated",
 276                            (GCallback)menu_provider_items_updated_handler,
 277                            NULL);
 278         }
 279 
 280         nautilus_module_extension_list_free (providers);
 281 }
 282 
 283 static void
 284 mark_desktop_files_trusted (void)
 285 {
 286 	char *do_once_file;
 287 	GFile *f, *c;
 288 	GFileEnumerator *e;
 289 	GFileInfo *info;
 290 	const char *name;
 291 	int fd;
 292 	
 293 	do_once_file = g_build_filename (g_get_user_data_dir (),
 294 					 ".converted-launchers", NULL);
 295 
 296 	if (g_file_test (do_once_file, G_FILE_TEST_EXISTS)) {
 297 		goto out;
 298 	}
 299 
 300 	f = nautilus_get_desktop_location ();
 301 	e = g_file_enumerate_children (f,
 302 				       G_FILE_ATTRIBUTE_STANDARD_TYPE ","
 303 				       G_FILE_ATTRIBUTE_STANDARD_NAME ","
 304 				       G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE
 305 				       ,
 306 				       G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
 307 				       NULL, NULL);
 308 	if (e == NULL) {
 309 		goto out2;
 310 	}
 311 	
 312 	while ((info = g_file_enumerator_next_file (e, NULL, NULL)) != NULL) {
 313 		name = g_file_info_get_name (info);
 314 		
 315 		if (g_str_has_suffix (name, ".desktop") &&
 316 		    !g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE)) {
 317 			c = g_file_get_child (f, name);
 318 			nautilus_file_mark_desktop_file_trusted (c,
 319 								 NULL, FALSE,
 320 								 NULL, NULL);
 321 			g_object_unref (c);
 322 		}
 323 		g_object_unref (info);
 324 	}
 325 	
 326 	g_object_unref (e);
 327  out2:
 328 	fd = g_creat (do_once_file, 0666);
 329 	close (fd);
 330 	
 331 	g_object_unref (f);
 332  out:	
 333 	g_free (do_once_file);
 334 }
 335 
 336 static void
 337 do_upgrades_once (NautilusApplication *self)
 338 {
 339 	char *metafile_dir, *updated, *nautilus_dir, *xdg_dir;
 340 	const gchar *message;
 341 	int fd, res;
 342 
 343 	if (!self->priv->no_desktop) {
 344 		mark_desktop_files_trusted ();
 345 	}
 346 
 347 	metafile_dir = g_build_filename (g_get_home_dir (),
 348 					 ".nautilus/metafiles", NULL);
 349 	if (g_file_test (metafile_dir, G_FILE_TEST_IS_DIR)) {
 350 		updated = g_build_filename (metafile_dir, "migrated-to-gvfs", NULL);
 351 		if (!g_file_test (updated, G_FILE_TEST_EXISTS)) {
 352 			g_spawn_command_line_async (LIBEXECDIR"/nautilus-convert-metadata --quiet", NULL);
 353 			fd = g_creat (updated, 0600);
 354 			if (fd != -1) {
 355 				close (fd);
 356 			}
 357 		}
 358 		g_free (updated);
 359 	}
 360 	g_free (metafile_dir);
 361 
 362 	nautilus_dir = g_build_filename (g_get_home_dir (),
 363 					 ".nautilus", NULL);
 364 	xdg_dir = nautilus_get_user_directory ();
 365 	if (g_file_test (nautilus_dir, G_FILE_TEST_IS_DIR)) {
 366 		/* test if we already attempted to migrate first */
 367 		updated = g_build_filename (nautilus_dir, "DEPRECATED-DIRECTORY", NULL);
 368 		message = _("Nautilus 3.0 deprecated this directory and tried migrating "
 369 			    "this configuration to ~/.config/nautilus");
 370 		if (!g_file_test (updated, G_FILE_TEST_EXISTS)) {
 371 			/* rename() works fine if the destination directory is
 372 			 * empty.
 373 			 */
 374 			res = g_rename (nautilus_dir, xdg_dir);
 375 
 376 			if (res == -1) {
 377 				fd = g_creat (updated, 0600);
 378 				if (fd != -1) {
 379 					res = write (fd, message, strlen (message));
Value stored to 'res' is never read
(emitted by clang-analyzer)

TODO: a detailed trace is available in the data model (not yet rendered in this report)

380 close (fd); 381 } 382 } 383 } 384 385 g_free (updated); 386 } 387 388 g_free (nautilus_dir); 389 g_free (xdg_dir); 390 } 391 392 static void 393 selection_get_cb (GtkWidget *widget, 394 GtkSelectionData *selection_data, 395 guint info, 396 guint time) 397 { 398 /* No extra targets atm */ 399 } 400 401 static GtkWidget * 402 get_desktop_manager_selection (GdkDisplay *display, int screen) 403 { 404 char selection_name[32]; 405 GdkAtom selection_atom; 406 Window selection_owner; 407 GtkWidget *selection_widget; 408 409 g_snprintf (selection_name, sizeof (selection_name), "_NET_DESKTOP_MANAGER_S%d", screen); 410 selection_atom = gdk_atom_intern (selection_name, FALSE); 411 412 selection_owner = XGetSelectionOwner (GDK_DISPLAY_XDISPLAY (display), 413 gdk_x11_atom_to_xatom_for_display (display, 414 selection_atom)); 415 if (selection_owner != None) { 416 return NULL; 417 } 418 419 selection_widget = gtk_invisible_new_for_screen (gdk_display_get_screen (display, screen)); 420 /* We need this for gdk_x11_get_server_time() */ 421 gtk_widget_add_events (selection_widget, GDK_PROPERTY_CHANGE_MASK); 422 423 if (gtk_selection_owner_set_for_display (display, 424 selection_widget, 425 selection_atom, 426 gdk_x11_get_server_time (gtk_widget_get_window (selection_widget)))) { 427 428 g_signal_connect (selection_widget, "selection_get", 429 G_CALLBACK (selection_get_cb), NULL); 430 return selection_widget; 431 } 432 433 gtk_widget_destroy (selection_widget); 434 435 return NULL; 436 } 437 438 static void 439 desktop_unrealize_cb (GtkWidget *widget, 440 GtkWidget *selection_widget) 441 { 442 gtk_widget_destroy (selection_widget); 443 } 444 445 static gboolean 446 selection_clear_event_cb (GtkWidget *widget, 447 GdkEventSelection *event, 448 NautilusDesktopWindow *window) 449 { 450 gtk_widget_destroy (GTK_WIDGET (window)); 451 452 nautilus_application_desktop_windows = 453 g_list_remove (nautilus_application_desktop_windows, window); 454 455 return TRUE; 456 } 457 458 static void 459 nautilus_application_create_desktop_windows (NautilusApplication *application) 460 { 461 GdkDisplay *display; 462 NautilusDesktopWindow *window; 463 GtkWidget *selection_widget; 464 int screens, i; 465 466 display = gdk_display_get_default (); 467 screens = gdk_display_get_n_screens (display); 468 469 for (i = 0; i < screens; i++) { 470 471 DEBUG ("Creating a desktop window for screen %d", i); 472 473 selection_widget = get_desktop_manager_selection (display, i); 474 if (selection_widget != NULL) { 475 window = nautilus_desktop_window_new (GTK_APPLICATION (application), 476 gdk_display_get_screen (display, i)); 477 478 g_signal_connect (selection_widget, "selection_clear_event", 479 G_CALLBACK (selection_clear_event_cb), window); 480 481 g_signal_connect (window, "unrealize", 482 G_CALLBACK (desktop_unrealize_cb), selection_widget); 483 484 /* We realize it immediately so that the NAUTILUS_DESKTOP_WINDOW_ID 485 property is set so gnome-settings-daemon doesn't try to set the 486 background. And we do a gdk_flush() to be sure X gets it. */ 487 gtk_widget_realize (GTK_WIDGET (window)); 488 gdk_flush (); 489 490 nautilus_application_desktop_windows = 491 g_list_prepend (nautilus_application_desktop_windows, window); 492 } 493 } 494 } 495 496 static gboolean 497 another_navigation_window_already_showing (NautilusApplication *application, 498 NautilusWindow *the_window) 499 { 500 GList *list, *item; 501 502 list = gtk_application_get_windows (GTK_APPLICATION (application)); 503 for (item = list; item != NULL; item = item->next) { 504 if (item->data != the_window) { 505 return TRUE; 506 } 507 } 508 509 return FALSE; 510 } 511 512 NautilusWindow * 513 nautilus_application_create_window (NautilusApplication *application, 514 GdkScreen *screen) 515 { 516 NautilusWindow *window; 517 char *geometry_string; 518 gboolean maximized; 519 520 g_return_val_if_fail (NAUTILUS_IS_APPLICATION (application), NULL); 521 nautilus_profile_start (NULL); 522 523 window = nautilus_window_new (GTK_APPLICATION (application), screen); 524 525 maximized = g_settings_get_boolean 526 (nautilus_window_state, NAUTILUS_WINDOW_STATE_MAXIMIZED); 527 if (maximized) { 528 gtk_window_maximize (GTK_WINDOW (window)); 529 } else { 530 gtk_window_unmaximize (GTK_WINDOW (window)); 531 } 532 533 geometry_string = g_settings_get_string 534 (nautilus_window_state, NAUTILUS_WINDOW_STATE_GEOMETRY); 535 if (geometry_string != NULL && 536 geometry_string[0] != 0) { 537 /* Ignore saved window position if a window with the same 538 * location is already showing. That way the two windows 539 * wont appear at the exact same location on the screen. 540 */ 541 eel_gtk_window_set_initial_geometry_from_string 542 (GTK_WINDOW (window), 543 geometry_string, 544 NAUTILUS_WINDOW_MIN_WIDTH, 545 NAUTILUS_WINDOW_MIN_HEIGHT, 546 another_navigation_window_already_showing (application, window)); 547 } 548 g_free (geometry_string); 549 550 DEBUG ("Creating a new navigation window"); 551 nautilus_profile_end (NULL); 552 553 return window; 554 } 555 556 static void 557 mount_added_callback (GVolumeMonitor *monitor, 558 GMount *mount, 559 NautilusApplication *application) 560 { 561 NautilusDirectory *directory; 562 GFile *root; 563 gchar *uri; 564 565 root = g_mount_get_root (mount); 566 uri = g_file_get_uri (root); 567 568 DEBUG ("Added mount at uri %s", uri); 569 g_free (uri); 570 571 directory = nautilus_directory_get_existing (root); 572 g_object_unref (root); 573 if (directory != NULL) { 574 nautilus_directory_force_reload (directory); 575 nautilus_directory_unref (directory); 576 } 577 } 578 579 static void 580 open_window (NautilusApplication *application, 581 GFile *location, GdkScreen *screen, const char *geometry) 582 { 583 NautilusWindow *window; 584 gchar *uri; 585 586 uri = g_file_get_uri (location); 587 DEBUG ("Opening new window at uri %s", uri); 588 nautilus_profile_start (NULL); 589 window = nautilus_application_create_window (application, 590 screen); 591 nautilus_window_go_to (window, location); 592 593 if (geometry != NULL && !gtk_widget_get_visible (GTK_WIDGET (window))) { 594 /* never maximize windows opened from shell if a 595 * custom geometry has been requested. 596 */ 597 gtk_window_unmaximize (GTK_WINDOW (window)); 598 eel_gtk_window_set_initial_geometry_from_string (GTK_WINDOW (window), 599 geometry, 600 APPLICATION_WINDOW_MIN_WIDTH, 601 APPLICATION_WINDOW_MIN_HEIGHT, 602 FALSE); 603 } 604 605 nautilus_profile_end (NULL); 606 607 g_free (uri); 608 } 609 610 static void 611 open_windows (NautilusApplication *application, 612 GFile **files, 613 gint n_files, 614 GdkScreen *screen, 615 const char *geometry) 616 { 617 guint i; 618 619 if (files == NULL || files[0] == NULL) { 620 /* Open a window pointing at the default location. */ 621 open_window (application, NULL, screen, geometry); 622 } else { 623 /* Open windows at each requested location. */ 624 for (i = 0; i < n_files; i++) { 625 open_window (application, files[i], screen, geometry); 626 } 627 } 628 } 629 630 void 631 nautilus_application_open_location (NautilusApplication *application, 632 GFile *location, 633 GFile *selection, 634 const char *startup_id) 635 { 636 NautilusWindow *window; 637 GList *sel_list = NULL; 638 639 nautilus_profile_start (NULL); 640 641 window = nautilus_application_create_window (application, gdk_screen_get_default ()); 642 gtk_window_set_startup_id (GTK_WINDOW (window), startup_id); 643 644 if (selection != NULL) { 645 sel_list = g_list_prepend (sel_list, nautilus_file_get (selection)); 646 } 647 648 nautilus_window_slot_open_location_full (nautilus_window_get_active_slot (window), location, 649 0, sel_list, NULL, NULL); 650 651 if (sel_list != NULL) { 652 nautilus_file_list_free (sel_list); 653 } 654 655 nautilus_profile_end (NULL); 656 } 657 658 static void 659 nautilus_application_open (GApplication *app, 660 GFile **files, 661 gint n_files, 662 const gchar *hint) 663 { 664 NautilusApplication *self = NAUTILUS_APPLICATION (app); 665 666 DEBUG ("Open called on the GApplication instance; %d files", n_files); 667 668 open_windows (self, files, n_files, 669 gdk_screen_get_default (), 670 self->priv->geometry); 671 } 672 673 static GtkWindow * 674 get_focus_window (GtkApplication *application) 675 { 676 GList *windows; 677 GtkWindow *window = NULL; 678 679 /* the windows are ordered with the last focused first */ 680 windows = gtk_application_get_windows (application); 681 682 if (windows != NULL) { 683 window = g_list_nth_data (windows, 0); 684 } 685 686 return window; 687 } 688 689 static void 690 action_new_window (GSimpleAction *action, 691 GVariant *parameter, 692 gpointer user_data) 693 { 694 GtkApplication *application = user_data; 695 NautilusWindow *window; 696 GtkWindow *cur_window; 697 698 cur_window = get_focus_window (application); 699 window = nautilus_application_create_window (NAUTILUS_APPLICATION (application), 700 cur_window ? 701 gtk_window_get_screen (cur_window) : 702 gdk_screen_get_default ()); 703 704 nautilus_window_slot_go_home (nautilus_window_get_active_slot (window), 0); 705 } 706 707 static gboolean 708 go_to_server_cb (NautilusWindow *window, 709 GFile *location, 710 GError *error, 711 gpointer user_data) 712 { 713 gboolean retval; 714 715 if (error == NULL) { 716 GBookmarkFile *bookmarks; 717 GError *error = NULL; 718 char *datadir; 719 char *filename; 720 char *uri; 721 char *title; 722 NautilusFile *file; 723 gboolean safe_to_save = TRUE; 724 725 file = nautilus_file_get_existing (location); 726 727 bookmarks = g_bookmark_file_new (); 728 datadir = g_build_filename (g_get_user_config_dir (), "nautilus", NULL); 729 filename = g_build_filename (datadir, "servers", NULL); 730 g_mkdir_with_parents (datadir, 0700); 731 g_free (datadir); 732 g_bookmark_file_load_from_file (bookmarks, 733 filename, 734 &error); 735 if (error != NULL) { 736 if (! g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) { 737 /* only warn if the file exists */ 738 g_warning ("Unable to open server bookmarks: %s", error->message); 739 safe_to_save = FALSE; 740 } 741 g_error_free (error); 742 } 743 744 if (safe_to_save) { 745 uri = nautilus_file_get_uri (file); 746 title = nautilus_file_get_display_name (file); 747 g_bookmark_file_set_title (bookmarks, uri, title); 748 g_bookmark_file_set_visited (bookmarks, uri, -1); 749 g_bookmark_file_add_application (bookmarks, uri, NULL, NULL); 750 g_free (uri); 751 g_free (title); 752 753 g_bookmark_file_to_file (bookmarks, filename, NULL); 754 } 755 756 g_free (filename); 757 g_bookmark_file_free (bookmarks); 758 759 retval = TRUE; 760 } else { 761 retval = FALSE; 762 } 763 764 return retval; 765 } 766 767 static void 768 on_connect_server_response (GtkDialog *dialog, 769 int response, 770 GtkApplication *application) 771 { 772 if (response == GTK_RESPONSE_OK) { 773 GFile *location; 774 NautilusWindow *window = NAUTILUS_WINDOW (get_focus_window (application)); 775 776 location = nautilus_connect_server_dialog_get_location (NAUTILUS_CONNECT_SERVER_DIALOG (dialog)); 777 if (location != NULL) { 778 nautilus_window_slot_open_location_full (nautilus_window_get_active_slot (window), 779 location, 780 NAUTILUS_WINDOW_OPEN_FLAG_USE_DEFAULT_LOCATION, 781 NULL, go_to_server_cb, application); 782 } 783 } 784 785 gtk_widget_destroy (GTK_WIDGET (dialog)); 786 } 787 788 static void 789 nautilus_application_connect_server (NautilusApplication *application, 790 NautilusWindow *window) 791 { 792 GtkWidget *dialog; 793 794 dialog = application->priv->connect_server_window; 795 796 if (dialog == NULL) { 797 dialog = nautilus_connect_server_dialog_new (window); 798 g_signal_connect (dialog, "response", G_CALLBACK (on_connect_server_response), application); 799 application->priv->connect_server_window = GTK_WIDGET (dialog); 800 801 g_object_add_weak_pointer (G_OBJECT (dialog), 802 (gpointer *) &application->priv->connect_server_window); 803 } 804 805 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (window)); 806 gtk_window_set_screen (GTK_WINDOW (dialog), gtk_window_get_screen (GTK_WINDOW (window))); 807 gtk_window_present (GTK_WINDOW (dialog)); 808 } 809 810 static void 811 action_connect_to_server (GSimpleAction *action, 812 GVariant *parameter, 813 gpointer user_data) 814 { 815 GtkApplication *application = user_data; 816 817 nautilus_application_connect_server (NAUTILUS_APPLICATION (application), NAUTILUS_WINDOW (get_focus_window (application))); 818 } 819 820 static void 821 action_enter_location (GSimpleAction *action, 822 GVariant *parameter, 823 gpointer user_data) 824 { 825 GtkApplication *application = user_data; 826 NautilusWindow *window; 827 GtkWindow *cur_window; 828 829 cur_window = get_focus_window (application); 830 window = NAUTILUS_WINDOW (cur_window); 831 nautilus_window_ensure_location_entry (window); 832 } 833 834 static void 835 action_bookmarks (GSimpleAction *action, 836 GVariant *parameter, 837 gpointer user_data) 838 { 839 GtkApplication *application = user_data; 840 841 nautilus_application_edit_bookmarks (NAUTILUS_APPLICATION (application), NAUTILUS_WINDOW (get_focus_window (application))); 842 } 843 844 static void 845 action_preferences (GSimpleAction *action, 846 GVariant *parameter, 847 gpointer user_data) 848 { 849 GtkApplication *application = user_data; 850 nautilus_file_management_properties_dialog_show (get_focus_window (application)); 851 } 852 853 static void 854 action_about (GSimpleAction *action, 855 GVariant *parameter, 856 gpointer user_data) 857 { 858 GtkApplication *application = user_data; 859 860 nautilus_window_show_about_dialog (NAUTILUS_WINDOW (get_focus_window (application))); 861 } 862 863 static void 864 action_help (GSimpleAction *action, 865 GVariant *parameter, 866 gpointer user_data) 867 { 868 GtkWindow *window; 869 GtkWidget *dialog; 870 GtkApplication *application = user_data; 871 GError *error = NULL; 872 873 window = get_focus_window (application); 874 gtk_show_uri (window ? 875 gtk_window_get_screen (GTK_WINDOW (window)) : 876 gdk_screen_get_default (), 877 "help:gnome-help/files", 878 gtk_get_current_event_time (), &error); 879 880 if (error) { 881 dialog = gtk_message_dialog_new (window ? GTK_WINDOW (window) : NULL, 882 GTK_DIALOG_MODAL, 883 GTK_MESSAGE_ERROR, 884 GTK_BUTTONS_OK, 885 _("There was an error displaying help: \n%s"), 886 error->message); 887 g_signal_connect (G_OBJECT (dialog), "response", 888 G_CALLBACK (gtk_widget_destroy), 889 NULL); 890 891 gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); 892 gtk_widget_show (dialog); 893 g_error_free (error); 894 } 895 } 896 897 static void 898 action_kill (GSimpleAction *action, 899 GVariant *parameter, 900 gpointer user_data) 901 { 902 GtkApplication *application = user_data; 903 GList *windows; 904 905 /* this will also destroy the desktop windows */ 906 windows = gtk_application_get_windows (application); 907 g_list_foreach (windows, (GFunc) gtk_widget_destroy, NULL); 908 } 909 910 static void 911 action_quit (GSimpleAction *action, 912 GVariant *parameter, 913 gpointer user_data) 914 { 915 GtkApplication *application = user_data; 916 GList *windows; 917 918 /* nautilus_window_close() doesn't do anything for desktop windows */ 919 windows = gtk_application_get_windows (application); 920 g_list_foreach (windows, (GFunc) nautilus_window_close, NULL); 921 } 922 923 static GActionEntry app_entries[] = { 924 { "new-window", action_new_window, NULL, NULL, NULL }, 925 { "connect-to-server", action_connect_to_server, NULL, NULL, NULL }, 926 { "enter-location", action_enter_location, NULL, NULL, NULL }, 927 { "bookmarks", action_bookmarks, NULL, NULL, NULL }, 928 { "preferences", action_preferences, NULL, NULL, NULL }, 929 { "about", action_about, NULL, NULL, NULL }, 930 { "help", action_help, NULL, NULL, NULL }, 931 { "quit", action_quit, NULL, NULL, NULL }, 932 { "kill", action_kill, NULL, NULL, NULL }, 933 }; 934 935 static void 936 nautilus_application_init_actions (NautilusApplication *self) 937 { 938 GtkBuilder *builder; 939 GError *error = NULL; 940 const gchar *debug_no_app_menu; 941 942 g_action_map_add_action_entries (G_ACTION_MAP (self), 943 app_entries, G_N_ELEMENTS (app_entries), 944 self); 945 gtk_application_add_accelerator (GTK_APPLICATION (self), "F10", "win.gear-menu", NULL); 946 947 builder = gtk_builder_new (); 948 gtk_builder_add_from_resource (builder, "/org/gnome/nautilus/nautilus-app-menu.ui", &error); 949 950 if (error == NULL) { 951 gtk_application_set_app_menu (GTK_APPLICATION (self), 952 G_MENU_MODEL (gtk_builder_get_object (builder, "app-menu"))); 953 } else { 954 g_critical ("Unable to add the application menu: %s\n", error->message); 955 g_error_free (error); 956 } 957 958 g_object_unref (builder); 959 960 debug_no_app_menu = g_getenv ("NAUTILUS_DEBUG_NO_APP_MENU"); 961 if (debug_no_app_menu) { 962 DEBUG ("Disabling app menu GtkSetting as requested..."); 963 g_object_set (gtk_settings_get_default (), 964 "gtk-shell-shows-app-menu", FALSE, 965 NULL); 966 } 967 } 968 969 static void 970 nautilus_application_init (NautilusApplication *application) 971 { 972 application->priv = 973 G_TYPE_INSTANCE_GET_PRIVATE (application, NAUTILUS_TYPE_APPLICATION, 974 NautilusApplicationPriv); 975 } 976 977 static void 978 nautilus_application_finalize (GObject *object) 979 { 980 NautilusApplication *application; 981 982 application = NAUTILUS_APPLICATION (object); 983 984 g_clear_object (&application->priv->volume_monitor); 985 g_clear_object (&application->priv->progress_handler); 986 g_clear_object (&application->priv->bookmark_list); 987 988 g_free (application->priv->geometry); 989 990 nautilus_dbus_manager_stop (); 991 nautilus_freedesktop_dbus_stop (); 992 notify_uninit (); 993 994 G_OBJECT_CLASS (nautilus_application_parent_class)->finalize (object); 995 } 996 997 static gboolean 998 do_cmdline_sanity_checks (NautilusApplication *self, 999 gboolean perform_self_check, 1000 gboolean version, 1001 gboolean kill_shell, 1002 gchar **remaining) 1003 { 1004 gboolean retval = FALSE; 1005 1006 if (perform_self_check && (remaining != NULL || kill_shell)) { 1007 g_printerr ("%s\n", 1008 _("--check cannot be used with other options.")); 1009 goto out; 1010 } 1011 1012 if (kill_shell && remaining != NULL) { 1013 g_printerr ("%s\n", 1014 _("--quit cannot be used with URIs.")); 1015 goto out; 1016 } 1017 1018 if (self->priv->geometry != NULL && 1019 remaining != NULL && remaining[0] != NULL && remaining[1] != NULL) { 1020 g_printerr ("%s\n", 1021 _("--geometry cannot be used with more than one URI.")); 1022 goto out; 1023 } 1024 1025 retval = TRUE; 1026 1027 out: 1028 return retval; 1029 } 1030 1031 static void 1032 do_perform_self_checks (gint *exit_status) 1033 { 1034 #ifndef NAUTILUS_OMIT_SELF_CHECK 1035 gtk_init (NULL, NULL); 1036 1037 nautilus_profile_start (NULL); 1038 /* Run the checks (each twice) for nautilus and libnautilus-private. */ 1039 1040 nautilus_run_self_checks (); 1041 nautilus_run_lib_self_checks (); 1042 eel_exit_if_self_checks_failed (); 1043 1044 nautilus_run_self_checks (); 1045 nautilus_run_lib_self_checks (); 1046 eel_exit_if_self_checks_failed (); 1047 nautilus_profile_end (NULL); 1048 #endif 1049 1050 *exit_status = EXIT_SUCCESS; 1051 } 1052 1053 static gboolean 1054 nautilus_application_local_command_line (GApplication *application, 1055 gchar ***arguments, 1056 gint *exit_status) 1057 { 1058 gboolean perform_self_check = FALSE; 1059 gboolean version = FALSE; 1060 gboolean browser = FALSE; 1061 gboolean kill_shell = FALSE; 1062 gboolean no_default_window = FALSE; 1063 gchar **remaining = NULL; 1064 NautilusApplication *self = NAUTILUS_APPLICATION (application); 1065 1066 const GOptionEntry options[] = { 1067 #ifndef NAUTILUS_OMIT_SELF_CHECK 1068 { "check", 'c', 0, G_OPTION_ARG_NONE, &perform_self_check, 1069 N_("Perform a quick set of self-check tests."), NULL }, 1070 #endif 1071 /* dummy, only for compatibility reasons */ 1072 { "browser", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &browser, 1073 NULL, NULL }, 1074 { "version", '\0', 0, G_OPTION_ARG_NONE, &version, 1075 N_("Show the version of the program."), NULL }, 1076 { "geometry", 'g', 0, G_OPTION_ARG_STRING, &self->priv->geometry, 1077 N_("Create the initial window with the given geometry."), N_("GEOMETRY") }, 1078 { "no-default-window", 'n', 0, G_OPTION_ARG_NONE, &no_default_window, 1079 N_("Only create windows for explicitly specified URIs."), NULL }, 1080 { "no-desktop", '\0', 0, G_OPTION_ARG_NONE, &self->priv->no_desktop, 1081 N_("Do not manage the desktop (ignore the preference set in the preferences dialog)."), NULL }, 1082 { "quit", 'q', 0, G_OPTION_ARG_NONE, &kill_shell, 1083 N_("Quit Nautilus."), NULL }, 1084 { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &remaining, NULL, N_("[URI...]") }, 1085 1086 { NULL } 1087 }; 1088 GOptionContext *context; 1089 GError *error = NULL; 1090 gint argc = 0; 1091 gchar **argv = NULL; 1092 1093 *exit_status = EXIT_SUCCESS; 1094 1095 nautilus_profile_start (NULL); 1096 1097 context = g_option_context_new (_("\n\nBrowse the file system with the file manager")); 1098 g_option_context_add_main_entries (context, options, NULL); 1099 g_option_context_add_group (context, gtk_get_option_group (FALSE)); 1100 1101 argv = *arguments; 1102 argc = g_strv_length (argv); 1103 1104 if (!g_option_context_parse (context, &argc, &argv, &error)) { 1105 /* Translators: this is a fatal error quit message printed on the 1106 * command line */ 1107 g_printerr ("%s: %s\n", _("Could not parse arguments"), error->message); 1108 g_error_free (error); 1109 1110 *exit_status = EXIT_FAILURE; 1111 goto out; 1112 } 1113 1114 if (version) { 1115 g_print ("GNOME nautilus " PACKAGE_VERSION "\n"); 1116 goto out; 1117 } 1118 1119 if (!do_cmdline_sanity_checks (self, perform_self_check, 1120 version, kill_shell, remaining)) { 1121 *exit_status = EXIT_FAILURE; 1122 goto out; 1123 } 1124 1125 if (perform_self_check) { 1126 do_perform_self_checks (exit_status); 1127 goto out; 1128 } 1129 1130 DEBUG ("Parsing local command line, no_default_window %d, quit %d, " 1131 "self checks %d, no_desktop %d", 1132 no_default_window, kill_shell, perform_self_check, self->priv->no_desktop); 1133 1134 g_application_register (application, NULL, &error); 1135 1136 if (error != NULL) { 1137 /* Translators: this is a fatal error quit message printed on the 1138 * command line */ 1139 g_printerr ("%s: %s\n", _("Could not register the application"), error->message); 1140 g_error_free (error); 1141 1142 *exit_status = EXIT_FAILURE; 1143 goto out; 1144 } 1145 1146 if (kill_shell) { 1147 DEBUG ("Killing application, as requested"); 1148 g_action_group_activate_action (G_ACTION_GROUP (application), 1149 "kill", NULL); 1150 goto out; 1151 } 1152 1153 GFile **files; 1154 gint idx, len; 1155 1156 len = 0; 1157 files = NULL; 1158 1159 /* Convert args to GFiles */ 1160 if (remaining != NULL) { 1161 GFile *file; 1162 GPtrArray *file_array; 1163 1164 file_array = g_ptr_array_new (); 1165 1166 for (idx = 0; remaining[idx] != NULL; idx++) { 1167 file = g_file_new_for_commandline_arg (remaining[idx]); 1168 if (file != NULL) { 1169 g_ptr_array_add (file_array, file); 1170 } 1171 } 1172 1173 len = file_array->len; 1174 files = (GFile **) g_ptr_array_free (file_array, FALSE); 1175 g_strfreev (remaining); 1176 } 1177 1178 if (files == NULL && !no_default_window) { 1179 files = g_malloc0 (2 * sizeof (GFile *)); 1180 len = 1; 1181 1182 files[0] = g_file_new_for_path (g_get_home_dir ()); 1183 files[1] = NULL; 1184 } 1185 1186 /* Invoke "Open" to create new windows */ 1187 if (len > 0) { 1188 g_application_open (application, files, len, ""); 1189 } 1190 1191 for (idx = 0; idx < len; idx++) { 1192 g_object_unref (files[idx]);
Array access (from variable 'files') results in a null pointer dereference
(emitted by clang-analyzer)

TODO: a detailed trace is available in the data model (not yet rendered in this report)

1193 } 1194 g_free (files); 1195 1196 out: 1197 g_option_context_free (context); 1198 nautilus_profile_end (NULL); 1199 1200 return TRUE; 1201 } 1202 1203 static void 1204 init_icons_and_styles (void) 1205 { 1206 /* initialize search path for custom icons */ 1207 gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (), 1208 NAUTILUS_DATADIR G_DIR_SEPARATOR_S "icons"); 1209 } 1210 1211 static void 1212 nautilus_application_open_desktop (NautilusApplication *application) 1213 { 1214 /* Initialize the desktop link monitor singleton */ 1215 nautilus_desktop_link_monitor_get (); 1216 1217 if (nautilus_application_desktop_windows == NULL) { 1218 nautilus_application_create_desktop_windows (application); 1219 } 1220 } 1221 1222 static void 1223 nautilus_application_close_desktop (void) 1224 { 1225 if (nautilus_application_desktop_windows != NULL) { 1226 g_list_foreach (nautilus_application_desktop_windows, 1227 (GFunc) gtk_widget_destroy, NULL); 1228 g_list_free (nautilus_application_desktop_windows); 1229 nautilus_application_desktop_windows = NULL; 1230 } 1231 nautilus_desktop_link_monitor_shutdown (); 1232 } 1233 1234 /* callback for showing or hiding the desktop based on the user's preference */ 1235 static void 1236 desktop_changed_callback (gpointer user_data) 1237 { 1238 NautilusApplication *application; 1239 1240 application = NAUTILUS_APPLICATION (user_data); 1241 if (g_settings_get_boolean (gnome_background_preferences, NAUTILUS_PREFERENCES_SHOW_DESKTOP)) { 1242 nautilus_application_open_desktop (application); 1243 } else { 1244 nautilus_application_close_desktop (); 1245 } 1246 } 1247 1248 static void 1249 init_desktop (NautilusApplication *self) 1250 { 1251 if (!self->priv->no_desktop && 1252 !g_settings_get_boolean (gnome_background_preferences, 1253 NAUTILUS_PREFERENCES_SHOW_DESKTOP)) { 1254 self->priv->no_desktop = TRUE; 1255 } 1256 1257 if (!self->priv->no_desktop) { 1258 nautilus_application_open_desktop (self); 1259 } 1260 1261 /* Monitor the preference to show or hide the desktop */ 1262 g_signal_connect_swapped (gnome_background_preferences, "changed::" NAUTILUS_PREFERENCES_SHOW_DESKTOP, 1263 G_CALLBACK (desktop_changed_callback), 1264 self); 1265 } 1266 1267 static gboolean 1268 nautilus_application_save_accel_map (gpointer data) 1269 { 1270 if (save_of_accel_map_requested) { 1271 char *accel_map_filename; 1272 accel_map_filename = nautilus_get_accel_map_file (); 1273 if (accel_map_filename) { 1274 gtk_accel_map_save (accel_map_filename); 1275 g_free (accel_map_filename); 1276 } 1277 save_of_accel_map_requested = FALSE; 1278 } 1279 1280 return FALSE; 1281 } 1282 1283 static void 1284 queue_accel_map_save_callback (GtkAccelMap *object, gchar *accel_path, 1285 guint accel_key, GdkModifierType accel_mods, 1286 gpointer user_data) 1287 { 1288 if (!save_of_accel_map_requested) { 1289 save_of_accel_map_requested = TRUE; 1290 g_timeout_add_seconds (NAUTILUS_ACCEL_MAP_SAVE_DELAY, 1291 nautilus_application_save_accel_map, NULL); 1292 } 1293 } 1294 1295 static void 1296 update_accel_due_to_scripts_migration (gpointer data, const gchar *accel_path, guint accel_key, 1297 GdkModifierType accel_mods, gboolean changed) 1298 { 1299 char *old_scripts_location_esc = data; 1300 char *old_scripts_pt; 1301 1302 old_scripts_pt = strstr (accel_path, old_scripts_location_esc); 1303 1304 if (old_scripts_pt != NULL) { 1305 /* There's a mention of the deprecated scripts directory in the accel. Remove it, and 1306 * add a migrated one. */ 1307 char *tmp; 1308 char *tmp2; 1309 GString *new_accel_path; 1310 1311 /* base part of accel */ 1312 tmp = g_strndup (accel_path, old_scripts_pt - accel_path); 1313 new_accel_path = g_string_new (tmp); 1314 g_free (tmp); 1315 1316 /* new script directory, escaped */ 1317 tmp = nautilus_get_scripts_directory_path (); 1318 tmp2 = nautilus_escape_action_name (tmp, ""); 1319 g_free (tmp); 1320 g_string_append (new_accel_path, tmp2); 1321 g_free (tmp2); 1322 1323 /* script path relative to scripts directory */ 1324 g_string_append (new_accel_path, old_scripts_pt + strlen (old_scripts_location_esc)); 1325 1326 /* exchange entry */ 1327 gtk_accel_map_change_entry (accel_path, 0, 0, FALSE); 1328 gtk_accel_map_change_entry (new_accel_path->str, accel_key, accel_mods, TRUE); 1329 1330 g_string_free (new_accel_path, TRUE); 1331 } 1332 } 1333 1334 static void 1335 init_gtk_accels (void) 1336 { 1337 char *accel_map_filename; 1338 gboolean performed_migration = FALSE; 1339 char *old_scripts_directory_path = NULL; 1340 1341 accel_map_filename = nautilus_get_accel_map_file (); 1342 1343 /* If the accel map file doesn't exist, try to migrate from 1344 * former locations. */ 1345 if (!g_file_test (accel_map_filename, G_FILE_TEST_IS_REGULAR)) { 1346 char *old_accel_map_filename; 1347 const gchar *override; 1348 1349 override = g_getenv ("GNOME22_USER_DIR"); 1350 if (override) { 1351 old_accel_map_filename = g_build_filename (override, 1352 "accels", "nautilus", NULL); 1353 old_scripts_directory_path = g_build_filename (override, 1354 "nautilus-scripts", 1355 NULL); 1356 } else { 1357 old_accel_map_filename = g_build_filename (g_get_home_dir (), 1358 ".gnome2", "accels", "nautilus", NULL); 1359 old_scripts_directory_path = g_build_filename (g_get_home_dir (), 1360 ".gnome2", 1361 "nautilus-scripts", 1362 NULL); 1363 } 1364 1365 if (g_file_test (old_accel_map_filename, G_FILE_TEST_IS_REGULAR)) { 1366 char *parent_dir; 1367 1368 parent_dir = g_path_get_dirname (accel_map_filename); 1369 if (g_mkdir_with_parents (parent_dir, 0700) == 0) { 1370 GFile *accel_map_file; 1371 GFile *old_accel_map_file; 1372 1373 accel_map_file = g_file_new_for_path (accel_map_filename); 1374 old_accel_map_file = g_file_new_for_path (old_accel_map_filename); 1375 1376 /* If the move fails, it's safer to not read any accel map 1377 * on startup instead of reading the old one and possibly 1378 * being stuck with it. */ 1379 performed_migration = g_file_move (old_accel_map_file, accel_map_file, 0, NULL, NULL, NULL, NULL); 1380 1381 g_object_unref (accel_map_file); 1382 g_object_unref (old_accel_map_file); 1383 } 1384 g_free (parent_dir); 1385 } 1386 1387 g_free (old_accel_map_filename); 1388 } 1389 1390 /* load accelerator map, and register save callback */ 1391 gtk_accel_map_load (accel_map_filename); 1392 g_free (accel_map_filename); 1393 1394 if (performed_migration) { 1395 /* Migrate accels pointing to scripts */ 1396 char *old_scripts_location_esc; 1397 1398 old_scripts_location_esc = nautilus_escape_action_name (old_scripts_directory_path, ""); 1399 gtk_accel_map_foreach (old_scripts_location_esc, update_accel_due_to_scripts_migration); 1400 g_free (old_scripts_location_esc); 1401 /* save map immediately */ 1402 save_of_accel_map_requested = TRUE; 1403 nautilus_application_save_accel_map (NULL); 1404 } 1405 1406 g_signal_connect (gtk_accel_map_get (), "changed", 1407 G_CALLBACK (queue_accel_map_save_callback), NULL); 1408 1409 g_free (old_scripts_directory_path); 1410 } 1411 1412 static void 1413 nautilus_application_startup (GApplication *app) 1414 { 1415 NautilusApplication *self = NAUTILUS_APPLICATION (app); 1416 1417 nautilus_profile_start (NULL); 1418 1419 /* chain up to the GTK+ implementation early, so gtk_init() 1420 * is called for us. 1421 */ 1422 G_APPLICATION_CLASS (nautilus_application_parent_class)->startup (app); 1423 1424 gtk_window_set_default_icon_name ("system-file-manager"); 1425 1426 /* initialize the previewer singleton */ 1427 nautilus_previewer_get_singleton (); 1428 1429 /* create DBus manager */ 1430 nautilus_dbus_manager_start (app); 1431 nautilus_freedesktop_dbus_start (self); 1432 1433 /* initialize preferences and create the global GSettings objects */ 1434 nautilus_global_preferences_init (); 1435 1436 /* register views */ 1437 nautilus_profile_start ("Register views"); 1438 nautilus_canvas_view_register (); 1439 nautilus_desktop_canvas_view_register (); 1440 nautilus_list_view_register (); 1441 #if ENABLE_EMPTY_VIEW 1442 nautilus_empty_view_register (); 1443 #endif 1444 nautilus_profile_end ("Register views"); 1445 1446 /* register property pages */ 1447 nautilus_image_properties_page_register (); 1448 1449 /* initialize theming */ 1450 init_icons_and_styles (); 1451 init_gtk_accels (); 1452 1453 /* initialize nautilus modules */ 1454 nautilus_profile_start ("Modules"); 1455 nautilus_module_setup (); 1456 nautilus_profile_end ("Modules"); 1457 1458 /* attach menu-provider module callback */ 1459 menu_provider_init_callback (); 1460 1461 /* Initialize the UI handler singleton for file operations */ 1462 notify_init (GETTEXT_PACKAGE); 1463 self->priv->progress_handler = nautilus_progress_ui_handler_new (); 1464 1465 self->priv->volume_monitor = g_volume_monitor_get (); 1466 g_signal_connect_object (self->priv->volume_monitor, "mount_added", 1467 G_CALLBACK (mount_added_callback), self, 0); 1468 1469 self->priv->bookmark_list = nautilus_bookmark_list_new (); 1470 1471 /* Check the user's .nautilus directories and post warnings 1472 * if there are problems. 1473 */ 1474 check_required_directories (self); 1475 init_desktop (self); 1476 1477 do_upgrades_once (self); 1478 1479 nautilus_application_init_actions (self); 1480 1481 nautilus_profile_end (NULL); 1482 } 1483 1484 static void 1485 nautilus_application_quit_mainloop (GApplication *app) 1486 { 1487 DEBUG ("Quitting mainloop"); 1488 1489 nautilus_icon_info_clear_caches (); 1490 nautilus_application_save_accel_map (NULL); 1491 1492 nautilus_application_notify_unmount_done (NAUTILUS_APPLICATION (app), NULL); 1493 1494 G_APPLICATION_CLASS (nautilus_application_parent_class)->quit_mainloop (app); 1495 } 1496 1497 static void 1498 nautilus_application_window_removed (GtkApplication *app, 1499 GtkWindow *window) 1500 { 1501 NautilusPreviewer *previewer; 1502 1503 /* chain to parent */ 1504 GTK_APPLICATION_CLASS (nautilus_application_parent_class)->window_removed (app, window); 1505 1506 /* if this was the last window, close the previewer */ 1507 if (g_list_length (gtk_application_get_windows (app)) == 0) { 1508 previewer = nautilus_previewer_get_singleton (); 1509 nautilus_previewer_call_close (previewer); 1510 } 1511 } 1512 1513 static void 1514 nautilus_application_class_init (NautilusApplicationClass *class) 1515 { 1516 GObjectClass *object_class; 1517 GApplicationClass *application_class; 1518 GtkApplicationClass *gtkapp_class; 1519 1520 object_class = G_OBJECT_CLASS (class); 1521 object_class->finalize = nautilus_application_finalize; 1522 1523 application_class = G_APPLICATION_CLASS (class); 1524 application_class->startup = nautilus_application_startup; 1525 application_class->quit_mainloop = nautilus_application_quit_mainloop; 1526 application_class->open = nautilus_application_open; 1527 application_class->local_command_line = nautilus_application_local_command_line; 1528 1529 gtkapp_class = GTK_APPLICATION_CLASS (class); 1530 gtkapp_class->window_removed = nautilus_application_window_removed; 1531 1532 g_type_class_add_private (class, sizeof (NautilusApplicationPriv)); 1533 }