[gnome-utils] screenshot: add a workaround to avoid capturing the selection window



commit 745eea03a3092fa055f76132971e3dd2bb4e8737
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Wed Mar 9 12:01:47 2011 -0500

    screenshot: add a workaround to avoid capturing the selection window
    
    We should have a way to know when the compositor has finished redrawing,
    so that we do not capture the area selection window, but there doesn't
    seem to be an easy way to do that. Workaround it with a FIXME for now.

 gnome-screenshot/gnome-screenshot.c |   61 ++++++++++++++++++-----------------
 gnome-screenshot/screenshot-utils.c |   45 +++++++++++++++++++-------
 gnome-screenshot/screenshot-utils.h |    7 ++--
 3 files changed, 67 insertions(+), 46 deletions(-)
---
diff --git a/gnome-screenshot/gnome-screenshot.c b/gnome-screenshot/gnome-screenshot.c
index f7a6d5f..a3a6ecc 100644
--- a/gnome-screenshot/gnome-screenshot.c
+++ b/gnome-screenshot/gnome-screenshot.c
@@ -858,7 +858,10 @@ async_existence_job_free (AsyncExistenceJob *job)
 
   g_free (job->base_uris[1]);
   g_free (job->base_uris[2]);
-  g_free (job->rectangle);
+
+  if (job->rectangle != NULL)
+    g_slice_free (GdkRectangle, job->rectangle);
+
   g_slice_free (AsyncExistenceJob, job);
 }
 
@@ -1048,35 +1051,11 @@ find_current_window (char **window_title)
   return window;
 }
 
-static GdkRectangle *
-find_rectangle (void)
-{
-  GdkRectangle *rectangle;
-
-  if (!take_area_shot)
-    return NULL;
-
-  rectangle = g_new0 (GdkRectangle, 1);
-  if (screenshot_select_area (&rectangle->x, &rectangle->y,
-                              &rectangle->width, &rectangle->height))
-    {
-      g_assert (rectangle->width >= 0);
-      g_assert (rectangle->height >= 0);
-
-      return rectangle;
-    }
-  else
-    {
-      g_free (rectangle);
-      return NULL;
-    }
-}
-
 static void
-prepare_screenshot (void)
-{
+push_check_file_job (GdkRectangle *rectangle)
+{ 
   AsyncExistenceJob *job;
-  
+
   job = g_slice_new0 (AsyncExistenceJob);
   job->base_uris[0] = last_save_dir;
   /* we'll have to free these two */
@@ -1085,7 +1064,15 @@ prepare_screenshot (void)
   job->iteration = 0;
   job->type = TEST_LAST_DIR;
   job->window = find_current_window (&window_title);
-  job->rectangle = find_rectangle ();
+
+  if (rectangle != NULL)
+    {
+      job->rectangle = g_slice_new0 (GdkRectangle);
+      job->rectangle->x = rectangle->x;
+      job->rectangle->y = rectangle->y;
+      job->rectangle->width = rectangle->width;
+      job->rectangle->height = rectangle->height;
+    }
 
   /* Check if the area selection was cancelled */
   if (job->rectangle &&
@@ -1100,7 +1087,21 @@ prepare_screenshot (void)
                            job,
                            NULL,
                            0, NULL);
-                           
+}
+
+static void
+rectangle_found_cb (GdkRectangle *rectangle)
+{
+  push_check_file_job (rectangle);
+}
+
+static void
+prepare_screenshot (void)
+{
+  if (take_area_shot)
+    screenshot_select_area_async (rectangle_found_cb);
+  else
+    push_check_file_job (NULL);
 }
 
 static gboolean
diff --git a/gnome-screenshot/screenshot-utils.c b/gnome-screenshot/screenshot-utils.c
index 2e44ad4..f54d43a 100644
--- a/gnome-screenshot/screenshot-utils.c
+++ b/gnome-screenshot/screenshot-utils.c
@@ -427,14 +427,30 @@ create_select_window (void)
   return window;
 }
 
-gboolean
-screenshot_select_area (int *px,
-                        int *py,
-                        int *pwidth,
-                        int *pheight)
+typedef struct {
+  GdkRectangle rectangle;
+  SelectAreaCallback callback;
+} CallbackData;
+
+static gboolean
+emit_select_callback_in_idle (gpointer user_data)
+{
+  CallbackData *data = user_data;
+
+  data->callback (&data->rectangle);
+
+  g_slice_free (CallbackData, data);
+
+  return FALSE;
+}
+
+void
+screenshot_select_area_async (SelectAreaCallback callback)
 {
   GdkCursor               *cursor;
   select_area_filter_data  data;
+  GdkRectangle *rectangle;
+  CallbackData *cb_data;
 
   data.rect.x = 0;
   data.rect.y = 0;
@@ -443,6 +459,9 @@ screenshot_select_area (int *px,
   data.button_pressed = FALSE;
   data.window = create_select_window();
 
+  cb_data = g_slice_new0 (CallbackData);
+  cb_data->callback = callback;
+
   g_signal_connect (data.window, "key-press-event", G_CALLBACK (select_area_key_press), &data);
   g_signal_connect (data.window, "button-press-event", G_CALLBACK (select_area_button_press), &data);
   g_signal_connect (data.window, "button-release-event", G_CALLBACK (select_area_button_release), &data);
@@ -456,14 +475,14 @@ screenshot_select_area (int *px,
                         GDK_CURRENT_TIME) != GDK_GRAB_SUCCESS)
     {
       gdk_cursor_unref (cursor);
-      return FALSE;
+      goto out;
     }
 
   if (gdk_keyboard_grab (gtk_widget_get_window (data.window), FALSE, GDK_CURRENT_TIME) != GDK_GRAB_SUCCESS)
     {
       gdk_pointer_ungrab (GDK_CURRENT_TIME);
       gdk_cursor_unref (cursor);
-      return FALSE;
+      goto out;
     }
 
   gtk_main ();
@@ -476,12 +495,14 @@ screenshot_select_area (int *px,
 
   gdk_flush ();
 
-  *px = data.rect.x;
-  *py = data.rect.y;
-  *pwidth  = data.rect.width;
-  *pheight = data.rect.height;
+ out:
+  cb_data->rectangle = data.rect;
 
-  return TRUE;
+  /* FIXME: we should actually be emitting the callback When
+   * the compositor has finished re-drawing, but there seems to be no easy
+   * way to know that.
+   */
+  g_timeout_add (200, emit_select_callback_in_idle, cb_data);
 }
 
 static Window
diff --git a/gnome-screenshot/screenshot-utils.h b/gnome-screenshot/screenshot-utils.h
index 97ca4f0..f9024cb 100644
--- a/gnome-screenshot/screenshot-utils.h
+++ b/gnome-screenshot/screenshot-utils.h
@@ -25,14 +25,13 @@
 
 G_BEGIN_DECLS
 
+typedef void (* SelectAreaCallback) (GdkRectangle *rectangle);
+
 gboolean   screenshot_grab_lock           (void);
 void       screenshot_release_lock        (void);
 gchar     *screenshot_get_window_title    (GdkWindow *win);
 GdkWindow *screenshot_find_current_window (void);
-gboolean   screenshot_select_area         (int *px,
-                                           int *py,
-                                           int *pwidth,
-                                           int *pheight);
+void       screenshot_select_area_async   (SelectAreaCallback callback);
 GdkPixbuf *screenshot_get_pixbuf          (GdkWindow *win,
                                            GdkRectangle *rectangle,
                                            gboolean include_pointer,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]