Index: src/orca/default.py
===================================================================
--- src/orca/default.py	(revision 2400)
+++ src/orca/default.py	(working copy)
@@ -1863,7 +1863,7 @@
         maxSearch = min(len(aParents), len(bParents))
         i = 0
         while i < maxSearch:
-            if aParents[i] == bParents[i]:
+            if self.isSameObject(aParents[i], bParents[i]):
                 commonAncestor = aParents[i]
                 i += 1
             else:
@@ -3895,8 +3895,22 @@
             return False
 
         try:
-            if obj1.name != obj2.name:
+            if (obj1.name != obj2.name) or (obj1.role != obj2.role):
                 return False
+            else:
+                # Gecko sometimes creates multiple accessibles to represent
+                # the same object.  If the two objects have the same name
+                # and the same role, check the extents.  If those also match
+                # then the two objects are for all intents and purposes the
+                # same object.
+                #
+                extents1 = obj1.component.getExtents(0)
+                extents2 = obj2.component.getExtents(0)
+                if (extents1.x == extents2.x) and \
+                   (extents1.y == extents2.y) and \
+                   (extents1.width == extents2.width) and \
+                   (extents1.height == extents2.height):
+                    return True
 
             # When we're looking at children of objects that manage
             # their descendants, we will often get different objects
Index: src/orca/Gecko.py
===================================================================
--- src/orca/Gecko.py	(revision 2400)
+++ src/orca/Gecko.py	(working copy)
@@ -787,17 +787,8 @@
             return utterances
 
         parent = obj.parent
-
-        # If we're in a toolbar, we want to stop before speaking the
-        # application frame.
-        #
-        containingToolbar = \
-               self._script.getContainingRole(obj, rolenames.ROLE_TOOL_BAR)
-        if containingToolbar:
-            stopAncestor = self._script.getFrame(obj)
-
         while parent and (parent.parent != parent):
-            if parent == stopAncestor:
+            if self._script.isSameObject(parent, stopAncestor):
                 break
 
             # We try to omit layout things right off the bat.
@@ -812,6 +803,13 @@
                 parent = parent.parent
                 continue
 
+            # To be consistent with how we provide access to other
+            # applications, don't speak the name of menu bars.
+            #
+            if parent.role == rolenames.ROLE_MENU_BAR:
+                parent = parent.parent
+                continue
+
             # Skip unfocusable menus.  This is for earlier versions
             # of Firefox where menus were nested in kind of an odd
             # dual nested menu hierarchy.
@@ -824,6 +822,8 @@
             # Now...autocompletes are wierd.  We'll let the handling of
             # the entry give us the name -- unless we're in a toolbar.
             #
+            containingToolbar = \
+                  self._script.getContainingRole(obj, rolenames.ROLE_TOOL_BAR)
             if parent.role == rolenames.ROLE_AUTOCOMPLETE and \
                not containingToolbar:
                 parent = parent.parent
@@ -2347,7 +2347,8 @@
         # in the Find toolbar), speak the line containing the caret
         # based on the user-customizable settings.
         #
-        if orca_state.locusOfFocus.role == rolenames.ROLE_ENTRY and \
+        if orca_state.locusOfFocus and \
+           orca_state.locusOfFocus.role == rolenames.ROLE_ENTRY and \
            orca_state.locusOfFocus.parent.role == rolenames.ROLE_TOOL_BAR \
            and self.inDocumentContent(event.source):
             [obj, offset] = self.getCaretContext()
@@ -2870,20 +2871,23 @@
             if newLocusOfFocus.text:
                 caretOffset = newLocusOfFocus.text.caretOffset
 
-                # If the old locusOfFocus was an entry in a toolbar, there's
-                # a good chance that we just returned from performing a find.
+                # If the old locusOfFocus was not in the document frame, and
+                # if the old locusOfFocus's frame is the same as the frame
+                # containing the new locusOfFocus, we likely just returned
+                # from a toolbar (find, location, menu bar, etc.).  We do
+                # not want to speak the hierarchy between that toolbar and
+                # the document frame.
                 #
-                if oldLocusOfFocus.role == rolenames.ROLE_ENTRY and \
-                   oldLocusOfFocus.parent.role == rolenames.ROLE_TOOL_BAR:
-                    # We don't want to speak all of the information
-                    # in the hierarchy; we should just read the line
-                    # with focus.
-                    #
-                    self.setCaretPosition(newLocusOfFocus, caretOffset)
-                    self.updateBraille(newLocusOfFocus)
-                    self.speakContents(self.getLineContentsAtOffset(
+                if oldLocusOfFocus and \
+                   not self.inDocumentContent(oldLocusOfFocus):
+                    oldFrame = self.getFrame(oldLocusOfFocus)
+                    newFrame = self.getFrame(newLocusOfFocus)
+                    if self.isSameObject(oldFrame, newFrame):
+                        self.setCaretPosition(newLocusOfFocus, caretOffset)
+                        self.updateBraille(newLocusOfFocus)
+                        self.speakContents(self.getLineContentsAtOffset(
                                                 newLocusOfFocus, caretOffset))
-                    return
+                        return
 
             else:
                 caretOffset = 0
