<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:Helvetica;
        panose-1:0 0 0 0 0 0 0 0 0 0;}
@font-face
        {font-family:Wingdings;
        panose-1:5 0 0 0 0 0 0 0 0 0;}
@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:Optima-Regular;
        panose-1:2 0 5 3 6 0 0 2 0 4;}
/* Style Definitions */
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.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;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style>
</head>
<body lang="EN-US" link="blue" vlink="purple" style="word-wrap:break-word;overflow-wrap: break-word;-webkit-nbsp-mode: space;line-break:after-white-space">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">Dear Martin:<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"">This basically is the minimal API surface as far as InputMap is concerned.  There are probably some methods still missing, such as ...<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"><span style="font-size:11.0pt">Say I want Ctrl-J to be Copy instead of whatever it’s default binding is.</span><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"">InputMap.unbind(FunctionTag.COPY);
</span><span style="font-size:11.0pt;font-family:Wingdings"></span><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> missing method.  Or we could add InputMap.getKeyBindingfor(FunctionTag)<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"">followed by<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"">InputMap.registerKey(KeyBinding.ctrl(KeyCode.J), COPY);<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"">So, basically, one or two methods are missing!<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" style="margin-left:.5in"><span style="font-size:11.0pt">Any control will need to ensure that it ignore tags it doesn’t understand. Who cares if Ctrl-A maps to SELECT_ALL for a button? It will just ignore it.<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:11.0pt">But I do get your point. If we ask a Control to map an event to an operation we should ensure that the control actually supports that operation. So we don’t need multiple SELECT_ALL
 tags, just a verification step so we don’t return bogus tags.<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"">Well, if we try to think of a union of all possible functions, it is just not right.  The functions have different semantics for different controls, even SELECT_ALL would be
 different, or there will be multiple flavors of SELECT_ALL or COPY.  I just don’t think it’s necessary. 
<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"">Each control declares a bunch of public methods specific to that control, and also declares a method identifiers corresponding to these methods (that’s FunctionTags).  If we
 try to add a key binding to a button passing a function tag from TextArea it will essentially be ignored because Button does not have the corresponding method.<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 don’t think there are methods that are common for *<b>every</b>* control.  So we have control-specific tags that might be in the control or its base class such as TextInputControl.<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"">P.S. thank you for uncovering a gap in the API!<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">Martin Fox <martin@martinfox.com><br>
<b>Date: </b>Tuesday, October 31, 2023 at 16:21<br>
<b>To: </b>Andy Goryachev <andy.goryachev@oracle.com><br>
<b>Cc: </b>Kevin Rushforth <kevin.rushforth@oracle.com>, openjfx-dev <openjfx-dev@openjdk.org><br>
<b>Subject: </b>Re: [External] : Re: [Request for Comments] Behavior / InputMap<o:p></o:p></span></p>
</div>
<p class="MsoNormal"><span style="font-size:11.0pt">Andy,<o:p></o:p></span></p>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">I should have been clearer on why I wrote this up. I think once you’ve identified the minimum API surface that’s probably all you should implement.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">More important to me is whether reducing the API to a bunch of function tags and two API calls does everything that needs to be done. For example, that reduction means you can’t enumerate the list of function
 tags a control supports or the full set of key bindings. Is that an issue? Is there a use case for these enumerations?<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
</div>
<div>
<div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p style="mso-margin-top-alt:5.0pt;margin-right:0in;margin-bottom:0in;margin-left:.5in">
<span style="font-size:9.0pt;font-family:Helvetica">3) Provide an API that asks a control to map an Event to a FunctionTag. This enables blocking existing mappings; if a user wants to block the default mappings for, say, COPY they can simply discard/consume
 any events that the control would map to COPY.</span><span style="font-size:10.5pt;font-family:Optima-Regular"><o:p></o:p></span></p>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">Supported via InputMap.registerFunction(FunctionTag, Runnable).  Just do registerFunction(COPY, () -> { }). </span><o:p></o:p></p>
