Re: RFR: 8301302: Platform preferences API [v15]

2023-10-16 Thread Michael Strauß
On Fri, 8 Sep 2023 05:17:43 GMT, Michael Strauß  wrote:

>> Please read [this 
>> document](https://gist.github.com/mstr2/9f46f92c98d3c86aa6a0b4224a9a6548) 
>> for an introduction to the Platform Preferences API, and how it interacts 
>> with the proposed style theme and stage appearance features.
>
> Michael Strauß has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   Handle key removals

Let's keep this open.

-

PR Comment: https://git.openjdk.org/jfx/pull/1014#issuecomment-1765683765


Re: RFR: JDK-8290310: ChangeListener events are incorrect or misleading when a nested change occurs [v11]

2023-10-16 Thread Michael Strauß
On Mon, 24 Jul 2023 22:09:49 GMT, John Hendrikx  wrote:

>> modules/javafx.base/src/main/java/com/sun/javafx/binding/ListenerManager.java
>>  line 143:
>> 
>>> 141:  */
>>> 142: public void fireValueChanged(I instance, T oldValue) {
>>> 143: Object data = getData(instance);
>> 
>> The `data` value could be passed into this method, which would save a 
>> (potentially not devirtualized) method call.
>
> Thanks, I'll look into that, it might speed up the 1 listener cases a bit.  
> The same applies to OldValueCachingListenerManager#getValue I think.  I know 
> it isn't possible for the add/remove calls, as the data may change if they're 
> nested, but for `fireValueChanged` I never really checked after going to this 
> strategy.

Have you considered passing `data` directly into the method? What is your 
conclusion?

-

PR Review Comment: https://git.openjdk.org/jfx/pull/1081#discussion_r1361519194


Re: RFR: 8306083: Text.hitTest is incorrect when more than one Text node in TextFlow [v7]

2023-10-16 Thread Karthik P K
On Wed, 27 Sep 2023 15:33:17 GMT, Phil Race  wrote:

>> Changes requested by prr (Reviewer).
>
>> @prrace could you please take a look at this?
> 
> Hmm. I did last week, but I see my review comments were still pending. I 
> don't know why, I thought I submitted them. Now submitted for sure.

@prrace could you please re-review?

-

PR Comment: https://git.openjdk.org/jfx/pull/1157#issuecomment-1765676165


RFR: 8318204: Use new EventTarget methods in ListenerHelper

2023-10-16 Thread Michael Strauß
As of OpenJFX 21, `EventTarget` has methods to add and remove event listeners.
The `instanceof` checks in `com.sun.javafx.scene.control.ListenerHelper` should 
be removed and replaced by a simple call to the respective interface method.

-

Commit messages:
 - Use new EventTarget methods in ListenerHelper

Changes: https://git.openjdk.org/jfx/pull/1262/files
 Webrev: https://webrevs.openjdk.org/?repo=jfx=1262=00
  Issue: https://bugs.openjdk.org/browse/JDK-8318204
  Stats: 87 lines in 2 files changed: 1 ins; 78 del; 8 mod
  Patch: https://git.openjdk.org/jfx/pull/1262.diff
  Fetch: git fetch https://git.openjdk.org/jfx.git pull/1262/head:pull/1262

PR: https://git.openjdk.org/jfx/pull/1262


Re: Wayland

2023-10-16 Thread Thiago Milczarek Sayão
Hi,

I am investigating about prism on Wayland.

It looks like we could just replace the GLX calls on X11 backend to EGL and
it will work on both (maybe rename it).

It will need some work to pass the native display around - it assumes X11
Display everywhere and it could be a Display or a wl_display.

-- Thiago.

Em dom., 15 de out. de 2023 às 16:06, Thiago Milczarek Sayão <
thiago.sa...@gmail.com> escreveu:

> Hi,
>
> Update: It now works on wayland with -Dprism.order=sw
>
>
>
> Em dom., 15 de out. de 2023 às 10:49, Thiago Milczarek Sayão <
> thiago.sa...@gmail.com> escreveu:
>
>> Hi,
>>
>> https://github.com/openjdk/jfx-sandbox/tree/tsayao_wayland
>>
>> I did some experiments here. So far, so good.
>>
>> 1) Replaced GDK events for Gtk Signals - It's the way to go for newer gtk.
>> 2) Replaced drawing directly in the window and added a GtkDrawingArea
>> with a GtkHeaderBar which allows control over the whole window
>> size and allows to get rid of extents* calls - this cleans up a lot.
>> 3) Unified the WindowContext to clean it up.
>>
>> I also integrated the IME replacement proposed here:
>> https://github.com/openjdk/jfx/pull/1080
>>
>> It almost runs with software rendering on Wayland, but something still
>> touches X11.
>>
>> To finally make it work on Wayland it requires to implement it on prism
>> es2. I see that there's a EGL part of Monocle. I still don't completely
>> understand it, but wouldn't it work as a drop-in replacement?
>>
>> -- Thiago.
>>
>>
>>


Re: RFR: 8317508: Provide media support for libavcodec version 60

2023-10-16 Thread Victor Dyakov
On Fri, 13 Oct 2023 01:24:36 GMT, Alexander Matveev  
wrote:

