[gnome-flashback/wip/desktop-background: 4/4] desktop-background: try to keep background window under all windows



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]