~noskcaj/ubuntu/trusty/xfdesktop4/4.11.2-1

« back to all changes in this revision

Viewing changes to .pc/0006-Fix-for-shift-drag-selections.patch/src/xfce-desktop.c

  • Committer: Package Import Robot
  • Author(s): Lionel Le Folgoc
  • Date: 2012-05-18 22:18:02 UTC
  • mfrom: (3.1.7 experimental)
  • Revision ID: package-import@ubuntu.com-20120518221802-htmj6h4apaij25l2
Tags: 4.10.0-1ubuntu1
* Merge from Debian experimental, remaining Ubuntu change:
  - debian/patches/xubuntu_improve-nautilus-interactions.patch: added,
    should prevent nautilus from taking over the desktop if xfdesktop is
    running (and vice-versa).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *  xfdesktop - xfce4's desktop manager
3
 
 *
4
 
 *  Copyright (c) 2004-2007 Brian Tarricone, <bjt23@cornell.edu>
5
 
 *
6
 
 *  This program is free software; you can redistribute it and/or modify
7
 
 *  it under the terms of the GNU General Public License as published by
8
 
 *  the Free Software Foundation; either version 2 of the License, or
9
 
 *  (at your option) any later version.
10
 
 *
11
 
 *  This program is distributed in the hope that it will be useful,
12
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 *  GNU Library General Public License for more details.
15
 
 *
16
 
 *  You should have received a copy of the GNU General Public License
17
 
 *  along with this program; if not, write to the Free Software
18
 
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
 
 *
20
 
 *  Random portions taken from or inspired by the original xfdesktop for xfce4:
21
 
 *     Copyright (C) 2002-2003 Jasper Huijsmans (huysmans@users.sourceforge.net)
22
 
 *     Copyright (C) 2003 Benedikt Meurer <benedikt.meurer@unix-ag.uni-siegen.de>
23
 
 */
24
 
 
25
 
#ifdef HAVE_CONFIG_H
26
 
#include <config.h>
27
 
#endif
28
 
 
29
 
#include <stdio.h>
30
 
 
31
 
#ifdef HAVE_STDLIB_H
32
 
#include <stdlib.h>
33
 
#endif
34
 
 
35
 
#ifdef HAVE_STRING_H
36
 
#include <string.h>
37
 
#endif
38
 
 
39
 
#ifdef HAVE_SYS_TYPES_H
40
 
#include <sys/types.h>
41
 
#endif
42
 
#ifdef HAVE_SYS_STAT_H
43
 
#include <sys/stat.h>
44
 
#endif
45
 
#ifdef HAVE_UNISTD_H
46
 
#include <unistd.h>
47
 
#endif
48
 
 
49
 
#ifdef HAVE_FCNTL_H
50
 
#include <fcntl.h>
51
 
#endif
52
 
 
53
 
#include <ctype.h>
54
 
#include <errno.h>
55
 
 
56
 
#ifdef HAVE_TIME_H
57
 
#include <time.h>
58
 
#endif
59
 
 
60
 
#include <X11/Xlib.h>
61
 
#include <X11/Xatom.h>
62
 
 
63
 
#include <glib.h>
64
 
#include <gdk/gdkx.h>
65
 
#include <gtk/gtk.h>
66
 
 
67
 
#ifdef ENABLE_DESKTOP_ICONS
68
 
#include "xfdesktop-icon-view.h"
69
 
#include "xfdesktop-window-icon-manager.h"
70
 
# ifdef ENABLE_FILE_ICONS
71
 
# include "xfdesktop-file-icon-manager.h"
72
 
# include "xfdesktop-special-file-icon.h"
73
 
# endif
74
 
#endif
75
 
 
76
 
#include <libxfce4util/libxfce4util.h>
77
 
#include <libxfce4ui/libxfce4ui.h>
78
 
 
79
 
#include <xfconf/xfconf.h>
80
 
 
81
 
#include "xfdesktop-common.h"
82
 
#include "xfce-desktop.h"
83
 
#include "xfce-desktop-enum-types.h"
84
 
 
85
 
struct _XfceDesktopPriv
86
 
{
87
 
    GdkScreen *gscreen;
88
 
    gboolean updates_frozen;
89
 
 
90
 
    XfconfChannel *channel;
91
 
    gchar *property_prefix;
92
 
    
93
 
    GdkPixmap *bg_pixmap;
94
 
    
95
 
    guint nbackdrops;
96
 
    XfceBackdrop **backdrops;
97
 
    
98
 
    gboolean xinerama_stretch;
99
 
    
100
 
    SessionLogoutFunc session_logout_func;
101
 
    
102
 
#ifdef ENABLE_DESKTOP_ICONS
103
 
    XfceDesktopIconStyle icons_style;
104
 
    gboolean icons_font_size_set;
105
 
    guint icons_font_size;
106
 
    guint icons_size;
107
 
    GtkWidget *icon_view;
108
 
    gdouble system_font_size;
109
 
#endif
110
 
};
111
 
 
112
 
enum
113
 
{
114
 
    SIG_POPULATE_ROOT_MENU = 0,
115
 
    SIG_POPULATE_SECONDARY_ROOT_MENU,
116
 
    N_SIGNALS
117
 
};
118
 
 
119
 
enum
120
 
{
121
 
    PROP_0 = 0,
122
 
    PROP_XINERAMA_STRETCH,
123
 
#ifdef ENABLE_DESKTOP_ICONS
124
 
    PROP_ICON_STYLE,
125
 
    PROP_ICON_SIZE,
126
 
    PROP_ICON_FONT_SIZE,
127
 
    PROP_ICON_FONT_SIZE_SET,
128
 
#endif
129
 
};
130
 
 
131
 
 
132
 
static void xfce_desktop_finalize(GObject *object);
133
 
static void xfce_desktop_set_property(GObject *object,
134
 
                                      guint property_id,
135
 
                                      const GValue *value,
136
 
                                      GParamSpec *pspec);
137
 
static void xfce_desktop_get_property(GObject *object,
138
 
                                      guint property_id,
139
 
                                      GValue *value,
140
 
                                      GParamSpec *pspec);
141
 
 
142
 
static void xfce_desktop_realize(GtkWidget *widget);
143
 
static void xfce_desktop_unrealize(GtkWidget *widget);
144
 
static gboolean xfce_desktop_button_press_event(GtkWidget *widget,
145
 
                                                GdkEventButton *evt);
146
 
static gboolean xfce_desktop_popup_menu(GtkWidget *widget);
147
 
 
148
 
static gboolean xfce_desktop_expose(GtkWidget *w,
149
 
                                    GdkEventExpose *evt);
150
 
static gboolean xfce_desktop_delete_event(GtkWidget *w,
151
 
                                          GdkEventAny *evt);
152
 
static void xfce_desktop_style_set(GtkWidget *w,
153
 
                                   GtkStyle *old_style);
154
 
 
155
 
static void xfce_desktop_connect_backdrop_settings(XfceDesktop *desktop,
156
 
                                                   XfceBackdrop *backdrop,
157
 
                                                   guint monitor);
158
 
 
159
 
static guint signals[N_SIGNALS] = { 0, };
160
 
 
161
 
/* private functions */
162
 
 
163
 
#ifdef ENABLE_DESKTOP_ICONS
164
 
static gdouble
165
 
xfce_desktop_ensure_system_font_size(XfceDesktop *desktop)
166
 
{
167
 
    GdkScreen *gscreen;
168
 
    GtkSettings *settings;
169
 
    gchar *font_name = NULL;
170
 
    PangoFontDescription *pfd;
171
 
    
172
 
    gscreen = gtk_widget_get_screen(GTK_WIDGET(desktop));
173
 
    /* FIXME: needed? */
174
 
    if(!gscreen)
175
 
        gscreen = gdk_display_get_default_screen(gdk_display_get_default());
176
 
    
177
 
    settings = gtk_settings_get_for_screen(gscreen);
178
 
    g_object_get(G_OBJECT(settings), "gtk-font-name", &font_name, NULL);
179
 
    
180
 
    pfd = pango_font_description_from_string(font_name);
181
 
    desktop->priv->system_font_size = pango_font_description_get_size(pfd);
182
 
    /* FIXME: this seems backwards from the documentation */
183
 
    if(!pango_font_description_get_size_is_absolute(pfd)) {
184
 
        DBG("dividing by PANGO_SCALE");
185
 
        desktop->priv->system_font_size /= PANGO_SCALE;
186
 
    }
187
 
    DBG("system font size is %.05f", desktop->priv->system_font_size);
188
 
    
189
 
    g_free(font_name);
190
 
    pango_font_description_free(pfd);
191
 
    
192
 
    return desktop->priv->system_font_size;
193
 
}
194
 
 
195
 
