]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkinvisible.c
Don't add attributes with empty ranges. (fixes #101564 and #80637)
[~andy/gtk] / gtk / gtkinvisible.c
index 1350a43900d734e4582a14a581a8375a61b9d530..7b7896bf3432d6bf644ec1c57f12d6a71d48d203 100644 (file)
  */
 
 #include <gdk/gdk.h>
-#include "gtksignal.h"
 #include "gtkinvisible.h"
+#include "gtkintl.h"
 
-static void gtk_invisible_class_init               (GtkInvisibleClass *klass);
-static void gtk_invisible_init                     (GtkInvisible      *invisible);
-static void gtk_invisible_destroy                  (GtkObject        *object);
-static void gtk_invisible_realize                  (GtkWidget        *widget);
-static void gtk_invisible_show                     (GtkWidget        *widget);
-static void gtk_invisible_size_allocate            (GtkWidget        *widget,
-                                                   GtkAllocation    *allocation);
+enum {
+  PROP_0,
+  PROP_SCREEN,
+  LAST_ARG
+};
 
-GtkType
+static void gtk_invisible_class_init    (GtkInvisibleClass *klass);
+static void gtk_invisible_init          (GtkInvisible      *invisible);
+static void gtk_invisible_destroy       (GtkObject         *object);
+static void gtk_invisible_realize       (GtkWidget         *widget);
+static void gtk_invisible_style_set     (GtkWidget         *widget,
+                                        GtkStyle          *previous_style);
+static void gtk_invisible_show          (GtkWidget         *widget);
+static void gtk_invisible_size_allocate (GtkWidget         *widget,
+                                        GtkAllocation     *allocation);
+static void gtk_invisible_set_property  (GObject           *object,
+                                        guint              prop_id,
+                                        const GValue      *value,
+                                        GParamSpec        *pspec);
+static void gtk_invisible_get_property  (GObject           *object,
+                                        guint              prop_id,
+                                        GValue            *value,
+                                        GParamSpec        *pspec);
+
+static GObject *gtk_invisible_constructor (GType                  type,
+                                          guint                  n_construct_properties,
+                                          GObjectConstructParam *construct_params);
+
+static GObjectClass *parent_class;
+
+GType
 gtk_invisible_get_type (void)
 {
-  static GtkType invisible_type = 0;
+  static GType invisible_type = 0;
 
   if (!invisible_type)
     {
-      static const GtkTypeInfo invisible_info =
+      static const GTypeInfo invisible_info =
       {
-       "GtkInvisible",
-       sizeof (GtkInvisible),
        sizeof (GtkInvisibleClass),
-       (GtkClassInitFunc) gtk_invisible_class_init,
-       (GtkObjectInitFunc) gtk_invisible_init,
-       /* reserved_1 */ NULL,
-        /* reserved_2 */ NULL,
-        (GtkClassInitFunc) NULL,
+       NULL,           /* base_init */
+       NULL,           /* base_finalize */
+       (GClassInitFunc) gtk_invisible_class_init,
+       NULL,           /* class_finalize */
+       NULL,           /* class_data */
+       sizeof (GtkInvisible),
+       0,              /* n_preallocs */
+       (GInstanceInitFunc) gtk_invisible_init,
       };
 
-      invisible_type = gtk_type_unique (GTK_TYPE_WIDGET, &invisible_info);
+      invisible_type = g_type_register_static (GTK_TYPE_WIDGET, "GtkInvisible",
+                                              &invisible_info, 0);
     }
 
   return invisible_type;
@@ -64,29 +88,52 @@ gtk_invisible_get_type (void)
 static void
 gtk_invisible_class_init (GtkInvisibleClass *class)
 {
+  GObjectClass  *gobject_class;
   GtkObjectClass *object_class;
   GtkWidgetClass *widget_class;
 
   widget_class = (GtkWidgetClass*) class;
   object_class = (GtkObjectClass*) class;
+  gobject_class = (GObjectClass*) class;
+
+  parent_class = g_type_class_peek_parent (class);
 
   widget_class->realize = gtk_invisible_realize;
+  widget_class->style_set = gtk_invisible_style_set;
   widget_class->show = gtk_invisible_show;
   widget_class->size_allocate = gtk_invisible_size_allocate;
 
   object_class->destroy = gtk_invisible_destroy;
+  gobject_class->set_property = gtk_invisible_set_property;
+  gobject_class->get_property = gtk_invisible_get_property;
+  gobject_class->constructor = gtk_invisible_constructor;
+
+  g_object_class_install_property (gobject_class,
+                                  PROP_SCREEN,
+                                  g_param_spec_object ("screen",
+                                                       _("Screen"),
+                                                       _("The screen where this window will be displayed"),
+                                                       GDK_TYPE_SCREEN,
+                                                       G_PARAM_READWRITE));
 }
 
 static void
 gtk_invisible_init (GtkInvisible *invisible)
 {
+  GdkColormap *colormap;
+  
   GTK_WIDGET_UNSET_FLAGS (invisible, GTK_NO_WINDOW);
   GTK_WIDGET_SET_FLAGS (invisible, GTK_TOPLEVEL);
 
-  gtk_widget_ref (GTK_WIDGET (invisible));
+  g_object_ref (invisible);
   gtk_object_sink (GTK_OBJECT (invisible));
 
   invisible->has_user_ref_count = TRUE;
+  invisible->screen = gdk_screen_get_default ();
+  
+  colormap = _gtk_widget_peek_colormap ();
+  if (colormap)
+    gtk_widget_set_colormap (GTK_WIDGET (invisible), colormap);
 }
 
 static void
@@ -97,17 +144,98 @@ gtk_invisible_destroy (GtkObject *object)
   if (invisible->has_user_ref_count)
     {
       invisible->has_user_ref_count = FALSE;
-      gtk_widget_unref (GTK_WIDGET (invisible));
+      g_object_unref (invisible);
     }
 }
 
