mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 07:42:04 +00:00
Bug 669130 [atk]Use emission hook for show/hide signal to add/remove GTK+ native a11y dialog to children of Mozilla application accessible. r=trev.saunders,roc
This commit is contained in:
parent
2b4e23daf5
commit
055b36abf1
@ -55,7 +55,7 @@
|
||||
|
||||
typedef GType (* AtkGetTypeType) (void);
|
||||
GType g_atk_hyperlink_impl_type = G_TYPE_INVALID;
|
||||
static PRBool sATKChecked = PR_FALSE;
|
||||
static bool sATKChecked = false;
|
||||
static PRLibrary *sATKLib = nsnull;
|
||||
static const char sATKLibName[] = "libatk-1.0.so.0";
|
||||
static const char sATKHyperlinkImplGetTypeSymbol[] =
|
||||
@ -100,8 +100,8 @@ static void insert_hf(gpointer key, gpointer value, gpointer data);
|
||||
static gint mai_key_snooper(GtkWidget *the_widget, GdkEventKey *event,
|
||||
gpointer func_data);
|
||||
|
||||
static GHashTable *listener_list = NULL;
|
||||
static gint listener_idx = 1;
|
||||
static GHashTable* sListener_list = NULL;
|
||||
static gint sListener_idx = 1;
|
||||
|
||||
#define MAI_TYPE_UTIL (mai_util_get_type ())
|
||||
#define MAI_UTIL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
|
||||
@ -115,8 +115,12 @@ static gint listener_idx = 1;
|
||||
#define MAI_UTIL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
|
||||
MAI_TYPE_UTIL, MaiUtilClass))
|
||||
|
||||
static GHashTable *key_listener_list = NULL;
|
||||
static guint key_snooper_id = 0;
|
||||
static GHashTable* sKey_listener_list = NULL;
|
||||
static guint sKey_snooper_id = 0;
|
||||
static GQuark sQuark_gecko_acc_obj = g_quark_from_static_string("GeckoAccObj");
|
||||
static bool sToplevel_event_hook_added = false;
|
||||
static gulong sToplevel_show_hook = 0;
|
||||
static gulong sToplevel_hide_hook = 0;
|
||||
|
||||
G_BEGIN_DECLS
|
||||
typedef void (*GnomeAccessibilityInit) (void);
|
||||
@ -270,8 +274,8 @@ mai_util_class_init(MaiUtilClass *klass)
|
||||
atk_class->get_toolkit_name = mai_util_get_toolkit_name;
|
||||
atk_class->get_toolkit_version = mai_util_get_toolkit_version;
|
||||
|
||||
listener_list = g_hash_table_new_full(g_int_hash, g_int_equal, NULL,
|
||||
_listener_info_destroy);
|
||||
sListener_list = g_hash_table_new_full(g_int_hash, g_int_equal, NULL,
|
||||
_listener_info_destroy);
|
||||
// Keep track of added/removed windows.
|
||||
AtkObject *root = atk_get_root ();
|
||||
g_signal_connect (root, "children-changed::add", (GCallback) window_added, NULL);
|
||||
@ -295,7 +299,7 @@ mai_util_add_global_event_listener(GSignalEmissionHook listener,
|
||||
gail_listenerid =
|
||||
gail_add_global_event_listener(listener, event_type);
|
||||
}
|
||||
|
||||
|
||||
rc = add_listener (listener, "MaiAtkObject", split_string[1],
|
||||
event_type, gail_listenerid);
|
||||
}
|
||||
@ -316,14 +320,14 @@ mai_util_remove_global_event_listener(guint remove_listener)
|
||||
gint tmp_idx = remove_listener;
|
||||
|
||||
listener_info = (MaiUtilListenerInfo *)
|
||||
g_hash_table_lookup(listener_list, &tmp_idx);
|
||||
g_hash_table_lookup(sListener_list, &tmp_idx);
|
||||
|
||||
if (listener_info != NULL) {
|
||||
if (gail_remove_global_event_listener &&
|
||||
listener_info->gail_listenerid) {
|
||||
gail_remove_global_event_listener(listener_info->gail_listenerid);
|
||||
}
|
||||
|
||||
|
||||
/* Hook id of 0 and signal id of 0 are invalid */
|
||||
if (listener_info->hook_id != 0 && listener_info->signal_id != 0) {
|
||||
/* Remove the emission hook */
|
||||
@ -331,7 +335,7 @@ mai_util_remove_global_event_listener(guint remove_listener)
|
||||
listener_info->hook_id);
|
||||
|
||||
/* Remove the element from the hash */
|
||||
g_hash_table_remove(listener_list, &tmp_idx);
|
||||
g_hash_table_remove(sListener_list, &tmp_idx);
|
||||
}
|
||||
else {
|
||||
g_warning("Invalid listener hook_id %ld or signal_id %d\n",
|
||||
@ -372,14 +376,14 @@ atk_key_event_from_gdk_event_key (GdkEventKey *key)
|
||||
event->state = key->state;
|
||||
event->keyval = key->keyval;
|
||||
event->length = key->length;
|
||||
if (key->string && key->string [0] &&
|
||||
if (key->string && key->string [0] &&
|
||||
(key->state & GDK_CONTROL_MASK ||
|
||||
g_unichar_isgraph (g_utf8_get_char (key->string)))) {
|
||||
event->string = key->string;
|
||||
}
|
||||
else if (key->type == GDK_KEY_PRESS ||
|
||||
key->type == GDK_KEY_RELEASE) {
|
||||
event->string = gdk_keyval_name (key->keyval);
|
||||
event->string = gdk_keyval_name (key->keyval);
|
||||
}
|
||||
event->keycode = key->hardware_keycode;
|
||||
event->timestamp = key->time;
|
||||
@ -415,9 +419,9 @@ mai_key_snooper(GtkWidget *the_widget, GdkEventKey *event, gpointer func_data)
|
||||
|
||||
MaiKeyEventInfo *info = g_new0(MaiKeyEventInfo, 1);
|
||||
gint consumed = 0;
|
||||
if (key_listener_list) {
|
||||
if (sKey_listener_list) {
|
||||
GHashTable *new_hash = g_hash_table_new(NULL, NULL);
|
||||
g_hash_table_foreach (key_listener_list, insert_hf, new_hash);
|
||||
g_hash_table_foreach (sKey_listener_list, insert_hf, new_hash);
|
||||
info->key_event = atk_key_event_from_gdk_event_key (event);
|
||||
info->func_data = func_data;
|
||||
consumed = g_hash_table_foreach_steal (new_hash, notify_hf, info);
|
||||
@ -436,13 +440,13 @@ mai_util_add_key_event_listener (AtkKeySnoopFunc listener,
|
||||
|
||||
static guint key=0;
|
||||
|
||||
if (!key_listener_list) {
|
||||
key_listener_list = g_hash_table_new(NULL, NULL);
|
||||
key_snooper_id = gtk_key_snooper_install(mai_key_snooper, data);
|
||||
if (!sKey_listener_list) {
|
||||
sKey_listener_list = g_hash_table_new(NULL, NULL);
|
||||
sKey_snooper_id = gtk_key_snooper_install(mai_key_snooper, data);
|
||||
}
|
||||
AtkKeySnoopFuncPointer atkKeySnoop;
|
||||
atkKeySnoop.func_ptr = listener;
|
||||
g_hash_table_insert(key_listener_list, GUINT_TO_POINTER (key++),
|
||||
g_hash_table_insert(sKey_listener_list, GUINT_TO_POINTER (key++),
|
||||
atkKeySnoop.data);
|
||||
return key;
|
||||
}
|
||||
@ -450,15 +454,15 @@ mai_util_add_key_event_listener (AtkKeySnoopFunc listener,
|
||||
static void
|
||||
mai_util_remove_key_event_listener (guint remove_listener)
|
||||
{
|
||||
if (!key_listener_list) {
|
||||
if (!sKey_listener_list) {
|
||||
// atk-bridge is initialized with gail (e.g. yelp)
|
||||
// try gail_remove_key_event_listener
|
||||
return gail_remove_key_event_listener(remove_listener);
|
||||
}
|
||||
|
||||
g_hash_table_remove(key_listener_list, GUINT_TO_POINTER (remove_listener));
|
||||
if (g_hash_table_size(key_listener_list) == 0) {
|
||||
gtk_key_snooper_remove(key_snooper_id);
|
||||
g_hash_table_remove(sKey_listener_list, GUINT_TO_POINTER (remove_listener));
|
||||
if (g_hash_table_size(sKey_listener_list) == 0) {
|
||||
gtk_key_snooper_remove(sKey_snooper_id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -518,11 +522,11 @@ add_listener (GSignalEmissionHook listener,
|
||||
if (signal_id > 0) {
|
||||
MaiUtilListenerInfo *listener_info;
|
||||
|
||||
rc = listener_idx;
|
||||
rc = sListener_idx;
|
||||
|
||||
listener_info = (MaiUtilListenerInfo *)
|
||||
g_malloc(sizeof(MaiUtilListenerInfo));
|
||||
listener_info->key = listener_idx;
|
||||
listener_info->key = sListener_idx;
|
||||
listener_info->hook_id =
|
||||
g_signal_add_emission_hook(signal_id, 0, listener,
|
||||
g_strdup(hook_data),
|
||||
@ -530,9 +534,9 @@ add_listener (GSignalEmissionHook listener,
|
||||
listener_info->signal_id = signal_id;
|
||||
listener_info->gail_listenerid = gail_listenerid;
|
||||
|
||||
g_hash_table_insert(listener_list, &(listener_info->key),
|
||||
g_hash_table_insert(sListener_list, &(listener_info->key),
|
||||
listener_info);
|
||||
listener_idx++;
|
||||
sListener_idx++;
|
||||
}
|
||||
else {
|
||||
g_warning("Invalid signal type %s\n", signal);
|
||||
@ -560,6 +564,49 @@ nsApplicationAccessibleWrap::~nsApplicationAccessibleWrap()
|
||||
nsAccessibleWrap::ShutdownAtkObject();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
toplevel_event_watcher(GSignalInvocationHint* ihint,
|
||||
guint n_param_values,
|
||||
const GValue* param_values,
|
||||
gpointer data)
|
||||
{
|
||||
if (nsAccessibilityService::IsShutdown())
|
||||
return TRUE;
|
||||
|
||||
GObject* object = reinterpret_cast<GObject*>(g_value_get_object(param_values));
|
||||
if (!GTK_IS_WINDOW(object))
|
||||
return TRUE;
|
||||
|
||||
AtkObject* child = gtk_widget_get_accessible(GTK_WIDGET(object));
|
||||
|
||||
// GTK native dialog
|
||||
if (!IS_MAI_OBJECT(child) &&
|
||||
(atk_object_get_role(child) == ATK_ROLE_DIALOG)) {
|
||||
|
||||
if (data == reinterpret_cast<gpointer>(nsIAccessibleEvent::EVENT_SHOW)) {
|
||||
|
||||
// Attach the dialog accessible to app accessible tree
|
||||
nsAccessible* windowAcc = GetAccService()->AddNativeRootAccessible(child);
|
||||
g_object_set_qdata(G_OBJECT(child), sQuark_gecko_acc_obj,
|
||||
reinterpret_cast<gpointer>(windowAcc));
|
||||
|
||||
} else {
|
||||
|
||||
// Deattach the dialog accessible
|
||||
nsAccessible* windowAcc =
|
||||
reinterpret_cast<nsAccessible*>
|
||||
(g_object_get_qdata(G_OBJECT(child), sQuark_gecko_acc_obj));
|
||||
if (windowAcc) {
|
||||
GetAccService()->RemoveNativeRootAccessible(windowAcc);
|
||||
g_object_set_qdata(G_OBJECT(child), sQuark_gecko_acc_obj, NULL);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsApplicationAccessibleWrap::Init()
|
||||
{
|
||||
@ -608,6 +655,18 @@ nsApplicationAccessibleWrap::Init()
|
||||
}
|
||||
else
|
||||
MAI_LOG_DEBUG(("Fail to load lib: %s\n", sAtkBridge.libName));
|
||||
|
||||
if (!sToplevel_event_hook_added) {
|
||||
sToplevel_event_hook_added = true;
|
||||
sToplevel_show_hook =
|
||||
g_signal_add_emission_hook(g_signal_lookup("show", GTK_TYPE_WINDOW),
|
||||
0, toplevel_event_watcher,
|
||||
reinterpret_cast<gpointer>(nsIAccessibleEvent::EVENT_SHOW), NULL);
|
||||
sToplevel_hide_hook =
|
||||
g_signal_add_emission_hook(g_signal_lookup("hide", GTK_TYPE_WINDOW),
|
||||
0, toplevel_event_watcher,
|
||||
reinterpret_cast<gpointer>(nsIAccessibleEvent::EVENT_HIDE), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return nsApplicationAccessible::Init();
|
||||
@ -616,6 +675,14 @@ nsApplicationAccessibleWrap::Init()
|
||||
void
|
||||
nsApplicationAccessibleWrap::Unload()
|
||||
{
|
||||
if (sToplevel_event_hook_added) {
|
||||
sToplevel_event_hook_added = false;
|
||||
g_signal_remove_emission_hook(g_signal_lookup("show", GTK_TYPE_WINDOW),
|
||||
sToplevel_show_hook);
|
||||
g_signal_remove_emission_hook(g_signal_lookup("hide", GTK_TYPE_WINDOW),
|
||||
sToplevel_hide_hook);
|
||||
}
|
||||
|
||||
if (sAtkBridge.lib) {
|
||||
// Do not shutdown/unload atk-bridge,
|
||||
// an exit function registered will take care of it
|
||||
@ -677,7 +744,7 @@ gboolean fireRootAccessibleAddedCB(gpointer data)
|
||||
g_object_unref(eventData->app_accessible);
|
||||
g_object_unref(eventData->root_accessible);
|
||||
free(data);
|
||||
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -747,7 +814,7 @@ nsApplicationAccessibleWrap::PreCreate()
|
||||
AtkSocketAccessible::g_atk_socket_embed;
|
||||
}
|
||||
}
|
||||
sATKChecked = PR_TRUE;
|
||||
sATKChecked = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,6 @@ CPPSRCS = \
|
||||
nsScreenGtk.cpp \
|
||||
nsScreenManagerGtk.cpp \
|
||||
nsImageToPixbuf.cpp \
|
||||
nsAccessibilityHelper.cpp \
|
||||
nsGtkIMModule.cpp \
|
||||
WidgetTraceEvent.cpp \
|
||||
$(NULL)
|
||||
|
@ -54,7 +54,6 @@
|
||||
#include "prlink.h"
|
||||
|
||||
#include "nsFilePicker.h"
|
||||
#include "nsAccessibilityHelper.h"
|
||||
|
||||
#if (MOZ_PLATFORM_MAEMO == 5)
|
||||
#include <hildon-fm-2/hildon/hildon-file-chooser-dialog.h>
|
||||
@ -425,7 +424,7 @@ confirm_overwrite_file(GtkWidget *parent, nsILocalFile* file)
|
||||
gtk_window_group_add_window(parent_window->group, GTK_WINDOW(dialog));
|
||||
}
|
||||
|
||||
PRBool result = (RunDialog(GTK_DIALOG(dialog)) == GTK_RESPONSE_YES);
|
||||
PRBool result = (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_YES);
|
||||
|
||||
gtk_widget_destroy(dialog);
|
||||
|
||||
@ -550,7 +549,7 @@ nsFilePicker::Show(PRInt16 *aReturn)
|
||||
}
|
||||
|
||||
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(file_chooser), PR_TRUE);
|
||||
gint response = RunDialog(GTK_DIALOG(file_chooser));
|
||||
gint response = gtk_dialog_run(GTK_DIALOG(file_chooser));
|
||||
|
||||
switch (response) {
|
||||
case GTK_RESPONSE_OK:
|
||||
|
@ -41,7 +41,6 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "mozcontainer.h"
|
||||
#include "nsAccessibilityHelper.h"
|
||||
#include "nsIPrintSettings.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsPrintDialogGTK.h"
|
||||
@ -142,7 +141,7 @@ ShowCustomDialog(GtkComboBox *changed_box, gpointer user_data)
|
||||
gtk_widget_show_all(custom_hbox);
|
||||
|
||||
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(prompt_dialog)->vbox), custom_hbox, FALSE, FALSE, 0);
|
||||
gint diag_response = RunDialog(GTK_DIALOG(prompt_dialog));
|
||||
gint diag_response = gtk_dialog_run(GTK_DIALOG(prompt_dialog));
|
||||
|
||||
if (diag_response == GTK_RESPONSE_ACCEPT) {
|
||||
const gchar* response_text = gtk_entry_get_text(GTK_ENTRY(custom_entry));
|
||||
@ -392,7 +391,7 @@ nsPrintDialogWidgetGTK::OptionWidgetToString(GtkWidget *dropdown)
|
||||
const gint
|
||||
nsPrintDialogWidgetGTK::Run()
|
||||
{
|
||||
const gint response = RunDialog(GTK_DIALOG(dialog));
|
||||
const gint response = gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
gtk_widget_hide(dialog);
|
||||
return response;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user