[gnome-flashback/wip/desktop-background: 4/4] desktop-background: try to keep background window under all windows
- From: Alberts Muktupāvels <muktupavels src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-flashback/wip/desktop-background: 4/4] desktop-background: try to keep background window under all windows
- Date: Tue, 26 Apr 2016 21:19:00 +0000 (UTC)
commit e7e93b0befcbcbed14a2d1c9c3b8d2172402119f
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date: Wed Apr 27 00:15:58 2016 +0300
desktop-background: try to keep background window under all windows
.../libdesktop-background/gf-background-window.c | 291 +++-----------------
1 files changed, 44 insertions(+), 247 deletions(-)
---
diff --git a/gnome-flashback/libdesktop-background/gf-background-window.c
b/gnome-flashback/libdesktop-background/gf-background-window.c
index aff19dc..47f53ee 100644
--- a/gnome-flashback/libdesktop-background/gf-background-window.c
+++ b/gnome-flashback/libdesktop-background/gf-background-window.c
@@ -24,237 +24,64 @@
struct _GfBackgroundWindow
{
- GtkWindow parent;
-
- Atom desktop_manager_atom;
- Atom client_list_atom;
- Atom type_atom;
- Atom type_desktop_atom;
-
- Window xbackground;
- GdkWindow *background;
-
- Window xdesktop;
- GdkWindow *desktop;
+ GtkWindow parent;
};
G_DEFINE_TYPE (GfBackgroundWindow, gf_background_window, GTK_TYPE_WINDOW)
-static GdkWindow *
-create_window_from_xwindow (Window xwindow)
-{
- GdkDisplay *display;
- GdkWindow *window;
- GdkEventMask mask;
-
- display = gdk_display_get_default ();
-
- gdk_error_trap_push ();
- window = gdk_x11_window_foreign_new_for_display (display, xwindow);
-
- if (gdk_error_trap_pop () != 0)
- return NULL;
-
- mask = gdk_window_get_events (window);
- gdk_window_set_events (window, mask | GDK_STRUCTURE_MASK);
-
- return window;
-}
-
-static gboolean
-is_desktop_window (GfBackgroundWindow *window,
- Display *display,
- Window xwindow)
-{
- Atom type;
- Atom *atoms;
- int result;
- int format;
- unsigned long items;
- unsigned long left;
-
- if (window->type_atom == None)
- window->type_atom = XInternAtom (display, "_NET_WM_WINDOW_TYPE", False);
-
- if (window->type_desktop_atom == None)
- window->type_desktop_atom = XInternAtom (display,
- "_NET_WM_WINDOW_TYPE_DESKTOP",
- False);
-
- gdk_error_trap_push ();
- result = XGetWindowProperty (display, xwindow, window->type_atom,
- 0L, 1L, False, XA_ATOM, &type, &format,
- &items, &left, (unsigned char **) &atoms);
-
- if (gdk_error_trap_pop () != 0 || result != Success)
- return FALSE;
-
- if (items && atoms[0] == window->type_desktop_atom)
- {
- XFree (atoms);
- return TRUE;
- }
-
- XFree (atoms);
- return FALSE;
-}
-
-static gboolean
-get_desktop (GfBackgroundWindow *window)
+static GdkFilterReturn
+event_filter_func (GdkXEvent *xevent,
+ GdkEvent *event,
+ gpointer data)
{
+ XEvent *e;
+ GtkWidget *widget;
GdkDisplay *display;
Display *xdisplay;
- Window root;
- Atom type;
+ Atom net_cls;
+ Window xwindow;
int result;
+ Atom type;
int format;
unsigned long items;
unsigned long left;
- unsigned long i;
Window *windows;
- Window desktop;
-
- display = gdk_display_get_default ();
- xdisplay = GDK_DISPLAY_XDISPLAY (display);
- if (window->client_list_atom == None)
- window->client_list_atom = XInternAtom (xdisplay, "_NET_CLIENT_LIST",
- False);
-
- gdk_error_trap_push ();
-
- root = XDefaultRootWindow (xdisplay);
- result = XGetWindowProperty (xdisplay, root, window->client_list_atom,
- 0L, 1024L, False, XA_WINDOW, &type, &format,
- &items, &left, (unsigned char **) &windows);
-
- if (gdk_error_trap_pop () != 0 || result != Success)
- return FALSE;
+ e = (GdkXEvent *) xevent;
- desktop = None;
- for (i = 0; i < items; i++)
+ if (e->type != CirculateNotify && e->type != ConfigureNotify &&
+ e->type != PropertyNotify)
{
- if (windows[i] == window->xbackground)
- continue;
-
- if (is_desktop_window (window, xdisplay, windows[i]))
- {
- desktop = windows[i];
- break;
- }
+ return GDK_FILTER_CONTINUE;
}
- XFree (windows);
-
- if (desktop == None)
- return FALSE;
+ widget = GTK_WIDGET (data);
- window->xdesktop = desktop;
- window->desktop = create_window_from_xwindow (desktop);
-
- return TRUE;
-}
-
-static Window
-get_desktop_manager (GfBackgroundWindow *window)
-{
- GdkDisplay *display;
- Display *xdisplay;
+ if (!gtk_widget_get_realized (widget))
+ return GDK_FILTER_CONTINUE;
display = gdk_display_get_default ();
xdisplay = gdk_x11_display_get_xdisplay (display);
+ net_cls = XInternAtom (xdisplay, "_NET_CLIENT_LIST_STACKING", False);
- if (window->desktop_manager_atom == None)
- {
- GdkScreen *screen;
- gint screen_number;
- gchar *name;
-
- screen = gdk_display_get_default_screen (display);
- screen_number = gdk_screen_get_number (screen);
-
- name = g_strdup_printf ("_NET_DESKTOP_MANAGER_S%d", screen_number);
- window->desktop_manager_atom = XInternAtom (xdisplay, name, False);
- g_free (name);
- }
-
- return XGetSelectionOwner (xdisplay, window->desktop_manager_atom);
-}
-
-static void
-handle_xevent (GfBackgroundWindow *window,
- XEvent *event)
-{
- static gboolean is_desktop_above_background;
-
- if (event->type == DestroyNotify && window->xdesktop != None)
- {
- if (window->xdesktop == event->xdestroywindow.window)
- {
- is_desktop_above_background = FALSE;
-
- window->xdesktop = None;
- g_clear_object (&window->desktop);
-
- return;
- }
- }
-
- if (get_desktop_manager (window) == None)
- return;
+ gdk_error_trap_push ();
- if (window->xdesktop == None && get_desktop (window) == FALSE)
- return;
+ xwindow = gdk_x11_window_get_xid (gtk_widget_get_window (widget));
+ result = XGetWindowProperty (xdisplay, XDefaultRootWindow (xdisplay),
+ net_cls, 0L, 1024L, False, XA_WINDOW,
+ &type, &format, &items, &left,
+ (unsigned char **) &windows);
- if (event->type == ConfigureNotify)
+ if (gdk_error_trap_pop () != 0 || result != Success)
{
- if (event->xconfigure.window == window->xdesktop)
- is_desktop_above_background = FALSE;
- else if (event->xconfigure.window == window->xbackground)
- is_desktop_above_background = FALSE;
+ XLowerWindow (xdisplay, xwindow);
+ return GDK_FILTER_CONTINUE;
}
- if (is_desktop_above_background == FALSE)
- {
- if (window->desktop == NULL)
- return;
-
- gdk_window_restack (window->desktop, window->background, TRUE);
- gdk_window_lower (window->background);
-
- is_desktop_above_background = TRUE;
- }
-}
+ if (items > 0 && windows[0] != xwindow)
+ XLowerWindow (xdisplay, xwindow);
-static GdkFilterReturn
-event_filter_func (GdkXEvent *xevent,
- GdkEvent *event,
- gpointer data)
-{
- GfBackgroundWindow *window;
- XEvent *e;
-
- window = GF_BACKGROUND_WINDOW (data);
- e = (GdkXEvent *) xevent;
-
- switch (e->type)
- {
- case CirculateNotify:
- case ConfigureNotify:
- case CreateNotify:
- case DestroyNotify:
- case GravityNotify:
- case MapNotify:
- case MappingNotify:
- case ReparentNotify:
- case UnmapNotify:
- case VisibilityNotify:
- handle_xevent (window, e);
- break;
-
- default:
- break;
- }
+ XFree (windows);
return GDK_FILTER_CONTINUE;
}
@@ -301,21 +128,6 @@ update_wm_protocols (Display *display,
}
static void
-set_no_input_and_no_focus (GdkWindow *window)
-{
- GdkDisplay *display;
- Display *xdisplay;
- Window xwindow;
-
- display = gdk_display_get_default ();
- xdisplay = gdk_x11_display_get_xdisplay (display);
- xwindow = gdk_x11_window_get_xid (window);
-
- update_wm_hints (xdisplay, xwindow);
- update_wm_protocols (xdisplay, xwindow);
-}
-
-static void
set_size_request (GdkScreen *screen,
GtkWidget *widget)
{
@@ -329,18 +141,6 @@ set_size_request (GdkScreen *screen,
}
static void
-gf_background_window_dispose (GObject *object)
-{
- GfBackgroundWindow *window;
-
- window = GF_BACKGROUND_WINDOW (object);
-
- g_clear_object (&window->desktop);
-
- G_OBJECT_CLASS (gf_background_window_parent_class)->dispose (object);
-}
-
-static void
gf_background_window_finalize (GObject *object)
{
GfBackgroundWindow *window;
@@ -360,31 +160,28 @@ gf_background_window_finalize (GObject *object)
static void
gf_background_window_map (GtkWidget *widget)
{
- GfBackgroundWindow *window;
-
- window = GF_BACKGROUND_WINDOW (widget);
-
GTK_WIDGET_CLASS (gf_background_window_parent_class)->map (widget);
- gdk_window_lower (window->background);
+ gdk_window_lower (gtk_widget_get_window (widget));
}
static void
gf_background_window_realize (GtkWidget *widget)
{
- GfBackgroundWindow *window;
- GdkWindow *gdk_window;
-
- window = GF_BACKGROUND_WINDOW (widget);
+ GdkDisplay *display;
+ Display *xdisplay;
+ GdkWindow *window;
+ Window xwindow;
GTK_WIDGET_CLASS (gf_background_window_parent_class)->realize (widget);
- gdk_window = gtk_widget_get_window (widget);
-
- window->xbackground = gdk_x11_window_get_xid (gdk_window);
- window->background = gdk_window;
+ display = gdk_display_get_default ();
+ xdisplay = gdk_x11_display_get_xdisplay (display);
+ window = gtk_widget_get_window (widget);
+ xwindow = gdk_x11_window_get_xid (window);
- set_no_input_and_no_focus (gdk_window);
+ update_wm_hints (xdisplay, xwindow);
+ update_wm_protocols (xdisplay, xwindow);
}
static void
@@ -396,7 +193,6 @@ gf_background_window_class_init (GfBackgroundWindowClass *window_class)
object_class= G_OBJECT_CLASS (window_class);
widget_class = GTK_WIDGET_CLASS (window_class);
- object_class->dispose = gf_background_window_dispose;
object_class->finalize = gf_background_window_finalize;
widget_class->map = gf_background_window_map;
@@ -418,13 +214,14 @@ gf_background_window_init (GfBackgroundWindow *window)
set_size_request (screen, gtk_widget);
gtk_window_set_keep_below (gtk_window, TRUE);
- gtk_widget_add_events (gtk_widget, GDK_STRUCTURE_MASK);
gtk_widget_realize (gtk_widget);
root = gdk_screen_get_root_window (screen);
mask = gdk_window_get_events (root);
- gdk_window_set_events (root, mask | GDK_SUBSTRUCTURE_MASK);
+ mask |= GDK_SUBSTRUCTURE_MASK | GDK_PROPERTY_CHANGE_MASK;
+
+ gdk_window_set_events (root, mask);
gdk_window_add_filter (root, event_filter_func, window);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]