~noskcaj/ubuntu/trusty/xfdesktop4/merge

« back to all changes in this revision

Viewing changes to .pc/xubuntu_improve-nautilus-interactions.patch/src/xfce-desktop.c

  • Committer: Package Import Robot
  • Author(s): Lionel Le Folgoc
  • Date: 2012-01-09 19:22:54 UTC
  • Revision ID: package-import@ubuntu.com-20120109192254-6m84ewh01sb82gdc
Tags: 4.8.3-1ubuntu4
* debian/patches:
  - xubuntu_avoid-multiple-instances.patch: updated, and simplified.
  - xubuntu_improve-nautilus-interactions.patch: added, should prevent
    nautilus from taking over the desktop if xfdesktop is running.

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];
 
478
    Atom 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
    /* the previous check in src/main.c occurs too early, so workaround by
 
488
     * adding this one. Hopefully it should help for lp #329616 */
 
489
    if(XGetSelectionOwner(GDK_DISPLAY(), selection_atom) != None) {
 
490
        g_warning("%s: already running, quitting.", PACKAGE);
 
491
        exit(0);
 
492
    }
 
493
 
 
494
    XSelectInput(GDK_DISPLAY(), xwin, PropertyChangeMask | ButtonPressMask);
 
495
    XSetSelectionOwner(GDK_DISPLAY(), selection_atom, xwin, GDK_CURRENT_TIME);
 
496
 
 
497
    /* Check to see if we managed to claim the selection. If not,
 
498
     * we treat it as if we got it then immediately lost it */
 
499
    if(XGetSelectionOwner(GDK_DISPLAY(), selection_atom) == xwin) {
 
500
        XClientMessageEvent xev;
 
501
        Window xroot = GDK_WINDOW_XID(gdk_screen_get_root_window(desktop->priv->gscreen));
 
502
        
 
503
        xev.type = ClientMessage;
 
504
        xev.window = xroot;
 
505
        xev.message_type = manager_atom;
 
506
        xev.format = 32;
 
507
        xev.data.l[0] = GDK_CURRENT_TIME;
 
508
        xev.data.l[1] = selection_atom;
 
509
        xev.data.l[2] = xwin;
 
510
        xev.data.l[3] = 0;    /* manager specific data */
 
511
        xev.data.l[4] = 0;    /* manager specific data */
 
512
 
 
513
        XSendEvent(GDK_DISPLAY(), xroot, False, StructureNotifyMask, (XEvent *)&xev);
 
514
    } else {
 
515
        g_error("%s: could not set selection ownership", PACKAGE);
 
516
        exit(1);
 
517
    }
 
518
}
 
519
 
 
520
 
 
521
 
 
522
/* gobject-related functions */
 
523
 
 
524
 
 
525
G_DEFINE_TYPE(XfceDesktop, xfce_desktop, GTK_TYPE_WINDOW)
 
526
 
 
527
 
 
528
static void
 
529
xfce_desktop_class_init(XfceDesktopClass *klass)
 
530
{
 
531
    GObjectClass *gobject_class = (GObjectClass *)klass;
 
532
    GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
 
533
    
 
534
    g_type_class_add_private(klass, sizeof(XfceDesktopPriv));
 
535
    
 
536
    gobject_class->finalize = xfce_desktop_finalize;
 
537
    gobject_class->set_property = xfce_desktop_set_property;
 
538
    gobject_class->get_property = xfce_desktop_get_property;
 
539
    
 
540
    widget_class->realize = xfce_desktop_realize;
 
541
    widget_class->unrealize = xfce_desktop_unrealize;
 
542
    widget_class->button_press_event = xfce_desktop_button_press_event;
 
543
    widget_class->expose_event = xfce_desktop_expose;
 
544
    widget_class->delete_event = xfce_desktop_delete_event;
 
545
    widget_class->popup_menu = xfce_desktop_popup_menu;
 
546
    widget_class->style_set = xfce_desktop_style_set;
 
547
    
 
548
    signals[SIG_POPULATE_ROOT_MENU] = g_signal_new("populate-root-menu",
 
549
                                                   XFCE_TYPE_DESKTOP,
 
550
                                                   G_SIGNAL_RUN_LAST,
 
551
                                                   G_STRUCT_OFFSET(XfceDesktopClass,
 
552
                                                                   populate_root_menu),
 
553
                                                   NULL, NULL,
 
554
                                                   g_cclosure_marshal_VOID__OBJECT,
 
555
                                                   G_TYPE_NONE, 1,
 
556
                                                   GTK_TYPE_MENU_SHELL);
 
557
    
 
558
    signals[SIG_POPULATE_SECONDARY_ROOT_MENU] = g_signal_new("populate-secondary-root-menu",
 
559
                                                             XFCE_TYPE_DESKTOP,
 
560
                                                             G_SIGNAL_RUN_LAST,
 
561
                                                             G_STRUCT_OFFSET(XfceDesktopClass,
 
562
                                                                             populate_secondary_root_menu),
 
563
                                                             NULL, NULL,
 
564
                                                             g_cclosure_marshal_VOID__OBJECT,
 
565
                                                             G_TYPE_NONE, 1,
 
566
                                                             GTK_TYPE_MENU_SHELL);
 
567
 
 
568
#define XFDESKTOP_PARAM_FLAGS  (G_PARAM_READWRITE \
 
569
                                | G_PARAM_CONSTRUCT \
 
570
                                | G_PARAM_STATIC_NAME \
 
571
                                | G_PARAM_STATIC_NICK \
 
572
                                | G_PARAM_STATIC_BLURB)
 
573
 
 
574
    g_object_class_install_property(gobject_class, PROP_XINERAMA_STRETCH,
 
575
                                    g_param_spec_boolean("xinerama-stretch",
 
576
                                                         "xinerama stretch",
 
577
                                                         "xinerama stretch",
 
578
                                                         FALSE,
 
579
                                                         XFDESKTOP_PARAM_FLAGS));
 
