[gtk+/gtk-3-2] Iconification using _NET_WM_STATE_HIDDEN hint if supported by WM



commit e9944eb3ffa2caba5531685bf5abf3dc011576ad
Author: Mikael Magnusson <mikachu src gnome org>
Date:   Fri Mar 2 20:50:05 2012 +0100

    Iconification using _NET_WM_STATE_HIDDEN hint if supported by WM
    
    If the Window Manager supports the _NET_WM_STATE_HIDDEN, we use it to use
    the _NET_WM_STATE protocol when de-iconifying windows (iconification is
    unchanged, via XIconifyWindow). Additionally, we no longer interpret all
    UnmapNotify events for our window as the result of iconification.
    
    (Based on patch by Tomas Frydrych <tf linux intel com>)

 gdk/x11/gdkdisplay-x11.c |   49 +++++++++++++++++++++++++++++++++++----------
 gdk/x11/gdkwindow-x11.c  |   17 ++++++++++++++++
 gdk/x11/gdkwindow-x11.h  |    1 +
 3 files changed, 56 insertions(+), 11 deletions(-)
---
diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c
index 401406c..87cf71e 100644
--- a/gdk/x11/gdkdisplay-x11.c
+++ b/gdk/x11/gdkdisplay-x11.c
@@ -240,6 +240,21 @@ do_net_wm_state_changes (GdkWindow *window)
                                      0,
                                      GDK_WINDOW_STATE_MAXIMIZED);
     }
+
+  if (old_state & GDK_WINDOW_STATE_ICONIFIED)
+    {
+      if (!toplevel->have_hidden)
+        gdk_synthesize_window_state (window,
+                                     GDK_WINDOW_STATE_ICONIFIED,
+                                     0);
+    }
+  else
+    {
+      if (toplevel->have_hidden)
+        gdk_synthesize_window_state (window,
+                                     0,
+                                     GDK_WINDOW_STATE_ICONIFIED);
+    }
 }
 
 static void
@@ -297,6 +312,7 @@ gdk_check_wm_state_changed (GdkWindow *window)
   toplevel->have_maxvert = FALSE;
   toplevel->have_maxhorz = FALSE;
   toplevel->have_fullscreen = FALSE;
+  toplevel->have_hidden = FALSE;
 
   type = None;
   gdk_x11_display_error_trap_push (display);
@@ -312,6 +328,7 @@ gdk_check_wm_state_changed (GdkWindow *window)
       Atom maxvert_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_MAXIMIZED_VERT");
       Atom maxhorz_atom	= gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_MAXIMIZED_HORZ");
       Atom fullscreen_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_FULLSCREEN");
+      Atom hidden_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_HIDDEN");
 
       atoms = (Atom *)data;
 
@@ -326,6 +343,8 @@ gdk_check_wm_state_changed (GdkWindow *window)
             toplevel->have_maxhorz = TRUE;
           else if (atoms[i] == fullscreen_atom)
             toplevel->have_fullscreen = TRUE;
+          else if (atoms[i] == hidden_atom)
+            toplevel->have_hidden = TRUE;
 
           ++i;
         }
@@ -606,19 +625,27 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
       event->any.type = GDK_UNMAP;
       event->any.window = window;
 
-      /* If we are shown (not withdrawn) and get an unmap, it means we
-       * were iconified in the X sense. If we are withdrawn, and get
-       * an unmap, it means we hid the window ourselves, so we
-       * will have already flipped the iconified bit off.
+      /* If the WM supports the _NET_WM_STATE_HIDDEN hint, we do not want to
+       * interpret UnmapNotify events as implying iconic state.
+       * http://bugzilla.gnome.org/show_bug.cgi?id=590726.
        */
-      if (window)
+      if (screen &&
+          !gdk_x11_screen_supports_net_wm_hint (screen,
+                                                gdk_atom_intern_static_string ("_NET_WM_STATE_HIDDEN")))
         {
-          if (GDK_WINDOW_IS_MAPPED (window))
-            gdk_synthesize_window_state (window,
-                                         0,
-                                         GDK_WINDOW_STATE_ICONIFIED);
-
-          _gdk_x11_window_grab_check_unmap (window, xevent->xany.serial);
+          /* If we are shown (not withdrawn) and get an unmap, it means we were
+           * iconified in the X sense. If we are withdrawn, and get an unmap, it
+           * means we hid the window ourselves, so we will have already flipped
+           * the iconified bit off.
+           */
+          if (window)
+            {
+              if (GDK_WINDOW_IS_MAPPED (window))
+                gdk_synthesize_window_state (window,
+                                             0,
+                                             GDK_WINDOW_STATE_ICONIFIED);
+              _gdk_x11_window_grab_check_unmap (window, xevent->xany.serial);
+            }
         }
 
       break;
diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c
index 28c45bd..f2f73c8 100644
--- a/gdk/x11/gdkwindow-x11.c
+++ b/gdk/x11/gdkwindow-x11.c
@@ -1272,6 +1272,14 @@ set_initial_hints (GdkWindow *window)
       ++i;
     }
 
+  if (window->state & GDK_WINDOW_STATE_ICONIFIED)
+    {
+      atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
+							"_NET_WM_STATE_HIDDEN");
+      ++i;
+      toplevel->have_hidden = TRUE;
+    }
+
   if (i > 0)
     {
       XChangeProperty (xdisplay,
@@ -3407,6 +3415,9 @@ gdk_x11_window_iconify (GdkWindow *window)
       gdk_synthesize_window_state (window,
                                    0,
                                    GDK_WINDOW_STATE_ICONIFIED);
+      gdk_wmspec_change_state (TRUE, window,
+                               gdk_atom_intern_static_string ("_NET_WM_STATE_HIDDEN"),
+                               GDK_NONE);
     }
 }
 
@@ -3420,6 +3431,9 @@ gdk_x11_window_deiconify (GdkWindow *window)
   if (GDK_WINDOW_IS_MAPPED (window))
     {  
       gdk_window_show (window);
+      gdk_wmspec_change_state (FALSE, window,
+                               gdk_atom_intern_static_string ("_NET_WM_STATE_HIDDEN"),
+                               GDK_NONE);
     }
   else
     {
@@ -3427,6 +3441,9 @@ gdk_x11_window_deiconify (GdkWindow *window)
       gdk_synthesize_window_state (window,
                                    GDK_WINDOW_STATE_ICONIFIED,
                                    0);
+      gdk_wmspec_change_state (FALSE, window,
+                               gdk_atom_intern_static_string ("_NET_WM_STATE_HIDDEN"),
+                               GDK_NONE);
     }
 }
 
diff --git a/gdk/x11/gdkwindow-x11.h b/gdk/x11/gdkwindow-x11.h
index b58a31b..f9ceaf3 100644
--- a/gdk/x11/gdkwindow-x11.h
+++ b/gdk/x11/gdkwindow-x11.h
@@ -121,6 +121,7 @@ struct _GdkToplevelX11
   guint have_maxvert : 1;       /* _NET_WM_STATE_MAXIMIZED_VERT */
   guint have_maxhorz : 1;       /* _NET_WM_STATE_MAXIMIZED_HORZ */
   guint have_fullscreen : 1;    /* _NET_WM_STATE_FULLSCREEN */
+  guint have_hidden : 1;	/* _NET_WM_STATE_HIDDEN */
 
   guint is_leader : 1;
   



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