> - Added support for libavcodec version 60.
> - Tested on Ubuntu 23.10 with all possible media formats.
> - Changed "--disable-yasm" to "--disable-asm". "--disable-asm" disables all 
> assembler optimization and "--disable-yasm" only x86. Without "--disable-asm" 
> I had issue building ffmpeg 6.0 on Ubuntu 23.10 most likely due to compiler 
> version. Disabling assembler optimization fixed issue and we do not need this 
> anyway for our stubs.

@arapte @johanvos  please review

-

PR Comment: https://git.openjdk.org/jfx/pull/1259#issuecomment-1765432959


Re: [External] : Re: [Request for Comments] Behavior / InputMap

2023-10-16 Thread Andy Goryachev
Sorry, I meant an example / use case where it is important and cannot be solved 
by the existing machinery.  Any change in this area is going to introduce a 
major regression risk, and before we talk about changing the foundation we need 
to make sure we are solving a problem that exists.

-andy



From: Martin Fox 
Date: Monday, October 16, 2023 at 14:20
To: Andy Goryachev 
Cc: John Hendrikx , openjfx-dev@openjdk.org 

Subject: Re: [External] : Re: [Request for Comments] Behavior / InputMap
Andy,

John Hendrikx has given specific instances where this is breaking down already. 
The JavaDoc suggest that you can handle events on a node by installing event 
handlers. What it does not say is that a control may have already installed 
some unknown number of event handlers and there’s no guarantee yours will go 
first. And the key to controlling the customization of event handling is to get 
there first.

The same problem occurs when subclassing a control (and I’m assuming we want to 
make it easier for clients to do that). Any one of the superclasses may have 
installed an event handler on the Node. If my subclass installs the same 
handler the two handlers will be executed in some random order which may or may 
not work.

In other words, we have an existing problem with contention in the Node’s 
dispatcher and it will get worse. There’s nothing here that’s *impossible* to 
solve using the existing machinery. In both instances there are ways of 
manipulating the event dispatch chain to do what needs to be done. But it is 
not easy to write a custom EventDispatcher. It has to be coded correctly to 
support the bubbling and capturing phases and there is special handling for 
mouse enter/exit events. So if we want to pursue dispatchers as a solution we 
need to provide one.

(Even if we don’t export an EventHandlerManager we have our own internal 
reasons to use one. Any time a control drops an event handler on the Node it 
will interact with every other event handler there. So if new code adds a new 
handler we should view that as a significant behavioral change that affects 
external clients. I don’t think we want to be in that position.)

Martin


On Oct 16, 2023, at 11:31 AM, Andy Goryachev  wrote:

Martin:

What would be the use case for creating a public EventHandlerManager?

In general, what is the problem we are trying to address that is impossible to 
solve using the existing machinery?

Thank you
-andy


From: Martin Fox 
Date: Saturday, October 14, 2023 at 14:48
To: John Hendrikx 
Cc: Andy Goryachev , openjfx-dev@openjdk.org 

Subject: Re: [External] : Re: [Request for Comments] Behavior / InputMap
I’ve been digging around in the code to get some context on the existing 
machinery for ordering event handler execution. I haven’t had time to write up 
test cases so all of this is based on reading the spec and the code.

The current problem is that all handlers for a given Node are thrown into the 
same bucket and that bucket isn't delivering the execution order clients 
expect. Within the existing framework the minimal solution would be to (a) 
segregate handlers into separate buckets and (b) control the order in which the 
buckets are processed.

The second problem is solved. The order of execution is controlled by the 
EventDispatchChain and there are public API’s for manipulating it. Note that 
it’s possible for one Node to have multiple dispatchers in the chain and anyone 
can take a fully constructed Node and add an EventDispatcher to it (if you’re 
subclassing a node you would override buildEventDispatchChain).

Internally the first problem also has a solution. EventDispatchers which manage 
event handlers and filters are called EventHandlerManagers (the bucket I 
referred to earlier is the Node’s event handler manager). Again, a Node can 
have multiple dispatchers and any of them could be an EventHandlerManager. For 
example, the Control class could have an internal EventHandlerManager with its 
own collection of handlers and filters that is entirely separate from the 
Node’s. It would be up to the class to determine whether its manager executed 
before or after the Node’s.

(In the public API anyone can implement an EventDispatcher but if they want to 
support the existing calls for managing event handlers and filters they are on 
their own. Personally I think we should provide an EventHandlerManager for 
public use.)

Martin



On Oct 14, 2023, at 10:19 AM, John Hendrikx  wrote:

On 12/10/2023 21:56, Andy Goryachev wrote:
Filters: are we talking about key bindings or event handlers?  With the key 
bindings, the user mappings take precedence over those registered through 
behavior.  There is no provision for adjusting priority of the event handlers – 
that’s the FX reality, we don’t get to rearrange event handlers within the 
node.  That’s why I mentioned event filters added to the control.  I am not 
sure why you talk about HBoxes – adding a filter on the control enables the 
user to intercept 

Re: [External] : Re: [Request for Comments] Behavior / InputMap

2023-10-16 Thread Martin Fox
Andy,

John Hendrikx has given specific instances where this is breaking down already. 
The JavaDoc suggest that you can handle events on a node by installing event 
handlers. What it does not say is that a control may have already installed 
some unknown number of event handlers and there’s no guarantee yours will go 
first. And the key to controlling the customization of event handling is to get 
there first.

