Merge lp:~santileortiz/gala/fix-print-screen into lp:gala

Proposed by Santiago
Status: Rejected
Rejected by: Rico Tzschichholz
Proposed branch: lp:~santileortiz/gala/fix-print-screen
Merge into: lp:gala
Diff against target: 286 lines (+197/-16)
6 files modified
src/DBus.vala (+10/-0)
src/DBusAccelerator.vala (+7/-16)
src/Makefile.am (+2/-0)
src/ScreenshotManager.vala (+153/-0)
vapi/Makefile.am (+1/-0)
vapi/temp_compat.vapi (+24/-0)
To merge this branch: bzr merge lp:~santileortiz/gala/fix-print-screen
Reviewer Review Type Date Requested Status
Rico Tzschichholz Disapprove
Review via email: mp+313452@code.launchpad.net

Description of the change

This implements part of the interface gnome-settings-daemon uses to take screenshots by using shortcuts (or the Print Screen key). It implements window screenshots and full screen screenshots.

To post a comment you must log in.
Revision history for this message
Rico Tzschichholz (ricotz) wrote :
review: Disapprove

Unmerged revisions

548. By Santiago

Fixing print screen key

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/DBus.vala'
2--- src/DBus.vala 2015-11-11 19:56:40 +0000
3+++ src/DBus.vala 2016-12-16 17:54:34 +0000
4@@ -39,6 +39,16 @@
5 },
6 () => {},
7 () => warning ("Could not acquire name\n") );
8+
9+ Bus.own_name (BusType.SESSION, "org.gnome.Shell", BusNameOwnerFlags.NONE,
10+ (connection) => {
11+ try {
12+ connection.register_object ("/org/gnome/Shell", DBusAccelerator.init (wm));
13+ connection.register_object ("/org/gnome/Shell/Screenshot", ScreenshotManager.init (wm));
14+ } catch (Error e) { warning (e.message); }
15+ },
16+ () => {},
17+ () => critical ("Could not acquire name") );
18 }
19
20 private DBus ()
21
22=== modified file 'src/DBusAccelerator.vala'
23--- src/DBusAccelerator.vala 2016-08-03 11:14:55 +0000
24+++ src/DBusAccelerator.vala 2016-12-16 17:54:34 +0000
25@@ -27,24 +27,13 @@
26 public class DBusAccelerator
27 {
28 static DBusAccelerator? instance;
29- static WindowManager wm;
30
31 [DBus (visible = false)]
32- public static void init (WindowManager _wm)
33+ public static unowned DBusAccelerator init (WindowManager _wm)
34 {
35- wm = _wm;
36-
37- Bus.own_name (BusType.SESSION, "org.gnome.Shell", BusNameOwnerFlags.NONE,
38- (connection) => {
39- if (instance == null)
40- instance = new DBusAccelerator ();
41-
42- try {
43- connection.register_object ("/org/gnome/Shell", instance);
44- } catch (Error e) { warning (e.message); }
45- },
46- () => {},
47- () => critical ("Could not acquire name") );
48+ if (instance == null)
49+ instance = new DBusAccelerator (wm);
50+ return instance;
51 }
52
53 #if HAS_GSD316
54@@ -53,10 +42,12 @@
55 public signal void accelerator_activated (uint action, uint device_id, uint timestamp);
56 #endif
57
58+ static WindowManager wm;
59 HashTable<string, uint?> grabbed_accelerators;
60
61- DBusAccelerator ()
62+ DBusAccelerator (WindowManager _wm)
63 {
64+ wm = _wm;
65 grabbed_accelerators = new HashTable<string, uint> (str_hash, str_equal);
66
67 wm.get_screen ().get_display ().accelerator_activated.connect (on_accelerator_activated);
68
69=== modified file 'src/Makefile.am'
70--- src/Makefile.am 2016-08-03 11:14:55 +0000
71+++ src/Makefile.am 2016-12-16 17:54:34 +0000
72@@ -8,6 +8,7 @@
73 --vapidir $(VAPIDIR) \
74 $(VAPIDIR)/config.vapi \
75 $(VAPIDIR)/cogl-fixes.vapi \
76+ $(VAPIDIR)/temp_compat.vapi \
77 $(NULL)
78
79 galadir = $(bindir)
80@@ -41,6 +42,7 @@
81 MediaFeedback.vala \
82 PluginManager.vala \
83 ScreenSaver.vala \
84+ ScreenshotManager.vala \
85 Settings.vala \
86 ShadowEffect.vala \
87 TextShadowEffect.vala \
88
89=== added file 'src/ScreenshotManager.vala'
90--- src/ScreenshotManager.vala 1970-01-01 00:00:00 +0000
91+++ src/ScreenshotManager.vala 2016-12-16 17:54:34 +0000
92@@ -0,0 +1,153 @@
93+//
94+// Copyright (C) 2016 Rico Tzschichholz, Santiago León O.
95+//
96+// This program is free software: you can redistribute it and/or modify
97+// it under the terms of the GNU General Public License as published by
98+// the Free Software Foundation, either version 3 of the License, or
99+// (at your option) any later version.
100+//
101+// This program is distributed in the hope that it will be useful,
102+// but WITHOUT ANY WARRANTY; without even the implied warranty of
103+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
104+// GNU General Public License for more details.
105+//
106+// You should have received a copy of the GNU General Public License
107+// along with this program. If not, see <http://www.gnu.org/licenses/>.
108+//
109+
110+namespace Gala
111+{
112+ [DBus (name="org.gnome.Shell.Screenshot")]
113+ public class ScreenshotManager : GLib.Object
114+ {
115+ static ScreenshotManager? instance;
116+
117+ [DBus (visible = false)]
118+ public static unowned ScreenshotManager init (WindowManager wm)
119+ {
120+ if (instance == null)
121+ instance = new ScreenshotManager (wm);
122+
123+ return instance;
124+ }
125+
126+ WindowManager wm;
127+
128+ ScreenshotManager (WindowManager _wm)
129+ {
130+ wm = _wm;
131+ }
132+
133+ [DBus (visible = false)]
134+ public static bool save_image (Cairo.ImageSurface image, string filename, out string used_filename)
135+ {
136+ used_filename = filename;
137+
138+ if (!Path.is_absolute (filename)) {
139+ string path = Environment.get_user_special_dir (UserDirectory.PICTURES);
140+ if (! FileUtils.test (path, FileTest.EXISTS)) {
141+ path = Environment.get_home_dir ();
142+ }
143+
144+ if (filename.rstr (".png") == null) {
145+ used_filename = filename.concat (".png");
146+ }
147+
148+ used_filename = Path.build_filename (path, used_filename, null);
149+ }
150+
151+ var screenshot = Gdk.pixbuf_get_from_surface (image, 0, 0, image.get_width (), image.get_height ());
152+ try {
153+ screenshot.save (used_filename, "png");
154+ return true;
155+ } catch (GLib.Error e) {
156+ return false;
157+ }
158+ }
159+
160+ [DBus (visible = false)]
161+ static Cairo.ImageSurface take_screenshot (int x, int y, int width, int height)
162+ {
163+ var backend = Clutter.get_default_backend ();
164+ var context = Clutter.backend_get_cogl_context (backend);
165+
166+ var image = new Cairo.ImageSurface (Cairo.Format.ARGB32, width, height);
167+ unowned uchar[] data = image.get_data ();
168+ int stride = image.get_stride ();
169+
170+ var bitmap = Cogl.bitmap_new_for_data (context, width, height,
171+ Cogl.PixelFormat.BGRA_8888_PRE, stride, data);
172+
173+ Cogl.framebuffer_read_pixels_into_bitmap (Cogl.get_draw_framebuffer (),
174+ x, y, Cogl.ReadPixelsFlags.BUFFER, bitmap );
175+
176+ image.mark_dirty ();
177+ return image;
178+ }
179+
180+ public void flash_area (int x, int y, int width, int height)
181+ {
182+ warning ("Flash area not implemented\n");
183+ }
184+
185+ public void screenshot (bool include_cursor, bool flash, string filename, out bool success, out string filename_used)
186+ {
187+ filename_used = "";
188+ success = false;
189+
190+ int width;
191+ int height;
192+ Meta.Screen screen = instance.wm.get_screen ();
193+ screen.get_size (out width, out height);
194+
195+ var image = take_screenshot (0, 0, width, height);
196+
197+ success = save_image (image, filename, out filename_used);
198+
199+ debug ("Taking screenshot\n");
200+ }
201+
202+ public async void screenshot_area (int x, int y, int width, int height, bool flash, string filename, out bool success, out string filename_used)
203+ {
204+ filename_used = "";
205+ success = false;
206+ warning ("Area screenshot not implemented\n");
207+ }
208+
209+ public void screenshot_window (bool include_frame, bool include_cursor, bool flash, string filename, out bool success, out string filename_used)
210+ {
211+ filename_used = "";
212+ success = false;
213+
214+ var display = instance.wm.get_screen ().get_display ();
215+ var window = display.get_focus_window ();
216+ Meta.WindowActor window_actor = (Meta.WindowActor)window.get_compositor_private ();
217+ Meta.ShapedTexture stex = (Meta.ShapedTexture)window_actor.get_texture ();
218+
219+ float actor_x, actor_y;
220+ window_actor.get_position (out actor_x, out actor_y);
221+
222+ var rect = window.get_frame_rect ();
223+ if (include_frame) {
224+ rect = window.frame_rect_to_client_rect (rect);
225+ }
226+
227+ Cairo.RectangleInt clip = Cairo.RectangleInt ();
228+ clip.x = rect.x - (int)actor_x;
229+ clip.y = rect.y - (int)actor_y;
230+ clip.width = rect.width;
231+ clip.height = rect.height;
232+
233+ Cairo.ImageSurface image = (Cairo.ImageSurface)stex.get_image (clip);
234+ success = save_image (image, filename, out filename_used);
235+
236+ debug ("Taking window screenshot\n");
237+ }
238+
239+ public async void select_area (out int x, out int y, out int width, out int height)
240+ {
241+ x = 0; y = 0; width = 0; height = 0;
242+ warning ("Select area not implemented\n");
243+ }
244+ }
245+}
246
247=== modified file 'vapi/Makefile.am'
248--- vapi/Makefile.am 2016-11-14 14:38:40 +0000
249+++ vapi/Makefile.am 2016-12-16 17:54:34 +0000
250@@ -7,6 +7,7 @@
251 libmutter.vapi \
252 mutter-clutter-1.0.vapi \
253 mutter-cogl-1.0.vapi \
254+ temp_compat.vapi \
255 xfixes-4.0.vapi \
256 $(NULL)
257
258
259=== added file 'vapi/temp_compat.vapi'
260--- vapi/temp_compat.vapi 1970-01-01 00:00:00 +0000
261+++ vapi/temp_compat.vapi 2016-12-16 17:54:34 +0000
262@@ -0,0 +1,24 @@
263+[CCode (cheader_filename = "clutter/clutter.h")]
264+namespace Cogl
265+{
266+ [CCode (cname = "CoglContext", free_function = "")]
267+ [Compact]
268+ public class Context{}
269+
270+ [CCode (cname = "cogl_bitmap_new_for_data")]
271+ public static Cogl.Bitmap bitmap_new_for_data (Cogl.Context Context, int width, int height,
272+ Cogl.PixelFormat format, int rowstride, [CCode (array_length = false)] uchar[] data);
273+
274+ [CCode (cname = "cogl_get_draw_framebuffer")]
275+ public static unowned Cogl.Framebuffer get_draw_framebuffer ();
276+
277+ [CCode (cname = "cogl_framebuffer_read_pixels_into_bitmap")]
278+ public static void framebuffer_read_pixels_into_bitmap (Cogl.Framebuffer framebuffer, int x, int y,
279+ Cogl.ReadPixelsFlags source, Cogl.Bitmap bitmap);
280+}
281+
282+namespace Clutter
283+{
284+ [CCode (cname = "clutter_backend_get_cogl_context")]
285+ public static Cogl.Context backend_get_cogl_context (Clutter.Backend backend);
286+}

Subscribers

People subscribed via source and target branches