<!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>