The same problem occurs when subclassing a control (and I’m assuming we want to 
make it easier for clients to do that). Any one of the superclasses may have 
installed an event handler on the Node. If my subclass installs the same 
handler the two handlers will be executed in some random order which may or may 
not work.

In other words, we have an existing problem with contention in the Node’s 
dispatcher and it will get worse. There’s nothing here that’s *impossible* to 
solve using the existing machinery. In both instances there are ways of 
manipulating the event dispatch chain to do what needs to be done. But it is 
not easy to write a custom EventDispatcher. It has to be coded correctly to 
support the bubbling and capturing phases and there is special handling for 
mouse enter/exit events. So if we want to pursue dispatchers as a solution we 
need to provide one.

(Even if we don’t export an EventHandlerManager we have our own internal 
reasons to use one. Any time a control drops an event handler on the Node it 
will interact with every other event handler there. So if new code adds a new 
handler we should view that as a significant behavioral change that affects 
external clients. I don’t think we want to be in that position.)

Martin

> On Oct 16, 2023, at 11:31 AM, Andy Goryachev  
> wrote:
> 
> Martin:
>  
> What would be the use case for creating a public EventHandlerManager?
>  
> In general, what is the problem we are trying to address that is impossible 
> to solve using the existing machinery?
>  
> Thank you
> -andy
>  
>  
> From: Martin Fox 
> Date: Saturday, October 14, 2023 at 14:48
> To: John Hendrikx 
> Cc: Andy Goryachev , openjfx-dev@openjdk.org 
> 
> Subject: Re: [External] : Re: [Request for Comments] Behavior / InputMap
> 
> I’ve been digging around in the code to get some context on the existing 
> machinery for ordering event handler execution. I haven’t had time to write 
> up test cases so all of this is based on reading the spec and the code.
>  
> The current problem is that all handlers for a given Node are thrown into the 
> same bucket and that bucket isn't delivering the execution order clients 
> expect. Within the existing framework the minimal solution would be to (a) 
> segregate handlers into separate buckets and (b) control the order in which 
> the buckets are processed.
>  
> The second problem is solved. The order of execution is controlled by the 
> EventDispatchChain and there are public API’s for manipulating it. Note that 
> it’s possible for one Node to have multiple dispatchers in the chain and 
> anyone can take a fully constructed Node and add an EventDispatcher to it (if 
> you’re subclassing a node you would override buildEventDispatchChain).
>  
> Internally the first problem also has a solution. EventDispatchers which 
> manage event handlers and filters are called EventHandlerManagers (the bucket 
> I referred to earlier is the Node’s event handler manager). Again, a Node can 
> have multiple dispatchers and any of them could be an EventHandlerManager. 
> For example, the Control class could have an internal EventHandlerManager 
> with its own collection of handlers and filters that is entirely separate 
> from the Node’s. It would be up to the class to determine whether its manager 
> executed before or after the Node’s.
>  
> (In the public API anyone can implement an EventDispatcher but if they want 
> to support the existing calls for managing event handlers and filters they 
> are on their own. Personally I think we should provide an EventHandlerManager 
> for public use.)
>  
> Martin
> 
> 
> On Oct 14, 2023, at 10:19 AM, John Hendrikx  wrote:
>  
> On 12/10/2023 21:56, Andy Goryachev wrote:
> Filters: are we talking about key bindings or event handlers?  With the key 
> bindings, the user mappings take precedence over those registered through 
> behavior.  There is no provision for adjusting priority of the event handlers 
> – that’s the FX reality, we don’t get to rearrange event handlers within the 
> node.  That’s why I mentioned event filters added to the control.  I am not 
> sure why you talk about HBoxes – adding a filter on the control enables the 
> user to intercept the event prior to skin/behavior.
> On simple Controls yes, filters can be used there for this purpose, even 
> though that's not their purpose.  It works because a Control (usually) is a 
> leaf node.  It breaks down however when you want to change behavior of the 
> View controls which have deeper control layers.  You may want to override 
> something 

Re: Alternative approach for behaviors, leveraging existing event system

2023-10-16 Thread John Hendrikx

Hi Andy,

Thanks for the quick response!

Let me see if I can clarify some of your questions.



Thank you, John, for a detailed writeup.

Before going into details, I would like to ask you to clarify some of 
the aspects of the alternative proposal:


1. What is the API for setting user event handlers vs. behavior event 
handlers?


User handlers stay backwards compatible, so no change there, they can be 
installed as usual.  I only want to prevent mixing them up with FX 
internals, as this makes the call order unpredictable depending on when 
exactly your event handler was installed/reinstalled, and what type of 
events it is interested in.


Handlers for behaviors have a lot of freedom of how they can be dealt 
with, as it will all be internal code (when users can create behaviors, 
a small API can be exposed for this when installing the behavior).  The 
event handler system could be extended with some kind of priority 
system, or we could create separate lists for behavioral handlers (these 
can use the same EventTypes, but they're marked as behavorial -- no need 
to create new ones, a method on EventType to create a behavioral 
EventType (or lower priority type) from the current one should suffice).


The separate list proposal seems easiest; as the event system already 
maintains lists per type, adding new types will separate them easily.  
The only thing that the event system than needs to do is to treat 
behavioral event handlers as lowest priority (either for a complete 
capture/bubble phase or per Node, not sure yet what would be best here).