580
 
 
581
#ifdef ENABLE_DESKTOP_ICONS
 
582
    g_object_class_install_property(gobject_class, PROP_ICON_STYLE,
 
583
                                    g_param_spec_enum("icon-style",
 
584
                                                      "icon style",
 
585
                                                      "icon style",
 
586
                                                      XFCE_TYPE_DESKTOP_ICON_STYLE,
 
587
#ifdef ENABLE_FILE_ICONS
 
588
                                                      XFCE_DESKTOP_ICON_STYLE_FILES,
 
589
#else
 
590
                                                      XFCE_DESKTOP_ICON_STYLE_WINDOWS,
 
591
#endif
 
592
                                                      XFDESKTOP_PARAM_FLAGS));
 
593
 
 
594
    g_object_class_install_property(gobject_class, PROP_ICON_SIZE,
 
595
                                    g_param_spec_uint("icon-size",
 
596
                                                      "icon size",
 
597
                                                      "icon size",
 
598
                                                      8, 192, 36,
 
599
                                                      XFDESKTOP_PARAM_FLAGS));
 
600
 
 
601
    g_object_class_install_property(gobject_class, PROP_ICON_FONT_SIZE,
 
602
                                    g_param_spec_uint("icon-font-size",
 
603
                                                      "icon font size",
 
604
                                                      "icon font size",
 
605
                                                      4, 144, 12,
 
606
                                                      XFDESKTOP_PARAM_FLAGS));
 
607
 
 
608
    g_object_class_install_property(gobject_class, PROP_ICON_FONT_SIZE_SET,
 
609
                                    g_param_spec_boolean("icon-font-size-set",
 
610
                                                         "icon font size set",
 
611
                                                         "icon font size set",
 
612
                                                         FALSE,
 
613
                                                         XFDESKTOP_PARAM_FLAGS));
 
614
#endif
 
615
#undef XFDESKTOP_PARAM_FLAGS
 
616
}
 
617
 
 
618
static void
 
619
xfce_desktop_init(XfceDesktop *desktop)
 
620
{
 
621
    desktop->priv = G_TYPE_INSTANCE_GET_PRIVATE(desktop, XFCE_TYPE_DESKTOP,
 
622
                                                XfceDesktopPriv);
 
623
    GTK_WINDOW(desktop)->type = GTK_WINDOW_TOPLEVEL;
 
624
    
 
625
    gtk_window_set_type_hint(GTK_WINDOW(desktop), GDK_WINDOW_TYPE_HINT_DESKTOP);
 
626
    gtk_window_set_accept_focus(GTK_WINDOW(desktop), FALSE);
 
627
    gtk_window_set_has_resize_grip(GTK_WINDOW(desktop), FALSE);
 
628
}
 
629
 
 
630
static void
 
631
xfce_desktop_finalize(GObject *object)
 
632
{
 
633
    XfceDesktop *desktop = XFCE_DESKTOP(object);
 
634
    
 
635
    g_object_unref(G_OBJECT(desktop->priv->channel));
 
636
    g_free(desktop->priv->property_prefix);
 
637
    
 
638
    G_OBJECT_CLASS(xfce_desktop_parent_class)->finalize(object);
 
639
}
 
640
 
 
641
static void
 
642
xfce_desktop_set_property(GObject *object,
 
643
                          guint property_id,
 
644
                          const GValue *value,
 
645
                          GParamSpec *pspec)
 
646
{
 
647
    XfceDesktop *desktop = XFCE_DESKTOP(object);
 
648
 
 
649
    switch(property_id) {
 
650
        case PROP_XINERAMA_STRETCH:
 
651
            xfce_desktop_set_xinerama_stretch(desktop,
 
652
                                              g_value_get_boolean(value));
 
653
            break;
 
654
 
 
655
#ifdef ENABLE_DESKTOP_ICONS
 
656
        case PROP_ICON_STYLE:
 
657
            xfce_desktop_set_icon_style(desktop,
 
658
                                        g_value_get_enum(value));
 
659
            break;
 
660
 
 
661
        case PROP_ICON_SIZE:
 
662
            xfce_desktop_set_icon_size(desktop,
 
663
                                       g_value_get_uint(value));
 
664
            break;
 
665
 
 
666
        case PROP_ICON_FONT_SIZE:
 
667
            xfce_desktop_set_icon_font_size(desktop,
 
668
                                            g_value_get_uint(value));
 
669
            break;
 
670
 
 
671
        case PROP_ICON_FONT_SIZE_SET:
 
672
            xfce_desktop_set_use_icon_font_size(desktop,
 
673
                                                g_value_get_boolean(value));
 
674
            break;
 
675
 
 
676
#endif
 
677
        default:
 
678
            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
 
679
            break;
 
680
    }
 
681
}
 
682
 
 
683
static void
 
684
xfce_desktop_get_property(GObject *object,
 
685
                          guint property_id,
 
686
                          GValue *value,
 
687
                          GParamSpec *pspec)
 
688
{
 
689
    XfceDesktop *desktop = XFCE_DESKTOP(object);
 
690
 
 
691
    switch(property_id) {
 
692
        case PROP_XINERAMA_STRETCH:
 
693
            g_value_set_boolean(value, desktop->priv->xinerama_stretch);
 
694
            break;
 
695
 
 
696
#ifdef ENABLE_DESKTOP_ICONS
 
697
        case PROP_ICON_STYLE:
 
698
            g_value_set_enum(value, desktop->priv->icons_style);
 
699
            break;
 
700
 
 
701
        case PROP_ICON_SIZE:
 
702
            g_value_set_uint(value, desktop->priv->icons_size);
 
703
            break;
 
704
 
 
705
        case PROP_ICON_FONT_SIZE:
 
706
            g_value_set_uint(value, desktop->priv->icons_font_size);
 
707
            break;
 
708
 
 
709
        case PROP_ICON_FONT_SIZE_SET:
 
710
            g_value_set_boolean(value, desktop->priv->icons_font_size_set);
 
711
            break;
 
712
 
 
713
#endif
 
714
        default:
 
715
            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
 
716
            break;
 
717
    }
 
718
}
 
