[mutter] Allow setting input region before output window is created



commit 7a7632fa9802512dace960eb2eff1f91361565da
Author: Owen W. Taylor <otaylor redhat com>
Date:   Thu Apr 23 16:33:16 2009 -0400

    Allow setting input region before output window is created
    
    If mutter_plugin_set_stage_input_region() and related methods are
    called before the output window is available, save the set input
    region and apply it to the output window later on.
    
    compository-mutter.[ch]: Add mutter_set_stage_input_region() and
    mutter_empty_stage_input_region(), move the input region handling
    here and implement the delayed shape setting described
    above.
    
    mutter-plugin.c: Implement shape setting in terms of the new methods.
    
    http://bugzilla.gnome.org/show_bug.cgi?id=580042
---
 src/compositor/mutter/compositor-mutter.c |   55 +++++++++++++++++++++++++++--
 src/compositor/mutter/mutter-plugin.c     |   51 +++------------------------
 src/include/compositor-mutter.h           |    5 +++
 3 files changed, 62 insertions(+), 49 deletions(-)

diff --git a/src/compositor/mutter/compositor-mutter.c b/src/compositor/mutter/compositor-mutter.c
index fe17a5a..3320e3e 100644
--- a/src/compositor/mutter/compositor-mutter.c
+++ b/src/compositor/mutter/compositor-mutter.c
@@ -148,6 +148,9 @@ typedef struct _MetaCompScreen
   Window                 output;
   GSList                *dock_windows;
 
+  /* Before we create the output window */
+  XserverRegion     pending_input_region;
+
   gint                   switch_workspace_in_progress;
 
   MutterPluginManager *plugin_mgr;
@@ -1827,6 +1830,45 @@ mutter_get_windows (MetaScreen *screen)
   return info->windows;
 }
 
+void
+mutter_set_stage_input_region (MetaScreen *screen,
+                               XserverRegion region)
+{
+  MetaCompScreen *info = meta_screen_get_compositor_data (screen);
+  MetaDisplay  *display = meta_screen_get_display (screen);
+  Display      *xdpy    = meta_display_get_xdisplay (display);
+
+  if (info->stage && info->output)
+    {
+      Window xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage));
+
+      XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region);
+      XFixesSetWindowShapeRegion (xdpy, info->output, ShapeInput, 0, 0, region);
+    }
+  else if (region != None)
+    {
+      info->pending_input_region = XFixesCreateRegion (xdpy, NULL, 0);
+      XFixesCopyRegion (xdpy, info->pending_input_region, region);
+    }
+}
+
+void
+mutter_empty_stage_input_region (MetaScreen *screen)
+{
+  /* Using a static region here is a bit hacky, but Metacity never opens more than
+   * one XDisplay, so it works fine. */
+  static XserverRegion region = None;
+
+  if (region == None)
+    {
+      MetaDisplay  *display = meta_screen_get_display (screen);
+      Display      *xdpy    = meta_display_get_xdisplay (display);
+      region = XFixesCreateRegion (xdpy, NULL, 0);
+    }
+
+  mutter_set_stage_input_region (screen, region);
+}
+
 static void
 clutter_cmp_manage_screen (MetaCompositor *compositor,
                            MetaScreen     *screen)
@@ -1914,15 +1956,22 @@ clutter_cmp_manage_screen (MetaCompositor *compositor,
   /*
    * Delay the creation of the overlay window as long as we can, to avoid
    * blanking out the screen. This means that during the plugin loading, the
-   * overlay window is not accessible, and so the plugins cannot do stuff
-   * like changing input shape; if that is required, the plugin should hook into
-   * "show" signal on stage, and do its stuff there.
+   * overlay window is not accessible; if the plugin needs to access it
+   * directly, it should hook into the "show" signal on stage, and do
+   * its stuff there.
    */
   info->output = get_output_window (screen);
   XReparentWindow (xdisplay, xwin, info->output, 0, 0);
 
   show_overlay_window (xdisplay, xwin, info->output);
 
+  if (info->pending_input_region != None)
+    {
+      mutter_set_stage_input_region (screen, info->pending_input_region);
+      XFixesDestroyRegion (xdisplay, info->pending_input_region);
+      info->pending_input_region = None;
+    }
+
   clutter_actor_show (info->overlay_group);
   clutter_actor_show (info->stage);
 #endif
diff --git a/src/compositor/mutter/mutter-plugin.c b/src/compositor/mutter/mutter-plugin.c
index 139a0c5..7714344 100644
--- a/src/compositor/mutter/mutter-plugin.c
+++ b/src/compositor/mutter/mutter-plugin.c
@@ -408,34 +408,11 @@ mutter_plugin_set_stage_reactive (MutterPlugin *plugin,
 {
   MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
   MetaScreen  *screen  = priv->screen;
-  MetaDisplay *display = meta_screen_get_display (screen);
-  Display     *xdpy    = meta_display_get_xdisplay (display);
-  Window       xstage, xoverlay;
-  ClutterActor *stage;
-
-  stage = mutter_get_stage_for_screen (screen);
-  xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
-  xoverlay = mutter_get_overlay_window (screen);
-
-  static XserverRegion region = None;
-
-  if (region == None)
-    region = XFixesCreateRegion (xdpy, NULL, 0);
 
   if (reactive)
-    {
-      XFixesSetWindowShapeRegion (xdpy, xstage,
-                                  ShapeInput, 0, 0, None);
-      XFixesSetWindowShapeRegion (xdpy, xoverlay,
-                                  ShapeInput, 0, 0, None);
-    }
+    mutter_set_stage_input_region (screen, None);
   else
-    {
-      XFixesSetWindowShapeRegion (xdpy, xstage,
-                                  ShapeInput, 0, 0, region);
-      XFixesSetWindowShapeRegion (xdpy, xoverlay,
-                                  ShapeInput, 0, 0, region);
-    }
+    mutter_empty_stage_input_region (screen);
 }
 
 void
@@ -446,25 +423,16 @@ mutter_plugin_set_stage_input_area (MutterPlugin *plugin,
   MetaScreen   *screen  = priv->screen;
   MetaDisplay  *display = meta_screen_get_display (screen);
   Display      *xdpy    = meta_display_get_xdisplay (display);
-  Window        xstage, xoverlay;
-  ClutterActor *stage;
   XRectangle    rect;
   XserverRegion region;
 
-  stage = mutter_get_stage_for_screen (screen);
-  xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
-  xoverlay = mutter_get_overlay_window (screen);
-
   rect.x = x;
   rect.y = y;
   rect.width = width;
   rect.height = height;
 
   region = XFixesCreateRegion (xdpy, &rect, 1);
-
-  XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region);
-  XFixesSetWindowShapeRegion (xdpy, xoverlay, ShapeInput, 0, 0, region);
-
+  mutter_set_stage_input_region (screen, region);
   XFixesDestroyRegion (xdpy, region);
 }
 
@@ -473,18 +441,9 @@ mutter_plugin_set_stage_input_region (MutterPlugin *plugin,
                                       XserverRegion region)
 {
   MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
-  MetaScreen   *screen  = priv->screen;
-  MetaDisplay  *display = meta_screen_get_display (screen);
-  Display      *xdpy    = meta_display_get_xdisplay (display);
-  Window        xstage, xoverlay;
-  ClutterActor *stage;
-
-  stage = mutter_get_stage_for_screen (screen);
-  xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
-  xoverlay = mutter_get_overlay_window (screen);
+  MetaScreen  *screen  = priv->screen;
 
-  XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region);
-  XFixesSetWindowShapeRegion (xdpy, xoverlay, ShapeInput, 0, 0, region);
+  mutter_set_stage_input_region (screen, region);
 }
 
 GList *
diff --git a/src/include/compositor-mutter.h b/src/include/compositor-mutter.h
index 083ab19..263485a 100644
--- a/src/include/compositor-mutter.h
+++ b/src/include/compositor-mutter.h
@@ -26,6 +26,7 @@
 #define MUTTER_H_
 
 #include <clutter/clutter.h>
+#include <X11/extensions/Xfixes.h>
 #include <X11/Xlib.h>
 
 #include "types.h"
@@ -80,4 +81,8 @@ Window         mutter_get_overlay_window (MetaScreen *screen);
 GList        * mutter_get_windows (MetaScreen *screen);
 ClutterActor * mutter_get_window_group_for_screen (MetaScreen *screen);
 
+void mutter_set_stage_input_region   (MetaScreen   *screen,
+                                      XserverRegion region);
+void mutter_empty_stage_input_region (MetaScreen   *screen);
+
 #endif



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