static void
196
 
xfce_desktop_setup_icon_view(XfceDesktop *desktop)
197
 
{
198
 
    XfdesktopIconViewManager *manager = NULL;
199
 
    
200
 
    switch(desktop->priv->icons_style) {
201
 
        case XFCE_DESKTOP_ICON_STYLE_NONE:
202
 
            /* nada */
203
 
            break;
204
 
        
205
 
        case XFCE_DESKTOP_ICON_STYLE_WINDOWS:
206
 
            manager = xfdesktop_window_icon_manager_new(desktop->priv->gscreen);
207
 
            break;
208
 
        
209
 
#ifdef ENABLE_FILE_ICONS
210
 
        case XFCE_DESKTOP_ICON_STYLE_FILES:
211
 
            {
212
 
                GFile *file;
213
 
                const gchar *desktop_path;
214
 
                
215
 
                desktop_path = g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP);
216
 
                file = g_file_new_for_path(desktop_path);
217
 
                manager = xfdesktop_file_icon_manager_new(file, desktop->priv->channel);
218
 
                g_object_unref(file);
219
 
            }
220
 
            break;
221
 
#endif
222
 
        
223
 
        default:
224
 
            g_critical("Unusable XfceDesktopIconStyle: %d.  Unable to " \
225
 
                       "display desktop icons.",
226
 
                       desktop->priv->icons_style);
227
 
            break;
228
 
    }
229
 
    
230
 
    if(manager) {
231
 
        xfce_desktop_ensure_system_font_size(desktop);
232
 
        
233
 
        desktop->priv->icon_view = xfdesktop_icon_view_new(manager);
234
 
        xfdesktop_icon_view_set_font_size(XFDESKTOP_ICON_VIEW(desktop->priv->icon_view),
235
 
                                          (!desktop->priv->icons_font_size_set
236
 
                                           || !desktop->priv->icons_font_size)
237
 
                                          ? desktop->priv->system_font_size
238
 
                                          : desktop->priv->icons_font_size);
239
 
        if(desktop->priv->icons_size > 0) {
240
 
            xfdesktop_icon_view_set_icon_size(XFDESKTOP_ICON_VIEW(desktop->priv->icon_view),
241
 
                                              desktop->priv->icons_size);
242
 
        }
243
 
        gtk_widget_show(desktop->priv->icon_view);
244
 
        gtk_container_add(GTK_CONTAINER(desktop), desktop->priv->icon_view);
245
 
    }
246
 
    
247
 
    gtk_widget_queue_draw(GTK_WIDGET(desktop));
248
 
}
249
 
#endif
250
 
 
251
 
static void
252
 
set_imgfile_root_property(XfceDesktop *desktop, const gchar *filename,
253
 
        gint monitor)
254
 
{
255
 
    gchar property_name[128];
256
 
    
257
 
    gdk_error_trap_push();
258
 
    
259
 
    g_snprintf(property_name, 128, XFDESKTOP_IMAGE_FILE_FMT, monitor);
260
 
    if(filename) {
261
 
        gdk_property_change(gdk_screen_get_root_window(desktop->priv->gscreen),
262
 
                            gdk_atom_intern(property_name, FALSE),
263
 
                            gdk_x11_xatom_to_atom(XA_STRING), 8,
264
 
                            GDK_PROP_MODE_REPLACE,
265
 
                            (guchar *)filename, strlen(filename)+1);
266
 
    } else {
267
 
        gdk_property_delete(gdk_screen_get_root_window(desktop->priv->gscreen),
268
 
                            gdk_atom_intern(property_name, FALSE));
269
 
    }
270
 
    
271
 
    gdk_error_trap_pop();
272
 
}
273
 
 
274
 
static void
275
 
set_real_root_window_pixmap(GdkScreen *gscreen,
276
 
                            GdkPixmap *pmap)
277
 
{
278
 
#if 0 /* see bug #7442 */
279
 
    Window xid;
280
 
    GdkWindow *groot;
281
 
    
282
 
    xid = GDK_DRAWABLE_XID(pmap);
283
 
    groot = gdk_screen_get_root_window(gscreen);
284
 
    
285
 
    gdk_error_trap_push();
286
 
    
287
 
    /* set root property for transparent Eterms */
288
 
    gdk_property_change(groot,
289
 
            gdk_atom_intern("_XROOTPMAP_ID", FALSE),
290
 
            gdk_atom_intern("PIXMAP", FALSE), 32,
291
 
            GDK_PROP_MODE_REPLACE, (guchar *)&xid, 1);
292
 
    /* set this other property because someone might need it sometime. */
293
 
    gdk_property_change(groot,
294
 
            gdk_atom_intern("ESETROOT_PMAP_ID", FALSE),
295
 
            gdk_atom_intern("PIXMAP", FALSE), 32,
296
 
            GDK_PROP_MODE_REPLACE, (guchar *)&xid, 1);
297
 
    /* and set the root window's BG pixmap, because aterm is somewhat lame. */
298
 
    gdk_window_set_back_pixmap(groot, pmap, FALSE);
299
 
    /* there really should be a standard for this crap... */
300
 
 
301
 
    gdk_error_trap_pop();
302
 
#endif
303
 
}
304
 
 
305
 
static void
306
 
backdrop_changed_cb(XfceBackdrop *backdrop, gpointer user_data)
307
 
{
308
 
    XfceDesktop *desktop = XFCE_DESKTOP(user_data);
309
 
    GdkPixmap *pmap = desktop->priv->bg_pixmap;
310
 
    GdkScreen *gscreen = desktop->priv->gscreen;
311
 
    GdkPixbuf *pix;
312
 
    GdkRectangle rect;
313
 
    guint i;
314
 
    gint monitor = -1;
315
 
    
316
 
    TRACE("entering");
317
 
    
318
 
    g_return_if_fail(XFCE_IS_DESKTOP(desktop));
319
 
    
320
 
    if(desktop->priv->updates_frozen || !GTK_WIDGET_REALIZED(GTK_WIDGET(desktop)))
321
 
        return;
322
 
    
323
 
    TRACE("really entering");
324
 
    
325
 
    for(i = 0; i < XFCE_DESKTOP(desktop)->priv->nbackdrops; i++) {
326
 
        if(backdrop == XFCE_DESKTOP(desktop)->priv->backdrops[i]) {
327
 
            monitor = i;
328
 
            break;
329
 
        }
330
 
    }
331
 
    if(monitor == -1)
332
 
        return;
333
 
    
334
 
    /* create/get the composited backdrop pixmap */
335
 
    pix = xfce_backdrop_get_pixbuf(backdrop);
336
 
    if(!pix)
337
 
        return;
338
 
    
339
 
    if(desktop->priv->nbackdrops == 1) {
340
 
        /* single monitor */
341
 
        rect.x = rect.y = 0;
342
 
        rect.width = gdk_screen_get_width(gscreen);
343
 
        rect.height = gdk_screen_get_height(gscreen);
344
 
    } else
345
 
        gdk_screen_get_monitor_geometry(gscreen, monitor, &rect);
346
 
 
347
 
    gdk_draw_pixbuf(GDK_DRAWABLE(pmap), GTK_WIDGET(desktop)->style->black_gc,
348
 
                    pix, 0, 0, rect.x, rect.y,
349
 
                    gdk_pixbuf_get_width(pix), gdk_pixbuf_get_height(pix),
350
 
                    GDK_RGB_DITHER_MAX, 0, 0);
351
 
    g_object_unref(G_OBJECT(pix));
352
 
    
353
 
    /* tell gtk to redraw the repainted area */
354
 
    gtk_widget_queue_draw_area(GTK_WIDGET(desktop), rect.x, rect.y,
355
 
                               rect.width, rect.height);
356
 
    
357
 
    set_imgfile_root_property(desktop,
358
 
                              xfce_backdrop_get_image_filename(backdrop),
359
 
                              monitor);
360
 
    
361
 
    /* do this again so apps watching the root win notice the update */
362
 
    set_real_root_window_pixmap(gscreen, pmap);
363
 
}
364
 
 
365
 
static void
366
 
screen_size_changed_cb(GdkScreen *gscreen, gpointer user_data)
367
 
