<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>Hi Andy,</p>
    <p>I'm sorry if you feel I blocked your proposal.  Discussions
      better happen at a stage far before a PR is being reviewed, and
      instead of having these discussions here, we could have had them
      on the PR. <br>
    </p>
    I'll try and formalize my proposals.<br>
    <p>--John<br>
    </p>
    <p><br>
    </p>
    <div class="moz-cite-prefix">On 30/10/2023 20:32, Andy Goryachev
      wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:DM5PR1001MB21721EAEFC04E40E61FB5423E5A1A@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:10.0pt;
        font-family:"Calibri",sans-serif;}a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}span.EmailStyle20
        {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-size:11.0pt;font-family:"Iosevka Fixed
            SS16"">Dear John:<o:p></o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal" style="margin-left:.5in">  I'm unsure what
          the JEP format would contribute here<span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16""><o:p></o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16"">The benefit of JEP format is<o:p></o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16"">a) to explicitly state the problem being solved
            (in the Motivation section)<o:p></o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16"">b) to enumerate the public APIs<o:p></o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal" style="margin-left:.5in">I have several
          proposals, and some are too big for a single proposal (IMHO)
          which would you like me to focus on?<span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16""><o:p></o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16"">The main reason I am asking you to go through
            the process is because you effectively blocked by InputMap
            proposal.  I keep hearing that my proposal is not good for
            various reasons, while there is a much better way for doing
            things, so let’s see it in full detail.  It would be nice to
            have proof-of-concept code based on a complex control rather
            than a simple Button, but it is not a requirement, at least
            initially.<o:p></o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16"">I still want to see code examples (pseudo code
            is fine) for my questions:<o:p></o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed SS16
            "">Q1. Changing an existing key binding from one key
            combination to another.</span><o:p></o:p></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed SS16
            "">Q2. Remapping an existing key binding to a different
            function.</span><o:p></o:p></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed SS16
            "">Q3. Unmapping an existing key binding.</span><o:p></o:p></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed SS16
            "">Q4. Adding a new key binding mapped to a new
            function.</span><o:p></o:p></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed SS16
            "">Q5. (Q1...Q4) scenarios, at run time.</span><o:p></o:p></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed SS16
            "">Q6. How the set behavior handles a change from the
            default skin to a custom skin with some visual elements that
            expects input removed, and some added.
          </span><o:p></o:p></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed SS16
            "">Q7. Once the key binding has been modified, is it
            possible to invoke the default functionality?</span><o:p></o:p></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed SS16
            "">Q8. How are the platform-specific key bindings
            created?</span><o:p></o:p></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed SS16
            "">Q9. How are the skin-specific (see Q6) handlers
            removed when changing the skins?</span><o:p></o:p></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed SS16
            "">Q10. When a key press happens, does it cause a
            linear search through listeners or just a map lookup?
          </span><o:p></o:p></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16"">I think it is important to answer all questions
            during the discussion, as it helps all sides to understand
            how things work, and possibly make corrections.  Since the
            bulk of my proposal deals with key bindings and user-/skin-
            installed handlers, I would like to see how you propose to
            deal with these problems.<o:p></o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16"">Another reason I asked you for a JEP is that you
            seem to brush aside my objections.  For example, my
            objection to the stateless behavior was dealt with by
            inventing BehaviorContext, which I basically take as an
            acknowledgement that behaviors are not stateless.  So let’s
            see exactly you envision things by describing the public API
            and perhaps the proof of concept code should also have two
            non-trivial controls, just to see whether BehaviorContext
            depends on the control class or not.<o:p></o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal" style="margin-left:.5in">How key bindings
          are done is IMHO more of an implementation detail of
          **specific** behaviors,<span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16""><o:p></o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16"">I categorically disagree with this statement. 
            As an application developer, I want to be able to
            set/modify/unmap key bindings via common public mechanism,
            make sure that the user mappings and handlers always take
            precedence over the skin ones, and make sure that skin
            changes leave the user mappings and handlers in place.<o:p></o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16"">It is certainly not an implementation detail and
            not a property of any specific behavior.<o:p></o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16"">Thank you, and I am looking forward to seeing
            answers to the questions posted earlier.<o:p></o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16"">-andy<o:p></o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16""><o:p> </o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16""><o:p> </o:p></span></p>
        <div id="mail-editor-reference-message-container">
          <div>
            <div style="border:none;border-top:solid #B5C4DF
              1.0pt;padding:3.0pt 0in 0in 0in">
              <p class="MsoNormal" style="margin-bottom:12.0pt"><b><span
                    style="font-size:12.0pt;color:black">From:
                  </span></b><span style="font-size:12.0pt;color:black">John
                  Hendrikx <a class="moz-txt-link-rfc2396E" href="mailto:john.hendrikx@gmail.com"><john.hendrikx@gmail.com></a><br>
                  <b>Date: </b>Saturday, October 28, 2023 at 12:55<br>
                  <b>To: </b>Andy Goryachev
                  <a class="moz-txt-link-rfc2396E" href="mailto:andy.goryachev@oracle.com"><andy.goryachev@oracle.com></a>,
                  <a class="moz-txt-link-abbreviated" href="mailto:openjfx-dev@openjdk.org">openjfx-dev@openjdk.org</a>
                  <a class="moz-txt-link-rfc2396E" href="mailto:openjfx-dev@openjdk.org"><openjfx-dev@openjdk.org></a>, Kevin Rushforth
                  <a class="moz-txt-link-rfc2396E" href="mailto:kevin.rushforth@oracle.com"><kevin.rushforth@oracle.com></a><br>
                  <b>Subject: </b>Re: [External] : Re: Proof of concept
                  pull request for Behavior API (PR 1265)<o:p></o:p></span></p>
            </div>
            <p>Hi Andy,<o:p></o:p></p>
            <p class="MsoNormal"><span style="font-size:11.0pt">On
                27/10/2023 19:10, Andy Goryachev wrote:<br>
                <br>
                <o:p></o:p></span></p>
            <blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
              <p class="MsoNormal"><span
                  style="font-size:11.0pt;font-family:"Iosevka
                  Fixed SS16 "">Dear John:</span><o:p></o:p></p>
              <p class="MsoNormal"><span
                  style="font-size:11.0pt;font-family:"Iosevka
                  Fixed SS16 ""> </span><o:p></o:p></p>
              <p class="MsoNormal"><span
                  style="font-size:11.0pt;font-family:"Iosevka
                  Fixed SS16 "">I think our goal is for all of us
                  to agree on a solution which solves the problems.  We
                  are still talking, right?</span><o:p></o:p></p>
              <p class="MsoNormal"><span
                  style="font-size:11.0pt;font-family:"Iosevka
                  Fixed SS16 ""> </span><o:p></o:p></p>
              <p class="MsoNormal"><span
                  style="font-size:11.0pt;font-family:"Iosevka
                  Fixed SS16 "">I have to say - it is very
                  difficult to have a meaningful conversation when
                  questions are not being answered.  It is even more
                  difficult to do over email and time zones, as the
                  context can often be lost.</span><o:p></o:p></p>
            </blockquote>
            <p>I'm really a bit surprised, as I think I responded quite
              quickly to a lot of the posts surrounding the proposals,
              and also answered quite a lot of questions.  The
              mailinglist format seems to have served Java quite well
              for this purpose for years now, and if memory serves,
              earlier FX proposals also were discussed here.  I'm unsure
              what the JEP format would contribute here, given that it
              does not allow for inline comments or threads, but I'm not
              unwilling to try my hand at one.<o:p></o:p></p>
            <p class="MsoNormal"><span style="font-size:11.0pt"><br>
                <br>
                <o:p></o:p></span></p>
            <blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
              <p class="MsoNormal"><span
                  style="font-size:11.0pt;font-family:"Iosevka
                  Fixed SS16 ""> </span><o:p></o:p></p>
              <p class="MsoNormal"><span
                  style="font-size:11.0pt;font-family:"Iosevka
                  Fixed SS16 "">To reiterate, a proposal in a JEP
                  format would be nice, so we can see the public API.</span><o:p></o:p></p>
            </blockquote>
            <p>Alright, this will take a bit of time.  I have several
              proposals, and some are too big for a single proposal
              (IMHO) which would you like me to focus on?<o:p></o:p></p>
            <p>1. A public Behavior API with the initial focus on being
              able to reuse and replace default behaviors<o:p></o:p></p>
            <p>This proposal would like to achieve a clear definition of
              a Behavior and clear separation (to aid in reusability and
              creation).  It would define a Behavior interface, and a
              clean way of installing/uninstalling a behavior on
              controls.  This would be primarily the
              Behavior/BehaviorContext part of my sample PR <a
