Merge lp:~noskcaj/ubuntu/trusty/xfdesktop4/merge into lp:ubuntu/trusty/xfdesktop4

Proposed by Jackson Doak
Status: Merged
Merge reported by: Dmitry Shachnev
Merged at revision: not available
Proposed branch: lp:~noskcaj/ubuntu/trusty/xfdesktop4/merge
Merge into: lp:ubuntu/trusty/xfdesktop4
Diff against target: 1819 lines (+1750/-0)
8 files modified
.pc/applied-patches (+1/-0)
.pc/git-fix-segfault-on-session-start.patch/src/xfce-desktop.c (+1695/-0)
.pc/xubuntu_improve-nautilus-interactions.patch/src/xfce-desktop.c (+4/-0)
.pc/xubuntu_set-accountsservice-user-bg.patch/src/xfce-desktop.c (+4/-0)
debian/changelog (+18/-0)
debian/patches/git-fix-segfault-on-session-start.patch (+23/-0)
debian/patches/series (+1/-0)
src/xfce-desktop.c (+4/-0)
To merge this branch: bzr merge lp:~noskcaj/ubuntu/trusty/xfdesktop4/merge
Reviewer Review Type Date Requested Status
Dmitry Shachnev Approve
Ubuntu branches Pending
Review via email: mp+208918@code.launchpad.net

Description of the change

Fixes xubuntu's current biggest bug

To post a comment you must log in.
Revision history for this message
Dmitry Shachnev (mitya57) wrote :

