<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<div class="moz-cite-prefix">On 12/11/2024 19:46, Nir Lisker wrote:<br>
</div>
<blockquote type="cite"
cite="mid:CA+0ynh89-CukAeSXw3Z_E2UOjgWK9HfKP0VC9seCAJZv8FSWmQ@mail.gmail.com">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<div dir="ltr">I'd like to understand the focus and event handling
problem better. If I have a focused TextField, all key events go
to it. If I have a Spinner, which is a TextField with 2 Buttons,
it is focused as a single unit and consumes key events whether
they are aimed at the text field or the buttons (I assume the
buttons handle arrow up/down keys?). If I have a ClolorPicker,
it is not focused as a single unit - it has sliders, buttons,
text fields and other things, which can be focused individually.</div>
</blockquote>
<p>For Spinner, all key events go to the main Spinner control,
including the arrow keys. This is because KeyEvents are always
dispatched to Scene#focusOwner which the user should never see to
be something other than the Spinner (ie. it shouldn't ever be
Spinner Up Button). The Behavior installed should act first on
any such keys, including the arrow keys. The reason there are no
arrow key handlers on the buttons is because the buttons are Skin
specific, and so handling them there would break the Spinner's
intended functionality if those buttons don't exist or are
implemented differently. The arrow keys will work regardless if
there are buttons or not, and so it is not a good idea to have
the Skin handle them (aside from the fact that the Behavior should
be deciding such matters, not the Skin).</p>
<p>However, if the TextField has focus (it really doesn't have it,
hence the FakeFocusTextField) then to make the TextField actually
work, the KeyEvents that are still going to Spinner must be
forwarded to the inner TextField. This is a Skin reponsibility as
only the skin knows where those events could possibly go (if there
is no TextField, then nothing needs forwarding). The current
implementation however does this in a really round-about way, and
will resend the KeyEvent from the top of the Scene graph all the
way back to the inner TextField as target -- this means any
handlers in between see these events twice. What should have been
done is that the event is only forwarded locally (I tested this in
a draft PR, and that works splendidly). Michael's proposal
essentially makes this standard functionality, so you don't need
to do any manual forwarding anymore.<br>
</p>
<p>ColorPicker is probably also faking the focus on its individual
components (I didn't check), but if it is supposed to be a
reusable integrated Control, then from the focus owner
perspective, only ColorPicker ever has the focus (of course, if it
opens a PopUp, that's a new Scene, which can have its own focus
owner).</p>
<blockquote type="cite"
cite="mid:CA+0ynh89-CukAeSXw3Z_E2UOjgWK9HfKP0VC9seCAJZv8FSWmQ@mail.gmail.com">
<div dir="ltr">
<div><br>
</div>
<div>What I'm trying to find out is what is "the primitive" in
the focus/event handling plan. A TextField and a Spinner are
treated as primitives, but a ColorPicker and a DatePicker are
not. Where does the line pass? If I'm a controls author, can I
create a Spinner that allows focusing/event-handling the text
field and the buttons separately, like ColorPicker allows? In
this case, Spinner is not a "primitive" control.</div>
</div>
</blockquote>
<p>IMHO ColorPicker and DatePicker are also primitive controls. I
want to be able to tab passed one without going into its inner
buttons/fields, same as combo box. If they open a Popup (after
pressing ENTER or SPACE) then the whole control is still focused,
but there is a 2nd focus inside the new popup created (we wouldn't
want the main control to lose its focus border as that's really
confusing). For Spinner for example, when its text field has the
focus, the focus border is around the entire control (including
the arrow buttons), not just on the TextField area.</p>
<p>--John<br>
</p>
<blockquote type="cite"
cite="mid:CA+0ynh89-CukAeSXw3Z_E2UOjgWK9HfKP0VC9seCAJZv8FSWmQ@mail.gmail.com"><br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Tue, Nov 12, 2024 at
7:56 PM Kevin Rushforth <<a
href="mailto:kevin.rushforth@oracle.com"
moz-do-not-send="true" class="moz-txt-link-freetext">kevin.rushforth@oracle.com</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote"
style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div> I think this is a good discussion to continue. I have a
a couple quick comments:<br>
<br>
<blockquote type="cite">The first question I would like to
resolve is to determine whether the problem exists
globally, or only at the controls level. If even once
scenario exists that does not involve controls, we must
find a solution at the event dispatch level. If not - the
solution can be at the controls level, and I have proposed
a good solution, but it's premature to talk about it right
now.</blockquote>
<br>
Unless it can be clearly shown that this is a controls-only
problem, and never will be something that other users of
events need to worry about, I favor a solution in the event
handling mechanism itself rather than something
controls-specific. So I agree with Michael on this point.<br>
<br>
<blockquote type="cite">4, 5. there seems to be general
misunderstanding why I see copyFor() as a big problem.
(Performance is **not** the issue here).</blockquote>
<br>
Very likely. I certainly don't see it as a big problem,
which suggests I might be missing something. I do find it
unlikely that we are going to change something as
fundamental as having a target in the event (which is the
main reason for using "copyFor").<br>
<br>
-- Kevin<br>
<br>
<br>
<div>On 11/12/2024 8:27 AM, Andy Goryachev wrote:<br>
</div>
<blockquote type="cite">
<div>
<p class="MsoNormal"><span
style="font-size:11pt;font-family:"Iosevka Fixed SS16"">Thank
you Michael for answering my questions!</span></p>
<p class="MsoNormal"><span
style="font-size:11pt;font-family:"Iosevka Fixed SS16""> </span></p>
<p class="MsoNormal"><span
style="font-size:11pt;font-family:"Iosevka Fixed SS16"">I get
from your answers that:</span></p>
<p class="MsoNormal"><span
style="font-size:11pt;font-family:"Iosevka Fixed SS16""> </span></p>
<p class="MsoNormal"><span
style="font-size:11pt;font-family:"Iosevka Fixed SS16"">1. the
priorities are still needed, in one form or the
other. Adding a different type of the EH
(ifUnconsumed) seems to me like a different
priority.</span></p>
<p class="MsoNormal"><span
style="font-size:11pt;font-family:"Iosevka Fixed SS16"">2. the
problem seems to exist only at the controls level -
nothing was mentioned to cause issues related to
priority outside of controls. This seems right,
because only in controls we have two (or more)
actors engaged in event handling - the application
and the skin.</span></p>
<p class="MsoNormal"><span
style="font-size:11pt;font-family:"Iosevka Fixed SS16"">3.
dispatching consumed events looks like a bug to all
respondents</span></p>
<p class="MsoNormal"><span
style="font-size:11pt;font-family:"Iosevka Fixed SS16"">4, 5.
there seems to be general misunderstanding why I see
copyFor() as a big problem. (Performance is **<b>not**</b>
the issue here).</span></p>
<p class="MsoNormal"><span
style="font-size:11pt;font-family:"Iosevka Fixed SS16""> </span></p>
<p class="MsoNormal"><span
style="font-size:11pt;font-family:"Iosevka Fixed SS16"">Please
correct me if I summarized it incorrectly.</span></p>
<p class="MsoNormal"><span
style="font-size:11pt;font-family:"Iosevka Fixed SS16""> </span></p>
<p class="MsoNormal"><span
style="font-size:11pt;font-family:"Iosevka Fixed SS16"">Another
interesting observation is that proposals seem to
have been replaced by widely different alternatives
- ifUnconsumed and event filters. This might
indicate that there is no consensus as of yet, and
the discussion must therefore be continued.</span></p>
<p class="MsoNormal"><span
style="font-size:11pt;font-family:"Iosevka Fixed SS16""> </span></p>
<p class="MsoNormal"><span
style="font-size:11pt;font-family:"Iosevka Fixed SS16"">The
first question I would like to resolve is to
determine whether the problem exists globally, or
only at the controls level. If even once scenario
exists that does not involve controls, we must find
a solution at the event dispatch level. If not -
the solution can be at the controls level, and I
have proposed a good solution, but it's premature to
talk about it right now.</span></p>
<p class="MsoNormal"><span
style="font-size:11pt;font-family:"Iosevka Fixed SS16""> </span></p>
<p class="MsoNormal"><span
style="font-size:11pt;font-family:"Iosevka Fixed SS16"">So I
would like to ask for clarifications on these three
questions:</span></p>
<p class="MsoNormal"><span
style="font-size:11pt;font-family:"Iosevka Fixed SS16""> </span></p>
<p class="MsoNormal"><span
style="font-size:11pt;font-family:"Iosevka Fixed SS16"">1. For
ifUnconsumed idea: how will it work when both the
application and the skin register ifUnconsumed EH?
Or is it only available to one side, but not the
other?</span></p>
<p class="MsoNormal"><span
style="font-size:11pt;font-family:"Iosevka Fixed SS16""> </span></p>
<p class="MsoNormal"><span
style="font-size:11pt;font-family:"Iosevka Fixed SS16"">2. For
event filter in behaviors idea: how does it work
when both behavior and the application register an
event filter? and then the skin is changed?
wouldn't we have the same issue?</span></p>
<p class="MsoNormal"><span
style="font-size:11pt;font-family:"Iosevka Fixed SS16""> </span></p>
<p class="MsoNormal"><span
style="font-size:11pt;font-family:"Iosevka Fixed SS16"">3. Are
there any examples outside of controls where
priority inversion happens, or where we need
explicit EH priorities for other reasons?</span></p>
<p class="MsoNormal"><span
style="font-size:11pt;font-family:"Iosevka Fixed SS16""> </span></p>
<p class="MsoNormal"><span
style="font-size:11pt;font-family:"Iosevka Fixed SS16"">Thank
you</span></p>
<p class="MsoNormal"><span
style="font-size:11pt;font-family:"Iosevka Fixed SS16"">-andy</span></p>
<p class="MsoNormal"><span
style="font-size:11pt;font-family:"Iosevka Fixed SS16""> </span></p>
<p class="MsoNormal"><span
style="font-size:11pt;font-family:"Iosevka Fixed SS16""> </span></p>
<p class="MsoNormal"><span
style="font-size:11pt;font-family:"Iosevka Fixed SS16""> </span></p>
<p class="MsoNormal"><span
style="font-size:11pt;font-family:"Iosevka Fixed SS16""> </span></p>
<p class="MsoNormal"><span
style="font-size:11pt;font-family:"Iosevka Fixed SS16""> </span></p>
<p class="MsoNormal"><span
style="font-size:11pt;font-family:"Iosevka Fixed SS16""> </span></p>
<div
id="m_1220407174510802471mail-editor-reference-message-container">
<div>
<div>
<div
style="border-right:none;border-bottom:none;border-left:none;border-top:1pt solid rgb(181,196,223);padding:3pt 0in 0in">
<p class="MsoNormal" style="margin-bottom:12pt"><b><span
style="font-size:12pt;color:black">From: </span></b><span
style="font-size:12pt;color:black">openjfx-dev
<a
href="mailto:openjfx-dev-retn@openjdk.org"
target="_blank" moz-do-not-send="true"><openjfx-dev-retn@openjdk.org></a>
on behalf of Michael Strauß <a
href="mailto:michaelstrau2@gmail.com"
target="_blank" moz-do-not-send="true"><michaelstrau2@gmail.com></a><br>
<b>Date: </b>Friday, November 8, 2024 at
17:52<br>
<b>To: </b><br>
<b>Cc: </b>openjfx-dev <a
href="mailto:openjfx-dev@openjdk.org"
target="_blank" moz-do-not-send="true"><openjfx-dev@openjdk.org></a><br>
<b>Subject: </b>Re: Prioritized event
handlers</span></p>
</div>
<div>
<p class="MsoNormal"><span
style="font-size:11pt">Hi Andy,<br>
<br>
1. What happened to this proposal?<br>
<br>
I've come to the conclusion that we need
something like that, but<br>
probably in a different form. My current
thinking is that we don't<br>
need prioritized handlers, but merely a way
for interested listeners<br>
to say "I'll take this event, but only if no
one else wants it".<br>
A possible API could be something like the
following:<br>
<br>
target.addEventHandler(KeyEvent.PRESSED,
event -> {<br>
event.ifUnconsumed(evt -> {<br>
// This will be called after the
event has bubbled up<br>
// without being consumed.<br>
});<br>
});<br>
<br>
This will allow skins to act on events only
if user code didn't consume them.<br>
<br>
2. Does it make sense to change the API at
the EventDispatcher level<br>
when the problem can be easily solved by the
InputMap at the Control<br>
level?<br>
<br>
Yes, because javafx.controls is not a core
part of JavaFX, and it<br>
should never be. People should be free to
create their own controls<br>
implementation, or alternative skinning
systems. We need to give them<br>
the tools to do so, and not continue the
anti-pattern of shifting core<br>
functionality into javafx.controls and
special-casing this module even<br>
more than it is already special-cased.<br>
<br>
3. dispatching of events that have been
consumed (as mentioned in the<br>
earlier discussion)<br>
<br>
Probably not necessary. Once an event is
consumed, it's gone; we don't<br>
need to dispatch it further.<br>
<br>
4. Problem of creating unnecessary clones of
events via Event.copyFor()<br>
<br>
Unless there is a clear performance problem,
I consider any<br>
fundamental change here as a solution in
search of a problem.<br>
Events are usually not so plentiful that
we're talking about serious<br>
CPU cycles here. The highest-frequency
events are probably mouse<br>
events, and they happen at most hundreds of
times per second.<br>
<br>
5. If we removed the target, then a listener
couldn't discern whether<br>
the event was targeted at the receiving
node, or at a descendant of<br>
the node.<br>
<br>
<br>
<br>
On Thu, Nov 7, 2024 at 1:03</span><span
style="font-size:11pt;font-family:Arial,sans-serif"> </span><span
style="font-size:11pt">AM Andy Goryachev <a
href="mailto:andy.goryachev@oracle.com"
target="_blank" moz-do-not-send="true"><andy.goryachev@oracle.com></a>
wrote:<br>
><br>
> Dear Michael:<br>
> What happened to this proposal? I
would like to restart the discussion, if
possible.<br>
><br>
> More specifically, I would like to
discuss the following topics:<br>
><br>
> the reason the discussion was started
was due to "priority inversion" problem in
Controls/Skins, ex.: JDK-8231245 Controls'
behavior must not depend on sequence of
handler registration. Do we have this
problem elsewhere? In other words, does it
make sense to change the API at the
EventDispatcher level when the problem can
be easily solved by the InputMap at the
Control level?<br>
> dispatching of events that have been
consumed (as mentioned in the earlier
discussion)<br>
> problem of creating unnecessary clones
of events via Event.copyFor(), leading to
ex.: JDK-8337246 SpinnerSkin does not
consume ENTER KeyEvent when editor
ActionEvent is consumed<br>
> why do we need Event.copyFor() in the
first place? why does Event contain the
target??<br>
></span></p>
</div>
</div>
</div>
</div>
</div>
</blockquote>
<br>
</div>
</blockquote>
</div>
</blockquote>
</body>
</html>