+/**
+ * gtk_invisible_new_for_screen:
+ * @screen: a #GdkScreen which identifies on which
+ *         the new #GtkInvisible will be created.
+ *
+ * Creates a new #GtkInvisible object for a specified screen
+ *
+ * Return value: a newly created #GtkInvisible object
+ *
+ * Since: 2.2
+ **/
+GtkWidget* 
+gtk_invisible_new_for_screen (GdkScreen *screen)
+{
+  g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+  
+  return g_object_new (GTK_TYPE_INVISIBLE, "screen", screen, NULL);
+}
+
+/**
+ * gtk_invisible_new:
+ * 
+ * Creates a new #GtkInvisible.
+ * 
+ * Return value: a new #GtkInvisible.
+ **/
 GtkWidget*
 gtk_invisible_new (void)
 {
-  GtkWidget *result = GTK_WIDGET (gtk_type_new (GTK_TYPE_INVISIBLE));
-  gtk_widget_realize (result);
+  return g_object_new (GTK_TYPE_INVISIBLE, NULL);
+}
+
+/**
+ * gtk_invisible_set_screen:
+ * @invisible: a #GtkInvisible.
+ * @screen: a #GdkScreen.
+ *
+ * Sets the #GdkScreen where the #GtkInvisible object will be displayed.
+ *
+ * Since: 2.2
+ **/ 
+void
+gtk_invisible_set_screen (GtkInvisible *invisible,
+                         GdkScreen    *screen)
+{
+  GtkWidget *widget;
+  GdkScreen *previous_screen;
+  gboolean was_realized;
+  
+  g_return_if_fail (GTK_IS_INVISIBLE (invisible));
+  g_return_if_fail (GDK_IS_SCREEN (screen));
+
+  if (screen == invisible->screen)
+    return;
+
+  widget = GTK_WIDGET (invisible);
 
-  return result;
+  previous_screen = invisible->screen;
+  was_realized = GTK_WIDGET_REALIZED (invisible);
+
+  if (was_realized)
+    gtk_widget_unrealize (widget);
+  
+  invisible->screen = screen;
+  if (screen != previous_screen)
+    _gtk_widget_propagate_screen_changed (widget, previous_screen);
+  g_object_notify (G_OBJECT (invisible), "screen");
+  
+  if (was_realized)
+    gtk_widget_realize (widget);
+}
+
+/**
+ * gtk_invisible_get_screen:
+ * @invisible: a #GtkInvisible.
+ *
+ * Returns the #GdkScreen object associated with @invisible
+ *
+ * Return value: the associated #GdkScreen.
+ *
+ * Since: 2.2
+ **/
+GdkScreen *
+gtk_invisible_get_screen (GtkInvisible *invisible)
+{
+  g_return_val_if_fail (GTK_IS_INVISIBLE (invisible), NULL);
+  
+  return invisible->screen;
 }
 
 static void
