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