2
* xfdesktop - xfce4's desktop manager
4
* Copyright (c) 2004-2007 Brian Tarricone, <bjt23@cornell.edu>
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.
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.
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.
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>
39
#ifdef HAVE_SYS_TYPES_H
40
#include <sys/types.h>
42
#ifdef HAVE_SYS_STAT_H
61
#include <X11/Xatom.h>
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"
76
#include <libxfce4util/libxfce4util.h>
77
#include <libxfce4ui/libxfce4ui.h>
79
#include <xfconf/xfconf.h>
81
#include "xfdesktop-common.h"
82
#include "xfce-desktop.h"
83
#include "xfce-desktop-enum-types.h"
85
struct _XfceDesktopPriv
88
gboolean updates_frozen;
90
XfconfChannel *channel;
91
gchar *property_prefix;
96
XfceBackdrop **backdrops;
98
gboolean xinerama_stretch;
100
SessionLogoutFunc session_logout_func;
102
#ifdef ENABLE_DESKTOP_ICONS
103
XfceDesktopIconStyle icons_style;
104
gboolean icons_font_size_set;
105
guint icons_font_size;
107
GtkWidget *icon_view;
108
gdouble system_font_size;
114
SIG_POPULATE_ROOT_MENU = 0,
115
SIG_POPULATE_SECONDARY_ROOT_MENU,
122
PROP_XINERAMA_STRETCH,
123
#ifdef ENABLE_DESKTOP_ICONS
127
PROP_ICON_FONT_SIZE_SET,
132
static void xfce_desktop_finalize(GObject *object);
133
static void xfce_desktop_set_property(GObject *object,
137
static void xfce_desktop_get_property(GObject *object,
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);
148
static gboolean xfce_desktop_expose(GtkWidget *w,
149
GdkEventExpose *evt);
150
static gboolean xfce_desktop_delete_event(GtkWidget *w,
152
static void xfce_desktop_style_set(GtkWidget *w,
153
GtkStyle *old_style);
155
static void xfce_desktop_connect_backdrop_settings(XfceDesktop *desktop,
156
XfceBackdrop *backdrop,
159
static guint signals[N_SIGNALS] = { 0, };
161
/* private functions */
163
#ifdef ENABLE_DESKTOP_ICONS
165
xfce_desktop_ensure_system_font_size(XfceDesktop *desktop)
168
GtkSettings *settings;
169
gchar *font_name = NULL;
170
PangoFontDescription *pfd;
172
gscreen = gtk_widget_get_screen(GTK_WIDGET(desktop));
175
gscreen = gdk_display_get_default_screen(gdk_display_get_default());
177
settings = gtk_settings_get_for_screen(gscreen);
178
g_object_get(G_OBJECT(settings), "gtk-font-name", &font_name, NULL);
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;
187
DBG("system font size is %.05f", desktop->priv->system_font_size);
190
pango_font_description_free(pfd);
192
return desktop->priv->system_font_size;
196
xfce_desktop_setup_icon_view(XfceDesktop *desktop)
198
XfdesktopIconViewManager *manager = NULL;
200
switch(desktop->priv->icons_style) {
201
case XFCE_DESKTOP_ICON_STYLE_NONE:
205
case XFCE_DESKTOP_ICON_STYLE_WINDOWS:
206
manager = xfdesktop_window_icon_manager_new(desktop->priv->gscreen);
209
#ifdef ENABLE_FILE_ICONS
210
case XFCE_DESKTOP_ICON_STYLE_FILES:
213
const gchar *desktop_path;
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);
224
g_critical("Unusable XfceDesktopIconStyle: %d. Unable to " \
225
"display desktop icons.",
226
desktop->priv->icons_style);
231
xfce_desktop_ensure_system_font_size(desktop);
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);
243
gtk_widget_show(desktop->priv->icon_view);
244
gtk_container_add(GTK_CONTAINER(desktop), desktop->priv->icon_view);
247
gtk_widget_queue_draw(GTK_WIDGET(desktop));
252
set_imgfile_root_property(XfceDesktop *desktop, const gchar *filename,
255
gchar property_name[128];
257
gdk_error_trap_push();
259
g_snprintf(property_name, 128, XFDESKTOP_IMAGE_FILE_FMT, monitor);
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);
267
gdk_property_delete(gdk_screen_get_root_window(desktop->priv->gscreen),
268
gdk_atom_intern(property_name, FALSE));
271
gdk_error_trap_pop();
275
set_real_root_window_pixmap(GdkScreen *gscreen,
278
#if 0 /* see bug #7442 */
282
xid = GDK_DRAWABLE_XID(pmap);
283
groot = gdk_screen_get_root_window(gscreen);
285
gdk_error_trap_push();
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... */
301
gdk_error_trap_pop();
306
backdrop_changed_cb(XfceBackdrop *backdrop, gpointer user_data)
308
XfceDesktop *desktop = XFCE_DESKTOP(user_data);
309
GdkPixmap *pmap = desktop->priv->bg_pixmap;
310
GdkScreen *gscreen = desktop->priv->gscreen;
318
g_return_if_fail(XFCE_IS_DESKTOP(desktop));
320
if(desktop->priv->updates_frozen || !GTK_WIDGET_REALIZED(GTK_WIDGET(desktop)))
323
TRACE("really entering");
325
for(i = 0; i < XFCE_DESKTOP(desktop)->priv->nbackdrops; i++) {
326
if(backdrop == XFCE_DESKTOP(desktop)->priv->backdrops[i]) {
334
/* create/get the composited backdrop pixmap */
335
pix = xfce_backdrop_get_pixbuf(backdrop);
339
if(desktop->priv->nbackdrops == 1) {
342
rect.width = gdk_screen_get_width(gscreen);
343
rect.height = gdk_screen_get_height(gscreen);
345
gdk_screen_get_monitor_geometry(gscreen, monitor, &rect);
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));
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);
357
set_imgfile_root_property(desktop,
358
xfce_backdrop_get_image_filename(backdrop),
361
/* do this again so apps watching the root win notice the update */
362
set_real_root_window_pixmap(gscreen, pmap);
366
screen_size_changed_cb(GdkScreen *gscreen, gpointer user_data)
368
XfceDesktop *desktop = user_data;
371
g_return_if_fail(XFCE_IS_DESKTOP(desktop));
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);
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),
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);
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);
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,
399
backdrop_changed_cb(desktop->priv->backdrops[i], desktop);
405
screen_composited_changed_cb(GdkScreen *gscreen,
408
/* fake a screen size changed, so the background is properly set */
409
screen_size_changed_cb(gscreen, user_data);
413
xfce_desktop_monitors_changed(GdkScreen *gscreen,
416
XfceDesktop *desktop = XFCE_DESKTOP(user_data);
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]));
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],
434
g_signal_connect(G_OBJECT(desktop->priv->backdrops[0]),
436
G_CALLBACK(backdrop_changed_cb), desktop);
438
desktop->priv->nbackdrops = 1;
441
guint n_monitors = gdk_screen_get_n_monitors(gscreen);
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]));
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],
458
g_signal_connect(G_OBJECT(desktop->priv->backdrops[i]),
460
G_CALLBACK(backdrop_changed_cb),
464
desktop->priv->nbackdrops = n_monitors;
468
/* update the total size of the screen and the size of each backdrop */
469
screen_size_changed_cb(gscreen, desktop);
473
screen_set_selection(XfceDesktop *desktop)
477
gchar selection_name[100];
478
Atom selection_atom, manager_atom;
480
xwin = GDK_WINDOW_XID(GTK_WIDGET(desktop)->window);
481
xscreen = gdk_screen_get_number(desktop->priv->gscreen);
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);
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);
494
XSelectInput(GDK_DISPLAY(), xwin, PropertyChangeMask | ButtonPressMask);
495
XSetSelectionOwner(GDK_DISPLAY(), selection_atom, xwin, GDK_CURRENT_TIME);
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));
503
xev.type = ClientMessage;
505
xev.message_type = manager_atom;
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 */
513
XSendEvent(GDK_DISPLAY(), xroot, False, StructureNotifyMask, (XEvent *)&xev);
515
g_error("%s: could not set selection ownership", PACKAGE);
522
/* gobject-related functions */
525
G_DEFINE_TYPE(XfceDesktop, xfce_desktop, GTK_TYPE_WINDOW)
529
xfce_desktop_class_init(XfceDesktopClass *klass)
531
GObjectClass *gobject_class = (GObjectClass *)klass;
532
GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
534
g_type_class_add_private(klass, sizeof(XfceDesktopPriv));
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;
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;
548
signals[SIG_POPULATE_ROOT_MENU] = g_signal_new("populate-root-menu",
551
G_STRUCT_OFFSET(XfceDesktopClass,
554
g_cclosure_marshal_VOID__OBJECT,
556
GTK_TYPE_MENU_SHELL);
558
signals[SIG_POPULATE_SECONDARY_ROOT_MENU] = g_signal_new("populate-secondary-root-menu",
561
G_STRUCT_OFFSET(XfceDesktopClass,
562
populate_secondary_root_menu),
564
g_cclosure_marshal_VOID__OBJECT,
566
GTK_TYPE_MENU_SHELL);
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)
574
g_object_class_install_property(gobject_class, PROP_XINERAMA_STRETCH,
575
g_param_spec_boolean("xinerama-stretch",
579
XFDESKTOP_PARAM_FLAGS));
581
#ifdef ENABLE_DESKTOP_ICONS
582
g_object_class_install_property(gobject_class, PROP_ICON_STYLE,
583
g_param_spec_enum("icon-style",
586
XFCE_TYPE_DESKTOP_ICON_STYLE,
587
#ifdef ENABLE_FILE_ICONS
588
XFCE_DESKTOP_ICON_STYLE_FILES,
590
XFCE_DESKTOP_ICON_STYLE_WINDOWS,
592
XFDESKTOP_PARAM_FLAGS));
594
g_object_class_install_property(gobject_class, PROP_ICON_SIZE,
595
g_param_spec_uint("icon-size",
599
XFDESKTOP_PARAM_FLAGS));
601
g_object_class_install_property(gobject_class, PROP_ICON_FONT_SIZE,
602
g_param_spec_uint("icon-font-size",
606
XFDESKTOP_PARAM_FLAGS));
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",
613
XFDESKTOP_PARAM_FLAGS));
615
#undef XFDESKTOP_PARAM_FLAGS
619
xfce_desktop_init(XfceDesktop *desktop)
621
desktop->priv = G_TYPE_INSTANCE_GET_PRIVATE(desktop, XFCE_TYPE_DESKTOP,
623
GTK_WINDOW(desktop)->type = GTK_WINDOW_TOPLEVEL;
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);
631
xfce_desktop_finalize(GObject *object)
633
XfceDesktop *desktop = XFCE_DESKTOP(object);
635
g_object_unref(G_OBJECT(desktop->priv->channel));
636
g_free(desktop->priv->property_prefix);
638
G_OBJECT_CLASS(xfce_desktop_parent_class)->finalize(object);
642
xfce_desktop_set_property(GObject *object,
647
XfceDesktop *desktop = XFCE_DESKTOP(object);
649
switch(property_id) {
650
case PROP_XINERAMA_STRETCH:
651
xfce_desktop_set_xinerama_stretch(desktop,
652
g_value_get_boolean(value));
655
#ifdef ENABLE_DESKTOP_ICONS
656
case PROP_ICON_STYLE:
657
xfce_desktop_set_icon_style(desktop,
658
g_value_get_enum(value));
662
xfce_desktop_set_icon_size(desktop,
663
g_value_get_uint(value));
666
case PROP_ICON_FONT_SIZE:
667
xfce_desktop_set_icon_font_size(desktop,
668
g_value_get_uint(value));
671
case PROP_ICON_FONT_SIZE_SET:
672
xfce_desktop_set_use_icon_font_size(desktop,
673
g_value_get_boolean(value));
678
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
684
xfce_desktop_get_property(GObject *object,
689
XfceDesktop *desktop = XFCE_DESKTOP(object);
691
switch(property_id) {
692
case PROP_XINERAMA_STRETCH:
693
g_value_set_boolean(value, desktop->priv->xinerama_stretch);
696
#ifdef ENABLE_DESKTOP_ICONS
697
case PROP_ICON_STYLE:
698
g_value_set_enum(value, desktop->priv->icons_style);
702
g_value_set_uint(value, desktop->priv->icons_size);
705
case PROP_ICON_FONT_SIZE:
706
g_value_set_uint(value, desktop->priv->icons_font_size);
709
case PROP_ICON_FONT_SIZE_SET:
710
g_value_set_boolean(value, desktop->priv->icons_font_size_set);
715
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
721
xfce_desktop_realize(GtkWidget *widget)
723
XfceDesktop *desktop = XFCE_DESKTOP(widget);
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))
737
g_signal_connect(G_OBJECT(desktop->priv->gscreen),
739
G_CALLBACK(xfce_desktop_monitors_changed),
744
GTK_WIDGET_CLASS(xfce_desktop_parent_class)->realize(widget);
746
gtk_window_set_title(GTK_WINDOW(desktop), _("Desktop"));
748
gtk_widget_set_size_request(GTK_WIDGET(desktop), sw, sh);
749
gtk_window_move(GTK_WINDOW(desktop), 0, 0);
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);
757
xid = GDK_WINDOW_XID(GTK_WIDGET(desktop)->window);
758
groot = gdk_screen_get_root_window(desktop->priv->gscreen);
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);
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);
770
screen_set_selection(desktop);
772
xfce_desktop_monitors_changed(desktop->priv->gscreen, desktop);
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);
779
gtk_widget_add_events(GTK_WIDGET(desktop), GDK_EXPOSURE_MASK);
781
#ifdef ENABLE_DESKTOP_ICONS
782
xfce_desktop_setup_icon_view(desktop);
789
xfce_desktop_unrealize(GtkWidget *widget)
791
XfceDesktop *desktop = XFCE_DESKTOP(widget);
794
gchar property_name[128];
796
g_return_if_fail(XFCE_IS_DESKTOP(desktop));
798
if(gtk_major_version > 2
799
|| (gtk_major_version == 2 && gtk_minor_version >= 13))
801
g_signal_handlers_disconnect_by_func(G_OBJECT(desktop->priv->gscreen),
802
G_CALLBACK(xfce_desktop_monitors_changed),
806
if(GTK_WIDGET_MAPPED(widget))
807
gtk_widget_unmap(widget);
808
GTK_WIDGET_UNSET_FLAGS(widget, GTK_MAPPED);
810
gtk_container_forall(GTK_CONTAINER(widget),
811
(GtkCallback)gtk_widget_unrealize,
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);
819
gdk_error_trap_push();
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));
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);
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]));
837
g_free(desktop->priv->backdrops);
838
desktop->priv->backdrops = NULL;
842
gdk_error_trap_pop();
844
g_object_unref(G_OBJECT(desktop->priv->bg_pixmap));
845
desktop->priv->bg_pixmap = NULL;
847
gtk_window_set_icon(GTK_WINDOW(widget), NULL);
849
gtk_style_detach(widget->style);
850
g_object_unref(G_OBJECT(widget->window));
851
widget->window = NULL;
853
gtk_selection_remove_all(widget);
855
GTK_WIDGET_UNSET_FLAGS(widget, GTK_REALIZED);
859
xfce_desktop_button_press_event(GtkWidget *w,
862
guint button = evt->button;
863
guint state = evt->state;
865
if(evt->type == GDK_BUTTON_PRESS) {
866
if(button == 2 || (button == 1 && (state & GDK_SHIFT_MASK)
867
&& (state & GDK_CONTROL_MASK)))
869
xfce_desktop_popup_secondary_root_menu(XFCE_DESKTOP(w),
872
} else if(button == 3 || (button == 1 && (state & GDK_SHIFT_MASK))) {
873
xfce_desktop_popup_root_menu(XFCE_DESKTOP(w),
883
xfce_desktop_popup_menu(GtkWidget *w)
888
evt = (GdkEventButton *)gtk_get_current_event();
889
if(evt && GDK_BUTTON_PRESS == evt->type) {
890
button = evt->button;
894
etime = gtk_get_current_event_time();
897
xfce_desktop_popup_root_menu(XFCE_DESKTOP(w), button, etime);
903
xfce_desktop_expose(GtkWidget *w,
908
/*TRACE("entering");*/
913
gdk_window_clear_area(w->window, evt->area.x, evt->area.y,
914
evt->area.width, evt->area.height);
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),
922
g_list_free(children);
928
xfce_desktop_delete_event(GtkWidget *w,
931
if(XFCE_DESKTOP(w)->priv->session_logout_func)
932
XFCE_DESKTOP(w)->priv->session_logout_func();
938
xfce_desktop_style_set(GtkWidget *w,
941
XfceDesktop *desktop = XFCE_DESKTOP(w);
942
#ifdef ENABLE_DESKTOP_ICONS
943
gdouble old_font_size;
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);
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)
955
xfdesktop_icon_view_set_font_size(XFDESKTOP_ICON_VIEW(desktop->priv->icon_view),
956
desktop->priv->system_font_size);
962
xfce_desktop_connect_settings(XfceDesktop *desktop)
964
XfconfChannel *channel = desktop->priv->channel;
967
xfce_desktop_freeze_updates(desktop);
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");
974
#ifdef ENABLE_DESKTOP_ICONS
975
#define ICONS_PREFIX "/desktop-icons/"
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",
986
G_OBJECT(desktop), "icon-font-size-set");
990
xfce_desktop_thaw_updates(desktop);
994
xfce_desktop_image_filename_changed(XfconfChannel *channel,
995
const gchar *property,
999
XfceDesktop *desktop = user_data;
1001
const gchar *filename;
1003
XfceBackdrop *backdrop;
1005
p = strstr(property, "/monitor");
1009
monitor = atoi(p + 8);
1010
if(monitor < 0 || monitor >= gdk_screen_get_n_monitors(desktop->priv->gscreen))
1013
if(desktop->priv->xinerama_stretch && monitor != 0)
1015
backdrop = desktop->priv->backdrops[monitor];
1017
if(!G_VALUE_HOLDS_STRING(value))
1018
filename = DEFAULT_BACKDROP;
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;
1026
backdrop_file = xfdesktop_backdrop_list_choose_random(filename,
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\""),
1032
xfce_message_dialog(GTK_WINDOW(desktop), _("Desktop Error"),
1033
GTK_STOCK_DIALOG_ERROR, primary,
1035
GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT,
1037
g_error_free(error);
1042
xfce_backdrop_set_image_filename(backdrop, backdrop_file);
1043
g_free(backdrop_file);
1045
xfce_backdrop_set_image_filename(backdrop, filename);
1050
xfce_desktop_connect_backdrop_settings(XfceDesktop *desktop,
1051
XfceBackdrop *backdrop,
1054
XfconfChannel *channel = desktop->priv->channel;
1055
char buf[1024], buf1[1024];
1057
GValue value = { 0, };
1059
g_snprintf(buf, sizeof(buf), "%smonitor%d/",
1060
desktop->priv->property_prefix, monitor);
1061
pp_len = strlen(buf);
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");
1068
g_strlcat(buf, "color1", sizeof(buf));
1069
xfconf_g_property_bind_gdkcolor(channel, buf,
1070
G_OBJECT(backdrop), "first-color");
1073
g_strlcat(buf, "color2", sizeof(buf));
1074
xfconf_g_property_bind_gdkcolor(channel, buf,
1075
G_OBJECT(backdrop), "second-color");
1078
g_strlcat(buf, "image-show", sizeof(buf));
1079
xfconf_g_property_bind(channel, buf, G_TYPE_BOOLEAN,
1080
G_OBJECT(backdrop), "show-image");
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");
1088
g_strlcat(buf, "brightness", sizeof(buf));
1089
xfconf_g_property_bind(channel, buf, G_TYPE_INT,
1090
G_OBJECT(backdrop), "brightness");
1093
g_strlcat(buf, "saturation", sizeof(buf));
1094
xfconf_g_property_bind(channel, buf, G_TYPE_DOUBLE,
1095
G_OBJECT(backdrop), "saturation");
1097
/* the image filename could be an image or a backdrop list, so we
1098
* can't just bind the property directly */
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);
1117
* @gscreen: The current #GdkScreen.
1118
* @channel: An #XfconfChannel to use for settings.
1119
* @property_prefix: String prefix for per-screen properties.
1121
* Creates a new #XfceDesktop for the specified #GdkScreen. If @gscreen is
1122
* %NULL, the default screen will be used.
1124
* Return value: A new #XfceDesktop.
1127
xfce_desktop_new(GdkScreen *gscreen,
1128
XfconfChannel *channel,
1129
const gchar *property_prefix)
1131
XfceDesktop *desktop;
1133
g_return_val_if_fail(channel && property_prefix, NULL);
1135
desktop = g_object_new(XFCE_TYPE_DESKTOP, NULL);
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;
1142
desktop->priv->channel = g_object_ref(G_OBJECT(channel));
1143
desktop->priv->property_prefix = g_strdup(property_prefix);
1145
xfce_desktop_connect_settings(desktop);
1147
return GTK_WIDGET(desktop);
1151
xfce_desktop_get_n_monitors(XfceDesktop *desktop)
1153
g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), 0);
1155
return desktop->priv->nbackdrops;
1159
xfce_desktop_get_width(XfceDesktop *desktop)
1161
g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), -1);
1163
return gdk_screen_get_width(desktop->priv->gscreen);
1167
xfce_desktop_get_height(XfceDesktop *desktop)
1169
g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), -1);
1171
return gdk_screen_get_height(desktop->priv->gscreen);
1175
xfce_desktop_set_xinerama_stretch(XfceDesktop *desktop,
1178
g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1180
if(stretch == desktop->priv->xinerama_stretch)
1183
desktop->priv->xinerama_stretch = stretch;
1185
if(!desktop->priv->updates_frozen)
1186
xfce_desktop_monitors_changed(desktop->priv->gscreen, desktop);
1190
xfce_desktop_get_xinerama_stretch(XfceDesktop *desktop)
1192
g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), FALSE);
1193
return desktop->priv->xinerama_stretch;
1197
xfce_desktop_set_icon_style(XfceDesktop *desktop,
1198
XfceDesktopIconStyle style)
1200
g_return_if_fail(XFCE_IS_DESKTOP(desktop)
1201
&& style <= XFCE_DESKTOP_ICON_STYLE_FILES);
1203
#ifdef ENABLE_DESKTOP_ICONS
1204
if(style == desktop->priv->icons_style)
1207
if(desktop->priv->icon_view) {
1208
gtk_widget_destroy(desktop->priv->icon_view);
1209
desktop->priv->icon_view = NULL;
1212
desktop->priv->icons_style = style;
1213
if(GTK_WIDGET_REALIZED(desktop))
1214
xfce_desktop_setup_icon_view(desktop);
1218
XfceDesktopIconStyle
1219
xfce_desktop_get_icon_style(XfceDesktop *desktop)
1221
g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), XFCE_DESKTOP_ICON_STYLE_NONE);
1223
#ifdef ENABLE_DESKTOP_ICONS
1224
return desktop->priv->icons_style;
1226
return XFCE_DESKTOP_ICON_STYLE_NONE;
1231
xfce_desktop_set_icon_size(XfceDesktop *desktop,
1234
g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1236
#ifdef ENABLE_DESKTOP_ICONS
1237
if(icon_size == desktop->priv->icons_size)
1240
desktop->priv->icons_size = icon_size;
1242
if(desktop->priv->icon_view) {
1243
xfdesktop_icon_view_set_icon_size(XFDESKTOP_ICON_VIEW(desktop->priv->icon_view),
1250
xfce_desktop_set_icon_font_size(XfceDesktop *desktop,
1251
guint font_size_points)
1253
g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1255
#ifdef ENABLE_DESKTOP_ICONS
1256
if(font_size_points == desktop->priv->icons_font_size)
1259
desktop->priv->icons_font_size = font_size_points;
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),
1269
xfce_desktop_set_use_icon_font_size(XfceDesktop *desktop,
1270
gboolean use_icon_font_size)
1272
g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1274
#ifdef ENABLE_DESKTOP_ICONS
1275
if(use_icon_font_size == desktop->priv->icons_font_size_set)
1278
desktop->priv->icons_font_size_set = use_icon_font_size;
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);
1286
xfdesktop_icon_view_set_font_size(XFDESKTOP_ICON_VIEW(desktop->priv->icon_view),
1287
desktop->priv->icons_font_size);
1294
xfce_desktop_set_session_logout_func(XfceDesktop *desktop,
1295
SessionLogoutFunc logout_func)
1297
g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1298
desktop->priv->session_logout_func = logout_func;
1302
xfce_desktop_freeze_updates(XfceDesktop *desktop)
1304
g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1305
desktop->priv->updates_frozen = TRUE;
1309
xfce_desktop_thaw_updates(XfceDesktop *desktop)
1311
g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1313
desktop->priv->updates_frozen = FALSE;
1314
if(GTK_WIDGET_REALIZED(desktop))
1315
xfce_desktop_monitors_changed(desktop->priv->gscreen, desktop);
1319
xfce_desktop_peek_backdrop(XfceDesktop *desktop,
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];
1329
xfce_desktop_menu_destroy_idled(gpointer data)
1331
gtk_widget_destroy(GTK_WIDGET(data));
1336
xfce_desktop_do_menu_popup(XfceDesktop *desktop,
1338
guint activate_time,
1339
guint populate_signal)
1343
GList *menu_children;
1347
if(gtk_widget_has_screen(GTK_WIDGET(desktop)))
1348
screen = gtk_widget_get_screen(GTK_WIDGET(desktop));
1350
screen = gdk_display_get_default_screen(gdk_display_get_default());
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);
1358
g_signal_emit(G_OBJECT(desktop), populate_signal, 0, menu);
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);
1367
g_list_free(menu_children);
1369
gtk_menu_attach_to_widget(GTK_MENU(menu), GTK_WIDGET(desktop), NULL);
1371
if(xfdesktop_popup_grab_available(gdk_screen_get_root_window(screen),
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,
1379
g_critical("Unable to get keyboard/mouse grab. Unable to pop up menu");
1383
xfce_desktop_popup_root_menu(XfceDesktop *desktop,
1385
guint activate_time)
1387
xfce_desktop_do_menu_popup(desktop, button, activate_time,
1388
signals[SIG_POPULATE_ROOT_MENU]);
1392
xfce_desktop_popup_secondary_root_menu(XfceDesktop *desktop,
1394
guint activate_time)
1396
xfce_desktop_do_menu_popup(desktop, button, activate_time,
1397
signals[SIG_POPULATE_SECONDARY_ROOT_MENU]);
1401
xfce_desktop_refresh(XfceDesktop *desktop)
1406
g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1408
if(!GTK_WIDGET_REALIZED(desktop))
1412
if(desktop->priv->xinerama_stretch)
1415
max = desktop->priv->nbackdrops;
1416
for(i = 0; i < max; ++i) {
1417
GValue val = { 0, };
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);
1423
xfce_desktop_image_filename_changed(desktop->priv->channel, buf,
1426
if(G_VALUE_TYPE(&val))
1427
g_value_unset(&val);
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;
1436
xfce_desktop_setup_icon_view(desktop);