{
368
 
    XfceDesktop *desktop = user_data;
369
 
    gint w, h;
370
 
    
371
 
    g_return_if_fail(XFCE_IS_DESKTOP(desktop));
372
 
    
373
 
    w = gdk_screen_get_width(gscreen);
374
 
    h = gdk_screen_get_height(gscreen);
375
 
    gtk_widget_set_size_request(GTK_WIDGET(desktop), w, h);
376
 
    gtk_window_resize(GTK_WINDOW(desktop), w, h);
377
 
    
378
 
    if(desktop->priv->bg_pixmap)
379
 
        g_object_unref(G_OBJECT(desktop->priv->bg_pixmap));
380
 
    desktop->priv->bg_pixmap = gdk_pixmap_new(GDK_DRAWABLE(GTK_WIDGET(desktop)->window),
381
 
                                              w, h, -1);
382
 
    set_real_root_window_pixmap(desktop->priv->gscreen,
383
 
                                desktop->priv->bg_pixmap);
384
 
    gdk_window_set_back_pixmap(GTK_WIDGET(desktop)->window,
385
 
                               desktop->priv->bg_pixmap, FALSE);
386
 
    
387
 
    /* special case for 1 backdrop to handle xinerama stretching */
388
 
    if(desktop->priv->xinerama_stretch) {
389
 
        xfce_backdrop_set_size(desktop->priv->backdrops[0], w, h);
390
 
        backdrop_changed_cb(desktop->priv->backdrops[0], desktop);
391
 
    } else {
392
 
        GdkRectangle rect;
393
 
        guint i;
394
 
 
395
 
        for(i = 0; i < desktop->priv->nbackdrops; i++) {
396
 
            gdk_screen_get_monitor_geometry(gscreen, i, &rect);
397
 
            xfce_backdrop_set_size(desktop->priv->backdrops[i], rect.width,
398
 
                                   rect.height);
399
 
            backdrop_changed_cb(desktop->priv->backdrops[i], desktop);
400
 
        }
401
 
    }
402
 
}
403
 
 
404
 
static void
405
 
screen_composited_changed_cb(GdkScreen *gscreen,
406
 
                             gpointer user_data)
407
 
{
408
 
    /* fake a screen size changed, so the background is properly set */
409
 
    screen_size_changed_cb(gscreen, user_data);
410
 
}
411
 
 
412
 
static void
413
 
xfce_desktop_monitors_changed(GdkScreen *gscreen,
414
 
                              gpointer user_data)
415
 
{
416
 
    XfceDesktop *desktop = XFCE_DESKTOP(user_data);
417
 
    guint i;
418
 
 
419
 
    if(desktop->priv->xinerama_stretch) {
420
 
        if(desktop->priv->nbackdrops > 1) {
421
 
            for(i = 1; i < desktop->priv->nbackdrops; ++i)
422
 
                g_object_unref(G_OBJECT(desktop->priv->backdrops[i]));
423
 
        }
424
 
 
425
 
        if(desktop->priv->nbackdrops != 1) {
426
 
            desktop->priv->backdrops = g_realloc(desktop->priv->backdrops,
427
 
                                                 sizeof(XfceBackdrop *));
428
 
            if(!desktop->priv->nbackdrops) {
429
 
                GdkVisual *vis = gtk_widget_get_visual(GTK_WIDGET(desktop));
430
 
                desktop->priv->backdrops[0] = xfce_backdrop_new(vis);
431
 
                xfce_desktop_connect_backdrop_settings(desktop,
432
 
                                                       desktop->priv->backdrops[0],
433
 
                                                       0);
434
 
                g_signal_connect(G_OBJECT(desktop->priv->backdrops[0]),
435
 
                                 "changed",
436
 
                                 G_CALLBACK(backdrop_changed_cb), desktop);
437
 
            }
438
 
            desktop->priv->nbackdrops = 1;
439
 
        }
440
 
    } else {
441
 
        guint n_monitors = gdk_screen_get_n_monitors(gscreen);
442
 
 
443
 
        if(n_monitors < desktop->priv->nbackdrops) {
444
 
            for(i = n_monitors; i < desktop->priv->nbackdrops; ++i)
445
 
                g_object_unref(G_OBJECT(desktop->priv->backdrops[i]));
446
 
        }
447
 
 
448
 
        if(n_monitors != desktop->priv->nbackdrops) {
449
 
            desktop->priv->backdrops = g_realloc(desktop->priv->backdrops,
450
 
                                                 sizeof(XfceBackdrop *) * n_monitors);
451
 
            if(n_monitors > desktop->priv->nbackdrops) {
452
 
                GdkVisual *vis = gtk_widget_get_visual(GTK_WIDGET(desktop));
453
 
                for(i = desktop->priv->nbackdrops; i < n_monitors; ++i) {
454
 
                    desktop->priv->backdrops[i] = xfce_backdrop_new(vis);
455
 
                    xfce_desktop_connect_backdrop_settings(desktop,
456
 
                                                           desktop->priv->backdrops[i],
457
 
                                                           i);
458
 
                    g_signal_connect(G_OBJECT(desktop->priv->backdrops[i]),
459
 
                                     "changed",
460
 
                                     G_CALLBACK(backdrop_changed_cb),
461
 
                                     desktop);
462
 
                }
463
 
            }
464
 
            desktop->priv->nbackdrops = n_monitors;
465
 
        }
466
 
    }
467
 
 
468
 
    /* update the total size of the screen and the size of each backdrop */
469
 
    screen_size_changed_cb(gscreen, desktop);
470
 
}
471
 
 
472
 
static void
473
 
screen_set_selection(XfceDesktop *desktop)
474
 
{
475
 
    Window xwin;
476
 
    gint xscreen;
477
 
    gchar selection_name[100], common_selection_name[32];
478
 
    Atom selection_atom, common_selection_atom, manager_atom;
479
 
    
480
 
    xwin = GDK_WINDOW_XID(GTK_WIDGET(desktop)->window);
481
 
    xscreen = gdk_screen_get_number(desktop->priv->gscreen);
482
 
    
483
 
    g_snprintf(selection_name, 100, XFDESKTOP_SELECTION_FMT, xscreen);
484
 
    selection_atom = XInternAtom(GDK_DISPLAY(), selection_name, False);
485
 
    manager_atom = XInternAtom(GDK_DISPLAY(), "MANAGER", False);
486
 
 
487
 
    g_snprintf(common_selection_name, 32, "_NET_DESKTOP_MANAGER_S%d", xscreen);
488
 
    common_selection_atom = XInternAtom(GDK_DISPLAY(), common_selection_name, False);
489
 
 
490
 
    /* the previous check in src/main.c occurs too early, so workaround by
491
 
     * adding this one. Hopefully it should help for lp #329616 */
492
 
    if(XGetSelectionOwner(GDK_DISPLAY(), selection_atom) != None) {
493
 
        g_warning("%s: already running, quitting.", PACKAGE);
494
 
        exit(0);
495
 
    }
496
 
 
497
 
    /* Check that _NET_DESKTOP_MANAGER_S%d isn't set, as it means another
498
 
     * desktop manager is running, e.g. nautilus */
499
 
    if(XGetSelectionOwner (GDK_DISPLAY(), common_selection_atom) != None) {
500
 
        g_warning("%s: another desktop manager is running.", PACKAGE);
501
 
        exit(1);
502
 
    }
503
 
 
504
 
    XSelectInput(GDK_DISPLAY(), xwin, PropertyChangeMask | ButtonPressMask);
505
 
    XSetSelectionOwner(GDK_DISPLAY(), selection_atom, xwin, GDK_CURRENT_TIME);
506
 
    XSetSelectionOwner(GDK_DISPLAY(), common_selection_atom, xwin, GDK_CURRENT_TIME);
507
 
 
508
 
    /* Check to see if we managed to claim the selection. If not,
509
 
     * we treat it as if we got it then immediately lost it */
510
 
    if(XGetSelectionOwner(GDK_DISPLAY(), selection_atom) == xwin) {
511
 
        XClientMessageEvent xev;
512
 
        Window xroot = GDK_WINDOW_XID(gdk_screen_get_root_window(desktop->priv->gscreen));
513
 
        
514
 
        xev.type = ClientMessage;
515
 
        xev.window = xroot;
516
 
        xev.message_type = manager_atom;
517
 
        xev.format = 32;
518
 
        xev.data.l[0] = GDK_CURRENT_TIME;
519
 
        xev.data.l[1] = selection_atom;
520
 
        xev.data.l[2] = xwin;
521
 
        xev.data.l[3] = 0;    /* manager specific data */
522
 
        xev.data.l[4] = 0;    /* manager specific data */
523
 
 
524
 
        XSendEvent(GDK_DISPLAY(), xroot, False, StructureNotifyMask, (XEvent *)&xev);
525
 
    } else {
526
 
        g_error("%s: could not set selection ownership", PACKAGE);
527
 
        exit(1);
528
 
    }
529
 
}
530
 
 
531
 
 
532
 
 
533
 
