After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 652952 - Add screenshot interface
Add screenshot interface
Status: RESOLVED FIXED
Product: gnome-shell
Classification: Core
Component: general
unspecified
Other All
: Normal normal
: ---
Assigned To: gnome-shell-maint
gnome-shell-maint
Depends on: 653590
Blocks:
 
 
Reported: 2011-06-19 16:07 UTC by drago01
Modified: 2012-02-14 20:26 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Add screenshot interface (3.92 KB, patch)
2011-06-19 16:07 UTC, drago01
none Details | Review
Add screenshot interface (3.92 KB, patch)
2011-06-19 16:14 UTC, drago01
needs-work Details | Review
Add screenshot interface (8.06 KB, patch)
2011-06-20 22:03 UTC, drago01
none Details | Review
Add screenshot interface (7.81 KB, patch)
2011-06-22 18:51 UTC, drago01
reviewed Details | Review
Add screenshot interface (10.46 KB, patch)
2011-06-27 20:14 UTC, drago01
none Details | Review
Add screenshot interface (10.46 KB, patch)
2011-06-28 08:49 UTC, drago01
needs-work Details | Review
Add screenshot interface (10.46 KB, patch)
2011-06-28 15:18 UTC, drago01
none Details | Review
Add screenshot interface (10.46 KB, patch)
2011-06-28 16:29 UTC, drago01
needs-work Details | Review
Add screenshot interface (13.16 KB, patch)
2011-07-22 22:22 UTC, drago01
none Details | Review
Add screenshot interface (13.12 KB, patch)
2011-07-22 22:30 UTC, drago01
committed Details | Review
Screenshot: Move filesystem I/O to a thread (10.64 KB, patch)
2012-01-22 10:25 UTC, drago01
committed Details | Review

Description drago01 2011-06-19 16:07:57 UTC
See patch.
Comment 1 drago01 2011-06-19 16:07:59 UTC
Created attachment 190212 [details] [review]
Add screenshot interface

Add a method to shell_global to allow screenshoting arbitary
parts of the screen and save the result into a specified png
image.

Also add a method to shellDBus to expose to applications like
gnome-screenshot.
Comment 2 drago01 2011-06-19 16:14:29 UTC
Created attachment 190213 [details] [review]
Add screenshot interface

Add a method to shell_global to allow screenshoting arbitary
parts of the screen and save the result into a specified png
image.

Also add a method to shellDBus to expose to applications like
gnome-screenshot.

---

Whitespace fix.
Comment 3 Cosimo Cecchi 2011-06-20 20:44:04 UTC
gnome-screenshot has three modes we want to support:

- get_whole_desktop(), just does what it says, it takes an image of the whole display. If you have multiple screens, all of them are grabbed, considering their geometry and relative positioning, like this [1] (don't look at the red lines there, I took this screenshot for some other bug a while ago).

- get_focused_window(), takes an image of the currently focused window. There should be an option to enable/disable WM borders.

- get_area(), takes an image of an user-defined rectangle, no options involved.

I think we want to keep the configuration/save parts separate from the shell still in gnome-screenshot, so it probably makes sense for those methods either to save to a path directly (gnome-screenshot could pass a temporary filename there in case it wants to e.g. save to clipboard directly), as passing a giant PNG over DBus could be really expensive.

[1] http://people.gnome.org/~cosimoc/multihead-shell.png
Comment 4 drago01 2011-06-20 20:47:58 UTC
(In reply to comment #3)
> gnome-screenshot has three modes we want to support:
> 
> - get_whole_desktop(), just does what it says, it takes an image of the whole
> display. If you have multiple screens, all of them are grabbed, considering
> their geometry and relative positioning, like this [1] (don't look at the red
> lines there, I took this screenshot for some other bug a while ago).
> 
> - get_focused_window(), takes an image of the currently focused window. There
> should be an option to enable/disable WM borders.
> 
> - get_area(), takes an image of an user-defined rectangle, no options involved.
> 
> I think we want to keep the configuration/save parts separate from the shell
> still in gnome-screenshot, so it probably makes sense for those methods either
> to save to a path directly (gnome-screenshot could pass a temporary filename
> there in case it wants to e.g. save to clipboard directly), as passing a giant
> PNG over DBus could be really expensive.

The current patch works this way, ie. you pass an image and it saves the result there. DBus isn't a protocol for large binary data so that's fine.

As for the other modes will add them.
Comment 5 drago01 2011-06-20 20:48:33 UTC
Review of attachment 190213 [details] [review]:

Need to add grab_display() and grab_window() methods.
Comment 6 drago01 2011-06-20 22:03:55 UTC
Created attachment 190318 [details] [review]
Add screenshot interface

Adds methods to shell_global to allow taking screenshots
save the result into a specified png image.

It exposes three methods via shellDBus applications like
gnome-screenshot:

*) Screenshot (screenshots the whole screen)
*) ScreenshotWindow (screenshots the focused window)
*) ScreenshotArea (screenshots a specific area)


