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
This commit is contained in:
Cosimo Cecchi 2012-01-24 16:29:56 -05:00
parent b40b19997a
commit 049a561466
7 changed files with 121 additions and 30 deletions

View File

@ -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;

View File

@ -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 \

45
js/ui/flashspot.js Normal file
View File

@ -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();
})
});
}
});

View File

@ -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() {

View File

@ -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;

View File

@ -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);

View File

@ -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,