Page 1 of 2

Hard crash on trying to resize stack to fit content

Posted: Mon Nov 28, 2022 5:19 pm
by stam
Hi all,
I seem to be doing some the that's causing a HARD crash. The code below works fine the first time I open a test stack, but if I close the and re-open it immediate crashes and exits LiveCode.

I know there are a lot of discussions about changing control dimensions/locations to fit the stack, but I have need of the opposite of this so that when I move from one card to another, the stack size changes to fit the content, and that the content should have equal margins from the edge of the stack all the way around.

My approach is to (in script) group all elements on the card into a temporary group, derive the rect of what the stack should be with default or given margins, resize/reposition the stack then ungroup the temporary group.

This all works well, but is very abrupt - I was hoping there would be some way of giving a smoother transition but unlock with visual effect seems to do nothing when switching to cards (I use Lock Screen instead of Lock Screen for visual effect, as the latter makes it *really* slow). Ideally I'd like to show a quick but smooth stretch in the top/left to bottom/right axis, but not found a way yet...

The problem is that this works well - but if I close and reopen the stack, it immediately and reproducibly crashes LC to crash hard and exit. If I relaunch LC and open the same stack again it works fine, but on closing and re-opening the test stack... BOOM!
I can't explain this...

My code resides in the stack script:

Code: Select all

## PURPOSE : resize stack to content when moving to another card
# NOTE: do not use with any cards containing background and/or shared groups, as these cannot be grouped

command autoResizeOnContent pMargins
    # groups all elements into a large temporary group, calls autoResize then ungroups the temp group
    local tControls, tGroupMembers, tGroupID
    lock screen  
    repeat with x = 1 to the number of controls of this card
        put the long name of control x of this card & return after tControls
    end repeat
    filter lines of tControls without regex pattern "\sgroup" // eliminates members of other groups
    repeat for each line tLine in tControls
        if there is a tLine then put the name of tLine & " and " after tGroupMembers
    end repeat
    delete the last word in tGroupMembers
    do merge ("group  [[tGroupMembers]]")
    put it into tGroupID
    autoResize pMargins
    ungroup tGroupID
    select empty
    unlock screen with visual "stretch from top" 
end autoResizeOnContent

command autoResize pMargins
    # Resizes stack by the rect of the temporary group of all content in autoResizeOnContent
    # default margin is 21 px (minus the 4 px of the group) = 17 px (leave blank to accept this)
    # the groups have margin of 4, so subtract that from whatever margin you choose, or leave blank for default of 21 px (= 17 )
    local tRect, tTopLeft, tWidth, tHeight, tGroup
    put the topLeft of this stack into tTopLeft
    if pMargins is empty then put 17 into pMargins
    put the groupIDs of this card into tGroup
    put the rect of group id tGroup into tRect
    
    subtract pMargins from item 1 of tRect
    subtract pMargins from item 2 of tRect
    add pMargins to item 3 of tRect
    add pMargins to item 4 of tRect
    put item 3 of tRect - item 1 of tRect into tWidth
    put item 4 of tRect - item 2 of tRect into tHeight
    
    set the width of this stack to tWidth
    set the height of this stack to tHeight
    set the topLeft of this stack to tTopLeft
    set the loc of group id tGroup to the loc of this card
end autoResize

on openCard
    # if in stack script and if a card has an openCard handler, end this with 'pass openCard' or just add to card script directly
    if the controlIDs of this card is not empty then
        autoResizeOnContent
    end if
end openCard
I attach the test stack - be aware that it will probably work fine to start with (just go to next card to test), but if you close and re-open the stack there should be an instantaneous crash - so please ensure your work is saved before testing this!