719
 
 
720
static void
 
721
xfce_desktop_realize(GtkWidget *widget)
 
722
{
 
723
    XfceDesktop *desktop = XFCE_DESKTOP(widget);
 
724
    GdkAtom atom;
 
725
    gint sw, sh;
 
726
    Window xid;
 
727
    GdkWindow *groot;
 
728
    
 
729
    TRACE("entering");
 
730
 
 
731
    gtk_window_set_screen(GTK_WINDOW(desktop), desktop->priv->gscreen);
 
732
    sw = gdk_screen_get_width(desktop->priv->gscreen);
 
733
    sh = gdk_screen_get_height(desktop->priv->gscreen);
 
734
    if(gtk_major_version > 2
 
735
       || (gtk_major_version == 2 && gtk_minor_version >= 13))
 
736
    {
 
737
        g_signal_connect(G_OBJECT(desktop->priv->gscreen),
 
738
                         "monitors-changed",
 
739
                         G_CALLBACK(xfce_desktop_monitors_changed),
 
740
                         desktop);
 
741
    }
 
742
    
 
743
    /* chain up */
 
744
    GTK_WIDGET_CLASS(xfce_desktop_parent_class)->realize(widget);
 
745
    
 
746
    gtk_window_set_title(GTK_WINDOW(desktop), _("Desktop"));
 
747
    
 
748
    gtk_widget_set_size_request(GTK_WIDGET(desktop), sw, sh);
 
749
    gtk_window_move(GTK_WINDOW(desktop), 0, 0);
 
750
    
 
751
    atom = gdk_atom_intern("_NET_WM_WINDOW_TYPE_DESKTOP", FALSE);
 
752
    gdk_property_change(GTK_WIDGET(desktop)->window,
 
753
            gdk_atom_intern("_NET_WM_WINDOW_TYPE", FALSE),
 
754
            gdk_atom_intern("ATOM", FALSE), 32,
 
755
            GDK_PROP_MODE_REPLACE, (guchar *)&atom, 1);
 
756
 
 
757
    xid = GDK_WINDOW_XID(GTK_WIDGET(desktop)->window);
 
758
    groot = gdk_screen_get_root_window(desktop->priv->gscreen);
 
759
    
 
760
    gdk_property_change(groot,
 
761
            gdk_atom_intern("XFCE_DESKTOP_WINDOW", FALSE),
 
762
            gdk_atom_intern("WINDOW", FALSE), 32,
 
763
            GDK_PROP_MODE_REPLACE, (guchar *)&xid, 1);
 
764
    
 
765
    gdk_property_change(groot,
 
766
            gdk_atom_intern("NAUTILUS_DESKTOP_WINDOW_ID", FALSE),
 
767
            gdk_atom_intern("WINDOW", FALSE), 32,
 
768
            GDK_PROP_MODE_REPLACE, (guchar *)&xid, 1);
 
769
    
 
770
    screen_set_selection(desktop);
 
771
 
 
772
    xfce_desktop_monitors_changed(desktop->priv->gscreen, desktop);
 
773
    
 
774
    g_signal_connect(G_OBJECT(desktop->priv->gscreen), "size-changed",
 
775
            G_CALLBACK(screen_size_changed_cb), desktop);
 
776
    g_signal_connect(G_OBJECT(desktop->priv->gscreen), "composited-changed",
 
777
            G_CALLBACK(screen_composited_changed_cb), desktop);
 
778
    
 
779
    gtk_widget_add_events(GTK_WIDGET(desktop), GDK_EXPOSURE_MASK);
 
780
    
 
781
#ifdef ENABLE_DESKTOP_ICONS
 
782
    xfce_desktop_setup_icon_view(desktop);
 
783
#endif
 
784
 
 
785
    TRACE("exiting");
 
786
}
 
787
 
 
788
static void
 
789
xfce_desktop_unrealize(GtkWidget *widget)
 