/* gobject-related functions */
534
 
 
535
 
 
536
 
G_DEFINE_TYPE(XfceDesktop, xfce_desktop, GTK_TYPE_WINDOW)
537
 
 
538
 
 
539
 
static void
540
 
xfce_desktop_class_init(XfceDesktopClass *klass)
541
 
{
542
 
    GObjectClass *gobject_class = (GObjectClass *)klass;
543
 
    GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
544
 
    
545
 
    g_type_class_add_private(klass, sizeof(XfceDesktopPriv));
546
 
    
547
 
    gobject_class->finalize = xfce_desktop_finalize;
548
 
    gobject_class->set_property = xfce_desktop_set_property;
549
 
    gobject_class->get_property = xfce_desktop_get_property;
550
 
    
551
 
    widget_class->realize = xfce_desktop_realize;
552
 
    widget_class->unrealize = xfce_desktop_unrealize;
553
 
    widget_class->button_press_event = xfce_desktop_button_press_event;
554
 
    widget_class->expose_event = xfce_desktop_expose;
555
 
    widget_class->delete_event = xfce_desktop_delete_event;
556
 
    widget_class->popup_menu = xfce_desktop_popup_menu;
557
 
    widget_class->style_set = xfce_desktop_style_set;
558
 
    
559
 
    signals[SIG_POPULATE_ROOT_MENU] = g_signal_new("populate-root-menu",
560
 
                                                   XFCE_TYPE_DESKTOP,
561
 
                                                   G_SIGNAL_RUN_LAST,
562
 
                                                   G_STRUCT_OFFSET(XfceDesktopClass,
563
 
                                                                   populate_root_menu),
564
 
                                                   NULL, NULL,
565
 
                                                   g_cclosure_marshal_VOID__OBJECT,
566
 
                                                   G_TYPE_NONE, 1,
567
 
                                                   GTK_TYPE_MENU_SHELL);
568
 
    
569
 
    signals[SIG_POPULATE_SECONDARY_ROOT_MENU] = g_signal_new("populate-secondary-root-menu",
570
 
                                                             XFCE_TYPE_DESKTOP,
571
 
                                                             G_SIGNAL_RUN_LAST,
572
 
                                                             G_STRUCT_OFFSET(XfceDesktopClass,
573
 
                                                                             populate_secondary_root_menu),
574
 
                                                             NULL, NULL,
575
 
                                                             g_cclosure_marshal_VOID__OBJECT,
576
 
                                                             G_TYPE_NONE, 1,
577
 
                                                             GTK_TYPE_MENU_SHELL);
578
 
 
579
 
#define XFDESKTOP_PARAM_FLAGS  (G_PARAM_READWRITE \
580
 
                                | G_PARAM_CONSTRUCT \
581
 
                                | G_PARAM_STATIC_NAME \
582
 
                                | G_PARAM_STATIC_NICK \
583
 
                                | G_PARAM_STATIC_BLURB)
584
 
 
585
 
    g_object_class_install_property(gobject_class, PROP_XINERAMA_STRETCH,
586
 
                                    g_param_spec_boolean("xinerama-stretch",
587
 
                                                         "xinerama stretch",
588
 
                                                         "xinerama stretch",
589
 
                                                         FALSE,
590
 
                                                         XFDESKTOP_PARAM_FLAGS));
591
 
 
592
 
#ifdef ENABLE_DESKTOP_ICONS
593
 
    g_object_class_install_property(gobject_class, PROP_ICON_STYLE,
594
 
                                    g_param_spec_enum("icon-style",
595
 
                                                      "icon style",
596
 
                                                      "icon style",
597
 
                                                      XFCE_TYPE_DESKTOP_ICON_STYLE,
598
 
#ifdef ENABLE_FILE_ICONS
599
 
                                                      XFCE_DESKTOP_ICON_STYLE_FILES,
600
 
#else
601
 
                                                      XFCE_DESKTOP_ICON_STYLE_WINDOWS,
602
 
#endif
603
 
                                                      XFDESKTOP_PARAM_FLAGS));
604
 
 
605
 
    g_object_class_install_property(gobject_class, PROP_ICON_SIZE,
606
 
                                    g_param_spec_uint("icon-size",
607
 
                                                      "icon size",
608
 
                                                      "icon size",
609
 
                                                      8, 192, 36,
610
 
                                                      XFDESKTOP_PARAM_FLAGS));
611
 
 
612
 
    g_object_class_install_property(gobject_class, PROP_ICON_FONT_SIZE,
613
 
                                    g_param_spec_uint("icon-font-size",
614
 
                                                      "icon font size",
615
 
                                                      "icon font size",
616
 
                                                      4, 144, 12,
617
 
                                                      XFDESKTOP_PARAM_FLAGS));
618
 
 
619
 
    g_object_class_install_property(gobject_class, PROP_ICON_FONT_SIZE_SET,
620
 
                                    g_param_spec_boolean("icon-font-size-set",
621
 
                                                         "icon font size set",
622
 
                                                         "icon font size set",
623
 
                                                         FALSE,
624
 
                                                         XFDESKTOP_PARAM_FLAGS));
625
 
#endif
626
 
#undef XFDESKTOP_PARAM_FLAGS
627
 
}
628
 
 
629
 
static void
630
 
xfce_desktop_init(XfceDesktop *desktop)
631
 
{
632
 
    desktop->priv = G_TYPE_INSTANCE_GET_PRIVATE(desktop, XFCE_TYPE_DESKTOP,
633
 
                                                XfceDesktopPriv);
634
 
    GTK_WINDOW(desktop)->type = GTK_WINDOW_TOPLEVEL;
635
 
    
636
 
    gtk_window_set_type_hint(GTK_WINDOW(desktop), GDK_WINDOW_TYPE_HINT_DESKTOP);
637
 
    gtk_window_set_accept_focus(GTK_WINDOW(desktop), FALSE);
638
 
}
639
 
 
640
 
static void
641
 
xfce_desktop_finalize(GObject *object)
642
 
{
643
 
    XfceDesktop *desktop = XFCE_DESKTOP(object);
644
 
    
645
 
    g_object_unref(G_OBJECT(desktop->priv->channel));
646
 
    g_free(desktop->priv->property_prefix);
647
 
    
648
 
    G_OBJECT_CLASS(xfce_desktop_parent_class)->finalize(object);
649
 
}
650
 
 
651
 
static void
652
 
xfce_desktop_set_property(GObject *object,
653
 
                          guint property_id,
654
 
                          const GValue *value,
655
 
                          GParamSpec *pspec)
656
 
{
657
 
    XfceDesktop *desktop = XFCE_DESKTOP(object);
658
 
 
659
 
    switch(property_id) {
660
 
        case PROP_XINERAMA_STRETCH:
661
 
            xfce_desktop_set_xinerama_stretch(desktop,
662
 
                                              g_value_get_boolean(value));
663
 
            break;
664
 
 
665
 
#ifdef ENABLE_DESKTOP_ICONS
666
 
        case PROP_ICON_STYLE:
667
 
            xfce_desktop_set_icon_style(desktop,
668
 
                                        g_value_get_enum(value));
669
 
            break;
670
 
 
671
 
        case PROP_ICON_SIZE:
672
 
            xfce_desktop_set_icon_size(desktop,
673
 
                                       g_value_get_uint(value));
674
 
            break;
675
 
 
676
 
        case PROP_ICON_FONT_SIZE:
677
 
            xfce_desktop_set_icon_font_size(desktop,
678
 
                                            g_value_get_uint(value));
679
 
            break;
680
 
 
681
 
        case PROP_ICON_FONT_SIZE_SET:
682
 
            xfce_desktop_set_use_icon_font_size(desktop,
683
 
                                                g_value_get_boolean(value));
684
 
            break;
685
 
 
686
 
#endif
687
 
        default:
688
 
            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
689
 
            break;
690
 
    }
691
 
}
692
 
 
693
 
static void
694
 
xfce_desktop_get_property(GObject *object,
695
 
                          guint property_id,
696
 
                          GValue *value,
697
 
                          GParamSpec *pspec)
698
 
