screenshot: Grab screenshot during paint on X11 for area type too

Turns out that shell_screenshot_screenshot_area was affected
by the same issue that shell_screenshot_screenshot used to have.
Adapting code changes from commit id c09be8b0:
"screenshot: Grab screenshot during paint on X11" fixes it.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1549>
This commit is contained in:
LuK1337 2020-12-26 11:57:24 +01:00 committed by Marge Bot
parent c401759c1a
commit 1989a2f9f9

View File

@ -18,6 +18,13 @@ typedef enum _ShellScreenshotFlag
SHELL_SCREENSHOT_FLAG_INCLUDE_CURSOR, SHELL_SCREENSHOT_FLAG_INCLUDE_CURSOR,
} ShellScreenshotFlag; } ShellScreenshotFlag;
typedef enum _ShellScreenshotMode
{
SHELL_SCREENSHOT_SCREEN,
SHELL_SCREENSHOT_WINDOW,
SHELL_SCREENSHOT_AREA,
} ShellScreenshotMode;
typedef struct _ShellScreenshotPrivate ShellScreenshotPrivate; typedef struct _ShellScreenshotPrivate ShellScreenshotPrivate;
struct _ShellScreenshot struct _ShellScreenshot
@ -33,6 +40,7 @@ struct _ShellScreenshotPrivate
GOutputStream *stream; GOutputStream *stream;
ShellScreenshotFlag flags; ShellScreenshotFlag flags;
ShellScreenshotMode mode;
GDateTime *datetime; GDateTime *datetime;
@ -42,13 +50,6 @@ struct _ShellScreenshotPrivate
gboolean include_frame; gboolean include_frame;
}; };
typedef enum
{
SHELL_SCREENSHOT_SCREEN,
SHELL_SCREENSHOT_WINDOW,
SHELL_SCREENSHOT_AREA,
} ShellScreenshotMode;
G_DEFINE_TYPE_WITH_PRIVATE (ShellScreenshot, shell_screenshot, G_TYPE_OBJECT); G_DEFINE_TYPE_WITH_PRIVATE (ShellScreenshot, shell_screenshot, G_TYPE_OBJECT);
static void static void
@ -350,10 +351,26 @@ on_after_paint (ClutterStage *stage,
ShellScreenshot *screenshot = g_task_get_task_data (result); ShellScreenshot *screenshot = g_task_get_task_data (result);
ShellScreenshotPrivate *priv = screenshot->priv; ShellScreenshotPrivate *priv = screenshot->priv;
MetaDisplay *display = shell_global_get_display (priv->global); MetaDisplay *display = shell_global_get_display (priv->global);
GTask *task;
g_signal_handlers_disconnect_by_func (stage, on_after_paint, result); g_signal_handlers_disconnect_by_func (stage, on_after_paint, result);
grab_screenshot (screenshot, priv->flags, result); if (priv->mode == SHELL_SCREENSHOT_AREA)
{
do_grab_screenshot (screenshot,
priv->screenshot_area.x,
priv->screenshot_area.y,
priv->screenshot_area.width,
priv->screenshot_area.height,
priv->flags);
task = g_task_new (screenshot, NULL, on_screenshot_written, result);
g_task_run_in_thread (task, write_screenshot_thread);
}
else
{
grab_screenshot (screenshot, priv->flags, result);
}
meta_enable_unredirect_for_display (display); meta_enable_unredirect_for_display (display);
} }
@ -422,6 +439,7 @@ shell_screenshot_screenshot (ShellScreenshot *screenshot,
meta_disable_unredirect_for_display (display); meta_disable_unredirect_for_display (display);
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage)); clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
priv->flags = flags; priv->flags = flags;
priv->mode = SHELL_SCREENSHOT_SCREEN;
g_signal_connect (stage, "after-paint", g_signal_connect (stage, "after-paint",
G_CALLBACK (on_after_paint), result); G_CALLBACK (on_after_paint), result);
} }
@ -504,6 +522,7 @@ shell_screenshot_screenshot_area (ShellScreenshot *screenshot,
result = g_task_new (screenshot, NULL, callback, user_data); result = g_task_new (screenshot, NULL, callback, user_data);
g_task_set_source_tag (result, shell_screenshot_screenshot_area); g_task_set_source_tag (result, shell_screenshot_screenshot_area);
g_task_set_task_data (result, screenshot, NULL);
priv->stream = g_object_ref (stream); priv->stream = g_object_ref (stream);
priv->screenshot_area.x = x; priv->screenshot_area.x = x;
@ -511,15 +530,31 @@ shell_screenshot_screenshot_area (ShellScreenshot *screenshot,
priv->screenshot_area.width = width; priv->screenshot_area.width = width;
priv->screenshot_area.height = height; priv->screenshot_area.height = height;
do_grab_screenshot (screenshot,
priv->screenshot_area.x,
priv->screenshot_area.y,
priv->screenshot_area.width,
priv->screenshot_area.height,
SHELL_SCREENSHOT_FLAG_NONE);
task = g_task_new (screenshot, NULL, on_screenshot_written, result); if (meta_is_wayland_compositor ())
g_task_run_in_thread (task, write_screenshot_thread); {
do_grab_screenshot (screenshot,
priv->screenshot_area.x,
priv->screenshot_area.y,
priv->screenshot_area.width,
priv->screenshot_area.height,
SHELL_SCREENSHOT_FLAG_NONE);
task = g_task_new (screenshot, NULL, on_screenshot_written, result);
g_task_run_in_thread (task, write_screenshot_thread);
}
else
{
MetaDisplay *display = shell_global_get_display (priv->global);
ClutterStage *stage = shell_global_get_stage (priv->global);
meta_disable_unredirect_for_display (display);
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
priv->flags = SHELL_SCREENSHOT_FLAG_NONE;
priv->mode = SHELL_SCREENSHOT_AREA;
g_signal_connect (stage, "after-paint",
G_CALLBACK (on_after_paint), result);
}
} }
/** /**