href="https://urldefense.com/v3/__https:/github.com/openjdk/jfx/pull/1265__;!!ACWV5N9M2RV99hQ!LvWBWlmjB-JYcKnpZTbvjYwd1CItXTmycfx2D-BYmkbS7lxG6f4kwt2bmokpBwh63Gg_MNX5JzP747J1wgPuPY6Rq1H1$"
                moz-do-not-send="true">
                https://github.com/openjdk/jfx/pull/1265</a>, leaving
              the more controversial event definition parts out for now<o:p></o:p></p>
            <p>1.1. A possible extension of the above Behavior API to
              allow changing high level behavior<o:p></o:p></p>
            <p>I'm not sure yet what would be a good approach here.  I
              would probably either lean towards reusing the Event
              system for this, or doing this with overridable methods;
              ie. in order to override a function, listen for its event
              and call different code or trigger a different event; or,
              ensure there is an overridable method so it can be
              overriden directly in code.<o:p></o:p></p>
            <p>1.2. An extension to the above behavior API to allow for
              more user friendly key rebinding<o:p></o:p></p>
            <p>The idea here would be to create a custom behavior
              (allowed by 1.), call into a behavior you want to modify
              to install its defaults, and then make changes after. 
              There is more than one possible approach here.  One I
              raised earlier was offering more specific methods on
              BehaviorContext.  Another possiblity is to make it
              specific to certain behaviors only (MappableBehavior), or
              behaviors that can somehow provide an InputMap (without
              entangling everything).<o:p></o:p></p>
            <p>2. An improved event handling system (Michael Strauss
              already did some work there) that would allow users to
              override or disable default event processing<o:p></o:p></p>
            <p>This would be a low-level improvement that would allow
              3rd parties to override large parts of JavaFX in a
              supported manner.  It would open the way to a 3rd party
              behavior system or navigation system, but also simpler
              things like just changing a key mapping, even ones claimed
              by behaviors currently.  As it is a low level API, this
              would be somewhat cumbersome for seemingly simple tasks,
              and the various platforms would need to be supported
              manually.<o:p></o:p></p>
            <p>In essence the above proposal would allow user installed
              event handlers to receive any event before a default
              handler can get to it, so that say remapping the
              LEFT_ARROW key is actualy possible and doesn't magically
              disappear (many new users, including me at the time
              were/are somewhat surprised that an event handler
              installed on the control is not receiving all events). 
              The root cause of this is the sharing of the event
              handling lists on the control with (magically) installed
              behaviors.  The above proposal would change this (in a
              backwards compatible way) to work more like how default
              exception handlers work -- only unconsumed events that
              bubble up to the root level are considered for default
              behavior actions.<o:p></o:p></p>
            <p>------<o:p></o:p></p>
            <p>As you can see, one my problems with answering the key
              rebinding questions is that IMHO this more of a later
              extension on a Behavior API; this means to get to the key
              remapping design, there first would need to be a Behavior
              API design.  How key bindings are done is IMHO more of an
              implementation detail of **specific** behaviors, as there
              are probably more ways to do this.  So for my proposals, a
              somewhat fleshed out Behavior API design is an important
              prerequisite before offering key rebinding. 
              <o:p></o:p></p>
            <p>If we can advance this design far enough, we may see a
              way to do this without needing a Behavior API first; for
              example, we could have a Behavior interface, and a
              subtype, MappableBehavior; only behaviors of that sub type
              support key remapping, while general behaviors don't have
              to.  This would make the key rebinding just something that
              **some** behaviors support, and not a general feature if
              it instead was added to say Control, Behavior or
              BehaviorContext.  This may be a short cut that we could
              take to get to key rebinding quickly, without closing off
              a future behavior API.<o:p></o:p></p>
            <p>Again, thanks for reading, I look forward to some
              feedback, and as said, I will try put some time towards
              writing a JEP.  I'm also happy to collaborate on this once
              a design direction becomes  a bit more clear.<o:p></o:p></p>
            <p>--John<o:p></o:p></p>
            <p class="MsoNormal"><span style="font-size:11.0pt"><br>
                <br>
                <o:p></o:p></span></p>
            <blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
              <p class="MsoNormal"><span
                  style="font-size:11.0pt;font-family:"Iosevka
                  Fixed SS16 ""> </span><o:p></o:p></p>
              <p class="MsoNormal"><span
                  style="font-size:11.0pt;font-family:"Iosevka
                  Fixed SS16 "">Please, if you have time, answer
                  these questions.  A short pseudo-code example will be
                  fine.</span><o:p></o:p></p>
              <p class="MsoNormal"><span
                  style="font-size:11.0pt;font-family:"Iosevka
                  Fixed SS16 ""> </span><o:p></o:p></p>
              <p class="MsoNormal"><span
                  style="font-size:11.0pt;font-family:"Iosevka
                  Fixed SS16 "">Q1. Changing an existing key
                  binding from one key combination to another.</span><o:p></o:p></p>
              <p class="MsoNormal"><span
                  style="font-size:11.0pt;font-family:"Iosevka
                  Fixed SS16 "">Q2. Remapping an existing key
                  binding to a different function.</span><o:p></o:p></p>
              <p class="MsoNormal"><span
                  style="font-size:11.0pt;font-family:"Iosevka
                  Fixed SS16 "">Q3. Unmapping an existing key
                  binding.</span><o:p></o:p></p>
              <p class="MsoNormal"><span
                  style="font-size:11.0pt;font-family:"Iosevka
                  Fixed SS16 "">Q4. Adding a new key binding mapped
                  to a new function.</span><o:p></o:p></p>
              <p class="MsoNormal"><span
                  style="font-size:11.0pt;font-family:"Iosevka
                  Fixed SS16 "">Q5. (Q1...Q4) scenarios, at run
                  time.</span><o:p></o:p></p>
              <p class="MsoNormal"><span
                  style="font-size:11.0pt;font-family:"Iosevka
                  Fixed SS16 "">Q6. How the set behavior handles a
                  change from the default skin to a custom skin with
                  some visual elements that expects input removed, and
                  some added.
                </span><o:p></o:p></p>
              <p class="MsoNormal"><span
                  style="font-size:11.0pt;font-family:"Iosevka
                  Fixed SS16 "">Q7. Once the key binding has been
                  modified, is it possible to invoke the default
                  functionality?</span><o:p></o:p></p>
              <p class="MsoNormal"><span
                  style="font-size:11.0pt;font-family:"Iosevka
                  Fixed SS16 "">Q8. How are the platform-specific
                  key bindings created?</span><o:p></o:p></p>
              <p class="MsoNormal"><span
                  style="font-size:11.0pt;font-family:"Iosevka
                  Fixed SS16 "">Q9. How are the skin-specific (see
                  Q6) handlers removed when changing the skins?</span><o:p></o:p></p>
              <p class="MsoNormal"><span
                  style="font-size:11.0pt;font-family:"Iosevka
                  Fixed SS16 "">Q10. When a key press happens, does
                  it cause a linear search through listeners or just a
                  map lookup?
                </span><o:p></o:p></p>
              <p class="MsoNormal"><span
                  style="font-size:11.0pt;font-family:"Iosevka
                  Fixed SS16 ""> </span><o:p></o:p></p>
              <p class="MsoNormal"><span
                  style="font-size:11.0pt;font-family:"Iosevka
                  Fixed SS16 "">Lastly, I do think prototyping the
                  alternative proposal using simple control like Button
                  is insufficient.  TextArea would be much better, as it
                  has a ton of key bindings, platform-specific logic,
                  various handlers that do and do not consume events by
                  default.</span><o:p></o:p></p>
              <p class="MsoNormal"><span
                  style="font-size:11.0pt;font-family:"Iosevka
                  Fixed SS16 ""> </span><o:p></o:p></p>
              <p class="MsoNormal"><span
                  style="font-size:11.0pt;font-family:"Iosevka
                  Fixed SS16 "">Thank you</span><o:p></o:p></p>
              <p class="MsoNormal"><span
                  style="font-size:11.0pt;font-family:"Iosevka
                  Fixed SS16 "">-andy</span><o:p></o:p></p>
              <p class="MsoNormal"><span
                  style="font-size:11.0pt;font-family:"Iosevka
                  Fixed SS16 ""> </span><o:p></o:p></p>
              <p class="MsoNormal"><span
                  style="font-size:11.0pt;font-family:"Iosevka
                  Fixed SS16 "">P.S. I noticed that I switched my
                  PR to Open by mistake.  Sorry, it’s back in Draft.</span><o:p></o:p></p>
              <p class="MsoNormal"><span
                  style="font-size:11.0pt;font-family:"Iosevka
                  Fixed SS16 ""> </span><o:p></o:p></p>
              <p class="MsoNormal"><span
                  style="font-size:11.0pt;font-family:"Iosevka
                  Fixed SS16 ""> </span><o:p></o:p></p>
              <p class="MsoNormal"><span
                  style="font-size:11.0pt;font-family:"Iosevka
                  Fixed SS16 ""> </span><o:p></o:p></p>
              <p class="MsoNormal"><span
                  style="font-size:11.0pt;font-family:"Iosevka
                  Fixed SS16 ""> </span><o:p></o:p></p>
              <div id="mail-editor-reference-message-container">
                <div>
                  <div style="border:none;border-top:solid #B5C4DF
                    1.0pt;padding:3.0pt 0in 0in 0in">
                    <p class="MsoNormal" style="margin-bottom:12.0pt"><b><span
                          style="font-size:12.0pt;color:black">From:
                        </span></b><span
                        style="font-size:12.0pt;color:black">John
                        Hendrikx <a
                          href="mailto:john.hendrikx@gmail.com"
                          moz-do-not-send="true">
                          <john.hendrikx@gmail.com></a><br>
                        <b>Date: </b>Thursday, October 26, 2023 at
                        02:15<br>
                        <b>To: </b>Andy Goryachev <a
                          href="mailto:andy.goryachev@oracle.com"
                          moz-do-not-send="true"><andy.goryachev@oracle.com></a>,
                        <a href="mailto:openjfx-dev@openjdk.org"
                          moz-do-not-send="true"
                          class="moz-txt-link-freetext">openjfx-dev@openjdk.org</a>
                        <a href="mailto:openjfx-dev@openjdk.org"
                          moz-do-not-send="true">
                          <openjfx-dev@openjdk.org></a>, Kevin
                        Rushforth <a
                          href="mailto:kevin.rushforth@oracle.com"
                          moz-do-not-send="true">
                          <kevin.rushforth@oracle.com></a><br>
                        <b>Subject: </b>Re: [External] : Re: Proof of
                        concept pull request for Behavior API (PR 1265)</span><o:p></o:p></p>
                  </div>
                  <p>The normal procedure I think is also to first
                    provide a JEP for review, before starting on the
                    implementation...<o:p></o:p></p>
                  <p>Given the doubts raised, feedback given and
                    potential alternatives proposed, I don't see why you
                    are still moving forward with your own proposal. The
                    critiques I've given have been mostly hand waved
                    with arguments that have no place in JEP evaluation
                    (time restrictions, existing code already works this
                    way, false equivalency with MVC pattern), and
                    therefore have IMHO not been taken serious at all.<o:p></o:p></p>
                  <p>This leaves me in the position of putting in a lot
                    of work that will essentially be ignored as I feel
                    an (internal) decision has already been reached,
                    regardless of the feedback on the mailinglist.<o:p></o:p></p>
                  <p>The (partial) proposal I've made, and also simpler
                    proposals so that 3rd parties could do a keybinding
                    implementation, should be sufficient to reconsider
                    the current proposal that is being moved forward.<o:p></o:p></p>
                  <p>I'll reiterate my problems with your proposal:<o:p></o:p></p>
                  <p>- Introduces a lot of API for what is essentially
                    the configuration of internal event handlers<br>
                    - The proposed API partially overlaps with the
                    existing event handler API, meaning that some keys
                    could be changed with just event handlers, while
                    some can only be changed with the BaseBehavior API;
                    it also provides for creating new functions and
                    assigning them to keys, essentially a new (very
                    limited) API for what was already possible in the
                    much more flexible event handling API<br>
                    - Introduces the term "Behavior" in public API
                    without clearly specifying what that is, nor showing
                    enough forethought that may make it possible in the
                    future to have public Behaviors<br>
                    - Introduces the term "InputMap" in public API,
                    which is just an implementation detail of the
                    internal event handlers<br>
                    - Doesn't address the real issue IMHO, which is that
                    JavaFX Skins/Behaviors install their Event Handlers
                    directly on Controls, mixing them with user event
                    handlers leading to all sorts of unpredictable
                    behavior due to call order and internal handlers
                    essentially stealing and consuming events before the
                    user has a chance to look at them (and thus blocking
                    any 3rd party key alterations) which leads to the
                    (false) need to change key bindings and Behaviors
                    directly...<o:p></o:p></p>
                  <p>So if you want me to work on such a proposal, fully
                    fleshing it out, I would like to know if it will be
                    given consideration. I would also like some more
                    feedback on what is already there, as I think it is
                    sufficient to decide if a full proposal is worth it
                    or not.<o:p></o:p></p>
                  <p>My proposals in short:<o:p></o:p></p>
                  <p>1.<o:p></o:p></p>
                  <p>- Fix the issues with Events being stolen before
                    users can get a them<br>
                        - Users should be able to have priority on
                    Events, Michael Strauss already has a PR that fixes
                    the issue in part<br>
                        - Events should not be consumed when not used
                    (navigation does this) as this precludes the user
                    being able to change their meaning<br>
                        - Even better would be if internal event
                    handlers were isolated and did not mix themselves
                    with user event handlers at all<o:p></o:p></p>
                  <p>The above can be done separately, and should
                    already make it possible to do a lot of things that
                    were close to impossible before when it comes to
                    changing key handling, but certainly not everything.<o:p></o:p></p>
                  <p>- Building on top of the improved event handling
                    system, introduce a flag to indicate an event is not
                    to be consumed by internal event handlers<br>
                    <br>
                    These two together can form the basis for a 3rd
                    party Behavior implementation as standard behavior
                    can be prevented from occurring.  It leaves platform
                    dependent behavior to be addressed by such a 3rd
                    party / user implementation as it is a very low
                    level API.  Any key remapping logic would be
                    provided by the 3rd party API. <o:p></o:p></p>
                  <p>2.<o:p></o:p></p>
                  <p>I also have a more fleshed out alternative proposal
                    that attempts to introduce Behaviors into JavaFX as
                    a first class concept, instead of a potential 3rd
                    party add-on.  Recap:<o:p></o:p></p>
                  <p>- Introduce a Behavior interface with a single
                    method "install" to be called by a Control<br>
                    - The "install" method is provided a context object,
                    BehaviorContext.  This indirects any changes the
                    Behavior can make to a Control, so the Control is
                    fully aware of all changes and can uninstall them
                    without further co-operation from the behavior.<br>
                    - The BehaviorContext provides low level functions
                    to add/remove event handlers and listeners, but can
                    also provide higher level functions (in perhap a
                    later PR) to allow for some kind of control provided
                    input map system<br>
                    - Standard Behaviors can be made public and can be
                    easily subclassed or composed as they need not have
                    any state.  State is tracked inside the behavorial
                    installed listeners and handlers themselves (either
                    directly or by referring to some shared State
                    object).<br>
                    - Clear separation of concerns; Behaviors, a
                    resuable concept that can be applied to a control;
                    BehaviorContext, manages behavior lifecycle by
                    abstracting away direct Control access; behavior
                    state management left up to the implementation and
                    created (on demand and as needed) when "install" is
                    called.<br>
                    - Indirection from key mapping to semantic meaning
                    is provided by introducing control specific events.
                    These semantic events can be handled, filtered and
                    consumed like all other events, allowing for
                    changing/remapping/blocking or ignoring; this part
                    can be left out from an initial implementation to
                    further evaluate how such events might interact with
                    Skins that need specific events (there is nothing
                    stopping us from having some of these semantic
                    events be handled by the Control directly, and some
                    by the specific needs of the Skin)<o:p></o:p></p>
                  <p>To get at the internal key mappings, you'd need to
                    subclass or compose a Behavior.  The Behaviors are
                    setup to allow this easily.  To modify the bindings
                    of a Control, one would install such a modified
                    Behavior as a whole; overkill perhaps for one
                    binding change, but convenient when multiple
                    bindings are changed, and reusable accross controls
                    (the Behavior only need to be created once).<o:p></o:p></p>
                  <p>The proposal also includes an indirection between
                    Key/Mouse event and its semantic meaning.  This is
                    achieved by firing higher level more meaningful
                    events, but that's not the only option; it could
                    also be done with overridable methods on the
                    Behavior, or a behavior specific interface if the
                    Event based proposal is seen as too audacious.<o:p></o:p></p>
                  <p>This proposal advocates a clear seperation of the
                    Behavior from the Skin, essentially making them
                    Controller and View, where the View has no knowledge
                    of the Controller. I see no reason why this wouldn't
                    be possible, given that it is a standard pattern. 
                    That existing controls may be difficult to untangle
                    is IMHO irrelevant, especially when this can be done
                    one at a time.  I realize that Controllers
                    (Behaviors) may have functions that are sort of View
                    (Skin) specific; this is not an issue, as it should
                    be fine to trigger a behavior without it being
                    consumed; unconsumed behaviorial events just bubble
                    up.  This allows Behaviors to have events specific
                    to a Skin without them interfering if they're unused
                    by an alternative Skin.  An alternative Skin that
                    also needs new behavior will also need to create a
                    new behavior to go along with it (or when paired
                    with the standard one, accept that those new
                    behaviors won't be triggered).<o:p></o:p></p>
                  <p>Thanks for reading.<o:p></o:p></p>
                  <p>--John<o:p></o:p></p>
                  <p> <o:p></o:p></p>
                  <p> <o:p></o:p></p>
                  <div>
                    <p class="MsoNormal"><span style="font-size:11.0pt">On
                        26/10/2023 00:59, Andy Goryachev wrote:</span><o:p></o:p></p>
                  </div>
                  <blockquote
                    style="margin-top:5.0pt;margin-bottom:5.0pt">
                    <p class="MsoNormal"><span
                        style="font-size:11.0pt;font-family:"Iosevka
                        Fixed SS16 "">Dear John:</span><o:p></o:p></p>
                    <p class="MsoNormal"><span
                        style="font-size:11.0pt;font-family:"Iosevka
                        Fixed SS16 ""> </span><o:p></o:p></p>
                    <p class="MsoNormal"><span
                        style="font-size:11.0pt;font-family:"Iosevka
                        Fixed SS16 "">It is difficult to review the
                        alternative proposal for a number of reasons.  A
                        prototype is a good start, but for any proposal
                        to go forward we need a bit more work.  Let me
                        enumerate the steps that we expect:</span><o:p></o:p></p>
                    <p class="MsoNormal"><span
                        style="font-size:11.0pt;font-family:"Iosevka
                        Fixed SS16 ""> </span><o:p></o:p></p>
                    <p class="MsoNormal"><span
                        style="font-size:11.0pt;font-family:"Iosevka
                        Fixed SS16 "">1. Provide an overview of the
                        proposal following a JEP outline:</span><o:p></o:p></p>
                    <p class="MsoNormal"><span
                        style="font-size:11.0pt;font-family:"Iosevka
                        Fixed SS16 ""> </span><o:p></o:p></p>
                    <p class="MsoNormal"><b><span
                          style="font-size:11.0pt;font-family:"Iosevka
                          Fixed SS16 "">Summary</span></b><o:p></o:p></p>
                    <p class="MsoNormal"><b><span
                          style="font-size:11.0pt;font-family:"Iosevka
                          Fixed SS16 "">Goals</span></b><o:p></o:p></p>
                    <p class="MsoNormal"><b><span
                          style="font-size:11.0pt;font-family:"Iosevka
                          Fixed SS16 "">Non-Goals</span></b><o:p></o:p></p>
                    <p class="MsoNormal"><b><span
                          style="font-size:11.0pt;font-family:"Iosevka
                          Fixed SS16 "">Motivation</span></b><o:p></o:p></p>
                    <p class="MsoNormal"><b><span
                          style="font-size:11.0pt;font-family:"Iosevka
                          Fixed SS16 "">Description</span></b><o:p></o:p></p>
                    <p class="MsoNormal"><b><span
                          style="font-size:11.0pt;font-family:"Iosevka
                          Fixed SS16 "">Alternatives</span></b><o:p></o:p></p>
                    <p class="MsoNormal"><b><span
                          style="font-size:11.0pt;font-family:"Iosevka
                          Fixed SS16 "">Risks and Assumptions</span></b><o:p></o:p></p>
                    <p class="MsoNormal"><b><span
                          style="font-size:11.0pt;font-family:"Iosevka
                          Fixed SS16 "">Dependencies</span></b><o:p></o:p></p>
                    <p class="MsoNormal"><span
                        style="font-size:11.0pt;font-family:"Iosevka
                        Fixed SS16 ""> </span><o:p></o:p></p>
                    <p class="MsoNormal"><span
                        style="font-size:11.0pt;font-family:"Iosevka
                        Fixed SS16 "">2. A draft PR that provides a
                        proof of concept, using, in this case, a few
                        complex controls like TextArea, TableView,
                        ComboBox.</span><o:p></o:p></p>
                    <p class="MsoNormal"><span
                        style="font-size:11.0pt;font-family:"Iosevka
                        Fixed SS16 ""> </span><o:p></o:p></p>
                    <p class="MsoNormal"><span
                        style="font-size:11.0pt;font-family:"Iosevka
                        Fixed SS16 "">3. Address the question
                        raised earlier, perhaps by providing code
                        examples (pseudo code is acceptable, I think).</span><o:p></o:p></p>
                    <p class="MsoNormal"><span
                        style="font-size:11.0pt;font-family:"Iosevka
                        Fixed SS16 ""> </span><o:p></o:p></p>
                    <p class="MsoNormal"><span
                        style="font-size:11.0pt;font-family:"Iosevka
                        Fixed SS16 "">More specifically, I’d like
                        to know how the following concerns will be
                        addressed by the new proposal:</span><o:p></o:p></p>
                    <p class="MsoNormal"><span
                        style="font-size:11.0pt;font-family:"Iosevka
                        Fixed SS16 ""> </span><o:p></o:p></p>
                    <p class="MsoNormal"><span
                        style="font-size:11.0pt;font-family:"Iosevka
                        Fixed SS16 "">Q1. Changing an existing key
                        binding from one key combination to another.</span><o:p></o:p></p>
                    <p class="MsoNormal"><span
                        style="font-size:11.0pt;font-family:"Iosevka
                        Fixed SS16 "">Q2. Remapping an existing key
                        binding to a different function.</span><o:p></o:p></p>
                    <p class="MsoNormal"><span
                        style="font-size:11.0pt;font-family:"Iosevka
                        Fixed SS16 "">Q3. Unmapping an existing key
                        binding.</span><o:p></o:p></p>
                    <p class="MsoNormal"><span
                        style="font-size:11.0pt;font-family:"Iosevka
                        Fixed SS16 "">Q4. Adding a new key binding
                        mapped to a new function.</span><o:p></o:p></p>
                    <p class="MsoNormal"><span
                        style="font-size:11.0pt;font-family:"Iosevka
                        Fixed SS16 "">Q5. (Q1...Q4) scenarios, at
                        run time.</span><o:p></o:p></p>
                    <p class="MsoNormal"><span
                        style="font-size:11.0pt;font-family:"Iosevka
                        Fixed SS16 "">Q6. How the set behavior
                        handles a change from the default skin to a
                        custom skin with some visual elements that
                        expects input removed, and some added.
                      </span><o:p></o:p></p>
                    <p class="MsoNormal"><span
                        style="font-size:11.0pt;font-family:"Iosevka
                        Fixed SS16 "">Q7. Once the key binding has
                        been modified, is it possible to invoke the
                        default functionality?</span><o:p></o:p></p>
                    <p class="MsoNormal"><span
                        style="font-size:11.0pt;font-family:"Iosevka
                        Fixed SS16 "">Q8. How are the
                        platform-specific key bindings created?</span><o:p></o:p></p>
                    <p class="MsoNormal"><span
                        style="font-size:11.0pt;font-family:"Iosevka
                        Fixed SS16 "">Q9. How are the skin-specific
                        (see Q6) handlers removed when changing the
                        skins?</span><o:p></o:p></p>
                    <p class="MsoNormal"><span
                        style="font-size:11.0pt;font-family:"Iosevka
                        Fixed SS16 "">Q10. When a key press
                        happens, does it cause a linear search or a map
                        lookup?
                      </span><o:p></o:p></p>
                    <p class="MsoNormal"><span
                        style="font-size:11.0pt;font-family:"Iosevka
                        Fixed SS16 ""> </span><o:p></o:p></p>
                    <p class="MsoNormal"><span
                        style="font-size:11.0pt;font-family:"Iosevka
                        Fixed SS16 "">Thank you</span><o:p></o:p></p>
                    <p class="MsoNormal"><span
                        style="font-size:11.0pt;font-family:"Iosevka
                        Fixed SS16 "">-andy</span><o:p></o:p></p>
                    <p class="MsoNormal"><span
                        style="font-size:11.0pt;font-family:"Iosevka
                        Fixed SS16 ""> </span><o:p></o:p></p>
                    <p class="MsoNormal"><span
                        style="font-size:11.0pt;font-family:"Iosevka
                        Fixed SS16 ""> </span><o:p></o:p></p>
                    <p class="MsoNormal"><span
                        style="font-size:11.0pt;font-family:"Iosevka
                        Fixed SS16 ""> </span><o:p></o:p></p>
                    <p class="MsoNormal"><span
                        style="font-size:11.0pt;font-family:"Iosevka
                        Fixed SS16 ""> </span><o:p></o:p></p>
                    <div id="mail-editor-reference-message-container">
                      <div>
                        <div style="border:none;border-top:solid #B5C4DF
                          1.0pt;padding:3.0pt 0in 0in 0in">
                          <p class="MsoNormal"
                            style="margin-bottom:12.0pt"><b><span
                                style="font-size:12.0pt;color:black">From:
                              </span></b><span
                              style="font-size:12.0pt;color:black">John
                              Hendrikx <a
                                href="mailto:john.hendrikx@gmail.com"
                                moz-do-not-send="true">
                                <john.hendrikx@gmail.com></a><br>
                              <b>Date: </b>Tuesday, October 24, 2023 at
                              04:58<br>
                              <b>To: </b>Andy Goryachev <a
                                href="mailto:andy.goryachev@oracle.com"
                                moz-do-not-send="true"><andy.goryachev@oracle.com></a>,
                              <a href="mailto:openjfx-dev@openjdk.org"
                                moz-do-not-send="true"
                                class="moz-txt-link-freetext">openjfx-dev@openjdk.org</a>
                              <a href="mailto:openjfx-dev@openjdk.org"
                                moz-do-not-send="true">
                                <openjfx-dev@openjdk.org></a><br>
                              <b>Subject: </b>Re: [External] : Re:
                              Proof of concept pull request for Behavior
                              API (PR 1265)</span><o:p></o:p></p>
                        </div>
                        <p> <o:p></o:p></p>
                        <div>
                          <p class="MsoNormal"><span
                              style="font-size:11.0pt">On 23/10/2023
                              23:57, Andy Goryachev wrote:</span><o:p></o:p></p>
                        </div>
                        <blockquote
                          style="margin-top:5.0pt;margin-bottom:5.0pt">
                          <p class="MsoNormal"><span
                              style="font-size:11.0pt;font-family:"Iosevka
                              Fixed SS16 ""> </span><span
                              style="font-size:11.0pt">
                            </span><o:p></o:p></p>
                          <p class="MsoNormal" style="margin-left:.5in">You'd
                            create a new class, `MyBehavior`,<o:p></o:p></p>
                          <p class="MsoNormal"><span
                              style="font-size:11.0pt;font-family:"Iosevka
                              Fixed SS16 ""> </span><o:p></o:p></p>
                          <p class="MsoNormal"><span
                              style="font-size:11.0pt;font-family:"Iosevka
                              Fixed SS16 "">By “customizing” I also
                              mean at run time.  Creating new classes
                              wouldn’t work. 
                            </span><o:p></o:p></p>
                        </blockquote>
                        <p>This would also work at runtime, as the class
                          you create can <span
                            style="background:yellow;mso-highlight:yellow">
                            be instantiated with parameters that control
                            its key binding behavior</span>.  Even
                          though the standard Behaviors should probably
                          be singletons (so they can be reused and
                          composed) or have public well documented
                          constructors, a custom behavior created by the
                          user has no such re-usability restrictions.<o:p></o:p></p>
                        <blockquote
                          style="margin-top:5.0pt;margin-bottom:5.0pt">
                          <p class="MsoNormal"><span
                              style="font-size:11.0pt;font-family:"Iosevka
                              Fixed SS16 ""> </span><o:p></o:p></p>
                          <p class="MsoNormal" style="margin-left:.5in"><span
style="background:yellow;mso-highlight:yellow">coupling</span><o:p></o:p></p>
                          <p class="MsoNormal"><span
                              style="font-size:11.0pt;font-family:"Iosevka
                              Fixed SS16 ""> </span><o:p></o:p></p>
                          <p class="MsoNormal"><span
                              style="font-size:11.0pt;font-family:"Iosevka
                              Fixed SS16 "">I don’t think it is our
                              choice - it is up to the skin designed. 
                              If they add a node that needs to take
                              input, or if the behavior is drastically
                              different, it is almost impossible to
                              create a common interface.  So skin and
                              behaviors are coupled, besides we have to
                              design for the worst case (of a totally
                              different skin).  The division between S
                              and B comes mostly from the division
                              between V and C in MVC.  From a distance,
                              the user does not see it at all - all they
                              see is a control.</span><o:p></o:p></p>
                        </blockquote>
                        <p>JavaFX is not doing MVC.<o:p></o:p></p>
                        <p class="MsoNormal"><span
                            style="font-size:11.0pt">In MVC, the 3
                            components are not entangled; Model refers
                            View, Controller refers View and Model, View
                            refers nothing; in JavaFX the View (Skin)
                            creates the Controller (Behavior); the View
                            especially normally can be created without
                            any dependencies, and can be tested as such;
                            with Skins being tightly coupled to both
                            Behaviors and Controls, that doesn't even
                            come close.</span><o:p></o:p></p>
                        <p>For it to be MVC you'd need to:<o:p></o:p></p>
                        <p>- Remove reference from Skin to Control<br>
                          - Do not let Skins create Behaviors<br>
                          - Instantation order should be, create a Skin
                          first (with no Control reference), then create
                          the Control (with Skin as parameter or
                          setter), then create a Behavior (with Control
                          as parameter, and one or more Views (Skins))<o:p></o:p></p>
                        <p>What JavaFX is exactly,  I don't know. It
                          doesn't follow MVC (even though it claims to)
                          because in the current setup the Skin is both
                          V and C; that's not MVC.  At most it is MS
                          (Model Skin), and so there is no reason to
                          expose anything beyond the Skin then, as that
                          would just be pretending to be something that
                          it is not.<o:p></o:p></p>
                        <blockquote
                          style="margin-top:5.0pt;margin-bottom:5.0pt">
                          <p class="MsoNormal"><span
                              style="font-size:11.0pt;font-family:"Iosevka
                              Fixed SS16 ""> </span><o:p></o:p></p>
                          <p class="MsoNormal"><span
                              style="font-size:11.0pt;font-family:"Iosevka
                              Fixed SS16 "">This suggest another
                              metric at judging the usefulness of a
                              design - how easy it is to understand and
                              perform 80% of most common tasks.</span><o:p></o:p></p>
                        </blockquote>
                        <p class="MsoNormal"><span
                            style="font-size:11.0pt">Now that I
                            explained how key remappings would work, I
                            don't see how this would disqualify the
                            alternative proposal.<br>
                            <br>
                            <br>
                            <br>
                          </span><o:p></o:p></p>
                        <blockquote
                          style="margin-top:5.0pt;margin-bottom:5.0pt">
                          <p class="MsoNormal"><span
                              style="font-size:11.0pt;font-family:"Iosevka
                              Fixed SS16 ""> </span><o:p></o:p></p>
                          <p class="MsoNormal"><span
                              style="font-size:11.0pt;font-family:"Iosevka
                              Fixed SS16 "">There are more
                              interesting ideas at the end of the
                              message I am replying to - fxml, css,
                              global changes - these go far beyond the
                              simple input map improvement.  I did
                              mention this already, but neither open
                              source community, nor my employer might
                              have the resources to make such drastic
                              changes.</span><o:p></o:p></p>
                        </blockquote>
                        <p class="MsoNormal"><span
                            style="font-size:11.0pt">I didn't mention
                            FXML, but yes, I gave some other things to
                            think about.  As for how drastic any of
                            those are, that remains to be seen. 
                            Certainly the global changes would not be
                            that hard at all.  The CSS proposal would
                            need some research if there is some will to
                            go there; it assumes that the information
                            needed can be transported in a reasonable
                            manner to the key binding system using the
                            existing CSS infrastructure.<br>
                            <br>
                            <br>
                            <br>
                          </span><o:p></o:p></p>
                        <blockquote
                          style="margin-top:5.0pt;margin-bottom:5.0pt">
                          <p class="MsoNormal"><span
                              style="font-size:11.0pt;font-family:"Iosevka
                              Fixed SS16 ""> </span><o:p></o:p></p>
                          <p class="MsoNormal"><span
                              style="font-size:11.0pt;font-family:"Iosevka
                              Fixed SS16 "">So we have to be
                              realistic, I think.  We are travelling to
                              a different planet in a small spaceship
                              and we only have so much material and
                              oxygen to play with.  A simple improvement
                              that helps 80% of use cases might be
                              better than a major redesign (I still
                              think the event proposal involves major
                              redesign).</span><o:p></o:p></p>
                        </blockquote>
                        <p>I think that if that's the case that we'd
                          better focus on making it possible for 3rd
                          parties to deliver these features, and do the
                          simplest thing that would allow them to do so.
                          That would be prioritized event handlers (so a
                          3rd party can always intercept before the
                          Skin/Behavior gets to it) + a flag to skip
                          system event handlers (ala consumed) to allow
                          bubbling up.<o:p></o:p></p>
                        <p>On top of that any key remapping or behavior
                          change system can be constructed already.<o:p></o:p></p>
                        <p>--John<o:p></o:p></p>
                      </div>
                    </div>
                  </blockquote>
                </div>
              </div>
            </blockquote>
          </div>
        </div>
      </div>
    </blockquote>
  </body>
</html>