nautilus-3.6.3/src/nautilus-desktop-window.c

No issues found

  1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
  2 
  3 /*
  4  * Nautilus
  5  *
  6  * Copyright (C) 2000 Eazel, Inc.
  7  *
  8  * Nautilus is free software; you can redistribute it and/or
  9  * modify it under the terms of the GNU General Public License as
 10  * published by the Free Software Foundation; either version 2 of the
 11  * License, or (at your option) any later version.
 12  *
 13  * Nautilus is distributed in the hope that it will be useful,
 14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 16  * General Public License for more details.
 17  *
 18  * You should have received a copy of the GNU General Public License
 19  * along with this program; if not, write to the Free Software
 20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 21  *
 22  * Authors: Darin Adler <darin@bentspoon.com>
 23  */
 24 
 25 #include <config.h>
 26 #include "nautilus-desktop-window.h"
 27 #include "nautilus-window-private.h"
 28 #include "nautilus-actions.h"
 29 
 30 #include <X11/Xatom.h>
 31 #include <gdk/gdkx.h>
 32 #include <gtk/gtk.h>
 33 #include <gio/gio.h>
 34 #include <glib/gi18n.h>
 35 
 36 #include <eel/eel-vfs-extensions.h>
 37 #include <libnautilus-private/nautilus-file-utilities.h>
 38 #include <libnautilus-private/nautilus-icon-names.h>
 39 #include <libnautilus-private/nautilus-global-preferences.h>
 40 
 41 struct NautilusDesktopWindowDetails {
 42 	gulong size_changed_id;
 43 
 44 	gboolean loaded;
 45 };
 46 
 47 G_DEFINE_TYPE (NautilusDesktopWindow, nautilus_desktop_window, 
 48 	       NAUTILUS_TYPE_WINDOW);
 49 
 50 static void
 51 nautilus_desktop_window_update_directory (NautilusDesktopWindow *window)
 52 {
 53 	GFile *location;
 54 
 55 	g_assert (NAUTILUS_IS_DESKTOP_WINDOW (window));
 56 
 57 	window->details->loaded = FALSE;
 58 	location = g_file_new_for_uri (EEL_DESKTOP_URI);
 59 	nautilus_window_go_to (NAUTILUS_WINDOW (window), location);
 60 	window->details->loaded = TRUE;
 61 
 62 	g_object_unref (location);
 63 }
 64 
 65 static void
 66 nautilus_desktop_window_constructed (GObject *obj)
 67 {
 68 	GtkActionGroup *action_group;
 69 	GtkAction *action;
 70 	AtkObject *accessible;
 71 	NautilusDesktopWindow *window = NAUTILUS_DESKTOP_WINDOW (obj);
 72 	NautilusWindow *nwindow = NAUTILUS_WINDOW (obj);
 73 
 74 	G_OBJECT_CLASS (nautilus_desktop_window_parent_class)->constructed (obj);
 75 
 76 	action_group = nautilus_window_get_main_action_group (nwindow);
 77 
 78 	/* Don't allow close action on desktop */
 79 	action = gtk_action_group_get_action (action_group,
 80 					      NAUTILUS_ACTION_CLOSE);
 81 	gtk_action_set_sensitive (action, FALSE);
 82 
 83 	/* Don't allow new tab on desktop */
 84 	action = gtk_action_group_get_action (action_group,
 85 					      NAUTILUS_ACTION_NEW_TAB);
 86 	gtk_action_set_sensitive (action, FALSE);
 87 
 88 	/* Set the accessible name so that it doesn't inherit the cryptic desktop URI. */
 89 	accessible = gtk_widget_get_accessible (GTK_WIDGET (window));
 90 
 91 	if (accessible) {
 92 		atk_object_set_name (accessible, _("Desktop"));
 93 	}
 94 }
 95 
 96 static void
 97 nautilus_desktop_window_init (NautilusDesktopWindow *window)
 98 {
 99 	window->details = G_TYPE_INSTANCE_GET_PRIVATE (window, NAUTILUS_TYPE_DESKTOP_WINDOW,
100 						       NautilusDesktopWindowDetails);
101 
102 	gtk_window_move (GTK_WINDOW (window), 0, 0);
103 
104 	/* shouldn't really be needed given our semantic type
105 	 * of _NET_WM_TYPE_DESKTOP, but why not
106 	 */
107 	gtk_window_set_resizable (GTK_WINDOW (window),
108 				  FALSE);
109 
110 	g_object_set_data (G_OBJECT (window), "is_desktop_window", 
111 			   GINT_TO_POINTER (1));
112 }
113 
114 static void
115 nautilus_desktop_window_screen_size_changed (GdkScreen             *screen,
116 					     NautilusDesktopWindow *window)
117 {
118 	int width_request, height_request;
119 
120 	width_request = gdk_screen_get_width (screen);
121 	height_request = gdk_screen_get_height (screen);
122 	
123 	g_object_set (window,
124 		      "width_request", width_request,
125 		      "height_request", height_request,
126 		      NULL);
127 }
128 
129 NautilusDesktopWindow *
130 nautilus_desktop_window_new (GtkApplication *application,
131 			     GdkScreen      *screen)
132 {
133 	NautilusDesktopWindow *window;
134 	int width_request, height_request;
135 
136 	width_request = gdk_screen_get_width (screen);
137 	height_request = gdk_screen_get_height (screen);
138 
139 	window = g_object_new (NAUTILUS_TYPE_DESKTOP_WINDOW,
140 			       "application", application,
141 			       "disable-chrome", TRUE,
142 			       "width_request", width_request,
143 			       "height_request", height_request,
144 			       "screen", screen,
145 			       NULL);
146 
147 	/* Special sawmill setting*/
148 	gtk_window_set_wmclass (GTK_WINDOW (window), "desktop_window", "Nautilus");
149 
150 	/* Point window at the desktop folder.
151 	 * Note that nautilus_desktop_window_init is too early to do this.
152 	 */
153 	nautilus_desktop_window_update_directory (window);
154 
155 	return window;
156 }
157 
158 static gboolean
159 nautilus_desktop_window_delete_event (GtkWidget *widget,
160 				      GdkEventAny *event)
161 {
162 	/* Returning true tells GTK+ not to delete the window. */
163 	return TRUE;
164 }
165 
166 static void
167 map (GtkWidget *widget)
168 {
169 	/* Chain up to realize our children */
170 	GTK_WIDGET_CLASS (nautilus_desktop_window_parent_class)->map (widget);
171 	gdk_window_lower (gtk_widget_get_window (widget));
172 }
173 
174 static void
175 unrealize (GtkWidget *widget)
176 {
177 	NautilusDesktopWindow *window;
178 	NautilusDesktopWindowDetails *details;
179 	GdkWindow *root_window;
180 
181 	window = NAUTILUS_DESKTOP_WINDOW (widget);
182 	details = window->details;
183 
184 	root_window = gdk_screen_get_root_window (
185 				gtk_window_get_screen (GTK_WINDOW (window)));
186 
187 	gdk_property_delete (root_window,
188 			     gdk_atom_intern ("NAUTILUS_DESKTOP_WINDOW_ID", TRUE));
189 
190 	if (details->size_changed_id != 0) {
191 		g_signal_handler_disconnect (gtk_window_get_screen (GTK_WINDOW (window)),
192 					     details->size_changed_id);
193 		details->size_changed_id = 0;
194 	}
195 
196 	GTK_WIDGET_CLASS (nautilus_desktop_window_parent_class)->unrealize (widget);
197 }
198 
199 static void
200 set_wmspec_desktop_hint (GdkWindow *window)
201 {
202 	GdkAtom atom;
203 
204 	atom = gdk_atom_intern ("_NET_WM_WINDOW_TYPE_DESKTOP", FALSE);
205         
206 	gdk_property_change (window,
207 			     gdk_atom_intern ("_NET_WM_WINDOW_TYPE", FALSE),
208 			     gdk_x11_xatom_to_atom (XA_ATOM), 32,
209 			     GDK_PROP_MODE_REPLACE, (guchar *) &atom, 1);
210 }
211 
212 static void
213 set_desktop_window_id (NautilusDesktopWindow *window,
214 		       GdkWindow             *gdkwindow)
215 {
216 	/* Tuck the desktop windows xid in the root to indicate we own the desktop.
217 	 */
218 	Window window_xid;
219 	GdkWindow *root_window;
220 
221 	root_window = gdk_screen_get_root_window (
222 				gtk_window_get_screen (GTK_WINDOW (window)));
223 
224 	window_xid = GDK_WINDOW_XID (gdkwindow);
225 
226 	gdk_property_change (root_window,
227 			     gdk_atom_intern ("NAUTILUS_DESKTOP_WINDOW_ID", FALSE),
228 			     gdk_x11_xatom_to_atom (XA_WINDOW), 32,
229 			     GDK_PROP_MODE_REPLACE, (guchar *) &window_xid, 1);
230 }
231 
232 static void
233 realize (GtkWidget *widget)
234 {
235 	NautilusDesktopWindow *window;
236 	NautilusDesktopWindowDetails *details;
237 
238 	window = NAUTILUS_DESKTOP_WINDOW (widget);
239 	details = window->details;
240 
241 	/* Make sure we get keyboard events */
242 	gtk_widget_set_events (widget, gtk_widget_get_events (widget) 
243 			      | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
244 			      
245 	/* Do the work of realizing. */
246 	GTK_WIDGET_CLASS (nautilus_desktop_window_parent_class)->realize (widget);
247 
248 	/* This is the new way to set up the desktop window */
249 	set_wmspec_desktop_hint (gtk_widget_get_window (widget));
250 
251 	set_desktop_window_id (window, gtk_widget_get_window (widget));
252 
253 	details->size_changed_id =
254 		g_signal_connect (gtk_window_get_screen (GTK_WINDOW (window)), "size_changed",
255 				  G_CALLBACK (nautilus_desktop_window_screen_size_changed), window);
256 }
257 
258 static NautilusIconInfo *
259 real_get_icon (NautilusWindow *window,
260 	       NautilusWindowSlot *slot)
261 {
262 	return nautilus_icon_info_lookup_from_name (NAUTILUS_DESKTOP_ICON_DESKTOP, 48);
263 }
264 
265 static void
266 real_sync_title (NautilusWindow *window,
267 		 NautilusWindowSlot *slot)
268 {
269 	/* hardcode "Desktop" */
270 	gtk_window_set_title (GTK_WINDOW (window), _("Desktop"));
271 }
272 
273 static void
274 real_window_close (NautilusWindow *window)
275 {
276 	/* stub, does nothing */
277 	return;
278 }
279 
280 static void
281 real_sync_view_as_menus (NautilusWindow *window)
282 {
283 	/* stub, does nothing */
284 	return;
285 }
286 
287 static void
288 nautilus_desktop_window_class_init (NautilusDesktopWindowClass *klass)
289 {
290 	GtkWidgetClass *wclass = GTK_WIDGET_CLASS (klass);
291 	NautilusWindowClass *nclass = NAUTILUS_WINDOW_CLASS (klass);
292 	GObjectClass *oclass = G_OBJECT_CLASS (klass);
293 
294 	oclass->constructed = nautilus_desktop_window_constructed;
295 
296 	wclass->realize = realize;
297 	wclass->unrealize = unrealize;
298 	wclass->map = map;
299 	wclass->delete_event = nautilus_desktop_window_delete_event;
300 
301 	nclass->sync_title = real_sync_title;
302 	nclass->sync_view_as_menus = real_sync_view_as_menus;
303 	nclass->get_icon = real_get_icon;
304 	nclass->close = real_window_close;
305 
306 	g_type_class_add_private (klass, sizeof (NautilusDesktopWindowDetails));
307 }
308 
309 gboolean
310 nautilus_desktop_window_loaded (NautilusDesktopWindow *window)
311 {
312 	return window->details->loaded;
313 }