summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authordmazzoni@chromium.org <dmazzoni@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-23 17:04:35 +0000
committerdmazzoni@chromium.org <dmazzoni@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-23 17:04:35 +0000
commit2b8002791e925dcdab88ebe1b74eb416f3b2d585 (patch)
tree3a7cdaad36988199d0499e12d7b561b31806ed87 /chrome/browser
parentbf767417d66c4d54761dd619cfb93838bdc2353a (diff)
downloadchromium_src-2b8002791e925dcdab88ebe1b74eb416f3b2d585.zip
chromium_src-2b8002791e925dcdab88ebe1b74eb416f3b2d585.tar.gz
chromium_src-2b8002791e925dcdab88ebe1b74eb416f3b2d585.tar.bz2
Add support for more types of controls and events to GTK implementation of
accessibility extension API. Enable accessibility API for all subdialogs of the main Options dialog. BUG=none TEST=none Review URL: http://codereview.chromium.org/651037 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@39738 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/accessibility_events.cc8
-rw-r--r--chrome/browser/accessibility_events.h48
-rw-r--r--chrome/browser/extensions/extension_accessibility_api.cc6
-rw-r--r--chrome/browser/extensions/extension_accessibility_api.h2
-rw-r--r--chrome/browser/extensions/extension_accessibility_api_constants.cc1
-rw-r--r--chrome/browser/extensions/extension_accessibility_api_constants.h1
-rw-r--r--chrome/browser/gtk/accessibility_event_router_gtk.cc278
-rw-r--r--chrome/browser/gtk/accessibility_event_router_gtk.h51
-rw-r--r--chrome/browser/gtk/accessible_widget_helper_gtk.cc21
-rw-r--r--chrome/browser/gtk/accessible_widget_helper_gtk.h7
-rw-r--r--chrome/browser/gtk/clear_browsing_data_dialog_gtk.cc14
-rw-r--r--chrome/browser/gtk/clear_browsing_data_dialog_gtk.h7
-rw-r--r--chrome/browser/gtk/edit_search_engine_dialog.cc30
-rw-r--r--chrome/browser/gtk/edit_search_engine_dialog.h8
-rw-r--r--chrome/browser/gtk/import_dialog_gtk.cc17
-rw-r--r--chrome/browser/gtk/import_dialog_gtk.h8
-rw-r--r--chrome/browser/gtk/keyword_editor_view.cc15
-rw-r--r--chrome/browser/gtk/keyword_editor_view.h6
-rw-r--r--chrome/browser/gtk/options/content_settings_window_gtk.cc24
-rw-r--r--chrome/browser/gtk/options/content_settings_window_gtk.h4
-rw-r--r--chrome/browser/gtk/options/general_page_gtk.cc10
-rw-r--r--chrome/browser/gtk/options/general_page_gtk.h4
-rw-r--r--chrome/browser/gtk/options/options_window_gtk.cc27
-rw-r--r--chrome/browser/gtk/options/passwords_exceptions_window_gtk.cc14
-rw-r--r--chrome/browser/gtk/options/url_picker_dialog_gtk.cc12
-rw-r--r--chrome/browser/gtk/options/url_picker_dialog_gtk.h6
26 files changed, 518 insertions, 111 deletions
diff --git a/chrome/browser/accessibility_events.cc b/chrome/browser/accessibility_events.cc
index fa1820a..b300183 100644
--- a/chrome/browser/accessibility_events.cc
+++ b/chrome/browser/accessibility_events.cc
@@ -79,3 +79,11 @@ void AccessibilityTextBoxInfo::SerializeToDict(DictionaryValue *dict) const {
dict->SetInteger(keys::kSelectionStartKey, selection_start_);
dict->SetInteger(keys::kSelectionEndKey, selection_end_);
}
+
+void AccessibilityListBoxInfo::SerializeToDict(DictionaryValue *dict) const {
+ AccessibilityControlInfo::SerializeToDict(dict);
+ dict->SetString(keys::kTypeKey, keys::kTypeListBox);
+ dict->SetString(keys::kValueKey, value_);
+ dict->SetInteger(keys::kItemIndexKey, item_index_);
+ dict->SetInteger(keys::kItemCountKey, item_count_);
+}
diff --git a/chrome/browser/accessibility_events.h b/chrome/browser/accessibility_events.h
index 2ef7535..da9189c 100644
--- a/chrome/browser/accessibility_events.h
+++ b/chrome/browser/accessibility_events.h
@@ -88,7 +88,8 @@ class AccessibilityRadioButtonInfo : public AccessibilityControlInfo {
: AccessibilityControlInfo(profile, name),
checked_(checked),
item_index_(item_index),
- item_count_(item_count) { }
+ item_count_(item_count) {
+ }
virtual void SerializeToDict(DictionaryValue *dict) const;
@@ -109,7 +110,8 @@ class AccessibilityCheckboxInfo : public AccessibilityControlInfo {
std::string name,
bool checked)
: AccessibilityControlInfo(profile, name),
- checked_(checked) { }
+ checked_(checked) {
+ }
virtual void SerializeToDict(DictionaryValue *dict) const;
@@ -129,7 +131,8 @@ class AccessibilityTabInfo : public AccessibilityControlInfo {
int tab_count)
: AccessibilityControlInfo(profile, tab_name),
tab_index_(tab_index),
- tab_count_(tab_count) { }
+ tab_count_(tab_count) {
+ }
virtual void SerializeToDict(DictionaryValue *dict) const;
@@ -156,7 +159,8 @@ class AccessibilityComboBoxInfo : public AccessibilityControlInfo {
: AccessibilityControlInfo(profile, name),
value_(value),
item_index_(item_index),
- item_count_(item_count) { }
+ item_count_(item_count) {
+ }
virtual void SerializeToDict(DictionaryValue *dict) const;
@@ -168,7 +172,7 @@ class AccessibilityComboBoxInfo : public AccessibilityControlInfo {
private:
std::string value_;
// The 0-based index of the current item and the number of total items.
- // If the value is not one of the drop-down options, item_index_ should
+ // If the value is not one of the drop-down options, |item_index_| should
// be -1.
int item_index_;
int item_count_;
@@ -185,7 +189,8 @@ class AccessibilityTextBoxInfo : public AccessibilityControlInfo {
value_(""),
password_(password),
selection_start_(0),
- selection_end_(0) { }
+ selection_end_(0) {
+ }
virtual void SerializeToDict(DictionaryValue *dict) const;
@@ -202,4 +207,35 @@ class AccessibilityTextBoxInfo : public AccessibilityControlInfo {
int selection_end_;
};
+// Accessibility information about a combo box passed to onControlFocused
+// and onControlAction event listeners.
+class AccessibilityListBoxInfo : public AccessibilityControlInfo {
+ public:
+ AccessibilityListBoxInfo(Profile* profile,
+ std::string name,
+ std::string value,
+ int item_index,
+ int item_count)
+ : AccessibilityControlInfo(profile, name),
+ value_(value),
+ item_index_(item_index),
+ item_count_(item_count) {
+ }
+
+ virtual void SerializeToDict(DictionaryValue *dict) const;
+
+ void SetValue(int item_index, std::string value) {
+ item_index_ = item_index;
+ value_ = value;
+ }
+
+ private:
+ std::string value_;
+ // The 0-based index of the current item and the number of total items.
+ // If the value is not one of the drop-down options, |item_index_| should
+ // be -1.
+ int item_index_;
+ int item_count_;
+};
+
#endif // CHROME_BROWSER_ACCESSIBILITY_EVENTS_H_
diff --git a/chrome/browser/extensions/extension_accessibility_api.cc b/chrome/browser/extensions/extension_accessibility_api.cc
index 24428af..2ea3775 100644
--- a/chrome/browser/extensions/extension_accessibility_api.cc
+++ b/chrome/browser/extensions/extension_accessibility_api.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/extensions/extension_tabs_module.h"
#include "base/json/json_writer.h"
+#include "base/stl_util-inl.h"
#include "base/string_util.h"
#include "base/values.h"
#include "chrome/browser/browser.h"
@@ -38,6 +39,11 @@ ExtensionAccessibilityEventRouter*
return Singleton<ExtensionAccessibilityEventRouter>::get();
}
+ExtensionAccessibilityEventRouter::~ExtensionAccessibilityEventRouter() {
+ STLDeleteElements(&on_enabled_listeners_);
+ STLDeleteElements(&on_disabled_listeners_);
+}
+
void ExtensionAccessibilityEventRouter::ObserveProfile(Profile* profile) {
last_focused_control_dict_.Clear();
diff --git a/chrome/browser/extensions/extension_accessibility_api.h b/chrome/browser/extensions/extension_accessibility_api.h
index fb3cb8d..9325dfb 100644
--- a/chrome/browser/extensions/extension_accessibility_api.h
+++ b/chrome/browser/extensions/extension_accessibility_api.h
@@ -47,7 +47,7 @@ class ExtensionAccessibilityEventRouter : public NotificationObserver {
ExtensionAccessibilityEventRouter()
: enabled_(false) {}
- virtual ~ExtensionAccessibilityEventRouter() {}
+ virtual ~ExtensionAccessibilityEventRouter();
// NotificationObserver::Observe.
virtual void Observe(NotificationType type,
diff --git a/chrome/browser/extensions/extension_accessibility_api_constants.cc b/chrome/browser/extensions/extension_accessibility_api_constants.cc
index 72d6138..8f52e14 100644
--- a/chrome/browser/extensions/extension_accessibility_api_constants.cc
+++ b/chrome/browser/extensions/extension_accessibility_api_constants.cc
@@ -30,6 +30,7 @@ extern const char kTypeButton[] = "button";
extern const char kTypeCheckbox[] = "checkbox";
extern const char kTypeComboBox[] = "combobox";
extern const char kTypeLink[] = "link";
+extern const char kTypeListBox[] = "listbox";
extern const char kTypeRadioButton[] = "radiobutton";
extern const char kTypeTab[] = "tab";
extern const char kTypeTextBox[] = "textbox";
diff --git a/chrome/browser/extensions/extension_accessibility_api_constants.h b/chrome/browser/extensions/extension_accessibility_api_constants.h
index 2020ec8..37a7210 100644
--- a/chrome/browser/extensions/extension_accessibility_api_constants.h
+++ b/chrome/browser/extensions/extension_accessibility_api_constants.h
@@ -33,6 +33,7 @@ extern const char kTypeButton[];
extern const char kTypeCheckbox[];
extern const char kTypeComboBox[];
extern const char kTypeLink[];
+extern const char kTypeListBox[];
extern const char kTypeRadioButton[];
extern const char kTypeTab[];
extern const char kTypeTextBox[];
diff --git a/chrome/browser/gtk/accessibility_event_router_gtk.cc b/chrome/browser/gtk/accessibility_event_router_gtk.cc
index f912fa7..833a47d 100644
--- a/chrome/browser/gtk/accessibility_event_router_gtk.cc
+++ b/chrome/browser/gtk/accessibility_event_router_gtk.cc
@@ -6,6 +6,7 @@
#include "base/basictypes.h"
#include "base/callback.h"
+#include "base/message_loop.h"
#include "base/stl_util-inl.h"
#include "chrome/browser/extensions/extension_accessibility_api.h"
#include "chrome/browser/gtk/gtk_chrome_link_button.h"
@@ -23,8 +24,8 @@ gboolean OnWidgetFocused(GSignalInvocationHint *ihint,
const GValue* param_values,
gpointer user_data) {
GtkWidget* widget = GTK_WIDGET(g_value_get_object(param_values));
- reinterpret_cast<AccessibilityEventRouter *>(user_data)
- ->DispatchAccessibilityNotification(
+ reinterpret_cast<AccessibilityEventRouter *>(user_data)->
+ DispatchAccessibilityNotification(
widget, NotificationType::ACCESSIBILITY_CONTROL_FOCUSED);
return true;
}
@@ -37,8 +38,8 @@ gboolean OnButtonClicked(GSignalInvocationHint *ihint,
// Skip toggle buttons because we're also listening on "toggle" events.
if (GTK_IS_TOGGLE_BUTTON(widget))
return true;
- reinterpret_cast<AccessibilityEventRouter *>(user_data)
- ->DispatchAccessibilityNotification(
+ reinterpret_cast<AccessibilityEventRouter *>(user_data)->
+ DispatchAccessibilityNotification(
widget, NotificationType::ACCESSIBILITY_CONTROL_ACTION);
return true;
}
@@ -54,26 +55,72 @@ gboolean OnButtonToggled(GSignalInvocationHint *ihint,
// a different radio button the group.
if (GTK_IS_RADIO_BUTTON(widget) && !checked)
return true;
- reinterpret_cast<AccessibilityEventRouter *>(user_data)
- ->DispatchAccessibilityNotification(
+ reinterpret_cast<AccessibilityEventRouter *>(user_data)->
+ DispatchAccessibilityNotification(
widget, NotificationType::ACCESSIBILITY_CONTROL_ACTION);
return true;
}
-gboolean OnSwitchPage(GSignalInvocationHint *ihint,
- guint n_param_values,
- const GValue* param_values,
- gpointer user_data) {
+gboolean OnPageSwitched(GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue* param_values,
+ gpointer user_data) {
GtkWidget* widget = GTK_WIDGET(g_value_get_object(param_values));
- reinterpret_cast<AccessibilityEventRouter *>(user_data)
- ->DispatchAccessibilityNotification(
+ // The page hasn't switched yet, so defer calling
+ // DispatchAccessibilityNotification.
+ reinterpret_cast<AccessibilityEventRouter *>(user_data)->
+ PostDispatchAccessibilityNotification(
widget, NotificationType::ACCESSIBILITY_CONTROL_ACTION);
return true;
}
+gboolean OnComboBoxChanged(GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue* param_values,
+ gpointer user_data) {
+ GtkWidget* widget = GTK_WIDGET(g_value_get_object(param_values));
+ if (!GTK_IS_COMBO_BOX(widget))
+ return true;
+ reinterpret_cast<AccessibilityEventRouter *>(user_data)->
+ DispatchAccessibilityNotification(
+ widget, NotificationType::ACCESSIBILITY_CONTROL_ACTION);
+ return true;
+}
+
+gboolean OnTreeViewCursorChanged(GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue* param_values,
+ gpointer user_data) {
+ GtkWidget* widget = GTK_WIDGET(g_value_get_object(param_values));
+ if (!GTK_IS_TREE_VIEW(widget)) {
+ return true;
+ }
+ reinterpret_cast<AccessibilityEventRouter *>(user_data)->
+ DispatchAccessibilityNotification(
+ widget, NotificationType::ACCESSIBILITY_CONTROL_ACTION);
+ return true;
+}
+
+gboolean OnEntryChanged(GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue* param_values,
+ gpointer user_data) {
+ GtkWidget* widget = GTK_WIDGET(g_value_get_object(param_values));
+ if (!GTK_IS_ENTRY(widget)) {
+ return true;
+ }
+ // The text hasn't changed yet, so defer calling
+ // DispatchAccessibilityNotification.
+ reinterpret_cast<AccessibilityEventRouter *>(user_data)->
+ PostDispatchAccessibilityNotification(
+ widget, NotificationType::ACCESSIBILITY_TEXT_CHANGED);
+ return true;
+}
+
} // anonymous namespace
-AccessibilityEventRouter::AccessibilityEventRouter() {
+AccessibilityEventRouter::AccessibilityEventRouter()
+ : method_factory_(this) {
// We don't want our event listeners to be installed if accessibility is
// disabled. Install listeners so we can install and uninstall them as
// needed, then install them now if it's currently enabled.
@@ -90,41 +137,60 @@ AccessibilityEventRouter::AccessibilityEventRouter() {
}
}
+AccessibilityEventRouter::~AccessibilityEventRouter() {
+ RemoveEventListeners();
+}
+
// static
AccessibilityEventRouter* AccessibilityEventRouter::GetInstance() {
return Singleton<AccessibilityEventRouter>::get();
}
+void AccessibilityEventRouter::InstallEventListener(
+ const char* signal_name,
+ GType widget_type,
+ GSignalEmissionHook hook_func) {
+ guint signal_id = g_signal_lookup(signal_name, widget_type);
+ gulong hook_id = g_signal_add_emission_hook(
+ signal_id, 0, hook_func, reinterpret_cast<gpointer>(this), NULL);
+ installed_hooks_.push_back(InstalledHook(signal_id, hook_id));
+}
+
void AccessibilityEventRouter::InstallEventListeners() {
- // Create and destroy a GtkNotebook to ensure this module is loaded,
- // otherwise we can't lookup its signals. All of the other modules we
- // need will already be loaded by the time we get here.
+ // Create and destroy each type of widget we need signals for,
+ // to ensure their modules are loaded, otherwise g_signal_lookup
+ // might fail.
+ g_object_unref(g_object_ref_sink(gtk_combo_box_new()));
+ g_object_unref(g_object_ref_sink(gtk_entry_new()));
g_object_unref(g_object_ref_sink(gtk_notebook_new()));
+ g_object_unref(g_object_ref_sink(gtk_toggle_button_new()));
+ g_object_unref(g_object_ref_sink(gtk_tree_view_new()));
// Add signal emission hooks for the events we're interested in.
- focus_hook_ = g_signal_add_emission_hook(
- g_signal_lookup("focus-in-event", GTK_TYPE_WIDGET),
- 0, OnWidgetFocused, (gpointer)this, NULL);
- click_hook_ = g_signal_add_emission_hook(
- g_signal_lookup("clicked", GTK_TYPE_BUTTON),
- 0, OnButtonClicked, (gpointer)this, NULL);
- toggle_hook_ = g_signal_add_emission_hook(
- g_signal_lookup("toggled", GTK_TYPE_TOGGLE_BUTTON),
- 0, OnButtonToggled, (gpointer)this, NULL);
- switch_page_hook_ = g_signal_add_emission_hook(
- g_signal_lookup("switch-page", GTK_TYPE_NOTEBOOK),
- 0, OnSwitchPage, (gpointer)this, NULL);
+ InstallEventListener("clicked", GTK_TYPE_BUTTON, OnButtonClicked);
+ InstallEventListener("changed", GTK_TYPE_COMBO_BOX, OnComboBoxChanged);
+ InstallEventListener("cursor-changed", GTK_TYPE_TREE_VIEW,
+ OnTreeViewCursorChanged);
+ InstallEventListener("changed", GTK_TYPE_ENTRY, OnEntryChanged);
+ InstallEventListener("insert-text", GTK_TYPE_ENTRY, OnEntryChanged);
+ InstallEventListener("delete-text", GTK_TYPE_ENTRY, OnEntryChanged);
+ InstallEventListener("move-cursor", GTK_TYPE_ENTRY, OnEntryChanged);
+ InstallEventListener("focus-in-event", GTK_TYPE_WIDGET, OnWidgetFocused);
+ InstallEventListener("switch-page", GTK_TYPE_NOTEBOOK, OnPageSwitched);
+ InstallEventListener("toggled", GTK_TYPE_TOGGLE_BUTTON, OnButtonToggled);
+
+ listening_ = true;
}
void AccessibilityEventRouter::RemoveEventListeners() {
- g_signal_remove_emission_hook(
- g_signal_lookup("focus-in-event", GTK_TYPE_WIDGET), focus_hook_);
- g_signal_remove_emission_hook(
- g_signal_lookup("clicked", GTK_TYPE_BUTTON), click_hook_);
- g_signal_remove_emission_hook(
- g_signal_lookup("toggled", GTK_TYPE_TOGGLE_BUTTON), toggle_hook_);
- g_signal_remove_emission_hook(
- g_signal_lookup("switch-page", GTK_TYPE_NOTEBOOK), switch_page_hook_);
+ for (size_t i = 0; i < installed_hooks_.size(); i++) {
+ g_signal_remove_emission_hook(
+ installed_hooks_[i].signal_id,
+ installed_hooks_[i].hook_id);
+ }
+ installed_hooks_.clear();
+
+ listening_ = false;
}
void AccessibilityEventRouter::AddRootWidget(
@@ -190,16 +256,34 @@ std::string AccessibilityEventRouter::GetWidgetName(GtkWidget* widget) {
}
}
+void AccessibilityEventRouter::StartListening() {
+ listening_ = true;
+}
+
+void AccessibilityEventRouter::StopListening() {
+ listening_ = false;
+}
+
void AccessibilityEventRouter::DispatchAccessibilityNotification(
GtkWidget* widget, NotificationType type) {
+ if (!listening_)
+ return;
Profile *profile;
if (!IsWidgetAccessible(widget, &profile))
return;
// The order of these checks matters, because, for example, a radio button
- // is a subclass of button. We need to catch the most specific type that
- // we can handle for each object.
- if (GTK_IS_RADIO_BUTTON(widget)) {
+ // is a subclass of button, and a combo box is a composite control where
+ // the focus event goes to the button that's a child of the combo box.
+ GtkWidget* parent = gtk_widget_get_parent(widget);
+ if (parent && GTK_IS_BUTTON(widget) && GTK_IS_TREE_VIEW(parent)) {
+ // This is a list box column header. Currently not supported.
+ return;
+ } else if (GTK_IS_COMBO_BOX(widget)) {
+ SendComboBoxNotification(widget, type, profile);
+ } else if (parent && GTK_IS_COMBO_BOX(parent)) {
+ SendComboBoxNotification(parent, type, profile);
+ } else if (GTK_IS_RADIO_BUTTON(widget)) {
SendRadioButtonNotification(widget, type, profile);
} else if (GTK_IS_TOGGLE_BUTTON(widget)) {
SendCheckboxNotification(widget, type, profile);
@@ -209,7 +293,32 @@ void AccessibilityEventRouter::DispatchAccessibilityNotification(
SendTextBoxNotification(widget, type, profile);
} else if (GTK_IS_NOTEBOOK(widget)) {
SendTabNotification(widget, type, profile);
+ } else if (GTK_IS_TREE_VIEW(widget)) {
+ SendListBoxNotification(widget, type, profile);
+ } else {
+ // If we have no idea what this control is, return and skip the
+ // temporary pause in event listening.
+ return;
}
+
+ // After this method returns, additional signal handlers will run,
+ // which will sometimes generate additional signals. To avoid
+ // generating redundant accessibility notifications for the same
+ // initial event, stop listening to all signals generated from now
+ // until this posted task runs.
+ StopListening();
+ MessageLoop::current()->PostTask(
+ FROM_HERE, method_factory_.NewRunnableMethod(
+ &AccessibilityEventRouter::StartListening));
+}
+
+void AccessibilityEventRouter::PostDispatchAccessibilityNotification(
+ GtkWidget* widget, NotificationType type) {
+ MessageLoop::current()->PostTask(
+ FROM_HERE, method_factory_.NewRunnableMethod(
+ &AccessibilityEventRouter::DispatchAccessibilityNotification,
+ widget,
+ type));
}
void AccessibilityEventRouter::SendRadioButtonNotification(
@@ -285,3 +394,94 @@ void AccessibilityEventRouter::SendTabNotification(
AccessibilityTabInfo info(profile, name, index, page_count);
SendAccessibilityNotification(type, &info);
}
+
+void AccessibilityEventRouter::SendComboBoxNotification(
+ GtkWidget* widget, NotificationType type, Profile* profile) {
+ // Get the index of the selected item. Will return -1 if no item is
+ // active, which matches the semantics of the extension API.
+ int index = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
+
+ // Get the number of items.
+ GtkTreeModel* model = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
+ int count = gtk_tree_model_iter_n_children(model, NULL);
+
+ // Get the value of the current item, if possible. Note that the
+ // model behind the combo box could be arbitrarily complex in theory,
+ // but this code just handles flat lists where the first string column
+ // contains the display value.
+ std::string value;
+ int string_column_index = -1;
+ for (int i = 0; i < gtk_tree_model_get_n_columns(model); i++) {
+ if (gtk_tree_model_get_column_type(model, i) == G_TYPE_STRING) {
+ string_column_index = i;
+ break;
+ }
+ }
+ if (string_column_index) {
+ GtkTreeIter iter;
+ if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(widget), &iter)) {
+ GValue gvalue = { 0 };
+ gtk_tree_model_get_value(model, &iter, string_column_index, &gvalue);
+ const char* string_value = g_value_get_string(&gvalue);
+ if (string_value) {
+ value = string_value;
+ }
+ g_value_unset(&gvalue);
+ }
+ } else {
+ // Otherwise this must be a gtk_combo_box_text, in which case this
+ // function will return the value of the current item, instead.
+ value = gtk_combo_box_get_active_text(GTK_COMBO_BOX(widget));
+ }
+
+ // Get the name of this combo box.
+ std::string name = GetWidgetName(widget);
+
+ // Send the notification.
+ AccessibilityComboBoxInfo info(profile, name, value, index, count);
+ SendAccessibilityNotification(type, &info);
+}
+
+void AccessibilityEventRouter::SendListBoxNotification(
+ GtkWidget* widget, NotificationType type, Profile* profile) {
+ // Get the number of items.
+ GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(widget));
+ int count = gtk_tree_model_iter_n_children(model, NULL);
+
+ // Get the current selected index and its value.
+ int index = -1;
+ std::string value;
+ GtkTreePath* path;
+ gtk_tree_view_get_cursor(GTK_TREE_VIEW(widget), &path, NULL);
+ if (path != NULL) {
+ gint* indices = gtk_tree_path_get_indices(path);
+ if (indices)
+ index = indices[0];
+
+ GtkTreeIter iter;
+ if (gtk_tree_model_get_iter(model, &iter, path)) {
+ for (int i = 0; i < gtk_tree_model_get_n_columns(model); i++) {
+ if (gtk_tree_model_get_column_type(model, i) == G_TYPE_STRING) {
+ GValue gvalue = { 0 };
+ gtk_tree_model_get_value(model, &iter, i, &gvalue);
+ const char* string_value = g_value_get_string(&gvalue);
+ if (string_value) {
+ if (!value.empty())
+ value += " ";
+ value += string_value;
+ }
+ g_value_unset(&gvalue);
+ }
+ }
+ }
+
+ gtk_tree_path_free(path);
+ }
+
+ // Get the name of this control.
+ std::string name = GetWidgetName(widget);
+
+ // Send the notification.
+ AccessibilityListBoxInfo info(profile, name, value, index, count);
+ SendAccessibilityNotification(type, &info);
+}
diff --git a/chrome/browser/gtk/accessibility_event_router_gtk.h b/chrome/browser/gtk/accessibility_event_router_gtk.h
index 7943ea4..57c65d9 100644
--- a/chrome/browser/gtk/accessibility_event_router_gtk.h
+++ b/chrome/browser/gtk/accessibility_event_router_gtk.h
@@ -13,6 +13,7 @@
#include "base/basictypes.h"
#include "base/hash_tables.h"
#include "base/singleton.h"
+#include "base/task.h"
#include "chrome/browser/accessibility_events.h"
class Profile;
@@ -27,6 +28,14 @@ struct hash<GtkWidget*> {
};
} // namespace __gnu_cxx
+// Struct to keep track of event listener hook ids to remove them later.
+struct InstalledHook {
+ InstalledHook(guint _signal_id, gulong _hook_id)
+ : signal_id(_signal_id), hook_id(_hook_id) { }
+ guint signal_id;
+ gulong hook_id;
+};
+
// Singleton class that adds a signal emission hook to many gtk events, and
// then sends an accessibility notification whenever a relevant event is
// sent to an accessible control.
@@ -43,6 +52,8 @@ class AccessibilityEventRouter {
// Internal information about a particular widget to override the
// information we get directly from gtk.
struct WidgetInfo {
+ WidgetInfo() : ignore(false) { }
+
// If nonempty, will use this name instead of the widget's label.
std::string name;
@@ -89,25 +100,46 @@ class AccessibilityEventRouter {
void DispatchAccessibilityNotification(
GtkWidget* widget, NotificationType type);
+ // Post a task to call DispatchAccessibilityNotification the next time
+ // through the event loop.
+ void PostDispatchAccessibilityNotification(
+ GtkWidget* widget, NotificationType type);
+
// Each of these methods constructs an AccessibilityControlInfo object
// and sends a notification of a specific accessibility event.
- void SendRadioButtonNotification(
+ void SendButtonNotification(
GtkWidget* widget, NotificationType type, Profile* profile);
void SendCheckboxNotification(
GtkWidget* widget, NotificationType type, Profile* profile);
- void SendButtonNotification(
+ void SendComboBoxNotification(
GtkWidget* widget, NotificationType type, Profile* profile);
- void SendTextBoxNotification(
+ void SendListBoxNotification(
+ GtkWidget* widget, NotificationType type, Profile* profile);
+ void SendRadioButtonNotification(
GtkWidget* widget, NotificationType type, Profile* profile);
void SendTabNotification(
GtkWidget* widget, NotificationType type, Profile* profile);
+ void SendTextBoxNotification(
+ GtkWidget* widget, NotificationType type, Profile* profile);
void InstallEventListeners();
void RemoveEventListeners();
+ // Start and stop listening to signals.
+ void StartListening();
+ void StopListening();
+
private:
AccessibilityEventRouter();
- virtual ~AccessibilityEventRouter() {}
+ virtual ~AccessibilityEventRouter();
+
+ // Add a signal emission hook for one particular signal name and
+ // widget type, and save the hook_id in installed_hooks so we can
+ // remove it later.
+ void InstallEventListener(
+ const char *signal_name,
+ GType widget_type,
+ GSignalEmissionHook hook_func);
friend struct DefaultSingletonTraits<AccessibilityEventRouter>;
@@ -119,12 +151,13 @@ class AccessibilityEventRouter {
base::hash_map<GtkWidget*, WidgetInfo> widget_info_map_;
// Installed event listener hook ids so we can remove them later.
- gulong focus_hook_;
- gulong click_hook_;
- gulong toggle_hook_;
- gulong switch_page_hook_;
+ std::vector<InstalledHook> installed_hooks_;
+
+ // True if we are currently listening to signals.
+ bool listening_;
- std::vector<gulong> event_listener_hook_ids_;
+ // Used to schedule invocations of StartListening().
+ ScopedRunnableMethodFactory<AccessibilityEventRouter> method_factory_;
};
#endif // CHROME_BROWSER_GTK_ACCESSIBILITY_EVENT_ROUTER_GTK_H_
diff --git a/chrome/browser/gtk/accessible_widget_helper_gtk.cc b/chrome/browser/gtk/accessible_widget_helper_gtk.cc
index 64710b1..e54c6ff 100644
--- a/chrome/browser/gtk/accessible_widget_helper_gtk.cc
+++ b/chrome/browser/gtk/accessible_widget_helper_gtk.cc
@@ -5,16 +5,27 @@
#include "chrome/browser/gtk/accessible_widget_helper_gtk.h"
#include "app/l10n_util.h"
+#include "chrome/browser/accessibility_events.h"
#include "chrome/browser/profile.h"
+#include "chrome/common/notification_service.h"
AccessibleWidgetHelper::AccessibleWidgetHelper(
GtkWidget* root_widget, Profile* profile)
: accessibility_event_router_(AccessibilityEventRouter::GetInstance()),
+ profile_(profile),
root_widget_(root_widget) {
accessibility_event_router_->AddRootWidget(root_widget_, profile);
}
AccessibleWidgetHelper::~AccessibleWidgetHelper() {
+ if (!window_title_.empty()) {
+ AccessibilityWindowInfo info(profile_, window_title_);
+ NotificationService::current()->Notify(
+ NotificationType::ACCESSIBILITY_WINDOW_CLOSED,
+ Source<Profile>(profile_),
+ Details<AccessibilityWindowInfo>(&info));
+ }
+
if (root_widget_)
accessibility_event_router_->RemoveRootWidget(root_widget_);
for (unsigned int i = 0; i < managed_widgets_.size(); i++) {
@@ -22,6 +33,16 @@ AccessibleWidgetHelper::~AccessibleWidgetHelper() {
}
}
+void AccessibleWidgetHelper::SendOpenWindowNotification(
+ const std::string& window_title) {
+ window_title_ = window_title;
+ AccessibilityWindowInfo info(profile_, window_title);
+ NotificationService::current()->Notify(
+ NotificationType::ACCESSIBILITY_WINDOW_OPENED,
+ Source<Profile>(profile_),
+ Details<AccessibilityWindowInfo>(&info));
+}
+
void AccessibleWidgetHelper::IgnoreWidget(GtkWidget* widget) {
accessibility_event_router_->IgnoreWidget(widget);
managed_widgets_.push_back(widget);
diff --git a/chrome/browser/gtk/accessible_widget_helper_gtk.h b/chrome/browser/gtk/accessible_widget_helper_gtk.h
index 94e9140..b677c39 100644
--- a/chrome/browser/gtk/accessible_widget_helper_gtk.h
+++ b/chrome/browser/gtk/accessible_widget_helper_gtk.h
@@ -38,6 +38,11 @@ class AccessibleWidgetHelper {
virtual ~AccessibleWidgetHelper();
+ // Send a notification that a new window was opened now, and a
+ // corresponding close window notification when this object
+ // goes out of scope.
+ void SendOpenWindowNotification(const std::string& window_title);
+
// Do not send accessibility events for this widget
void IgnoreWidget(GtkWidget* widget);
@@ -51,7 +56,9 @@ class AccessibleWidgetHelper {
private:
AccessibilityEventRouter* accessibility_event_router_;
+ Profile* profile_;
GtkWidget* root_widget_;
+ std::string window_title_;
std::vector<GtkWidget*> managed_widgets_;
};
diff --git a/chrome/browser/gtk/clear_browsing_data_dialog_gtk.cc b/chrome/browser/gtk/clear_browsing_data_dialog_gtk.cc
index 1e2e533..183f641 100644
--- a/chrome/browser/gtk/clear_browsing_data_dialog_gtk.cc
+++ b/chrome/browser/gtk/clear_browsing_data_dialog_gtk.cc
@@ -4,10 +4,13 @@
#include "chrome/browser/gtk/clear_browsing_data_dialog_gtk.h"
+#include <string>
+
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browsing_data_remover.h"
+#include "chrome/browser/gtk/accessible_widget_helper_gtk.h"
#include "chrome/browser/gtk/browser_window_gtk.h"
#include "chrome/browser/gtk/gtk_chrome_link_button.h"
#include "chrome/browser/pref_service.h"
@@ -26,13 +29,19 @@ ClearBrowsingDataDialogGtk::ClearBrowsingDataDialogGtk(GtkWindow* parent,
Profile* profile) :
profile_(profile), remover_(NULL) {
// Build the dialog.
+ std::string dialog_name = l10n_util::GetStringUTF8(
+ IDS_CLEAR_BROWSING_DATA_TITLE);
GtkWidget* dialog = gtk_dialog_new_with_buttons(
- l10n_util::GetStringUTF8(IDS_CLEAR_BROWSING_DATA_TITLE).c_str(),
+ dialog_name.c_str(),
parent,
(GtkDialogFlags) (GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR),
GTK_STOCK_CLOSE,
GTK_RESPONSE_REJECT,
NULL);
+
+ accessible_widget_helper_.reset(new AccessibleWidgetHelper(dialog, profile));
+ accessible_widget_helper_->SendOpenWindowNotification(dialog_name);
+
gtk_widget_realize(dialog);
gtk_util::SetWindowSizeFromResources(GTK_WINDOW(dialog),
IDS_CLEARDATA_DIALOG_WIDTH_CHARS,
@@ -164,6 +173,9 @@ ClearBrowsingDataDialogGtk::ClearBrowsingDataDialogGtk(GtkWindow* parent,
gtk_widget_show_all(dialog);
}
+ClearBrowsingDataDialogGtk::~ClearBrowsingDataDialogGtk() {
+}
+
void ClearBrowsingDataDialogGtk::OnDialogResponse(GtkWidget* widget,
int response) {
if (response == GTK_RESPONSE_ACCEPT) {
diff --git a/chrome/browser/gtk/clear_browsing_data_dialog_gtk.h b/chrome/browser/gtk/clear_browsing_data_dialog_gtk.h
index 896119e..ce452f6 100644
--- a/chrome/browser/gtk/clear_browsing_data_dialog_gtk.h
+++ b/chrome/browser/gtk/clear_browsing_data_dialog_gtk.h
@@ -6,10 +6,12 @@
#define CHROME_BROWSER_GTK_CLEAR_BROWSING_DATA_DIALOG_GTK_H_
#include "base/basictypes.h"
+#include "base/scoped_ptr.h"
typedef struct _GtkWidget GtkWidget;
typedef struct _GtkWindow GtkWindow;
+class AccessibleWidgetHelper;
class BrowsingDataRemover;
class Profile;
@@ -20,7 +22,7 @@ class ClearBrowsingDataDialogGtk {
private:
ClearBrowsingDataDialogGtk(GtkWindow* parent, Profile* profile);
- ~ClearBrowsingDataDialogGtk() { }
+ ~ClearBrowsingDataDialogGtk();
// Handler to respond to Ok and Cancel responses from the dialog.
static void HandleOnResponseDialog(GtkWidget* widget,
@@ -59,6 +61,9 @@ class ClearBrowsingDataDialogGtk {
// of deleting itself when done.
BrowsingDataRemover* remover_;
+ // Helper object to manage accessibility metadata.
+ scoped_ptr<AccessibleWidgetHelper> accessible_widget_helper_;
+
DISALLOW_COPY_AND_ASSIGN(ClearBrowsingDataDialogGtk);
};
diff --git a/chrome/browser/gtk/edit_search_engine_dialog.cc b/chrome/browser/gtk/edit_search_engine_dialog.cc
index 1aa3576..6830b63 100644
--- a/chrome/browser/gtk/edit_search_engine_dialog.cc
+++ b/chrome/browser/gtk/edit_search_engine_dialog.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -10,6 +10,7 @@
#include "app/resource_bundle.h"
#include "base/message_loop.h"
#include "base/string_util.h"
+#include "chrome/browser/gtk/accessible_widget_helper_gtk.h"
#include "chrome/browser/net/url_fixer_upper.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/search_engines/edit_search_engine_controller.h"
@@ -63,21 +64,27 @@ EditSearchEngineDialog::EditSearchEngineDialog(
Profile* profile)
: controller_(new EditSearchEngineController(template_url, delegate,
profile)) {
- Init(parent_window);
+ Init(parent_window, profile);
}
-void EditSearchEngineDialog::Init(GtkWindow* parent_window) {
+void EditSearchEngineDialog::Init(GtkWindow* parent_window, Profile* profile) {
+ std::string dialog_name = l10n_util::GetStringUTF8(
+ controller_->template_url() ?
+ IDS_SEARCH_ENGINES_EDITOR_EDIT_WINDOW_TITLE :
+ IDS_SEARCH_ENGINES_EDITOR_NEW_WINDOW_TITLE);
+
dialog_ = gtk_dialog_new_with_buttons(
- l10n_util::GetStringUTF8(
- controller_->template_url() ?
- IDS_SEARCH_ENGINES_EDITOR_EDIT_WINDOW_TITLE :
- IDS_SEARCH_ENGINES_EDITOR_NEW_WINDOW_TITLE).c_str(),
+ dialog_name.c_str(),
parent_window,
static_cast<GtkDialogFlags>(GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR),
GTK_STOCK_CANCEL,
GTK_RESPONSE_CANCEL,
NULL);
+ accessible_widget_helper_.reset(new AccessibleWidgetHelper(
+ dialog_, profile));
+ accessible_widget_helper_->SendOpenWindowNotification(dialog_name);
+
ok_button_ = gtk_dialog_add_button(GTK_DIALOG(dialog_),
controller_->template_url() ?
GTK_STOCK_SAVE :
@@ -110,6 +117,9 @@ void EditSearchEngineDialog::Init(GtkWindow* parent_window) {
gtk_entry_set_activates_default(GTK_ENTRY(title_entry_), TRUE);
g_signal_connect(title_entry_, "changed",
G_CALLBACK(OnEntryChanged), this);
+ accessible_widget_helper_->SetWidgetName(
+ title_entry_,
+ IDS_SEARCH_ENGINES_EDITOR_DESCRIPTION_LABEL);
keyword_entry_ = gtk_entry_new();
gtk_entry_set_activates_default(GTK_ENTRY(keyword_entry_), TRUE);
@@ -117,11 +127,17 @@ void EditSearchEngineDialog::Init(GtkWindow* parent_window) {
G_CALLBACK(OnEntryChanged), this);
g_signal_connect(keyword_entry_, "insert-text",
G_CALLBACK(LowercaseInsertTextHandler), NULL);
+ accessible_widget_helper_->SetWidgetName(
+ keyword_entry_,
+ IDS_SEARCH_ENGINES_EDITOR_KEYWORD_LABEL);
url_entry_ = gtk_entry_new();
gtk_entry_set_activates_default(GTK_ENTRY(url_entry_), TRUE);
g_signal_connect(url_entry_, "changed",
G_CALLBACK(OnEntryChanged), this);
+ accessible_widget_helper_->SetWidgetName(
+ url_entry_,
+ IDS_SEARCH_ENGINES_EDITOR_URL_LABEL);
title_image_ = gtk_image_new_from_pixbuf(NULL);
keyword_image_ = gtk_image_new_from_pixbuf(NULL);
diff --git a/chrome/browser/gtk/edit_search_engine_dialog.h b/chrome/browser/gtk/edit_search_engine_dialog.h
index 9635d9f..790a94d 100644
--- a/chrome/browser/gtk/edit_search_engine_dialog.h
+++ b/chrome/browser/gtk/edit_search_engine_dialog.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -11,6 +11,7 @@
#include "base/basictypes.h"
#include "base/scoped_ptr.h"
+class AccessibleWidgetHelper;
class EditSearchEngineController;
class EditSearchEngineControllerDelegate;
class Profile;
@@ -25,7 +26,7 @@ class EditSearchEngineDialog {
private:
// Create and show the window.
- void Init(GtkWindow* parent_window);
+ void Init(GtkWindow* parent_window, Profile* profile);
// Retrieve the user input in the various fields.
std::wstring GetTitleInput() const;
@@ -71,6 +72,9 @@ class EditSearchEngineDialog {
scoped_ptr<EditSearchEngineController> controller_;
+ // Helper object to manage accessibility metadata.
+ scoped_ptr<AccessibleWidgetHelper> accessible_widget_helper_;
+
DISALLOW_COPY_AND_ASSIGN(EditSearchEngineDialog);
};
diff --git a/chrome/browser/gtk/import_dialog_gtk.cc b/chrome/browser/gtk/import_dialog_gtk.cc
index 71546b2..fb3d92d 100644
--- a/chrome/browser/gtk/import_dialog_gtk.cc
+++ b/chrome/browser/gtk/import_dialog_gtk.cc
@@ -1,11 +1,14 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/gtk/import_dialog_gtk.h"
+#include <string>
+
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
+#include "chrome/browser/gtk/accessible_widget_helper_gtk.h"
#include "chrome/common/gtk_util.h"
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"
@@ -34,13 +37,20 @@ ImportDialogGtk::ImportDialogGtk(GtkWindow* parent, Profile* profile,
importer_host_(new ImporterHost()),
initial_state_(initial_state) {
// Build the dialog.
+ std::string dialog_name = l10n_util::GetStringUTF8(
+ IDS_IMPORT_SETTINGS_TITLE);
dialog_ = gtk_dialog_new_with_buttons(
- l10n_util::GetStringUTF8(IDS_IMPORT_SETTINGS_TITLE).c_str(),
+ dialog_name.c_str(),
parent,
(GtkDialogFlags) (GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR),
GTK_STOCK_CANCEL,
GTK_RESPONSE_REJECT,
NULL);
+
+ accessible_widget_helper_.reset(new AccessibleWidgetHelper(
+ dialog_, profile));
+ accessible_widget_helper_->SendOpenWindowNotification(dialog_name);
+
gtk_widget_realize(dialog_);
gtk_util::SetWindowSizeFromResources(GTK_WINDOW(dialog_),
IDS_IMPORT_DIALOG_WIDTH_CHARS,
@@ -128,6 +138,9 @@ ImportDialogGtk::ImportDialogGtk(GtkWindow* parent, Profile* profile,
gtk_widget_show_all(dialog_);
}
+ImportDialogGtk::~ImportDialogGtk() {
+}
+
void ImportDialogGtk::OnDialogResponse(GtkWidget* widget, int response) {
gtk_widget_hide_all(dialog_);
if (response == GTK_RESPONSE_ACCEPT) {
diff --git a/chrome/browser/gtk/import_dialog_gtk.h b/chrome/browser/gtk/import_dialog_gtk.h
index 8be3dd0..1d3f5e5 100644
--- a/chrome/browser/gtk/import_dialog_gtk.h
+++ b/chrome/browser/gtk/import_dialog_gtk.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -7,6 +7,7 @@
#include "chrome/browser/importer/importer.h"
+class AccessibleWidgetHelper;
class Profile;
class ImportDialogGtk : public ImportObserver {
@@ -22,7 +23,7 @@ class ImportDialogGtk : public ImportObserver {
private:
ImportDialogGtk(GtkWindow* parent, Profile* profile, int initial_state);
- ~ImportDialogGtk() { }
+ ~ImportDialogGtk();
static void HandleOnResponseDialog(GtkWidget* widget,
int response,
@@ -60,6 +61,9 @@ class ImportDialogGtk : public ImportObserver {
int initial_state_;
+ // Helper object to manage accessibility metadata.
+ scoped_ptr<AccessibleWidgetHelper> accessible_widget_helper_;
+
DISALLOW_COPY_AND_ASSIGN(ImportDialogGtk);
};
diff --git a/chrome/browser/gtk/keyword_editor_view.cc b/chrome/browser/gtk/keyword_editor_view.cc
index 4482216..f88409b 100644
--- a/chrome/browser/gtk/keyword_editor_view.cc
+++ b/chrome/browser/gtk/keyword_editor_view.cc
@@ -1,12 +1,15 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/gtk/keyword_editor_view.h"
+#include <string>
+
#include "app/gfx/gtk_util.h"
#include "app/l10n_util.h"
#include "base/message_loop.h"
+#include "chrome/browser/gtk/accessible_widget_helper_gtk.h"
#include "chrome/browser/gtk/edit_search_engine_dialog.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/metrics/user_metrics.h"
@@ -75,8 +78,10 @@ KeywordEditorView::KeywordEditorView(Profile* profile)
}
void KeywordEditorView::Init() {
+ std::string dialog_name =
+ l10n_util::GetStringUTF8(IDS_SEARCH_ENGINES_EDITOR_WINDOW_TITLE);
dialog_ = gtk_dialog_new_with_buttons(
- l10n_util::GetStringUTF8(IDS_SEARCH_ENGINES_EDITOR_WINDOW_TITLE).c_str(),
+ dialog_name.c_str(),
NULL,
// Non-modal.
GTK_DIALOG_NO_SEPARATOR,
@@ -84,6 +89,10 @@ void KeywordEditorView::Init() {
GTK_RESPONSE_CLOSE,
NULL);
+ accessible_widget_helper_.reset(new AccessibleWidgetHelper(
+ dialog_, profile_));
+ accessible_widget_helper_->SendOpenWindowNotification(dialog_name);
+
gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog_)->vbox),
gtk_util::kContentAreaSpacing);
@@ -368,7 +377,7 @@ void KeywordEditorView::OnItemsRemoved(int start, int length) {
// This is quite likely not correct with removing multiple in one call, but
// that shouldn't happen since we only can select and modify/remove one at a
// time.
- DCHECK(length == 1);
+ DCHECK_EQ(length, 1);
for (int i = 0; i < length; ++i) {
int row = GetListStoreRowForModelRow(start + i);
GtkTreeIter iter;
diff --git a/chrome/browser/gtk/keyword_editor_view.h b/chrome/browser/gtk/keyword_editor_view.h
index 75a8db9..8651fa80 100644
--- a/chrome/browser/gtk/keyword_editor_view.h
+++ b/chrome/browser/gtk/keyword_editor_view.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -13,6 +13,7 @@
#include "chrome/browser/search_engines/template_url_model.h"
#include "testing/gtest/include/gtest/gtest_prod.h"
+class AccessibleWidgetHelper;
class KeywordEditorController;
class Profile;
class TemplateURLTableModel;
@@ -147,6 +148,9 @@ class KeywordEditorView : public TableModelObserver,
// |list_store_|.
int model_second_group_index_;
+ // Helper object to manage accessibility metadata.
+ scoped_ptr<AccessibleWidgetHelper> accessible_widget_helper_;
+
friend class KeywordEditorViewTest;
FRIEND_TEST(KeywordEditorViewTest, Empty);
FRIEND_TEST(KeywordEditorViewTest, Add);
diff --git a/chrome/browser/gtk/options/content_settings_window_gtk.cc b/chrome/browser/gtk/options/content_settings_window_gtk.cc
index eeaecd5..8334a9f 100644
--- a/chrome/browser/gtk/options/content_settings_window_gtk.cc
+++ b/chrome/browser/gtk/options/content_settings_window_gtk.cc
@@ -4,10 +4,13 @@
#include "chrome/browser/gtk/options/content_settings_window_gtk.h"
+#include <string>
+
#include "app/l10n_util.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_process.h"
+#include "chrome/browser/gtk/accessible_widget_helper_gtk.h"
#include "chrome/browser/gtk/browser_window_gtk.h"
#include "chrome/browser/pref_service.h"
#include "chrome/browser/profile.h"
@@ -45,15 +48,6 @@ void ContentSettingsWindowGtk::Show(GtkWindow* parent,
profile->ResumeAccessibilityEvents();
}
settings_window->ShowContentSettingsTab(page);
-
- std::string name = l10n_util::GetStringUTF8(
- IDS_CONTENT_SETTINGS_TITLE);
- AccessibilityWindowInfo info(profile, name);
-
- NotificationService::current()->Notify(
- NotificationType::ACCESSIBILITY_WINDOW_OPENED,
- Source<Profile>(profile),
- Details<AccessibilityWindowInfo>(&info));
}
ContentSettingsWindowGtk::ContentSettingsWindowGtk(GtkWindow* parent,
@@ -68,13 +62,20 @@ ContentSettingsWindowGtk::ContentSettingsWindowGtk(GtkWindow* parent,
last_selected_page_.Init(prefs::kContentSettingsWindowLastTabIndex,
profile->GetPrefs(), NULL);
+ std::string dialog_name = l10n_util::GetStringUTF8(
+ IDS_CONTENT_SETTINGS_TITLE);
dialog_ = gtk_dialog_new_with_buttons(
- l10n_util::GetStringUTF8(IDS_CONTENT_SETTINGS_TITLE).c_str(),
+ dialog_name.c_str(),
parent,
static_cast<GtkDialogFlags>(GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR),
GTK_STOCK_CLOSE,
GTK_RESPONSE_CLOSE,
NULL);
+
+ accessible_widget_helper_.reset(new AccessibleWidgetHelper(
+ dialog_, profile_));
+ accessible_widget_helper_->SendOpenWindowNotification(dialog_name);
+
gtk_window_set_default_size(GTK_WINDOW(dialog_), 500, -1);
// Allow browser windows to go in front of the options dialog in metacity.
gtk_window_set_type_hint(GTK_WINDOW(dialog_), GDK_WINDOW_TYPE_HINT_NORMAL);
@@ -82,9 +83,6 @@ ContentSettingsWindowGtk::ContentSettingsWindowGtk(GtkWindow* parent,
gtk_util::kContentAreaSpacing);
gtk_util::SetWindowIcon(GTK_WINDOW(dialog_));
- accessibility_widget_helper_.reset(new AccessibleWidgetHelper(
- dialog_, profile));
-
notebook_ = gtk_notebook_new();
gtk_notebook_append_page(
diff --git a/chrome/browser/gtk/options/content_settings_window_gtk.h b/chrome/browser/gtk/options/content_settings_window_gtk.h
index d6a1b91..554aef5 100644
--- a/chrome/browser/gtk/options/content_settings_window_gtk.h
+++ b/chrome/browser/gtk/options/content_settings_window_gtk.h
@@ -8,7 +8,6 @@
#include <gtk/gtk.h>
#include "base/scoped_ptr.h"
-#include "chrome/browser/gtk/accessible_widget_helper_gtk.h"
#include "chrome/browser/gtk/options/cookie_filter_page_gtk.h"
#include "chrome/browser/gtk/options/content_filter_page_gtk.h"
#include "chrome/browser/pref_member.h"
@@ -60,7 +59,8 @@ class ContentSettingsWindowGtk {
ContentFilterPageGtk plugin_page_;
ContentFilterPageGtk popup_page_;
- scoped_ptr<AccessibleWidgetHelper> accessibility_widget_helper_;
+ // Helper object to manage accessibility metadata.
+ scoped_ptr<AccessibleWidgetHelper> accessible_widget_helper_;
DISALLOW_COPY_AND_ASSIGN(ContentSettingsWindowGtk);
};
diff --git a/chrome/browser/gtk/options/general_page_gtk.cc b/chrome/browser/gtk/options/general_page_gtk.cc
index 78aa693..8fed28c 100644
--- a/chrome/browser/gtk/options/general_page_gtk.cc
+++ b/chrome/browser/gtk/options/general_page_gtk.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -8,6 +8,7 @@
#include "base/callback.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_list.h"
+#include "chrome/browser/gtk/accessible_widget_helper_gtk.h"
#include "chrome/browser/gtk/keyword_editor_view.h"
#include "chrome/browser/gtk/list_store_favicon_loader.h"
#include "chrome/browser/gtk/options/options_layout_gtk.h"
@@ -64,6 +65,10 @@ GeneralPageGtk::GeneralPageGtk(Profile* profile)
default_browser_worker_(
new ShellIntegration::DefaultBrowserWorker(this)) {
OptionsLayoutBuilderGtk options_builder;
+ page_ = options_builder.get_page_widget();
+ accessible_widget_helper_.reset(new AccessibleWidgetHelper(
+ page_, profile));
+
options_builder.AddOptionGroup(
l10n_util::GetStringUTF8(IDS_OPTIONS_STARTUP_GROUP_NAME),
InitStartupGroup(), true);
@@ -78,7 +83,6 @@ GeneralPageGtk::GeneralPageGtk(Profile* profile)
l10n_util::GetStringUTF8(IDS_OPTIONS_DEFAULTBROWSER_GROUP_NAME),
InitDefaultBrowserGroup(), false);
#endif
- page_ = options_builder.get_page_widget();
profile->GetPrefs()->AddPrefObserver(prefs::kRestoreOnStartup, this);
profile->GetPrefs()->AddPrefObserver(prefs::kURLsToRestoreOnStartup, this);
@@ -323,6 +327,8 @@ GtkWidget* GeneralPageGtk::InitDefaultSearchGroup() {
g_signal_connect(default_search_engine_combobox_, "changed",
G_CALLBACK(OnDefaultSearchEngineChanged), this);
gtk_container_add(GTK_CONTAINER(hbox), default_search_engine_combobox_);
+ accessible_widget_helper_->SetWidgetName(
+ default_search_engine_combobox_, IDS_OPTIONS_DEFAULTSEARCH_GROUP_NAME);
GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(default_search_engine_combobox_),
diff --git a/chrome/browser/gtk/options/general_page_gtk.h b/chrome/browser/gtk/options/general_page_gtk.h
index b394e6f..fcb87b2 100644
--- a/chrome/browser/gtk/options/general_page_gtk.h
+++ b/chrome/browser/gtk/options/general_page_gtk.h
@@ -17,6 +17,7 @@
#include "chrome/browser/shell_integration.h"
#include "googleurl/src/gurl.h"
+class AccessibleWidgetHelper;
class Profile;
class ListStoreFavIconLoader;
@@ -181,6 +182,9 @@ class GeneralPageGtk : public OptionsPageBase,
// The helper object that performs default browser set/check tasks.
scoped_refptr<ShellIntegration::DefaultBrowserWorker> default_browser_worker_;
+ // Helper object to manage accessibility metadata.
+ scoped_ptr<AccessibleWidgetHelper> accessible_widget_helper_;
+
DISALLOW_COPY_AND_ASSIGN(GeneralPageGtk);
};
diff --git a/chrome/browser/gtk/options/options_window_gtk.cc b/chrome/browser/gtk/options/options_window_gtk.cc
index b459f46..58498a2 100644
--- a/chrome/browser/gtk/options/options_window_gtk.cc
+++ b/chrome/browser/gtk/options/options_window_gtk.cc
@@ -72,7 +72,7 @@ class OptionsWindowGtk {
// The last page the user was on when they opened the Options window.
IntegerPrefMember last_selected_page_;
- scoped_ptr<AccessibleWidgetHelper> accessibility_widget_helper_;
+ scoped_ptr<AccessibleWidgetHelper> accessible_widget_helper_;
DISALLOW_COPY_AND_ASSIGN(OptionsWindowGtk);
};
@@ -96,9 +96,12 @@ OptionsWindowGtk::OptionsWindowGtk(Profile* profile)
last_selected_page_.Init(prefs::kOptionsWindowLastTabIndex,
g_browser_process->local_state(), NULL);
+ std::string dialog_name =
+ l10n_util::GetStringFUTF8(
+ IDS_OPTIONS_DIALOG_TITLE,
+ WideToUTF16(l10n_util::GetString(IDS_PRODUCT_NAME)));
dialog_ = gtk_dialog_new_with_buttons(
- l10n_util::GetStringFUTF8(IDS_OPTIONS_DIALOG_TITLE,
- WideToUTF16(l10n_util::GetString(IDS_PRODUCT_NAME))).c_str(),
+ dialog_name.c_str(),
// Prefs window is shared between all browser windows.
NULL,
// Non-modal.
@@ -106,15 +109,17 @@ OptionsWindowGtk::OptionsWindowGtk(Profile* profile)
GTK_STOCK_CLOSE,
GTK_RESPONSE_CLOSE,
NULL);
+
+ accessible_widget_helper_.reset(new AccessibleWidgetHelper(
+ dialog_, profile));
+ accessible_widget_helper_->SendOpenWindowNotification(dialog_name);
+
gtk_window_set_default_size(GTK_WINDOW(dialog_), 500, -1);
// Allow browser windows to go in front of the options dialog in metacity.
gtk_window_set_type_hint(GTK_WINDOW(dialog_), GDK_WINDOW_TYPE_HINT_NORMAL);
gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog_)->vbox),
gtk_util::kContentAreaSpacing);
- accessibility_widget_helper_.reset(new AccessibleWidgetHelper(
- dialog_, profile));
-
notebook_ = gtk_notebook_new();
#if defined(OS_CHROMEOS)
@@ -250,14 +255,4 @@ void ShowOptionsWindow(OptionsPage page,
profile->ResumeAccessibilityEvents();
}
options_window->ShowOptionsPage(page, highlight_group);
-
- std::string name = l10n_util::GetStringFUTF8(
- IDS_OPTIONS_DIALOG_TITLE,
- WideToUTF16(l10n_util::GetString(IDS_PRODUCT_NAME)));
- AccessibilityWindowInfo info(profile, name);
-
- NotificationService::current()->Notify(
- NotificationType::ACCESSIBILITY_WINDOW_OPENED,
- Source<Profile>(profile),
- Details<AccessibilityWindowInfo>(&info));
}
diff --git a/chrome/browser/gtk/options/passwords_exceptions_window_gtk.cc b/chrome/browser/gtk/options/passwords_exceptions_window_gtk.cc
index 260a934..fc93954 100644
--- a/chrome/browser/gtk/options/passwords_exceptions_window_gtk.cc
+++ b/chrome/browser/gtk/options/passwords_exceptions_window_gtk.cc
@@ -6,9 +6,12 @@
#include <gtk/gtk.h>
+#include <string>
+
#include "app/l10n_util.h"
#include "base/message_loop.h"
#include "chrome/browser/browser_process.h"
+#include "chrome/browser/gtk/accessible_widget_helper_gtk.h"
#include "chrome/browser/gtk/options/passwords_exceptions_page_gtk.h"
#include "chrome/browser/gtk/options/passwords_page_gtk.h"
#include "chrome/browser/options_window.h"
@@ -49,6 +52,9 @@ class PasswordsExceptionsWindowGtk {
// The exceptions page.
PasswordsExceptionsPageGtk exceptions_page_;
+ // Helper object to manage accessibility metadata.
+ scoped_ptr<AccessibleWidgetHelper> accessible_widget_helper_;
+
DISALLOW_COPY_AND_ASSIGN(PasswordsExceptionsWindowGtk);
};
@@ -62,8 +68,10 @@ PasswordsExceptionsWindowGtk::PasswordsExceptionsWindowGtk(Profile* profile)
: profile_(profile),
passwords_page_(profile_),
exceptions_page_(profile_) {
+ std::string dialog_name = l10n_util::GetStringUTF8(
+ IDS_PASSWORDS_EXCEPTIONS_WINDOW_TITLE);
dialog_ = gtk_dialog_new_with_buttons(
- l10n_util::GetStringUTF8(IDS_PASSWORDS_EXCEPTIONS_WINDOW_TITLE).c_str(),
+ dialog_name.c_str(),
// Passwords and exceptions window is shared between all browser windows.
NULL,
// Non-modal.
@@ -74,6 +82,10 @@ PasswordsExceptionsWindowGtk::PasswordsExceptionsWindowGtk(Profile* profile)
gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog_)->vbox),
gtk_util::kContentAreaSpacing);
+ accessible_widget_helper_.reset(new AccessibleWidgetHelper(
+ dialog_, profile));
+ accessible_widget_helper_->SendOpenWindowNotification(dialog_name);
+
notebook_ = gtk_notebook_new();
gtk_notebook_append_page(
diff --git a/chrome/browser/gtk/options/url_picker_dialog_gtk.cc b/chrome/browser/gtk/options/url_picker_dialog_gtk.cc
index b08eef7..49e0f0b 100644
--- a/chrome/browser/gtk/options/url_picker_dialog_gtk.cc
+++ b/chrome/browser/gtk/options/url_picker_dialog_gtk.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -7,6 +7,7 @@
#include "app/gfx/gtk_util.h"
#include "app/l10n_util.h"
#include "base/message_loop.h"
+#include "chrome/browser/gtk/accessible_widget_helper_gtk.h"
#include "chrome/browser/gtk/options/url_picker_dialog_gtk.h"
#include "chrome/browser/net/url_fixer_upper.h"
#include "chrome/browser/possible_url_model.h"
@@ -41,13 +42,17 @@ UrlPickerDialogGtk::UrlPickerDialogGtk(UrlPickerCallback* callback,
GtkWindow* parent)
: profile_(profile),
callback_(callback) {
+ std::string dialog_name = l10n_util::GetStringUTF8(IDS_ASI_ADD_TITLE);
dialog_ = gtk_dialog_new_with_buttons(
- l10n_util::GetStringUTF8(IDS_ASI_ADD_TITLE).c_str(),
+ dialog_name.c_str(),
parent,
static_cast<GtkDialogFlags>(GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR),
GTK_STOCK_CANCEL,
GTK_RESPONSE_CANCEL,
NULL);
+ accessible_widget_helper_.reset(new AccessibleWidgetHelper(
+ dialog_, profile));
+ accessible_widget_helper_->SendOpenWindowNotification(dialog_name);
add_button_ = gtk_dialog_add_button(GTK_DIALOG(dialog_),
GTK_STOCK_ADD, GTK_RESPONSE_OK);
@@ -62,6 +67,7 @@ UrlPickerDialogGtk::UrlPickerDialogGtk(UrlPickerCallback* callback,
gtk_box_pack_start(GTK_BOX(url_hbox), url_label,
FALSE, FALSE, 0);
url_entry_ = gtk_entry_new();
+ accessible_widget_helper_->SetWidgetName(url_entry_, IDS_ASI_URL);
gtk_entry_set_activates_default(GTK_ENTRY(url_entry_), TRUE);
g_signal_connect(url_entry_, "changed",
G_CALLBACK(OnUrlEntryChanged), this);
@@ -103,6 +109,8 @@ UrlPickerDialogGtk::UrlPickerDialogGtk(UrlPickerCallback* callback,
gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(history_list_sort_),
COL_DISPLAY_URL, CompareURL, this, NULL);
history_tree_ = gtk_tree_view_new_with_model(history_list_sort_);
+ accessible_widget_helper_->SetWidgetName(
+ history_tree_, IDS_ASI_DESCRIPTION);
g_object_unref(history_list_store_);
g_object_unref(history_list_sort_);
gtk_container_add(GTK_CONTAINER(scroll_window), history_tree_);
diff --git a/chrome/browser/gtk/options/url_picker_dialog_gtk.h b/chrome/browser/gtk/options/url_picker_dialog_gtk.h
index 7d21359..8da397d 100644
--- a/chrome/browser/gtk/options/url_picker_dialog_gtk.h
+++ b/chrome/browser/gtk/options/url_picker_dialog_gtk.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -12,6 +12,7 @@
#include "chrome/browser/history/history.h"
#include "chrome/common/gtk_tree.h"
+class AccessibleWidgetHelper;
class GURL;
class Profile;
class PossibleURLModel;
@@ -92,6 +93,9 @@ class UrlPickerDialogGtk : public gtk_tree::TableAdapter::Delegate {
// Called if the user selects an url.
UrlPickerCallback* callback_;
+ // Helper object to manage accessibility metadata.
+ scoped_ptr<AccessibleWidgetHelper> accessible_widget_helper_;
+
DISALLOW_COPY_AND_ASSIGN(UrlPickerDialogGtk);
};