]> Pileus Git - ~andy/gtk/blobdiff - docs/widget_system.txt
gtk: Add GtkSearchEntry
[~andy/gtk] / docs / widget_system.txt
index 6607aa27689bbbdd3ddb6ceb047efb077f6dd7c6..9463f10db9925b0cbf2d7d6a2d0faa0ab2344797 100644 (file)
@@ -1,3 +1,6 @@
+Notes about the inner workings of the widget system of GTK+
+===========================================================
+
 This file contains some notes as to how the widget system does
 and should work. It consists of three parts:
 
@@ -5,7 +8,7 @@ and should work. It consists of three parts:
 
  II) A list of invariants about the states of the widgets. 
     (Throughout this document, we refer to the states of the
-     widgets by referring to the flags for gtkwidget)
+     widgets by referring to the flags for GtkWidget)
 
  III) Some notes about the ways that a widget changes states
 
@@ -26,73 +29,196 @@ Section II is mostly of interest to those maintaining GTK, the
 other sections may also be interesting to people writing
 new widgets.
 
-                            Owen Taylor <owt1@cornell.edu>
-                           98/02/03
+Main outline:
+       - Owen Taylor <owt1@cornell.edu>
+         1998/02/03
+
+Flag descriptions:
+       - Tim Janik <timj@gimp.org>
+         1998/02/04
 
 I. Flags
 --------
 
+GtkObject:
+
+GTK_DESTROYED:
+       This flagged is set for a GtkObject right before its
+       destruction code is executed. Its main use is the
+       prevention of multiple destruction invocations.
+       
+GTK_FLOATING:
+       This flag reflects the fact that the holder of the
+       initial reference count is unknown. Refer to refcounting.txt
+       for further details.
+
+GTK_RESERVED_1:
+GTK_RESERVED_2:
+       Reserved flags.
+
+
+GtkWidget, public flags:
+
+GTK_TOPLEVEL:
+       Widgets without a real parent, as there are GtkWindows and
+       GtkMenus have this flag set throughout their lifetime.
+       Toplevel widgets always contain their own GdkWindow.
+       
+GTK_NO_WINDOW:
+       This flag is indicative for a widget that does not provide
+       its own GdkWindow. Visible action (e.g. drawing) is performed
+       on the parent's GdkWindow.
+
 GTK_REALIZED:
