summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlberts Muktupāvels <alberts.muktupavels@gmail.com>2016-08-15 21:30:36 +0300
committerAlberts Muktupāvels <alberts.muktupavels@gmail.com>2016-08-19 12:57:06 +0300
commite1649a30606d0c9906510f1e9b3fbf545979823b (patch)
treed7536e528a78386872cf22462c23c490997a9ae3
parentebe7ccc181f81051f2d981edd7a8a4caca0ec4f6 (diff)
downloadnautilus-e1649a30606d0c9906510f1e9b3fbf545979823b.tar.gz
nautilus-desktop: draw background when screen is not composited
At least GNOME Flashback session with Metacity still can be used without compositing manager. Since transparency is not available nautilus currently draw black background. Fix it by checking if compositing manager is running and if it is not then get background surface from root window and draw it on nautilus desktop window. https://bugzilla.gnome.org/show_bug.cgi?id=769360
-rw-r--r--nautilus-desktop/nautilus-desktop-window.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/nautilus-desktop/nautilus-desktop-window.c b/nautilus-desktop/nautilus-desktop-window.c
index 7c3abecb6..c8909dabe 100644
--- a/nautilus-desktop/nautilus-desktop-window.c
+++ b/nautilus-desktop/nautilus-desktop-window.c
@@ -32,6 +32,9 @@
#include <gio/gio.h>
#include <glib/gi18n.h>
+#define GNOME_DESKTOP_USE_UNSTABLE_API
+#include <libgnome-desktop/gnome-bg.h>
+
#include <eel/eel-vfs-extensions.h>
#include <src/nautilus-file-utilities.h>
#include <src/nautilus-icon-names.h>
@@ -45,12 +48,92 @@ struct NautilusDesktopWindowDetails {
gboolean loaded;
GtkWidget *desktop_selection;
+
+ gboolean composited;
+ cairo_surface_t *surface;
};
G_DEFINE_TYPE (NautilusDesktopWindow, nautilus_desktop_window,
NAUTILUS_TYPE_WINDOW);
static void
+background_changed (NautilusDesktopWindow *window)
+{
+ GtkWidget *widget = GTK_WIDGET (window);
+ GdkScreen *screen = gtk_widget_get_screen (widget);
+
+ g_clear_pointer (&window->details->surface, cairo_surface_destroy);
+
+ window->details->surface = gnome_bg_get_surface_from_root (screen);
+ gtk_widget_queue_draw (widget);
+}
+
+static GdkFilterReturn
+filter_func (GdkXEvent *xevent,
+ GdkEvent *event,
+ NautilusDesktopWindow *window)
+{
+ XEvent *xev = (XEvent *) xevent;
+ GdkAtom gdkatom;
+
+ if (xev->type != PropertyNotify) {
+ return GDK_FILTER_CONTINUE;
+ }
+
+ gdkatom = gdk_atom_intern_static_string ("_XROOTPMAP_ID");
+ if (xev->xproperty.atom != gdk_x11_atom_to_xatom (gdkatom)) {
+ return GDK_FILTER_CONTINUE;
+ }
+
+ background_changed (window);
+
+ return GDK_FILTER_CONTINUE;
+}
+
+static void
+nautilus_desktop_window_composited_changed (GtkWidget *widget)
+{
+ NautilusDesktopWindow *window = NAUTILUS_DESKTOP_WINDOW (widget);
+ GdkScreen *screen = gtk_widget_get_screen (widget);
+ gboolean composited = gdk_screen_is_composited (screen);
+ GdkWindow *root;
+ gint events;
+
+ if (window->details->composited == composited) {
+ return;
+ }
+
+ window->details->composited = composited;
+ root = gdk_screen_get_root_window (screen);
+
+ if (composited) {
+ gdk_window_remove_filter (root, (GdkFilterFunc) filter_func, window);
+
+ g_clear_pointer (&window->details->surface, cairo_surface_destroy);
+ } else {
+ events = gdk_window_get_events (root);
+
+ gdk_window_set_events (root, events | GDK_PROPERTY_CHANGE_MASK);
+ gdk_window_add_filter (root, (GdkFilterFunc) filter_func, window);
+ background_changed (window);
+ }
+}
+
+static gboolean
+nautilus_desktop_window_draw (GtkWidget *widget,
+ cairo_t *cr)
+{
+ NautilusDesktopWindow *window = NAUTILUS_DESKTOP_WINDOW (widget);
+
+ if (window->details->surface) {
+ cairo_set_source_surface (cr, window->details->surface, 0, 0);
+ cairo_paint (cr);
+ }
+
+ return GTK_WIDGET_CLASS (nautilus_desktop_window_parent_class)->draw (widget, cr);
+}
+
+static void
nautilus_desktop_window_update_directory (NautilusDesktopWindow *window)
{
GFile *location;
@@ -74,8 +157,21 @@ nautilus_desktop_window_update_directory (NautilusDesktopWindow *window)
static void
nautilus_desktop_window_finalize (GObject *obj)
{
+ NautilusDesktopWindow *window = NAUTILUS_DESKTOP_WINDOW (obj);
+ GdkScreen *screen;
+ GdkWindow *root;
+
nautilus_desktop_link_monitor_shutdown ();
+ if (window->details->composited == FALSE) {
+ screen = gtk_widget_get_screen (GTK_WIDGET (window));
+ root = gdk_screen_get_root_window (screen);
+
+ gdk_window_remove_filter (root, (GdkFilterFunc) filter_func, window);
+ }
+
+ g_clear_pointer (&window->details->surface, cairo_surface_destroy);
+
G_OBJECT_CLASS (nautilus_desktop_window_parent_class)->finalize (obj);
}
@@ -221,11 +317,16 @@ nautilus_desktop_window_constructed (GObject *obj)
static void
nautilus_desktop_window_init (NautilusDesktopWindow *window)
{
+ GtkWidget *widget = GTK_WIDGET (window);
+ GdkScreen *screen = gtk_widget_get_screen (widget);
+
window->details = G_TYPE_INSTANCE_GET_PRIVATE (window, NAUTILUS_TYPE_DESKTOP_WINDOW,
NautilusDesktopWindowDetails);
gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (window)),
"nautilus-desktop-window");
+ window->details->composited = gdk_screen_is_composited (screen);
+ nautilus_desktop_window_composited_changed (widget);
}
static void
@@ -401,6 +502,8 @@ nautilus_desktop_window_class_init (NautilusDesktopWindowClass *klass)
wclass->unrealize = unrealize;
wclass->map = map;
wclass->delete_event = nautilus_desktop_window_delete_event;
+ wclass->composited_changed = nautilus_desktop_window_composited_changed;
+ wclass->draw = nautilus_desktop_window_draw;
nclass->sync_title = real_sync_title;
nclass->close = real_window_close;