{
699
 
    XfceDesktop *desktop = XFCE_DESKTOP(object);
700
 
 
701
 
    switch(property_id) {
702
 
        case PROP_XINERAMA_STRETCH:
703
 
            g_value_set_boolean(value, desktop->priv->xinerama_stretch);
704
 
            break;
705
 
 
706
 
#ifdef ENABLE_DESKTOP_ICONS
707
 
        case PROP_ICON_STYLE:
708
 
            g_value_set_enum(value, desktop->priv->icons_style);
709
 
            break;
710
 
 
711
 
        case PROP_ICON_SIZE:
712
 
            g_value_set_uint(value, desktop->priv->icons_size);
713
 
            break;
714
 
 
715
 
        case PROP_ICON_FONT_SIZE:
716
 
            g_value_set_uint(value, desktop->priv->icons_font_size);
717
 
            break;
718
 
 
719
 
        case PROP_ICON_FONT_SIZE_SET:
720
 
            g_value_set_boolean(value, desktop->priv->icons_font_size_set);
721
 
            break;
722
 
 
723
 
#endif
724
 
        default:
725
 
            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
726
 
            break;
727
 
    }
728
 
}
729
 
 
730
 
static void
731
 
xfce_desktop_realize(GtkWidget *widget)
732
 
{
733
 
    XfceDesktop *desktop = XFCE_DESKTOP(widget);
734
 
    GdkAtom atom;
735
 
    gint sw, sh;
736
 
    Window xid;
737
 
    GdkWindow *groot;
738
 
    
739
 
    TRACE("entering");
740
 
 
741
 
    gtk_window_set_screen(GTK_WINDOW(desktop), desktop->priv->gscreen);
742
 
    sw = gdk_screen_get_width(desktop->priv->gscreen);
743
 
    sh = gdk_screen_get_height(desktop->priv->gscreen);
744
 
    if(gtk_major_version > 2
745
 
       || (gtk_major_version == 2 && gtk_minor_version >= 13))
746
 
    {
747
 
        g_signal_connect(G_OBJECT(desktop->priv->gscreen),
748
 
                         "monitors-changed",
749
 
                         G_CALLBACK(xfce_desktop_monitors_changed),
750
 
                         desktop);
751
 
    }
752
 
    
753
 
    /* chain up */
754
 
    GTK_WIDGET_CLASS(xfce_desktop_parent_class)->realize(widget);
755
 
    
756
 
    gtk_window_set_title(GTK_WINDOW(desktop), _("Desktop"));
757
 
    
758
 
    gtk_widget_set_size_request(GTK_WIDGET(desktop), sw, sh);
759
 
    gtk_window_move(GTK_WINDOW(desktop), 0, 0);
760
 
    
761
 
    atom = gdk_atom_intern("_NET_WM_WINDOW_TYPE_DESKTOP", FALSE);
762
 
    gdk_property_change(GTK_WIDGET(desktop)->window,
763
 
            gdk_atom_intern("_NET_WM_WINDOW_TYPE", FALSE),
764
 
            gdk_atom_intern("ATOM", FALSE), 32,
765
 
            GDK_PROP_MODE_REPLACE, (guchar *)&atom, 1);
766
 
 
767
 
    xid = GDK_WINDOW_XID(GTK_WIDGET(desktop)->window);
768
 
    groot = gdk_screen_get_root_window(desktop->priv->gscreen);
769
 
    
770
 
    gdk_property_change(groot,
771
 
            gdk_atom_intern("XFCE_DESKTOP_WINDOW", FALSE),
772
 
            gdk_atom_intern("WINDOW", FALSE), 32,
773
 
            GDK_PROP_MODE_REPLACE, (guchar *)&xid, 1);
774
 
    
775
 
    gdk_property_change(groot,
776
 
            gdk_atom_intern("NAUTILUS_DESKTOP_WINDOW_ID", FALSE),
777
 
            gdk_atom_intern("WINDOW", FALSE), 32,
778
 
            GDK_PROP_MODE_REPLACE, (guchar *)&xid, 1);
779
 
    
780
 
    screen_set_selection(desktop);
781
 
 
782
 
    xfce_desktop_monitors_changed(desktop->priv->gscreen, desktop);
783
 
    
784
 
    g_signal_connect(G_OBJECT(desktop->priv->gscreen), "size-changed",
785
 
            G_CALLBACK(screen_size_changed_cb), desktop);
786
 
    g_signal_connect(G_OBJECT(desktop->priv->gscreen), "composited-changed",
787
 
            G_CALLBACK(screen_composited_changed_cb), desktop);
788
 
    
789
 
    gtk_widget_add_events(GTK_WIDGET(desktop), GDK_EXPOSURE_MASK);
790
 
    
791
 
#ifdef ENABLE_DESKTOP_ICONS
792
 
    xfce_desktop_setup_icon_view(desktop);
793
 
#endif
794
 
 
795
 
    TRACE("exiting");
796
 
}
797
 
 
798
 
static void
799
 
xfce_desktop_unrealize(GtkWidget *widget)
800
 
{
801
 
    XfceDesktop *desktop = XFCE_DESKTOP(widget);
802
 
    guint i;
803
 
    GdkWindow *groot;
804
 
    gchar property_name[128];
805
 
    
806
 
    g_return_if_fail(XFCE_IS_DESKTOP(desktop));
807
 
    
808
 
    if(gtk_major_version > 2
809
 
       || (gtk_major_version == 2 && gtk_minor_version >= 13))
810
 
    {
811
 
        g_signal_handlers_disconnect_by_func(G_OBJECT(desktop->priv->gscreen),
812
 
                                             G_CALLBACK(xfce_desktop_monitors_changed),
813
 
                                             desktop);
814
 
    }
815
 
    
816
 
    if(GTK_WIDGET_MAPPED(widget))
817
 
        gtk_widget_unmap(widget);
818
 
    GTK_WIDGET_UNSET_FLAGS(widget, GTK_MAPPED);
819
 
    
820
 
    gtk_container_forall(GTK_CONTAINER(widget),
821
 
                         (GtkCallback)gtk_widget_unrealize,
822
 
                         NULL);
823
 
    
824
 
    g_signal_handlers_disconnect_by_func(G_OBJECT(desktop->priv->gscreen),
825
 
            G_CALLBACK(screen_size_changed_cb), desktop);
826
 
    g_signal_handlers_disconnect_by_func(G_OBJECT(desktop->priv->gscreen),
827
 
            G_CALLBACK(screen_composited_changed_cb), desktop);
828
 
 
829
 
    gdk_error_trap_push();
830
 
    
831
 
    groot = gdk_screen_get_root_window(desktop->priv->gscreen);
832
 
    gdk_property_delete(groot, gdk_atom_intern("XFCE_DESKTOP_WINDOW", FALSE));
833
 
    gdk_property_delete(groot, gdk_atom_intern("NAUTILUS_DESKTOP_WINDOW_ID", FALSE));
834
 
 
835
 
#if 0 /* see bug #7442 */
836
 
    gdk_property_delete(groot, gdk_atom_intern("_XROOTPMAP_ID", FALSE));
837
 
    gdk_property_delete(groot, gdk_atom_intern("ESETROOT_PMAP_ID", FALSE));
838
 
    gdk_window_set_back_pixmap(groot, NULL, FALSE);
839
 
#endif
840
 
 
841
 
    if(desktop->priv->backdrops) {
842
 
        for(i = 0; i < desktop->priv->nbackdrops; i++) {
843
 
            g_snprintf(property_name, 128, XFDESKTOP_IMAGE_FILE_FMT, i);
844
 
            gdk_property_delete(groot, gdk_atom_intern(property_name, FALSE));
845
 
            g_object_unref(G_OBJECT(desktop->priv->backdrops[i]));
846
 
        }
847
 
        g_free(desktop->priv->backdrops);
848
 
        desktop->priv->backdrops = NULL;
849
 
    }
850
 
 
851
 
    gdk_flush();
852
 
    gdk_error_trap_pop();
853
 
 
854
 
    g_object_unref(G_OBJECT(desktop->priv->bg_pixmap));
855
 
    desktop->priv->bg_pixmap = NULL;
856
 
    
857
 
    gtk_window_set_icon(GTK_WINDOW(widget), NULL);
858
 
    
859
 
    gtk_style_detach(widget->style);
860
 
    g_object_unref(G_OBJECT(widget->window));
861
 
    widget->window = NULL;
862
 
    
863
 
    gtk_selection_remove_all(widget);
864
 
    
865
 
    GTK_WIDGET_UNSET_FLAGS(widget, GTK_REALIZED);
866
 
}
867
 
 
868
 
static gboolean
869
 
xfce_desktop_button_press_event(GtkWidget *w,
870
 
                                GdkEventButton *evt)
871
 
