Opened 3 years ago

Last modified 3 years ago

#5149 defect new

insults ContainerWidget doesn't remove focus when child removed

Reported by: magmatt Owned by:
Priority: normal Milestone:
Component: conch Keywords:
Cc: z3p Branch:
Author: Launchpad Bug:

Description

If a ContainerWidget's focusedChild is removed, focus is not removed.

This is bad because the focusedChild continues to receive characterReceived calls instead of newly added children.

Here's some code that demonstrates the problem:

>>> from twisted.conch.insults.window import Widget, ContainerWidget
>>> c = ContainerWidget()
>>> c.focused = True
>>> a = Widget()
>>> c.addChild(a)
>>> assert c.focusedChild == a
>>> c.remChild(a)
>>> assert c.focusedChild == None
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError
>>> c.focusedChild == a
True

Attachments (1)

b5149.patch (372 bytes) - added by magmatt 3 years ago.
Patch attempt

Download all attachments as: .zip

Change History (4)

comment:1 Changed 3 years ago by DefaultCC Plugin

  • Cc z3p added

Changed 3 years ago by magmatt

Patch attempt

comment:2 Changed 3 years ago by magmatt

I changed the test code to this to avoid Container throwing YieldFocus:

from twisted.conch.insults.window import Widget, TopWindow
c = TopWindow(lambda: None, lambda x:None)                
c.focusReceived()                                         
a = Widget()                                              
c.addChild(a)                                             
assert c.focusedChild == a, (c.focusedChild, a)           
c.remChild(a)                                             
assert c.focusedChild == None, c.focusedChild             
assert a not in c.children, 'should remove'               

and here's the patch:

  • window.py

    diff --git a/window.py b/window.py                
    index 51cdeba..6c18c9b 100644                     
    a b class ContainerWidget(Widget): 
    139139        assert child.parent is self               
    140140        child.parent = None                       
    141141        self.children.remove(child)               
     142        if self.focusedChild == child:            
     143            self.changeFocus()                    
    142144        self.repaint()                            
    143145                                                  
    144146    def filthy(self):                             

comment:3 Changed 3 years ago by magmatt

Hmm... it would also work if changeFocus were run after the repaint. I think this might be better. Someone who knows more about how things work together could judge:

  • window.py

    diff --git a/window.py b/window.py                
    index 51cdeba..6c3ec3b 100644                     
    a b class ContainerWidget(Widget): 
    140140        child.parent = None                       
    141141        self.children.remove(child)               
    142142        self.repaint()                            
     143        if self.focusedChild == child:            
     144            self.changeFocus()                    
    143145                                                  
    144146    def filthy(self):                             
    145147        for ch in self.children:                  
Note: See TracTickets for help on using tickets.