790
{
 
791
    XfceDesktop *desktop = XFCE_DESKTOP(widget);
 
792
    guint i;
 
793
    GdkWindow *groot;
 
794
    gchar property_name[128];
 
795
    
 
796
    g_return_if_fail(XFCE_IS_DESKTOP(desktop));
 
797
    
 
798
    if(gtk_major_version > 2
 
799
       || (gtk_major_version == 2 && gtk_minor_version >= 13))
 
800
    {
 
801
        g_signal_handlers_disconnect_by_func(G_OBJECT(desktop->priv->gscreen),
 
802
                                             G_CALLBACK(xfce_desktop_monitors_changed),
 
803
                                             desktop);
 
804
    }
 
805
    
 
806
    if(GTK_WIDGET_MAPPED(widget))
 
807
        gtk_widget_unmap(widget);
 
808
    GTK_WIDGET_UNSET_FLAGS(widget, GTK_MAPPED);
 
809
    
 
810
    gtk_container_forall(GTK_CONTAINER(widget),
 
811
                         (GtkCallback)gtk_widget_unrealize,
 
812
                         NULL);
 
813
    
 
814
    g_signal_handlers_disconnect_by_func(G_OBJECT(desktop->priv->gscreen),
 
815
            G_CALLBACK(screen_size_changed_cb), desktop);
 
816
    g_signal_handlers_disconnect_by_func(G_OBJECT(desktop->priv->gscreen),
 
817
            G_CALLBACK(screen_composited_changed_cb), desktop);
 
818
 
 
819
    gdk_error_trap_push();
 
820
    
 
821
    groot = gdk_screen_get_root_window(desktop->priv->gscreen);
 
822
    gdk_property_delete(groot, gdk_atom_intern("XFCE_DESKTOP_WINDOW", FALSE));
 
823
    gdk_property_delete(groot, gdk_atom_intern("NAUTILUS_DESKTOP_WINDOW_ID", FALSE));
 
824
 
 
825
#if 0 /* see bug #7442 */
 
826
    gdk_property_delete(groot, gdk_atom_intern("_XROOTPMAP_ID", FALSE));
 
827
    gdk_property_delete(groot, gdk_atom_intern("ESETROOT_PMAP_ID", FALSE));
 
828
    gdk_window_set_back_pixmap(groot, NULL, FALSE);
 
829
#endif
 
830
 
 
831
    if(desktop->priv->backdrops) {
 
832
        for(i = 0; i < desktop->priv->nbackdrops; i++) {
 
833
            g_snprintf(property_name, 128, XFDESKTOP_IMAGE_FILE_FMT, i);
 
834
            gdk_property_delete(groot, gdk_atom_intern(property_name, FALSE));
 
835
            g_object_unref(G_OBJECT(desktop->priv->backdrops[i]));
 
836
        }
 
837
        g_free(desktop->priv->backdrops);
 
838
        desktop->priv->backdrops = NULL;
 
839
    }
 
840
 
 
841
    gdk_flush();
 
842
    gdk_error_trap_pop();
 
843
 
 
844
    g_object_unref(G_OBJECT(desktop->priv->bg_pixmap));
 
845
    desktop->priv->bg_pixmap = NULL;
 
846
    
 
847
    gtk_window_set_icon(GTK_WINDOW(widget), NULL);
 
848
    
 
849
    gtk_style_detach(widget->style);
 
850
    g_object_unref(G_OBJECT(widget->window));
 
851
    widget->window = NULL;
 
852
    
 
853
    gtk_selection_remove_all(widget);
 
854
    
 
855
    GTK_WIDGET_UNSET_FLAGS(widget, GTK_REALIZED);
 
856
}
 
857
 
 
858
static gboolean
 
859
xfce_desktop_button_press_event(GtkWidget *w,
 
860
                                GdkEventButton *evt)
 
861
{
 
862
    guint button = evt->button;
 
863
    guint state = evt->state;
 
864
    
 
865
    if(evt->type == GDK_BUTTON_PRESS) {
 
866
        if(button == 2 || (button == 1 && (state & GDK_SHIFT_MASK)
 
867
                           && (state & GDK_CONTROL_MASK)))
 
868
        {
 
869
            xfce_desktop_popup_secondary_root_menu(XFCE_DESKTOP(w),
 
870
                                                   button, evt->time);
 
871
            return TRUE;
 
872
        } else if(button == 3 || (button == 1 && (state & GDK_SHIFT_MASK))) {
 
873
            xfce_desktop_popup_root_menu(XFCE_DESKTOP(w),
 
874
                                         button, evt->time);
 
875
            return TRUE;
 
876
        }
 
877
    }
 
878
    
 
879
    return FALSE;
 
880
}
 
881
 
 
882
static gboolean
 
883
xfce_desktop_popup_menu(GtkWidget *w)
 
884
{
 
885
    GdkEventButton *evt;
 
886
    guint button, etime;
 
887
    
 
888
    evt = (GdkEventButton *)gtk_get_current_event();
 
889
    if(evt && GDK_BUTTON_PRESS == evt->type) {
 
890
        button = evt->button;
 
891
        etime = evt->time;
 
892
    } else {
 
893
        button = 0;
 
894
        etime = gtk_get_current_event_time();
 
895
    }
 
896
    
 
897
    xfce_desktop_popup_root_menu(XFCE_DESKTOP(w), button, etime);
 
898
    
 
899
    return TRUE;
 
900
}
 
901
 
 
902
static gboolean
 
903
xfce_desktop_expose(GtkWidget *w,
 
904
                    GdkEventExpose *evt)
 
905
{
 
906
    GList *children, *l;
 
907
    
 
908
    /*TRACE("entering");*/
 
909
    
 
910
    if(evt->count != 0)
 
911
        return FALSE;
 
912
    
 
913
    gdk_window_clear_area(w->window, evt->area.x, evt->area.y,
 
914
                          evt->area.width, evt->area.height);
 
915
    
 
916
    children = gtk_container_get_children(GTK_CONTAINER(w));
 
917
    for(l = children; l; l = l->next) {
 
918
        gtk_container_propagate_expose(GTK_CONTAINER(w),
 
919
                                       GTK_WIDGET(l->data),
 
920
                                       evt);
 
921
    }
 
922
    g_list_free(children);
 
923
    
 
924
    return FALSE;
 
925
}
 
926
 
 
927
static gboolean
 
928
xfce_desktop_delete_event(GtkWidget *w,
 
929
                          GdkEventAny *evt)
 
930
{
 
931
    if(XFCE_DESKTOP(w)->priv->session_logout_func)
 
932
        XFCE_DESKTOP(w)->priv->session_logout_func();
 
933
    
 
934
    return TRUE;
 
935
}
 
936
 
 
937
static void
 
938
xfce_desktop_style_set(GtkWidget *w,
 
939
                       GtkStyle *old_style)
 
