📄 widget_system.txt
字号:
is made in gtkwidget.c, 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:----------------------------How can the user control the state of a widget:-----------------------------------------------(In the following, set flag means set the flag, do appropriateactions, and enforce above invariants) gtk_widget_show: if !GTK_DESTROYED sets GTK_VISIBLEgtk_widget_hide: if !GTK_VISIBLE for widgetgtk_widget_destroy: sets GTK_DESTROYED For a top-level widgetgtk_widget_realize: if !GTK_DESTROYED sets GTK_REALIZED- Calling gtk_widget_realize when the widget is not a descendent of a toplevel is an ERROR.gtk_container_add (container, widget) [ and container-specific variants ] Sets widget->parent gtk_container_remove (container, widget) unsets widget->parentgtk_widget_reparent (widget, new_parent) Equivalent to removing widget from old parent and adding it to the new parent, except that the widget will not be temporarily unrealized if both the old parent and the new parent are realized.gtk_widget_unrealizegtk_widget_mapgtk_widget_unmapThese functions are not meant to be used by applications - theyare used only by GTK and widgets to enforce invariants on thestate.When The X window corresponding to a GTK window is destroyed:-------------------------------------------------------------gtk_widget_destroy is called (as above).IV. Responsibilities of widgets--------------------------------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 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 mappedNote: 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)Removing from a container-------------------------When a widget is removed to a container, the container: 1) Calls gtk_widget_unparent (widget) 2) Queues a resize.Notes: gtk_widget_unparent unrealizes the widget except in the special case GTK_IN_REPARENT is set.At widget creation------------------Widgets are created in an unrealized state. 1) The widget should allocate and initialize needed data structuresThe Realize signal------------------When a widget recieves 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); 3) attach the widget's style widget->style = gtk_style_attach (widget->style, widget->window); widget with window(s) 1) set the REALIZED flag 2) create windows with the parent obtained from gtk_widget_get_parent_window (widget); 3) attach the widget's style 4) set the background color for the new window based on the styleThe 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 widgets that are VISIBLE and !MAPPED. 3) Do any other functions related to putting the widget onscreen. (for instance, showing extra popup windows...)The Unmap signal----------------When a widget receives the unmap signal, it must: 1) If the widget has a window, gdk_window_hide that window, 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...) 4) Unset GTK_MAPPEDThe Unrealize signal--------------------When a widget receives the unrealize signal, it must 1) For any windows other than widget->window do: gdk_window_set_user_data (window, NULL); gdk_window_destroy (window); 2) Call the parent's unrealize handlerThe Widget class unrealize handler will take care of unrealizingall children if necessary. [should this be made consistent withunmap???]The Destroy Signal------------------Commentary: The destroy signal probably shouldn't exist at all. A widget should merely be unrealized and removed from its parent when the user calls gtk_widget_destroy or a GDK_DESTROY event is received. However, a large body of code depends on getting a definitive signal when a widget goes away. That could be put in the finalization step, but, especially with language bindings, the cleanup step may need to refer back to the widget. (To use gtk_widget_get_data, for instance) If it does so via a pointer in a closure (natural for Scheme, or Perl), then the finalization procedure will never be called. Also, if we made that the finalization step, we would have to propagate the GDK_DESTROY event in any case, since it is at that point at which user-visible actions need to be taken.When a widget receives the destroy signal, it must: 1) If the widget "owns" any widgets other than its child widgets, (for instance popup windows) it should call gtk_widget_destroy () for them. 2) Call the parent class's destroy handler.The "destroy" signal will only be received once. A widgetwill never receive any other signals after the destroysignal (but see the sectionalize on "Finalize" below)The widget must handle calls to all publically accessiblefunctions in an innocuous manner even after a "destroy"signal. (A widget can assume that it will not be realized after a "destroy" signal is received, which may simplifyhandling this requirement)The Finalize Pseudo-signal--------------------------The finalize pseudo-signal is received after all referencesto the widget have been removed. The finalize callbackcannot make any GTK calls with the widget as a parameter.1) Free any memory allocated by the widget. (But _not_ the widget structure itself.2) Call the parent class's finalize signalA note on chaining "destroy" signals and finalize signals:---------------------------------------------------------This is done by code like: if (GTK_OBJECT_CLASS (parent_class)->destroy) (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);It may not be completely obvious why this works. Notethat parent_class is a static variable on a per-classbasis. So say: we have GtkFoo <- GtkBar <- GtkWidget <-GtkObjectAnd that Foo, Widget, and Object all have destructors, butnot Bar.Then gtk_foo_destroy will call gtk_widget_destroy (becauseit was not overridden in the Bar class structure) andgtk_widget_destroy will call gtk_object_destroy becausethe parent_class variable referenced by gtk_foo_destroy is the static variable in gtkwidget.c: GtkObjectClass.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -