[mutter] Add MUTTER_WM_CLASS_FILTER environment variable



commit 9043191927169111f917f7c5cbfb2f85595a9765
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Tue Mar 8 17:15:56 2011 -0500

    Add MUTTER_WM_CLASS_FILTER environment variable
    
    In a performance or regression testing environment, we may want to
    only manage windows from a particular test program, and ignore all
    other windows. The MUTTER_WM_CLASS_FILTER environment variable is a
    list of WM_CLASS values that should be managed; other windows will
    be unmapped and ignored.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=644252

 src/core/window.c |  121 ++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 111 insertions(+), 10 deletions(-)
---
diff --git a/src/core/window.c b/src/core/window.c
index a0f1f47..69104ab 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -64,6 +64,9 @@ static void     recalc_window_type        (MetaWindow     *window);
 static void     recalc_window_features    (MetaWindow     *window);
 static void     invalidate_work_areas     (MetaWindow     *window);
 static void     recalc_window_type        (MetaWindow     *window);
+static void     set_wm_state_on_xwindow   (MetaDisplay    *display,
+                                           Window          xwindow,
+                                           int             state);
 static void     set_wm_state              (MetaWindow     *window,
                                            int             state);
 static void     set_net_wm_state          (MetaWindow     *window);
@@ -517,6 +520,90 @@ meta_window_new (MetaDisplay *display,
   return window;
 }
 
+/* The MUTTER_WM_CLASS_FILTER environment variable is designed for
+ * performance and regression testing environments where we want to do
+ * tests with only a limited set of windows and ignore all other windows
+ *
+ * When it is set to a comma separated list of WM_CLASS class names, all
+ * windows not matching the list will be ignored.
+ *
+ * Returns TRUE if window has been filtered out and should be ignored.
+ */
+static gboolean
+maybe_filter_window (MetaDisplay       *display,
+                     Window             xwindow,
+                     gboolean           must_be_viewable,
+                     XWindowAttributes *attrs)
+{
+  static char **filter_wm_classes = NULL;
+  static gboolean initialized = FALSE;
+  XClassHint class_hint;
+  gboolean filtered;
+  Status success;
+  int i;
+
+  if (!initialized)
+    {
+      const char *filter_string = g_getenv ("MUTTER_WM_CLASS_FILTER");
+      if (filter_string)
+        filter_wm_classes = g_strsplit (filter_string, ",", -1);
+      initialized = TRUE;
+    }
+
+  if (!filter_wm_classes || !filter_wm_classes[0])
+    return FALSE;
+
+  filtered = TRUE;
+
+  meta_error_trap_push (display);
+  success = XGetClassHint (display->xdisplay, xwindow, &class_hint);
+
+  if (success)
+    {
+      for (i = 0; filter_wm_classes[i]; i++)
+        {
+          if (strcmp (class_hint.res_class, filter_wm_classes[i]) == 0)
+            {
+              filtered = FALSE;
+              break;
+            }
+        }
+
+      XFree (class_hint.res_name);
+      XFree (class_hint.res_class);
+    }
+
+  if (filtered)
+    {
+      /* We want to try and get the window managed by the next WM that come along,
+       * so we need to make sure that windows that are requested to be mapped while
+       * Mutter is running (!must_be_viewable), or windows already viewable at startup
+       * get a non-withdrawn WM_STATE property. Previously unmapped windows are left
+       * with whatever WM_STATE property they had.
+       */
+      if (!must_be_viewable || attrs->map_state == IsViewable)
+        {
+          gulong old_state;
+
+          if (!meta_prop_get_cardinal_with_atom_type (display, xwindow,
+                                                      display->atom_WM_STATE,
+                                                      display->atom_WM_STATE,
+                                                      &old_state))
+            old_state = WithdrawnState;
+
+          if (old_state == WithdrawnState)
+            set_wm_state_on_xwindow (display, xwindow, NormalState);
+        }
+
+      /* Make sure filtered windows are hidden from view */
+      XUnmapWindow (display->xdisplay, xwindow);
+    }
+
+  meta_error_trap_pop (display);
+
+  return filtered;
+}
+
 MetaWindow*
 meta_window_new_with_attrs (MetaDisplay       *display,
                             Window             xwindow,
@@ -579,6 +666,12 @@ meta_window_new_with_attrs (MetaDisplay       *display,
     return NULL;
   }
 
+  if (maybe_filter_window (display, xwindow, must_be_viewable, attrs))
+    {
+      meta_verbose ("Not managing filtered window\n");
+      return NULL;
+    }
+
   /* Grab server */
   meta_display_grab (display);
   meta_error_trap_push (display); /* Push a trap over all of window
@@ -1632,26 +1725,34 @@ meta_window_update_on_all_workspaces (MetaWindow *window)
 }
 
 static void
-set_wm_state (MetaWindow *window,
-              int         state)
+set_wm_state_on_xwindow (MetaDisplay *display,
+                         Window       xwindow,
+                         int          state)
 {
   unsigned long data[2];
 
-  meta_verbose ("Setting wm state %s on %s\n",
-                wm_state_to_string (state), window->desc);
-
   /* Mutter doesn't use icon windows, so data[1] should be None
    * according to the ICCCM 2.0 Section 4.1.3.1.
    */
   data[0] = state;
   data[1] = None;
 
-  meta_error_trap_push (window->display);
-  XChangeProperty (window->display->xdisplay, window->xwindow,
-                   window->display->atom_WM_STATE,
-                   window->display->atom_WM_STATE,
+  meta_error_trap_push (display);
+  XChangeProperty (display->xdisplay, xwindow,
+                   display->atom_WM_STATE,
+                   display->atom_WM_STATE,
                    32, PropModeReplace, (guchar*) data, 2);
-  meta_error_trap_pop (window->display);
+  meta_error_trap_pop (display);
+}
+
+static void
+set_wm_state (MetaWindow *window,
+              int         state)
+{
+  meta_verbose ("Setting wm state %s on %s\n",
+                wm_state_to_string (state), window->desc);
+
+  set_wm_state_on_xwindow (window->display, window->xwindow, state);
 }
 
 static void



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