Many thanks for any suggestions (both for the crash and on how to smooth the widow size change if that's possible)
Stam

PS: As an aside, why is the rect of the stack so much larger than the rect of the card, but the height/width of the 2 are the same???

Re: Hard crash on trying to resize stack to fit content

Posted: Mon Nov 28, 2022 5:28 pm
by Klaus
Hi stam,

problem confirmed with LC 9.6.9 rc2 on macOS 12.6.1, I can open the stack and go to the next card and back.
When I close the stack and open it again, LC crashes immediately.


Best

Klaus

Re: Hard crash on trying to resize stack to fit content

Posted: Mon Nov 28, 2022 6:28 pm
by stam
Klaus wrote:
Mon Nov 28, 2022 5:28 pm
problem confirmed with LC 9.6.9 rc2 on macOS 12.6.1, I can open the stack and go to the next card and back.
When I close the stack and open it again, LC crashes immediately.
Thank you Klaus - are you on an Intel or ARM Mac?
If you're also using an M1/M2 Mac, it still may be that - I probably have an old intel Mac kicking about somewhere to test on that as well, as I too am using 9.6.2 RC2 and 10 DP4, although on MacOS 13.0.1.

My code seemed to be working exactly as expected until I closed and re-opened the stack. Aggravating :-/

Bug reported here: https://quality.livecode.com/show_bug.cgi?id=24033

Thanks once again for testing Klaus,
Stam

Re: Hard crash on trying to resize stack to fit content

Posted: Mon Nov 28, 2022 6:30 pm
by Klaus
I'm on an INTEL MacMini late 2014

Re: Hard crash on trying to resize stack to fit content

Posted: Mon Nov 28, 2022 7:17 pm
by Cairoo
Hi stam

A temporary workaround would be to insert the following code after the line "select empty":

Code: Select all

create field "tempfield1"
create field "tempfield2"
group field "tempfield1" and field "tempfield2"
delete it
This lets the IDE forget the previously ungrouped controls.

Gerrie

Re: Hard crash on trying to resize stack to fit content

Posted: Mon Nov 28, 2022 7:30 pm
by SWEdeAndy
stam wrote:
Mon Nov 28, 2022 5:19 pm
PS: As an aside, why is the rect of the stack so much larger than the rect of the card, but the height/width of the 2 are the same???
The stack rect is relative to the screen.
The card rect is relative to the stack.

So the card's topLeft is always 0,0 and the card's width/height = the stack's width/height.

This may not be relevant to the error you experience, but just to answer that question... :)

Re: Hard crash on trying to resize stack to fit content

Posted: Mon Nov 28, 2022 8:49 pm
by stam
Cairoo wrote:
Mon Nov 28, 2022 7:17 pm
Hi stam

A temporary workaround would be to insert the following code after the line "select empty":

Code: Select all

create field "tempfield1"
create field "tempfield2"
group field "tempfield1" and field "tempfield2"
delete it
This lets the IDE forget the previously ungrouped controls.

Gerrie
Thanks Gerrie, that indeed prevents the crash on re-opening the stack.
But how bizarre/random is that? Was this a known bug?

Stam

Re: Hard crash on trying to resize stack to fit content

Posted: Mon Nov 28, 2022 8:50 pm
by stam
SWEdeAndy wrote:
Mon Nov 28, 2022 7:30 pm
This may not be relevant to the error you experience, but just to answer that question... :)
Thanks Andreas - quite obvious when you point it out :oops: :oops:

Re: Hard crash on trying to resize stack to fit content

Posted: Mon Nov 28, 2022 9:55 pm
by Cairoo
stam wrote:
Mon Nov 28, 2022 8:49 pm
But how bizarre/random is that? Was this a known bug?
I didn't know about it. The line of code where it crashed was:

Code: Select all

do merge ("group  [[tGroupMembers]]")
suggesting that the IDE tried to refer to the previously ungrouped controls that were no longer in memory because of the "destroyStack" property.

Gerrie

Re: Hard crash on trying to resize stack to fit content

Posted: Mon Nov 28, 2022 10:18 pm
by stam
Cairoo wrote:
Mon Nov 28, 2022 9:55 pm
stam wrote:
Mon Nov 28, 2022 8:49 pm
But how bizarre/random is that? Was this a known bug?
I didn't know about it. The line of code where it crashed was:

Code: Select all