940
{
 
941
    XfceDesktop *desktop = XFCE_DESKTOP(w);
 
942
#ifdef ENABLE_DESKTOP_ICONS
 
943
    gdouble old_font_size;
 
944
#endif
 
945
    
 
946
    if(GDK_IS_WINDOW(desktop->priv->bg_pixmap))
 
947
        gdk_window_set_back_pixmap(w->window, desktop->priv->bg_pixmap, FALSE);
 
948
    gtk_widget_queue_draw(w);
 
949
 
 
950
#ifdef ENABLE_DESKTOP_ICONS
 
951
    old_font_size = desktop->priv->system_font_size;
 
952
    if(xfce_desktop_ensure_system_font_size(desktop) != old_font_size
 
953
       && desktop->priv->icon_view && !desktop->priv->icons_font_size_set)
 
954
    {
 
955
        xfdesktop_icon_view_set_font_size(XFDESKTOP_ICON_VIEW(desktop->priv->icon_view),
 
956
                                          desktop->priv->system_font_size);
 
957
    }
 
958
#endif
 
959
}
 
960
 
 
961
static void
 
962
xfce_desktop_connect_settings(XfceDesktop *desktop)
 
963
{
 
964
    XfconfChannel *channel = desktop->priv->channel;
 
965
    gchar buf[1024];
 
966
 
 
967
    xfce_desktop_freeze_updates(desktop);
 
968
 
 
969
    g_strlcpy(buf, desktop->priv->property_prefix, sizeof(buf));
 
970
    g_strlcat(buf, "xinerama-stretch", sizeof(buf));
 
971
    xfconf_g_property_bind(channel, buf, G_TYPE_BOOLEAN,
 
972
                           G_OBJECT(desktop), "xinerama-stretch");
 
973
 
 
974
#ifdef ENABLE_DESKTOP_ICONS
 
975
#define ICONS_PREFIX "/desktop-icons/"
 
976
 
 
977
    xfconf_g_property_bind(channel, ICONS_PREFIX "style",
 
978
                           XFCE_TYPE_DESKTOP_ICON_STYLE,
 
979
                           G_OBJECT(desktop), "icon-style");
 
980
    xfconf_g_property_bind(channel, ICONS_PREFIX "icon-size", G_TYPE_UINT,
 
981
                           G_OBJECT(desktop), "icon-size");
 
982
    xfconf_g_property_bind(channel, ICONS_PREFIX "font-size", G_TYPE_UINT,
 
983
                           G_OBJECT(desktop), "icon-font-size");
 
984
    xfconf_g_property_bind(channel, ICONS_PREFIX "use-custom-font-size",
 
985
                           G_TYPE_BOOLEAN,
 
986
                           G_OBJECT(desktop), "icon-font-size-set");
 
987
#undef ICONS_PREFIX
 
988
#endif
 
989
 
 
990
    xfce_desktop_thaw_updates(desktop);
 
991
}
 
992
 
 
993
static void
 
994
xfce_desktop_image_filename_changed(XfconfChannel *channel,
 
995
                                    const gchar *property,
 
996
                                    const GValue *value,
 
997
                                    gpointer user_data)
 
998
{
 
999
    XfceDesktop *desktop = user_data;
 
1000
    gchar *p;
 
1001
    const gchar *filename;
 
1002
    gint monitor;
 
1003
    XfceBackdrop *backdrop;
 
1004
 
 
1005
    p = strstr(property, "/monitor");
 
1006
    if(!p)
 
1007
        return;
 
1008
 
 
1009
    monitor = atoi(p + 8);
 
1010
    if(monitor < 0 || monitor >= gdk_screen_get_n_monitors(desktop->priv->gscreen))
 
1011
        return;
 
1012
 
 
1013
    if(desktop->priv->xinerama_stretch && monitor != 0)
 
1014
        return;
 
1015
    backdrop = desktop->priv->backdrops[monitor];
 
1016
 
 
1017
    if(!G_VALUE_HOLDS_STRING(value))
 
1018
        filename = DEFAULT_BACKDROP;
 
1019
    else
 
1020
        filename = g_value_get_string(value);
 
1021
    if(G_LIKELY(filename && *filename)) {
 
1022
        if(xfdesktop_backdrop_list_is_valid(filename)) {
 
1023
            gchar *backdrop_file;
 
1024
            GError *error = NULL;
 
1025
            
 
1026
            backdrop_file = xfdesktop_backdrop_list_choose_random(filename,
 
1027
                                                                  &error);
 
1028
#if 0
 
1029
            if(!backdrop_file && !xfdesktop_backdrop_list_is_valid(filename)) {
 
1030
                gchar *primary = g_strdup_printf(_("Unable to load image from backdrop list file \"%s\""),
 
1031
                                                 filename);
 
1032
                xfce_message_dialog(GTK_WINDOW(desktop), _("Desktop Error"),
 
1033
                                    GTK_STOCK_DIALOG_ERROR, primary,
 
1034
                                    error->message,
 
1035
                                    GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT,
 
1036
                                    NULL);
 
1037
                g_error_free(error);
 
1038
                g_free(primary);
 
1039
            }
 
1040
#endif
 
1041
 
 
1042
            xfce_backdrop_set_image_filename(backdrop, backdrop_file);
 
1043
            g_free(backdrop_file);
 
1044
        } else
 
1045
            xfce_backdrop_set_image_filename(backdrop, filename);
 
1046
    }
 
1047
}
 
1048
 
 
1049
static void
 
1050
xfce_desktop_connect_backdrop_settings(XfceDesktop *desktop,
 
1051
                                       XfceBackdrop *backdrop,
 
1052
                                       guint monitor)
 
