Skip to content

Commit ebf6f29

Browse files
committed
Include popovers and menus in window screenshots
1 parent 550d053 commit ebf6f29

File tree

1 file changed

+74
-11
lines changed

1 file changed

+74
-11
lines changed

src/ScreenshotManager.vala

Lines changed: 74 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -329,33 +329,96 @@ public class Gala.ScreenshotManager : Object {
329329
throw new DBusError.FAILED ("Cannot find active window");
330330
}
331331

332-
var window_actor = (Meta.WindowActor) window.get_compositor_private ();
332+
Meta.Window[] transients = {};
333+
window.foreach_transient ((transient) => {
334+
if (transient.window_type == MENU ||
335+
transient.window_type == DROPDOWN_MENU ||
336+
transient.window_type == POPUP_MENU ||
337+
transient.window_type == TOOLTIP ||
338+
transient.window_type == OVERRIDE_OTHER
339+
) {
340+
transients += transient;
341+
}
342+
343+
return true;
344+
});
345+
346+
var main_rect = include_frame ? window.get_buffer_rect () : window.get_frame_rect ();
347+
var full_rect = main_rect;
348+
foreach (unowned var transient in transients) {
349+
var transient_rect = include_frame ? transient.get_buffer_rect () : transient.get_frame_rect ();
333350

334-
var rect = window.get_buffer_rect ();
335-
if (!include_frame) {
336-
rect = window.get_frame_rect ();
351+
var previous_x2 = full_rect.x + full_rect.width;
352+
var previous_y2 = full_rect.y + full_rect.height;
353+
354+
var transient_x2 = transient_rect.x + transient_rect.width;
355+
var transient_y2 = transient_rect.y + transient_rect.height;
356+
357+
var new_x2 = int.max (previous_x2, transient_x2);
358+
var new_y2 = int.max (previous_y2, transient_y2);
359+
360+
full_rect.x = int.min (full_rect.x, transient_rect.x);
361+
full_rect.y = int.min (full_rect.y, transient_rect.y);
362+
full_rect.width = new_x2 - full_rect.x;
363+
full_rect.height = new_y2 - full_rect.y;
364+
}
365+
366+
unowned var window_actor = (Meta.WindowActor) window.get_compositor_private ();
367+
var resource_scale = window_actor.get_resource_scale ();
368+
369+
Mtk.Rectangle main_clip = { main_rect.x - (int) window_actor.x, main_rect.y - (int) window_actor.y, main_rect.width, main_rect.height };
370+
var window_image = (Cairo.ImageSurface) window_actor.get_image (main_clip);
371+
372+
var image = new Cairo.ImageSurface (
373+
ARGB32,
374+
Utils.scale_to_int (main_rect.width, resource_scale),
375+
Utils.scale_to_int (main_rect.height, resource_scale)
376+
);
377+
378+
var cairo_context = new Cairo.Context (image);
379+
cairo_context.set_operator (OVER);
380+
cairo_context.set_source_surface (
381+
window_image,
382+
Utils.scale_to_int (main_rect.x - full_rect.x, resource_scale),
383+
Utils.scale_to_int (main_rect.y - full_rect.y, resource_scale)
384+
);
385+
cairo_context.paint ();
386+
387+
foreach (unowned var transient in transients) {
388+
var transient_rect = include_frame ? transient.get_buffer_rect () : transient.get_frame_rect ();
389+
unowned var transient_actor = (Meta.WindowActor) transient.get_compositor_private ();
390+
Mtk.Rectangle transient_clip = {
391+
transient_rect.x - (int) transient_actor.x,
392+
transient_rect.y - (int) transient_actor.y,
393+
transient_rect.width,
394+
transient_rect.height
395+
};
396+
var transient_image = (Cairo.ImageSurface) transient_actor.get_image (transient_clip);
397+
398+
cairo_context.set_source_surface (
399+
transient_image,
400+
Utils.scale_to_int (transient_rect.x - full_rect.x, resource_scale),
401+
Utils.scale_to_int (transient_rect.y - full_rect.y, resource_scale)
402+
);
403+
cairo_context.paint ();
337404
}
338405

339-
Mtk.Rectangle clip = { rect.x - (int) window_actor.x, rect.y - (int) window_actor.y, rect.width, rect.height };
340-
var image = (Cairo.ImageSurface) window_actor.get_image (clip);
341406
if (include_cursor) {
342407
if (window.get_client_type () == Meta.WindowClientType.WAYLAND) {
343-
float resource_scale = window_actor.get_resource_scale ();
344-
345408
image.set_device_scale (resource_scale, resource_scale);
346409
}
347410

348-
image = composite_stage_cursor (image, { rect.x, rect.y, rect.width, rect.height });
411+
image = composite_stage_cursor (image, { full_rect.x, full_rect.y, full_rect.width, full_rect.height });
349412
}
350413

351414
unconceal_text ();
352415

353416
if (flash) {
354-
flash_area (rect.x, rect.y, rect.width, rect.height);
417+
flash_area (full_rect.x, full_rect.y, full_rect.width, full_rect.height);
355418
}
356419

357420
unowned var display = wm.get_display ();
358-
var scale = display.get_monitor_scale (display.get_monitor_index_for_rect (rect));
421+
var scale = display.get_monitor_scale (display.get_monitor_index_for_rect (full_rect));
359422

360423
success = yield save_image (image, filename, scale, out filename_used);
361424

0 commit comments

Comments
 (0)