diff options
Diffstat (limited to 'Source/WebCore/editing/gtk/SelectionControllerGtk.cpp')
-rw-r--r-- | Source/WebCore/editing/gtk/SelectionControllerGtk.cpp | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/Source/WebCore/editing/gtk/SelectionControllerGtk.cpp b/Source/WebCore/editing/gtk/SelectionControllerGtk.cpp new file mode 100644 index 0000000..19097b2 --- /dev/null +++ b/Source/WebCore/editing/gtk/SelectionControllerGtk.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2009 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 "SelectionController.h" + +#include "AccessibilityObjectWrapperAtk.h" +#include "AXObjectCache.h" +#include "Frame.h" +#include "RefPtr.h" + +#include <gtk/gtk.h> + +namespace WebCore { + +static void emitTextSelectionChange(AccessibilityObject* object, VisibleSelection selection, int offset) +{ + AtkObject* axObject = object->wrapper(); + if (!axObject || !ATK_IS_TEXT(axObject)) + return; + + g_signal_emit_by_name(axObject, "text-caret-moved", offset); + if (selection.isRange()) + g_signal_emit_by_name(axObject, "text-selection-changed"); +} + +static void maybeEmitTextFocusChange(PassRefPtr<AccessibilityObject> prpObject) +{ + // This static variable is needed to keep track of the old object + // as per previous calls to this function, in order to properly + // decide whether to emit some signals or not. + DEFINE_STATIC_LOCAL(RefPtr<AccessibilityObject>, oldObject, ()); + + RefPtr<AccessibilityObject> object = prpObject; + + // Ensure the oldObject belongs to the same document that the + // current object so further comparisons make sense. Otherwise, + // just reset oldObject to 0 so it won't be taken into account in + // the immediately following call to this function. + if (object && oldObject && oldObject->document() != object->document()) + oldObject = 0; + + AtkObject* axObject = object ? object->wrapper() : 0; + AtkObject* oldAxObject = oldObject ? oldObject->wrapper() : 0; + + if (axObject != oldAxObject) { + if (oldAxObject && ATK_IS_TEXT(oldAxObject)) { + g_signal_emit_by_name(oldAxObject, "focus-event", false); + g_signal_emit_by_name(oldAxObject, "state-change", "focused", false); + } + if (axObject && ATK_IS_TEXT(axObject)) { + g_signal_emit_by_name(axObject, "focus-event", true); + g_signal_emit_by_name(axObject, "state-change", "focused", true); + } + } + + // Update pointer to last focused object. + oldObject = object; +} + + +void SelectionController::notifyAccessibilityForSelectionChange() +{ + if (!AXObjectCache::accessibilityEnabled()) + return; + + // Reset lastFocuseNode and return for no valid selections. + if (!m_selection.start().isNotNull() || !m_selection.end().isNotNull()) + return; + + RenderObject* focusedNode = m_selection.end().node()->renderer(); + AccessibilityObject* accessibilityObject = m_frame->document()->axObjectCache()->getOrCreate(focusedNode); + + // Need to check this as getOrCreate could return 0, + if (!accessibilityObject) + return; + + int offset; + // Always report the events w.r.t. the non-linked unignored parent. (i.e. ignoreLinks == true). + RefPtr<AccessibilityObject> object = objectAndOffsetUnignored(accessibilityObject, offset, true); + if (!object) + return; + + // Emit relatedsignals. + emitTextSelectionChange(object.get(), m_selection, offset); + maybeEmitTextFocusChange(object.release()); +} + +} // namespace WebCore |