﻿id	summary	reporter	owner	description	type	status	priority	milestone	component	version	resolution	keywords	cc	blockedby	blocking	notify_on_close	platform	project
1717	QResizeEvent can break graphics under some circumstances	Tristan Croll	Tom Goddard	"I've stumbled on a (very specific) combination of circumstances where triggering a `QResizeEvent` breaks things due to deleted drawings still somehow being in the `View` drawing tree. In brief, if I: 

- load a model
- start ISOLDE (which triggers the model to be briefly removed from the session, re-instated subordinate to a higher-level ""Data manager"" model, and then redrawn on the next 'frame drawn' trigger to change the cartoon style using the method below - If I run this before loading the model, it gets overridden)

{{{
def set_to_default_cartoon(session, model = None):
    '''
    Adjust the ribbon representation to provide information without
    getting in the way.
    '''
    from chimerax.core.commands import atomspec
    from chimerax.std_commands import cartoon
    from chimerax.atomic.nucleotides.cmd import nucleotides
    from chimerax.atomic import AtomicStructures
    try:
        if model is None:
            atoms = None
            models = AtomicStructures([model])
        else:
            models = None
            atoms = model.atoms
            atoms.displays=False
            atoms[atoms.idatm_types!='HC'].displays=True
            arg = atomspec.AtomSpecArg('thearg')
            aspec= arg.parse('#' + model.id_string, session)[0]
        cartoon.cartoon(session, atoms = aspec, suppress_backbone_display=False)
        cartoon.cartoon_style(session, atoms = aspec, width=0.4, thickness=0.1, arrows_helix=True, arrow_scale = 2)
        cartoon.cartoon_tether(session, structures=models, opacity=0)
        nucleotides(session, 'atoms')
        from chimerax.std_commands import color
        color.color(session, model, color='bychain', target='ac')
        color.color(session, model, color='byhetero', target='a')
}}}

- while the above is processing, I drag the ISOLDE window to dock into the GUI triggering a `QResizeEvent`, then I get a traceback:

{{{
Traceback (most recent call last):
  File ""/opt/UCSF/ChimeraX-daily/lib/python3.7/site-packages/chimerax/ui/graphics.py"", line 80, in resizeEvent
    v.draw(check_for_changes = False)
  File ""/opt/UCSF/ChimeraX-daily/lib/python3.7/site-packages/chimerax/core/graphics/view.py"", line 159, in draw
    self._draw_scene(camera, drawings)
  File ""/opt/UCSF/ChimeraX-daily/lib/python3.7/site-packages/chimerax/core/graphics/view.py"", line 218, in _draw_scene
    draw_opaque(r, opaque_drawings)
  File ""/opt/UCSF/ChimeraX-daily/lib/python3.7/site-packages/chimerax/core/graphics/drawing.py"", line 1394, in draw_opaque
    _draw_multiple(drawings, renderer, Drawing.OPAQUE_DRAW_PASS)
  File ""/opt/UCSF/ChimeraX-daily/lib/python3.7/site-packages/chimerax/core/graphics/drawing.py"", line 1405, in _draw_multiple
    d.draw(renderer, draw_pass)
  File ""/opt/UCSF/ChimeraX-daily/lib/python3.7/site-packages/chimerax/core/graphics/drawing.py"", line 699, in draw
    if not self.display:
  File ""/opt/UCSF/ChimeraX-daily/lib/python3.7/site-packages/chimerax/core/graphics/drawing.py"", line 324, in get_display
    raise e
  File ""/opt/UCSF/ChimeraX-daily/lib/python3.7/site-packages/chimerax/core/graphics/drawing.py"", line 319, in get_display
    return self._any_displayed_positions and len(self._positions) > 0
TypeError: object of type 'NoneType' has no len()
}}}

... and if I open the shell and start typing, then every keypress triggers:
{{{
/opt/UCSF/ChimeraX-daily/lib/python3.7/site-packages/IPython/core/history.py:226: UserWarning: IPython History requires SQLite, your history will not be saved
warn(""IPython History requires SQLite, your history will not be saved"")
Traceback (most recent call last):
  File ""/opt/UCSF/ChimeraX-daily/lib/python3.7/site-packages/qtconsole/completion_html.py"", line 152, in eventFilter
    key = event.key()
AttributeError: 'QResizeEvent' object has no attribute 'key'

AttributeError: 'QResizeEvent' object has no attribute 'key'

File ""/opt/UCSF/ChimeraX-daily/lib/python3.7/site-packages/qtconsole/completion_html.py"", line 152, in eventFilter
key = event.key()
}}}

I've done some preliminary tracking down to try to work out if this is a ChimeraX bug or an ISOLDE bug. Editing `Drawing` with the following changes:
{{{
    def remove_drawings(self, drawings, delete=True):
        '''Remove specified child drawings.'''
        dset = set(drawings)
        self._child_drawings = [d for d in self._child_drawings
                                if d not in dset]
        for d in drawings:
            #d.parent = None
            pass
        if delete:
            for d in drawings:
                d.delete()
        self.redraw_needed(shape_changed=True, highlight_changed=True)

    def get_display(self):
        try:
            return self._any_displayed_positions and len(self._positions) > 0
        except TypeError as e:
            lineage = '; '.join([d.name for d in self.drawing_lineage])
            print(""Failed drawing: {}"".format(lineage))
            print(""Was deleted: {}"".format(self.was_deleted))
            raise e

}}}

Gives me:
{{{
Failed drawing: root; Data manager (6iqg.pdb); 6iqg.pdb; ribbon; 6iqg.pdb /A GLY 237 ribbons
Was deleted: True
}}}

... and if I revert the edit to `remove_drawings()` then the lineage collapses to just `6iqg.pdb /A GLY 237 ribbons`. 

Yet if I edit `view.py` at line 218 to put a `try...except` around `draw_opaque()` and list `opaque_drawings` on an exception, then all the deleted ribbon drawings are still in the list.

That's as far as I've gotten. It can of course be trivially avoided by changing `Drawing.get_display()` to

{{{
    def get_display(self):
        return not self.was_deleted and self._any_displayed_positions and len(self._positions) > 0
}}}

... but deleted drawings not being immediately removed from the `View` seems like the sort of thing that could trigger nasty bugs in the future."	defect	closed	moderate		Graphics		fixed						all	ChimeraX
