[gnome-flashback] shell: destroy allocated windows



commit 300ae0afc505d0436dd08a04fbbbc4d38fad2133
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Wed Apr 27 18:28:31 2016 +0300

    shell: destroy allocated windows

 ...kground-try-to-keep-background-window-und.patch |  394 ++++++++++++++++++++
 gnome-flashback/libshell/flashback-osd.c           |    9 +
 2 files changed, 403 insertions(+), 0 deletions(-)
---
diff --git a/0004-desktop-background-try-to-keep-background-window-und.patch 
b/0004-desktop-background-try-to-keep-background-window-und.patch
new file mode 100644
index 0000000..2598583
--- /dev/null
+++ b/0004-desktop-background-try-to-keep-background-window-und.patch
@@ -0,0 +1,394 @@
+From e7e93b0befcbcbed14a2d1c9c3b8d2172402119f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Alberts=20Muktup=C4=81vels?= <alberts muktupavels gmail com>
+Date: Wed, 27 Apr 2016 00:15:58 +0300
+Subject: [PATCH 4/4] desktop-background: try to keep background window under
+ all windows
+
+---
+ .../libdesktop-background/gf-background-window.c   | 291 ++++-----------------
+ 1 file 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);
+ }
+ 
+-- 
+2.7.4
+
diff --git a/gnome-flashback/libshell/flashback-osd.c b/gnome-flashback/libshell/flashback-osd.c
index 086be08..4b6a7a9 100644
--- a/gnome-flashback/libshell/flashback-osd.c
+++ b/gnome-flashback/libshell/flashback-osd.c
@@ -66,6 +66,15 @@ flashabck_osd_finalize (GObject *object)
 
   g_signal_handlers_disconnect_by_func (screen, monitors_changed, osd);
 
+  if (osd->windows != NULL)
+    {
+      gint i;
+
+      for (i = 0; i < osd->n_monitors; i++)
+        gtk_widget_destroy (GTK_WIDGET (osd->windows[i]));
+      g_free (osd->windows);
+    }
+
   G_OBJECT_CLASS (flashback_osd_parent_class)->finalize (object);
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]