---

For some reason the window method sometimes produces garbage, need to investigate.
Comment 7 drago01 2011-06-22 18:51:50 UTC
Created attachment 190465 [details] [review]
Add screenshot interface

Adds methods to shell_global to allow taking screenshots
save the result into a specified png image.

It exposes three methods via shellDBus applications like
gnome-screenshot:

*) Screenshot (screenshots the whole screen)
*) ScreenshotWindow (screenshots the focused window)
*) ScreenshotArea (screenshots a specific area)

---

*) Fixed corruption issues
*) Fix litte vs. big endian bug
Comment 8 Dan Winship 2011-06-27 13:08:24 UTC
Comment on attachment 190465 [details] [review]
Add screenshot interface

>+     * indicating whether the operation was successfull or not.

"successful" (likewise in other funcs)

>+     * Takes a screenshot of the focused window (optionally ommitting the frame)

"omitting" 

>+    Screenshot : function (filename) {
>+        return global.screenshot_area (0, 0, global.screen_width, global.screen_height, filename);

does this do the right thing with dead areas in multi-monitor setups?

>+shell_global_screenshot_area (ShellGlobal  *global,
>+                              int x,

align the parameters

>+  cogl_read_pixels (x, y, width, height, COGL_READ_PIXELS_COLOR_BUFFER, COGL_PIXEL_FORMAT_BGRA_8888_PRE, data);

you check byte order in screenshow_window, but not in screenshot_area... ?
Comment 9 drago01 2011-06-27 15:08:22 UTC
(In reply to comment #8)
> (From update of attachment 190465 [details] [review])
> >+     * indicating whether the operation was successfull or not.
> 
> "successful" (likewise in other funcs)

OK

> >+     * Takes a screenshot of the focused window (optionally ommitting the frame)
> 
> "omitting" 

OK

> >+    Screenshot : function (filename) {
> >+        return global.screenshot_area (0, 0, global.screen_width, global.screen_height, filename);
> 
> does this do the right thing with dead areas in multi-monitor setups?

I suppose so but I can't test right now due to libtool + rpath spoiling my day.

> >+shell_global_screenshot_area (ShellGlobal  *global,
> >+                              int x,
> 
> align the parameters

OK
 
> >+  cogl_read_pixels (x, y, width, height, COGL_READ_PIXELS_COLOR_BUFFER, COGL_PIXEL_FORMAT_BGRA_8888_PRE, data);
> 
> you check byte order in screenshow_window, but not in screenshot_area... ?

Oops...
Comment 10 drago01 2011-06-27 20:13:05 UTC
(In reply to comment #8)
> >+    Screenshot : function (filename) {
> >+        return global.screenshot_area (0, 0, global.screen_width, global.screen_height, filename);
> 
> does this do the right thing with dead areas in multi-monitor setups?

No.
Comment 11 drago01 2011-06-27 20:14:04 UTC
Created attachment 190811 [details] [review]
Add screenshot interface

Adds methods to shell_global to allow taking screenshots
save the result into a specified png image.

It exposes three methods via shellDBus applications like
gnome-screenshot:

*) Screenshot (screenshots the whole screen)
*) ScreenshotWindow (screenshots the focused window)
*) ScreenshotArea (screenshots a specific area)

---

*) Fix multiscreen bug
*) Fix byte order in !ScreenShotWindow
*) Fix spelling / style
Comment 12 drago01 2011-06-28 08:49:51 UTC
Created attachment 190833 [details] [review]
Add screenshot interface

Adds methods to shell_global to allow taking screenshots
save the result into a specified png image.

It exposes three methods via shellDBus applications like
gnome-screenshot:

*) Screenshot (screenshots the whole screen)
*) ScreenshotWindow (screenshots the focused window)
*) ScreenshotArea (screenshots a specific area)

---

*) Whitespace fix
Comment 13 drago01 2011-06-28 15:18:10 UTC
Created attachment 190875 [details] [review]
Add screenshot interface

Adds methods to shell_global to allow taking screenshots
save the result into a specified png image.

It exposes three methods via shellDBus applications like
gnome-screenshot:

*) Screenshot (screenshots the whole screen)
*) ScreenshotWindow (screenshots the focused window)
*) ScreenshotArea (screenshots a specific area)


---

*) Fix build ...
Comment 14 Dan Winship 2011-06-28 15:56:09 UTC
Comment on attachment 190833 [details] [review]
Add screenshot interface

