google / blockly

The web-based visual programming editor.
https://developers.google.com/blockly/
Apache License 2.0
12.48k stars 3.71k forks source link

Clicking ⚙ of "if" block makes the block fly far away #4175

Closed zhouxiaobo1990 closed 4 years ago

zhouxiaobo1990 commented 4 years ago

Describe the bug

Clicking ⚙ of "if" block makes the block fly far away. This happens when there are many blocks

To Reproduce

  1. Go to https://blockly-demo.appspot.com/static/demos/code/index.html

  2. In "XML" tab, add following codes:

<xml xmlns="https://developers.google.com/blockly/xml">
  <block type="controls_if" id="|My_n_!S!133K]i^65i:" x="0" y="0">
    <mutation elseif="1"></mutation>
    <statement name="DO0">
      <block type="text_print" id="l1GOG$U!$+.jB@ly[0T=">
        <value name="TEXT">
          <shadow type="text" id="^`A2]$)_fL98Sj$q1@Li">
            <field name="TEXT">abc</field>
          </shadow>
        </value>
        <next>
          <block type="text_print" id="]wpq(y]Dd%vjo)bF)%_#">
            <value name="TEXT">
              <shadow type="text" id="-H_lP^d.~}?nCZmk)$}8">
                <field name="TEXT">abc</field>
              </shadow>
            </value>
          </block>
        </next>
      </block>
    </statement>
    <statement name="DO1">
      <block type="text_print" id="!,In!xB(::Z4S_Asa|7@">
        <value name="TEXT">
          <shadow type="text" id="TPMno!vD;sLsW%U`3Imm">
            <field name="TEXT">abc</field>
          </shadow>
        </value>
      </block>
    </statement>
    <next>
      <block type="controls_if" id="W5gST][l*q@Pku/2AB^M">
        <mutation elseif="1"></mutation>
        <statement name="DO0">
          <block type="text_print" id="w[i{lPW|ri.rdQNM!)?6">
            <value name="TEXT">
              <shadow type="text" id="h{W8KGwYAej^s[^8UVdp">
                <field name="TEXT">abc</field>
              </shadow>
            </value>
            <next>
              <block type="text_print" id="vP:/JovqxIf3lOZbpXKr">
                <value name="TEXT">
                  <shadow type="text" id=";/H/6Kk!m=~tChXxSSJj">
                    <field name="TEXT">abc</field>
                  </shadow>
                </value>
              </block>
            </next>
          </block>
        </statement>
        <statement name="DO1">
          <block type="text_print" id="!9|CDUhS(dxNkh0u31t,">
            <value name="TEXT">
              <shadow type="text" id="gWXdxLy|]*C4XaQnJK2_">
                <field name="TEXT">abc</field>
              </shadow>
            </value>
          </block>
        </statement>
        <next>
          <block type="text_print" id="2{sWuibvL8TSAikmHA/j">
            <value name="TEXT">
              <shadow type="text" id="o=}9m!T/bbt9+h=-7J%U">
                <field name="TEXT">abc</field>
              </shadow>
            </value>
            <next>
              <block type="controls_if" id="9P7wN9Hiv,z8:mUDdj|X">
                <mutation else="1"></mutation>
                <statement name="DO0">
                  <block type="text_print" id="yjy@-;|R!4ekM[H;D:b$">
                    <value name="TEXT">
                      <shadow type="text" id="?g*/%:=g8p_ojU%%0!QZ">
                        <field name="TEXT">abc</field>
                      </shadow>
                    </value>
                  </block>
                </statement>
                <statement name="ELSE">
                  <block type="text_print" id="4[0Hg%#-9zcrp.rM7$sO">
                    <value name="TEXT">
                      <shadow type="text" id="1djsA83sg!I6#%sWEiUF">
                        <field name="TEXT">abc</field>
                      </shadow>
                    </value>
                  </block>
                </statement>
                <next>
                  <block type="text_print" id="/*hcRRzbBxRn*|lg[B,$">
                    <value name="TEXT">
                      <shadow type="text" id="TOq9RpuI##L`D*![N{VZ">
                        <field name="TEXT">abc</field>
                      </shadow>
                    </value>
                    <next>
                      <block type="controls_if" id="(ym(qRAm[5h,mY+VWXf5">
                        <mutation elseif="1"></mutation>
                        <statement name="DO0">
                          <block type="text_print" id="6j3-V63r*jO[ZxK`P|.{">
                            <value name="TEXT">
                              <shadow type="text" id="=bTXxhQ?IW9U7~g}$.V~">
                                <field name="TEXT">abc</field>
                              </shadow>
                            </value>
                            <next>
                              <block type="text_print" id="=9Usyz.~f|-sAALV:~u4">
                                <value name="TEXT">
                                  <shadow type="text" id="03D]04Kc1Y?=rD^{8-Xf">
                                    <field name="TEXT">abc</field>
                                  </shadow>
                                </value>
                              </block>
                            </next>
                          </block>
                        </statement>
                        <statement name="DO1">
                          <block type="text_print" id="h|k0%:LGm]-08r[Vu}Rd">
                            <value name="TEXT">
                              <shadow type="text" id="BH3$hI.Zd|:uK~ewGGf_">
                                <field name="TEXT">abc</field>
                              </shadow>
                            </value>
                          </block>
                        </statement>
                        <next>
                          <block type="controls_if" id="q3wLV.)CJb}8u2n?PJd3">
                            <mutation elseif="1"></mutation>
                            <statement name="DO0">
                              <block type="text_print" id="@q+RX)Us7*@{f0zYUl`v">
                                <value name="TEXT">
                                  <shadow type="text" id="Y?K[X-h8GnRXz%dKVsxq">
                                    <field name="TEXT">abc</field>
                                  </shadow>
                                </value>
                                <next>
                                  <block type="text_print" id="vu+QNLF6xKZ],#nhLp2O">
                                    <value name="TEXT">
                                      <shadow type="text" id="GrvGnIm7R-i:?QQ9(GHe">
                                        <field name="TEXT">abc</field>
                                      </shadow>
                                    </value>
                                  </block>
                                </next>
                              </block>
                            </statement>
                            <statement name="DO1">
                              <block type="text_print" id="lj5=W%S1b/Q0_lR|W*$,">
                                <value name="TEXT">
                                  <shadow type="text" id="V[4Nsfg+|SKdj-a%@D^]">
                                    <field name="TEXT">abc</field>
                                  </shadow>
                                </value>
                              </block>
                            </statement>
                            <next>
                              <block type="controls_if" id="H{Vm~_!/YGM3Ah0#;+%i">
                                <mutation elseif="1"></mutation>
                                <statement name="DO0">
                                  <block type="text_print" id="*~?VOE!{TF2K]mJqXC`R">
                                    <value name="TEXT">
                                      <shadow type="text" id="NIj1A0$c^;V)ClhJd}K!">
                                        <field name="TEXT">abc</field>
                                      </shadow>
                                    </value>
                                    <next>
                                      <block type="text_print" id="lln%Y{%Q|~U*E|o]~tFR">
                                        <value name="TEXT">
                                          <shadow type="text" id="hmn-k;8[z2D/p~x1#@jc">
                                            <field name="TEXT">abc</field>
                                          </shadow>
                                        </value>
                                      </block>
                                    </next>
                                  </block>
                                </statement>
                                <statement name="DO1">
                                  <block type="text_print" id="fN?Sxrnb2,U-W6R{];Lj">
                                    <value name="TEXT">
                                      <shadow type="text" id="E},;l8*32lh}+3-~RNX?">
                                        <field name="TEXT">abc</field>
                                      </shadow>
                                    </value>
                                  </block>
                                </statement>
                                <next>
                                  <block type="controls_if" id="ZlqpK=rl_~v3ZRl]6,7^">
                                    <mutation elseif="1"></mutation>
                                    <statement name="DO0">
                                      <block type="text_print" id="fNlg!/d!}+2xHD?/ydob">
                                        <value name="TEXT">
                                          <shadow type="text" id="DHxWIl32ypfEE*KU!p.M">
                                            <field name="TEXT">abc</field>
                                          </shadow>
                                        </value>
                                        <next>
                                          <block type="text_print" id="^hS/^E;5X%n_2s1U*qMN">
                                            <value name="TEXT">
                                              <shadow type="text" id=":fNNS6iBNF^N8lVB/NiO">
                                                <field name="TEXT">abc</field>
                                              </shadow>
                                            </value>
                                          </block>
                                        </next>
                                      </block>
                                    </statement>
                                    <statement name="DO1">
                                      <block type="text_print" id="C/eJ%n3#dRQt;_0)CUvW">
                                        <value name="TEXT">
                                          <shadow type="text" id="wu+VN~M:AbAn|$a,Ijrp">
                                            <field name="TEXT">abc</field>
                                          </shadow>
                                        </value>
                                      </block>
                                    </statement>
                                    <next>
                                      <block type="controls_if" id="F0C8{T[Vddh8ZZJO^/);">
                                        <mutation elseif="1"></mutation>
                                        <statement name="DO0">
                                          <block type="text_print" id="Pdcl,n[9v-,YCB0]ni]O">
                                            <value name="TEXT">
                                              <shadow type="text" id="B5}f8Ca[WNU{J[FhPVky">
                                                <field name="TEXT">abc</field>
                                              </shadow>
                                            </value>
                                            <next>
                                              <block type="text_print" id="hGdLWrQRpaq*mEDd)7VK">
                                                <value name="TEXT">
                                                  <shadow type="text" id="pfg$Phe+5Qf4N)DHx6AZ">
                                                    <field name="TEXT">abc</field>
                                                  </shadow>
                                                </value>
                                              </block>
                                            </next>
                                          </block>
                                        </statement>
                                        <statement name="DO1">
                                          <block type="text_print" id=".?Od)}KO#P_u[p:8Q^Hl">
                                            <value name="TEXT">
                                              <shadow type="text" id="c(@`^#K^?O@!h4z(7RQ`">
                                                <field name="TEXT">abc</field>
                                              </shadow>
                                            </value>
                                          </block>
                                        </statement>
                                        <next>
                                          <block type="controls_if" id="((*pGFIc0lx[WZoMgw#}">
                                            <mutation elseif="1"></mutation>
                                            <statement name="DO0">
                                              <block type="text_print" id="ds~}=6K*X-A^pT,dK@EG">
                                                <value name="TEXT">
                                                  <shadow type="text" id="73?i/3Mdiacg^v-aV*|%">
                                                    <field name="TEXT">abc</field>
                                                  </shadow>
                                                </value>
                                                <next>
                                                  <block type="text_print" id="O8,70-hj%W+-^]_pi?mR">
                                                    <value name="TEXT">
                                                      <shadow type="text" id=")XB^A70V9^=-Pv_)9^SU">
                                                        <field name="TEXT">abc</field>
                                                      </shadow>
                                                    </value>
                                                  </block>
                                                </next>
                                              </block>
                                            </statement>
                                            <statement name="DO1">
                                              <block type="text_print" id="(kvObNX,iip8lXQMAfwt">
                                                <value name="TEXT">
                                                  <shadow type="text" id="p@S!]V*7tU/4_IjDJ3G.">
                                                    <field name="TEXT">abc</field>
                                                  </shadow>
                                                </value>
                                              </block>
                                            </statement>
                                            <next>
                                              <block type="controls_if" id="jeiQ;SY8.vuB;@$pKXd1">
                                                <mutation elseif="1"></mutation>
                                                <statement name="DO0">
                                                  <block type="text_print" id="N2zC6)}x^*;]}#`{c*.o">
                                                    <value name="TEXT">
                                                      <shadow type="text" id="zHIXG*Z7~rm50uvjEFov">
                                                        <field name="TEXT">abc</field>
                                                      </shadow>
                                                    </value>
                                                    <next>
                                                      <block type="text_print" id="S^2iUPhe0Lr(]aUv,?eo">
                                                        <value name="TEXT">
                                                          <shadow type="text" id="Ox3]1[{B5+Jpv{y]:vuT">
                                                            <field name="TEXT">abc</field>
                                                          </shadow>
                                                        </value>
                                                      </block>
                                                    </next>
                                                  </block>
                                                </statement>
                                                <statement name="DO1">
                                                  <block type="text_print" id="~TO{,!4vBA55]wm!COWa">
                                                    <value name="TEXT">
                                                      <shadow type="text" id="=l-L8I3GGk7jWg{3!I@f">
                                                        <field name="TEXT">abc</field>
                                                      </shadow>
                                                    </value>
                                                  </block>
                                                </statement>
                                                <next>
                                                  <block type="text_print" id="(_KTQEP0gJQfLUna)H%b">
                                                    <value name="TEXT">
                                                      <shadow type="text" id="5!It57]IJD1@jvf{7~[%">
                                                        <field name="TEXT">abc</field>
                                                      </shadow>
                                                    </value>
                                                    <next>
                                                      <block type="controls_if" id="tcA;m^U74;y3g[`VM$lL">
                                                        <mutation else="1"></mutation>
                                                        <statement name="DO0">
                                                          <block type="text_print" id="@md=JHxD_dRu{,ion[x7">
                                                            <value name="TEXT">
                                                              <shadow type="text" id="@PqbhvwT+k*Vbbs?=J;p">
                                                                <field name="TEXT">abc</field>
                                                              </shadow>
                                                            </value>
                                                          </block>
                                                        </statement>
                                                        <statement name="ELSE">
                                                          <block type="text_print" id="1L%hq+jQ`lpPwl1?:T7X">
                                                            <value name="TEXT">
                                                              <shadow type="text" id="By2yI|KMIkBe?1XQh)Hj">
                                                                <field name="TEXT">abc</field>
                                                              </shadow>
                                                            </value>
                                                          </block>
                                                        </statement>
                                                        <next>
                                                          <block type="text_print" id="RhH$(e|^a)C@=cC2STY#">
                                                            <value name="TEXT">
                                                              <shadow type="text" id="=xjWs,G|q3^J6VD,KUjx">
                                                                <field name="TEXT">abc</field>
                                                              </shadow>
                                                            </value>
                                                            <next>
                                                              <block type="controls_if" id="Kp0sM?0h?/bXk?k#K[bM">
                                                                <mutation elseif="1"></mutation>
                                                                <statement name="DO0">
                                                                  <block type="text_print" id="sK#PLzy]91ik:wvW7:U1">
                                                                    <value name="TEXT">
                                                                      <shadow type="text" id="|G.yI@);UjE#8nJ1JtS)">
                                                                        <field name="TEXT">abc</field>
                                                                      </shadow>
                                                                    </value>
                                                                    <next>
                                                                      <block type="text_print" id="rwO54hd,KXUCjcnze8i9">
                                                                        <value name="TEXT">
                                                                          <shadow type="text" id="~fjkC?M]F){Q(.Xi_@E4">
                                                                            <field name="TEXT">abc</field>
                                                                          </shadow>
                                                                        </value>
                                                                      </block>
                                                                    </next>
                                                                  </block>
                                                                </statement>
                                                                <statement name="DO1">
                                                                  <block type="text_print" id="eV.am^1zH1DGD=#tbZiR">
                                                                    <value name="TEXT">
                                                                      <shadow type="text" id="[EcfQN^lrfnw^*V8)u~0">
                                                                        <field name="TEXT">abc</field>
                                                                      </shadow>
                                                                    </value>
                                                                  </block>
                                                                </statement>
                                                                <next>
                                                                  <block type="controls_if" id="o1XB,dJ.M4m%O[HCVef:">
                                                                    <mutation elseif="1"></mutation>
                                                                    <statement name="DO0">
                                                                      <block type="text_print" id="4~9)_.+q;QY|Z[m~x1x:">
                                                                        <value name="TEXT">
                                                                          <shadow type="text" id=")$iz@W6F1M-eCdUggT*E">
                                                                            <field name="TEXT">abc</field>
                                                                          </shadow>
                                                                        </value>
                                                                        <next>
                                                                          <block type="text_print" id="-kCQf#i38agVCYC*OViQ">
                                                                            <value name="TEXT">
                                                                              <shadow type="text" id=":0Kujj]MIAoT_p=nnT#7">
                                                                                <field name="TEXT">abc</field>
                                                                              </shadow>
                                                                            </value>
                                                                          </block>
                                                                        </next>
                                                                      </block>
                                                                    </statement>
                                                                    <statement name="DO1">
                                                                      <block type="text_print" id="R!=.kS7an9B1g;BVD~Cz">
                                                                        <value name="TEXT">
                                                                          <shadow type="text" id="[cCdoX|EhmP|]A@[Pi^l">
                                                                            <field name="TEXT">abc</field>
                                                                          </shadow>
                                                                        </value>
                                                                      </block>
                                                                    </statement>
                                                                    <next>
                                                                      <block type="controls_if" id="#q_nhofJ2Z(1Z1OR=0un">
                                                                        <mutation elseif="1"></mutation>
                                                                        <statement name="DO0">
                                                                          <block type="text_print" id="bitYn|ac(t*_kP1k([Y:">
                                                                            <value name="TEXT">
                                                                              <shadow type="text" id="@vkgIHGrX}VxrZO^H15a">
                                                                                <field name="TEXT">abc</field>
                                                                              </shadow>
                                                                            </value>
                                                                            <next>
                                                                              <block type="text_print" id="[vsHSlR?74GS`5Lv`-{l">
                                                                                <value name="TEXT">
                                                                                  <shadow type="text" id="mI)}oAS4N=V4*:nyBD45">
                                                                                    <field name="TEXT">abc</field>
                                                                                  </shadow>
                                                                                </value>
                                                                              </block>
                                                                            </next>
                                                                          </block>
                                                                        </statement>
                                                                        <statement name="DO1">
                                                                          <block type="text_print" id="@2/87e2;O/NW^(@+lQ:p">
                                                                            <value name="TEXT">
                                                                              <shadow type="text" id="=WIkc5BBBf%S%1vEj-Oj">
                                                                                <field name="TEXT">abc</field>
                                                                              </shadow>
                                                                            </value>
                                                                          </block>
                                                                        </statement>
                                                                        <next>
                                                                          <block type="controls_if" id="WwxZTH~W_d)}n!Wg)%Fw">
                                                                            <mutation elseif="1"></mutation>
                                                                            <statement name="DO0">
                                                                              <block type="text_print" id="!:o%dJ,wKLPt@vTk6m/R">
                                                                                <value name="TEXT">
                                                                                  <shadow type="text" id="*?+]UnLXmyu~=LnW7N^:">
                                                                                    <field name="TEXT">abc</field>
                                                                                  </shadow>
                                                                                </value>
                                                                                <next>
                                                                                  <block type="text_print" id="wtnbrQZ4kcSH?{Rhg{-q">
                                                                                    <value name="TEXT">
                                                                                      <shadow type="text" id="Q=pTb%m}_w$gJQKjM;`+">
                                                                                        <field name="TEXT">abc</field>
                                                                                      </shadow>
                                                                                    </value>
                                                                                  </block>
                                                                                </next>
                                                                              </block>
                                                                            </statement>
                                                                            <statement name="DO1">
                                                                              <block type="text_print" id="fy!=nlTUgTRr9.kSd(tz">
                                                                                <value name="TEXT">
                                                                                  <shadow type="text" id="MHur(8?i4M^btS5C[8u=">
                                                                                    <field name="TEXT">abc</field>
                                                                                  </shadow>
                                                                                </value>
                                                                              </block>
                                                                            </statement>
                                                                            <next>
                                                                              <block type="controls_if" id="Ae,{b.f=},v{O~+|].gO">
                                                                                <mutation elseif="1"></mutation>
                                                                                <statement name="DO0">
                                                                                  <block type="text_print" id="m916m|c=4(wsN/L97|oT">
                                                                                    <value name="TEXT">
                                                                                      <shadow type="text" id="A#M-f}%*VQ7]IVIhxm7:">
                                                                                        <field name="TEXT">abc</field>
                                                                                      </shadow>
                                                                                    </value>
                                                                                    <next>
                                                                                      <block type="text_print" id="(Q?$OfFiC%{rK`[;)2#E">
                                                                                        <value name="TEXT">
                                                                                          <shadow type="text" id="v27|[/R`_Z_FUugaH~`m">
                                                                                            <field name="TEXT">abc</field>
                                                                                          </shadow>
                                                                                        </value>
                                                                                      </block>
                                                                                    </next>
                                                                                  </block>
                                                                                </statement>
                                                                                <statement name="DO1">
                                                                                  <block type="text_print" id="rdyFNsh/?$B58OhZ~Gw3">
                                                                                    <value name="TEXT">
                                                                                      <shadow type="text" id="Q{eyj~v[[,OKrPc(u|1D">
                                                                                        <field name="TEXT">abc</field>
                                                                                      </shadow>
                                                                                    </value>
                                                                                  </block>
                                                                                </statement>
                                                                              </block>
                                                                            </next>
                                                                          </block>
                                                                        </next>
                                                                      </block>
                                                                    </next>
                                                                  </block>
                                                                </next>
                                                              </block>
                                                            </next>
                                                          </block>
                                                        </next>
                                                      </block>
                                                    </next>
                                                  </block>
                                                </next>
                                              </block>
                                            </next>
                                          </block>
                                        </next>
                                      </block>
                                    </next>
                                  </block>
                                </next>
                              </block>
                            </next>
                          </block>
                        </next>
                      </block>
                    </next>
                  </block>
                </next>
              </block>
            </next>
          </block>
        </next>
      </block>
    </next>
  </block>