{
872
 
    guint button = evt->button;
873
 
    guint state = evt->state;
874
 
    
875
 
    if(evt->type == GDK_BUTTON_PRESS) {
876
 
        if(button == 2 || (button == 1 && (state & GDK_SHIFT_MASK)
877
 
                           && (state & GDK_CONTROL_MASK)))
878
 
        {
879
 
            xfce_desktop_popup_secondary_root_menu(XFCE_DESKTOP(w),
880
 
                                                   button, evt->time);
881
 
            return TRUE;
882
 
        } else if(button == 3 || (button == 1 && (state & GDK_SHIFT_MASK))) {
883
 
            xfce_desktop_popup_root_menu(XFCE_DESKTOP(w),
884
 
                                         button, evt->time);
885
 
            return TRUE;
886
 
        }
887
 
    }
888
 
    
889
 
    return FALSE;
890
 
}
891
 
 
892
 
static gboolean
893
 
xfce_desktop_popup_menu(GtkWidget *w)
894
 
{
895
 
    GdkEventButton *evt;
896
 
    guint button, etime;
897
 
    
898
 
    evt = (GdkEventButton *)gtk_get_current_event();
899
 
    if(evt && GDK_BUTTON_PRESS == evt->type) {
900
 
        button = evt->button;
901
 
        etime = evt->time;
902
 
    } else {
903
 
        button = 0;
904
 
        etime = gtk_get_current_event_time();
905
 
    }
906
 
    
907
 
    xfce_desktop_popup_root_menu(XFCE_DESKTOP(w), button, etime);
908
 
    
909
 
    return TRUE;
910
 
}
911
 
 
912
 
static gboolean
913
 
xfce_desktop_expose(GtkWidget *w,
914
 
                    GdkEventExpose *evt)
915
 
{
916
 
    GList *children, *l;
917
 
    
918
 
    /*TRACE("entering");*/
919
 
    
920
 
    if(evt->count != 0)
921
 
        return FALSE;
922
 
    
923
 
    gdk_window_clear_area(w->window, evt->area.x, evt->area.y,
924
 
                          evt->area.width, evt->area.height);
925
 
    
926
 
    children = gtk_container_get_children(GTK_CONTAINER(w));
927
 
    for(l = children; l; l = l->next) {
928
 
        gtk_container_propagate_expose(GTK_CONTAINER(w),
929
 
                                       GTK_WIDGET(l->data),
930
 
                                       evt);
931
 
    }
932
 
    g_list_free(children);
933
 
    
934
 
    return FALSE;
935
 
}
936
 
 
937
 
static gboolean
938
 
xfce_desktop_delete_event(GtkWidget *w,
939
 
                          GdkEventAny *evt)
940
 
{
941
 
    if(XFCE_DESKTOP(w)->priv->session_logout_func)
942
 
        XFCE_DESKTOP(w)->priv->session_logout_func();
943
 
    
944
 
    return TRUE;
945
 
}
946
 
 
947
 
static void
948
 
xfce_desktop_style_set(GtkWidget *w,
949
 
                       GtkStyle *old_style)
950
 
{
951
 
    XfceDesktop *desktop = XFCE_DESKTOP(w);
952
 
#ifdef ENABLE_DESKTOP_ICONS
953
 
    gdouble old_font_size;
954
 
#endif
955
 
    
956
 
    if(GDK_IS_WINDOW(desktop->priv->bg_pixmap))
957
 
        gdk_window_set_back_pixmap(w->window, desktop->priv->bg_pixmap, FALSE);
958
 
    gtk_widget_queue_draw(w);
959
 
 
960
 
#ifdef ENABLE_DESKTOP_ICONS
961
 
    old_font_size = desktop->priv->system_font_size;
962
 
    if(xfce_desktop_ensure_system_font_size(desktop) != old_font_size
963
 
       && desktop->priv->icon_view && !desktop->priv->icons_font_size_set)
964
 
    {
965
 
        xfdesktop_icon_view_set_font_size(XFDESKTOP_ICON_VIEW(desktop->priv->icon_view),
966
 
                                          desktop->priv->system_font_size);
967
 
    }
968
 
#endif
969
 
}
970
 
 
971
 
static void
972
 
xfce_desktop_connect_settings(XfceDesktop *desktop)
973
 
{
974
 
    XfconfChannel *channel = desktop->priv->channel;
975
 
    gchar buf[1024];
976
 
 
977
 
    xfce_desktop_freeze_updates(desktop);
978
 
 
979
 
    g_strlcpy(buf, desktop->priv->property_prefix, sizeof(buf));
980
 
    g_strlcat(buf, "xinerama-stretch", sizeof(buf));
981
 
    xfconf_g_property_bind(channel, buf, G_TYPE_BOOLEAN,
982
 
                           G_OBJECT(desktop), "xinerama-stretch");
983
 
 
984
 
#ifdef ENABLE_DESKTOP_ICONS
985
 
#define ICONS_PREFIX "/desktop-icons/"
986
 
 
987
 
    xfconf_g_property_bind(channel, ICONS_PREFIX "style",
988
 
                           XFCE_TYPE_DESKTOP_ICON_STYLE,
989
 
                           G_OBJECT(desktop), "icon-style");
990
 
    xfconf_g_property_bind(channel, ICONS_PREFIX "icon-size", G_TYPE_UINT,
991
 
                           G_OBJECT(desktop), "icon-size");
992
 
    xfconf_g_property_bind(channel, ICONS_PREFIX "font-size", G_TYPE_UINT,
993
 
                           G_OBJECT(desktop), "icon-font-size");
994
 
    xfconf_g_property_bind(channel, ICONS_PREFIX "use-custom-font-size",
995
 
                           G_TYPE_BOOLEAN,
996
 
                           G_OBJECT(desktop), "icon-font-size-set");
997
 
#undef ICONS_PREFIX
998
 
#endif
999
 
 
1000
 
    xfce_desktop_thaw_updates(desktop);
1001
 
}
1002
 
 
1003
 
static void
1004
 
xfce_desktop_image_filename_changed(XfconfChannel *channel,
1005
 
                                    const gchar *property,
1006
 
                                    const GValue *value,
1007
 
                                    gpointer user_data)
1008
 
{
1009
 
    XfceDesktop *desktop = user_data;
1010
 
    gchar *p;
1011
 
    const gchar *filename;
1012
 
    gint monitor;
1013
 
    XfceBackdrop *backdrop;
1014
 
 
1015
 
    p = strstr(property, "/monitor");
1016
 
    if(!p)
1017
 
        return;
1018
 
 
1019
 
    monitor = atoi(p + 8);
1020
 
    if(monitor < 0 || monitor >= gdk_screen_get_n_monitors(desktop->priv->gscreen))
1021
 
        return;
1022
 
 
1023
 
    if(desktop->priv->xinerama_stretch && monitor != 0)
1024
 
        return;
1025
 
    backdrop = desktop->priv->backdrops[monitor];
1026
 
 
1027
 
    if(!G_VALUE_HOLDS_STRING(value))
1028
 
        filename = DEFAULT_BACKDROP;
1029
 
    else
1030
 
        filename = g_value_get_string(value);
1031
 
    if(G_LIKELY(filename && *filename)) {
1032
 
        if(xfdesktop_backdrop_list_is_valid(filename)) {
1033
 
            gchar *backdrop_file;
1034
 
            GError *error = NULL;
1035
 
            
1036
 
            backdrop_file = xfdesktop_backdrop_list_choose_random(filename,
1037
 
                                                                  &error);
1038
 
#if 0
1039
 
            if(!backdrop_file && !xfdesktop_backdrop_list_is_valid(filename)) {
1040
 
                gchar *primary = g_strdup_printf(_("Unable to load image from backdrop list file \"%s\""),
1041
 
                                                 filename);
1042
 
                xfce_message_dialog(GTK_WINDOW(desktop), _("Desktop Error"),
1043
 
                                    GTK_STOCK_DIALOG_ERROR, primary,
1044
 
                                    error->message,
1045
 
                                    GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT,
1046
 
                                    NULL);
1047
 
                g_error_free(error);
1048
 
                g_free(primary);
1049
 
            }
1050
 
#endif
1051
 
 
1052
 
            xfce_backdrop_set_image_filename(backdrop, backdrop_file);
1053
 
            g_free(backdrop_file);
1054
 
        } else
1055
 
            xfce_backdrop_set_image_filename(backdrop, filename);
1056
 
    }
1057
 
}
1058
 
 
1059
 
static void
1060
 
xfce_desktop_connect_backdrop_settings(XfceDesktop *desktop,
1061
 
                                       XfceBackdrop *backdrop,
1062
 
                                       guint monitor)
1063
 
