Index: src/Perks/BasicSpeechPerk.py
===================================================================
--- src/Perks/BasicSpeechPerk.py	(revision 542)
+++ src/Perks/BasicSpeechPerk.py	(working copy)
@@ -885,6 +885,7 @@
     self.inhibitMayStop()
     # reset stateful variables
     self.perk.resetLastsOnFocus()
+    print 'handling focus'
     return True
 
 class HandleSelectorChange(Task.SelectorTask):
@@ -918,15 +919,13 @@
     @param text: The currently selected text
     @type text: string
     '''
-    if self.hasAccState('single line'):
-      self.stopNow()
-      self.inhibitMayStop()
     n = len(text)
     if n >= self.perk.last_sel_len:
-      self.sayItem(text=n, template=_('selected %d'))
+      print 'saying selection on select', self.may_stop, self.getItemText(por)
+      self.sayTextAttrs(text=n, template=_('selected %d'))
     elif n != 0:
-      self.sayItem(text=(self.perk.last_sel_len-n, n),\
-                   template=_('unselected %d, %d left'))
+      self.sayTextAttrs(text=(self.perk.last_sel_len-n, n),\
+                   template=_('unselected %d, %d remaining'))
     self.perk.last_sel_len = n
     
     
@@ -977,7 +976,6 @@
     @param text_offset: The offset of the inserted text
     @type text_offset: integer
     '''
-    #print 'CHANGED: insert'
     self.changed = True
     if len(text) == 1:
       w = (self.perk_state.WordEcho and 
@@ -1014,24 +1012,25 @@
     '''
     # don't echo again if a change just happened
     if self.changed:
-      #print 'UNCHANGED: moved'
       self.changed = False
       return
-    
     if not por.isSameAcc(self.perk.last_caret):
       # say the current line
       self.mayStop()
+      print 'saying item on focus move', self.may_stop
       self.sayItem(text=text)
-      if self.getAccTextSelectionCount() > 0:
+      if (self.hasAccState('multi line') and 
+          self.getAccTextSelectionCount() > 0):
         # and the total number of selected characters if there's a selection
         self.sayTextAttrs(text=len(self.getAccTextSelection()[0]),
                           template=_('selected %s'))
     elif not por.isSameItem(self.perk.last_caret):
+      print 'saying item on across line move', self.may_stop
       # say the new line when item_offset changes
       self.mayStop()
       self.sayItem(text=text)
     else:
-      #print 'move:', por, self.perk.last_caret
+      print 'saying diff on within line move', self.may_stop
       # respond to caret movement on same line
       if por.isCharBefore(self.perk.last_caret):
         # moved left, say text between positions
@@ -1062,7 +1061,6 @@
       # say backspace if we're backing up
       self.sayItem(text=text, template=_('backspace %s'))
       self.changed = True
-      #print 'CHANGED: delete'
     else:
       # say delete if we're deleting the current
       self.sayItem(text=text, template=_('delete %s'))
@@ -1089,7 +1087,6 @@
     # store for next comparison
     self.perk.last_caret = por
     self.changed = False
-    #print 'UNCHANGED: update'
   
 class HandleStateChange(Task.StateTask):
   '''  
Index: src/EventManager.py
===================================================================
--- src/EventManager.py	(revision 542)
+++ src/EventManager.py	(working copy)
@@ -242,3 +242,4 @@
     # put all events that failed to execute back in the queue for later
     map(self.postEvents, later)
     return True
+
Index: src/Adapters/ATSPI/DefaultEventHandler.py
===================================================================
--- src/Adapters/ATSPI/DefaultEventHandler.py	(revision 542)
+++ src/Adapters/ATSPI/DefaultEventHandler.py	(working copy)
@@ -216,7 +216,8 @@
           # a redundant object role
           return
         # make a first guess as to whether the object is focused or not
-        focused = (ss.contains(Constants.STATE_FOCUSED) or
+        focused = (DefaultEventHandlerAdapter.last_focus == event.source or 
+                   #ss.contains(Constants.STATE_FOCUSED) or
                    ss.contains(Constants.STATE_ACTIVE))
       except AttributeError:
         # abort immediately if the CORBA object is dead
Index: src/Adapters/ATSPI/TextAdapter.py
===================================================================
--- src/Adapters/ATSPI/TextAdapter.py	(revision 542)
+++ src/Adapters/ATSPI/TextAdapter.py	(working copy)
@@ -470,6 +470,7 @@
     '''
     # get text interface
     text = Interfaces.IText(self.subject)
+    print 'raw selection on', text.getText(0, -1), kwargs
     # get selections
     n = text.getNSelections()
     # create a POR with start offset of the line and relative caret offset
@@ -487,7 +488,39 @@
       sel = text.getText(*text.getSelection(0))
       return (SelectorChange(por, unicode(sel, 'utf-8'), 
                              AEConstants.EVENT_CHANGE_TEXT_SELECT, **kwargs),)
+    
+  def _handleFocusEvent(self, event, **kwargs):
+    '''
+    Creates an L{AEEvent.FocusChange} indicating that the accessible being
+    adapted has gained the focus. Also a L{AEEvent.CaretChange}. This sequence 
+    of L{AEEvent}s will be posted by the caller.
+     
+    @param event: Raw focus change event
+    @type event: L{pyLinAcc.Event.Event}
+    @param kwargs: Parameters to be passed to any created L{AEEvent}
+    @type kwargs: dictionary
+    @return: L{AEEvent.FocusChange} and L{AEEvent.CaretChange}
+    @rtype: tuple of L{AEEvent}
+    '''
+    print 'raw focus'
+    try:
+      text = Interfaces.IEditableText(self.subject)
+    except NotImplementedError:
+      # only fire caret move when the text is editable, else fire selector
+      return super(SimpleTextEventHandlerAdapter,
+                   self)._handleFocusEvent(event, **kwargs)
 
+    kwargs['focused'] = True
+    # get the text of the caret line, it's starting and ending offsets
+    line = text.getText(0, -1)
+    # create a POR with start offset of the line and relative caret offset
+    por = POR(self.subject, 0, 0)
+    
+    # create a focus event for this POR
+    # and add a caret event to indicate the current position
+    return (FocusChange(por, True, **kwargs),    
+            CaretChange(por, unicode(line, 'utf-8'), 0, **kwargs))
+
 class TextEventHandlerAdapter(SimpleTextEventHandlerAdapter):
   '''  
   Overrides L{SimpleTextEventHandlerAdapter} to fire L{AEEvent.CaretChange}