2. Is there a way to conditionally invoke the default (behavior) event 
handler if the user event handler decides to do so?



I see two options;

1. The user handler mimics some behavior and fires the same event (ie. 
control.fireEvent(new ButtonEvent(ButtonEvent.BUTTON_FIRE)))
2. The user can install an event handler/filter to block the behavior 
events when it does not pass a condition


3. How is the key bindings registered / unregistered / reverted to 
default?


Initially, you would do this by registering your own event handler that 
overrides an existing key binding; consuming the event will block the 
default behavior.  Removing your event handler will revert it back to 
default.  The only thing that may need additional work is when you want 
to block it from being used by the behavior, but still want to let it 
buble up.  My other post had a suggestion to be able to mark the event 
in some way.


More control can be gained by subclassing or composing an existing 
behavior; see below.


4. How is the functions mapped to key bindings are registered / 
unregistered / reverted?


Functions can be blocked by consuming the relevant ButtonEvent; removing 
that handler will revert it to defaults.


Influencing existing behaviors directly I think should be done by 
subclassing the behavior or composing it (if they become public). I have 
some ideas here, where you are passed a Context object:


    interface Behavior {
        void install(BehaviorContext context);
    }

The BehaviorContext has primarily a method to install an event handler:

     void addEventHandler(EventType type, 
BiConsumer consumer);


...which is only slightly different from what InputMap offers.

The context can further have methods that are more convenient:

    void addKeyMapping(KeyCode keyCode, EventType type, 
BiConsumer consumer);


The context can also offer methods to remove mappings, so subclassed or 
composed behaviors can remove mappings they want to specifically 
disable.  Other options include providing a predicate to make them 
conditional in a subclass/composition.


It could look something like:

  class MyBehavior implements Behavior {
    public void install(BehaviorContext context) {
   // call behavior you wish to base your behavior on:
  ButtonBehavior.getInstance().install(context);

  // call methods on context to 
add/remove/remap/conditionalize things that ButtonBehavior did
  // call methods on context to add your own custom 
mappings

    }
  }

Installing the custom behavior is then a matter of passing it to a Control:

  control.setBehavior(new MyBehavior());  // can be a singleton, 
but not static as it implements interface


