[gnome-terminal] Get the minimization status by reading _NET_WM_STATE



commit 52b93f209f0a3c8f089aba7809b55844be4f75dd
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Mon Jun 22 13:59:53 2009 -0400

    Get the minimization status by reading _NET_WM_STATE
    
    A GDK bug or (arguably) misfeature means that the minimization status
    of GtkWindow is not properly saved and restored when unmapping and
    then mapping.
    
    Work around this by directly reading the _NET_WM_STATE property
    and looking for _NET_WM_STATE_HIDDEN.
    
    http://bugzilla.gnome.org/show_bug.cgi?id=564648

 src/terminal-util.c   |   52 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/terminal-util.h   |    2 +
 src/terminal-window.c |   13 ++++++++++++
 3 files changed, 67 insertions(+), 0 deletions(-)
---
diff --git a/src/terminal-util.c b/src/terminal-util.c
index fbaf372..cd5f675 100644
--- a/src/terminal-util.c
+++ b/src/terminal-util.c
@@ -1018,4 +1018,56 @@ terminal_util_x11_clear_demands_attention (GdkWindow *window)
 	      (XEvent *)&xclient);
 }
 
+/* Check if a GdkWindow is minimized. This is a workaround for a
+ * GDK bug/misfeature. gdk_window_get_state (window) has the
+ * GDK_WINDOW_STATE_ICONIFIED bit for all unmapped windows,
+ * even windows on another desktop.
+ *
+ * http://bugzilla.gnome.org/show_bug.cgi?id=586664
+ *
+ * Code to read _NET_WM_STATE adapted from GDK
+ */
+gboolean
+terminal_util_x11_window_is_minimized (GdkWindow *window)
+{
+  GdkDisplay *display = gdk_drawable_get_display (window);
+
+  Atom type;
+  gint format;
+  gulong nitems;
+  gulong bytes_after;
+  guchar *data;
+  Atom *atoms = NULL;
+  gulong i;
+
+  gboolean minimized = FALSE;
+
+  type = None;
+  gdk_error_trap_push ();
+  XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
+                      gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"),
+                      0, G_MAXLONG, False, XA_ATOM, &type, &format, &nitems,
+                      &bytes_after, &data);
+  gdk_error_trap_pop ();
+
+  if (type != None)
+    {
+      Atom hidden_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_HIDDEN");
+
+      atoms = (Atom *)data;
+
+      for (i = 0; i < nitems; i++)
+        {
+          if (atoms[i] == hidden_atom)
+            minimized = TRUE;
+
+          ++i;
+        }
+
+      XFree (atoms);
+    }
+
+  return minimized;
+}
+
 #endif /* GDK_WINDOWING_X11 */
diff --git a/src/terminal-util.h b/src/terminal-util.h
index 71743f9..8c10517 100644
--- a/src/terminal-util.h
+++ b/src/terminal-util.h
@@ -107,4 +107,6 @@ void     terminal_util_x11_set_net_wm_desktop (GdkWindow *window,
 
 void terminal_util_x11_clear_demands_attention (GdkWindow *window);
 
+gboolean terminal_util_x11_window_is_minimized (GdkWindow *window);
+
 #endif /* TERMINAL_UTIL_H */
diff --git a/src/terminal-window.c b/src/terminal-window.c
index 5d0345f..f51b018 100644
--- a/src/terminal-window.c
+++ b/src/terminal-window.c
@@ -1517,6 +1517,7 @@ terminal_window_composited_changed_cb (GdkScreen *screen,
       guint32 user_time;
       gboolean have_desktop;
       guint32 desktop = 0; /* Quiet GCC */
+      gboolean was_minimized;
       int x, y;
 
       user_time = gdk_x11_display_get_user_time (gtk_widget_get_display (widget));
@@ -1530,6 +1531,13 @@ terminal_window_composited_changed_cb (GdkScreen *screen,
        * But at worst, we'll be off by a few pixels (the frame size). */
       gtk_window_get_position (GTK_WINDOW (window), &x, &y);
 
+      /* GtkWindow tries to save whether the window was iconified
+       * and restore it, but that doesn't work because of problems
+       * GDK_WINDOW_STATE_ICONIFIED. For details, see comment for
+       * terminal_util_x11_window_is_minimized()
+       */
+      was_minimized = terminal_util_x11_window_is_minimized (widget->window);
+
       /* And the desktop */
       have_desktop = terminal_util_x11_get_net_wm_desktop (widget->window, &desktop);
 
@@ -1541,6 +1549,11 @@ terminal_window_composited_changed_cb (GdkScreen *screen,
       gtk_widget_realize (widget);
       gdk_x11_window_set_user_time (widget->window, user_time);
 
+      if (was_minimized)
+	gtk_window_iconify (GTK_WINDOW (window));
+      else
+	gtk_window_deiconify (GTK_WINDOW (window));
+
       gtk_widget_show (widget);
       if (have_desktop)
         terminal_util_x11_set_net_wm_desktop (widget->window, desktop);



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