1053
{
 
1054
    XfconfChannel *channel = desktop->priv->channel;
 
1055
    char buf[1024], buf1[1024];
 
1056
    gint pp_len;
 
1057
    GValue value = { 0, };
 
1058
 
 
1059
    g_snprintf(buf, sizeof(buf), "%smonitor%d/",
 
1060
               desktop->priv->property_prefix, monitor);
 
1061
    pp_len = strlen(buf);
 
1062
 
 
1063
    g_strlcat(buf, "color-style", sizeof(buf));
 
1064
    xfconf_g_property_bind(channel, buf, XFCE_TYPE_BACKDROP_COLOR_STYLE,
 
1065
                           G_OBJECT(backdrop), "color-style");
 
1066
 
 
1067
    buf[pp_len] = 0;
 
1068
    g_strlcat(buf, "color1", sizeof(buf));
 
1069
    xfconf_g_property_bind_gdkcolor(channel, buf,
 
1070
                                    G_OBJECT(backdrop), "first-color");
 
1071
 
 
1072
    buf[pp_len] = 0;
 
1073
    g_strlcat(buf, "color2", sizeof(buf));
 
1074
    xfconf_g_property_bind_gdkcolor(channel, buf,
 
1075
                                    G_OBJECT(backdrop), "second-color");
 
1076
 
 
1077
    buf[pp_len] = 0;
 
1078
    g_strlcat(buf, "image-show", sizeof(buf));
 
1079
    xfconf_g_property_bind(channel, buf, G_TYPE_BOOLEAN,
 
1080
                           G_OBJECT(backdrop), "show-image");
 
1081
 
 
1082
    buf[pp_len] = 0;
 
1083
    g_strlcat(buf, "image-style", sizeof(buf));
 
1084
    xfconf_g_property_bind(channel, buf, XFCE_TYPE_BACKDROP_IMAGE_STYLE,
 
1085
                           G_OBJECT(backdrop), "image-style");
 
1086
 
 
1087
    buf[pp_len] = 0;
 
1088
    g_strlcat(buf, "brightness", sizeof(buf));
 
1089
    xfconf_g_property_bind(channel, buf, G_TYPE_INT,
 
1090
                           G_OBJECT(backdrop), "brightness");
 
1091
 
 
1092
    buf[pp_len] = 0;
 
1093
    g_strlcat(buf, "saturation", sizeof(buf));
 
1094
    xfconf_g_property_bind(channel, buf, G_TYPE_DOUBLE,
 
1095
                           G_OBJECT(backdrop), "saturation");
 
1096
 
 
1097
    /* the image filename could be an image or a backdrop list, so we
 
1098
     * can't just bind the property directly */
 
1099
    buf[pp_len] = 0;
 
1100
    g_strlcat(buf, "image-path", sizeof(buf));
 
1101
    g_strlcpy(buf1, "property-changed::", sizeof(buf1));
 
1102
    g_strlcat(buf1, buf, sizeof(buf1));
 
1103
    g_signal_connect(G_OBJECT(channel), buf1,
 
1104
                     G_CALLBACK(xfce_desktop_image_filename_changed), desktop);
 
1105
    if(xfconf_channel_get_property(channel, buf, &value)) {
 
1106
        xfce_desktop_image_filename_changed(channel, buf, &value, desktop);
 
1107
        g_value_unset(&value);
 
1108
    }
 
1109
}
 
1110
 
 
1111
 
 
1112
 
 
1113
/* public api */
 
1114
 
 
1115
/**
 
1116
 * xfce_desktop_new:
 
1117
 * @gscreen: The current #GdkScreen.
 
1118
 * @channel: An #XfconfChannel to use for settings.
 
1119
 * @property_prefix: String prefix for per-screen properties.
 
1120
 *
 
1121
 * Creates a new #XfceDesktop for the specified #GdkScreen.  If @gscreen is
 
1122
 * %NULL, the default screen will be used.
 
1123
 *
 
1124
 * Return value: A new #XfceDesktop.
 
1125
 **/
 
1126
GtkWidget *
 
1127
xfce_desktop_new(GdkScreen *gscreen,
 
1128
                 XfconfChannel *channel,
 
1129
                 const gchar *property_prefix)
 
1130
{
 
1131
    XfceDesktop *desktop;
 
1132
    
 
1133
    g_return_val_if_fail(channel && property_prefix, NULL);
 
1134
 
 
1135
    desktop = g_object_new(XFCE_TYPE_DESKTOP, NULL);
 
1136
 
 
1137
    if(!gscreen)
 
1138
        gscreen = gdk_display_get_default_screen(gdk_display_get_default());
 
1139
    gtk_window_set_screen(GTK_WINDOW(desktop), gscreen);
 
1140
    desktop->priv->gscreen = gscreen;
 
1141
    
 
1142
    desktop->priv->channel = g_object_ref(G_OBJECT(channel));
 
1143
    desktop->priv->property_prefix = g_strdup(property_prefix);
 
1144
 
 
1145
    xfce_desktop_connect_settings(desktop);
 
1146
    
 
1147
    return GTK_WIDGET(desktop);
 
1148
}
 
1149
 
 
1150
guint
 
1151
xfce_desktop_get_n_monitors(XfceDesktop *desktop)
 
1152
{
 
1153
    g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), 0);
 
1154
    
 
1155
    return desktop->priv->nbackdrops;
 
1156
}
 
1157
 
 
1158
gint
 
1159
xfce_desktop_get_width(XfceDesktop *desktop)
 
1160
{
 
1161
    g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), -1);
 
1162
    
 
1163
    return gdk_screen_get_width(desktop->priv->gscreen);
 
1164
}
 
1165
 
 
1166
gint
 
1167
xfce_desktop_get_height(XfceDesktop *desktop)
 
1168
{
 
1169
    g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), -1);
 
1170
    
 
1171
    return gdk_screen_get_height(desktop->priv->gscreen);
 
1172
}
 
1173
 
 
1174
void
 
1175
xfce_desktop_set_xinerama_stretch(XfceDesktop *desktop,
 
1176
                                  gboolean stretch)
 
1177
{
 
1178
    g_return_if_fail(XFCE_IS_DESKTOP(desktop));
 
1179
    
 
1180
    if(stretch == desktop->priv->xinerama_stretch)
 
1181
        return;
 
1182
    
 
1183
    desktop->priv->xinerama_stretch = stretch;
 
1184
    
 
1185
    if(!desktop->priv->updates_frozen)
 
1186
        xfce_desktop_monitors_changed(desktop->priv->gscreen, desktop);
 
1187
}
 