{
1064
 
    XfconfChannel *channel = desktop->priv->channel;
1065
 
    char buf[1024], buf1[1024];
1066
 
    gint pp_len;
1067
 
    GValue value = { 0, };
1068
 
 
1069
 
    g_snprintf(buf, sizeof(buf), "%smonitor%d/",
1070
 
               desktop->priv->property_prefix, monitor);
1071
 
    pp_len = strlen(buf);
1072
 
 
1073
 
    g_strlcat(buf, "color-style", sizeof(buf));
1074
 
    xfconf_g_property_bind(channel, buf, XFCE_TYPE_BACKDROP_COLOR_STYLE,
1075
 
                           G_OBJECT(backdrop), "color-style");
1076
 
 
1077
 
    buf[pp_len] = 0;
1078
 
    g_strlcat(buf, "color1", sizeof(buf));
1079
 
    xfconf_g_property_bind_gdkcolor(channel, buf,
1080
 
                                    G_OBJECT(backdrop), "first-color");
1081
 
 
1082
 
    buf[pp_len] = 0;
1083
 
    g_strlcat(buf, "color2", sizeof(buf));
1084
 
    xfconf_g_property_bind_gdkcolor(channel, buf,
1085
 
                                    G_OBJECT(backdrop), "second-color");
1086
 
 
1087
 
    buf[pp_len] = 0;
1088
 
    g_strlcat(buf, "image-show", sizeof(buf));
1089
 
    xfconf_g_property_bind(channel, buf, G_TYPE_BOOLEAN,
1090
 
                           G_OBJECT(backdrop), "show-image");
1091
 
 
1092
 
    buf[pp_len] = 0;
1093
 
    g_strlcat(buf, "image-style", sizeof(buf));
1094
 
    xfconf_g_property_bind(channel, buf, XFCE_TYPE_BACKDROP_IMAGE_STYLE,
1095
 
                           G_OBJECT(backdrop), "image-style");
1096
 
 
1097
 
    buf[pp_len] = 0;
1098
 
    g_strlcat(buf, "brightness", sizeof(buf));
1099
 
    xfconf_g_property_bind(channel, buf, G_TYPE_INT,
1100
 
                           G_OBJECT(backdrop), "brightness");
1101
 
 
1102
 
    buf[pp_len] = 0;
1103
 
    g_strlcat(buf, "saturation", sizeof(buf));
1104
 
    xfconf_g_property_bind(channel, buf, G_TYPE_DOUBLE,
1105
 
                           G_OBJECT(backdrop), "saturation");
1106
 
 
1107
 
    /* the image filename could be an image or a backdrop list, so we
1108
 
     * can't just bind the property directly */
1109
 
    buf[pp_len] = 0;
1110
 
    g_strlcat(buf, "image-path", sizeof(buf));
1111
 
    g_strlcpy(buf1, "property-changed::", sizeof(buf1));
1112
 
    g_strlcat(buf1, buf, sizeof(buf1));
1113
 
    g_signal_connect(G_OBJECT(channel), buf1,
1114
 
                     G_CALLBACK(xfce_desktop_image_filename_changed), desktop);
1115
 
    if(xfconf_channel_get_property(channel, buf, &value)) {
1116
 
        xfce_desktop_image_filename_changed(channel, buf, &value, desktop);
1117
 
        g_value_unset(&value);
1118
 
    }
1119
 
}
1120
 
 
1121
 
 
1122
 
 
1123
 
/* public api */
1124
 
 
1125
 
/**
1126
 
 * xfce_desktop_new:
1127
 
 * @gscreen: The current #GdkScreen.
1128
 
 * @channel: An #XfconfChannel to use for settings.
1129
 
 * @property_prefix: String prefix for per-screen properties.
1130
 
 *
1131
 
 * Creates a new #XfceDesktop for the specified #GdkScreen.  If @gscreen is
1132
 
 * %NULL, the default screen will be used.
1133
 
 *
1134
 
 * Return value: A new #XfceDesktop.
1135
 
 **/
1136
 
GtkWidget *
1137
 
xfce_desktop_new(GdkScreen *gscreen,
1138
 
                 XfconfChannel *channel,
1139
 
                 const gchar *property_prefix)
1140
 
{
1141
 
    XfceDesktop *desktop;
1142
 
    
1143
 
    g_return_val_if_fail(channel && property_prefix, NULL);
1144
 
 
1145
 
    desktop = g_object_new(XFCE_TYPE_DESKTOP, NULL);
1146
 
 
1147
 
    if(!gscreen)
1148
 
        gscreen = gdk_display_get_default_screen(gdk_display_get_default());
1149
 
    gtk_window_set_screen(GTK_WINDOW(desktop), gscreen);
1150
 
    desktop->priv->gscreen = gscreen;
1151
 
    
1152
 
    desktop->priv->channel = g_object_ref(G_OBJECT(channel));
1153
 
    desktop->priv->property_prefix = g_strdup(property_prefix);
1154
 
 
1155
 
    xfce_desktop_connect_settings(desktop);
1156
 
    
1157
 
    return GTK_WIDGET(desktop);
1158
 
}
1159
 
 
1160
 
guint
1161
 
xfce_desktop_get_n_monitors(XfceDesktop *desktop)
1162
 
{
1163
 
    g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), 0);
1164
 
    
1165
 
    return desktop->priv->nbackdrops;
1166
 
}
1167
 
 
1168
 
gint
1169
 
xfce_desktop_get_width(XfceDesktop *desktop)
1170
 
{
1171
 
    g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), -1);
1172
 
    
1173
 
    return gdk_screen_get_width(desktop->priv->gscreen);
1174
 
}
1175
 
 
1176
 
gint
1177
 
xfce_desktop_get_height(XfceDesktop *desktop)
1178
 
{
1179
 
    g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), -1);
1180
 
    
1181
 
    return gdk_screen_get_height(desktop->priv->gscreen);
1182
 
}
1183
 
 
1184
 
void
1185
 
xfce_desktop_set_xinerama_stretch(XfceDesktop *desktop,
1186
 
                                  gboolean stretch)
1187
 
{
1188
 
    g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1189
 
    
1190
 
    if(stretch == desktop->priv->xinerama_stretch)
1191
 
        return;
1192
 
    
1193
 
    desktop->priv->xinerama_stretch = stretch;
1194
 
    
1195
 
    if(!desktop->priv->updates_frozen)
1196
 
        xfce_desktop_monitors_changed(desktop->priv->gscreen, desktop);
1197
 
}
1198
 
 
1199
 
gboolean
1200
 
xfce_desktop_get_xinerama_stretch(XfceDesktop *desktop)
1201
 
{
1202
 
    g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), FALSE);
1203
 
    return desktop->priv->xinerama_stretch;
1204
 
}
1205
 
 
1206
 
void
1207
 
xfce_desktop_set_icon_style(XfceDesktop *desktop,
1208
 
                            XfceDesktopIconStyle style)
1209
 
{
1210
 
    g_return_if_fail(XFCE_IS_DESKTOP(desktop)
1211
 
                     && style <= XFCE_DESKTOP_ICON_STYLE_FILES);
1212
 
    
1213
 
#ifdef ENABLE_DESKTOP_ICONS
1214
 
    if(style == desktop->priv->icons_style)
1215
 
        return;
1216
 
    
1217
 
    if(desktop->priv->icon_view) {
1218
 
        gtk_widget_destroy(desktop->priv->icon_view);
1219
 
        desktop->priv->icon_view = NULL;
1220
 
    }
1221
 
    
1222
 
    desktop->priv->icons_style = style;
1223
 
    if(GTK_WIDGET_REALIZED(desktop))
1224
 
        xfce_desktop_setup_icon_view(desktop);
1225
 
#endif
1226
 
}
1227
 
 
1228
 
XfceDesktopIconStyle
1229
 
xfce_desktop_get_icon_style(XfceDesktop *desktop)
1230
 
{
1231
 
    g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), XFCE_DESKTOP_ICON_STYLE_NONE);
1232
 
    
1233
 
#ifdef ENABLE_DESKTOP_ICONS
1234
 
    return desktop->priv->icons_style;
1235
 
#else
1236
 
    return XFCE_DESKTOP_ICON_STYLE_NONE;
1237
 
#endif
1238
 
}
1239
 
 
1240
 
void
1241
 
xfce_desktop_set_icon_size(XfceDesktop *desktop,
1242
 
                           guint icon_size)
1243
 
{
1244
 
    g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1245
 
    
1246
 
#ifdef ENABLE_DESKTOP_ICONS
1247
 
    if(icon_size == desktop->priv->icons_size)
1248
 
        return;
1249
 
    
1250
 
    desktop->priv->icons_size = icon_size;
1251
 
    
1252
 
    if(desktop->priv->icon_view) {
1253
 
        xfdesktop_icon_view_set_icon_size(XFDESKTOP_ICON_VIEW(desktop->priv->icon_view),
1254
 
                                          icon_size);
1255
 
    }
1256
 
#endif
1257
 
}
1258
 
 
1259
 
