[cheese] Make the flash window a popup



commit 272eb3fde8ddbeba908d319df4631ddbd7c2fc5f
Author: Bastien Nocera <hadess hadess net>
Date:   Thu Dec 3 19:41:34 2009 +0000

    Make the flash window a popup
    
    To fix problems with some window managers.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=598902

 libcheese/cheese-avatar-chooser.c |    2 +-
 libcheese/cheese-flash.c          |   72 +++++++++++++++++++++++++++++++++---
 libcheese/cheese-flash.h          |    2 +-
 src/cheese-window.c               |    3 +-
 4 files changed, 70 insertions(+), 9 deletions(-)
---
diff --git a/libcheese/cheese-avatar-chooser.c b/libcheese/cheese-avatar-chooser.c
index ca590aa..ecc0c3b 100644
--- a/libcheese/cheese-avatar-chooser.c
+++ b/libcheese/cheese-avatar-chooser.c
@@ -203,7 +203,7 @@ cheese_avatar_chooser_init (CheeseAvatarChooser *chooser)
 {
   CheeseAvatarChooserPrivate *priv = CHEESE_AVATAR_CHOOSER_GET_PRIVATE (chooser);
 
-  priv->flash = cheese_flash_new ();
+  priv->flash = cheese_flash_new (GTK_WIDGET (chooser));
 
   gtk_dialog_add_buttons (GTK_DIALOG (chooser),
 			  GTK_STOCK_CANCEL,
diff --git a/libcheese/cheese-flash.c b/libcheese/cheese-flash.c
index 90c66c8..60acf72 100644
--- a/libcheese/cheese-flash.c
+++ b/libcheese/cheese-flash.c
@@ -27,6 +27,12 @@
 #include <cheese-camera.h>
 #include "cheese-flash.h"
 
+enum
+{
+  PROP_0,
+  PROP_PARENT
+};
+
 /* How long to hold the flash for */
 #define FLASH_DURATION 250
 
@@ -45,6 +51,7 @@ G_DEFINE_TYPE (CheeseFlash, cheese_flash, G_TYPE_OBJECT);
 
 typedef struct
 {
+  GtkWidget *parent;
   GtkWindow *window;
   guint flash_timeout_tag;
   guint fade_timeout_tag;
@@ -74,13 +81,12 @@ cheese_flash_init (CheeseFlash *self)
   priv->flash_timeout_tag = 0;
   priv->fade_timeout_tag  = 0;
 
-  window = GTK_WINDOW (gtk_window_new (GTK_WINDOW_TOPLEVEL));
+  window = GTK_WINDOW (gtk_window_new (GTK_WINDOW_POPUP));
 
   /* 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_fullscreen (window);
   gtk_window_set_keep_above (window, TRUE);
 
   /* Don't take focus */
@@ -107,6 +113,10 @@ cheese_flash_dispose (GObject *object)
     gtk_widget_destroy (GTK_WIDGET (priv->window));
     priv->window = NULL;
   }
+  if (priv->parent != NULL) {
+    g_object_unref (priv->parent);
+    priv->parent = NULL;
+  }
 
   if (G_OBJECT_CLASS (cheese_flash_parent_class)->dispose)
     G_OBJECT_CLASS (cheese_flash_parent_class)->dispose (object);
@@ -120,14 +130,47 @@ cheese_flash_finalize (GObject *object)
 }
 
 static void
+cheese_flash_set_property (GObject *object,
+			   guint prop_id,
+			   const GValue *value,
+			   GParamSpec *pspec)
+{
+  CheeseFlashPrivate *priv = CHEESE_FLASH_GET_PRIVATE (object);
+
+  switch (prop_id)
+  {
+    case PROP_PARENT: {
+      GObject *object;
+      object = g_value_get_object (value);
+      if (object != NULL)
+        priv->parent = g_object_ref (object);
+      else
+        priv->parent = NULL;
+      }
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+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;
+  object_class->set_property = cheese_flash_set_property;
+  object_class->dispose      = cheese_flash_dispose;
+  object_class->finalize     = cheese_flash_finalize;
+
+  g_object_class_install_property (object_class, PROP_PARENT,
+				   g_param_spec_object ("parent",
+							NULL,
+							NULL,
+							GTK_TYPE_WIDGET,
+							G_PARAM_WRITABLE));
 }
 
 static gboolean
@@ -173,6 +216,12 @@ void
 cheese_flash_fire (CheeseFlash *flash)
 {
   CheeseFlashPrivate *flash_priv = CHEESE_FLASH_GET_PRIVATE (flash);
+  GtkWidget *parent;
+  GdkScreen *screen;
+  GdkRectangle rect;
+  int monitor;
+
+  g_return_if_fail (flash_priv->parent != NULL);
 
   GtkWindow *flash_window = flash_priv->window;
 
@@ -181,13 +230,24 @@ cheese_flash_fire (CheeseFlash *flash)
   if (flash_priv->fade_timeout_tag > 0)
     g_source_remove (flash_priv->fade_timeout_tag);
 
+  parent = gtk_widget_get_toplevel (flash_priv->parent);
+  screen = gtk_widget_get_screen (parent);
+  monitor = gdk_screen_get_monitor_at_window (screen,
+					      gtk_widget_get_window (parent));
+  gdk_screen_get_monitor_geometry (screen, monitor, &rect);
+  gtk_window_set_transient_for (GTK_WINDOW (flash_window), GTK_WINDOW (parent));
+  gtk_window_resize (flash_window, rect.width, rect.height);
+  gtk_window_move (flash_window, rect.x, rect.y);
+
   gtk_window_set_opacity (flash_window, 1);
   gtk_widget_show_all (GTK_WIDGET (flash_window));
   flash_priv->flash_timeout_tag = g_timeout_add (FLASH_DURATION, cheese_flash_start_fade, (gpointer) flash);
 }
 
 CheeseFlash *
-cheese_flash_new (void)
+cheese_flash_new (GtkWidget *parent)
 {
-  return g_object_new (CHEESE_TYPE_FLASH, NULL);
+  return g_object_new (CHEESE_TYPE_FLASH,
+		       "parent", parent,
+		       NULL);
 }
diff --git a/libcheese/cheese-flash.h b/libcheese/cheese-flash.h
index 0ac0033..3571729 100644
--- a/libcheese/cheese-flash.h
+++ b/libcheese/cheese-flash.h
@@ -42,7 +42,7 @@ typedef struct
 } CheeseFlash;
 
 GType        cheese_flash_get_type (void) G_GNUC_CONST;
-CheeseFlash *cheese_flash_new (void);
+CheeseFlash *cheese_flash_new (GtkWidget *parent);
 
 void cheese_flash_fire (CheeseFlash *flash);
 
diff --git a/src/cheese-window.c b/src/cheese-window.c
index 83ac059..b18b858 100644
--- a/src/cheese-window.c
+++ b/src/cheese-window.c
@@ -2105,7 +2105,7 @@ cheese_window_init (char *hal_dev_udi, CheeseDbus *dbus_server, gboolean startup
   cheese_window->startup_hal_dev_udi = hal_dev_udi;
   cheese_window->gconf               = cheese_gconf_new ();
   cheese_window->fileutil            = cheese_fileutil_new ();
-  cheese_window->flash               = cheese_flash_new ();
+  cheese_window->flash               = cheese_flash_new (NULL);
   cheese_window->isFullscreen        = FALSE;
   cheese_window->is_bursting         = FALSE;
 
@@ -2117,6 +2117,7 @@ cheese_window_init (char *hal_dev_udi, CheeseDbus *dbus_server, gboolean startup
   cheese_window->fullscreen_timeout_source = NULL;
 
   cheese_window_create_window (cheese_window);
+  g_object_set (G_OBJECT (cheese_window->flash), "parent", cheese_window->window, NULL);
   gtk_action_group_set_sensitive (cheese_window->actions_effects, FALSE);
 
   gtk_spinner_start (GTK_SPINNER (cheese_window->throbber));



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