<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p>Hi Andy,<br>
</p>
<div class="moz-cite-prefix">On 23/10/2023 20:56, Andy Goryachev
wrote:<br>
</div>
<blockquote type="cite"
cite="mid:DM5PR1001MB21726855929D27BADA68EEE1E5D8A@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: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;}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.EmailStyle19
{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"><span
style="font-size:11.0pt;font-family:"Iosevka Fixed
SS16"">Thank you for providing the alternative
proposal. One thing I liked is the clarification of the
purpose of behavior to translate input events into
platform-independent actions.<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 noticed you tried to validate the design using
Button - a rather simple Control. I think a better choice
would be to pick one of the more complex controls such as
TableView or TextArea.</span></p>
</div>
</blockquote>
Yeah, I had limited time, but may have some time next weekend to
look at a more complicated control.<br>
<blockquote type="cite"
cite="mid:DM5PR1001MB21726855929D27BADA68EEE1E5D8A@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"">Another missing piece is probably a set of
behavior tests similar to
<a href="https://bugs.openjdk.org/browse/JDK-8314906"
moz-do-not-send="true" class="moz-txt-link-freetext">https://bugs.openjdk.org/browse/JDK-8314906</a>
to verify that the behavior does not change from the user
perspective.</span></p>
</div>
</blockquote>
For now it's a (bare bones) proof of concept, I validated manually
that the Buttons still work as before (including things like holding
keys down, then messing with it with the mouse) -- there's no reason
to assume it wouldn't work, all that was added was a little
indirection.<br>
<blockquote type="cite"
cite="mid:DM5PR1001MB21726855929D27BADA68EEE1E5D8A@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"">One important problem I tried to solve is
managing the key bindings. I think it’s an important
functionality that needs to be provided, evident from the
plethora of use cases described earlier in the discussion.
I cannot see from the PR how you propose to address the
issue, and the examples you mentioned earlier look to me
more complicated than necessary.</span></p>
</div>
</blockquote>
<p>The idea would be that you can customize the keybindings by
creating a new Behavior.</p>
<p>You'd create a new class, `MyBehavior`, in `install` you'd call
`ButtonBehavior.getInstance().install(context)` to install the
default keybindings and handlers from whatever base behavior you'd
like. Then you use the `context` to change the bindings you don't
like. <br>
</p>
<p>The context in this simple proof of concept does not have methods
yet to make this easy, but the methods that you provided in
`BehaviorBase` could live in the `BehaviorContext` interface in
the sample I provided; in other words, a method like `registerKey`
could live there; in effect, a method like `registerKey` is the
same as installing a KEY_PRESSED handler, but which already does
the `== getCode()` check for you (and allows grouping multiple
keys in one handler for efficiency). If `BehaviorContext` becomes
too big with all these methods, it could offer a getter to get
something where all those methods could live (`InputMap` seems
like a decent name for that).<br>
</p>
<blockquote type="cite"
cite="mid:DM5PR1001MB21726855929D27BADA68EEE1E5D8A@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 have hard time understanding where the idea of
static or singleton behavior comes from exactly, and what
benefits it provides. The whole design overlooks the fact
that behaviors are tightly coupled to skins - to the point
where it gets progressively difficult to provide a
reasonable skin-to-behavior interface when skins have a
different design (in appearance and the kinds and number of
nodes involved).</span></p>
</div>
</blockquote>
<p>I'm aware, I'm saying that the whole design will benefit
immensely from getting rid of this coupling. You can already see
how trivial (and how safe) it is to install a Behavior in the
proof of concept; no risk of anything being left behind, full
isolation of behavior installed event handlers/listeners is
possible, and with the Behavior, BehaviorContext and handlers each
handling a particular aspect, it offers a much better separation
of concerns. <br>
</p>
<p>Perhaps it is impossible to uncouple Skins, but I don't think
that is the case, simply because if you build a Skin from scratch
with this in mind, you'd be able to do it without the tight
coupling; tightly coupling it to skins was just the first
iteration that got the job done -- without a clear mental model of
what is supposed to be Skin and what is Behavior, things got mixed
up and tightly coupled; no doubt that has resulted in a lot of
hesitation to make Behaviors public as they're currently more of a
Skin implementation detail than a proper separated concern.<br>
</p>
<p>With a (possible) definition that Behaviors offer translation to
higher level events, Skins can make use of those, but need not use
all of them. This means that a Behavior can also offer
translations that may not be useful by current JavaFX skins, but
may be useful for custom skins or future adjustments to FX skins.
For example, a custom ButtonSkin may not care for "ARM" and
"DISARM", but might want to trigger a flashing animation when
"FIRE" is triggered.<br>
</p>
<blockquote type="cite"
cite="mid:DM5PR1001MB21726855929D27BADA68EEE1E5D8A@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"">Adding more events and have them bubble up the
hierarchy is, in my opinion, a departure from the current
design, possibly a source of regression, impacts performance
(however slightly), and is completely unnecessary. The
application developer can easily achieve that with existing
mechanisms should such a function is indeed needed.<br>
</span></p>
</div>
</blockquote>
<p>Perhaps they're not needed, as the functions, if public, are
easily called directly as well; they're offered as an alternative
to FunctionTags as it is an existing mechanism, and events are
quite suited for interpretation and translation to a different
meaning (like FunctionTags are offering), or to higher level
events with more meaning. If we can drop FunctionTags, then
there'd be no need (yet) for these events.</p>
<p>If we go the event route, the possibilities are left open ended,
as the user can decide where and how to deal with them (which need
not be at the Control level at all). It's even possible such
higher level events are picked up by a Behavior again (3 "disarms"
in a row triggers something new).</p>
<p> It IMHO certainly is worth consideration before dismissing them.</p>
<p>Anyway, I certainly don't agree that they're a regression risk,
nor do I think the performance should matter here -- events are
already being sent out, a few more is not going to be a problem;
events are also in reaction to user actions which are measured in
milliseconds.</p>
<p>I also don't see how they're a departure from the current design
(and by design I mean current public API's -- not private ones,
nor non-finalized ones).<br>
</p>
<blockquote type="cite"
cite="mid:DM5PR1001MB21726855929D27BADA68EEE1E5D8A@DM5PR1001MB2172.namprd10.prod.outlook.com">
<div class="WordSection1">
<p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Iosevka Fixed
SS16"">
<br>
<o:p></o:p></span></p>
<p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Iosevka Fixed
SS16"">Of course, I can be missing some important
points altogether, and/or be completely wrong about
<i>what people want (tm)</i>.</span></p>
</div>
</blockquote>
<p>No, I think key remapping is probably a fair assesment of what
people want, although we do disagree a bit at what level it should
be offered. I can imagine a couple of systems:</p>
<p>- Per control mappings</p>
<p>The customization is per control, and all changed mappings need
to be (re)applied after constructing the control.<br>
</p>
<p>- Global changes of keymappings (ie. something that affects all
Buttons with a single call)</p>
<p>The customization happens on a BehaviorFactory level, which if
manipulated before any controls are created, would result in all
the controls using the changed mappings.<br>
</p>
<p>- CSS based (a selector decides which controls gets different
mappings)<br>
<br>
This could take the form of being able to install a Behavior like
you could with Skins (ie. -fx-behavior, -fx-skin), or a completely
different form where a CSS property is able to change mappings:</p>
<p> -fx-key-mappings: addKey(SPACE, fire) removeKey(ENTER)</p>
<p>Indirections could be done the way color indirections are done
(some prefixes may be needed):</p>
<p> .root { fire: BUTTON_FIRE }<br>
</p>
<p>- Behavior based (replace a Behavior, but only change the
mappings)</p>
<p>Allow a Behavior to be set, and to be easily overriden and its
mappings altered. This would be per control, but differs slightly
in that you only need to change one thing (the Behavior) instead
of multiple things (each mapping). It may also open up a path
towards doing CSS based installing of behaviors (using
-fx-behavior).<br>
</p>
<blockquote type="cite"
cite="mid:DM5PR1001MB21726855929D27BADA68EEE1E5D8A@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"">Now that Kevin is back from vacation, we could
have an internal discussion of the two proposals to
determine how we can move forward.<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"">Thanks again for a lively discussion and the PR.</span></p>
</div>
</blockquote>
<p>Maybe a bit too lively; I may have come off as very direct (even
more so when it is via a text medium) and it took me a while to
also see all the issues (and I'm sure I'm still missing alot given
limited resources to look into this, and then to provide good
feedback/criticism); that was not my intention, I'm just hoping
for the best API we can manage, if possible one that looks as if
it was part of JavaFX from the start, even if it takes a bit more
effort.<br>
</p>
<p><br>
</p>
<blockquote type="cite"
cite="mid:DM5PR1001MB21726855929D27BADA68EEE1E5D8A@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"">Cheers,<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>
</div>
</blockquote>
<p>--John</p>
<p><br>
</p>
<blockquote type="cite"
cite="mid:DM5PR1001MB21726855929D27BADA68EEE1E5D8A@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>
<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>Friday, October 20, 2023 at 14:40<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>Proof of concept pull request for
Behavior API (PR 1265)<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:12.0pt"><span
style="font-size:11.0pt">Hi list,<br>
<br>
I've made a proof of concept for possibly exposing
Behaviors as a first <br>
class API in JavaFX. It's by no means complete, and
there will be some <br>
significant hurdles still no doubt, but this proof of
concept does <br>
replace the internal ButtonBehavior completely with a
newly implemented <br>
public ButtonBehavior (and it seems to be all working
still).<br>
<br>
The proof of concept shows the basics behind this
proposal, and <br>
introduces a Behavior interface, a BehaviorContext
interface, a public <br>
ButtonBehavior and a class with ButtonEvents.<br>
<br>
There is also an Alternate ButtonBehavior which
(somewhat clumsily) <br>
changes the SPACE key for selecting a button to the
"A" key. I suspect <br>
it shouldn't be too hard to make this a bit more
streamlined.<br>
<br>
One thing of note that I haven't quite figured out
yet; even though the <br>
new ButtonBehavior does not install the Navigation
keys, Navigation <br>
still works; this is not because the old behavior is
still active behind <br>
the scenes, but just seems to work out of the box.<br>
<br>
I'm hoping this will make the idea behind this
proposal a bit easier to <br>
grasp. Note that I'm also mainly trying to make it
possible to be able <br>
to remap keys, but I want to make sure that this is
done in such a way <br>
that it doesn't block a future open sourcing of a
Behavior API. With <br>
this proposal it's possible however that Behaviors
must become public <br>
first though before being able to access the necessary
classes to change <br>
input mappings.<br>
<br>
The PR can be found here: <a
href="https://github.com/openjdk/jfx/pull/1265"
moz-do-not-send="true" class="moz-txt-link-freetext">https://github.com/openjdk/jfx/pull/1265</a><br>
<br>
Feel free to comment here or on the PR. The PR is in
draft, so comments <br>
there will not show up on the mailing list.<br>
<br>
Note: the test failure is because tests are using
reflection to access a <br>
behavior field that is part of skins; this field is no
longer present <br>
for ButtonSkin.<br>
<br>
--John<o:p></o:p></span></p>
</div>
</div>
</div>
</div>
</blockquote>
</body>
</html>