]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkwidget.c
spinbutton: don't override initial text in non-numeric-only spin buttons
[~andy/gtk] / gtk / gtkwidget.c
index 58c6d901e0bb6a472d75d69df5a8f09423389f10..37460e3419680aab8b42d52e0f51003bb474fc0a 100644 (file)
@@ -1805,6 +1805,13 @@ gtk_widget_class_init (GtkWidgetClass *klass)
    * restore it. The signal emission takes care of calling cairo_save()
    * before and cairo_restore() after invoking the handler.
    *
+   * The signal handler will get a @cr with a clip region already set to the
+   * widget's dirty region, i.e. to the area that needs repainting.  Complicated
+   * widgets that want to avoid redrawing themselves completely can get the full
+   * extents of the clip region with gdk_cairo_get_clip_rectangle(), or they can
+   * get a finer-grained representation of the dirty region with
+   * cairo_copy_clip_rectangle_list().
+   *
    * Returns: %TRUE to stop other handlers from being invoked for the event.
    % %FALSE to propagate the event further.
    *
@@ -4554,6 +4561,7 @@ unref_tick_callback_info (GtkWidget           *widget,
       g_signal_handlers_disconnect_by_func (frame_clock,
                                             (gpointer) gtk_widget_on_frame_clock_update,
                                             widget);
+      gdk_frame_clock_end_updating (frame_clock);
     }
 }
 