>+      cairo_region_destroy screen_region);
>+
>+      cr = cairo_create (image);
>+
>+      for (i = 0; i < cairo_region_num_rectangles (screen_region); i++)

that needs to be "stage_region". But even then the generated PNG file is wrong. (screenshot_window() works, screenshot() doesn't).
Comment 15 drago01 2011-06-28 16:29:26 UTC
Created attachment 190882 [details] [review]
Add screenshot interface

Adds methods to shell_global to allow taking screenshots
save the result into a specified png image.

It exposes three methods via shellDBus applications like
gnome-screenshot:

*) Screenshot (screenshots the whole screen)
*) ScreenshotWindow (screenshots the focused window)
*) ScreenshotArea (screenshots a specific area)


--

s/screen_region/stage_region/
Comment 16 drago01 2011-06-28 17:39:10 UTC
Review of attachment 190882 [details] [review]:

Marking needs-work based on IRC discussion with Robert.
Comment 17 drago01 2011-07-22 22:22:06 UTC
Created attachment 192507 [details] [review]
Add screenshot interface

Adds methods to shell_global to allow taking screenshots
save the result into a specified png image.

It exposes three methods via shellDBus applications like
gnome-screenshot:

*) Screenshot (screenshots the whole screen)
*) ScreenshotWindow (screenshots the focused window)
*) ScreenshotArea (screenshots a specific area)

---

Read the backbuffer directly after paint asynchrounsly to avoid reading it
while it is in an undefined state.
Comment 18 drago01 2011-07-22 22:30:33 UTC
Created attachment 192508 [details] [review]
Add screenshot interface

Adds methods to shell_global to allow taking screenshots
save the result into a specified png image.

It exposes three methods via shellDBus applications like
gnome-screenshot:

*) Screenshot (screenshots the whole screen)
*) ScreenshotWindow (screenshots the focused window)
*) ScreenshotArea (screenshots a specific area)

--

*) Cleanups
Comment 19 Dan Winship 2011-07-26 13:26:20 UTC
Comment on attachment 192508 [details] [review]
Add screenshot interface

Note that this patch is currently based on top of the unredirect patch, so make sure you don't accidentally commit that with it.

Graphically it seems to work. It's still annoyingly slow. (With my 1400x1050 laptop screen, the shell freezes for .5s when taking the screenshot. With a 1920x1200 external monitor attached as well, it takes 1.5s.) It looks like about 1/3 of that time is cogl_read_pixels(), and 2/3 is cairo_surface_write_to_png(). At least the latter part could be moved to another thread. Not sure if we can do anything about cogl_read_pixels(). (How does the recorder avoid being slow?)
Comment 20 drago01 2011-07-26 15:38:04 UTC
(In reply to comment #19)
> (From update of attachment 192508 [details] [review])
> Note that this patch is currently based on top of the unredirect patch, so make
> sure you don't accidentally commit that with it.

Oops ... forgot to clean my tree.

> Graphically it seems to work. It's still annoyingly slow. (With my 1400x1050
> laptop screen, the shell freezes for .5s when taking the screenshot. With a
> 1920x1200 external monitor attached as well, it takes 1.5s.) It looks like
> about 1/3 of that time is cogl_read_pixels(), and 2/3 is
> cairo_surface_write_to_png(). At least the latter part could be moved to
> another thread. Not sure if we can do anything about cogl_read_pixels(). (How
> does the recorder avoid being slow?)

The recorder avoids being slow by ..... being slow. I have been testing using my nvidia system where glReadPixel does not suck like that. 

Will test on my INTEL system later but really reading a *single* frame back shouldn't take that long ... not sure about how to make it faster ... could try using PBO but not sure that would really help.