void
1260
 
xfce_desktop_set_icon_font_size(XfceDesktop *desktop,
1261
 
                                guint font_size_points)
1262
 
{
1263
 
    g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1264
 
    
1265
 
#ifdef ENABLE_DESKTOP_ICONS
1266
 
    if(font_size_points == desktop->priv->icons_font_size)
1267
 
        return;
1268
 
    
1269
 
    desktop->priv->icons_font_size = font_size_points;
1270
 
    
1271
 
    if(desktop->priv->icons_font_size_set && desktop->priv->icon_view) {
1272
 
        xfdesktop_icon_view_set_font_size(XFDESKTOP_ICON_VIEW(desktop->priv->icon_view),
1273
 
                                          font_size_points);
1274
 
    }
1275
 
#endif
1276
 
}
1277
 
 
1278
 
void
1279
 
xfce_desktop_set_use_icon_font_size(XfceDesktop *desktop,
1280
 
                                    gboolean use_icon_font_size)
1281
 
{
1282
 
    g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1283
 
    
1284
 
#ifdef ENABLE_DESKTOP_ICONS
1285
 
    if(use_icon_font_size == desktop->priv->icons_font_size_set)
1286
 
        return;
1287
 
    
1288
 
    desktop->priv->icons_font_size_set = use_icon_font_size;
1289
 
    
1290
 
    if(desktop->priv->icon_view) {
1291
 
        if(!use_icon_font_size) {
1292
 
            xfce_desktop_ensure_system_font_size(desktop);
1293
 
            xfdesktop_icon_view_set_font_size(XFDESKTOP_ICON_VIEW(desktop->priv->icon_view),
1294
 
                                              desktop->priv->system_font_size);
1295
 
        } else {
1296
 
            xfdesktop_icon_view_set_font_size(XFDESKTOP_ICON_VIEW(desktop->priv->icon_view),
1297
 
                                              desktop->priv->icons_font_size);
1298
 
        }
1299
 
    }
1300
 
#endif
1301
 
}
1302
 
 
1303
 
void
1304
 
xfce_desktop_set_session_logout_func(XfceDesktop *desktop,
1305
 
                                     SessionLogoutFunc logout_func)
1306
 
{
1307
 
    g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1308
 
    desktop->priv->session_logout_func = logout_func;
1309
 
}
1310
 
 
1311
 
void
1312
 
xfce_desktop_freeze_updates(XfceDesktop *desktop)
1313
 
{
1314
 
    g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1315
 
    desktop->priv->updates_frozen = TRUE;
1316
 
}
1317
 
 
1318
 
void
1319
 
xfce_desktop_thaw_updates(XfceDesktop *desktop)
1320
 
{
1321
 
    g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1322
 
    
1323
 
    desktop->priv->updates_frozen = FALSE;
1324
 
    if(GTK_WIDGET_REALIZED(desktop))
1325
 
        xfce_desktop_monitors_changed(desktop->priv->gscreen, desktop);
1326
 
}
1327
 
 
1328
 
XfceBackdrop *
1329
 
xfce_desktop_peek_backdrop(XfceDesktop *desktop,
1330
 
                           guint monitor)
1331
 
{
1332
 
    g_return_val_if_fail(XFCE_IS_DESKTOP(desktop)
1333
 
                         && GTK_WIDGET_REALIZED(GTK_WIDGET(desktop))
1334
 
                         && monitor < desktop->priv->nbackdrops, NULL);
1335
 
    return desktop->priv->backdrops[monitor];
1336
 
}
1337
 
 
1338
 
static gboolean
1339
 
xfce_desktop_menu_destroy_idled(gpointer data)
1340
 
{
1341
 
    gtk_widget_destroy(GTK_WIDGET(data));
1342
 
    return FALSE;
1343
 
}
1344
 
 
1345
 
static void
1346
 
xfce_desktop_do_menu_popup(XfceDesktop *desktop,
1347
 
                           guint button,
1348
 
                           guint activate_time,
1349
 
                           guint populate_signal)
1350
 
{
1351
 
    GdkScreen *screen;
1352
 
    GtkWidget *menu;
1353
 
    GList *menu_children;
1354
 
    
1355
 
    TRACE("entering");
1356
 
    
1357
 
    if(gtk_widget_has_screen(GTK_WIDGET(desktop)))
1358
 
        screen = gtk_widget_get_screen(GTK_WIDGET(desktop));
1359
 
    else
1360
 
        screen = gdk_display_get_default_screen(gdk_display_get_default());
1361
 
 
1362
 
    if(xfdesktop_popup_grab_available(gdk_screen_get_root_window(screen),
1363
 
                                      activate_time))
1364
 
    {
1365
 
        menu = gtk_menu_new();
1366
 
        gtk_menu_set_screen(GTK_MENU(menu), screen);
1367
 
        g_signal_connect_swapped(G_OBJECT(menu), "deactivate",
1368
 
                                 G_CALLBACK(g_idle_add),
1369
 
                                 (gpointer)xfce_desktop_menu_destroy_idled);
1370
 
 
1371
 
        g_signal_emit(G_OBJECT(desktop), populate_signal, 0, menu);
1372
 
 
1373
 
        /* if nobody populated the menu, don't do anything */
1374
 
        menu_children = gtk_container_get_children(GTK_CONTAINER(menu));
1375
 
        if(!menu_children) {
1376
 
            gtk_widget_destroy(menu);
1377
 
            return;
1378
 
        }
1379
 
 
1380
 
        g_list_free(menu_children);
1381
 
 
1382
 
        gtk_menu_attach_to_widget(GTK_MENU(menu), GTK_WIDGET(desktop), NULL);
1383
 
 
1384
 
        /* bug #3652: for some reason passing the correct button here breaks
1385
 
         * on some systems but not others.  always pass 0 for now. */
1386
 
        gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 0,
1387
 
                       activate_time);
1388
 
    } else
1389
 
        g_critical("Unable to get keyboard/mouse grab. Unable to pop up menu");
1390
 
}
1391
 
 
1392
 
void
1393
 
xfce_desktop_popup_root_menu(XfceDesktop *desktop,
1394
 
                             guint button,
1395
 
                             guint activate_time)
1396
 
{
1397
 
    xfce_desktop_do_menu_popup(desktop, button, activate_time,
1398
 
                               signals[SIG_POPULATE_ROOT_MENU]);
1399
 
}
1400
 
 
1401
 
void
1402
 
xfce_desktop_popup_secondary_root_menu(XfceDesktop *desktop,
1403
 
                                       guint button,
1404
 
                                       guint activate_time)
1405
 
{
1406
 
    xfce_desktop_do_menu_popup(desktop, button, activate_time,
1407
 
                               signals[SIG_POPULATE_SECONDARY_ROOT_MENU]);
1408
 
}
1409
 
 
1410
 
void
1411
 
xfce_desktop_refresh(XfceDesktop *desktop)
1412
 
{
1413
 
    gchar buf[256];
1414
 
    guint i, max;
1415
 
 
1416
 
    g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1417
 
 
1418
 
    if(!GTK_WIDGET_REALIZED(desktop))
1419
 
        return;
1420
 
 
1421
 
    /* reload image */
1422
 
    if(desktop->priv->xinerama_stretch)
1423
 
        max = 1;
1424
 
    else
1425
 
        max = desktop->priv->nbackdrops;
1426
 
    for(i = 0; i < max; ++i) {
1427
 
        GValue val = { 0, };
1428
 
 
1429
 
        g_snprintf(buf, sizeof(buf), "%smonitor%d/image-path",
1430
 
                   desktop->priv->property_prefix, i);
1431
 
        xfconf_channel_get_property(desktop->priv->channel, buf, &val);
1432
 
 
1433
 
        xfce_desktop_image_filename_changed(desktop->priv->channel, buf,
1434
 
                                            &val, desktop);
1435
 
 
1436
 
        if(G_VALUE_TYPE(&val))
1437
 
            g_value_unset(&val);
1438
 
    }
1439
 
 
1440
 
#ifdef ENABLE_DESKTOP_ICONS
1441
 
    /* reload icon view */
1442
 
    if(desktop->priv->icon_view) {
1443
 
        gtk_widget_destroy(desktop->priv->icon_view);
1444
 
        desktop->priv->icon_view = NULL;
1445
 
    }
1446
 
    xfce_desktop_setup_icon_view(desktop);
1447
 
#endif
1448
 
}