<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p><br>
    </p>
    <div class="moz-cite-prefix">On 11/10/2023 19:44, Andy Goryachev
      wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:DM5PR1001MB21725BD7F14CD505C561B424E5CCA@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)">
      <!--[if !mso]><style>v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style><![endif]-->
      <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><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
      <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"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16"">Seems like addEventFilter() was specifically
            designed to intercept events before any other handlers, so I
            see no problem there.</span></p>
      </div>
    </blockquote>
    <p>This is a misunderstanding of what filters are for.  They're
      called in the capturing phase and they can prevent an event from
      reaching its intended target, but you want it to reach the
      intended target FIRST, as you still want to give the target the
      chance to be the first to act upon the event.  For example, let's
      say I want to attach a function to the SPACE key in some
      specialized HBox, it should only do something when something
      closer to the target doesn't need it first (like a nested HBox of
      the same type, or an active TextField that uses SPACE for input). 
      Now if HBox had some FX default event handler that consumed SPACE,
      I have no options to override SPACE anymore; the filter is not a
      good spot, as its too early, and the handler is not a good spot
      because Behavior handlers were added before mine was.<br>
    </p>
    <br>
    <blockquote type="cite"
cite="mid:DM5PR1001MB21725BD7F14CD505C561B424E5CCA@DM5PR1001MB2172.namprd10.prod.outlook.com">
      <div class="WordSection1">
        <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"">I somewhat disagree about the purpose of the key
            mapping system – the proposed solution solves two existing
            issues (the skin/behavior mappings and the user mappings) in
            one neat package.  Every other instrument such as
            addEventHandler/Filter is still there.</span></p>
      </div>
    </blockquote>
    <p>I'm saying that the need for this would be almost non-existent if
      user event handlers weren't considered less important than FX
      ones. You have to be careful that there aren't two ways of doing
      things here:<br>
    </p>
    <p>If the event you wish to give an alternative purpose to is unused
      by FX, you can use an event handler; otherwise you must disable it
      (so you can use an event handler!) or remap it (using an
      alternative system).  Note that if FX at some point decides to
      "claim" another mapping, that would be a breaking change as some
      user event handlers may cease to function.</p>
    <p>This is why I think the input mapping system should stay hidden;
      its an implementation detail of the Event handlers added by FX so
      they don't need to write long if/else/switch chains, and so they
      can more easily switch out mappings depending on state.  Opening
      up the input map effectively is being able to influence those FX
      added event handlers to do something different, while there is a
      perfectly good way of doing that already: add your own event
      handler (with higher priority).<br>
    </p>
    <blockquote type="cite"