As for cairo_surface_write_to_png() yeah pushing that to a thread would definitely help (we shouldn't really do any I/O in the main thread).
Comment 21 drago01 2011-08-24 14:07:53 UTC
Comment on attachment 192508 [details] [review]
Add screenshot interface

Attachment 192508 [details] pushed as b7fd78b - Add screenshot interface


Pushed based on IRC discussion, bug is still open for the speed issues.
Comment 22 Matthias Clasen 2011-08-25 13:43:12 UTC
taking off the blocker, since the patch got committed
Comment 23 Dan Winship 2011-08-31 15:53:11 UTC
bug 653590 adds an async read_pixels API
Comment 24 Ionut Biru 2011-09-04 12:24:54 UTC
i noticed that when grabbing the whole screen the white effect is missing the fade and is ugly and i believe slower, compared with alt+print screen effect, with a fullscreen window, 1280x800
Comment 25 drago01 2011-09-04 12:41:13 UTC
(In reply to comment #24)
> i noticed that when grabbing the whole screen the white effect is missing the
> fade and is ugly and i believe slower, compared with alt+print screen effect,
> with a fullscreen window, 1280x800

Not sure what you are talking about ... nothing in this bug has anything to do with a fade effect.
Comment 26 drago01 2011-09-04 14:29:17 UTC
(In reply to comment #25)
> (In reply to comment #24)
> > i noticed that when grabbing the whole screen the white effect is missing the
> > fade and is ugly and i believe slower, compared with alt+print screen effect,
> > with a fullscreen window, 1280x800
> 
> Not sure what you are talking about ... nothing in this bug has anything to do
> with a fade effect.

Follow up on that; IRC conversation:

<ioni> drago01, in the screenshot support i mean that when print screen is used the effect has a solid white screen and with alt+printscreen the effect is with a white that is transparent and it looks like a while that fades in to white and then fades out to transparent
<ioni> but definitely print screen effect is ugly than with alt+printscreen
<ioni> or just slow and that's why is ugly?
<drago01> ioni: that has nothing to do with that bug
<drago01> ioni: that is done by gnome-screenshot
<drago01> ioni: not by the shell
<drago01> ioni: the bug is about a dbus interface to let the shell dump a screenshot to a file
<ioni> the effect is done by gnome-screenshot?
<drago01> yes
<ioni> ok
<ioni> drago01, so right now in 3.1.90 who is doing the screenshot?
<ioni> gnome-shell or gnome-screenshot?
<drago01> currently still gome-screenshot see https://bugzilla.gnome.org/show_bug.cgi?id=657330
<bebot> Bug 657330: normal, Normal, ---, gnome-utils-maint, UNCONFIRMED, use the gnome-shell api for taking screenshots when available
<ioni> ok, now i understand

And he filed a new bug 658172
Comment 27 Tobias Wolf 2011-10-23 22:03:13 UTC
What about window alpha? Semi-translucent windows, etc? What about taking area screenshot without root window?

Cf. this example. Click it, observe window borders are smooth, opacity i preserved and no root window.

http://screenshots.debian.net/package/octave3.2
Comment 28 drago01 2012-01-22 10:25:31 UTC
Created attachment 205793 [details] [review]
Screenshot: Move filesystem I/O to a thread

Writting the screenshot to a file can take a relativly long time
in which we block the compositor,so do that part in a separate thread to avoid the hang.
Comment 29 Jasper St. Pierre (not reading bugmail) 2012-01-22 10:36:55 UTC
Review of attachment 205793 [details] [review]:

Since the implementation is getting quite complicated, can we move this from ShellGlobal into a new file? I'm fine with committing this patch, and then moving it.

::: src/shell-global.c
@@ +2199,3 @@
                                                    window_rect->height);
 
+      screenshot_data->image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, window_rect->width, window_rect->height);

Keep the line wrapping the same as it was.
Comment 30 drago01 2012-01-22 10:46:17 UTC
(In reply to comment #29)
> Review of attachment 205793 [details] [review]:
> 
> Since the implementation is getting quite complicated, can we move this from
> ShellGlobal into a new file? I'm fine with committing this patch, and then
> moving it.

Yeah makes sense.

> ::: src/shell-global.c
> @@ +2199,3 @@
>                                                     window_rect->height);
> 
> +      screenshot_data->image = cairo_image_surface_create
> (CAIRO_FORMAT_ARGB32, window_rect->width, window_rect->height);
> 
> Keep the line wrapping the same as it was.

OK.
Comment 31 drago01 2012-01-22 10:48:05 UTC
Comment on attachment 205793 [details] [review]
Screenshot: Move filesystem I/O to a thread

Attachment 205793 [details] pushed as 882fe48 - Screenshot: Move filesystem I/O to a thread

Leaving the bug open for the async read pixels and moving the screenshot stuff 
into a new file.
Comment 32 drago01 2012-02-02 22:02:57 UTC
(In reply to comment #19)

> Graphically it seems to work. It's still annoyingly slow. (With my 1400x1050
> laptop screen, the shell freezes for .5s when taking the screenshot. With a
> 1920x1200 external monitor attached as well, it takes 1.5s.) It looks like
> about 1/3 of that time is cogl_read_pixels(), and 2/3 is
> cairo_surface_write_to_png().

Is it still slow for you? Now that the pixel grabbing should be faster with Owen's ScreenGrabber and the cairo_surface_write_to_png() has been moved to a  thread?
Comment 33 drago01 2012-02-14 20:26:11 UTC
Owen's patches fixed the slowdown; we have it split out of shell-global now so nothing left here.