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], common_selection_name[32];
478
Atom selection_atom, common_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
g_snprintf(common_selection_name, 32, "_NET_DESKTOP_MANAGER_S%d", xscreen);
488
common_selection_atom = XInternAtom(GDK_DISPLAY(), common_selection_name, False);
490
/* the previous check in src/main.c occurs too early, so workaround by
491
* adding this one. Hopefully it should help for lp #329616 */
492
if(XGetSelectionOwner(GDK_DISPLAY(), selection_atom) != None) {
493
g_warning("%s: already running, quitting.", PACKAGE);
497
/* Check that _NET_DESKTOP_MANAGER_S%d isn't set, as it means another
498
* desktop manager is running, e.g. nautilus */
499
if(XGetSelectionOwner (GDK_DISPLAY(), common_selection_atom) != None) {
500
g_warning("%s: another desktop manager is running.", PACKAGE);
504
XSelectInput(GDK_DISPLAY(), xwin, PropertyChangeMask | ButtonPressMask);
505
XSetSelectionOwner(GDK_DISPLAY(), selection_atom, xwin, GDK_CURRENT_TIME);
506
XSetSelectionOwner(GDK_DISPLAY(), common_selection_atom, xwin, GDK_CURRENT_TIME);
508
/* Check to see if we managed to claim the selection. If not,
509
* we treat it as if we got it then immediately lost it */
510
if(XGetSelectionOwner(GDK_DISPLAY(), selection_atom) == xwin) {
511
XClientMessageEvent xev;
512
Window xroot = GDK_WINDOW_XID(gdk_screen_get_root_window(desktop->priv->gscreen));
514
xev.type = ClientMessage;
516
xev.message_type = manager_atom;
518
xev.data.l[0] = GDK_CURRENT_TIME;
519
xev.data.l[1] = selection_atom;
520
xev.data.l[2] = xwin;
521
xev.data.l[3] = 0; /* manager specific data */
522
xev.data.l[4] = 0; /* manager specific data */
524
XSendEvent(GDK_DISPLAY(), xroot, False, StructureNotifyMask, (XEvent *)&xev);
526
g_error("%s: could not set selection ownership", PACKAGE);
533
/* gobject-related functions */
536
G_DEFINE_TYPE(XfceDesktop, xfce_desktop, GTK_TYPE_WINDOW)
540
xfce_desktop_class_init(XfceDesktopClass *klass)
542
GObjectClass *gobject_class = (GObjectClass *)klass;
543
GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
545
g_type_class_add_private(klass, sizeof(XfceDesktopPriv));
547
gobject_class->finalize = xfce_desktop_finalize;
548
gobject_class->set_property = xfce_desktop_set_property;
549
gobject_class->get_property = xfce_desktop_get_property;
551
widget_class->realize = xfce_desktop_realize;
552
widget_class->unrealize = xfce_desktop_unrealize;
553
widget_class->button_press_event = xfce_desktop_button_press_event;
554
widget_class->expose_event = xfce_desktop_expose;
555
widget_class->delete_event = xfce_desktop_delete_event;
556
widget_class->popup_menu = xfce_desktop_popup_menu;
557
widget_class->style_set = xfce_desktop_style_set;
559
signals[SIG_POPULATE_ROOT_MENU] = g_signal_new("populate-root-menu",
562
G_STRUCT_OFFSET(XfceDesktopClass,
565
g_cclosure_marshal_VOID__OBJECT,
567
GTK_TYPE_MENU_SHELL);
569
signals[SIG_POPULATE_SECONDARY_ROOT_MENU] = g_signal_new("populate-secondary-root-menu",
572
G_STRUCT_OFFSET(XfceDesktopClass,
573
populate_secondary_root_menu),
575
g_cclosure_marshal_VOID__OBJECT,
577
GTK_TYPE_MENU_SHELL);
579
#define XFDESKTOP_PARAM_FLAGS (G_PARAM_READWRITE \
580
| G_PARAM_CONSTRUCT \
581
| G_PARAM_STATIC_NAME \
582
| G_PARAM_STATIC_NICK \
583
| G_PARAM_STATIC_BLURB)
585
g_object_class_install_property(gobject_class, PROP_XINERAMA_STRETCH,
586
g_param_spec_boolean("xinerama-stretch",
590
XFDESKTOP_PARAM_FLAGS));
592
#ifdef ENABLE_DESKTOP_ICONS
593
g_object_class_install_property(gobject_class, PROP_ICON_STYLE,
594
g_param_spec_enum("icon-style",
597
XFCE_TYPE_DESKTOP_ICON_STYLE,
598
#ifdef ENABLE_FILE_ICONS
599
XFCE_DESKTOP_ICON_STYLE_FILES,
601
XFCE_DESKTOP_ICON_STYLE_WINDOWS,
603
XFDESKTOP_PARAM_FLAGS));
605
g_object_class_install_property(gobject_class, PROP_ICON_SIZE,
606
g_param_spec_uint("icon-size",
610
XFDESKTOP_PARAM_FLAGS));
612
g_object_class_install_property(gobject_class, PROP_ICON_FONT_SIZE,
613
g_param_spec_uint("icon-font-size",
617
XFDESKTOP_PARAM_FLAGS));
619
g_object_class_install_property(gobject_class, PROP_ICON_FONT_SIZE_SET,
620
g_param_spec_boolean("icon-font-size-set",
621
"icon font size set",
622
"icon font size set",
624
XFDESKTOP_PARAM_FLAGS));
626
#undef XFDESKTOP_PARAM_FLAGS
630
xfce_desktop_init(XfceDesktop *desktop)
632
desktop->priv = G_TYPE_INSTANCE_GET_PRIVATE(desktop, XFCE_TYPE_DESKTOP,
634
GTK_WINDOW(desktop)->type = GTK_WINDOW_TOPLEVEL;
636
gtk_window_set_type_hint(GTK_WINDOW(desktop), GDK_WINDOW_TYPE_HINT_DESKTOP);
637
gtk_window_set_accept_focus(GTK_WINDOW(desktop), FALSE);
641
xfce_desktop_finalize(GObject *object)
643
XfceDesktop *desktop = XFCE_DESKTOP(object);
645
g_object_unref(G_OBJECT(desktop->priv->channel));
646
g_free(desktop->priv->property_prefix);
648
G_OBJECT_CLASS(xfce_desktop_parent_class)->finalize(object);
652
xfce_desktop_set_property(GObject *object,
657
XfceDesktop *desktop = XFCE_DESKTOP(object);
659
switch(property_id) {
660
case PROP_XINERAMA_STRETCH:
661
xfce_desktop_set_xinerama_stretch(desktop,
662
g_value_get_boolean(value));
665
#ifdef ENABLE_DESKTOP_ICONS
666
case PROP_ICON_STYLE:
667
xfce_desktop_set_icon_style(desktop,
668
g_value_get_enum(value));
672
xfce_desktop_set_icon_size(desktop,
673
g_value_get_uint(value));
676
case PROP_ICON_FONT_SIZE:
677
xfce_desktop_set_icon_font_size(desktop,
678
g_value_get_uint(value));
681
case PROP_ICON_FONT_SIZE_SET:
682
xfce_desktop_set_use_icon_font_size(desktop,
683
g_value_get_boolean(value));
688
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
694
xfce_desktop_get_property(GObject *object,
699
XfceDesktop *desktop = XFCE_DESKTOP(object);
701
switch(property_id) {
702
case PROP_XINERAMA_STRETCH:
703
g_value_set_boolean(value, desktop->priv->xinerama_stretch);
706
#ifdef ENABLE_DESKTOP_ICONS
707
case PROP_ICON_STYLE:
708
g_value_set_enum(value, desktop->priv->icons_style);
712
g_value_set_uint(value, desktop->priv->icons_size);
715
case PROP_ICON_FONT_SIZE:
716
g_value_set_uint(value, desktop->priv->icons_font_size);
719
case PROP_ICON_FONT_SIZE_SET:
720
g_value_set_boolean(value, desktop->priv->icons_font_size_set);
725
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
731
xfce_desktop_realize(GtkWidget *widget)
733
XfceDesktop *desktop = XFCE_DESKTOP(widget);
741
gtk_window_set_screen(GTK_WINDOW(desktop), desktop->priv->gscreen);
742
sw = gdk_screen_get_width(desktop->priv->gscreen);
743
sh = gdk_screen_get_height(desktop->priv->gscreen);
744
if(gtk_major_version > 2
745
|| (gtk_major_version == 2 && gtk_minor_version >= 13))
747
g_signal_connect(G_OBJECT(desktop->priv->gscreen),
749
G_CALLBACK(xfce_desktop_monitors_changed),
754
GTK_WIDGET_CLASS(xfce_desktop_parent_class)->realize(widget);
756
gtk_window_set_title(GTK_WINDOW(desktop), _("Desktop"));
758
gtk_widget_set_size_request(GTK_WIDGET(desktop), sw, sh);
759
gtk_window_move(GTK_WINDOW(desktop), 0, 0);
761
atom = gdk_atom_intern("_NET_WM_WINDOW_TYPE_DESKTOP", FALSE);
762
gdk_property_change(GTK_WIDGET(desktop)->window,
763
gdk_atom_intern("_NET_WM_WINDOW_TYPE", FALSE),
764
gdk_atom_intern("ATOM", FALSE), 32,
765
GDK_PROP_MODE_REPLACE, (guchar *)&atom, 1);
767
xid = GDK_WINDOW_XID(GTK_WIDGET(desktop)->window);
768
groot = gdk_screen_get_root_window(desktop->priv->gscreen);
770
gdk_property_change(groot,
771
gdk_atom_intern("XFCE_DESKTOP_WINDOW", FALSE),
772
gdk_atom_intern("WINDOW", FALSE), 32,
773
GDK_PROP_MODE_REPLACE, (guchar *)&xid, 1);
775
gdk_property_change(groot,
776
gdk_atom_intern("NAUTILUS_DESKTOP_WINDOW_ID", FALSE),
777
gdk_atom_intern("WINDOW", FALSE), 32,
778
GDK_PROP_MODE_REPLACE, (guchar *)&xid, 1);
780
screen_set_selection(desktop);
782
xfce_desktop_monitors_changed(desktop->priv->gscreen, desktop);
784
g_signal_connect(G_OBJECT(desktop->priv->gscreen), "size-changed",
785
G_CALLBACK(screen_size_changed_cb), desktop);
786
g_signal_connect(G_OBJECT(desktop->priv->gscreen), "composited-changed",
787
G_CALLBACK(screen_composited_changed_cb), desktop);
789
gtk_widget_add_events(GTK_WIDGET(desktop), GDK_EXPOSURE_MASK);
791
#ifdef ENABLE_DESKTOP_ICONS
792
xfce_desktop_setup_icon_view(desktop);
799
xfce_desktop_unrealize(GtkWidget *widget)
801
XfceDesktop *desktop = XFCE_DESKTOP(widget);
804
gchar property_name[128];
806
g_return_if_fail(XFCE_IS_DESKTOP(desktop));
808
if(gtk_major_version > 2
809
|| (gtk_major_version == 2 && gtk_minor_version >= 13))
811
g_signal_handlers_disconnect_by_func(G_OBJECT(desktop->priv->gscreen),
812
G_CALLBACK(xfce_desktop_monitors_changed),
816
if(GTK_WIDGET_MAPPED(widget))
817
gtk_widget_unmap(widget);
818
GTK_WIDGET_UNSET_FLAGS(widget, GTK_MAPPED);
820
gtk_container_forall(GTK_CONTAINER(widget),
821
(GtkCallback)gtk_widget_unrealize,
824
g_signal_handlers_disconnect_by_func(G_OBJECT(desktop->priv->gscreen),
825
G_CALLBACK(screen_size_changed_cb), desktop);
826
g_signal_handlers_disconnect_by_func(G_OBJECT(desktop->priv->gscreen),
827
G_CALLBACK(screen_composited_changed_cb), desktop);
829
gdk_error_trap_push();
831
groot = gdk_screen_get_root_window(desktop->priv->gscreen);
832
gdk_property_delete(groot, gdk_atom_intern("XFCE_DESKTOP_WINDOW", FALSE));
833
gdk_property_delete(groot, gdk_atom_intern("NAUTILUS_DESKTOP_WINDOW_ID", FALSE));
835
#if 0 /* see bug #7442 */
836
gdk_property_delete(groot, gdk_atom_intern("_XROOTPMAP_ID", FALSE));
837
gdk_property_delete(groot, gdk_atom_intern("ESETROOT_PMAP_ID", FALSE));
838
gdk_window_set_back_pixmap(groot, NULL, FALSE);
841
if(desktop->priv->backdrops) {
842
for(i = 0; i < desktop->priv->nbackdrops; i++) {
843
g_snprintf(property_name, 128, XFDESKTOP_IMAGE_FILE_FMT, i);
844
gdk_property_delete(groot, gdk_atom_intern(property_name, FALSE));
845
g_object_unref(G_OBJECT(desktop->priv->backdrops[i]));
847
g_free(desktop->priv->backdrops);
848
desktop->priv->backdrops = NULL;
852
gdk_error_trap_pop();
854
g_object_unref(G_OBJECT(desktop->priv->bg_pixmap));
855
desktop->priv->bg_pixmap = NULL;
857
gtk_window_set_icon(GTK_WINDOW(widget), NULL);
859
gtk_style_detach(widget->style);
860
g_object_unref(G_OBJECT(widget->window));
861
widget->window = NULL;
863
gtk_selection_remove_all(widget);
865
GTK_WIDGET_UNSET_FLAGS(widget, GTK_REALIZED);
869
xfce_desktop_button_press_event(GtkWidget *w,
872
guint button = evt->button;
873
guint state = evt->state;
875
if(evt->type == GDK_BUTTON_PRESS) {
876
if(button == 2 || (button == 1 && (state & GDK_SHIFT_MASK)
877
&& (state & GDK_CONTROL_MASK)))
879
xfce_desktop_popup_secondary_root_menu(XFCE_DESKTOP(w),
882
} else if(button == 3 || (button == 1 && (state & GDK_SHIFT_MASK))) {
883
xfce_desktop_popup_root_menu(XFCE_DESKTOP(w),
893
xfce_desktop_popup_menu(GtkWidget *w)
898
evt = (GdkEventButton *)gtk_get_current_event();
899
if(evt && GDK_BUTTON_PRESS == evt->type) {
900
button = evt->button;
904
etime = gtk_get_current_event_time();
907
xfce_desktop_popup_root_menu(XFCE_DESKTOP(w), button, etime);
913
xfce_desktop_expose(GtkWidget *w,
918
/*TRACE("entering");*/
923
gdk_window_clear_area(w->window, evt->area.x, evt->area.y,
924
evt->area.width, evt->area.height);
926
children = gtk_container_get_children(GTK_CONTAINER(w));
927
for(l = children; l; l = l->next) {
928
gtk_container_propagate_expose(GTK_CONTAINER(w),
932
g_list_free(children);
938
xfce_desktop_delete_event(GtkWidget *w,
941
if(XFCE_DESKTOP(w)->priv->session_logout_func)
942
XFCE_DESKTOP(w)->priv->session_logout_func();
948
xfce_desktop_style_set(GtkWidget *w,
951
XfceDesktop *desktop = XFCE_DESKTOP(w);
952
#ifdef ENABLE_DESKTOP_ICONS
953
gdouble old_font_size;
956
if(GDK_IS_WINDOW(desktop->priv->bg_pixmap))
957
gdk_window_set_back_pixmap(w->window, desktop->priv->bg_pixmap, FALSE);
958
gtk_widget_queue_draw(w);
960
#ifdef ENABLE_DESKTOP_ICONS
961
old_font_size = desktop->priv->system_font_size;
962
if(xfce_desktop_ensure_system_font_size(desktop) != old_font_size
963
&& desktop->priv->icon_view && !desktop->priv->icons_font_size_set)
965
xfdesktop_icon_view_set_font_size(XFDESKTOP_ICON_VIEW(desktop->priv->icon_view),
966
desktop->priv->system_font_size);
972
xfce_desktop_connect_settings(XfceDesktop *desktop)
974
XfconfChannel *channel = desktop->priv->channel;
977
xfce_desktop_freeze_updates(desktop);
979
g_strlcpy(buf, desktop->priv->property_prefix, sizeof(buf));
980
g_strlcat(buf, "xinerama-stretch", sizeof(buf));
981
xfconf_g_property_bind(channel, buf, G_TYPE_BOOLEAN,
982
G_OBJECT(desktop), "xinerama-stretch");
984
#ifdef ENABLE_DESKTOP_ICONS
985
#define ICONS_PREFIX "/desktop-icons/"
987
xfconf_g_property_bind(channel, ICONS_PREFIX "style",
988
XFCE_TYPE_DESKTOP_ICON_STYLE,
989
G_OBJECT(desktop), "icon-style");
990
xfconf_g_property_bind(channel, ICONS_PREFIX "icon-size", G_TYPE_UINT,
991
G_OBJECT(desktop), "icon-size");
992
xfconf_g_property_bind(channel, ICONS_PREFIX "font-size", G_TYPE_UINT,
993
G_OBJECT(desktop), "icon-font-size");
994
xfconf_g_property_bind(channel, ICONS_PREFIX "use-custom-font-size",
996
G_OBJECT(desktop), "icon-font-size-set");
1000
xfce_desktop_thaw_updates(desktop);
1004
xfce_desktop_image_filename_changed(XfconfChannel *channel,
1005
const gchar *property,
1006
const GValue *value,
1009
XfceDesktop *desktop = user_data;
1011
const gchar *filename;
1013
XfceBackdrop *backdrop;
1015
p = strstr(property, "/monitor");
1019
monitor = atoi(p + 8);
1020
if(monitor < 0 || monitor >= gdk_screen_get_n_monitors(desktop->priv->gscreen))
1023
if(desktop->priv->xinerama_stretch && monitor != 0)
1025
backdrop = desktop->priv->backdrops[monitor];
1027
if(!G_VALUE_HOLDS_STRING(value))
1028
filename = DEFAULT_BACKDROP;
1030
filename = g_value_get_string(value);
1031
if(G_LIKELY(filename && *filename)) {
1032
if(xfdesktop_backdrop_list_is_valid(filename)) {
1033
gchar *backdrop_file;
1034
GError *error = NULL;
1036
backdrop_file = xfdesktop_backdrop_list_choose_random(filename,
1039
if(!backdrop_file && !xfdesktop_backdrop_list_is_valid(filename)) {
1040
gchar *primary = g_strdup_printf(_("Unable to load image from backdrop list file \"%s\""),
1042
xfce_message_dialog(GTK_WINDOW(desktop), _("Desktop Error"),
1043
GTK_STOCK_DIALOG_ERROR, primary,
1045
GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT,
1047
g_error_free(error);
1052
xfce_backdrop_set_image_filename(backdrop, backdrop_file);
1053
g_free(backdrop_file);
1055
xfce_backdrop_set_image_filename(backdrop, filename);
1060
xfce_desktop_connect_backdrop_settings(XfceDesktop *desktop,
1061
XfceBackdrop *backdrop,
1064
XfconfChannel *channel = desktop->priv->channel;
1065
char buf[1024], buf1[1024];
1067
GValue value = { 0, };
1069
g_snprintf(buf, sizeof(buf), "%smonitor%d/",
1070
desktop->priv->property_prefix, monitor);
1071
pp_len = strlen(buf);
1073
g_strlcat(buf, "color-style", sizeof(buf));
1074
xfconf_g_property_bind(channel, buf, XFCE_TYPE_BACKDROP_COLOR_STYLE,
1075
G_OBJECT(backdrop), "color-style");
1078
g_strlcat(buf, "color1", sizeof(buf));
1079
xfconf_g_property_bind_gdkcolor(channel, buf,
1080
G_OBJECT(backdrop), "first-color");
1083
g_strlcat(buf, "color2", sizeof(buf));
1084
xfconf_g_property_bind_gdkcolor(channel, buf,
1085
G_OBJECT(backdrop), "second-color");
1088
g_strlcat(buf, "image-show", sizeof(buf));
1089
xfconf_g_property_bind(channel, buf, G_TYPE_BOOLEAN,
1090
G_OBJECT(backdrop), "show-image");
1093
g_strlcat(buf, "image-style", sizeof(buf));
1094
xfconf_g_property_bind(channel, buf, XFCE_TYPE_BACKDROP_IMAGE_STYLE,
1095
G_OBJECT(backdrop), "image-style");
1098
g_strlcat(buf, "brightness", sizeof(buf));
1099
xfconf_g_property_bind(channel, buf, G_TYPE_INT,
1100
G_OBJECT(backdrop), "brightness");
1103
g_strlcat(buf, "saturation", sizeof(buf));
1104
xfconf_g_property_bind(channel, buf, G_TYPE_DOUBLE,
1105
G_OBJECT(backdrop), "saturation");
1107
/* the image filename could be an image or a backdrop list, so we
1108
* can't just bind the property directly */
1110
g_strlcat(buf, "image-path", sizeof(buf));
1111
g_strlcpy(buf1, "property-changed::", sizeof(buf1));
1112
g_strlcat(buf1, buf, sizeof(buf1));
1113
g_signal_connect(G_OBJECT(channel), buf1,
1114
G_CALLBACK(xfce_desktop_image_filename_changed), desktop);
1115
if(xfconf_channel_get_property(channel, buf, &value)) {
1116
xfce_desktop_image_filename_changed(channel, buf, &value, desktop);
1117
g_value_unset(&value);
1127
* @gscreen: The current #GdkScreen.
1128
* @channel: An #XfconfChannel to use for settings.
1129
* @property_prefix: String prefix for per-screen properties.
1131
* Creates a new #XfceDesktop for the specified #GdkScreen. If @gscreen is
1132
* %NULL, the default screen will be used.
1134
* Return value: A new #XfceDesktop.
1137
xfce_desktop_new(GdkScreen *gscreen,
1138
XfconfChannel *channel,
1139
const gchar *property_prefix)
1141
XfceDesktop *desktop;
1143
g_return_val_if_fail(channel && property_prefix, NULL);
1145
desktop = g_object_new(XFCE_TYPE_DESKTOP, NULL);
1148
gscreen = gdk_display_get_default_screen(gdk_display_get_default());
1149
gtk_window_set_screen(GTK_WINDOW(desktop), gscreen);
1150
desktop->priv->gscreen = gscreen;
1152
desktop->priv->channel = g_object_ref(G_OBJECT(channel));
1153
desktop->priv->property_prefix = g_strdup(property_prefix);
1155
xfce_desktop_connect_settings(desktop);
1157
return GTK_WIDGET(desktop);
1161
xfce_desktop_get_n_monitors(XfceDesktop *desktop)
1163
g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), 0);
1165
return desktop->priv->nbackdrops;
1169
xfce_desktop_get_width(XfceDesktop *desktop)
1171
g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), -1);
1173
return gdk_screen_get_width(desktop->priv->gscreen);
1177
xfce_desktop_get_height(XfceDesktop *desktop)
1179
g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), -1);
1181
return gdk_screen_get_height(desktop->priv->gscreen);
1185
xfce_desktop_set_xinerama_stretch(XfceDesktop *desktop,
1188
g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1190
if(stretch == desktop->priv->xinerama_stretch)
1193
desktop->priv->xinerama_stretch = stretch;
1195
if(!desktop->priv->updates_frozen)
1196
xfce_desktop_monitors_changed(desktop->priv->gscreen, desktop);
1200
xfce_desktop_get_xinerama_stretch(XfceDesktop *desktop)
1202
g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), FALSE);
1203
return desktop->priv->xinerama_stretch;
1207
xfce_desktop_set_icon_style(XfceDesktop *desktop,
1208
XfceDesktopIconStyle style)
1210
g_return_if_fail(XFCE_IS_DESKTOP(desktop)
1211
&& style <= XFCE_DESKTOP_ICON_STYLE_FILES);
1213
#ifdef ENABLE_DESKTOP_ICONS
1214
if(style == desktop->priv->icons_style)
1217
if(desktop->priv->icon_view) {
1218
gtk_widget_destroy(desktop->priv->icon_view);
1219
desktop->priv->icon_view = NULL;
1222
desktop->priv->icons_style = style;
1223
if(GTK_WIDGET_REALIZED(desktop))
1224
xfce_desktop_setup_icon_view(desktop);
1228
XfceDesktopIconStyle
1229
xfce_desktop_get_icon_style(XfceDesktop *desktop)
1231
g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), XFCE_DESKTOP_ICON_STYLE_NONE);
1233
#ifdef ENABLE_DESKTOP_ICONS
1234
return desktop->priv->icons_style;
1236
return XFCE_DESKTOP_ICON_STYLE_NONE;
1241
xfce_desktop_set_icon_size(XfceDesktop *desktop,
1244
g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1246
#ifdef ENABLE_DESKTOP_ICONS
1247
if(icon_size == desktop->priv->icons_size)
1250
desktop->priv->icons_size = icon_size;
1252
if(desktop->priv->icon_view) {
1253
xfdesktop_icon_view_set_icon_size(XFDESKTOP_ICON_VIEW(desktop->priv->icon_view),
1260
xfce_desktop_set_icon_font_size(XfceDesktop *desktop,
1261
guint font_size_points)
1263
g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1265
#ifdef ENABLE_DESKTOP_ICONS
1266
if(font_size_points == desktop->priv->icons_font_size)
1269
desktop->priv->icons_font_size = font_size_points;
1271
if(desktop->priv->icons_font_size_set && desktop->priv->icon_view) {
1272
xfdesktop_icon_view_set_font_size(XFDESKTOP_ICON_VIEW(desktop->priv->icon_view),
1279
xfce_desktop_set_use_icon_font_size(XfceDesktop *desktop,
1280
gboolean use_icon_font_size)
1282
g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1284
#ifdef ENABLE_DESKTOP_ICONS
1285
if(use_icon_font_size == desktop->priv->icons_font_size_set)
1288
desktop->priv->icons_font_size_set = use_icon_font_size;
1290
if(desktop->priv->icon_view) {
1291
if(!use_icon_font_size) {
1292
xfce_desktop_ensure_system_font_size(desktop);
1293
xfdesktop_icon_view_set_font_size(XFDESKTOP_ICON_VIEW(desktop->priv->icon_view),
1294
desktop->priv->system_font_size);
1296
xfdesktop_icon_view_set_font_size(XFDESKTOP_ICON_VIEW(desktop->priv->icon_view),
1297
desktop->priv->icons_font_size);
1304
xfce_desktop_set_session_logout_func(XfceDesktop *desktop,
1305
SessionLogoutFunc logout_func)
1307
g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1308
desktop->priv->session_logout_func = logout_func;
1312
xfce_desktop_freeze_updates(XfceDesktop *desktop)
1314
g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1315
desktop->priv->updates_frozen = TRUE;
1319
xfce_desktop_thaw_updates(XfceDesktop *desktop)
1321
g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1323
desktop->priv->updates_frozen = FALSE;
1324
if(GTK_WIDGET_REALIZED(desktop))
1325
xfce_desktop_monitors_changed(desktop->priv->gscreen, desktop);
1329
xfce_desktop_peek_backdrop(XfceDesktop *desktop,
1332
g_return_val_if_fail(XFCE_IS_DESKTOP(desktop)
1333
&& GTK_WIDGET_REALIZED(GTK_WIDGET(desktop))
1334
&& monitor < desktop->priv->nbackdrops, NULL);
1335
return desktop->priv->backdrops[monitor];
1339
xfce_desktop_menu_destroy_idled(gpointer data)
1341
gtk_widget_destroy(GTK_WIDGET(data));
1346
xfce_desktop_do_menu_popup(XfceDesktop *desktop,
1348
guint activate_time,
1349
guint populate_signal)
1353
GList *menu_children;
1357
if(gtk_widget_has_screen(GTK_WIDGET(desktop)))
1358
screen = gtk_widget_get_screen(GTK_WIDGET(desktop));
1360
screen = gdk_display_get_default_screen(gdk_display_get_default());
1362
if(xfdesktop_popup_grab_available(gdk_screen_get_root_window(screen),
1365
menu = gtk_menu_new();
1366
gtk_menu_set_screen(GTK_MENU(menu), screen);
1367
g_signal_connect_swapped(G_OBJECT(menu), "deactivate",
1368
G_CALLBACK(g_idle_add),
1369
(gpointer)xfce_desktop_menu_destroy_idled);
1371
g_signal_emit(G_OBJECT(desktop), populate_signal, 0, menu);
1373
/* if nobody populated the menu, don't do anything */
1374
menu_children = gtk_container_get_children(GTK_CONTAINER(menu));
1375
if(!menu_children) {
1376
gtk_widget_destroy(menu);
1380
g_list_free(menu_children);
1382
gtk_menu_attach_to_widget(GTK_MENU(menu), GTK_WIDGET(desktop), NULL);
1384
/* bug #3652: for some reason passing the correct button here breaks
1385
* on some systems but not others. always pass 0 for now. */
1386
gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 0,
1389
g_critical("Unable to get keyboard/mouse grab. Unable to pop up menu");
1393
xfce_desktop_popup_root_menu(XfceDesktop *desktop,
1395
guint activate_time)
1397
xfce_desktop_do_menu_popup(desktop, button, activate_time,
1398
signals[SIG_POPULATE_ROOT_MENU]);
1402
xfce_desktop_popup_secondary_root_menu(XfceDesktop *desktop,
1404
guint activate_time)
1406
xfce_desktop_do_menu_popup(desktop, button, activate_time,
1407
signals[SIG_POPULATE_SECONDARY_ROOT_MENU]);
1411
xfce_desktop_refresh(XfceDesktop *desktop)
1416
g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1418
if(!GTK_WIDGET_REALIZED(desktop))
1422
if(desktop->priv->xinerama_stretch)
1425
max = desktop->priv->nbackdrops;
1426
for(i = 0; i < max; ++i) {
1427
GValue val = { 0, };
1429
g_snprintf(buf, sizeof(buf), "%smonitor%d/image-path",
1430
desktop->priv->property_prefix, i);
1431
xfconf_channel_get_property(desktop->priv->channel, buf, &val);
1433
xfce_desktop_image_filename_changed(desktop->priv->channel, buf,
1436
if(G_VALUE_TYPE(&val))
1437
g_value_unset(&val);
1440
#ifdef ENABLE_DESKTOP_ICONS
1441
/* reload icon view */
1442
if(desktop->priv->icon_view) {
1443
gtk_widget_destroy(desktop->priv->icon_view);
1444
desktop->priv->icon_view = NULL;
1446
xfce_desktop_setup_icon_view(desktop);