pharo-graphics / Bloc

Low-level UI infrastructure & framework for Pharo
MIT License
81 stars 40 forks source link

Concurrency problem when element is exported to Form while its space is opened #560

Open tinchodias opened 3 months ago

tinchodias commented 3 months ago

This can happen when a script in a Workspace creates an element in a space, sends show it it, and immediately sends inspect to the element.

The inspector preview tab for element defined in:

BlElement >>
inspectionPreview: aBuilder
    <inspectorPresentationOrder: 1 title: 'Preview'>

    ^ aBuilder newMorph
        morph: self asPreviewMorph;
        yourself

ends up executing this:

BlElement >>
aeAsForm

    | invalidationBounds aCanvas |
    self isLayoutRequested ifTrue: [ self forceLayout ].

    "We want to consider our border, effect, as well as children's."
    invalidationBounds := self invalidationBoundsInSpace.
    aCanvas := AeCanvas extent: invalidationBounds extent.
    aCanvas pathTranslate: invalidationBounds origin negated.
    self aeFullDrawOn: aCanvas.
    ^ aCanvas asForm

This can be seen in this example of Toplo:

ToSandbox >>
example_SelectMaterialDesignIconMultiFiltrable

    | select   |
    select := ToMultiSelectElement new.
    self buildSelectListElementIn: select withIconProvider: ToMaterialDesignIconProvider.

    select filtrable: true.

    select nodeBuilder: [ :node :holder :iconDesc|
        | imPane |
        imPane := ToElement new layout: BlFrameLayout new.
        imPane fitContent.
        imPane withNullSkin.
        imPane background: Color veryLightGray.
        imPane addChild: (iconDesc icon size: 48 asPoint).
        node middleElement: imPane ].
    select fakeDataItem: select dataAccessor first.
    select hMatchParent.
    select placeholderText:
        ('Select icons' asRopedText foreground: Color red).

    select inputTextField requestFocus.
    select openInSpace.
    select inspect
tinchodias commented 2 months ago

Related reading, in web/chrome:

-> A common performance issue in web apps is forced synchronous layout: reading the size of an element and forcing the browser to immediately and synchronously undergo layout and style calculations in order to figure out the size. (https://tigeroakes.com/posts/resize-observer-avoid-forced-sync-layout/)

-> "Avoid forced synchronous layouts": https://web.dev/articles/avoid-large-complex-layouts-and-layout-thrashing#avoid_forced_synchronous_layouts