[gnome-flashback] desktop: handle !draw-background case
- From: Alberts Muktupāvels <muktupavels src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-flashback] desktop: handle !draw-background case
- Date: Tue, 29 Oct 2019 13:31:56 +0000 (UTC)
commit 9005220f2689e9f5ff3ee0e5f2e7296eded6a9fb
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date: Tue Oct 29 01:29:58 2019 +0200
desktop: handle !draw-background case
If we are not drawing background then desktop window will be
transparent if screen is composited, otherwise we will draw surface
from root window.
configure.ac | 1 +
gnome-flashback/libdesktop/Makefile.am | 1 +
gnome-flashback/libdesktop/gf-desktop-window.c | 170 ++++++++++++++++++++++++-
3 files changed, 166 insertions(+), 6 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 739796b..08253d0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -154,6 +154,7 @@ PKG_CHECK_MODULES([COMMON], [
PKG_CHECK_MODULES([DESKTOP], [
glib-2.0 >= $GLIB_REQUIRED
gio-2.0 >= $GLIB_REQUIRED
+ gnome-desktop-3.0 >= $LIBGNOME_DESKTOP_REQUIRED
gtk+-3.0 >= $GTK_REQUIRED
])
diff --git a/gnome-flashback/libdesktop/Makefile.am b/gnome-flashback/libdesktop/Makefile.am
index 73041c2..3a69aa9 100644
--- a/gnome-flashback/libdesktop/Makefile.am
+++ b/gnome-flashback/libdesktop/Makefile.am
@@ -5,6 +5,7 @@ noinst_LTLIBRARIES = \
$(NULL)
libdesktop_la_CPPFLAGS = \
+ -DGNOME_DESKTOP_USE_UNSTABLE_API \
-I$(top_builddir)/gnome-flashback/libdesktop \
$(NULL)
diff --git a/gnome-flashback/libdesktop/gf-desktop-window.c b/gnome-flashback/libdesktop/gf-desktop-window.c
index 161c412..69564ba 100644
--- a/gnome-flashback/libdesktop/gf-desktop-window.c
+++ b/gnome-flashback/libdesktop/gf-desktop-window.c
@@ -18,20 +18,25 @@
#include "config.h"
#include "gf-desktop-window.h"
+#include <gdk/gdkx.h>
+#include <libgnome-desktop/gnome-bg.h>
+
#include "gf-background.h"
#include "gf-icon-view.h"
struct _GfDesktopWindow
{
- GtkWindow parent;
+ GtkWindow parent;
- gboolean draw_background;
- GfBackground *background;
+ gboolean draw_background;
+ GfBackground *background;
+ gboolean event_filter_added;
+ cairo_surface_t *surface;
- gboolean show_icons;
- GtkWidget *icon_view;
+ gboolean show_icons;
+ GtkWidget *icon_view;
- gboolean ready;
+ gboolean ready;
};
enum
@@ -57,6 +62,98 @@ static guint window_signals[LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE (GfDesktopWindow, gf_desktop_window, GTK_TYPE_WINDOW)
+static void
+ensure_surface (GfDesktopWindow *self)
+{
+ GtkWidget *widget;
+ GdkScreen *screen;
+
+ widget = GTK_WIDGET (self);
+
+ screen = gtk_widget_get_screen (widget);
+
+ self->surface = gnome_bg_get_surface_from_root (screen);
+ gtk_widget_queue_draw (widget);
+}
+
+static GdkFilterReturn
+filter_func (GdkXEvent *xevent,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ XEvent *x;
+ GdkAtom atom;
+ GfDesktopWindow *self;
+
+ x = (XEvent *) xevent;
+
+ if (x->type != PropertyNotify)
+ return GDK_FILTER_CONTINUE;
+
+ atom = gdk_atom_intern_static_string ("_XROOTPMAP_ID");
+
+ if (x->xproperty.atom != gdk_x11_atom_to_xatom (atom))
+ return GDK_FILTER_CONTINUE;
+
+ self = GF_DESKTOP_WINDOW (user_data);
+
+ g_clear_pointer (&self->surface, cairo_surface_destroy);
+ ensure_surface (self);
+
+ return GDK_FILTER_CONTINUE;
+}
+
+static void
+remove_event_filter (GfDesktopWindow *self)
+{
+ GdkScreen *screen;
+ GdkWindow *root;
+
+ if (!self->event_filter_added)
+ return;
+
+ screen = gtk_widget_get_screen (GTK_WIDGET (self));
+ root = gdk_screen_get_root_window (screen);
+
+ gdk_window_remove_filter (root, filter_func, self);
+ self->event_filter_added = FALSE;
+}
+
+static void
+add_event_filter (GfDesktopWindow *self)
+{
+ GdkScreen *screen;
+ GdkWindow *root;
+
+ if (self->event_filter_added)
+ return;
+
+ screen = gtk_widget_get_screen (GTK_WIDGET (self));
+ root = gdk_screen_get_root_window (screen);
+
+ gdk_window_add_filter (root, filter_func, self);
+ self->event_filter_added = TRUE;
+}
+
+static void
+composited_changed_cb (GdkScreen *screen,
+ GfDesktopWindow *self)
+{
+ if (self->draw_background)
+ return;
+
+ if (gdk_screen_is_composited (screen))
+ {
+ remove_event_filter (self);
+ g_clear_pointer (&self->surface, cairo_surface_destroy);
+ }
+ else
+ {
+ add_event_filter (self);
+ ensure_surface (self);
+ }
+}
+
static void
emit_ready (GfDesktopWindow *self)
{
@@ -79,6 +176,9 @@ draw_background_changed (GfDesktopWindow *self)
{
if (self->draw_background)
{
+ remove_event_filter (self);
+ g_clear_pointer (&self->surface, cairo_surface_destroy);
+
g_assert (self->background == NULL);
self->background = gf_background_new (GTK_WIDGET (self));
@@ -86,7 +186,19 @@ draw_background_changed (GfDesktopWindow *self)
}
else
{
+ GdkScreen *screen;
+
g_clear_object (&self->background);
+
+ screen = gtk_widget_get_screen (GTK_WIDGET (self));
+
+ if (!gdk_screen_is_composited (screen))
+ {
+ add_event_filter (self);
+ ensure_surface (self);
+ }
+
+ emit_ready (self);
}
}
@@ -161,6 +273,19 @@ gf_desktop_window_dispose (GObject *object)
G_OBJECT_CLASS (gf_desktop_window_parent_class)->dispose (object);
}
+static void
+gf_desktop_window_finalize (GObject *object)
+{
+ GfDesktopWindow *self;
+
+ self = GF_DESKTOP_WINDOW (object);
+
+ remove_event_filter (self);
+ g_clear_pointer (&self->surface, cairo_surface_destroy);
+
+ G_OBJECT_CLASS (gf_desktop_window_parent_class)->finalize (object);
+}
+
static void
gf_desktop_window_set_property (GObject *object,
guint property_id,
@@ -187,6 +312,23 @@ gf_desktop_window_set_property (GObject *object,
}
}
+static gboolean
+gf_desktop_window_draw (GtkWidget *widget,
+ cairo_t *cr)
+{
+ GfDesktopWindow *self;
+
+ self = GF_DESKTOP_WINDOW (widget);
+
+ if (self->surface != NULL)
+ {
+ cairo_set_source_surface (cr, self->surface, 0, 0);
+ cairo_paint (cr);
+ }
+
+ return GTK_WIDGET_CLASS (gf_desktop_window_parent_class)->draw (widget, cr);
+}
+
static void
gf_desktop_window_realize (GtkWidget *widget)
{
@@ -245,8 +387,10 @@ gf_desktop_window_class_init (GfDesktopWindowClass *self_class)
object_class->constructed = gf_desktop_window_constructed;
object_class->dispose = gf_desktop_window_dispose;
+ object_class->finalize = gf_desktop_window_finalize;
object_class->set_property = gf_desktop_window_set_property;
+ widget_class->draw = gf_desktop_window_draw;
widget_class->realize = gf_desktop_window_realize;
install_properties (object_class);
@@ -257,12 +401,25 @@ static void
gf_desktop_window_init (GfDesktopWindow *self)
{
GParamSpecBoolean *spec;
+ GdkScreen *screen;
+ GdkWindow *root;
+ gint events;
spec = (GParamSpecBoolean *) window_properties[PROP_DRAW_BACKGROUND];
self->draw_background = spec->default_value;
spec = (GParamSpecBoolean *) window_properties[PROP_SHOW_ICONS];
self->show_icons = spec->default_value;
+
+ screen = gtk_widget_get_screen (GTK_WIDGET (self));
+ root = gdk_screen_get_root_window (screen);
+ events = gdk_window_get_events (root);
+
+ gdk_window_set_events (root, events | GDK_PROPERTY_CHANGE_MASK);
+
+ g_signal_connect_object (screen, "composited-changed",
+ G_CALLBACK (composited_changed_cb),
+ self, 0);
}
GtkWidget *
@@ -270,6 +427,7 @@ gf_desktop_window_new (gboolean draw_background,
gboolean show_icons)
{
return g_object_new (GF_TYPE_DESKTOP_WINDOW,
+ "app-paintable", TRUE,
"type", GTK_WINDOW_TOPLEVEL,
"type-hint", GDK_WINDOW_TYPE_HINT_DESKTOP,
"draw-background", draw_background,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]