diff --git a/src/shell-recorder.c b/src/shell-recorder.c index 9bf36e6db..c2e83412c 100644 --- a/src/shell-recorder.c +++ b/src/shell-recorder.c @@ -51,6 +51,10 @@ struct _ShellRecorder { int stage_width; int stage_height; + int capture_width; + int capture_height; + float scale; + int pointer_x; int pointer_y; @@ -430,10 +434,8 @@ recorder_record_frame (ShellRecorder *recorder, return; recorder->last_frame_time = now; - clutter_stage_capture (recorder->stage, paint, &recorder->area, - &captures, &n_captures); - - if (n_captures == 0) + if (!clutter_stage_capture (recorder->stage, paint, &recorder->area, + &captures, &n_captures)) return; if (n_captures == 1) @@ -443,8 +445,9 @@ recorder_record_frame (ShellRecorder *recorder, n_captures, recorder->area.x, recorder->area.y, - recorder->area.width, - recorder->area.height); + recorder->capture_width, + recorder->capture_height, + recorder->scale); data = cairo_image_surface_get_data (image); size = (cairo_image_surface_get_height (image) * @@ -500,6 +503,11 @@ recorder_update_size (ShellRecorder *recorder) recorder->area.y = 0; recorder->area.width = recorder->stage_width; recorder->area.height = recorder->stage_height; + + clutter_stage_get_capture_final_size (recorder->stage, NULL, + &recorder->capture_width, + &recorder->capture_height, + &recorder->scale); } } @@ -618,6 +626,8 @@ recorder_connect_stage_callbacks (ShellRecorder *recorder) G_CALLBACK (recorder_on_stage_notify_size), recorder); g_signal_connect (recorder->stage, "notify::height", G_CALLBACK (recorder_on_stage_notify_size), recorder); + g_signal_connect (recorder->stage, "notify::resource-scale", + G_CALLBACK (recorder_on_stage_notify_size), recorder); } static void @@ -875,6 +885,7 @@ shell_recorder_class_init (ShellRecorderClass *klass) static void recorder_pipeline_set_caps (RecorderPipeline *pipeline) { + ShellRecorder *recorder = pipeline->recorder; GstCaps *caps; /* The data is always native-endian xRGB; videoconvert @@ -887,9 +898,9 @@ recorder_pipeline_set_caps (RecorderPipeline *pipeline) #else "format", G_TYPE_STRING, "xRGB", #endif - "framerate", GST_TYPE_FRACTION, pipeline->recorder->framerate, 1, - "width", G_TYPE_INT, pipeline->recorder->area.width, - "height", G_TYPE_INT, pipeline->recorder->area.height, + "framerate", GST_TYPE_FRACTION, recorder->framerate, 1, + "width", G_TYPE_INT, recorder->capture_width, + "height", G_TYPE_INT, recorder->capture_height, NULL); g_object_set (pipeline->src, "caps", caps, NULL); gst_caps_unref (caps); @@ -1496,6 +1507,11 @@ shell_recorder_set_area (ShellRecorder *recorder, recorder->area.height = CLAMP (height, 0, recorder->stage_height - recorder->area.y); + clutter_stage_get_capture_final_size (recorder->stage, &recorder->area, + &recorder->capture_width, + &recorder->capture_height, + &recorder->scale); + /* This breaks the recording but tweaking the GStreamer pipeline a bit * might make it work, at least if the codec can handle a stream where * the frame size changes in the middle. diff --git a/src/shell-screenshot.c b/src/shell-screenshot.c index 4a119a153..125af823e 100644 --- a/src/shell-screenshot.c +++ b/src/shell-screenshot.c @@ -222,29 +222,32 @@ do_grab_screenshot (ShellScreenshot *screenshot, int height) { ShellScreenshotPrivate *priv = screenshot->priv; + cairo_rectangle_int_t screenshot_rect = { x, y, width, height }; ClutterCapture *captures; int n_captures; int i; - clutter_stage_capture (stage, FALSE, - &(cairo_rectangle_int_t) { - .x = x, - .y = y, - .width = width, - .height = height - }, - &captures, - &n_captures); - - if (n_captures == 0) + if (!clutter_stage_capture (stage, FALSE, + &screenshot_rect, + &captures, + &n_captures)) return; - else if (n_captures == 1) + + if (n_captures == 1) priv->image = cairo_surface_reference (captures[0].image); else - priv->image = shell_util_composite_capture_images (captures, - n_captures, - x, y, - width, height); + { + float target_scale; + + clutter_stage_get_capture_final_size (stage, &screenshot_rect, + &width, &height, &target_scale); + priv->image = shell_util_composite_capture_images (captures, + n_captures, + x, y, + width, height, + target_scale); + } + priv->datetime = g_date_time_new_now_local (); for (i = 0; i < n_captures; i++) diff --git a/src/shell-util.c b/src/shell-util.c index 95d9f8e14..88a9ce11e 100644 --- a/src/shell-util.c +++ b/src/shell-util.c @@ -462,31 +462,20 @@ shell_util_composite_capture_images (ClutterCapture *captures, int n_captures, int x, int y, - int width, - int height) + int target_width, + int target_height, + float target_scale) { int i; - double target_scale; cairo_format_t format; cairo_surface_t *image; cairo_t *cr; g_assert (n_captures > 0); - - target_scale = 0.0; - for (i = 0; i < n_captures; i++) - { - ClutterCapture *capture = &captures[i]; - double capture_scale = 1.0; - - cairo_surface_get_device_scale (capture->image, &capture_scale, NULL); - target_scale = MAX (target_scale, capture_scale); - } + g_assert (target_scale > 0.0f); format = cairo_image_surface_get_format (captures[0].image); - image = cairo_image_surface_create (format, - width * target_scale, - height * target_scale); + image = cairo_image_surface_create (format, target_width, target_height); cairo_surface_set_device_scale (image, target_scale, target_scale); cr = cairo_create (image); diff --git a/src/shell-util.h b/src/shell-util.h index 914f438d2..6904f43bc 100644 --- a/src/shell-util.h +++ b/src/shell-util.h @@ -53,8 +53,9 @@ cairo_surface_t * shell_util_composite_capture_images (ClutterCapture *captures int n_captures, int x, int y, - int width, - int height); + int target_width, + int target_height, + float target_scale); void shell_util_check_cloexec_fds (void);