Scratch Pad

Scratch pad for those items we just want to 'jot down now' for inclusion later.

AtkValue

atk_value_set_current_value ()

"Implementor note: The implementation must handle values outisde of the range given by min and max. THe behavior in those cases is implementation-defined. If the implementation allows multiple behaviors, clamping is preferred."

Best-Practices-Like Stuff Found During the Wiki Clean-Up

  • We may or may not wish to keep these (typically old) examples from abandoned pages.
  • If we do decide to keep them or some variant thereof, we'll need to update them (e.g. w.r.t. the gailectomy)

How to issue events to reflect "focused" change

It is quite simple for us to notice what is going on when operating on the computer, but it may be a little challenging for a blind person to do so. As a result, we should provide feedback to these users by issuing events to Orca (a flexible accessibility application for people with visual impairments) to tell it what is going on. Specifically, to tell users which object is focused on the desktop, we need to issue "object:state-changed:focused" and "focus:" events to reflect the new object with focus.

The "object:state-changed:focused" Event

When to Emit "object:state-changed:focused" Event

When focus moves from one object to another, this event should be issued to reflect that the former object lost "focused" state and the latter one got it. Consequently, if there is a "focused" change, "object:state-changed:focused" event with regard to the above two objects will be emitted to specify the state change for both of them.

For example, if we press Arrow Right to move focus from one object (named "bin") to another ("boot"), Orca will receive the following events:

 object:state-changed:focused(0, 0, None)
        source: [icon | bin]
        application: [application | gtk-demo]
 object:state-changed:focused(1, 0, None)
        source: [icon | boot]
        application: [application | gtk-demo]

Where focused(0, 0, None) represents that "focused" state has been removed from "bin", while focused(1, 0, None) denotes that "focused" state has been added to "boot".

How to Emit "object:state-changed:focused" Event

To illustrate the process of emitting events, we continue to analyse the above example, pressing Arrow Right to move focus from one object ("bin") to another ("boot").

  • Get the GTK widget with focus change:
    1. When pressing Arrow Right, gtk_main (gtkmain.c) will connect to a function gtk_widget_real_key_press_event (gtkwidget.c) to cope with this action leading to "focused" change.

    2. Then gtk_widget_grab_focus (gtkwidget.c) will be invoked, which is in charge of finding the widget with "focused" state change by iteratively running gtk_widget_child_focus (gtkwidget.c).

  • GTK widget emits "FOCUS_IN_EVENT" or "FOCUS_OUT_EVENT" event:
    1. Getting the widget with "focused" change (e.g., widget "bin" losing "focused" state), gtk_window_real_set_focus (gtkwindow.c) will bind an event (event->focus_change.type = GDK_FOCUS_CHANGE, event->focus_change.in = 0) to this GTK Widget via the function do_focus_change (gtkwindown.c). Here "event->focus_change.in" is a boolean variable (0 represents losing "focused" state, 1 denots obtaining "focused" state). So for Widget "bin", "event->focus_change.in" is set to be 0 because it lost "focused" state in this process, while as to Widget "boot", event->focus_change.in=1.

    2. Then gtk_widget_event_internal (gtkwidget.c) emits "FOCUS_IN_EVENT" event (event->focus_change.in=1) or "FOCUS_OUT_EVENT" event (event->focus_change.in=0) to Gail.

  • ATK object emits "focus_event" event and "ATK_STATE_FOCUSED" event:
    1. Receiving the above event, gail_widget_focus_gtk (gailwidget.c) will establish the corresponding ATK Object as to this GTK Widget (e.g., "bin") and emit "focus_event" signal via the function g_signal_emit_by_name (accessible, "focus_event", event->in, &return_val). Here event->in is a boolean variable which has the same meaning with "event->focus_change.in".

    2. The "focus_event" signal will connect to gail_widget_focus_event (gailwidget.c), which emits "ATK_STATE_FOCUSED" event via atk_object_notify_state_change (focus_obj, ATK_STATE_FOCUSED, focus_in), where "focus_obj" refers to the ATK Object with "focused" change and the value of "focus_in" equals to "event->focus_change.in".

  • ATK object emits "object:state-changed:focused" event:
    1. The "ATK_STATE_FOCUSED" event will connect to spi_atk_emit_eventv (bridge.c), where "object:state-changed:focused" will be emitted to Orca.

The "focus:" Event

When to Emit "focus:" Event

Let's take the above case as an example again, pressing Arrow Right to move focus from one object(named "bin") to another ("boot"). As the focus on the desktop has changed, it is reasonable to report this alteration to Orca. Consequently, "focus:" event as follows is needed to tell Orca which object is focused currently.

 focus:(0, 0, None)
       source: [icon | boot]
       application: [application | gtk-demo]

The above event denotes that the icon named "boot" is focused at present.

How to Emit "focus:" Event

There are several key functions to complete this process:

  • gail_focus_watcher (gail.c) looks for "event-after" signal, and checks whether the signal is "FOCUS_IN_EVENT" or not. If yes, gail_focus_notify_when_idle (gail.c) will run.

  • gail_focus_notify_when_idle (gail.c) is used to invoke the function gail_focus_idle_handler (gail.c), in order to connect to gail_focus_notify (gail.c).

  • gail_focus_notify (gail.c) mainly undertakes two tasks:

    1. make sure "focus_widget = widget" (the current widget is set to be focus_widget)
    2. connect to atk_focus_tracker_notify (atkutil.c) if "focus_widget = widget".
  • atk_focus_tracker_notify (atkutil.c) connects to spi_atk_bridge_focus_tracker (bridge.c) to emit "focus:" event to Orca.

How to add children to GtkContainer

Quick Introduction to GtkContainer

A GTK+ user interface is constructed by nesting widgets inside widget. Container widgets are the inner nodes in the resulting tree of widgets: they contain other widgets. For example, you might have a GtkWindow containing a GtkButton containing a GtkLabel.

Abstractly, GtkContainer is a base class for widgets which contain other widgets. GtkBin, GtkBox, GtkTable, GtkList, GtkMenuShell... are all subclasses of the abstract GtkContainer base class. Generally, all the subclasses could be divided into two major kinds of container widgets in GTK+. The first type of container widget has a single child widget and derives from GtkBin, such as GtkButton, GtkFrame. The second type of container widget has more than one child, such as, GtkBox, GtkTable.

Anyway, all the container widgets are aimed to contain other widget. Consequently, the following will discuss how to add widgets to containers.

How to add a widget to containers

To demonstrate the process of adding a child to containers, we firstly take GtkBox as an example.

Example: GtkBox

GtkBox is a typical subclass of GtkContainer, which could contain more than one child. If we want to add a menubar to a GtkBox, the process is described as follows.

  • gtk_container_add will be used to emit a signal container_signals [ADD]
  • This "ADD" signal can be connected to gtk_box_add to implement the adding task for Gtk
  • Meanwhile, "ADD" signal will link gail_container_add_gtk, which is in charge of emitting a signal "children_changed::add"
  • Then, spi_atk_bridge_signal_listener will receive "children_changed::add" signal and report it to Orca through spi_atk_emit_event

Accessibility/ATK/BestPractices/Scratch (last edited 2011-07-15 03:09:15 by JoanmarieDiggs)