summaryrefslogtreecommitdiff
path: root/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBaseAccessible.cpp
blob: 7b069dd94f85aec28c06d795ab98e5da5b6bb278 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/*
 * Copyright (C) 2012 Igalia S.L.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "config.h"
#include "WebKitWebViewBaseAccessible.h"

#include "WebKitPrivate.h"
#include <gtk/gtk.h>

struct _WebKitWebViewBaseAccessiblePrivate {
    GtkWidget* widget;
};

WEBKIT_DEFINE_TYPE(WebKitWebViewBaseAccessible, webkit_web_view_base_accessible, ATK_TYPE_SOCKET)

static void webkitWebViewBaseAccessibleWidgetDestroyed(GtkWidget* widget, WebKitWebViewBaseAccessible* accessible)
{
    accessible->priv->widget = 0;
    atk_object_notify_state_change(ATK_OBJECT(accessible), ATK_STATE_DEFUNCT, TRUE);
}

static void webkitWebViewBaseAccessibleInitialize(AtkObject* atkObject, gpointer data)
{
    if (ATK_OBJECT_CLASS(webkit_web_view_base_accessible_parent_class)->initialize)
        ATK_OBJECT_CLASS(webkit_web_view_base_accessible_parent_class)->initialize(atkObject, data);

    if (data && GTK_IS_WIDGET(data)) {
        WebKitWebViewBaseAccessible* accessible = WEBKIT_WEB_VIEW_BASE_ACCESSIBLE(atkObject);
        accessible->priv->widget = GTK_WIDGET(data);

        g_signal_connect_after(accessible->priv->widget, "destroy",
                               G_CALLBACK(webkitWebViewBaseAccessibleWidgetDestroyed), atkObject);
    }

    atk_object_set_role(atkObject, ATK_ROLE_FILLER);
}

static AtkStateSet* webkitWebViewBaseAccessibleRefStateSet(AtkObject* atkObject)
{
    WebKitWebViewBaseAccessible* accessible = WEBKIT_WEB_VIEW_BASE_ACCESSIBLE(atkObject);

    AtkStateSet* stateSet;
    if (accessible->priv->widget) {
        // Use the implementation of AtkSocket if the widget is still alive.
        stateSet = ATK_OBJECT_CLASS(webkit_web_view_base_accessible_parent_class)->ref_state_set(atkObject);
    } else {
        // If the widget is no longer alive, save some remote calls
        // (because of AtkSocket's implementation of ref_state_set())
        // and just return that this AtkObject is defunct.
        stateSet = atk_state_set_new();
        atk_state_set_add_state(stateSet, ATK_STATE_DEFUNCT);
    }

    return stateSet;
}

static gint webkitWebViewBaseAccessibleGetIndexInParent(AtkObject* atkObject)
{
    AtkObject* atkParent = atk_object_get_parent(atkObject);
    if (!atkParent)
        return -1;

    guint count = atk_object_get_n_accessible_children(atkParent);
    for (guint i = 0; i < count; ++i) {
        AtkObject* child = atk_object_ref_accessible_child(atkParent, i);
        bool childIsObject = child == atkObject;
        g_object_unref(child);
        if (childIsObject)
            return i;
    }

    return -1;
}

static void webkit_web_view_base_accessible_class_init(WebKitWebViewBaseAccessibleClass* klass)
{
    // No need to implement get_n_children() and ref_child() here
    // since this is a subclass of AtkSocket and all the logic related
    // to those functions will be implemented by the ATK bridge.
    AtkObjectClass* atkObjectClass = ATK_OBJECT_CLASS(klass);
    atkObjectClass->initialize = webkitWebViewBaseAccessibleInitialize;
    atkObjectClass->ref_state_set = webkitWebViewBaseAccessibleRefStateSet;
    atkObjectClass->get_index_in_parent = webkitWebViewBaseAccessibleGetIndexInParent;
}

WebKitWebViewBaseAccessible* webkitWebViewBaseAccessibleNew(GtkWidget* widget)
{
    AtkObject* object = ATK_OBJECT(g_object_new(WEBKIT_TYPE_WEB_VIEW_BASE_ACCESSIBLE, NULL));
    atk_object_initialize(object, widget);
    return WEBKIT_WEB_VIEW_BASE_ACCESSIBLE(object);
}