1
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
6
* Copyright (C) 2000 Eazel, Inc.
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.
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.
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.
22
* Authors: Darin Adler <darin@bentspoon.com>
26
#include "nautilus-desktop-window.h"
27
#include "nautilus-window-private.h"
28
#include "nautilus-actions.h"
30
#include <X11/Xatom.h>
34
#include <glib/gi18n.h>
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
#include <libnautilus-private/nautilus-ui-utilities.h>
42
struct NautilusDesktopWindowDetails {
43
gulong size_changed_id;
49
desktop_background_cb (GtkAction * action, gpointer user_data)
51
g_spawn_command_line_async("gnome-control-center background", NULL);
56
ubuntu_docs_cb (GtkAction * action, gpointer user_data)
58
g_spawn_command_line_async("yelp", NULL);
62
static const GtkActionEntry desktop_entries[] = {
63
/* name, stock id, label */ { "Change Desktop Background", NULL, N_("Change Desktop _Background"),
64
/* accel, tooltip */ NULL, NULL,
65
G_CALLBACK(desktop_background_cb)},
66
/* name, stock id, label */ { "Ubuntu Documentation", NULL, N_("Ubuntu Help"),
67
/* accel, tooltip */ NULL, NULL,
68
G_CALLBACK(ubuntu_docs_cb)}
71
static void set_wmspec_desktop_hint (GdkWindow *window);
73
G_DEFINE_TYPE (NautilusDesktopWindow, nautilus_desktop_window,
74
NAUTILUS_TYPE_WINDOW);
77
nautilus_desktop_window_dispose (GObject *obj)
79
NautilusDesktopWindow *window = NAUTILUS_DESKTOP_WINDOW (obj);
81
g_signal_handlers_disconnect_by_func (nautilus_preferences,
82
nautilus_desktop_window_update_directory,
85
G_OBJECT_CLASS (nautilus_desktop_window_parent_class)->dispose (obj);
89
nautilus_desktop_window_constructed (GObject *obj)
92
AtkObject *accessible;
93
NautilusDesktopWindow *window = NAUTILUS_DESKTOP_WINDOW (obj);
95
G_OBJECT_CLASS (nautilus_desktop_window_parent_class)->constructed (obj);
97
gtk_widget_hide (NAUTILUS_WINDOW (window)->details->statusbar);
98
gtk_widget_hide (NAUTILUS_WINDOW (window)->details->menubar);
100
/* Don't allow close action on desktop */
101
action = gtk_action_group_get_action (NAUTILUS_WINDOW (window)->details->main_action_group,
102
NAUTILUS_ACTION_CLOSE);
103
gtk_action_set_sensitive (action, FALSE);
105
UbuntuMenuProxy * proxy = ubuntu_menu_proxy_get();
107
ubuntu_menu_proxy_insert(proxy, GTK_WIDGET(window), NAUTILUS_WINDOW(window)->details->menubar, 0);
110
/* Add actions for the desktop */
111
GtkActionGroup * desktop_agroup = gtk_action_group_new("DesktopActions");
112
gtk_action_group_set_translation_domain(desktop_agroup, GETTEXT_PACKAGE);
113
gtk_action_group_add_actions(desktop_agroup, desktop_entries, G_N_ELEMENTS(desktop_entries), window);
114
gtk_ui_manager_insert_action_group(nautilus_window_get_ui_manager(NAUTILUS_WINDOW(window)),
116
g_object_unref(desktop_agroup);
118
GtkUIManager * ui_manager = nautilus_window_get_ui_manager(NAUTILUS_WINDOW(window));
119
const gchar * ui = nautilus_ui_string_get ("nautilus-desktop-window-ui.xml");
121
gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, NULL);
124
/* Hide actions that don't make sense on the desktop */
125
GList * agroups = gtk_ui_manager_get_action_groups(NAUTILUS_WINDOW(window)->details->ui_manager);
126
while (agroups != NULL) {
127
GtkActionGroup * agroup = GTK_ACTION_GROUP(agroups->data);
128
const gchar * name = gtk_action_group_get_name(agroup);
130
if (g_strcmp0(name, "LaunchpadIntegration") == 0) {
131
gtk_action_group_set_visible(agroup, FALSE);
132
} else if (g_strcmp0(name, "SpatialActions") == 0) {
133
GtkAction * action = NULL;
135
action = gtk_action_group_get_action(agroup, "Close Parent Folders");
136
gtk_action_set_visible(action, FALSE);
138
action = gtk_action_group_get_action(agroup, "Close All Folders");
139
gtk_action_set_visible(action, FALSE);
140
} else if (g_strcmp0(name, "ShellActions") == 0) {
141
GtkAction * action = NULL;
143
action = gtk_action_group_get_action(agroup, "Close All Windows");
144
gtk_action_set_visible(action, FALSE);
146
action = gtk_action_group_get_action(agroup, NAUTILUS_ACTION_CLOSE);
147
gtk_action_set_visible(action, FALSE);
149
action = gtk_action_group_get_action(agroup, NAUTILUS_ACTION_STOP);
150
gtk_action_set_visible(action, FALSE);
152
action = gtk_action_group_get_action(agroup, NAUTILUS_ACTION_RELOAD);
153
gtk_action_set_visible(action, FALSE);
155
action = gtk_action_group_get_action(agroup, "Preferences");
156
gtk_action_set_visible(action, FALSE);
158
action = gtk_action_group_get_action(agroup, "About Nautilus");
159
gtk_action_set_visible(action, FALSE);
161
action = gtk_action_group_get_action(agroup, "Up");
162
gtk_action_set_visible(action, FALSE);
164
action = gtk_action_group_get_action(agroup, "New Tab");
165
gtk_action_set_visible(action, FALSE);
167
action = gtk_action_group_get_action(agroup, NAUTILUS_ACTION_BACK);
168
gtk_action_set_visible(action, FALSE);
170
action = gtk_action_group_get_action(agroup, NAUTILUS_ACTION_FORWARD);
171
gtk_action_set_visible(action, FALSE);
173
action = gtk_action_group_get_action(agroup, NAUTILUS_ACTION_SHOW_HIDE_EXTRA_PANE);
174
gtk_action_set_visible(action, FALSE);
176
action = gtk_action_group_get_action(agroup, "SplitViewSameLocation");
177
gtk_action_set_visible(action, FALSE);
179
action = gtk_action_group_get_action(agroup, "Go to Location");
180
gtk_action_set_visible(action, FALSE);
182
action = gtk_action_group_get_action(agroup, "Search");
183
gtk_action_set_visible(action, FALSE);
185
action = gtk_action_group_get_action(agroup, "Add Bookmark");
186
gtk_action_set_visible(action, FALSE);
188
action = gtk_action_group_get_action(agroup, "Show Hide Sidebar");
189
gtk_action_set_visible(action, FALSE);
191
action = gtk_action_group_get_action(agroup, "Show Hide Statusbar");
192
gtk_action_set_visible(action, FALSE);
194
action = gtk_action_group_get_action(agroup, "Show Hide Toolbar");
195
gtk_action_set_visible(action, FALSE);
197
action = gtk_action_group_get_action(agroup, "Sidebar Places");
198
gtk_action_set_visible(action, FALSE);
200
action = gtk_action_group_get_action(agroup, "Sidebar Tree");
201
gtk_action_set_visible(action, FALSE);
203
action = gtk_action_group_get_action(agroup, "NautilusHelp");
204
gtk_action_set_visible(action, FALSE);
206
action = gtk_action_group_get_action(agroup, "NautilusHelpSearch");
207
gtk_action_set_visible(action, FALSE);
209
action = gtk_action_group_get_action(agroup, "NautilusHelpSort");
210
gtk_action_set_visible(action, FALSE);
212
action = gtk_action_group_get_action(agroup, "NautilusHelpLost");
213
gtk_action_set_visible(action, FALSE);
215
action = gtk_action_group_get_action(agroup, "NautilusHelpShare");
216
gtk_action_set_visible(action, FALSE);
219
agroups = g_list_next(agroups);
222
/* Set the accessible name so that it doesn't inherit the cryptic desktop URI. */
223
accessible = gtk_widget_get_accessible (GTK_WIDGET (window));
226
atk_object_set_name (accessible, _("Desktop"));
229
/* Monitor the preference to have the desktop */
230
/* point to the Unix home folder */
231
g_signal_connect_swapped (nautilus_preferences, "changed::" NAUTILUS_PREFERENCES_DESKTOP_IS_HOME_DIR,
232
G_CALLBACK (nautilus_desktop_window_update_directory),
237
nautilus_desktop_window_init (NautilusDesktopWindow *window)
239
window->details = G_TYPE_INSTANCE_GET_PRIVATE (window, NAUTILUS_TYPE_DESKTOP_WINDOW,
240
NautilusDesktopWindowDetails);
242
gtk_window_move (GTK_WINDOW (window), 0, 0);
244
/* shouldn't really be needed given our semantic type
245
* of _NET_WM_TYPE_DESKTOP, but why not
247
gtk_window_set_resizable (GTK_WINDOW (window),
250
g_object_set_data (G_OBJECT (window), "is_desktop_window",
251
GINT_TO_POINTER (1));
257
nautilus_desktop_window_delete_event (NautilusDesktopWindow *window)
259
/* Returning true tells GTK+ not to delete the window. */
264
nautilus_desktop_window_update_directory (NautilusDesktopWindow *window)
268
g_assert (NAUTILUS_IS_DESKTOP_WINDOW (window));
270
window->details->loaded = FALSE;
271
location = g_file_new_for_uri (EEL_DESKTOP_URI);
272
nautilus_window_go_to (NAUTILUS_WINDOW (window), location);
273
window->details->loaded = TRUE;
275
g_object_unref (location);
279
nautilus_desktop_window_screen_size_changed (GdkScreen *screen,
280
NautilusDesktopWindow *window)
282
int width_request, height_request;
284
width_request = gdk_screen_get_width (screen);
285
height_request = gdk_screen_get_height (screen);
287
g_object_set (window,
288
"width_request", width_request,
289
"height_request", height_request,
293
NautilusDesktopWindow *
294
nautilus_desktop_window_new (GdkScreen *screen)
296
NautilusDesktopWindow *window;
297
int width_request, height_request;
299
width_request = gdk_screen_get_width (screen);
300
height_request = gdk_screen_get_height (screen);
302
window = g_object_new (NAUTILUS_TYPE_DESKTOP_WINDOW,
303
"disable-chrome", TRUE,
304
"width_request", width_request,
305
"height_request", height_request,
309
/* Special sawmill setting*/
310
gtk_window_set_wmclass (GTK_WINDOW (window), "desktop_window", "Nautilus");
312
g_signal_connect (window, "delete_event", G_CALLBACK (nautilus_desktop_window_delete_event), NULL);
314
/* Point window at the desktop folder.
315
* Note that nautilus_desktop_window_init is too early to do this.
317
nautilus_desktop_window_update_directory (window);
323
map (GtkWidget *widget)
325
/* Chain up to realize our children */
326
GTK_WIDGET_CLASS (nautilus_desktop_window_parent_class)->map (widget);
327
gdk_window_lower (gtk_widget_get_window (widget));
331
unrealize (GtkWidget *widget)
333
NautilusDesktopWindow *window;
334
NautilusDesktopWindowDetails *details;
335
GdkWindow *root_window;
337
window = NAUTILUS_DESKTOP_WINDOW (widget);
338
details = window->details;
340
root_window = gdk_screen_get_root_window (
341
gtk_window_get_screen (GTK_WINDOW (window)));
343
gdk_property_delete (root_window,
344
gdk_atom_intern ("NAUTILUS_DESKTOP_WINDOW_ID", TRUE));
346
if (details->size_changed_id != 0) {
347
g_signal_handler_disconnect (gtk_window_get_screen (GTK_WINDOW (window)),
348
details->size_changed_id);
349
details->size_changed_id = 0;
352
GTK_WIDGET_CLASS (nautilus_desktop_window_parent_class)->unrealize (widget);
356
set_wmspec_desktop_hint (GdkWindow *window)
360
atom = gdk_atom_intern ("_NET_WM_WINDOW_TYPE_DESKTOP", FALSE);
362
gdk_property_change (window,
363
gdk_atom_intern ("_NET_WM_WINDOW_TYPE", FALSE),
364
gdk_x11_xatom_to_atom (XA_ATOM), 32,
365
GDK_PROP_MODE_REPLACE, (guchar *) &atom, 1);
369
set_desktop_window_id (NautilusDesktopWindow *window,
370
GdkWindow *gdkwindow)
372
/* Tuck the desktop windows xid in the root to indicate we own the desktop.
375
GdkWindow *root_window;
377
root_window = gdk_screen_get_root_window (
378
gtk_window_get_screen (GTK_WINDOW (window)));
380
window_xid = GDK_WINDOW_XID (gdkwindow);
382
gdk_property_change (root_window,
383
gdk_atom_intern ("NAUTILUS_DESKTOP_WINDOW_ID", FALSE),
384
gdk_x11_xatom_to_atom (XA_WINDOW), 32,
385
GDK_PROP_MODE_REPLACE, (guchar *) &window_xid, 1);
389
realize (GtkWidget *widget)
391
NautilusDesktopWindow *window;
392
NautilusDesktopWindowDetails *details;
394
window = NAUTILUS_DESKTOP_WINDOW (widget);
395
details = window->details;
397
/* Make sure we get keyboard events */
398
gtk_widget_set_events (widget, gtk_widget_get_events (widget)
399
| GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
401
/* Do the work of realizing. */
402
GTK_WIDGET_CLASS (nautilus_desktop_window_parent_class)->realize (widget);
404
/* This is the new way to set up the desktop window */
405
set_wmspec_desktop_hint (gtk_widget_get_window (widget));
407
set_desktop_window_id (window, gtk_widget_get_window (widget));
409
details->size_changed_id =
410
g_signal_connect (gtk_window_get_screen (GTK_WINDOW (window)), "size_changed",
411
G_CALLBACK (nautilus_desktop_window_screen_size_changed), window);
414
static NautilusIconInfo *
415
real_get_icon (NautilusWindow *window,
416
NautilusWindowSlot *slot)
418
return nautilus_icon_info_lookup_from_name (NAUTILUS_ICON_DESKTOP, 48);
422
real_sync_title (NautilusWindow *window,
423
NautilusWindowSlot *slot)
425
/* hardcode "Desktop" */
426
gtk_window_set_title (GTK_WINDOW (window), _("Desktop"));
430
real_window_close (NautilusWindow *window)
432
/* stub, does nothing */
437
nautilus_desktop_window_class_init (NautilusDesktopWindowClass *klass)
439
GtkWidgetClass *wclass = GTK_WIDGET_CLASS (klass);
440
NautilusWindowClass *nclass = NAUTILUS_WINDOW_CLASS (klass);
441
GObjectClass *oclass = G_OBJECT_CLASS (klass);
443
oclass->constructed = nautilus_desktop_window_constructed;
444
oclass->dispose = nautilus_desktop_window_dispose;
446
wclass->realize = realize;
447
wclass->unrealize = unrealize;
450
nclass->window_type = NAUTILUS_WINDOW_DESKTOP;
451
nclass->sync_title = real_sync_title;
452
nclass->get_icon = real_get_icon;
453
nclass->close = real_window_close;
455
g_type_class_add_private (klass, sizeof (NautilusDesktopWindowDetails));
459
nautilus_desktop_window_loaded (NautilusDesktopWindow *window)
461
return window->details->loaded;