<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p><br>
    </p>
    <div class="moz-cite-prefix">On 09/10/2023 22:24, Andy Goryachev
      wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:DM5PR1001MB2172452D7FA8F9417F88A11EE5CEA@DM5PR1001MB2172.namprd10.prod.outlook.com">
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <meta name="Generator" content="Microsoft Word 15 (filtered
        medium)">
      <style>@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}@font-face
        {font-family:"Yu Gothic";
        panose-1:2 11 4 0 0 0 0 0 0 0;}@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}@font-face
        {font-family:"Iosevka Fixed SS16";
        panose-1:2 0 5 9 3 0 0 0 0 4;}@font-face
        {font-family:"Times New Roman \(Body CS\)";
        panose-1:2 11 6 4 2 2 2 2 2 4;}@font-face
        {font-family:"\@Yu Gothic";
        panose-1:2 11 4 0 0 0 0 0 0 0;}@font-face
        {font-family:"Iosevka Fixed SS16 ";
        panose-1:2 0 5 9 3 0 0 0 0 4;}p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;
        mso-ligatures:standardcontextual;}a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:#0563C1;
        text-decoration:underline;}span.apple-converted-space
        {mso-style-name:apple-converted-space;}span.EmailStyle21
        {mso-style-type:personal-reply;
        font-family:"Iosevka Fixed SS16";
        color:windowtext;}.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;
        mso-ligatures:none;}div.WordSection1
        {page:WordSection1;}</style>
      <div class="WordSection1">
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16"">Dear John:<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16"">Thank you for a very thoughtful analysis! 
            I wanted to initiate a discussion, with the goal of making
            FX better.  Let me try to respond to your comments.<o:p></o:p></span></p>
        <p style="margin-left:.5in">The main odd thing that jumps out
          immediately is the fact that Behaviors and InputMaps need a
          reference to their linked Node. This will result in
          chicken-egg style problems where you can't create the Control
          without an InputMap, and you can't create an InputMap without
          a Control.  It will also lead to problems where if a Behavior
          is replaced that we must take care to dispose it, or use only
          weak references to the Control. 
          <o:p></o:p></p>
        <p class="MsoNormal" style="margin-left:.5in"><span
            style="font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16"">If we were to place FX parts in the
            standard MVC paradigm, behavior is the controller, skin is
            the view, and the model is a part of control (at least in
            the case of TextInputControl).  In FX world I would say the
            control represents a façade which provides programmatic
            access to the control functionality to the app developers. 
            Since the behavior needs access to both the view and the
            model, it having a pointer to the control is not an issue.</span></p>
      </div>
    </blockquote>
    <p>The MVC paradigm is not really relevant here, and has been
      superceded by much better paradigms; what we need is good
      abstractions that are easy to use and reason about.  Attaching a
      Behavior should be a simple one step process:</p>
    <p>     void setBehavior(Behavior behavior);</p>
    <p>This has repercussions for how Behaviors should be designed;
      first it should not take the control as a contructor parameter
      (and nor should InputMap).  This isn't needed; the context the
      Behavior needs to do its job is provided through Events.</p>
    <p>After calling the above setter, the Control will first call the
      old Behavior to remove its hooks, and then call the new Behavior
      to install the necessary hooks on the control.  The Control is in
      the lead here, as it should be given that it is what actually
      represents a control.  This also means that an interface is
      needed, something like:</p>
    <p>     interface Behavior<T extends Control> {<br>
                 Subscription addBehaviorListeners(T control);<br>
           }</p>
    <p>As you can see, the control is passed here, allowing the Behavior
      to either: keep track of the control with the listeners it
      registers (but don't store it in a field), or only use the control
      to install the listeners and rely on the Event#getSource or
      Observable passed to listeners if it needs the control.  This
      latter option allows all the installed listeners to be shared
      amongst all controls -- as Behaviors often install quite a few
      listeners, let's not underestimate how much resources this could
      potentially save.  Duplicating all these just to keep track of a
      different control is not the high level of optimization I've come
      to expect from JavaFX.</p>
    <p>The above also means that a Behavior is stateless; all its state
      is captured in the listeners it registers (if any is needed). 
      Stateless objects can be shared, so I can do:</p>
    <p>      TextField f1, f2;<br>
            Behavior behavior = new MyBehavior();<br>
      <br>
            f1.setBehavior(behavior);<br>
            f2.setBehavior(behavior);</p>
    <p>... or for cell factories, a single behavior can be set on all
      cells created.<br>
    </p>
    <span style="font-family:"Iosevka Fixed SS16""><o:p> </o:p></span>
    <blockquote type="cite"
cite="mid:DM5PR1001MB2172452D7FA8F9417F88A11EE5CEA@DM5PR1001MB2172.namprd10.prod.outlook.com">
      <div class="WordSection1">
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16"">With the InputMap having a pointer – it’s
            a convenience.  I mean, we could hide the input map
            altogether and add a bunch of methods to the Control for
            manipulating the key bindings – would that be better?  I
            personally don’t think so, but it’s definitely an option.</span></p>
      </div>
    </blockquote>
    <p>A Control always has an InputMap.  This means any methods
      InputMap exposes are available if you have a Control.  Effectively
      this means the methods could have been put on Control as well
      (they'd just be shortcuts), but to avoid clutter it is nicer to
      put them on a new concept, the InputMap.  Such a new concept
      should be easy to use for anybody now, not just for Controls when
      InputMap was just an implementation detail.  An InputMap, when it
      was an implementation detail, can have a "convenient" pointer back
      to the control, as nobody could use InputMaps before and nobody
      could construct them incorrectly.  That changes when you make it
      public, and so its design should be reconsidered.</p>
    <p>Mirroring the above, an InputMap can be constructed without
      providing a Control, mappings can be added and removed (or just
      provided in a constructor immedaitely), and then such an InputMap
      can be set with a single setter on a control.  The only state it
      needs is its mappings, and as long as you want the same mappings,
      the same InputMap can be shared amongst however many controls
      you'd want.  Sample:</p>
    <p>      InputMap map = new InputMap(Map.of(KEY_A,
      FunctionKey.of("type A"));</p>
    <p>      control.setInputMap(map);</p>
    <p>      // control is in the lead, and first removes any mappings
      from the previous InputMap,<br>
            // then calls methods on InputMap to get the new mappings
      installed<br>
    </p>
    <br>
    <blockquote type="cite"
cite="mid:DM5PR1001MB2172452D7FA8F9417F88A11EE5CEA@DM5PR1001MB2172.namprd10.prod.outlook.com">
      <div class="WordSection1">
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16""><o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16"">There is no problem (anymore) with
            disposal or life cycle of skins and associated behaviors:
            there is Skin.install() and Skin.dispose().</span></p>
      </div>
    </blockquote>
    <p>Skins use this solution because there was no other option anymore
      as their API was already public.  It is however not a good
      solution, but the best possible given the restrictions imposed by
      API's that were already public.  I'm not criticizing that
      solution.<br>
    </p>
    <p>Skins could however have been much easier to use if they had
      foregone their pointer to the control, and if the API was not
      public yet (or if we were willing to create a SkinV2
      imlementation).  A simple "setSkin(STATIC_SKIN)" would have
      sufficed.  Skins would then be called to install their hooks with
      a reference to the control.  The hooks themselves are passed the
      control on every callback (through Observable) but could in theory
      also track this information by capturing the control variable:</p>
    <p>      class MySkin implements Skin<T> {<br>
                // called by the control<br>
                Subscription applySkin(T control) {<br>
                        return Subscription.combine(<br>
                               control.backgroundProperty().subscribe(v
      -> { <br>
                                     // do something with captured
      control here, or use a listener's Observable<br>
                               })<br>
                        };  <br>
                }<br>
           }<br>
      <br>
    </p>
    <blockquote type="cite"
cite="mid:DM5PR1001MB2172452D7FA8F9417F88A11EE5CEA@DM5PR1001MB2172.namprd10.prod.outlook.com">
      <div class="WordSection1">
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16""><o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal" style="margin-left:.5in">The Skin API
          suffers from this problem, and I think we can do better.<span
            style="font-family:"Iosevka Fixed SS16""><o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16"">Let’s keep in mind that a major redesign
            which will create a compatibility issues for all the
            controls and their skins is most likely not an option, but I
            would be very interested to hear how we can do it better
            within the constraints of the existing design.</span></p>
      </div>
    </blockquote>
    <p>You misunderstand, I'm not criticizing the solution for Skins
      here, the current solution is the best that could be done given
      the API's that were already public and in place.</p>
    <p>Behaviors and InputMap however are not public yet, and so I think
      their design should be carefully considered.<br>
    </p>
    <blockquote type="cite"
cite="mid:DM5PR1001MB2172452D7FA8F9417F88A11EE5CEA@DM5PR1001MB2172.namprd10.prod.outlook.com">
      <div class="WordSection1">
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16""><o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal" style="margin-left:.5in">Looking at
          InputMap first, I see no real reason why it needs the Node<span
            style="font-family:"Iosevka Fixed SS16""><o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16"">Mainly for convenience, and to prevent the
            user from supplying completely unrelated control reference. 
            Yes, it’s a waste of a pointer, but the alternative is to
            move the APIs to Control.</span></p>
      </div>
    </blockquote>
    If InputMaps are not control specific, then this becomes
    irrelevant.  I'm not sure why you'd think that the only alternative
    then would be to put these API's on Control.<br>
    <blockquote type="cite"
cite="mid:DM5PR1001MB2172452D7FA8F9417F88A11EE5CEA@DM5PR1001MB2172.namprd10.prod.outlook.com">
      <div class="WordSection1">
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16""><o:p></o:p></span></p>
        <p style="margin-left:.5in"><span
            style="font-family:"Iosevka Fixed SS16""><o:p> </o:p></span>    
          Subscription installEventHandlers(Node node);<o:p></o:p></p>
        <p style="margin-left:.5in">Note that the above returns a
          Subscription, which can be used to remove the event handlers
          again without requiring an interaction with the InputMap.<o:p></o:p></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16"">What would prevent the user from supplying
            a totally unrelated Node (or rather, Control)?</span></p>
      </div>
    </blockquote>
    <p>Nothing, it does not need to be prevented.  The user already has
      full access to the Control and can do anything to that Control,
      including installing their own event handlers to create a whole
      different InputMap system.  Calling it the "wrong" way just
      installs some (more) handlers without the Control being in the
      lead; to uninstall these, the user needs to call `unsubcribe`
      themselves.  If you however want to make things easy for yourself
      and you wish to fully replace the standard InputMap, then you'd
      call `Control.setInputMap`.  If you just want to add a few
      bindings, you can either create a full fledged subclass of an
      existing InputMap you like, or provide a partial InputMap that you
      install directly yourself.  Or of course you can keep the option
      to add separate mappings.<br>
    </p>
    <p>The same applies to Skins really.  A control can be skinned
      without using the Skin system, all it takes is making a subclass
      to get access to (mutable) getChildren and layoutChildren.  This
      is done often enough to create new (adhoc) Controls with a new
      look without having to bother with creating a Skin as well.</p>
    <blockquote type="cite"
cite="mid:DM5PR1001MB2172452D7FA8F9417F88A11EE5CEA@DM5PR1001MB2172.namprd10.prod.outlook.com">
      <div class="WordSection1">
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16""><o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16"">And, as it currently stands, there is no
            need to use Subscription, as all the mappings created by the
            behavior will be automatically removed with
            BaseBehavior.uninstall().  (And Subscription would waste
            more bytes for each instance that one InputMap.control,
            wouldn’t you agree?)</span></p>
      </div>
    </blockquote>
    A single Subscription can track as many resources as you'd like, so
    I don't think that's correct.  What would however save a lot of
    memory is if Behaviors were stateless, as all the listeners can then
    be re-used accross controls, only wrapping the uninstall logic in a
    Subscription.  Effectively a Behavior would go from one behavior
    instance + X event handler instances per control to a single
    Behavior global instance, X stateless event handlers + 1
    Subscription per control.  The Subscription effectively carries any
    state that Behaviors may need per Control instance.<br>
    <blockquote type="cite"
cite="mid:DM5PR1001MB2172452D7FA8F9417F88A11EE5CEA@DM5PR1001MB2172.namprd10.prod.outlook.com">
      <div class="WordSection1">
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16""><o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal" style="margin-left:.5in">That brings us to
          InputMap's being mutable.  I would first spend some serious
          effort to see if this is strictly needed<span
            style="font-family:"Iosevka Fixed SS16""><o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16"">Yes, one of the features the new design
            provides is ability to modify key mappings by the user at
            runtime.  So yes, not only it needs to be mutable, but it
            also adds some APIs for exactly that.</span></p>
      </div>
    </blockquote>
    <p>Having Immutable input maps does not preclude you from changing
      mappings. It would just mean that if there's is need for an
      InputMap with some mappings changed, that you'd create a new one
      to install on the control.</p>
    <p>Something I've been wondering: what are the use cases currently? 
      I would imagine that if I want to change a mapping for a certain
      type of control (let's say I want Buttons to react to
      <ENTER>), do I need to make a ButtonFactory that will call
      "addMapping" on every button I create?  Can I override the
      standard Button InputMap somewhere globally?  Will it be possible
      with CSS (so I can do it globally)?  Currently, I already can do
      this to affect all Buttons:</p>
    <div style="background-color:#ffffff;padding:0px 0px 0px 2px;">
      <div style="color:#000000;background-color:#ffffff;font-family:"Consolas";font-size:11pt;white-space:pre;"><p style="margin:0;"><span style="color:#000000;">    </span><span style="color:#0000a0;font-weight:bold;">private</span><span style="color:#000000;"> </span><span style="color:#0000a0;font-weight:bold;">static</span><span style="color:#000000;"> </span><span style="color:#0000a0;font-weight:bold;">void</span><span style="color:#000000;"> buttonsRespondToEnter(Scene scene) {</span></p><p style="margin:0;"><span style="color:#000000;">      scene.addEventHandler(KeyEvent.</span><span style="color:#0000c0;">KEY_PRESSED</span><span style="color:#000000;">, e -> {</span></p><p style="margin:0;"><span style="color:#000000;">        </span><span style="color:#0000a0;font-weight:bold;">if</span><span style="color:#000000;">(!</span>e<span style="color:#000000;">.isConsumed() && e.getCode() == KeyCode.</span><span style="color:#0000c0;">ENTER</span><span style="color:#000000;">) {</span></p><p style="margin:0;"><span style="color:#000000;">          Node node = scene.getFocusOwner();</span></p><p style="margin:0;"><span style="color:#000000;">  </span></p><p style="margin:0;"><span style="color:#000000;">          </span><span style="color:#0000a0;font-weight:bold;">if</span><span style="color:#000000;">(node </span><span style="color:#0000a0;font-weight:bold;">instanceof</span><span style="color:#000000;"> Button button) {</span></p><p style="margin:0;"><span style="color:#000000;">            button.fire();</span></p><p style="margin:0;"><span style="color:#000000;">            e.consume();</span></p><p style="margin:0;"><span style="color:#000000;">          }</span></p><p style="margin:0;"><span style="color:#000000;">        }</span></p><p style="margin:0;"><span style="color:#000000;">      });</span></p><p style="margin:0;"><span style="color:#000000;">    }</span></p></div>
    </div>
    <p>Will the new API be able to this as easily?</p>
    <p>I struggle to think of a good use case for an addMapping method
      that only works for a single instance of a control.  In almost all
      cases I'd want to modify **all** controls of a certain type, or
      perhaps with a certain style associated with them.<br>
    </p>
    <blockquote type="cite"
cite="mid:DM5PR1001MB2172452D7FA8F9417F88A11EE5CEA@DM5PR1001MB2172.namprd10.prod.outlook.com">
      <div class="WordSection1">
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16""><o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16"">A shared InputMap (or, strictly speaking a
            shared InputMap and a per-control InputMap) is an
            alternative that might have some benefit in terms of memory
            consumption, at the expense of some complication.  It will,
            however, change the design as right now FX does not have
            such a global map.  I can see how we can explore this avenue
            at a later date, since it will not require public API
            changes as far as I can tell.</span></p>
      </div>
    </blockquote>
    <p>InputMap as it is currently requires a control in its
      constructor, that would preclude making them shareable later. 
      Same for BehaviorBase.</p>
    <p>Also they're not interfaces, they really should be if you want to
      design them now correctly to allow for user provided Behaviors and
      InputMaps later.<br>
    </p>
    <blockquote type="cite"
cite="mid:DM5PR1001MB2172452D7FA8F9417F88A11EE5CEA@DM5PR1001MB2172.namprd10.prod.outlook.com">
      <div class="WordSection1">
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16""><o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16""><o:p> </o:p></span></p>
        <p style="margin-left:.5in">First, I think there should be a
          real Behavior interface.  A required abtract base class will
          just lead to the tempatation to use JavaFX internals when
          things get inconvenient for internal Controls (using the
          accessor pattern), and will result in users not being able to
          replicate all the behaviors that FX controls can exhibit (as
          they won't have access to the same internals).<o:p></o:p></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16"">Can you explain what you mean?  I see no
            need for an interface, the base class provides all the
            necessary methods to deal with the control’s InputMap.  We
            are not (at this time) talking about making the actual
            behaviors public as it is a much larger task, but nothing
            precludes us from doing so in the future.  We do need the
            base class public though.</span></p>
      </div>
    </blockquote>
    <p>You're making BehaviorBase public (it's not package private), and
      locking any Behavior classes into providing several protected
      methods (like getControl and getInputMap). This would preclude
      major design shifts later.  For example, I'm not so sure that a
      behavior should have a reference to the InputMap or the Control,
      at least not if you are introducing the FunctionTag mechanic.</p>
    <blockquote type="cite"
cite="mid:DM5PR1001MB2172452D7FA8F9417F88A11EE5CEA@DM5PR1001MB2172.namprd10.prod.outlook.com">
      <div class="WordSection1">
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16""><o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16""><o:p> </o:p></span></p>
        <p style="margin-left:.5in">BehaviorBase immediately shows the
          same problem as InputMap. Even though you'd expect that a
          Behavior should be sharable between controls (it is after all
          the case that for most controls of a certain type all their
          behaviors will be the same) it has elected to explicitely
          couple itself to a specific control instance.  The base class
          itself only does this because InputMap needs the Node,
          however, subclasses are using this judiciously everywhere to
          access the Node linked to a Behavior.<o:p></o:p></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16"">I would <u>not</u> expect a shared
            behavior.  This isn’t how FX works right now, it isn’t how
            Swing works, and it is certainly not a requirement.  It
            <u>might</u> be considered as an optimization in some cases,
            but the key bindings and event handlers are certainly added
            on a per-control basis.</span></p>
      </div>
    </blockquote>
    <p>From a user point of view, a Behavior is the same accross many
      controls.  How Swing does things does not figure into this.  The
      handlers are indeed added on a control basis, but they can be the
      same shared handlers.</p>
    <blockquote type="cite"
cite="mid:DM5PR1001MB2172452D7FA8F9417F88A11EE5CEA@DM5PR1001MB2172.namprd10.prod.outlook.com">
      <div class="WordSection1">
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16""><o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal" style="margin-left:.5in">Looking at various
          uses of `getNode` (used in about 200-300 places) I haven't
          found one yet that isn't responding to an event. <span
            style="font-family:"Iosevka Fixed SS16""><o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16"">Behavior, being a “controller” needs a
            pointer to the view and the model, so having control
            instance (renamed from getNode()) is a non-issue.  And
            nobody is going to rewrite 200-300 places, realistically
            speaking.</span></p>
      </div>
    </blockquote>
    <p>Its responding to an event, which has this pointer, so this is
      basically disproven.</p>
    <p>The "rewrite" would be a minor refactoring where to get the
      control pointer, certainly worth considering when introducing and
      committing to new API's forever.  I don't think all need to be
      adjusted immediately either.<br>
    </p>
    <blockquote type="cite"
cite="mid:DM5PR1001MB2172452D7FA8F9417F88A11EE5CEA@DM5PR1001MB2172.namprd10.prod.outlook.com">
      <div class="WordSection1">
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16""><o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16""><o:p>  <br>
            </o:p></span></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16"">To summarize, I think that having control
            pointer in the InputMap or BehaviorBase is a non-issue,
            there are no cycling dependencies or chicken-egg problem
            because the life cycle is well determined.</span></p>
      </div>
    </blockquote>
    <p>It currently is well determined and guarded as they're private. 
      This will not be the case when these classes/interfaces become
      public.  Repeating the solution for Skins is sub-optimal and was
      necessity driven, so saying its a non-issue given the roundabout
      ways Skins currently need to be installed, and how we struggled to
      find a satisfactory solution there seems to me somewhat unfair.  <br>
    </p>
    <p>The design should look much further ahead if it is truly a goal
      to keep evolving JavaFX into a better framework. Once these
      classes are public, they can't be changed, so we better make
      absolutely sure that if we indeed want to do things like sharing
      behaviors or inputmaps, or allowing user made custom behaviors,
      that that is indeed going to be possible with what is being made
      public now.<br>
    </p>
    <blockquote type="cite"
cite="mid:DM5PR1001MB2172452D7FA8F9417F88A11EE5CEA@DM5PR1001MB2172.namprd10.prod.outlook.com">
      <div class="WordSection1">
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16"">Please don’t regard my responses as
            dismissals but rather as clarifications, and most certainly
            I welcome further discussion.  I think this proposal
            provides a good benefit-to-cost ratio, unless somebody can
            find a scenario where things would definitely not work.<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-family:"Iosevka
            Fixed SS16"">What do you think?</span></p>
      </div>
    </blockquote>
    <p>I welcome the work, I just have this feeling we're not designing
      far enough ahead, and letting existing private code dictate the
      design. When it comes to API's, the costs of not thinking far
      enough ahead are massive, so I changing a bit of existing
      non-public code should never figure into a design choice.<br>
    </p>
    <p>--John<br>
    </p>
    <span style="font-family:"Iosevka Fixed SS16 ""></span><o:p></o:p>
  </body>
</html>