Thanks, uploaded.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file '.pc/applied-patches'
--- .pc/applied-patches 2014-01-22 11:02:26 +0000
+++ .pc/applied-patches 2014-03-01 05:37:37 +0000
@@ -1,2 +1,3 @@
1git-fix-segfault-on-session-start.patch
1xubuntu_set-accountsservice-user-bg.patch2xubuntu_set-accountsservice-user-bg.patch
2xubuntu_improve-nautilus-interactions.patch3xubuntu_improve-nautilus-interactions.patch
34
=== added directory '.pc/git-fix-segfault-on-session-start.patch'
=== added file '.pc/git-fix-segfault-on-session-start.patch/.timestamp'
=== added directory '.pc/git-fix-segfault-on-session-start.patch/src'
=== added file '.pc/git-fix-segfault-on-session-start.patch/src/xfce-desktop.c'
--- .pc/git-fix-segfault-on-session-start.patch/src/xfce-desktop.c 1970-01-01 00:00:00 +0000
+++ .pc/git-fix-segfault-on-session-start.patch/src/xfce-desktop.c 2014-03-01 05:37:37 +0000
@@ -0,0 +1,1695 @@
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 Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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#include <libwnck/libwnck.h>
81
82#include "xfdesktop-common.h"
83#include "xfce-desktop.h"
84#include "xfce-desktop-enum-types.h"
85#include "xfce-workspace.h"
86
87/* disable setting the x background for bug 7442 */
88//#define DISABLE_FOR_BUG7442
89
90struct _XfceDesktopPriv
91{
92 GdkScreen *gscreen;
93 WnckScreen *wnck_screen;
94 gboolean updates_frozen;
95
96 XfconfChannel *channel;
97 gchar *property_prefix;
98
99 GdkPixmap *bg_pixmap;
100
101 gint nworkspaces;
102 XfceWorkspace **workspaces;
103 gint current_workspace;
104
105 gboolean single_workspace_mode;
106 gint single_workspace_num;
107
108 SessionLogoutFunc session_logout_func;
109
110 guint32 grab_time;
111
112#ifdef ENABLE_DESKTOP_ICONS
113 XfceDesktopIconStyle icons_style;
114 gboolean icons_font_size_set;
115 guint icons_font_size;
116 guint icons_size;
117 gint style_refresh_timer;
118 GtkWidget *icon_view;
119 gdouble system_font_size;
120#endif
121};
122
123enum
124{
125 SIG_POPULATE_ROOT_MENU = 0,
126 SIG_POPULATE_SECONDARY_ROOT_MENU,
127 N_SIGNALS
128};
129
130enum
131{
132 PROP_0 = 0,
133#ifdef ENABLE_DESKTOP_ICONS
134 PROP_ICON_STYLE,
135 PROP_ICON_SIZE,
136 PROP_ICON_FONT_SIZE,
137 PROP_ICON_FONT_SIZE_SET,
138#endif
139 PROP_SINGLE_WORKSPACE_MODE,
140 PROP_SINGLE_WORKSPACE_NUMBER,
141};
142
143
144static void xfce_desktop_finalize(GObject *object);
145static void xfce_desktop_set_property(GObject *object,
146 guint property_id,
147 const GValue *value,
148 GParamSpec *pspec);
149static void xfce_desktop_get_property(GObject *object,
150 guint property_id,
151 GValue *value,
152 GParamSpec *pspec);
153
154static void xfce_desktop_realize(GtkWidget *widget);
155static void xfce_desktop_unrealize(GtkWidget *widget);
156static gboolean xfce_desktop_button_press_event(GtkWidget *widget,
157 GdkEventButton *evt);
158static gboolean xfce_desktop_button_release_event(GtkWidget *widget,
159 GdkEventButton *evt);
160static gboolean xfce_desktop_popup_menu(GtkWidget *widget);
161
162static gboolean xfce_desktop_expose(GtkWidget *w,
163 GdkEventExpose *evt);
164static gboolean xfce_desktop_delete_event(GtkWidget *w,
165 GdkEventAny *evt);
166static void xfce_desktop_style_set(GtkWidget *w,
167 GtkStyle *old_style);
168
169static void xfce_desktop_set_single_workspace_mode(XfceDesktop *desktop,
170 gboolean single_workspace);
171static void xfce_desktop_set_single_workspace_number(XfceDesktop *desktop,
172 gint workspace_num);
173
174static gboolean xfce_desktop_get_single_workspace_mode(XfceDesktop *desktop);
175static gint xfce_desktop_get_current_workspace(XfceDesktop *desktop);
176
177static guint signals[N_SIGNALS] = { 0, };
178
179/* private functions */
180
181#ifdef ENABLE_DESKTOP_ICONS
182static gdouble
183xfce_desktop_ensure_system_font_size(XfceDesktop *desktop)
184{
185 GdkScreen *gscreen;
186 GtkSettings *settings;
187 gchar *font_name = NULL;
188 PangoFontDescription *pfd;
189
190 gscreen = gtk_widget_get_screen(GTK_WIDGET(desktop));
191
192 settings = gtk_settings_get_for_screen(gscreen);
193 g_object_get(G_OBJECT(settings), "gtk-font-name", &font_name, NULL);
194
195 pfd = pango_font_description_from_string(font_name);
196 desktop->priv->system_font_size = pango_font_description_get_size(pfd);
197 /* FIXME: this seems backwards from the documentation */
198 if(!pango_font_description_get_size_is_absolute(pfd)) {
199 DBG("dividing by PANGO_SCALE");
200 desktop->priv->system_font_size /= PANGO_SCALE;
201 }
202 DBG("system font size is %.05f", desktop->priv->system_font_size);
203
204 g_free(font_name);
205 pango_font_description_free(pfd);
206
207 return desktop->priv->system_font_size;
208}
209
210static void
211xfce_desktop_setup_icon_view(XfceDesktop *desktop)
212{
213 XfdesktopIconViewManager *manager = NULL;
214
215 switch(desktop->priv->icons_style) {
216 case XFCE_DESKTOP_ICON_STYLE_NONE:
217 /* nada */
218 break;
219
220 case XFCE_DESKTOP_ICON_STYLE_WINDOWS:
221 manager = xfdesktop_window_icon_manager_new(desktop->priv->gscreen);
222 break;
223
224#ifdef ENABLE_FILE_ICONS
225 case XFCE_DESKTOP_ICON_STYLE_FILES:
226 {
227 GFile *file;
228 const gchar *desktop_path;
229
230 desktop_path = g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP);
231 file = g_file_new_for_path(desktop_path);
232 manager = xfdesktop_file_icon_manager_new(file, desktop->priv->channel);
233 g_object_unref(file);
234 }
235 break;
236#endif
237
238 default:
239 g_critical("Unusable XfceDesktopIconStyle: %d. Unable to " \
240 "display desktop icons.",
241 desktop->priv->icons_style);
242 break;
243 }
244
245 if(manager) {
246 xfce_desktop_ensure_system_font_size(desktop);
247
248 desktop->priv->icon_view = xfdesktop_icon_view_new(manager);
249 /* If the user set a custom font size, use it. Otherwise use the system
250 * font size */
251 xfdesktop_icon_view_set_font_size(XFDESKTOP_ICON_VIEW(desktop->priv->icon_view),
252 (!desktop->priv->icons_font_size_set)
253 ? desktop->priv->system_font_size
254 : desktop->priv->icons_font_size);
255 if(desktop->priv->icons_size > 0) {
256 xfdesktop_icon_view_set_icon_size(XFDESKTOP_ICON_VIEW(desktop->priv->icon_view),
257 desktop->priv->icons_size);
258 }
259 gtk_widget_show(desktop->priv->icon_view);
260 gtk_container_add(GTK_CONTAINER(desktop), desktop->priv->icon_view);
261 }
262
263 gtk_widget_queue_draw(GTK_WIDGET(desktop));
264}
265#endif
266
267static void
268set_imgfile_root_property(XfceDesktop *desktop, const gchar *filename,
269 gint monitor)
270{
271 gchar property_name[128];
272
273 gdk_error_trap_push();
274
275 g_snprintf(property_name, 128, XFDESKTOP_IMAGE_FILE_FMT, monitor);
276 if(filename) {
277 gdk_property_change(gdk_screen_get_root_window(desktop->priv->gscreen),
278 gdk_atom_intern(property_name, FALSE),
279 gdk_x11_xatom_to_atom(XA_STRING), 8,
280 GDK_PROP_MODE_REPLACE,
281 (guchar *)filename, strlen(filename)+1);
282 } else {
283 gdk_property_delete(gdk_screen_get_root_window(desktop->priv->gscreen),
284 gdk_atom_intern(property_name, FALSE));
285 }
286
287 gdk_error_trap_pop();
288}
289
290static void
291set_real_root_window_pixmap(GdkScreen *gscreen,
292 GdkPixmap *pmap)
293{
294#ifndef DISABLE_FOR_BUG7442
295 Window xid;
296 GdkWindow *groot;
297
298 xid = GDK_DRAWABLE_XID(pmap);
299 groot = gdk_screen_get_root_window(gscreen);
300
301 gdk_error_trap_push();
302
303 /* set root property for transparent Eterms */
304 gdk_property_change(groot,
305 gdk_atom_intern("_XROOTPMAP_ID", FALSE),
306 gdk_atom_intern("PIXMAP", FALSE), 32,
307 GDK_PROP_MODE_REPLACE, (guchar *)&xid, 1);
308 /* and set the root window's BG pixmap, because aterm is somewhat lame. */
309 gdk_window_set_back_pixmap(groot, pmap, FALSE);
310 /* there really should be a standard for this crap... */
311
312 gdk_error_trap_pop();
313#endif
314}
315
316static GdkPixmap *
317create_bg_pixmap(GdkScreen *gscreen, gpointer user_data)
318{
319 XfceDesktop *desktop = user_data;
320 gint w, h;
321
322 TRACE("entering");
323
324 g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), NULL);
325
326 /* If the workspaces haven't been created yet there's no need to do the
327 * background pixmap */
328 if(desktop->priv->workspaces == NULL) {
329 DBG("exiting, desktop->priv->workspaces == NULL");
330 return NULL;
331 }
332
333 TRACE("really entering");
334
335 w = gdk_screen_get_width(gscreen);
336 h = gdk_screen_get_height(gscreen);
337 gtk_widget_set_size_request(GTK_WIDGET(desktop), w, h);
338 gtk_window_resize(GTK_WINDOW(desktop), w, h);
339
340 if(desktop->priv->bg_pixmap)
341 g_object_unref(G_OBJECT(desktop->priv->bg_pixmap));
342 desktop->priv->bg_pixmap = gdk_pixmap_new(GDK_DRAWABLE(gtk_widget_get_window(GTK_WIDGET(desktop))),
343 w, h, -1);
344
345 if(!GDK_IS_PIXMAP(desktop->priv->bg_pixmap))
346 return NULL;
347
348 gdk_window_set_back_pixmap(gtk_widget_get_window(GTK_WIDGET(desktop)),
349 desktop->priv->bg_pixmap, FALSE);
350
351 return desktop->priv->bg_pixmap;
352}
353
354static void
355backdrop_changed_cb(XfceBackdrop *backdrop, gpointer user_data)
356{
357 XfceDesktop *desktop = XFCE_DESKTOP(user_data);
358 GdkPixmap *pmap = desktop->priv->bg_pixmap;
359 GdkScreen *gscreen = desktop->priv->gscreen;
360 GdkRectangle rect;
361 GdkRegion *clip_region = NULL;
362 gint i, monitor = -1, current_workspace;
363#ifdef G_ENABLE_DEBUG
364 gchar *monitor_name = NULL;
365#endif
366
367 TRACE("entering");
368
369 g_return_if_fail(XFCE_IS_DESKTOP(desktop));
370
371 if(desktop->priv->updates_frozen || !gtk_widget_get_realized(GTK_WIDGET(desktop)))
372 return;
373
374 TRACE("really entering");
375
376 current_workspace = xfce_desktop_get_current_workspace(desktop);
377
378 /* Find out which monitor the backdrop is on */
379 for(i = 0; i < xfce_desktop_get_n_monitors(desktop); i++) {
380 if(backdrop == xfce_workspace_get_backdrop(desktop->priv->workspaces[current_workspace], i)) {
381 monitor = i;
382 break;
383 }
384 }
385 if(monitor == -1)
386 return;
387
388#ifdef G_ENABLE_DEBUG
389 monitor_name = gdk_screen_get_monitor_plug_name(gscreen, monitor);
390
391 DBG("backdrop changed for workspace %d, monitor %d (%s)", current_workspace, monitor, monitor_name);
392
393 g_free(monitor_name);
394#endif
395
396 if(xfce_desktop_get_n_monitors(desktop) > 1
397 && xfce_workspace_get_xinerama_stretch(desktop->priv->workspaces[current_workspace])) {
398 /* Spanning screens */
399 GdkRectangle monitor_rect;
400
401 gdk_screen_get_monitor_geometry(gscreen, 0, &rect);
402 /* Get the lowest x and y value for all the monitors in
403 * case none of them start at 0,0 for whatever reason.
404 */
405 for(i = 1; i < xfce_desktop_get_n_monitors(desktop); i++) {
406 gdk_screen_get_monitor_geometry(gscreen, i, &monitor_rect);
407
408 if(monitor_rect.x < rect.x)
409 rect.x = monitor_rect.x;
410 if(monitor_rect.y < rect.y)
411 rect.y = monitor_rect.y;
412 }
413
414 rect.width = gdk_screen_get_width(gscreen);
415 rect.height = gdk_screen_get_height(gscreen);
416 DBG("xinerama_stretch x %d, y %d, width %d, height %d",
417 rect.x, rect.y, rect.width, rect.height);
418 } else {
419 gdk_screen_get_monitor_geometry(gscreen, monitor, &rect);
420 DBG("monitor x %d, y %d, width %d, height %d",
421 rect.x, rect.y, rect.width, rect.height);
422 }
423
424 xfce_backdrop_set_size(backdrop, rect.width, rect.height);
425
426 if(monitor > 0
427 && !xfce_workspace_get_xinerama_stretch(desktop->priv->workspaces[current_workspace])) {
428 clip_region = gdk_region_rectangle(&rect);
429
430 DBG("clip_region: x: %d, y: %d, w: %d, h: %d",
431 rect.x, rect.y, rect.width, rect.height);
432
433 /* If we are not monitor 0 on a multi-monitor setup we need to subtract
434 * all the previous monitor regions so we don't draw over them. This
435 * should prevent the overlap and double backdrop drawing bugs.
436 */
437 for(i = 0; i < monitor; i++) {
438 GdkRectangle previous_monitor;
439 GdkRegion *previous_region;
440 gdk_screen_get_monitor_geometry(gscreen, i, &previous_monitor);
441
442 DBG("previous_monitor: x: %d, y: %d, w: %d, h: %d",
443 previous_monitor.x, previous_monitor.y,
444 previous_monitor.width, previous_monitor.height);
445
446 previous_region = gdk_region_rectangle(&previous_monitor);
447
448 gdk_region_subtract(clip_region, previous_region);
449
450 gdk_region_destroy(previous_region);
451 }
452 }
453
454 if(clip_region != NULL) {
455 /* Update the area to redraw to limit the icons/area painted */
456 gdk_region_get_clipbox(clip_region, &rect);
457 DBG("area to update: x: %d, y: %d, w: %d, h: %d",
458 rect.x, rect.y, rect.width, rect.height);
459 }
460
461 if(rect.width != 0 && rect.height != 0) {
462 /* get the composited backdrop pixmap */
463 GdkPixbuf *pix = xfce_backdrop_get_pixbuf(backdrop);
464 cairo_t *cr;
465
466 /* create the backdrop if needed */
467 if(!pix) {
468 xfce_backdrop_generate_async(backdrop);
469
470 if(clip_region != NULL)
471 gdk_region_destroy(clip_region);
472
473 return;
474 }
475
476 /* Create the background pixmap if it isn't already */
477 if(!GDK_IS_PIXMAP(pmap)) {
478 pmap = create_bg_pixmap(gscreen, desktop);
479
480 if(!GDK_IS_PIXMAP(pmap)) {
481 g_object_unref(pix);
482
483 if(clip_region != NULL)
484 gdk_region_destroy(clip_region);
485
486 return;
487 }
488 }
489
490 cr = gdk_cairo_create(GDK_DRAWABLE(pmap));
491 gdk_cairo_set_source_pixbuf(cr, pix, rect.x, rect.y);
492
493 /* clip the area so we don't draw over a previous wallpaper */
494 if(clip_region != NULL) {
495 gdk_cairo_region(cr, clip_region);
496 cairo_clip(cr);
497 }
498
499 cairo_paint(cr);
500
501 /* tell gtk to redraw the repainted area */
502 gtk_widget_queue_draw_area(GTK_WIDGET(desktop), rect.x, rect.y,
503 rect.width, rect.height);
504
505 set_imgfile_root_property(desktop,
506 xfce_backdrop_get_image_filename(backdrop),
507 monitor);
508
509 /* do this again so apps watching the root win notice the update */
510 set_real_root_window_pixmap(gscreen, pmap);
511
512 g_object_unref(G_OBJECT(pix));
513 cairo_destroy(cr);
514 gtk_widget_show(GTK_WIDGET(desktop));
515 }
516
517 if(clip_region != NULL)
518 gdk_region_destroy(clip_region);
519}
520
521static void
522screen_size_changed_cb(GdkScreen *gscreen, gpointer user_data)
523{
524 XfceDesktop *desktop = user_data;
525 gint current_workspace;
526
527 TRACE("entering");
528
529 current_workspace = xfce_desktop_get_current_workspace(desktop);
530
531 if(desktop->priv->nworkspaces <= current_workspace)
532 return;
533
534 if(current_workspace < 0)
535 return;
536
537 /* release the bg_pixmap since the dimensions may have changed */
538 if(desktop->priv->bg_pixmap) {
539 g_object_unref(desktop->priv->bg_pixmap);
540 desktop->priv->bg_pixmap = NULL;
541 }
542
543 /* special case for 1 backdrop to handle xinerama stretching */
544 if(xfce_workspace_get_xinerama_stretch(desktop->priv->workspaces[current_workspace])) {
545 backdrop_changed_cb(xfce_workspace_get_backdrop(desktop->priv->workspaces[current_workspace], 0), desktop);
546 } else {
547 gint i;
548
549 for(i = 0; i < xfce_desktop_get_n_monitors(desktop); i++) {
550 XfceBackdrop *current_backdrop;
551 current_backdrop = xfce_workspace_get_backdrop(desktop->priv->workspaces[current_workspace], i);
552 backdrop_changed_cb(current_backdrop, desktop);
553 }
554 }
555}
556
557static void
558screen_composited_changed_cb(GdkScreen *gscreen,
559 gpointer user_data)
560{
561 TRACE("entering");
562 /* fake a screen size changed, so the background is properly set */
563 screen_size_changed_cb(gscreen, user_data);
564}
565
566static void
567xfce_desktop_monitors_changed(GdkScreen *gscreen,
568 gpointer user_data)
569{
570 XfceDesktop *desktop = XFCE_DESKTOP(user_data);
571 gint i;
572
573 TRACE("entering");
574
575 /* Update the workspaces */
576 for(i = 0; i < desktop->priv->nworkspaces; i++) {
577 xfce_workspace_monitors_changed(desktop->priv->workspaces[i],
578 gscreen);
579 }
580
581 /* fake a screen size changed, so the background is properly set */
582 screen_size_changed_cb(gscreen, user_data);
583}
584
585static void
586workspace_backdrop_changed_cb(XfceWorkspace *workspace,
587 XfceBackdrop *backdrop,
588 gpointer user_data)
589{
590 XfceDesktop *desktop = XFCE_DESKTOP(user_data);
591
592 TRACE("entering");
593
594 g_return_if_fail(XFCE_IS_WORKSPACE(workspace) && XFCE_IS_BACKDROP(backdrop));
595
596 if(xfce_desktop_get_current_workspace(desktop) == xfce_workspace_get_workspace_num(workspace))
597 backdrop_changed_cb(backdrop, user_data);
598}
599
600static void
601workspace_changed_cb(WnckScreen *wnck_screen,
602 WnckWorkspace *previously_active_space,
603 gpointer user_data)
604{
605 XfceDesktop *desktop = XFCE_DESKTOP(user_data);
606 gint current_workspace, new_workspace, i;
607 XfceBackdrop *new_backdrop;
608
609 TRACE("entering");
610
611 /* Ignore workspace changes in single workspace mode so long as we
612 * already have the bg_pixmap loaded */
613 if(xfce_desktop_get_single_workspace_mode(desktop) && desktop->priv->bg_pixmap)
614 return;
615
616 current_workspace = desktop->priv->current_workspace;
617 new_workspace = xfce_desktop_get_current_workspace(desktop);
618
619 if(new_workspace < 0 || new_workspace >= desktop->priv->nworkspaces)
620 return;
621
622 desktop->priv->current_workspace = new_workspace;
623
624 DBG("current_workspace %d, new_workspace %d",
625 current_workspace, new_workspace);
626
627 for(i = 0; i < xfce_desktop_get_n_monitors(desktop); i++) {
628 /* Sanity check */
629 if(current_workspace < desktop->priv->nworkspaces && current_workspace >= 0) {
630 /* update! */
631 new_backdrop = xfce_workspace_get_backdrop(desktop->priv->workspaces[new_workspace], i);
632 backdrop_changed_cb(new_backdrop, user_data);
633 } else {
634 /* If current_workspace was removed or never existed, get the new
635 * backdrop and apply it */
636 new_backdrop = xfce_workspace_get_backdrop(desktop->priv->workspaces[new_workspace], i);
637 backdrop_changed_cb(new_backdrop, user_data);
638 }
639
640 /* When we're spanning screens we only care about the first monitor */
641 if(xfce_workspace_get_xinerama_stretch(desktop->priv->workspaces[new_workspace]))
642 break;
643 }
644}
645
646static void
647workspace_created_cb(WnckScreen *wnck_screen,
648 WnckWorkspace *new_workspace,
649 gpointer user_data)
650{
651 XfceDesktop *desktop = XFCE_DESKTOP(user_data);
652 gint nlast_workspace;
653 TRACE("entering");
654
655 nlast_workspace = desktop->priv->nworkspaces;
656
657 /* add one more workspace */
658 desktop->priv->nworkspaces = nlast_workspace + 1;
659
660 /* allocate size for it */
661 desktop->priv->workspaces = g_realloc(desktop->priv->workspaces,
662 desktop->priv->nworkspaces * sizeof(XfceWorkspace *));
663
664 /* create the new workspace and set it up */
665 desktop->priv->workspaces[nlast_workspace] = xfce_workspace_new(desktop->priv->gscreen,
666 desktop->priv->channel,
667 desktop->priv->property_prefix,
668 nlast_workspace);
669
670 /* Tell workspace whether to cache pixbufs */
671 xfce_workspace_set_cache_pixbufs(desktop->priv->workspaces[nlast_workspace],
672 !desktop->priv->single_workspace_mode);
673
674 xfce_workspace_monitors_changed(desktop->priv->workspaces[nlast_workspace],
675 desktop->priv->gscreen);
676
677 g_signal_connect(desktop->priv->workspaces[nlast_workspace],
678 "workspace-backdrop-changed",
679 G_CALLBACK(workspace_backdrop_changed_cb), desktop);
680}
681
682static void
683workspace_destroyed_cb(WnckScreen *wnck_screen,
684 WnckWorkspace *old_workspace,
685 gpointer user_data)
686{
687 XfceDesktop *desktop = XFCE_DESKTOP(user_data);
688 gint nlast_workspace;
689 TRACE("entering");
690
691 g_return_if_fail(XFCE_IS_DESKTOP(desktop));
692 g_return_if_fail(desktop->priv->nworkspaces - 1 >= 0);
693 g_return_if_fail(XFCE_IS_WORKSPACE(desktop->priv->workspaces[desktop->priv->nworkspaces-1]));
694
695 nlast_workspace = desktop->priv->nworkspaces - 1;
696
697 g_signal_handlers_disconnect_by_func(desktop->priv->workspaces[nlast_workspace],
698 G_CALLBACK(workspace_backdrop_changed_cb),
699 desktop);
700
701 g_object_unref(desktop->priv->workspaces[nlast_workspace]);
702
703 /* Remove one workspace */
704 desktop->priv->nworkspaces = nlast_workspace;
705
706 /* deallocate it */
707 desktop->priv->workspaces = g_realloc(desktop->priv->workspaces,
708 desktop->priv->nworkspaces * sizeof(XfceWorkspace *));
709
710 /* Make sure we stay within bounds now that we removed a workspace */
711 if(desktop->priv->current_workspace > desktop->priv->nworkspaces)
712 desktop->priv->current_workspace = desktop->priv->nworkspaces;
713}
714
715static void
716screen_set_selection(XfceDesktop *desktop)
717{
718 Window xwin;
719 gint xscreen;
720 gchar selection_name[100];
721 Atom selection_atom, manager_atom;
722
723 xwin = GDK_WINDOW_XID(gtk_widget_get_window(GTK_WIDGET(desktop)));
724 xscreen = gdk_screen_get_number(desktop->priv->gscreen);
725
726 g_snprintf(selection_name, 100, XFDESKTOP_SELECTION_FMT, xscreen);
727 selection_atom = XInternAtom(gdk_x11_get_default_xdisplay(), selection_name, False);
728 manager_atom = XInternAtom(gdk_x11_get_default_xdisplay(), "MANAGER", False);
729
730 /* the previous check in src/main.c occurs too early, so workaround by
731 * adding this one. */
732 if(XGetSelectionOwner(gdk_x11_get_default_xdisplay(), selection_atom) != None) {
733 g_warning("%s: already running, quitting.", PACKAGE);
734 exit(0);
735 }
736
737 XSelectInput(gdk_x11_get_default_xdisplay(), xwin, PropertyChangeMask | ButtonPressMask);
738 XSetSelectionOwner(gdk_x11_get_default_xdisplay(), selection_atom, xwin, GDK_CURRENT_TIME);
739
740 /* Check to see if we managed to claim the selection. If not,
741 * we treat it as if we got it then immediately lost it */
742 if(XGetSelectionOwner(gdk_x11_get_default_xdisplay(), selection_atom) == xwin) {
743 XClientMessageEvent xev;
744 Window xroot = GDK_WINDOW_XID(gdk_screen_get_root_window(desktop->priv->gscreen));
745
746 xev.type = ClientMessage;
747 xev.window = xroot;
748 xev.message_type = manager_atom;
749 xev.format = 32;
750 xev.data.l[0] = GDK_CURRENT_TIME;
751 xev.data.l[1] = selection_atom;
752 xev.data.l[2] = xwin;
753 xev.data.l[3] = 0; /* manager specific data */
754 xev.data.l[4] = 0; /* manager specific data */
755
756 XSendEvent(gdk_x11_get_default_xdisplay(), xroot, False, StructureNotifyMask, (XEvent *)&xev);
757 } else {
758 g_error("%s: could not set selection ownership", PACKAGE);
759 exit(1);
760 }
761}
762
763
764
765/* gobject-related functions */
766
767
768G_DEFINE_TYPE(XfceDesktop, xfce_desktop, GTK_TYPE_WINDOW)
769
770
771static void
772xfce_desktop_class_init(XfceDesktopClass *klass)
773{
774 GObjectClass *gobject_class = (GObjectClass *)klass;
775 GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
776
777 g_type_class_add_private(klass, sizeof(XfceDesktopPriv));
778
779 gobject_class->finalize = xfce_desktop_finalize;
780 gobject_class->set_property = xfce_desktop_set_property;
781 gobject_class->get_property = xfce_desktop_get_property;
782
783 widget_class->realize = xfce_desktop_realize;
784 widget_class->unrealize = xfce_desktop_unrealize;
785 widget_class->button_press_event = xfce_desktop_button_press_event;
786 widget_class->button_release_event = xfce_desktop_button_release_event;
787 widget_class->expose_event = xfce_desktop_expose;
788 widget_class->delete_event = xfce_desktop_delete_event;
789 widget_class->popup_menu = xfce_desktop_popup_menu;
790 widget_class->style_set = xfce_desktop_style_set;
791
792 signals[SIG_POPULATE_ROOT_MENU] = g_signal_new("populate-root-menu",
793 XFCE_TYPE_DESKTOP,
794 G_SIGNAL_RUN_LAST,
795 G_STRUCT_OFFSET(XfceDesktopClass,
796 populate_root_menu),
797 NULL, NULL,
798 g_cclosure_marshal_VOID__OBJECT,
799 G_TYPE_NONE, 1,
800 GTK_TYPE_MENU_SHELL);
801
802 signals[SIG_POPULATE_SECONDARY_ROOT_MENU] = g_signal_new("populate-secondary-root-menu",
803 XFCE_TYPE_DESKTOP,
804 G_SIGNAL_RUN_LAST,
805 G_STRUCT_OFFSET(XfceDesktopClass,
806 populate_secondary_root_menu),
807 NULL, NULL,
808 g_cclosure_marshal_VOID__OBJECT,
809 G_TYPE_NONE, 1,
810 GTK_TYPE_MENU_SHELL);
811
812#define XFDESKTOP_PARAM_FLAGS (G_PARAM_READWRITE \
813 | G_PARAM_CONSTRUCT \
814 | G_PARAM_STATIC_NAME \
815 | G_PARAM_STATIC_NICK \
816 | G_PARAM_STATIC_BLURB)
817
818#ifdef ENABLE_DESKTOP_ICONS
819 g_object_class_install_property(gobject_class, PROP_ICON_STYLE,
820 g_param_spec_enum("icon-style",
821 "icon style",
822 "icon style",
823 XFCE_TYPE_DESKTOP_ICON_STYLE,
824#ifdef ENABLE_FILE_ICONS
825 XFCE_DESKTOP_ICON_STYLE_FILES,
826#else
827 XFCE_DESKTOP_ICON_STYLE_WINDOWS,
828#endif /* ENABLE_FILE_ICONS */
829 XFDESKTOP_PARAM_FLAGS));
830
831 g_object_class_install_property(gobject_class, PROP_ICON_SIZE,
832 g_param_spec_uint("icon-size",
833 "icon size",
834 "icon size",
835 8, 192, 36,
836 XFDESKTOP_PARAM_FLAGS));
837
838 g_object_class_install_property(gobject_class, PROP_ICON_FONT_SIZE,
839 g_param_spec_uint("icon-font-size",
840 "icon font size",
841 "icon font size",
842 0, 144, 12,
843 XFDESKTOP_PARAM_FLAGS));
844
845 g_object_class_install_property(gobject_class, PROP_ICON_FONT_SIZE_SET,
846 g_param_spec_boolean("icon-font-size-set",
847 "icon font size set",
848 "icon font size set",
849 FALSE,
850 XFDESKTOP_PARAM_FLAGS));
851
852#endif /* ENABLE_DESKTOP_ICONS */
853
854 g_object_class_install_property(gobject_class, PROP_SINGLE_WORKSPACE_MODE,
855 g_param_spec_boolean("single-workspace-mode",
856 "single-workspace-mode",
857 "single-workspace-mode",
858 TRUE,
859 XFDESKTOP_PARAM_FLAGS));
860
861 g_object_class_install_property(gobject_class, PROP_SINGLE_WORKSPACE_NUMBER,
862 g_param_spec_int("single-workspace-number",
863 "single-workspace-number",
864 "single-workspace-number",
865 0, G_MAXINT16, 0,
866 XFDESKTOP_PARAM_FLAGS));
867
868#undef XFDESKTOP_PARAM_FLAGS
869}
870
871static void
872xfce_desktop_init(XfceDesktop *desktop)
873{
874 desktop->priv = G_TYPE_INSTANCE_GET_PRIVATE(desktop, XFCE_TYPE_DESKTOP,
875 XfceDesktopPriv);
876
877 gtk_window_set_type_hint(GTK_WINDOW(desktop), GDK_WINDOW_TYPE_HINT_DESKTOP);
878 /* Accept focus is needed for the menu pop up either by the menu key on
879 * the keyboard or Shift+F10. */
880 gtk_window_set_accept_focus(GTK_WINDOW(desktop), TRUE);
881 /* Can focus is needed for the gtk_grab_add/remove commands */
882 gtk_widget_set_can_focus(GTK_WIDGET(desktop), TRUE);
883 gtk_window_set_resizable(GTK_WINDOW(desktop), FALSE);
884}
885
886static void
887xfce_desktop_finalize(GObject *object)
888{
889 XfceDesktop *desktop = XFCE_DESKTOP(object);
890
891 g_object_unref(G_OBJECT(desktop->priv->channel));
892 g_free(desktop->priv->property_prefix);
893
894 if(desktop->priv->style_refresh_timer != 0)
895 g_source_remove(desktop->priv->style_refresh_timer);
896
897 G_OBJECT_CLASS(xfce_desktop_parent_class)->finalize(object);
898}
899
900static void
901xfce_desktop_set_property(GObject *object,
902 guint property_id,
903 const GValue *value,
904 GParamSpec *pspec)
905{
906 XfceDesktop *desktop = XFCE_DESKTOP(object);
907
908 switch(property_id) {
909#ifdef ENABLE_DESKTOP_ICONS
910 case PROP_ICON_STYLE:
911 xfce_desktop_set_icon_style(desktop,
912 g_value_get_enum(value));
913 break;
914
915 case PROP_ICON_SIZE:
916 xfce_desktop_set_icon_size(desktop,
917 g_value_get_uint(value));
918 break;
919
920 case PROP_ICON_FONT_SIZE:
921 xfce_desktop_set_icon_font_size(desktop,
922 g_value_get_uint(value));
923 break;
924
925 case PROP_ICON_FONT_SIZE_SET:
926 xfce_desktop_set_use_icon_font_size(desktop,
927 g_value_get_boolean(value));
928 break;
929
930#endif
931 case PROP_SINGLE_WORKSPACE_MODE:
932 xfce_desktop_set_single_workspace_mode(desktop,
933 g_value_get_boolean(value));
934 break;
935
936 case PROP_SINGLE_WORKSPACE_NUMBER:
937 xfce_desktop_set_single_workspace_number(desktop,
938 g_value_get_int(value));
939 break;
940
941 default:
942 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
943 break;
944 }
945}
946
947static void
948xfce_desktop_get_property(GObject *object,
949 guint property_id,
950 GValue *value,
951 GParamSpec *pspec)
952{
953 XfceDesktop *desktop = XFCE_DESKTOP(object);
954
955 switch(property_id) {
956#ifdef ENABLE_DESKTOP_ICONS
957 case PROP_ICON_STYLE:
958 g_value_set_enum(value, desktop->priv->icons_style);
959 break;
960
961 case PROP_ICON_SIZE:
962 g_value_set_uint(value, desktop->priv->icons_size);
963 break;
964
965 case PROP_ICON_FONT_SIZE:
966 g_value_set_uint(value, desktop->priv->icons_font_size);
967 break;
968
969 case PROP_ICON_FONT_SIZE_SET:
970 g_value_set_boolean(value, desktop->priv->icons_font_size_set);
971 break;
972
973#endif
974 case PROP_SINGLE_WORKSPACE_MODE:
975 g_value_set_boolean(value, desktop->priv->single_workspace_mode);
976 break;
977
978 case PROP_SINGLE_WORKSPACE_NUMBER:
979 g_value_set_int(value, desktop->priv->single_workspace_num);
980 break;
981
982 default:
983 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
984 break;
985 }
986}
987
988static void
989xfce_desktop_realize(GtkWidget *widget)
990{
991 XfceDesktop *desktop = XFCE_DESKTOP(widget);
992 GdkAtom atom;
993 gint sw, sh;
994 Window xid;
995 GdkWindow *groot;
996 WnckScreen *wnck_screen;
997
998 TRACE("entering");
999
1000 gtk_window_set_screen(GTK_WINDOW(desktop), desktop->priv->gscreen);
1001 sw = gdk_screen_get_width(desktop->priv->gscreen);
1002 sh = gdk_screen_get_height(desktop->priv->gscreen);
1003 if(gtk_major_version > 2
1004 || (gtk_major_version == 2 && gtk_minor_version >= 13))
1005 {
1006 g_signal_connect(G_OBJECT(desktop->priv->gscreen),
1007 "monitors-changed",
1008 G_CALLBACK(xfce_desktop_monitors_changed),
1009 desktop);
1010 }
1011
1012 /* chain up */
1013 GTK_WIDGET_CLASS(xfce_desktop_parent_class)->realize(widget);
1014
1015 gtk_window_set_title(GTK_WINDOW(desktop), _("Desktop"));
1016
1017 gtk_widget_set_size_request(GTK_WIDGET(desktop), sw, sh);
1018 gtk_window_move(GTK_WINDOW(desktop), 0, 0);
1019
1020 atom = gdk_atom_intern("_NET_WM_WINDOW_TYPE_DESKTOP", FALSE);
1021 gdk_property_change(gtk_widget_get_window(GTK_WIDGET(desktop)),
1022 gdk_atom_intern("_NET_WM_WINDOW_TYPE", FALSE),
1023 gdk_atom_intern("ATOM", FALSE), 32,
1024 GDK_PROP_MODE_REPLACE, (guchar *)&atom, 1);
1025
1026 xid = GDK_WINDOW_XID(gtk_widget_get_window(GTK_WIDGET(desktop)));
1027 groot = gdk_screen_get_root_window(desktop->priv->gscreen);
1028
1029 gdk_property_change(groot,
1030 gdk_atom_intern("XFCE_DESKTOP_WINDOW", FALSE),
1031 gdk_atom_intern("WINDOW", FALSE), 32,
1032 GDK_PROP_MODE_REPLACE, (guchar *)&xid, 1);
1033
1034 gdk_property_change(groot,
1035 gdk_atom_intern("NAUTILUS_DESKTOP_WINDOW_ID", FALSE),
1036 gdk_atom_intern("WINDOW", FALSE), 32,
1037 GDK_PROP_MODE_REPLACE, (guchar *)&xid, 1);
1038
1039 screen_set_selection(desktop);
1040
1041 wnck_screen = wnck_screen_get(gdk_screen_get_number(desktop->priv->gscreen));
1042 desktop->priv->wnck_screen = wnck_screen;
1043
1044 /* Watch for single workspace setting changes */
1045 xfconf_g_property_bind(desktop->priv->channel,
1046 SINGLE_WORKSPACE_MODE, G_TYPE_BOOLEAN,
1047 G_OBJECT(desktop), "single-workspace-mode");
1048 xfconf_g_property_bind(desktop->priv->channel,
1049 SINGLE_WORKSPACE_NUMBER, G_TYPE_INT,
1050 G_OBJECT(desktop), "single-workspace-number");
1051
1052 /* watch for workspace changes */
1053 g_signal_connect(desktop->priv->wnck_screen, "active-workspace-changed",
1054 G_CALLBACK(workspace_changed_cb), desktop);
1055 g_signal_connect(desktop->priv->wnck_screen, "workspace-created",
1056 G_CALLBACK(workspace_created_cb), desktop);
1057 g_signal_connect(desktop->priv->wnck_screen, "workspace-destroyed",
1058 G_CALLBACK(workspace_destroyed_cb), desktop);
1059
1060 /* watch for screen changes */
1061 g_signal_connect(G_OBJECT(desktop->priv->gscreen), "size-changed",
1062 G_CALLBACK(screen_size_changed_cb), desktop);
1063 g_signal_connect(G_OBJECT(desktop->priv->gscreen), "composited-changed",
1064 G_CALLBACK(screen_composited_changed_cb), desktop);
1065
1066 gtk_widget_add_events(GTK_WIDGET(desktop), GDK_EXPOSURE_MASK);
1067
1068#ifdef ENABLE_DESKTOP_ICONS
1069 xfce_desktop_setup_icon_view(desktop);
1070#endif
1071
1072 TRACE("exiting");
1073}
1074
1075static void
1076xfce_desktop_unrealize(GtkWidget *widget)
1077{
1078 XfceDesktop *desktop = XFCE_DESKTOP(widget);
1079 gint i;
1080 GdkWindow *groot;
1081 gchar property_name[128];
1082
1083 g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1084
1085 /* disconnect all the xfconf settings to this desktop */
1086 xfconf_g_property_unbind_all(G_OBJECT(desktop));
1087
1088 g_signal_handlers_disconnect_by_func(G_OBJECT(desktop->priv->gscreen),
1089 G_CALLBACK(xfce_desktop_monitors_changed),
1090 desktop);
1091
1092 if(gtk_widget_get_mapped(widget))
1093 gtk_widget_unmap(widget);
1094 gtk_widget_set_mapped(widget, FALSE);
1095
1096 gtk_container_forall(GTK_CONTAINER(widget),
1097 (GtkCallback)gtk_widget_unrealize,
1098 NULL);
1099
1100 g_signal_handlers_disconnect_by_func(G_OBJECT(desktop->priv->gscreen),
1101 G_CALLBACK(screen_size_changed_cb), desktop);
1102 g_signal_handlers_disconnect_by_func(G_OBJECT(desktop->priv->gscreen),
1103 G_CALLBACK(screen_composited_changed_cb), desktop);
1104
1105 gdk_error_trap_push();
1106
1107 groot = gdk_screen_get_root_window(desktop->priv->gscreen);
1108 gdk_property_delete(groot, gdk_atom_intern("XFCE_DESKTOP_WINDOW", FALSE));
1109 gdk_property_delete(groot, gdk_atom_intern("NAUTILUS_DESKTOP_WINDOW_ID", FALSE));
1110
1111#ifndef DISABLE_FOR_BUG7442
1112 gdk_property_delete(groot, gdk_atom_intern("_XROOTPMAP_ID", FALSE));
1113 gdk_property_delete(groot, gdk_atom_intern("ESETROOT_PMAP_ID", FALSE));
1114 gdk_window_set_back_pixmap(groot, NULL, FALSE);
1115#endif
1116
1117 if(desktop->priv->workspaces) {
1118 for(i = 0; i < desktop->priv->nworkspaces; i++) {
1119 g_snprintf(property_name, 128, XFDESKTOP_IMAGE_FILE_FMT, i);
1120 gdk_property_delete(groot, gdk_atom_intern(property_name, FALSE));
1121 g_object_unref(G_OBJECT(desktop->priv->workspaces[i]));
1122 }
1123 g_free(desktop->priv->workspaces);
1124 desktop->priv->workspaces = NULL;
1125 }
1126
1127 gdk_flush();
1128 gdk_error_trap_pop();
1129
1130 if(desktop->priv->bg_pixmap) {
1131 g_object_unref(G_OBJECT(desktop->priv->bg_pixmap));
1132 desktop->priv->bg_pixmap = NULL;
1133 }
1134
1135 gtk_window_set_icon(GTK_WINDOW(widget), NULL);
1136
1137 gtk_style_detach(gtk_widget_get_style(widget));
1138 g_object_unref(G_OBJECT(gtk_widget_get_window(widget)));
1139 gtk_widget_set_window(widget, NULL);
1140
1141 gtk_selection_remove_all(widget);
1142
1143 gtk_widget_set_realized(widget, FALSE);
1144}
1145
1146static gboolean
1147xfce_desktop_button_press_event(GtkWidget *w,
1148 GdkEventButton *evt)
1149{
1150 guint button = evt->button;
1151 guint state = evt->state;
1152 XfceDesktop *desktop = XFCE_DESKTOP(w);
1153
1154 TRACE("entering");
1155
1156 g_return_val_if_fail(XFCE_IS_DESKTOP(w), FALSE);
1157
1158 if(evt->type == GDK_BUTTON_PRESS) {
1159 if(button == 3 || (button == 1 && (state & GDK_SHIFT_MASK))) {
1160#ifdef ENABLE_DESKTOP_ICONS
1161 /* Let the icon view handle these menu pop ups */
1162 if(desktop->priv->icons_style != XFCE_DESKTOP_ICON_STYLE_NONE)
1163 return FALSE;
1164#endif
1165 /* no icons on the desktop, grab the focus and pop up the menu */
1166 if(!gtk_widget_has_grab(w))
1167 gtk_grab_add(w);
1168
1169 xfce_desktop_popup_root_menu(desktop, button, evt->time);
1170 return TRUE;
1171 } else if(button == 2 || (button == 1 && (state & GDK_SHIFT_MASK)
1172 && (state & GDK_CONTROL_MASK)))
1173 {
1174 /* always grab the focus and pop up the menu */
1175 if(!gtk_widget_has_grab(w))
1176 gtk_grab_add(w);
1177
1178 xfce_desktop_popup_secondary_root_menu(desktop, button, evt->time);
1179 return TRUE;
1180 }
1181 }
1182
1183 return FALSE;
1184}
1185
1186static gboolean
1187xfce_desktop_button_release_event(GtkWidget *w,
1188 GdkEventButton *evt)
1189{
1190 TRACE("entering");
1191
1192 gtk_grab_remove(w);
1193
1194 return FALSE;
1195}
1196
1197/* This function gets called when the user presses the menu key on the keyboard.
1198 * Or Shift+F10 or whatever key binding the user has chosen. */
1199static gboolean
1200xfce_desktop_popup_menu(GtkWidget *w)
1201{
1202 GdkEventButton *evt;
1203 guint button, etime;
1204
1205 TRACE("entering");
1206
1207 evt = (GdkEventButton *)gtk_get_current_event();
1208 if(evt && GDK_BUTTON_PRESS == evt->type) {
1209 button = evt->button;
1210 etime = evt->time;
1211 } else {
1212 button = 0;
1213 etime = gtk_get_current_event_time();
1214 }
1215
1216 xfce_desktop_popup_root_menu(XFCE_DESKTOP(w), button, etime);
1217
1218 return TRUE;
1219}
1220
1221static gboolean
1222xfce_desktop_expose(GtkWidget *w,
1223 GdkEventExpose *evt)
1224{
1225 GList *children, *l;
1226
1227 /*TRACE("entering");*/
1228
1229 if(evt->count != 0)
1230 return FALSE;
1231
1232 gdk_window_clear_area(gtk_widget_get_window(w), evt->area.x, evt->area.y,
1233 evt->area.width, evt->area.height);
1234
1235 children = gtk_container_get_children(GTK_CONTAINER(w));
1236 for(l = children; l; l = l->next) {
1237 gtk_container_propagate_expose(GTK_CONTAINER(w),
1238 GTK_WIDGET(l->data),
1239 evt);
1240 }
1241 g_list_free(children);
1242
1243 return FALSE;
1244}
1245
1246static gboolean
1247xfce_desktop_delete_event(GtkWidget *w,
1248 GdkEventAny *evt)
1249{
1250 if(XFCE_DESKTOP(w)->priv->session_logout_func)
1251 XFCE_DESKTOP(w)->priv->session_logout_func();
1252
1253 return TRUE;
1254}
1255
1256static gboolean
1257style_refresh_cb(gpointer *w)
1258{
1259 XfceDesktop *desktop = XFCE_DESKTOP(w);
1260
1261 xfce_desktop_refresh(desktop);
1262 desktop->priv->style_refresh_timer = 0;
1263
1264 return FALSE;
1265}
1266
1267static void
1268xfce_desktop_style_set(GtkWidget *w, GtkStyle *old_style)
1269{
1270 XfceDesktop *desktop = XFCE_DESKTOP(w);
1271
1272 if(desktop->priv->style_refresh_timer != 0)
1273 g_source_remove(desktop->priv->style_refresh_timer);
1274
1275 desktop->priv->style_refresh_timer = g_timeout_add_seconds(1, (GSourceFunc)style_refresh_cb, w);
1276}
1277
1278static void
1279xfce_desktop_connect_settings(XfceDesktop *desktop)
1280{
1281#ifdef ENABLE_DESKTOP_ICONS
1282#define ICONS_PREFIX "/desktop-icons/"
1283 XfconfChannel *channel = desktop->priv->channel;
1284
1285 xfce_desktop_freeze_updates(desktop);
1286
1287 xfconf_g_property_bind(channel, ICONS_PREFIX "style",
1288 XFCE_TYPE_DESKTOP_ICON_STYLE,
1289 G_OBJECT(desktop), "icon-style");
1290 xfconf_g_property_bind(channel, ICONS_PREFIX "icon-size", G_TYPE_UINT,
1291 G_OBJECT(desktop), "icon-size");
1292 xfconf_g_property_bind(channel, ICONS_PREFIX "font-size", G_TYPE_UINT,
1293 G_OBJECT(desktop), "icon-font-size");
1294 xfconf_g_property_bind(channel, ICONS_PREFIX "use-custom-font-size",
1295 G_TYPE_BOOLEAN,
1296 G_OBJECT(desktop), "icon-font-size-set");
1297
1298 xfce_desktop_thaw_updates(desktop);
1299#undef ICONS_PREFIX
1300#endif
1301}
1302
1303static gboolean
1304xfce_desktop_get_single_workspace_mode(XfceDesktop *desktop)
1305{
1306 g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), TRUE);
1307
1308 return desktop->priv->single_workspace_mode;
1309}
1310
1311static gint
1312xfce_desktop_get_current_workspace(XfceDesktop *desktop)
1313{
1314 WnckWorkspace *wnck_workspace;
1315 gint workspace_num, current_workspace;
1316
1317 g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), -1);
1318
1319 wnck_workspace = wnck_screen_get_active_workspace(desktop->priv->wnck_screen);
1320
1321 if(wnck_workspace != NULL) {
1322 workspace_num = wnck_workspace_get_number(wnck_workspace);
1323 } else {
1324 workspace_num = desktop->priv->nworkspaces;
1325 }
1326
1327 /* If we're in single_workspace mode we need to return the workspace that
1328 * it was set to, if possible, otherwise return the current workspace */
1329 if(xfce_desktop_get_single_workspace_mode(desktop) &&
1330 desktop->priv->single_workspace_num < desktop->priv->nworkspaces) {
1331 current_workspace = desktop->priv->single_workspace_num;
1332 } else {
1333 current_workspace = workspace_num;
1334 }
1335
1336 DBG("workspace_num %d, single_workspace_num %d, current_workspace %d, max workspaces %d",
1337 workspace_num, desktop->priv->single_workspace_num, current_workspace,
1338 desktop->priv->nworkspaces);
1339
1340 return current_workspace;
1341}
1342
1343/* public api */
1344
1345/**
1346 * xfce_desktop_new:
1347 * @gscreen: The current #GdkScreen.
1348 * @channel: An #XfconfChannel to use for settings.
1349 * @property_prefix: String prefix for per-screen properties.
1350 *
1351 * Creates a new #XfceDesktop for the specified #GdkScreen. If @gscreen is
1352 * %NULL, the default screen will be used.
1353 *
1354 * Return value: A new #XfceDesktop.
1355 **/
1356GtkWidget *
1357xfce_desktop_new(GdkScreen *gscreen,
1358 XfconfChannel *channel,
1359 const gchar *property_prefix)
1360{
1361 XfceDesktop *desktop;
1362
1363 g_return_val_if_fail(channel && property_prefix, NULL);
1364
1365 desktop = g_object_new(XFCE_TYPE_DESKTOP, NULL);
1366
1367 if(!gscreen)
1368 gscreen = gdk_display_get_default_screen(gdk_display_get_default());
1369 gtk_window_set_screen(GTK_WINDOW(desktop), gscreen);
1370 desktop->priv->gscreen = gscreen;
1371
1372 desktop->priv->channel = g_object_ref(G_OBJECT(channel));
1373 desktop->priv->property_prefix = g_strdup(property_prefix);
1374
1375 xfce_desktop_connect_settings(desktop);
1376
1377 return GTK_WIDGET(desktop);
1378}
1379
1380gint
1381xfce_desktop_get_n_monitors(XfceDesktop *desktop)
1382{
1383 g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), 0);
1384
1385 return gdk_screen_get_n_monitors(desktop->priv->gscreen);
1386}
1387
1388gint
1389xfce_desktop_get_width(XfceDesktop *desktop)
1390{
1391 g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), -1);
1392
1393 return gdk_screen_get_width(desktop->priv->gscreen);
1394}
1395
1396gint
1397xfce_desktop_get_height(XfceDesktop *desktop)
1398{
1399 g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), -1);
1400
1401 return gdk_screen_get_height(desktop->priv->gscreen);
1402}
1403
1404void
1405xfce_desktop_set_icon_style(XfceDesktop *desktop,
1406 XfceDesktopIconStyle style)
1407{
1408 g_return_if_fail(XFCE_IS_DESKTOP(desktop)
1409 && style <= XFCE_DESKTOP_ICON_STYLE_FILES);
1410
1411#ifdef ENABLE_DESKTOP_ICONS
1412 if(style == desktop->priv->icons_style)
1413 return;
1414
1415 if(desktop->priv->icon_view) {
1416 gtk_widget_destroy(desktop->priv->icon_view);
1417 desktop->priv->icon_view = NULL;
1418 }
1419
1420 desktop->priv->icons_style = style;
1421 if(gtk_widget_get_realized(GTK_WIDGET(desktop)))
1422 xfce_desktop_setup_icon_view(desktop);
1423#endif
1424}
1425
1426XfceDesktopIconStyle
1427xfce_desktop_get_icon_style(XfceDesktop *desktop)
1428{
1429 g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), XFCE_DESKTOP_ICON_STYLE_NONE);
1430
1431#ifdef ENABLE_DESKTOP_ICONS
1432 return desktop->priv->icons_style;
1433#else
1434 return XFCE_DESKTOP_ICON_STYLE_NONE;
1435#endif
1436}
1437
1438void
1439xfce_desktop_set_icon_size(XfceDesktop *desktop,
1440 guint icon_size)
1441{
1442 g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1443
1444#ifdef ENABLE_DESKTOP_ICONS
1445 if(icon_size == desktop->priv->icons_size)
1446 return;
1447
1448 desktop->priv->icons_size = icon_size;
1449
1450 if(desktop->priv->icon_view) {
1451 xfdesktop_icon_view_set_icon_size(XFDESKTOP_ICON_VIEW(desktop->priv->icon_view),
1452 icon_size);
1453 }
1454#endif
1455}
1456
1457void
1458xfce_desktop_set_icon_font_size(XfceDesktop *desktop,
1459 guint font_size_points)
1460{
1461 g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1462
1463#ifdef ENABLE_DESKTOP_ICONS
1464 if(font_size_points == desktop->priv->icons_font_size)
1465 return;
1466
1467 desktop->priv->icons_font_size = font_size_points;
1468
1469 if(desktop->priv->icons_font_size_set && desktop->priv->icon_view) {
1470 xfdesktop_icon_view_set_font_size(XFDESKTOP_ICON_VIEW(desktop->priv->icon_view),
1471 font_size_points);
1472 }
1473#endif
1474}
1475
1476void
1477xfce_desktop_set_use_icon_font_size(XfceDesktop *desktop,
1478 gboolean use_icon_font_size)
1479{
1480 g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1481
1482#ifdef ENABLE_DESKTOP_ICONS
1483 if(use_icon_font_size == desktop->priv->icons_font_size_set)
1484 return;
1485
1486 desktop->priv->icons_font_size_set = use_icon_font_size;
1487
1488 if(desktop->priv->icon_view) {
1489 if(!use_icon_font_size) {
1490 xfce_desktop_ensure_system_font_size(desktop);
1491 xfdesktop_icon_view_set_font_size(XFDESKTOP_ICON_VIEW(desktop->priv->icon_view),
1492 desktop->priv->system_font_size);
1493 } else {
1494 xfdesktop_icon_view_set_font_size(XFDESKTOP_ICON_VIEW(desktop->priv->icon_view),
1495 desktop->priv->icons_font_size);
1496 }
1497 }
1498#endif
1499}
1500
1501static void
1502xfce_desktop_set_single_workspace_mode(XfceDesktop *desktop,
1503 gboolean single_workspace)
1504{
1505 gint i;
1506
1507 g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1508
1509 if(single_workspace == desktop->priv->single_workspace_mode)
1510 return;
1511
1512 desktop->priv->single_workspace_mode = single_workspace;
1513
1514 DBG("single_workspace_mode now %s", single_workspace ? "TRUE" : "FALSE");
1515
1516 /* update the workspaces & backdrops if they should cache their pixbuf */
1517 if(desktop->priv->workspaces) {
1518 for(i = 0; i < desktop->priv->nworkspaces; i++) {
1519 /* set cache to TRUE when single_workspace is FALSE */
1520 xfce_workspace_set_cache_pixbufs(desktop->priv->workspaces[i], !single_workspace);
1521 }
1522 }
1523
1524 /* If the desktop has been realized then fake a screen size change to
1525 * update the backdrop. There's no reason to if there's no desktop yet */
1526 if(gtk_widget_get_realized(GTK_WIDGET(desktop)))
1527 screen_size_changed_cb(desktop->priv->gscreen, desktop);
1528}
1529
1530static void
1531xfce_desktop_set_single_workspace_number(XfceDesktop *desktop,
1532 gint workspace_num)
1533{
1534 g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1535
1536 if(workspace_num == desktop->priv->single_workspace_num)
1537 return;
1538
1539 DBG("single_workspace_num now %d", workspace_num);
1540
1541 desktop->priv->single_workspace_num = workspace_num;
1542
1543 if(xfce_desktop_get_single_workspace_mode(desktop)) {
1544 /* Fake a screen size changed to update the backdrop */
1545 screen_size_changed_cb(desktop->priv->gscreen, desktop);
1546 }
1547}
1548
1549void
1550xfce_desktop_set_session_logout_func(XfceDesktop *desktop,
1551 SessionLogoutFunc logout_func)
1552{
1553 g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1554 desktop->priv->session_logout_func = logout_func;
1555}
1556
1557void
1558xfce_desktop_freeze_updates(XfceDesktop *desktop)
1559{
1560 g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1561 desktop->priv->updates_frozen = TRUE;
1562}
1563
1564void
1565xfce_desktop_thaw_updates(XfceDesktop *desktop)
1566{
1567 g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1568
1569 desktop->priv->updates_frozen = FALSE;
1570 if(gtk_widget_get_realized(GTK_WIDGET(desktop)))
1571 xfce_desktop_monitors_changed(desktop->priv->gscreen, desktop);
1572}
1573
1574static gboolean
1575xfce_desktop_menu_destroy_idled(gpointer data)
1576{
1577 gtk_widget_destroy(GTK_WIDGET(data));
1578 return FALSE;
1579}
1580
1581static void
1582xfce_desktop_do_menu_popup(XfceDesktop *desktop,
1583 guint button,
1584 guint activate_time,
1585 guint populate_signal)
1586{
1587 GdkScreen *screen;
1588 GtkWidget *menu;
1589 GList *menu_children;
1590
1591 TRACE("entering");
1592
1593 if(gtk_widget_has_screen(GTK_WIDGET(desktop)))
1594 screen = gtk_widget_get_screen(GTK_WIDGET(desktop));
1595 else
1596 screen = gdk_display_get_default_screen(gdk_display_get_default());
1597
1598 menu = gtk_menu_new();
1599 gtk_menu_set_screen(GTK_MENU(menu), screen);
1600 g_signal_connect_swapped(G_OBJECT(menu), "deactivate",
1601 G_CALLBACK(g_idle_add),
1602 (gpointer)xfce_desktop_menu_destroy_idled);
1603
1604 g_signal_emit(G_OBJECT(desktop), populate_signal, 0, menu);
1605
1606 /* if nobody populated the menu, don't do anything */
1607 menu_children = gtk_container_get_children(GTK_CONTAINER(menu));
1608 if(!menu_children) {
1609 gtk_widget_destroy(menu);
1610 return;
1611 }
1612
1613 g_list_free(menu_children);
1614
1615 gtk_menu_attach_to_widget(GTK_MENU(menu), GTK_WIDGET(desktop), NULL);
1616
1617 /* Per gtk_menu_popup's documentation "for conflict-resolve initiation of
1618 * concurrent requests for mouse/keyboard grab requests." */
1619 if(activate_time == 0)
1620 activate_time = gtk_get_current_event_time();
1621
1622 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, button, activate_time);
1623}
1624
1625void
1626xfce_desktop_popup_root_menu(XfceDesktop *desktop,
1627 guint button,
1628 guint activate_time)
1629{
1630 TRACE("entering");
1631
1632 /* If it's launched by xfdesktop --menu we won't have an event time.
1633 * Grab the keyboard focus */
1634 if(activate_time == 0)
1635 activate_time = xfdesktop_popup_keyboard_grab_available(gtk_widget_get_window(GTK_WIDGET(desktop)));
1636
1637 xfce_desktop_do_menu_popup(desktop, button, activate_time,
1638 signals[SIG_POPULATE_ROOT_MENU]);
1639
1640}
1641
1642void
1643xfce_desktop_popup_secondary_root_menu(XfceDesktop *desktop,
1644 guint button,
1645 guint activate_time)
1646{
1647 /* If it's launched by xfdesktop --windowlist we won't have an event time.
1648 * Grab the keyboard focus */
1649 if(activate_time == 0)
1650 activate_time = xfdesktop_popup_keyboard_grab_available(gtk_widget_get_window(GTK_WIDGET(desktop)));
1651
1652 xfce_desktop_do_menu_popup(desktop, button, activate_time,
1653 signals[SIG_POPULATE_SECONDARY_ROOT_MENU]);
1654}
1655void
1656xfce_desktop_refresh(XfceDesktop *desktop)
1657{
1658 gint i, current_workspace;
1659
1660 g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1661
1662 if(!gtk_widget_get_realized(GTK_WIDGET(desktop)))
1663 return;
1664
1665 current_workspace = xfce_desktop_get_current_workspace(desktop);
1666
1667 /* reload backgrounds */
1668 for(i = 0; i < xfce_desktop_get_n_monitors(desktop); i++) {
1669 XfceBackdrop *backdrop;
1670
1671 backdrop = xfce_workspace_get_backdrop(desktop->priv->workspaces[current_workspace], i);
1672
1673 backdrop_changed_cb(backdrop, desktop);
1674 }
1675
1676#ifdef ENABLE_DESKTOP_ICONS
1677 /* reload icon view */
1678 if(desktop->priv->icon_view) {
1679 gtk_widget_destroy(desktop->priv->icon_view);
1680 desktop->priv->icon_view = NULL;
1681 }
1682 xfce_desktop_setup_icon_view(desktop);
1683#endif
1684}
1685
1686void xfce_desktop_arrange_icons(XfceDesktop *desktop)
1687{
1688 g_return_if_fail(XFCE_IS_DESKTOP(desktop));
1689
1690#ifdef ENABLE_DESKTOP_ICONS
1691 g_return_if_fail(XFDESKTOP_IS_ICON_VIEW(desktop->priv->icon_view));
1692
1693 xfdesktop_icon_view_sort_icons(XFDESKTOP_ICON_VIEW(desktop->priv->icon_view));
1694#endif
1695}
01696
=== added file '.pc/xubuntu_improve-nautilus-interactions.patch/.timestamp'
=== modified file '.pc/xubuntu_improve-nautilus-interactions.patch/src/xfce-desktop.c'
--- .pc/xubuntu_improve-nautilus-interactions.patch/src/xfce-desktop.c 2014-02-20 15:59:49 +0000
+++ .pc/xubuntu_improve-nautilus-interactions.patch/src/xfce-desktop.c 2014-03-01 05:37:37 +0000
@@ -1747,6 +1747,10 @@
1747 if(!gtk_widget_get_realized(GTK_WIDGET(desktop)))1747 if(!gtk_widget_get_realized(GTK_WIDGET(desktop)))
1748 return;1748 return;
17491749
1750 if(desktop->priv->workspaces == NULL) {
1751 return;
1752 }
1753
1750 current_workspace = xfce_desktop_get_current_workspace(desktop);1754 current_workspace = xfce_desktop_get_current_workspace(desktop);
17511755
1752 /* reload backgrounds */1756 /* reload backgrounds */
17531757
=== added file '.pc/xubuntu_set-accountsservice-user-bg.patch/.timestamp'
=== modified file '.pc/xubuntu_set-accountsservice-user-bg.patch/src/xfce-desktop.c'
--- .pc/xubuntu_set-accountsservice-user-bg.patch/src/xfce-desktop.c 2014-02-20 15:59:49 +0000
+++ .pc/xubuntu_set-accountsservice-user-bg.patch/src/xfce-desktop.c 2014-03-01 05:37:37 +0000
@@ -1662,6 +1662,10 @@
1662 if(!gtk_widget_get_realized(GTK_WIDGET(desktop)))1662 if(!gtk_widget_get_realized(GTK_WIDGET(desktop)))
1663 return;1663 return;
16641664
1665 if(desktop->priv->workspaces == NULL) {
1666 return;
1667 }
1668
1665 current_workspace = xfce_desktop_get_current_workspace(desktop);1669 current_workspace = xfce_desktop_get_current_workspace(desktop);
16661670
1667 /* reload backgrounds */1671 /* reload backgrounds */
16681672
=== modified file 'debian/changelog'
--- debian/changelog 2014-02-20 15:59:49 +0000
+++ debian/changelog 2014-03-01 05:37:37 +0000
@@ -1,3 +1,21 @@
1xfdesktop4 (4.11.3-2ubuntu1) trusty; urgency=medium
2
3 * Merge from debian. Remaining changes:
4 - debian/patches/xubuntu_improve-nautilus-interactions.patch: added,
5 should prevent nautilus from taking over the desktop if xfdesktop is
6 running (and vice-versa).
7 - debian/patches/xubuntu_set-accountsservice-user-bg.patch: update the
8 user background property of Accountsservice on backdrop change.
9
10 -- Jackson Doak <noskcaj@ubuntu.com> Sat, 01 Mar 2014 16:02:38 +1100
11
12xfdesktop4 (4.11.3-2) experimental; urgency=medium
13
14 [ Jackson Doak ]
15 * Add git-fix-segfault-on-session-start.patch. LP: #1282509
16
17 -- Yves-Alexis Perez <corsac@debian.org> Fri, 28 Feb 2014 21:52:55 +0100
18
1xfdesktop4 (4.11.3-1ubuntu1) trusty; urgency=medium19xfdesktop4 (4.11.3-1ubuntu1) trusty; urgency=medium
220
3 * Merge from debian. Remaining changes:21 * Merge from debian. Remaining changes:
422
=== added file 'debian/patches/git-fix-segfault-on-session-start.patch'
--- debian/patches/git-fix-segfault-on-session-start.patch 1970-01-01 00:00:00 +0000
+++ debian/patches/git-fix-segfault-on-session-start.patch 2014-03-01 05:37:37 +0000
@@ -0,0 +1,23 @@
1Description: Stop segfaulting on session start
2 Stop segfaulting on session start. Fix taken from upstream git
3Author: Thaddäus Tintenfisch
4Bug: https://bugzilla.xfce.org/show_bug.cgi?id=10705
5Bug-Ubuntu: https://launchpad.net/bugs/1282509
6
7---
8 src/xfce-desktop.c | 4 ++++
9 1 file changed, 4 insertions(+)
10
11--- a/src/xfce-desktop.c
12+++ b/src/xfce-desktop.c
13@@ -1662,6 +1662,10 @@ xfce_desktop_refresh(XfceDesktop *deskto
14 if(!gtk_widget_get_realized(GTK_WIDGET(desktop)))
15 return;
16
17+ if(desktop->priv->workspaces == NULL) {
18+ return;
19+ }
20+
21 current_workspace = xfce_desktop_get_current_workspace(desktop);
22
23 /* reload backgrounds */
024
=== modified file 'debian/patches/series'
--- debian/patches/series 2014-01-22 11:02:26 +0000
+++ debian/patches/series 2014-03-01 05:37:37 +0000
@@ -1,2 +1,3 @@
1git-fix-segfault-on-session-start.patch
1xubuntu_set-accountsservice-user-bg.patch2xubuntu_set-accountsservice-user-bg.patch
2xubuntu_improve-nautilus-interactions.patch3xubuntu_improve-nautilus-interactions.patch
34
=== modified file 'src/xfce-desktop.c'
--- src/xfce-desktop.c 2014-02-20 15:59:49 +0000
+++ src/xfce-desktop.c 2014-03-01 05:37:37 +0000
@@ -1758,6 +1758,10 @@
1758 if(!gtk_widget_get_realized(GTK_WIDGET(desktop)))1758 if(!gtk_widget_get_realized(GTK_WIDGET(desktop)))
1759 return;1759 return;
17601760
1761 if(desktop->priv->workspaces == NULL) {
1762 return;
1763 }
1764
1761 current_workspace = xfce_desktop_get_current_workspace(desktop);1765 current_workspace = xfce_desktop_get_current_workspace(desktop);
17621766
1763 /* reload backgrounds */1767 /* reload backgrounds */

Subscribers

People subscribed via source and target branches

to all changes: