[gnome-shell] screenshot: add a 'flash' boolean flag to screenshot methods



commit 049a56146699812f057d3f0711469846edb05736
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Tue Jan 24 16:29:56 2012 -0500

    screenshot: add a 'flash' boolean flag to screenshot methods
    
    Add a flag to these methods that allows flashing the area of the
    screenshot directly from the compositor.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=668618

 data/theme/gnome-shell.css |    4 +++
 js/Makefile.am             |    1 +
 js/ui/flashspot.js         |   45 +++++++++++++++++++++++++++++++++++++++
 js/ui/shellDBus.js         |   41 +++++++++++++++++++++++++----------
 src/shell-global-private.h |    6 +----
 src/shell-global.c         |   50 +++++++++++++++++++++++++++++++++----------
 src/shell-global.h         |    4 ++-
 7 files changed, 121 insertions(+), 30 deletions(-)
---
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
index 5a4b1ea..33b0630 100644
--- a/data/theme/gnome-shell.css
+++ b/data/theme/gnome-shell.css
@@ -1716,6 +1716,10 @@ StTooltip StLabel {
     background-color: rgba(0, 0, 0, 0.4);
 }
 
+.flashspot {
+    background-color: white;
+}
+
 /* End Session Dialog */
 .end-session-dialog {
     spacing: 42px;
diff --git a/js/Makefile.am b/js/Makefile.am
index 63c11a0..28d9352 100644
--- a/js/Makefile.am
+++ b/js/Makefile.am
@@ -35,6 +35,7 @@ nobase_dist_js_DATA = 	\
 	ui/endSessionDialog.js	\
 	ui/environment.js	\
 	ui/extensionSystem.js	\
+	ui/flashspot.js		\
 	ui/iconGrid.js		\
 	ui/keyboard.js		\
 	ui/layout.js		\
diff --git a/js/ui/flashspot.js b/js/ui/flashspot.js
new file mode 100644
index 0000000..eabbac6
--- /dev/null
+++ b/js/ui/flashspot.js
@@ -0,0 +1,45 @@
+// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
+
+const Lang = imports.lang;
+
+const Lightbox = imports.ui.lightbox;
+const Main = imports.ui.main;
+const Tweener = imports.ui.tweener;
+
+const FLASHSPOT_ANIMATION_TIME = 0.25; // seconds
+
+const Flashspot = new Lang.Class({
+    Name: 'Flashspot',
+    Extends: Lightbox.Lightbox,
+
+    _init: function(area) {
+        this.parent(Main.uiGroup, { inhibitEvents: true,
+                                    width: area.width,
+                                    height: area.height });
+
+        this.actor.style_class = 'flashspot';
+        this.actor.set_position(area.x, area.y);
+    },
+
+    fire: function() {
+        this.actor.opacity = 0;
+        Tweener.addTween(this.actor,
+                         { opacity: 255,
+                           time: FLASHSPOT_ANIMATION_TIME,
+                           transition: 'linear',
+                           onComplete: Lang.bind(this, this._onFireShowComplete)
+                         });
+        this.actor.show();
+    },
+
+    _onFireShowComplete: function() {
+        Tweener.addTween(this.actor,
+                         { opacity: 0,
+                           time: FLASHSPOT_ANIMATION_TIME,
+                           transition: 'linear',
+                           onComplete: Lang.bind(this, function() {
+                               this.destroy();
+                           })
+                         });
+    }
+});
diff --git a/js/ui/shellDBus.js b/js/ui/shellDBus.js
index ee88594..63d9101 100644
--- a/js/ui/shellDBus.js
+++ b/js/ui/shellDBus.js
@@ -6,6 +6,7 @@ const GLib = imports.gi.GLib;
 
 const Config = imports.misc.config;
 const ExtensionSystem = imports.ui.extensionSystem;
+const Flashspot = imports.ui.flashspot;
 const Main = imports.ui.main;
 
 const GnomeShellIface = <interface name="org.gnome.Shell">
@@ -30,15 +31,18 @@ const GnomeShellIface = <interface name="org.gnome.Shell">
     <arg type="i" direction="in" name="y"/>
     <arg type="i" direction="in" name="width"/>
     <arg type="i" direction="in" name="height"/>
+    <arg type="b" direction="in" name="flash"/>
     <arg type="s" direction="in" name="filename"/>
     <arg type="b" direction="out" name="success"/>
 </method>
 <method name="ScreenshotWindow">
     <arg type="b" direction="in" name="include_frame"/>
+    <arg type="b" direction="in" name="flash"/>
     <arg type="s" direction="in" name="filename"/>
     <arg type="b" direction="out" name="success"/>
 </method>
 <method name="Screenshot">
+    <arg type="b" direction="in" name="flash"/>
     <arg type="s" direction="in" name="filename"/>
     <arg type="b" direction="out" name="success"/>
 </method>
@@ -109,6 +113,13 @@ const GnomeShell = new Lang.Class({
         return [success, returnValue];
     },
 
+    _handleScreenshotFlash: function(flash, area) {
+        if (flash) {
+            let flashspot = new Flashspot.Flashspot(area);
+            flashspot.fire();
+        }
+    },
+
     /**
      * ScreenshotArea:
      * @x: The X coordinate of the area
@@ -123,12 +134,14 @@ const GnomeShell = new Lang.Class({
      *
      */
     ScreenshotAreaAsync : function (params, invocation) {
-        let [x, y, width, height, filename, callback] = params;
-        global.screenshot_area (x, y, width, height, filename,
-            function (obj, result) {
+        let [x, y, width, height, flash, filename, callback] = params;
+        global.screenshot_area (x, y, width, height, filename, Lang.bind(this,
+            function (obj, result, area) {
+                this._handleScreenshotFlash(flash, area);
+
                 let retval = GLib.Variant.new('(b)', [result]);
                 invocation.return_value(retval);
-            });
+            }));
     },
 
     /**
@@ -142,12 +155,14 @@ const GnomeShell = new Lang.Class({
      *
      */
     ScreenshotWindowAsync : function (params, invocation) {
-        let [include_frame, filename] = params;
-        global.screenshot_window (include_frame, filename,
-            function (obj, result) {
+        let [include_frame, flash, filename] = params;
+        global.screenshot_window (include_frame, filename, Lang.bind(this,
+            function (obj, result, area) {
+                this._handleScreenshotFlash(flash, area);
+
                 let retval = GLib.Variant.new('(b)', [result]);
                 invocation.return_value(retval);
-            });
+            }));
     },
 
     /**
@@ -160,12 +175,14 @@ const GnomeShell = new Lang.Class({
      *
      */
     ScreenshotAsync : function (params, invocation) {
-        let [filename] = params;
-        global.screenshot(filename,
-            function (obj, result) {
+        let [flash, filename] = params;
+        global.screenshot(filename, Lang.bind(this,
+            function (obj, result, area) {
+                this._handleScreenshotFlash(flash, area);
+
                 let retval = GLib.Variant.new('(b)', [result]);
                 invocation.return_value(retval);
-            });
+            }));
     },
 
     ListExtensions: function() {
diff --git a/src/shell-global-private.h b/src/shell-global-private.h
index 5cb9d6a..5f2faf8 100644
--- a/src/shell-global-private.h
+++ b/src/shell-global-private.h
@@ -25,12 +25,8 @@ typedef struct _screenshot_data {
 
   char *filename;
 
-  int x;
-  int y;
-  int width;
-  int height;
-
   cairo_surface_t *image;
+  cairo_rectangle_int_t screenshot_area;
 
   ShellGlobalScreenshotCallback callback;
 } _screenshot_data;
diff --git a/src/shell-global.c b/src/shell-global.c
index c8f8014..1855644 100644
--- a/src/shell-global.c
+++ b/src/shell-global.c
@@ -1967,7 +1967,9 @@ on_screenshot_written (GObject *source,
 {
   _screenshot_data *screenshot_data = (_screenshot_data*) user_data;
   if (screenshot_data->callback)
-    screenshot_data->callback (screenshot_data->global, g_simple_async_result_get_op_res_gboolean (G_SIMPLE_ASYNC_RESULT (result)));
+    screenshot_data->callback (screenshot_data->global, 
+                               g_simple_async_result_get_op_res_gboolean (G_SIMPLE_ASYNC_RESULT (result)),
+                               &screenshot_data->screenshot_area);
 
   cairo_surface_destroy (screenshot_data->image);
   g_free (screenshot_data->filename);
@@ -2045,6 +2047,11 @@ grab_screenshot (ClutterActor *stage,
       cairo_region_destroy (stage_region);
     }
 
+  screenshot_data->screenshot_area.x = 0;
+  screenshot_data->screenshot_area.y = 0;
+  screenshot_data->screenshot_area.width = width;
+  screenshot_data->screenshot_area.height = height;
+
   g_signal_handlers_disconnect_by_func (stage, (void *)grab_screenshot, (gpointer)screenshot_data);
 
   result = g_simple_async_result_new (NULL, on_screenshot_written, (gpointer)screenshot_data, grab_screenshot);
@@ -2059,12 +2066,15 @@ grab_area_screenshot (ClutterActor *stage,
   GSimpleAsyncResult *result;
   guchar *data;
 
-  screenshot_data->image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, screenshot_data->width, screenshot_data->height);
+  screenshot_data->image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 
+                                                       screenshot_data->screenshot_area.width, 
+                                                       screenshot_data->screenshot_area.height);
   data = cairo_image_surface_get_data (screenshot_data->image);
 
   cogl_flush();
 
-  cogl_read_pixels (screenshot_data->x, screenshot_data->y, screenshot_data->width, screenshot_data->height,
+  cogl_read_pixels (screenshot_data->screenshot_area.x, screenshot_data->screenshot_area.y,
+                    screenshot_data->screenshot_area.width, screenshot_data->screenshot_area.height,
                     COGL_READ_PIXELS_COLOR_BUFFER, CLUTTER_CAIRO_FORMAT_ARGB32, data);
 
   cairo_surface_mark_dirty (screenshot_data->image);
@@ -2088,8 +2098,8 @@ grab_area_screenshot (ClutterActor *stage,
  */
 void
 shell_global_screenshot (ShellGlobal  *global,
-                        const char *filename,
-                        ShellGlobalScreenshotCallback callback)
+                         const char *filename,
+                         ShellGlobalScreenshotCallback callback)
 {
   ClutterActor *stage;
   _screenshot_data *data = g_new0 (_screenshot_data, 1);
@@ -2134,10 +2144,10 @@ shell_global_screenshot_area (ShellGlobal  *global,
 
   data->global = global;
   data->filename = g_strdup (filename);
-  data->x = x;
-  data->y = y;
-  data->width = width;
-  data->height = height;
+  data->screenshot_area.x = x;
+  data->screenshot_area.y = y;
+  data->screenshot_area.width = width;
+  data->screenshot_area.height = height;
   data->callback = callback;
 
   stage = CLUTTER_ACTOR (meta_plugin_get_stage (global->plugin));
@@ -2176,6 +2186,7 @@ shell_global_screenshot_window (ShellGlobal  *global,
   MetaDisplay *display = meta_screen_get_display (screen);
   MetaWindow *window = meta_display_get_focus_window (display);
   ClutterActor *window_actor;
+  gint width, height;
 
   screenshot_data->global = global;
   screenshot_data->filename = g_strdup (filename);
@@ -2184,6 +2195,9 @@ shell_global_screenshot_window (ShellGlobal  *global,
   window_actor = CLUTTER_ACTOR (meta_window_get_compositor_private (window));
   texture = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (meta_window_actor_get_texture (META_WINDOW_ACTOR (window_actor))));
 
+  screenshot_data->screenshot_area.x = (gint) clutter_actor_get_x (window_actor);
+  screenshot_data->screenshot_area.y = (gint) clutter_actor_get_y (window_actor);
+
   if (!include_frame)
     {
       MetaRectangle *window_rect = meta_window_get_rect (window);
@@ -2196,11 +2210,23 @@ shell_global_screenshot_window (ShellGlobal  *global,
       screenshot_data->image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
                                                           window_rect->width,
                                                           window_rect->height);
+
+      screenshot_data->screenshot_area.x += window_rect->x;
+      screenshot_data->screenshot_area.y += window_rect->y;
+      screenshot_data->screenshot_area.width = window_rect->width;
+      screenshot_data->screenshot_area.height = window_rect->height;
     }
   else
-    screenshot_data->image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
-                                                        clutter_actor_get_width (window_actor),
-                                                        clutter_actor_get_height (window_actor));
+    {
+      width = (gint) clutter_actor_get_width (window_actor);
+      height = (gint) clutter_actor_get_height (window_actor);
+
+      screenshot_data->image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+                                                           width, height);
+
+      screenshot_data->screenshot_area.width = width;
+      screenshot_data->screenshot_area.height = height;
+    }
 
   data = cairo_image_surface_get_data (screenshot_data->image);
 
diff --git a/src/shell-global.h b/src/shell-global.h
index 4433025..ba87f46 100644
--- a/src/shell-global.h
+++ b/src/shell-global.h
@@ -146,7 +146,9 @@ void     shell_global_reexec_self               (ShellGlobal  *global);
 
 void     shell_global_launch_calendar_server    (ShellGlobal  *global);
 
-typedef void (*ShellGlobalScreenshotCallback)  (ShellGlobal *global, gboolean success);
+typedef void (*ShellGlobalScreenshotCallback)  (ShellGlobal *global, 
+                                                gboolean success,
+                                                cairo_rectangle_int_t *screenshot_area);
 
 void    shell_global_screenshot_area           (ShellGlobal  *global,
                                                 int x,



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