/* This function is the default implementation for the notify_gtk
 * vfunc which gets called when a property changes value on the
 * GtkWidget associated with a GtkWidgetAccessible. It constructs
 * an AtkPropertyValues structure and emits a "property_changed"
 * signal which causes the user specified AtkPropertyChangeHandler
 * to be called.
 */
static void
gtk_widget_accessible_notify_gtk (GObject    *obj,
                                  GParamSpec *pspec)
{
  GtkWidget* widget = GTK_WIDGET (obj);
  AtkObject* atk_obj = gtk_widget_get_accessible (widget);
  AtkState state;
  gboolean value;

  if (g_strcmp0 (pspec->name, "has-focus") == 0)
    /*
     * We use focus-in-event and focus-out-event signals to catch
     * focus changes so we ignore this.
     */
    return;
  else if (g_strcmp0 (pspec->name, "tooltip-text") == 0)
    {
      gtk_widget_accessible_update_tooltip (GTK_WIDGET_ACCESSIBLE (atk_obj),
                                            widget);
      return;
    }
  else if (g_strcmp0 (pspec->name, "visible") == 0)
    {
      state = ATK_STATE_VISIBLE;
      value = gtk_widget_get_visible (widget);
    }
  else if (g_strcmp0 (pspec->name, "sensitive") == 0)
    {
      state = ATK_STATE_SENSITIVE;
      value = gtk_widget_get_sensitive (widget);
    }
  else if (g_strcmp0 (pspec->name, "orientation") == 0 &&
           GTK_IS_ORIENTABLE (widget))
    {
      GtkOrientable *orientable;

      orientable = GTK_ORIENTABLE (widget);

      state = ATK_STATE_HORIZONTAL;
      value = (gtk_orientable_get_orientation (orientable) == GTK_ORIENTATION_HORIZONTAL);
    }
  else
    return;

  atk_object_notify_state_change (atk_obj, state, value);
  if (state == ATK_STATE_SENSITIVE)
    atk_object_notify_state_change (atk_obj, ATK_STATE_ENABLED, value);

  if (state == ATK_STATE_HORIZONTAL)
    atk_object_notify_state_change (atk_obj, ATK_STATE_VERTICAL, !value);
}
Example #2
0
static AtkStateSet *
gtk_widget_accessible_ref_state_set (AtkObject *accessible)
{
  GtkWidget *widget;
  AtkStateSet *state_set;

  state_set = ATK_OBJECT_CLASS (_gtk_widget_accessible_parent_class)->ref_state_set (accessible);

  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
  if (widget == NULL)
    atk_state_set_add_state (state_set, ATK_STATE_DEFUNCT);
  else
    {
      if (gtk_widget_is_sensitive (widget))
        {
          atk_state_set_add_state (state_set, ATK_STATE_SENSITIVE);
          atk_state_set_add_state (state_set, ATK_STATE_ENABLED);
        }
  
      if (gtk_widget_get_can_focus (widget))
        {
          atk_state_set_add_state (state_set, ATK_STATE_FOCUSABLE);
        }
      /*
       * We do not currently generate notifications when an ATK object
       * corresponding to a GtkWidget changes visibility by being scrolled
       * on or off the screen.  The testcase for this is the main window
       * of the testgtk application in which a set of buttons in a GtkVBox
       * is in a scrolled window with a viewport.
       *
       * To generate the notifications we would need to do the following:
       * 1) Find the GtkViewport among the ancestors of the objects
       * 2) Create an accessible for the viewport
       * 3) Connect to the value-changed signal on the viewport
       * 4) When the signal is received we need to traverse the children
       *    of the viewport and check whether the children are visible or not
       *    visible; we may want to restrict this to the widgets for which
       *    accessible objects have been created.
       * 5) We probably need to store a variable on_screen in the
       *    GtkWidgetAccessible data structure so we can determine whether
       *    the value has changed.
       */
      if (gtk_widget_get_visible (widget))
        {
          atk_state_set_add_state (state_set, ATK_STATE_VISIBLE);
          if (gtk_widget_accessible_on_screen (widget) &&
              gtk_widget_get_mapped (widget) &&
              gtk_widget_accessible_all_parents_visible (widget))
            atk_state_set_add_state (state_set, ATK_STATE_SHOWING);
        }

      if (gtk_widget_has_focus (widget) && (widget == _focus_widget))
        {
          AtkObject *focus_obj;

          focus_obj = g_object_get_data (G_OBJECT (accessible), "gail-focus-object");
          if (focus_obj == NULL)
            atk_state_set_add_state (state_set, ATK_STATE_FOCUSED);
        }

      if (gtk_widget_has_default (widget))
        atk_state_set_add_state (state_set, ATK_STATE_DEFAULT);

      if (GTK_IS_ORIENTABLE (widget))
        {
          if (gtk_orientable_get_orientation (GTK_ORIENTABLE (widget)) == GTK_ORIENTATION_HORIZONTAL)
            atk_state_set_add_state (state_set, ATK_STATE_HORIZONTAL);
          else
            atk_state_set_add_state (state_set, ATK_STATE_VERTICAL);
        }
    }
  return state_set;
}