@@ -4576,6 +4584,8 @@ gtk_widget_on_frame_clock_update (GdkFrameClock *frame_clock,
   GtkWidgetPrivate *priv = widget->priv;
   GList *l;
 
+  g_object_ref (widget);
+
   for (l = priv->tick_callbacks; l;)
     {
       GtkTickCallbackInfo *info = l->data;
@@ -4597,9 +4607,7 @@ gtk_widget_on_frame_clock_update (GdkFrameClock *frame_clock,
       l = next;
     }
 
-  if (priv->tick_callbacks != NULL)
-    gdk_frame_clock_request_phase (frame_clock,
-                                   GDK_FRAME_CLOCK_PHASE_UPDATE);
+  g_object_unref (widget);
 }
 
 static guint tick_callback_id;
@@ -4626,11 +4634,16 @@ static guint tick_callback_id;
  * gdk_frame_clock_get_frame_time() should generally be used for timing
  * continuous animations and
  * gdk_frame_timings_get_predicted_presentation_time() if you are
- * trying to display isolated frames particular times.
+ * trying to display isolated frames at particular times.
  *
  * This is a more convenient alternative to connecting directly to the
- * ::update signal of GdkFrameClock, since you don't have to worry about
- * when a #GdkFrameClock is assigned to a widget.
+ * #GdkFrameClock::update signal of #GdkFrameClock, since you don't
+ * have to worry about when a #GdkFrameClock is assigned to a widget.
+ *
+ * Returns: an id for the connection of this callback. Remove the callback
+ *     by passing it to gtk_widget_remove_tick_callback()
+ *
+ * Since: 3.8
  */
 guint
 gtk_widget_add_tick_callback (GtkWidget       *widget,
@@ -4651,11 +4664,10 @@ gtk_widget_add_tick_callback (GtkWidget       *widget,
       g_signal_connect (frame_clock, "update",
                         G_CALLBACK (gtk_widget_on_frame_clock_update),
                         widget);
-      gdk_frame_clock_request_phase (frame_clock,
-                                     GDK_FRAME_CLOCK_PHASE_UPDATE);
+      gdk_frame_clock_begin_updating (frame_clock);
     }
 
-  info = g_slice_new (GtkTickCallbackInfo);
+  info = g_slice_new0 (GtkTickCallbackInfo);
 
   info->refcount = 1;
   info->id = ++tick_callback_id;
@@ -4669,6 +4681,16 @@ gtk_widget_add_tick_callback (GtkWidget       *widget,
   return info->id;
 }
 
+/**
+ * gtk_widget_remove_tick_callback:
+ * @widget: a #GtkWidget
+ * @id: an id returned by gtk_widget_add_tick_callback()
+ *
+ * Removes a tick callback previously registered with
+ * gtk_widget_add_tick_callback().
+ *
+ * Since: 3.8
+ */
 void
 gtk_widget_remove_tick_callback (GtkWidget *widget,
                                  guint      id)
@@ -4702,8 +4724,7 @@ gtk_widget_connect_frame_clock (GtkWidget     *widget,
       g_signal_connect (frame_clock, "update",
                         G_CALLBACK (gtk_widget_on_frame_clock_update),
                         widget);
-      gdk_frame_clock_request_phase (frame_clock,
-                                     GDK_FRAME_CLOCK_PHASE_UPDATE);
+      gdk_frame_clock_begin_updating (frame_clock);
     }
 
   if (priv->context)
@@ -4720,9 +4741,12 @@ gtk_widget_disconnect_frame_clock (GtkWidget     *widget,
     _gtk_container_stop_idle_sizer (GTK_CONTAINER (widget));
 
   if (priv->tick_callbacks)
-    g_signal_handlers_disconnect_by_func (frame_clock,
-                                          (gpointer) gtk_widget_on_frame_clock_update,
-                                          widget);
+    {
+      g_signal_handlers_disconnect_by_func (frame_clock,
+                                            (gpointer) gtk_widget_on_frame_clock_update,
+                                            widget);
+      gdk_frame_clock_end_updating (frame_clock);
+    }
 
   if (priv->context)
     gtk_style_context_set_frame_clock (priv->context, NULL);
@@ -5032,8 +5056,9 @@ gtk_widget_queue_resize_no_redraw (GtkWidget *widget)
  *
  * Unrealized widgets do not have a frame clock.
  *
- * Since: 3.0
  * Return value: (transfer none): a #GdkFrameClock (or #NULL if widget is unrealized)
+ *
+ * Since: 3.0
  */
 GdkFrameClock*
 gtk_widget_get_frame_clock (GtkWidget *widget)
@@ -7478,13 +7503,13 @@ gtk_widget_set_receives_default (GtkWidget *widget,
  * gtk_widget_get_receives_default:
  * @widget: a #GtkWidget
  *
- * Determines whether @widget is alyways treated as default widget
- * withing its toplevel when it has the focus, even if another widget
+ * Determines whether @widget is always treated as the default widget
+ * within its toplevel when it has the focus, even if another widget
  * is the default.
  *
  * See gtk_widget_set_receives_default().
  *
- * Return value: %TRUE if @widget acts as default widget when focussed,
+ * Return value: %TRUE if @widget acts as the default widget when focussed,
  *               %FALSE otherwise
  *
  * Since: 2.18
@@ -14073,7 +14098,7 @@ gtk_widget_register_window (GtkWidget    *widget,
   gdk_window_set_user_data (window, widget);
   priv->registered_windows = g_list_prepend (priv->registered_windows, window);
 
-  if (!gtk_widget_get_has_window (widget) && !gdk_window_has_native (window))
+  if (priv->window != window && !gdk_window_has_native (window))
     gdk_window_set_opacity (window,
                            priv->norender_children ? 0.0 : 1.0);
 }
@@ -14205,21 +14230,25 @@ gtk_widget_propagate_alpha (GtkWidget *widget)
 
   parent = priv->parent;
 
-  norender =
-    /* If this widget has an opacity group, never render it */
-    priv->opacity_group ||
-    /* If the parent has norender_children, propagate that here */
-    (parent != NULL && parent->priv->norender_children);
-
-  /* Windowed widget children should norender if: */
+  /* Norender affects only windowed widget and means don't render widget->window in the
+     normal fashion.
+     We only set this if the parent has norender_children, because:
+     a) For an opacity group (that does not have a norender_children parent) we still
+     need to render the window or we will never get an expose event.
+     b) For alpha we set the opacity of window->widget directly, so no other
+     work is needed.
+  */
+  norender = (parent != NULL && parent->priv->norender_children);
+
+  /* windows under this widget should not render if:
+     a) This widget has an opacity group
+     b) This widget has alpha and is no-windowed (otherwise we'd set alpha on widget->window)
+     c) This widget has norender but is no-windowed (a windowed widget would "swallow" the norender)
+  */
   norender_children =
-    /* The widget is no_window (otherwise its enought to mark it norender/alpha), and */
-    !gtk_widget_get_has_window (widget) &&
-     ( /* norender is set, or */
-      norender ||
-      /* widget has an alpha */
-      priv->alpha != 255
-       );
+    priv->opacity_group ||
+    (!gtk_widget_get_has_window (widget) &&
+     ( norender || priv->alpha != 255));
 
   if (gtk_widget_get_has_window (widget))
     {
@@ -14227,14 +14256,12 @@ gtk_widget_propagate_alpha (GtkWidget *widget)
        gdk_window_set_opacity (priv->window,
                                norender ? 0 : priv->alpha / 255.0);
     }
-  else /* !has_window */
+
+  for (l = priv->registered_windows; l != NULL; l = l->next)
     {
-      for (l = priv->registered_windows; l != NULL; l = l->next)
-       {
-         GdkWindow *w = l->data;
-         if (!gdk_window_has_native (w))
-           gdk_window_set_opacity (w, norender_children ? 0.0 : 1.0);
-       }
+      GdkWindow *w = l->data;
+      if (w != priv->window && !gdk_window_has_native (w))
+       gdk_window_set_opacity (w, norender_children ? 0.0 : 1.0);
     }
 
   priv->norender = norender;