1188
 
 
1189
gboolean
 
1190
xfce_desktop_get_xinerama_stretch(XfceDesktop *desktop)
 
1191
{
 
1192
    g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), FALSE);
 
1193
    return desktop->priv->xinerama_stretch;
 
1194
}
 
1195
 
 
1196
void
 
1197
xfce_desktop_set_icon_style(XfceDesktop *desktop,
 
1198
                            XfceDesktopIconStyle style)
 
1199
{
 
1200
    g_return_if_fail(XFCE_IS_DESKTOP(desktop)
 
1201
                     && style <= XFCE_DESKTOP_ICON_STYLE_FILES);
 
1202
    
 
1203
#ifdef ENABLE_DESKTOP_ICONS
 
1204
    if(style == desktop->priv->icons_style)
 
1205
        return;
 
1206
    
 
1207
    if(desktop->priv->icon_view) {
 
1208
        gtk_widget_destroy(desktop->priv->icon_view);
 
1209
        desktop->priv->icon_view = NULL;
 
1210
    }
 
1211
    
 
1212
    desktop->priv->icons_style = style;
 
1213
    if(GTK_WIDGET_REALIZED(desktop))
 
1214
        xfce_desktop_setup_icon_view(desktop);
 
1215
#endif
 
1216
}
 
1217
 
 
1218
XfceDesktopIconStyle
 
1219
xfce_desktop_get_icon_style(XfceDesktop *desktop)
 
1220
{
 
1221
    g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), XFCE_DESKTOP_ICON_STYLE_NONE);
 
1222
    
 
1223
#ifdef ENABLE_DESKTOP_ICONS
 
1224
    return desktop->priv->icons_style;
 
1225
#else
 
1226
    return XFCE_DESKTOP_ICON_STYLE_NONE;
 
1227
#endif
 
1228
}
 
1229
 
 
1230
void
 
1231
xfce_desktop_set_icon_size(XfceDesktop *desktop,
 
1232
                           guint icon_size)
 
1233
{
 
1234
    g_return_if_fail(XFCE_IS_DESKTOP(desktop));
 
1235
    
 
1236
#ifdef ENABLE_DESKTOP_ICONS
 
1237
    if(icon_size == desktop->priv->icons_size)
 
1238
        return;
 
1239
    
 
1240
    desktop->priv->icons_size = icon_size;
 
1241
    
 
1242
    if(desktop->priv->icon_view) {
 
1243
        xfdesktop_icon_view_set_icon_size(XFDESKTOP_ICON_VIEW(desktop->priv->icon_view),
 
1244
                                          icon_size);
 
1245
    }
 
1246
#endif
 
1247
}
 
1248
 
 
1249
void
 
1250
xfce_desktop_set_icon_font_size(XfceDesktop *desktop,
 
1251
                                guint font_size_points)
 
1252
{
 
1253
    g_return_if_fail(XFCE_IS_DESKTOP(desktop));
 
1254
    
 
1255
#ifdef ENABLE_DESKTOP_ICONS
 
1256
    if(font_size_points == desktop->priv->icons_font_size)
 
1257
        return;
 
1258
    
 
1259
    desktop->priv->icons_font_size = font_size_points;
 
1260
    
 
1261
    if(desktop->priv->icons_font_size_set && desktop->priv->icon_view) {
 
1262
        xfdesktop_icon_view_set_font_size(XFDESKTOP_ICON_VIEW(desktop->priv->icon_view),
 
1263
                                          font_size_points);
 
1264
    }
 
1265
#endif
 
1266
}
 
1267
 
 
1268
void
 
1269
xfce_desktop_set_use_icon_font_size(XfceDesktop *desktop,
 
1270
                                    gboolean use_icon_font_size)
 
1271
{
 
1272
    g_return_if_fail(XFCE_IS_DESKTOP(desktop));
 
1273
    
 
1274
#ifdef ENABLE_DESKTOP_ICONS
 
1275
    if(use_icon_font_size == desktop->priv->icons_font_size_set)
 
1276
        return;
 
1277
    
 
1278
    desktop->priv->icons_font_size_set = use_icon_font_size;
 
1279
    
 
1280
    if(desktop->priv->icon_view) {
 
1281
        if(!use_icon_font_size) {
 
1282
            xfce_desktop_ensure_system_font_size(desktop);
 
1283
            xfdesktop_icon_view_set_font_size(XFDESKTOP_ICON_VIEW(desktop->priv->icon_view),
 
1284
                                              desktop->priv->system_font_size);
 
1285
        } else {
 
1286
            xfdesktop_icon_view_set_font_size(XFDESKTOP_ICON_VIEW(desktop->priv->icon_view),
 
1287
                                              desktop->priv->icons_font_size);
 
1288
        }
 
1289
    }
 
1290
#endif
 
1291
}
 
1292
 
 
1293
void
 
1294
xfce_desktop_set_session_logout_func(XfceDesktop *desktop,
 
1295
                                     SessionLogoutFunc logout_func)
 
1296
{
 
1297
    g_return_if_fail(XFCE_IS_DESKTOP(desktop));
 
1298
    desktop->priv->session_logout_func = logout_func;
 
1299
}
 
1300
 
 
1301
void
 
1302
xfce_desktop_freeze_updates(XfceDesktop *desktop)
 
1303
{
 
1304
    g_return_if_fail(XFCE_IS_DESKTOP(desktop));
 
1305
    desktop->priv->updates_frozen = TRUE;
 
1306
}
 
1307
 
 
1308
void
 
1309
xfce_desktop_thaw_updates(XfceDesktop *desktop)
 