@@ -116,9 +244,6 @@ gtk_invisible_realize (GtkWidget *widget)
   GdkWindowAttr attributes;
   gint attributes_mask;
 
-  g_return_if_fail (widget != NULL);
-  g_return_if_fail (GTK_IS_INVISIBLE (widget));
-
   GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
 
   attributes.x = -100;
@@ -132,15 +257,24 @@ gtk_invisible_realize (GtkWidget *widget)
 
   attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_NOREDIR;
 
-  widget->window = gdk_window_new (NULL, &attributes, attributes_mask);
+  widget->window = gdk_window_new (gtk_widget_get_root_window (widget),
+                                  &attributes, attributes_mask);
+                                             
   gdk_window_set_user_data (widget->window, widget);
+  
+  widget->style = gtk_style_attach (widget->style, widget->window);
 }
 
 static void
-gtk_invisible_show (GtkWidget *widget)
+gtk_invisible_style_set (GtkWidget *widget,
+                        GtkStyle  *previous_style)
 {
-  g_return_if_fail (widget != NULL);
+  /* Don't chain up to parent implementation */
+}
 
+static void
+gtk_invisible_show (GtkWidget *widget)
+{
   GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
   gtk_widget_map (widget);
 }
@@ -150,4 +284,63 @@ gtk_invisible_size_allocate (GtkWidget     *widget,
                            GtkAllocation *allocation)
 {
   widget->allocation = *allocation;
+} 
+
+
+static void 
+gtk_invisible_set_property  (GObject      *object,
+                            guint         prop_id,
+                            const GValue *value,
+                            GParamSpec   *pspec)
+{
+  GtkInvisible *invisible = GTK_INVISIBLE (object);
+  
+  switch (prop_id)
+    {
+    case PROP_SCREEN:
+      gtk_invisible_set_screen (invisible, g_value_get_object (value));
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
 }
+
+static void 
+gtk_invisible_get_property  (GObject      *object,
+                            guint         prop_id,
+                            GValue       *value,
+                            GParamSpec   *pspec)
+{
+  GtkInvisible *invisible = GTK_INVISIBLE (object);
+
+  switch (prop_id)
+    {
+    case PROP_SCREEN:
+      g_value_set_object (value, invisible->screen);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+/* We use a constructor here so that we can realize the invisible on
+ * the correct screen after the "screen" property has been set
+ */
+static GObject*
+gtk_invisible_constructor (GType                  type,
+                          guint                  n_construct_properties,
+                          GObjectConstructParam *construct_params)
+{
+  GObject *object;
+
+  object = (* G_OBJECT_CLASS (parent_class)->constructor) (type,
+                                                          n_construct_properties,
+                                                          construct_params);
+
+  gtk_widget_realize (GTK_WIDGET (object));
+
+  return object;
+}
+