The `install` method can associate state if needed by associating it 
with the callbacks it installs:


  State state = new State();
  BiConsumer bc = (b, c) -> {  // access state here };

Alternatively, the State class can have methods like:

    class State {
    boolean keyDown;  // some state

    void keyPressed(Button control, KeyEvent event) {
    if (!control.isPressed() && !control.isArmed()) {
    keyDown = true;
    control.fireEvent(new ButtonEvent(ButtonEvent.BUTTON_ARM));
    }
    }
    }

And the handler for installing can be referred to with "state::keyPressed".


Re: [External] : Re: [Request for Comments] Behavior / InputMap

2023-10-16 Thread Andy Goryachev
Martin:

What would be the use case for creating a public EventHandlerManager?

In general, what is the problem we are trying to address that is impossible to 
solve using the existing machinery?

Thank you
-andy


From: Martin Fox 
Date: Saturday, October 14, 2023 at 14:48
To: John Hendrikx 
Cc: Andy Goryachev , openjfx-dev@openjdk.org 

Subject: Re: [External] : Re: [Request for Comments] Behavior / InputMap
I’ve been digging around in the code to get some context on the existing 
machinery for ordering event handler execution. I haven’t had time to write up 
test cases so all of this is based on reading the spec and the code.

The current problem is that all handlers for a given Node are thrown into the 
same bucket and that bucket isn't delivering the execution order clients 
expect. Within the existing framework the minimal solution would be to (a) 
segregate handlers into separate buckets and (b) control the order in which the 
buckets are processed.

The second problem is solved. The order of execution is controlled by the 
EventDispatchChain and there are public API’s for manipulating it. Note that 
it’s possible for one Node to have multiple dispatchers in the chain and anyone 
can take a fully constructed Node and add an EventDispatcher to it (if you’re 
subclassing a node you would override buildEventDispatchChain).

Internally the first problem also has a solution. EventDispatchers which manage 
event handlers and filters are called EventHandlerManagers (the bucket I 
referred to earlier is the Node’s event handler manager). Again, a Node can 
have multiple dispatchers and any of them could be an EventHandlerManager. For 
example, the Control class could have an internal EventHandlerManager with its 
own collection of handlers and filters that is entirely separate from the 
Node’s. It would be up to the class to determine whether its manager executed 
before or after the Node’s.

(In the public API anyone can implement an EventDispatcher but if they want to 
support the existing calls for managing event handlers and filters they are on 
their own. Personally I think we should provide an EventHandlerManager for 
public use.)

Martin


On Oct 14, 2023, at 10:19 AM, John Hendrikx  wrote:

On 12/10/2023 21:56, Andy Goryachev wrote:
Filters: are we talking about key bindings or event handlers?  With the key 
bindings, the user mappings take precedence over those registered through 
behavior.  There is no provision for adjusting priority of the event handlers – 
that’s the FX reality, we don’t get to rearrange event handlers within the 
node.  That’s why I mentioned event filters added to the control.  I am not 
sure why you talk about HBoxes – adding a filter on the control enables the 
user to intercept the event prior to skin/behavior.

On simple Controls yes, filters can be used there for this purpose, even though 
that's not their purpose.  It works because a Control (usually) is a leaf node. 
 It breaks down however when you want to change behavior of the View controls 
which have deeper control layers.  You may want to override something defined 
for ListView, but only if say a focused editable control isn't consuming that 
event for a different purpose.  A filter won't be able to do this.

So yes, this proposal does not address the event handlers (sorry for confusing 
key bindings with event handlers).  Unless we add addListenerBefore() API, we’d 
need to use event filters – but this is out of scope for this proposal.

I do agree with you that we should keep the concrete Behaviors private for now. 
 In any case, public behaviors are outside of scope for this proposal.

I see BehaviorBase moving to a public package though, and it is not package 
private, is that intended then?

One thing you mentioned several times is a “truly good design”.  Let’s hear it! 
 Could you give us an outline, at the public API level at least, of such a 
design?

Alright; these things take a lot of time, but I've taken a few hours to think 
about it today. First, a lot of things just triggered me with the current 
proposal;

- The mutable maps, immutability would allow making these static, saving many 
objects; when I have some time I can take a look at how many are in memory when 
a decent sized FX application is running; as even Labels are Controls, and 
Labels are the base class for any Cell, this number might be larger than 
expected and potentially could allow for some significant memory savings; 
making it public as-is closes that road down forever.  Immutability does not 
mean things can't be changed, it just requires a slightly different mindset 
(ie. you combine a standard InputMap with a custom InputMap to form a new 
InputMap in which a binding is changed/overriden/disabled); this was also 
proposed on JDK-8091189

- The Control back reference; I firmly believe this is unnecessary, and also 
very undesirable.  Events already contain this reference, its superflous and 
requires a new instance for an 

Re: [External] : Re: [Request for Comments] Behavior / InputMap

2023-10-16 Thread Andy Goryachev
Thank you for clarification!

I just want to mention that here we are straying into what looks like a 
parallel discussion about skins (nothing wrong about it!).

just the Skin part. This would likely be a big effort but perhaps it could be 
split into smaller tasks till the end goal is achieved.

Could you please expand upon this?  What parts should skins be split into?

As it currently stands, Skins have two responsibilities - visual representation 
(the View in MVC paradigm) and handling of events, currently represented by the 
private behavior implementation.  In some sense, behaviors and skins are 
tightly coupled - it would be hard, in my opinion, to separate them without 
introducing large public API surface and consequently solidifying certain 
aspects of one particular implementation.

As far as I can tell, the input map proposal addresses the low hanging fruit of 
simple customization like your case of unregistering all key mappings from the 
ScrollPane.  It is certainly not a call to a major redesign.

Cheers,
-andy

From: Pedro Duque Vieira 
Date: Sunday, October 15, 2023 at 05:11
To: Andy Goryachev 
Cc: openjfx-dev@openjdk.org 
Subject: [External] : Re: [Request for Comments] Behavior / InputMap
Hi Andy,

Sorry for the late reply but unfortunately I didn't have time to respond to you 
earlier.

Yes, you're right, Swing did allow for easier extension of controls' themes and 
you did see people coming up with new theme libraries that overwrote Controls 
appearance/behavior through code.

I think the main issue with Skins being difficult to extend is that they're 
taking on too much responsibility. They do both the View and Controller part of 
the Controls (the model being the part that developers interact with). When I 
talk about MVC here I mean it in a loose way, I'm referring to any and all the 
MVC like patterns. If for instance there was a clear class, in the Skin 
architecture, that just took care of how a Control is displayed, and nothing 
else, it would be easier to overwrite, for example, how the Control is 
displayed and hence override Skins.


  *   What are the missing APIs in Skins that we can add to simplify extension 
of skins?
I think, as I said above, Skins would have to have a different architecture. 
IMHO, their responsibilities would likely have to be split into different 
classes each with a smaller set of concerns. I'm not talking about changing the 
whole Control architecture, just the Skin part. This would likely be a big 
effort but perhaps it could be split into smaller tasks till the end goal is 
achieved.


  *   Would this proposal (BehaviorBase + InputMap) prevent us from moving 
forward?
Likely no.

BTW, in the past I already had the need for this API (InputMap) for an 
application I was developing that's now in production. To do what I needed I 
had to call on private methods using reflection, etc, since there's no public 
API to achieve this yet.
My use case was that I was creating a custom control, "inside" that control I 
used a ScrollPane but ScrollPane has a bunch of default key mappings, like 
SPACE, PAGE_UP, PAGE_DOWN, HOME that when pressed already do predefined things. 
I needed to remove those key mappings as in this application those keys were 
already meant to do something else other than what the default JavaFX 
ScrollPane does with them.

Thnaks. Kind regards,

On Mon, Oct 9, 2023 at 7:38 PM Andy Goryachev 
mailto:andy.goryac...@oracle.com>> wrote:
Thank you for the feedback!

You are right: even though Skins are public classes now, they are very 
difficult to extend – at least, much more difficult that Swing UIs.  It’s a 
source of constant discussions within the team – how much of it should be made 
public (protected) to allow for extension vs. how much of it should be hidden 
as implementation detail to minimize the API surface and allow for evolution.  
While opening it all up might alleviate developers’ pain when extending, it 
poses a great(er) danger of introducing of all sorts of compatibility issues 
with respect to bug fixes and other changes.

If we speak about extending skins specifically, a good question might be: what 
exactly is missing?  Which APIs do we need to enable easier extension of skins?

One thing I would like to clarify is that the Behavior / InputMap proposal is 
not about extending skins.  It is also not about making the concrete behaviors 
public (a task which is probably as large as adding missing public APIs to 
skins).

The main goal is to allow for extending and slightly modifying the behavior – 
like altering the way navigation works in a text control, or adding a new key 
binding.  As a result, the overall proposal is smaller than it could be.

Having said that, nothing prevents us from exploring options to open up skins, 
or making behaviors public.

To summarize:

  *   What are the missing APIs in Skins that we can add to simplify extension 
of skins?
  *   Would this proposal (BehaviorBase + InputMap) prevent 

Re: Alternative approach for behaviors, leveraging existing event system

2023-10-16 Thread Andy Goryachev
Thank you, John, for a detailed writeup.

Before going into details, I would like to ask you to clarify some of the 
aspects of the alternative proposal:

1. What is the API for setting user event handlers vs. behavior event handlers?
2. Is there a way to conditionally invoke the default (behavior) event handler 
if the user event handler decides to do so?
3. How is the key bindings registered / unregistered / reverted to default?
4. How is the functions mapped to key bindings are registered / unregistered / 
reverted?
5. Propagating the new events (TextInputControl.SELECT_ALL) up to unsuspecting 
parents represents a bit of departure, how will that impact all the existing 
applications?  Probably not much since they will be ignored, with a bit of 
overhead due to memory allocation, right?
6. If I read it right, it is impossible to redefine the behavior of 
SomeControl.someFunction() except by subclassing, correct?
7. I wonder if this will require a more drastic re-write of all the skins?

Thank you
-andy


From: openjfx-dev  on behalf of John Hendrikx 

Date: Monday, October 16, 2023 at 04:51
To: openjfx-dev@openjdk.org 
Subject: Alternative approach for behaviors, leveraging existing event system
Hi Andy, hi list,

I've had the weekend to think about the proposal made by Andy Goryachev
to make some of the API's surrounding InputMap / Behaviors public.

I'm having some nagging doubts if that proposal is really the way
forward, and I'd like to explore a different approach which leverages
more of FX's existing event infrastructure.

First, let me repeat an earlier observation; I think event handlers
installed by users should always have priority over handlers installed
by FX behaviors. The reasoning here is that the user (the developer in
this case) should be in control.  Just like CSS will back off when the
user changes values directly, so should default behaviors.  For this
proposal to have merit, this needs to be addressed.

One thing that I think Andy's proposal addresses very nicely is the need
for an indirection between low level key and mouse events and their
associated behavior. Depending on the platform, or even platform
configuration, certain keys and mouse events will result in certain high
level actions.  Which keys and mouse events is platform specific.  A
user wishing to change this behavior should not need to be aware of how
these key and mouse events are mapped to a behavior.

I however think this can be addressed in a different way, and I will use
the Button control to illustrate this, as it is already doing something
similar out of the box.

The Button control will trigger itself when a specific combination of
key/mouse events occurs.  In theory, a user could install event handlers
to check if the mouse was released over the button, and then perform
some kind of action that the button is supposed to perform.  In practice
however, this is tricky, and would require mimicing the whole process to
ensure the mouse was also first **pressed** on that button, if it wasn't
moved outside the clickable area, etc.

Obviously expecting a user to install the necessary event handlers to
detect button presses based on key and mouse events is a ridiculous
expectation, and so Button offers a much simpler alternative: the
ActionEvent; this is a high level event that encapsulates several other
events, and translates it to a new concept.  It is triggered when all
the criteria to fire the button have been met without the user needing
to be aware of what those are.

I think the strategy of translating low level events to high level
events, is a really good one, and suitable for reusing for other purposes.

One such purpose is converting platform dependent events into platform
independent ones. Instead of needing to know the exact key press that
would fire a Button, there can be an event that can fire a button.  Such
a specific event can be filtered and listened for as usual, it can be
redirected, blocked and it can be triggered by anyone for any reason.

For a Button, the sequence of events is normally this:

- User presses SPACE, resulting in a KeyEvent
- Behavior receives KeyEvent and arms the button
- User releases SPACE, resulting in a KeyEvent
- Behavior receives KeyEvent, disarms and fires the button
- Control fires an ActionEvent

What I'm proposing is to change it to:

- User presses SPACE, resulting in a KeyEvent
- Behavior receives KeyEvent, and sends out ButtonEvent.BUTTON_ARM
- Control receives BUTTON_ARM, and arms the button
- User releases SPACE, resulting in a KeyEvent
- Behavior receives KeyEvent and sends out ButtonEvent.BUTTON_FIRE
- Control receives BUTTON_FIRE, disarms the button and fires an ActionEvent

The above basically adds an event based indirection.  Normally it is
KeyEvent -> ActionEvent, but now it would be KeyEvent -> ButtonEvent ->
ActionEvent. The user now has the option of hooking into the mechanics
of a Button at several different levels:

- The "raw" level, listening for raw 

Re: [External] : Re: Question: bidi navigation

2023-10-16 Thread Andy Goryachev
Nir, thank you for responding!

The behavior you describe (“logical” navigation) is what can be seen in many, 
but not all applications, and that is what puzzles me.  What’s more 
interesting, the applications that use a “visual” kind of navigation, that is 
the RIGHT ARROW key always moving the cursor right regardless of the text, is 
used by javafx8 (it’s totally broken in jfx17, but it looks from the code that 
it is supposed to be the same as in javafx8), java swing, MS Word 2007 on 
Windows 10, macOS Notes app, macOS TextEdit, and Mozilla Thunderbird.  Also, 
this is the kind of navigation that some users prefer (based on a very, very 
limited sample I was able to contact).

What puzzles me is that there is no apparent standard even among the modern 
applications (bundled macOS apps), although the transition from visual to 
logical navigation in MS Word might indicate that the logical navigation is 
winning.

The appearance of caret is another aspect that seem to have no standard.  In 
many apps the caret does not change at all, very rarely we see a flag 
indicating direction (java swing), and only javafx8 and some obsolete mac 
Carbon reference doc shows a split caret.

More questions for you:

  1.  it looks like you are on Windows, and are you using (or have you seen) a 
fully localized version of Windows with all the UI set to RTL mode?
  2.  Have you seen any native applications that use the visual navigation 
model?

Getting back to the problem at hand: if we were to retain the backward 
compatibility in FX, we would need to fix the “visual” navigation.  FX uses the 
split caret which some users find confusing but we probably are stuck with it.  
If we were to assume that the “logical” navigation is a standard everyone is 
slowly converging to, then my fix for 
https://bugs.openjdk.org/browse/JDK-8296266 is the right one and we should 
declare a change in behavior.

What do you think?

P.S. I wonder if the logical navigation was chosen because of ease of 
implementation, or is there a deeper reason?




From: Nir Lisker 
Date: Monday, October 16, 2023 at 04:52
To: Andy Goryachev 
Cc: openjfx-dev@openjdk.org 
Subject: [External] : Re: Question: bidi navigation
This is a tricky one. All applications I have seen, and I think that's what 
people expect, is that the cursor changes direction during traversal.

A key point is where the paragraph is aligned to (in Windows adjusted with left 
CTRL+SHIFT and right CTRL+SHIFT). This sets the forward and backward direction: 
if the paragraph is left-aligned, pressing the right arrow moves the cursor 
forward, and for a right aligned, the right arrow moves the cursor backward. 
Then the actual movement of the cursor is relative to the paragraph alignment: 
in RTL alignment, traversing RTL text moves the cursor forward, while 
traversing LTR moves the cursor backward.

Examples
In a left-aligned paragraph, pressing the right arrow will move the cursor (|) 
like this:
|ab אבג cd
a|b אבג cd
ab| אבג cd
ab |אבג cd  OR ab אבג| cd(there is ambiguity because the space 
character can be both RTL or LTR)
ab א|בג cd
ab אב|ג cd
ab אבג| cd  OR ab |אבג cd
ab אבג |cd
ab אבג c|d
ab אבג cd|

To help with navigation, the cursor has a line attached to its top showing 
which direction it's facing.

Hope this helps.

On Thu, Oct 12, 2023 at 3:42 AM Andy Goryachev 
mailto:andy.goryac...@oracle.com>> wrote:
Hi.

I have a question for people who routinely use right-to-left RTL languages 
(Arabic, Hebrew, etc.):

What is your expectation for navigating text using left/right arrow keys when 
the text contains a mixture of RTL and LTR?

It looks like there is no standard when it comes to modern applications – see a 
small sample:
https://gist.github.com/andy-goryachev-oracle/4802f9380fb03ec2be7ac36bd98a2059

In javafx, the navigation of bidirectional (bidi) text might have been broken 
sometime after jfx8, and even jfx8 might have issues, see
https://bugs.openjdk.org/browse/JDK-8296266

It looks like the most modern applications use logical navigation and logical 
selection (that is, when navigating using left/right arrow keys, the cursor 
position reflects previous/next insertion indexes in the text, rather than 
visual position).  This causes the cursor to change the direction of movement 
when it crosses the bidi boundary.  Would you say this is the expected behavior?

Thank you
-andy


Re: Question: bidi navigation

2023-10-16 Thread Nir Lisker
This is a tricky one. All applications I have seen, and I think that's what
people expect, is that the cursor changes direction during traversal.

A key point is where the paragraph is aligned to (in Windows adjusted with
left CTRL+SHIFT and right CTRL+SHIFT). This sets the forward and backward
direction: if the paragraph is left-aligned, pressing the right arrow moves
the cursor forward, and for a right aligned, the right arrow moves the
cursor backward. Then the actual movement of the cursor is relative to the
paragraph alignment: in RTL alignment, traversing RTL text moves the
cursor forward, while traversing LTR moves the cursor backward.

Examples
In a left-aligned paragraph, pressing the right arrow will move the cursor
(|) like this:
|ab אבג cd
a|b אבג cd
ab| אבג cd
ab |אבג cd  OR ab אבג| cd(there is ambiguity because the space
character can be both RTL or LTR)
ab א|בג cd
ab אב|ג cd
ab אבג| cd  OR ab |אבג cd
ab אבג |cd
ab אבג c|d
ab אבג cd|

To help with navigation, the cursor has a line attached to its top showing
which direction it's facing.

Hope this helps.

On Thu, Oct 12, 2023 at 3:42 AM Andy Goryachev 
wrote:

> Hi.
>
>
>
> I have a question for people who routinely use right-to-left RTL languages
> (Arabic, Hebrew, etc.):
>
>
>
> *What is your expectation for navigating text using left/right arrow keys
> when the text contains a mixture of RTL and LTR?*
>
>
>
> It looks like there is no standard when it comes to modern applications –
> see a small sample:
>
>
> https://gist.github.com/andy-goryachev-oracle/4802f9380fb03ec2be7ac36bd98a2059
>
>
>
> In javafx, the navigation of bidirectional (bidi) text might have been
> broken sometime after jfx8, and even jfx8 might have issues, see
>
> https://bugs.openjdk.org/browse/JDK-8296266
>
>
>
> It looks like the most modern applications use logical navigation and
> logical selection (that is, when navigating using left/right arrow keys,
> the cursor position reflects previous/next insertion indexes in the text,
> rather than visual position).  This causes the cursor to change the
> direction of movement when it crosses the bidi boundary.  Would you say
> this is the expected behavior?
>
>
>
> Thank you
>
> -andy
>


Alternative approach for behaviors, leveraging existing event system

2023-10-16 Thread John Hendrikx

Hi Andy, hi list,

I've had the weekend to think about the proposal made by Andy Goryachev 
to make some of the API's surrounding InputMap / Behaviors public.


I'm having some nagging doubts if that proposal is really the way 
forward, and I'd like to explore a different approach which leverages 
more of FX's existing event infrastructure.


First, let me repeat an earlier observation; I think event handlers 
installed by users should always have priority over handlers installed 
by FX behaviors. The reasoning here is that the user (the developer in 
this case) should be in control.  Just like CSS will back off when the 
user changes values directly, so should default behaviors.  For this 
proposal to have merit, this needs to be addressed.


One thing that I think Andy's proposal addresses very nicely is the need 
for an indirection between low level key and mouse events and their 
associated behavior. Depending on the platform, or even platform 
configuration, certain keys and mouse events will result in certain high 
level actions.  Which keys and mouse events is platform specific.  A 
user wishing to change this behavior should not need to be aware of how 
these key and mouse events are mapped to a behavior.


I however think this can be addressed in a different way, and I will use 
the Button control to illustrate this, as it is already doing something 
similar out of the box.


The Button control will trigger itself when a specific combination of 
key/mouse events occurs.  In theory, a user could install event handlers 
to check if the mouse was released over the button, and then perform 
some kind of action that the button is supposed to perform.  In practice 
however, this is tricky, and would require mimicing the whole process to 
ensure the mouse was also first **pressed** on that button, if it wasn't 
moved outside the clickable area, etc.


Obviously expecting a user to install the necessary event handlers to 
detect button presses based on key and mouse events is a ridiculous 
expectation, and so Button offers a much simpler alternative: the 
ActionEvent; this is a high level event that encapsulates several other 
events, and translates it to a new concept.  It is triggered when all 
the criteria to fire the button have been met without the user needing 
to be aware of what those are.


I think the strategy of translating low level events to high level 
events, is a really good one, and suitable for reusing for other purposes.


One such purpose is converting platform dependent events into platform 
independent ones. Instead of needing to know the exact key press that 
would fire a Button, there can be an event that can fire a button.  Such 
a specific event can be filtered and listened for as usual, it can be 
redirected, blocked and it can be triggered by anyone for any reason.


For a Button, the sequence of events is normally this:

- User presses SPACE, resulting in a KeyEvent
- Behavior receives KeyEvent and arms the button
- User releases SPACE, resulting in a KeyEvent
- Behavior receives KeyEvent, disarms and fires the button
- Control fires an ActionEvent

What I'm proposing is to change it to:

- User presses SPACE, resulting in a KeyEvent
- Behavior receives KeyEvent, and sends out ButtonEvent.BUTTON_ARM
- Control receives BUTTON_ARM, and arms the button
- User releases SPACE, resulting in a KeyEvent
- Behavior receives KeyEvent and sends out ButtonEvent.BUTTON_FIRE
- Control receives BUTTON_FIRE, disarms the button and fires an ActionEvent

The above basically adds an event based indirection.  Normally it is 
KeyEvent -> ActionEvent, but now it would be KeyEvent -> ButtonEvent -> 
ActionEvent. The user now has the option of hooking into the mechanics 
of a Button at several different levels:


- The "raw" level, listening for raw key/mouse events, useful for 
creating custom behavior that can be platform specific
- The "interpreted" level, listening for things like ARM, DISARM, FIRE, 
SELECT_NEXT_WORD, SELECT_ALL, etc...; these are platform independent

- The "application" level, primarily action type events

There is sufficient precedence for such a system.  Action events are a 
good example, but another example are the DnD events which are created 
by looking at raw mouse events, effectively interpreting magic mouse 
movements and presses into more useful DnD events.


The event based indirection here is very similar to the FunctionTag 
indirection in Andy's proposal.  Instead of FunctionTags, there would be 
new events defined:


    ButtonEvent {
    public static final EventType ANY = ... ;
    public static final EventType BUTTON_ARM = ... ;
    public static final EventType BUTTON_DISARM = ... ;
    public static final EventType BUTTON_FIRE = ... ;
    }

    TextFieldEvent {
    public static final EventType ANY = ... ;
    public static final EventType SELECT_ALL = ... ;
    public static final EventType SELECT_NEXT_WORD 
= ... ;

    }