[gnome-flashback] shell: destroy allocated windows
- From: Alberts Muktupāvels <muktupavels src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-flashback] shell: destroy allocated windows
- Date: Wed, 27 Apr 2016 15:50:14 +0000 (UTC)
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]