</div>
</blockquote>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
</div>
<p class="MsoNormal"><span style="font-size:11.0pt">Sorry I didn’t make myself clear. Say I want Ctrl-J to be Copy instead of whatever it’s default binding is. The flow would be:<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">if the event is Ctrl-J<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">ask the control to perform the COPY operation<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">else if the control maps this event to COPY<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">discard the event (it’s the default binding)<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
</div>
<div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">They are not.  There is no SELECT_ALL in Button control, for example.  Where the hierarchy exists, so does the hierarchy of tags, for example TextInputControl.SELECT_ALL which
 is applicable/used in TextField and TextArea.  But we can’t extend it to TableView, for example, as there is no common ancestor - unless we invent one (an interface).</span><o:p></o:p></p>
</div>
</blockquote>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
</div>
<p class="MsoNormal"><span style="font-size:11.0pt">Any control will need to ensure that it ignore tags it doesn’t understand. Who cares if Ctrl-A maps to SELECT_ALL for a button? It will just ignore it.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">But I do get your point. If we ask a Control to map an event to an operation we should ensure that the control actually supports that operation. So we don’t need multiple SELECT_ALL tags, just a verification
 step so we don’t return bogus tags.<o:p></o:p></span></p>
</div>
<div>
<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">
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">What do you think?</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">Thank you</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">-andy</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
<div id="mail-editor-reference-message-container">
<div>
<div style="border:none;border-top:solid windowtext 1.0pt;padding:3.0pt 0in 0in 0in;border-color:currentcolor currentcolor;border-image: none">
<p class="MsoNormal" style="margin-bottom:12.0pt"><b><span style="font-size:12.0pt">From:<span class="apple-converted-space"> </span></span></b><span style="font-size:12.0pt">Martin Fox <martin@martinfox.com><br>
<b>Date:<span class="apple-converted-space"> </span></b>Monday, October 30, 2023 at 17:24<br>
<b>To:<span class="apple-converted-space"> </span></b>Andy Goryachev <andy.goryachev@oracle.com><br>
<b>Cc:<span class="apple-converted-space"> </span></b>Kevin Rushforth <kevin.rushforth@oracle.com>, openjfx-dev <openjfx-dev@openjdk.org><br>
<b>Subject:<span class="apple-converted-space"> </span></b>[External] : Re: [Request for Comments] Behavior / InputMap</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Helvetica">I was looking over the InputMap proposal with an eye toward paring it down to the bare minimum.</span><span style="font-size:10.5pt;font-family:Optima-Regular"><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Helvetica"> </span><span style="font-size:10.5pt;font-family:Optima-Regular"><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Helvetica">From the perspective of a user who wants to manipulate a control without subclassing it I think there are only a few essential components.</span><span style="font-size:10.5pt;font-family:Optima-Regular"><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Helvetica"> </span><span style="font-size:10.5pt;font-family:Optima-Regular"><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Helvetica">1) Ensure the user gets events before the control does. That’s a topic for a different thread.</span><span style="font-size:10.5pt;font-family:Optima-Regular"><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Helvetica"> </span><span style="font-size:10.5pt;font-family:Optima-Regular"><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Helvetica">2) Provide an API that asks a control to perform the operation identified by a FunctionTag. This is the only way to access operations like COPY and MOVE_RIGHT that are implemented behind
 the scenes.</span><span style="font-size:10.5pt;font-family:Optima-Regular"><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Helvetica"> </span><span style="font-size:10.5pt;font-family:Optima-Regular"><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Helvetica">3) Provide an API that asks a control to map an Event to a FunctionTag. This enables blocking existing mappings; if a user wants to block the default mappings for, say, COPY they can simply
 discard/consume any events that the control would map to COPY.</span><span style="font-size:10.5pt;font-family:Optima-Regular"><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Helvetica"> </span><span style="font-size:10.5pt;font-family:Optima-Regular"><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Helvetica">If a user wants to subclass an existing control they could also use these API’s to do full customization but only if they can guarantee that their subclass will process events before the
 superclass. That, too, might be a separate discussion.</span><span style="font-size:10.5pt;font-family:Optima-Regular"><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Helvetica"> </span><span style="font-size:10.5pt;font-family:Optima-Regular"><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Helvetica">I would like to discuss these API’s without getting too deep into implementation details. With that said, I do have one implementation suggestion: since most of the event => FunctionTag
 mappings are common (SELECT_ALL is always Shortcut+A) there should be an internal shared object containing the common mappings.</span><span style="font-size:10.5pt;font-family:Optima-Regular"><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Helvetica"> </span><span style="font-size:10.5pt;font-family:Optima-Regular"><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Helvetica">Martin</span><span style="font-size:10.5pt;font-family:Optima-Regular"><o:p></o:p></span></p>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt"><br>
