<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p>Hi Andy,</p>
On 27/10/2023 19:10, Andy Goryachev wrote:<br>
<blockquote type="cite"
cite="mid:DM5PR1001MB217264BFBB08A6A91B8E644CE5DCA@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"><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?<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 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></p>
</div>
</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.<br>
</p>
<br>
<blockquote type="cite"
cite="mid:DM5PR1001MB217264BFBB08A6A91B8E644CE5DCA@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"">To reiterate, a proposal in a JEP format would
be nice, so we can see the public API.</span></p>
</div>
</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?</p>
<p>1. A public Behavior API with the initial focus on being able to
reuse and replace default behaviors</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 class="moz-txt-link-freetext" href="https://github.com/openjdk/jfx/pull/1265">https://github.com/openjdk/jfx/pull/1265</a>, leaving the more
controversial event definition parts out for now<br>
</p>
<p>1.1. A possible extension of the above Behavior API to allow
changing high level behavior<br>
</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.</p>
<p>1.2. An extension to the above behavior API to allow for more
user friendly key rebinding</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).</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</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.<br>
</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.</p>
<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. <br>
</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.</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.</p>
<p>--John<br>
</p>
<br>
<blockquote type="cite"
cite="mid:DM5PR1001MB217264BFBB08A6A91B8E644CE5DCA@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"">Please, if you have time, answer these
questions. A short pseudo-code example will be fine.<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"">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.<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<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. I noticed that I switched my PR to Open by
mistake. Sorry, it’s back in Draft.<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>Thursday, October 26, 2023 at 02:15<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>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:<o:p></o:p></span></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>
</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>
</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>
</div>
</blockquote>
</body>
</html>