do merge ("group  [[tGroupMembers]]")
suggesting that the IDE tried to refer to the previously ungrouped controls that were no longer in memory because of the "destroyStack" property.
erm... tGroupMembers is simply a collection of names of the controls/groups on the current card. It should not rely on memory and is independent of grouping - in fact the controls have to be ungrouped to be included in this, or be the top level group (the group's subgroups and controls are ignored). With 'destroyStack' set to false, you are effectively never 'closing' the stack until you quit LC, so that's the same scenario as saying it never crashes the first time you open the stack, no matter how many cards you navigate, which is indeed the case.

I suspect it must be something to do with the way LC remembers group names or the last group that incorrectly persists after the stack has been closed and removed from memory. The stack itself is in exactly the same state as when first opened, so LC must be doing something funky.

Not sure I understand that tbh, but who knows. Your fix worked but searching bug database it seems that at least since v4 there have been reports of being able to crash LC in 4 lines, relating to groups. I guess we'll see ;)

thanks once again,
Stam

Re: Hard crash on trying to resize stack to fit content

Posted: Tue Nov 29, 2022 12:29 am
by bn
Hi Stam,

I modified your stack a bit by calculating the rects of the controls and deriving the enclosing rect. That does not crash.
Furthermore for visual effect you have to lock the screen for it to work. Although I do not know if that is the effect you had in mind. The transition from one stack rect to the other is not animated, only the controls of the next card do a visual effect.

Code: Select all

lock screen for visual effect
Kind regards
Bernd

Re: Hard crash on trying to resize stack to fit content

Posted: Tue Nov 29, 2022 2:54 am
by stam
Thanks Bernd - genius as always ;)
I had considered something similar but was concerned I wouldn't be able to ensure equal margins around the controls but your solution certainly does and doesn't crash.
Still, my grouping method works and with @Cairoo's workaround it doesn't crash now either - I guess that's uncovered some weird bug.

As to the transition - no that wasn't I was looking for really and tbh having tried several options I don't think LC can really do what I had in mind... probably.

What I had in mind is more or less like the mockup below - but in LC the controls get distorted by the visual effect and then the window resizes - with things like dissolve it's excruciatingly slow and the window remains unchanged during the transition, then snaps to a new size, whereas the animation I'm looking for is more about simultaneously resizing the window as repositioning the controls:
Image
I guess I could simulate it by getting a snapshot of it and shrinking the snapshot, but that seems like a ridiculous amount of work for a simple graphics nicety that doesn't change anything...

Thanks once again for your excellent solution :)

Re: Hard crash on trying to resize stack to fit content

Posted: Wed Nov 30, 2022 2:07 am
by bn
Hi Stam,

Here is a version of your stack that animates the change of the stack rect. It does nothing to the location of the controls etc. And it has no visual effect.

Maybe this makes the change of the stack rect less abrupt.
I do not know how it behaves with larger stacks and cards with more graphically intensive content but with your sample stack it works well.

You can fiddle with the transition by changing "stepfactor" and the "wait x milliseconds..." in handler "autoResize" in the stack script. It is marked by comments.

It is just an exercise to see if it could be done and how it would perform. Your use case to change the dimensions of a stack when going from card to card is a bit unusual.

Kind regards
Bernd

Re: Hard crash on trying to resize stack to fit content

Posted: Wed Nov 30, 2022 3:18 am
by stam
Bernd you are the man!
Exactly what I was looking for :)

I found that increasing the stepFactor produces smoother animations (although I guess that's more CPU heavy)

Very nice!

Re: Hard crash on trying to resize stack to fit content

Posted: Sat Dec 03, 2022 12:15 am
by bn
Stam,

I tinkered with the resize problem and took the occasion to implement a time dependent resize routine that I took from Scott Rossis' stack "ease.rev".
The math was done (according to Scott) by Richard Herz. I just adapted the code to handle stack resizing instead of moving controls.

The main advantage is that you can give a duration in milliseconds and the code adapts the step sizes. That should be easier to deploy to computers that vary in speed.

You can do an "ease-in" or "ease-out", see code of stack script. It is set to "ease-out", the animation time is hard-coded to 300 milliseconds, change that in code.
I only tested on my M1 arm MacBook Pro natively in 9.6.9 dp-2 and in rosetta mode in 9.6.6. Both worked well whereas in my previous version running on 9.6.6 in rosetta mode the difference in performance were more noticeable.

By repurposing Scott's code I finally understood what was going on. (as soon as someone says "phi" I feel stunned :( )

Kind regards
Bernd