diff options
author | Cosimo Cecchi <cosimoc@gnome.org> | 2019-07-24 17:28:15 +0200 |
---|---|---|
committer | Cosimo Cecchi <cosimoc@gnome.org> | 2019-07-24 20:31:39 +0200 |
commit | 3f25eb50c562d3dc267c987329e0c8ec9cca6d94 (patch) | |
tree | d8db9fb49ce473d90ce4957e8e23fd0a39650caf | |
parent | efd710e77dc726579eade140823d9774baad9c19 (diff) | |
download | gnome-screenshot-3f25eb50c562d3dc267c987329e0c8ec9cca6d94.tar.gz |
flash: update from libcheese
This fixes the flash not working at all in the X11 fallback code
path, at least in the area screenshot case.
-rw-r--r-- | src/cheese-flash.c | 233 | ||||
-rw-r--r-- | src/cheese-flash.h | 35 | ||||
-rw-r--r-- | src/screenshot-utils.c | 2 |
3 files changed, 135 insertions, 135 deletions
diff --git a/src/cheese-flash.c b/src/cheese-flash.c index e04dec0..4d2b861 100644 --- a/src/cheese-flash.c +++ b/src/cheese-flash.c @@ -19,197 +19,202 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* This is a "flash" object that you can create and invoke a method "flash" on to - * flood the screen with white temporarily */ - #include <gtk/gtk.h> #include "cheese-flash.h" -#ifdef GDK_WINDOWING_X11 -#include <X11/Xproto.h> -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#include <X11/Xatom.h> -#include <gdk/gdkx.h> -#endif /* GDK_WINDOWING_X11 */ +/** + * SECTION:cheese-flash + * @short_description: Flash the screen, like a real camera flash + * @stability: Unstable + * @include: cheese/cheese-flash.h + * + * #CheeseFlash is a window that you can create and invoke a method "flash" on + * to temporarily flood the screen with white. + */ -/* How long to hold the flash for */ -#define FLASH_DURATION 150 +/* How long to hold the flash for, in milliseconds. */ +static const guint FLASH_DURATION = 150; /* The factor which defines how much the flash fades per frame */ -#define FLASH_FADE_FACTOR 0.95 +static const gdouble FLASH_FADE_FACTOR = 0.95; /* How many frames per second */ -#define FLASH_ANIMATION_RATE 120 +static const guint FLASH_ANIMATION_RATE = 120; /* When to consider the flash finished so we can stop fading */ -#define FLASH_LOW_THRESHOLD 0.01 - -G_DEFINE_TYPE (CheeseFlash, cheese_flash, G_TYPE_OBJECT); - -#define CHEESE_FLASH_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CHEESE_TYPE_FLASH, CheeseFlashPrivate)) +static const gdouble FLASH_LOW_THRESHOLD = 0.01; +/* + * CheeseFlashPrivate: + * @flash_timeout_tag: signal ID of the timeout to start fading in the flash + * @fade_timeout_tag: signal ID of the timeout to start fading out the flash + * + * Private data for #CheeseFlash. + */ typedef struct { - GtkWindow *window; + /*< private >*/ guint flash_timeout_tag; guint fade_timeout_tag; + gdouble opacity; } CheeseFlashPrivate; -static gboolean -cheese_flash_window_draw_event_cb (GtkWidget *widget, cairo_t *cr, gpointer user_data) -{ - cairo_fill (cr); - return TRUE; -} +G_DEFINE_TYPE_WITH_PRIVATE (CheeseFlash, cheese_flash, GTK_TYPE_WINDOW) static void cheese_flash_init (CheeseFlash *self) { - CheeseFlashPrivate *priv = CHEESE_FLASH_GET_PRIVATE (self); + CheeseFlashPrivate *priv = cheese_flash_get_instance_private (self); cairo_region_t *input_region; - GtkWindow *window; - GdkScreen *screen; - GdkVisual *visual; + GtkWindow *window = GTK_WINDOW (self); + const GdkRGBA white = { 1.0, 1.0, 1.0, 1.0 }; priv->flash_timeout_tag = 0; priv->fade_timeout_tag = 0; - - window = GTK_WINDOW (gtk_window_new (GTK_WINDOW_POPUP)); + priv->opacity = 1.0; /* make it so it doesn't look like a window on the desktop (+fullscreen) */ gtk_window_set_decorated (window, FALSE); gtk_window_set_skip_taskbar_hint (window, TRUE); gtk_window_set_skip_pager_hint (window, TRUE); gtk_window_set_keep_above (window, TRUE); - gtk_window_set_type_hint (window, GDK_WINDOW_TYPE_HINT_NOTIFICATION); /* Don't take focus */ gtk_window_set_accept_focus (window, FALSE); gtk_window_set_focus_on_map (window, FALSE); - /* no shadow */ - screen = gtk_widget_get_screen (GTK_WIDGET (window)); - visual = gdk_screen_get_rgba_visual (screen); - if (visual == NULL) - visual = gdk_screen_get_system_visual (screen); - - gtk_widget_set_visual (GTK_WIDGET (window), visual); + /* Make it white */ + gtk_widget_override_background_color (GTK_WIDGET (window), GTK_STATE_NORMAL, + &white); /* Don't consume input */ gtk_widget_realize (GTK_WIDGET (window)); - input_region = cairo_region_create (); gdk_window_input_shape_combine_region (gtk_widget_get_window (GTK_WIDGET (window)), input_region, 0, 0); cairo_region_destroy (input_region); - - g_signal_connect (G_OBJECT (window), "draw", G_CALLBACK (cheese_flash_window_draw_event_cb), NULL); - priv->window = window; -} - -static void -cheese_flash_dispose (GObject *object) -{ - CheeseFlashPrivate *priv = CHEESE_FLASH_GET_PRIVATE (object); - - if (priv->window != NULL) - { - gtk_widget_destroy (GTK_WIDGET (priv->window)); - priv->window = NULL; - } - - if (G_OBJECT_CLASS (cheese_flash_parent_class)->dispose) - G_OBJECT_CLASS (cheese_flash_parent_class)->dispose (object); -} - -static void -cheese_flash_finalize (GObject *object) -{ - if (G_OBJECT_CLASS (cheese_flash_parent_class)->finalize) - G_OBJECT_CLASS (cheese_flash_parent_class)->finalize (object); } static void cheese_flash_class_init (CheeseFlashClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (CheeseFlashPrivate)); - - object_class->dispose = cheese_flash_dispose; - object_class->finalize = cheese_flash_finalize; } +/* + * cheese_flash_opacity_fade: + * @data: the #CheeseFlash + * + * Fade the flash out. + * + * Returns: %TRUE if the fade was completed, %FALSE if the flash must continue + * to fade + */ static gboolean cheese_flash_opacity_fade (gpointer data) { - CheeseFlash *flash = data; - CheeseFlashPrivate *flash_priv = CHEESE_FLASH_GET_PRIVATE (flash); - GtkWidget *flash_window = GTK_WIDGET (flash_priv->window); - double opacity = gtk_widget_get_opacity (flash_window); + CheeseFlashPrivate *priv; + GtkWidget *flash_window; - /* exponentially decrease */ - gtk_widget_set_opacity (flash_window, opacity * FLASH_FADE_FACTOR); - - if (opacity <= FLASH_LOW_THRESHOLD) - { - /* the flasher has finished when we reach the quit value */ - gtk_widget_hide (flash_window); - return FALSE; - } + flash_window = GTK_WIDGET (data); + priv = cheese_flash_get_instance_private (CHEESE_FLASH (data)); - return TRUE; + /* exponentially decrease */ + priv->opacity *= FLASH_FADE_FACTOR; + + if (priv->opacity <= FLASH_LOW_THRESHOLD) + { + /* the flasher has finished when we reach the quit value */ + priv->fade_timeout_tag = 0; + gtk_widget_destroy (flash_window); + return G_SOURCE_REMOVE; + } + else + { + gtk_widget_set_opacity (flash_window, priv->opacity); + } + + return G_SOURCE_CONTINUE; } +/* + * cheese_flash_start_fade: + * @data: the #CheeseFlash + * + * Add a timeout to start the fade animation. + * + * Returns: %FALSE + */ static gboolean cheese_flash_start_fade (gpointer data) { - CheeseFlash *self = data; - CheeseFlashPrivate *flash_priv = CHEESE_FLASH_GET_PRIVATE (self); - GtkWindow *flash_window = flash_priv->window; + CheeseFlashPrivate *priv = cheese_flash_get_instance_private (CHEESE_FLASH (data)); + GtkWindow *flash_window = GTK_WINDOW (data); - /* If the screen is non-composited, just hide and finish up */ + /* If the screen is non-composited, just destroy and finish up */ if (!gdk_screen_is_composited (gtk_window_get_screen (flash_window))) - { - gtk_widget_hide (GTK_WIDGET (flash_window)); - return FALSE; - } - - flash_priv->fade_timeout_tag = - g_timeout_add_full (G_PRIORITY_DEFAULT, - 1000.0 / FLASH_ANIMATION_RATE, - cheese_flash_opacity_fade, - g_object_ref (self), g_object_unref); - return FALSE; + { + gtk_widget_destroy (GTK_WIDGET (flash_window)); + return G_SOURCE_REMOVE; + } + + priv->fade_timeout_tag = g_timeout_add (1000.0 / FLASH_ANIMATION_RATE, cheese_flash_opacity_fade, data); + priv->flash_timeout_tag = 0; + return G_SOURCE_REMOVE; } +/** + * cheese_flash_fire: + * @flash: a #CheeseFlash + * @rect: a #GdkRectangle + * + * Fire the flash. + */ void cheese_flash_fire (CheeseFlash *flash, GdkRectangle *rect) { - CheeseFlashPrivate *flash_priv = CHEESE_FLASH_GET_PRIVATE (flash); - GtkWindow *flash_window = flash_priv->window; + CheeseFlashPrivate *priv; + GtkWindow *flash_window; + + g_return_if_fail (CHEESE_IS_FLASH (flash)); + g_return_if_fail (rect != NULL); - if (flash_priv->flash_timeout_tag > 0) - g_source_remove (flash_priv->flash_timeout_tag); - if (flash_priv->fade_timeout_tag > 0) - g_source_remove (flash_priv->fade_timeout_tag); + priv = cheese_flash_get_instance_private (flash); + flash_window = GTK_WINDOW (flash); + + if (priv->flash_timeout_tag > 0) + { + g_source_remove (priv->flash_timeout_tag); + priv->flash_timeout_tag = 0; + } + + if (priv->fade_timeout_tag > 0) + { + g_source_remove (priv->fade_timeout_tag); + priv->fade_timeout_tag = 0; + } + + priv->opacity = 1.0; gtk_window_resize (flash_window, rect->width, rect->height); gtk_window_move (flash_window, rect->x, rect->y); - gtk_widget_set_opacity (GTK_WIDGET (flash_window), 0.99); + gtk_widget_set_opacity (GTK_WIDGET (flash_window), 1); gtk_widget_show_all (GTK_WIDGET (flash_window)); - flash_priv->flash_timeout_tag = - g_timeout_add_full (G_PRIORITY_DEFAULT, - FLASH_DURATION, - cheese_flash_start_fade, - g_object_ref (flash), g_object_unref); + priv->flash_timeout_tag = g_timeout_add (FLASH_DURATION, cheese_flash_start_fade, (gpointer) flash); } +/** + * cheese_flash_new: + * + * Create a new #CheeseFlash. + * + * Returns: a new #CheeseFlash + */ CheeseFlash * cheese_flash_new (void) { - return g_object_new (CHEESE_TYPE_FLASH, NULL); + return g_object_new (CHEESE_TYPE_FLASH, + "type", GTK_WINDOW_POPUP, + NULL); } diff --git a/src/cheese-flash.h b/src/cheese-flash.h index 6248aea..9783557 100644 --- a/src/cheese-flash.h +++ b/src/cheese-flash.h @@ -17,36 +17,33 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef _CHEESE_FLASH_H_ -#define _CHEESE_FLASH_H_ +#ifndef CHEESE_FLASH_H_ +#define CHEESE_FLASH_H_ +#include <gtk/gtk.h> #include <glib-object.h> G_BEGIN_DECLS -#define CHEESE_TYPE_FLASH (cheese_flash_get_type ()) -#define CHEESE_FLASH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CHEESE_TYPE_FLASH, CheeseFlash)) -#define CHEESE_FLASH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CHEESE_TYPE_FLASH, CheeseFlashClass)) -#define CHEESE_IS_FLASH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CHEESE_TYPE_FLASH)) -#define CHEESE_IS_FLASH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CHEESE_TYPE_FLASH)) -#define CHEESE_FLASH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CHEESE_TYPE_FLASH, CheeseFlashClass)) - -typedef struct +/** + * CheeseFlash: + * + * Use the accessor functions below. + */ +struct _CheeseFlash { - GObjectClass parent_class; -} CheeseFlashClass; + /*< private >*/ + GtkWindow parent_instance; + void *unused; +}; -typedef struct -{ - GObject parent_instance; -} CheeseFlash; +#define CHEESE_TYPE_FLASH (cheese_flash_get_type ()) +G_DECLARE_FINAL_TYPE (CheeseFlash, cheese_flash, CHEESE, FLASH, GtkWindow) -GType cheese_flash_get_type (void) G_GNUC_CONST; CheeseFlash *cheese_flash_new (void); - void cheese_flash_fire (CheeseFlash *flash, GdkRectangle *rect); G_END_DECLS -#endif /* _CHEESE_FLASH_H_ */ +#endif /* CHEESE_FLASH_H_ */ diff --git a/src/screenshot-utils.c b/src/screenshot-utils.c index fc8c3eb..434b6ee 100644 --- a/src/screenshot-utils.c +++ b/src/screenshot-utils.c @@ -322,8 +322,6 @@ screenshot_fallback_fire_flash (GdkWindow *window, flash = cheese_flash_new (); cheese_flash_fire (flash, &rect); - - g_object_unref (flash); } GdkWindow * |