-       set by gtk_widget_realize, unset by gtk_widget_unrealize
-       relies on ((widget->parent && widget->parent->window)
-                  || GTK_WIDGET_TOPLEVEL (widget);
-       means: widget has an associated GdkWindow (XWindow)
+       Set by gtk_widget_realize, unset by gtk_widget_unrealize.
+       Relies on ((widget->parent && widget->parent->window)
+                  || GTK_WIDGET_TOPLEVEL (widget));
+       Means: widget has an associated GdkWindow (XWindow).
 
 GTK_MAPPED:
-       set by gtk_widget_map, unset by gtk_widget_unmap
-       may only be set if GTK_WIDGET_REALIZED(widget)
-       means: gdk_window_show() has been called on the widgets window(s).
+       Set by gtk_widget_map, unset by gtk_widget_unmap.
+       May only be set if GTK_WIDGET_REALIZED (widget).
+       Means: gdk_window_show() has been called on the widgets window(s).
 
 GTK_VISIBLE:
-       set by gtk_widget_show
-       implies that a widget will be GTK_MAPPED as soon as it's
-       parent is GTK_MAPPED.
+       Set by gtk_widget_show.
+       Implies that a widget will be flagged GTK_MAPPED as soon as its
+       parent is mapped.
 !GTK_VISIBLE:
-       set by gtk_widget_hide
-       implies that a widget is not onscreen, therefore !GTK_MAPPED
-
-GTK_REDRAW_PENDING:
-       relies on GTK_WIDGET_MAPPED(widget)
-       [this is not really enforced throughout the code, but should
-        be. it only requires a few checks for GTK_WIDGET_MAPPED and
-        minor changes to gtk_widget_unmap, we can then remove the check
-        in gtk_widget_real_destroy]
-       means: there is an idle handler waiting for the widget, that
-       will cause a full redraw (gtk_widget_draw(widget, NULL))
+       Set by gtk_widget_hide.
+       Implies that a widget is not onscreen, therefore !GTK_MAPPED.
+
+GTK_CHILD_VISIBLE
+        Set by gtk_widget_set_child_visible, and if FALSE indicates that 
+        the widget should not be mapped even if the parent is mapped
+        and visible. Containers like GtkNotebook use this flag.
+        A private flag, not a public flag, so if you need to check
+        this flag, you should call gtk_widget_get_child_visible().
+        (Should be very rarely necessary.)
+
+GTK_SENSITIVE:
+       Set and unset by gtk_widget_set_sensitive.
+       The sensitivity of a widget determines whether it will receive
+       certain events (e.g. button or key presses). One premise for
+       the widgets sensitivity is to have GTK_SENSITIVE set.
+
+GTK_PARENT_SENSITIVE:
+       Set and unset by gtk_widget_set_sensitive operations on the
+       parents of the widget.
+       This is the second premise for the widgets sensitivity. Once
+       it has GTK_SENSITIVE and GTK_PARENT_SENSITIVE set, its state is
+       effectively sensitive. This is expressed (and can be examined) by
+       the GTK_WIDGET_IS_SENSITIVE macro.
+
+GTK_CAN_FOCUS:
+       There are no directly corresponding functions for setting/unsetting
+       this flag, but it can be affected by the GtkWidget::has_focus argument
+       via gtk_widget_set_arg.
+       This flag determines whether a widget is able to handle focus grabs.
+
+GTK_HAS_FOCUS:
+       This flag will be set by gtk_widget_grab_focus for widgets that also
+       have GTK_CAN_FOCUS set. The flag will be unset once another widget
+       grabs the focus.
+       
+GTK_CAN_DEFAULT:
+GTK_HAS_DEFAULT:
+       These two flags are mostly equal in functionality to their *_FOCUS
+       counterparts, but for the default widget.
 
+GTK_HAS_GRAB:
+       Set by gtk_grab_add, unset by gtk_grab_remove.
+       Means: widget is in the grab_widgets stack, and will be the preferred
+       one for receiving events other than ones of cosmetic value.
+
+GTK_BASIC:
+       The GTK_BASIC flag is an attempt at making a distinction
+       between widgets that handle user input e.g. key/button presses
+       and those that don't. Subsequent parent<->child relation ships
+       of non `basic' widgets should be avoided. The checking for
+       this is currently not properly enforced in the code. For
+       example GtkButton is a non `basic' widget, that will therefore
+       disallow to act as a container for another GtkButton. Now the
+       gnit is, one can add a GtkHBox (which is a `basic' widget) to
+       the first button, and put the second into the box.
+
+GTK_RESERVED_3:
+
+GTK_RC_STYLE:
+       This flag indicates that its style has been looked up through
+       the rc mechanism. It does not imply that the widget actually
+       had a style defined through the rc mechanism.
+
+
+GtkWidget, private flags:
+
+GTK_USER_STYLE:
+       A widget is flagged to have a user style, once gtk_widget_set_style
+       has been invoked for it. The use of this flag is to tell widgets
+       which share a global user style from the ones which got a certain
+       style assign from outside the toolkit.
+       
 GTK_RESIZE_PENDING:
-       first, this is only valid for GtkContainers.
+       First, this is only valid for GtkContainers.
        [some of the code should move to gtkcontainer.c therefore]
-       relies on GTK_WIDGET_REALIZED(widget)
+       Relies on GTK_WIDGET_REALIZED(widget)
        [this is not really enforced throughout the code, but should
-        be. it only requires a few checks for GTK_WIDGET_RELIZED and
+        be. it only requires a few checks for GTK_WIDGET_REALIZED and
         minor changes to gtk_widget_unrealize, we can then remove the check
         in gtk_widget_real_destroy]
-       means: there is an idle handler waiting for the container to
+       Means: there is an idle handler waiting for the container to
        resize it.
 
 GTK_RESIZE_NEEDED:
-       relies on GTK_WIDGET_REALIZED(widget)
-       [puhhh, this isn't rely enforced either..., bla bla ...remove check
-        in gtk_widget_real_destroy]
-       means: a widget has been added to the resize_widgets list of
+       Relies on GTK_WIDGET_REALIZED(widget)
+       [this is not really enforced throughout the code, but should
+        be. once this is done special checking in gtk_widget_real_destroy
+        can be avoided]
+       Means: a widget has been added to the resize_widgets list of
        its _toplevel_ container (keep this in mind for GtkViewport).
-       remark: this flag is also used internaly by gtkwindow.c.
+       Remark: this flag is also used internally by gtkwindow.c during
+       the evaluation of resizing worthy widgets.
 
 GTK_LEAVE_PENDING:
-       a widget is flagged as such if there is a leave_notify event
-       pending for it. it receives this event regardless of a grab or
-       its current sensitivity.
+       A widget is flagged as such if there is a leave_notify event
+       pending for it. It will receive this event regardless of a grab
+       through another widget or its current sensitivity.
        [this should be made relying on GTK_REALIZED]
 
-GTK_HAS_GRAB:
-       set by gtk_grab_add, unset by gtk_grab_remove
-       means: widget is in the grab_widgets stack.
+GTK_HAS_SHAPE_MASK:
+       Set by gtk_widget_shape_combine_mask if a widget got a shape mask
+       assigned (making use of the X11 shaped window extension).
+
+GTK_IN_REPARENT:
+       During the act of reparentation widgets which are already
+       realized and will be added to an already realized parent need
+       to have this flag set to prevent natural unrealization on the
+       process of getting unparented.
+
+GTK_NEED_REQUEST:
+       This flag is set if the widget doesn't have an up to date 
+       requisition. If this flag is set, we must actually emit ::size-request
+        when gtk_widget_size_request() is called. Otherwise, we can
+        simply widget->requisition. We keep track of this all the time
+        however, widgets with this flag set are only added to the resize 
+       queue if they are viewable.
+
+GTK_NEED_ALLOCATION:
+       This flag is set if the widget doesn't have an up to date 
+       allocation. If this flag is set, we must actually emit ::size-allocate
+        when gtk_widget_size_allocate() is called, even if the new allocation
+        is the same as the current allocation.
+Related Macros:
 
 GTK_WIDGET_DRAWABLE:
-       a widget is flagged as GTK_WIDGET_VISIBLE and GTK_WIDGET_MAPPED
-       means: it _makes sense_ to draw in a widgets window.
+       This macro examines whether a widget is flagged as GTK_WIDGET_VISIBLE
+       and GTK_WIDGET_MAPPED.
+       Means: it _makes sense_ to draw in a widgets window.
 
+GTK_WIDGET_IS_SENSITIVE:
+       This macro tells the real sensitivity state of a widget. It returns
+       whether both the widget and all its parents are in sensitive state.
 
 
 II. Invariants:
@@ -105,7 +231,7 @@ In the following
 
   A => B     means  if A is true, than B is true
   A <=> B    means  A is true, if and only if B is true
-                    (equivalent to A => B and B <= A)
+                    (equivalent to A => B and A <= B)
 
 
 1)  GTK_WIDGET_DESTROYED (widget) => !GTK_WIDGET_REALIZED (widget)
@@ -124,20 +250,25 @@ In the following
 5) if !GTK_WIDGET_TOPLEVEL (widget):
 
    GTK_WIDGET_MAPPED (widget) => GTK_WIDGET_VISIBLE (widget)
+                              => GTK_WIDGET_CHILD_VISIBLE (widget)
                               => GTK_WIDGET_REALIZED (widget)
 
    widget->parent && GTK_WIDGET_MAPPED (widget->parent) && 
-     GTK_WIDGET_VISIBLE (widget) => GTK_WIDGET_MAPPED (widget)
+     GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_CHILD_VISIBLE 
+       <=> GTK_WIDGET_MAPPED (widget)
 
 Note:, the definition
 
 [  GTK_WIDGET_DRAWABLE = GTK_WIDGET_VISIBLE && GTK_WIDGET_MAPPED
-   is made in gtkwidget.c, but by 3) and 5), 
+   is made in gtkwidget.h, but by 3) and 5), 
      
       GTK_WIDGET_MAPPED => GTK_WIDGET_VISIBLE
 ]
 
-
+6) GTK_REDRAW_PENDING => GTK_WIDGET_REALIZED
+   GTK_RESIZE_PENDING =>         "
+   GTK_LEAVE_PENDING  =>         "
+   GTK_RESIZE_NEEDED  =>         "
 
 III. How states are changed:
 ----------------------------
@@ -160,7 +291,7 @@ gtk_widget_destroy:
 
 gtk_widget_realize:
  if !GTK_DESTROYED sets GTK_REALIZED
-- Calling gtk_widget_realize when the widget is not a descendent
+- Calling gtk_widget_realize when the widget is not a descendant
   of a toplevel is an ERROR.
 
 gtk_container_add (container, widget) [ and container-specific variants ]
@@ -198,18 +329,9 @@ Adding to a container
 
 When a widget is added to a container, the container:
 
-  1) calls gtk_widget_set_parent (widget, container)
-  2) calls gtk_widget_set_parent_window (widget, window) if 
+  1) calls gtk_widget_set_parent_window (widget, window) if 
      the widget is being added to something other than container->window
-  3) if container is realized, and not widget, realizes widget
-  4) if container is mapped, and not widget and widget is GTK_VISIBLE,
-     maps widget
-  5) Queues a resize if the widget is mapped
-
-Note: It would be nice to remove 3) and 4) out of widget specific code
-  since they are of the invariant-enforcing nature, but it is
-  a bit hard, since they can't be done until after 2)
-
+  2) calls gtk_widget_set_parent (widget, container)
 
 Removing from a container
 -------------------------
@@ -217,8 +339,7 @@ Removing from a container
 When a widget is removed to a container, the container:
 
   1) Calls gtk_widget_unparent (widget)
-  2) Sets widget->parent to NULL
-  3) Queues a resize.
+  2) Queues a resize.
 
 Notes:
 
@@ -237,14 +358,14 @@ Widgets are created in an unrealized state.
 The Realize signal
 ------------------
 
-When a widget recieves the "realize" signal it should:
+When a widget receives the "realize" signal it should:
 
  NO_WINDOW widgets: (probably OK to use default handler)
 
   1) set the realized flag
   2) set widget->window
       widget->window = gtk_widget_get_parent_window (widget);
-      gdk_window_ref (widget->window);
+      g_object_ref (widget->window);
   3) attach the widget's style
 
   widget->style = gtk_style_attach (widget->style, widget->window);
@@ -262,8 +383,10 @@ The Map signal
 
   1) Set the MAPPED flag
   2) If the widget has any windows, gdk_window_show those windows
-  3) call gtk_widget_map for all child windows that are 
-     VISIBLE and !MAPPED.
+  3) call gtk_widget_map for all child widgets that are 
+     VISIBLE, CHILD_VISIBLE and !MAPPED. (A widget will only
+     be !CHILD_VISIBLE if the container set it that way, so
+     most containers will not have to check this.)
   3) Do any other functions related to putting the widget onscreen.
      (for instance, showing extra popup windows...)
 
@@ -276,7 +399,7 @@ When a widget receives the unmap signal, it must:
  2) If the widget does not have a window, unmap all child widgets
  3) Do any other functions related to taking the widget offscreen
      (for instance, removing popup windows...)
3) Unset GTK_MAPPED
4) Unset GTK_MAPPED
 
 
 The Unrealize signal
@@ -331,7 +454,7 @@ When a widget receives the destroy signal, it must:
 
 The "destroy" signal will only be received once. A widget
 will never receive any other signals after the destroy
-signal (but see the sectionalize on "Finalize" below)
+signal (but see the section on "Finalize" below)
 
 The widget must handle calls to all publically accessible
 functions in an innocuous manner even after a "destroy"
@@ -375,5 +498,3 @@ it was not overridden in the Bar class structure) and
 gtk_widget_destroy will call gtk_object_destroy because
 the parent_class variable referenced by gtk_foo_destroy is the 
 static variable in gtkwidget.c: GtkObjectClass.
-
-