</xml>
  1. In "Blocks" tab, disconnect some blocks like this.

  2. Clicking ⚙ of the top "if" block.

  3. The "if" block flies far away.

  4. Find the "if" block and clicks ⚙ twice. (once for close and once for reopen)

  5. The "if" block flies again.

Expected behavior

Should not fly.

Desktop (please complete the following information):

Stack Traces

No console logs generated.

alschmiedt commented 4 years ago

I ran a git bisect and it looks like this is the offending PR #3468.

BeksOmega commented 4 years ago

Looked into this! The issue is that #3468 removed the setting of .rendered to false, and the rendered property is used to check if the block needs to be bumped (eg here).

So when the if block's mutator is opened the inputs are removed and the child print blocks are kicked. Because the child blocks are temporarily disconnected it causes the if block to bump away from them.

We cannot add the .rendered assignments back in, because that would cause #3458 to reoccur.

Personally I think a more complex system for handling rendering is necessary. Something that can handle states like:

Also here's some more minimal XML for getting the issue to occur:

<xml xmlns="https://developers.google.com/blockly/xml">
  <block type="controls_if" id="|My_n_!S!133K]i^65i:" x="0" y="0">
    <mutation elseif="1"></mutation>
    <statement name="DO1">
      <block type="text_print" id="!,In!xB(::Z4S_Asa|7@">
        <value name="TEXT">
          <shadow type="text" id="TPMno!vD;sLsW%U`3Imm">
            <field name="TEXT">abc</field>
          </shadow>
        </value>
      </block>
    </statement>
    <next>
      <block type="controls_if" id="W5gST][l*q@Pku/2AB^M">
        <statement name="DO0">
          <block type="text_print" id="w[i{lPW|ri.rdQNM!)?6">
            <value name="TEXT">
              <shadow type="text" id="h{W8KGwYAej^s[^8UVdp">
                <field name="TEXT">abc</field>
              </shadow>
            </value>
            <next>
              <block type="text_print" id="vP:/JovqxIf3lOZbpXKr">
                <value name="TEXT">
                  <shadow type="text" id=";/H/6Kk!m=~tChXxSSJj">
                    <field name="TEXT">abc</field>
                  </shadow>
                </value>
              </block>
            </next>
          </block>
        </statement>
      </block>
    </next>
  </block>
</xml>

As in the OP just open the mutator to observe the issue.

alschmiedt commented 4 years ago

Looking into this a bit more, it looks like the change from setValue to doValueUpdate_ by itself fixes the bug in #3458. However, the change to turn rendering on in the mutator allows other fields to call methods in initModel that might possibly force a re render without this same bug resurfacing.

@BeksOmega does this sound correct?

BeksOmega commented 4 years ago

@BeksOmega does this sound correct?

Yes I would agree. I wish I would have written tests when I put up that PR, because I just spent way too much time remembering why I did what hehe.

alschmiedt commented 4 years ago

Ok great. So I think the plan is that we are going to add back turning off rendering when we mutate for the current release in order to fix this bug. However, I think you are correct above when you said we need a way to handle different states for rendering. I'll open a new bug for that so we can dig deeper into it next quarter.

Also your comments were super helpful in understanding the different issues so thank you!