cite="mid:DM5PR1001MB21725BD7F14CD505C561B424E5CCA@DM5PR1001MB2172.namprd10.prod.outlook.com">
      <div class="WordSection1">
        <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"">And, if we look at the three bullet points<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 style="margin-left:.5in">- Ensure user event handlers have
          priority over behavior/inputmap added ones<br>
          - Ensure all behavior actions are available as methods on
          controls<br>
          - Ensure that if a key is handled by the control, that it is
          ONLY consumed when it actually triggers an action (navigation
          keys get consumed regardless, even if no focus change results,
          that's wrong).<o:p></o:p></p>
        <p class="MsoNormal"><span
            style="font-size:11.0pt;font-family:"Iosevka Fixed
            SS16"">I absolutely agree, and in fact the first three
            are indeed a part of the proposal.  Well, the 3<sup>rd</sup>
            one might unfortunately be a subject of backward
            compatibility limitation since one of the requirements was
            no behavior change w.r.t. the earlier versions.  We can
            always change the behavior if we have a completing reason
            and go through the usual process, nothing in the proposal
            precludes that.</span></p>
      </div>
    </blockquote>
    <p>I don't see how your proposal addresses the first point.  <br>
    </p>
    <p>I've been reading the comments attached to
      <a class="moz-txt-link-freetext" href="https://bugs.openjdk.org/browse/JDK-8091189">https://bugs.openjdk.org/browse/JDK-8091189</a> and it has a lot of
      good information, and raises many good points (immutable input
      maps, keep input maps/behaviors as implementation details, use
      interfaces instead of base classes, what about controls that have
      no Skin, even the point I made about having the Control be in
      charge of registering the event handlers instead of letting
      InputMap do it requiring a Control field...).  There are several
      patches by Jonathan Giles, and there is even a library created by
      the author of ReactFX that allows for replacing key bindings with
      a much nicer API already (in so far that is possible without
      having inside FX support).  </p>
    <p>The general tone of the comments seems to be that Behaviors
      should be kept as implementation details -- they're not well
      defined (what is a Behavior, what should be in the Behavior, what
      should be in the Skin and what should be in the Control) and until
      that is absolutely clear, exposing any of that as API is
      premature.  <br>
    </p>
    <blockquote type="cite"
cite="mid:DM5PR1001MB21725BD7F14CD505C561B424E5CCA@DM5PR1001MB2172.namprd10.prod.outlook.com">
      <div class="WordSection1">
        <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"">Making the behaviors completely independent with
            setBehavior() and FXML, as you said, might be a future
            effort, perhaps we could attempt opening up certain controls
            at some point.  On one hand, I am for increasing the
            extensibility of FX, on the other hand the same argument can
            be made against it (as in solidifying a particular way of
            constructing skins and behaviors), but I feel it’s a
            separate issue that is independent of this proposal.</span></p>
      </div>
    </blockquote>
    <p>I'm starting to lean towards keeping all of this as
      implementation details, at least until the current implementation
      is much cleaner than it is currently (the way InputMap and
      Behaviors currently are set up is more pragmatic than truly a good
      design), and just address the main issue: JavaFX stealing events
      that users want to override, note that I say events, key bindings
      are only part of it.</p>
    <p>--John<br>
    </p>
    <blockquote type="cite"
cite="mid:DM5PR1001MB21725BD7F14CD505C561B424E5CCA@DM5PR1001MB2172.namprd10.prod.outlook.com">
      <div class="WordSection1">
        <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"">-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>
        <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">openjfx-dev
                  <a class="moz-txt-link-rfc2396E" href="mailto:openjfx-dev-retn@openjdk.org"><openjfx-dev-retn@openjdk.org></a> on behalf of John
                  Hendrikx <a class="moz-txt-link-rfc2396E" href="mailto:john.hendrikx@gmail.com"><john.hendrikx@gmail.com></a><br>
                  <b>Date: </b>Wednesday, October 11, 2023 at 01:04<br>
                  <b>To: </b><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><br>
                  <b>Subject: </b>Re: [Request for Comments] Behavior /
                  InputMap<o:p></o:p></span></p>
            </div>
            <p>I'm sorry, but that providing an arbitrary key mapping
              system seems completely out of scope and not something
              that JavaFX should concern itself with.  It's much too
              high level, when the key mappings involved should only be
              for actions that the control can provide on its own.<o:p></o:p></p>
            <p class="MsoNormal"><span style="font-size:11.0pt">I think
                the problem we should be solving is that JavaFX control
                behaviors shouldn't be first in line when it comes to
                consuming events (which currently is only the case due
                to event handlers being added at the earliest possible
                opportunity, and event handlers being called in order). 
                If something as trivial as:
                <o:p></o:p></span></p>
            <p>       control.addEventHandler(KeyEvent.KEY_PRESSED, e
              -> {<br>
                            if (e.getCode() == KeyCode.LEFT) {<br>
                                  e.consume();  // stop default behavior<br>
                            }<br>
                     });<o:p></o:p></p>
            <p>... actually worked, then there is much less need to
              redefine/disable behavior key mappings, and no need for a
              secondary system that deals with mappings (the first
              system, event handlers, can simply be used for this).  If
              user event handlers had priority over behavior ones, then
              everything you want can be achieved with the above,
              including:<o:p></o:p></p>
            <p>- Stopping default behavior<br>
              - Triggering different behavior (just call something on
              control, of course, make sure all behavior actions are
              available on the control in the first place)<br>
              - Remapping (a combination of the above two)<br>
              - Adding an alternative key for the same behavior<o:p></o:p></p>
            <p>A system to remap keys can then be left squarely in the
              realm of user space, and much nicer solutions can be build
              by users than whatever JavaFX will provide out of the box.<o:p></o:p></p>
            <p>Changes to the Behavior system can then focus on
              replacing complete behaviors (including their input map)
              and being able to use these by default for a certain
              subset of controls (like -fx-skin provide in CSS), as this
              is something users currently can't do.<o:p></o:p></p>
            <p>So in short, what I think this should be about is:<o:p></o:p></p>
            <p>- Ensure user event handlers have priority over
              behavior/inputmap added ones<br>
              - Ensure all behavior actions are available as methods on
              controls<br>
              - Ensure that if a key is handled by the control, that it
              is ONLY consumed when it actually triggers an action
              (navigation keys get consumed regardless, even if no focus
              change results, that's wrong).<o:p></o:p></p>
            <p>Future:<o:p></o:p></p>
            <p>- Make behaviors public and allow Behaviors to be
              replaced with -fx-behavior type CSS syntax /
              control.setBehavior calls<o:p></o:p></p>
            <p>--John<o:p></o:p></p>
            <p><o:p> </o:p></p>
            <p>The focus should be on being able to modify standard
              behavior of controls (arrow-left, enter, ctrl-shift-right,
              etc.), specifically also to be able to disable these when
              undesired, and, on top of that, that they bubble up when
              NOT used even when they are configured (focus navigation
              keys currently are always consumed, whether they actually
              do something or not -- that's a big issue).  The other
              focus should be on providing an alternative behavior (or
              at least mappings) for all controls of a certain type -- I
              don't see the need for adding a mapping to a specific
              control, that's already covered with event handlers; the
              problem is mostly that behaviors currently steal certain
              events before the user can get at them.<o:p></o:p></p>
            <p>Custom behaviors can then be constructed that provide
              more things that may need mapping.  I'd expect those
              however to be limited in scope to what the control offers,
              certainly not an arbitrary key/action mapping system (that
              wouldn't even work, as most of these would be in the scope
              of several controls or be global).  This kind of
              functionality is much better provided by event handlers at
              the correct level for a group of controls, and I wouldn't
              expect to find such an eloborate system incorporated in
              behaviors.<o:p></o:p></p>
            <p>In fact, thinking about all of this a bit more, <o:p></o:p></p>
            <p><o:p> </o:p></p>
            <p>On 10/10/2023 19:54, Andy Goryachev wrote:<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 "">Re-sending with a smaller image
                  (256kb limit, really?).</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">Andy
                        Goryachev <a
                          href="mailto:andy.goryachev@oracle.com"
                          moz-do-not-send="true">
                          <andy.goryachev@oracle.com></a><br>
                        <b>Date: </b>Tuesday, October 10, 2023 at 10:49<br>
                        <b>To: </b>Michael Strauß <a
                          href="mailto:michaelstrau2@gmail.com"
                          moz-do-not-send="true"><michaelstrau2@gmail.com></a><br>
                        <b>Cc: </b><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: [Request for Comments]
                        Behavior / InputMap</span><o:p></o:p></p>
                  </div>
                  <p class="MsoNormal"><span
                      style="font-size:11.0pt;font-family:"Iosevka
                      Fixed SS16 "">Dear Michael:</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 "">Here is a use case for
                      (re-)mapping by the user at runtime:</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"><img
                      style="width:8.052in;height:6.8333in"
                      id="Picture_x0020_2"
                      src="cid:part1.Mz2XogCD.DoK2QaIf@gmail.com"
                      class="" width="773" height="656" border="0"><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 "">(key mappings UI in Eclipse).</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 can think of several other
                      cases (mentioned in the proposal, I think) so I
                      think we can put the concept of immutable or
                      global InputMap to rest.</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 "">Whether the InputMap contains
                      the reference to its control or not is a minor
                      implementation detail, 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 "">-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>
                  <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">openjfx-dev
                            <a
                              href="mailto:openjfx-dev-retn@openjdk.org"
                              moz-do-not-send="true">
                              <openjfx-dev-retn@openjdk.org></a>
                            on behalf of Michael Strauß <a
                              href="mailto:michaelstrau2@gmail.com"
                              moz-do-not-send="true">
                              <michaelstrau2@gmail.com></a><br>
                            <b>Date: </b>Tuesday, October 10, 2023 at
                            10:36<br>
                            <b>To: </b><br>
                            <b>Cc: </b><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: [Request for Comments]
                            Behavior / InputMap</span><o:p></o:p></p>
                      </div>
                      <div>
                        <p class="MsoNormal"><span
                            style="font-size:11.0pt">> 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.<br>
                            ><br>
                            <br>
                            I struggle to see a use case for this
                            feature. I can imagine that<br>
                            there might be some use cases that call for
                            customized input mappings,<br>
                            but why would this translate to a _mutable_
                            input map? That's quite a<br>
                            departure from the way other parts of JavaFX
                            work.<br>
                            <br>
                            For example, skins are also immutable. If
                            you want to have a different<br>
                            skin for a control, you don't somehow modify
                            the existing skin<br>
                            instance; instead, you'd create a new skin
                            class (or -- somehow --<br>
                            extend an existing skin class), and then
                            install that new skin on your<br>
                            control.<br>
                            <br>
                            An input map shouldn't bind input events
                            directly to instance methods<br>
                            of a particular control instance. It should
                            define the mapping of<br>
                            events to methods symbolically:<br>
                            <br>
                            Instead of mapping Event =>
                            instance.method(), it should map Event =><br>
                            Control::method. The input map could then be
                            stateless and immutable,<br>
                            and can be set on any control instance. If
                            you want to change the<br>
                            mappings, just set a different input map
                            instance. There's no need<br>
                            that an input map would retain a reference
                            to any particular control,<br>
                            since the control reference can be passed
                            into the input map just as<br>
                            easily.</span><o:p></o:p></p>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </blockquote>
          </div>
        </div>
      </div>
    </blockquote>
  </body>
</html>