<br>
<br>
</span><o:p></o:p></p>
</div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">On Oct 30, 2023, at 3:11 PM, Andy Goryachev <andy.goryachev@oracle.com> wrote:</span><o:p></o:p></p>
</div>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt"> </span><o:p></o:p></p>
</div>
<div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">Dear Kevin:</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">Thank you for providing a summary to our (lively) discussion.  Even though I think I answered these concerns, I don’t mind to have another go at it.</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">Please find the updated proposal here (same link):</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><a href="https://urldefense.com/v3/__https:/gist.github.com/andy-goryachev-oracle/294d8e4b3094fe16f8d55f6dd8b21c09__;!!ACWV5N9M2RV99hQ!MAhFywXruyvFlvk6whGVWBb9fTI-f1D-16YuJbRGdJe52rX503CFBK8S6IamyzPVzQBcJZmg6c_Jh1CfsDxVFw$"><span style="color:#0563C1">https://gist.github.com/andy-goryachev-oracle/294d8e4b3094fe16f8d55f6dd8b21c09</span></a></span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">Let me first define what I mean by “behavior” in the context of this proposal.  A behavior is a translation layer between input events - coming either from the control, or
 from some nodes contained in the skin, or from the platform itself - into some actions.  These translation mappings are maintained by a new property in Control - the InputMap.  The InputMap has two sides - one for the user application, and another - for the
 skins/behaviors.  Both are “public APIs” but the latter is represented as protected methods of BehaviorBase class which forms a foundation of the behavior part of the skins that want to use the InputMap paradigm.</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">Back to individual concerns.</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
</div>
<div style="margin-left:.5in">
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">* We should not make anything related to Behaviors public without a full design of how Behaviors should work, what their responsibilities are, how they interact with Skins<br>
<br>
<br>
<br>
</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">And we don’t.  We recommend to use BehaviorBase, but it’s still possible to use event handlers or any other home-grown mechanism to implement skins/behaviors and suffer from
 the lack of functionality as a result.  If BehaviorBase is not the right name, we can call it InputMapAccessorForSkinUse any other name.</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
</div>
<div style="margin-left:.5in">
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">* This proposal doesn't solve the coupling of Skins and behaviors</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">The skins and behaviors are tightly coupled in some cases.  It is possible that a simple control such as Button does not require tight coupling, but a complex control such
 as TextArea does (see TextAreaSkin:1214).</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">With the InputMap, we now can separate user mappings from skin mappings and handlers.  Changing a skin will unregister all of the handlers added by the associated behavior,
 leaving the user mappings intact.</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