1310
{
 
1311
    g_return_if_fail(XFCE_IS_DESKTOP(desktop));
 
1312
    
 
1313
    desktop->priv->updates_frozen = FALSE;
 
1314
    if(GTK_WIDGET_REALIZED(desktop))
 
1315
        xfce_desktop_monitors_changed(desktop->priv->gscreen, desktop);
 
1316
}
 
1317
 
 
1318
XfceBackdrop *
 
1319
xfce_desktop_peek_backdrop(XfceDesktop *desktop,
 
1320
                           guint monitor)
 
1321
{
 
1322
    g_return_val_if_fail(XFCE_IS_DESKTOP(desktop)
 
1323
                         && GTK_WIDGET_REALIZED(GTK_WIDGET(desktop))
 
1324
                         && monitor < desktop->priv->nbackdrops, NULL);
 
1325
    return desktop->priv->backdrops[monitor];
 
1326
}
 
1327
 
 
1328
static gboolean
 
1329
xfce_desktop_menu_destroy_idled(gpointer data)
 
1330
{
 
1331
    gtk_widget_destroy(GTK_WIDGET(data));
 
1332
    return FALSE;
 
1333
}
 
1334
 
 
1335
static void
 
1336
xfce_desktop_do_menu_popup(XfceDesktop *desktop,
 
1337
                           guint button,
 
1338
                           guint activate_time,
 
1339
                           guint populate_signal)
 
1340
{
 
1341
    GdkScreen *screen;
 
1342
    GtkWidget *menu;
 
1343
    GList *menu_children;
 
1344
    
 
1345
    TRACE("entering");
 
1346
    
 
1347
    if(gtk_widget_has_screen(GTK_WIDGET(desktop)))
 
1348
        screen = gtk_widget_get_screen(GTK_WIDGET(desktop));
 
1349
    else
 
1350
        screen = gdk_display_get_default_screen(gdk_display_get_default());
 
1351
    
 
1352
    menu = gtk_menu_new();
 
1353
    gtk_menu_set_screen(GTK_MENU(menu), screen);
 
1354
    g_signal_connect_swapped(G_OBJECT(menu), "deactivate",
 
1355
                             G_CALLBACK(g_idle_add),
 
1356
                             (gpointer)xfce_desktop_menu_destroy_idled);
 
1357
    
 
1358
    g_signal_emit(G_OBJECT(desktop), populate_signal, 0, menu);
 
1359
    
 
1360
    /* if nobody populated the menu, don't do anything */
 
1361
    menu_children = gtk_container_get_children(GTK_CONTAINER(menu));
 
1362
    if(!menu_children) {
 
1363
        gtk_widget_destroy(menu);
 
1364
        return;
 
1365
    }
 
1366
    
 
1367
    g_list_free(menu_children);
 
1368
    
 
1369
    gtk_menu_attach_to_widget(GTK_MENU(menu), GTK_WIDGET(desktop), NULL);
 
1370
    
 
1371
    if(xfdesktop_popup_grab_available(gdk_screen_get_root_window(screen),
 
1372
                                      activate_time))
 
1373
    {
 
1374
        /* bug #3652: for some reason passing the correct button here breaks
 
1375
         * on some systems but not others.  always pass 0 for now. */
 
1376
        gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 0,
 
1377
                       activate_time);
 
1378
    } else
 
1379
        g_critical("Unable to get keyboard/mouse grab. Unable to pop up menu");
 
1380
}
 
1381
 
 
1382
void
 
1383
xfce_desktop_popup_root_menu(XfceDesktop *desktop,
 
1384
                             guint button,
 
1385
                             guint activate_time)
 
1386
{
 
1387
    xfce_desktop_do_menu_popup(desktop, button, activate_time,
 
1388
                               signals[SIG_POPULATE_ROOT_MENU]);
 
1389
}
 
1390
 
 
1391
void
 
1392
xfce_desktop_popup_secondary_root_menu(XfceDesktop *desktop,
 
1393
                                       guint button,
 
1394
                                       guint activate_time)
 
1395
{
 
1396
    xfce_desktop_do_menu_popup(desktop, button, activate_time,
 
1397
                               signals[SIG_POPULATE_SECONDARY_ROOT_MENU]);
 
1398
}
 
1399
 
 
1400
void
 
1401
xfce_desktop_refresh(XfceDesktop *desktop)
 
1402
{
 
1403
    gchar buf[256];
 
1404
    guint i, max;
 
1405
 
 
1406
    g_return_if_fail(XFCE_IS_DESKTOP(desktop));
 
1407
 
 
1408
    if(!GTK_WIDGET_REALIZED(desktop))
 
1409
        return;
 
1410
 
 
1411
    /* reload image */
 
1412
    if(desktop->priv->xinerama_stretch)
 
1413
        max = 1;
 
1414
    else
 
1415
        max = desktop->priv->nbackdrops;
 
1416
    for(i = 0; i < max; ++i) {
 
1417
        GValue val = { 0, };
 
1418
 
 
1419
        g_snprintf(buf, sizeof(buf), "%smonitor%d/image-path",
 
1420
                   desktop->priv->property_prefix, i);
 
1421
        xfconf_channel_get_property(desktop->priv->channel, buf, &val);
 
1422
 
 
1423
        xfce_desktop_image_filename_changed(desktop->priv->channel, buf,
 
1424
                                            &val, desktop);
 
1425
 
 
1426
        if(G_VALUE_TYPE(&val))
 
1427
            g_value_unset(&val);
 
1428
    }
 
1429
 
 
1430
#ifdef ENABLE_DESKTOP_ICONS
 
1431
    /* reload icon view */
 
1432
    if(desktop->priv->icon_view) {
 
1433
        gtk_widget_destroy(desktop->priv->icon_view);
 
1434
        desktop->priv->icon_view = NULL;
 
1435
    }
 
1436
    xfce_desktop_setup_icon_view(desktop);
 
1437
#endif
 
1438
}