</div>
<div style="margin-left:.5in">
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">* Function tags are defined in control class, but don't match the functionality of control class<br>
NOTE: this begs the question of whether there should always be a method on control for each such function (even if the implementation just delegates to the behavior<br>
<br>
<br>
<br>
</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">May be it was not described extensively, but it is being suggested to have one public method for each function tag, which does invoke the said tag.  This enabled indirection
 via InputMap which in turn allows the app- or skin- developer to redefine the functionality (in effect, allowing for changing the behavior without subclassing the behavior).</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">So, for example, SomeControl.copy() would invoke execute(TAG_COPY), which by default would invoke SomeControlBehavior.copy().</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">This proposal did not make this change for the subset of controls - intentionally - because it can be done later in a separate PR.</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
</div>
<div style="margin-left:.5in">
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">* An input map should not refer to the node and be stateless and sharable among all (or some) instances of the same class; this would mean mapping input events to Control::method rather than to instance::method
 or to some arbitrary lambda<br>
NOTE: this would depend on the previous being resolved</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">I think we are confusing two things.  The InputMap allows for per-control mapping, so it cannot be shareable or static.  Period.</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">Now, the other thing is a possible requirement to allow for changing the mapping on per-control-type basis, to overwrite the behavior for each instance of a particular control. 
 This I did not address because it’s an implementation detail for<span class="apple-converted-space"> </span><b><i><u>that control type</u></i></b>.  I did not want to add child maps, but perhaps we could add another API to the skin/behavior side of InputMap
 to allow for such a static map.</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">Personally, I don’t like the idea as it basically adds nothing: event handlers still need to be added to each control and each Node in the skin (if any) and there is an extra
 complexity added.  A better solution would be to subclass the control class and add the mappings for each instance just like we do today.</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
</div>
<div style="margin-left:.5in">
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">* Arbitrary key mapping seems out of scope for the core of JavaFX; this sort of mapping could be done by the application if the event order problem was solved, and if we had public API on control for all functions
 that are called by the behavior.</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">Arbitrary (user) key bindings are<span class="apple-converted-space"> </span><b><i><u>enabled</u></i></b><span class="apple-converted-space"> </span>by the proposed InputMap. 
 Any alternative proposal, in my opinion, should support this function out of the box.</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
</div>
<div style="margin-left:.5in">
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">* Should Input map be immutable?</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">The value of InputMap is ability to change the mapping, so I don’t understand where this requirement is coming from.  Perhaps an example or a use case could be provided?</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
</div>
<div style="margin-left:.5in">
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">* Changes to the Behavior system should focus on replacing complete behaviors, and being able to use these by default for a certain subset of controls (like -fx-skin provide in CSS)<br>
<br>
<br>
<br>
</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">As I mentioned earlier, the skin and its behavior might be tightly coupled.  So if a use case exists for changing the behavior, we already have a solution - a custom skin. 
 May be a use case or an example of why we can’t do that with the existing architecture would help here.</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">And finally, I would like to emphasize that even though the InputMap proposal is fairly well developed and validated using a number of non-trivial controls and some new controls
 (RichTextArea<span class="apple-converted-space"> </span><a href="https://urldefense.com/v3/__https:/github.com/andy-goryachev-oracle/jfx/pull/1__;!!ACWV5N9M2RV99hQ!MAhFywXruyvFlvk6whGVWBb9fTI-f1D-16YuJbRGdJe52rX503CFBK8S6IamyzPVzQBcJZmg6c_Jh1ACM9EGvA$"><span style="color:#0563C1">https://github.com/andy-goryachev-oracle/jfx/pull/1</span></a><span class="apple-converted-space"> </span>),
 I am not against modifying/enhancing it based on the community feedback.  I hope we can get to a good solution in a reasonable time frame, or we all would have to learn react and program in javascript.</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">Cheers,</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">-andy</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
</div>
</div>
<div id="mail-editor-reference-message-container">
<div>
<div style="border:none;border-top:solid windowtext 1.0pt;padding:3.0pt 0in 0in 0in;border-color:currentcolor;border-image: none">
<p class="MsoNormal" style="margin-bottom:12.0pt"><b><span style="font-size:12.0pt">From:<span class="apple-converted-space"> </span></span></b><span style="font-size:12.0pt">openjfx-dev <openjfx-dev-retn@openjdk.org> on behalf of Kevin Rushforth <kevin.rushforth@oracle.com><br>
<b>Date:<span class="apple-converted-space"> </span></b>Friday, October 27, 2023 at 16:34<br>
<b>To:<span class="apple-converted-space"> </span></b>openjfx-dev <openjfx-dev@openjdk.org><br>
<b>Subject:<span class="apple-converted-space"> </span></b>Re: [Request for Comments] Behavior / InputMap</span><o:p></o:p></p>
</div>
<p class="MsoNormal" style="margin-bottom:12.0pt"><span style="font-size:11.0pt">I've mostly caught up on the (lively) discussion surrounding this feature request.<br>
<br>
It is clear that we do not yet have general agreement on the direction this proposal should take, so let's continue to discuss the proposal, its shortcomings, and any alternative approaches.<br>
<br>
We should start by making sure that the motivation for doing this -- what problem is being solved -- is well understood. Andy will rework the initial sections of the proposal to make it more clear.<br>
<br>
If I can summarize what I see are the main concerns that have been raised:<br>
<br>
* We should not make anything related to Behaviors public without a full design of how Behaviors should work, what their responsibilities are, how they interact with Skins<br>
<br>
* This proposal doesn't solve the coupling of Skins and behaviors<br>
<br>
* Function tags are defined in control class, but don't match the functionality of control class<br>
NOTE: this begs the question of whether there should always be a method on control for each such function (even if the implementation just delegates to the behavior<br>
<br>
* An input map should not refer to the node and be stateless and sharable among all (or some) instances of the same class; this would mean mapping input events to Control::method rather than to instance::method or to some arbitrary lambda<br>
NOTE: this would depend on the previous being resolved<br>
<br>
* Arbitrary key mapping seems out of scope for the core of JavaFX; this sort of mapping could be done by the application if the event order problem was solved, and if we had public API on control for all functions that are called by the behavior.<br>
<br>
* Should Input map be immutable?<br>
<br>
* Changes to the Behavior system should focus on replacing complete behaviors, and being able to use these by default for a certain subset of controls (like -fx-skin provide in CSS)<br>
<br>
There are probably other concerns as well.<br>
<br>
Finally, one of the comments made, which I completely agree with, is that API design needs to come first. It needs to be fully fleshed out, and needs to be forward-looking. We should only expose as public API what is needed to solve the problem and no more.<br>
<br>
Let's continue the discussion with this in mind.<br>
<br>
-- Kevin<br>
<br>
<br>
<br>
</span><o:p></o:p></p>
<div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">On 9/29/2023 3:44 PM, Andy Goryachev wrote:</span><o:p></o:p></p>
</div>
</div>
</div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121">Dear fellow JavaFX developers:</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121"> </span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121">For some time now, we’ve been working to identify missing features in JavaFX that hinder application development.  We’ve been working on adding some of the missing
 features (for which we’ll have a separate announcement), but I feel that engaging wider community is a rather important part of the process.</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121"> </span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121">I would like to share with you one such missing feature - ability to extend behavior of the existing components (and make the task of creating new components
 easier) by adding a public InputMap and BehaviorBase. <span class="apple-converted-space"> </span></span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121"> </span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121">Please find the actual proposal here</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121"><a href="https://urldefense.com/v3/__https:/gist.github.com/andy-goryachev-oracle/294d8e4b3094fe16f8d55f6dd8b21c09__;!!ACWV5N9M2RV99hQ!MAhFywXruyvFlvk6whGVWBb9fTI-f1D-16YuJbRGdJe52rX503CFBK8S6IamyzPVzQBcJZmg6c_Jh1CfsDxVFw$"><span style="color:#0563C1">https://gist.github.com/andy-goryachev-oracle/294d8e4b3094fe16f8d55f6dd8b21c09</span></a></span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121"> </span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121">We are very much interested in your feedback.  Thank you in advance.</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121"> </span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121">-andy</span><o:p></o:p></p>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</blockquote>
</div>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
</div>
</div>
</div>
</div>
</body>
</html>